Kaynağa Gözat

Merge branch 'develop' of http://112.172.147.34:4936/style24/STYLE24.git into develop

gagamel 5 yıl önce
ebeveyn
işleme
061214ab6e
31 değiştirilmiş dosya ile 5636 ekleme ve 54 silme
  1. 8 0
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaCommonDao.java
  2. 128 0
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java
  3. 59 0
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaStockDao.java
  4. 13 0
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaCommonService.java
  5. 333 0
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaGoodsService.java
  6. 213 0
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaStockService.java
  7. 281 19
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaGoodsController.java
  8. 202 0
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaStockController.java
  9. 19 0
      style24.admin/src/main/java/com/style24/persistence/domain/GoodsPriceRes.java
  10. 7 3
      style24.admin/src/main/java/com/style24/persistence/domain/GoodsSearch.java
  11. 32 0
      style24.admin/src/main/java/com/style24/persistence/domain/GoodsVideo.java
  12. 9 0
      style24.admin/src/main/java/com/style24/persistence/domain/Option.java
  13. 38 0
      style24.admin/src/main/java/com/style24/persistence/domain/Video.java
  14. 9 0
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaCommon.xml
  15. 417 21
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml
  16. 493 0
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaStock.xml
  17. 2 2
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html
  18. 1 1
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsEpSkipForm.html
  19. 460 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsInstockAlarmForm.html
  20. 104 1
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsListForm.html
  21. 435 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsMassRegisterForm.html
  22. 513 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsPriceReserveForm.html
  23. 319 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsPriceReservePopupForm.html
  24. 1 1
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsReserveSellForm.html
  25. 344 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsSupplyPriceForm.html
  26. 2 2
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsTitleReserveForm.html
  27. 327 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsVideoForm.html
  28. 300 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsWmsInstockForm.html
  29. 545 0
      style24.admin/src/main/webapp/WEB-INF/views/stock/GoodsSizeStockForm.html
  30. 18 1
      style24.admin/src/main/webapp/ux/js/admin.common.js
  31. 4 3
      style24.admin/src/main/webapp/ux/js/admin.popup.js

+ 8 - 0
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaCommonDao.java

@@ -48,5 +48,13 @@ public interface TsaCommonDao {
 	 */
 	String getSampleFileSystemFilename(String sampleFileId);
 
+	/**
+	 * ERP 연동 여부
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 16
+	 */
+	String getErpSyncYn();
 
 }

+ 128 - 0
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java

@@ -10,14 +10,17 @@ import com.style24.persistence.domain.GoodsDesc;
 import com.style24.persistence.domain.GoodsEpSkip;
 import com.style24.persistence.domain.GoodsHst;
 import com.style24.persistence.domain.GoodsNotiInfo;
+import com.style24.persistence.domain.GoodsPriceRes;
 import com.style24.persistence.domain.GoodsResSell;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.GoodsTnmRes;
+import com.style24.persistence.domain.GoodsVideo;
 import com.style24.persistence.domain.Itemkind;
 import com.style24.persistence.domain.NotiInfo;
 import com.style24.persistence.domain.Notice;
 import com.style24.persistence.domain.NoticeGoods;
 import com.style24.persistence.domain.Option;
+import com.style24.persistence.domain.Video;
 import com.style24.persistence.domain.WmsColorMapping;
 import com.style24.persistence.domain.WmsSeasonMapping;
 import com.style24.persistence.domain.WmsStyleYearMapping;
@@ -655,4 +658,129 @@ public interface TsaGoodsDao {
 	 */
 	void deleteNoticeGoods(NoticeGoods noticeGoods);
 
+	/**
+	 * 상품 가격예약 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	int getGoodsPriceResCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 가격예약 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<GoodsPriceRes>
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	Collection<GoodsPriceRes> getGoodsPriceResList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 가격예약 조회(기간 체크용)
+	 *
+	 * @param goodsPriceRes
+	 * @return int
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	int getGoodsPriceResDupChkCount(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 가격예약 등록(화면)
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	void createGoodPriceRes(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 가격예약 삭제
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	void deleteGoodPriceRes(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	Collection<GoodsVideo> getGoodsVideoList(GoodsVideo goodsVideo);
+
+	/**
+	 * 상품 동영상 사용안함으로 변경
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void updateNotUseGoodsVideo(Video video);
+
+	/**
+	 * 동영상 일련번호 조회
+	 *
+	 * @param video
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	String getVideoSeq(Video video);
+
+	/**
+	 * 동영상 등록
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void createVideo(Video video);
+
+	/**
+	 * 동영상 수정
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void updateVideo(Video video);
+
+	/**
+	 * 동영상 위치 삭제 Y 처리
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void delVideoDispLoc(Video video);
+
+	/**
+	 * 동영상 위치 수정/저장
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void saveVideoDispLoc(Video video);
+
+	/**
+	 * 상품 사이즈 존재여부 확인
+	 *
+	 * @param option
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	int getGoodsSizeCount(Option option);
+
 }

+ 59 - 0
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaStockDao.java

@@ -0,0 +1,59 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.GoodsSearch;
+import com.style24.persistence.domain.Option;
+
+import com.gagaframework.web.parameter.GagaMap;
+
+/**
+ * 재고관리 Dao
+ *
+ * @author eskim
+ * @since 2020. 11. 17
+ */
+@ShopDs
+public interface TsaStockDao {
+
+	/**
+	 * 상품 사이즈별 재고 현황 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2010. 11. 17
+	 */
+	int getGoodsSizeStockCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 사이즈별 재고 현황 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2010. 11. 17
+	 */
+	Collection<Option> getGoodsSizeStockList(GoodsSearch goodsSearch);
+
+	/**
+	 * 사이즈별재고현황 - 엑셀다운로드
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	Collection<GagaMap> getGoodsSizeStockExcelList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 사이즈별 품절여부 변경
+	 *
+	 * @param stock
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	void updateStockSoldOut(Option stock);
+
+}

+ 13 - 0
style24.admin/src/main/java/com/style24/admin/biz/service/TsaCommonService.java

@@ -68,4 +68,17 @@ public class TsaCommonService {
 		return commonDao.getSampleFileSystemFilename(sampleFileId);
 	}
 
+	/**
+	 * ERP 연동 여부
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 16
+	 */
+	public String getErpSyncYn() {
+		return commonDao.getErpSyncYn();
+	}
+
+
 }

+ 333 - 0
style24.admin/src/main/java/com/style24/admin/biz/service/TsaGoodsService.java

@@ -1,6 +1,7 @@
 package com.style24.admin.biz.service;
 
 import java.io.IOException;
+import java.text.SimpleDateFormat;
 import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,15 +24,18 @@ import com.style24.persistence.domain.GoodsDesc;
 import com.style24.persistence.domain.GoodsEpSkip;
 import com.style24.persistence.domain.GoodsHst;
 import com.style24.persistence.domain.GoodsNotiInfo;
+import com.style24.persistence.domain.GoodsPriceRes;
 import com.style24.persistence.domain.GoodsResSell;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.GoodsTnmRes;
+import com.style24.persistence.domain.GoodsVideo;
 import com.style24.persistence.domain.Itemkind;
 import com.style24.persistence.domain.NotiInfo;
 import com.style24.persistence.domain.Notice;
 import com.style24.persistence.domain.NoticeGoods;
 import com.style24.persistence.domain.Option;
 import com.style24.persistence.domain.SearchData;
+import com.style24.persistence.domain.Video;
 import com.style24.persistence.domain.WmsColorMapping;
 import com.style24.persistence.domain.WmsSeasonMapping;
 import com.style24.persistence.domain.WmsStyleYearMapping;
@@ -1132,6 +1136,19 @@ public class TsaGoodsService {
 		}
 	}
 
+
+	/**
+	 * 상품 사이즈 옵션정보 이력 생성
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	@Transactional("shopTxnManager")
+	public void createStockHst(Option option) {
+		goodsDao.createStockHst(option);
+	}
+
 	/**
 	 * 상품 정보고시 변경 - 상품상세
 	 *
@@ -1787,4 +1804,320 @@ public class TsaGoodsService {
 		}
 
 	}
+
+	/**
+	 * 상품 가격예약 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	public int getGoodsPriceResCount(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsPriceResCount(goodsSearch);
+	}
+
+	/**
+	 * 상품 가격예약 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<TsaGoodsResSell>
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	public Collection<GoodsPriceRes> getGoodsPriceResList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsPriceResList(goodsSearch);
+	}
+
+	/**
+	 * 상품 가격예약 등록
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void createGoodPriceRes(GoodsPriceRes goodsPriceRes) {
+		if (goodsPriceRes.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		int idx = 0;
+		for (String goodsCd : goodsPriceRes.getArrGoodsCd()) {
+
+			goodsPriceRes.setGoodsCd(goodsCd);
+			goodsPriceRes.setEndGoodsPrice(goodsPriceRes.getArrEndGoodsPrice()[idx]);
+			goodsPriceRes.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsPriceRes.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if(goodsDao.getGoodsPriceResDupChkCount(goodsPriceRes) > 0 ) {
+				throw new IllegalStateException("이미 등록된 상품 가격예약이 존재합니다. \n(상품코드 : " + goodsCd + ")");
+			}
+
+			goodsDao.createGoodPriceRes(goodsPriceRes);
+
+			Goods goods = new Goods();
+			goods.setRegNo(TsaSession.getInfo().getUserNo());
+			goods.setUpdNo(TsaSession.getInfo().getUserNo());
+			goods.setGoodsCd(goodsPriceRes.getGoodsCd());
+			idx++;
+		}
+	}
+
+	/**
+	 * 상품 가격예약 삭제
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteGoodsPriceRes(GoodsPriceRes goodsPriceRes) {
+		if (goodsPriceRes.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		int idx = 0;
+		for (String goodsCd : goodsPriceRes.getArrGoodsCd()) {
+			goodsPriceRes.setGoodsPriceResSq(goodsPriceRes.getArrGoodsPriceResSq()[idx]);
+			goodsDao.deleteGoodPriceRes(goodsPriceRes);
+			idx++;
+		}
+	}
+
+	/**
+	 * 상품 가격예약 저장
+	 *
+	 * @param goodsPriceList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsPriceExcelupload(Collection<GoodsPriceRes> goodsPriceList, String excelFilename) {
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		if (goodsPriceList == null || goodsPriceList.isEmpty()) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		// 입력값 확인
+		String goodsPriceResvCheck = getGoodsPriceResvCheck(goodsPriceList);
+		if (!"SUCC".equals(goodsPriceResvCheck)) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(goodsPriceResvCheck);
+		}
+
+		int index = 0;
+		for (GoodsPriceRes goodsPriceRes : goodsPriceList) {
+			goodsPriceRes.setUpdNo(TsaSession.getInfo().getUserNo());
+			goodsPriceRes.setRegNo(TsaSession.getInfo().getUserNo());
+
+			// 엑셀조회를 위한 SEARCH 테이블 생성
+			SearchData searchData = new SearchData();
+			searchData.setRegNo(goodsPriceRes.getRegNo());
+			searchData.setSearchCd(goodsPriceRes.getGoodsCd());
+			searchData.setDispOrd(index);
+			if (index == 0) {
+				commonService.deleteExceluploadSearCh(searchData);
+			}
+
+			commonService.createExceluploadSearch(searchData);
+
+			goodsDao.createGoodPriceRes(goodsPriceRes);
+
+			index++;
+		}
+	}
+
+	/*
+	 * 상품 가격예약 엑셀조회용 상품 저장 - 입력값 확인
+	 */
+	private String getGoodsPriceResvCheck(Collection<GoodsPriceRes> goodsPriceList) {
+
+		int cnt = 0;
+		for (GoodsPriceRes goodsPriceRes : goodsPriceList) {
+
+			if (StringUtils.isEmpty(goodsPriceRes.getGoodsCd())) {
+				return (cnt + 2) + "행의 상품코드를 확인해주세요";
+			}
+			if (StringUtils.isEmpty(goodsPriceRes.getResGoodsPrice())) {
+				return (cnt + 2) + "행의 예약가격을 확인해주세요.";
+			}
+			if (goodsPriceRes.getResGoodsPrice() <= 0) {
+				return (cnt + 2) + "행의 예약가격을 확인해주세요.";
+			}
+
+			String nowDate = GagaDateUtil.getToday();	//yyyyMMdd
+			SimpleDateFormat dateFormatParser = new SimpleDateFormat("yyyyMMdd");
+			dateFormatParser.setLenient(false);
+			try {
+				dateFormatParser.parse(goodsPriceRes.getApplyStdt() );
+			} catch (Exception e) {
+				return (cnt + 2) + "행의 예약시작일을 확인해주세요.";
+			}
+			try {
+				dateFormatParser.parse(goodsPriceRes.getApplyEddt() );
+			} catch (Exception e) {
+				return (cnt + 2) + "행의 예약종료일을 확인해주세요.";
+			}
+
+			if (Integer.parseInt(goodsPriceRes.getApplyStdt()) > Integer.parseInt(goodsPriceRes.getApplyEddt())) {
+				return (cnt + 2) + "행의 예약 시작일은 종료일보다 보다 클 수 없습니다.";
+			}
+
+			if (Integer.parseInt(goodsPriceRes.getApplyStdt()) <= Integer.parseInt(nowDate)) {
+				return (cnt + 2) + "행의 예약 시작일자는 현재일자 보다 작거나 같을 수 없습니다.";
+			}
+
+			//정상가와 비교
+			Goods searchGoods = new Goods();
+			searchGoods.setGoodsCd(goodsPriceRes.getGoodsCd());
+			Goods goods = goodsDao.getGoods(searchGoods);
+			if (goods == null) {
+				return (cnt + 2) + "행의 상품코드를 확인해주세요";
+			}
+			if (goods.getListPrice() < goodsPriceRes.getResGoodsPrice()) {
+				return (cnt + 2) + "행의 상품 정상가보다 예약판매가가 더 큽니다.";
+			}
+			if (!"Y".equals(goods.getSelfGoodsYn())) {
+				return (cnt + 2) + "행의 상품은 자사상품이 아닙니다.";
+			}
+
+			if(goodsDao.getGoodsPriceResDupChkCount(goodsPriceRes) > 0 ) {
+				return (cnt + 2) + "행은 이미 등록된 상품 가격예약이 존재합니다. \n(상품코드 : " + goodsPriceRes.getGoodsCd() + ")";
+			}
+
+
+			cnt++;
+		}
+
+		return "SUCC";
+	}
+
+
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	public Collection<GoodsVideo> getGoodsVideoList(GoodsVideo goodsVideo) {
+		return goodsDao.getGoodsVideoList(goodsVideo);
+	}
+
+	/**
+	 * 상품 동영상 삭제로 변경
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void updateNotUseGoodsVideo(Collection<GoodsVideo> goodsVideos) {
+		for (GoodsVideo goodsVideo : goodsVideos) {
+			Video video = new Video();
+			video.setUpdNo(TsaSession.getInfo().getUserNo());
+			video.setVideoSq(goodsVideo.getVideoSq());
+			goodsDao.updateNotUseGoodsVideo(video);
+		}
+	}
+
+	/**
+	 * 상품동영상 수정/저장
+	 *
+	 * @param video
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsVideo(Video video) {
+		video.setRegNo(TsaSession.getInfo().getUserNo());
+		video.setUpdNo(TsaSession.getInfo().getUserNo());
+		if (video.getVideoSq() == null ||  video.getVideoSq() == 0) {
+
+			String videoSeq = goodsDao.getVideoSeq(video);
+			if (StringUtils.isEmpty(videoSeq)) {
+				goodsDao.createVideo(video);
+			}else {
+				//video.setVideoSq(Integer.parseInt(videoSeq));  //why?
+				//goodsDao.updateVideo(video);
+			}
+		}
+
+		if (video.getVideoSq() == null ||  video.getVideoSq() == 0) {
+			String videoSeq = goodsDao.getVideoSeq(video);
+
+			if (!StringUtils.isEmpty(videoSeq)) {
+				video.setVideoSq(Integer.parseInt(videoSeq));
+			}
+		}
+
+		//goodsDao.delVideoDispLoc(video);  why?
+		String[] displocValArr = video.getDisplocValArr();
+		for (String displocVal : displocValArr) {
+			video.setDisplocVal(displocVal);
+			goodsDao.saveVideoDispLoc(video);
+		}
+	}
+
+	/**
+	 * 상품동영상 엑셀파일 등록
+	 *
+	 * @param dataList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public int saveExcelGoodsVideo(Collection<GagaMap> dataList) {
+
+		int cnt = 0;
+
+		for (GagaMap map : dataList) {
+			Video video = mapper.convertValue(map, Video.class);
+			video.setUpdNo(TsaSession.getInfo().getUserNo());
+			video.setRegNo(TsaSession.getInfo().getUserNo());
+			video.setDisplocGb("G");
+			video.setDispYn("Y");
+			String videoVal = video.getVideoVal();
+			if (videoVal.contains("http")) {
+				video.setVideoGb("M");
+			} else {
+				video.setVideoGb("Y");
+			}
+			String videoSeq = goodsDao.getVideoSeq(video);
+
+			if (StringUtils.isEmpty(videoSeq)) {
+				goodsDao.createVideo(video);
+			}
+
+			videoSeq = goodsDao.getVideoSeq(video);
+			if (!StringUtils.isEmpty(videoSeq)) {
+				video.setVideoSq(Integer.parseInt(videoSeq));
+			}
+			goodsDao.saveVideoDispLoc(video);
+			cnt++;
+		}
+
+		return cnt;
+	}
+
+	/**
+	 * 상품별 사이즈 등록 여부 확인
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	public int getGoodsSizeCount(Option option) {
+
+		return goodsDao.getGoodsSizeCount(option);
+	}
 }

+ 213 - 0
style24.admin/src/main/java/com/style24/admin/biz/service/TsaStockService.java

@@ -0,0 +1,213 @@
+package com.style24.admin.biz.service;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import com.style24.admin.biz.dao.TsaStockDao;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.GoodsSearch;
+import com.style24.persistence.domain.Option;
+import com.style24.persistence.domain.SearchData;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.excel.env.GagaExcelConstants;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaFileUtil;
+
+
+/**
+ * 재고관리 Service
+ *
+ * @author eskim
+ * @since 2020. 11. 17
+ */
+@Service
+@Slf4j
+public class TsaStockService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaStockDao stockDao;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+	@Autowired
+	private TsaGoodsService goodsService;
+
+	/**
+	 * 상품 사이즈별 재고 현황 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2010. 11. 17
+	 */
+	public int getGoodsSizeStockCount(GoodsSearch goodsSearch) {
+		return stockDao.getGoodsSizeStockCount(goodsSearch);
+	}
+
+	/**
+	 * 상품 사이즈별 재고 현황 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2010. 11. 17
+	 */
+	public Collection<Option> getGoodsSizeStockList(GoodsSearch goodsSearch) {
+		return stockDao.getGoodsSizeStockList(goodsSearch);
+	}
+
+	/**
+	 * 사이즈별재고현황 - 엑셀다운로드
+	 *
+	 * @param goodsSearch
+	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	public void getGoodsSizeStockExcelList(GoodsSearch goodsSearch, String excelFilenameWithPath) {
+		// 헤더 title 설정
+		String[] listTitles = {"브랜드명","상품명", "품목", "상품상태", "상품코드",  "옵션코드", "색상" , "사이즈", "품절여부",
+			"재고", "안전재고","출고대기", "판매가능재고"};
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellNames = { "BRAND_ENM", "GOODS_NM", "ITEMKIND_NM","GOODS_STAT_NM","GOODS_CD", "OPT_CD", "OPT_CD1","OPT_CD2", "SOLDOUT_YN",
+			"CURR_STOCK_QTY", "BASE_STOCK_QTY", "SALE_STOCK_QTY", "ABLE_STOCK_QTY"};
+
+		String[] cellTypes = {GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
+			GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name()
+		};
+
+		Collection<GagaMap> dataList = stockDao.getGoodsSizeStockExcelList(goodsSearch);
+
+		try {
+			GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "사이즈별재고현황", listTitles, cellNames, cellTypes,
+				TsaConstants.EXCEL_FOOTER_TITLE);
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	/**
+	 * 상품 입출고 엑셀조회용 상품 저장
+	 *
+	 * @param procJob : goodsExcelUpload
+	 * @param goodsSizeList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 02. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsSizeSoldoutExcelupload(Collection<Option> goodsSizeList, String excelFilename) {
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		if (goodsSizeList == null || goodsSizeList.isEmpty()) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		// 입력값 확인
+		String goodsSizeSoldoutCheck = getGoodsSizeSoldoutCheck(goodsSizeList);
+		if (!"SUCC".equals(goodsSizeSoldoutCheck)) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(goodsSizeSoldoutCheck);
+		}
+
+		int index = 0;
+		for (Option stock : goodsSizeList) {
+			stock.setUpdNo(TsaSession.getInfo().getUserNo());
+			stock.setRegNo(TsaSession.getInfo().getUserNo());
+
+			// 엑셀조회를 위한 SEARCH 테이블 생성
+			SearchData searchData = new SearchData();
+			searchData.setRegNo(stock.getRegNo());
+			searchData.setSearchCd(stock.getGoodsCd());
+			searchData.setDispOrd(index);
+			searchData.setDummy1(stock.getOptCd());
+			if (index == 0) {
+				commonService.deleteExceluploadSearCh(searchData);
+			}
+
+			commonService.createExceluploadSearchByAll(searchData);
+
+			goodsService.createStockHst(stock);
+
+			stockDao.updateStockSoldOut(stock);
+
+			index++;
+		}
+	}
+
+	/*
+	 * 상품 입출고 엑셀조회용 상품 저장 - 입력값 확인
+	 */
+	private String getGoodsSizeSoldoutCheck(Collection<Option> goodsStockList) {
+
+		int cnt = 0;
+		for (Option stock : goodsStockList) {
+
+			if (StringUtils.isEmpty(stock.getGoodsCd())) {
+				return (cnt + 2) + "행의 상품코드를 확인해주세요";
+			}
+			if (StringUtils.isEmpty(stock.getOptCd())) {
+				return (cnt + 2) + "행의 사이즈를 확인해주세요.";
+			}
+			if (!"N".equals(stock.getSoldoutYn()) && !"Y".equals(stock.getSoldoutYn())) {
+				return (cnt + 2) + "행의 품절여부  확인해주세요.";
+			}
+			// 상품코드 사이즈 확인
+			int stockCnt = goodsService.getGoodsSizeCount(stock);
+			if (stockCnt <= 0) {
+				return (cnt + 2) + "행의 상품 사이즈는 존재하지 않습니다.<br/>확인해주세요.";
+			}
+			if (StringUtils.isEmpty(stock.getBaseStockQty())) {
+				return (cnt + 2) + "행의 안전재고 수량을 확인해주세요.";
+			}
+
+			cnt++;
+		}
+
+		return "SUCC";
+	}
+
+	/**
+	 * 파일 삭제
+	 *
+	 * @param targetPath
+	 * @param excelFilename
+	 * @author eskim
+	 * @since 2019. 09. 26
+	 */
+	private void deleteExceluploadFile(String targetPath, String excelFilename) {
+		// 파일 삭제
+		try {
+			GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, excelFilename));
+		} catch (IOException e) {
+			// Nothing Do
+		}
+	}
+
+}

+ 281 - 19
style24.admin/src/main/java/com/style24/admin/biz/web/TsaGoodsController.java

@@ -21,8 +21,10 @@ import org.springframework.web.servlet.ModelAndView;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.style24.admin.biz.service.TsaCommonService;
 import com.style24.admin.biz.service.TsaGoodsService;
 import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaSystemService;
 import com.style24.admin.support.controller.TsaBaseController;
 import com.style24.admin.support.security.session.TsaSession;
 import com.style24.core.support.message.TscMessageByLocale;
@@ -33,13 +35,17 @@ import com.style24.persistence.domain.GoodsCompose;
 import com.style24.persistence.domain.GoodsEpSkip;
 import com.style24.persistence.domain.GoodsHst;
 import com.style24.persistence.domain.GoodsNotiInfo;
+import com.style24.persistence.domain.GoodsPriceRes;
 import com.style24.persistence.domain.GoodsResSell;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.GoodsTnmRes;
+import com.style24.persistence.domain.GoodsVideo;
 import com.style24.persistence.domain.Itemkind;
 import com.style24.persistence.domain.NotiInfo;
 import com.style24.persistence.domain.Notice;
 import com.style24.persistence.domain.NoticeGoods;
+import com.style24.persistence.domain.User;
+import com.style24.persistence.domain.Video;
 import com.style24.persistence.domain.WmsColorMapping;
 import com.style24.persistence.domain.WmsSeasonMapping;
 import com.style24.persistence.domain.WmsStyleYearMapping;
