Selaa lähdekoodia

상품상세 공지

eskim 5 vuotta sitten
vanhempi
commit
b648159cdd

+ 58 - 0
style24.scm/src/main/java/com/style24/persistence/domain/Notice.java

@@ -0,0 +1,58 @@
+package com.style24.persistence.domain;
+
+import java.util.Collection;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 공지사항 Domain
+ *
+ * @author gagamel
+ * @since 2020. 10. 30
+ */
+@SuppressWarnings("serial")
+@Data
+public class Notice extends TscBaseDomain {
+
+	private Integer noticeSq;		// 공지사항일련번호
+	private String noticeType;		// 공지사항유형
+	private String urgentYn;		// 긴급여부
+	private String noticeTitle;		// 공지사항제목
+	private String noticeContent;	// 공지사항내용
+	private int fileCnt;			// 파일건수
+	private String noticeStdt;		// 공지시작일시
+	private String noticeEddt;		// 공지종료일시
+	private int readCnt;			// 조회수
+	private String useYn;			// 사용여부
+
+	// 검색용
+	private String startDt;			// 시작일자
+	private String endDt;			// 종료일자
+	private String receiverId;		// 수신자ID
+
+	//private String goodsList;
+	private String crud;
+	private String goodsCd;
+	private String goodsNm;
+
+	// 공지사항 수신자
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] receiverIds;
+
+	// 공지사항 첨부파일
+	private Integer seq;
+	private String orgFileNm;
+	private String sysFileNm;
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] orgFileNms;
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] sysFileNms;
+
+
+	private String goodsList;
+	private Collection<NoticeGoods> goodsListNew;
+
+}

+ 27 - 0
style24.scm/src/main/java/com/style24/persistence/domain/NoticeGoods.java

@@ -0,0 +1,27 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 공지사항 상품 Domain
+ *
+ * @author eskim
+ * @since 2020. 11. 06
+ */
+@SuppressWarnings("serial")
+@Data
+public class NoticeGoods extends TscBaseDomain {
+
+	private Integer noticeSq;		// 공지사항일련번호
+	private String goodsCd;
+	private String goodsNm;
+	private String crud;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] arrGoodsCd;
+
+
+}

+ 125 - 0
style24.scm/src/main/java/com/style24/persistence/mybatis/shop/TssGoods.xml

@@ -1514,4 +1514,129 @@
 		<include refid="getListPagingCondition_sql"/>
 	</select>
 	
