Pārlūkot izejas kodu

Merge branch 'sowon' into develop

sowon4187 5 gadi atpakaļ
vecāks
revīzija
b2975d082a

+ 284 - 2
src/main/java/com/style24/persistence/mybatis/shop/TssPlan.xml

@@ -229,7 +229,7 @@
 	</insert>
 	
 	<select id="getPlanBrandList" parameterType="Plan" resultType="Plan">
-		/* TsaPlan.getPlanBrandList */
+		/* TssPlan.getPlanBrandList */
 		SELECT TP.PLAN_NM AS PLAN_NM
 		     , TP.PLAN_SQ AS PLAN_SQ
 		     , TB.BRAND_GROUP_ENM AS BRAND_GROUP_ENM
@@ -249,7 +249,7 @@
 	</select>
 	
 	<select id="getPlanCateList" parameterType="Plan" resultType="Plan">
-		/* TsaPlan.getPlanCateList */
+		/* TssPlan.getPlanCateList */
 		 SELECT TP.PLAN_NM AS PLAN_NM
 		      , TP.PLAN_SQ AS PLAN_SQ
 		      , TC.CATE1_NM AS CATE_NM
@@ -266,7 +266,289 @@
 		AND TP.DEL_YN = 'N'
 	</select>
 	
+	<delete id="deletePlanCate" parameterType="Plan">
+		/* TssPlan.deletePlanCate */
+		DELETE 
+		FROM TB_PLAN_CATE
+		WHERE PLAN_SQ = #{planSq}
+	</delete>
 	