@@ -76,6 +82,12 @@ public class TsaGoodsController extends TsaBaseController {
 	@Autowired
 	private TsaRendererService rendererService;
 
+	@Autowired
+	private TsaCommonService commonService;
+
+	@Autowired
+	private TsaSystemService systemService;
+
 	/**
 	 * 품목관리 화면
 	 *
@@ -467,7 +479,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 
 		// multi row 검색관련 처리
@@ -507,7 +519,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
 
@@ -679,7 +691,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
 		result.set("goodsExcelList", goodsService.getGoodsList(goodsSearch));
@@ -1027,6 +1039,21 @@ public class TsaGoodsController extends TsaBaseController {
 	public ModelAndView massRegisterForm() {
 		ModelAndView mav = new ModelAndView();
 
+		// 상품상태
+		mav.addObject("goodsStatList", rendererService.getAvailCommonCodeList("G008"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// ERP 연동여부
+		mav.addObject("erpSyncYn", commonService.getErpSyncYn());
+		// 정보고시 목록
+		mav.addObject("niClsfCdList", rendererService.getAvailCommonCodeList("G004"));
+		// 사용자 업체
+		User loginInfo = systemService.getUser(TsaSession.getInfo().getUserNo());
+		String supplyCompCd = "NONE";
+		if (loginInfo != null) {
+			supplyCompCd = loginInfo.getSupplyCompCd();
+		}
+		mav.addObject("supplyCompCd", supplyCompCd);
 		mav.setViewName("goods/GoodsMassRegisterForm");
 
 		return mav;
@@ -1043,6 +1070,12 @@ public class TsaGoodsController extends TsaBaseController {
 	public ModelAndView wmsInstockForm() {
 		ModelAndView mav = new ModelAndView();
 
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+
 		mav.setViewName("goods/GoodsWmsInstockForm");
 
 		return mav;
@@ -1101,17 +1134,23 @@ public class TsaGoodsController extends TsaBaseController {
 
 
 	/**
-	 * 상품 가격예약 관리 화면
+	 * 입점 가격 관리 화면
 	 *
 	 * @return
 	 * @author eskim
 	 * @since 2020. 10. 16
 	 */
-	@GetMapping("/price/form")
+	@GetMapping("/supply/price/form")
 	public ModelAndView priceForm() {
 		ModelAndView mav = new ModelAndView();
-
-		mav.setViewName("goods/GoodsPriceForm");
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList());
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		mav.setViewName("goods/GoodsSupplyPriceForm");
 
 		return mav;
 	}
@@ -1175,7 +1214,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 
 		// multi row 검색관련 처리
@@ -1236,16 +1275,15 @@ public class TsaGoodsController extends TsaBaseController {
 	@ResponseBody
 	public GagaResponse deleteGoodsRsvtTnm(@RequestBody GoodsTnmRes goodsTnmRes) {
 		goodsService.deleteGoodsRsvtTnm(goodsTnmRes);
-		return super.ok(message.getMessage("SUCC_0001"));
+		return super.ok(message.getMessage("SUCC_0003"));
 	}
 
-
 	/**
 	 * 상품 동영상관리 화면
 	 *
 	 * @return
 	 * @author eskim
-	 * @since 2020. 10. 16
+	 * @since 2020. 11. 16
 	 */
 	@GetMapping("/video/form")
 	public ModelAndView videoForm() {
@@ -1256,6 +1294,75 @@ public class TsaGoodsController extends TsaBaseController {
 		return mav;
 	}
 
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/list")
+	@ResponseBody
+	public Collection<GoodsVideo> getGoodsVideoList(@RequestBody GoodsVideo goodsVideo) {
+		return goodsService.getGoodsVideoList(goodsVideo);
+	}
+
+	/**
+	 * 상품 동영상 미노출 변경
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/update/notUse")
+	@ResponseBody
+	public GagaResponse updateNotUseGoodsVideo(@RequestBody Collection<GoodsVideo> goodsVideos) {
+		goodsService.updateNotUseGoodsVideo(goodsVideos);
+		return super.ok(message.getMessage("SUCC_0009"));
+	}
+
+	/**
+	 * 상품동영상 수정/저장
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/save")
+	@ResponseBody
+	public GagaResponse saveGoodsVideo(@RequestBody Video video) {
+		goodsService.saveGoodsVideo(video);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품동영상 엑셀 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/excel/save")
+	@ResponseBody
+	public GagaResponse saveExcelGoodsVideo(@RequestBody Video video) throws Exception {
+		String[] cellName = null;
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		cellName = new String[2];
+		cellName[0] = "displocVal";
+		cellName[1] = "videoVal";
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.default.target.path"), "excel");
+		Collection<GagaMap> dataList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, video.getExcelFileNm()), 0, cellName);
+
+		int cnt = goodsService.saveExcelGoodsVideo(dataList);
+
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, video.getExcelFileNm()));
+
+		return super.ok(cnt + " 건 처리되었습니다.");
+	}
+
 	/**
 	 * 상품 EP제외상품관리 화면
 	 *
@@ -1311,7 +1418,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 
 		// multi row 검색관련 처리
@@ -1372,7 +1479,7 @@ public class TsaGoodsController extends TsaBaseController {
 	@ResponseBody
 	public GagaResponse deleteGoodsEpSkip(@RequestBody GoodsEpSkip goodsEpSkip) {
 		goodsService.deleteGoodsEpSkip(goodsEpSkip);
-		return super.ok(message.getMessage("SUCC_0001"));
+		return super.ok(message.getMessage("SUCC_0003"));
 	}
 
 
@@ -1450,7 +1557,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001-B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 
 		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
@@ -1470,7 +1577,7 @@ public class TsaGoodsController extends TsaBaseController {
 	 * @author eskim
 	 * @since 2020. 11. 12
 	 */
-	@GetMapping("/reserve/sell/regist/form")
+	@GetMapping("/reserve/sell/popup/form")
 	@ResponseBody
 	public ModelAndView goodsReserveSellRegistForm() {
 		ModelAndView mav = new ModelAndView();
@@ -1506,7 +1613,7 @@ public class TsaGoodsController extends TsaBaseController {
 	@ResponseBody
 	public GagaResponse deleteGoodsResSell(@RequestBody GoodsResSell goodsResSell) {
 		goodsService.deleteGoodsResSell(goodsResSell);
-		return super.ok(message.getMessage("SUCC_0001"));
+		return super.ok(message.getMessage("SUCC_0003"));
 	}
 
 	/**
@@ -1542,7 +1649,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 
 		// multi row 검색관련 처리
@@ -1595,7 +1702,7 @@ public class TsaGoodsController extends TsaBaseController {
 	@ResponseBody
 	public GagaResponse deleteNoticeGoods(@RequestBody NoticeGoods noticeGoods) {
 		goodsService.deleteNoticeGoods(noticeGoods);
-		return super.ok(message.getMessage("SUCC_0001"));
+		return super.ok(message.getMessage("SUCC_0003"));
 	}
 
 	/**
@@ -1659,7 +1766,7 @@ public class TsaGoodsController extends TsaBaseController {
 		// 입점업체담당자는 업체코드 설정
 		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
 			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
-			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
 		}
 
 		// multi row 검색관련 처리
@@ -1683,4 +1790,159 @@ public class TsaGoodsController extends TsaBaseController {
 		return result;
 	}
 
+	/**
+	 * 상품 가격예약관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/price/reserve/form")
+	public ModelAndView priceReserveForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+		String supplyCompCd = "";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear,0,5));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+
+		mav.setViewName("goods/GoodsPriceReserveForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 가격예약 목록 조회
+	 *
+	 * @param goodsSearch
+	 * @return GagaMap
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/price/reserve/list")
+	@ResponseBody
+	public GagaMap goodsPriceReserveList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001-B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsPriceResCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsPriceResList", goodsService.getGoodsPriceResList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 상품 가격예약 등록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/price/reserve/popup/form")
+	@ResponseBody
+	public ModelAndView goodsPriceReserveRegistForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsPriceReservePopupForm");
+		return mav;
+	}
+
+	/**
+	 * 상품 가격예약 저장
+	 *
+	 * @param goodsResSell
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/price/reserve/save")
+	@ResponseBody
+	public GagaResponse saveGoodsPriceRes(@RequestBody GoodsPriceRes goodsPriceRes) {
+		goodsService.createGoodPriceRes(goodsPriceRes);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 가격예약 삭제
+	 *
+	 * @param goodsResSell
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/price/reserve/delete")
+	@ResponseBody
+	public GagaResponse deleteGoodsPriceRes(@RequestBody GoodsPriceRes goodsPriceRes) {
+		goodsService.deleteGoodsPriceRes(goodsPriceRes);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+
+	/**
+	 * 상품 가격예약 변경
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 02. 20
+	 */
+	@PostMapping("/price/excelupload/save")
+	@ResponseBody
+	public GagaResponse saveGoodsPriceResvExcelupload(@RequestBody Goods goods) throws Exception {
+
+		log.info("[saveGoodsPriceResvExcelupload] goods={} ",goods);
+		ObjectMapper mapper = new ObjectMapper();
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		log.info("[saveGoodsPriceResvExcelupload] targetPath={} ",targetPath);
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellName = {"goodsCd", "resGoodsPrice", "applyStdt", "applyEddt"};
+
+		Collection<GagaMap> ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()), 0, cellName, 0);
+
+		Collection<GoodsPriceRes> goodsPriceList = new ArrayList<>();
+		for (GagaMap map : ecxelGoodsList) {
+			GoodsPriceRes goodsPriceRes = mapper.convertValue(map, GoodsPriceRes.class);
+			goodsPriceList.add(goodsPriceRes);
+		}
+
+		goodsService.saveGoodsPriceExcelupload(goodsPriceList, goods.getExcelFileNm());
+
+		// 파일 삭제
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()));
+
+		return super.ok("");
+	}
+
 }

+ 202 - 0
style24.admin/src/main/java/com/style24/admin/biz/web/TsaStockController.java

@@ -0,0 +1,202 @@
+package com.style24.admin.biz.web;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaStockService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.TsaPageRequest;
+import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.Goods;
+import com.style24.persistence.domain.GoodsSearch;
+import com.style24.persistence.domain.Option;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+
+/**
+ * 상품 재고 Controller
+ *
+ * @author eskim
+ * @since 2020. 11. 17
+ */
+@Controller
+@RequestMapping("/stock")
+@Slf4j
+public class TsaStockController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaStockService stockService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	/**
+	 * 사이즈별재고현황 화면
+	 *
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	@RequestMapping(value = "/size/form", method = RequestMethod.GET)
+	public ModelAndView goodsSizeStockListForm() {
+
+		ModelAndView mav = new ModelAndView();
+		//사이트
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		String supplyCompCd = "";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear,0,5));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+		// 색상
+		Color color = new Color();
+		mav.addObject("colorList", rendererService.getColorList(color));
+
+		mav.setViewName("stock/GoodsSizeStockForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사이즈별재고현황 조회
+	 *
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	@RequestMapping(value = "/sizeStock/list", method = RequestMethod.POST)
+	@ResponseBody
+	public GagaMap getGoodsSizeStockList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		//입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo());	//엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(stockService.getGoodsSizeStockCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsSizeStockList", stockService.getGoodsSizeStockList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 사이즈별재고현황 - 엑셀다운로드
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	@RequestMapping(value = "/sizeStock/excel/list", method = RequestMethod.GET)
+	public ResponseEntity<InputStreamResource> downloadGoodsInfoExcelList(HttpServletRequest request, GoodsSearch goodsSearch) throws Exception {
+		String excelfileName = "사이즈별재고현황_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilenameWithPath = GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+
+		log.info("downloadGoodsInfoExcelList goodsSearch= {}", goodsSearch);
+		//입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo());	//엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+
+		// 대용량엑셀파일다운로드는 이런 식으로 ...
+		stockService.getGoodsSizeStockExcelList(goodsSearch, excelFilenameWithPath);
+
+		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
+	}
+
+	/**
+	 * 상품 사이즈별 품절/안전재고 변경
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 02. 20
+	 */
+	@PostMapping("/sizeSoldout/excelupload/save")
+	@ResponseBody
+	public GagaResponse saveGoodsSizeSoldoutExcelupload(@RequestBody Goods goods) throws Exception {
+
+		ObjectMapper mapper = new ObjectMapper();
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellName = { "brandEnm", "goodsNm", "itemkindCd","goodsStat","goodsCd", "optCd", "optCd1", "optCd2",  "soldoutYn",
+			"currStockQty", "baseStockQty","saleStockQty", "ableStockQty"};
+
+		Collection<GagaMap> ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()), 0, cellName, 0);
+
+		Collection<Option> goodsSizeList = new ArrayList<>();
+		for (GagaMap map : ecxelGoodsList) {
+			Option tmpGoods = mapper.convertValue(map, Option.class);
+			goodsSizeList.add(tmpGoods);
+		}
+
+		stockService.saveGoodsSizeSoldoutExcelupload(goodsSizeList, goods.getExcelFileNm());
+
+		// 파일 삭제
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()));
+
+		return super.ok("");
+	}
+}

+ 19 - 0
style24.admin/src/main/java/com/style24/persistence/domain/GoodsPriceRes.java

@@ -1,5 +1,6 @@
 package com.style24.persistence.domain;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.style24.persistence.TscBaseDomain;
 
 import lombok.Data;
@@ -24,4 +25,22 @@ public class GoodsPriceRes extends TscBaseDomain {
 	private String cfrmDt;
 	private String applyYn;
 
+	private String cfrmNm;
+
+	private String goodsNm;
+	private String supplyGoodsCd;
+	private String brandEnm;
+	private String goodsStat;
+	private int currPrice;
+
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] arrGoodsCd;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private int[] arrEndGoodsPrice;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private int[] arrGoodsPriceResSq;
+
 }

+ 7 - 3
style24.admin/src/main/java/com/style24/persistence/domain/GoodsSearch.java

@@ -36,7 +36,7 @@ public class GoodsSearch extends TscBaseDomain {
 	private String soldOutYn;
 	private String erpStockLinkYn;
 	private String erpPriceLinkYn;
-	private int mdNo;
+	private String mdNo;
 	private String currPrice;
 	private String currPriceSt;
 	private String currPriceEd;
@@ -57,8 +57,8 @@ public class GoodsSearch extends TscBaseDomain {
 	private String callBackFun;
 	private String applyStdt;
 	private String applyEddt;
-	private String sizeCd;
-	private String colorCd;
+	private String optCd2;	//옵션2
+	private String colorCd;	//옵션1
 	private String beforSkipFlag;
 	private String goodsTnm;
 	private String imageViewYn;
@@ -69,6 +69,10 @@ public class GoodsSearch extends TscBaseDomain {
 	private String applyFlag;
 	private String barcode;
 	private String dateGbn;
+	private String goodsTnmRes;
+	private int goodsPriceResSt;
+	private int goodsPriceResEd;
+	private String selfGoodsYn;
 
 	private String goodsType;
 	private String selfMallYn;

+ 32 - 0
style24.admin/src/main/java/com/style24/persistence/domain/GoodsVideo.java

@@ -0,0 +1,32 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+
+/**
+ * 상품 동영상 Domain
+ *
+ * @author eskim
+ * @since 2020. 11. 16
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsVideo extends TscBaseDomain {
+
+	private Integer videoSq;
+	private String brandCd; // 브랜드코드
+	private String brandEnm; // 브랜드영문명
+	private String brandGrpNm; // 브랜드그룹명
+	private String goodsCd;
+	private String videoGb;
+	private String videoVal;
+	private String dispYn;
+	private String goodsNm;
+	private String goodsNum;
+	private String supplyGoodsCd;
+	private String excelFileNm;
+	private String stDate;
+	private String edDate;
+}

+ 9 - 0
style24.admin/src/main/java/com/style24/persistence/domain/Option.java

@@ -30,7 +30,16 @@ public class Option extends TscBaseDomain {
 	private int rcount;
 	private int saleStockQty;
 	private int ableStockQty;
+	private String goodsNm;
+	private String goodsStat;
+	private String goodsStatNm;
 	private String compsGoodsCd;
 	private String selfGoodsYn;
+	private String itemkindNm;
+	private String brandEnm;
+	private String brandCd;
+	private String itemkindCd;
+	private String supplyCompCd;
+	private String supplyGoodsCd;
 
 }

+ 38 - 0
style24.admin/src/main/java/com/style24/persistence/domain/Video.java

@@ -0,0 +1,38 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+
+/**
+ * 동영상 Domain
+ *
+ * @author eskim
+ * @since 2020. 11. 16
+ */
+@SuppressWarnings("serial")
+@Data
+public class Video extends TscBaseDomain {
+
+	private Integer videoSq;
+	private String displocGb;	//노출위치구분(B:브랜드, G:상품)
+	private String displocVal;	//노출위치값(노출위치구분이 "B:브랜드"이면 브랜드코드, "G:상품"이면 상품코드)
+	private String videoGb;	//동영상구분(Y:유투브, M:MP4)
+	private String videoVal;	//동영상값(동영상구분이 Y이면 유투브ID, M이면 URL)
+	private String videoTitle;
+	private String videoTitle2;
+	private String dispYn;
+	private String excelFileNm;
+	private String brandEnm;
+	private String stDate;
+	private String edDate;
+	private String fyear;
+	private String tyear;
+	private String seasonStr;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] displocValArr;
+
+}

+ 9 - 0
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaCommon.xml

@@ -62,4 +62,13 @@
 		FROM   TB_SAMPLE_FILE
 		WHERE  SAMPLE_FILE_ID = #{sampleFileId}
 	</select>
+	
+	<!-- ERP 연동 여부 -->
+	<select id="getErpSyncYn" resultType="String">
+		/* TsaSystem.getErpSyncYn */
+		SELECT UPPER(NVL(USE_YN,'N')) AS ERP_SYNC_YN
+		FROM TB_COMMON_CODE
+		WHERE CD_GB = 'G077'
+		AND CD = 'ERPSYNCYN'
+	</select>
 </mapper>

+ 417 - 21
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml

@@ -377,11 +377,11 @@
 		                   ) SD
 		                   ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		                        OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		                        <if test="mdNo != null and mdNo > 0">
+		                        <if test="mdNo != null and mdNo != ''">
 		                        AND G.BRAND_CD IN (
 		                                           SELECT DISTINCT BRAND_CD
 		                                           FROM TB_BRAND_MD
-		                                           WHERE MD_NO = #{mdNo}
+		                                           WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                           )
 		                       </if>
 		                   )
@@ -486,11 +486,11 @@
 		                   ) SD
 		                   ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		                        OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		                        <if test="mdNo != null and mdNo > 0">
+		                        <if test="mdNo != null and mdNo != ''">
 		                        AND G.BRAND_CD IN (
 		                                           SELECT DISTINCT BRAND_CD
 		                                           FROM TB_BRAND_MD
-		                                           WHERE MD_NO = #{mdNo}
+		                                           WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                           )
 		                       </if>
 		                   )
@@ -647,11 +647,11 @@
 		        <if test="erpPriceLinkYn != null and erpPriceLinkYn != ''">
 		        AND G.ERP_PRICE_LINK_YN = #{erpPriceLinkYn}
 		        </if>
-		        <if test="mdNo != null and mdNo > 0">
+		        <if test="mdNo != null and mdNo != ''">
 		        AND G.BRAND_CD IN (
 		            SELECT DISTINCT BRAND_CD
 		            FROM   TB_BRAND_MD
-		            WHERE  MD_NO = #{mdNo}
+		            WHERE  MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		        )
 		        </if>
 		        <if test="currPriceSt != null and currPriceSt != ''">
@@ -808,11 +808,11 @@
 		          ) SD
 		           ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		                 OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		                <if test="mdNo != null and mdNo > 0">
+		                <if test="mdNo != null and mdNo != ''">
 		                AND G.BRAND_CD IN (
 		                                   SELECT DISTINCT BRAND_CD
 		                                   FROM TB_BRAND_MD
-		                                   WHERE MD_NO = #{mdNo}
+		                                   WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                  )
 		               </if>
 		              )
@@ -1712,6 +1712,9 @@
 		    <if test='beforSkipFlag != null and beforSkipFlag == "Y"'>
 		                               AND GR.APPLY_EDDT >= NOW() 
 		    </if>
+		    <if test="goodsTnmRes != null and goodsTnmRes != ''">
+		                               AND UPPER(GR.GOODS_TNM) LIKE CONCAT('%',UPPER(#{goodsTnmRes}),'%')
+		    </if>
 		</if>
 		<if test="searchGb != null and searchGb =='EXCEL'">
 		INNER JOIN (
@@ -1726,11 +1729,11 @@
 		          ) SD
 		          ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		               OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		               <if test="mdNo != null and mdNo > 0">
+		               <if test="mdNo != null and mdNo != ''">
 		               AND G.BRAND_CD IN (
 		                                  SELECT DISTINCT BRAND_CD
 		                                  FROM TB_BRAND_MD
-		                                  WHERE MD_NO = #{mdNo}
+		                                  WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                  )
 		              </if>
 		           )
@@ -1782,6 +1785,9 @@
 		            <if test='beforSkipFlag != null and beforSkipFlag == "Y"'>
 		                                       AND GR.APPLY_EDDT >= NOW() 
 		            </if>
+		            <if test="goodsTnmRes != null and goodsTnmRes != ''">
+		                                       AND UPPER(GR.GOODS_TNM) LIKE CONCAT('%',UPPER(#{goodsTnmRes}),'%')
+		            </if>
 		        </if>
 		        <if test="searchGb != null and searchGb =='EXCEL'">
 		        INNER JOIN (
@@ -1796,11 +1802,11 @@
 		                  ) SD
 		                  ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		                       OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		                       <if test="mdNo != null and mdNo > 0">
+		                       <if test="mdNo != null and mdNo != ''">
 		                      AND G.BRAND_CD IN (
 		                                          SELECT DISTINCT BRAND_CD
 		                                          FROM TB_BRAND_MD
-		                                          WHERE MD_NO = #{mdNo}
+		                                          WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                          )
 		                      </if>
 		                   )
@@ -1949,11 +1955,11 @@
 		         ) SD
 		         ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		               OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		               <if test="mdNo != null and mdNo > 0">
+		               <if test="mdNo != null and mdNo !='' ">
 		               AND G.BRAND_CD IN (
 		                                  SELECT DISTINCT BRAND_CD
 		                                  FROM TB_BRAND_MD
-		                                  WHERE MD_NO = #{mdNo}
+		                                  WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                  )
 		              </if>
 		           )
@@ -2019,11 +2025,11 @@
 		                     ) SD
 		                     ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		                           OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		                           <if test="mdNo != null and mdNo > 0">
+		                           <if test="mdNo != null and mdNo != ''">
 		                           AND G.BRAND_CD IN (
 		                                              SELECT DISTINCT BRAND_CD
 		                                              FROM TB_BRAND_MD
-		                                              WHERE MD_NO = #{mdNo}
+		                                              WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                              )
 		                          </if>
 		                       )
@@ -2123,11 +2129,11 @@
 		  ) SD
 		  ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		       OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		       <if test="mdNo != null and mdNo > 0">
+		       <if test="mdNo != null and mdNo != ''">
 		       AND G.BRAND_CD IN (
 		                          SELECT DISTINCT BRAND_CD
 		                          FROM TB_BRAND_MD
-		                          WHERE MD_NO = #{mdNo}
+		                          WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                          )
 		      </if>
 		   )
@@ -2192,11 +2198,11 @@
 		                  ) SD
 		                  ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
 		                       OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
-		                       <if test="mdNo != null and mdNo > 0">
+		                       <if test="mdNo != null and mdNo != ''">
 		                      AND G.BRAND_CD IN (
 		                                          SELECT DISTINCT BRAND_CD
 		                                          FROM TB_BRAND_MD
-		                                          WHERE MD_NO = #{mdNo}
+		                                          WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
 		                                          )
 		                      </if>
 		                   )
@@ -2382,5 +2388,395 @@
 		AND GOODS_CD = #{goodsCd}
 	</delete>
 	
