Forráskód Böngészése

ep제외상품관리

eskim 5 éve
szülő
commit
8ffb21371c

+ 62 - 11
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java

@@ -8,6 +8,7 @@ import com.style24.persistence.domain.Color;
 import com.style24.persistence.domain.Goods;
 import com.style24.persistence.domain.GoodsCompose;
 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.GoodsSearch;
@@ -402,7 +403,7 @@ public interface TsaGoodsDao {
 	 * @param goodsSearch
 	 * @return
 	 * @author eskim
-	 * @since 2020. 02. 02
+	 * @since 2020. 10. 30
 	 */
 	int getGoodsTitleReserveCount(GoodsSearch goodsSearch);
 
@@ -412,7 +413,7 @@ public interface TsaGoodsDao {
 	 * @param goodsSearch
 	 * @return
 	 * @author eskim
-	 * @since 2020. 02. 02
+	 * @since 2020. 10. 30
 	 */
 	Collection<GoodsTnmRes> getGoodsTitleReserveList(GoodsSearch goodsSearch);
 
@@ -420,18 +421,18 @@ public interface TsaGoodsDao {
 	 * 상품 타이틀 조회(기간 체크용)
 	 *
 	 * @param goodsTnmRes
-	 * @return Collection<TsaGoodsTnmRes>
-	 * @author daehyoung
-	 * @since 2020. 06. 16
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 02
 	 */
-	Collection<GoodsTnmRes> getGoodsTnm(GoodsTnmRes goodsTnmRes);
+	int getGoodsTnmDupChkCount(GoodsTnmRes goodsTnmRes);
 
 	/**
 	 * 상품 타이틀 예약 등록
 	 *
 	 * @param goodsTnmRes
 	 * @author eskim
-	 * @since 2020. 02. 02
+	 * @since 2020. 11. 02
 	 */
 	void createGoodTnmRes(GoodsTnmRes goodsTnmRes);
 
@@ -440,7 +441,7 @@ public interface TsaGoodsDao {
 	 *
 	 * @param goods
 	 * @author eskim
-	 * @since 2020. 02. 02
+	 * @since 2020. 11. 02
 	 */
 	void updateGoodTnm(Goods goods);
 
@@ -449,7 +450,7 @@ public interface TsaGoodsDao {
 	 *
 	 * @param goods
 	 * @author eskim
-	 * @since 2020. 02. 02
+	 * @since 2020. 11. 02
 	 */
 	void updateGoodTnmInit(Goods goods);
 
@@ -458,7 +459,7 @@ public interface TsaGoodsDao {
 	 *
 	 * @param goodsTnmRes
 	 * @author eskim
-	 * @since 2020. 02. 02
+	 * @since 2020. 11. 02
 	 */
 	void deleteGoodTnmRes(GoodsTnmRes goodsTnmRes);
 
@@ -468,8 +469,58 @@ public interface TsaGoodsDao {
 	 * @param goods
 	 * @return
 	 * @author eskim
-	 * @since 2020. 02. 04
+	 * @since 2020. 11. 02
 	 */
 	Goods getGoodTnmInit(Goods goods);
 
+	/**
+	 * 네이버 EP 제외 상품 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	int getGoodsEpSkipCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 네이버 EP 제외 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<GoodsEpSkip>
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	Collection<GoodsEpSkip> getGoodsEpSkipList(GoodsSearch goodsSearch);
+
+	/**
+	 * 네이버 EP 제외 상품 조회(기간 체크용)
+	 *
+	 * @param GoodsEpSkip
+	 * @return Collection<GoodsEpSkip>
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	int getGoodsEpSkipDupChkCount(GoodsEpSkip GoodsEpSkip);
+
+	/**
+	 * 네이버 EP 제외 상품 예약 등록
+	 *
+	 * @param goodsEpSkip
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	void createGoodEpSkip(GoodsEpSkip goodsEpSkip);
+
+	/**
+	 * 네이버 EP 제외 상품 예약 삭제
+	 *
+	 * @param goodsEpSkip
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	void deleteGoodEpSkip(GoodsEpSkip goodsEpSkip);
+
 }

+ 78 - 14
style24.admin/src/main/java/com/style24/admin/biz/service/TsaGoodsService.java

@@ -1,7 +1,6 @@
 package com.style24.admin.biz.service;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,6 +22,7 @@ import com.style24.persistence.domain.CommonCode;
 import com.style24.persistence.domain.Goods;
 import com.style24.persistence.domain.GoodsCompose;
 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.GoodsSearch;
@@ -1283,7 +1283,7 @@ public class TsaGoodsService {
 	 * @param goodsSearch
 	 * @return
 	 * @author eskim
-	 * @since 2020. 02 .02
+	 * @since 2020. 11 .02
 	 */
 	public int getGoodsTitleReserveCount(GoodsSearch goodsSearch) {
 		return goodsDao.getGoodsTitleReserveCount(goodsSearch);
@@ -1295,7 +1295,7 @@ public class TsaGoodsService {
 	 * @param goodsSearch
 	 * @return
 	 * @author eskim
-	 * @since 2020. 02 .02
+	 * @since 2020. 11 .02
 	 */
 	public Collection<GoodsTnmRes> getGoodsTitleReserveList(GoodsSearch goodsSearch) {
 		return goodsDao.getGoodsTitleReserveList(goodsSearch);
@@ -1306,7 +1306,7 @@ public class TsaGoodsService {
 	 *
 	 * @param goodsTnmRes
 	 * @author eskim
-	 * @since 2020. 02 .02
+	 * @since 2020. 11 .02
 	 */
 	@Transactional("shopTxnManager")
 	public void saveGoodsRsvtTnm(GoodsTnmRes goodsTnmRes) {
@@ -1322,15 +1322,8 @@ public class TsaGoodsService {
 			goodsTnmRes.setRegNo(TsaSession.getInfo().getUserNo());
 			goodsTnmRes.setUpdNo(TsaSession.getInfo().getUserNo());
 
-			ArrayList<GoodsTnmRes> arrTnmRes = (ArrayList<GoodsTnmRes>)goodsDao.getGoodsTnm(goodsTnmRes);
-			int newStdt = Integer.valueOf(goodsTnmRes.getApplyStdt().substring(2, 10));
-			int newEddt = Integer.valueOf(goodsTnmRes.getApplyEddt().substring(2, 10));
-			for (GoodsTnmRes oneTnmRes : arrTnmRes) {
-				int oldStdt = Integer.valueOf(oneTnmRes.getApplyStdt().substring(2, 10));
-				int oldEddt = Integer.valueOf(oneTnmRes.getApplyEddt().substring(2, 10));
-				if ((oldStdt >= newStdt && oldStdt <= newEddt) || (oldEddt >= newStdt && oldEddt <= newEddt)) {
-					throw new IllegalStateException("이미 등록된 상품 타이틀예약이 등록하려는 예약기간내에 존재합니다. \n(상품코드 : " + goodsCd + ")");
-				}
+			if (goodsDao.getGoodsTnmDupChkCount(goodsTnmRes) > 0) {
+				throw new IllegalStateException("이미 등록된 상품 타이틀예약이 등록하려는 예약기간내에 존재합니다. \n(상품코드 : " + goodsCd + ")");
 			}
 
 			goodsDao.createGoodTnmRes(goodsTnmRes);
@@ -1358,7 +1351,7 @@ public class TsaGoodsService {
 	 *
 	 * @param goodsTnmRes
 	 * @author eskim
-	 * @since 2020. 02 .03
+	 * @since 2020. 11 .02
 	 */
 	@Transactional("shopTxnManager")
 	public void deleteGoodsRsvtTnm(GoodsTnmRes goodsTnmRes) {
@@ -1393,4 +1386,75 @@ public class TsaGoodsService {
 		}
 	}
 
+	/**
+	 * 네이버 EP 제외 상품 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return int
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	public int getGoodsEpSkipCount(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsEpSkipCount(goodsSearch);
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<TsaGoodsEpSkip>
+	 * @author daehyoung
+	 * @since 2020. 11. 03
+	 */
+	public Collection<GoodsEpSkip> getGoodsEpSkipList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsEpSkipList(goodsSearch);
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 등록
+	 *
+	 * @param goodsEpSkip
+	 * @return void
+	 * @author daehyoung
+	 * @since 2020. 11. 03
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsRsvtEpSkip(GoodsEpSkip goodsEpSkip) {
+		if (goodsEpSkip.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		for (String goodsCd : goodsEpSkip.getArrGoodsCd()) {
+
+			goodsEpSkip.setGoodsCd(goodsCd);
+			goodsEpSkip.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsEpSkip.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if (goodsDao.getGoodsEpSkipDupChkCount(goodsEpSkip) > 0) {
+				throw new IllegalStateException("비노출예약이 중복된 상품이 존재합니다.<br/>(상품코드 : " + goodsCd + ")");
+			}
+			goodsDao.createGoodEpSkip(goodsEpSkip);
+		}
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 삭제
+	 *
+	 * @param goodsEpSkip
+	 * @return void
+	 * @author daehyoung
+	 * @since 2020. 11. 03
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteGoodsEpSkip(GoodsEpSkip goodsEpSkip) {
+		if (goodsEpSkip.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		int idx = 0;
+		for (String goodsCd : goodsEpSkip.getArrGoodsCd()) {
+			goodsEpSkip.setGoodsEpSkipSq(goodsEpSkip.getArrGoodsEpSkipSq()[idx]);
+			goodsDao.deleteGoodEpSkip(goodsEpSkip);
+			idx++;
+		}
+	}
 }

+ 107 - 2
style24.admin/src/main/java/com/style24/admin/biz/web/TsaGoodsController.java

@@ -30,6 +30,7 @@ import com.style24.persistence.domain.CodiGoods;
 import com.style24.persistence.domain.Color;
 import com.style24.persistence.domain.Goods;
 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.GoodsSearch;
@@ -1100,7 +1101,7 @@ public class TsaGoodsController extends TsaBaseController {
 	 * @param goodsTnmRes
 	 * @return
 	 * @author eskim
-	 * @since 2020. 02. 02
+	 * @since 2020. 11. 02
 	 */
 	@PostMapping("/title/reserve/delete")
 	@ResponseBody
@@ -1131,17 +1132,121 @@ public class TsaGoodsController extends TsaBaseController {
 	 *
 	 * @return
 	 * @author eskim
-	 * @since 2020. 10. 16
+	 * @since 2020. 11. 03
 	 */
 	@GetMapping("/ep/skip/form")
 	public ModelAndView epSkipForm() {
 		ModelAndView mav = new ModelAndView();
 
+		String supplyCompCd = "";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd));
+		// 상품상태
+		String[] exceptCds = {"G001_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/GoodsEpSkipForm");
 
 		return mav;
 	}
 
+	/**
+	 * 네이버 EP 제외 상품 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@PostMapping("/ep/skip/list")
+	@ResponseBody
+	public GagaMap goodsEpSkipList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdId(Integer.toString(TsaSession.getInfo().getUserNo()));
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+		}
+
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsEpSkipCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsEpSkipList", goodsService.getGoodsEpSkipList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약등록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@GetMapping("/ep/skip/popup/form")
+	@ResponseBody
+	public ModelAndView goodsEpSkipPopupForm(GoodsEpSkip goodsEpSkip) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsEpSkipPopupForm");
+		return mav;
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 저장
+	 *
+	 * @param goodsEpSkip
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@PostMapping("/rsvt/ep/skip/save")
+	@ResponseBody
+	public GagaResponse saveGoodsRsvtEpSkip(@RequestBody GoodsEpSkip goodsEpSkip) {
+		goodsService.saveGoodsRsvtEpSkip(goodsEpSkip);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 삭제
+	 *
+	 * @param goodsEpSkip
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@PostMapping("/rsvt/ep/skip/delete")
+	@ResponseBody
+	public GagaResponse deleteGoodsEpSkip(@RequestBody GoodsEpSkip goodsEpSkip) {
+		goodsService.deleteGoodsEpSkip(goodsEpSkip);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+
 	/**
 	 * 상품 재입고알림관리 화면
 	 *

+ 36 - 0
style24.admin/src/main/java/com/style24/persistence/domain/GoodsEpSkip.java

@@ -0,0 +1,36 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * EP제외상품 Domain
+ *
+ * @author eskim
+ * @since 2020. 11. 03
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsEpSkip extends TscBaseDomain {
+
+	private Integer goodsEpSkipSq;
+	private String goodsCd;
+	private String applyStdt;
+	private String applyEddt;
+
+	private String goodsNm;
+	private String goodsNum;
+	private String supplyGoodsCd;
+	private String brandNm;
+	private String brandEnm;
+	private String goodsStat;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] arrGoodsCd;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private int[] arrGoodsEpSkipSq;
+
+}

+ 175 - 5
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml

@@ -1725,13 +1725,15 @@
 	</select>
 
 	<!-- 상품 타이틀 예약조회(기간 체크용) -->
-	<select id="getGoodsTnm" parameterType="GoodsTnmRes" resultType="GoodsTnmRes">
-		/* TsaGoods.getGoodsTnm */
-		SELECT GOODS_CD
-		     , DATE_FORMAT(APPLY_STDT,'%Y%m%d%H%i%S') AS APPLY_STDT
-		     , DATE_FORMAT(APPLY_EDDT, '%Y%m%d%H%i%S') AS APPLY_EDDT
+	<select id="getGoodsTnmDupChkCount" parameterType="GoodsTnmRes" resultType="int">
+		/* TsaGoods.getGoodsTnmDupChkCount */
+		SELECT COUNTS(GOODS_CD)
 		FROM TB_GOODS_TNM_RES
 		WHERE 1=1
+		<![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')
 		AND GOODS_CD = #{goodsCd}
 	</select>
 	
@@ -1821,4 +1823,172 @@
 		WHERE GOODS_CD = #{goodsCd}
 	</select>
 	
+	<!-- 네이버 EP 제외 상품 목록 건수 -->
+	<select id="getGoodsEpSkipCount" parameterType="GoodsSearch" resultType="int">
+		/* TsaGoods.getGoodsEpSkipCount */
+		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_EP_SKIP GE ON G.GOODS_CD = GE.GOODS_CD
+		<if test="searchGb == null or searchGb =='BASIC'" >
+		<if test="applyStdt != null and applyStdt != ''">
+		                               AND GE.APPLY_EDDT >= DATE_FORMAT(#{applyStdt}, '%Y-%m-%d %H:%i:%S')
+		</if>
+		<if test="applyEddt != null and applyEddt != ''">
+		<![CDATA[
+		                               AND GE.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 GE.APPLY_EDDT >= NOW() 
+		</if>
+		</if>
+		<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="mdId != null and mdId != ''">
+		       AND G.BRAND_CD IN (
+		                          SELECT DISTINCT BRAND_CD
+		                          FROM TB_BRAND_MD
+		                          WHERE MD_ID = #{mdId}
+		                          )
+		      </if>
+		   )
+		</if>
+		WHERE 1=1
+		<if test="searchGb == null or searchGb =='BASIC'" >
+		<include refid="getGoodsListCondition_sql"/>
+		</if>
+	</select>
+
+	<!-- 네이버 EP 제외 상품 목록 -->
+	<select id="getGoodsEpSkipList" parameterType="GoodsSearch" resultType="GoodsEpSkip">
+		/* TsaGoods.getGoodsEpSkipList */
+		SELECT Z.*
+		FROM (
+		    SELECT A.*, @rownum := @rownum + 1 AS RNUM FROM (
+		        SELECT
+		                G.GOODS_CD
+		              , B.BRAND_ENM
+		              , G.BRAND_CD
+		              , G.SUPPLY_COMP_CD
+		              , G.SUPPLY_GOODS_CD
+		              , G.GOODS_NM
+		              , G.GOODS_STAT
+		              , GE.GOODS_EP_SKIP_SQ
+		              , DATE_FORMAT(GE.APPLY_STDT,'%Y%m%d%H%i%S') AS APPLY_STDT
+		              , DATE_FORMAT(GE.APPLY_EDDT,'%Y%m%d%H%i%S') AS APPLY_EDDT
+		              , GE.REG_NO
+		              , FN_GET_USER_NM(GE.REG_NO) AS REG_NM
+		              , DATE_FORMAT(GE.REG_DT,'%Y%m%d%H%i%S') AS REG_DT
+		              , GE.UPD_NO
+		              , FN_GET_USER_NM(GE.UPD_NO) AS UPD_NM
+		              , DATE_FORMAT(GE.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_EP_SKIP GE ON G.GOODS_CD = GE.GOODS_CD
+		        <if test="searchGb == null or searchGb =='BASIC'" >
+		            <if test="applyStdt != null and applyStdt != ''">
+		                                       AND GE.APPLY_EDDT >= DATE_FORMAT(#{applyStdt}, '%Y-%m-%d %H:%i:%S')
+		            </if>
+		            <if test="applyEddt != null and applyEddt != ''">
+		            <![CDATA[
+		                                       AND GE.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 GE.APPLY_EDDT >= NOW() 
+		            </if>
+		        </if>
+		        <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="mdId != null and mdId != ''">
+		                      AND G.BRAND_CD IN (
+		                                          SELECT DISTINCT BRAND_CD
+		                                          FROM TB_BRAND_MD
+		                                          WHERE MD_ID = #{mdId}
+		                                          )
+		                      </if>
+		                   )
+		        </if>
+		        WHERE 1=1
+		        <if test="searchGb == null or searchGb =='BASIC'">
+		        <include refid="getGoodsListCondition_sql"/>
+		        ORDER BY GE.APPLY_STDT DESC, GE.APPLY_EDDT DESC, G.GOODS_CD, GE.GOODS_EP_SKIP_SQ
+		        </if>
+		         <if test="searchGb != null and searchGb =='EXCEL'">
+		        ORDER BY SD.TMP_DISP_ORD
+		        </if>
+		<include refid="getListPagingCondition_sql"/>
+	</select>
+
+	<!-- 네이버 EP 제외 상품 조회(기간 체크용) -->
+	<select id="getGoodsEpSkipDupChkCount" parameterType="GoodsEpSkip" resultType="int">
+		/* TsaGoods.getGoodsEpSkipDupChkCount */
+		SELECT COUNT(GOODS_CD)
+		FROM TB_GOODS_EP_SKIP
+		WHERE 1=1
+		<![CDATA[
+		AND APPLY_STDT <= DATE_FORMAT(#{applyStdt}, '%Y%m%d')
+		]]>
+		AND APPLY_EDDT >= DATE_FORMAT(#{applyEddt},'%Y%m%d%')
+		AND GOODS_CD = #{goodsCd}
+	</select>
+
+	<!-- 네이버 EP 제외 상품 예약 등록 -->
+	<insert id="createGoodEpSkip" parameterType="GoodsEpSkip">
+		/* TsaGoods.createGoodEpSkip */
+		INSERT INTO TB_GOODS_EP_SKIP (
+		GOODS_EP_SKIP_SQ
+		, GOODS_CD
+		, APPLY_STDT
+		, APPLY_EDDT
+		, REG_NO
+		, REG_DT
+		, UPD_NO
+		, UPD_DT
+		)
+		VALUES(
+		  NULL
+		, #{goodsCd}
+		, STR_TO_DATE(#{applyStdt},'%Y%m%d%H%i%S')
+		, STR_TO_DATE(#{applyEddt},'%Y%m%d%H%i%S')
+		, #{regNo}
+		, NOW()
+		, #{updNo}
+		, NOW()
+		)
+	</insert>
+
+	<!-- 네이버 EP 제외 상품 예약 삭제 -->
+	<delete id="deleteGoodEpSkip" parameterType="GoodsEpSkip">
+		/* TsaGoods.deleteGoodEpSkip */
+		DELETE FROM TB_GOODS_EP_SKIP
+		WHERE GOODS_EP_SKIP_SQ = #{goodsEpSkipSq}
+	</delete>
+	
 </mapper>

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

@@ -0,0 +1,411 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsEpSkipForm.html
+ * @desc    : 네이버EP제외상품관리
+ *============================================================================
+ * PASTEL
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.03   eskim       최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<form id="goodsEpSkipListForm" name="goodsEpSkipListForm" action="#" th:action="@{'/goods/ep/skip/list'}">
+		<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="8%"/>
+						<col/>
+						<col width="8%"/>
+						<col width="25%"/>
+						<col width="8%"/>
+						<col width="20%"/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드</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>키워드</th>
+						<td>
+							<select name="search" id="search">
+								<option value="searchGoodsCd">상품코드</option>
+								<option value="searchGoodsNm">상품명</option>
+								<option value="searchGoodsNum">품번</option>
+								<option value="searchSupplyGoodsCd">업체상품코드</option>
+							</select>
+							<input type="text" class="w50p" name="condition" id="condition" maxlength="50"/>
+						</td>
+						<th>시즌/년도</th>
+						<td>
+							<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 class="left">
+					<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF003');">상품엑셀조회 양식 다운로드</button>
+					<button type="button" class="btn btn-base btn-lg" id="btnGoodsExcelUpLoad">엑셀조회</button>
+					<button type="button" class="btn btn-success  btn-lg" id="btnGoodsEpSkipSave">비노출예약등록</button>
+					<button type="button" class="btn btn-danger btn-lg" id="btnGoodsEpSkipDelete">비노출예약삭제</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('goodsEpSkipListForm',params.node.rowIndex, 'A');}
+		},
+		{headerName: "브랜드명", field: "brandEnm", width: 130, cellClass: 'text-center'},
+		{headerName: "상품코드", field: "goodsCd", width: 140, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 180, 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: "applyStdt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD") : '';
+			}
+		},
+		{headerName: "예약종료일", field: "applyEddt", width: 150, 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'}
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// 중복 선택 가능
+	gridOptions.rowSelection = 'multiple';
+	gridOptions.suppressRowClickSelection = true;
+
+	// 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(){
+		$('#goodsEpSkipListForm')[0].reset();
+		$("#goodsEpSkipListForm input[type=checkbox]").removeClass("checked");
+		$("#goodsEpSkipListForm input[type=checkbox]").parent("label").removeClass("checked");
+		$("#goodsEpSkipListForm input[type=radio][checked]").parent("label").addClass("checked");
+	}
+	
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		$("#goodsEpSkipListForm input[name=pageNo]").val('1');
+		fnGoodsEpSkipListSearch('BASIC');
+	});
+
+	// 조회
+	var fnGoodsEpSkipListSearch = function(gbn) {
+		
+		if (typeof(gbn) != 'undefined' &&  gbn == 'EXCEL'){
+			$("#goodsEpSkipListForm input[name=searchGb]").val("EXCEL");
+		}else{
+			$("#goodsEpSkipListForm input[name=searchGb]").val("BASIC");
+		}
+		
+		if(!fnConditionCheck()) return;
+		
+		gagaPaging.init('goodsEpSkipListForm', fnSearchCallBack, 'goodsListPagination', $('#goodsEpSkipListForm').find('#pageSize').val());
+		gagaPaging.load($("#goodsEpSkipListForm input[name=pageNo]").val());
+	}
+
+	// 조회 (등록 창 닫을 때)
+	var fnGoodsRsvtEpSkipListSearch = function(gbn) {
+
+		if (typeof(gbn) != 'undefined' &&  gbn == 'EXCEL'){
+			$("#goodsEpSkipListForm input[name=searchGb]").val("EXCEL");
+		}else{
+			$("#goodsEpSkipListForm input[name=searchGb]").val("BASIC");
+		}
+
+		gagaPaging.init('goodsEpSkipListForm', fnSearchCallBack, 'goodsListPagination', $('#goodsEpSkipListForm').find('#pageSize').val());
+		gagaPaging.load($("#goodsEpSkipListForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#goodsEpSkipListForm';
+		var form = document.goodsEpSkipListForm;
+
+		if($("#goodsEpSkipListForm 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")) {
+				if (!(el.value == null || el.value == "")) {
+					cnt++;
+				}
+			}
+		}
+			
+		if(cnt > 0) searchFlag = true;
+
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		
+		var fromDate = $('#goodsEpSkipListForm input[name=stDate]').val();
+		var toDate = $('#goodsEpSkipListForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function(){
+						$('#goodsEpSkipListForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function(){
+						$('#goodsEpSkipListForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		}
+
+		return true;
+	}
+	
+	var fnSearchCallBack = function(result){
+
+		$('#goodsEpSkipListForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#goodsEpSkipListForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#goodsEpSkipListForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#goodsEpSkipListForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.goodsEpSkipList);
+		gagaPaging.createPagination(result.pageing.pageable);
+	}
+	
+	//페이징 
+	$('#goodsEpSkipListForm select[name=pageSize]').on('change', function() {
+		$("#goodsEpSkipListForm input[name=pageNo]").val('1');
+		fnGoodsEpSkipListSearch($("#goodsEpSkipListForm input[name=searchGb]").val());
+	});
+	
+	//업체변경시
+	$('#goodsEpSkipListForm select[name=supplyCompCd]').on('change', function() {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
+
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		$("#goodsEpSkipListForm select[name=brandCd] option:gt(0)").remove();
+
+		cfnCreateCombo(actionUrl, $('#goodsEpSkipListForm select[name=brandCd]'), "[전체]", "");
+	});
+	
+	//엑셀 상품 조회
+	$('#btnGoodsExcelUpLoad').on('click', function() {
+		cfnExcelUploadPopup('goodsEpSkipExcelUpload', 'goodsEpSkipExcelUpload');
+	});
+	
+	var goodsEpSkipExcelUpload = function(result){
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, fngoodsEpSkipExcelUploadCallBack);
+	}
+	
+	var fngoodsEpSkipExcelUploadCallBack = function(result){
+		fnGoodsEpSkipListSearch("EXCEL");
+	}
+	
+	//예약등록
+	$('#btnGoodsEpSkipSave').click(function(e) {
+		var actionUrl = "/goods/ep/skip/popup/form";
+		cfnOpenModalPopup(actionUrl, 'popupGoodsEpSkip');
+	});
+	
+	//예약삭제
+	$('#btnGoodsEpSkipDelete').click(function(e) {
+		//상품선택여부 확인처리 추가
+		var selectedData = gridOptions.api.getSelectedRows();
+
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return false;
+		}
+		
+		var arrGoodsCd = [];
+		var arrGoodsEpSkipSq = [];
+		var chkFlag = false;
+		$.each(selectedData, function(idx, item) {
+			
+			var toDateStr = new Date().format("YYYYMMDDHHmmss");
+			if (toDateStr > item.applyEddt){
+				chkFlag = true;
+				mcxDialog.alertC("종료된 네이버 EP 제외 상품은 삭제할 수 없습니다.",  {
+					sureBtnText: "확인",
+					sureBtnClick: function(){
+						$('#goodsRsvtEpSkipForm input[name=applyEdYMD]').focus();
+					}
+				});
+				return false;
+			}
+		
+			arrGoodsCd.push(item.goodsCd);
+			arrGoodsEpSkipSq.push(item.goodsEpSkipSq);
+		});
+
+		if (chkFlag){
+			return;
+		}
+		
+		mcxDialog.confirm('삭제하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {arrGoodsCd : arrGoodsCd
+						,arrGoodsEpSkipSq : arrGoodsEpSkipSq
+							};
+			
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/rsvt/ep/skip/delete', jsonData, fnGoodsEpSkipResDeleteCallBack);
+			}
+		});
+	});
+	
+	var fnGoodsEpSkipResDeleteCallBack = function(){
+		//fnGoodsRsvtEpSkipListSearch($("#goodsEpSkipListForm input[name=searchGb]").val());
+	}
+	
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'applyStdt', 'applyEddt', true, '예약일', 'X');
+		var chkBeforSkipFlag = '&nbsp;&nbsp;<label class="chkBox"><input type="checkbox" name="beforSkipFlag" value="Y" >이전데이터 제외</label>';
+		$("#goodsEpSkipListForm").find('#sellTerms').append(chkBeforSkipFlag);
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+ 	
+</html>

+ 265 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsEpSkipPopupForm.html

@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsEpSkipPopupForm.html
+ * @desc    : 네이버 EP 제외 상품 예약 화면
+ *============================================================================
+ * PASTEL
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.03   eskim       최초 작성
+ *******************************************************************************
+ -->	
+	<div class="modalPopup"  data-width="750" >
+		<div class="panelStyle">
+			<div class="panelTitle">
+				<h2>상품비노출예약</h2>
+				<button type="button" class="close" onclick="uifnPopupClose('popupGoodsEpSkip')"><i class="fa fa-times"></i></button>
+			</div>
+			<form id="goodsRsvtEpSkipForm" name="goodsRsvtEpSkipForm" >
+			<input type="hidden" id="goodsCd" name="goodsCd" />
+			<div class="panelContent">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<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="btnDeleteGoodsEpSkip">상품삭제</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="gridGoodsRsvtEpSkipList" style="width: 100%; height: 500px;" class="ag-theme-balham"></div>
+			</form>
+			<ul class="panelBar">
+				<li class="right">
+					<button type="button" class="btnRight btn btn-base btn-lg" id=btnSaveGoodsRsvtTnm>저장</button>
+				</li>
+			</ul>
+		</div>
+	</div>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var rsvtGoodsTnmColumnDefs = [
+		{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: 140, cellClass: 'text-center'},
+		{headerName: "상품코드", field: "goodsCd", width: 140, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 250, cellClass: 'text-left'}
+	];
+	
+	// Get GridOptions
+	var rsvtGoodsEpSkipGridOptions = gagaAgGrid.getGridOptions(rsvtGoodsTnmColumnDefs);
+
+	// 중복 선택 가능
+	rsvtGoodsEpSkipGridOptions.rowSelection = 'multiple';
+	rsvtGoodsEpSkipGridOptions.suppressRowClickSelection = true;
+
+	// 상품 조회 클릭 시
+	$('#btnSearchGoods').on('click', function() {
+		cfnOpenGoodsPopup('fnSearchGoods');
+	});
+
+	// 상품 조회 콜백함수
+	var fnSearchGoods = function(result) {
+		if (result.length < 1) return;
+		var oldData = gagaAgGrid.getAllRowData(rsvtGoodsEpSkipGridOptions);
+		$.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(rsvtGoodsEpSkipGridOptions, {"goodsCd" : item.goodsCd, "goodsNm" : item.goodsNm, "brandEnm" : item.brandEnm});
+		});
+		uifnPopClose('popupGoods');
+		return;
+	};
+
+	// 저장 클릭 시
+	$('#btnSaveGoodsRsvtTnm').on('click', function() {
+		
+		var fromDate = $('#goodsRsvtEpSkipForm input[name=applyStYMD]').val();
+		var toDate = $('#goodsRsvtEpSkipForm input[name=applyEdYMD]').val();
+
+		if (gagajf.isNull(fromDate)) {
+			mcxDialog.alertC("예약  시작일자를 입력하세요.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsRsvtEpSkipForm input[name=applyStYMD]').focus();
+				}
+			});
+			return false;
+		}
+		
+		if (gagajf.isNull(toDate)) {
+			mcxDialog.alertC("예약  종료일자를 입력하세요.",  {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsRsvtEpSkipForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		}
+
+		if (fromDate > toDate) {
+			mcxDialog.alertC("예약 시작일자는 종료일자 보다 클 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsRsvtEpSkipForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		} 
+		
+		var applyStdt = $('#goodsRsvtEpSkipForm input[name=applyStYMD]').val().replaceAll("-","");
+
+		var applyEddt = $('#goodsRsvtEpSkipForm input[name=applyEdYMD]').val().replaceAll("-","");
+		
+		$('#goodsRsvtEpSkipForm input[name=applyStdt]').val(applyStdt);
+		$('#goodsRsvtEpSkipForm input[name=applyEddt]').val(applyEddt);
+		
+		if ($('#goodsRsvtEpSkipForm input[name=applyStdt]').val() > $('#goodsRsvtEpSkipForm input[name=applyEddt]').val()) {
+			mcxDialog.alertC("예약 시작일자는 종료일자 보다 클 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsRsvtEpSkipForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		}
+		
+		var toDateStr = new Date().format("YYYYMMDD");
+
+		if (toDateStr > applyStdt){
+			mcxDialog.alertC("예약 시작일시는 현재일시 보다 작을 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsRsvtEpSkipForm input[name=applyStYMD]').focus();
+				}
+			});
+			return false;
+		}
+
+		if (toDateStr >= applyEddt){
+			mcxDialog.alertC("예약 종료일시는 현재일시 보다 작거나 같을 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsRsvtEpSkipForm input[name=applyEdYMD]').focus();
+				}
+			});
+			return false;
+		}
+		
+		mcxDialog.confirm('저장하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var arrGoodsCd = [];
+				var allRowData = gagaAgGrid.getAllRowData(rsvtGoodsEpSkipGridOptions);
+				allRowData.forEach(function(item, index) {
+					arrGoodsCd.push(item.goodsCd);
+				});
+
+				var data = {applyStdt : $('#goodsRsvtEpSkipForm input[name=applyStdt]').val()
+						, applyEddt : $('#goodsRsvtEpSkipForm input[name=applyEddt]').val()
+						, arrGoodsCd : arrGoodsCd
+				};
+				
+				var jsonData = JSON.stringify(data);
+				gagajf.ajaxJsonSubmit('/goods/rsvt/ep/skip/save', jsonData, fnGoodsRsvtEpSkipListFormClose);
+			}
+		});
+	});
+
+	//엑셀 상품 조회
+	$('#btnSearchExcel').on('click', function() {
+		cfnExcelUploadPopup('goodsRsvtEpSkipExcelUpload', 'goodsRsvtEpSkipExcelUpload');
+	});
+
+	var goodsRsvtEpSkipExcelUpload = function(result){
+		var data = {procJob : result.procJob
+			,excelFileNm : result.excelFileNm
+		};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, fnRsvtGoodsEpSkipExcelUploadCallBack);
+	}
+
+	var fnRsvtGoodsEpSkipExcelUploadCallBack = function(result){
+		gagajf.ajaxJsonSubmit('/goods/excel/upload/goods/list', '', fnExcelSearchCallBack);
+	}
+
+	var fnExcelSearchCallBack = function(result){
+		if (result.goodsExcelList.length < 1) return;
+		var oldData = gagaAgGrid.getAllRowData(rsvtGoodsEpSkipGridOptions);
+		$.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(rsvtGoodsEpSkipGridOptions, {"goodsCd" : item.goodsCd, "goodsNm" : item.goodsNm, "brandEnm" : item.brandEnm});
+		});
+		return;
+	}
+	
+	// 조회상품 삭제
+	$('#btnDeleteGoodsEpSkip').on('click', function() {
+		var selectedData = rsvtGoodsEpSkipGridOptions.api.getSelectedRows();
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+
+		//화면에서 삭제
+		var removedData = gagaAgGrid.removeRowData(rsvtGoodsEpSkipGridOptions, false);
+	});
+	
+	//창종료
+	var fnGoodsRsvtEpSkipListFormClose = function(){
+		uifnPopClose('popupGoodsEpSkip');
+		fnGoodsEpSkipResDeleteCallBack();
+	}
+
+	$(document).ready(function() {
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridGoodsRsvtEpSkipList', rsvtGoodsEpSkipGridOptions);
+	});
+
+/*]]>*/
+</script>
+</html>

+ 514 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsSetForm.html

@@ -0,0 +1,514 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsSetForm.html
+ * @desc    : 세트상품 구성 관리
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.05.26   eskim       최초 작성
+ *******************************************************************************
+ -->	
+	<ul class="popup modal" data-width="1100" >
+		<li class="mdPopTitle">
+			<strong>세트 상품 구성</strong>
+			<button type="button" class="close" onclick="fnGoodsSetFormClose()"><i class="fa fa-times"></i></button>
+		</li>
+		<li class="mdPopContent" style="height:610px; overflow-y: auto;">
+			<ul class="notice">
+				<li>구성상품 등록시 기본값&nbsp;
+					<!-- 아이콘 툴팁 -->
+					<div class="iconTooltip">
+						<i class="fa fa-info" aria-hidden="true"></i>
+						<span class="left" style="width:400px; text-align:left;">
+						<!-- class="left" 또는 class="right" -->
+							- 상품상태 : 정보부족<br/>
+							- TAG가 : 구성상품의 TAG가 합<br/>
+							- 정상가 : 구성상품의 정상가 합<br/>
+							- 판매가 : 구성상품 판매가 입력값의 합<br/>
+							- 브랜드코드 : 구성상품의 기준여부 'Y'상품의 브랜드코드<br/>
+							- 품목코드 : 구성상품의 기준여부 'Y'상품의 품목코드<br/>
+							- 포인트 : 구성상품의 기준여부 'Y'상품의 브랜드 포인트<br/>
+							- 기본배송비 : 구성상품의 기준여부 'Y'상품의 브랜드 기본배송비<br/>
+							- 무료배송비기준 : 구성상품의 기준여부 'Y'상품의 브랜드 무료배송비기준<br/>
+							- 외부몰 판매가 : 구성상품 판매가 입력값의 합<br/>
+							- 상품이미지 : 상품상세에서 이미지 경로 등록 처리
+						</span>
+					</div>
+					<!-- //아이콘 툴팁 --> 
+				</li>
+			</ul>
+			<form id="goodsSetForm" name="goodsSetForm" th:method="post">
+			<input type="hidden" id="extendGoodsList" name="extendGoodsList" />
+			<table class="frmStyle">
+				<colgroup>
+					<col width="10%"/>
+					<col/>
+					<col width="10%"/>
+					<col width="23%"/>
+					<col width="10%"/>
+					<col width="23%"/>
+				</colgroup>
+				<tr>
+					<th>상품명<i class="star"></i></th>
+					<td><input type="text" id="goodsNm" name="goodsNm" maxlength="60"/></td>
+					<th>자사노출여부<i class="star"></i></th>
+					<td><label><input type="radio" name="selfMallYn" id="selfMallYnY" value="Y" checked/>Y</label>
+						<label><input type="radio" name="selfMallYn" id="selfMallYnN" value="N"/>N</label>
+					</td>
+					<th>성별<i class="star"></i></th>
+					<td><select  name="sexGb" id="sexGb">
+							<option value="">[전체]</option>
+							<option th:if="${sexGbList}" th:each="oneData, status : ${sexGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+						</select>
+					</td>
+				</tr>
+				<tr>
+					<th>년도/시즌<i class="star"></i></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>원산지<i class="star"></i></th>
+					<td><input type="text" class="w100" id="makeNm" name="makeNm" maxlength="20" /></td>
+				</tr>
+				<tr>
+					<th>색상<i class="star"></i></th>
+					<td colspan="3">
+						<select name="colorCd" id="colorCd">
+						</select>
+					</td>
+					<th>제조년월일<i class="star"></i></th>
+					<td><input type="text" class="w100" id="makeYmd" name="makeYmd" maxlength="8" data-valid-type="date"/></td>
+					<!-- <th>매입유형<i class="star"></i></th>
+					<td colspan="3">
+						<select  name="buyingType" id="buyingType">
+							<option value="">[선택]</option>
+							<option th:if="${buyingTypeList}" th:each="oneData, status : ${buyingTypeList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+						</select>
+					</td> -->
+				</tr>
+			</table>
+			<div class="padT15 padB15">
+				<button type="button" class="btn btn-danger btn-lg" onclick="fnGoodsSetDeleteRow();">행삭제</button>
+				<button type="button" class="btn btnRight  btn-base btn-lg" onclick="fnOpenGoodsSetPopup();">구상상품추가</button>
+			</div>
+			<div id="gridGoodsSetList" style="height: 390px;" class="ag-theme-balham lh60"></div>
+		</form>	
+		</li>
+		<li class="mdPopBtnB padT15">
+			<th:block th:if="${sessionInfo.roleCd == '0000' OR sessionInfo.roleCd == 'A000' OR sessionInfo.roleCd == 'A101' OR sessionInfo.roleCd == 'A100' OR sessionInfo.roleCd == 'A001'}">
+			<button type="button" class="btn btnRight btn-success btn-lg" id="btnGoodsSetSave">저장</button>
+			</th:block>
+		</li>
+	</ul>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var useYnList = cfnConvertToArray([[${useYnList}]]);
+	var goodsStatList = cfnConvertToArray([[${goodsStatList}]]);
+	// specify the columns
+	var columnGoodsSetDefs = [
+		{headerName: "정렬", field: "dispOrd", width: 70 ,hide: false, cellClass: 'text-center',  rowDrag: true },
+		{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: "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: "extendGoodsCd" , width: 130, cellClass: 'text-center'},
+		{headerName: "구성상품명", field: "goodsNm" , width: 130, cellClass: 'text-left'},
+		//{headerName: "순서", field: "dispOrd" , width: 100, cellClass: 'text-center',editable: true, required: true},
+		{headerName: "수량", field: "qty" , width: 80, cellClass: 'text-right',editable: true, required: true},
+		{headerName: "상품판매가", field: "extendCurrPrice" , width: 120, cellClass: 'text-right',editable: true, required: true,
+			cellEditor: 'textCellEditor',
+			cellEditorParams: { maxlength: 14, validType: 'numeric'}
+		},
+		/* {headerName: "임직원판매가", field: "extendStaffCurrPrice" , width: 120, cellClass: 'text-right',editable: true, required: true,
+			cellEditor: 'textCellEditor',
+			cellEditorParams: { maxlength: 14, validType: 'numeric'}
+		}, */
+		{headerName: "기준여부(품목/전시카테)", field: "baseYn" , width: 160, cellClass: 'text-center',editable: true, required: true,
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }
+		},
+		{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: "selfGoodsYn" , width: 100, cellClass: 'text-center'}
+		/* {headerName: "등록일자", field: "regDt", width: 150, cellClass: 'text-center' ,
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmm").format("YYYY-MM-DD HH:mm") : '';
+			}
+		},
+		{headerName: "등록자", field: "regId", width: 100, cellClass: 'text-center'},
+		{headerName: "수정일자", field: "regDt", width: 150, cellClass: 'text-center' ,
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmm").format("YYYY-MM-DD HH:mm") : '';
+			}
+		},
+		{headerName: "수정자", field: "regId", width: 100, cellClass: 'text-center'} */
+	];
+
+	// Get GridOptions
+	var gridGoodsSetOptions = gagaAgGrid.getGridOptions(columnGoodsSetDefs);
+	gridGoodsSetOptions.rowSelection = 'multiple';
+	gridGoodsSetOptions.suppressRowClickSelection = true;
+	
+	// 드래그
+	gridGoodsSetOptions.rowDragManaged = true;
+	gridGoodsSetOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+ 	
+	//기준여부 표시
+	gridGoodsSetOptions.getRowStyle = function(params) {
+		if ("Y" == params.data.baseYn) {
+			return { background: '#1ab394' };
+		}
+	}
+	
+	// Row 
+	gridGoodsSetOptions.onCellValueChanged = function(event) {
+		var rowIdx = null;
+		var isChangColor = true;
+		if (event.colDef.field == "baseYn"){
+			if (event.data.baseYn == "Y"){
+				rowIdx = event.rowIndex;
+				
+				//다른 기준여부 'Y'가 존재하는지 확인
+				gridGoodsSetOptions.api.forEachNode(function(rowNode, index) {
+					if (rowNode.data.baseYn == "Y" && index != rowIdx){
+						event.data.baseYn = event.oldValue;
+						gridGoodsSetOptions.api.updateRowData({update: [event.data]});
+						isChangColor = false;
+						return;
+					}
+				});
+				
+				if (!isChangColor){ 
+					mcxDialog.alert('다른 구성상품에 기준여부가 선택되어 있습니다.');
+					return;
+				}
+				
+				//기준상품의 색상 정보 읽어오기
+				var goodsCd = event.data.extendGoodsCd;
+				$("#goodsSetForm select[name=colorCd] option:gt(0)").remove();
+				cfnCreateCombo("/renderer/goods/brand/color/list/" + goodsCd, $('#goodsSetForm select[name=colorCd]'), "[선택]");
+			}	
+		}
+	}
+	
+	//창종료
+	var fnGoodsSetFormClose = function(){
+		uifnPopupClose('popupGoodsSet');
+	}
+	
+	$(document).ready(function() {
+		gagaAgGrid.createGrid('gridGoodsSetList', gridGoodsSetOptions);
+	});
+	
+	//상품조회 팝업
+	var fnOpenGoodsSetPopup = function() {
+		cfnOpenGoodsPopup('fnCreateGoodsSet');
+	}
+
+	// 상품추가
+	var fnCreateGoodsSet = function(goodsData) {
+		if (goodsData.length < 1) return;
+		
+		// 기존상품
+		var oldGoodsSetList = gagaAgGrid.getAllRowData(gridGoodsSetOptions);
+		var idx = oldGoodsSetList.length+1; 
+		
+		var isExist = false;
+		goodsData.forEach(function(goods){
+			isExist = false;
+
+			gridGoodsSetOptions.api.forEachNode(function(rowNode, index) {
+				if (goods.goodsCd == rowNode.data.extendGoodsCd){
+					isExist = true;
+				}
+			});
+
+			if (goods.goodsType != 'N'){
+				isExist = true;
+			}
+			
+			if(!isExist){
+				
+				var data = { 
+						  extendGoodsCd: goods.goodsCd
+						, goodsType: 'S'
+						, dispOrd: idx
+						, qty: 1
+						, extendCurrPrice: goods.currPrice
+						, extendStaffCurrPrice: goods.currPrice
+						, baseYn: 'N'
+						, goodsStat : goods.goodsStat
+						, useYn: 'Y'
+						, goodsNm : goods.goodsNm
+						, selfGoodsYn : goods.selfGoodsYn
+						, imgType : goods.imgType
+						, imgPath1 : goods.imgPath1
+						, imgPath6 : goods.imgPath6
+						};
+				//그리드 마지막에 추가해야함
+				gridGoodsSetOptions.api.updateRowData({add: [data], addIndex: idx});
+				gridGoodsSetOptions.api.refreshCells();
+				idx++;
+			
+			}
+		});
+	}
+	
+	// 저장클릭시
+	$('#btnGoodsSetSave').on('click', function() {
+
+		if(!fnGoodsSetConditionCheck()) return;
+		
+		mcxDialog.confirm('세트상품을 등록 하시겠습니까?',  {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var extendGoodsList = gagaAgGrid.getAllRowData(gridGoodsSetOptions);
+				$("#goodsSetForm input[name=extendGoodsList]").val(JSON.stringify(extendGoodsList));
+				gagajf.ajaxFormSubmit("/goods/set/save", "#goodsSetForm", fnGoodsSetFormClose);
+			}
+		});
+	});
+
+	//저장 조건 확인
+	var fnGoodsSetConditionCheck = function(){
+		var optCheck = false;
+		
+		if(gagajf.isNull($("#goodsSetForm input[name=goodsNm]").val())){
+			mcxDialog.alertC('상품명을 입력해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm input[name=goodsNm]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		if(gagajf.isNull($("#goodsSetForm select[name=colorCd]").val())){
+			mcxDialog.alertC('색상을 입력해 주세요.<br/>기준여부를 선택하시면<br/>해당브랜드의 색상을 노출합니다.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm select[name=colorCd]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		if (gagajf.isNull($("#goodsSetForm input[name=selfMallYn]").val())){
+			mcxDialog.alertC('자사노출여부를 선택해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm input[name=selfMallYn]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		if(gagajf.isNull($("#goodsSetForm select[name=styleYear]").val())){
+			mcxDialog.alertC('년도을 선택해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm select[name=styleYear]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		if(gagajf.isNull($("#goodsSetForm select[name=seasonCd]").val())){
+			mcxDialog.alertC('시즌을 선택해주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm select[name=seasonCd]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		if(gagajf.isNull($("#goodsSetForm select[name=sexGb]").val())){
+			mcxDialog.alertC('성별을 선택해주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm select[name=sexGb]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		if(gagajf.isNull($("#goodsSetForm input[name=makeNm]").val())){
+			mcxDialog.alertC('원산지를 입력해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm input[name=makeNm]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		var makeYmd = $("#goodsSetForm input[name=makeYmd]").val();
+		
+		if(gagajf.isNull(makeYmd)){
+			mcxDialog.alertC('제조년월일를 입력해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm input[name=makeYmd]").focus();
+				}
+			});	
+			return;
+		}
+		
+		if(makeYmd.length < 8){
+			mcxDialog.alertC('제조년월일를 바르게 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm input[name=makeYmd]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		if(isNaN(Date.parse(makeYmd.substr(0, 4) +'-'+ makeYmd.substr(4, 2) +'-'+ makeYmd.substr(6, 2)))){
+			mcxDialog.alertC('날짜형식이 아닙니다.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$("#goodsSetForm input[name=makeYmd]").focus();
+				}
+			});	
+			return false;
+		}
+		
+		var allData = gagaAgGrid.getAllRowData(gridGoodsSetOptions);
+		// Validation
+		if (!gagaAgGrid.validation(gridGoodsSetOptions, allData))
+			return false;
+		
+		var comSupplyCompCd = '';
+		var comSelfGoodsYn = '';
+		//기준여부 Y  존재하는지 확인
+		var checkBaseYn = false;
+		optCheck = false;
+		$.each(allData, function(index, item) {
+			if (index == 0){
+				comSelfGoodsYn = item.selfGoodsYn;
+				comSupplyCompCd = item.supplyCompCd;
+			}
+			
+			if (item.baseYn == "Y"){
+				checkBaseYn = true;
+			}
+			
+			if(item.goodsStat != "90"){
+				optCheck = true;
+				mcxDialog.alertC("상품상태를 확인해 주세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						gridGoodsSetOptions.api.setFocusedCell(index, "goodsStat", null);
+					}
+				});	
+				return false;
+			}
+			
+			if(Number(item.qty)  ==  0){
+				optCheck = true;
+				mcxDialog.alertC("수량을 입력해 주세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						gridGoodsSetOptions.api.setFocusedCell(index, "qty", null);
+					}
+				});	
+				return false;
+			}
+			
+			if (comSelfGoodsYn != item.selfGoodsYn){
+				optCheck = true;
+				mcxDialog.alertC("구상상품중 자사/입점상품 구분값이 다릅니다.\n확인해 주세요", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						gridGoodsSetOptions.api.setFocusedCell(index, "goodsCd", null);
+					}
+				});	
+				return false;
+			}else{
+				if (comSelfGoodsYn == "N" && (comSupplyCompCd != item.supplyCompCd)){
+					optCheck = true;
+					mcxDialog.alertC("구상상품중 입점은 같은 업체 상품만 가능합니다.\n확인해 주세요", {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							gridGoodsSetOptions.api.setFocusedCell(index, "goodsCd", null);
+						}
+					});	
+					return false;
+				}
+			}
+			
+			
+		});
+		
+		if(optCheck) {
+			return false;
+		}
+		
+		if (!checkBaseYn){
+			mcxDialog.alert('구성상품중 기준여부를 선택해 주세요.');
+			return false;
+		}
+		
+		return true;
+	}
+	
+	//상품삭제
+	var fnGoodsSetDeleteRow = function() {
+		var selectedData = gagaAgGrid.selectedRowData(gridGoodsSetOptions);
+		
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+		
+		var iTotalCnt = 0;
+		var iCnt = 0;
+		$.each(selectedData, function(index, item) {	
+			iTotalCnt ++;
+			if (item.crud == "C"){
+				gridGoodsSetOptions.api.updateRowData({remove: [item]});	
+				iCnt ++;
+			}
+		});
+	}
+	
+/*]]>*/
+</script>
+</html>

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

@@ -28,11 +28,11 @@
 						<col/>
 					</colgroup>
 					<tr>
-						<th>상품타이틀<i class="star"></i></th>
+						<th>상품타이틀<em class="required" title="필수"></em></th>
 						<td><input type="text" class="w100p" id="goodsTnm" name="goodsTnm"  maxlength="50" /></td>
 					</tr>
 					<tr>
-						<th>예약일시<i class="star"></i></th>
+						<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="예약시작일" />
 							<select name="applyStHH" id="applyStHH" required="required" data-valid-name="예약 시작시간">