+	<!-- 상품상세 공지사항 목록 -->
+	<select id="getNoticeList" parameterType="GoodsSearch" resultType="Notice">
+		/* TsaGoods.getNoticeList */
+		SELECT A.NOTICE_SQ                                  
+		     , A.NOTICE_TYPE                                
+		     , A.NOTICE_TITLE                               
+		     , A.NOTICE_CONTENT                             
+		     , DATE_FORMAT(A.NOTICE_STDT,'%Y-%m-%d')  AS NOTICE_STDT 
+		     , DATE_FORMAT(A.NOTICE_EDDT,'%Y-%m-%d')  AS NOTICE_EDDT 
+		     , A.USE_YN                                          
+		     , FN_GET_USER_NM(A.REG_NO)             AS REG_NM    
+		     , DATE_FORMAT(A.REG_DT,'%Y-%m-%d %H:%i:%S') AS REG_DT
+		     , FN_GET_USER_NM(A.UPD_NO)             AS UPD_NM    
+		     , DATE_FORMAT(A.UPD_DT,'%Y%m%d%H%i%S') AS UPD_DT    
+		FROM   TB_NOTICE A
+		WHERE  A.NOTICE_TYPE = 'G047_30'
+		<if test="stDate != null and stDate !=''">
+		AND A.NOTICE_EDDT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		</if>
+		<if test="edDate != null and edDate !=''">
+		<![CDATA[
+		AND A.NOTICE_STDT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		]]>
+		</if>
+		<if test='useYn != null and useYn !=""'>
+		AND A.USE_YN = #{useYn}
+		</if>
+		<if test="noticeTitle != null and noticeTitle !=''">
+		AND LOWER(A.NOTICE_TITLE) LIKE CONCAT('%',LOWER(#{noticeTitle}),'%')
+		</if>
+		<if test='conditionList != null and conditionList.length>0'>
+		AND A.NOTICE_SQ IN (
+		                    SELECT NOTICE_SQ
+		                    FROM TB_NOTICE_GOODS
+		                    WHERE GOODS_CD IN (
+		                                       SELECT GOODS_CD 
+		                                       FROM TB_GOODS G
+		                                       WHERE 1 = 1
+		                                       AND (
+		    <choose>
+		      <when test='search != null and search == "searchGoodsCd"'>
+		          <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(G.GOODS_CD) LIKE CONCAT('%',UPPER(#{item}),'%') 
+		          </foreach>
+		      </when>
+		      <when test='search != null and search == "searchGoodsNm"'>
+		          <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(G.GOODS_NM) LIKE CONCAT('%',UPPER(#{item}),'%')
+		          </foreach>
+		      </when>
+		      <when test='search != null and search == "searchGoodsNum"'>
+		          <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(G.GOODS_NUM) LIKE CONCAT('%',UPPER(#{item}),'%')
+		          </foreach>
+		      </when>
+		      <when test='search != null and search == "searchSupplyGoodsCd"'>
+		          <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(G.SUPPLY_GOODS_CD) LIKE CONCAT('%',UPPER(#{item}),'%')
+		          </foreach>
+		      </when>
+		    </choose>
+		                                            )
+		                                      )
+		                   )
+		</if>
+		<if test="supplyCompCd != null and supplyCompCd  != ''">
+		AND A.NOTICE_SQ IN (
+		                    SELECT NOTICE_SQ
+		                    FROM TB_NOTICE_GOODS
+		                    WHERE GOODS_CD IN (
+		                                       SELECT GOODS_CD 
+		                                       FROM TB_GOODS 
+		                                       WHERE SUPPLY_COMP_CD = #{supplyCompCd}
+		                                       <if test="brandCd != null and brandCd  != ''">
+		                                       AND BRAND_CD = #{brandCd} 
+		                                       </if>
+		                                      )
+		                   )
+		</if>
+		ORDER  BY A.NOTICE_SQ DESC
+	</select>
+	
+	<!-- 상품상세 공지사항 상품 목록 -->
+	<select id="getNoticeGoodsList" parameterType="Notice" resultType="NoticeGoods">
+		/* TsaGoods.getNoticeGoodsList */
+		SELECT A.NOTICE_SQ
+		     , A.GOODS_CD
+		     , B.GOODS_NM
+		FROM TB_NOTICE_GOODS A
+		INNER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+		WHERE NOTICE_SQ = #{noticeSq}
+		ORDER BY A.GOODS_CD
+	</select>
+	
+	<!-- 상품상세 공지사항 상품저장 -->
+	<insert id="saveNoticeGoods" parameterType="NoticeGoods">
+		/* TsaGoods.saveNoticeGoods */
+		INSERT INTO TB_NOTICE_GOODS (
+		       NOTICE_SQ
+		     , GOODS_CD
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{noticeSq}
+		     , #{goodsCd}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       GOODS_CD = #{goodsCd}
+	</insert>
+	
+	<!-- 상품상세 공지사항 상품 삭제 -->
+	<delete id="deleteNoticeGoods" parameterType="NoticeGoods">
+		/* TsaGoods.deleteNoticeGoods */
+		DELETE FROM TB_NOTICE_GOODS 
+		WHERE NOTICE_SQ =  #{noticeSq}
+		AND GOODS_CD = #{goodsCd}
+	</delete>
+	
 </mapper>

+ 55 - 0
style24.scm/src/main/java/com/style24/persistence/mybatis/shop/TssNotice.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.style24.admin.biz.dao.TssNoticeDao">
+
+	<!-- 공지사항 저장 -->
+	<insert id="createNotice" parameterType="Notice" keyProperty="noticeSq">
+		/* TsaNotice.createNotice */
+		INSERT INTO TB_NOTICE (
+		       NOTICE_SQ
+		     , NOTICE_TYPE
+		     , NOTICE_TITLE
+		     , NOTICE_STDT
+		     , NOTICE_EDDT
+		     , NOTICE_CONTENT
+		     , URGENT_YN
+		     , USE_YN
+		     , READ_CNT
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       NULL
+		     , #{noticeType}
+		     , #{noticeTitle}
+		     , STR_TO_DATE(#{noticeStdt},'%Y-%m-%d')
+		     , STR_TO_DATE(#{noticeEddt},'%Y-%m-%d')
+		     , #{noticeContent}
+		     , IFNULL(#{urgentYn},'N')
+		     , #{useYn}
+		     , IFNULL(#{readCnt},0)
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+	</insert>
+
+	<!-- 공지사항 수정 -->
+	<update id="updateNotice" parameterType="Notice">
+		/* TsaNotice.updateNotice */
+		UPDATE TB_NOTICE
+		SET    NOTICE_TITLE = #{noticeTitle}
+		     , NOTICE_CONTENT = #{noticeContent}
+		     , NOTICE_STDT = STR_TO_DATE(#{noticeStdt},'%Y-%m-%d')
+		     , NOTICE_EDDT = STR_TO_DATE(#{noticeEddt},'%Y-%m-%d')
+		     , URGENT_YN = IFNULL(#{urgentYn},'N')
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  NOTICE_SQ = #{noticeSq}
+	</update>
+
+</mapper>

+ 42 - 0
style24.scm/src/main/java/com/style24/scm/biz/dao/TssGoodsDao.java

@@ -11,6 +11,8 @@ import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsPriceRes;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.NotiInfo;
+import com.style24.persistence.domain.Notice;
+import com.style24.persistence.domain.NoticeGoods;
 import com.style24.persistence.domain.Option;
 
 import com.gagaframework.web.parameter.GagaMap;
@@ -285,4 +287,44 @@ public interface TssGoodsDao {
 	 */
 	Collection<GoodsPriceRes> getGoodsSupplyPriceList(GoodsPriceRes goodsPriceRes);
 
+	/**
+	 * 상품 상세공지 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	Collection<Notice> getNoticeList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 상세공지 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	Collection<NoticeGoods> getNoticeGoodsList(Notice notice);
+
+	/**
+	 * 상품 상세공지 상품 저장
+	 *
+	 * @param noticeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	void saveNoticeGoods(NoticeGoods noticeGoods);
+
+	/**
+	 * 상품 상세공지 상품 삭제
+	 *
+	 * @param noticeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	void deleteNoticeGoods(NoticeGoods noticeGoods);
+
 }

+ 90 - 0
style24.scm/src/main/java/com/style24/scm/biz/dao/TssNoticeDao.java

@@ -0,0 +1,90 @@
+package com.style24.scm.biz.dao;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Notice;
+
+/**
+ * 공지사항 Dao
+ *
+ * @author gagamel
+ * @since 2020. 10. 30
+ */
+@ShopDs
+public interface TssNoticeDao {
+
+//	/**
+//	 * 공지사항 목록
+//	 * @param notice - 공지사항 정보
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	Collection<Notice> getNoticeList(Notice notice);
+//
+//	/**
+//	 * 공지사항 수신자 목록
+//	 * @param noticeSq - 공지사항일련번호
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	Collection<Notice> getNoticeReceiverList(Integer noticeSq);
+//
+//	/**
+//	 * 공지사항 파일 목록
+//	 * @param noticeSq - 공지사항일련번호
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	Collection<Notice> getNoticeFileList(Integer noticeSq);
+
+	/**
+	 * 공지사항 저장
+	 * @param notice - 공지사항 정보
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	void createNotice(Notice notice);
+
+	/**
+	 * 공지사항 수정
+	 * @param notice - 공지사항 정보
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	void updateNotice(Notice notice);
+
+//	/**
+//	 * 공지사항 파일 저장
+//	 * @param notice - 공지사항 정보
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	void createNoitceFlie(Notice notice);
+//
+//	/**
+//	 * 공지사항 파일 삭제
+//	 * @param notice - 공지사항 정보
+//	 * @author jaewonHo
+//	 * @since 2020. 01. 15
+//	 */
+//	void deleteNoticeFile(Notice notice);
+//
+//	/**
+//	 * 공지사항 수신자 삭제
+//	 * @param notice - 공지사항 정보
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	void deleteNoticeReceiver(Notice notice);
+//
+//	/**
+//	 * 공지사항 수신자 저장
+//	 * @param notice - 공지사항 정보
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	void createNoticeReceiver(Notice notice);
+
+}

+ 107 - 0
style24.scm/src/main/java/com/style24/scm/biz/service/TssGoodsService.java

@@ -9,6 +9,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.domain.Brand;
 import com.style24.persistence.domain.Goods;
@@ -19,6 +21,8 @@ import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsPriceRes;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.NotiInfo;
+import com.style24.persistence.domain.Notice;
+import com.style24.persistence.domain.NoticeGoods;
 import com.style24.persistence.domain.Option;
 import com.style24.persistence.domain.SearchData;
 import com.style24.scm.biz.dao.TssGoodsDao;
@@ -59,6 +63,12 @@ public class TssGoodsService {
 	@Autowired
 	private TssBusinessService businessService;
 
+	@Autowired
+	private TssNoticeService noticeService;
+
+	@Autowired
+	private ObjectMapper mapper;
+
 	/**
 	 * 상품 목록 건수
 	 *
@@ -874,4 +884,101 @@ public class TssGoodsService {
 		return goodsDao.getGoodsSupplyPriceList(goodsPriceHst);
 	}
 
+	/**
+	 * 상품 상세공지 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	public Collection<Notice> getNoticeList(GoodsSearch goodsSearch) {
+		return goodsDao.getNoticeList(goodsSearch);
+	}
+
+	/**
+	 * 상품 상세공지 상품 목록
+	 *
+	 * @param notice
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	public Collection<NoticeGoods> getNoticeGoodsList(Notice notice) {
+		return goodsDao.getNoticeGoodsList(notice);
+	}
+
+	/**
+	 * 공지사항 저장
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	@Transactional("shopTxnManager")
+	public void saveNotice(Notice notice) {
+		notice.setRegNo(TssSession.getInfo().getUserNo());
+		notice.setUpdNo(TssSession.getInfo().getUserNo());
+
+		// 신규 일때
+		if (notice.getNoticeSq() == null) {
+			// 공지사항 저장
+			noticeService.createNotice(notice);
+
+			// 등록된 사용자번호 값 가져오기
+			Integer noticeSq = notice.getNoticeSq();
+
+			notice.setNoticeSq(noticeSq);
+
+		} else {
+			// 공지사항 수정
+			noticeService.updateNotice(notice);
+		}
+
+		if (!StringUtils.isEmpty(notice.getGoodsList())) {
+			Collection<NoticeGoods> noticeGoodsList = null;
+			try {
+				noticeGoodsList = mapper.readValue(notice.getGoodsList(), new TypeReference<Collection<NoticeGoods>>() {
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new IllegalStateException(message.getMessage("상품상세공지 저장 중 오류로 인해 저장되지 않았습니다."));
+			}
+			log.info("noticeGoodsList: {}", noticeGoodsList);
+			for (NoticeGoods noticeGoods : noticeGoodsList) {
+				noticeGoods.setNoticeSq(notice.getNoticeSq());
+				noticeGoods.setRegNo(TssSession.getInfo().getUserNo());
+				noticeGoods.setUpdNo(TssSession.getInfo().getUserNo());
+
+				goodsDao.saveNoticeGoods(noticeGoods);
+			}
+
+		}
+	}
+
+	/**
+	 * 공지사항 상품 삭제
+	 * @param noticeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteNoticeGoods(NoticeGoods noticeGoods) {
+
+		if (noticeGoods == null || (noticeGoods.getArrGoodsCd() == null && noticeGoods.getArrGoodsCd().length <= 0)) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		if (noticeGoods.getArrGoodsCd().length > 0) {
+			for (String goodsCd : noticeGoods.getArrGoodsCd()) {
+				noticeGoods.setGoodsCd(goodsCd);
+				noticeGoods.setRegNo(TssSession.getInfo().getUserNo());
+				noticeGoods.setUpdNo(TssSession.getInfo().getUserNo());
+
+				goodsDao.deleteNoticeGoods(noticeGoods);
+			}
+		}
+
+	}
 }

+ 149 - 0
style24.scm/src/main/java/com/style24/scm/biz/service/TssNoticeService.java

@@ -0,0 +1,149 @@
+package com.style24.scm.biz.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.persistence.domain.Notice;
+import com.style24.scm.biz.dao.TssNoticeDao;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 공지사항 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 30
+ */
+@Service
+@Slf4j
+public class TssNoticeService {
+
+	@Autowired
+	private TssNoticeDao noticeDao;
+
+//	/**
+//	 * 공지사항 목록
+//	 * @param notice - 공지사항 정보
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	public Collection<Notice> getNoticeList(Notice notice) {
+//		return noticeDao.getNoticeList(notice);
+//	}
+//
+//	/**
+//	 * 공지사항 수신자 목록
+//	 * @param noticeSq - 공지사항일련번호
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	public Collection<Notice> getNoticeReceiverList(Integer noticeSq) {
+//		return noticeDao.getNoticeReceiverList(noticeSq);
+//	}
+//
+//	/**
+//	 * 공지사항 파일 목록
+//	 * @param noticeSq - 공지사항일련번호
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	public Collection<Notice> getNoticeFileList(Integer noticeSq) {
+//		return noticeDao.getNoticeFileList(noticeSq);
+//	}
+//
+//	/**
+//	 * 공지사항 저장
+//	 * @param notice - 공지사항 정보
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	@Transactional("shopTxnManager")
+//	public void saveNotice(Notice notice) {
+//		notice.setRegNo(TsaSession.getInfo().getUserNo());
+//		notice.setUpdNo(TsaSession.getInfo().getUserNo());
+//
+//		// 신규 일때
+//		if (notice.getNoticeSq() == null) {
+//			// 공지사항 저장
+//			noticeDao.createNotice(notice);
+//
+//			// 등록된 사용자번호 값 가져오기
+//			Integer noticeSq = notice.getNoticeSq();
+//			log.info("noticeSq: {}", noticeSq);
+//			notice.setNoticeSq(noticeSq);
+//		} else {
+//			// 공지사항 수정
+//			noticeDao.updateNotice(notice);
+//		}
+//
+//		// 수신자 저장
+//		if (!StringUtils.isAllBlank(notice.getReceiverIds())) {
+//			noticeDao.deleteNoticeReceiver(notice);
+//
+////			for (int i = 0; i < notice.getReceiverIds().length; i++) {
+//			for (String receiverId : notice.getReceiverIds()) {
+//				if (StringUtils.isNotBlank(receiverId)) {
+//					notice.setReceiverId(receiverId);
+//					log.info("noticeReceiver: {}", notice);
+//					noticeDao.createNoticeReceiver(notice);
+//				}
+//			}
+//		}
+//
+//		// 파일이 존재할때
+//		if (!StringUtils.isAllBlank(notice.getSysFileNms())) {
+//			noticeDao.deleteNoticeFile(notice);
+//
+//			for (int i = 0; i < notice.getFileCnt(); i++) {
+//				notice.setOrgFileNm(notice.getOrgFileNms()[i]);
+//				notice.setSysFileNm(notice.getSysFileNms()[i]);
+//				log.info("noticeFile: {}", notice);
+//				noticeDao.createNoitceFlie(notice);
+//			}
+//		}
+//	}
+//
+//	/**
+//	 * 공지사항 첨부파일 삭제
+//	 * @param notice - 공지사항 정보
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 10. 30
+//	 */
+//	@Transactional("shopTxnManager")
+//	public void deleteNoticeFile(Notice notice) {
+//		noticeDao.deleteNoticeFile(notice);
+//	}
+
+	/**
+	 * 공지사항 등록(상품상세공지에서 사용)
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 05
+	 */
+	@Transactional("shopTxnManager")
+	public void createNotice(Notice notice) {
+		noticeDao.createNotice(notice);
+	}
+
+	/**
+	 * 공지사항 수정(상품상세공지에서 사용)
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 05
+	 */
+	@Transactional("shopTxnManager")
+	public void updateNotice(Notice notice) {
+		noticeDao.updateNotice(notice);
+	}
+
+
+
+}

+ 92 - 0
style24.scm/src/main/java/com/style24/scm/biz/web/TssGoodsController.java

@@ -12,6 +12,7 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Controller;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -28,6 +29,8 @@ import com.style24.persistence.domain.GoodsNotiInfo;
 import com.style24.persistence.domain.GoodsPriceRes;
 import com.style24.persistence.domain.GoodsSearch;
 import com.style24.persistence.domain.NotiInfo;
+import com.style24.persistence.domain.Notice;
+import com.style24.persistence.domain.NoticeGoods;
 import com.style24.persistence.domain.Option;
 import com.style24.persistence.domain.User;
 import com.style24.scm.biz.service.TssCommonService;
@@ -692,5 +695,94 @@ public class TssGoodsController extends TssBaseController {
 		return result;
 	}
 
+	/**
+	 * 상품 상세공지 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/notice/form")
+	public ModelAndView detailNoticeForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+
+		mav.setViewName("goods/GoodsNoticeForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 상세공지 목록
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	@PostMapping("/notice/list")
+	@ResponseBody
+	public Collection<Notice> getNoticeList(@RequestBody GoodsSearch goodsSearch) {
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TssSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TssSession.getInfo().getUserNo().toString());
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+		}
+
+		return goodsService.getNoticeList(goodsSearch);
+	}
+
+	/**
+	 * 상품 상세공지 상품목록
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	@GetMapping("/notice/goods/list/{noticeSq}")
+	@ResponseBody
+	public Collection<NoticeGoods> getNoticeGoodsList(@PathVariable Integer noticeSq) {
+		Notice notice = new Notice();
+		notice.setNoticeSq(noticeSq);
+		return goodsService.getNoticeGoodsList(notice);
+	}
+
+	/**
+	 * 상품 상세공지 저장/등록
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 27
+	 */
+	@PostMapping("/notice/save")
+	@ResponseBody
+	public GagaResponse saveNotice(@RequestBody Notice notice) {
+		goodsService.saveNotice(notice);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 상세공지상품 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 09
+	 */
+	@PostMapping("/notice/goods/delete")
+	@ResponseBody
+	public GagaResponse deleteNoticeGoods(@RequestBody NoticeGoods noticeGoods) {
+		goodsService.deleteNoticeGoods(noticeGoods);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
 
 }

+ 1 - 1
style24.scm/src/main/webapp/WEB-INF/views/goods/GoodsImageMassForm.html

@@ -557,7 +557,7 @@
 
 	//창종료
 	var fnGoodsImgFormClose = function(){
-		uifnPopupClose('popupGoodsImage');
+		uifnPopupClose('popupGoodsImageMass');
 	}
 
 	//안내팝업

+ 522 - 0
style24.scm/src/main/webapp/WEB-INF/views/goods/GoodsNoticeForm.html

@@ -0,0 +1,522 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsNoticeForm.html
+ * @desc    : 상품상세공지관리 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.11.27   eskim     최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+		
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<!-- TITLE -->
+			<div class="panelTitle">
+				<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 하나를 꼭 입력해 주세요.</h3>
+			</div>
+			<!-- //TITLE -->
+			<form id="searchForm" name="searchForm" action="#" th:action="@{'/goods/notice/list'}" >
+				<input type="hidden" name="noticeType" value="G047_30"/>
+				<input type="hidden" id="searchGb" name="searchGb" />
+			<div class="panelContent">	
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col width="10%"/>
+						<col width="40%"/>
+						<col width="10%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드</th>
+						<td>
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" th:if="${sessionInfo.roleCd} != '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>
+					</tr>
+					<tr>
+						<th>공지제목</th>
+						<td>
+							<input name="noteicTitle" type="text" maxlength="200"/>
+						</td>
+						<th>사용여부</th>
+						<td>
+							<select name="useYn">
+								<option value="">[전체]</option>
+								<option value="Y">[Y] Yes</option>
+								<option value="N">[N] No</option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>공지기간</th>
+						<td colspan="3" id="sellTerms">
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button>
+						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+					</li>
+				</ul>
+			</div>	
+			</form>
+		</div>
+		<!-- 검색조건 영역 -->
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<div id="gridNoticeList" style="width: 100%; height: 400px" class="ag-theme-balham"></div>
+		</div>
+		<!-- //리스트 영역 -->
+		<form id="goodsNoticeForm" name="goodsNoticeForm" action="#" th:action="@{'/goods/notice/save'}">
+		<input type="hidden" name="urgentYn" value="N"/> <!-- 긴급공지여부 -->
+		<input type="hidden" name="noticeType" value="G047_30"/>
+		<input type="hidden" name="goodsList" />
+		<!-- 등록/수정 -->
+		<div class="panelStyle" >
+			<ul>
+				<li>
+					<table class="w100p">
+						<colgroup>
+							<col style="width:65%;"/>
+							<col style="width:1%;"/>
+							<col/>
+						</colgroup>
+						<tr>
+							<td>
+								<table class="frmStyle" aria-describedby="등록/수정 폼">
+									<colgroup>
+										<col style="width:10%;"/>
+										<col style="width:15%;"/>
+										<col style="width:10%;"/>
+										<col style="width:15%;"/>
+										<col style="width:10%;"/>
+										<col/>
+									</colgroup>
+									<tr>
+										<th>공지번호</th>
+										<td>
+											<input type="text" class="w100" name="noticeSq" placeholder="자동부여" readonly="readonly"/>
+										</td>
+										<th>사용여부</th>
+										<td>
+											<input type="hidden" name="useYn"/>
+											<label class="chkBox"><input type="checkbox" name="chkUseYn" checked="checked" value="Y"/>사용</label>
+										</td>
+										<th>공지기간<i class="required" title="필수"></i></th>
+										<td>
+											<input type="text" class="schDate w100" name="noticeStdt" maxlength="10" th:value="${#calendars.format(#calendars.createNow(), 'yyyy-MM-dd')}"/>
+											~
+											<input type="text" class="schDate w100" name="noticeEddt" maxlength="10" th:value="${#calendars.format(#calendars.createNow(), 'yyyy-MM-dd')}"/>
+										</td>
+									</tr>
+									<tr>
+										<th>제목<i class="required" title="필수"></i></th>
+										<td colspan="5">
+											<input type="text" name="noticeTitle" required="required" data-valid-name="제목"/>
+										</td>
+									</tr>
+									<tr>
+										<th>공지내용<i class="required" title="필수"></i></th>
+										<td colspan="5">
+											<textarea class="textareaR4" name="noticeContent" id="noticeContent"></textarea>
+										</td>
+									</tr>
+								</table>
+							</td>
+							<td>&nbsp;</td>
+							<td>
+							<ul class="panelBar">
+								<li class="left">
+									<button type="button" class="btn btn-danger btn-lg" id="btnDeleteNoticeGoods">삭제</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>
+							<ul>
+								<li id="gridNoticeGoodsList" style="width: 100%; height: 450px;" class="ag-theme-balham"></li>
+							</ul>
+							</td>
+						</tr>
+					</table>
+				</li>
+			</ul>
+			<!-- 버튼 배치 영역 -->
+			<ul class="panelBar">
+				<li class="right">
+					<button type="button" class="btn btn-info btn-lg" id="btnNew">신규</button>
+					<button type="button" class="btn btn-success btn-lg" id="btnSave">저장</button>
+				</li>
+			</ul>
+			<!-- //버튼 배치 영역 -->
+		</div>
+		<!-- 등록/수정 -->
+		</form>
+	</div>
+
+<script type="text/javascript" src="/ux/plugins/summernote/summernote.js?v=2020103001"></script>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.summernote.js?v=2020103001"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var columnNoticeDefs = [
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "공지번호", field: "noticeSq", width: 90, cellClass: 'text-center'},
+		{headerName: "공지제목", field: "noticeTitle", width: 500,
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: "공지시작일", field: "noticeStdt", width:150, cellClass: 'text-center',
+			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
+		},
+		{headerName: "공지종료일", field: "noticeEddt", width:150, cellClass: 'text-center',
+			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
+		},
+		{headerName: "사용여부", field: "useYn", width:90, cellClass: 'text-center'},
+		{headerName: "등록자", field: "regNm", width:90, cellClass: 'text-center'},
+		{headerName: "등록일자", field: "regDt", width:150, cellClass: 'text-center',
+			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
+		}
+	];
+	
+	var columnNoticeGoodsDefs = [
+		{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: "CRUD", field: "crud", width: 75, minWidth: 75, hide: true},
+		{headerName: "상품코드", field: "goodsCd", width: 140, cellClass: 'text-center'},
+		{headerName: "상품명", field: "goodsNm", width: 260, cellClass: 'text-left'}
+	];
+
+	var gridNoticeOptions = gagaAgGrid.getGridOptions(columnNoticeDefs);
+	var gridNoticeGoodsOptions = gagaAgGrid.getGridOptions(columnNoticeGoodsDefs);
+
+	gridNoticeGoodsOptions.rowSelection = 'multiple';
+	gridNoticeGoodsOptions.suppressRowClickSelection = true;
+	
+	// Cell click
+	gridNoticeOptions.onCellClicked = function(event) {
+		if (event.colDef.field != 'noticeTitle')
+			return;
+		
+		$('#goodsNoticeForm input[name=noticeSq]').val(event.data.noticeSq);
+		if (event.data.useYn == 'Y') {
+			$('#goodsNoticeForm input:checkbox[name=chkUseYn]').prop('checked', true);
+			$('#goodsNoticeForm input:checkbox[name=chkUseYn]').parent("label").addClass("checked");
+		} else {
+			$('#goodsNoticeForm input:checkbox[name=chkUseYn]').prop('checked', false);
+			$('#goodsNoticeForm input:checkbox[name=chkUseYn]').parent("label").removeClass("checked");
+		}
+		
+		$('#goodsNoticeForm input[name=noticeStdt]').val(event.data.noticeStdt);
+		$('#goodsNoticeForm input[name=noticeEddt]').val(event.data.noticeEddt);
+		$('#goodsNoticeForm input[name=noticeTitle]').val(event.data.noticeTitle);
+
+		// 공지내용. Summernote에 값 세팅
+		gagaSn.setContents('#noticeContent', event.data.noticeContent);
+
+		// 상품 목록
+		fnGetNoticeGoodsList(event.data.noticeSq);
+	}
+
+	// 검색
+	$('#btnSearch').on('click', function() {
+		if(!fnConditionCheck()) return;
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridNoticeOptions, '#searchForm');
+	});
+	
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#searchForm';
+		var form = document.searchForm;
+
+		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 = $('#searchForm input[name=stDate]').val();
+		var toDate = $('#searchForm input[name=edDate]').val();
+		
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+			
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("공지기간 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function(){
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("공지기간 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function(){
+						$('#goodsNoticeForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			} 
+		}
+
+		return true;
+	}
+	
+	// 상품 목록 조회
+	var fnGetNoticeGoodsList = function(noticeSq) {
+		var actionUrl = '/goods/notice/goods/list/' + noticeSq;
+		gagaAgGrid.fetch(actionUrl, gridNoticeGoodsOptions);
+	}
+	
+	//업체변경시
+	$('#searchForm select[name=supplyCompCd]').on('change', function() {
+		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
+
+		if(sessRoleCd == "G001_B000"){
+			actionUrl = '/renderer/brand/AuthBrandlist';
+		}
+		$("#searchForm select[name=brandCd] option:gt(0)").remove();
+
+		cfnCreateCombo(actionUrl, $('#searchForm select[name=brandCd]'), "[전체]", "");
+	});	
+	
+	//엑셀 상품 조회
+	$('#btnSearchExcel').on('click', function() {
+		cfnExcelUploadPopup('goodsNoticeExcelUpload', 'goodsNoticeExcelUpload');
+	});
+
+	var goodsNoticeExcelUpload = function(result){
+		var data = {procJob : result.procJob
+			,excelFileNm : result.excelFileNm
+		};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/goods/search/excelupload/save', jsonData, fnGoodsNoticeExcelUploadCallBack);
+	}
+	
+	var fnGoodsNoticeExcelUploadCallBack = function(result){
+		gagajf.ajaxJsonSubmit('/goods/excel/upload/goods/list', '', fnExcelSearchCallBack);
+	}
+	
+	// 상품 엑셀 조회 콜백함수
+	var fnExcelSearchCallBack = function(result) {
+		if (result.goodsExcelList.length < 1) return;
+		var oldData = gagaAgGrid.getAllRowData(gridNoticeGoodsOptions);
+		$.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(gridNoticeGoodsOptions, {"goodsCd" : item.goodsCd, "goodsNm" : item.goodsNm, "crud" : "C"});
+		});
+		return;
+	};
+	
+	// 상품 조회 클릭 시
+	$('#btnSearchGoods').on('click', function() {
+		cfnOpenGoodsPopup('fnSearchCallBack');
+	});
+
+	// 상품 조회 콜백함수
+	var fnSearchCallBack = function(result) {
+		if (result.length < 1) return;
+		var oldData = gagaAgGrid.getAllRowData(gridNoticeGoodsOptions);
+		$.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(gridNoticeGoodsOptions, {"goodsCd" : item.goodsCd, "goodsNm" : item.goodsNm, "crud" : "C"});
+		});
+		return;
+	};
+	
+	// 상품 삭제
+	$('#btnDeleteNoticeGoods').on('click', function() {
+		
+		var selectedData = gridNoticeGoodsOptions.api.getSelectedRows();
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+		
+		var removedData = gagaAgGrid.removeRowData(gridNoticeGoodsOptions, false);
+		
+		// 신규 상세 공지일경우 화면에서만 삭제
+		if (gagajf.isNull($('#goodsNoticeForm input[name=noticeSq]').val())){
+			return;
+		}
+		
+		var arrGoodsCd = [];
+		$.each(selectedData, function(idx, item) {
+			arrGoodsCd.push(item.goodsCd);
+		});
+		
+		mcxDialog.confirm('삭제하시겠습니까?',  {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var data = {arrGoodsCd : arrGoodsCd
+							,noticeSq : $('#goodsNoticeForm input[name=noticeSq]').val()
+			};
+			
+			var jsonData = JSON.stringify(data);
+			gagajf.ajaxJsonSubmit('/goods/notice/goods/delete', jsonData);
+			}
+		});
+	});
+	
+	// 신규 버튼 클릭
+	$("#btnNew").on("click", function(){
+		$('#goodsNoticeForm')[0].reset();
+		
+		// 공지내용. Summernote에 값 세팅
+		gagaSn.setContents('#noticeContent', "");
+
+		// 그리드 초기화
+		gridNoticeGoodsOptions.api.setRowData(null);
+		 
+		$('#goodsNoticeForm input[name=noticeSq]').val('');
+		$('#goodsNoticeForm input[name=noticeStdt]').val(_today);
+		$('#goodsNoticeForm input[name=noticeEddt]').val(_today);
+	});
+	
+	// 저장
+	$("#btnSave").on("click", function() {
+		// 날짜 체크
+		if (gagajf.isNull($('#goodsNoticeForm input[name=noticeStdt]').val())) {
+			mcxDialog.alertC('공지시작일자를 입력해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsNoticeForm input[name=noticeStdt]').focus();
+				}
+			});
+			return;
+		}
+
+		if (gagajf.isNull($('#goodsNoticeForm input[name=noticeEddt]').val())) {
+			mcxDialog.alertC('공지종료일자를 입력해 주세요.', {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsNoticeForm input[name=noticeEddt]').focus();
+				}
+			});
+			return;
+		}
+		var stDate = $('#goodsNoticeForm input[name=noticeStdt]').val().toDate('YYYY-MM-DD');
+		var edDate = $('#goodsNoticeForm input[name=noticeEddt]').val().toDate('YYYY-MM-DD');
+
+		if (stDate > edDate) {
+			mcxDialog.alert("공지기간 종료일자는 시작일자 보다 클 수 없습니다.");
+			return;
+		}
+
+		// validation
+		if (!gagajf.validation('#goodsNoticeForm'))
+			return false;
+
+		$('#goodsNoticeForm input[name=useYn]').val($('#goodsNoticeForm input:checkbox[name=chkUseYn]').is(":checked") ? 'Y' : 'N');
+
+		mcxDialog.confirm('저장하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				
+				//var goodsAllData = gagaAgGrid.getAllRowData(gridNoticeGoodsOptions);
+				var goodsAllData = gagaAgGrid.getChangedData(gridNoticeGoodsOptions);
+				
+				var jsonGoodsData = JSON.stringify(goodsAllData);
+				$('#goodsNoticeForm input[name=goodsList]').val(jsonGoodsData);
+				
+				var jsonData = JSON.stringify($('#goodsNoticeForm').serializeObject());
+				gagajf.ajaxJsonSubmit($('#goodsNoticeForm').prop('action'), jsonData, function() {
+					$('#btnSearch').trigger('click');
+					fnGetNoticeGoodsList($('#goodsNoticeForm input[name=noticeSq]').val());
+					
+				});
+			}
+		});
+	});
+	
+	$(document).ready(function() {
+		
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '공지일', 'X');
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridNoticeList', gridNoticeOptions);
+		gagaAgGrid.createGrid('gridNoticeGoodsList', gridNoticeGoodsOptions);
+		
+		// Create a summernote
+		var snOptions = gagaSn.getToolbarOptions('media');
+		gagaSn.createSummernote(snOptions, '#noticeContent');
+		
+	});
+	
+/*]]>*/
+</script>
+
+</html>