-
+	<!-- 상품 가격예약 목록 건수 -->
+	<select id="getGoodsPriceResCount" parameterType="GoodsSearch" resultType="int">
+		/* TsaGoods.getGoodsPriceResCount */
+		SELECT COUNT(*) AS TOTCNT
+		FROM TB_GOODS G
+		INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		INNER JOIN TB_SUPPLY_COMPANY S ON G.SUPPLY_COMP_CD = S.SUPPLY_COMP_CD
+		INNER JOIN TB_GOODS_PRICE_RES GR ON G.GOODS_CD = GR.GOODS_CD
+		<if test="searchGb == null or searchGb =='BASIC'" >
+		    <if test="applyStdt != null and applyStdt != ''">
+		                               AND GR.APPLY_EDDT >= DATE_FORMAT(#{applyStdt}, '%Y-%m-%d %H:%i:%S')
+		    </if>
+		    <if test="applyEddt != null and applyEddt != ''">
+		    <![CDATA[
+		                               AND GR.APPLY_STDT < DATE_FORMAT(DATE_ADD(#{applyEddt}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		    ]]>
+		    </if>
+		    <if test='beforSkipFlag != null and beforSkipFlag == "Y"'>
+		                               AND GR.APPLY_EDDT >= NOW() 
+		    </if>
+		    <if test="goodsPriceResSt != null and goodsPriceResSt != ''">
+		                               AND GR.RES_GOODS_PRICE >= #{goodsPriceResSt}
+		    </if>
+		    <if test="goodsPriceResEd != null and goodsPriceResEd != ''">
+		    <![CDATA[
+		                               AND GR.RES_GOODS_PRICE <= #{goodsPriceResEd}
+		     ]]>
+		    </if>
+		</if>
+		<if test="searchGb != null and (searchGb =='EXCEL' or searchGb =='EXCELRESULT')">
+		INNER JOIN (
+		            SELECT SEARCH_CD
+		                 , TMP_DISP_ORD
+		            FROM (
+		                  SELECT SEARCH_CD
+		                       , MIN(DISP_ORD) AS TMP_DISP_ORD
+		                  FROM TB_SEARCH_DATA
+		                  WHERE REG_NO = #{regNo}
+		                  GROUP BY SEARCH_CD) T
+		          ) SD
+		          ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
+		               OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
+		               <if test="mdNo != null and mdNo != ''">
+		               AND G.BRAND_CD IN (
+		                                  SELECT DISTINCT BRAND_CD
+		                                  FROM TB_BRAND_MD
+		                                  WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
+		                                  )
+		              </if>
+		           )
+		</if>
+		WHERE 1=1
+		<if test="searchGb == null or searchGb =='BASIC'" >
+		<include refid="getGoodsListCondition_sql"/>
+		</if>
+	</select>
+
+	<!-- 상품 가격예약 목록 -->
+	<select id="getGoodsPriceResList" parameterType="GoodsSearch" resultType="GoodsPriceRes">
+		/* TsaGoods.getGoodsPriceResList */
+		SELECT Z.*
+		FROM (
+		    SELECT A.*, @rownum := @rownum + 1 AS RNUM FROM (
+		        SELECT
+		                G.GOODS_CD
+		              , G.CURR_PRICE
+		              , G.LIST_PRICE
+		              , B.BRAND_ENM
+		              , B.BRAND_GRP_NM
+		              , G.BRAND_CD
+		              , G.SUPPLY_COMP_CD
+		              , G.SUPPLY_GOODS_CD
+		              , G.GOODS_NM
+		              , G.GOODS_TNM
+		              , G.SELF_GOODS_YN
+		              , G.GOODS_STAT
+		              , GR.GOODS_PRICE_RES_SQ
+		              , GR.RES_GOODS_PRICE
+		              , GR.END_GOODS_PRICE
+		              , DATE_FORMAT(GR.APPLY_STDT,'%Y%m%d%H%i%S') AS APPLY_STDT
+		              , DATE_FORMAT(GR.APPLY_EDDT,'%Y%m%d%H%i%S') AS APPLY_EDDT
+		              , GR.CFRM_YN
+		              , GR.CFRM_NO
+		              , FN_GET_USER_NM(GR.REG_NO) AS CFRM_NM
+		              , DATE_FORMAT(GR.CFRM_DT,'%Y%m%d%H%i%S') AS CFRM_DT
+		              , GR.APPLY_YN
+		              , GR.REG_NO
+		              , FN_GET_USER_NM(GR.REG_NO) AS REG_NM
+		              , DATE_FORMAT(GR.REG_DT,'%Y%m%d%H%i%S') AS REG_DT
+		              , FN_GET_USER_NM(GR.UPD_NO) AS UPD_NM
+		              , DATE_FORMAT(GR.UPD_DT,'%Y%m%d%H%i%S') AS UPD_DT
+		        FROM TB_GOODS G
+		        JOIN ( SELECT @rownum := 0) R
+		        INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		        INNER JOIN TB_SUPPLY_COMPANY S ON G.SUPPLY_COMP_CD = S.SUPPLY_COMP_CD
+		        INNER JOIN TB_GOODS_PRICE_RES GR ON G.GOODS_CD = GR.GOODS_CD
+		        <if test="searchGb == null or searchGb =='BASIC'" >
+		            <if test="applyStdt != null and applyStdt != ''">
+		                                       AND GR.APPLY_EDDT >= DATE_FORMAT(#{applyStdt}, '%Y-%m-%d %H:%i:%S')
+		            </if>
+		            <if test="applyEddt != null and applyEddt != ''">
+		            <![CDATA[
+		                                       AND GR.APPLY_STDT < DATE_FORMAT(DATE_ADD(#{applyEddt}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		            ]]>
+		            </if>
+		            <if test='beforSkipFlag != null and beforSkipFlag == "Y"'>
+		                                       AND GR.APPLY_EDDT >= NOW() 
+		            </if>
+		            <if test="goodsPriceResSt != null and goodsPriceResSt != ''">
+		                                       AND GR.RES_GOODS_PRICE >= #{goodsPriceResSt}
+		            </if>
+		            <if test="goodsPriceResEd != null and goodsPriceResEd != ''">
+		            <![CDATA[
+		                                       AND GR.RES_GOODS_PRICE <= #{goodsPriceResEd}
+		             ]]>
+		            </if>
+		        </if>
+		        <if test="searchGb != null and (searchGb =='EXCEL' or searchGb =='EXCELRESULT')">
+		        INNER JOIN (
+		                    SELECT SEARCH_CD
+		                         , TMP_DISP_ORD
+		                    FROM (
+		                          SELECT SEARCH_CD
+		                               , MIN(DISP_ORD) AS TMP_DISP_ORD
+		                          FROM TB_SEARCH_DATA
+		                          WHERE REG_NO = #{regNo}
+		                          GROUP BY SEARCH_CD) T
+		                  ) SD
+		                  ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
+		                       OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
+		                       <if test="mdNo != null and mdNo != ''">
+		                      AND G.BRAND_CD IN (
+		                                          SELECT DISTINCT BRAND_CD
+		                                          FROM TB_BRAND_MD
+		                                          WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
+		                                          )
+		                      </if>
+		                   )
+		        </if>
+		        WHERE 1=1
+		        AND G.SELF_GOODS_YN = #{selfGoodsYn}
+		        <if test="searchGb == null or searchGb =='BASIC'" >
+		        <include refid="getGoodsListCondition_sql"/>
+		        ORDER BY  GR.APPLY_STDT DESC, GR.APPLY_EDDT DESC, G.GOODS_CD, GR.GOODS_PRICE_RES_SQ
+		        </if>
+		        <if test="searchGb != null and searchGb =='EXCEL'">
+		        ORDER BY SD.TMP_DISP_ORD
+		        </if>
+		<include refid="getListPagingCondition_sql"/>
+	</select>
+
+	<!-- 상품 가격예약 조회(기간 체크용) -->
+	<select id="getGoodsPriceResDupChkCount" parameterType="GoodsPriceRes" resultType="int">
+		/* TsaGoods.getGoodsPriceResDupChkCount */
+		SELECT COUNT(GOODS_CD)
+		FROM TB_GOODS_PRICE_RES
+		WHERE GOODS_CD = #{goodsCd}
+		<![CDATA[
+		AND APPLY_STDT <= DATE_FORMAT(#{applyStdt}, '%Y%m%d%H%i%S')
+		]]>
+		AND APPLY_EDDT >= DATE_FORMAT(#{applyEddt},'%Y%m%d%H%i%S')
+	</select>
+
+	<!-- 상품 가격예약 등록 -->
+	<insert id="createGoodPriceRes" parameterType="GoodsPriceRes">
+		/* TsaGoods.createGoodPriceRes */
+		INSERT INTO TB_GOODS_PRICE_RES (
+		  GOODS_PRICE_RES_SQ
+		, GOODS_CD
+		, RES_GOODS_PRICE
+		, END_GOODS_PRICE
+		, APPLY_STDT
+		, APPLY_EDDT
+		, CFRM_YN
+		, CFRM_NO
+		, CFRM_DT
+		, APPLY_YN
+		, REG_NO
+		, REG_DT
+		, UPD_NO
+		, UPD_DT
+		)
+		VALUES(
+		  NULL
+		, #{goodsCd}
+		, #{resGoodsPrice}
+		, #{endGoodsPrice}
+		, STR_TO_DATE(#{applyStdt},'%Y%m%d%H%i%S')
+		, STR_TO_DATE(#{applyEddt},'%Y%m%d%H%i%S')
+		, NVL(#{cfrmYn},'N')
+		, #{cfrmNo}
+		, #{cfrmDt}
+		, NVL(#{applyYn},'N')
+		, #{regNo}
+		, NOW()
+		, #{updNo}
+		, NOW()
+		)
+	</insert>
+
+	<!-- 상품 가격예약 삭제 -->
+	<delete id="deleteGoodPriceRes" parameterType="GoodsPriceRes">
+		/* TsaGoods.deleteGoodPriceRes */
+		DELETE FROM TB_GOODS_PRICE_RES
+		WHERE GOODS_PRICE_RES_SQ = #{goodsPriceResSq}
+		AND APPLY_YN = 'N'
+	</delete>
+
+	<!-- 상품 동영상 조회 -->
+	<select id="getGoodsVideoList" parameterType="GoodsVideo" resultType="GoodsVideo">
+		/* TsaGoods.getGoodsVideoList */
+		SELECT A.VIDEO_SQ
+		     , B.BRAND_CD
+		     , B.BRAND_ENM
+		     , B.BRAND_GRP_NM
+		     , A.DISPLOC_VAL AS GOODS_CD
+		     , E.VIDEO_GB
+		     , E.VIDEO_VAL
+		     , A.DISP_YN
+		     , A.REG_NO
+		     , FN_GET_USER_NM(A.REG_NO) AS REG_NM
+		     , DATE_FORMAT(A.REG_DT,'%Y%m%d%H%i%S') AS REG_DT
+		     , A.UPD_NO
+		     , FN_GET_USER_NM(A.UPD_NO) AS REG_NM
+		     , DATE_FORMAT(A.UPD_DT,'%Y%m%d%H%i%S') AS UPD_DT
+		FROM TB_VIDEO_DISPLOC A
+		INNER JOIN TB_VIDEO E ON A.VIDEO_SQ = E.VIDEO_SQ
+		INNER JOIN (SELECT C.GOODS_CD
+		                 , C.BRAND_CD
+		                 , D.BRAND_ENM
+		                 , D.BRAND_GRP_NM
+		            FROM TB_GOODS C
+		            INNER JOIN TB_BRAND D ON C.BRAND_CD = D.BRAND_CD
+		            WHERE 1 = 1
+		            <if test='goodsNm != null and goodsNm != "" '>
+		            AND C.GOODS_NM = #{goodsNm}
+		            </if>
+		            <if test='goodsNum != null and goodsNum != "" '>
+		            AND C.GOODS_NUM = #{goodsNum}
+		            </if>
+		            <if test='supplyGoodsCd != null and supplyGoodsCd != "" '>
+		            AND C.SUPPLY_GOODS_CD = #{supplyGoodsCd}
+		            </if>
+		            <if test='brandEnm != null and brandEnm != "" '>
+		            AND (
+		                 D.BRAND_ENM LIKE #{brandEnm}||'%'
+		                 OR
+		                 D.BRAND_KNM LIKE #{brandEnm}||'%'
+		                )
+		            </if>
+		            ) B
+		           ON (A.DISPLOC_VAL = B.GOODS_CD
+		           )
+		WHERE A.DISPLOC_VAL = B.GOODS_CD
+		AND A.DISPLOC_GB = 'G'
+		<if test='goodsCd != null and goodsCd != "" '>
+		AND A.DISPLOC_VAL = #{goodsCd}
+		</if>
+		<if test='stDate != null and stDate != "" '>
+		<![CDATA[
+		AND A.REG_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d')
+		]]>
+		</if>
+		<if test='edDate != null and edDate != "" '>
+		<![CDATA[
+		AND A.REG_DT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		]]>
+		</if>
+		ORDER BY A.DISPLOC_VAL
+	</select>
+		
+	<!-- 상품 동영상 노출안함으로 변경 -->
+	<update id="updateNotUseGoodsVideo" parameterType="Video">
+		/* TsaGoods.updateNotUseGoodsVideo */
+		UPDATE TB_VIDEO_DISPLOC
+		SET DISP_YN = 'N'
+		  , UPD_NO = #{updNo}
+		  , UPD_DT = NOW()
+		WHERE VIDEO_SQ = #{videoSq}
+	</update>
+	
+	<!-- 동영상 코드 조회 -->
+	<select id="getVideoSeq" parameterType="Video" resultType="String">
+		/* TsaGoods.getVideoSeq */
+		SELECT MAX(VIDEO_SQ) AS VIDEO_SQ
+		FROM TB_VIDEO
+		WHERE VIDEO_GB = #{videoGb}
+		AND VIDEO_VAL = #{videoVal}
+	</select>
+	
+	<!-- 동영상  등록 -->
+	<insert id="createVideo" parameterType="Video">
+		/* TsaGoods.createVideo */
+		INSERT INTO TB_VIDEO
+		    (
+		           VIDEO_SQ
+		         , VIDEO_GB
+		         , VIDEO_VAL
+		         , FYEAR
+		         , TYEAR
+		         , SEASON_STR
+		         , VIDEO_TITLE
+		         , VIDEO_TITLE2
+		         , DISP_YN
+		         , REG_NO
+		         , REG_DT
+		         , UPD_NO
+		         , UPD_DT
+		    )
+		    VALUES (
+		           NULL
+		         , #{videoGb}
+		         , #{videoVal}
+		         , #{fyear}
+		         , #{tyear}
+		         , #{seasonStr}
+		         , #{videoTitle}
+		         , #{videoTitle2}
+		         , #{dispYn}
+		         , #{regNo}
+		         , NOW()
+		         , #{updNo}
+		         , NOW()
+		    )
+	</insert>
+	
+	<!-- 동영상  수정 -->
+	<update id="updateVideo" parameterType="Video">
+		/* TsaGoods.saveVideo */
+		UPDATE TB_VIDEO SET
+		           DISP_YN = #{dispYn}
+		         , VIDEO_GB = #{videoGb}
+		         , VIDEO_VAL = #{videoVal}
+		         , FYEAR = #{fyear}
+		         , TYEAR = #{tyear}
+		         , SEASON_STR = #{seasonStr}
+		         , VIDEO_TITLE = #{videoTitle}
+		         , VIDEO_TITLE2 = #{videoTitle2}
+		         , UPD_NO = #{updNo}
+		         , UPD_DT = NOW()
+	</update>
+	
+	<!-- 동영상 위치 노출안함으로 처리 -->
+	<update id="delVideoDispLoc" parameterType="Video">
+		/* TsaGoods.initVideoDispLoc */
+		UPDATE TB_VIDEO_DISPLOC
+		SET DISP_YN = 'N'
+		WHERE VIDEO_SQ = #{videoSq}
+		AND DISPLOC_GB = #{displocGb}
+	</update>
+	
+	<!-- 동영상 위치 등록 -->
+	<insert id="saveVideoDispLoc" parameterType="Video">
+		/* TsaGoods.saveVideoDispLoc */
+		INSERT INTO TB_VIDEO_DISPLOC
+		    (
+		           VIDEO_SQ
+		         , DISPLOC_GB
+		         , DISPLOC_VAL
+		         , DISP_YN
+		         , REG_NO
+		         , REG_DT
+		         , UPD_NO
+		         , UPD_DT
+		    )
+		    VALUES (
+		           #{videoSq}
+		         , #{displocGb}
+		         , #{displocVal}
+		         , #{dispYn}
+		         , #{regNo}
+		         , NOW()
+		         , #{updNo}
+		         , NOW()
+		    )
+		ON DUPLICATE KEY UPDATE
+		       DISP_YN = #{dispYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 상품 사이즈 존재여부 확인 -->
+	<select id="getGoodsSizeCount" parameterType="Option" resultType="int">
+		/* TsaGoods.getGoodsSizeCount */
+		SELECT COUNT(*)
+		FROM TB_OPTION
+		WHERE GOODS_CD = #{goodsCd}
+		<if test='optCd != null and optCd != ""'>
+		AND OPT_CD = #{optCd}
+		</if>
+	</select>
 </mapper>

+ 493 - 0
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaStock.xml

@@ -0,0 +1,493 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.style24.admin.biz.dao.TsaStockDao">
+	
+	<!-- 상품 목록 조건 정보 -->
+	<sql id="getGoodsListCondition_sql">
+		        <if test='conditionList != null and conditionList.length>0'>
+		            <choose>
+		              <when test='search != null and search == "searchGoodsCd"'>
+		        AND (
+		              <foreach collection="conditionList" item="item" index="index" separator="or">
+		               UPPER(G.GOODS_CD) LIKE CONCAT('%',UPPER(#{item}),'%') 
+		              </foreach>
+		             )
+		              </when>
+		              <when test='search != null and search == "searchGoodsNum"'>
+		        AND (
+		              <foreach collection="conditionList" item="item" index="index" separator="or">
+		               UPPER(G.GOODS_NUM) LIKE CONCAT('%',UPPER(#{item}),'%')
+		              </foreach>
+		             )
+		              </when>
+		              <when test='search != null and search == "searchSupplyGoodsCd"'>
+		        AND (
+		              <foreach collection="conditionList" item="item" index="index" separator="or">
+		               UPPER(G.SUPPLY_GOODS_CD) LIKE CONCAT('%',UPPER(#{item}),'%')
+		              </foreach>
+		             )
+		              </when>
+		              <when test='search != null and search == "searchExtendGoodsCd"'>
+		        AND 1 = 1
+		              </when>
+		              <when test='search != null and search == "searchMasterGoodsCd"'>
+		        AND 1 = 1
+		              </when>
+		              <otherwise>
+		        AND UPPER(G.REG_ID) LIKE CONCAT('%',UPPER(#{item}),'%')
+		              </otherwise>
+		            </choose>
+		        </if>
+		        <if test="goodsCd != null and goodsCd != ''">
+		        AND UPPER(G.GOODS_CD) LIKE CONCAT('%',UPPER(#{goodsCd}),'%')
+		        </if>
+		         <if test="goodsNm != null and goodsNm != ''">
+		        AND UPPER(G.GOODS_NM) LIKE CONCAT('%',UPPER(#{goodsNm}),'%')
+		        </if>
+		        <if test="goodsType != null and goodsType != ''">
+		        AND G.GOODS_TYPE = #{goodsType}
+		        </if>
+		        <if test="supplyCompCd != null and supplyCompCd != ''">
+		        AND G.SUPPLY_COMP_CD = #{supplyCompCd}
+		        </if>
+		        <if test="brandCd != null and brandCd != ''">
+		        AND G.BRAND_CD = #{brandCd}
+		        </if>
+		        <if test="multiBrand != null and multiBrand != ''">
+		        AND G.BRAND_CD IN
+		            <foreach collection="multiBrand" item="item" index="index"  open="(" close=")" separator=",">
+		        #{item}
+		            </foreach>
+		        </if>
+		        <if test="selfMallYn != null and selfMallYn != ''">
+		        AND G.SELF_MALL_YN = #{selfMallYn}
+		        </if>
+		        <if test="itemkindCd != null and itemkindCd != ''">
+		        AND G.ITEMKIND_CD = #{itemkindCd}
+		        </if>
+		        <if test="multiItemkindCd != null and multiItemkindCd != ''">
+		        AND G.ITEMKIND_CD IN
+		            <foreach collection="multiItemkindCd" item="item" index="index"  open="(" close=")" separator=",">
+		        #{item}
+		            </foreach>
+		        </if>
+		        <if test="goodsStat != null and goodsStat != ''">
+		        AND G.GOODS_STAT = #{goodsStat}
+		        </if>
+		        <if test="multiGoodsStat != null and multiGoodsStat != ''">
+		        AND G.GOODS_STAT IN
+		            <foreach collection="multiGoodsStat" item="item" index="index"  open="(" close=")" separator=",">
+		        #{item}
+		            </foreach>
+		        </if>
+		        <if test="styleYear != null and styleYear != ''">
+		        AND G.STYLE_YEAR = (SELECT CD_NM FROM TB_COMMON_CODE WHERE CD = #{styleYear} AND CD_GB='G023')
+		        </if>
+		        <if test="multiStyleYear != null and multiStyleYear != ''">
+		        AND G.STYLE_YEAR IN (SELECT CD_NM 
+		                             FROM TB_COMMON_CODE 
+		                             WHERE CD_GB='G023' 
+		                             AND CD IN 
+		                             <foreach collection="multiStyleYear" item="item" index="index"  open="(" close=")" separator=",">
+		                             #{item}
+		                             </foreach>
+		                             )
+		        </if>
+		        <if test="seasonCd != null and seasonCd != ''">
+		        AND G.SEASON_CD = #{seasonCd}
+		        </if>
+		        <if test="multiSeasonCd != null and multiSeasonCd != ''">
+		        AND G.SEASON_CD IN
+		            <foreach collection="multiSeasonCd" item="item" index="index"  open="(" close=")" separator=",">
+		        #{item}
+		            </foreach>
+		        </if>
+		        <if test="sexGb != null and sexGb != ''">
+		        AND G.SEX_GB = #{sexGb}
+		        </if>
+		        <if test="changeableYn != null and changeableYn != ''">
+		        AND G.CHANGEABLE_YN = #{changeableYn}
+		        </if>
+		        <if test="returnableYn != null and returnableYn != ''">
+		        AND G.RETURNABLE_YN = #{returnableYn}
+		        </if>
+		        <if test="returnFeeFreeYn != null and returnFeeFreeYn != ''">
+		        AND G.RETURN_FEE_FREE_YN = #{returnFeeFreeYn}
+		        </if>
+		        <if test="changeFeeFreeYn != null and changeFeeFreeYn != ''">
+		        AND G.CHANGE_FEE_FREE_YN = #{changeFeeFreeYn}
+		        </if>
+		        <if test="formalGb != null and formalGb != ''">
+		        AND G.FORMAL_GB = #{formalGb}
+		        </if>
+		        <if test='soldOutYn != null and soldOutYn == "Y"'>
+		        AND EXISTS (
+		                    SELECT GOODS_CD 
+		                    FROM VW_STOCK
+		                    WHERE SOLDOUT_YN = 'Y'
+		                    AND GOODS_CD = G.GOODS_CD
+		                   )
+		        </if>
+		        <if test='soldOutYn != null and soldOutYn == "N"'>
+		        AND NOT EXISTS (
+		                    SELECT GOODS_CD 
+		                    FROM VW_STOCK
+		                    WHERE SOLDOUT_YN = 'Y'
+		                    AND GOODS_CD = G.GOODS_CD
+		                   )
+		        </if>
+		        <if test="erpStockLinkYn != null and erpStockLinkYn != ''">
+		        AND G.ERP_STOCK_LINK_YN = #{erpStockLinkYn}
+		        </if>
+		        <if test="erpPriceLinkYn != null and erpPriceLinkYn != ''">
+		        AND G.ERP_PRICE_LINK_YN = #{erpPriceLinkYn}
+		        </if>
+		        <if test="mdNo != null and mdNo != ''">
+		        AND G.BRAND_CD IN (
+		            SELECT DISTINCT BRAND_CD
+		            FROM   TB_BRAND_MD
+		            WHERE  MD_NO = CAST(#{mdNo} AS UNSIGNED)
+		        )
+		        </if>
+		        <if test="currPriceSt != null and currPriceSt != ''">
+		        AND G.CURR_PRICE >= #{currPriceSt}
+		        </if>
+		        <if test="currPriceEd != null and currPriceEd != ''">
+		        <![CDATA[
+		        AND G.CURR_PRICE <= #{currPriceEd}
+		         ]]>
+		        </if>
+		        <if test="dcRateSt != null and dcRateSt != ''">
+		        AND G.DC_RATE >= #{dcRateSt}
+		        </if>
+		        <if test="dcRateEd != null and dcRateEd != ''">
+		        <![CDATA[
+		        AND G.DC_RATE <= #{dcRateEd}
+		        ]]>
+		        </if>
+		        <if test='dateGbn != null and dateGbn == "P"'>
+		            <if test="stDate != null and stDate != ''">
+		        AND G.PRICE_UPD_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		            </if>
+		            <if test="edDate != null and edDate != ''">
+		            <![CDATA[
+		        AND G.PRICE_UPD_DT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		            ]]>
+		            </if>
+		        </if>
+		        <if test='dateGbn != null and dateGbn == "R"'>
+		            <if test="stDate != null and stDate != ''">
+		        AND G.REG_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		            </if>
+		            <if test="edDate != null and edDate != ''">
+		            <![CDATA[
+		        AND G.REG_DT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		            ]]>
+		            </if>
+		        </if>
+		        <if test='dateGbn != null and dateGbn == "S"'>
+		            <if test="stDate != null and stDate != ''">
+		        AND G.APPR_UPD_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		            </if>
+		            <if test="edDate != null and edDate != ''">
+		            <![CDATA[
+		        AND G.APPR_UPD_DT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		            ]]>
+		            </if>
+		        </if>
+		        <if test="stockQtySt != null and stockQtySt != ''">
+		        AND ST.CURR_STOCK_QTY >= #{stockQtySt}
+		        </if>
+		        <if test="stockQtyEd != null and stockQtyEd != ''">
+		        <![CDATA[
+		        AND ST.CURR_STOCK_QTY <= #{stockQtyEd}
+		        ]]>
+		        </if>
+		        <if test="ageGrpCd != null and ageGrpCd != ''">
+		        AND G.AGE_GRP_CD = #{ageGrpCd}
+		        </if>
+		        <if test="cateCd != null and cateCd != ''">
+		        AND G.GOODS_CD IN (
+		            SELECT GOODS_CD
+		            FROM   TB_CATEGORY_GOODS
+		            WHERE  CATE_CD = #{cateCd}
+		        )
+		        </if>
+	</sql>
+	
+	<!-- 목록 페이징 정보 -->
+	<sql id="getListPagingCondition_sql">
+		<choose>
+		<when test="pageable != null">
+		    ) A
+		    JOIN ( SELECT @rownum := 0) R
+		)Z WHERE RNUM BETWEEN  #{pageable.startRow} AND #{pageable.endRow}
+		</when>
+		<otherwise>
+		    ) A
+		    JOIN ( SELECT @rownum := 0) R
+		)Z
+		</otherwise>
+		</choose>
+	</sql>
+	
+	<!-- 상품 사이즈별 재고 현황 목록 건수 -->
+	<select id="getGoodsSizeStockCount" parameterType="GoodsSearch" resultType="int">
+		/* TsaStock.getGoodsSizeStockCount */
+		SELECT COUNT(*) AS TOTCNT
+		FROM (
+		      SELECT Y.*
+		      FROM (
+		            SELECT G.GOODS_CD
+		                 , ST.OPT_CD
+		                 , GREATEST(GREATEST(ST.CURR_STOCK_QTY - ST.BASE_STOCK_QTY, 0) - IFNULL(SQ.STOCK_QTY, 0), 0) AS STOCK_QTY
+		            FROM TB_GOODS G
+		            INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		            INNER JOIN TB_SUPPLY_COMPANY S ON G.SUPPLY_COMP_CD = S.SUPPLY_COMP_CD
+		            INNER JOIN TB_OPTION ST ON G.GOODS_CD = ST.GOODS_CD
+		            <if test="searchGb == null or searchGb =='BASIC'">
+		                                    <if test="optCd2 == null or optCd2 != ''">
+		                                    AND ST.OPT_CD2 = ${optCd2}
+		                                    </if>
+		            </if>
+		            LEFT OUTER JOIN  (SELECT GOODS_CD,
+		                                     OPT_CD,
+		                                     SUM((CASE SELL_GB WHEN '10' THEN 1
+		                                                       WHEN '20' THEN -1
+		                                           END) * SELL_QTY) AS STOCK_QTY
+		                              FROM TB_SELL_QTY
+		                              GROUP BY GOODS_CD, OPT_CD
+		                              ) SQ
+		                           ON (    ST.GOODS_CD = SQ.GOODS_CD
+		                               AND ST.OPT_CD = SQ.OPT_CD
+		                              )
+		            <if test="searchGb != null and searchGb =='EXCEL' ">
+		            INNER JOIN (
+		                        SELECT SEARCH_CD
+		                             , TMP_DISP_ORD
+		                        FROM (
+		                              SELECT SEARCH_CD
+		                                   , MIN(DISP_ORD) AS TMP_DISP_ORD
+		                              FROM TB_SEARCH_DATA
+		                              WHERE REG_NO = #{regNo}
+		                              GROUP BY SEARCH_CD) T
+		                      ) SD
+		                   ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
+		                        OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
+		                        <if test="mdNo != null and mdNo != ''">
+		                        AND G.BRAND_CD IN (
+		                                           SELECT DISTINCT BRAND_CD
+		                                           FROM TB_BRAND_MD
+		                                           WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
+		                                           )
+		                       </if>
+		                   )
+		            </if>
+		            <if test="searchGb != null and searchGb =='EXCELRESULT'">
+		            INNER JOIN (
+		                        SELECT SEARCH_CD
+		                             , TMP_DISP_ORD
+		                             , OPT_CD
+		                        FROM (
+		                              SELECT SEARCH_CD
+		                                   , DUMMY1 AS OPT_CD
+		                                   , MIN(DISP_ORD) AS TMP_DISP_ORD
+		                              FROM TB_SEARCH_DATA
+		                              WHERE REG_NO = #{regNo}
+		                              GROUP BY SEARCH_CD, DUMMY1) T
+		                      ) SD
+		                   ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
+		                        OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
+		                        <if test="mdNo != null and mdNo != ''">
+		                        AND G.BRAND_CD IN (
+		                                           SELECT DISTINCT BRAND_CD
+		                                           FROM TB_BRAND_MD
+		                                           WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
+		                                           )
+		                        </if>
+		                        AND ST.GOODS_CD = SD.SEARCH_CD
+		                        AND ST.OPT_CD = SD.OPT_CD
+		                   )
+		            </if>
+		            WHERE 1=1
+		            AND G.GOODS_TYPE = 'G056_N' /*일반상품만 조회*/
+		            <if test="searchGb == null or searchGb =='BASIC'">
+		            <include refid="getGoodsListCondition_sql"/>
+		            </if>
+		            
+		           ) Y
+		      ) X
+		WHERE 1 = 1
+		<if test="searchGb == null or searchGb =='BASIC'">
+		    <if test="stockQtySt != null and stockQtySt != ''">
+		AND X.STOCK_QTY >= #{stockQtySt}
+		    </if>
+		    <if test="stockQtyEd != null and stockQtyEd != ''">
+		    <![CDATA[
+		AND X.STOCK_QTY <= #{stockQtyEd}
+		    ]]>
+		    </if> 
+		</if>
+	</select>
+
+	<!-- 상품 사이즈별 재고 현황 목록  -->
+	<select id="getGoodsSizeStockList" parameterType="GoodsSearch" resultType="Option">
+		/* TsaStock.getGoodsSizeStockList */
+		<include refid="getGoodsSizeStockList_sql"/>
+	</select>
+	
+	<!-- 사이즈별재고현황 - 엑셀다운로드 -->
+	<select id="getGoodsSizeStockExcelList" parameterType="GoodsSearch" resultType="paramMap">
+		/* TsaStock.getGoodsSizeStockExcelList */
+		<include refid="getGoodsSizeStockList_sql"/>
+	</select>
+	
+	<!--  사이즈별 재고현황 정보 -->
+	<sql id="getGoodsSizeStockList_sql">
+		SELECT Z.*
+		    , (SELECT ITEMKIND_NM FROM TB_ITEMKIND WHERE ITEMKIND_CD = Z.ITEMKIND_CD) AS ITEMKIND_NM
+		    , FN_GET_CODE_NM('G008', Z.GOODS_STAT) AS GOODS_STAT_NM
+		FROM (
+		    SELECT A.*, @rownum := @rownum + 1  RNUM 
+		    FROM (
+		        SELECT  X.GOODS_CD
+		              , X.BRAND_ENM
+		              , X.BRAND_GRP_NM
+		              , X.BRAND_CD
+		              , X.ITEMKIND_CD
+		              , X.SUPPLY_COMP_CD
+		              , X.SUPPLY_GOODS_CD
+		              , X.GOODS_NM
+		              , X.GOODS_STAT
+		              , X.OPT_CD
+		              , X.OPT_CD1
+		              , X.OPT_CD2
+		              , X.SOLDOUT_YN
+		              , X.CURR_STOCK_QTY
+		              , X.BASE_STOCK_QTY
+		              , X.SALE_STOCK_QTY /*출고대기*/
+		              , X.ABLE_STOCK_QTY /*판매가능재고*/
+		              , X.REG_DT
+		        FROM (
+		              
+		                    SELECT
+		                            G.GOODS_CD
+		                          , B.BRAND_ENM
+		                          , B.BRAND_GRP_NM
+		                          , G.BRAND_CD
+		                          , G.ITEMKIND_CD
+		                          , G.SUPPLY_COMP_CD
+		                          , G.SUPPLY_GOODS_CD
+		                          , G.GOODS_NM
+		                          , G.GOODS_STAT
+		                          , ST.OPT_CD
+		                          , ST.OPT_CD1
+		                          , ST.OPT_CD2
+		                          , ST.SOLDOUT_YN
+		                          , ST.CURR_STOCK_QTY
+		                          , ST.BASE_STOCK_QTY
+		                          , NVL(SQ.STOCK_QTY,0) AS SALE_STOCK_QTY
+		                          , GREATEST(GREATEST(ST.CURR_STOCK_QTY - ST.BASE_STOCK_QTY, 0) - IFNULL(SQ.STOCK_QTY, 0), 0) AS ABLE_STOCK_QTY
+		                          , G.REG_DT
+		                    FROM TB_GOODS G
+		                    INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		                    INNER JOIN TB_SUPPLY_COMPANY S ON G.SUPPLY_COMP_CD = S.SUPPLY_COMP_CD
+		                    INNER JOIN TB_OPTION ST ON G.GOODS_CD = ST.GOODS_CD
+		                    <if test="searchGb == null or searchGb =='BASIC'">
+		                                            <if test="optCd2 == null or optCd2 != ''">
+		                                            AND ST.OPT_CD2 = ${optCd2}
+		                                            </if>
+		                    </if>
+		                    LEFT OUTER JOIN  (SELECT GOODS_CD,
+		                                             OPT_CD,
+		                                             SUM((CASE SELL_GB WHEN '10' THEN 1
+		                                                               WHEN '20' THEN -1
+		                                                   END) * SELL_QTY) AS STOCK_QTY
+		                                      FROM TB_SELL_QTY
+		                                      GROUP BY GOODS_CD, OPT_CD
+		                                      ) SQ
+		                                   ON (    ST.GOODS_CD = SQ.GOODS_CD
+		                                       AND ST.OPT_CD = SQ.OPT_CD
+		                                      )
+		                    <if test="searchGb != null and searchGb =='EXCEL'">
+		                    INNER JOIN (
+		                                SELECT SEARCH_CD
+		                                     , TMP_DISP_ORD
+		                                FROM (
+		                                      SELECT SEARCH_CD
+		                                           , MIN(DISP_ORD) AS TMP_DISP_ORD
+		                                      FROM TB_SEARCH_DATA
+		                                      WHERE REG_NO = #{regNo}
+		                                      GROUP BY SEARCH_CD) T
+		                              ) SD
+		                           ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
+		                                OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
+		                                <if test="mdNo != null and mdNo != ''">
+		                                AND G.BRAND_CD IN (
+		                                                   SELECT DISTINCT BRAND_CD
+		                                                   FROM TB_BRAND_MD
+		                                                   WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
+		                                                   )
+		                               </if>
+		                           )
+		                    </if>
+		                    <if test="searchGb != null and searchGb =='EXCELRESULT'">
+		                    INNER JOIN (
+		                                SELECT SEARCH_CD
+		                                     , TMP_DISP_ORD
+		                                     , OPT_CD
+		                                FROM (
+		                                      SELECT SEARCH_CD
+		                                           , DUMMY1 AS OPT_CD
+		                                           , MIN(DISP_ORD) AS TMP_DISP_ORD
+		                                      FROM TB_SEARCH_DATA
+		                                      WHERE REG_NO = #{regNo}
+		                                      GROUP BY SEARCH_CD, DUMMY1) T
+		                              ) SD
+		                           ON ( (G.GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')
+		                                OR G.SUPPLY_GOODS_CD LIKE CONCAT(SD.SEARCH_CD,'%')) 
+		                                <if test="mdNo != null and mdNo != ''">
+		                                AND G.BRAND_CD IN (
+		                                                   SELECT DISTINCT BRAND_CD
+		                                                   FROM TB_BRAND_MD
+		                                                   WHERE MD_NO = CAST(#{mdNo} AS UNSIGNED)
+		                                                   )
+		                               </if>
+		                                AND ST.GOODS_CD = SD.SEARCH_CD
+		                                AND ST.OPT_CD = SD.OPT_CD
+		                           )
+		                    </if>
+		                    WHERE 1=1
+		                    AND G.GOODS_TYPE = 'G056_N' /*일반상품만 조회*/
+		                    <if test="searchGb == null or searchGb =='BASIC'">
+		                    <include refid="getGoodsListCondition_sql"/>
+		                    </if>
+		              ) X
+		        WHERE 1 = 1
+		        <if test="searchGb == null or searchGb =='BASIC'">
+		            <if test="stockQtySt != null and stockQtySt != ''">
+		        AND X.STOCK_QTY >= #{stockQtySt}
+		            </if>
+		            <if test="stockQtyEd != null and stockQtyEd != ''">
+		            <![CDATA[
+		        AND X.STOCK_QTY <= #{stockQtyEd}
+		            ]]>
+		            </if>
+		        ORDER BY X.GOODS_CD, X.OPT_CD, X.REG_DT DESC
+		        </if>
+		<include refid="getListPagingCondition_sql"/>
+	</sql>
+	
+	<!-- 상품 사이즈별 품절여부 변경 -->
+	<update id="updateStockSoldOut" parameterType="Option">
+		/* TsaStock.updateStockSoldOut */
+		UPDATE TB_OPTION
+		SET BASE_STOCK_QTY = #{baseStockQty}
+		  , UPD_NO = #{updNo}
+		  , UPD_DT = NOW()
+		  , SOLDOUT_YN = #{soldoutYn}
+		WHERE GOODS_CD = #{goodsCd}
+		AND OPT_CD = #{optCd}
+	</update>
+	
+</mapper>

+ 2 - 2
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html

@@ -208,7 +208,7 @@
 											<input type="hidden" id="listPrice" name="listPrice"/>
 										</td>
 										<th>판매가<em class="required" title="필수"></em></th>
-										<td><input type="text" class="w80p aR" id="currPrice" name="currPrice" maxlength="10" data-valid-type="integer"/> 원
+										<td><input type="text" class="w80p aR" id="currPrice" name="currPrice" maxlength="10" data-valid-type="numeric"/> 원
 											<input type="hidden" id="currPriceOrg" name="currPriceOrg"/>
 										</td>
 										<th>할인율</th>
@@ -263,7 +263,7 @@
 										</td>
 										<th>무료배송비기준<em class="required" title="필수"></em></th>
 										<td>
-											<input type="text" class="w100 aR" id="minOrdAmt" name="minOrdAmt" data-valid-type="real" maxlength="10"/> 원
+											<input type="text" class="w100 aR" id="minOrdAmt" name="minOrdAmt" data-valid-type="numeric" maxlength="10"/> 원
 											<input type="hidden" id="minOrdAmtOrg" name="minOrdAmtOrg"/>
 										</td>
 									</tr>

+ 1 - 1
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsEpSkipForm.html

@@ -7,7 +7,7 @@
  * @desc    : 네이버EP제외상품관리
  *============================================================================
  * PASTEL
- * Copyright(C) 2019 TSIT, All rights reserved.
+ * Copyright(C) 2020 TSIT, All rights reserved.
  *============================================================================
  * VER  DATE         AUTHOR      DESCRIPTION
  * ===  ===========  ==========  =============================================

+ 460 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsInstockAlarmForm.html

@@ -0,0 +1,460 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsInstockAlarmForm.html
+ * @desc    : 재입고알림관리
+ *============================================================================
+ * PASTEL
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.18   eskim   최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<form id="searchForm" name="searchForm" action="#" th:action="@{'/goods/inStockAlarm/list'}">
+		<input type="hidden" id="searchGb" name="searchGb" />
+ 		<!-- 패널 영역1 -->
+		<div class="panelStyle" >
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중  하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col width="13%"/>
+						<col width="37%"/>
+						<col width="13%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드</th>
+						<td>
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" th:if="${sessionInfo.roleCd} != 'G001_B000'">[전체]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="brandCd" id="brandCd">
+								<option value="">[전체]</option>
+							</select>
+						</td>
+						<th>키워드</th>
+						<td>
+							<select name="search" id="search">
+								<option value="searchGoodsCd">상품코드</option>
+								<option value="searchGoodsNum">품번</option>
+								<option value="searchGoodsNm">상품명</option>
+								<option value="searchColorNm">색상명</option>
+								<option value="searchSizeNm">옵션명</option>
+							</select>
+							<input type="text" class="w50p" name="condition" id="condition" maxlength="50"/>
+						</td>
+					</tr>
+					<tr>
+						<th>카테고리</th>
+						<td colspan="3">
+							<input name="siteCd" id="siteCd" type="hidden" value="10"/>
+							<input name="selLvl" id="selLvl" type="hidden"/>
+							<input name="cateCd" id="cateCd" type="hidden"/>
+							<input name="cateType" id="cateType" type="hidden"/>
+							<select name="cateGb" id="selCate1" onchange="fnChangeSelect($(this).val(), 2);">
+								<option value="">[카테고리구분]</option>
+								<option th:if="${cateGbList}" th:each="oneData, status : ${cateGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select id="selCate2" name="tcateCd" onchange="fnChangeSelect($(this).val(), 3);">
+								<option value="">[대카테고리]</option>
+							</select>
+							<select id="selCate3" name="mcateCd" onchange="fnChangeSelect($(this).val(), 4);">
+								<option value="">[중카테고리]</option>
+							</select>
+							<select id="selCate4" name="scateCd" onchange="fnChangeSelect($(this).val(), 5);">
+								<option value="">[소카테고리]</option>
+							</select>
+							<select id="selCate5" name="dcateCd" onchange="fnChangeSelect($(this).val(), 6);">
+								<option value="">[세카테고리]</option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>일자</th>
+						<td colspan="3" id="sellTerms"></td>
+					</tr>
+					<tr>
+						<th>발송여부</th>
+						<td colspan="3">
+							<select id="alarmYn" name="alarmYn">
+								<option value="">[전체]</option>
+								<option value="N">미발송</option>
+								<option value="Y">발송완료</option>
+							</select>
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
+					</li>
+				</ul>
+			</div>
+			<!-- //검색조건 영역 -->
+		</div>
+		<!-- 패널 영역1 -->
+		<div class="panelStyle">
+			<!-- 상단버튼 영역  -->
+			<ul class="panelBar">
+				<li class="right">
+					<button type="button" class="btn btn-primary btn-lg" id="inStockAlarmSend">재입고알림 발송</button>
+					<div class="iconTooltip">
+						<i class="fa fa-info" aria-hidden="true"></i>
+						<span class="left" style="width:300px;">
+						<!-- class="left" 또는 class="right" -->
+							PC재고, MO재고, APP재고 3가지 재고가 모두 있고, <br>품절여부가 아닐 때, 재입고알림 발송이 가능합니다.
+						</span>
+					</div>
+					검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+					쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+					<select id="pageSize" name="pageSize">
+						<option value="50" selected="selected">50개씩 보기</option>
+						<option value="100">100개씩 보기</option>
+						<option value="500">500개씩 보기</option>
+						<option value="1000">1000개씩 보기</option>
+					</select>
+					<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+				</li>
+			</ul>
+			<!-- //상단버튼 영역  -->
+			<div id="gridList" style="width: 100%; height: 500px;" class="ag-theme-balham lh60"></div>
+			<ul class="panelBar">
+				<li class="center">
+					<div class="tablePaging" id="goodsListPagination"></div>
+				</li>
+			</ul>
+			<!-- 검색결과 영역 -->
+		</div>
+		</form>
+		<!-- //패널 영역2 -->
+	</div>
+
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var sessRoleCd = [[${sessionInfo.roleCd}]];
+	var uploadGoodsUrl = [[${@environment.getProperty('upload.goods.view')}]];
+
+	var columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 60, cellClass: 'text-center',
+			valueGetter: function(params) { return cfnGridNumner('searchForm',params.node.rowIndex, 'A');}
+		},
+		{headerName: "상세보기", field: "instockAlarmSq", width: 100, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return '<button type="button" class="btn btn-success btn-sm" onclick="fnOpenInStockDetailPopup(\'' + params.value + '\');">상세정보</button>';
+			}
+		},
+		{headerName: "브랜드명", field: "brandEnm", width: 130, cellClass: 'text-center'},
+		{headerName: "이미지", field: "imgPath1", width: 100, height: 60, cellClass: 'text-center'
+			,cellRenderer: function(params) {
+				if (params.data.imgType == "A"){
+					if(!gagajf.isNull(params.data.imgPath6)){
+						return '<img width="60" src="'+ uploadGoodsUrl+params.data.imgPath6.replace("/1000/","/100/") + '" alt=""  onerror="this.src=\'/image/no.gif\';"/>';
+					}else{
+						return '<img width="60" src="'+ uploadGoodsUrl+params.value.replace("/1000/","/100/") + '" alt=""  onerror="this.src=\'/image/no.gif\';"/>';
+					}
+				}else{
+					if(!gagajf.isNull(params.data.imgPath6)){
+						return '<img width="60" src="'+ params.data.imgPath1 + '" alt="" onerror="this.src=\'/image/no.gif\';"/>';
+					}else{
+						return '<img width="60" src="'+ params.value + '" alt="" onerror="this.src=\'/image/no.gif\';"/>';
+					}
+				}
+			}
+		},
+		{headerName: "상품코드", field: "goodsCd", width: 140, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 250, cellClass: 'text-left'
+			,cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}
+		},
+		{headerName: "품목", field: "itemkindNm", width: 180, cellClass: 'text-center'},
+		{headerName: "신청수", field: "applycount", width: 80, cellClass: 'text-center'},
+		{headerName: "가용재고", field: "currStockQty" , width: 100, cellClass: 'text-center'},
+		{headerName: "색상명", field: "colorEnm", width: 150, cellClass: 'text-center'},
+		{headerName: "옵션", field: "sizeNm" , width: 80, cellClass: 'text-center'},
+		{headerName: "최초 접수일시", field: "updDt", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD") : '';
+			}
+		},
+		{headerName: "알림 발송일시", field: "alarmDt", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD") : '';
+			}
+		}
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+	gridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var goodsCd = event.data.goodsCd;
+		if (event.colDef.field == "goodsNm"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}else if (event.colDef.field == "goodsCd"){
+			
+		}
+	}
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		fnInit();
+	});
+	
+	var fnInit = function(){
+		$('#searchForm')[0].reset();
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnInStockAlarmListSearch();
+	});
+
+	// 조회
+	var fnInStockAlarmListSearch = function(gbn) {
+
+		$("#searchForm input[name=searchGb]").val("BASIC");
+		
+		if(!fnConditionCheck()) return;
+		
+		gagaPaging.init('searchForm', fnSearchCallBack, 'goodsListPagination', $('#searchForm').find('#pageSize').val());
+		gagaPaging.load($("#searchForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#searchForm';
+		var form = document.searchForm;
+
+		if($("#searchForm input[name=searchGb]").val() == "EXCEL") return true;
+		
+		var searchFlag = false;
+		var cnt = 0;
+
+		for (i = 0; i < form.elements.length; i++ ) {
+			var el = form.elements[i];
+
+			if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize" && el.name != "termGb")) {
+				if (!(el.value == null || el.value == "")) {
+					cnt++;
+				}
+			}
+		}
+			
+		if(cnt > 0) searchFlag = true;
+
+		if(searchFlag == false){
+			gagaAlert.alert("검색조건을 입력하세요.", function(){
+
+			});
+			return false;
+		}
+		
+		var fromDate = $('#searchForm input[name=stDate]').val();
+		var toDate = $('#searchForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				gagaAlert.alert("등록일 조회시 시작일자와 종료일자를 입력하세요.", function() {
+					$('#searchForm input[name=stDate]').focus();
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				gagaAlert.alert("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", function() {
+					$('#searchForm input[name=stDate]').focus();
+				});
+				return false;
+			} 
+		}
+
+		return true;
+	}
+
+	var fnChangeSelect = function(val, selLvl){
+		$("#cateCd").val('');
+		$('#tcateCd').val('');
+		$('#mcateCd').val('');
+		$('#scateCd').val('');
+		$('#dcateCd').val('');
+		if(val==''){
+			if(selLvl>1){
+				selLvl = selLvl - 1;
+				if(selLvl>2){
+					$("#cateCd").val($("#selCate"+(selLvl-1)).val());
+				}
+			}else{
+				selLvl = '';
+			}
+		}else{
+			if(selLvl>2){
+				$("#cateCd").val(val);
+			}
+		}
+		$("#searchForm input[name=selLvl]").val(selLvl);
+		$("#searchForm input[name=searchGb]").val("BASIC");
+		gagajf.ajaxFormSubmit('/display/category/list', "#searchForm", fnChangeCategory);
+	}
+
+	var fnChangeCategory = function(data){
+		var selLvl = $("#searchForm input[name=selLvl]").val();
+		var html = '<option value="">[선택]</option>';
+		for(var i=1; i<6; i++){
+			if(i>selLvl){
+				$("#selCate"+i).html(html);
+			}
+		}
+		for(var i=0; i<data.length; i++){
+			var cd = '';
+			var nm = '';
+			if(data[i].useYn=='Y'){
+				if(selLvl=='1'){
+					cd = data[i].cateGb;
+					nm = gagaAgGrid.lookupValue(cateGbList, cd);
+				}else{
+					cd = data[i].cateCd;
+					nm = data[i].cateNm;
+					$("#cateType").val(data[i].cateType);
+				}
+				html += '<option value="'+cd+'">['+cd+'] '+nm+'</option>';
+			}
+		}
+		$("#selCate"+selLvl).html(html);
+	}
+	
+	var fnSearchCallBack = function(result){
+
+		$('#searchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#searchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.inStockAlarmList);
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+
+	// 재입고알림 상세정보 버튼
+	var fnOpenInStockDetailPopup = function(instockAlarmSq){
+		var actionUrl = "/goods/inStockAlarm/detail/form?instockAlarmSq=" + instockAlarmSq;
+
+		uifnPopClose('popupInStockDetail');
+		cfnOpenModalPopup(actionUrl, 'popupInStockDetail');
+	}
+	
+	//페이징 
+	$('#searchForm select[name=pageSize]').on('change', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnInStockAlarmListSearch($("#searchForm input[name=searchGb]").val());
+	});
+	
+	//업체변경시
+	$('#searchForm select[name=supplyCompCd]').on('change', function() {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
+
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		$("#searchForm select[name=brandCd] option:gt(0)").remove();
+
+		cfnCreateCombo(actionUrl, $('#searchForm select[name=brandCd]'), "[전체]", "");
+	});
+
+	// 재입고알림 발송
+	$('#inStockAlarmSend').click(function(e) {
+		//상품선택여부 확인처리 추가
+		var selectedData = gridOptions.api.getSelectedRows();
+
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return false;
+		}
+
+		var arrInstockAlarmSq = [];
+		var chkFlag = false;
+		$.each(selectedData, function(idx, item) {
+
+			if (item.alarmYn == "Y"){
+				chkFlag = true;
+				mcxDialog.alert(item.goodsCd +"상품은 이미 재입고알림 발송되었습니다.");
+				return false;
+			}
+
+			if (item.currStockQty < 1 || item.soldoutYn == 'Y'){
+				chkFlag = true;
+				mcxDialog.alert(item.goodsCd +"상품( 사이즈 : " + item.sizeNm + " )은 가용재고가 없습니다.");
+				return false;
+			}
+
+			arrInstockAlarmSq.push(item.instockAlarmSq);
+		});
+
+		if (chkFlag){
+			return;
+		}
+
+		mcxDialog.confirm('재입고알림을 발송하시겠습니까?',  {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {arrInstockAlarmSq : arrInstockAlarmSq
+				};
+
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/inStockAlarm/send', jsonData, fnSendInstockCallBack);
+			}
+		});
+	});
+
+	// 재입고알림 발송 콜백
+	var fnSendInstockCallBack = function(){
+		fnInStockAlarmListSearch();
+	}
+	
+	$(document).ready(function() {
+		
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '예약일', 'X');
+
+		var selectCode = '<select  name="termGb" id="termGb">';
+		selectCode += '<option value="regDt" seledted>접수일</option>';
+		selectCode += '<option value="alarmDt">발송일</option>';
+		selectCode += '</select>';
+
+		$("#searchForm").find('#sellTerms').prepend(selectCode);
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+ 	
+</html>

+ 104 - 1
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsListForm.html

@@ -177,7 +177,7 @@
 						</td>
 						<th>판매가</th>
 						<td>
-							<input type="text" class="w90" name="currPriceSt" id="currPriceSt" maxlength="10" data-valid-type="numeric"/>원 ~ <input type="text" class="w90" name="currPriceEd" id="currPriceEd" maxlength="10" data-valid-type="numeric"/>원
+							<input type="text" class="w90 aR" name="currPriceSt" id="currPriceSt" maxlength="10" data-valid-type="numeric"/>원 ~ <input type="text" class="w90 aR" name="currPriceEd" id="currPriceEd" maxlength="10" data-valid-type="numeric"/>원
 						</td>
 						<th>할인율</th>
 						<td>
@@ -236,6 +236,7 @@
 			<ul class="panelBar">
 				<li class="right">
 					<button type="button" class="btn btn-info btn-sm"  onclick="fnGoodsStatArea();" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">상태일괄적용</button>
+					<button type="button" class="btn btn-info btn-sm" onclick="fnGoodsStaSelfNotArea();" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">입점상태일괄적용</button>
 				</li>
 			</ul>
 			<ul class="boxContent off" id="goodsStatArea">
@@ -330,6 +331,26 @@
 					</table>
 				</li>
 			</ul>
+			<ul class="boxContent off" id="goodsStatSelfNoArea">
+				<li class="pad20">
+					<table class="frmStyle">
+						<colgroup>
+							<col width="7%"/>
+							<col/>
+						</colgroup>
+						<tr>
+							<th>상품상태</th>
+							<td>
+								<select  name="goodsStatNC" id="goodsStatNC">
+									<option value="">[선택]</option>
+									<option th:if="${goodsStatList}" th:each="oneData, status : ${goodsStatList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+								</select>
+								<button type="button" class="btn btn-dark btn-sm" onclick="fnChangeGoodsStateSelfNo('goodsStat')">적용</button>
+							</td>
+						</tr>
+					</table>
+				</li>
+			</ul>
 			<!-- 검색결과 영역 -->
 		</div>
 		</form>
@@ -801,6 +822,71 @@
 			}
 		});
 	}
+	
+	// 입점 상품상태 변경시
+	var fnChangeGoodsStateSelfNo = function(proc){
+
+		var objId = '#'+proc+"NC";
+		
+		if (gagajf.isNull($(objId).val())){
+			mcxDialog.alertC('적용하실 항목을 선택(입력)해주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$(objId).focus();
+				}
+			});
+			return;
+		}
+	
+		var selectedData = gridOptions.api.getSelectedRows();
+
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+		
+		var checkFlag = false;
+		$.each(selectedData, function(idx, item) {
+			if (item.selfGoodsYn == 'Y'){
+				checkFlag = true;
+				mcxDialog.alert('자사상품은 수정하실 수 없습니다.');
+				return;
+			}
+		});
+		
+		if (checkFlag){
+			return false;
+		}
+		
+		var goodsStatVal  = '';
+
+		if (proc == "goodsStat") {
+			goodsStatVal = $(objId).val();
+		}else{
+			return;
+		}
+
+		mcxDialog.confirm('적용 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var arrGoodsCd = [];
+
+				$.each(selectedData, function(idx, item) {
+					arrGoodsCd.push(item.goodsCd);
+				});
+
+				var data = {arrGoodsCd: arrGoodsCd
+							,goodsStat : goodsStatVal
+							,procJob : proc
+							};
+
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/state/update', jsonData, fnChangeGoodsStateCollback);
+
+			}
+		});
+	}
 
 	var fnChangeGoodsStateCollback = function(result){
 		if (result.resultFlag == "FAIL"){
@@ -817,12 +903,29 @@
 		if ($("#searchForm").find("#goodsStatArea").hasClass('off')) {
 			$("#searchForm").find("#goodsStatArea").removeClass('off');
 			$("#searchForm").find("#goodsStatArea").addClass('on');
+			
+			$("#searchForm").find("#goodsStatSelfNoArea").removeClass('on');
+			$("#searchForm").find("#goodsStatSelfNoArea").addClass('off');
 		}else{
 			$("#searchForm").find("#goodsStatArea").removeClass('on');
 			$("#searchForm").find("#goodsStatArea").addClass('off');
 		}
 	}
 	
+	// 입점 상태일괄변경 버튼 클릭시
+	var fnGoodsStaSelfNotArea = function(){
+		if ($("#searchForm").find("#goodsStatSelfNoArea").hasClass('off')) {
+			$("#searchForm").find("#goodsStatSelfNoArea").removeClass('off');
+			$("#searchForm").find("#goodsStatSelfNoArea").addClass('on');
+			
+			$("#searchForm").find("#goodsStatArea").removeClass('on');
+			$("#searchForm").find("#goodsStatArea").addClass('off');
+		}else{
+			$("#searchForm").find("#goodsStatSelfNoArea").removeClass('on');
+			$("#searchForm").find("#goodsStatSelfNoArea").addClass('off');
+		}
+	}
+	
 	//세트상품구성 클릭 시
 	$('#btnGoodsSetMake').click(function(e) {
 		cfnOpenGoodsSetPopup();

+ 435 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsMassRegisterForm.html

@@ -0,0 +1,435 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"        >
+<!--
+ *******************************************************************************
+ * @source  : GoodsMassRegisterForm.html
+ * @desc    : 대량상품등록
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.18   eskim       최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- 검색조건 영역 -->
+		<form id="massForm" name="massForm" >
+		<div class="panelStyle">
+			<ul class="notice">
+				<li>상품을 대량으로 등록하는 페이지입니다.</li>
+				<li>상품을 등록 할 경우 [승인대기] 상태이며, STYLE 관리자의 [승인완료] 상태 변경 후 FRONT애 노출이 가능합니다.</li>
+				<li><th:block th:if="${erpSyncYn == 'N'}"><em><b>ERP연동여부가 [N]입니다. 관리자에게 문의하세요.</b></em></th:block></li>
+			</ul>
+			<ul class="panelBar">
+				<li class="center">
+					<th:block th:if="${sessionInfo.roleCd == 'G001_0000' 
+									or sessionInfo.roleCd == 'G001_A000' 
+									or sessionInfo.roleCd == 'G001_A001' 
+									or sessionInfo.roleCd == 'G001_A100' 
+									or sessionInfo.roleCd == 'G001_A101'
+									or (sessionInfo.roleCd == 'G001_E000' and ( #strings.isEmpty(supplyCompCd) or supplyCompCd =='P'  or supplyCompCd =='T') )
+									}">
+						<button type="button" class="btn btn-default btn-lg" id="btnInit" onclick="cfnDownloadSampleFile('SF001');">자사상품 등록양식 다운로드</button>
+						<button th:if="${erpSyncYn == 'Y'}" type="button" class="btn btn-primary btn-lg" id="btnGoodsSelfCreate" >자사상품 등록</button>
+					</th:block>
+					<th:block th:if="${sessionInfo.roleCd == 'G001_0000' 
+									or sessionInfo.roleCd == 'G001_A000' 
+									or sessionInfo.roleCd == 'G001_A001' 
+									or sessionInfo.roleCd == 'G001_A100' 
+									or sessionInfo.roleCd == 'G001_B000' 
+									or (sessionInfo.roleCd == 'G001_E000' and (#strings.isEmpty(supplyCompCd) or (supplyCompCd != 'P' and supplyCompCd != 'T')) )
+									}">
+						<button type="button" class="btn btn-default btn-lg" id="btnInit" onclick="cfnDownloadSampleFile('SF005');">입점상품 등록양식 다운로드</button>
+						<button th:if="${erpSyncYn == 'Y'}" type="button" class="btn btn-primary btn-lg" id="btnGoodsCreate" >입점상품 등록</button>
+					</th:block>
+					<label class="off"><a href="javascript:void(0);" id="excelList" style="display: none;">엑셀다운로드</a></label>
+					<!--  추후 대량 수정 권한-->
+					<span th:if="${sessionInfo.roleCd == 'G001_0000' 
+									or sessionInfo.roleCd == 'G001_A000' 
+									or sessionInfo.roleCd == 'G001_A001' 
+									or sessionInfo.roleCd == 'G001_A100' 
+									or sessionInfo.roleCd == 'G001_A101'
+									or sessionInfo.roleCd == 'G001_B000' 
+								}" 
+							th:style="'padding-left:80px;'">
+						<button type="button" class="btn btn-default btn-lg" id="btnInit" onclick="cfnDownloadSampleFile('SF014');">상품대량수정 등록양식 다운로드</button>
+						<button th:if="${erpSyncYn == 'Y'}" type="button" class="btn btn-primary btn-lg" id="btnGoodsUpdate" >입점상품 등록</button>
+					</span>
+				</li>
+			</ul>
+		</div>
+		<div class="panelStyle" >
+			<!-- 검색조건 영역 -->
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col width="10%"/>
+						<col width="40%"/>
+						<col width="10%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>상품코드<i class="star"></i></th>
+						<td><input type="text" class="w130" name="condition" id="condition" maxlength="50"/></td>
+						<th>등록여부</th>
+						<td>
+							<select  name="regSuccYn" id="regSuccYn">
+								<option value="">[전체]</option>
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>등록일<i class="star"></i></th>
+						<td colspan="3" id="sellTerms"></td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li>
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
+					</li>
+				</ul>
+			</div>
+			<!-- //검색조건 영역 -->
+		</div>
+		<div class="panelStyle">
+			<!-- 검색결과 영역 -->
+			<!-- 상단버튼 영역  -->
+			<ul class="panelBar">
+				<li class="left">
+					<!-- 아이콘 툴팁 -->
+					<div class="iconTooltip">
+						<i class="fa fa-info" aria-hidden="true"></i>
+						<span class="left aL" style="width:580px;">
+						<!-- class="left" 또는 class="right" -->
+							<em>상품미등록</em><br/>
+							- 상품코드 오류 : 빈값, 길이 11이 아닐경우, '_'가 미존재<br/>
+							- 업체 오류 : 빈값, 'W'나 'F' 가 아닌경우<br/>
+							- 상품명 오류 : 빈값<br/>
+							- 제조국 오류 : 빈값<br/>
+							- 제조년월일 오류 : 빈값, 날짜형식이 맞는지<br/>
+							- ERP 미존재 상품코드 : ERP에 상품코드가 존재하는지<br/>
+							- 스타일 연도 오류 : 온라인에서 관리되지 않는 스타일 연도<br/>
+							- 성별 오류 : 온라인에서 관리되지 않는 성별<br/>
+							- 컬러 오류 : 온라인에서 관리되지 않는 컬러<br/>
+							- 상품코드 중복등록요청 : 등록된 상품코드 등록요청<br/>
+							- 품목 오류 : 온라인에서 관리되지 않는 품목<br/>
+							- ERP 브랜드 오류 : 온라인에서 관리되지 않는 ERP 브랜드<br/>
+							- 이미지 유형 오류 : 온라인에서 관리되지 않는 이미지유형<br/>
+							- 상품이미지 필수 오류 : IMG_PATH1
+							- 품목의 고시정보 없음 : 품목의 고시분류 매핑이 안되어 있는 경우<br/>
+							- 고시분류 오류 : 등록요청 고시분류 와 온라인에서 품목과 매핑된 고시분류가 다른 경우<br/>
+							<em>상품등록</em><br/>
+							- ERP 상품 사이즈 정보 없음 : ERP에 상품코드의 사이즈가 없을 경우<br/>
+						</span>
+					</div>
+					<!-- //아이콘 툴팁 -->
+				</li>
+				<li class="right">
+					<button type="button" class="btn btn-default btn-lg" id="btnGoodsRegExcelDownLoad">엑셀다운로드</button>
+				</li>
+			</ul>
+			<!-- //상단버튼 영역  -->
+			<div id="gridList" style="width: 100%; height: 500px;" class="ag-theme-balham"></div>
+			<!-- 검색결과 영역 -->
+		</div>
+		<!-- //검색조건 영역 -->
+		</form>
+	</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var niClsfCdList = gagajf.convertToArray([[${niClsfCdList}]]);
+	var columnDefs = [
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "작업일시", field: "regDt", width: 150, cellClass: 'text-center'},
+		{headerName: "상품등록여부", field: "regSuccYn", width: 100, cellClass: 'text-center'},
+		{headerName: "등록결과메세지", field: "regFailRsn", width: 200, cellClass: 'text-left'},
+		{headerName: "등록브랜드코드", field: "brandCd", width: 120, cellClass: 'text-center'},
+		{headerName: "업체코드", field: "supplyCompCd", width: 130, cellClass: 'text-center'},
+		{headerName: "상품코드", field: "goodsCd", width: 130, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 150, cellClass: 'text-left'},
+		{headerName: "상품타이틀", field: "goodsTnm", width: 150, cellClass: 'text-left'},
+		{headerName: "검색어", field: "goodsSnm1", width: 150, cellClass: 'text-left'},
+		{headerName: "제조국", field: "makeNm", width: 100, cellClass: 'text-center'},
+		{headerName: "제조일", field: "makeYmd", width: 100, cellClass: 'text-center'},
+		{headerName: "이지미타입", field: "imgType", width: 100, cellClass: 'text-center'},
+		{headerName: "이미지경로1", field: "imgPath1", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로2", field: "imgPath2", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로3", field: "imgPath3", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로4", field: "imgPath4", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로5", field: "imgPath5", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로6", field: "imgPath6", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로7", field: "imgPath7", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로8", field: "imgPath8", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로9", field: "imgPath9", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로10", field: "imgPath10", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로11", field: "imgPath11", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로12", field: "imgPath12", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로13", field: "imgPath13", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로14", field: "imgPath14", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로15", field: "imgPath15", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로16", field: "imgPath16", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로17", field: "imgPath17", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로18", field: "imgPath18", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로19", field: "imgPath19", width: 200, cellClass: 'text-left'},
+		{headerName: "이미지경로20", field: "imgPath20", width: 200, cellClass: 'text-left'},
+		{headerName: "고시분류코드", field: "niClsfCd", width: 200, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(niClsfCdList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(niClsfCdList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(niClsfCdList, params.newValue); }
+		},
+		{headerName: "고시내용1", field: "niContent1", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용2", field: "niContent2", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용3", field: "niContent3", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용4", field: "niContent4", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용5", field: "niContent5", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용6", field: "niContent6", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용7", field: "niContent7", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용8", field: "niContent8", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용9", field: "niContent9", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용10", field: "niContent10", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용11", field: "niContent11", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용12", field: "niContent12", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용13", field: "niContent13", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용14", field: "niContent14", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용15", field: "niContent15", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용16", field: "niContent16", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용17", field: "niContent17", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용18", field: "niContent18", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용19", field: "niContent19", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용20", field: "niContent20", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용21", field: "niContent21", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용22", field: "niContent22", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용23", field: "niContent23", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용24", field: "niContent24", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용25", field: "niContent25", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용26", field: "niContent26", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용27", field: "niContent27", width: 200, cellClass: 'text-left'},
+		{headerName: "고시내용28", field: "niContent28", width: 200, cellClass: 'text-left'},
+		{headerName: "브랜드", field: "brandCd", width: 100, cellClass: 'text-center'},
+		{headerName: "품목", field: "itemkindCd", width: 100, cellClass: 'text-center'},
+		{headerName: "스타일연도", field: "styleYear", width: 100, cellClass: 'text-center'},
+		{headerName: "시즌", field: "seasonCd", width: 80, cellClass: 'text-center'},
+		{headerName: "성별", field: "sexGb", width: 80, cellClass: 'text-center'},
+		{headerName: "품번", field: "goodsNum", width: 100, cellClass: 'text-center'},
+		{headerName: "형태", field: "shapeCd", width: 80, cellClass: 'text-center'},
+		{headerName: "색상", field: "colorCd", width: 80, cellClass: 'text-center'},
+		{headerName: "TAG가", field: "tagPrice", width: 100, cellClass: 'text-center'},
+		{headerName: "정상가", field: "listPrice", width: 100, cellClass: 'text-center'},
+		{headerName: "판매가", field: "currPrice", width: 100, cellClass: 'text-center'},
+		{headerName: "공급업체상품코드", field: "supplyGoodsCd", width: 130, cellClass: 'text-center'},
+		{headerName: "정상이월", field: "formalGb", width: 100, cellClass: 'text-center'},
+		/* {headerName: "옵션문자열", field: "optStr", width: 200, cellClass: 'text-center'},
+		{headerName: "안전재고문자열", field: "baseStockStr", width: 200, cellClass: 'text-center'},
+		{headerName: "현재고문자열", field: "currStockStr", width: 200, cellClass: 'text-center'}, */
+		{headerName: "매입유형", field: "buyingType", width: 80, cellClass: 'text-center'}
+	];
+
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	$(document).ready(function() {
+		
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', 'X');
+		gagaAgGrid.createGrid('gridList', gridOptions);
+		
+	});
+	
+	//자사상품대량등록 클릭시
+	$('#btnGoodsSelfCreate').on('click', function() {
+		cfnExcelUploadPopup('createSelfGoods', 'createSelfGoods');
+	});
+	
+	var createSelfGoods = function(result){
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/mass/excelupload/create', jsonData, fnGoodsSelfCreateCallBack);
+	}
+	
+	var fnGoodsSelfCreateCallBack = function(result){
+		
+		var date = new Date();
+		$("#massForm input[name=stDate]").val(date.format("YYYY-MM-DD"));
+		$("#massForm input[name=edDate]").val(date.format("YYYY-MM-DD"));
+		fnGoodsListSearch();
+	}
+	
+	//입점상품대량등록 클릭시
+	$('#btnGoodsCreate').on('click', function() {
+		cfnExcelUploadPopup('createGoods', 'createGoods');
+	});
+	
+	var createGoods = function(result){
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/mass/excelupload/create', jsonData, fnGoodsCreateCallBack);
+	}
+	
+	var fnGoodsCreateCallBack = function(result){
+		
+		var date = new Date();
+		$("#massForm input[name=stDate]").val(date.format("YYYY-MM-DD"));
+		$("#massForm input[name=edDate]").val(date.format("YYYY-MM-DD"));
+		fnGoodsListSearch();
+	}
+	
+	//상품대량수정 클릭시
+	$('#btnGoodsUpdate').on('click', function() {
+		cfnExcelUploadPopup('updateGoods', 'updateGoods');
+	});
+	
+	var updateGoods = function(result){
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/mass/excelupload/update', jsonData, fnGoodsUpdateCallBack);
+	}
+	
+	var fnGoodsUpdateCallBack = function(result){
+		
+		var date = new Date();
+		$("#massForm input[name=stDate]").val(date.format("YYYY-MM-DD"));
+		$("#massForm input[name=edDate]").val(date.format("YYYY-MM-DD"));
+		fnGoodsListSearch();
+	}
+	
+	$('#btnGoodsRegExcelDownLoad').on('click', function() {
+		
+		var date = new Date().format("YYYYMMDDHHmmss");
+		var params = {
+			
+			fileName : "상품대량등록결과_"+ date,
+			sheetName: "DATA"
+		}
+		gridOptions.excelStyles = [
+			{
+				id: 'text-center',
+				dataType: 'string',
+				font: {size : 10, bold: false}
+			},
+			{
+				id: 'text-left',
+				dataType: 'string',
+				font: {size : 10, bold: false}
+			}
+		]
+		
+		gridOptions.api.exportDataAsExcel(params);
+		
+	});
+	
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		$('#massForm')[0].reset();
+	});
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		
+		if( gagajf.isNull($("#massForm input[name=condition]").val())
+			&& gagajf.isNull($("#massForm input[name=stDate]").val()) 
+			&& gagajf.isNull($("#massForm input[name=edDate]").val())){
+			
+			mcxDialog.alertC("검색조건을 입력하세요.",  {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#massForm input[name=condition]').focus();
+				}
+			});
+			return false;
+		}
+		
+		var fromDate = $('#massForm input[name=stDate]').val();
+		var toDate = $('#massForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#massForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#massForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		}
+		fnGoodsListSearch();
+	});
+	
+	// 조회
+	var fnGoodsListSearch = function(gbn) {
+		gagaAgGrid.fetch('/goods/reg/log/list', gridOptions, '#massForm');
+	}
+	
+	//안내팝업
+	var fnGoodsOpenCommentPopup = function(id) {
+		var str = '<div class="popupWrap" id="'+id+'" style="z-index:30">';
+		str = str + '<div class="popup modeless ui-widget-content ui-draggable ui-draggable-handle" style="display: block;  position: relative;">';
+		str = str + '<button type="button" class="close" onclick="uifnPopClose(\''+id+'\')"><i class="fa fa-times"></i></button>';
+		str = str + '<div class="mdPopContent">';
+		str = str + '<ul class="notice ">';
+		str = str + '- <em>상품미등록</em>';
+		str = str + '<li>상품코드 오류 : 빈값, 길이 11, \'_\'가 존재하는지</li>';
+		str = str + '<li>업체 오류 : 빈값, \'W\'나 \'F\' 가 아닌경우</li>';
+		str = str + '<li>상품명 오류 : 빈값</li>';
+		str = str + '<li>제조국 오류 : 빈값</li>';
+		str = str + '<li>제조년월일 오류 : 빈값, 날짜형식이 맞는지</li>';
+		str = str + '<li>ERP 미존재 상품코드 : ERP에 상품코드가 존재하는지</li>';
+		str = str + '<li>스타일 연도 오류 : 온라인에서 관리되지 않는 스타일 연도</li>';
+		str = str + '<li>성별 오류 : 온라인에서 관리되지 않는 성별</li>';
+		str = str + '<li>컬러 오류 : 온라인에서 관리되지 않는 컬러</li>';
+		str = str + '<li>상품코드 중복등록요청 : 등록된 상품코드 등록요청</li>';
+		str = str + '<li>품목 오류 : 온라인에서 관리되지 않는 품목</li>';
+		str = str + '<li>ERP 브랜드 오류 : 온라인에서 관리되지 않는 ERP 브랜드</li>';
+		str = str + '<li>이미지 유형 오류 : 온라인에서 관리되지 않는 이미지유형</li>';
+		str = str + '<li>상품이미지 필수 오류 : A타입 : IMG_PATH1: 정사각형이미지(앞면),IMG_PATH3: 작사각형이미지(정면),<br/></li>';
+		str = str + '<span style="padding-left:185px;"></span>';
+		str = str + 'IMG_PATH4: 직사각형이미지(뒷면), IMG_PATH5: 상품상세컷(통자)';
+		str = str + '<li>상품이미지 필수 오류 : B타입 : IMG_PATH1, IMG_PATH2</li>';
+		str = str + '<li>품목의 고시정보 없음 : 품목의 고시분류 매핑이 안되어 있는 경우</li>';
+		str = str + '<li>고시분류 오류 : 등록요청 고시분류 와 온라인에서 품목과 매핑된 고시분류가 다른 경우</li>';
+		str = str + '- <em>상품등록</em>';
+		str = str + '<li>ERP 상품 사이즈 정보 없음 : ERP에 상품코드의 사이즈가 없을 경우</li>';
+		str = str + '</ul>';
+		str = str + '</div></div></div>';
+
+		if ($('#'+ id).length == 0) {
+			$('body').append(str);
+		}
+		$("#"+id).css({display:"block"});
+	}
+	
+/*]]>*/
+</script>
+</html>

+ 513 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsPriceReserveForm.html

@@ -0,0 +1,513 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsPriceReserveForm.html
+ * @desc    : 상품 가격 예약관리
+ *============================================================================
+ * PASTEL
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.13   eskim       최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<form id="goodsPriceResForm" name="goodsPriceResForm" action="#" th:action="@{'/goods/price/reserve/list'}">
+		<input type="hidden" id="selfGoodsYn" name="selfGoodsYn" value="Y"/>
+		<input type="hidden" id="searchGb" name="searchGb" />
+		<input type="hidden" id="arrGoodsCd" name="arrGoodsCd" />
+ 		<!-- 패널 영역1 -->
+		<div class="panelStyle" >
+			<!-- TITLE -->
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<!-- //TITLE -->
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col width="10%"/>
+						<col width="23%"/>
+						<col width="10%"/>
+						<col width="23%"/>
+						<col width="10%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드</th>
+						<td colspan="3">
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" th:if="${sessionInfo.roleCd} != 'G001_B000'">[전체]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<span id="multiBrand"></span>
+						</td>
+						<th rowspan="3">키워드</th>
+						<td rowspan="3">
+							<select name="search" id="search">
+								<option value="searchGoodsCd">상품코드</option>
+								<option value="searchGoodsNum">품번</option>
+								<option value="searchSupplyGoodsCd">업체상품코드</option>
+							</select>
+							<textarea class="textareaR3 w50p" name="condition" id="condition"></textarea>
+						</td>
+					</tr>
+					<tr>
+						<th>상품명</th>
+						<td>
+							<input type="text" class="w200" name="goodsNm" id="goodsNm" maxlength="50"/>
+						</td>
+						<th>예약가격</th>
+						<td>
+							<input type="text" class="w100 aR" name="goodsPriceResSt" id="goodsPriceResSt" maxlength="10" data-valid-type="numeric"/>원 ~ <input type="text" class="w100 aR" name="goodsPriceResEd" id="goodsPriceResEd" maxlength="10" data-valid-type="numeric"/>원
+						</td>
+					</tr>
+					<tr>
+						<th>시즌/년도</th>
+						<td colspan="3">
+							<select  name="styleYear" id="styleYear">
+								<option value="">[전체]</option>
+								<option th:if="${styleYearList}" th:each="oneData, status : ${styleYearList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select  name="seasonCd" id="seasonCd">
+								<option value="">[전체]</option>
+								<option th:if="${seasonList}" th:each="oneData, status : ${seasonList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>예약일</th>
+						<td colspan="5" id="sellTerms"></td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
+					</li>
+				</ul>	
+			</div>
+			<!-- //검색조건 영역 -->
+		</div>
+		<!-- 패널 영역1 -->
+		<div class="panelStyle">
+			<!-- 검색결과 영역 -->
+			<!-- 상단버튼 영역  -->
+			<ul class="panelBar">
+				<li>
+					<select id="excelSample" name="excelSample">
+						<option value="">[선택]</option>
+						<option value="SF003">상품엑셀조회양식</option>
+						<option value="SF018" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">상품가격예약등록양식</option>
+					</select>
+					<button type="button" class="btn btn-default btn-lg" id="btnExcelSampleDownLoad">다운로드</button>
+					<button type="button" class="btn btn-base btn-lg" id="btnGoodsExcelUpLoad">엑셀조회</button>
+					<button type="button" class="btn btn-success btn-lg" id="btnGoodsExcelSave" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">상품가격예약등록</button>
+					<button type="button" class="btn btn-success  btn-lg" id="btnGoodsPriceResSave">예약등록</button>
+					<button type="button" class="btn btn-danger btn-lg" id="btnGoodsPriceResDelete">예약삭제</button>
+				</li>
+				<li class="right">
+					검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+					
+					쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+					<select id="pageSize" name="pageSize">
+						<option value="50" selected="selected">50개씩 보기</option>
+						<option value="100">100개씩 보기</option>
+						<option value="500">500개씩 보기</option>
+						<option value="1000">1000개씩 보기</option>
+					</select>
+					<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+				</li>
+			</ul>
+			<!-- //상단버튼 영역  -->
+			<div id="gridList" style="width: 100%; height: 550px;" class="ag-theme-balham"></div>
+			<ul class="panelBar">
+				<li class="center">
+					<div class="tablePaging" id="goodsListPagination"></div>
+				</li>
+			</ul>
+			<!-- 검색결과 영역 -->
+		</div>
+		</form>
+		<!-- //패널 영역2 -->
+	</div>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var sessRoleCd = [[${sessionInfo.roleCd}]];
+	var goodsStatList = gagajf.convertToArray([[${goodsStatList}]]);
+	var formalGbList = gagajf.convertToArray([[${formalGbList}]]);
+
+	var columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 60, cellClass: 'text-center',
+			valueGetter: function(params) { return cfnGridNumner('goodsPriceResForm',params.node.rowIndex, 'A');}
+		},
+		{headerName: "브랜드명", field: "brandEnm", width: 110, cellClass: 'text-center'},
+		{headerName: "상품코드", field: "goodsCd", width: 110, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 200, cellClass: 'text-left'
+			,cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}
+		},
+		{headerName: "상품상태", field: "goodsStat" , width: 100, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(goodsStatList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(goodsStatList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(goodsStatList, params.newValue); }
+		},
+		{headerName: "현재상품가격", field: "currPrice", width: 110, cellClass: 'text-right'
+			,valueFormatter: function(params) {return params.value.addComma();}
+		},
+		{headerName: "예약상품가격", field: "resGoodsPrice", width: 110, cellClass: 'text-right'
+			,valueFormatter: function(params) {return params.value.addComma();}
+			,cellStyle : function(params){return { 'color': 'red'}}
+		},
+		{headerName: "예약시작일시", field: "applyStdt", width: 130, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD") : '';
+			}
+		},
+		{headerName: "예약종료일시", field: "applyEddt", width: 130, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD") : '';
+			}
+		},
+		{headerName: "등록일시", field: "regDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록자", field: "regNm", width: 100, cellClass: 'text-center'},
+		{headerName: "수정일시", field: "updDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "수정자", field: "updNm", width: 100, cellClass: 'text-center'},
+		{headerName: "상품가겨예약순번", field: "goodsPriceResSq", hide: true},
+		{headerName: "적용여부", field: "applyYn", hide: true}
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+	//gridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var goodsCd = event.data.goodsCd;
+		if (event.colDef.field == "goodsNm"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}else if (event.colDef.field == "goodsCd"){
+			
+		}
+	}
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		fnInit();
+	});
+	
+	var fnInit = function(){
+		$("#goodsPriceResForm input[name=siteCd]").prop("disabled", true);
+		$("#goodsPriceResForm input[name=siteCd]").addClass("formControl");
+		
+		$('#goodsPriceResForm')[0].reset();
+		//$("#goodsPriceResForm input[type=radio]").removeClass("checked");
+		$("#goodsPriceResForm input[type=checkbox]").removeClass("checked");
+		//$("#goodsPriceResForm input[type=radio]").parent("label").removeClass("checked");
+		$("#goodsPriceResForm input[type=checkbox]").parent("label").removeClass("checked");
+		$("#goodsPriceResForm input[type=radio][checked]").parent("label").addClass("checked");
+		$("#multiBrand").empty();
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		$("#goodsPriceResForm input[name=pageNo]").val('1');
+		fnGoodsPriceSearch('BASIC');
+	});
+
+	// 조회
+	var fnGoodsPriceSearch = function(gbn) {
+		
+		if (typeof(gbn) != 'undefined' &&  gbn == 'EXCEL'){
+			$("#goodsPriceResForm input[name=searchGb]").val("EXCEL");
+		}else if (typeof(gbn) != 'undefined' &&  gbn == 'EXCELRESULT'){
+			$("#goodsPriceResForm input[name=searchGb]").val("EXCELRESULT");
+		}else{
+			$("#goodsPriceResForm input[name=searchGb]").val("BASIC");
+		}
+		
+		
+		if(!fnConditionCheck()) return;
+		
+		gagaPaging.init('goodsPriceResForm', fnSearchCallBack, 'goodsListPagination', $('#goodsPriceResForm').find('#pageSize').val());
+		gagaPaging.load($("#goodsPriceResForm input[name=pageNo]").val());
+	}
+
+	// 조회 (등록 창 닫을 때)
+	var fnGoodsRsvtTnmListSearch = function(gbn) {
+
+		if (typeof(gbn) != 'undefined' &&  gbn == 'EXCEL'){
+			$("#goodsPriceResForm input[name=searchGb]").val("EXCEL");
+		}else{
+			$("#goodsPriceResForm input[name=searchGb]").val("BASIC");
+		}
+
+		gagaPaging.init('goodsPriceResForm', fnSearchCallBack, 'goodsListPagination', $('#goodsPriceResForm').find('#pageSize').val());
+		gagaPaging.load($("#goodsPriceResForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#goodsPriceResForm';
+		var form = document.goodsPriceResForm;
+
+		if($("#goodsPriceResForm input[name=searchGb]").val() == "EXCEL" || $("#goodsPriceResForm input[name=searchGb]").val() == "EXCELRESULT") {
+			return true;
+		}
+		
+		var searchFlag = false;
+		var cnt = 0;
+
+		/* if( !gagajf.isNull($("#goodsPriceResForm select[name=supplyCompCd]").val())
+				|| !gagajf.isNull($("#goodsPriceResForm input[name=condition]").val())
+				|| (!gagajf.isNull($("#goodsPriceResForm input[name=stDate]").val()) && !gagajf.isNull($("#goodsPriceResForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{ */
+			for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+				if ($(el).prop("type") == "text" || $(el).prop("type") == "textarea" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+			
+			if(cnt > 0) searchFlag = true;
+			
+		/* } */
+		
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		
+		var fromDate = $('#goodsPriceResForm input[name=stDate]').val();
+		var toDate = $('#goodsPriceResForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsPriceResForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alert("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsPriceResForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		}
+
+		return true;
+	}
+	
+	var fnSearchCallBack = function(result){
+
+		$('#goodsPriceResForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#goodsPriceResForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#goodsPriceResForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#goodsPriceResForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.goodsPriceResList);
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+	
+	//페이징 
+	$('#goodsPriceResForm select[name=pageSize]').on('change', function() {
+		$("#goodsPriceResForm input[name=pageNo]").val('1');
+		fnGoodsPriceSearch($("#goodsPriceResForm input[name=searchGb]").val());
+	});
+	
+	//업체변경시
+	$('#goodsPriceResForm select[name=supplyCompCd]').on('change', function() {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
+
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		cfnCreateMultiCombo(actionUrl,"multiBrand",  "[전체]",null, 'Y');
+	});
+	
+	//엑셀 상품 조회
+	$('#btnGoodsExcelUpLoad').on('click', function() {
+		cfnExcelUploadPopup('goodsPriceExcelUpload', 'goodsPriceExcelUpload');
+	});
+	
+	var goodsPriceExcelUpload = function(result){
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, fnGoodsPriceExcelUploadCallBack);
+	}
+	
+	var fnGoodsPriceExcelUploadCallBack = function(result){
+		fnGoodsPriceSearch("EXCEL");
+	}
+	
+	//예약등록 팝업
+	$('#btnGoodsPriceResSave').click(function(e) {
+		var actionUrl = "/goods/price/reserve/popup/form";
+		cfnOpenModalPopup(actionUrl, 'popupGoodsPriceReserve'); 
+	});
+	
+	//예약삭제
+	$('#btnGoodsPriceResDelete').click(function(e) {
+		//상품선택여부 확인처리 추가
+		var selectedData = gridOptions.api.getSelectedRows();
+
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return false;
+		}
+		
+		var arrGoodsCd = [];
+		var arrGoodsPriceResSq = [];
+		var chkFlag = false;
+		//selectedData = gagaAgGrid.getAllRowData(gridOptions);
+		$.each(selectedData, function(idx, item) {
+			
+			if (gagajf.isNull(item.goodsPriceResSq) || item.goodsPriceResSq == "0"){
+				chkFlag = true;
+				mcxDialog.alert(item.goodsCd +"상품은 가격이 예약된 상품이 아닙니다.");
+				return false;
+			}
+			
+			var toDateStr = new Date().format("YYYYMMDDHHmmss");
+			if (toDateStr > item.applyEddt){
+				chkFlag = true;
+				mcxDialog.alertC("종료된 예약 상품은 삭제할 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsRsvtTnmForm input[name=applyEdYMD]').focus();
+					}
+				});
+				return false;
+			}
+		
+			if ((toDateStr > item.applyStdt) && ("Y" == $('#goodsRsvtTnmForm input[name=applyYn]').val())){
+				chkFlag = true;
+				mcxDialog.alertC("시작된 예약 상품은 삭제할 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsRsvtTnmForm input[name=applyEdYMD]').focus();
+					}
+				});
+				return false;
+			}
+			
+			arrGoodsCd.push(item.goodsCd);
+			arrGoodsPriceResSq.push(item.goodsPriceResSq);
+		});
+
+		if (chkFlag){
+			return;
+		}
+		
+		mcxDialog.confirm('삭제하시겠습니까?',  {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {arrGoodsCd : arrGoodsCd
+						,arrGoodsPriceResSq : arrGoodsPriceResSq
+			};
+			
+			var jsonData = JSON.stringify(data);
+			gagajf.ajaxJsonSubmit('/goods/price/reserve/delete', jsonData, fnGoodsPriceResDeleteCollBack);
+			}
+		});
+	});
+	
+	var fnGoodsPriceResDeleteCollBack = function(){
+		//fnGoodsRsvtTnmListSearch($("#goodsPriceResForm input[name=searchGb]").val());
+	}
+	
+	//엑셀양식 다운로드
+	$('#btnExcelSampleDownLoad').on('click', function (){
+		var gb = $("#goodsPriceResForm select[name=excelSample]").val();
+		if (gagajf.isNull(gb)){
+			mcxDialog.alertC("다운로드 할 양식을 선택해주세요", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsPriceResForm select[name=excelSample]').focus();
+				}
+			});
+			return false;
+		}
+		
+		cfnDownloadSampleFile($("#goodsPriceResForm select[name=excelSample]").val());	
+		
+	});
+	
+	//엑셀 상품 가격예약 저장
+	$('#btnGoodsExcelSave').on('click', function() {
+		cfnExcelUploadPopup('goodsPriceResvExcelUpload', 'goodsPriceResvExcelSave');
+	});
+	
+	var goodsPriceResvExcelSave = function(result){
+		mcxDialog.confirm('상품가격예약을 진행하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {procJob : result.procJob
+						,excelFileNm : result.excelFileNm
+						};
+			var jsonData = JSON.stringify(data);
+			gagajf.ajaxJsonSubmit('/goods/price/excelupload/save', jsonData, fnGoodsSizeStockExcelSaveCallBack);
+			}
+		});	
+	}
+	
+	var fnGoodsSizeStockExcelSaveCallBack = function(result){
+		fnGoodsPriceSearch("EXCELRESULT");
+	}
+	
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'applyStdt', 'applyEddt', true, '예약일', 'X');
+		var chkBeforSkipFlag = '&nbsp;&nbsp;<label class="chkBox"><input type="checkbox" name="beforSkipFlag" value="Y" >이전데이터 제외</label>';
+		$("#goodsPriceResForm").find('#sellTerms').append(chkBeforSkipFlag);
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+ 	
+</html>