+	<delete id="deletePlanBrand" parameterType="Plan">
+		/* TssPlan.deletePlanBrand */
+		DELETE 
+		FROM TB_PLAN_BRAND
+		WHERE PLAN_SQ = #{planSq}
+	</delete>
+	
+	<delete id="deletePlanCustGb" parameterType="Plan">
+		/* TssPlan.deletePlanCustGb */
+		DELETE 
+		FROM TB_PLAN_CUST_DIVISION
+		WHERE PLAN_SQ= #{planSq}
+	</delete>
+	
+	<!-- 기획전 수정 -->
+	<update id="updatePlanInfo" parameterType="Plan">
+		/* TssPlan.updatePlanInfo */
+		UPDATE TB_PLAN
+		   SET PLAN_GB = #{planGb}
+		     , FRONT_GB = #{frontGb}
+		     , PLAN_NM = #{planNm}
+		     , DISP_STDT = DATE_FORMAT(#{dispStdt} , '%Y-%m-%d %H:%i:%s')
+		     , DISP_EDDT = DATE_FORMAT(#{dispEddt} , '%Y-%m-%d %H:%i:%s')
+		     , CORNER_NM_DISP_YN = #{cornerNmDispYn}
+		     , OPEN_YN = #{openYn}
+		     , SITE_CD = #{siteCd}
+		     , DISP_ORD = IFNULL(#{dispOrd}, 999)
+		     , DTL_TITLE1 = #{dtlTitle1}
+		     , MAIN_PIMG = #{mainPimg}
+		     , MAIN_MIMG = #{mainMimg}
+		     , DTL_PIMG = #{dtlPimg}
+		     , DTL_MIMG = #{dtlMimg}
+		     , DEV_URL = #{devUrl}
+		     , BADGE_NM = #{badgeNm}
+		     , BADGE_FCOLOR = #{badgeFcolor}
+		     , BADGE_BCOLOR = #{badgeBcolor}
+		<if test='goodsLimitYn == "Y"'>
+		     , GOODS_LIMIT_YN = 'Y'
+		     , GOODS_LIMIT_QTY = #{goodsLimitQty}
+		</if>
+		<if test='goodsLimitYn == null or goodsLimitYn == "" or goodsLimitYn == "N"'>
+		     , GOODS_LIMIT_YN = 'N'
+		     , GOODS_LIMIT_QTY = 0
+		</if>
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = now()
+		WHERE  PLAN_SQ = #{planSq}
+	</update>
+	
+	<!-- 기획전 코너 목록 -->
+	<select id="getPlanCornerList" parameterType="Plan" resultType="Plan">
+		/* TssPlan.getPlanCornerList */
+		SELECT A.PLAN_SQ
+		     , B.PLAN_DTL_SQ
+		     , B.CORNER_NM
+		     , B.CORNER_DISP_TYPE
+	<!-- 	     , #{adminPreview} AS ADMIN_PREVIEW -->
+	         , FN_GET_USER_NM(B.REG_NO) AS REG_NM
+	         , FN_GET_USER_NM(B.UPD_NO) AS UPD_NM     
+	         , B.DISP_STDT 
+     	     , B.DISP_EDDT 
+     	     , B.DISP_ORD 
+		FROM   TB_PLAN A
+		     , TB_PLAN_DETAIL B
+		WHERE  A.PLAN_SQ = B.PLAN_SQ
+	<!-- 	<if test='adminPreview != "Y"'> 
+		AND    now() BETWEEN B.DISP_STDT AND B.DISP_EDDT
+		</if> -->
+		AND    A.PLAN_SQ = #{planSq}
+		ORDER  BY B.DISP_ORD
+	</select>
+	
+	<!-- 기획전 코너 저장 -->
+	<insert id="savePlanCornerInfo" parameterType="Plan">
+		/* TssPlan.savePlanCornerInfo */
+		<selectKey keyProperty="planDtlSq" resultType="Integer" order="AFTER">
+			SELECT LAST_INSERT_ID()	/* 기획전 일련번호  */
+		</selectKey>
+		INSERT INTO
+			      TB_PLAN_DETAIL (
+			            PLAN_SQ         
+                      , PLAN_DTL_SQ     
+                      , DISP_STDT       
+                      , DISP_EDDT       
+                      , CORNER_DISP_TYPE
+                      , CORNER_NM       
+                      , DISP_ORD        
+                      , REG_NO          
+                      , REG_DT          
+                      , UPD_DT          
+                      , UPD_NO          
+			      )
+			   VALUES (
+			    	   #{planSq}                                        
+                     , #{planDtlSq}                                      
+                     , DATE_FORMAT(#{dispStdt} , '%Y-%m-%d %H:%i:%s')     
+                     , DATE_FORMAT(#{dispEddt} , '%Y-%m-%d %H:%i:%s')   
+                     , #{cornerDispType}                                 
+                     , #{cornerNm}                                       
+                     , #{dispOrd}                                        
+                     , #{regNo}                                          
+                     , now()                                           
+                     , now()                                           
+                     , #{updNo}                                          
+			     )
+			   ON
+			      DUPLICATE KEY
+			   UPDATE
+			        DISP_STDT = DATE_FORMAT(#{dispStdt} , '%Y-%m-%d %H:%i:%s')      
+				  , DISP_EDDT = DATE_FORMAT(#{dispEddt} , '%Y-%m-%d %H:%i:%s')      
+				  , CORNER_DISP_TYPE = #{cornerDispType}                         
+				  , CORNER_NM = #{cornerNm}                                      
+				  , DISP_ORD = #{dispOrd}                                        
+				  , UPD_DT = now()                                             
+				  , UPD_NO = #{updNo}                                            
+	</insert>
+	
+	<!-- 기획전 코너 상품 목록 조회 건수 -->
+	<select id="getPlanGoodsListCount" parameterType="Plan" resultType="int">
+		/* TssPlan.getPlanGoodsListCount */
+		SELECT COUNT(*) AS CNT
+		FROM (
+		    SELECT
+		            G.GOODS_CD
+		          , G.GOODS_TYPE
+		          , G.SUPPLY_COMP_CD
+		          , G.SUPPLY_GOODS_CD
+		          , G.GOODS_NUM
+		          , G.GOODS_NM
+		          , G.GOODS_STAT
+		          , G.LIST_PRICE
+		          , G.CURR_PRICE
+		          , G.DC_RATE
+		          , G.FORMAL_GB
+		          , G.STYLE_YEAR
+		          , G.SEASON_CD
+		          , G.ERP_STOCK_LINK_YN
+		          , G.ERP_PRICE_LINK_YN
+		          , G.CHANGEABLE_YN
+		          , G.RETURNABLE_YN
+		          , G.NEW_CUST_ORD_YN
+		          , G.GIFT_PACK_YN
+		          , G.DELV_FEE_CD
+		          , G.MAIN_COLOR_CD
+		          , DATE_FORMAT(G.FRST_CFRM_DT, '%Y%m%d%H%i%S') AS FRST_CFRM_DT
+		          , G.SELL_FEE_RATE
+		          , DATE_FORMAT(G.PRICE_UPD_DT,'%Y%m%d%H%i%S') AS PRICE_UPD_DT
+		          , TG.REG_NO
+		          , DATE_FORMAT(TG.REG_DT,'%Y%m%d%H%i%S') AS REG_DT
+		          , TG.UPD_NO
+		          , DATE_FORMAT(TG.UPD_DT,'%Y%m%d%H%i%S') AS UPD_DT
+		          , G.TAG_PRICE
+		        FROM TB_GOODS G
+		        INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		        INNER JOIN TB_PLAN_GOODS TG ON G.GOODS_CD = TG.GOODS_CD 
+		        WHERE 1=1
+		        AND TG.PLAN_DTL_SQ = #{planDtlSq}
+	            AND TG.DEL_YN = 'N'
+		    ) CNT
+	</select>
+	
+	<!-- 기획전 코너 상품 목록 조회 -->
+	<select id="getPlanGoodsList" parameterType="Plan" resultType="Plan">
+		/* TssPlan.getPlanGoodsList */
+		SELECT Q.*
+		    , (CASE WHEN Q.GOODS_TYPE = 'G056_N' THEN (SELECT IFNULL(SUM(CURR_STOCK_QTY - BASE_STOCK_QTY),0) FROM VW_STOCK WHERE GOODS_CD = Q.GOODS_CD) 
+		            ELSE (SELECT IFNULL(SUM(CURR_STOCK_QTY - BASE_STOCK_QTY),0) FROM VW_STOCK_COMPOSE WHERE GOODS_CD = Q.GOODS_CD) 
+		            END) AS STOCK_QTY_SUM
+		    , FN_GET_USER_NM(REG_NO) AS REG_NM
+		    , FN_GET_USER_NM(UPD_NO) AS UPD_NM
+		    , (SELECT MAX(SYS_IMG_NM) FROM TB_GOODS_IMG  WHERE GOODS_CD = Q.GOODS_CD AND COLOR_CD = Q.MAIN_COLOR_CD AND DEFAULT_IMG_YN = 'Y' ) AS SYS_IMG_NM
+		    , CASE IFNULL((SELECT COUNT(SYS_IMG_NM) FROM TB_GOODS_IMG  WHERE GOODS_CD = Q.GOODS_CD AND COLOR_CD = Q.MAIN_COLOR_CD AND DEFAULT_IMG_YN = 'Y' ),0) 
+		            WHEN 0 THEN 'N'
+		            ELSE 'Y' END AS GOODS_IMAGE_YN
+		FROM (     
+			SELECT Z.*
+			FROM (
+			    SELECT A.*, @rownum := @rownum + 1 AS RNUM 
+			    FROM (
+			        SELECT
+			                 G.GOODS_CD                                                                   
+			               , G.GOODS_TYPE                                                                 
+			               , G.SUPPLY_COMP_CD                                                             
+			               , G.SUPPLY_GOODS_CD                                                            
+			               , G.GOODS_NUM                                                                  
+			               , G.GOODS_NM                                                                   
+			               , G.GOODS_STAT                                                                 
+			               , G.LIST_PRICE                                                                 
+			               , G.CURR_PRICE                                                                 
+			               , G.DC_RATE                                                                    
+			               , CASE G.FORMAL_GB WHEN 'G009_20' THEN '이월' ELSE '정상' END AS FORMAL_GB                                                                 
+			               , G.SEASON_CD       
+			               , (SELECT SUPPLY_COMP_NM
+                 				FROM   TB_SUPPLY_COMPANY
+                 				WHERE  SUPPLY_COMP_CD = G.SUPPLY_COMP_CD
+              				   ) AS SUPPLY_COMP_NM                                                           
+			               , G.ERP_STOCK_LINK_YN                                                          
+			               , G.ERP_PRICE_LINK_YN                                                          
+			               , G.CHANGEABLE_YN                                                              
+			               , G.RETURNABLE_YN                                                              
+			               , G.NEW_CUST_ORD_YN                                                            
+			               , G.GIFT_PACK_YN                                                               
+			               , G.DELV_FEE_CD                                                                
+			               , G.MAIN_COLOR_CD                                                              
+			               , G.FRST_CFRM_DT                  
+			               , G.SELL_FEE_RATE                                                              
+			               , G.PRICE_UPD_DT                   
+			               , TG.REG_NO                                                                    
+			               , TG.REG_DT                              
+			               , TG.UPD_NO                                                                    
+			               , TG.UPD_DT     
+			               , TG.PLAN_DTL_SQ                          
+			         FROM TB_GOODS G
+					        JOIN ( SELECT @rownum := 0) R
+					        INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+					        INNER JOIN TB_PLAN_GOODS TG ON G.GOODS_CD = TG.GOODS_CD 
+			         WHERE 1=1
+			         	 AND TG.PLAN_DTL_SQ = #{planDtlSq}
+			         	 AND TG.DEL_YN = 'N'
+			         ORDER BY G.REG_DT DESC, G.GOODS_CD
+		<include refid="getListPagingCondition_sql"/>
+		)Q
+	</select>
+	
+	<!-- 기획전 코너 상품저장 -->
+	<insert id="savePlanCornerGoods" parameterType="Plan">
+		/* TssPlan.savePlanCornerGoods */
+		INSERT INTO
+			      TB_PLAN_GOODS (
+			                PLAN_DTL_SQ
+				          , GOODS_CD
+				          , DISP_ORD
+				          , DEL_YN
+				          , REG_NO
+				          , REG_DT
+				          , UPD_DT
+				          , UPD_NO    
+			      )
+			   VALUES (
+			    	    #{planDtlSq}
+			          , #{goodsCd}
+			          , 0
+			          , 'N'
+			          , #{regNo}
+			          , now()
+			          , now()
+			          , #{updNo}                                  
+			     )
+			   ON
+			      DUPLICATE KEY
+			   UPDATE
+			        DEL_YN = 'N'
+		          , UPD_DT = now()
+		          , UPD_NO = #{updNo}                                  
+	</insert>
+	
+	<!-- 기획전 코너 삭제 처리 -->
+	<delete id="deletePlanCornerInfo" parameterType="Plan">
+		/* TssPlan.deletePlanCornerInfo */
+		DELETE 
+		FROM TB_PLAN_DETAIL 
+		WHERE  PLAN_SQ = #{planSq}
+		AND    PLAN_DTL_SQ = #{planDtlSq}
+	</delete>
+	
+	<!-- 기획전 코너 상품 삭제 처리 -->
+	<update id="deletePlanCornerGoods" parameterType="Plan">
+		/* TssPlan.deletePlanCornerGoods */
+		UPDATE TB_PLAN_GOODS
+		SET    DEL_YN = 'Y'
+		     , DISP_ORD = 0
+		WHERE  PLAN_DTL_SQ = #{planDtlSq}
+		<if test="goodsCd != null and goodsCd != ''">
+		AND    GOODS_CD = #{goodsCd}
+		</if>
+	</update>
 	
 	
 

+ 106 - 0
src/main/java/com/style24/scm/biz/dao/TssPlanDao.java

@@ -101,4 +101,110 @@ public interface TssPlanDao {
 	 * @since 2021. 05. 05
 	 */
 	Collection<Plan> getPlanCateList(Plan param);
+	
+	/**
+	 * 기획전 카테고리 삭제
+	 *
+	 * @param
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void deletePlanCate(Plan param);
+	
+	/**
+	 * 기획전 브랜드 삭제
+	 *
+	 * @param
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void deletePlanBrand(Plan param);
+	
+	/**
+	 * 기획전 회원구분 삭제
+	 *
+	 * @param
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void deletePlanCustGb(Plan param);
+	
+	/**
+	 * 기획전 웹 수정
+	 *
+	 * @param 기획전 등록 정보
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void updatePlanInfo(Plan param);
+	
+	/**
+	 * 기획전 코너 목록 조회
+	 *
+	 * @param 기획전 일련번호
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	Collection<Plan> getPlanCornerList(Plan param);
+	
+	/**
+	 * 기획전 코너 정보 저장
+	 *
+	 * @param 기획전 코너 정보
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void savePlanCornerInfo(Plan param);
+	
+	/**
+	 * 기획전 코너 상품 조회 건수
+	 *
+	 * @param 기획전 상세번호
+	 * @return
+	 * @author sowon
+	 * @since  2021. 05. 06
+	 */
+	int getPlanGoodsListCount(Plan param);
+	
+	/**
+	 * 기획전 코너 상품 조회
+	 *
+	 * @param 기획전 상세번호
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	Collection<Plan> getPlanGoodsList(Plan param);
+	
+	/**
+	 * 기획전 코너 상품 등록
+	 *
+	 * @param
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void savePlanCornerGoods(Plan param);
+	
+
+	/**
+	 * 기획전 코너 삭제
+	 *
+	 * @param 기획전 상세번호
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void deletePlanCornerInfo(Plan param);
+	
+	/**
+	 * 기획전 코너 상품 삭제
+	 *
+	 * @param 기획전 상세번호
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	void deletePlanCornerGoods(Plan param);
+	
+	
+	
 }

+ 377 - 0
src/main/java/com/style24/scm/biz/service/TssPlanService.java

@@ -1,6 +1,8 @@
 package com.style24.scm.biz.service;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -8,11 +10,16 @@ import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseBody;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.web.parameter.GagaMap;
 import com.gagaframework.web.util.GagaDateUtil;
 import com.gagaframework.web.util.GagaFileUtil;
 import com.gagaframework.web.util.GagaStringUtil;
+import com.style24.persistence.TscPageRequest;
 import com.style24.persistence.domain.Plan;
 import com.style24.scm.biz.dao.TssPlanDao;
 import com.style24.scm.support.security.session.TssSession;
@@ -223,4 +230,374 @@ public class TssPlanService {
 	public Collection<Plan> getPlanCateList(Plan param){
 		return planDao.getPlanCateList(param);
 	}
+	
+	/**
+	 * 기획전 웹 수정
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 8
+	 */
+	@Transactional("shopTxnManager")
+	public void updatePlanInfo(Plan param) {
+		Plan plan = new Plan();
+		log.debug("param {}", param);
+		String targetPath = env.getProperty("upload.default.target.path") + "/planning";
+		param.setRegNo(TssSession.getInfo().getUserNo());
+		param.setUpdNo(TssSession.getInfo().getUserNo());
+
+		// 이미지 삭제 여부에 따른 이미지 삭제 처리
+		if (("Y").equals(param.getOrgMainPimgDelYn())) {
+			deleteFile(targetPath, param.getOrgMainPimg());
+		}
+
+		if (("Y").equals(param.getOrgMainMimgDelYn())) {
+			deleteFile(targetPath, param.getOrgMainMimg());
+		}
+
+		if (("Y").equals(param.getOrgDtlPimgDelYn())) {
+			deleteFile(targetPath, param.getOrgDtlPimg());
+		}
+
+		if (("Y").equals(param.getOrgDtlMimgDelYn())) {
+			deleteFile(targetPath, param.getOrgDtlMimg());
+		}
+
+		if (("Y").equals(param.getOrgReplyImgDelYn())) {
+			//param.setReplyImg(null);
+			deleteFile(targetPath, param.getOrgReplyImg());
+		}
+
+		// 기존 기획전 카테고리 삭제 
+		planDao.deletePlanCate(param);
+		
+		String[] cate = param.getMultiCate();
+		// 기획전 카테고리insert
+		for (int j = 0; j < cate.length; j++) {
+			plan.setCateNo(cate[j]);
+			plan.setPlanSq(param.getPlanSq());
+			plan.setRegNo(TssSession.getInfo().getUserNo());
+			plan.setUpdNo(TssSession.getInfo().getUserNo());
+			planDao.createPlanCate(plan);
+		}
+		
+		// 기존 기획전 브랜드 삭제
+		planDao.deletePlanBrand(param);;
+		
+		
+		
+		String[] brand = param.getMultiBrand();
+		// 기획전 브랜드 insert
+		for (int j = 0; j < brand.length; j++) {
+			plan.setBrandGroupNo(brand[j]);
+			plan.setPlanSq(param.getPlanSq());
+			plan.setRegNo(TssSession.getInfo().getUserNo());
+			plan.setUpdNo(TssSession.getInfo().getUserNo());
+			planDao.createPlanBrand(plan);
+		}
+		
+		//기존 회원구분 삭제
+		planDao.deletePlanCustGb(param);
+		
+		
+		// 기획전 회원구분 insert
+		String[] custGb = param.getUsableCustGbArr();
+		for (int j = 0; j < custGb.length; j++) {
+			plan.setCustGb(custGb[j]);
+			plan.setPlanSq(param.getPlanSq());
+			plan.setRegNo(TssSession.getInfo().getUserNo());
+			planDao.createPlanCustGb(plan);
+		}
+		
+		//기존 회원등급 삭제
+//		planDao.deletePlanCustGrade(param);
+//		
+//		
+//		// 기획전 회원등급 insert
+//		String[] custGrade = param.getUsableCustGradeArr();
+//		for (int j = 0; j < custGrade.length; j++) {
+//			plan.setCustGrade(custGrade[j]);
+//			plan.setPlanSq(param.getPlanSq());
+//			plan.setRegNo(TsaSession.getInfo().getUserNo());
+//			planDao.createPlanCustGrade(plan);
+//		}
+//		
+		int ind = 1;
+		if(param.getMainPimg() != null && !"".equals(param.getMainPimg())){
+			String imgInd = String.valueOf(ind);
+			if (ind < 10) {
+				imgInd = "0" + imgInd;
+			}
+			if (!param.getMainPimg().contains("planning")) {
+				String planUploadPath = env.getProperty("upload.default.target.path");
+				String yearMonth = GagaDateUtil.getToday().substring(0, 6);
+				planUploadPath = GagaFileUtil.getConcatenationPath(planUploadPath, "/planning");
+				File newFile = new File(GagaFileUtil.getConcatenationPath(planUploadPath, param.getMainPimg()));
+				planUploadPath = GagaFileUtil.getConcatenationPath(planUploadPath, yearMonth);
+				String newFilename = "PLANNING_" + GagaDateUtil.getTodayDateTime() + "_" + imgInd + "." + StringUtils.getFilenameExtension(param.getMainPimg());
+				File uniqueFile = GagaFileUtil.getUniqueFile(new File(GagaFileUtil.getConcatenationPath(planUploadPath, newFilename)));
+				// Rename a file
+				File path = new File(planUploadPath);
+				if (!path.exists()) {
+					path.mkdir();
+				}
+				newFile.renameTo(uniqueFile);
+				param.setMainPimg("/planning/" + yearMonth + "/" + newFilename);
+			}
+			
+		}
+		if(param.getMainMimg() != null && !"".equals(param.getMainMimg())){
+			String imgInd = String.valueOf(ind);
+			if (ind < 10) {
+				imgInd = "0" + imgInd;
+			}
+			if(!param.getMainMimg().contains("planning")) {
+				String planUploadPath = env.getProperty("upload.default.target.path");
+				String yearMonth = GagaDateUtil.getToday().substring(0, 6);
+				planUploadPath = GagaFileUtil.getConcatenationPath(planUploadPath, "/planning");
+				File newFile = new File(GagaFileUtil.getConcatenationPath(planUploadPath, param.getMainMimg()));
+				planUploadPath = GagaFileUtil.getConcatenationPath(planUploadPath, yearMonth);
+				String newFilename = "PLANNING_" + GagaDateUtil.getTodayDateTime() + "_" + imgInd + "." + StringUtils.getFilenameExtension(param.getMainMimg());
+				File uniqueFile = GagaFileUtil.getUniqueFile(new File(GagaFileUtil.getConcatenationPath(planUploadPath, newFilename)));
+				// Rename a file
+				File path = new File(planUploadPath);
+				if (!path.exists()) {
+					path.mkdir();
+				}
+				newFile.renameTo(uniqueFile);
+				param.setMainMimg("/planning/" + yearMonth + "/" + newFilename);
+			}
+			
+		}
+		
+		// 최종업데이트 
+		planDao.updatePlanInfo(param);
+
+		//기획전 응모이벤트
+//		if (StringUtils.isNotBlank(param.getPrivacyPolicy())) {
+//			int i = 0;
+//			for (String planQtitle : param.getPlanQtitle()) {
+//				PlanQuestAnswer planQuestAnswer = new TsaPlanQuestAnswer();
+//				planQuestAnswer.setPlanSq(param.getPlanSq());
+//				planQuestAnswer.setPlanQtitle(planQtitle);
+//				planQuestAnswer.setAttachYn(param.getAttachYn()[i]);
+//				planQuestAnswer.setQuestNo(i);
+//				planQuestAnswer.setRegNo(param.getRegNo());
+//				planQuestAnswer.setUpdNo(param.getUpdNo());
+//				planDao.savePlanQuestion(planQuestAnswer);
+//				i++;
+//			}
+//		}
+	}
+	
+	/**
+	 * 기획전 코너 목록 조회
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	public Collection<Plan> getPlanCornerList(Plan param) {
+		
+		Collection<Plan> cornerList = planDao.getPlanCornerList(param);
+		for (Plan corner : cornerList) {
+			// 날짜 설정
+			String[] stDate = corner.getDispStdt().split(" ");
+			corner.setStartSearchDate(stDate[0]);                                                 
+			corner.setStartSearchTime(stDate[1].substring(0, 8));
+			
+			String[] edDate = corner.getDispEddt().split(" ");
+			corner.setEndSearchDate(edDate[0]);                                                 
+			corner.setEndSearchTime(edDate[1].substring(0, 8));
+		}
+		return cornerList;
+	}
+	
+	/**
+	 * 기획전 코너 저장
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@Transactional("shopTxnManager")
+	public void savePlanCornerInfo(Collection<Plan> paramList) {
+		for (Plan cornerInfo : paramList) {
+			cornerInfo.setRegNo(TssSession.getInfo().getUserNo());
+			cornerInfo.setUpdNo(TssSession.getInfo().getUserNo());
+			planDao.savePlanCornerInfo(cornerInfo);
+		}
+
+	}
+	
+	/**
+	 * 기획전 코너 상품 조회 건수
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	public int getPlanGoodsListCount(Plan param) {
+		return planDao.getPlanGoodsListCount(param);
+	}
+
+	/**
+	 * 기획전 코너 상품 조회
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	public Collection<Plan> getPlanGoodsList(Plan param) {
+		return planDao.getPlanGoodsList(param);
+	}
+	
+	/**
+	 * 파일 삭제
+	 *
+	 * @param targetPath
+	 * @param excelFilename
+	 * @author sowon
+	 * @since 2021. 5. 6
+	 */
+	private void deleteFile(String targetPath, String excelFilename) {
+		// 파일 삭제
+		try {
+			GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, excelFilename));
+		} catch (IOException e) {
+			// Nothing Do
+		}
+	}
+	
+	/**
+	 * 기획전 코너 상품 엑셀 저장
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 5. 6
+	 */
+	@Transactional("shopTxnManager")
+	public void createExceluploadGoods(Collection<GagaMap> ecxelGoodsList, Plan param) {
+		String targetPath = env.getProperty("upload.excel.target.path");
+
+		if ((ecxelGoodsList == null || ecxelGoodsList.isEmpty())) {
+			deleteFile(targetPath, param.getExcelFileNm());
+			throw new IllegalStateException("저장 할 데이터가 없습니다.");
+		}
+
+		Collection<Plan> dtlPlan = new ArrayList<>();
+		Collection<Plan> goodsList = new ArrayList<>();
+
+		long tempPlanDtlSq = 0;
+		for (GagaMap gagaMap : ecxelGoodsList) {
+			Plan planGoods = mapper.convertValue(gagaMap, Plan.class);
+			planGoods.setPlanSq(param.getPlanSq());
+
+			String planDtlSq = String.valueOf(planGoods.getPlanDtlSq());
+			if (org.apache.commons.lang3.StringUtils.isBlank(planDtlSq)) {
+				throw new IllegalStateException("상품코드 : " + planGoods.getGoodsCd() + " 기획전 코너 번호가 없습니다.");
+			}
+
+			if (org.apache.commons.lang3.StringUtils.isBlank(planGoods.getGoodsCd())) {
+				throw new IllegalStateException("비어 있는 상품코드가 존재합니다.");
+			}
+
+			// 중복 확인 위한 데이터 적제
+			if (tempPlanDtlSq != planGoods.getPlanDtlSq()) {
+				dtlPlan.add(planGoods);
+			}
+
+			// 상품 데이터 적제
+			goodsList.add(planGoods);
+		}
+
+		// 기획전 유효성 체크
+		for (Plan plan : dtlPlan) {
+			Plan searchCorner = new Plan();
+			searchCorner.setPlanSq(plan.getPlanSq());
+			searchCorner.setPlanDtlSq(plan.getPlanDtlSq());
+
+			Collection<Plan> cornerList = planDao.getPlanCornerList(searchCorner);
+
+			if (cornerList == null || cornerList.isEmpty()) {
+				throw new IllegalStateException("상품코드 : " + plan.getGoodsCd() + "의 " + plan.getPlanDtlSq() + " 기획전 코너가 존재 하지 않습니다.");
+			}
+		}
+
+		// 기획전 상품 저장
+		for (Plan goods : goodsList) {
+			savePlanCornerGoods(goods);
+		}
+	}
+	
+	/**
+	 * 기획전 코너 상품 저장
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@Transactional("shopTxnManager")
+	public void savePlanCornerGoods(Plan param) {
+		Plan plan = new Plan();
+		
+		plan.setRegNo(TssSession.getInfo().getUserNo());
+		plan.setUpdNo(TssSession.getInfo().getUserNo());
+		plan.setGoodsCd(param.getGoodsCd());
+		plan.setPlanDtlSq(param.getPlanDtlSq());
+		planDao.savePlanCornerGoods(plan);
+	}
+	
+	/**
+	 * 기획전 코너 상품 추가
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@Transactional("shopTxnManager")
+	public void savePlanGoods(Collection<Plan> paramList) {
+		for (Plan param : paramList) {
+			savePlanCornerGoods(param);
+		}
+	}
+	
+	/**
+	 * 기획전 코너 삭제 처리
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@Transactional("shopTxnManager")
+	public void deletePlanCornerInfo(Collection<Plan> paramList) {
+		for (Plan cornerInfo : paramList) {
+			planDao.deletePlanCornerInfo(cornerInfo);
+			planDao.deletePlanCornerGoods(cornerInfo);
+		}
+	}
+	
+	/**
+	 * 기획전 코너 상품 삭제 처리
+	 *
+	 * @param
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@Transactional("shopTxnManager")
+	public void deletePlanCornerGoods(Collection<Plan> paramList) {
+		for (Plan cornerInfo : paramList) {
+			planDao.deletePlanCornerGoods(cornerInfo);
+		}
+	}
 }

+ 174 - 2
src/main/java/com/style24/scm/biz/web/TssMarketingController.java

@@ -8,6 +8,7 @@ import com.style24.core.biz.service.TscCouponService;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -16,8 +17,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 
+import com.gagaframework.excel.GagaExcelUtil;
 import com.gagaframework.web.parameter.GagaMap;
 import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.rest.server.GagaResponseStatus;
+import com.gagaframework.web.util.GagaFileUtil;
 import com.style24.core.support.env.TscConstants;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.TscPageRequest;
@@ -41,6 +45,9 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class TssMarketingController extends TssBaseController {
 
+	@Autowired
+	private Environment env;
+	
 	@Autowired
 	private TscMessageByLocale message;
 	
@@ -124,7 +131,7 @@ public class TssMarketingController extends TssBaseController {
 	 *
 	 * @return
 	 * @author sowon
-	 * @since 2021. 2. 04
+	 * @since 2021. 05. 05
 	 */
 	@GetMapping("/planning/detail/form")
 	public ModelAndView planDetailForm(Plan param) {
@@ -179,7 +186,7 @@ public class TssMarketingController extends TssBaseController {
 	 *
 	 * @return
 	 * @author sowon
-	 * @since 2021. 2. 4
+	 * @since 2021. 05. 05
 	 */
 	@PostMapping("/planning/detail/create")
 	@ResponseBody
@@ -187,6 +194,171 @@ public class TssMarketingController extends TssBaseController {
 		planService.createPlanInfo(param);
 		return super.ok(message.getMessage("SUCC_0001"));
 	}
+	
+	/**
+	 * 기획전 웹 수정
+	 *
+	 * @return
+	 * @author sowon		
+	 * @since 2021. 05. 06
+	 */
+	@PostMapping("/plan/detail/update")
+	@ResponseBody
+	public GagaResponse updatePlanInfo(@RequestBody Plan param) {
+		planService.updatePlanInfo(param);
+		return super.ok(message.getMessage("SUCC_0002"));
+	}
+	
+	/**
+	 * 기획전 코너 팝업 화면
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@GetMapping("/planning/corner/list/form")
+	public ModelAndView planCornerListForm(Plan param) {
+		ModelAndView mav = new ModelAndView();
+
+		// 코너유형목록
+		mav.addObject("cornerDispTypeList", rendererService.getCommonCodeList("G045", "Y"));
+
+		// 코너유형
+		mav.addObject("planDtlStatList", rendererService.getCommonCodeList("G044", "Y"));
+
+		// 상품상태
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y"));
+
+		// 기획전 상세 정보
+		mav.addObject("planInfo", planService.getPlanDetailInfo(param));
+
+		mav.setViewName("marketing/PlanCornerListForm");
+
+		return mav;
+	}
+	
+	/**
+	 * 기획전 코너 목록
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@PostMapping("/planning/corner/list")
+	@ResponseBody
+	public Collection<Plan> getPlanCornerList(@RequestBody Plan param) {
+		return planService.getPlanCornerList(param);
+	}
+	
+	/**
+	 * 기획전 코너 저장
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@PostMapping("/planning/corner/save")
+	@ResponseBody
+	public GagaResponse savePlanCornerInfo(@RequestBody Collection<Plan> paramList) {
+		planService.savePlanCornerInfo(paramList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 기획전 코너 상품 조회
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 16
+	 */
+	@PostMapping("/planning/corner/goods/list")
+	@ResponseBody
+	public GagaMap getPlanGoodsList(@RequestBody Plan plan) {
+		GagaMap result = new GagaMap();
+
+		if ("Y".equals(plan.getPageYn())) {
+			plan.setPageable(new TscPageRequest(plan.getPageNo() - 1, plan.getPageSize()));
+			plan.getPageable().setTotalCount(planService.getPlanGoodsListCount(plan));
+		}
+		result.set("pageing", plan);
+		result.set("planGoodsList", planService.getPlanGoodsList(plan));
+		return result;
+	}
+	
+	/**
+	 * 기획전 코너 상품 엑셀상품추가
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@PostMapping("/planning/corner/goods/excelupload")
+	@ResponseBody
+	public GagaMap createExceluploadGoods(@RequestBody Plan param) throws Exception {
+		String targetPath = env.getProperty("upload.excel.target.path") + "/excel/";
+		String[] goodsNames = {"planDtlSq", "goodsCd"};
+
+		Collection<GagaMap> ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, param.getExcelFileNm()), 0, goodsNames, 0);
+
+		try {
+			planService.createExceluploadGoods(ecxelGoodsList, param);
+		} catch (Exception e) {
+			// 파일 삭제
+			GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, param.getExcelFileNm()));
+			throw new IllegalStateException(e.getMessage());
+		}
+
+		// 파일 삭제
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, param.getExcelFileNm()));
+
+		GagaMap result = new GagaMap();
+		result.set("status", GagaResponseStatus.SUCCESS.getCode()); // 200
+		result.set("message", message.getMessage("SUCC_0001"));
+		return result;
+	}
+	
+	/**
+	 * 기획전 코너 상품 추가
+	 *
+	 * @return
+	 * @author sowon
+	 * @since  2021. 05. 06
+	 */
+	@PostMapping("/planning/corner/goods/save")
+	@ResponseBody
+	public GagaResponse savePlanGoods(@RequestBody Collection<Plan> paramList) {
+		planService.savePlanGoods(paramList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+	
+	/**
+	 * 기획전 코너 삭제
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 05. 06
+	 */
+	@PostMapping("/planning/corner/delete")
+	@ResponseBody
+	public GagaResponse deletePlanCornerInfo(@RequestBody Collection<Plan> paramList) {
+		planService.deletePlanCornerInfo(paramList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+	
+	/**
+	 * 기획전 코너 상품 삭제
+	 *
+	 * @return
+	 * @author sowon
+	 * @since 2021. 2. 18
+	 */
+	@PostMapping("/planning/corner/goods/delete")
+	@ResponseBody
+	public GagaResponse deletePlanCornerGoods(@RequestBody Collection<Plan> paramList) {
+		planService.deletePlanCornerGoods(paramList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
 
     /**
      * 쿠폰목록 화면

+ 541 - 0
src/main/webapp/WEB-INF/views/marketing/PlanCornerListForm.html

@@ -0,0 +1,541 @@
+<!DOCTYPE html>
+<html lang="ko" xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : PlanCornerListForm.html
+ * @desc    : 기획전 코너 관리 화면 Page
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.05.06   sowon   최초 작성
+ *******************************************************************************
+ -->
+
+<div class="modalPopup" data-width="1200" data-height="800" id="popupPlanCorner">
+
+	<div class="panelStyle" style="height: 750px;">
+		<div class="panelTitle">
+			<strong>기획전 관리</strong>
+			<button type="button" class="close"	onclick="uifnPopupClose('popupPlanCorner')">
+				<i class="fa fa-times"></i>
+			</button>
+		</div>
+
+		<div class="panelContent">
+			<form th:object="${planInfo}" id="planCornerListForm"
+				name="planCornerListForm" action="#"
+				th:action="@{'/marketing/planning/corner/list'}" th:method="post">
+				<input type="hidden" th:field="*{planSq}" />
+				<input type="hidden" th:field="*{planDtlSq}" />
+				<table class="frmStyle" style="margin-bottom: 10px;">
+					<colgroup>
+						<col style="width: 10%;" />
+						<col style="width: 10%;" />
+						<col style="width: 10%;" />
+						<col style="width: 20%;" />
+						<col style="width: 10%;" />
+						<col style="width: 15%;" />
+						<col style="width: 10%;" />
+						<col style="width: 15%;" />
+					</colgroup>
+					<tr>
+						<th>기획전번호</th>
+						<td><label th:text="*{planSq}" id="planSq"></label></td>
+						<th>기획전명</th>
+						<td><label th:text="*{planNm}" id="planNm"></label></td>
+						<th>기획전시작일</th>
+						<td><label th:text="*{dispStdt}" id="dispStdt"></label></td>
+						<th>기획전종료일</th>
+						<td><label th:text="*{dispEddt}" id="dispEddt"></label></td>
+					</tr>
+				</table>
+
+				<div class="panelContent">
+					<ul class="panelBar">
+						<li class="boxContentBtnT" style="margin-left: -20px; margin-right: -23px;">
+							<span class="btnLeft">
+								<button type="button" class="btn btn-warning btn-sm" id="btnAddRow">행추가</button>
+								<button type="button" class="btn btn-danger btn-sm" id="btnDeleteRow">행삭제</button>
+							</span> 
+						</li>
+						<li class="right">
+							<span class="btnRight"> 
+								<!-- <button type="button" class="btn btn-default btn-lg" onclick="fnCornerCopyPopup();">코너복사</button> -->
+								<button type="button" class="btn btn-success btn-lg" onclick="fnPlanCornerSave();">저장</button>
+						   </span>
+					   </li>
+					</ul>
+					<div id="gridListCorner" style="width: 100%; max-height: 230px; height: 230px;" 	class="ag-theme-balham"></div>
+				</div>
+			</form>
+		</div>
+
+		<div class="panelContent">
+			<div>
+				<h4>
+					코너명 : <label id="cornerNm"></label>
+				</h4>
+				<div class="aR" style="float: right; margin-top: 10px;">
+					<button type="button" class="btn btn-Right btn-default btn-lg"onclick="fnGoodsExcelUpload();">엑셀상품추가</button>
+					<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF012');">엑셀상품추가 양식 다운로드</button>
+					<button type="button" class="btn btn-default btn-lg" onclick="fnOpenGoodsPopup();">상품추가</button>
+					<!-- <button type="button" class="btn btn-default btn-lg"onclick="fnDispOrdChange();">순서변경</button> -->
+					<button type="button" class="btn btn-danger btn-lg"	onclick="fnDeleteGoods();">선택삭제</button>
+				</div>
+			</div>
+
+			<div id="gridListGoods"	style="width: 100%; max-height: 350px; height: 350px;" class="ag-theme-balham lh60"></div>
+			<ul class="panelBar">
+				<li class="center">
+					<div class="tablePaging" id="planListPagination"></div>
+				</li>
+			</ul>
+		</div>
+
+	</div>
+</div>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var planInfo = [[${planInfo}]];
+	var cornerDispTypeList = gagajf.convertToArray([[${cornerDispTypeList}]]);
+	var planDtlStatList = gagajf.convertToArray([[${planDtlStatList}]]);
+	var goodsStatList =gagajf.convertToArray([[${goodsStatList}]]);
+	var uploadGoodsUrl = [[${@environment.getProperty('upload.goods.view')}]];
+
+	var columnDefsCorner = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: "코너번호"		, field:'planDtlSq'			, width:120, cellClass: 'text-center', editable: false },
+		{headerName: "코너명"			, field:'cornerNm'			, width:400, cellClass: 'text-left',
+			cellRenderer: function(params) {return '<a href="javascript:void(0);">' + params.value + '</a>'; },
+			cellEditor: 'textCellEditor',
+			cellEditorParams: { maxlength: 50, required: true }
+		},
+		{headerName: "코너유형"		, field:'cornerDispType'		, width:180, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(cornerDispTypeList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(cornerDispTypeList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(cornerDispTypeList, params.newValue); }
+		},
+		{headerName: "전시순서"		, field:'dispOrd'				, width:100, cellClass: 'text-right',
+			cellEditor: 'textCellEditor',
+			cellEditorParams: { maxlength: 3, required: true }
+		},
+		{headerName: "기획전 일련번호"	, field:'planSq'	, width:90, cellClass: 'text-left', hide: true},
+		{headerName: "시작일"			, field:'startSearchDate'	, width:110, cellClass: 'text-center',
+			cellEditor: 'datePicker',
+			cellEditorParams: { maxlength: 10, required: true },
+		},
+		{headerName: "시작시간"		, field:'startSearchTime'	, width:150, cellClass: 'text-center',
+			cellEditor: 'dateTimer',
+			cellEditorParams: { maxlength: 8, required: true },
+		},
+		{headerName: "종료일"			, field:'endSearchDate'		, width:110, cellClass: 'text-center',
+			cellEditor: 'datePicker',
+			cellEditorParams: { maxlength: 10, required: true }
+		},
+		{headerName: "종료시간"		, field:'endSearchTime'		, width:150, cellClass: 'text-center',
+			cellEditor: 'dateTimer',
+			cellEditorParams: { maxlength: 8, required: true },
+		},
+		{headerName: "등록자"			, field:'regNm'				, width:120, cellClass: 'text-center', editable: false },
+		{headerName: "수정자"			, field:'updNm'				, width:120, cellClass: 'text-center', editable: false }
+	];
+
+	var gridOptionsCorner = gagaAgGrid.getGridOptions(columnDefsCorner);
+	gridOptionsCorner.suppressRowClickSelection = true;
+	gridOptionsCorner.stopEditingWhenGridLosesFocus = true;
+	gridOptionsCorner.defaultColDef.editable = true;
+	gridOptionsCorner.rowSelection = 'multiple';
+
+	
+	// 코너 셀 클릭 이벤트
+	gridOptionsCorner.onCellClicked = function(event) {
+		var field = event.colDef.field;
+		if (field != 'cornerNm') return;
+
+		fnBindSearch(event.data);
+	}
+
+	// 코너 상품 조회 바인딩
+	var fnBindSearch = function(data) {
+		if (!gagajf.isNull(data.cornerNm)) {
+
+			$('#cornerNm').html(data.cornerNm);
+			_planDtlSq = data.planDtlSq;
+
+			fnConnerGoodsSearch();
+		}
+	}
+
+	// 코너 상품 조회
+	var fnConnerGoodsSearch = function() {
+		var actionUrl = '/marketing/planning/corner/goods/list';
+		var data = {planDtlSq:_planDtlSq};
+		var jsonData = JSON.stringify(data);
+
+		gagajf.ajaxJsonSubmit(actionUrl, jsonData, function(data) {
+			gridOptionsGoods.api.setRowData(data.planGoodsList);
+		});
+	}
+
+	// 코너 조회
+	var fnCornerSearch = function() {
+		var formId = '#planCornerListForm';
+		gagaAgGrid.fetch($(formId).prop('action'), gridOptionsCorner, formId
+						, function() {
+								$('#gridListGoods').html('');
+								$('#cornerNm').html('');
+								gagaAgGrid.createGrid('gridListGoods', gridOptionsGoods);
+				});
+		
+		uifnPopupClose('fnCreateGoods');
+	}
+	// 행추가
+	$('#btnAddRow').on('click', function() {
+		var allData = gagaAgGrid.getAllRowData(gridOptionsCorner);
+		var planSq = $('#planCornerListForm input[name=planSq]').val();
+		var stdt = planInfo.dispStdt.split(" ");
+		var eddt = planInfo.dispEddt.split(" ");
+
+		if (allData.length > 0 && typeof allData[0].crud == 'undefined') {
+			mcxDialog.alert('추가 된 코너를 저장 후 코너를 추가하세요.');
+			return;
+		} else {
+	
+			var data = { planDtlSq: '', planSq:planSq, cornerNm:'',cornerDispType: '', startSearchDate: _today, startSearchTime: stdt[1], endSearchDate: eddt[0], endSearchTime: eddt[1]};
+			gagaAgGrid.addRowData(gridOptionsCorner, data);
+		}
+
+	});
+
+	// 행삭제
+	$('#btnDeleteRow').on('click', function() {
+		var selectData = gagaAgGrid.selectedRowData(gridOptionsCorner);
+
+		if (selectData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+
+		mcxDialog.confirm('선택된 코너를 삭제하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(selectData);
+
+				gagajf.ajaxJsonSubmit('/marketing/planning/corner/delete', jsonData, fnCornerSearch);
+			}
+		});
+	});
+
+	// 코너승인
+	var fnCornerConfirm = function() {
+		var selectData = gagaAgGrid.selectedRowData(gridOptionsCorner);
+		if (selectData.length < 1) {
+			mcxDialog.alert('승인 할 코너가 없습니다.');
+			return;
+		}
+
+		if (selectData.length == 1) {
+			if (gagajf.isNull(selectData[0].planDtlStat)) {
+				mcxDialog.alert('승인할 코너가 없습니다.');
+				return;
+			}
+		}
+
+		var Msg = '';
+		$(selectData).each(function(idx, data) {
+			if (data.planDtlStat == '90') {
+				Msg = '승인상태가 삭제인 코너가 존재합니다.<br/>선택한 코너를 승인 하시겠습니까?';
+			}
+			if (data.planDtlStat != '20') {
+				data.planDtlStat = '20'; // 승인
+			}
+		});
+
+		Msg = !gagajf.isNull(Msg) ? Msg : '선택 된 코너를 승인 하시겠습니까?';
+		mcxDialog.confirm(Msg, {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(selectData);
+				gagajf.ajaxJsonSubmit('/marketing/plan/corner/confirm', jsonData, fnCornerSearch);
+			}
+		});
+	}
+
+	// 코너 저장
+	var fnPlanCornerSave = function() {
+		var changeData = gagaAgGrid.getChangedData(gridOptionsCorner);
+
+		if (changeData.length < 1) {
+			mcxDialog.alert('변경 된 코너가 없습니다.');
+			return;
+		}
+
+		// Validation
+		if (!gagaAgGrid.validation(gridOptionsCorner, changeData))
+			return;
+
+		var result = true;
+		$(changeData).each(function(idx, data) {
+			var stdt = planInfo.dispStdt.split(" ");
+			var eddt = planInfo.dispEddt.split(" ");
+
+			// 날짜 유효성 체크
+			if (Number(stdt[0]) > Number(data.startSearchDate)) {
+				mcxDialog.alert('코너의 시작일이 유효하지 않습니다.');
+				result = false;
+			}
+
+			if (Number(eddt[0]) < Number(data.endSearchDate)) {
+				mcxDialog.alert('코너의 종료일이 유효하지 않습니다.');
+				result = false;
+			}
+
+			if (Number(data.startSearchDate.replaceAll("-", "")) > Number(data.endSearchDate.replaceAll("-", ""))) {
+				mcxDialog.alert('진행기간 시작일자는 종료일자보다 클 수 없습니다.');
+				result = false;
+			}
+
+			if (Number(data.startSearchDate.replaceAll("-", "")) < Number(_today.replaceAll("-", "")) && data.crud == 'C') {
+				mcxDialog.alert('시작일자는 오늘포함 이후로 등록해주세요.');
+				result = false;
+			}
+
+			if (Number(data.endSearchDate.replaceAll("-", "")) < Number(_today.replaceAll("-", "")) && data.crud == 'C') {
+				mcxDialog.alert('종료일자는 오늘포함 이후로 등록해주세요.');
+				result = false;
+			}
+
+			// 기획전 시작종료일과 코너 시작종료일 체크
+			if (stdt[0].replaceAll("-", "") > data.startSearchDate.replaceAll("-", "")) {
+				mcxDialog.alert("기획전 시작일보다 코너시작일이 작을 수 없습니다.");
+				result = false;
+			}
+
+			if (eddt[0].replaceAll("-", "") < data.endSearchDate.replaceAll("-", "")) {
+				mcxDialog.alert("기획전 종료일보다 코너종료일이 클 수 없습니다.");
+				result = false;
+			}
+
+			if (result) {
+				data.dispStdt = data.startSearchDate + ' ' + data.startSearchTime;
+				data.dispEddt = data.endSearchDate + ' ' + data.endSearchTime;
+			}
+		});
+
+		if (!result) return;
+
+		mcxDialog.confirm('저장 하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(changeData);
+				gagajf.ajaxJsonSubmit('/marketing/planning/corner/save', jsonData, fnCornerSearch);
+			}
+		});
+	}
+
+	// 코너 복사
+/* 	var fnCornerCopyPopup = function() {
+		var actionUrl = '/marketing/planning/corner/copy/list/form?planSq=' + planInfo.planSq;
+		actionUrl += '&copyMode=CORNER';
+		cfnOpenModalPopup(actionUrl,'popupCornerCopy');
+	} */
+	
+	var uploadGoodsUrl = [[${@environment.getProperty('upload.goods.view')}]];
+	var columnDefsGoods = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: "상품코드"	, field:'goodsCd'		, width:150, cellClass: 'text-left'
+			, cellRenderer: function(params) {return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: "상품명"		, field:'goodsNm'		, width:300, cellClass: 'text-left'},
+		{headerName: "이미지"		, field:'imgPath6'		, width:100 , height:60, cellClass: 'text-right'
+			, cellRenderer: function(params) {
+				var imgPath = '';
+				if (params.data.imgType == "A"){
+					imgPath = uploadGoodsUrl;
+				}
+				if(typeof params.value!='undefined' && params.value!='' && params.value!=null){
+					imgPath = imgPath + params.value;
+				}else{
+					imgPath = imgPath + params.data.imgPath1;
+				}
+				return '<img width="60" src="'+imgPath.replace('1000', '100')+'" onerror="this.src=\''+_uximgUrl+'/image/no.gif\';">';
+			}
+		},
+		/* {headerName: "전시순서"	, field:'dispOrd'		, width:80 , cellClass: 'text-center'
+			, editable : true, cellEditor: 'numericCellEditor'
+			, valueFormatter: function(params) { return params.value.addComma(); }
+		}, */
+		{headerName: "재고"		, field:'stockQtySum'			, width:80 , cellClass: 'text-center'
+			, cellRenderer: function(params) {return !gagajf.isNull(params.value) ? params.value : '0'; }
+		},
+		{headerName: "할인율(%)"		, field:'dcRate'		, width:80 , cellClass: 'text-center'},
+		{headerName: "TAG가"		, field:'tagPrice'		, width:100, cellClass: 'text-right'
+			,valueFormatter: function(params) {
+				if(params.value && params.value > 0) {
+					return params.value.addComma();
+				} else {
+					return '0';
+				}
+			}
+		},
+		{headerName: "정상가"		, field:'listPrice'		, width:100, cellClass: 'text-right' , hide : true
+			, valueFormatter: function(params) { return params.value.addComma(); }
+		},
+		{headerName: "판매가"		, field:'currPrice'		, width:100, cellClass: 'text-right'
+			, valueFormatter: function(params) { return params.value.addComma(); }
+		},
+		{headerName: "정상/이월여부", field:'formalGb'		, width:120, cellClass: 'text-center'},
+		{headerName: "상품상태"	, field:'goodsStat'		, width:100, cellClass: 'text-center'
+			, valueFormatter: function(params) { return gagaAgGrid.lookupValue(goodsStatList, params.value); }
+		},
+		{headerName: "업체"		, field:'supplyCompNm'	, width:150, cellClass: 'text-left'},
+		{headerName: "기획전상세"	, field:'planDtlSq'		, width:200, cellClass: 'text-left', hide: true},
+		{headerName: "등록일"		, field:'regDt'			, width:100,  cellClass: 'text-left'
+			, cellRenderer: function(params) { return !gagajf.isNull(params.value) ? params.value.toDate("YYYY-MM-DD HH:MM:SS").format("YYYY-MM-DD") : ''; }
+		},
+	];
+
+	var gridOptionsGoods = gagaAgGrid.getGridOptions(columnDefsGoods);
+	gridOptionsGoods.rowSelection = 'multiple';
+	gridOptionsGoods.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+	gridOptionsGoods.suppressRowClickSelection = true;
+
+	gridOptionsGoods.onCellClicked = function(event) {
+		if (event.colDef.field == 'goodsCd') {
+			// 상품 상세 팝업
+			cfnOpenGoodsDetailPopup('U',event.data.goodsCd);
+		}
+
+// 		if (event.colDef.field == 'imgPath1') {
+// 			// 이미지 팝업
+// 			cfnOpenImagePreViewPopup('planGoodsDetail', event.data.imgPath1);
+// 		}
+	}
+
+	// 상품 선택삭제
+	var fnDeleteGoods = function() {
+		var removedData = gagaAgGrid.removeRowData(gridOptionsGoods);
+
+		if (removedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+
+		mcxDialog.confirm('선택된 상품을 삭제하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(removedData);
+
+				gagajf.ajaxJsonSubmit('/marketing/planning/corner/goods/delete', jsonData, function() {
+					fnCornerSearch();
+				});
+			}
+		});
+	}
+
+	// 기획전 상세일련번호 전역 변수
+	var _planDtlSq = '';
+
+	// 엑셀상품추가
+	var fnGoodsExcelUpload = function() {
+		cfnExcelUploadPopup('createGoods', 'fnCreatePlanGoodsExcel');
+	}
+
+	var fnCreatePlanGoodsExcel = function(result) {
+		var data = {planSq : planInfo.planSq
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/marketing/planning/corner/goods/excelupload', jsonData, fnCornerSearch);
+	}
+
+	var fnOpenGoodsPopup = function() {
+		var allData = gagaAgGrid.getAllRowData(gridOptionsCorner);
+		if (allData.length < 1 ) {
+			mcxDialog.alert('기획전 코너가 존재 하지 않습니다.');
+			return;
+		}
+		if (allData[0].regNm == '' || allData[0].regNm == null) {
+			mcxDialog.alert('추가 된 코너를 저장 후 코너를 추가하세요.');
+			return;
+		}
+
+		if ($("#cornerNm").text() == null || $("#cornerNm").text()=='') {
+			mcxDialog.alert('코너를 선택해주세요.');
+			return;
+		}
+		cfnOpenGoodsPopup('fnCreateGoods');
+	}
+
+	// 상품추가
+	var fnCreateGoods = function(result) {
+		if (result.length < 1) return;
+
+		// 기존상품
+		var oldGoodsList = gagaAgGrid.getAllRowData(gridOptionsGoods);
+
+		// 중복체크
+		var check = true;
+		var checkData = [];
+		$(oldGoodsList).each(function(idx) {
+
+			$(result).each(function(newIdx) {
+
+				if (oldGoodsList[idx].goodsCd == result[newIdx].goodsCd) {
+					check = false;
+					checkData.push(result[newIdx].goodsCd);
+				}
+			});
+		});
+
+		if (!check) {
+			mcxDialog.alert('아래 중복상품이 존재 합니다.<br/>' + checkData.join(","));
+			return;
+
+		} else {
+			for (var disp = 0; disp < result.length; disp++) {
+				var goods = { planDtlSq : _planDtlSq ,
+							  goodsCd : result[disp].goodsCd };
+				oldGoodsList.unshift(goods);
+			}
+			
+			mcxDialog.confirm('선택하신 상품을 추가 하시겠습니까?', {
+				cancelBtnText: "취소",
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					var jsonData = JSON.stringify(oldGoodsList);
+					gagajf.ajaxJsonSubmit('/marketing/planning/corner/goods/save', jsonData, fnCornerSearch);
+				}
+			});
+		}
+	}
+
+	// 순셔 변경 팝업
+	var fnDispOrdChange = function(result) {
+		var selectData = gagaAgGrid.selectedRowData(gridOptionsCorner);
+		var params = 'planDtlSq='+ _planDtlSq;
+
+		cfnOpenGoodsDispOrdChangePopup('fnConnerGoodsSearch', params);
+	}
+	
+	$(document).ready(function() {
+		gagaAgGrid.createGrid('gridListCorner', gridOptionsCorner);
+		gagaAgGrid.createGrid('gridListGoods', gridOptionsGoods);
+
+		fnCornerSearch();
+	});
+
+
+/*]]>*/
+</script>
+</html>

+ 48 - 60
src/main/webapp/WEB-INF/views/marketing/PlanDetailPopupForm.html

@@ -499,38 +499,6 @@
 	let useYnList = { "Y":"Yes", "N":"No" };
 	let channelName = {"G053_01":"직접","G053_02":"네이버","G053_03":"다음","G053_04":"크리데오","G053_05":"카카오","G053_06":"인스타그램","G053_07":"페이스북","G053_08":"구글"
 			          ,"G053_09":"바이럴","G053_10":"모비온","G053_11":"YES24","G053_12":"한세드림"}
-    
-	if(planCateList.length > 0){
-		var chkboxCnt = $('#planUpdateForm input:checkbox[name=cateList]').length;
-		var dataCnt = planCateList.length;
-		for(var i=0; i<chkboxCnt; i++){
-			for(var j=0; j<dataCnt; j++){
-				var data = planCateList[j].cateNo;
-				if($('#planUpdateForm input:checkbox[name=cateList]').eq(i).val() == data){
-					$('#planUpdateForm input:checkbox[name=cateList]').eq(i).prop('checked', true);
-					$("#planUpdateForm input:checkbox[name=cateList]").eq(i).parent().addClass('checked');
-				}
-			}
-		}
-	}
-	
-	if(planBrandList.length > 0){
-		setTimeout(function(){
-			var chkboxCnt = $('input:checkbox[name=multiBrand]').length;
-			var dataCnt = planBrandList.length;
-			for(var i=0; i<10; i++){
-				for(var j=0; j<dataCnt; j++){
-					var data = planBrandList[j].brandCd;
-					if($('input:checkbox[name=multiBrand]').eq(i).val() == data){
-						$('input:checkbox[name=multiBrand]').eq(i).prop('checked', true);
-						$("input:checkbox[name=multiBrand]").eq(i).parent().addClass('checked');
-					}
-				}
-			}
-		}, 1000);
-		
-	}
-
 
     
 	// 카테고리 전시 여부
@@ -799,10 +767,22 @@
 					for(let i=0; i< chkCustGb.length; i++){
 						usableCustGbArr.push(chkCustGb.eq(i).val());
 					}
+					
+					var chkCate = $('#planUpdateForm input:checkbox[name=cateList]:checked');
+					var allCateData = [];
+					for(let i=0; i< chkCate.length; i++){
+						allCateData.push(chkCate.eq(i).val());
+					}
+					
+					var chkBrand = $('#planUpdateForm input:checkbox[name=multiBrand]:checked');
+					var allBrandData = [];
+					for(let i=0; i< chkBrand.length; i++){
+						allBrandData.push(chkBrand.eq(i).val());
+					}
 					let data = {
-							 multiCate : multiCate
-							,CateList : allCateData
-							,usableCustGradeArr : usableCustGradeArr
+							 multiCate : allCateData
+							,multiBrand : allBrandData
+							//,usableCustGradeArr : usableCustGradeArr
 							,usableCustGbArr : usableCustGbArr
 						    ,mode : $('#planUpdateForm input[name=mode]').val()
 						    ,planSq : $('#planUpdateForm input[name=planSq]').val()
@@ -821,7 +801,6 @@
 							,cornerNmDispYn :  $('#planUpdateForm select[name=cornerNmDispYn]').val()
 							,openYn :  $('#planUpdateForm select[name=openYn]').val()
 							,siteCd :$('#planUpdateForm select[name=siteCd]').val()
-							,replyYn : $('#planUpdateForm select[name=replyYn]').val()
 							,mainPimg :$('#planUpdateForm input[name=mainPimg]').val()
 							,mainMimg : $('#planUpdateForm input[name=mainMimg]').val()
 							,fsrcPc :  $('#planUpdateForm input[name=fsrcPc]').val()
@@ -903,30 +882,6 @@
 		
 	}
 	
-	 
-	// 업체변경시
-/* 	$('#planRegisterForm 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');
-	});
-	 */
-	// 업체변경시
-/* 	$('#planUpdateForm 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');
-	});
-	 */
-	
 	// validation 체크
 	function validationPlanDetail() {
 		if( $('#planUpdateForm input[name=planNm]').val() == '' || $('#planRegisterForm input[name=planNm]').val() == ''){
@@ -954,6 +909,39 @@
 		//gagaAgGrid.createGrid("gridFGCateList", gridOptionsFGCateList);
 		
 		 if (mode =='U') {
+			 
+
+				if(planCateList.length > 0){
+					var chkboxCnt = $('#planUpdateForm input:checkbox[name=cateList]').length;
+					var dataCnt = planCateList.length;
+					for(var i=0; i<chkboxCnt; i++){
+						for(var j=0; j<dataCnt; j++){
+							var data = planCateList[j].cateNo;
+							if($('#planUpdateForm input:checkbox[name=cateList]').eq(i).val() == data){
+								$('#planUpdateForm input:checkbox[name=cateList]').eq(i).prop('checked', true);
+								$("#planUpdateForm input:checkbox[name=cateList]").eq(i).parent().addClass('checked');
+							}
+						}
+					}
+				}
+				
+				if(planBrandList.length > 0){
+					setTimeout(function(){
+						var chkboxCnt = $('input:checkbox[name=multiBrand]').length;
+						var dataCnt = planBrandList.length;
+						for(var i=0; i<10; i++){
+							for(var j=0; j<dataCnt; j++){
+								var data = planBrandList[j].brandCd;
+								if($('input:checkbox[name=multiBrand]').eq(i).val() == data){
+									$('input:checkbox[name=multiBrand]').eq(i).prop('checked', true);
+									$("input:checkbox[name=multiBrand]").eq(i).parent().addClass('checked');
+								}
+							}
+						}
+					}, 1000);
+					
+				}
+				
 			//gridOptionsFGCateList.api.setRowData(planCateList);