+ 319 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsPriceReservePopupForm.html

@@ -0,0 +1,319 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsPriceReservePopupForm.html
+ * @desc    : 상품 가격 예약등록 화면
+ *============================================================================
+ * PASTEL
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.13   eskim       최초 작성
+ *******************************************************************************
+ -->	
+	<div class="modalPopup" data-width="850" >
+		<div class="panelStyle">
+			<div class="panelTitle">
+				<h2>상품가격예약</h2>
+				<button type="button" class="close" onclick="uifnPopupClose('popupGoodsPriceReserve')"><i class="fa fa-times"></i></button>
+			</div>
+			<form id="goodsPriceRsvtForm" name="goodsPriceRsvtForm" >
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>상품예약가격<em class="required" title="필수"></em></th>
+						<td><input type="text" class="w100p aR" id="resGoodsPrice" name="resGoodsPrice" maxlength="10" data-valid-type="numeric" /></td>
+						<th>예약일자<em class="required" title="필수"></em></th>
+						<td>
+							<input name="applyStYMD" id="applyStYMD" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="예약시작일" />
+							<input name="applyStdt" id="applyStdt" type="hidden" />
+							~
+							<input name="applyEdYMD" id="applyEdYMD" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="예약 종료일" />
+							<input name="applyEddt" id="applyEddt" type="hidden" />
+						</td>
+					</tr>
+				</table>
+			</div>
+			<ul class="panelBar">
+				<li class="left">
+					<button type="button" class="btn btn-danger btn-lg" id="btnDeleteGoodsPriceRsvt">상품삭제</button>
+				</li>
+				<li class="right">
+					<button type="button" class="btn btn-base btn-lg" id="btnSearchExcel">엑셀조회</button>
+					<button type="button" class="btn btn-info btn-lg" id="btnSearchGoods">상품조회</button>
+				</li>
+			</ul>
+			<div id="gridGoodsPriceRsvtList" style="width: 100%; height: 400px;" class="ag-theme-balham"></div>
+			<ul class="panelBar">
+				<li class="right">
+					<button type="button" class="btnRight btn btn-base btn-lg" id="btnSaveGoodsPriceRsvt">적용</button>
+				</li>
+			</ul>
+			</form>	
+		</div>
+	</div>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	
+	var rsvtGoodsPriceColumnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 50, cellClass: 'text-center',valueGetter: function(params) { return params.node.rowIndex+1}},
+		{headerName: "상품코드", field: "goodsCd", width: 140, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 330, cellClass: 'text-left'},
+		{headerName: "정상가", field: "listPrice" , width: 120, cellClass: 'text-right'
+			,valueFormatter: function(params) {return params.value.addComma();}
+		},
+		{headerName: "현재판매가", field: "currPrice", width: 120, cellClass: 'text-right'
+			,valueFormatter: function(params) {return params.value.addComma();},
+		}
+		
+	];
+	
+	// Get GridOptions
+	var rsvtGoodsPriceGridOptions = gagaAgGrid.getGridOptions(rsvtGoodsPriceColumnDefs);
+	rsvtGoodsPriceGridOptions.enableBrowserTooltips = true;
+	
+	// 중복 선택 가능
+	rsvtGoodsPriceGridOptions.rowSelection = 'multiple';
+	rsvtGoodsPriceGridOptions.suppressRowClickSelection = true;
+	//rsvtGoodsPriceGridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+
+	// 상품 조회 클릭 시
+	$('#btnSearchGoods').on('click', function() {
+		cfnOpenGoodsPopup('fnSearchGoods');
+	});
+
+	// 상품 조회 콜백함수
+	var fnSearchGoods = function(result) {
+		if (result.length < 1) return;
+		var oldData = gagaAgGrid.getAllRowData(rsvtGoodsPriceGridOptions);
+		$.each(result, function(idx, item) {
+			var isInvalid = false;
+			if (oldData != null && oldData.length != 0){
+				oldData.forEach(function(oneData){
+					if(oneData.goodsCd == item.goodsCd){
+						isInvalid = true;
+						return true;
+					}
+				});
+				if(isInvalid){
+					return isInvalid;
+				}
+			}
+			gagaAgGrid.addRowData(rsvtGoodsPriceGridOptions, {"goodsCd" : item.goodsCd, "goodsNm" : item.goodsNm, "listPrice" : item.listPrice, "currPrice" : item.currPrice});
+		});
+		uifnPopupClose('popupGoods');
+		return false;
+	};
+
+	// 저장 클릭 시
+	$('#btnSaveGoodsPriceRsvt').on('click', function() {
+
+		var allRowData = gagaAgGrid.getAllRowData(rsvtGoodsPriceGridOptions);
+
+		if(allRowData.length == 0){
+			mcxDialog.alertC("상품을 조회한 후 추가해주세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+				}
+			});
+			return;
+		}
+
+		if(gagajf.isNull($("#goodsPriceRsvtForm input[name=resGoodsPrice]").val())) {
+			mcxDialog.alertC("상품 예약가격을 입력하세요.",{
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsPriceRsvtForm input[name=resGoodsPrice]").focus();
+				}
+			});
+			return false;
+		}
+
+		var fromDate = $('#goodsPriceRsvtForm input[name=applyStYMD]').val();
+		var toDate = $('#goodsPriceRsvtForm input[name=applyEdYMD]').val();
+
+		if (gagajf.isNull(fromDate)) {
+			mcxDialog.alertC("예약 시작일자를 입력하세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsPriceRsvtForm input[name=applyStYMD]').focus();
+				}
+			});
+			return false;
+		}
+
+		if (gagajf.isNull(toDate)) {
+			mcxDialog.alertC("예약  종료일자를 입력하세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsPriceRsvtForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		}
+
+		if (fromDate > toDate) {
+			mcxDialog.alertC("예약 시작일자는 종료일자 보다 클 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsPriceRsvtForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		}
+		
+		var optCheck = false;
+		$.each(allRowData, function(index, item) {
+			if (item.listPrice < $("#goodsPriceRsvtForm input[name=resGoodsPrice]").val()){
+				optCheck = true;
+				mcxDialog.alertC("가격예약 상품중 정상가보다 높은 상품이 존재합니다.<br/>확인해 주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						rsvtGoodsPriceGridOptions.api.setFocusedCell(index, "goodsCd", null);
+					}
+				});	
+				return false;
+			}
+		});
+
+		if (optCheck) return false;
+		
+		var applyStdt = $('#goodsPriceRsvtForm input[name=applyStYMD]').val().replaceAll("-","") ;
+		var applyEddt = $('#goodsPriceRsvtForm input[name=applyEdYMD]').val().replaceAll("-","");
+
+		
+
+		if ($('#goodsPriceRsvtForm input[name=applyStdt]').val() > $('#goodsPriceRsvtForm input[name=applyEddt]').val()) {
+			mcxDialog.alertC("예약 시작일자는 종료일자 보다 클 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsPriceRsvtForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		}
+
+		var toDateStr = new Date().format("YYYYMMDD");
+
+		if (toDateStr >= applyStdt){
+			mcxDialog.alertC("예약 시작일자는 현재일자 보다 작거나 같을 수 없습니다.",  {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsPriceRsvtForm input[name=applyStYMD]').focus();
+				}
+			});
+			return false;
+		}
+
+		if (toDateStr >= applyEddt){
+			mcxDialog.alertC("예약 종료일자는 현재일자 보다 작거나 같을 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsPriceRsvtForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		}
+
+		mcxDialog.confirm('저장하시겠습니까?',  {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var arrGoodsCd = [];
+				var arrEndGoodsPrice = [];
+				allRowData.forEach(function(item, index) {
+					arrGoodsCd.push(item.goodsCd);
+					arrEndGoodsPrice.push(item.currPrice);
+				});
+				
+				$('#goodsPriceRsvtForm input[name=applyStdt]').val(applyStdt +"000000");
+				$('#goodsPriceRsvtForm input[name=applyEddt]').val(applyEddt +"235959");
+
+				var data = {resGoodsPrice : $('#goodsPriceRsvtForm input[name=resGoodsPrice]').val()
+							, applyStdt : $('#goodsPriceRsvtForm input[name=applyStdt]').val()
+							, applyEddt : $('#goodsPriceRsvtForm input[name=applyEddt]').val()
+							, arrGoodsCd : arrGoodsCd
+							, arrEndGoodsPrice : arrEndGoodsPrice
+				};
+
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/price/reserve/save', jsonData, fnGoodsPriceRsvtListFormClose);
+
+			}
+		});
+	});
+
+	// 조회상품 삭제
+	$('#btnDeleteGoodsPriceRsvt').on('click', function() {
+		var selectedData = rsvtGoodsPriceGridOptions.api.getSelectedRows();
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+
+		//화면에서 삭제
+		var removedData = gagaAgGrid.removeRowData(rsvtGoodsPriceGridOptions, false);
+	});
+	
+	//엑셀 상품 조회
+	$('#btnSearchExcel').on('click', function() {
+		cfnExcelUploadPopup('goodsPriceRsvtExcelUpload', 'goodsPriceRsvtExcelUpload');
+	});
+
+	var goodsPriceRsvtExcelUpload = function(result){
+		var data = {procJob : result.procJob
+			,excelFileNm : result.excelFileNm
+		};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, fnRsvtGoodsPriceExcelUploadCallBack);
+	}
+
+	var fnRsvtGoodsPriceExcelUploadCallBack = function(result){
+		gagajf.ajaxJsonSubmit('/goods/excel/upload/goods/list', '', fnExcelSearchCallBack);
+	}
+
+	var fnExcelSearchCallBack = function(result){
+		if (result.goodsExcelList.length < 1) return;
+		var oldData = gagaAgGrid.getAllRowData(rsvtGoodsPriceGridOptions);
+		$.each(result.goodsExcelList, function(idx, item) {
+			var isInvalid = false;
+			if (oldData != null && oldData.length != 0){
+				oldData.forEach(function(oneData){
+					if(oneData.goodsCd == item.goodsCd){
+						isInvalid = true;
+						return true;
+					}
+				});
+				if(isInvalid){
+					return isInvalid;
+				}
+			}
+			gagaAgGrid.addRowData(rsvtGoodsPriceGridOptions, {"goodsCd" : item.goodsCd, "goodsNm" : item.goodsNm, "listPrice" : item.listPrice, "currPrice" : item.currPrice});
+		});
+		return;
+	}
+
+	//창종료
+	var fnGoodsPriceRsvtListFormClose = function(){
+		uifnPopupClose('popupGoodsTitleReserve');
+		fnGoodsTnmResDeleteCollBack();
+	}
+
+	$(document).ready(function() {
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridGoodsPriceRsvtList', rsvtGoodsPriceGridOptions);
+	});
+
+/*]]>*/
+</script>
+</html>

+ 1 - 1
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsReserveSellForm.html

@@ -323,7 +323,7 @@
 	
 	//예약등록
 	$('#btnGoodsResSellSave').click(function(e) {
-		var actionUrl = "/goods/reserve/sell/regist/form";
+		var actionUrl = "/goods/reserve/sell/popup/form";
 		cfnOpenModalPopup(actionUrl, 'popupGoodsRsvtList');
 	});
 	

+ 344 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsSupplyPriceForm.html

@@ -0,0 +1,344 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsSupplyPriceForm.html
+ * @desc    : 입점 상품 가격 승인  관리
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.18   eskim       최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<form id="goodsPriceHstForm" name="goodsPriceHstForm" action="#" th:action="@{'/goods/price/hst/list'}">
+		<input type="hidden" id="confirmY" name="confirmY">
+ 		<!-- 패널 영역1 -->
+		<div class="panelStyle" >
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col width="10%"/>
+						<col width="40%"/>
+						<col width="10%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드</th>
+						<td>
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" th:if="${sessionInfo.roleCd} != 'A101'">[전체]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="brandCd" id="brandCd">
+								<option value="">[전체]</option>
+							</select>
+						</td>
+						<th>상품코드</th>
+						<td>
+							<input type="text" class="w150" name="goodsCd" id="goodsCd" maxlength="50"/>
+						</td>
+					</tr>
+					<tr>
+						<th>발생일</th>
+						<td colspan="3" id="sellTerms"></td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>&nbsp;&nbsp;&nbsp;&nbsp;
+						<button type="button" class="btn btn-base btn-lg" id="btnConfirmSearch" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">미승인목록 조회</button>
+					</li>
+				</ul>
+			</div>
+			<!-- //검색조건 영역 -->
+		</div>
+		<!-- 패널 영역1 -->
+		<div class="panelStyle">
+			<!-- 상단버튼 영역  -->
+			<ul class="panelBar">
+				<li class="right">
+					<button type="button" class="btn btn-success btn-lg" id="btnSaveGoodsPriceConfirm" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">승인</button>
+				</li>
+			</ul>
+			<!-- //상단버튼 영역  -->
+			<!-- 검색결과 영역 -->
+			<div id="gridList" style="width: 100%; height: 550px;" class="ag-theme-balham"></div>
+			<!-- 검색결과 영역 -->
+		</div>
+		</form>
+		<!-- //패널 영역2 -->
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var sessRoleCd = [[${sessionInfo.roleCd}]];
+	var goodsStatList = gagajf.convertToArray([[${goodsStatList}]]);
+	var formalGbList = gagajf.convertToArray([[${formalGbList}]]);
+	var columnDefs = [];
+	
+	columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "등록일", field: "regYmd", width: 90, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDD").format("YYYY-MM-DD") : '';
+			}
+		},
+		{headerName: "상품코드", field: "goodsCd", width: 130, cellClass: 'text-center'
+			,cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}
+		},
+		{headerName: "상품상태", field: "goodsStat" , width: 100, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(goodsStatList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(goodsStatList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(goodsStatList, params.newValue); }
+		},
+		{headerName: "온라인 판매가", field: "onPrice", width: 120, cellClass: 'text-right'
+			,valueFormatter: function(params) {return params.value.addComma();}
+		},
+		{headerName: "판매가조정대상금액", field: "gapPrice", width: 140, cellClass: 'text-right'
+			,cellRenderer: function(params) {
+				var gapPrice = Number(params.data.onPrice) - Number(params.data.erpPrice);
+				
+				if (gapPrice >= 0){
+					return '<font color="red"> '+ gapPrice.addComma() +'</font>';
+				}else{
+					return '<font color="blue"> '+ gapPrice.addComma() +'</font>';
+				}
+			}
+		},
+		{headerName: "온라인 판매수수료", field: "onTagPrice", width: 140, cellClass: 'text-right'
+			,valueFormatter: function(params) {return params.value.addComma();}
+		},
+		{headerName: "판매수수료 조정대상수수료", field: "gapTagPrice", width: 180, cellClass: 'text-right'
+			,cellRenderer: function(params) {
+				var gapTagPrice = Number(params.data.onTagPrice) - Number(params.data.erpTagPrice);
+				
+				if (gapTagPrice >= 0){
+					return '<font color="red"> '+ gapTagPrice.addComma() +'</font>';
+				}else{
+					return '<font color="blue"> '+ gapTagPrice.addComma() +'</font>';
+				}
+			}
+		},
+		{headerName: "승인자", field: "applyId", width: 130, cellClass: 'text-center'},
+		{headerName: "승인일자", field: "applyDt" , width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록일시", field: "regDt", width: 180, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록자", field: "regId" , width: 100, cellClass: 'text-center'}
+		
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	gridOptions.rowSelection = 'multiple';
+ 	gridOptions.suppressRowClickSelection = true;
+	//gridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+	
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var goodsCd = event.data.goodsCd;
+		if (event.colDef.field == "goodsCd"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}
+	}
+	
+	gridOptions.excelStyles = [
+			{
+				id: 'text-center',
+				dataType: 'string',
+				font: {size : 10, bold: false}
+			},
+			{
+				id: 'text-left',
+				dataType: 'string',
+				font: {size : 10, bold: false}
+			},
+			{
+				id: 'text-right',
+				font: {size : 10, bold: false}
+			}
+		]
+		
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		fnInit();
+	});
+	
+	var fnInit = function(){
+		$('#goodsPriceHstForm')[0].reset();
+		//$("#goodsPriceHstForm input[type=radio]").removeClass("checked");
+		$("#goodsPriceHstForm input[type=checkbox]").removeClass("checked");
+		//$("#goodsPriceHstForm input[type=radio]").parent("label").removeClass("checked");
+		$("#goodsPriceHstForm input[type=checkbox]").parent("label").removeClass("checked");
+		$("#goodsPriceHstForm input[type=radio][checked]").parent("label").addClass("checked");
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		fnGoodsPriceHstListSearch('N');
+	});
+
+	// 미승인목록 조회클릭시
+	$('#btnConfirmSearch').on('click', function() {
+		fnGoodsPriceHstListSearch('Y');
+	});
+	
+	// 조회
+	var fnGoodsPriceHstListSearch = function(confirmY) {
+		
+		$("#goodsPriceHstForm input[name=confirmY]").val(confirmY);
+		
+		if(!fnConditionCheck()) return;
+		
+		var formId = "#goodsPriceHstForm";
+		gagaAgGrid.fetch($(formId).prop('action'), gridOptions, formId);
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#goodsPriceHstForm';
+		var form = document.goodsPriceHstForm;
+
+		if ($("#goodsPriceHstForm input[name=confirmY]").val() == "Y") return true;
+		
+		var searchFlag = false;
+		var cnt = 0;
+
+		/* if( !gagajf.isNull($("#goodsPriceHstForm select[name=supplyCompCd]").val())
+				|| !gagajf.isNull($("#goodsPriceHstForm input[name=condition]").val())
+				|| (!gagajf.isNull($("#goodsPriceHstForm input[name=stDate]").val()) && !gagajf.isNull($("#goodsPriceHstForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{ */
+			for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+				
+				if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "dateGbn")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+			
+			if(cnt > 0) searchFlag = true;
+			
+		/* } */
+		
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		return true;
+	}
+	
+	//업체변경시
+	$('#goodsPriceHstForm select[name=supplyCompCd]').on('change', function() {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
+
+		if(sessRoleCd == "G001_A1001"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		$("#goodsPriceHstForm select[name=brandCd] option:gt(0)").remove();
+
+		cfnCreateCombo(actionUrl, $('#goodsPriceHstForm select[name=brandCd]'), "[전체]", "");
+		
+	});
+	
+	//브랜드 변경시
+	$('#goodsPriceHstForm select[name=brandCd]').on('change', function() {
+		
+		var supplyCompCd = $('#goodsPriceHstForm select[name=supplyCompCd]').val();
+		var brandCd = $('#goodsPriceHstForm select[name=brandCd]').val();
+		$("#goodsPriceHstForm select[name=sellStoreCd] option:gt(0)").remove();
+		if (!gagajf.isNull(brandCd)){
+			var url = "/renderer/extmall/sellstore/list/"+supplyCompCd+"/"+brandCd+"/";
+			cfnCreateCombo(url, $('#goodsPriceHstForm select[name=sellStoreCd]'), "[전체]", "");	
+		}
+		
+	});
+	
+	// 승인 클릭 시
+	$('#btnSaveGoodsPriceConfirm').on('click', function() {
+		
+		if ($("#goodsPriceHstForm input[name=confirmY]").val() != "Y"){
+			mcxDialog.alert("미승인목록 조회후 승인하세요.");
+			return false;
+		}
+		
+		var selectedData = gagaAgGrid.selectedRowData(gridOptions);
+		
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+
+		mcxDialog.confirm('승인 하시겠습니까?',{
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var jsonData = JSON.stringify(selectedData);
+				gagajf.ajaxJsonSubmit('/goods/price/hst/save', jsonData, fnSaveGoodsPriceConfirmCollBack); 
+			}
+		});
+	});	
+	
+	var fnSaveGoodsPriceConfirmCollBack = function(){
+		fnGoodsPriceHstListSearch('Y');
+	}
+	
+	$(document).ready(function() {
+		
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', 'X');
+
+		var selectCode = '<select  name="dateGbn" id="dateGbn">';
+		selectCode += '<option value="R" seledted>가격변경일</option>';
+		selectCode += '<option value="P">승인일자</option>';
+		selectCode += '</select>';
+		
+		$("#goodsPriceHstForm").find('#sellTerms').prepend(selectCode);
+		
+		
+		if(sessRoleCd == "G001_A101") {
+			$("#goodsPriceHstForm select[name=supplyCompCd]").val([[${sessionInfo.supplyCompCd}]]);
+			$("#goodsPriceHstForm select[name=supplyCompCd]").attr("disabled", true);
+			$("select[disabled]").addClass("formControl");
+			var actionUrl = '/renderer/brand/AuthBrandlist';
+			cfnCreateCombo(actionUrl, $('#goodsPriceHstForm select[name=brandCd]'), "[전체]");
+		}
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+ 	</div>
+
+</html>

+ 2 - 2
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsTitleReserveForm.html

@@ -66,11 +66,11 @@
 					<tr>
 						<th>상품명</th>
 						<td>
-							<input type="text" class="w200" name="goodsTnm11" id="goodsTnm111" maxlength="50"/>
+							<input type="text" class="w200" name="goodsnm" id="goodsnm" maxlength="50"/>
 						</td>
 						<th>예약타이틀</th>
 						<td>
-							<input type="text" class="w200" name="goodsTnm" id="goodsTnm" maxlength="50"/>
+							<input type="text" class="w200" name="goodsTnmRes" id="goodsTnmRes" maxlength="50"/>
 						</td>
 						<th>시즌/년도</th>
 						<td>

+ 327 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsVideoForm.html

@@ -0,0 +1,327 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsVideoForm.html
+ * @desc    : 상품동영상관리 Page
+ *============================================================================
+ * Pastelmall
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.16   eskim       최초 작성
+  *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<!-- TITLE -->
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<!-- //TITLE -->
+			<div class="panelContent">
+			
+			<form id="searchForm" name="searchForm" action="#" th:action="@{'/goods/video/list'}">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:40%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>키워드</th>
+						<td>
+							<select name="keyWord">
+								<option value="goodsCd">상품코드</option>
+								<option value="goodsNm">상품명</option>
+								<option value="goodsNum">품번</option>
+								<option value="supplyGoodsCd">업체상품코드</option>
+							</select>
+							<input type="text" class="w100" maxlength="20" name="searchTxt" placeholder=""/>
+							<input type="text" class="off" name="goodsCd" id="goodsCd"/>
+							<input type="text" class="off" name="goodsNm" id="goodsNm"/>
+							<input type="text" class="off" name="goodsNum" id="goodsNum"/>
+							<input type="text" class="off" name="supplyGoodsCd" id="supplyGoodsCd"/>
+						</td>
+						<th>브랜드명</th>
+						<td>
+							<input type="text" class="w200" name="brandEnm" placeholder="" maxlength="50"/>
+						</td>
+					</tr>
+					<tr>
+						<th>등록일</th>
+						<td colspan="3" id="sellTerms">
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-default btn-lg" id="btnInit">초기화</button>
+						<button type="button" class="btn btn-success btn-lg" id="btnSearch">조회</button>
+					</li>
+				</ul>
+			</form>
+			</div>
+		</div>
+		<!-- //검색조건 영역 -->
+		
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<ul class="panelBar">
+				<li class="left">
+					<button type="button" class="btn btn-danger btn-lg" id="btnNotUse">노출안함</button>
+				</li>
+				<li  class="right">
+					<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF002');">상품동영상등록 양식다운로드</button>
+					<button type="button" class="btn btn-info btn-lg" id="btnExcReg">엑셀등록</button>
+				</li>
+			</ul>
+			<div id="gridList" style="width: 100%; height: 450px;" class="ag-theme-balham"></div>
+		</div>
+		<!-- //리스트 영역 -->
+		<!-- 등록/수정 -->
+		<div class="panelStyle">
+			<form id="detailForm" name="detailForm" action="#" th:action="@{'/display/brand/save'}">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<td colspan='6'>동영상등록(상세)</td>
+					</tr>
+					<tr>
+						<th>상품코드<em class="required" title="필수"></em></th>
+						<td>
+							<input name="videoSq"  data-valid-name="상품동영상일련번호" type="hidden"/>
+							<input type="text" class="w150" name="goodsCd" maxlength="20" required="required" data-valid-name="상품코드"/>
+						</td>
+						<th>동영상구분<em class="required" title="필수"></em></th>
+						<td>
+							<select name="videoGb" id="videoGb" required="required" data-valid-name="동영상구분" onchange="">
+								<option value="">[선택]</option>
+								<option value="Y">[Y] 유투브</option>
+								<option value="M">[M] MP4</option>
+							</select>
+						</td>
+						<th>노출여부<em class="required" title="필수"></em></th>
+						<td>
+							<label class="rdoBtn"><input type="radio" name="dispYn" id="dispYn" value="Y" checked="checked">Y</label>
+							<label class="rdoBtn"><input type="radio" name="dispYn" id="dispYn" value="N">N</label>
+						</td>
+					</tr>
+					<tr>
+						<th>동영상URL<em class="required" title="필수"></em></th>
+						<td class="infoTxt" colspan="5">
+							<em><i class="fa fa-info-circle"></i>유투브의 경우 빨간색 표시로 되어있는 값만 넣으세요.</em><br/>
+							예시 : https://www.youtube.com/embed/<em><strong>5YqYG71bQ3s</strong></em>?showinfo=0&amp;rel=0&amp;vp=hd1080&amp;fs=0&amp;wmode=opaque&amp;enablejsapi=1
+							<br/>
+							<input type="text" class="w400" id="videoVal" name="videoVal" maxlength="100" required="required" data-valid-name="동영상URL">
+							<button type="button" class="btn btn-dark btn-lg" onclick="cfnOpenGoodsVideoPopup('filmVideoView','videoVal', '#detailForm', $('#videoGb').val());">미리보기</button>
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-info btn-lg" id="btnNew">신규</button>
+						<button type="button" class="btn btn-success btn-lg" id="btnSave">저장</button>
+					</li>
+				</ul>
+			</form>
+		</div>
+	</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var videoGbList = {'Y':'유투브', 'M':'MP4'};
+	// specify the columns
+	var columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "브랜드명", field: "brandEnm", width: 120, cellClass: 'text-center'},
+		{headerName: "상품동영상일련번호", field: "goodsVideoSq", width: 120, cellClass: 'text-center', hide: true},
+		{headerName: "상품코드", field: "goodsCd", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}	
+		},
+ 		{headerName: "동영상구분", field: "videoGb", width: 100, cellClass: 'text-center',
+			cellRenderer: function (params) { return !gagajf.isNull(params.value) ? "["+params.value+"] "+gagaAgGrid.lookupValue(videoGbList, params.value) : '';}
+		},
+		{headerName: "동영상정보", field: "videoVal", width: 300, cellClass: 'text-center'},
+		{headerName: "노출여부", field: "dispYn", width: 80, cellClass: 'text-center'},
+		{headerName: "등록일자", field: "regDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록자", field: "regNo", width: 150, cellClass: 'text-center'},
+		{headerName: "수정일자", field: "updDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "수정자", field: "updNo", width: 150, cellClass: 'text-center'},
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+	
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+	
+	// 상품코드 셀 클릭
+	gridOptions.onCellClicked = function(event) {
+		if (event.colDef.field == "goodsCd"){
+			var formId = '#detailForm';
+			$(formId + " input[name=videoSq]").val(event.data.videoSq);
+			$(formId + " input[name=goodsCd]").val(event.data.goodsCd);
+			$(formId + " select[name=videoGb]").val(event.data.videoGb);
+			$(formId + " input[name=videoVal]").val(event.data.videoVal);
+			$(formId + " input:radio[name=dispYn]:input[value="+event.data.dispYn+"]").click();
+			$(formId + " input[name=goodsCd]").prop("disabled", true);
+			$(formId).closest("div").show();
+		}
+	}
+	
+	// 신규 버튼 클릭
+	$("#btnNew").on('click', function() {
+		$("#detailForm")[0].reset();
+		$("#detailForm input[name=videoSq]").val('');
+		$("#detailForm input[name=goodsCd]").prop("disabled", false);
+	});
+
+	// 엑셀등록
+	$("#btnExcReg").on('click', function() {
+		cfnExcelUploadPopup('','fnExcelUpoadCallback');
+	});
+	
+	var fnExcelUpoadCallback = function(data){
+		
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/video/excel/save', jsonData, fnSaveCallback);
+		
+	}
+	
+	// 조회
+	$('#btnSearch').on('click', function() {
+		$("#goodsCd").val('');
+		$("#goodsNm").val('');
+		$("#goodsNum").val('');
+		$("#supplyGoodsCd").val('');
+		$("#"+$("#searchForm select[name=keyWord]").val()).val($("#searchForm input[name=searchTxt]").val());
+		// 기간 값 체크
+		if (!fnCalendarDateValidation('#sellTerms', 'stDate', 'edDate')){
+			return false;
+		}
+		// Fetch data
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+		$("#btnNew").click();
+	});
+	
+	// 검색조건 초기화
+	$('#btnInit').on('click', function() {
+		$("#searchForm")[0].reset();
+	});
+	
+	// 선택상품 사용안함
+	$("#btnNotUse").on('click', function() {
+		var selectRowData = gagaAgGrid.selectedRowData(gridOptions);
+		if(selectRowData.length>0){
+			mcxDialog.confirm('선택한 상품동영상을 미노출처리 하시겠습니까?', {
+				cancelBtnText: "취소",
+				sureBtnText: "확인",
+				sureBtnClick: function(){
+					var jsonData = JSON.stringify(selectRowData);
+					gagajf.ajaxJsonSubmit('/goods/video/update/notUse', jsonData, fnSaveCallback);
+				}
+			})
+		}else{
+			mcxDialog.alert("선택된 상품동영상이 없습니다.");
+		}
+	});
+	
+	// 동영상 저장
+	$("#btnSave").on('click', function() {
+		
+		var formId = '#detailForm';
+		var videoSq = $(formId + " input[name=videoSq]").val();
+		var displocVal = $(formId + " input[name=goodsCd]").val();
+		var videoGb = $(formId + " select[name=videoGb]").val();
+		var videoVal = $(formId + " input[name=videoVal]").val();
+		var dispYn = $(formId + " input:radio[name=dispYn]:checked").val();
+		
+		if(displocVal==''){
+			gagajf.alertMessage(formId + " input[name=goodsCd]", 'input');
+			return;
+		}
+		if(videoGb==''){
+			gagajf.alertMessage(formId + " select[name=videoGb]", 'select');
+			return;
+		}
+		if(videoVal==''){
+			gagajf.alertMessage(formId + " input[name=videoVal]", 'input');
+			return;
+		}
+		
+		if(videoVal.indexOf("http")>-1){
+			if(videoGb=='Y'){
+				mcxDialog.alert('동영상URL 형식이 유투브와 맞지 않습니다.');
+				return;
+			}
+		}else{
+			if(videoGb=='M'){
+				mcxDialog.alert('동영상URL 형식이 MP4와 맞지 않습니다.');
+				return;
+			}
+		}
+		
+		mcxDialog.confirm('저장 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {videoSq : videoSq
+							,displocGb : 'G'
+							,displocValArr : [displocVal]
+							,videoGb : videoGb
+							,videoVal : videoVal
+							,dispYn : dispYn
+							};
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/video/save', jsonData, fnSaveCallback);
+			}
+		})
+	});
+	
+	var fnSaveCallback = function() {
+		$('#btnSearch').click();
+	}
+	
+	$(document).ready(function() {
+		
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', true);
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+		
+		//$('#btnSearch').click();
+	});
+/*]]>*/
+</script>
+
+</html>

+ 300 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsWmsInstockForm.html

@@ -0,0 +1,300 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsWmsInstockForm.html
+ * @desc    : WMS입고상품관리 화면
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.18   eskim       최초 작성
+ *******************************************************************************
+ -->	
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<form id="goodsUnregisterListForm" name="goodsUnregisterListForm" action="#" th:action="@{'/goods/unregister/list'}">
+		<input type="hidden" id="searchGb" name="searchGb" />
+		<input type="hidden" id="dateGbn" name="dateGbn" value="R" />
+ 		<!-- 패널 영역1 -->
+		<div class="panelStyle" >
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col width="10%"/>
+						<col width="40%"/>
+						<col width="10%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드<i class="star"></i></th>
+						<td>
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" th:if="${sessionInfo.roleCd} != 'B000'">[전체]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="brandCd" id="brandCd">
+								<option value="">[전체]</option>
+							</select>
+						</td>
+						<th>상품코드<i class="star"></i></th>
+						<td>
+							<input id="goodsCd" name=goodsCd type="text" class="w150"  maxlength="20"/>
+						</td>
+					</tr>
+					<tr>
+						<th>등록일<i class="star"></i></th>
+						<td colspan="3" id="sellTerms"></td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
+					</li>
+				</ul>
+			</div>
+			<!-- //검색조건 영역 -->
+		</div>
+		<!-- 패널 영역1 -->
+		<div class="panelStyle">
+			<!-- 검색결과 영역 -->
+			<div id="gridList" style="width: 100%; height: 500px;" class="ag-theme-balham"></div>
+			<ul class="panelBar">
+				<li class="center">
+					<div class="tablePaging" id="goodsListPagination"></div>
+				</li>
+			</ul>
+			<!-- 검색결과 영역 -->
+		</div>
+		</form>
+		<!-- //패널 영역2 -->
+	</div>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var sessRoleCd = [[${sessionInfo.roleCd}]];
+	var goodsStatList = gagajf.convertToArray([[${goodsStatList}]]);
+	var itemkindList = gagajf.convertToArray([[${itemkindList}]]);
+	var columnDefs = [
+		/* {width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false}, */
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "브랜드", field: "brandCd", width: 100, cellClass: 'text-center'},
+		{headerName: "브랜드명", field: "brandEnm", width: 130, cellClass: 'text-center'},
+		{headerName: "상품코드", field: "goodsCd", width: 120, cellClass: 'text-center'},
+		{headerName: "ERP상품명", field: "erpGoodsNm", width: 200, cellClass: 'text-left'},
+		{headerName: "상품명", field: "goodsNm", width: 200, cellClass: 'text-left'},
+		//{headerName: "품목코드", field: "itemkindCd", width: 100, cellClass: 'text-center'},
+		{headerName: "품목명", field: "itemkindCd" , width: 200, cellClass: 'text-left',
+			cellEditorParams: { values: gagaAgGrid.extractValues(itemkindList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(itemkindList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(itemkindList, params.newValue); }
+		},
+		{headerName: "등록일시", field: "regDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록자", field: "regId", width: 100, cellClass: 'text-center'},
+		{headerName: "수정일시", field: "updDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "수정자", field: "updId", width: 100, cellClass: 'text-center'}
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	//gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+	//gridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		fnInit();
+	});
+	
+	var fnInit = function(){
+		$('#goodsUnregisterListForm')[0].reset();
+		//$("#goodsUnregisterListForm input[type=radio]").removeClass("checked");
+		$("#goodsUnregisterListForm input[type=checkbox]").removeClass("checked");
+		//$("#goodsUnregisterListForm input[type=radio]").parent("label").removeClass("checked");
+		$("#goodsUnregisterListForm input[type=checkbox]").parent("label").removeClass("checked");
+		$("#goodsUnregisterListForm input[type=radio][checked]").parent("label").addClass("checked");
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		fnGoodsUnregisterListSearch('BASIC');
+	});
+
+	// 조회
+	var fnGoodsUnregisterListSearch = function(gbn) {
+
+		if (typeof(gbn) != 'undefined' &&  gbn == 'EXCEL'){
+			$("#goodsUnregisterListForm input[name=searchGb]").val("EXCEL");
+		}else if (typeof(gbn) != 'undefined' &&  gbn == 'EXCELRESULT'){
+			$("#goodsUnregisterListForm input[name=searchGb]").val("EXCELRESULT");
+		}else{
+			$("#goodsUnregisterListForm input[name=searchGb]").val("BASIC");
+		}
+		
+		if(!fnConditionCheck()) return;
+		
+		gagaAgGrid.fetch($('#goodsUnregisterListForm').prop('action'), gridOptions, '#goodsUnregisterListForm');
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#goodsUnregisterListForm';
+		var form = document.goodsUnregisterListForm;
+
+		if($("#goodsUnregisterListForm input[name=searchGb]").val() == "EXCEL" || $("#goodsUnregisterListForm input[name=searchGb]").val() == "EXCELRESULT") {
+			return true;
+		}
+		
+		var searchFlag = false;
+		var cnt = 0;
+
+		/* if( !gagajf.isNull($("#goodsUnregisterListForm select[name=supplyCompCd]").val())
+				|| !gagajf.isNull($("#goodsUnregisterListForm input[name=condition]").val())
+				|| (!gagajf.isNull($("#goodsUnregisterListForm input[name=stDate]").val()) && !gagajf.isNull($("#goodsUnregisterListForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{ */
+			for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+				
+				if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+			
+			if(cnt > 0) searchFlag = true;
+			
+		/* } */
+		
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		
+		var fromDate = $('#goodsUnregisterListForm input[name=stDate]').val();
+		var toDate = $('#goodsUnregisterListForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsUnregisterListForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alert("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsUnregisterListForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		}
+
+		return true;
+	}
+	
+	//업체변경시
+	$('#goodsUnregisterListForm select[name=supplyCompCd]').on('change', function() {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
+
+		if(sessRoleCd == "B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		$("#goodsUnregisterListForm select[name=brandCd] option:gt(0)").remove();
+
+		cfnCreateCombo(actionUrl, $('#goodsUnregisterListForm select[name=brandCd]'), "[전체]", "");
+	});
+	
+	//엑셀 다운로드 클릭시
+	$('#btnGoodsUnregisterExcelDownLoad').on('click', function() {
+		//gagaAgGrid.exportToExcel('온라인미등록상품', gridOptions);
+		var date = new Date().format("YYYYMMDDHHmmss");
+		var params = {
+			
+			fileName : "온라인미등록상품_"+ date,
+			sheetName: "DATA"
+		}
+		gridOptions.excelStyles = [
+			{
+				id: 'text-center',
+				dataType: 'string',
+				font: {size : 10, bold: false}
+			},
+			{
+				id: 'text-left',
+				dataType: 'string',
+				font: {size : 10, bold: false}
+			}
+		]
+		
+		gridOptions.api.exportDataAsExcel(params);
+	});
+	
+	//엑셀 상품명/품목코드 저장
+	$('#btnGoodsExcelSave').on('click', function() {
+		cfnExcelUploadPopup('goodsInfoExcelUpload', 'goodsInfoExcelSave');
+	});
+	
+	var goodsInfoExcelSave = function(result){
+		mcxDialog.confirm('상품명/품목코드 저장을 진행하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {procJob : result.procJob
+						,excelFileNm : result.excelFileNm
+						};
+			var jsonData = JSON.stringify(data);
+			gagajf.ajaxJsonSubmit('/goods/unregister/excelupload/save', jsonData, fnGoodsInfoExcelSaveCallBack);
+			}
+		});	
+	}
+	
+	var fnGoodsInfoExcelSaveCallBack = function(result){
+		fnGoodsUnregisterListSearch("EXCELRESULT");
+	}
+	
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일');
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+ 	
+</html>

+ 545 - 0
style24.admin/src/main/webapp/WEB-INF/views/stock/GoodsSizeStockForm.html

@@ -0,0 +1,545 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsSizeStockForm.html
+ * @desc    : 상품 사이즈별 재고 현황
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.17   eskim       수정
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<form id="goodsSizeStockForm" name="goodsSizeStockForm" action="#" th:action="@{'/stock/sizeStock/list'}">
+		<input type="hidden" id="searchGb" name="searchGb" />
+ 		<!-- 패널 영역1 -->
+		<div class="panelStyle" >
+			<!-- TITLE -->
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 <font color="red">업체, 키워드</font>중 하나를 꼭 입력해 주세요.</h3>
+				<span class="panelControl">
+					<i class="fa fa-chevron-up"></i>
+				</span>
+			</div>
+			<!-- //TITLE -->
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col width="9%"/>
+						<col width="16%"/>
+						<col width="9%"/>
+						<col width="16%"/>
+						<col width="9%"/>
+						<col width="16%"/>
+						<col width="9%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드<em class="required" title="필수"></em></th>
+						<td colspan="3">
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" th:if="${sessionInfo.roleCd} != 'G001_B000'">[전체]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="brandCd" id="brandCd">
+								<option value="">[전체]</option>
+							</select>
+						</td>
+						<th>품목</th>
+						<td colspan="3">
+							<select name="itemkindCd" id="itemkindCd">
+								<option value="">[전체]</option>
+								<option th:if="${itemkindList}" th:each="oneData, status : ${itemkindList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>키워드<em class="required" title="필수"></em></th>
+						<td colspan="3">
+							<select name="search" id="search">
+								<option value="searchGoodsCd">상품코드</option>
+								<option value="searchGoodsNm">상품명</option>
+								<option value="searchGoodsNum">품번</option>
+								<option value="searchSupplyGoodsCd">업체상품코드</option>
+								<option value="searchRegId">등록자</option>
+							</select>
+							<input type="text" class="w150" name="condition" id="condition" maxlength="50"/>
+						</td>
+						<th>상품상태</th>
+						<td>
+							<select  name="goodsStat" id="goodsStat">
+								<option value="">[전체]</option>
+								<option th:if="${goodsStatList}" th:each="oneData, status : ${goodsStatList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>정상/이월 구분</th>
+						<td>
+							<select  name="formalGb" id="formalGb">
+								<option value="">[전체]</option>
+								<option th:if="${formalGbList}" th:each="oneData, status : ${formalGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>	
+						<th>년도/시즌</th>
+						<td colspan="3">
+							<select  name="styleYear" id="styleYear">
+								<option value="">[전체]</option>
+								<option th:if="${styleYearList}" th:each="oneData, status : ${styleYearList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select  name="seasonCd" id="seasonCd">
+								<option value="">[전체]</option>
+								<option th:if="${seasonList}" th:each="oneData, status : ${seasonList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>색상</th>
+						<td>
+							<select name="colorCd" id="colorCd">
+								<option value="">[전체]</option>
+								<option th:if="${colorList}" th:each="oneData, status : ${colorList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>사이즈</th>
+						<td>
+							<input type="text" class="w80" name="optCd2" id="optCd2" maxlength="50"/>
+						</td>
+						
+					</tr>
+					<tr>
+						<th>품절여부</th>
+						<td>
+							<select  name="soldOutYn" id="soldOutYn">
+								<option value="">[전체]</option>
+								<option th:if="${useYnList}" th:each="oneData, status : ${useYnList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>담당MD</th>
+						<td>
+							<select  name="mdNo" id="mdNo">
+								<option value="">[전체]</option>
+								<option th:if="${brandMdList}" th:each="oneData, status : ${brandMdList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>재고수량</th>
+						<td colspan="3">
+							<input type="text" class="w70" name="stockQtySt" id="stockQtySt" maxlength="5" data-valid-type="numeric"/> ~ <input type="text" class="w70" name="stockQtyEd" id="stockQtyEd" maxlength="5" data-valid-type="numeric"/>
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
+					</li>
+				</ul>
+
+			</div>
+			<!-- //검색조건 영역 -->
+		</div>
+		<!-- 패널 영역1 -->
+		<div class="panelStyle">
+			<!-- 검색결과 영역 -->
+			<!-- 상단버튼 영역  -->
+			<ul class="panelBar">
+				<li class="left">
+					<select id="excelSample" name="excelSample">
+						<option value="">[선택]</option>
+						<option value="SF003">상품엑셀조회양식</option>
+						<option value="SF008" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">상품사이즈품절/안전재고양식</option>
+						<option value="EXCELDOWN">엑셀다운로드</option>
+					</select>
+					<button type="button" class="btn btn-default btn-lg" id="btnExcelSampleDownLoad">다운로드</button>
+					<button type="button" class="btn btn-base btn-lg" id="btnGoodsExcelSearch">엑셀조회</button>
+					<button type="button" class="btn btn-success btn-lg" id="btnGoodsExcelSave" th:if="${sessionInfo.roleCd == 'G001_0000' OR sessionInfo.roleCd == 'G001_A000' OR sessionInfo.roleCd == 'G001_A101' OR sessionInfo.roleCd == 'G001_A100' OR sessionInfo.roleCd == 'G001_A001'}">품절/안전재고 저장</button>
+					<!-- 아이콘 툴팁 -->
+					&nbsp;<div class="iconTooltip">
+						<i class="fa fa-info" aria-hidden="true"></i>
+						<span class="left" style="width:300px;">
+						<!-- class="left" 또는 class="right" -->
+							* 매체별판매가능재고 = WMS가용재고 - 안전재고 - 출고대기
+						</span>
+					</div>
+					<!-- //아이콘 툴팁 -->
+				</li>
+				<li class="right">
+					검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+					쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+					<select id="pageSize" name="pageSize">
+						<option value="100" selected="selected">100개씩 보기</option>
+						<option value="500">500개씩 보기</option>
+						<option value="1000">1000개씩 보기</option>
+						<option value="5000">5000개씩 보기</option>
+					</select>
+					<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+				</li>
+			</ul>
+			<!-- //상단버튼 영역  -->
+			<div id="gridList" style="width: 100%; height:550px" class="ag-theme-balham"></div>
+			<ul class="panelBar">
+				<li class="center">
+					<div class="tablePaging" id="goodsListPagination"></div>
+				</li>
+			</ul>
+			<!-- 검색결과 영역 -->
+		</div>
+		<label class="off">
+			<a href="javascript:void(0);" id="GoodsSizeStockExcelList" style="display: none;">사이즈별 재고현황 엑셀다운로드</a>
+		</label>
+		</form>
+		<!-- //패널 영역2 -->
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var sessRoleCd = [[${sessionInfo.roleCd}]];
+	var goodsStatList = gagajf.convertToArray([[${goodsStatList}]]);
+	var formalGbList = gagajf.convertToArray([[${formalGbList}]]);
+	var siteList = gagajf.convertToArray([[${siteList}]]);
+	var columnDefs = [];
+	
+	columnDefs = [
+		//{width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: 'No', width: 60, cellClass: 'text-center',
+			valueGetter: function(params) { return cfnGridNumner('goodsSizeStockForm',params.node.rowIndex, 'A');}
+		},
+		{headerName: "브랜드명", field: "brandEnm", width: 130, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 200, cellClass: 'text-left',
+			cellRenderer: function(params) {
+				if (params.data.sizeSoldoutYn == "Y"){
+					return '<a href="javascript:void(0);" style="color:red">' + params.value + '</a>';
+				}else{
+					return '<a href="javascript:void(0);">' + params.value + '</a>';	
+				}
+			}	
+		},
+		{headerName: "품목", field: "itemkindNm", width: 180, cellClass: 'text-left'},
+		{headerName: "상품상태", field: "goodsStat" , width: 120, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(goodsStatList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(goodsStatList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(goodsStatList, params.newValue); }
+		},
+		{headerName: "상품코드", field: "goodsCd", width: 140, cellClass: 'text-center'},
+		{headerName: "색상", field: "optCd1", width: 100, cellClass: 'text-center'},
+		{headerName: "사이즈", field: "optCd2", width: 100, cellClass: 'text-center'},
+		{headerName: "품절여부", field: "soldoutYn", width: 100, cellClass: 'text-center',
+			cellStyle : function(params){
+				var color = "";
+				if (params.value == "Y"){
+					color = "red";
+				}
+				return { 'color': color}
+			} 
+		},
+		
+		{headerName: "재고", field: "currStockQty", width: 100, cellClass: 'text-right',
+			valueFormatter: function(params) {	return params.value.addComma();}
+		},
+		{headerName: "안전재고", field: "baseStockQty", width: 100, cellClass: 'text-right',
+			valueFormatter: function(params) {	return params.value.addComma();}
+		},
+		{headerName: "출고대기", field: "saleStockQty", width: 100, cellClass: 'text-right',
+			valueFormatter: function(params) {	return params.value.addComma();}
+		},
+		{headerName: "판매가능재고", field: "ableStockQty", width: 100, cellClass: 'text-right',
+			valueFormatter: function(params) {	return params.value.addComma();},
+			cellStyle : function(params){
+				var color = "";
+				if (params.value <= 0){
+					color = '#ff96689c';
+				}
+				return { 'background-color': color};
+			}
+		}
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+	//gridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var goodsCd = event.data.goodsCd;
+		if (event.colDef.field == "goodsNm"){
+			cfnOpenGoodsDetailPopup('U',goodsCd);
+		}else if (event.colDef.field == "goodsCd"){
+			
+			//cfnOpenFrontGoodsPopup(goodsCd, event.data.siteCd);
+		}
+	}
+
+	gridOptions.getRowStyle = function(params) {
+		if ("G008_00" == params.data.goodsStat  || "G008_10" == params.data.goodsStatG008_ || "20" == params.data.goodsStat || "G008_30" == params.data.goodsStat) {
+			return { background: '#23c6c8' };
+		}
+	}
+	
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+		fnInit();
+	});
+	
+	var fnInit = function(){
+		$("#goodsSizeStockForm input[name=siteCd]").prop("disabled", true);
+		$("#goodsSizeStockForm input[name=siteCd]").addClass("formControl");
+		
+		$('#goodsSizeStockForm')[0].reset();
+		//$("#goodsSizeStockForm input[type=radio]").removeClass("checked");
+		$("#goodsSizeStockForm input[type=checkbox]").removeClass("checked");
+		//$("#goodsSizeStockForm input[type=radio]").parent("label").removeClass("checked");
+		$("#goodsSizeStockForm input[type=checkbox]").parent("label").removeClass("checked");
+		$("#goodsSizeStockForm input[type=radio][checked]").parent("label").addClass("checked");
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		$("#goodsSizeStockForm input[name=pageNo]").val('1');
+		fnGoodsListSearch('BASIC');
+	});
+
+	// 조회
+	var fnGoodsListSearch = function(gbn) {
+		
+		if (typeof(gbn) != 'undefined' &&  gbn == 'EXCEL'){
+			$("#goodsSizeStockForm input[name=searchGb]").val("EXCEL");
+		}else if (typeof(gbn) != 'undefined' &&  gbn == 'EXCELRESULT'){
+			$("#goodsSizeStockForm input[name=searchGb]").val("EXCELRESULT");
+		}else{
+			$("#goodsSizeStockForm input[name=searchGb]").val("BASIC");
+		}
+		
+		if(!fnConditionCheck()) return;
+		
+		gagaPaging.init('goodsSizeStockForm', fnSearchCallBack, 'goodsListPagination', $('#goodsSizeStockForm').find('#pageSize').val());
+		gagaPaging.load($("#goodsSizeStockForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#goodsSizeStockForm';
+		var form = document.goodsSizeStockForm;
+
+		if($("#goodsSizeStockForm input[name=searchGb]").val() == "EXCEL" || $("#goodsSizeStockForm input[name=searchGb]").val() == "EXCELRESULT") {
+			return true;
+		}
+		
+		var searchFlag = false;
+		var cnt = 0;
+
+		/* if( !gagajf.isNull($("#goodsSizeStockForm select[name=supplyCompCd]").val())
+				|| !gagajf.isNull($("#goodsSizeStockForm input[name=condition]").val())
+				|| (!gagajf.isNull($("#goodsSizeStockForm input[name=stDate]").val()) && !gagajf.isNull($("#goodsSizeStockForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{ */
+			for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+				
+				if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize" && el.name != "excelSample")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+
+			if(cnt > 0) searchFlag = true;
+			
+		/* } */
+		
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		
+		/* if(!gagajf.isNull($("#goodsSizeStockForm input[name=currPriceSt]").val()) && !gagajf.isNull($("#goodsSizeStockForm input[name=currPriceEd]").val())){
+			if (Number($("#goodsSizeStockForm input[name=currPriceSt]").val().removeComma()) > Number($("#goodsSizeStockForm input[name=currPriceEd]").val().removeComma()) ){
+				mcxDialog.alertC("판매가를 확인해 주세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsSizeStockForm input[name=currPriceEd]").focus();
+					}
+				});
+				return false;
+			}
+		} */
+		
+		/* if(!gagajf.isNull($("#goodsSizeStockForm input[name=dcRateSt]").val()) && !gagajf.isNull($("#goodsSizeStockForm input[name=dcRateEd]").val())){
+			if (Number($("#goodsSizeStockForm input[name=dcRateSt]").val().removeComma()) > Number($("#goodsSizeStockForm input[name=dcRateEd]").val().removeComma()) ){
+				mcxDialog.alertC("할인율를 확인해 주세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsSizeStockForm input[name=dcRateEd]").focus();
+					}
+				});
+				return false;
+			}
+		} */
+		
+		/* var fromDate = $('#goodsSizeStockForm input[name=stDate]').val();
+		var toDate = $('#goodsSizeStockForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsSizeStockForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsSizeStockForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		} */
+
+		return true;
+	}
+	
+	var fnSearchCallBack = function(result){
+		$('#goodsSizeStockForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#goodsSizeStockForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#goodsSizeStockForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#goodsSizeStockForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.goodsSizeStockList);
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+	
+	//페이징 
+	$('#goodsSizeStockForm select[name=pageSize]').on('change', function() {
+		$("#goodsSizeStockForm input[name=pageNo]").val('1');
+		fnGoodsListSearch($("#goodsSizeStockForm input[name=searchGb]").val());
+	});
+
+	
+	//업체변경시
+	$('#goodsSizeStockForm select[name=supplyCompCd]').on('change', function() {
+		var supplyCompCd = $(this).val();
+		
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + supplyCompCd;
+
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		$("#goodsSizeStockForm select[name=brandCd] option:gt(0)").remove();
+
+		cfnCreateCombo(actionUrl, $('#goodsSizeStockForm select[name=brandCd]'), "[전체]", "");
+
+	});
+	
+	//엑셀양식 다운로드
+	$('#btnExcelSampleDownLoad').on('click', function (){
+		var gb = $("#goodsSizeStockForm select[name=excelSample]").val();
+		if (gagajf.isNull(gb)){
+			mcxDialog.alertC("다운로드 할 양식을 선택해주세요", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsSizeStockForm select[name=excelSample]').focus();
+				}
+			});
+			return false;
+		}
+		if ("EXCELDOWN" == gb){
+			fnGoodsExcelDownLoad('');
+		}else{
+			cfnDownloadSampleFile($("#goodsSizeStockForm select[name=excelSample]").val());	
+		}
+	});
+	
+	//엑셀다운로드
+	var fnGoodsExcelDownLoad = function(flag){
+		var formId = '#goodsSizeStockForm';
+		
+		if(!fnConditionCheck()) return;
+		
+		if (gridOptions.api.getDisplayedRowCount() <= 0){
+			mcxDialog.alert("조회된 데이터가 없습니다.<br/>다시 조회 후 다운로드 받으세요.");
+			return;
+		}
+		
+		var params =  $(formId).serialize();
+		$('#GoodsSizeStockExcelList').attr({ href : '/stock/sizeStock/excel/list?' + params }).get(0).click();
+	}
+	
+	//엑셀 상품 조회
+	$('#btnGoodsExcelSearch').on('click', function() {
+		cfnExcelUploadPopup('goodsSizeStockExcelUpload', 'goodsSizeStockExcelSearch');
+	});
+	
+	var goodsSizeStockExcelSearch = function(result){
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, fnGoodsSizeStockExcelSearchCallBack);
+	}
+	
+	var fnGoodsSizeStockExcelSearchCallBack = function(result){
+		fnGoodsListSearch("EXCEL");
+	}
+	
+	//엑셀 상품 사이즈별 품절 저장
+	$('#btnGoodsExcelSave').on('click', function() {
+		cfnExcelUploadPopup('goodsSizeStockExcelUpload', 'goodsSizeStockExcelSave');
+	});
+	
+	var goodsSizeStockExcelSave = function(result){
+		mcxDialog.confirm('품절/안전재고 변경을 진행하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {procJob : result.procJob
+						,excelFileNm : result.excelFileNm
+						};
+			var jsonData = JSON.stringify(data);
+			gagajf.ajaxJsonSubmit('/stock/sizeSoldout/excelupload/save', jsonData, fnGoodsSizeStockExcelSaveCallBack);
+			}
+		});	
+	}
+	
+	var fnGoodsSizeStockExcelSaveCallBack = function(result){
+		fnGoodsListSearch("EXCELRESULT");
+	}
+	
+	$(document).ready(function() {
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+		//$('.ag-header-group-cell').each(function(item){$(this).css('text-align', 'center')});
+		//$('.ag-header-group-cell-label').each(function(item){$(this).css('display', 'inline-block')});
+
+		// 입점 사용자 브랜드 조회 처리
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+			cfnCreateCombo(actionUrl, $('#goodsSizeStockForm select[name=brandCd]'), "[전체]", "");
+		}
+
+	});
+
+/*]]>*/
+</script>
+ 	</div>
+
+</html>

+ 18 - 1
style24.admin/src/main/webapp/ux/js/admin.common.js

@@ -931,4 +931,21 @@ function cfnGoogleLogin(googleUser) {
 function cfnCellPhonnHypen(obj) {
 	//$(obj).val( $(obj).val().replace(/[^0-9]/g, '').replace(/(^0[0-9]{2})([0-9]+)?([0-9]{4})/, '$1-$2-$3').replace('--', '-') );
 	$(obj).val( $(obj).val().replace(/[^0-9]/g, "").replace(/(^02|^050[0-9]{1}|^1[0-9]{3}|^0[0-9]{2})([0-9]+)?([0-9]{4})$/,"$1-$2-$3").replace("--", "-") );
-}
+}
+
+
+var fnCalendarDateValidation = function(tgtId, dtFromId, dtToId) {
+	var fromVal = Number($(tgtId+" #"+dtFromId).val().replace(/-/gi, ''));
+	var toVal = Number($(tgtId+" #"+dtToId).val().replace(/-/gi, ''));
+	var result = true;
+	if(fromVal > toVal) {
+		mcxDialog.alertC('시작일자가 종료일자보다 큽니다.',{
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				$(tgtId+" #"+dtFromId).focus();
+			}
+		});
+		result = false;
+	}
+	return result;
+};

+ 4 - 3
style24.admin/src/main/webapp/ux/js/admin.popup.js

@@ -178,16 +178,17 @@ var cfnOpenImagePreViewPopup = function(id,imgUrl) {
  */
 //비디오 팝업 열기
 var cfnOpenGoodsVideoPopup = function(id, objId, formid, type, fullUrl) {
+	
 	var src = $(formid).find("#"+objId).val();
-	var str = '<div class="popupWrap videoClose" id="'+id+'">';
-	str += '<div class="videoPopup modal" data-width="700" data-height="350">';
+	var str = '';
+	str += '<div class="videoPopup"  style="width:700px; height:350px"  id="'+id+'">';
 	str += '<button type="button" class="close" onclick="uifnPopupClose(\''+id+'\')"><i class="fa fa-times"></i></button>';
 	if(src.indexOf('http://')!=-1 || src.indexOf('https://')!=-1 && src.indexOf('youtube')==-1){
 		str += '<video id="video" autoplay></video>';
 	}else{
 		str +='<iframe id="video" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>';
 	}
-	str += '</div></div>';
+	str += '</div>';
 
 	if ($('#'+ id).length == 0) {
 		$('body').append(str);