Browse Source

Merge branch 'develop' into xyzp1539

# Conflicts:
#	.gitignore
#	style24.admin/.gitignore
#	style24.batch/.classpath
#	style24.front/.classpath
#	style24.front/target/m2e-wtp/web-resources/META-INF/maven/com.style24.front/style24.front/pom.properties
xyzp1539 5 years ago
parent
commit
a3b07a1dd8
100 changed files with 7983 additions and 1084 deletions
  1. 10 2
      .gitignore
  2. 11 1
      style24.admin/.gitignore
  3. 0 9
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaAnswerPhaseDao.java
  4. 19 0
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaCommonDao.java
  5. 117 5
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaDisplayDao.java
  6. 57 5
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java
  7. 11 0
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaMarketingDao.java
  8. 61 1
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaOrderDao.java
  9. 2 2
      style24.admin/src/main/java/com/style24/admin/biz/dao/TsaRendererDao.java
  10. 0 11
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaAnswerPhaseService.java
  11. 23 1
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaCommonService.java
  12. 0 5
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaCounselService.java
  13. 126 5
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaDisplayService.java
  14. 135 40
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaGoodsService.java
  15. 12 0
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaMarketingService.java
  16. 315 0
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaOrderService.java
  17. 3 3
      style24.admin/src/main/java/com/style24/admin/biz/service/TsaRendererService.java
  18. 21 31
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaCustomerController.java
  19. 147 5
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaDisplayController.java
  20. 118 2
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaGoodsController.java
  21. 44 7
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaMarketingController.java
  22. 20 4
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaOcmController.java
  23. 65 2
      style24.admin/src/main/java/com/style24/admin/biz/web/TsaOrderController.java
  24. 30 31
      style24.admin/src/main/java/com/style24/persistence/domain/Category.java
  25. 20 5
      style24.admin/src/main/java/com/style24/persistence/domain/Counsel.java
  26. 3 0
      style24.admin/src/main/java/com/style24/persistence/domain/Extmall.java
  27. 29 0
      style24.admin/src/main/java/com/style24/persistence/domain/FreeGoods.java
  28. 30 8
      style24.admin/src/main/java/com/style24/persistence/domain/FreeGoodsPromotion.java
  29. 31 0
      style24.admin/src/main/java/com/style24/persistence/domain/FreeGoodsSectionVal.java
  30. 4 1
      style24.admin/src/main/java/com/style24/persistence/domain/Goods.java
  31. 2 0
      style24.admin/src/main/java/com/style24/persistence/domain/GoodsCompose.java
  32. 23 0
      style24.admin/src/main/java/com/style24/persistence/domain/ItemkindCategory.java
  33. 36 0
      style24.admin/src/main/java/com/style24/persistence/domain/MoreBetter.java
  34. 3 1
      style24.admin/src/main/java/com/style24/persistence/domain/Notice.java
  35. 6 0
      style24.admin/src/main/java/com/style24/persistence/domain/Order.java
  36. 75 0
      style24.admin/src/main/java/com/style24/persistence/domain/OrderChange.java
  37. 10 0
      style24.admin/src/main/java/com/style24/persistence/domain/ReinboundInform.java
  38. 20 0
      style24.admin/src/main/java/com/style24/persistence/domain/Sequence.java
  39. 38 0
      style24.admin/src/main/java/com/style24/persistence/domain/WmsGoods.java
  40. 0 12
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaAnswerPhase.xml
  41. 17 0
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaCommon.xml
  42. 15 14
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaCounsel.xml
  43. 522 92
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaDsiplay.xml
  44. 179 5
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml
  45. 30 0
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaMarketing.xml
  46. 186 174
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaNotice.xml
  47. 208 4
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaOrder.xml
  48. 3 3
      style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaRenderer.xml
  49. 80 79
      style24.admin/src/main/resources/i18n/messages/message_ko_KR.properties
  50. 126 15
      style24.admin/src/main/webapp/WEB-INF/views/board/NoticeForm.html
  51. 19 21
      style24.admin/src/main/webapp/WEB-INF/views/customer/GoodsQnaDetailForm.html
  52. 17 6
      style24.admin/src/main/webapp/WEB-INF/views/customer/GoodsQnaForm.html
  53. 6 11
      style24.admin/src/main/webapp/WEB-INF/views/customer/OneToOneQnaDetailForm.html
  54. 433 0
      style24.admin/src/main/webapp/WEB-INF/views/display/CategoryForm.html
  55. 292 0
      style24.admin/src/main/webapp/WEB-INF/views/display/ItemkindCategoryForm.html
  56. 55 7
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDealForm.html
  57. 155 26
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html
  58. 1 1
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDetailSizeStockForm.html
  59. 331 0
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsFreeGoodsForm.html
  60. 1 1
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsListForm.html
  61. 9 19
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsMassRegisterForm.html
  62. 16 9
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsSetForm.html
  63. 74 86
      style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsWmsIncomelotForm.html
  64. 2 2
      style24.admin/src/main/webapp/WEB-INF/views/marketing/FreeGoodsPromotionForm.html
  65. 98 58
      style24.admin/src/main/webapp/WEB-INF/views/marketing/FreeGoodsPromotionRegiForm.html
  66. 233 0
      style24.admin/src/main/webapp/WEB-INF/views/marketing/MorebetterListForm.html
  67. 133 0
      style24.admin/src/main/webapp/WEB-INF/views/ocm/ExtmallSearchForm.html
  68. 248 133
      style24.admin/src/main/webapp/WEB-INF/views/order/CancelRequestForm.html
  69. 1092 0
      style24.admin/src/main/webapp/WEB-INF/views/order/CancelRequestFormBack.html
  70. 1 1
      style24.admin/src/main/webapp/WEB-INF/views/system/CommoncodeForm.html
  71. 4 3
      style24.admin/src/main/webapp/WEB-INF/views/system/MenuForm.html
  72. 22 5
      style24.admin/src/main/webapp/ux/js/admin.popup.js
  73. 32 0
      style24.batch/.classpath
  74. 13 1
      style24.batch/.gitignore
  75. 57 0
      style24.batch/src/main/java/com/style24/batch/biz/dao/TsbCommonDao.java
  76. 52 0
      style24.batch/src/main/java/com/style24/batch/biz/dao/TsbGoodsDao.java
  77. 75 0
      style24.batch/src/main/java/com/style24/batch/biz/dao/TsbWmsGoodsDao.java
  78. 65 0
      style24.batch/src/main/java/com/style24/batch/biz/job/goods/TsbGoodsWmsBrandproviderJob.java
  79. 72 0
      style24.batch/src/main/java/com/style24/batch/biz/job/goods/TsbGoodsWmsIncomelotJob.java
  80. 66 0
      style24.batch/src/main/java/com/style24/batch/biz/job/goods/TsbGoodsWmsMeasurementJob.java
  81. 57 0
      style24.batch/src/main/java/com/style24/batch/biz/service/TsbCommonService.java
  82. 105 1
      style24.batch/src/main/java/com/style24/batch/biz/service/TsbGoodsService.java
  83. 89 0
      style24.batch/src/main/java/com/style24/batch/biz/service/TsbWmsGoodsService.java
  84. 50 1
      style24.batch/src/main/java/com/style24/batch/biz/task/TsbGoodsTask.java
  85. 28 0
      style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfIncomelot.java
  86. 30 0
      style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfIncomelotitem.java
  87. 33 0
      style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfMeasurement.java
  88. 33 0
      style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfProductsku.java
  89. 28 0
      style24.batch/src/main/java/com/style24/persistence/domain/IfBrand.java
  90. 30 0
      style24.batch/src/main/java/com/style24/persistence/domain/IfProvider.java
  91. 15 0
      style24.batch/src/main/java/com/style24/persistence/mybatis/shop/TsbCommon.xml
  92. 246 1
      style24.batch/src/main/java/com/style24/persistence/mybatis/shop/TsbGoods.xml
  93. 197 0
      style24.batch/src/main/java/com/style24/persistence/mybatis/wms/TsbWmsGoods.xml
  94. 3 0
      style24.batch/src/main/resources/config/application-locd.yml
  95. 11 1
      style24.core/.gitignore
  96. 33 33
      style24.core/src/main/java/com/style24/core/biz/dao/TscAnswerPhaseDao.java
  97. 46 46
      style24.core/src/main/java/com/style24/core/biz/service/TscAnswerPhaseService.java
  98. 174 0
      style24.core/src/main/java/com/style24/core/support/util/MaskingUtils.java
  99. 26 26
      style24.core/src/main/java/com/style24/persistence/mybatis/shop/TscAnswerPhase.xml
  100. 32 0
      style24.front/.classpath

+ 10 - 2
.gitignore

@@ -2,6 +2,14 @@ target/
 .settings/
 .classpath
 /bin/
-/webapp/dx5/
+/target/
 
-.idea
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### MacOS ###
+.DS_Store
+META-INF/context.xml

+ 11 - 1
style24.admin/.gitignore

@@ -2,4 +2,14 @@ target/
 .settings/
 .classpath
 /bin/
-/webapp/dx5/
+/target/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### MacOS ###
+.DS_Store
+META-INF/context.xml

+ 0 - 9
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaAnswerPhaseDao.java

@@ -31,13 +31,4 @@ public interface TsaAnswerPhaseDao {
 	 */
 	void saveAnswerPhase(AnswerPhase ansPhase);
 
-	/**
-	 * 문의용 답변문구 조회
-	 * @param ansPhase - 답변문구 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 12. 24
-	 */
-	AnswerPhase getQnaAnswerPhase(AnswerPhase ansPhase);
-
 }

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

@@ -2,6 +2,7 @@ package com.style24.admin.biz.dao;
 
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.SearchData;
+import com.style24.persistence.domain.Sequence;
 
 /**
  * 공용 Dao
@@ -12,6 +13,24 @@ import com.style24.persistence.domain.SearchData;
 @ShopDs
 public interface TsaCommonDao {
 
+	/**
+	 * 시퀀스 조회
+	 * @param value - 시퀀스명
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	Integer getNextSequence(String value);
+
+	/**
+	 * 시퀀스 생성
+	 * @param sequence - 시퀀스정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void createNextSequence(Sequence sequence);
+
 	/**
 	 * 엑셀조회를 위한 SEARCH 테이블 삭제
 	 *

+ 117 - 5
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaDisplayDao.java

@@ -4,6 +4,7 @@ import java.util.Collection;
 
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.Category;
+import com.style24.persistence.domain.ItemkindCategory;
 
 /**
  * 전시 Dao
@@ -15,13 +16,124 @@ import com.style24.persistence.domain.Category;
 public interface TsaDisplayDao {
 
 	/**
-	 * 카테고리관리 목록
-	 *
-	 * @param category
+	 * 카테고리 목록
+	 * @param category - 카테고리 정보
 	 * @return
-	 * @author eskim
-	 * @since 2020. 12. 16
+	 * @author gagamel
+	 * @since 2021. 1. 4
 	 */
 	Collection<Category> getCategoryList(Category category);
 
+	/**
+	 * 카테고리1 저장
+	 * @param category - 카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void saveCategory1(Category category);
+
+	/**
+	 * 카테고리2 저장
+	 * @param category - 카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void saveCategory2(Category category);
+
+	/**
+	 * 카테고리3 저장
+	 * @param category - 카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void saveCategory3(Category category);
+
+	/**
+	 * 카테고리4 저장
+	 * @param category - 카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void saveCategory4(Category category);
+
+	/**
+	 * 카테고리5 저장
+	 * @param category - 카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void saveCategory5(Category category);
+
+	/**
+	 * 상위카테고리 단말여부 "N" 처리
+	 * @param category - 카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void updateUpperCategoryLeafNo(Category category);
+
+	/**
+	 * 카테고리4SRCH truncate
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void truncateCategory4Srch();
+
+	/**
+	 * 카테고리4SRCH 생성
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	void createCategory4Srch();
+
+	/**
+	 * 카테고리구분 목록
+	 * @param cateGb - 카테고리구분
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	Collection<Category> getCategoryGbList(String cateGb);
+
+	/**
+	 * 품목카테고리매핑 생성
+	 * @param itemkindCate - 품목카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	void createItemkindCategoryMapping(ItemkindCategory itemkindCate);
+
+	/**
+	 * 품목카테고리매핑에 의한 카테고리상품 생성
+	 * @param itemkindCate - 품목카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	void createCategoryGoodsByItemkindCategoryMapping(ItemkindCategory itemkindCate);
+
+	/**
+	 * 품목카테고리매핑 삭제
+	 * @param itemkindCate - 품목카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	void deleteItemkindCategoryMapping(ItemkindCategory itemkindCate);
+
+	/**
+	 * 품목카테고리매핑에 의한 카테고리상품 삭제
+	 * @param itemkindCate - 품목카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	void deleteCategoryGoodsByItemkindCategoryMapping(ItemkindCategory itemkindCate);
+
+	/**
+	 * 품목카테고리매핑 목록
+	 * @param itemkindCd - 품목코드
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 5
+	 */
+	Collection<ItemkindCategory> getItemkindCategoryMappingList(String itemkindCd);
+
 }

+ 57 - 5
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java

@@ -2,12 +2,11 @@ package com.style24.admin.biz.dao;
 
 import java.util.Collection;
 
-import org.springframework.dao.DataAccessException;
-
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.AdKeyword;
 import com.style24.persistence.domain.AdKeywordGoods;
 import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.FreeGoods;
 import com.style24.persistence.domain.Goods;
 import com.style24.persistence.domain.GoodsCompose;
 import com.style24.persistence.domain.GoodsDesc;
@@ -30,6 +29,7 @@ import com.style24.persistence.domain.Option;
 import com.style24.persistence.domain.ReinboundInform;
 import com.style24.persistence.domain.Video;
 import com.style24.persistence.domain.WmsColorMapping;
+import com.style24.persistence.domain.WmsGoods;
 import com.style24.persistence.domain.WmsSeasonMapping;
 import com.style24.persistence.domain.WmsStyleYearMapping;
 
@@ -387,6 +387,14 @@ public interface TsaGoodsDao {
 	 */
 	void deleteGoodsDesc(GoodsDesc godsDesc);
 
+	/**
+	 * 상품 상세 정보 이력 생성
+	 * @param createGoodsDetailDesc
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	public void createGoodsDetailDescHst(GoodsDesc godsDesc);
+
 	/**
 	 * 상품 상세정보 등록
 	 *
@@ -1018,7 +1026,7 @@ public interface TsaGoodsDao {
 	/**
 	 * 상품이미지 전체 삭제
 	 * @param goodsImg - 상품이미지 정보
-	 * @throws DataAccessException
+	 * @throws
 	 * @author eskim
 	 * @since 2020. 12. 21
 	 */
@@ -1027,7 +1035,7 @@ public interface TsaGoodsDao {
 	/**
 	 * 상품이미지 삭제
 	 * @param goodsImg - 상품이미지 정보
-	 * @throws DataAccessException
+	 * @throws
 	 * @author eskim
 	 * @since 2020. 12. 21
 	 */
@@ -1036,10 +1044,54 @@ public interface TsaGoodsDao {
 	/**
 	 * 상품이미지 등록
 	 * @param goodsImg - 상품이미지 정보
-	 * @throws DataAccessException
+	 * @throws
 	 * @author eskim
 	 * @since 2020. 12. 21
 	 */
 	public void createGoodsImage(GoodsImg goodsImg);
 
+	/**
+	 * 사은품 목록
+	 *
+	 * @param GoodsSearch
+	 * @return Collection<FreeGoods>
+	 * @author eskim
+	 * @since 2020. 12. 28
+	 */
+	Collection<FreeGoods> getFreeGoodsList(GoodsSearch goodsSearch);
+
+	/**
+	 * 사은품 정보 수정
+	 * @param freeGoods
+	 * @author eskim
+	 * @since 2020. 12. 28
+	 */
+	public void updateFreeGoods(FreeGoods freeGoods);
+
+	/**
+	 * WMS입고상품관리 목록 조회
+	 * @param goodsSearch
+	 * @return Collection<WmsGoods>
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	Collection<WmsGoods> getGoodsWmsIncomelotList(WmsGoods wmsGoods);
+
+	/**
+	 *  WMS 입고상품 사은품 등록
+	 * @param freeGoods
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	public void saveFreeGoods(FreeGoods freeGoods);
+
+	/**
+	 *  WMS 입고상품 사은품 상품 구분 저장
+	 * @param wmsGoods
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	public void saveGoodsWmsIncomelot(WmsGoods wmsGoods);
+
+
 }

+ 11 - 0
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaMarketingDao.java

@@ -4,6 +4,7 @@ import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.FreeGoodsPromotion;
 import com.style24.persistence.domain.Itemkind;
+import com.style24.persistence.domain.MoreBetter;
 import org.springframework.stereotype.Component;
 
 import java.util.ArrayList;
@@ -51,4 +52,14 @@ public interface TsaMarketingDao {
 	int getCouponListCnt(Coupon param);
 	/* // JSM 진행 */
 
+	/* CSB 진행 */
+	/**
+	 * 사은품 프로모션 리스트
+	 * @param MoreBetter
+	 * @return
+	 * @author bin2107
+	 * @since 2020. 12. 28
+	 */
+	Collection<MoreBetter> getMorebetterList(MoreBetter param);
+	/* // CSB 진행 */
 }

+ 61 - 1
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaOrderDao.java

@@ -2,11 +2,11 @@ package com.style24.admin.biz.dao;
 
 import java.util.Collection;
 
-import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.session.ResultHandler;
 
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.OrderChange;
 
 /**
  * 주문관리 Dao
@@ -359,6 +359,66 @@ public interface TsaOrderDao {
 	 */
 	Collection<Order> getCancelRequestTargetList(Order order);
 	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문변경정보 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createOrderChange(OrderChange orderChange);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문변경정보 상세 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createOrderChangeDetail(OrderChange orderChange);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문상세단품정보 수정
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int updateOrderDetailItem(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문상세단품정보 이력 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createOrderDetailItemHst(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문상세정보 수정
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int updateOrderDetail(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문상세정보 수정
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createOrderDetailhst(Order order);
+	
 	
 }
 

+ 2 - 2
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaRendererDao.java

@@ -196,13 +196,13 @@ public interface TsaRendererDao {
 //	Collection<CommonCode> getSellStoreList();
 
 	/**
-	 * 1:1문의용 답변문구 목록
+	 * 문의용 답변문구 목록
 	 * @param ansClsf - 답변종류
 	 * @return
 	 * @author gagamel
 	 * @since 2020. 12. 24
 	 */
-	Collection<CommonCode> getAnswerPhaseList(String ansClsf);
+	Collection<CommonCode> getQnaAnswerPhaseList(String ansClsf);
 
 //	/**
 //	 * 제휴링크 목록

+ 0 - 11
style24.admin/src/main/java/com/style24/admin/biz/service/TsaAnswerPhaseService.java

@@ -50,15 +50,4 @@ public class TsaAnswerPhaseService {
 		ansPhaseDao.saveAnswerPhase(ansPhase);
 	}
 
-	/**
-	 * 문의용 답변문구 조회
-	 * @param ansPhase - 답변문구 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 12. 24
-	 */
-	public AnswerPhase getQnaAnswerPhase(AnswerPhase ansPhase) {
-		return ansPhaseDao.getQnaAnswerPhase(ansPhase);
-	}
-
 }

+ 23 - 1
style24.admin/src/main/java/com/style24/admin/biz/service/TsaCommonService.java

@@ -2,9 +2,13 @@ package com.style24.admin.biz.service;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 import com.style24.admin.biz.dao.TsaCommonDao;
 import com.style24.persistence.domain.SearchData;
+import com.style24.persistence.domain.Sequence;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -21,6 +25,25 @@ public class TsaCommonService {
 	@Autowired
 	private TsaCommonDao commonDao;
 
+	/**
+	 * 시퀀스 조회(중첩트랜잭션으로 처리. 부모 트랜잭션의 커밋과 롤백에는 영향을 받지만 자신의 커밋과 롤백은 부모 트랜잭션에게 영향을 주지 않는다.)
+	 * @param sequenceNm - 시퀀스명
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	@Transactional(value = "shopTxnManager", isolation = Isolation.SERIALIZABLE, propagation = Propagation.NESTED)
+	public Integer getNextSequence(String sequenceNm) {
+		Integer nextVal = commonDao.getNextSequence(sequenceNm);
+
+		Sequence sequence = new Sequence();
+		sequence.setSequenceNm(sequenceNm);
+		sequence.setNextVal(nextVal);
+		commonDao.createNextSequence(sequence);
+
+		return sequence.getNextVal();
+	}
+
 	/**
 	 * 엑셀조회를 위한 SEARCH 테이블 삭제
 	 *
@@ -80,5 +103,4 @@ public class TsaCommonService {
 		return commonDao.getErpSyncYn();
 	}
 
-
 }

+ 0 - 5
style24.admin/src/main/java/com/style24/admin/biz/service/TsaCounselService.java

@@ -7,7 +7,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import com.style24.admin.biz.dao.TsaCounselDao;
-import com.style24.admin.support.security.session.TsaSession;
 import com.style24.persistence.domain.Counsel;
 
 import lombok.extern.slf4j.Slf4j;
@@ -68,8 +67,6 @@ public class TsaCounselService {
 	 * @since 2020. 12. 24
 	 */
 	public Collection<Counsel> getGoodsQnaList(Counsel counsel) {
-		counsel.setRoleCd(TsaSession.getInfo().getRoleCd());
-		counsel.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
 		return counselDao.getGoodsQnaList(counsel);
 	}
 
@@ -83,8 +80,6 @@ public class TsaCounselService {
 	public Counsel getGoodsQna(Integer counselSq) {
 		Counsel counsel = new Counsel();
 		counsel.setCounselSq(counselSq);
-		counsel.setRoleCd(TsaSession.getInfo().getRoleCd());
-		counsel.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
 		return counselDao.getGoodsQna(counsel);
 	}
 

+ 126 - 5
style24.admin/src/main/java/com/style24/admin/biz/service/TsaDisplayService.java

@@ -3,10 +3,14 @@ package com.style24.admin.biz.service;
 import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import com.style24.admin.biz.dao.TsaDisplayDao;
+import com.style24.admin.support.security.session.TsaSession;
 import com.style24.persistence.domain.Category;
+import com.style24.persistence.domain.ItemkindCategory;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -23,17 +27,134 @@ public class TsaDisplayService {
 	@Autowired
 	private TsaDisplayDao displayDao;
 
+	@Autowired
+	private TsaCommonService commonService;
+
 	/**
-	 * 카테고리관리 목록
-	 *
-	 * @param category
+	 * 카테고리 목록
+	 * @param category - 카테고리 정보
 	 * @return
-	 * @author sasa004
-	 * @since 2020.01.07
+	 * @author gagamel
+	 * @since 2021. 1. 4
 	 */
 	public Collection<Category> getCategoryList(Category category) {
 		return displayDao.getCategoryList(category);
 	}
 
+	/**
+	 * 카테고리 저장
+	 * @param category - 카테고리 정보
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	@Transactional("shopTxnManager")
+	public void saveCategory(Category category) {
+		category.setRegNo(TsaSession.getInfo().getUserNo());
+		category.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		Integer selLvl = category.getSelLvl();
+
+		// 카테고리번호
+		Integer cateNo = category.getCateNo();
+		if (cateNo == null) {
+			cateNo = commonService.getNextSequence("SEQ_CATE");
+		}
+
+		if (selLvl == 1) {
+			category.setCate1No(cateNo);
+			category.setCate1Nm(category.getCateNm());
+			displayDao.saveCategory1(category);
+		} else if (selLvl == 2) {
+			category.setCate2No(cateNo);
+			category.setCate2Nm(category.getCateNm());
+			displayDao.saveCategory2(category);
+		} else if (selLvl == 3) {
+			category.setCate3No(cateNo);
+			category.setCate3Nm(category.getCateNm());
+			displayDao.saveCategory3(category);
+		} else if (selLvl == 4) {
+			category.setCate4No(cateNo);
+			category.setCate4Nm(category.getCateNm());
+			displayDao.saveCategory4(category);
+		} else if (selLvl == 5) {
+			category.setCate5No(cateNo);
+			category.setCate5Nm(category.getCateNm());
+			displayDao.saveCategory5(category);
+		}
+
+		if (selLvl >= 2) {
+			displayDao.updateUpperCategoryLeafNo(category);
+		}
+	}
+
+	/**
+	 * 카테고리 갱신
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	@Transactional("shopTxnManager")
+	@CacheEvict(value = "cate", allEntries = true)
+	public void refreshCategory() {
+		displayDao.truncateCategory4Srch();
+		displayDao.createCategory4Srch();
+	}
+
+	/**
+	 * 카테고리구분 목록
+	 * @param cateGb - 카테고리구분
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	public Collection<Category> getCategoryGbList(String cateGb) {
+		return displayDao.getCategoryGbList(cateGb);
+	}
+
+	/**
+	 * 품목카테고리매핑 저장
+	 * @param itemkindCateList - 품목카테고리 목록
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	@Transactional("shopTxnManager")
+	public void saveItemkindCategoryMappingList(Collection<ItemkindCategory> itemkindCateList) {
+		for (ItemkindCategory itemkindCate : itemkindCateList) {
+			itemkindCate.setRegNo(TsaSession.getInfo().getUserNo());
+
+			// 품목카테고리매핑 생성
+			displayDao.createItemkindCategoryMapping(itemkindCate);
+
+			// 품목카테고리매핑에 의한 카테고리상품 생성
+			displayDao.createCategoryGoodsByItemkindCategoryMapping(itemkindCate);
+		}
+	}
+
+	/**
+	 * 품목카테고리매핑 삭제
+	 * @param itemkindCateList - 품목카테고리 목록
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteItemkindCategoryMappingList(Collection<ItemkindCategory> itemkindCateList) {
+		for (ItemkindCategory itemkindCate : itemkindCateList) {
+			// 품목카테고리매핑 삭제
+			displayDao.deleteItemkindCategoryMapping(itemkindCate);
+
+			// 품목카테고리매핑에 의한 카테고리상품 삭제
+			displayDao.deleteCategoryGoodsByItemkindCategoryMapping(itemkindCate);
+		}
+	}
+
+	/**
+	 * 품목카테고리매핑 목록
+	 * @param itemkindCd - 품목코드
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 5
+	 */
+	public Collection<ItemkindCategory> getItemkindCategoryMappingList(String itemkindCd) {
+		return displayDao.getItemkindCategoryMappingList(itemkindCd);
+	}
 
 }

+ 135 - 40
style24.admin/src/main/java/com/style24/admin/biz/service/TsaGoodsService.java

@@ -22,6 +22,7 @@ import com.style24.persistence.domain.AdKeyword;
 import com.style24.persistence.domain.AdKeywordGoods;
 import com.style24.persistence.domain.Brand;
 import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.FreeGoods;
 import com.style24.persistence.domain.Goods;
 import com.style24.persistence.domain.GoodsCompose;
 import com.style24.persistence.domain.GoodsDesc;
@@ -46,6 +47,7 @@ import com.style24.persistence.domain.ReinboundInform;
 import com.style24.persistence.domain.SearchData;
 import com.style24.persistence.domain.Video;
 import com.style24.persistence.domain.WmsColorMapping;
+import com.style24.persistence.domain.WmsGoods;
 import com.style24.persistence.domain.WmsSeasonMapping;
 import com.style24.persistence.domain.WmsStyleYearMapping;
 
@@ -480,27 +482,38 @@ public class TsaGoodsService {
 		GoodsDesc goods = new GoodsDesc();
 		goods.setGoodsCd(resultGoods.getGoodsCd());
 
-		//		goods.setDescGb("10");
-		//		String goodsDesc = this.getGoodsDescList(goods);
-		//		resultGoods.setGoodsDesc(goodsDesc);
+		// 상품 상세 타이틀
+		goods.setDescGb("10");
+		String goodsTitlesDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsTitlesDesc(goodsTitlesDesc);
 
-		// 상품 상세 pc 상단
+		// 상품 상세 내용
 		goods.setDescGb("20");
+		String goodsContentsDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsContentsDesc(goodsContentsDesc);
+
+		// 상품 상세 특징
+		goods.setDescGb("30");
+		String goodsCharacterDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsCharacterDesc(goodsCharacterDesc);
+
+		// 상품 상세 pc 상단
+		goods.setDescGb("40");
 		String goodsPcTopDesc = this.getGoodsDescList(goods);
 		resultGoods.setGoodsPcTopDesc(goodsPcTopDesc);
 
 		// 상품 상세  pc 하단
-		goods.setDescGb("30");
+		goods.setDescGb("50");
 		String goodsPcDownDesc = this.getGoodsDescList(goods);
 		resultGoods.setGoodsPcDownDesc(goodsPcDownDesc);
 
 		// 상품 상세 mobile 상단
-		goods.setDescGb("40");
+		goods.setDescGb("60");
 		String goodsMobileTopDesc = this.getGoodsDescList(goods);
 		resultGoods.setGoodsMobileTopDesc(goodsMobileTopDesc);
 
-		// 상품 상세 mpbile 하단
-		goods.setDescGb("50");
+		// 상품 상세 mobile 하단
+		goods.setDescGb("70");
 		String goodsMobileDownDesc = this.getGoodsDescList(goods);
 		resultGoods.setGoodsMobileDownDesc(goodsMobileDownDesc);
 
@@ -522,6 +535,8 @@ public class TsaGoodsService {
 			for (GoodsDesc tmpGoodsDesc : goodsDescList) {
 				goodsDescSb.append(tmpGoodsDesc.getGoodsDesc());
 			}
+		}else {
+			goodsDescSb.append("");
 		}
 		return goodsDescSb.toString();
 	}
@@ -942,20 +957,35 @@ public class TsaGoodsService {
 		goods.setGoodsTnm(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsTnm(), "&lt;", "<"), "&gt;", ">"));
 		goods.setGoodsSnm1(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsSnm1(), "&lt;", "<"), "&gt;", ">"));
 
-		// 세트일 경우 상품 가격 확인
-		if ("G056_S".equals(goods.getGoodsType())) {
+		// 딜상품의 대표상품 변경여부 확인
+		if ("G056_D".equals(goods.getGoodsType())) {
 
+			String newRepGoodsCd = "";
+			int newRepGoodsPrice = 0;
 			Collection<GoodsCompose> goodsExtendList = goods.getGoodsComposeListNew();
-			int currPriceSum = 0;
 			for (GoodsCompose regGoodsExtend : goodsExtendList) {
-				currPriceSum  = currPriceSum + regGoodsExtend.getCompsCurrPrice();
+				if ("Y".equals(regGoodsExtend.getRepYn())) {
+					newRepGoodsCd = regGoodsExtend.getCompsGoodsCd();
+					newRepGoodsPrice = regGoodsExtend.getCurrPrice();
+				}
 			}
 
-			if (currPriceSum != goods.getCurrPriceOrg()) {
+			log.info("newRepGoodsCd = {}, newRepGoodsPrice = {}, goods.getRepGoodsCd = {}", newRepGoodsCd, newRepGoodsPrice, goods.getRepGoodsCd());
+			// 1순 : 대표상품 변경, 2순 : 판매가 변경
+			if (!newRepGoodsCd.equals(goods.getRepGoodsCd())) {
 				goods.setCurrBprice(goods.getCurrPriceOrg());
-				goods.setCurrPrice(currPriceSum);
-				goods.setDcRate((int)(this.getDcRate(goods.getListPrice() , currPriceSum)));
+				goods.setCurrPrice(newRepGoodsPrice);
+				goods.setListPrice(newRepGoodsPrice);
+				goods.setDcRate(0);
+				goods.setChDataYn("Y");
+			}else {
+				if (goods.getCurrPrice() != goods.getCurrPriceOrg()) {
+					goods.setCurrBprice(goods.getCurrPriceOrg());
+					goods.setListPrice(goods.getCurrPrice());
+					goods.setDcRate(0);
+				}
 			}
+
 		}else {
 			// 가격변경일
 			if (goods.getCurrPrice() != goods.getCurrPriceOrg()) {
@@ -1061,6 +1091,7 @@ public class TsaGoodsService {
 			goodsOrderGrade.setRegNo(TsaSession.getInfo().getUserNo());
 			goodsDao.deleteGoodsCustGrade(goodsOrderGrade);
 		}
+
 	}
 
 	/**
@@ -1071,40 +1102,47 @@ public class TsaGoodsService {
 	 * @since 2020. 10. 27.
 	 */
 	private void saveGoodsDetailDesc(Goods goods) {
-		// 상품상세 구분(10:상품설명, 20:상위컨텐츠, 30:하위컨텐츠, 40:하위컨텐츠-모바일, 50:상위컨텐츠-모바일)
+		// 상품상세 구분(10:상품타이틀,20:상품타이틀내용,30:상품특징,40:상위컨텐츠,50:하위컨텐츠,60:하위컨텐츠-모바일,70:상위컨텐츠-모바일)
 		GoodsDesc goodsDesc = new GoodsDesc();
 		goodsDesc.setGoodsCd(goods.getGoodsCd());
 		goodsDesc.setRegNo(goods.getRegNo());
 		goodsDesc.setUpdNo(goods.getUpdNo());
 
-		// PC 상단
+		// AS-IS 상세 정보 이력 처리
+		goodsDao.createGoodsDetailDescHst(goodsDesc);
+
+		// 상세 타이틀
 		goodsDesc.setDescGb("10");
-		goodsDesc.setGoodsDesc(goods.getGoodsPcTopDesc());
+		goodsDesc.setGoodsDesc(goods.getGoodsTitlesDesc());
 		this.saveGoodsDesc(goodsDesc);
 
-		// PC 하단
+		// 상세 내용
 		goodsDesc.setDescGb("20");
-		goodsDesc.setGoodsDesc(goods.getGoodsPcTopDesc());
+		goodsDesc.setGoodsDesc(goods.getGoodsContentsDesc());
 		this.saveGoodsDesc(goodsDesc);
 
-		// 공용 하단
+		// 상세 특징
 		goodsDesc.setDescGb("30");
-		goodsDesc.setGoodsDesc(goods.getGoodsPcDownDesc());
+		goodsDesc.setGoodsDesc(goods.getGoodsCharacterDesc());
 		this.saveGoodsDesc(goodsDesc);
 
-		// MO 상단
+		// PC 상단
 		goodsDesc.setDescGb("40");
-		goodsDesc.setGoodsDesc(goods.getGoodsMobileTopDesc());
+		goodsDesc.setGoodsDesc(goods.getGoodsPcTopDesc());
 		this.saveGoodsDesc(goodsDesc);
 
-		//		// 상품상세 저장
+		// PC 하단
+		goodsDesc.setDescGb("50");
+		goodsDesc.setGoodsDesc(goods.getGoodsPcDownDesc());
+		this.saveGoodsDesc(goodsDesc);
 
-		//
-		//		// 세트상품의 구서상품으로 있을경우 처리
-		//		this.saveGoodsSetDesc(goodsDesc);
+		// MO 상단
+		goodsDesc.setDescGb("60");
+		goodsDesc.setGoodsDesc(goods.getGoodsMobileTopDesc());
+		this.saveGoodsDesc(goodsDesc);
 
 		// MO 하단
-		goodsDesc.setDescGb("50");
+		goodsDesc.setDescGb("70");
 		goodsDesc.setGoodsDesc(goods.getGoodsMobileDownDesc());
 		this.saveGoodsDesc(goodsDesc);
 
@@ -1489,25 +1527,15 @@ public class TsaGoodsService {
 			dispOrd++;
 		}
 
-
 		// 사용자 검색어를 검색어에 적용
 		String goodsSnm = goodsDao.getGoodsSnm(regGoods.getGoodsCd());
 		regGoods.setGoodsSnm(goodsSnm);
 		goodsDao.updateGoodsSnm(regGoods);
+
 		// 카테고리 전시
 		// 추후 작업 해야함 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 		//goodsDao.createCategoryGoods(regGoods);
 
-		// 추후 작업 해야함 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-		// 대표 이미지만 생성
-//		GoodsImg goodsImg = new GoodsImg();
-//		goodsImg.setGoodsCd(regGoods.getGoodsCd());
-//		goodsImg.setImgType("A");
-//		// 이미지 경로 확인하자!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-//		goodsImg.setImgPath1(this.getGoodsImgPath(regGoods.getGoodsCd(), regGoods.getBrandCd()) + "01.jpg");
-//		goodsImg.setRegNo(TsaSession.getInfo().getUserNo());
-//		goodsImg.setUpdNo(TsaSession.getInfo().getUserNo());
-//		goodsDao.saveGoodsImgInfo(goodsImg);
 	}
 
 //	/**
@@ -2600,4 +2628,71 @@ public class TsaGoodsService {
 		}
 	}
 
+	/**
+	 * 사은품 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<FreeGoods>
+	 * @author eskim
+	 * @since 2020. 12. 28
+	 */
+	public Collection<FreeGoods> getFreeGoodsList(GoodsSearch goodsSearch) {
+		return goodsDao.getFreeGoodsList(goodsSearch);
+	}
+
+	/**
+	 * 사은품 정보 수정
+	 * @param goodsImgList - 상품이미지 목록
+	 * @throws AdmBizException
+	 * @author eskim
+	 * @since 2020. 12. 21
+	 */
+	@Transactional("shopTxnManager")
+	public void updateFreeGoods(FreeGoods freeGoods){
+
+		freeGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+		goodsDao.updateFreeGoods(freeGoods);
+	}
+
+	/**
+	 * WMS입고상품관리 목록 조회
+	 *
+	 * @param goodsSearch
+	 * @return Collection<WmsGoods>
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	public Collection<WmsGoods> getGoodsWmsIncomelotList(WmsGoods wmsGoods) {
+		return goodsDao.getGoodsWmsIncomelotList(wmsGoods);
+	}
+
+	/**
+	 * WMS 입고상품 사은품 등록
+	 * @param wmsGoodsList
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	@Transactional("shopTxnManager")
+	public void saveFreeGoods(Collection<WmsGoods> wmsGoodsList){
+
+		for (WmsGoods wmsGoods: wmsGoodsList) {
+			FreeGoods freeGoods = new FreeGoods();
+			freeGoods.setProductNo(wmsGoods.getProductNo());
+			freeGoods.setProductCode(wmsGoods.getProductCode());
+			freeGoods.setGoodsNum(wmsGoods.getModelNo());
+			freeGoods.setBrandCd(wmsGoods.getBrandCd());
+			freeGoods.setGoodsNm(wmsGoods.getProductName());
+			freeGoods.setUseYn("Y");
+			freeGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+			freeGoods.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsDao.saveFreeGoods(freeGoods);
+
+			//WMS 상품등록구분
+			wmsGoods.setGoodsRegGb("F");
+			wmsGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+			wmsGoods.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsDao.saveGoodsWmsIncomelot(wmsGoods);
+		}
+	}
+
 }

+ 12 - 0
style24.admin/src/main/java/com/style24/admin/biz/service/TsaMarketingService.java

@@ -113,4 +113,16 @@ public class TsaMarketingService {
 	}
 	/* // JSM 진행 */
 
+	/* CSB 진행 */
+	/**
+	 * 다다익선 리스트
+	 * @param param
+	 * @return
+	 * @author bin2107
+	 * @since 2020. 12. 28
+	 */
+	public Collection<MoreBetter> getMorebetterList(MoreBetter param) {
+		return marketingDao.getMorebetterList(param);
+	}
+	/* // CSB 진행 */
 }

+ 315 - 0
style24.admin/src/main/java/com/style24/admin/biz/service/TsaOrderService.java

@@ -1,6 +1,8 @@
 package com.style24.admin.biz.service;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -11,11 +13,13 @@ import org.springframework.transaction.annotation.Transactional;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.gagaframework.excel.env.GagaExcelConstants;
 import com.gagaframework.excel.xssf.GagaExcelResultHandler;
+import com.gagaframework.web.parameter.GagaMap;
 import com.style24.admin.biz.dao.TsaOrderDao;
 import com.style24.admin.support.security.session.TsaSession;
 import com.style24.admin.support.util.TsitUtil;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.OrderChange;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -587,4 +591,315 @@ public class TsaOrderService {
 		return orderDao.getCancelRequestTargetList(order);
 	}
 	
+	/**
+	 * 주문상세 > 주문취소대상목록
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public GagaMap orderCancelRefundAmt(List<Order> cancelReqList) {
+		GagaMap mav = new GagaMap();
+		
+		int spanPayAmt			= 0; // 총 결제 금액
+		int spanSumRealOrdAmt	= 0; // 상품 실결제 금액
+		int spanSumDeliveryFee	= 0; // 배송금액
+		int spanOrdAmt			= 0; // 주문 상품 금액
+		int spanCnclRtnAmt		= 0; // 취소 상품 금액
+		int spanTotPntDcAmt		= 0; // 취소 사용 포인트
+		int spanPntDcAmt		= 0; // 고객 포인트
+		int spanPrePntDcAmt		= 0; // 상품 선포인트
+		int spanCpnDcAmt		= 0; // 취소 사용 쿠폰금액
+		int spanCpn1DcAmt		= 0; // 즉시할인쿠폰
+		int spanGoodsCpnDcAmt	= 0; // 상품쿠폰
+		int spanCartCpnDcAmt	= 0; // 장바구니쿠폰
+		int spanTmtbDcAmt		= 0; // 취소 다다익선 금액
+		int spanTmtb1DcAmt		= 0; // 수량할인
+		int spanTmtb2DcAmt		= 0; // 금액할인
+		int spanGfcdUseAmt		= 0; // 취소 고객 상품권 금액
+		int spanRealCnclRtnAmt	= 0; // 취소 상품 실결제 금액
+		int spanTotDeliveryFee	= 0; // 환불 배송 금액
+		int spanRefundAmt		= 0; // 환불 금액 합계
+		
+		List<Order> cancelOrderRefundList = new ArrayList<Order>();		// 주문환불금액목록
+		List<Order> cancelDelvRefundList 	= new ArrayList<Order>();	// 주문환불배송금액목록
+		
+		Order orderObj	= new Order();
+		Order delvObj	= new Order();
+		int k 			= 0 ;
+		
+		// 최초의 배송정보를 설정
+		delvObj.setOrdAmt(0);
+		delvObj.setCnclRtnAmt(0);
+		delvObj.setRealOrdAmt(0);
+		delvObj.setDelvFee(cancelReqList.get(k).getDelvFee());
+		delvObj.setMinOrdAmt(cancelReqList.get(k).getMinOrdAmt());
+		delvObj.setOrgDelvFee(cancelReqList.get(k).getOrgDelvFee());
+		delvObj.setSupplyCompCd(cancelReqList.get(k).getSupplyCompCd());
+		delvObj.setDelvFeeCd(cancelReqList.get(k).getDelvFeeCd());
+		delvObj.setAllCanYn(cancelReqList.get(k).getAllCanYn());
+		cancelDelvRefundList.add(delvObj);
+
+		for (Order oneData : cancelReqList) {
+			orderObj	= new Order();
+			
+			// 주문정보설정
+			orderObj.setItemQty(oneData.getItemQty());
+			orderObj.setOrdQty(oneData.getOrdQty());
+			orderObj.setCnclRtnQty(oneData.getCnclRtnQty());
+			orderObj.setOrdReqChgQty(oneData.getOrdReqChgQty());
+			orderObj.setOrdCanChgQty(oneData.getOrdCanChgQty());
+			orderObj.setItemPrice(oneData.getItemPrice());
+			orderObj.setOptAddPrice	(oneData.getOptAddPrice());
+			orderObj.setOrdAmt(oneData.getOrdAmt());
+			
+			orderObj.setOrdNo(oneData.getOrdNo());
+			orderObj.setOrdDtlNo(oneData.getOrdDtlNo());
+			orderObj.setGoodsCd(oneData.getGoodsCd());
+			orderObj.setGoodsNm(oneData.getGoodsNm());
+			orderObj.setOrdDtlItemSq(oneData.getOrdDtlItemSq());
+			orderObj.setItemCd(oneData.getItemCd());
+			orderObj.setItemNm(oneData.getItemNm());
+			orderObj.setOptCd1(oneData.getOptCd1());
+			orderObj.setOptCd2(oneData.getOptCd2());
+			
+			int ordQty 			= oneData.getOrdQty();
+			int itemQty 		= oneData.getItemQty();
+			int ordCanChgQty 	= oneData.getOrdCanChgQty();
+			
+			// 취소금액계산
+			orderObj.setCnclRtnAmt(((oneData.getItemPrice() + oneData.getOptAddPrice()) * itemQty) * ordCanChgQty);
+			orderObj.setCpn1DcAmt(oneData.getCpn1DcAmt() 			* (ordCanChgQty/ordQty));
+			orderObj.setTmtb1DcAmt(oneData.getTmtb1DcAmt() 			* (ordCanChgQty/ordQty));
+			orderObj.setTmtb2DcAmt(oneData.getTmtb2DcAmt() 			* (ordCanChgQty/ordQty));
+			orderObj.setGoodsCpnDcAmt(oneData.getGoodsCpnDcAmt() 	* (ordCanChgQty/ordQty));
+			orderObj.setCartCpnDcAmt(oneData.getCartCpnDcAmt() 		* (ordCanChgQty/ordQty));
+			orderObj.setPntDcAmt(oneData.getPntDcAmt() 				* (ordCanChgQty/ordQty));
+			orderObj.setPrePntDcAmt(oneData.getPrePntDcAmt() 		* (ordCanChgQty/ordQty));
+			orderObj.setGfcdUseAmt(oneData.getGfcdUseAmt() 			* (ordCanChgQty/ordQty));
+			
+			// 취소할인금액
+			int dcTotAmt		= 0;
+			dcTotAmt			+= orderObj.getTmtb1DcAmt();
+			dcTotAmt			+= orderObj.getTmtb2DcAmt();
+			dcTotAmt			+= orderObj.getGoodsCpnDcAmt();
+			dcTotAmt			+= orderObj.getCartCpnDcAmt();
+			dcTotAmt			+= orderObj.getPntDcAmt();
+			dcTotAmt			+= orderObj.getPrePntDcAmt();
+			dcTotAmt			+= orderObj.getCpn1DcAmt();
+			dcTotAmt			+= orderObj.getGfcdUseAmt();
+			
+			// 취소환불금액
+			orderObj.setRealOrdAmt(orderObj.getCnclRtnAmt() - dcTotAmt);
+			
+			// 배송관련 설정		
+			orderObj.setOrdDtlNo(oneData.getOrdDtlNo());
+			orderObj.setGoodsTypeNm(oneData.getGoodsTypeNm());
+			orderObj.setDelvFee(oneData.getDelvFee());
+			orderObj.setSupplyCompCd(oneData.getSupplyCompCd());
+			orderObj.setDelvFeeCd(oneData.getDelvFeeCd());
+			orderObj.setMinOrdAmt(oneData.getMinOrdAmt());
+			orderObj.setOrgDelvFee(oneData.getOrgDelvFee());
+			
+			// 주문상세상태
+			orderObj.setOrdDtlStat(oneData.getOrdDtlStat());
+			orderObj.setOrdDtlStatNm(oneData.getOrdDtlStatNm());
+			orderObj.setAllCanYn(oneData.getAllCanYn());
+			
+			cancelOrderRefundList.add(orderObj);
+			
+			// 배송비 정책 기준으로 조건 처리
+			if (cancelDelvRefundList.get(k).getSupplyCompCd().equals(orderObj.getSupplyCompCd()) && cancelDelvRefundList.get(k).getDelvFeeCd().equals(orderObj.getDelvFeeCd())) {
+				// 공급업체 와 배송정책코드가 같으면 주문금액, 취소금액 SUM
+				cancelDelvRefundList.get(k).setOrdAmt(cancelDelvRefundList.get(k).getOrdAmt() + orderObj.getOrdAmt());
+				cancelDelvRefundList.get(k).setCnclRtnAmt(cancelDelvRefundList.get(k).getCnclRtnAmt() + orderObj.getCnclRtnAmt());
+				cancelDelvRefundList.get(k).setRealOrdAmt(cancelDelvRefundList.get(k).getRealOrdAmt() + orderObj.getRealOrdAmt());
+				
+				if ("N".equals(orderObj.getAllCanYn())) {
+					cancelDelvRefundList.get(k).setAllCanYn("N");
+				}
+			} else {			
+				k++;
+				
+				delvObj	= new Order();
+				
+				// 공급업체 와 배송정책코드가 같지안으면 주문금액, 취소금액 RESET
+				delvObj.setOrdAmt(orderObj.getOrdAmt());
+				delvObj.setCnclRtnAmt(orderObj.getCnclRtnAmt());
+				delvObj.setRealOrdAmt(orderObj.getRealOrdAmt());
+				
+				delvObj.setDelvFee(orderObj.getDelvFee());
+				delvObj.setMinOrdAmt(orderObj.getMinOrdAmt());			
+				delvObj.setOrgDelvFee(orderObj.getOrgDelvFee());
+				delvObj.setSupplyCompCd(orderObj.getSupplyCompCd());
+				delvObj.setDelvFeeCd(orderObj.getDelvFeeCd());
+				delvObj.setAllCanYn(orderObj.getAllCanYn());
+				
+				cancelDelvRefundList.add(delvObj);
+			}
+			
+			spanSumRealOrdAmt	+= oneData.getRealOrdAmt();
+			spanPntDcAmt		+= orderObj.getPntDcAmt();
+			spanPrePntDcAmt		+= orderObj.getPrePntDcAmt();
+			spanCpn1DcAmt		+= orderObj.getCpn1DcAmt();
+			spanGoodsCpnDcAmt	+= orderObj.getGoodsCpnDcAmt();
+			spanCartCpnDcAmt	+= orderObj.getCartCpnDcAmt();
+			spanTmtb1DcAmt		+= orderObj.getTmtb1DcAmt();
+			spanTmtb2DcAmt		+= orderObj.getTmtb2DcAmt();
+			spanGfcdUseAmt		+= orderObj.getGfcdUseAmt();
+			spanRealCnclRtnAmt	+= orderObj.getRealOrdAmt();
+		}
+		
+		// 추가배송비 발생여부 , 추가배송비, 배송비정책단위 전체취소 여부
+		for (int i=0 ; i<cancelDelvRefundList.size() ; i++) {
+			Order obj = cancelDelvRefundList.get(i);
+			
+			// 무료배송비용 > (주문금액 - 취소금액)
+			if (obj.getMinOrdAmt() > (obj.getOrdAmt() - obj.getCnclRtnAmt())) {
+				// 2020.12.28 
+				// case : 배송정책 기준으로 1,2 상품 주문 후 1번 출고 후 1번반품 2번취소 할 경우 전체 취소 가 아니므로 배송비 부과 있을지 모르겠음 주문업체 단위로 배송되기 때문에 발생하지 않을것 같음
+				if ((obj.getOrdAmt() - obj.getCnclRtnAmt()) == 0) {
+					if ("N".equals(obj.getAllCanYn())) {
+						obj.setAddDelvFeeYn("Y");
+						obj.setAddDelvFee(obj.getOrgDelvFee());
+					} else {
+						// 전체취소의 경우에 해당
+						obj.setAddDelvFeeYn("N");
+						obj.setAddDelvFee(0);
+					}
+				} else {
+					// 취소신청화면에서 대부분 아래의 조건에 해당
+					obj.setAddDelvFeeYn("Y");
+					obj.setAddDelvFee(obj.getOrgDelvFee());
+				}
+			} else {
+				obj.setAddDelvFeeYn("N");
+				obj.setAddDelvFee(0);
+			}
+			
+			spanSumDeliveryFee	+= obj.getDelvFee();
+			spanOrdAmt			+= obj.getOrdAmt();
+			spanCnclRtnAmt		+= obj.getCnclRtnAmt();
+			spanTotDeliveryFee  += obj.getAddDelvFee();
+			
+			cancelDelvRefundList.set(i, obj);
+		}
+		
+		// 2020.12.30 프론트에서 필요한 부분 작업 필여
+		// 관리자 화면에서 사용하는 환불 칼럼 정보
+		// 환불금액표시
+		spanPayAmt 			= spanSumRealOrdAmt + spanSumDeliveryFee;
+		spanTotPntDcAmt 	= spanPntDcAmt + spanPrePntDcAmt;
+		spanCpnDcAmt 		= spanCpn1DcAmt + spanGoodsCpnDcAmt + spanCartCpnDcAmt;
+		spanTmtbDcAmt 		= spanTmtb1DcAmt + spanTmtb2DcAmt;
+		spanRefundAmt 		= spanRealCnclRtnAmt - spanTotDeliveryFee;
+
+		mav.set("cancelOrderRefundList"	, cancelOrderRefundList);	//주문 환불 금액 목록
+		mav.set("cancelDelvRefundList"	, cancelDelvRefundList);	//주문 환불 배송 금액 목록
+		mav.set("spanPayAmt"			, spanPayAmt);				//총 결제 금액
+		mav.set("spanSumRealOrdAmt"		, spanSumRealOrdAmt);		//상품 실결제 금액
+		mav.set("spanSumDeliveryFee"	, spanSumDeliveryFee);		//배송금액
+		mav.set("spanOrdAmt"			, spanOrdAmt);				//주문 상품 금액
+		mav.set("spanCnclRtnAmt"		, spanCnclRtnAmt);			//취소 상품 금액
+		mav.set("spanTotPntDcAmt"		, spanTotPntDcAmt);			//취소 사용 포인트
+		mav.set("spanPntDcAmt"			, spanPntDcAmt);			//고객 포인트
+		mav.set("spanPrePntDcAmt"		, spanPrePntDcAmt);			//상품 선포인트
+		mav.set("spanCpnDcAmt"			, spanCpnDcAmt);			//취소 사용 쿠폰금액
+		mav.set("spanCpn1DcAmt"			, spanCpn1DcAmt);			//즉시할인쿠폰
+		mav.set("spanGoodsCpnDcAmt"		, spanGoodsCpnDcAmt);		//상품쿠폰
+		mav.set("spanCartCpnDcAmt"		, spanCartCpnDcAmt);		//장바구니쿠폰
+		mav.set("spanTmtbDcAmt"			, spanTmtbDcAmt);			//취소 다다익선 금액
+		mav.set("spanTmtb1DcAmt"		, spanTmtb1DcAmt);			//수량할인
+		mav.set("spanTmtb2DcAmt"		, spanTmtb2DcAmt);			//금액할인
+		mav.set("spanGfcdUseAmt"		, spanGfcdUseAmt);			//취소 고객 상품권 금액
+		mav.set("spanRealCnclRtnAmt"	, spanRealCnclRtnAmt);		//취소 상품 실결제 금액
+		mav.set("spanTotDeliveryFee"	, spanTotDeliveryFee);		//환불 배송 금액
+		mav.set("spanRefundAmt"			, spanRefundAmt);			//환불 금액 합계
+		
+		return mav;
+	}
+	
+	// 문자의 오른쪽으로 숫자만큼 공백 삽인
+	private static String padRight(String s, int n) {
+		return String.format("%-" + n + "s", s);
+	}
+	
+	// 문자의 왼쪽으로 숫자만큼 공백 삽인
+	private static String padLeft(String s, int n) {
+		return String.format("%" + n + "s", s);
+	}
+	
+	/**
+	 * 주문상세 > 주문취소
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 30
+	 */
+	@Transactional("shopTxnManager")
+	public void orderCancel(GagaMap mav) {
+		
+		// 1. 세션회원조회
+		int userNo = TsaSession.getInfo().getUserNo();
+		
+		// 2. 취소요정정보목록
+		List<Order> cancelOrderRefundList = (List<Order>) mav.get("cancelOrderRefundList");
+		
+		// 3. 취소신청정보
+		int ordNo 			= Integer.parseInt(mav.getString("ordNo").toString());
+		String chgReason 	= mav.getString("chgReason").toString();
+		String chgMemo 		= mav.getString("chgMemo").toString();
+		String chgGb		= "G680_20";
+		
+		// 4.1 주문변경 기본정보 등록
+		OrderChange orderChange = new OrderChange();
+		orderChange.setOrdNo(ordNo);
+		orderChange.setChgGb(chgGb);
+		orderChange.setChgReason(chgReason);
+		orderChange.setChgMemo(chgMemo);
+		orderChange.setAddPayCost(0);
+		orderChange.setAddPayAmt(0);
+		orderChange.setRegNo(userNo);
+		orderChange.setUpdNo(userNo);
+		
+		orderDao.createOrderChange(orderChange);
+		
+		// 4.2 주문변경 상세 정보 등록
+		for (int i=0 ; i<cancelOrderRefundList.size() ; i++) {
+			Order vo = cancelOrderRefundList.get(i);
+			vo.setRegNo(userNo);
+			vo.setUpdNo(userNo);
+			vo.setOrdDtlStat("G685_21");
+			
+			// 4.2.1 취소수량이 존재하면 주문정보 수정 및 주문변경정보 등록
+			if (vo.getOrdCanChgQty() > 0) {
+				OrderChange po = new OrderChange();
+				
+				po.setOrdChgSq(orderChange.getOrdChgSq());
+				po.setOrdDtlNo(vo.getOrdDtlNo());
+				po.setChgQty(vo.getOrdCanChgQty());
+				po.setChgStat("G685_21");
+				po.setRegNo(userNo);
+				po.setUpdNo(userNo);
+				
+				// 4.2.2 주문변경상세정보 등록
+				orderDao.createOrderChangeDetail(po);
+				
+				// 4.2.3 주문상세단품정보 수정
+				orderDao.updateOrderDetailItem(vo);
+				
+				// 4.2.4 주문상세단품정보 이력 등록
+				orderDao.createOrderDetailItemHst(vo);
+				
+				// 4.2.5 주문변경상세정보 수정
+				orderDao.updateOrderDetail(vo);
+				
+				// 4.2.6 주문변경상세정보 이력 등록
+				orderDao.createOrderDetailhst(vo);
+				
+				int a = 100/0;
+			}
+		}
+	}
+	
 }

+ 3 - 3
style24.admin/src/main/java/com/style24/admin/biz/service/TsaRendererService.java

@@ -498,14 +498,14 @@ public class TsaRendererService {
 //	}
 
 	/**
-	 * 1:1문의용 답변문구 목록
+	 * 문의용 답변문구 목록
 	 * @param ansClsf - 답변종류
 	 * @return CommonCode
 	 * @author gagamel
 	 * @since 2020. 12. 24
 	 */
-	public Collection<CommonCode> getAnswerPhaseList(String ansClsf) {
-		return rendererDao.getAnswerPhaseList(ansClsf);
+	public Collection<CommonCode> getQnaAnswerPhaseList(String ansClsf) {
+		return rendererDao.getQnaAnswerPhaseList(ansClsf);
 	}
 
 //	/**

+ 21 - 31
style24.admin/src/main/java/com/style24/admin/biz/web/TsaCustomerController.java

@@ -12,11 +12,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 
-import com.style24.admin.biz.service.TsaAnswerPhaseService;
 import com.style24.admin.biz.service.TsaCounselService;
 import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.support.controller.TsaBaseController;
 import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.biz.service.TscAnswerPhaseService;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.domain.AnswerPhase;
 import com.style24.persistence.domain.Counsel;
@@ -29,7 +29,7 @@ import com.gagaframework.web.rest.server.GagaResponse;
  * 고객 Controller
  *
  * @author gagamel
- * @since 2020. 12. 24
+ * @since 2020. 12. 28
  */
 @Controller
 @RequestMapping("/customer")
@@ -46,14 +46,14 @@ public class TsaCustomerController extends TsaBaseController {
 	private TsaRendererService rendererService;
 
 	@Autowired
-	private TsaAnswerPhaseService answerPhaseService;
+	private TscAnswerPhaseService ansPhaseService;
 
 	/**
-	* 1:1문의관리 화면
-	* @return
-	* @author gagamel
-	* @since 2020. 12. 24
-	*/
+	 * 1:1문의관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
 	@GetMapping("/onetoone/qna/form")
 	public ModelAndView oneToOneQnaForm() {
 		ModelAndView mav = new ModelAndView();
@@ -99,8 +99,8 @@ public class TsaCustomerController extends TsaBaseController {
 		// 1:1문의 상세 정보
 		mav.addObject("counselInfo", counselService.getOneToOneQna(counselSq));
 
-		// 1:1문의용 답변문구
-		mav.addObject("ansPhaseList", rendererService.getAnswerPhaseList("20"));
+		// 문의용 답변문구
+		mav.addObject("ansPhaseList", rendererService.getQnaAnswerPhaseList("G061_20"));
 
 		mav.setViewName("customer/OneToOneQnaDetailForm");
 
@@ -121,7 +121,7 @@ public class TsaCustomerController extends TsaBaseController {
 		AnswerPhase ansPhase = new AnswerPhase();
 		ansPhase.setAnsSq(ansSq);
 		ansPhase.setAnsClsf(ansClsf);
-		return answerPhaseService.getQnaAnswerPhase(ansPhase);
+		return ansPhaseService.getQnaAnswerPhase(ansPhase);
 	}
 
 	/**
@@ -145,18 +145,8 @@ public class TsaCustomerController extends TsaBaseController {
 //		// TODO. 고객이 SMS답변수신을 요청했을 때
 //		if (counsel.getSmsReqYn().equals("Y")) {
 //			try {
-//				// 답변완료안내 카카오알림톡 발송
-//				kakaoService.sendOnetoOneAnswer(tCounsel);
-//			} catch (Exception e) {
-//				// Do nothing
-//			}
-//		}
-
-		// 고객이 이메일답변수신을 요청했을 때
-//		if (counsel.getEmailReqYn().equals("Y")) {
-//			try {
-//				// 답변완료안내 메일 발송
-//				mailService.sendOneToOneAnswer(tCounsel);
+//				// 문의답변완료안내 카카오알림톡 발송
+//				kakaoService.sendQnaAnswer(tCounsel);
 //			} catch (Exception e) {
 //				// Do nothing
 //			}
@@ -166,11 +156,11 @@ public class TsaCustomerController extends TsaBaseController {
 	}
 
 	/**
-	* 상품문의관리 화면
-	* @return
-	* @author gagamel
-	* @since 2020. 12. 24
-	*/
+	 * 상품문의관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
 	@GetMapping("/goods/qna/form")
 	public ModelAndView goodsQnaForm() {
 		ModelAndView mav = new ModelAndView();
@@ -219,8 +209,8 @@ public class TsaCustomerController extends TsaBaseController {
 		// 상품문의 상세
 		mav.addObject("counselInfo", counselService.getGoodsQna(counselSq));
 
-		// 상품문의용 답변문구
-		mav.addObject("ansPhaseList", rendererService.getAnswerPhaseList("20"));
+		// 문의용 답변문구
+		mav.addObject("ansPhaseList", rendererService.getQnaAnswerPhaseList("G061_20"));
 
 		mav.setViewName("customer/GoodsQnaDetailForm");
 
@@ -242,7 +232,7 @@ public class TsaCustomerController extends TsaBaseController {
 
 		counselService.updateGoodsQnaAnswerTransfer(counsel);
 
-		return super.ok(message.getMessage("SUCC_0001"));
+		return super.ok(message.getMessage("SUCC_0004"));
 	}
 
 }

+ 147 - 5
style24.admin/src/main/java/com/style24/admin/biz/web/TsaDisplayController.java

@@ -4,17 +4,25 @@ import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
+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;
 import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
 
 import com.style24.admin.biz.service.TsaDisplayService;
+import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.domain.Category;
+import com.style24.persistence.domain.ItemkindCategory;
 
 import lombok.extern.slf4j.Slf4j;
 
+import com.gagaframework.web.rest.server.GagaResponse;
+
 /**
  * 전시 Controller
  *
@@ -26,16 +34,42 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class TsaDisplayController extends TsaBaseController {
 
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
 	@Autowired
 	private TsaDisplayService displayService;
 
 	/**
-	 * 카테고리관리 조회
-	 *
-	 * @param category
+	 * 카테고리관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	@GetMapping("/category/form")
+	public ModelAndView categoryForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+		mav.addObject("cateGbList", rendererService.getAvailCommonCodeList("G032"));
+		mav.addObject("cateTypeList", rendererService.getAvailCommonCodeList("G031"));
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		mav.addObject("conentsLocList", rendererService.getAvailCommonCodeList("G028"));
+
+		mav.setViewName("display/CategoryForm");
+
+		return mav;
+	}
+
+	/**
+	 * 카테고리 목록
+	 * @param category - 카테고리 정보
 	 * @return
-	 * @author eskim
-	 * @since 2020. 12. 16
+	 * @author gagamel
+	 * @since 2021. 1. 4
 	 */
 	@PostMapping("/category/list")
 	@ResponseBody
@@ -43,4 +77,112 @@ public class TsaDisplayController extends TsaBaseController {
 		return displayService.getCategoryList(category);
 	}
 
+	/**
+	 * 카테고리 저장
+	 * @param category - 카테고리 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	@PostMapping("/category/save")
+	@ResponseBody
+	public GagaResponse saveCategory(@RequestBody Category category) {
+		displayService.saveCategory(category);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 카테고리 갱신
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 4
+	 */
+	@PostMapping("/category/refresh")
+	@ResponseBody
+	public GagaResponse refreshCategory() {
+		displayService.refreshCategory();
+		return super.ok(message.getMessage("SUCC_0010"));
+	}
+
+	/**
+	 * 품목카테고리매핑관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 5
+	 */
+	@GetMapping("/itemkind/category/mapping/form")
+	public ModelAndView itemkindCategoryMappingForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 카테고리구분
+		mav.addObject("cateGbList", rendererService.getAvailCommonCodeList("G032"));
+
+		mav.setViewName("display/ItemkindCategoryForm");
+
+		return mav;
+	}
+
+	/**
+	 * 카테고리구분 목록
+	 * @param cateGb - 카테고리구분
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	@GetMapping("/category/gb/list/{cateGb}")
+	@ResponseBody
+	public Collection<Category> getCategoryGbList(@PathVariable String cateGb) {
+		return displayService.getCategoryGbList(cateGb);
+	}
+
+	/**
+	 * 품목카테고리매핑 저장
+	 * @param itemkindCateList - 품목카테고리 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	@PostMapping("/itemkind/category/mapping/save")
+	@ResponseBody
+	public GagaResponse saveItemkindCategoryMappingList(@RequestBody Collection<ItemkindCategory> itemkindCateList) {
+		if (itemkindCateList == null || itemkindCateList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		displayService.saveItemkindCategoryMappingList(itemkindCateList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 품목카테고리매핑 삭제
+	 * @param itemkindCateList - 품목카테고리 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	@PostMapping("/itemkind/category/mapping/delete")
+	@ResponseBody
+	public GagaResponse deleteItemkindCategoryMappingList(@RequestBody Collection<ItemkindCategory> itemkindCateList) {
+		if (itemkindCateList == null || itemkindCateList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1004"));
+		}
+
+		displayService.deleteItemkindCategoryMappingList(itemkindCateList);
+
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 품목카테고리매핑 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 5
+	 */
+	@GetMapping("/itemkind/category/mapping/list/{itemkindCd}")
+	@ResponseBody
+	public Collection<ItemkindCategory> getItemkindCategoryMappingList(@PathVariable String itemkindCd) {
+		return displayService.getItemkindCategoryMappingList(itemkindCd);
+	}
+
 }

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

@@ -1,6 +1,7 @@
 package com.style24.admin.biz.web;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -34,6 +35,7 @@ import com.style24.persistence.TsaPageRequest;
 import com.style24.persistence.domain.AdKeyword;
 import com.style24.persistence.domain.AdKeywordGoods;
 import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.FreeGoods;
 import com.style24.persistence.domain.Goods;
 import com.style24.persistence.domain.GoodsCompose;
 import com.style24.persistence.domain.GoodsEpSkip;
@@ -55,6 +57,7 @@ import com.style24.persistence.domain.ReinboundInform;
 import com.style24.persistence.domain.User;
 import com.style24.persistence.domain.Video;
 import com.style24.persistence.domain.WmsColorMapping;
+import com.style24.persistence.domain.WmsGoods;
 import com.style24.persistence.domain.WmsSeasonMapping;
 import com.style24.persistence.domain.WmsStyleYearMapping;
 
@@ -1241,7 +1244,7 @@ public class TsaGoodsController extends TsaBaseController {
 	 * @author eskim
 	 * @since 2020. 10. 16
 	 */
-	@GetMapping("/wms/instock/form")
+	@GetMapping("/wms/incomelot/form")
 	public ModelAndView wmsInstockForm() {
 		ModelAndView mav = new ModelAndView();
 
@@ -1254,11 +1257,40 @@ public class TsaGoodsController extends TsaBaseController {
 		// 품목
 		mav.addObject("itemkindList", rendererService.getAllItemkindList());
 
-		mav.setViewName("goods/GoodsWmsInstockForm");
+		mav.setViewName("goods/GoodsWmsIncomelotForm");
 
 		return mav;
 	}
 
+	/**
+	 * WMS입고상품관리 목록 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	@PostMapping("/wms/incomelot/list")
+	@ResponseBody
+	public Collection<WmsGoods> getGoodsWmsIncomelotList(@RequestBody WmsGoods wmsGoods) {
+
+		return goodsService.getGoodsWmsIncomelotList(wmsGoods);
+	}
+
+	/**
+	 * WMS 입고상품 사은품 등록
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	@PostMapping("/free/goods/save")
+	@ResponseBody
+	public GagaResponse saveFreeGoods(@RequestBody Collection<WmsGoods> wmsGoodsList) {
+		goodsService.saveFreeGoods(wmsGoodsList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
 	/**
 	 * 상품품목변경관리 화면
 	 *
@@ -2368,4 +2400,88 @@ public class TsaGoodsController extends TsaBaseController {
 		return mav;
 	}
 
+	/**
+	 * 사은품 화면
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 28
+	 */
+	@GetMapping("/freeGoods/form")
+	public ModelAndView goodsfreeGoodsForm() {
+		ModelAndView mav = new ModelAndView();
+
+		String supplyCompCd = "";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+
+		mav.setViewName("goods/GoodsFreeGoodsForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사은품 목록
+	 * @param adKeywordSq
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 28
+	 */
+	@PostMapping("/freeGoods/list")
+	@ResponseBody
+	public Collection<FreeGoods> getFreeGoodsList(@RequestBody GoodsSearch goodsSearch) {
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+		}
+		log.info("[getFreeGoodsList] goodsSearch={}", goodsSearch);
+		return goodsService.getFreeGoodsList(goodsSearch);
+	}
+
+	/**
+	 * 광고 키워드 상품 삭제
+	 *
+	 * @param freeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 28
+	 */
+	@PostMapping("/freeGoods/update")
+	@ResponseBody
+	public GagaResponse updateFreeGoods(@RequestBody FreeGoods freeGoods) {
+
+		if (freeGoods.getNewSysImgNm() != null && !"".equals(freeGoods.getNewSysImgNm())) {
+			String sysImgNm =  freeGoods.getProductNo() + "_" + GagaDateUtil.getTodayDateTime() + "." + StringUtils.getFilenameExtension(freeGoods.getNewSysImgNm());
+
+			String imgUploadPath = env.getProperty("upload.default.target.path");
+			imgUploadPath = GagaFileUtil.getConcatenationPath(imgUploadPath, "display", "freegoods");
+
+			//기존이미지 삭제
+			try {
+				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(imgUploadPath, freeGoods.getSysImgNm()));
+			} catch (IOException e) {
+				//  nothing
+				log.info("[updateFreeGoods 기존 이미지 삭제중 error]");
+				//e.printStackTrace();
+			}
+
+			File uniqueFile = GagaFileUtil.getUniqueFile(new File(GagaFileUtil.getConcatenationPath(imgUploadPath, sysImgNm)));
+
+			File file = new File(GagaFileUtil.getConcatenationPath(imgUploadPath, freeGoods.getNewSysImgNm()));
+
+			// Rename a file
+			file.renameTo(uniqueFile);
+
+			freeGoods.setSysImgNm(sysImgNm);
+
+		}
+		goodsService.updateFreeGoods(freeGoods);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
 }

+ 44 - 7
style24.admin/src/main/java/com/style24/admin/biz/web/TsaMarketingController.java

@@ -10,6 +10,7 @@ import com.style24.persistence.domain.CommonCode;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.FreeGoodsPromotion;
 
+import com.style24.persistence.domain.MoreBetter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
@@ -68,7 +69,7 @@ public class TsaMarketingController extends TsaBaseController {
 	/**
 	 * 사은품 프로모션 목록 조회
 	 * @author xodud1202
-	 * @since 2020. 10. 17
+	 * @since 2020. 12. 16
 	 */
 	@PostMapping("/freeGoodsPromotion/list")
 	@ResponseBody
@@ -89,12 +90,11 @@ public class TsaMarketingController extends TsaBaseController {
 
 
 	/**
-	 * 세트상품구성 화면
-	 *
-	 * @param
-	 * @return
-	 * @author eskim
-	 * @since 2020. 05. 26
+	 * 사은품 프로모션 등록 팝업창
+	 * @param param
+	 * @return ModelAndView
+	 * @author xodud1202
+	 * @since 2020. 12. 23
 	 */
 	@ResponseBody
 	@GetMapping("/freeGoodsRegiPopup/form")
@@ -106,6 +106,7 @@ public class TsaMarketingController extends TsaBaseController {
 		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
 
 		mav.addObject("param", param);
+		log.info("CHECK PARAM.GBN >> " + param.getGbn());
 		mav.setViewName("marketing/FreeGoodsPromotionRegiForm");
 		return mav;
 	}
@@ -236,4 +237,40 @@ public class TsaMarketingController extends TsaBaseController {
 		return mav;
 	}
 	/* // JSM 진행 */
+
+	/* CSB 진행 */
+	/**
+	 * 다다익선 화면
+	 * @author bin2107
+	 * @since 2020. 12. 28
+	 */
+	@GetMapping("/morebetter/form")
+	public ModelAndView morebetterForm() {
+		ModelAndView mav = new ModelAndView();
+		mav.setViewName("marketing/MorebetterListForm");
+		return mav;
+	}
+
+	/**
+	 * 다다익선 리스트 조회
+	 * @author bin2107
+	 * @since 2020. 12. 28
+	 */
+	@PostMapping("/morebetter/list")
+	@ResponseBody
+	public GagaMap getMorebetterList(@RequestBody MoreBetter param) {
+		GagaMap result = new GagaMap();
+
+		List<MoreBetter> tmtbList = (ArrayList<MoreBetter>) marketingService.getMorebetterList(param);
+
+		param.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		param.setPageable(new TsaPageRequest(param.getPageNo() - 1, param.getPageSize()));
+		param.getPageable().setTotalCount(tmtbList.size());
+
+		result.set("pageing", param);
+		result.set("morebetterList", tmtbList);
+
+		return result;
+	}
+	/* // CSB 진행 */
 }

+ 20 - 4
style24.admin/src/main/java/com/style24/admin/biz/web/TsaOcmController.java

@@ -2,6 +2,7 @@ package com.style24.admin.biz.web;
 
 import java.util.Collection;
 
+import com.style24.persistence.domain.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -16,10 +17,6 @@ import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.support.controller.TsaBaseController;
 import com.style24.admin.support.security.session.TsaSession;
 import com.style24.core.support.message.TscMessageByLocale;
-import com.style24.persistence.domain.Extmall;
-import com.style24.persistence.domain.ExtmallNoti;
-import com.style24.persistence.domain.ExtmallOrigin;
-import com.style24.persistence.domain.ExtmallPriceSync;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -79,6 +76,25 @@ public class TsaOcmController extends TsaBaseController {
 		return ocmService.getExtmallList(extmall);
 	}
 
+	/**
+	 * 제휴몰 목록 화면(팝업)
+	 * @param extmall - 제휴몰 정보
+	 * @return
+	 * @author xodud1202
+	 * @since 2020. 12. 28
+	 */
+	@GetMapping("/extmall/search/form")
+	public ModelAndView extmallSearchForm(Extmall extmall) {
+		ModelAndView mav = new ModelAndView();
+
+		// 상품상태
+		mav.addObject("extmallGbList", rendererService.getCommonCodeList("G003", "Y"));
+
+		mav.addObject("params", extmall);
+		mav.setViewName("ocm/ExtmallSearchForm");
+		return mav;
+	}
+
 	/**
 	 * 제휴몰 등록/수정 처리
 	 * @param extmall - 제휴몰 정보

+ 65 - 2
style24.admin/src/main/java/com/style24/admin/biz/web/TsaOrderController.java

@@ -3,6 +3,7 @@ package com.style24.admin.biz.web;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 
@@ -31,8 +32,11 @@ import com.style24.admin.biz.service.TsaOrderService;
 import com.style24.admin.biz.service.TsaRendererService;
 import com.style24.admin.support.controller.TsaBaseController;
 import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.TsaPageRequest;
+import com.style24.persistence.domain.CommonCode;
 import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.OrderChange;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -47,6 +51,9 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class TsaOrderController extends TsaBaseController {
 	
+	@Autowired
+	private TscMessageByLocale message;
+	
 	@Autowired
 	private Environment env;
 	
@@ -637,18 +644,74 @@ public class TsaOrderController extends TsaBaseController {
 		
 		Collection<Order> cancelRequestTargetList = orderService.getCancelRequestTargetList(order);
 
-		Order orderInfo = orderService.getOrderInfo(order);
+		//Order orderInfo = orderService.getOrderInfo(order);
 
 		//mav.addObject("nicePay", nicePay);
 		mav.addObject("chgReasonList"				, rendererService.getAvailCommonCodeList("G686"));	// 취소사유
 		mav.addObject("cancelRequestTargetList"		, cancelRequestTargetList);							// 취소요청대상 목록
-		mav.addObject("orderInfo"					, orderInfo);										// 주문정보
+		//mav.addObject("orderInfo"					, orderInfo);										// 주문정보
 		mav.addObject("ordNo"						, ordNo);
 		mav.addObject("cncWait"						, cncWait);
 
 		mav.setViewName("order/CancelRequestForm");
 		return mav;
 	}
+	
+	/**
+	 * 주문취소신청환불금액 계산
+	 * @param Collection<Order>- 주문취소신청목록
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 29
+	 */
+	@PostMapping("/cancel/refundAmt")
+	@ResponseBody
+	public GagaMap orderCancelRefundAmt(@RequestBody List<Order> cancelReqList) {
+		
+		GagaMap mav = new GagaMap();
+		
+		if (cancelReqList == null || cancelReqList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		
+		// 1. 환불금액정보 계산 & 조회
+		mav = orderService.orderCancelRefundAmt(cancelReqList);
+		
+		return mav;
+	}
+	
+	/**
+	 * 주문취소신청
+	 * @param Collection<Order> - 주문취소신청목록
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 29
+	 */
+	@PostMapping("/cancel")
+	@ResponseBody
+	public GagaResponse orderCancel(@RequestBody OrderChange cancelReq) {
+		
+		GagaMap mav = new GagaMap();
+		
+		if (cancelReq== null) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		List<Order> cancelReqList = cancelReq.getCancelReqList(); // 취소요청정보
+		
+		// 1. 환불금액정보 계산 & 조회
+		mav = orderService.orderCancelRefundAmt(cancelReqList);
+		
+		// 2. 주문변경기본정보 설정
+		mav.set("ordNo"			, cancelReq.getOrdNo());
+		mav.set("chgReason"		, cancelReq.getChgReason());
+		mav.set("chgMemo"		, cancelReq.getChgMemo());
+		
+		// 3. 주문변경 DB 등록 (주문정보, 배송정보)
+		orderService.orderCancel(mav);
+		
+		return super.ok("성공");
+	}
 }
 
 

+ 30 - 31
style24.admin/src/main/java/com/style24/persistence/domain/Category.java

@@ -14,39 +14,38 @@ import lombok.Data;
 @Data
 public class Category extends TscBaseDomain {
 
-	private Integer cateNo;
-	private String cateType;
-//	private String upperCateCode;
-	private String cateNm;
-	private Integer clsLvl;
-	private String selLvl;
-	private Integer dispOrd;
-	private String dispYn;
-	private String useYn;
-	private String cateGb;
-	private String formalGb;
-	private String leafYn;
-	private String contentsLoc;
-//	private String treePath;
+	private Integer cateNo;		// 카테고리번호
+	private String cateNm;		// 카테고리명
+	private String cateGb;		// 카테고리구분
+	private String cateType;	// 카테고리유형
+	private Integer cate1No;	// 카테고리1번호
+	private String cate1Nm;		// 카테고리1명
+	private Integer cate2No;	// 카테고리2번호
+	private String cate2Nm;		// 카테고리2명
+	private Integer cate3No;	// 카테고리3번호
+	private String cate3Nm;		// 카테고리3명
+	private Integer cate4No;	// 카테고리4번호
+	private String cate4Nm;		// 카테고리4명
+	private Integer cate5No;	// 카테고리5번호
+	private String cate5Nm;		// 카테고리5명
+	private String leafYn;		// 단말여부
+	private String formalGb;	// 정상이월구분
+	private String contentsLoc;	// 컨텐츠위치
+	private Integer dispOrd;	// 표시순서
+	private String dispYn;		// 노출여부
+	private String useYn;		// 사용여부
 
 //	private String clocPrefix;      // 메인전시 컨텐츠 위치 프리픽스
-//
-//	private String fullCateCd;
-//	private String fullCateNm;
-//
-	private String siteCd;
-//
 //	private String brandGrpNm;
-//
-	private Integer cate1No;
-	private String cate1Nm;
-	private Integer cate2No;
-	private String cate2Nm;
-	private Integer cate3No;
-	private String cate3Nm;
-	private Integer cate4No;
-	private String cate4Nm;
-	private Integer cate5No;
-	private String cate5Nm;
+
+	// 검색조건
+	private String siteCd;		// 사이트코드
+	private Integer selLvl;		// 선택레벨
+
+	// 품목카테고리매핑관리 화면에서 사용
+	private String fullCateNo;	// FULL카테고리번호
+	private String fullCateNm;	// FULL카테고리명
+	private Integer clsLvl;		// 분류레벨
+	private String treePath;	// AG-GRID트리패스(ag-Grid미사용시 필요 없음)
 
 }

+ 20 - 5
style24.admin/src/main/java/com/style24/persistence/domain/Counsel.java

@@ -1,5 +1,7 @@
 package com.style24.persistence.domain;
 
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.util.MaskingUtils;
 import com.style24.persistence.TscBaseDomain;
 
 import lombok.Data;
@@ -8,7 +10,7 @@ import lombok.Data;
  * 상담(1:1문의) Domain
  *
  * @author gagamel
- * @since 2020. 11. 3
+ * @since 2020. 12. 24
  */
 @SuppressWarnings("serial")
 @Data
@@ -33,6 +35,7 @@ public class Counsel extends TscBaseDomain {
 //	private String emailSendYn;		// 이메일발송여부
 	private String relGoodsCd;		// 관련상품코드(상품문의에서만 사용)
 	private String goodsNm;			// 상품명(상품문의에서만 사용)
+	private String goodsImg;		// 상품이미지
 	private String selfGoodsYn;		// 자사상품여부(상품문의에서만 사용)
 	private String questTitle;		// 문의제목
 	private String questContent;	// 문의내용
@@ -64,10 +67,6 @@ public class Counsel extends TscBaseDomain {
 	private Integer ansSq;
 	private String ansClsf;
 
-	// 입점업체일 경우 본인 것만 조회되도록 사용
-	private String roleCd;
-	private String supplyCompCd;
-
 	// 검색조건
 	private String condition;		// 검색어
 	private String custGb;			// 회원구분
@@ -75,4 +74,20 @@ public class Counsel extends TscBaseDomain {
 	private String termStdt;		// 검색시작날짜
 	private String termEddt;		// 검색끝날짜
 
+	public String getMaskingCustId() {
+		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.id(custId) : custId;
+	}
+
+	public String getMaskingCustNm() {
+		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.name(custNm) : custNm;
+	}
+
+	public String getMaskingCellPhnno() {
+		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.phoneNo(cellPhnno) : cellPhnno;
+	}
+
+	public String getMaskingEmail() {
+		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.email(email) : email;
+	}
+
 }

+ 3 - 0
style24.admin/src/main/java/com/style24/persistence/domain/Extmall.java

@@ -25,4 +25,7 @@ public class Extmall extends TscBaseDomain {
 	private String dwdpYn;			// 직접회수여부(Y:제휴몰에서회수, N:자사몰에서회수)
 	private String useYn;			// 사용여부
 
+	// 검색조건
+	private String searchTxt;		// 검색어
+	private String callbackFn;		// 콜백함수
 }

+ 29 - 0
style24.admin/src/main/java/com/style24/persistence/domain/FreeGoods.java

@@ -0,0 +1,29 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 사은품 Domain
+ *
+ * @author eskim
+ * @since 2020. 12. 28
+ */
+@SuppressWarnings("serial")
+@Data
+public class FreeGoods extends TscBaseDomain {
+
+	private Integer productNo;	//사은품 상품 번호 - ProductNo(WMS)
+	private int productCode;	//ProductCode(WMS)
+	private String goodsNum;	//품번
+	private String brandCd;		//브랜드코드
+	private String goodsNm;		//상품명
+	private String useYn;		//사용여부
+	private String sysImgNm;	//시스템이미지
+	private String newSysImgNm;	//신규 시스템이미지
+
+	private String brandEnm;		//브랜드명
+
+
+}

+ 30 - 8
style24.admin/src/main/java/com/style24/persistence/domain/FreeGoodsPromotion.java

@@ -1,9 +1,12 @@
 package com.style24.persistence.domain;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.style24.persistence.TsaPageRequest;
 import com.style24.persistence.TscBaseDomain;
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * 품목 Domain
  *
@@ -14,14 +17,33 @@ import lombok.Data;
 @Data
 public class FreeGoodsPromotion extends TscBaseDomain {
 	// 사은품 프로모션
-	private int freeGiftSq;			// 프로모션ID
-	private String freeGiftName;	// 프로모션명
-	private String freeGiftStat;	// 프로모션 상태
-	private String freeGiftStdt;	// 프로모션 시작일
-	private String freeGiftEddt;	// 프로모션 종료일
-	private String promotionGubun;	// 프로모션 조회 검색 구분
-	private String searchTxt;		// 프로모션 검색 조건
-	private String gbn;				// 팝업 구분 : C=등록, U=수정
+	private int freeGiftSq;				// 프로모션ID
+	private String freeGiftName;		// 프로모션명
+	private String freeGiftStat;		// 프로모션 상태
+	private String freeGiftStdt;		// 프로모션 시작일
+	private String freeGiftEddt;		// 프로모션 종료일
+	private String selfYn;				// 자사몰 적용 여부
+	private String allYn;				// 모두 지급 구분 (모두지급 일때는 포인트 금액을 설정 할 수 없음 Y(모두지급), N(선택사은품))
+
+	// 사은품 프로모션 제휴몰
+	private int freegiftExtmallSq;		// 프로모션 제휴몰 ID
+	private String extmallId;			// 외부몰ID
+	private String vendorId;			// 벤더ID
+
+	// 사은품 프로모션 적용 및 제외 상품
+	private String goodsGb;				// 상품 구분 (G800_10|기본상품, G800_20|적용상품, G800_30|제외상품, G800_40|ALL)
+	private String targetGb;			// 적용 구분 (G260_10|상품, G260_12|브랜드, G260_13|공급처)
+	private String targetVal;			// 적용 값 (브랜드코드, 상품코드, 공급처코드)
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)	private String[] applyGoodsCds;		// 적용 상품 번호
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)	private String[] exceptGoodsCds;	// 제외 상품 번호
+
+	// 사은품 조건
+	private List<FreeGoodsSectionVal> goodsListNew;		// 사은품 조건 리스트
+
+	// 기타 조건
+	private String promotionGubun;		// 프로모션 조회 검색 구분
+	private String searchTxt;			// 프로모션 검색 조건
+	private String gbn;					// 팝업 구분 : C=등록, U=수정
 
 	// Pagination
 	private TsaPageRequest pageable;

+ 31 - 0
style24.admin/src/main/java/com/style24/persistence/domain/FreeGoodsSectionVal.java

@@ -0,0 +1,31 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TsaPageRequest;
+import com.style24.persistence.TscBaseDomain;
+import lombok.Data;
+
+import java.util.Collection;
+
+/**
+ * 품목 Domain
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@SuppressWarnings("serial")
+@Data
+public class FreeGoodsSectionVal {
+	// 사은품 조건
+	private int freegiftSectionSq;		// 사은품 조건 목록 ID
+	private int freegiftValSq;			// 사은품 조건 리스트 사은품ID
+	private int usePoint;				// 포인트액
+	private int itemQty;				// 지급 수량
+	private int limitQty;				// 한정 수량
+	private int leftQty;				// 잔여 수량
+	private String sectionGb;			// 사은품 조건 구분(G810_10|수량, G810_11|금액)
+	private String sectionVal;			// 구간 설정 값 | 구간 할인 시작 (수량이상, 금액이상)
+	private String itemCd;				// 사은품ID
+	private String itemOptCd1;			// ??
+	private String itemOptCd2;			// ??
+}

+ 4 - 1
style24.admin/src/main/java/com/style24/persistence/domain/Goods.java

@@ -78,11 +78,13 @@ public class Goods extends TscBaseDomain {
 	private String brandGrpNm;		//브랜드그룹명
 	private int brandNo;			// 브랜드번호
 
-	private String goodsDesc;
 	private String goodsPcTopDesc;
 	private String goodsPcDownDesc;
 	private String goodsMobileTopDesc;
 	private String goodsMobileDownDesc;
+	private String goodsTitlesDesc;
+	private String goodsContentsDesc;
+	private String goodsCharacterDesc;
 	private String chkDescKeep = "N";
 //
 	private String chDataYn = "N";
@@ -95,6 +97,7 @@ public class Goods extends TscBaseDomain {
 	private String itemkindNm;
 	private String niClsfCd;
 	private String makeNm;
+	private String repGoodsCd;
 
 	private int currPriceOrg;
 	private String goodsStatOrg;

+ 2 - 0
style24.admin/src/main/java/com/style24/persistence/domain/GoodsCompose.java

@@ -23,8 +23,10 @@ public class GoodsCompose extends TscBaseDomain {
 	private int compsCurrPrice;
 	private String compsGoodsOptNm;
 	private String baseYn;
+	private String repYn;
 	private String useYn;
 
+	private String repGoodsCd;
 	private int compsCurrPriceOrg;
 	private int currPrice;
 	private String goodsStat;

+ 23 - 0
style24.admin/src/main/java/com/style24/persistence/domain/ItemkindCategory.java

@@ -0,0 +1,23 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 품목카테고리 Domain
+ *
+ * @author gagamel
+ * @since 2021. 1. 5
+ */
+@SuppressWarnings("serial")
+@Data
+public class ItemkindCategory extends TscBaseDomain {
+
+	private String itemkindCd;	// 품목코드
+	private String cateGb;		// 카테고리구분
+	private Integer cateNo;		// 카테고리번호
+	private String fullCateNo;	// FULL카테고리번호
+	private String fullCateNm;	// FULL카테고리명
+
+}

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

@@ -0,0 +1,36 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TsaPageRequest;
+import com.style24.persistence.TscBaseDomain;
+import lombok.Data;
+
+/**
+ * 품목 Domain
+ *
+ * @author bin2107
+ * @since 2020. 12. 28
+ */
+@SuppressWarnings("serial")
+@Data
+public class MoreBetter extends TscBaseDomain {
+	// 사은품 프로모션
+	private int tmtbSq;				// 프로모션ID
+	private String tmtbNm;			// 프로모션명
+	private String tmtbStat;		// 프로모션 상태
+	private String tmtbStdt;		// 프로모션 시작일
+	private String tmtbEddt;		// 프로모션 종료일
+	private String delYn;			// 삭제여부
+	private Integer regNo;			// 등록자
+	private String  regDt;			// 등록일시
+	private Integer udpNo;			// 수정자
+	private String  udtDt;			// 수정일시
+	private String searchGubun;		// 프로모션 조회 검색 구분
+	private String searchTxt;		// 프로모션 검색 조건
+	private String gbn;				// 팝업 구분 : C=등록, U=수정
+
+	// Pagination
+	private TsaPageRequest pageable;
+	private int pageNo = 1;
+	private int pageSize = 50;
+	private int pageUnit = 10;
+}

+ 3 - 1
style24.admin/src/main/java/com/style24/persistence/domain/Notice.java

@@ -26,6 +26,9 @@ public class Notice extends TscBaseDomain {
 	private String noticeStdt;		// 공지시작일시
 	private String noticeEddt;		// 공지종료일시
 	private int readCnt;			// 조회수
+	private String popupYn;			// 팝업여부
+	private String popupDispStdt;	// 팝업노출시작일시
+	private String popupDispEddt;	// 팝업노출종료일시
 	private String useYn;			// 사용여부
 
 	// 검색용
@@ -51,7 +54,6 @@ public class Notice extends TscBaseDomain {
 	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 	private String[] sysFileNms;
 
-
 	private String goodsList;
 	private Collection<NoticeGoods> goodsListNew;
 

+ 6 - 0
style24.admin/src/main/java/com/style24/persistence/domain/Order.java

@@ -315,6 +315,12 @@ public class Order extends TscBaseDomain {
 	private int orgDelvFee;
 	private String delvFeeCd;
 	private int ordCanChgQty;
+	private String allCanYn;
+	
+	private String addDelvFeeYn;
+	private int addDelvFee;
+	private int ordDtlItemSq;
+	
 
 }
 

+ 75 - 0
style24.admin/src/main/java/com/style24/persistence/domain/OrderChange.java

@@ -0,0 +1,75 @@
+package com.style24.persistence.domain;
+
+import java.util.List;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 주문 취소 Domain
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@SuppressWarnings("serial")
+@Data
+public class OrderChange extends TscBaseDomain {
+	
+	List<Order> cancelReqList;
+	private int ordNo;
+	
+	private int ordChgSq;
+	private String chgGb;
+	private String chgReason;
+	private String chgMemo;
+	private String chgerNm;
+	private String chgerPhnno;
+	private String chgerTelno;
+	private String chgerEmail;
+	private String chgerZipNo;
+	private String chgerBaseAddr;
+	private String chgerDtlAddr;
+	private String chgerRtnMemo;
+	private int addPayCost;
+	private int addPayAmt;
+	private String wdInvoiceNo;
+	private String wdInvoiceSendYn;
+	private String wdStdt;
+	private String wdEddt;
+	private String shipCompCd;
+	
+	private int ordDtlNo;
+	private int chgQty;
+	private String chgStat;
+	private String chgStatNm;
+	private String whMemo;
+	
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 10 - 0
style24.admin/src/main/java/com/style24/persistence/domain/ReinboundInform.java

@@ -1,6 +1,8 @@
 package com.style24.persistence.domain;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.util.MaskingUtils;
 import com.style24.persistence.TscBaseDomain;
 
 import lombok.Data;
@@ -37,4 +39,12 @@ public class ReinboundInform extends TscBaseDomain {
 	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 	private String[] arrRinbdInfoSq;
 
+	public String getCustId() {
+		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.id(custId) : custId;
+	}
+
+	public String getCustNm() {
+		return TsaSession.getInfo().getMaskingYn().equals("Y") ? MaskingUtils.name(custNm) : custNm;
+	}
+
 }

+ 20 - 0
style24.admin/src/main/java/com/style24/persistence/domain/Sequence.java

@@ -0,0 +1,20 @@
+package com.style24.persistence.domain;
+
+import java.io.Serializable;
+
+import lombok.Data;
+
+/**
+ * SEQUENCE Domain
+ * 
+ * @author gagamel
+ * @since 2021. 1. 4
+ */
+@SuppressWarnings("serial")
+@Data
+public class Sequence implements Serializable {
+
+	private String sequenceNm;	// 시퀀스명
+	private Integer nextVal;	// 다음값
+
+}

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

@@ -0,0 +1,38 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * wms 상품 정보 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 04
+ */
+@SuppressWarnings("serial")
+@Data
+public class WmsGoods extends TscBaseDomain {
+
+	private Integer productNo;		//wms상품번호
+	private int productCode;		//wms상품코드
+	private String productName;		//상품명
+	private String skucode;			//옵션번호
+	private int normalQty;			//일반수량
+	private int brokenQty;			//불량수량
+	private int totalQty;			//총수량
+	private String modelNo;			//모델번호
+	private int providerNo;			//공급처번호
+	private String providerName;	//공급처명
+	private int brandNo;			//브랜드번호
+	private String brandName;		//브랜드명
+	private String goodsRegDt;		//상품등록일시
+	private String goodsRegGb;		//상품등록구분(G:상품, F:사은품)
+
+	private String supplyCompCd;
+	private String brandCd;
+	private String brandEnm;
+	private String stDate;
+	private String edDate;
+
+}

+ 0 - 12
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaAnswerPhase.xml

@@ -69,16 +69,4 @@
 		     , UPD_DT = NOW()
 	</insert>
 	
-	<!-- 문의용 답변문구 조회 -->
-	<select id="getQnaAnswerPhase" parameterType="AnswerPhase" resultType="AnswerPhase">
-		/* TsaAnswerPhase.getQnaAnswerPhase */
-		SELECT ANS_SQ      --답변일련번호
-		     , ANS_TITLE   --답변제목
-		     , ANS_CONTENT --답변내용
-		FROM   TB_ANS_PHASE
-		WHERE  ANS_SQ = #{ansSq}
-		AND    ANS_CLSF = #{ansClsf}
-		AND    USE_YN = 'Y'
-	</select>
-
 </mapper>

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

@@ -2,6 +2,22 @@
 <!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.TsaCommonDao">
 
+	<!-- 시퀀스 값 조회 -->
+	<select id="getNextSequence" parameterType="String" resultType="Integer">
+		/* TsaCommon.getNextSequence */
+		SELECT IFNULL((SELECT NEXT_VAL
+		               FROM   TB_SEQUENCE
+		               WHERE  SEQUENCE_NM = #{sequenceNm}
+		              ),0) + 1 AS NEXT_VAL
+	</select>
+
+	<!-- 시퀀스 생성 -->
+	<insert id="createNextSequence" parameterType="Sequence">
+		/* TsaCommon.createNextSequence */
+		INSERT INTO TB_SEQUENCE (SEQUENCE_NM, NEXT_VAL) VALUES (#{sequenceNm}, #{nextVal})
+		ON DUPLICATE KEY UPDATE NEXT_VAL = #{nextVal}
+	</insert>
+	
 	<!-- 엑셀조회를 위한 SEARCH 테이블 삭제  -->
 	<delete id="deleteExceluploadSearCh" parameterType="SearchData">
 		/* TsaCommon.deleteExceluploadSearCh */
@@ -71,4 +87,5 @@
 		WHERE CD_GB = 'G077'
 		AND CD = 'ERPSYNCYN'
 	</select>
+	
 </mapper>

+ 15 - 14
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaCounsel.xml

@@ -19,8 +19,6 @@
 		     , A.SMS_REQ_YN                                                        /*SMS요청여부*/
 		     , A.SMS_SEND_YN                                                       /*SMS발송여부*/
 		     , A.EMAIL                                                             /*이메일*/
-		     -- , A.EMAIL_REQ_YN                                                      /*이메일요청여부*/
-		     -- , A.EMAIL_SEND_YN                                                     /*이메일발송여부*/
 		     , A.ANS_STAT                                                          /*답변상태*/
 		     , DATE_FORMAT(A.ANS_DT, '%Y-%m-%d %H:%i:%S')      AS ANS_DT           /*답변일시*/
 		     , A.ANS_NO                                                            /*답변자번호*/
@@ -81,8 +79,6 @@
 		     , A.SMS_REQ_YN                                                       /*SMS요청여부*/
 		     , A.SMS_SEND_YN                                                      /*SMS발송여부*/
 		     , A.EMAIL                                                            /*이메일*/
-		     -- , A.EMAIL_REQ_YN                                                     /*이메일요청여부*/
-		     -- , A.EMAIL_SEND_YN                                                    /*이메일발송여부*/
 		     , DATE_FORMAT(A.QUEST_DT,'%Y-%m-%d %H:%i:%S')    AS QUEST_DT         /*문의일시*/
 		     , A.ANS_NO                                                           /*답변자번호*/
 		     , C.USER_NM                                      AS ANS_NM           /*답변자명*/
@@ -134,10 +130,15 @@
 		     , A.SMS_REQ_YN                                                        /*SMS요청여부*/
 		     , A.SMS_SEND_YN                                                       /*SMS발송여부*/
 		     , A.EMAIL                                                             /*이메일*/
-		     -- , A.EMAIL_REQ_YN                                                      /*이메일요청여부*/
-		     -- , A.EMAIL_SEND_YN                                                     /*이메일발송여부*/
 		     , A.REL_GOODS_CD                                                      /*관련상품코드*/
 		     , G.GOODS_NM                                                          /*상품명*/
+		     , (SELECT SYS_IMG_NM
+		        FROM   TB_GOODS_IMG
+		        WHERE  GOODS_CD = G.GOODS_CD
+		        AND    COLOR_CD = G.MAIN_COLOR_CD
+		        AND    DEFAULT_IMG_YN = 'Y' /*디폴트이미지*/
+		        LIMIT 1
+		       )                                               AS GOODS_IMG        /*상품이미지*/
 		     , A.ANS_STAT                                                          /*답변상태*/
 		     , A.ANS_TRANS_YN                                                      /*답변의뢰여부*/
 		     , A.ANS_COMP_CD                                                       /*답변업체코드*/
@@ -195,9 +196,6 @@
 		<if test="ansCompCd != null and ansCompCd != ''">
 		AND    A.ANS_COMP_CD = #{ansCompCd}
 		</if>
-		<if test="roleCd == 'B000'"> <!-- 입점업체권한일 때는 본인 것만 보도록 처리 -->
-		AND    A.ANS_COMP_CD = #{supplyCompCd}
-		</if>
 		<if test="ansStat != null and ansStat != ''">
 		AND    A.ANS_STAT = #{ansStat}
 		</if>
@@ -216,12 +214,18 @@
 		     , A.SMS_REQ_YN                                                        /*SMS요청여부*/
 		     , A.SMS_SEND_YN                                                       /*SMS발송여부*/
 		     , A.EMAIL                                                             /*이메일*/
-		     -- , A.EMAIL_REQ_YN                                                      /*이메일요청여부*/
-		     -- , A.EMAIL_SEND_YN                                                     /*이메일발송여부*/
 		     , A.REL_GOODS_CD                                                      /*관련상품코드*/
 		     , G.GOODS_NM                                                          /*상품명*/
+		     , (SELECT SYS_IMG_NM
+		        FROM   TB_GOODS_IMG
+		        WHERE  GOODS_CD = G.GOODS_CD
+		        AND    COLOR_CD = G.MAIN_COLOR_CD
+		        AND    DEFAULT_IMG_YN = 'Y' /*디폴트이미지*/
+		        LIMIT 1
+		       )                                               AS GOODS_IMG        /*상품이미지*/
 		     , G.SELF_GOODS_YN                                                     /*자사상품여부*/
 		     , DATE_FORMAT(A.QUEST_DT,'%Y-%m-%d %H:%i:%S')     AS QUEST_DT         /*문의일시*/
+		     , A.SECRET_YN                                                         /*비밀글여부*/
 		     , A.ANS_NO                                                            /*답변자번호*/
 		     , D.USER_NM                                       AS ANS_NM           /*답변자명*/
 		     , DATE_FORMAT(A.ANS_DT,'%Y-%m-%d %H:%i:%S')       AS ANS_DT           /*답변일시*/
@@ -244,9 +248,6 @@
 		LEFT OUTER JOIN TB_USER D ON A.ANS_NO = D.USER_NO
 		WHERE  A.COUNSEL_SQ = #{counselSq}
 		AND    A.COUNSEL_TYPE = 'G' /*상담유형(상품문의)*/
-		<if test="roleCd == 'B000'"> <!-- 입점업체권한일 때는 본인 것만 보도록 처리 -->
-		AND    A.ANS_COMP_CD = #{supplyCompCd}
-		</if>
 	</select>
 
 	<!--상품문의 입점업체에 답변의뢰 -->

+ 522 - 92
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaDsiplay.xml

@@ -2,123 +2,553 @@
 <!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.TsaDisplayDao">
 
-	<!-- 카테고리관리 목록 -->
+	<!-- 카테고리 목록 -->
 	<select id="getCategoryList" parameterType="Category" resultType="Category">
 		/* TsaDisplay.getCategoryList */
 		<if test='selLvl != null and selLvl != ""'>
-		<choose>
-		<when test='selLvl == "1"'>
-		SELECT SITE_CD
-		     , CATE_GB
-		     , '' AS CATE1_NO
-		     , '' AS CATE2_NO
-		     , '' AS CATE3_NO
-		     , '' AS CATE4_NO
-		     , '' AS CATE5_NO
-		     , '' AS CATE_NO
-		     , '' AS CATE_NM
-		     , '' AS CATE_TYPE     /*카테고리유형*/
-		     , 'N' AS LEAF_YN      /*단말여부*/
-		     , '' AS DISP_ORD      /*우선순위*/
-		     , '' AS FORMAL_GB     /*정상이월구분*/
-		     , '' AS CONTENTS_LOC  /*컨텐츠위치코드*/
-		     , 'N' AS DISP_YN   /*전시여부*/
-		     , 'Y' AS USE_YN   /*사용여부*/
-		FROM TB_CATE1
-		WHERE SITE_CD =  #{siteCd}
-		AND USE_YN = 'Y'
-		GROUP BY SITE_CD, CATE_GB
-		</when>
-		<otherwise>
-		SELECT SITE_CD
-		     , CATE_GB
+		SELECT SITE_CD                 /*사이트코드*/
+		     , CATE_GB                 /*카테고리구분*/
+		    <if test='selLvl == 1'>
 		     , CATE1_NO
-		     <if test='selLvl == "2"'>
-		     , '' AS CATE2_NO
-		     , '' AS CATE3_NO
-		     , '' AS CATE4_NO
-		     , '' AS CATE5_NO
-		     , CATE1_NO AS CATE_NO     /*카테고리코드*/
+		     , NULL     AS CATE2_NO
+		     , NULL     AS CATE3_NO
+		     , NULL     AS CATE4_NO
+		     , NULL     AS CATE5_NO
+		     , CATE1_NO AS CATE_NO     /*카테고리번호*/
 		     , CATE1_NM AS CATE_NM     /*카테고리명*/
-		     </if>
-		     <if test='selLvl == "3"'>
+		    </if>
+		    <if test='selLvl == 2'>
 		     , CATE2_NO
-		     , '' AS CATE3_NO
-		     , '' AS CATE4_NO
-		     , '' AS CATE5_NO
-		     , CATE2_NO AS CATE_NO     /*카테고리코드*/
+		     , NULL     AS CATE3_NO
+		     , NULL     AS CATE4_NO
+		     , NULL     AS CATE5_NO
+		     , CATE2_NO AS CATE_NO     /*카테고리번호*/
 		     , CATE2_NM AS CATE_NM     /*카테고리명*/
-		     </if>
-		     <if test='selLvl == "4"'>
+		    </if>
+		    <if test='selLvl == 3'>
 		     , CATE2_NO
 		     , CATE3_NO
-		     , '' AS CATE4_NO
-		     , '' AS CATE5_NO
-		     , CATE3_NO AS CATE_NO     /*카테고리코드*/
+		     , NULL     AS CATE4_NO
+		     , NULL     AS CATE5_NO
+		     , CATE3_NO AS CATE_NO     /*카테고리번호*/
 		     , CATE3_NM AS CATE_NM     /*카테고리명*/
-		     </if>
-		     <if test='selLvl == "5"'>
+		    </if>
+		    <if test='selLvl == 4'>
 		     , CATE2_NO
 		     , CATE3_NO
 		     , CATE4_NO
-		     , '' AS CATE5_NO
-		     , CATE4_NO AS CATE_NO     /*카테고리코드*/
+		     , NULL     AS CATE5_NO
+		     , CATE4_NO AS CATE_NO     /*카테고리번호*/
 		     , CATE4_NM AS CATE_NM     /*카테고리명*/
-		     </if>
-		     <if test='selLvl == "6"'>
+		    </if>
+		    <if test='selLvl == 5'>
 		     , CATE2_NO
 		     , CATE3_NO
 		     , CATE4_NO
 		     , CATE5_NO
-		     , CATE5_NO AS CATE_NO     /*카테고리코드*/
+		     , CATE5_NO AS CATE_NO     /*카테고리번호*/
 		     , CATE5_NM AS CATE_NM     /*카테고리명*/
-		     </if>
-		     , CATE_TYPE    /*카테고리유형*/
-		     , LEAF_YN      /*단말여부*/
-		     , DISP_ORD     /*우선순위*/
-		     , FORMAL_GB    /*정상이월구분*/
-		     , CONTENTS_LOC /*컨텐츠위치코드*/
-		     , DISP_YN      /*전시여부*/
-		     , USE_YN       /*사용여부*/
-		<if test='selLvl == "2"'>
-		  FROM TB_CATE1
-		 WHERE SITE_CD = #{siteCd}
-		   AND CATE_GB = #{cateGb}
+		    </if>
+		     , CATE_TYPE               /*카테고리유형*/
+		     , LEAF_YN                 /*단말여부*/
+		     , DISP_ORD                /*노출순서*/
+		     , FORMAL_GB               /*정상이월구분*/
+		     , CONTENTS_LOC            /*컨텐츠위치*/
+		     , DISP_YN                 /*전시여부*/
+		     , USE_YN                  /*사용여부*/
+		    <if test='selLvl == 1'>
+		FROM   TB_CATE1
+		WHERE  SITE_CD = #{siteCd}
+		AND    CATE_GB = #{cateGb}
+		    </if>
+		    <if test='selLvl == 2'>
+		FROM   TB_CATE2
+		WHERE  SITE_CD = #{siteCd}
+		AND    CATE_GB = #{cateGb}
+		AND    CATE1_NO = #{cate1No}
+		    </if>
+		    <if test='selLvl == 3'>
+		FROM   TB_CATE3
+		WHERE  SITE_CD = #{siteCd}
+		AND    CATE_GB = #{cateGb}
+		AND    CATE1_NO = #{cate1No}
+		AND    CATE2_NO = #{cate2No}
+		    </if>
+		    <if test='selLvl == 4'>
+		FROM   TB_CATE4
+		WHERE  SITE_CD = #{siteCd}
+		AND    CATE_GB = #{cateGb}
+		AND    CATE1_NO = #{cate1No}
+		AND    CATE2_NO = #{cate2No}
+		AND    CATE3_NO = #{cate3No}
+		    </if>
+		    <if test='selLvl == 5'>
+		FROM   TB_CATE5
+		WHERE  SITE_CD = #{siteCd}
+		AND    CATE_GB = #{cateGb}
+		AND    CATE1_NO = #{cate1No}
+		AND    CATE2_NO = #{cate2No}
+		AND    CATE3_NO = #{cate3No}
+		AND    CATE4_NO = #{cate4No}
+		    </if>
+		ORDER  BY DISP_ORD
+		</if>
+	</select>
+	
+	<!-- 카테고리1 저장 -->
+	<insert id="saveCategory1" parameterType="Category">
+		/* TsaDisplay.saveCategory1 */
+		INSERT INTO TB_CATE1 (
+		       SITE_CD
+		     , CATE_GB
+		     , CATE1_NO
+		     , CATE1_NM
+		     , CATE_TYPE
+		     , LEAF_YN
+		     , DISP_ORD
+		     , FORMAL_GB
+		     , CONTENTS_LOC
+		     , DISP_YN
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{siteCd}
+		     , #{cateGb}
+		     , #{cate1No}
+		     , #{cate1Nm}
+		     , #{cateType}
+		     , 'Y'
+		     , #{dispOrd}
+		     , #{formalGb}
+		     , #{contentsLoc}
+		     , #{dispYn}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       CATE1_NM = #{cate1Nm}
+		     , CATE_TYPE = #{cateType}
+		     , DISP_ORD = #{dispOrd}
+		     , FORMAL_GB = #{formalGb}
+		     , CONTENTS_LOC = #{contentsLoc}
+		     , DISP_YN = #{dispYn}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 카테고리2 저장 -->
+	<insert id="saveCategory2" parameterType="Category">
+		/* TsaDisplay.saveCategory2 */
+		INSERT INTO TB_CATE2 (
+		       SITE_CD
+		     , CATE_GB
+		     , CATE1_NO
+		     , CATE2_NO
+		     , CATE2_NM
+		     , CATE_TYPE
+		     , LEAF_YN
+		     , DISP_ORD
+		     , FORMAL_GB
+		     , CONTENTS_LOC
+		     , DISP_YN
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{siteCd}
+		     , #{cateGb}
+		     , #{cate1No}
+		     , #{cate2No}
+		     , #{cate2Nm}
+		     , #{cateType}
+		     , 'Y'
+		     , #{dispOrd}
+		     , #{formalGb}
+		     , #{contentsLoc}
+		     , #{dispYn}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       CATE1_NO = #{cate1No}
+		     , CATE2_NM = #{cate2Nm}
+		     , CATE_TYPE = #{cateType}
+		     , DISP_ORD = #{dispOrd}
+		     , FORMAL_GB = #{formalGb}
+		     , CONTENTS_LOC = #{contentsLoc}
+		     , DISP_YN = #{dispYn}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 카테고리3 저장 -->
+	<insert id="saveCategory3" parameterType="Category">
+		/* TsaDisplay.saveCategory3 */
+		INSERT INTO TB_CATE3 (
+		       SITE_CD
+		     , CATE_GB
+		     , CATE1_NO
+		     , CATE2_NO
+		     , CATE3_NO
+		     , CATE3_NM
+		     , CATE_TYPE
+		     , LEAF_YN
+		     , DISP_ORD
+		     , FORMAL_GB
+		     , CONTENTS_LOC
+		     , DISP_YN
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{siteCd}
+		     , #{cateGb}
+		     , #{cate1No}
+		     , #{cate2No}
+		     , #{cate3No}
+		     , #{cate3Nm}
+		     , #{cateType}
+		     , 'Y'
+		     , #{dispOrd}
+		     , #{formalGb}
+		     , #{contentsLoc}
+		     , #{dispYn}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       CATE2_NO = #{cate2No}
+		     , CATE3_NM = #{cate3Nm}
+		     , CATE_TYPE = #{cateType}
+		     , DISP_ORD = #{dispOrd}
+		     , FORMAL_GB = #{formalGb}
+		     , CONTENTS_LOC = #{contentsLoc}
+		     , DISP_YN = #{dispYn}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 카테고리4 저장 -->
+	<insert id="saveCategory4" parameterType="Category">
+		/* TsaDisplay.saveCategory4 */
+		INSERT INTO TB_CATE4 (
+		       SITE_CD
+		     , CATE_GB
+		     , CATE1_NO
+		     , CATE2_NO
+		     , CATE3_NO
+		     , CATE4_NO
+		     , CATE4_NM
+		     , CATE_TYPE
+		     , LEAF_YN
+		     , DISP_ORD
+		     , FORMAL_GB
+		     , CONTENTS_LOC
+		     , DISP_YN
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{siteCd}
+		     , #{cateGb}
+		     , #{cate1No}
+		     , #{cate2No}
+		     , #{cate3No}
+		     , #{cate4No}
+		     , #{cate4Nm}
+		     , #{cateType}
+		     , 'Y'
+		     , #{dispOrd}
+		     , #{formalGb}
+		     , #{contentsLoc}
+		     , #{dispYn}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       CATE3_NO = #{cate3No}
+		     , CATE4_NM = #{cate4Nm}
+		     , CATE_TYPE = #{cateType}
+		     , DISP_ORD = #{dispOrd}
+		     , FORMAL_GB = #{formalGb}
+		     , CONTENTS_LOC = #{contentsLoc}
+		     , DISP_YN = #{dispYn}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 카테고리5 저장 -->
+	<insert id="saveCategory5" parameterType="Category">
+		/* TsaDisplay.saveCategory5 */
+		INSERT INTO TB_CATE5 (
+		       SITE_CD
+		     , CATE_GB
+		     , CATE1_NO
+		     , CATE2_NO
+		     , CATE3_NO
+		     , CATE4_NO
+		     , CATE5_NO
+		     , CATE5_NM
+		     , CATE_TYPE
+		     , LEAF_YN
+		     , DISP_ORD
+		     , FORMAL_GB
+		     , CONTENTS_LOC
+		     , DISP_YN
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{siteCd}
+		     , #{cateGb}
+		     , #{cate1No}
+		     , #{cate2No}
+		     , #{cate3No}
+		     , #{cate4No}
+		     , #{cate5No}
+		     , #{cate5Nm}
+		     , #{cateType}
+		     , 'Y'
+		     , #{dispOrd}
+		     , #{formalGb}
+		     , #{contentsLoc}
+		     , #{dispYn}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       CATE4_NO = #{cate4No}
+		     , CATE5_NM = #{cate5Nm}
+		     , CATE_TYPE = #{cateType}
+		     , DISP_ORD = #{dispOrd}
+		     , FORMAL_GB = #{formalGb}
+		     , CONTENTS_LOC = #{contentsLoc}
+		     , DISP_YN = #{dispYn}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 상위카테고리 단말여부 "N" 처리-->
+	<update id="updateUpperCategoryLeafNo" parameterType="Category">
+		/* TsaDisplay.updateUpperCategoryLeafNo */
+		<if test='selLvl == 2'>
+		UPDATE TB_CATE1
 		</if>
-		<if test='selLvl == "3"'>
-		  FROM TB_CATE2
-		 WHERE SITE_CD = #{siteCd}
-		   AND CATE_GB = #{cateGb}
-		   AND CATE1_NO = #{cate1No}
+		<if test='selLvl == 3'>
+		UPDATE TB_CATE2
 		</if>
-		<if test='selLvl == "4"'>
-		  FROM TB_CATE3
-		 WHERE SITE_CD = #{siteCd}
-		   AND CATE_GB = #{cateGb}
-		   AND CATE1_NO = #{cate1No}
-		   AND CATE2_NO = #{cate2No}
+		<if test='selLvl == 4'>
+		UPDATE TB_CATE3
 		</if>
-		<if test='selLvl == "5"'>
-		  FROM TB_CATE4
-		 WHERE SITE_CD = #{siteCd}
-		   AND CATE_GB = #{cateGb}
-		   AND CATE1_NO = #{cate1No}
-		   AND CATE2_NO = #{cate2No}
-		   AND CATE3_NO = #{cate3No}
+		<if test='selLvl == 5'>
+		UPDATE TB_CATE4
 		</if>
-		<if test='selLvl == "6"'>
-		  FROM TB_CATE5
-		 WHERE SITE_CD = #{siteCd}
-		   AND CATE_GB = #{cateGb}
-		   AND CATE1_NO = #{cate1No}
-		   AND CATE2_NO = #{cate2No}
-		   AND CATE3_NO = #{cate3No}
-		   AND CATE4_NO = #{cate4No}
+		SET    LEAF_YN = 'N'
+		WHERE  SITE_CD = #{siteCd}
+		AND    CATE_GB = #{cateGb}
+		<if test='selLvl gte 2'>
+		AND    CATE1_NO = #{cate1No}
 		</if>
-		 ORDER BY SITE_CD, DISP_ORD
-		</otherwise>
-		</choose>
+		<if test='selLvl gte 3'>
+		AND    CATE2_NO = #{cate2No}
 		</if>
+		<if test='selLvl gte 4'>
+		AND    CATE3_NO = #{cate3No}
+		</if>
+		<if test='selLvl gte 5'>
+		AND    CATE4_NO = #{cate4No}
+		</if>
+		AND    LEAF_YN = 'Y'
+	</update>
+	
+	<!-- 카테고리4SRCH truncate -->
+	<delete id="truncateCategory4Srch">
+		/* TsaDisplay.truncateCategory4Srch */
+		TRUNCATE TABLE TB_CATE_4SRCH
+	</delete>
+	
+	<!-- 카테고리4SRCH 생성 -->
+	<insert id="createCategory4Srch">
+		/* TsaDisplay.createCategory4Srch */
+		INSERT INTO TB_CATE_4SRCH (
+		       SITE_CD
+		     , CATE_GB
+		     , LEAF_CATE_NO
+		     , CATE_TYPE
+		     , CATE1_NO
+		     , CATE1_NM
+		     , CATE2_NO
+		     , CATE2_NM
+		     , CATE3_NO
+		     , CATE3_NM
+		     , CATE4_NO
+		     , CATE4_NM
+		     , CATE5_NO
+		     , CATE5_NM
+		     , FULL_CATE_NO
+		     , FULL_CATE_NM
+		     , DISP_ORD
+		     , FORMAL_GB
+		     , CONTENTS_LOC
+		)
+		SELECT SITE_CD
+		     , CATE_GB
+		     , LEAF_CATE_NO
+		     , CATE_TYPE
+		     , CATE1_NO
+		     , CATE1_NM
+		     , CATE2_NO
+		     , CATE2_NM
+		     , CATE3_NO
+		     , CATE3_NM
+		     , CATE4_NO
+		     , CATE4_NM
+		     , CATE5_NO
+		     , CATE5_NM
+		     , FULL_CATE_NO
+		     , FULL_CATE_NM
+		     , DISP_ORD
+		     , FORMAL_GB
+		     , CONTENTS_LOC
+		FROM   VW_CATE_4SRCH
+	</insert>
+	
+	<!-- 카테고리구분 목록 -->
+	<select id="getCategoryGbList" parameterType="String" resultType="Category">
+		/* TsaDisplay.getCategoryGbList */
+		SELECT CATE_GB                                        /*카테고리구분*/
+		     , LEAF_CATE_NO                    AS CATE_NO     /*카테고리번호*/
+		     , CASE WHEN LEAF_CATE_NO = CATE5_NO THEN CATE5_NM
+		            WHEN LEAF_CATE_NO = CATE4_NO THEN CATE4_NM
+		            WHEN LEAF_CATE_NO = CATE3_NO THEN CATE3_NM
+		            WHEN LEAF_CATE_NO = CATE2_NO THEN CATE2_NM
+		            WHEN LEAF_CATE_NO = CATE1_NO THEN CATE1_NM
+		       END                             AS CATE_NM     /*카테고리명*/
+		     , FULL_CATE_NO                                   /*FULL카테고리번호*/
+		     , FULL_CATE_NM                                   /*FULL카테고리명*/
+		     , CASE WHEN LEAF_CATE_NO = CATE5_NO THEN 5
+		            WHEN LEAF_CATE_NO = CATE4_NO THEN 4
+		            WHEN LEAF_CATE_NO = CATE3_NO THEN 3
+		            WHEN LEAF_CATE_NO = CATE2_NO THEN 2
+		            WHEN LEAF_CATE_NO = CATE1_NO THEN 1
+		       END                             AS CLS_LVL     /*분류레벨*/
+		     , REPLACE(FULL_CATE_NO,' > ','/') AS TREE_PATH   /*AG-GRID트리패스(ag-Grid미사용시 필요 없음)*/
+		FROM   TB_CATE_4SRCH C4
+		WHERE  CATE_GB = #{cateGb}
+		AND    CATE_TYPE = 'G031_10' /*상품분류카테고리*/
+		ORDER  BY DISP_ORD
+	</select>
+	
+	<!-- 품목카테고리매핑 생성  -->
+	<insert id="createItemkindCategoryMapping" parameterType="ItemkindCategory">
+		/* TsaDisplay.createItemkindCategoryMapping */
+		INSERT INTO TB_ITEMKIND_CATE (
+		       ITEMKIND_CD
+		     , CATE_NO
+		     , REG_NO
+		     , REG_DT
+		)
+		VALUES (
+		       #{itemkindCd}
+		     , #{cateNo}
+		     , #{regNo}
+		     , NOW()
+		)
+	</insert>
+	
+	<!-- 품목카테고리매핑에 의한 카테고리상품 생성  -->
+	<insert id="createCategoryGoodsByItemkindCategoryMapping" parameterType="ItemkindCategory">
+		/* TsaDisplay.createCategoryGoodsByItemkindCategoryMapping */
+		INSERT INTO TB_CATE_GOODS (
+		       CATE_NO
+		     , GOODS_CD
+		     , DISP_ORD
+		     , REG_NO
+		     , REG_DT
+		)
+		SELECT #{cateNo} AS CATE_NO
+		     , GOODS_CD
+		     , 100       AS DISP_ORD
+		     , #{regNo}  AS REG_NO
+		     , NOW()     AS REG_DT
+		FROM   TB_GOODS A
+		WHERE  ITEMKIND_CD = #{itemkindCd}
+		AND    GOODS_STAT NOT IN ('G008_95','G008_99') /*시즌아웃,DROP(삭제)가 아닌넘*/
+		AND    NOT EXISTS (SELECT 1
+		                   FROM   TB_CATE_GOODS
+		                   WHERE  CATE_NO = #{cateNo}
+		                   AND    GOODS_CD = A.GOODS_CD
+		                  )
+	</insert>
+
+	<!-- 품목카테고리매핑 삭제  -->
+	<delete id="deleteItemkindCategoryMapping" parameterType="ItemkindCategory">
+		/* TsaDisplay.deleteItemkindCategoryMapping */
+		DELETE FROM TB_ITEMKIND_CATE
+		WHERE  ITEMKIND_CD = #{itemkindCd}
+		AND    CATE_NO = #{cateNo}
+	</delete>
+	
+	<!-- 품목카테고리매핑에 의한 카테고리상품 삭제  -->
+	<delete id="deleteCategoryGoodsByItemkindCategoryMapping" parameterType="ItemkindCategory">
+		/* TsaDisplay.deleteCategoryGoodsByItemkindCategoryMapping */
+		DELETE FROM TB_CATE_GOODS
+		WHERE  CATE_NO = #{cateNo}
+		AND    GOODS_CD IN (SELECT GOODS_CD
+		                    FROM   TB_GOODS
+		                    WHERE  ITEMKIND_CD = #{itemkindCd}
+		                   )
+	</delete>
+	
+	<!-- 품목카테고리매핑 목록 -->
+	<select id="getItemkindCategoryMappingList" parameterType="String" resultType="ItemkindCategory">
+		/* TsaDisplay.getItemkindCategoryMappingList */
+		SELECT IC.ITEMKIND_CD             /*품목코드*/
+		     , C4.CATE_GB                 /*카테고리구분*/
+		     , C4.LEAF_CATE_NO AS CATE_NO /*카테고리번호*/
+		     , C4.FULL_CATE_NO            /*FULL카테고리번호*/
+		     , C4.FULL_CATE_NM            /*FULL카테고리명*/
+		FROM   TB_ITEMKIND_CATE IC
+		     , TB_CATE_4SRCH C4
+		WHERE  IC.CATE_NO = C4.LEAF_CATE_NO
+		AND    IC.ITEMKIND_CD = #{itemkindCd}
+		ORDER  BY C4.CATE_GB, C4.LEAF_CATE_NO
 	</select>
 	
 </mapper>

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

@@ -539,7 +539,7 @@
 		        AND 1 = 1
 		              </when>
 		              <otherwise>
-		        AND UPPER(G.REG_ID) LIKE CONCAT('%',UPPER(#{item}),'%')
+		        AND 1 = 1
 		              </otherwise>
 		            </choose>
 		        </if>
@@ -1456,11 +1456,13 @@
 		     , A.COMPS_CURR_PRICE AS COMPS_CURR_PRICE_ORG
 		     , A.COMPS_GOODS_OPT_NM
 		     , A.BASE_YN
+		     , A.REP_YN
 		     , A.USE_YN
 		     , B.CURR_PRICE
 		     , B.GOODS_STAT
 		     , B.SELF_GOODS_YN
 		     , B.SUPPLY_COMP_CD
+		     , (SELECT MAX(COMPS_GOODS_CD) FROM TB_GOODS_COMPOSE WHERE GOODS_CD  = #{goodsCd} AND REP_YN='Y') AS REP_GOODS_CD
 		     , (SELECT MAX(SYS_IMG_NM) FROM TB_GOODS_IMG  WHERE GOODS_CD = B.GOODS_CD AND COLOR_CD = B.MAIN_COLOR_CD AND DEFAULT_IMG_YN = 'Y' ) AS SYS_IMG_NM
 		     , A.REG_NO
 		     , FN_GET_USER_NM(A.REG_NO) AS REG_NM
@@ -1479,6 +1481,8 @@
 		/* TsaGoods.createGoods */
 		INSERT INTO TB_GOODS (
 		    GOODS_CD
+		  , PRODUCT_NO
+		  , PRODUCT_CODE
 		  , BRAND_CD
 		  , ITEMKIND_CD
 		  , GOODS_NM
@@ -1522,6 +1526,8 @@
 		)
 		VALUES(
 		    #{goodsCd}
+		  , NVL(#{productNo},0)
+		  , NVL(#{productCode},0)
 		  , #{brandCd}
 		  , #{itemkindCd}
 		  , NVL(#{goodsNm},'상품명없음')
@@ -1592,6 +1598,7 @@
 		  , GOODS_NM = #{goodsNm}
 		  , SEASON_CD = #{seasonCd}
 		  , SEX_GB = #{sexGb}
+		  , LIST_PRICE = #{listPrice}
 		  , CURR_PRICE = #{currPrice}
 		  <if test="currBprice != null and currBprice != ''">
 		  , CURR_BPRICE = #{currBprice}
@@ -1631,6 +1638,28 @@
 		WHERE GOODS_CD = #{goodsCd}
 	</update>
 	
+	<!-- 상품 상세 정보 이력 생성 -->
+	<insert id="createGoodsDetailDescHst" parameterType="GoodsDesc">
+		/* TsaGoods.createGoodsDetailDescHst */
+		INSERT INTO TB_GOODS_DESC_HST (
+		    GOODS_CD
+		  , DESC_GB
+		  , SEQ
+		  , GOODS_DESC
+		  , REG_NO
+		  , REG_DT
+		)
+		SELECT GOODS_CD
+		     , DESC_GB
+		     , SEQ
+		     , GOODS_DESC
+		     , #{regNo}
+		     , NOW()
+		FROM TB_GOODS_DESC
+		WHERE GOODS_CD = #{goodsCd}
+		ORDER BY DESC_GB, DESC_GB
+	</insert>
+	
 	<!-- 상품 상세정보 삭제 -->
 	<delete id="deleteGoodsDesc" parameterType="GoodsDesc">
 		/* TsaGoods.deleteGoodsDesc */
@@ -1672,6 +1701,7 @@
 		         , COMPS_CURR_PRICE
 		         , COMPS_GOODS_OPT_NM
 		         , BASE_YN
+		         , REP_YN
 		         , USE_YN
 		         , REG_NO
 		         , REG_DT
@@ -1688,6 +1718,7 @@
 		                ELSE 0 END)
 		         , #{compsGoodsOptNm}
 		         , #{baseYn}
+		         , IFNULL(#{repYn},'N')
 		         , #{useYn}
 		         , #{regNo}
 		         , NOW()
@@ -1801,11 +1832,8 @@
 	</update>
 	
 	<!-- 상품코드 생성 -->
-	<insert id="createGoodsSequence" parameterType="Goods">
+	<insert id="createGoodsSequence" parameterType="Goods"  keyProperty="goodsSq">
 		/* TsaGoods.createGoodsSequence */
-		<selectKey keyProperty="goodsSq" resultType="int" order="AFTER">
-		SELECT MAX(GOODS_SQ) FROM TB_GOODS_SEQUENCE
-		</selectKey>
 		INSERT INTO TB_GOODS_SEQUENCE (GOODS_SQ) VALUES (NULL)
 	</insert>
 
@@ -3566,5 +3594,151 @@
 		     , NOW()
 		)
 	</insert>
+	
+	<!-- 사은품 목록 -->
+	<select id="getFreeGoodsList" parameterType="GoodsSearch" resultType="FreeGoods">
+		/* TsaGoods.getFreeGoodsList */
+		SELECT G.PRODUCT_NO 
+		     , G.PRODUCT_CODE 
+		     , G.GOODS_NUM 
+		     , G.GOODS_NM 
+		     , G.USE_YN 
+		     , G.SYS_IMG_NM 
+		     , G.BRAND_CD 
+		     , B.BRAND_ENM
+		     , FN_GET_USER_NM(G.REG_NO) AS REG_NM
+		     , DATE_FORMAT(G.REG_DT,'%Y%m%d%H%i%S') AS REG_DT
+		     , FN_GET_USER_NM(G.UPD_NO) AS UPD_NM
+		     , DATE_FORMAT(G.UPD_DT,'%Y%m%d%H%i%S') AS UPD_DT
+		FROM TB_FREE_GOODS G
+		INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD 
+		WHERE 1 = 1
+		<if test='conditionList != null and conditionList.length>0'>
+		    <choose>
+		      <when test='search != null and search == "searchProductNo"'>
+		AND (
+		      <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(G.PRODUCT_NO) = UPPER(#{item}) 
+		      </foreach>
+		     )
+		      </when>
+		      <when test='search != null and search == "searchGoodsNm"'>
+		AND (
+		      <foreach collection="conditionList" item="item" index="index" separator="or">
+		       UPPER(G.GOODS_NM) LIKE CONCAT('%',UPPER(#{item}),'%')
+		      </foreach>
+		     )
+		      </when>
+		      <otherwise>
+		AND 1 = 1
+		      </otherwise>
+		    </choose>
+		</if>
+		<include refid="getGoodsListCondition_sql"/>
+		ORDER BY G.PRODUCT_NO DESC
+	</select>
+	
+	<!-- 상품이미지 삭제 -->
+	<update id="updateFreeGoods" parameterType="FreeGoods">
+		/* TsaGoods.updateFreeGoods */
+		UPDATE TB_FREE_GOODS
+		SET GOODS_NM = #{goodsNm}
+		  , SYS_IMG_NM = #{sysImgNm}
+		  , USE_YN = #{useYn}
+		  , UPD_NO = #{updNo}
+		  , UPD_DT = NOW()
+		WHERE PRODUCT_NO = #{productNo}
+	</update>
+	
+	<!-- WMS입고상품 목록 -->
+	<select id="getGoodsWmsIncomelotList" parameterType="WmsGoods" resultType="WmsGoods">
+		/* TsaGoods.getGoodsWmsIncomelotList */
+		SELECT A.PRODUCT_NO
+		     , A.PRODUCT_CODE
+		     , A.PRODUCT_NAME
+		     , A.SKUCODE
+		     , A.NORMAL_QTY
+		     , A.BROKEN_QTY
+		     , A.TOTAL_QTY
+		     , A.MODEL_NO
+		     , A.PROVIDER_NO
+		     , A.PROVIDER_NAME
+		     , A.BRAND_NO
+		     , A.BRAND_NAME
+		     , A.GOODS_REG_DT
+		     , A.GOODS_REG_GB
+		     , B.BRAND_CD
+		     , B.BRAND_ENM
+		     , A.REG_NO
+		     , FN_GET_USER_NM(A.REG_NO) AS REG_NM
+		     , DATE_FORMAT(A.REG_DT,'%Y%m%d%H%i%S') AS REG_DT
+		     , A.UPD_NO
+		     , FN_GET_USER_NM(A.UPD_NO) AS UPD_NM
+		     , DATE_FORMAT(A.UPD_DT,'%Y%m%d%H%i%S') AS UPD_DT
+		FROM TB_WMS_GOODS A
+		LEFT OUTER JOIN TB_BRAND B ON A.BRAND_NO = B.BRAND_NO 
+		LEFT OUTER JOIN TB_SUPPLY_COMPANY S ON A.PROVIDER_NO = S.PROVIDER_NO
+		WHERE GOODS_REG_GB IS NULL   /* 온라인 미등록 상품 */
+		<if test="modelNo != null and modelNo != ''">
+		AND UPPER(A.MODEL_NO) = CONCAT('%',UPPER(#{modelNo}),'%') 
+		</if>
+		<if test="stDate != null and stDate != ''">
+		AND A.REG_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+		</if>
+		<if test="edDate != null and edDate != ''">
+		<![CDATA[
+		AND A.REG_DT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+		]]>
+		</if>
+		<if test="supplyCompCd != null and supplyCompCd != ''">
+		AND UPPER(S.SUPPLY_COMP_CD) = UPPER(#{supplyCompCd}) 
+		</if>
+		<if test="brandCd != null and brandCd != ''">
+		AND UPPER(B.BRAND_CD) = UPPER(#{brandCd}) 
+		</if>
+		ORDER BY A.UPD_DT DESC
+	</select>
+	
+	<!-- 사은품 등록 -->
+	<insert id="saveFreeGoods" parameterType="WmsGoods">
+		/* TsaGoods.saveFreeGoods */
+		INSERT INTO TB_FREE_GOODS (
+		       PRODUCT_NO
+		     , PRODUCT_CODE
+		     , GOODS_NUM
+		     , BRAND_CD
+		     , GOODS_NM
+		     , USE_YN
+		     , SYS_IMG_NM
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{productNo}
+		     , #{productCode}
+		     , #{goodsNum}
+		     , #{brandCd}
+		     , #{goodsNm}
+		     , #{useYn}
+		     , NULL
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+	</insert>
+	
+	<!-- WMS 입고상품 사은품 상품 구분 저장 -->
+	<update id="saveGoodsWmsIncomelot" parameterType="WmsGoods">
+		/* TsaGoods.saveGoodsWmsIncomelot */
+		UPDATE TB_WMS_GOODS
+		SET GOODS_REG_GB = #{goodsRegGb}
+		  , GOODS_REG_DT = NOW()
+		  , UPD_NO = #{updNo}
+		  , UPD_DT = NOW()
+		WHERE PRODUCT_NO = #{productNo}
+	</update>
 	
 </mapper>

+ 30 - 0
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaMarketing.xml

@@ -134,4 +134,34 @@
 		</if>
 	</select>
 	<!-- // JSM 진행 -->
+
+	<!-- // CSB 진행 -->
+	<select id="getMorebetterList" parameterType="MoreBetter" resultType="MoreBetter">
+		SELECT TMTB_SQ
+			 , TMTB_NM
+			 , FN_GET_CODE_NM('G232',TMTB_STAT) as TMTB_STAT
+			 , DATE_FORMAT(TMTB_ST_DT, '%Y.%m.%d') AS TMTB_STDT
+			 , DATE_FORMAT(TMTB_ED_DT, '%Y.%m.%d') AS TMTB_EDDT
+			 , DEL_YN
+			 , FN_GET_USER_NM(REG_NO) AS REG_NM
+			 , DATE_FORMAT(REG_DT, '%Y.%m.%d %H:%i:%S') AS REG_DT
+			 , FN_GET_USER_NM(UDP_NO) AS UPD_NM
+			 , DATE_FORMAT(UDT_DT, '%Y.%m.%d %H:%i:%S') AS UPD_DT
+		FROM TB_TMTB
+		WHERE 1=1
+		<if test="tmtbStdt != null and tmtbStdt != '' and tmtbEddt != null and tmtbEddt != ''">
+			AND TMTB_ST_DT >= DATE_FORMAT(#{tmtbStdt} , '%Y-%m-%d')
+			AND TMTB_ED_DT <![CDATA[ <= ]]> DATE_FORMAT(#{tmtbEddt} , '%Y-%m-%d')
+		</if>
+		<if test="searchTxt != null and searchTxt != ''">
+			<if test="searchGubun != null and searchGubun == 'tmtbSq'">
+				AND TMTB_SQ = #{searchTxt}
+			</if>
+			<if test="searchGubun != null and searchGubun == 'tmtbNm'">
+				AND TMTB_NM = #{searchTxt}
+			</if>
+		</if>
+		ORDER BY REG_DT DESC
+	</select>
+	<!--// CSB 진행 -->
 </mapper>

+ 186 - 174
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaNotice.xml

@@ -1,175 +1,187 @@
-<?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.TsaNoticeDao">
-
-	<!-- 공지사항 목록 -->
-	<select id="getNoticeList" parameterType="Notice" resultType="Notice">
-		/* TsaNotice.getNoticeList */
-		SELECT A.NOTICE_SQ                                         /*공지번호*/
-		     , A.NOTICE_TYPE                                       /*공지유형*/
-		     , A.URGENT_YN                                         /*긴급여부*/
-		     , A.NOTICE_TITLE                                      /*공지제목*/
-		     , A.NOTICE_CONTENT                                    /*공지내용*/
-		     , IFNULL((SELECT COUNT(*)
-		               FROM   TB_NOTICE_FILE
-		               WHERE  NOTICE_SQ = A.NOTICE_SQ
-		              ),0)                          AS FILE_CNT    /*파일건수*/
-		     , 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                                            /*사용여부*/
-		     , A.READ_CNT                                          /*조회수*/
-		     , 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 = #{noticeType}
-		<if test="startDt != null and startDt !=''">
-		AND    A.REG_DT <![CDATA[>=]]> STR_TO_DATE(#{startDt},'%Y-%m-%d')
-		</if>
-		<if test="startDt != null and startDt !='' and endDt != null and endDt != ''">
-		AND    A.REG_DT <![CDATA[<]]> DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'),INTERVAL 1 DAY)
-		</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='receiverId != null and receiverId !=""'>
-		AND    A.NOTICE_SQ IN (SELECT NOTICE_SQ
-		                       FROM   TB_NOTICE_RECEIVER
-		                       WHERE  RECEIVER_ID = #{receiverId}
-		                      )
-		</if>
-		ORDER  BY A.URGENT_YN DESC, A.NOTICE_SQ DESC
-	</select>
-
-	<!-- 공지사항 수신자 목록 -->
-	<select id="getNoticeReceiverList" parameterType="Integer" resultType="Notice">
-		/* TsaNotice.getNoticeReceiverList */
-		SELECT RECEIVER_ID
-		FROM   TB_NOTICE_RECEIVER
-		WHERE  NOTICE_SQ = #{noticeSq}
-	</select>
-
-	<!-- 공지사항 파일 목록 -->
-	<select id="getNoticeFileList" parameterType="Integer" resultType="Notice">
-		/* TsaNotice.getNoticeFileList */
-		SELECT NOTICE_SQ
-		     , SEQ
-		     , ORG_FILE_NM
-		     , SYS_FILE_NM
-		FROM   TB_NOTICE_FILE
-		WHERE  NOTICE_SQ = #{noticeSq}
-	</select>
-
-	<!-- 공지사항 저장 -->
-	<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>
-
-	<!-- 공지사항 수신자 삭제 -->
-	<delete id="deleteNoticeReceiver" parameterType="Notice">
-		/* TsaNotice.deleteNoticeReceiver */
-		DELETE FROM TB_NOTICE_RECEIVER
-		WHERE  NOTICE_SQ = #{noticeSq}
-	</delete>
-
-	<!--공지사항 수신자 등록 -->
-	<insert id="createNoticeReceiver" parameterType="Notice">
-		/* TsaNotice.createNoticeReceiver */
-		INSERT INTO TB_NOTICE_RECEIVER (
-		       NOTICE_SQ
-		     , RECEIVER_ID
-		     , REG_NO
-		     , REG_DT
-		)
-		VALUES (
-		       #{noticeSq}
-		     , #{receiverId}
-		     , #{regNo}
-		     , NOW()
-		)
-	</insert>
-
-	<!-- 공지사항 파일 삭제 -->
-	<delete id="deleteNoticeFile" parameterType="Notice">
-		/* TsaNotice.deleteNoticeFile */
-		DELETE FROM TB_NOTICE_FILE
-		WHERE  NOTICE_SQ = #{noticeSq}
-		<if test="seq != null and seq !=''">
-		AND    SEQ = #{seq}
-		</if>
-	</delete>
-
-	<!-- 공지사항 파일 저장 -->
-	<insert id="createNoitceFlie" parameterType="Notice">
-		/* TsaNotice.createNoitceFlie */
-		INSERT INTO TB_NOTICE_FILE (
-		       NOTICE_SQ
-		     , SEQ
-		     , ORG_FILE_NM
-		     , SYS_FILE_NM
-		     , REG_NO
-		     , REG_DT
-		)
-		VALUES (
-		       #{noticeSq}
-		     , IFNULL((SELECT MAX(SEQ)
-		               FROM   TB_NOTICE_FILE
-		               WHERE  NOTICE_SQ = #{noticeSq}
-		              ),0) + 1
-		     , #{orgFileNm}
-		     , #{sysFileNm}
-		     , #{regNo}
-		     , NOW()
-		)
-	</insert>
-
+<?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.TsaNoticeDao">
+
+	<!-- 공지사항 목록 -->
+	<select id="getNoticeList" parameterType="Notice" resultType="Notice">
+		/* TsaNotice.getNoticeList */
+		SELECT A.NOTICE_SQ                                                /*공지번호*/
+		     , A.NOTICE_TYPE                                              /*공지유형*/
+		     , A.URGENT_YN                                                /*긴급여부*/
+		     , A.NOTICE_TITLE                                             /*공지제목*/
+		     , A.NOTICE_CONTENT                                           /*공지내용*/
+		     , IFNULL((SELECT COUNT(*)
+		               FROM   TB_NOTICE_FILE
+		               WHERE  NOTICE_SQ = A.NOTICE_SQ
+		              ),0)                             AS FILE_CNT        /*파일건수*/
+		     , 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                                                   /*사용여부*/
+		     , A.READ_CNT                                                 /*조회수*/
+		     , A.POPUP_YN                                                 /*팝업여부*/
+		     , DATE_FORMAT(A.POPUP_DISP_STDT,'%Y%m%d') AS POPUP_DISP_STDT /*팝업노출시작일자*/
+		     , DATE_FORMAT(A.POPUP_DISP_EDDT,'%Y%m%d') AS POPUP_DISP_EDDT /*팝업노출종료일자*/
+		     , 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 = #{noticeType}
+		<if test="startDt != null and startDt !=''">
+		AND    A.REG_DT <![CDATA[>=]]> STR_TO_DATE(#{startDt},'%Y-%m-%d')
+		</if>
+		<if test="startDt != null and startDt !='' and endDt != null and endDt != ''">
+		AND    A.REG_DT <![CDATA[<]]> DATE_ADD(STR_TO_DATE(#{endDt},'%Y-%m-%d'),INTERVAL 1 DAY)
+		</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='receiverId != null and receiverId !=""'>
+		AND    A.NOTICE_SQ IN (SELECT NOTICE_SQ
+		                       FROM   TB_NOTICE_RECEIVER
+		                       WHERE  RECEIVER_ID = #{receiverId}
+		                      )
+		</if>
+		ORDER  BY A.URGENT_YN DESC, A.NOTICE_SQ DESC
+	</select>
+
+	<!-- 공지사항 수신자 목록 -->
+	<select id="getNoticeReceiverList" parameterType="Integer" resultType="Notice">
+		/* TsaNotice.getNoticeReceiverList */
+		SELECT RECEIVER_ID
+		FROM   TB_NOTICE_RECEIVER
+		WHERE  NOTICE_SQ = #{noticeSq}
+	</select>
+
+	<!-- 공지사항 파일 목록 -->
+	<select id="getNoticeFileList" parameterType="Integer" resultType="Notice">
+		/* TsaNotice.getNoticeFileList */
+		SELECT NOTICE_SQ
+		     , SEQ
+		     , ORG_FILE_NM
+		     , SYS_FILE_NM
+		FROM   TB_NOTICE_FILE
+		WHERE  NOTICE_SQ = #{noticeSq}
+	</select>
+
+	<!-- 공지사항 저장 -->
+	<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
+		     , POPUP_YN
+		     , POPUP_DISP_STDT
+		     , POPUP_DISP_EDDT
+		     , 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)
+		     , IFNULL(#{popupYn},'N')
+		     , STR_TO_DATE(#{popupDispStdt},'%Y-%m-%d')
+		     , STR_TO_DATE(#{popupDispEddt},'%Y-%m-%d')
+		     , #{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')
+		     , POPUP_YN = IFNULL(#{popupYn},'N')
+		     , POPUP_DISP_STDT = STR_TO_DATE(#{popupDispStdt},'%Y-%m-%d')
+		     , POPUP_DISP_EDDT = STR_TO_DATE(#{popupDispEddt},'%Y-%m-%d')
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  NOTICE_SQ = #{noticeSq}
+	</update>
+
+	<!-- 공지사항 수신자 삭제 -->
+	<delete id="deleteNoticeReceiver" parameterType="Notice">
+		/* TsaNotice.deleteNoticeReceiver */
+		DELETE FROM TB_NOTICE_RECEIVER
+		WHERE  NOTICE_SQ = #{noticeSq}
+	</delete>
+
+	<!--공지사항 수신자 등록 -->
+	<insert id="createNoticeReceiver" parameterType="Notice">
+		/* TsaNotice.createNoticeReceiver */
+		INSERT INTO TB_NOTICE_RECEIVER (
+		       NOTICE_SQ
+		     , RECEIVER_ID
+		     , REG_NO
+		     , REG_DT
+		)
+		VALUES (
+		       #{noticeSq}
+		     , #{receiverId}
+		     , #{regNo}
+		     , NOW()
+		)
+	</insert>
+
+	<!-- 공지사항 파일 삭제 -->
+	<delete id="deleteNoticeFile" parameterType="Notice">
+		/* TsaNotice.deleteNoticeFile */
+		DELETE FROM TB_NOTICE_FILE
+		WHERE  NOTICE_SQ = #{noticeSq}
+		<if test="seq != null and seq !=''">
+		AND    SEQ = #{seq}
+		</if>
+	</delete>
+
+	<!-- 공지사항 파일 저장 -->
+	<insert id="createNoitceFlie" parameterType="Notice">
+		/* TsaNotice.createNoitceFlie */
+		INSERT INTO TB_NOTICE_FILE (
+		       NOTICE_SQ
+		     , SEQ
+		     , ORG_FILE_NM
+		     , SYS_FILE_NM
+		     , REG_NO
+		     , REG_DT
+		)
+		VALUES (
+		       #{noticeSq}
+		     , IFNULL((SELECT MAX(SEQ)
+		               FROM   TB_NOTICE_FILE
+		               WHERE  NOTICE_SQ = #{noticeSq}
+		              ),0) + 1
+		     , #{orgFileNm}
+		     , #{sysFileNm}
+		     , #{regNo}
+		     , NOW()
+		)
+	</insert>
+
 </mapper>

+ 208 - 4
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaOrder.xml

@@ -33,7 +33,9 @@
 			     , OCD.CHG_STAT
 			FROM   TB_ORDER_CHANGE OC
 			INNER  JOIN TB_ORDER_CHANGE_DETAIL OCD
-			ON     OC.ORD_CHG_SQ  = OCD.ORD_CHG_SQ 
+			ON     OC.ORD_CHG_SQ  = OCD.ORD_CHG_SQ
+			WHERE  1=1 
+			GROUP  BY OCD.ORD_DTL_NO 
 		) OCD
 		ON    OD.ORD_DTL_NO = OCD.ORD_DTL_NO
 		WHERE  1=1
@@ -246,6 +248,8 @@
 					FROM   TB_ORDER_CHANGE OC
 					INNER  JOIN TB_ORDER_CHANGE_DETAIL OCD
 					ON     OC.ORD_CHG_SQ  = OCD.ORD_CHG_SQ 
+					WHERE  1=1
+					GROUP  BY OCD.ORD_DTL_NO 
 				) OCD
 				ON    OD.ORD_DTL_NO = OCD.ORD_DTL_NO
 				WHERE  1=1
@@ -1569,6 +1573,7 @@
 	
 	<!-- 주문정보 -->
 	<select id="getOrderInfo" parameterType="Order" resultType="Order">
+		/* order.getOrderInfo */
 		SELECT O.ORD_NO
 		     , O.MALL_GB
 		     , FN_GET_CODE_NM('G011', O.MALL_GB) AS MALL_GB_NM
@@ -1633,8 +1638,15 @@
 	
 	<!-- 주문상세 > 주문취소대상목록 -->
 	<select id="getCancelRequestTargetList" parameterType="Order" resultType="Order">
+		/* order.getCancelRequestTargetList */
 		SELECT OD.ORD_NO
 		     , OD.ORD_DTL_NO
+		     , OD.ORD_DTL_STAT
+		     , FN_GET_CODE_NM('G013', OD.ORD_DTL_STAT) AS ORD_DTL_STAT_NM
+		     , CASE WHEN OD.ORD_DTL_STAT IN ('G013_20', 'G013_30', 'G013_40')
+		            THEN 'Y'
+		            ELSE 'N'
+		             END ALL_CAN_YN
 		     , G1.GOODS_CD
 		     , G1.GOODS_NM
 		     , G1.GOODS_TYPE
@@ -1686,7 +1698,7 @@
 			INNER  JOIN TB_ORDER_DETAIL OD
 			ON     OCD.ORD_DTL_NO = OD.ORD_DTL_NO
 			WHERE  1=1
-			AND    OD.ORD_NO = 9
+			AND    OD.ORD_NO = #{ordNo}
 			AND    OCD.CHG_STAT IN (
 				'G685_20', 'G685_30', 'G685_40'
 			)
@@ -1703,12 +1715,204 @@
 		AND    OD.ORD_DTL_STAT IN (
 			'G013_10', 'G013_20', 'G013_30', 'G013_40'
 		)
-		AND    OD.ORD_NO = 9
+		AND    OD.ORD_NO = #{ordNo}
 		GROUP  BY OD.ORD_NO
 		     , OD.ORD_DTL_NO
 	    ORDER  BY OD.ORD_NO
 	         , OD.ORD_DTL_NO
-	</select>
+	</select>
+	
+	<!-- 주문상세 > 주문취소신청 > 주문변경정보 등록-->
+	<insert id="createOrderChange" parameterType="OrderChange" keyProperty="ordChgSq">
+		/* Order.createOrderChange */
+		INSERT INTO TB_ORDER_CHANGE (
+			CHG_GB
+			, CHG_REASON
+			, CHG_MEMO
+			, CHGER_NM
+			, CHGER_PHNNO
+			, CHGER_TELNO
+			, CHGER_EMAIL
+			, CHGER_ZIP_NO
+			, CHGER_BASE_ADDR
+			, CHGER_DTL_ADDR
+			, CHGER_RTN_MEMO
+			, ADD_PAY_COST
+			, ADD_PAY_AMT
+			, REG_NO
+			, REG_DT
+			, UPD_NO
+			, UPD_DT
+		) 
+		SELECT #{chgGb}
+			 , #{chgReason}
+			 , #{chgMemo}
+			 , ORD_NM
+			 , ORD_PHNNO
+			 , ORD_TELNO
+			 , ORD_EMAIL
+			 , #{chgerZipNo}
+			 , #{chgerBaseAddr}
+			 , #{chgerDtlAddr}
+			 , #{chgerRtnMemo}
+			 , #{addPayCost}
+			 , #{addPayAmt}
+			 , #{regNo}
+			 , SYSDATE()
+			 , #{updNo}
+			 , SYSDATE()
+		FROM   TB_ORDER  
+		WHERE  ORD_NO = #{ordNo}
+	</insert>
+	
+	<!-- 주문상세 > 주문취소신청 > 주문변경정보 등록-->
+	<insert id="createOrderChangeDetail" parameterType="OrderChange">
+		/* Order.createOrderChangeDetail */
+		INSERT INTO TB_ORDER_CHANGE_DETAIL (
+			ORD_CHG_SQ
+			, ORD_DTL_NO
+			, CHG_QTY
+			, CHG_STAT
+			, COMPLETE_DT
+			, REG_NO
+			, REG_DT
+			, UPD_NO
+			, UPD_DT
+		) VALUES (
+			#{ordChgSq}
+			, #{ordDtlNo}
+			, #{chgQty}
+			, #{chgStat}
+			, SYSDATE()
+			, #{regNo}
+			, SYSDATE()
+			, #{updNo}
+			, SYSDATE()
+		)
+	</insert>
+	
+	<!-- 주문상세 > 주문취소신청 > 주문상세단품정보 수정 -->
+	<update id="updateOrderDetailItem" parameterType="Order">
+		/* Order.updateOrderDetailItem */
+		UPDATE TB_ORDER_DETAIL_ITEM
+		SET    ORD_AMT 				= ORD_AMT 				- #{cnclRtnAmt}
+		     , CNCL_RTN_AMT 		= CNCL_RTN_AMT 			+ #{cnclRtnAmt}
+		     , CPN1_DC_AMT 			= CPN1_DC_AMT 			- #{cpn1DcAmt}
+		     , TMTB1_DC_AMT 		= TMTB1_DC_AMT 			- #{tmtb1DcAmt}
+		     , TMTB2_DC_AMT 		= TMTB1_DC_AMT 			- #{tmtb2DcAmt}
+		     , GOODS_CPN_DC_AMT 	= GOODS_CPN_DC_AMT 		- #{goodsCpnDcAmt}
+		     , CART_CPN_DC_AMT 		= CART_CPN_DC_AMT 		- #{cartCpnDcAmt}
+		     , PNT_DC_AMT 			= PNT_DC_AMT 			- #{pntDcAmt}
+		     , PRE_PNT_DC_AMT 		= PRE_PNT_DC_AMT 		- #{prePntDcAmt}
+		     , SAVE_PNT_AMT 		= SAVE_PNT_AMT 			- #{savePntAmt}
+		     , REAL_ORD_AMT 		= REAL_ORD_AMT 			- #{realOrdAmt}
+		     , GFCD_USE_AMT 		= GFCD_USE_AMT 			- #{gfcdUseAmt}
+		     , UPD_NO 				= #{updNo}
+		     , UPD_DT 				= SYSDATE()
+		WHERE  1=1
+		AND    ORD_NO 				= #{ordNo} 
+		AND    ORD_DTL_NO 			= #{ordDtlNo} 
+		AND    ORD_DTL_ITEM_SQ 		= #{ordDtlItemSq}
+	</update>
+	
+	<!-- 주문상세 > 주문취소신청 > 주문상세단품정보 이력 등록 -->
+	<insert id="createOrderDetailItemHst" parameterType="Order">
+		/* Order.createOrderDetailItemHst */
+		INSERT INTO TB_ORDER_DETAIL_ITEM_HST (
+			ORD_DTL_ITEM_SQ
+			, ORD_DTL_NO
+			, ORD_NO
+			, ORD_DTL_STAT
+			, ITEM_CD
+			, OPT_CD
+			, OPT_CD1
+			, OPT_CD2
+			, SKU_MODEL_NO
+			, PRODUCT_NO
+			, PRODUCT_CODE
+			, ITEM_QTY
+			, ITEM_PRICE
+			, OPT_ADD_PRICE
+			, DISP_ORD
+			, ORD_AMT
+			, CNCL_RTN_AMT
+			, CPN1_DC_AMT
+			, TMTB1_DC_AMT
+			, TMTB2_DC_AMT
+			, GOODS_CPN_DC_AMT
+			, CART_CPN_DC_AMT
+			, PNT_DC_AMT
+			, PRE_PNT_DC_AMT
+			, SAVE_PNT_AMT
+			, REAL_ORD_AMT
+			, GFCD_USE_AMT
+			, REG_NO
+			, REG_DT
+			, UPD_NO
+			, UPD_DT
+		) 
+		SELECT ORD_DTL_ITEM_SQ
+			 , ORD_DTL_NO
+			 , ORD_NO
+			 , #{ordDtlStat}
+			 , ITEM_CD
+			 , OPT_CD
+			 , OPT_CD1
+			 , OPT_CD2
+			 , SKU_MODEL_NO
+			 , PRODUCT_NO
+			 , PRODUCT_CODE
+			 , ITEM_QTY
+			 , ITEM_PRICE
+			 , OPT_ADD_PRICE
+			 , DISP_ORD
+			 , #{ordAmt}
+			 , #{cnclRtnAmt}
+			 , #{cpn1DcAmt}
+			 , #{tmtb1DcAmt}
+			 , #{tmtb2DcAmt}
+			 , #{goodsCpnDcAmt}
+			 , #{cartCpnDcAmt}
+			 , #{pntDcAmt}
+			 , #{prePntDcAmt}
+			 , #{savePntAmt}
+			 , #{realOrdAmt}
+			 , #{gfcdUseAmt}
+			 , REG_NO
+			 , REG_DT
+			 , UPD_NO
+			 , UPD_DT
+		FROM   TB_ORDER_DETAIL_ITEM
+		WHERE  1=1
+		AND    ORD_NO = #{ordNo} 
+		AND    ORD_DTL_NO = #{ordDtlNo} 
+		AND    ORD_DTL_ITEM_SQ = #{ordDtlItemSq}
+	</insert>
+	
+	<!-- 주문상세 > 주문취소신청 > 주문상세정보 수정 -->
+	<update id="updateOrderDetail" parameterType="Order">
+		/* Order.updateOrderDetail */
+		UPDATE TB_ORDER_DETAIL
+		SET    ORD_AMT 				= ORD_AMT 				- #{cnclRtnAmt}
+		     , CNCL_RTN_AMT 		= CNCL_RTN_AMT 			+ #{cnclRtnAmt}
+		     , CPN1_DC_AMT 			= CPN1_DC_AMT 			- #{cpn1DcAmt}
+		     , TMTB1_DC_AMT 		= TMTB1_DC_AMT 			- #{tmtb1DcAmt}
+		     , TMTB2_DC_AMT 		= TMTB1_DC_AMT 			- #{tmtb2DcAmt}
+		     , GOODS_CPN_DC_AMT 	= GOODS_CPN_DC_AMT 		- #{goodsCpnDcAmt}
+		     , CART_CPN_DC_AMT 		= CART_CPN_DC_AMT 		- #{cartCpnDcAmt}
+		     , PNT_DC_AMT 			= PNT_DC_AMT 			- #{pntDcAmt}
+		     , PRE_PNT_DC_AMT 		= PRE_PNT_DC_AMT 		- #{prePntDcAmt}
+		     , SAVE_PNT_AMT 		= SAVE_PNT_AMT 			- #{savePntAmt}
+		     , REAL_ORD_AMT 		= REAL_ORD_AMT 			- #{realOrdAmt}
+		     , GFCD_USE_AMT 		= GFCD_USE_AMT 			- #{gfcdUseAmt}
+		     , UPD_NO 				= #{updNo}
+		     , UPD_DT 				= SYSDATE()
+		WHERE  1=1
+		AND    ORD_NO 				= #{ordNo} 
+		AND    ORD_DTL_NO 			= #{ordDtlNo} 
+		AND    ORD_DTL_ITEM_SQ 		= #{ordDtlItemSq}
+	</update>
+	
 </mapper>
 
 

+ 3 - 3
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaRenderer.xml

@@ -331,9 +331,9 @@
 		FROM   TB_SELL_STORE
 	</select>
 
-	<!-- 1:1문의용 답변문구 목록 -->
-	<select id="getAnswerPhaseList" parameterType="String" resultType="CommonCode">
-		/* TsaRenderer.getAnswerPhaseList */
+	<!-- 문의용 답변문구 목록 -->
+	<select id="getQnaAnswerPhaseList" parameterType="String" resultType="CommonCode">
+		/* TsaRenderer.getQnaAnswerPhaseList */
 		SELECT ANS_SQ     AS CD
 		     , ANS_TITLE  AS CD_NM
 		FROM   TB_ANS_PHASE

+ 80 - 79
style24.admin/src/main/resources/i18n/messages/message_ko_KR.properties

@@ -1,79 +1,80 @@
-## -----------------------------------------------------------------------------
-## Message properties
-## -----------------------------------------------------------------------------
-SUCC_0001=\uc131\uacf5\uc801\uc73c\ub85c \uc800\uc7a5\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SUCC_0002=\uc131\uacf5\uc801\uc73c\ub85c \uc218\uc815\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SUCC_0003=\uc131\uacf5\uc801\uc73c\ub85c \uc0ad\uc81c\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SUCC_0004=\uc131\uacf5\uc801\uc73c\ub85c \ucc98\ub9ac\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SUCC_0005=\uc131\uacf5\uc801\uc73c\ub85c \ubc1c\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SUCC_0006=\uc131\uacf5\uc801\uc73c\ub85c \ubc1c\ud589\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SUCC_0007=\uc131\uacf5\uc801\uc73c\ub85c \uc5c5\ub85c\ub4dc \ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-#SUCC_0008=\uc131\uacf5\uc801\uc73c\ub85c \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SUCC_0009=\uc131\uacf5\uc801\uc73c\ub85c \ubcc0\uacbd\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-
-FAIL_0001=\uc624\ub958\ub85c \uc778\ud574 \uc800\uc7a5\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_0002=\uc624\ub958\ub85c \uc778\ud574 \uc218\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_0003=\uc624\ub958\ub85c \uc778\ud574 \uc0ad\uc81c\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_0004=\uc624\ub958\ub85c \uc778\ud574 \ucc98\ub9ac\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_0005=\uc624\ub958\ub85c \uc778\ud574 \ubc1c\uc1a1\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_0006=\uc624\ub958\ub85c \uc778\ud574 \ubc1c\ud589\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_0007=\uc624\ub958\ub85c \uc778\ud574 \uc5c5\ub85c\ub4dc \ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-#FAIL_0008=\uc624\ub958\ub85c \uc778\ud574 \ub4f1\ub85d\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_0009=\uc624\ub958\ub85c \uc778\ud574 \ubcc0\uacbd\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
-FAIL_1001=\uc800\uc7a5\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
-FAIL_1002=\uc804\uc1a1\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
-FAIL_1003=\uc5d1\uc140\ub2e4\uc6b4\ub85c\ub4dc\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
-FAIL_1004=\uc0ad\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
-
-LOGN_0001=\uc785\ub825\ud558\uc2e0 \uc815\ubcf4\ub85c \uac00\uc785\ub41c \ub0b4\uc5ed\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
-LOGN_0002=\ube44\ubc00\ubc88\ud638\uac00 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
-LOGN_0003=\ub85c\uadf8\uc778 \uc0c1\ud0dc\uac00 \uc544\ub2d9\ub2c8\ub2e4. \ub2e4\uc2dc \ub85c\uadf8\uc778 \ud574\uc8fc\uc138\uc694.
-LOGN_0004=\ube44\ubc00\ubc88\ud638\ub97c \ubcc0\uacbd\ud55c \ub0a0\ub85c\ubd80\ud130 3\uac1c\uc6d4\uc774 \uacbd\uacfc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-
-##\uc8fc\ubb38
-ORDER_0001=\uc8fc\ubb38\uc815\ubcf4\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
-ORDER_0002=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uacb0\uc81c\uc644\ub8cc][\ucd9c\uace0\uc644\ub8cc] \uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uc0c1\ud488\uc900\ube44\uc911\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ORDER_0003=\ud574\ub2f9 \uc0c1\ud488 \ube0c\ub79c\ub4dc \uc218\uc815 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
-ORDER_0004=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uc0c1\ud488\uc900\ube44\uc911][\uad6c\ub9e4\ud655\uc815] \uc0c1\ud0dc\uc5d0\ub9cc \uc1a1\uc7a5\ubc88\ud638\ub97c \uc785\ub825\ud558\uc2e4\uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ORDER_0005=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucd9c\uace0\uc644\ub8cc]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad6c\ub9e4\ud655\uc815 \uc0c1\ud0dc\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ORDER_0006=\uad6c\ub9e4\ud655\uc815\uc744 \ud558\uc2e4\uc218 \uc788\ub294 \uc0c1\ud488\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. \n\ubc18\ud488\uc774\ub098 \uad50\ud658\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
-ORDER_0007=\uc8fc\ubb38 \uc804\uccb4\ucde8\uc18c\ub97c \ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uad50\ud658,\ubc18\ud488,\ucde8\uc18c\uc911\uc778 \uc0c1\ud488\uc774 \uc788\ub294\uc9c0 \ud655\uc778 \ubc14\ub78d\ub2c8\ub2e4.
-ORDER_0008=\ud0c0 \uc5c5\uccb4\uc758 \uc0c1\ud488\uc774 \uc788\uc2b5\ub2c8\ub2e4. \uc804\uccb4 \ubc18\ud488\uc744 \uc9c4\ud589\ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
-ORDER_0009=\ud3ec\uc778\ud2b8 \uc6d0\ubcf5 \ucc98\ub9ac\ub97c \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.
-ORDER_0010=\uacb0\uc81c \ucde8\uc18c\ub97c \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4.
-ORDER_0011=\uce74\ub4dc \uacb0\uc81c\uc778 \uacbd\uc6b0\uc5d0\ub9cc \ubd80\ubd84\ucde8\uc18c\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0012=\ucde8\uc18c\uc218\ub7c9\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694. \ucde8\uc18c\uac00\ub2a5 \uc218\ub7c9\ubcf4\ub2e4 \ub9ce\uc2b5\ub2c8\ub2e4.
-ORDER_0013=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uacb0\uc81c\uc644\ub8cc][\uc0c1\ud488\uc900\ube44\uc911]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubd80\ubd84\ucde8\uc18c\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0014=\ucd9c\uace0\uc644\ub8cc\ub97c \ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uc8fc\ubb38 \ucde8\uc18c\uc2e0\uccad\ub41c \uc8fc\ubb38\uc744 \uba3c\uc800 \ucc98\ub9ac\ud574\uc8fc\uc2dc\uae30\ubc14\ub78d\ub2c8\ub2e4.
-ORDER_0015=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucd9c\uace0\uc644\ub8cc]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uc8fc\ubb38\uad50\ud658\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0016=\uad50\ud658\uc218\ub7c9\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694.\uad50\ud658\uac00\ub2a5 \uc218\ub7c9\ubcf4\ub2e4 \ub9ce\uc2b5\ub2c8\ub2e4.
-ORDER_0017=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uad50\ud658\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad50\ud658\uc9c4\ud589\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0018=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uad50\ud658\uc9c4\ud589]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad50\ud658\uc644\ub8cc\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0019=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uad50\ud658\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad50\ud658\ubc18\ub824\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0020=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ubc18\ud488\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubc18\ud488\uc9c4\ud589\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0021=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ubc18\ud488\uc9c4\ud589]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubc18\ud488\uc644\ub8cc\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0022=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ubc18\ud488\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubc18\ud488\ubc18\ub824\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0023=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucde8\uc18c\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ucde8\uc18c\ubc18\ub824\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0024=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucde8\uc18c\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ucde8\uc18c\uc644\ub8cc\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
-ORDER_0025=\ubc18\ud488\uc218\ub7c9\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694. \ubc18\ud488\uac00\ub2a5 \uc218\ub7c9\ubcf4\ub2e4 \ub9ce\uc2b5\ub2c8\ub2e4.
-ORDER_0026=\uc8fc\ubb38 \uc804\uccb4\ubc18\ud488\uc744 \ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uad50\ud658,\ubc18\ud488,\ucde8\uc18c\uc911\uc778 \uc0c1\ud488\uc774 \uc788\ub294\uc9c0 \ud655\uc778 \ubc14\ub78d\ub2c8\ub2e4.
-ORDER_0027=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uc0c1\ud488\uc900\ube44\uc911] \uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uacb0\uc81c\uc644\ub8cc \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ORDER_0028=\uacb0\uc81c \uc644\ub8cc \uc0c1\ud0dc\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\ucde8\uc18c,\ubc18\ud488\uc774 \uc644\ub8cc\ub41c \uc8fc\ubb38\uc785\ub2c8\ub2e4.
-ORDER_0029=\uc8fc\ubb38 \uc0c1\ud0dc\ub97c \ud655\uc778\ud574 \uc8fc\uc138\uc694. [\ucd9c\uace0\uc911][\uad6c\ub9e4\ud655\uc815]\uc0c1\ud0dc\uc778 \uc8fc\ubb38\uac74\uc774 \uc788\uc2b5\ub2c8\ub2e4.
-ORDER_0030=\ud544\uc218\uac12\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
-ORDER_0031=\uc8fc\ubb38\uc804\uccb4\ucde8\uc18c \ucc98\ub9ac\uac00 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-
-#\uc0ac\ubc29\ub137
-SABANGNET_0001=\uc131\uacf5\uc801\uc73c\ub85c \uc0c1\ud488 \uc815\ubcf4\uac00 \uc804\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5)
-SABANGNET_0002=\uc131\uacf5\uc801\uc73c\ub85c \uc1fc\ud551\ubab0\ubcc4 DATA \uac00 \uc804\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5)
-SABANGNET_0003=\uc131\uacf5\uc801\uc73c\ub85c \uc0c1\ud488 \uc694\uc57d \uc815\ubcf4\uac00 \uc804\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5)
-SABANGNET_0004=\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5, \uc2e4\ud328: {2}\uac74)
-SABANGNET_0005=\uc131\uacf5\uc801\uc73c\ub85c \uc1a1\uc7a5\ubc88\ud638\uac00 \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-SABANGNET_0006=\ucde8\uc18c\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc2e4\ud328 {2}\uac74 \uc131\uacf5)
-SABANGNET_0007=\uad50\ud658\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc2e4\ud328 {2}\uac74 \uc131\uacf5)
-SABANGNET_0008=\ubc18\ud488\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc2e4\ud328 {2}\uac74 \uc131\uacf5)
-SABANGNET_0009=\uc720\ud6a8\uc131 \uac80\uc99d \uc2e4\ud328\ub85c \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
-SABANGNET_0010=\ucd9c\uace0\ub97c \uc704\ud574 ERP\ub85c \uc804\uc1a1\ud558\uc600\uc2b5\ub2c8\ub2e4.(\uc131\uacf5: {0}\uac74, \uc2e4\ud328: {1}\uac74)
-
-#\ubc30\uc1a1
-DELIVERY_0001=\ub4f1\ub85d \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4. \uc774\ubbf8 \ub4f1\ub85d\ub41c \ucd9c\uace0\uae08\uc9c0 \uc0c1\ud488\uc774 \uc788\uc2b5\ub2c8\ub2e4.
+## -----------------------------------------------------------------------------
+## Message properties
+## -----------------------------------------------------------------------------
+SUCC_0001=\uc131\uacf5\uc801\uc73c\ub85c \uc800\uc7a5\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0002=\uc131\uacf5\uc801\uc73c\ub85c \uc218\uc815\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0003=\uc131\uacf5\uc801\uc73c\ub85c \uc0ad\uc81c\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0004=\uc131\uacf5\uc801\uc73c\ub85c \ucc98\ub9ac\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0005=\uc131\uacf5\uc801\uc73c\ub85c \ubc1c\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0006=\uc131\uacf5\uc801\uc73c\ub85c \ubc1c\ud589\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0007=\uc131\uacf5\uc801\uc73c\ub85c \uc5c5\ub85c\ub4dc \ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+#SUCC_0008=\uc131\uacf5\uc801\uc73c\ub85c \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0009=\uc131\uacf5\uc801\uc73c\ub85c \ubcc0\uacbd\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SUCC_0010=\uc131\uacf5\uc801\uc73c\ub85c \uac31\uc2e0\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+
+FAIL_0001=\uc624\ub958\ub85c \uc778\ud574 \uc800\uc7a5\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_0002=\uc624\ub958\ub85c \uc778\ud574 \uc218\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_0003=\uc624\ub958\ub85c \uc778\ud574 \uc0ad\uc81c\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_0004=\uc624\ub958\ub85c \uc778\ud574 \ucc98\ub9ac\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_0005=\uc624\ub958\ub85c \uc778\ud574 \ubc1c\uc1a1\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_0006=\uc624\ub958\ub85c \uc778\ud574 \ubc1c\ud589\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_0007=\uc624\ub958\ub85c \uc778\ud574 \uc5c5\ub85c\ub4dc \ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+#FAIL_0008=\uc624\ub958\ub85c \uc778\ud574 \ub4f1\ub85d\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_0009=\uc624\ub958\ub85c \uc778\ud574 \ubcc0\uacbd\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+FAIL_1001=\uc800\uc7a5\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
+FAIL_1002=\uc804\uc1a1\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
+FAIL_1003=\uc5d1\uc140\ub2e4\uc6b4\ub85c\ub4dc\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
+FAIL_1004=\uc0ad\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
+
+LOGN_0001=\uc785\ub825\ud558\uc2e0 \uc815\ubcf4\ub85c \uac00\uc785\ub41c \ub0b4\uc5ed\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
+LOGN_0002=\ube44\ubc00\ubc88\ud638\uac00 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+LOGN_0003=\ub85c\uadf8\uc778 \uc0c1\ud0dc\uac00 \uc544\ub2d9\ub2c8\ub2e4. \ub2e4\uc2dc \ub85c\uadf8\uc778 \ud574\uc8fc\uc138\uc694.
+LOGN_0004=\ube44\ubc00\ubc88\ud638\ub97c \ubcc0\uacbd\ud55c \ub0a0\ub85c\ubd80\ud130 3\uac1c\uc6d4\uc774 \uacbd\uacfc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+
+##\uc8fc\ubb38
+ORDER_0001=\uc8fc\ubb38\uc815\ubcf4\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
+ORDER_0002=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uacb0\uc81c\uc644\ub8cc][\ucd9c\uace0\uc644\ub8cc] \uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uc0c1\ud488\uc900\ube44\uc911\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+ORDER_0003=\ud574\ub2f9 \uc0c1\ud488 \ube0c\ub79c\ub4dc \uc218\uc815 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
+ORDER_0004=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uc0c1\ud488\uc900\ube44\uc911][\uad6c\ub9e4\ud655\uc815] \uc0c1\ud0dc\uc5d0\ub9cc \uc1a1\uc7a5\ubc88\ud638\ub97c \uc785\ub825\ud558\uc2e4\uc218 \uc788\uc2b5\ub2c8\ub2e4.
+ORDER_0005=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucd9c\uace0\uc644\ub8cc]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad6c\ub9e4\ud655\uc815 \uc0c1\ud0dc\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+ORDER_0006=\uad6c\ub9e4\ud655\uc815\uc744 \ud558\uc2e4\uc218 \uc788\ub294 \uc0c1\ud488\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. \n\ubc18\ud488\uc774\ub098 \uad50\ud658\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+ORDER_0007=\uc8fc\ubb38 \uc804\uccb4\ucde8\uc18c\ub97c \ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uad50\ud658,\ubc18\ud488,\ucde8\uc18c\uc911\uc778 \uc0c1\ud488\uc774 \uc788\ub294\uc9c0 \ud655\uc778 \ubc14\ub78d\ub2c8\ub2e4.
+ORDER_0008=\ud0c0 \uc5c5\uccb4\uc758 \uc0c1\ud488\uc774 \uc788\uc2b5\ub2c8\ub2e4. \uc804\uccb4 \ubc18\ud488\uc744 \uc9c4\ud589\ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+ORDER_0009=\ud3ec\uc778\ud2b8 \uc6d0\ubcf5 \ucc98\ub9ac\ub97c \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.
+ORDER_0010=\uacb0\uc81c \ucde8\uc18c\ub97c \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4.
+ORDER_0011=\uce74\ub4dc \uacb0\uc81c\uc778 \uacbd\uc6b0\uc5d0\ub9cc \ubd80\ubd84\ucde8\uc18c\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0012=\ucde8\uc18c\uc218\ub7c9\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694. \ucde8\uc18c\uac00\ub2a5 \uc218\ub7c9\ubcf4\ub2e4 \ub9ce\uc2b5\ub2c8\ub2e4.
+ORDER_0013=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uacb0\uc81c\uc644\ub8cc][\uc0c1\ud488\uc900\ube44\uc911]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubd80\ubd84\ucde8\uc18c\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0014=\ucd9c\uace0\uc644\ub8cc\ub97c \ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uc8fc\ubb38 \ucde8\uc18c\uc2e0\uccad\ub41c \uc8fc\ubb38\uc744 \uba3c\uc800 \ucc98\ub9ac\ud574\uc8fc\uc2dc\uae30\ubc14\ub78d\ub2c8\ub2e4.
+ORDER_0015=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucd9c\uace0\uc644\ub8cc]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uc8fc\ubb38\uad50\ud658\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0016=\uad50\ud658\uc218\ub7c9\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694.\uad50\ud658\uac00\ub2a5 \uc218\ub7c9\ubcf4\ub2e4 \ub9ce\uc2b5\ub2c8\ub2e4.
+ORDER_0017=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uad50\ud658\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad50\ud658\uc9c4\ud589\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0018=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uad50\ud658\uc9c4\ud589]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad50\ud658\uc644\ub8cc\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0019=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uad50\ud658\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uad50\ud658\ubc18\ub824\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0020=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ubc18\ud488\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubc18\ud488\uc9c4\ud589\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0021=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ubc18\ud488\uc9c4\ud589]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubc18\ud488\uc644\ub8cc\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0022=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ubc18\ud488\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ubc18\ud488\ubc18\ub824\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0023=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucde8\uc18c\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ucde8\uc18c\ubc18\ub824\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0024=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\ucde8\uc18c\uc2e0\uccad]\uc0c1\ud0dc\uc5d0\uc11c\ub9cc \ucde8\uc18c\uc644\ub8cc\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+ORDER_0025=\ubc18\ud488\uc218\ub7c9\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694. \ubc18\ud488\uac00\ub2a5 \uc218\ub7c9\ubcf4\ub2e4 \ub9ce\uc2b5\ub2c8\ub2e4.
+ORDER_0026=\uc8fc\ubb38 \uc804\uccb4\ubc18\ud488\uc744 \ud558\uc2e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uad50\ud658,\ubc18\ud488,\ucde8\uc18c\uc911\uc778 \uc0c1\ud488\uc774 \uc788\ub294\uc9c0 \ud655\uc778 \ubc14\ub78d\ub2c8\ub2e4.
+ORDER_0027=\uc8fc\ubb38\uc0c1\ud0dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.\n[\uc0c1\ud488\uc900\ube44\uc911] \uc0c1\ud0dc\uc5d0\uc11c\ub9cc \uacb0\uc81c\uc644\ub8cc \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+ORDER_0028=\uacb0\uc81c \uc644\ub8cc \uc0c1\ud0dc\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\ucde8\uc18c,\ubc18\ud488\uc774 \uc644\ub8cc\ub41c \uc8fc\ubb38\uc785\ub2c8\ub2e4.
+ORDER_0029=\uc8fc\ubb38 \uc0c1\ud0dc\ub97c \ud655\uc778\ud574 \uc8fc\uc138\uc694. [\ucd9c\uace0\uc911][\uad6c\ub9e4\ud655\uc815]\uc0c1\ud0dc\uc778 \uc8fc\ubb38\uac74\uc774 \uc788\uc2b5\ub2c8\ub2e4.
+ORDER_0030=\ud544\uc218\uac12\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
+ORDER_0031=\uc8fc\ubb38\uc804\uccb4\ucde8\uc18c \ucc98\ub9ac\uac00 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+
+#\uc0ac\ubc29\ub137
+SABANGNET_0001=\uc131\uacf5\uc801\uc73c\ub85c \uc0c1\ud488 \uc815\ubcf4\uac00 \uc804\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5)
+SABANGNET_0002=\uc131\uacf5\uc801\uc73c\ub85c \uc1fc\ud551\ubab0\ubcc4 DATA \uac00 \uc804\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5)
+SABANGNET_0003=\uc131\uacf5\uc801\uc73c\ub85c \uc0c1\ud488 \uc694\uc57d \uc815\ubcf4\uac00 \uc804\uc1a1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5)
+SABANGNET_0004=\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc131\uacf5, \uc2e4\ud328: {2}\uac74)
+SABANGNET_0005=\uc131\uacf5\uc801\uc73c\ub85c \uc1a1\uc7a5\ubc88\ud638\uac00 \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SABANGNET_0006=\ucde8\uc18c\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc2e4\ud328 {2}\uac74 \uc131\uacf5)
+SABANGNET_0007=\uad50\ud658\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc2e4\ud328 {2}\uac74 \uc131\uacf5)
+SABANGNET_0008=\ubc18\ud488\uc8fc\ubb38\uc774 \uc218\uc9d1\ub418\uc5c8\uc2b5\ub2c8\ub2e4.(\ucd1d {0}\uac74 \uc911 {1}\uac74 \uc2e4\ud328 {2}\uac74 \uc131\uacf5)
+SABANGNET_0009=\uc720\ud6a8\uc131 \uac80\uc99d \uc2e4\ud328\ub85c \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+SABANGNET_0010=\ucd9c\uace0\ub97c \uc704\ud574 ERP\ub85c \uc804\uc1a1\ud558\uc600\uc2b5\ub2c8\ub2e4.(\uc131\uacf5: {0}\uac74, \uc2e4\ud328: {1}\uac74)
+
+#\ubc30\uc1a1
+DELIVERY_0001=\ub4f1\ub85d \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4. \uc774\ubbf8 \ub4f1\ub85d\ub41c \ucd9c\uace0\uae08\uc9c0 \uc0c1\ud488\uc774 \uc788\uc2b5\ub2c8\ub2e4.

+ 126 - 15
style24.admin/src/main/webapp/WEB-INF/views/board/NoticeForm.html

@@ -114,7 +114,7 @@
 						<th>사용여부</th>
 						<td>
 							<input type="hidden" name="useYn"/>
-							<label class="chkBox"><input type="checkbox" name="chkUseYn" checked="checked" value="Y"/>사용</label>
+							<label class="chkBox checked"><input type="checkbox" name="chkUseYn" value="Y" checked="checked"/>사용</label>
 						</td>
 					</tr>
 					<tr id="trNew">
@@ -151,6 +151,19 @@
 							</label>
 						</td>
 					</tr>
+					<tr th:style="${noticeType == 'G047_10' ? 'display: none;' : ''}">
+						<th>팝업여부</th>
+						<td>
+							<input type="hidden" name="popupYn"/>
+							<label class="chkBox"><input type="checkbox" name="chkPopupYn" value="Y"/>팝업</label>
+						</td>
+						<th>팝업노출기간</th>
+						<td colspan="5">
+							<input type="text" class="schDate w100" name="popupDispStdt" maxlength="10"/>
+							~
+							<input type="text" class="schDate w100" name="popupDispEddt" maxlength="10"/>
+						</td>
+					</tr>
 					<tr>
 						<th>제목<i class="required" title="필수"></i></th>
 						<td colspan="5">
@@ -209,10 +222,10 @@
 	// 공지사항유형(10:사이트공지, 20:내부공지)
 	let noticeType = [[${noticeType}]];
 
-	let columnDefs = [
+	let columnDefs1 = [
 		{headerName: "공지번호", field: "noticeSq", width: 90, cellClass: 'text-center'},
 		{
-			headerName: "긴급공지", field: "urgentYn", width:90, cellClass: 'text-center',
+			headerName: "긴급공지", field: "urgentYn", width: 90, cellClass: 'text-center',
 			cellRenderer: function(params) { return params.value == 'Y' ? '긴급' : '일반'; }
 		},
 // 		{headerName: "사이트", field: "siteNm", width: 200, cellClass: 'text-center'},
@@ -226,24 +239,75 @@
 		},
 		{headerName: "공지내용", field: "noticeContent", width: 500, hide: true },
 		{
-			headerName: "공지시작일", field: "noticeStdt", width:120, cellClass: 'text-center',
+			headerName: "공지시작일", field: "noticeStdt", width: 120, cellClass: 'text-center',
 			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
 		},
 		{
-			headerName: "공지종료일", field: "noticeEddt", width:120, cellClass: 'text-center',
+			headerName: "공지종료일", field: "noticeEddt", width: 120, cellClass: 'text-center',
 			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
 		},
 		{headerName: "조회수", field: "readCnt", width:90, cellClass: 'text-center'},
-		{headerName: "사용여부", field: "useYn", width:90, cellClass: 'text-center'},
-		{headerName: "등록자", field: "regNm", width:90, cellClass: 'text-center'},
+		{headerName: "사용여부", field: "useYn", width: 90, cellClass: 'text-center'},
+		{headerName: "등록자", field: "regNm", width: 90, cellClass: 'text-center'},
 		{
-			headerName: "등록일자", field: "regDt", width:120, cellClass: 'text-center',
+			headerName: "등록일자", field: "regDt", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
+		}
+	];
+	
+	let columnDefs2 = [
+		{headerName: "공지번호", field: "noticeSq", width: 90, cellClass: 'text-center'},
+		{
+			headerName: "긴급공지", field: "urgentYn", width: 90, cellClass: 'text-center',
+			cellRenderer: function(params) { return params.value == 'Y' ? '긴급' : '일반'; }
+		},
+// 		{headerName: "사이트", field: "siteNm", width: 200, cellClass: 'text-center'},
+		{
+			headerName: "공지제목", field: "noticeTitle", width: 500,
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{
+			headerName: "파일", field: "fileCnt", width: 50, cellClass: 'text-center',
+			cellRenderer: function(params) { return params.value > 0 ? '<i class="fa fa-folder fa-lg"></i>' : ''; }
+		},
+		{headerName: "공지내용", field: "noticeContent", width: 500, hide: true },
+		{
+			headerName: "공지시작일", field: "noticeStdt", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
+		},
+		{
+			headerName: "공지종료일", field: "noticeEddt", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
+		},
+		{headerName: "조회수", field: "readCnt", width:90, cellClass: 'text-center'},
+		{headerName: "팝업여부", field: "popupYn", width: 90, cellClass: 'text-center'},
+		{
+			headerName: "팝업노출시작일", field: "popupDispStdt", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return params.value == '00000000' ? '' : gagaAgGrid.toDateFormat(params.value);
+			}
+		},
+		{
+			headerName: "팝업노출종료일", field: "popupDispEddt", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return params.value == '00000000' ? '' : gagaAgGrid.toDateFormat(params.value);
+			}
+		},
+		{headerName: "사용여부", field: "useYn", width: 90, cellClass: 'text-center'},
+		{headerName: "등록자", field: "regNm", width: 90, cellClass: 'text-center'},
+		{
+			headerName: "등록일자", field: "regDt", width: 120, cellClass: 'text-center',
 			cellRenderer: function(params) { return gagaAgGrid.toDateFormat(params.value); }
 		}
 	];
 
-	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
-
+	let gridOptions;
+	if (noticeType == 'G047_10') { // 사이트공지
+		gridOptions = gagaAgGrid.getGridOptions(columnDefs1);
+	} else if (noticeType == 'G047_20') { // 내부공지
+		gridOptions = gagaAgGrid.getGridOptions(columnDefs2);
+	}
+	
 	// Cell click
 	gridOptions.onCellClicked = function(event) {
 		if (event.colDef.field != 'noticeTitle')
@@ -275,6 +339,18 @@
 		$('#detailForm input[name=regNm]').val(event.data.regNm);
 		$('#detailForm input[name=regDt]').val(event.data.regDt.toDate("YYYYMMDD").format("YYYY-MM-DD"));
 		$('#detailForm input[name=noticeTitle]').val(event.data.noticeTitle);
+		
+		if (noticeType == 'G047_20') { // 내부공지
+			if (event.data.popupYn == 'Y') {
+				$('#detailForm input:checkbox[name=chkPopupYn]').prop('checked', true);
+				$("#detailForm input:checkbox[name=chkPopupYn]").parent().addClass('checked');
+			} else {
+				$('#detailForm input:checkbox[name=chkPopupYn]').prop('checked', false);
+				$("#detailForm input:checkbox[name=chkPopupYn]").parent().removeClass('checked');
+			}
+			$('#detailForm input[name=popupDispStdt]').val(event.data.popupDispStdt == '00000000' ? '' : event.data.popupDispStdt.toDate("YYYYMMDD").format("YYYY-MM-DD"));
+			$('#detailForm input[name=popupDispEddt]').val(event.data.popupDispEddt == '00000000' ? '' : event.data.popupDispEddt.toDate("YYYYMMDD").format("YYYY-MM-DD"));
+		}
 
 		// 공지내용. Summernote에 값 세팅
 		gagaSn.setContents('#noticeContent', event.data.noticeContent);
@@ -294,9 +370,6 @@
 	// 수신자 목록 조회
 	var fnGetNoticeReceiverList = function(noticeSq) {
 		let actionUrl = '/board/notice/receiver/list/' + noticeSq;
-		if (noticeType == 'G047_20') {
-			actionUrl = '/renderer/avail/commonCode/list/G048'; // 부서
-		}
 		
 		$.getJSON(actionUrl
 			, function(result) {
@@ -315,7 +388,7 @@
 							var data = result[j].receiverId;
 							if ($('#detailForm input:checkbox[name=receiverIds]').eq(i).val() == data) {
 								$('#detailForm input:checkbox[name=receiverIds]').eq(i).prop('checked', true);
-								$("#detailForm input:checkbox[name=receiverIds]").parent().addClass('checked');
+								$("#detailForm input:checkbox[name=receiverIds]").eq(i).parent().addClass('checked');
 							}
 						}
 					}
@@ -479,6 +552,38 @@
 			return;
 		}
 
+		if (noticeType == 'G047_20') { // 내부공지
+			if ($('#detailForm input:checkbox[name=chkPopupYn]').is(":checked")) {
+				if (gagajf.isNull($('#detailForm input[name=popupDispStdt]').val())) {
+					mcxDialog.alertC('팝업노출시작일자를 입력해 주세요.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							$('#detailForm input[name=popupDispStdt]').focus();
+						}
+					});
+					return;
+				}
+
+				if (gagajf.isNull($('#detailForm input[name=popupDispEddt]').val())) {
+					mcxDialog.alertC('팝업노출종료일자를 입력해 주세요.', {
+						sureBtnText: "확인",
+						sureBtnClick: function() {
+							$('#detailForm input[name=popupDispEddt]').focus();
+						}
+					});
+					return;
+				}
+
+				var stDate = $('#detailForm input[name=popupDispStdt]').val().toDate('YYYY-MM-DD');
+				var edDate = $('#detailForm input[name=popupDispEddt]').val().toDate('YYYY-MM-DD');
+
+				if (stDate > edDate) {
+					mcxDialog.alert("팝업노출기간 종료일자는 시작일자 보다 클 수 없습니다.");
+					return;
+				}
+			}
+		}
+		
 		// 수신자 선택
 		if ($('#detailForm input:checkbox[name=receiverIds]').is(":checked") != true) {
 			if (noticeType == 'G047_10') { // 사이트공지
@@ -494,8 +599,14 @@
 		if (!gagajf.validation('#detailForm'))
 			return false;
 
+		if (gagajf.isNull($('#detailForm textarea[name=noticeContent]').val())) {
+			mcxDialog.alert('공지내용을 입력해 주세요.');
+			return;
+		}
+		
 		$('#detailForm input[name=useYn]').val($('#detailForm input:checkbox[name=chkUseYn]').is(":checked") ? 'Y' : 'N');
-
+		$('#detailForm input[name=popupYn]').val($('#detailForm input:checkbox[name=chkPopupYn]').is(":checked") ? 'Y' : 'N');
+		
 		mcxDialog.confirm('저장하시겠습니까?', {
 			cancelBtnText: "취소",
 			sureBtnText: "확인",

+ 19 - 21
style24.admin/src/main/webapp/WEB-INF/views/customer/GoodsQnaDetailForm.html

@@ -14,12 +14,12 @@
  * 1.0  2020.12.25   gagamel     최초 작성
  *******************************************************************************
  -->
-<div class="modalPopup" data-width="1200" id="popupQna">
+<div class="modalPopup" data-width="1200" id="popupGoodsQnaDetail">
 	<div class="panelStyle">
 		<!-- TITLE -->
 		<div class="panelTitle">
 			<strong>상품문의 상세</strong>
-			<button type="button" class="close" onclick="uifnPopupClose('popupQna');"><em class="fa fa-times"></em></button>
+			<button type="button" class="close" onclick="uifnPopupClose('popupGoodsQnaDetail');"><em class="fa fa-times"></em></button>
 		</div>
 		<!-- //TITLE -->
 		
@@ -79,7 +79,9 @@
 							<th>상품코드</th>
 							<td colspan="3" th:text="*{relGoodsCd}"></td>
 							<th rowspan="3">상품이미지</th>
-							<td rowspan="3" class="userImg" id="onetooneImg"></td>
+							<td rowspan="3" class="userImg">
+								<img style="height: 100px;" th:src="${@environment.getProperty('upload.goods.view') + '/' + counselInfo.goodsImg}" alt="" onerror='this.src="/image/no.gif"'/>
+							</td>
 						</tr>
 						<tr>
 							<th>상품명</th>
@@ -100,6 +102,17 @@
 					</tbody>
 				</table>
 				
+				<!-- 아직 업체에게 의뢰를 하지 않은 답변대기중인 입점상품이면서 권한이 "SUPER관리자, 어드민관리자, CS관리자, CS상담사"일 때 -->
+				<ul class="panelBar" th:if="${counselInfo.selfGoodsYn == 'N' && counselInfo.ansTransYn == 'N' && counselInfo.ansStat == 'G060_10' && (sessionInfo.roleCd == 'G001_0000' || sessionInfo.roleCd == 'G001_A000' || sessionInfo.roleCd == 'G001_A3000' || sessionInfo.roleCd == 'G001_A301')}">
+					<li class="right">
+						<select name="ansCompCd" id="ansCompCd">
+							<option value="">[답변의뢰업체]</option>
+							<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}"></option>
+						</select>
+						<button type="button" class="btn btn-danger btn-lg" id="btnTransferAnswer">답변의뢰</button>
+					</li>
+				</ul>
+				
 				<h4>답변등록</h4>
 				<table class="frmStyle" aria-describedby="답변등록">
 					<colgroup>
@@ -141,14 +154,6 @@
 		<!-- 버튼 배치 영역 -->
 		<ul class="panelBar">
 			<li class="right">
-				<!-- 아직 업체에게 의뢰를 하지 않은 답변대기중인 입점상품이면서 권한이 "SUPER관리자, 어드민관리자, CS관리자, CS상담사"일 때 -->
-				<span th:if="${counselInfo.selfGoodsYn == 'N' && counselInfo.ansTransYn == 'N' && counselInfo.ansStat == 'G060_10' && (sessionInfo.roleCd == 'G001_0000' || sessionInfo.roleCd == 'G001_A000' || sessionInfo.roleCd == 'G001_A3000' || sessionInfo.roleCd == 'G001_A301')}">
-					<select name="ansCompCd" id="ansCompCd">
-						<option value="">[답변의뢰업체]</option>
-						<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${oneData.cdNm}"></option>
-					</select>
-					<button type="button" class="btn btn-danger btn-lg" id="btnTransferAnswer">답변의뢰</button>
-				</span>
 				<button type="button" class="btn btn-info btn-lg" id="btnSaveAnswer" th:if="${counselInfo.ansStat == 'G060_10'}">답변저장</button>
 			</li>
 		</ul>
@@ -180,8 +185,8 @@
 
 				var jsonData = JSON.stringify(params);
 
-				gagajf.ajaxJsonSubmit('/customer/goods/answer/transfer/save', jsonData, function() {
-					uifnPopupClose('popupQna');
+				gagajf.ajaxJsonSubmit('/customer/goods/qna/answer/transfer/save', jsonData, function() {
+					uifnPopupClose('popupGoodsQnaDetail');
 					$('#btnSearch').trigger('click');
 				});
 			}
@@ -199,7 +204,7 @@
 			sureBtnText: "확인",
 			sureBtnClick: function() {
 				gagajf.ajaxFormSubmit($('#qnaDetailForm').prop('action'), '#qnaDetailForm', function() {
-					uifnPopupClose('popupQna');
+					uifnPopupClose('popupGoodsQnaDetail');
 					$('#btnSearch').trigger('click');
 				});
 			}
@@ -229,13 +234,6 @@
 	});
 	
 	$(document).ready(function() {
-// 		var counsel = [[${counsel}]];
-
-// 		if (!gagajf.isNull(counselInfo.sysFileNm)) {
-// 			var imgTag = '<img style="height: 100px;" onclick="cfnOpenImagePreViewPopup(\'goodsImgView\', \'' + _imgUrl + '/counsel/' + counselInfo.sysFileNm + '\')" src="' + _imgUrl + '/counsel/' + counselInfo.sysFileNm + '">';
-// 			$('#onetooneImg').append(imgTag);
-// 		}
-
 		cfnGetTextLength($('textarea[name=ansContent]'), 4000, $('#dpLocAnsContent'));
 	});
 /*]]>*/

+ 17 - 6
style24.admin/src/main/webapp/WEB-INF/views/customer/GoodsQnaForm.html

@@ -101,7 +101,7 @@
 		
 		<!-- 리스트 영역 -->
 		<div class="panelStyle">
-			<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
+			<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham lh60"></div>
 		</div>
 		<!-- //리스트 영역 -->
 	</div>
@@ -126,6 +126,12 @@
 			headerName: "문의일시", field: "questDt", width: 150, cellClass: 'text-center',
 			cellRenderer: function (params) { return gagaAgGrid.toDateTimeFormat(params.value); }
 		},
+		{
+			headerName: "이미지", field: "goodsImg", width: 100, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return '<img width="60" src="' + _goodsUrl +  "/" + params.value + '" alt="" onerror="this.src=\'/image/no.gif\';"/>';
+			}
+		},
 		{
 			headerName: "상품코드", field: "relGoodsCd", width: 100, cellClass: 'text-center',
 			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
@@ -136,12 +142,12 @@
 			cellRenderer: function(params) { return params.value == 'Y' ? 'Yes' : 'No'; }
 		},
 		{headerName: "고객번호", field: "custNo", width: 100, cellClass: 'text-center', hide: true},
-		{headerName: "고객ID", field: "custId", width: 100, cellClass: 'text-center', hide: true},
+		{headerName: "고객ID", field: "maskingCustId", width: 100, cellClass: 'text-center', hide: true},
 		{
-			headerName: "고객명", field: "custNm", width: 150, cellClass: 'text-center',
-			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '(' + params.data.custId + ')</a>'; }
+			headerName: "고객명", field: "maskingCustNm", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) { return '<a href="javascript:void(0);">' + params.value + '(' + params.data.maskingCustId + ')</a>'; }
 		},
-		{headerName: "휴대전화번호", field: "cellPhnno", width: 120, cellClass: 'text-center'},
+		{headerName: "휴대전화번호", field: "maskingCellPhnno", width: 120, cellClass: 'text-center'},
 		{
 			headerName: "SMS답변요청", field: "smsReqYn", width: 120, cellClass: 'text-center',
 			cellRenderer: function(params) { return params.value == 'Y' ? 'Yes' : 'No'; }
@@ -150,7 +156,7 @@
 			headerName: "SMS답변발송", field: "smsSendYn", width: 120, cellClass: 'text-center',
 			cellRenderer: function(params) { return params.value == 'Y' ? 'Yes' : 'No'; }
 		},
-		{headerName: "이메일", field: "email", width: 200},
+		{headerName: "이메일", field: "maskingEmail", width: 200},
 // 		{
 // 			headerName: "이메일답변요청", field: "emailReqYn", width: 120, cellClass: 'text-center',
 // 			cellRenderer: function(params) { return params.value == 'Y' ? 'Yes' : 'No'; }
@@ -184,6 +190,9 @@
 	// Get GridOptions
 	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
 	
+	// 이미지가 있을 경우 높이 지정
+	gridOptions.rowHeight = 60;
+	
 	// 셀 클릭 이벤트
 	gridOptions.onCellClicked = function(event) {
 		if (event.colDef.field == 'counselSq') {
@@ -192,6 +201,8 @@
 		} else if (event.colDef.field == 'custNm') {
 			// 고객 상세
 			cfnOpenCustDetailPopup(event.data.custNo);
+		} else if (event.colDef.field == 'relGoodsCd') {
+			cfnOpenGoodsDetailPopup('U', event.data.relGoodsCd);
 		}
 	}
 	

+ 6 - 11
style24.admin/src/main/webapp/WEB-INF/views/customer/OneToOneQnaDetailForm.html

@@ -14,12 +14,12 @@
  * 1.0  2020.12.24   gagamel     최초 작성
  *******************************************************************************
  -->
-<div class="modalPopup" data-width="1200" id="popupQna">
+<div class="modalPopup" data-width="1200" id="popupOneToOneQnaDetail">
 	<div class="panelStyle">
 		<!-- TITLE -->
 		<div class="panelTitle">
 			<strong>1:1문의 상세</strong>
-			<button type="button" class="close" onclick="uifnPopupClose('popupQna');"><em class="fa fa-times"></em></button>
+			<button type="button" class="close" onclick="uifnPopupClose('popupOneToOneQnaDetail');"><em class="fa fa-times"></em></button>
 		</div>
 		<!-- //TITLE -->
 		
@@ -88,7 +88,9 @@
 								<textarea class="textareaR4" style="resize: none;" name="questContent" th:text="*{questContent}" disabled="disabled"></textarea>
 							</td>
 							<th>첨부 이미지</th>
-							<td class="userImg" id="onetooneImg">
+							<td class="userImg">
+								<img th:if="${counselInfo.sysFileNm1 != null}" style="height: 100px;" th:src="${@environment.getProperty('domain.image') + '/counsel/' + counselInfo.sysFileNm1}" alt="" onerror='this.src="/image/no.gif"'/>
+								<img th:if="${counselInfo.sysFileNm2 != null}" style="height: 100px;" th:src="${@environment.getProperty('domain.image') + '/counsel/' + counselInfo.sysFileNm2}" alt="" onerror='this.src="/image/no.gif"'/>
 							</td>
 						</tr>
 					</tbody>
@@ -155,7 +157,7 @@
 			sureBtnText: "확인",
 			sureBtnClick: function() {
 				gagajf.ajaxFormSubmit($('#qnaDetailForm').prop('action'), '#qnaDetailForm', function() {
-					uifnPopupClose('popupQna');
+					uifnPopupClose('popupOneToOneQnaDetail');
 					$('#btnSearch').trigger('click');
 				});
 			}
@@ -185,13 +187,6 @@
 	});
 	
 	$(document).ready(function() {
-// 		var counsel = [[${counsel}]];
-
-// 		if (!gagajf.isNull(counselInfo.sysFileNm)) {
-// 			var imgTag = '<img style="height: 100px;" onclick="cfnOpenImagePreViewPopup(\'goodsImgView\', \'' + _imgUrl + '/counsel/' + counselInfo.sysFileNm + '\')" src="' + _imgUrl + '/counsel/' + counselInfo.sysFileNm + '">';
-// 			$('#onetooneImg').append(imgTag);
-// 		}
-
 		cfnGetTextLength($('textarea[name=ansContent]'), 4000, $('#dpLocAnsContent'));
 	});
 /*]]>*/

+ 433 - 0
style24.admin/src/main/webapp/WEB-INF/views/display/CategoryForm.html

@@ -0,0 +1,433 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : CategoryForm.html
+ * @desc    : 카테고리관리 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.12.30   gagamel     최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+		
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<form id="searchForm" name="searchForm" action="#" th:action="@{'/display/category/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col width="10%"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>카테고리</th>
+						<td>
+							<input type="hidden" name="selLvl"/>
+							<select name="siteCd">
+<!-- 								<option value="">[사이트]</option> -->
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="cateGb" id="selCate1" onchange="fnChangeSearchCondition($(this).val(), 1);">
+								<option value="">[카테고리구분]</option>
+								<option th:if="${cateGbList}" th:each="oneData, status : ${cateGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="cate1No" id="selCate2" onchange="fnChangeSearchCondition($(this).val(), 2);">
+								<option value="">[카테고리1]</option>
+							</select>
+							<select name="cate2No" id="selCate3" onchange="fnChangeSearchCondition($(this).val(), 3);">
+								<option value="">[카테고리2]</option>
+							</select>
+							<select name="cate3No" id="selCate4" onchange="fnChangeSearchCondition($(this).val(), 4);">
+								<option value="">[카테고리3]</option>
+							</select>
+							<select name="cate4No" id="selCate5" onchange="fnChangeSearchCondition($(this).val(), 5);">
+								<option value="">[카테고리4]</option>
+							</select>
+						</td>
+					</tr>
+				</table>
+			</form>
+		</div>
+		<!-- 검색조건 영역 -->
+
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<div id="gridList" style="width: 100%; height: 470px" class="ag-theme-balham"></div>
+		</div>
+		<!-- //리스트 영역 -->
+		
+		<!-- 등록/수정 -->
+		<div class="panelStyle">
+			<form id="detailForm" name="detailForm" action="#" th:action="@{'/display/category/save'}">
+				<table class="frmStyle" aria-describedby="등록/수정 폼">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:23%;"/>
+						<col style="width:10%;"/>
+						<col style="width:23%;"/>
+						<col style="width:10%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>카테고리번호</th>
+						<td>
+							<input type="text" class="w200" name="cateNo" placeholder="자동생성" readonly="readonly"/>
+						</td>
+						<th>카테고리명<i class="required" title="필수"></i></th>
+						<td class="infoTxt">
+							<input type="text" class="w200" name="cateNm" maxlength="50" required="required" data-valid-name="카테고리명"/>
+						</td>
+						<th>카테고리유형<i class="required" title="필수"></i></th>
+						<td>
+							<select name="cateType" data-valid-name="카테고리유형">
+								<option th:if="${cateTypeList}" th:each="oneData, status : ${cateTypeList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>상위카테고리<i class="required" title="필수"></i></th>
+						<td colspan="5">
+							<input type="hidden" name="selLvl"/>
+							<select name="siteCd" data-valid-name="사이트">
+<!-- 								<option value="">[사이트]</option> -->
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="cateGb" id="cateLvl1" data-valid-name="카테고리구분" onchange="fnChangeUpperCategory($(this).val(), 1);">
+								<option value="">[카테고리구분]</option>
+								<option th:if="${cateGbList}" th:each="oneData, status : ${cateGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<select name="cate1No" id="cateLvl2" data-valid-name="카테고리1" onchange="fnChangeUpperCategory($(this).val(), 2);">
+								<option value="">[카테고리1]</option>
+							</select>
+							<select name="cate2No" id="cateLvl3" data-valid-name="카테고리2" onchange="fnChangeUpperCategory($(this).val(), 3);">
+								<option value="">[카테고리2]</option>
+							</select>
+							<select name="cate3No" id="cateLvl4" data-valid-name="카테고리3" onchange="fnChangeUpperCategory($(this).val(), 4);">
+								<option value="">[카테고리3]</option>
+							</select>
+							<select name="cate4No" id="cateLvl5" data-valid-name="카테고리4" onchange="fnChangeUpperCategory($(this).val(), 5);">
+								<option value="">[카테고리4]</option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>노출순서<i class="required" title="필수"></i></th>
+						<td>
+							<input type="text" class="aR w100" name="dispOrd" maxlength="5" required="required" data-valid-type="integer" data-valid-name="노출순서"/>
+						</td>
+						<th>정상이월구분</th>
+						<td>
+							<select name="formalGb">
+								<option value="">[선택]</option>
+								<option th:if="${formalGbList}" th:each="oneData, status : ${formalGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>컨텐츠위치</th>
+						<td>
+							<select name="contentsLoc">
+								<option value="">[선택]</option>
+								<option th:if="${contentsLocList}" th:each="oneData, status : ${contentsLocList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>노출여부<i class="required" title="필수"></i></th>
+						<td>
+<!-- 							<input type="hidden" name="useYn"/> -->
+<!-- 							<label class="chkBox checked"><input type="checkbox" name="chkUseYn" value="Y" checked="checked"/>사용</label> -->
+							<label class="rdoBtn"><input type="radio" name="dispYn" value="Y" checked="checked">노출</label>
+							<label class="rdoBtn"><input type="radio" name="dispYn" value="N">미노출</label>
+						</td>
+						<th>사용여부<i class="required" title="필수"></i></th>
+						<td colspan="3">
+							<label class="rdoBtn"><input type="radio" name="useYn" value="Y" checked="checked">사용</label>
+							<label class="rdoBtn"><input type="radio" name="useYn" value="N">미사용</label>
+						</td>
+					</tr>
+				</table>
+			</form>
+			
+			<!-- 버튼 배치 영역 -->
+			<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>
+					<button type="button" class="btn btn-base btn-lg" id="btnRefresh4Srch" th:if="${sessionInfo.roleCd == 'G001_0000'}">4SRCH 갱신</button>
+				</li>
+			</ul>
+			<!-- //버튼 배치 영역 -->
+		</div>
+		<!-- 등록/수정 -->
+	</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	let siteList = gagajf.convertToArray([[${siteList}]]);
+	let cateGbList = gagajf.convertToArray([[${cateGbList}]]);
+	let cateTypeList = gagajf.convertToArray([[${cateTypeList}]]);
+	let formalGbList = gagajf.convertToArray([[${formalGbList}]]);
+	let conentsLocList = gagajf.convertToArray([[${conentsLocList}]]);
+
+	let columnDefs = [
+		{
+			headerName: "사이트", field: "siteCd", width: 150, cellClass: 'text-center',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(siteList, params.value); }
+		},
+		{
+			headerName: "카테고리구분", field: "cateGb", width: 150, cellClass: 'text-center',
+			cellRenderer: function (params) { return gagaAgGrid.lookupValue(cateGbList, params.value); }
+		},
+		{headerName: "카테고리번호", field: "cateNo", width: 150, cellClass: 'text-center'},
+		{
+			headerName: "카테고리명", field: "cateNm", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}
+		},
+		{
+			headerName: "카테고리유형", field: "cateType", width: 150, cellClass: 'text-center',
+			cellRenderer: function (params) { return gagaAgGrid.lookupValue(cateTypeList, params.value); }
+		},
+		{headerName: "말단여부", field: "leafYn", width: 80, cellClass: 'text-center'},
+		{headerName: "노출순서", field: "dispOrd", width: 100, cellClass: 'text-center'},
+		{
+			headerName: "정상이월구분", field: "formalGb", width: 150, cellClass: 'text-center',
+			cellRenderer: function (params) { return gagaAgGrid.lookupValue(formalGbList, params.value); }
+		},
+		{
+			headerName: "컨텐츠위치", field: "contentsLoc", width: 200, cellClass: 'text-center',
+			cellRenderer: function (params) { return gagaAgGrid.lookupValue(conentsLocList, params.value); }
+		},
+		{headerName: "노출여부", field: "dispYn", width: 80, cellClass: 'text-center'},
+		{headerName: "사용여부", field: "useYn", width: 80, cellClass: 'text-center'}
+	];
+	
+	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+	
+	// Cell click
+	gridOptions.onCellClicked = function(event) {
+		if (event.colDef.field != 'cateNm')
+			return;
+		
+		$("#btnNew").click();
+		$('#detailForm input[name=siteCd]').val(event.data.siteCd);
+		$('#detailForm input[name=cateNo]').val(event.data.cateNo);
+		$('#detailForm input[name=cateNm]').val(event.data.cateNm);
+		$('#detailForm select[name=cateType]').val(event.data.cateType);
+		
+		// 상위카테고리
+		var selLvl = $("#searchForm input[name=selLvl]").val();
+		for (let i = 1; i <= 5; i++) {
+			$("#cateLvl" + i).html($("#selCate" + i).html());
+			$("#cateLvl" + i).val($("#selCate" + i).val());
+			if (i >= selLvl) {
+				$("#cateLvl" + i).hide();
+			} else {
+				$("#cateLvl" + i).show();
+			}
+		}
+		$('#detailForm input[name=selLvl]').val(selLvl);
+		
+		$('#detailForm input[name=dispOrd]').val(event.data.dispOrd);
+		$('#detailForm select[name=formalGb]').val(event.data.formalGb);
+		$('#detailForm select[name=contentsLoc]').val(event.data.contentsLoc);
+		
+		// 카테고리유형에 따른 컨텐츠위치 설정 변경
+		if (event.data.cateType == 'G031_10') {
+			$('#detailForm select[name=contentsLoc]').prop('disabled', true);
+		} else if (event.data.cateType == 'G031_20') {
+			$('#detailForm select[name=contentsLoc]').prop('disabled', false);
+		}
+		
+		$('#detailForm input:radio[name=dispYn]:input[value=' + event.data.dispYn + ']').click();
+		$('#detailForm input:radio[name=useYn]:input[value=' + event.data.useYn + ']').click();
+	}
+
+	/**
+	 * 검색폼의 카테고리 선택 시
+	 */
+	var fnChangeSearchCondition = function(val, selLvl) {
+		if (gagajf.isNull(val)) {
+			if (selLvl > 1) {
+				selLvl = selLvl - 1;
+			} else {
+				selLvl = 1;
+			}
+		}
+		$('#searchForm input[name=selLvl]').val(selLvl);
+		
+		// Fetch data
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm', function(data) {
+			let selLvl = Number($('#searchForm input[name=selLvl]').val()) + 1;
+			
+			for (let i = 2; i <= 5; i++) {
+				if (i >= selLvl) {
+					$('#selCate' + i).html('<option value="">[카테고리' + (i - 1) + ']</option>');
+				}
+			}
+			
+			let tag = '';
+			for (let i = 0; i < data.length; i++) {
+				if (data[i].useYn == 'Y') {
+					tag += '<option value="' + data[i].cateNo + '">[' + data[i].cateNo + '] ' + data[i].cateNm + '</option>';
+				}
+			}
+			
+			$("#selCate" + selLvl).append(tag);
+			$("#btnNew").click();
+		});
+	}
+	
+	// 카테고리유형 변경 시
+	$('#detailForm select[name=cateType]').on('change', function() {
+		if ($(this).val() == 'G031_10') { // 상품분류카테고리
+			$("#detailForm select[name=contentsLoc]").prop('disabled', true);
+		} else if ($(this).val() == 'G031_20') { // 컨텐츠카테고리
+			$("#detailForm select[name=contentsLoc]").prop('disabled', false);
+		}
+	});
+	
+	// 등록/수정폼의 상위카테고리 선택 시
+	var fnChangeUpperCategory = function(val, selLvl) {
+		if (gagajf.isNull(val)) {
+			if (selLvl > 1) {
+				selLvl = selLvl - 1;
+			} else {
+				selLvl = 1;
+			}
+		}
+		$('#detailForm input[name=selLvl]').val(selLvl);
+		
+		gagajf.ajaxFormSubmit($('#searchForm').prop('action'), "#detailForm", function(data) {
+			let selLvl = Number($('#detailForm input[name=selLvl]').val()) + 1;
+			
+			for (let i = 2; i <= 5; i++) {
+				if (i >= selLvl) {
+					$('#cateLvl' + i).html('<option value="">[카테고리' + (i - 1) + ']</option>');
+				}
+			}
+			
+			let tag = '';
+			for (let i = 0; i < data.length; i++) {
+				if (data[i].useYn == 'Y') {
+					tag += '<option value="' + data[i].cateNo + '">[' + data[i].cateNo + '] ' + data[i].cateNm + '</option>';
+				}
+			}
+			
+			$("#cateLvl" + selLvl).append(tag);
+		});
+	}
+	
+	// 신규
+	$('#btnNew').on('click', function(){
+		$("#detailForm")[0].reset();
+// 		$("#detailForm input[name=selLvl]").val('');
+		for (let i = 2; i <= 5; i++) {
+			$("#cateLvl" + i).show();
+		}
+	});
+	
+	// 저장
+	$('#btnSave').on('click', function() {
+		// 입력 값 체크
+		if (!gagajf.validation('#detailForm'))
+			return false;
+		
+		let selLvl = Number($('#detailForm input[name=selLvl]').val());
+		if (gagajf.isNull($('#detailForm select[name=cate1No]').val())) {
+			if (selLvl > 2) {
+				mcxDialog.alertC('카테고리1을 선택해 주세요.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#detailForm select[name=cate1No]').focus();
+					}
+				});
+				return;
+			}
+		}
+		
+		if (gagajf.isNull($('#detailForm select[name=cate2No]').val())) {
+			if (selLvl > 3) {
+				mcxDialog.alertC('카테고리2를 선택해 주세요.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#detailForm select[name=cate2No]').focus();
+					}
+				});
+				return;
+			}
+		}
+		
+		if (gagajf.isNull($('#detailForm select[name=cate3No]').val())) {
+			if (selLvl > 4) {
+				mcxDialog.alertC('카테고리3을 선택해 주세요.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#detailForm select[name=cate3No]').focus();
+					}
+				});
+				return;
+			}
+		}
+		
+		if (gagajf.isNull($('#detailForm select[name=cate4No]').val())) {
+			if (selLvl > 5) {
+				mcxDialog.alertC('카테고리4를 선택해 주세요.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#detailForm select[name=cate4No]').focus();
+					}
+				});
+				return;
+			}
+		}
+		
+		mcxDialog.confirm('저장하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				$("#detailForm select[name=contentsLoc]").prop('disabled', false);
+				
+				var jsonData = JSON.stringify($('#detailForm').serializeObject());
+				gagajf.ajaxFormSubmit($('#detailForm').prop('action'), '#detailForm', function() {
+					$('#btnNew').trigger('click');
+				});
+			}
+		});
+	});
+	
+	// 카테고리 갱신
+	$("#btnRefresh4Srch").on("click", function() {
+		mcxDialog.confirm('갱신하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				gagajf.ajaxJsonSubmit('/display/category/refresh', null);
+			}
+		});
+	});
+	
+	$(document).ready(function() {
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+		
+		$("#detailForm select[name=contentsLoc]").prop('disabled', false);
+	});
+/*]]>*/
+</script>
+
+</html>

+ 292 - 0
style24.admin/src/main/webapp/WEB-INF/views/display/ItemkindCategoryForm.html

@@ -0,0 +1,292 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ItemkindCategoryForm.html
+ * @desc    : 품목카테고리관리 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.01.06   gagamel     최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+		
+		<div class="panelStyle">
+			<!-- 다중 TABLE 배치 -->
+			<ul class="division">
+				<li style="width: 40%">
+					<form id="searchForm" name="searchForm" action="#" th:action="@{'/goods/itemkind/base/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+						<ul class="panelBar">
+							<li>
+								<h4 class="marR10">품목 목록</h4>
+								<input type="text" class="w300" name="itemkindNm" placeholder="품목명" maxlength="50"/>
+								<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+							</li>
+						</ul>
+					</form>
+					<div id="gridList1" style="width: 100%; height: 670px" class="ag-theme-balham"></div>
+				</li>
+				<li style="width: 60%">
+					<form id="searchForm2" name="searchForm2" action="#" th:action="@{'/display/category/gb/list'}">
+						<ul class="panelBar">
+							<li>
+								<h4 class="marR10">카테고리 목록</h4>
+								<select name="cateGb">
+									<option value="">[카테고리구분]</option>
+									<option th:if="${cateGbList}" th:each="oneData, status : ${cateGbList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+								</select>
+								<button type="button" class="btn btn-info btn-lg" id="btnApply">품목카테고리매핑 목록에 추가</button>
+							</li>
+						</ul>
+					</form>
+					<div id="gridList2" style="width: 100%; height: 340px" class="ag-theme-balham"></div>
+					
+					<ul class="panelBar">
+						<li>
+							<h4><span id="itemkindCd" class="cBlue"></span><span id="itemkindNm" class="cBlue"></span> 품목의 자동전시카테고리매핑 목록</h4>
+						</li>
+						<li class="right">
+							<button type="button" class="btn btn-danger btn-lg" id="btnDelete">삭제</button>
+							<button type="button" class="btn btn-success btn-lg" id="btnSave">저장</button>
+						</li>
+					</ul>
+					<div id="gridList3" style="width: 100%; height: 270px" class="ag-theme-balham"></div>
+				</li>
+			</ul>
+		</div>
+	</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	let cateGbList = gagajf.convertToArray([[${cateGbList}]]);
+
+	let columnDefs1 = [
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{
+			headerName: "품목코드", field: "itemkindCd", width: 150, cellClass: 'text-center',
+			cellRenderer: function (params) { return '<a href="javascript:void(0);">' + params.value + '</a>'; }
+		},
+		{headerName: "품목명", field: "itemkindNm", width: 300}
+	];
+	
+	let columnDefs2 = [
+		{headerName: "FULL카테고리번호", field: "fullCateNo", width: 200, hide: true},
+		{
+			headerName: "카테고리구분", field: "cateGb", width: 120, cellClass: 'text-center',
+			cellRenderer: function (params) { return gagaAgGrid.lookupValue(cateGbList, params.value); }
+		},
+		{headerName: "FULL카테고리명", field: "fullCateNm", width: 400},
+		{headerName: "카데고리명", field: "cateNm", width: 150, cellClass: 'text-center', hide: true},
+		{headerName: "분류레벨", field: "clsLvl", width: 100, hide: true}
+	];
+	
+	let columnDefs3 = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+		{headerName: "CRUD", field: "crud", width: 75, cellClass: 'text-center', hide: true},
+		{headerName: "품목코드", field: "itemkindCd", cellClass: 'text-center', hide: true},
+		{
+			headerName: "카테고리구분", field: "cateGb", width: 120, cellClass: 'text-center',
+			cellRenderer: function (params) { return gagaAgGrid.lookupValue(cateGbList, params.value); }
+		},
+		{headerName: "카테고리번호", field: "cateNo", width: 150, cellClass: 'text-center'},
+		{headerName: "FULL카테고리번호", field: "fullCateNo", width: 200},
+		{headerName: "FULL카테고리명", field: "fullCateNm", width: 400}
+	];
+	
+	let gridOptions1 = gagaAgGrid.getGridOptions(columnDefs1);
+	let gridOptions2 = gagaAgGrid.getGridOptions(columnDefs2);
+	let gridOptions3 = gagaAgGrid.getGridOptions(columnDefs3);
+	
+	// Add on options
+	gridOptions2.suppressRowClickSelection = true;
+	gridOptions2.rowSelection = 'multiple';
+	gridOptions2.treeData = true; // enable Tree Data mode
+	gridOptions2.groupDefaultExpanded = -1; // expand all groups by default
+	gridOptions2.getDataPath = function(data) { // just return the hierarchy, no conversion required
+		return data.treePath.split("/");
+	};
+	gridOptions2.autoGroupColumnDef = {
+		headerName: "카데고리번호", field: "cateNo", width: 200,
+		cellRendererParams: {
+			suppressCount: true, // 하위의 항목 건수 표시 안 함
+			checkbox: function (params) {
+				if (!gagajf.isNull(params.data)) {
+					return true;
+				}
+			}
+		}
+	};
+	
+	gridOptions3.rowSelection = 'multiple';
+	
+	// Cell click
+	gridOptions1.onCellClicked = function(event) {
+		if (event.colDef.field != 'itemkindCd') {
+			return;
+		}
+		
+		// 품목카테고리매핑 조회
+		fnSearchItemkindCategoryMapping(event.data.itemkindCd, event.data.itemkindNm);
+	}
+
+	// 검색 버튼 클릭 시
+	$('#btnSearch').on('click', function() {
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions1, '#searchForm');
+	});
+	
+	// 카테고리구분 변경 시
+	$('select[name=cateGb]').on('change', function() {
+		if (gagajf.isNull($(this).val())) {
+			mcxDialog.alert("카테고리구분을 선택해 주세요.");
+			$(this).focus();
+			return false;
+		}
+		
+		let actionUrl = $('#searchForm2').prop('action') + '/' + $(this).val();
+		gagaAgGrid.fetch(actionUrl, gridOptions2);
+	});
+	
+	// 적용 버튼 클릭 시
+	$('#btnApply').on('click', function() {
+		if (gagajf.isNull($('#itemkindCd').html())) {
+			mcxDialog.alert("선택된 품목이 없습니다. 먼저 품목 목록을 조회하고 [품목코드]를 선택 후 진행해 주세요.");
+			return false;
+		}
+		
+		let selectedData = gridOptions2.api.getSelectedRows();
+		
+		if (selectedData.length == 0) {
+			mcxDialog.alert("선택된 데이터가 없습니다.");
+			return false;
+		}
+		
+		var applyData = [];
+		
+		selectedData.forEach(function(item) {
+			if (item.clsLvl >= 3) {
+				applyData.push(item);
+			}
+		});
+		
+		fnAddCategory(applyData);
+	});
+	
+	// 선택된 카테고리를 품목카테고리매핑 그리드에 추가
+	var fnAddCategory = function(cateData) {
+		var isExist = false;
+		
+		cateData.forEach(function(item) {
+			isExist = false;
+			
+			gridOptions3.api.forEachNode(function(rowNode, index) {
+				if (item.cateNo == rowNode.data.cateNo) {
+					isExist = true;
+				}
+			});
+			
+			if (!isExist) {
+				var data = {
+						cateGb : item.cateGb,
+						cateNo : item.cateNo,
+						fullCateNo : item.fullCateNo,
+						fullCateNm : item.fullCateNm,
+						itemkindCd : $('#itemkindCd').html()
+				};
+				
+				gagaAgGrid.addRowData(gridOptions3, data, "cateNo");
+			}
+		});
+	}
+	
+	// 품목카테고리매핑 조회
+	var fnSearchItemkindCategoryMapping = function(itemkindCd, itemkindNm) {
+		$('#itemkindCd').html(itemkindCd);
+		if (typeof(itemkindNm) != 'undefined') $('#itemkindNm').html(':' + itemkindNm);
+		
+		let actionUrl = "/display/itemkind/category/mapping/list/" + itemkindCd;
+		gagaAgGrid.fetch(actionUrl, gridOptions3);
+	}
+	
+	// 품목카테고리매핑 삭제
+	$('#btnDelete').on('click', function() {
+		// 추가된 ROW만 삭제하는 경우 DB 처리를 하지 않도록
+		let selectedData = gagaAgGrid.selectedRowData(gridOptions3);
+		let iTotCnt = 0;
+		let iCnt = 0;
+		selectedData.forEach(function(item, idx) {
+			iTotCnt++;
+			if (item.crud == "C") {
+				gridOptions3.api.updateRowData({remove: [item]});
+				iCnt ++;
+			}
+		});
+		if (iTotCnt > 0 && iTotCnt == iCnt) { return; }
+		// 추가된 ROW만 삭제하는 경우 DB 처리를 하지 않도록
+		
+		var removedData = gagaAgGrid.removeRowData(gridOptions3);
+		
+		if (removedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+		
+		mcxDialog.confirm('삭제하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(removedData);
+				gagajf.ajaxJsonSubmit('/display/itemkind/category/mapping/delete', jsonData, function() {
+					// 품목카테고리매핑 조회
+					fnSearchItemkindCategoryMapping($('#itemkindCd').html());
+				});
+			}
+		});
+	});
+	
+	// 품목카테고리매핑 저장
+	$('#btnSave').on('click', function() {
+		// 변경된 데이터
+		var changedData = gagaAgGrid.getChangedData(gridOptions3);
+		
+		if (changedData.length == 0) {
+			mcxDialog.alert('변경된 데이터가 없습니다.');
+			return;
+		}
+		
+		mcxDialog.confirm('저장하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function(){
+				var jsonData = JSON.stringify(changedData);
+				gagajf.ajaxJsonSubmit('/display/itemkind/category/mapping/save', jsonData, function() {
+					// 품목카테고리매핑 조회
+					fnSearchItemkindCategoryMapping($('#itemkindCd').html());
+				});
+			}
+		});
+	});
+	
+	$(document).ready(function() {
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList1', gridOptions1);
+		gagaAgGrid.createGrid('gridList2', gridOptions2);
+		gagaAgGrid.createGrid('gridList3', gridOptions3);
+	});
+/*]]>*/
+</script>
+
+</html>

+ 55 - 7
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsDealForm.html

@@ -29,12 +29,18 @@
 						<div class="iconTooltip">
 							<i class="fa fa-info" aria-hidden="true"></i>
 							<span class="left" style="width:450px; text-align:left;">
-								- 상품상태 : 정보부족<br/>
-								- 정상가 : 판매가 입력값<br/>
-								- 브랜드코드 : 구성상품의 기준여부 'Y'상품의 브랜드코드<br/>
-								- 품목코드 : 구성상품의 기준여부 'Y'상품의 품목코드<br/>
-								- 포인트 : 구성상품의 기준여부 'Y'상품의 브랜드 포인트<br/>
-								- 배송비정책 : 구성상품의 기준여부 'Y'상품의 브랜드 배송비정책<br/>
+								* 딜상품 정보<br/>
+								&nbsp;&nbsp;- 상품상태 : 정보부족<br/>
+								&nbsp;&nbsp;- 정상가 : 판매가 입력값<br/>
+								&nbsp;&nbsp;- 판매가 : 구성상품의 대표여부 'Y' 상품의 판매가<br/>
+								&nbsp;&nbsp;- 브랜드코드 : 구성상품의 기준여부 'Y'상품의 브랜드코드<br/>
+								&nbsp;&nbsp;- 품목코드 : 구성상품의 기준여부 'Y'상품의 품목코드<br/>
+								&nbsp;&nbsp;- 포인트 : 구성상품의 기준여부 'Y'상품의 브랜드 포인트<br/>
+								&nbsp;&nbsp;- 배송비정책 : 구성상품의 기준여부 'Y'상품의 브랜드 배송비정책<br/>
+								<br/>
+								* 구성상품 정보<br/>
+								&nbsp;&nbsp;- 구상상품의 기준상품 : 수정 불가<br/>
+								&nbsp;&nbsp;- 구상상품의 대표상품 : 수정 가능<br/>
 							</span>
 						</div>
 						<!-- //아이콘 툴팁 --> 
@@ -131,6 +137,12 @@
 			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
 			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }
 		},
+		{headerName: "대표여부(가격)", field: "repYn" , width: 120, cellClass: 'text-center',editable: true, required: true,
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }
+		},
 		{headerName: "전시여부", field: "useYn" , width: 80, cellClass: 'text-center',editable: true, required: true,
 			cellEditor: 'agRichSelectCellEditor',
 			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList) },
@@ -149,7 +161,7 @@
 	var gridGoodsDealOptions = gagaAgGrid.getGridOptions(columnGoodsDealDefs);
 	gridGoodsDealOptions.rowSelection = 'multiple';
 	gridGoodsDealOptions.suppressRowClickSelection = true;
-	gridGoodsSetOptions.stopEditingWhenGridLosesFocus = true;	//그리드 에디터 값 저장가능
+	gridGoodsDealOptions.stopEditingWhenGridLosesFocus = true;	//그리드 에디터 값 저장가능
 	
 	// 드래그
 	gridGoodsDealOptions.rowDragManaged = true;
@@ -159,6 +171,8 @@
 	gridGoodsDealOptions.getRowStyle = function(params) {
 		if ("Y" == params.data.baseYn) {
 			return { background: '#1ab394' };
+		}else{
+			return { background: '#ffffff' };
 		}
 	}
 	
@@ -186,6 +200,28 @@
 				}
 			}	
 		}
+		
+		isChangColor = true;
+		if (event.colDef.field == "repYn"){
+			if (event.data.repYn == "Y"){
+				rowIdx = event.rowIndex;
+				
+				//다른 대표여부 'Y'가 존재하는지 확인
+				gridGoodsDealOptions.api.forEachNode(function(rowNode, index) {
+					if (rowNode.data.repYn == "Y" && index != rowIdx){
+						event.data.repYn = event.oldValue;
+						gridGoodsDealOptions.api.updateRowData({update: [event.data]});
+						isChangColor = false;
+						return;
+					}
+				});
+				
+				if (!isChangColor){ 
+					mcxDialog.alert('다른 구성상품에 대표여부가 선택되어 있습니다.');
+					return;
+				}
+			}	
+		}
 	}
 	
 	//창종료
@@ -232,6 +268,7 @@
 						, compsCurrPrice: goods.currPrice
 						, compsStaffCurrPrice: goods.currPrice
 						, baseYn: 'N'
+						, repYn: 'N'
 						, goodsStat : goods.goodsStat
 						, useYn: 'Y'
 						, compsGoodsOptNm : goods.goodsNm
@@ -400,6 +437,8 @@
 		var comSelfGoodsYn = '';
 		//기준여부 Y  존재하는지 확인
 		var checkBaseYn = false;
+		//대표여부 Y  존재하는지 확인
+		var checkRepYn = false;
 		optCheck = false;
 		$.each(allData, function(index, item) {
 			if (index == 0){
@@ -411,6 +450,10 @@
 				checkBaseYn = true;
 			}
 			
+			if (item.repYn == "Y"){
+				checkRepYn = true;
+			}
+			
 			if(item.goodsStat != "G008_90"){
 				optCheck = true;
 				mcxDialog.alertC("상품상태를 확인해 주세요.", {
@@ -466,6 +509,11 @@
 			return false;
 		}
 		
+		if (!checkRepYn){
+			mcxDialog.alert('구성상품중 대표여부를 선택해 주세요.');
+			return false;
+		}
+		
 		return true;
 	}
 	

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

@@ -14,13 +14,12 @@
  * 1.0  2020.10.23   eskim       최초 작성
  *******************************************************************************
  -->
-	<div class="modalPopup" data-width="1500"> <!-- data-width="1500" data-height="870" -->
+	<div class="modalPopup" data-width="1500" > <!-- data-width="1500" data-height="870" -->
 		<div class="panelStyle">
 			<div class="panelTitle">
 				<h2>상품상세</h2>
 				<button type="button" class="close" onclick="fnGoodsDetailClose()"><i class="fa fa-times"></i></button>
 			</div>
-			<div class="panelContent">
 			<form id="goodsDetailForm" name="goodsDetailForm" action="#" th:method="post">
 				<input type="hidden" id="mode" name="mode" th:value="${params.mode}"/>
 				<input type="hidden" id="goodsCd" name="goodsCd" th:value="${params.goodsCd}"/>
@@ -35,6 +34,8 @@
 				<input type="hidden" id="mainColorCd" name="mainColorCd" />
 				<input type="hidden" id="goodsType" name="goodsType" />
 				<input type="hidden" id="goodsComposeList" name="goodsComposeList" />
+				<input type="hidden" id="repGoodsCd" name="repGoodsCd" /> <!-- 대표상품(딜 가격) -->
+			<div class="panelContent">
 				<table class="frmStyle">
 					<colgroup>
 						<col width="11%"/>
@@ -371,12 +372,31 @@
 						<li class="tab" id="goodstab3">
 							<!-- TAB3 CONTENTS AREA -->
 							<div class="panelStyle">
+								<table class="frmStyle">
+									<colgroup>
+										<col width="12%"/>
+										<col/>
+									</colgroup>
+									<tr>
+										<th>상세설명</th>
+										<td><label class="chkBox"><input type="checkbox" name="chkDescKeep" checked="checked" value="Y">정보유지<span></span></label>
+										</td>
+									</tr>
+								</table>
 								<!-- TABS SPACE -->
 								<div class="tabsJr">
+									<!-- TABS NAVI -->
+									<ul class="tabsJrNav">
+										<li class="on"><a href="#goodstab11">타이틀/내용/특징</a></li>
+										<li><a href="#goodstab12">상세html</a></li>
+									</ul>
+									<!-- //TABS NAVI -->
 									<!-- TABS CONTENT -->
 									<ul class="tabsJrCont">
+										<!-- TAB11 CONTENTS AREA -->
 										<!-- TAB -->
 										<li class="tabJr on" id="goodstab11">
+											<div class="panelStyle">
 											<!-- TAB11 CONTENTS AREA -->
 											<table class="frmStyle">
 											<colgroup>
@@ -384,10 +404,35 @@
 												<col/>
 											</colgroup>
 											<tr>
-												<th>상세설명</th>
-												<td><label class="chkBox"><input type="checkbox" name="chkDescKeep" checked="checked" value="Y">정보유지<span></span></label>
+												<th>타이틀</th>
+												<td><input type="text" class= "w100p" id="goodsTitlesDesc" name="goodsTitlesDesc" maxlength="100" />
+												</td>
+											</tr>
+											<tr>
+												<th>내용</th>
+												<td><div class="tabJrContArea">
+													<textarea class="textareaR3 summernote" name="goodsContentsDesc" id="goodsContentsDesc"></textarea>
+													</div>
 												</td>
 											</tr>
+											<tr>
+												<th>상품 특징</th>
+												<td><div class="tabJrContArea">
+													<textarea class="textareaR3 summernote" name="goodsCharacterDesc" id="goodsCharacterDesc"></textarea>
+													</div>
+												</td>
+											</tr>
+											</table>
+											</div>
+										</li>
+										<li class="tabJr" id="goodstab12">
+											<div class="panelStyle">
+												<!-- TAB11 CONTENTS AREA -->
+												<table class="frmStyle">
+											<colgroup>
+												<col width="12%"/>
+												<col/>
+											</colgroup>
 											<tr>
 												<th>상위(PC)</th>
 												<td><div class="tabJrContArea">
@@ -417,6 +462,7 @@
 												</td>
 											</tr>
 											</table>
+											</div>
 										</li>
 										<!-- //TAB -->
 									</ul>
@@ -468,7 +514,7 @@
 										<button type="button" class="btn btn-base btn-lg" onclick="fnOpenGoodsDetailPopup()">상품조회</button>
 									</li>
 								</ul>
-								<div id="gridGoodsComposeList" style="height: 500px;" class="ag-theme-balham lh60"></div>
+								<div id="gridGoodsComposeList" style="height: 600px;" class="ag-theme-balham lh60"></div>
 								<!-- 내용 삽입 -->
 							</div>
 							<!-- //TAB6 CONTENTS AREA -->
@@ -478,7 +524,7 @@
 							<!-- TAB8 CONTENTS AREA -->
 							<div class="panelStyle">
 								<!-- 내용 삽입 -->
-								<div id="gridGoodsHstoryList" style="height: 500px;" class="ag-theme-balham"></div>
+								<div id="gridGoodsHstoryList" style="height: 600px;" class="ag-theme-balham"></div>
 								<!-- 내용 삽입 -->
 							</div>
 							<!-- //TAB5 CONTENTS AREA -->
@@ -501,8 +547,9 @@
 					<!-- //TABS BUTTON AREA -->
 				</div>
 				<!-- //TABS SPACE -->
-			</form>
+			
 			</div>	<!--  class=panelContent -->
+			</form>
 		</div>	<!--  class=panelStyle -->
 	</div> <!--  class=modalPopup -->
 <script type="text/javascript" src="/ux/plugins/summernote/summernote.js?v=2020103001"></script>
@@ -596,7 +643,15 @@
 			cellEditorParams: { maxlength: 14, validType: 'numeric'}
 		},
 		{headerName: "상품판매가ORG", field: "compsCurrPriceOrg" , width: 100, cellClass: 'text-right', hide: true},
-		{headerName: "기준여부(품목-카테고리)", field: "baseYn", width: 160, cellClass: 'text-center'},
+		{headerName: "기준여부(품목-카테고리)", field: "baseYn", width: 160, cellClass: 'text-center'
+		},
+		{headerName: "대표여부(가격)", field: "repYn", width: 160, cellClass: 'text-center',editable: true,
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList), required: true },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }
+		},
+		{headerName: "대표상품", field: "repGoodsCd" , width: 100, cellClass: 'text-right', hide: true},
 		{headerName: "전시여부", field: "useYn", width: 100, cellClass: 'text-center',editable: true,
 			cellEditor: 'agRichSelectCellEditor',
 			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList), required: true },
@@ -643,6 +698,58 @@
 	gridGoodsComposeOptions.getRowStyle = function(params) {
 		if ("Y" == params.data.baseYn) {
 			return { background: '#1ab394' };
+		}else{
+			return { background: '#ffffff' };	
+		}
+	}
+	
+	// Row 
+	gridGoodsComposeOptions.onCellValueChanged = function(event) {
+		var rowIdx = null;
+		var isChangColor = true;
+		if (event.colDef.field == "baseYn"){
+			if (event.data.baseYn == "Y"){
+				rowIdx = event.rowIndex;
+				
+				//다른 기준여부 'Y'가 존재하는지 확인
+				gridGoodsComposeOptions.api.forEachNode(function(rowNode, index) {
+					if (rowNode.data.baseYn == "Y" && index != rowIdx){
+						event.data.baseYn = event.oldValue;
+						gridGoodsComposeOptions.api.updateRowData({update: [event.data]});
+						isChangColor = false;
+						return;
+					}
+				});
+				
+				if (!isChangColor){ 
+					mcxDialog.alert('다른 구성상품에 기준여부가 선택되어 있습니다.');
+					return;
+				}
+			}	
+		}
+		
+		if ($("#goodsDetailForm input[name=goodsType]").val() == "G056_D"){
+			isChangColor = true;
+			if (event.colDef.field == "repYn"){
+				if (event.data.repYn == "Y"){
+					rowIdx = event.rowIndex;
+					
+					//다른 대표여부 'Y'가 존재하는지 확인
+					gridGoodsComposeOptions.api.forEachNode(function(rowNode, index) {
+						if (rowNode.data.repYn == "Y" && index != rowIdx){
+							event.data.repYn = event.oldValue;
+							gridGoodsComposeOptions.api.updateRowData({update: [event.data]});
+							isChangColor = false;
+							return;
+						}
+					});
+					
+					if (!isChangColor){ 
+						mcxDialog.alert('다른 구성상품에 대표여부가 선택되어 있습니다.');
+						return;
+					}
+				}	
+			}	
 		}
 	}
 	
@@ -832,12 +939,18 @@
 			$('#goodsDetailForm input[name=certNum]').val(result.certNum);
 			$('#goodsDetailForm input[name=certNumOrg]').val(result.certNum);
 			
+			
+			
 			//상품상세
-			// 공지내용. Summernote에 값 세팅
-			gagaSn.setContents('#goodsPcTopDesc', result.goodsPcTopDesc);
-			gagaSn.setContents('#goodsMobileTopDesc', result.goodsMobileTopDesc);
-			gagaSn.setContents('#goodsPcDownDesc', result.goodsPcDownDesc);
-			gagaSn.setContents('#goodsMobileDownDesc', result.goodsMobileDownDesc);
+			$('#goodsDetailForm input[name=goodsTitlesDesc]').val(result.goodsTitlesDesc);
+			// Summernote에 값 세팅
+			gagaSn.setContents('#goodsContentsDesc', result.goodsContentsDesc); 
+			gagaSn.setContents('#goodsCharacterDesc', result.goodsCharacterDesc);
+			gagaSn.setContents('#goodsPcTopDesc', result.goodsPcTopDesc); 
+			gagaSn.setContents('#goodsMobileTopDesc', result.goodsMobileTopDesc); 
+			gagaSn.setContents('#goodsPcDownDesc', result.goodsPcDownDesc); 
+			gagaSn.setContents('#goodsMobileDownDesc', result.goodsMobileDownDesc); 
+			
 
 			if (!gagajf.isNull(result.niClsfNm)){
 				$('#goodsDetailForm').find('#itemkindNoti').html('품목기준 고시분류 : ' + result.niClsfNm);
@@ -939,7 +1052,7 @@
 			gagaAgGrid.showOrHideColumn(gridGoodsComposeOptions, 'currPrice', false);
 			gagaAgGrid.showOrHideColumn(gridGoodsComposeOptions, 'useYn', false);
 			gagaAgGrid.showOrHideColumn(gridGoodsComposeOptions, 'compsGoodsOptNm', false);
-			
+			gagaAgGrid.showOrHideColumn(gridGoodsComposeOptions, 'repYn', false);
 			$('#GoodsComposeBtnArea').addClass("off");
 		}else{	//딜
 			gagaAgGrid.showOrHideColumn(gridGoodsComposeOptions, 'qty', false);
@@ -1303,15 +1416,18 @@
 		} */
 
 		//정상가와 판매가 비교
-		if(Number($("#goodsDetailForm input[name=listPrice]").val().removeComma()) < Number($("#goodsDetailForm input[name=currPrice]").val().removeComma())) {
-			mcxDialog.alertC("판매가를 올바르게 입력해주세요.", {
-				sureBtnText: "확인",
-				sureBtnClick: function() {
-					$("#goodsDetailForm input[name=currPrice]").focus();
-				}
-			});
-			return false;
+		if ($("#goodsDetailForm input[name=goodsType]").val() != "G056_D"){
+			if(Number($("#goodsDetailForm input[name=listPrice]").val().removeComma()) < Number($("#goodsDetailForm input[name=currPrice]").val().removeComma())) {
+				mcxDialog.alertC("판매가를 올바르게 입력해주세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsDetailForm input[name=currPrice]").focus();
+					}
+				});
+				return false;
+			}	
 		}
+		
 		//판매 수수료율
 		if ( gagajf.isNull($("#goodsDetailForm input[name=sellFeeRate]").val())) {
 			mcxDialog.alertC("판매수수료를 입력해 주세요.", {
@@ -1563,7 +1679,7 @@
 		var currPrice = $("#goodsDetailForm input[name=currPrice]").val().removeComma();
 		dcRate =  100 - Math.floor(Number(currPrice) / Number(listPrice) * 100);	//절사
 			
-		if (dcRate < 0){
+		if (dcRate < 0 && ($("#goodsDetailForm input[name=goodsType]").val() != "G056_D")){
 			mcxDialog.alertC('할인율이 0보다 작습니다.\n판매가를 확인해주세요.', {
 				sureBtnText: "확인",
 				sureBtnClick: function() {
@@ -1571,7 +1687,7 @@
 				}
 			});
 			return false;
-		}else if (dcRate >= 90){
+		}else if (dcRate >= 90 && ($("#goodsDetailForm input[name=goodsType]").val() != "G056_D")){
 			mcxDialog.confirmC("할인율이 90%이상입니다. 계속하시겠습니까?", {
 				btn: ["아니요","예"],
 				btnClick: function(index){
@@ -1622,18 +1738,26 @@
 		var allData = gagaAgGrid.getAllRowData(gridGoodsComposeOptions);
 		var comSupplyCompCd = '';
 		var comSelfGoodsYn = '';
+		var index = 0;
 		//기준여부 Y  존재하는지 확인
 		var checkBaseYn = false;
+		//대표여부 Y  존재하는지 확인
+		var checkRepYn = false;
 		optCheck = false;
-		$.each(allData, function(index, item) {
+		$.each(allData, function(index, item) { 
 			if (index == 0){
 				comSelfGoodsYn = item.selfGoodsYn;
 				comSupplyCompCd = item.supplyCompCd;
+				$("#goodsDetailForm input[name=repGoodsCd]").val(item.repGoodsCd);	// 대표상품
+				
 			}
 			
 			if (item.baseYn == "Y"){
 				checkBaseYn = true;
 			}
+			if (item.repYn == "Y"){
+				checkRepYn = true;
+			}
 			
 			if (comSelfGoodsYn != item.selfGoodsYn){
 				optCheck = true;
@@ -1674,7 +1798,7 @@
 					return false;
 				}
 			}
-			
+			index++;
 		});
 		
 		if(optCheck) {
@@ -1686,6 +1810,11 @@
 			return false;
 		}
 		
+		if (!checkRepYn){
+			mcxDialog.alert('구성상품중 대표여부를 선택해 주세요.');
+			return false;
+		}
+		
 		return true;
 	}
 

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

@@ -67,7 +67,7 @@
 			<col width="7%"/>
 		</colgroup>
 		<tr th:if="${goods.selfGoodsYn == 'Y' and goods.goodsType == 'G056_N'}">
-			<th colspan="2">ERP재고연동여부<i class="star"></i></th>
+			<th colspan="2">WMS재고연동여부<i class="star"></i></th>
 			<td colspan="2">
 				<label class="rdoBtn"><input type="radio" name="erpStockLinkYn" id="erpStockLinkYnY" value="Y" th:checked="${goods.erpStockLinkYn == 'Y'}"/>Y</label>
 				<label class="rdoBtn"><input type="radio" name="erpStockLinkYn" id="erpStockLinkYnN" value="N" th:checked="${goods.erpStockLinkYn == 'N'}"/>N</label>

+ 331 - 0
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsFreeGoodsForm.html

@@ -0,0 +1,331 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : GoodsFreeGoodsForm.html
+ * @desc    : 사은품관리 Page
+ *============================================================================
+ * Pastelmall
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.12.28   eskim       최초 작성
+  *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<div class="panelContent">
+			<form id="searchForm" name="searchForm" action="#" th:action="@{'/goods/freeGoods/list'}">
+			<input type="hidden" id="searchGb" name="searchGb" value="BASIC" />
+			<input type="hidden" id="dateGbn" name="dateGbn" value="R"/> <!-- 등록일 -->
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:9%;"/>
+						<col style="width:20%;"/>
+						<col style="width:9%;"/>
+						<col style="width:20%;"/>
+						<col style="width:9%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<th>업체/브랜드<em class="required" title="필수"></em></th>
+						<td colspan="3">
+							<label class="rdoBtn"><input type="radio" name="selfYn" id="selfYnY" value="Y"  checked/>자사</label>
+							<label class="rdoBtn"><input type="radio" name="selfYn" id="selfYnN" value="N"/>입점</label>
+							<select name="supplyCompCd" id="supplyCompCd">
+								<option value="" th:if="${sessionInfo.roleCd} != 'G001_B000'">[전체]</option>
+								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+							<span id="multiBrand"></span>
+						</td>
+						<th rowspan="2">키워드</th>
+						<td rowspan="2">
+							<select name="search" id="search">
+								<option value="searchProductNo">사은품번호</option>
+								<option value="searchGoodsNm">사은품명</option>
+								<option value="searchGoodsNum">품번</option>
+							</select>
+							<textarea class="textareaR2 w130" name="condition" id="condition"></textarea>
+						</td>
+					</tr>
+					<tr>
+						<th>등록일</th>
+						<td colspan="3" id="sellTerms">
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-default btn-lg" id="btnInit">초기화</button>
+						<button type="button" class="btn btn-success btn-lg" id="btnSearch">조회</button>
+					</li>
+				</ul>
+			</form>
+			</div>
+		</div>
+		<!-- //검색조건 영역 -->
+		
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<div id="gridList" style="width: 100%; height: 450px;" class="ag-theme-balham lh60"></div>
+		</div>
+		<!-- //리스트 영역 -->
+		<!-- 등록/수정 -->
+		<div class="panelStyle">
+			<form id="detailForm" name="detailForm" action="#" th:action="@{'/goods/freeGoods/update'}">
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:8%;"/>
+						<col style="width:11%;"/>
+						<col style="width:8%;"/>
+						<col style="width:11%;"/>
+						<col style="width:8%;"/>
+						<col style="width:11%;"/>
+						<col style="width:8%;"/>
+						<col style="width:17%;"/>
+						<col style="width:8%;"/>
+						<col/>
+					</colgroup>
+					<tr>
+						<td colspan='10'>사은품 상세</td>
+					</tr>
+					<tr>
+						<th>사은품번호</th>
+						<td>
+							<input class="w130" type="text"  name="productNo"  data-valid-name="사은품번호"  readonly="readonly"/>
+						</td>
+						<th>품번</th>
+						<td>
+							<input class="w130" type="text"  name="goodsNum"  data-valid-name="품번"  readonly="readonly"/>
+						</td>
+						<th>브랜드</th>
+						<td>
+							<!-- <input class="w130" type="text"  name="brandCd"  data-valid-name="브랜드코드"  readonly="readonly" />/ -->
+							<input class="w130" type="text"  name="brandEnm"  data-valid-name="브랜드명"  readonly="readonly" />
+						</td>
+						<th>사은품명<em class="required" title="필수"></em></th>
+						<td>
+							<input class="w200" type="text"  name="goodsNm" maxlength="50" required="required" data-valid-name="사은품명"/>
+						</td>
+						<th>사용여부<em class="required" title="필수"></em></th>
+						<td>
+							<label class="rdoBtn"><input type="radio" name="useYn" value="Y" checked="checked">Y</label>
+							<label class="rdoBtn"><input type="radio" name="useYn" value="N">N</label>
+						</td>
+					</tr>
+					<tr>
+						<th>이미지</th>
+						<td colspan="9">
+							<div class="uFile w300">
+								<input type="file" id="file" name="file" class="uFileInput"/>
+								<label for="file" class="uFileLabel">파일 선택</label>
+								<input type="hidden" name="sysImgNm" id="sysImgNm"/>
+								<input type="hidden" name="newSysImgNm" id="newSysImgNm"/>
+							</div>
+							<input type="hidden" name="uploadDefaultUrl" id="uploadDefaultUrl" th:value="${@environment.getProperty('upload.default.view') + '/display/freegoods/'}"/>
+							<div id="imgView" class="off">
+								<img id="bannerPreViewUrl" src="" style="height:100px"/>
+							</div>
+						</td>
+					</tr>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-success btn-lg" id="btnSave">저장</button>
+					</li>
+				</ul>
+			</form>
+		</div>
+	</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+	// specify the columns
+	var columnDefs = [
+		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
+		{headerName: "이미지", field: "sysImgNm", width: 100, height: 60, cellClass: 'text-center'
+			,cellRenderer: function(params) {
+				return '<img width="60" src="'+ _imgUrl+ "/display/freegoods/" + params.value + '" alt="" onerror="this.src=\'/image/no.gif\';"/>';
+			}
+		},
+		{headerName: "브랜드", field: "brandEnm", width: 130, cellClass: 'text-center'},
+		{headerName: "사은품 상품번호", field: "productNo", width: 120, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return '<a href="javascript:void(0);">' + params.value + '</a>';
+			}
+		},
+		{headerName: "사은품 품번", field: "goodsNum", width: 150, cellClass: 'text-center'},
+ 		{headerName: "사은품명", field: "goodsNm", width: 300, cellClass: 'text-left'},
+		{headerName: "사용여부", field: "useYn", width: 100, cellClass: 'text-center'},
+		{headerName: "등록일자", field: "regDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "등록자", field: "regNm", width: 130, cellClass: 'text-center'},
+		{headerName: "수정일자", field: "updDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "수정자", field: "updNm", width: 130, cellClass: 'text-center'},
+	];
+	
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+	
+	//gridOptions.suppressRowClickSelection = true;
+	gridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
+	
+	// 상품코드 셀 클릭
+	gridOptions.onCellClicked = function(event) {
+		if (event.colDef.field == "productNo"){
+			
+			$("#detailForm")[0].reset();
+			$("#detailForm input[name=productNo]").val('');
+			$("#detailForm input[name=goodsNum]").val('');
+			$("#detailForm input[name=brandNm]").val('');
+			
+			var formId = '#detailForm';
+			$(formId + " input[name=productNo]").val(event.data.productNo);
+			$(formId + " input[name=goodsNum]").val(event.data.goodsNum);
+			$(formId + " input[name=brandEnm]").val(event.data.brandEnm);
+			$(formId + " input[name=goodsNm]").val(event.data.goodsNm);
+			$(formId + " input:radio[name=useYn]:input[value="+event.data.useYn+"]").click();
+			var sysImgNm = event.data.sysImgNm;
+			if(!gagajf.isNull(sysImgNm)){
+				$("#sysImgNm").val(sysImgNm);
+				$("#bannerPreViewUrl").attr('src', $("#uploadDefaultUrl").val()+sysImgNm);
+				$("#imgView").removeClass("off").addClass("on");
+			}else {
+				$("#sysImgNm").val('');
+			}
+			$('#detailForm input[name=file]').closest('div').find('label').text('파일선택');
+		}
+	}
+	
+	//업체변경시
+	$('#searchForm 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');
+	});
+
+	
+	// 조회
+	$('#btnSearch').on('click', function() {
+		var formId = '#searchForm';
+		var form = document.searchForm;
+		var searchFlag = false;
+		var cnt = 0;
+
+		if( !gagajf.isNull($("#searchForm select[name=supplyCompCd]").val()) 
+				|| !gagajf.isNull($("#searchForm textarea[name=condition]").val())
+				|| (!gagajf.isNull($("#searchForm input[name=stDate]").val()) && !gagajf.isNull($("#searchForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{
+			/* for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+
+				if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+
+			if(cnt > 0) searchFlag = true; */
+		}
+
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+		
+		// 기간 값 체크
+		if (!fnCalendarDateValidation('#sellTerms', 'stDate', 'edDate')){
+			return false;
+		}
+		// Fetch data
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+	});
+	
+	// 검색조건 초기화
+	$('#btnInit').on('click', function() {
+		$("#searchForm")[0].reset();
+		$("#multiBrand").empty();
+	});
+	
+	// 파일첨부 선택 시
+	$('#detailForm input[name=file]').on('change', function() {
+		// multiple 속성이 있으면 files에는 다수의 객체가 할당됨
+		var file = this.files[0];
+
+		// 파일 업로드
+		gagajf.ajaxFileUpload('/common/file/upload?subDir=/display/freegoods'
+				, file
+				, function(result) {
+					// 업로드한 파일명 설정
+					$('#detailForm input[name=newSysImgNm]').val(result.newFileName);
+					$("#bannerPreViewUrl").attr('src', $("#uploadDefaultUrl").val()+result.newFileName);
+					$("#imgView").removeClass("off").addClass("on");
+				}
+		);
+	});
+	
+	// 사은품 저장
+	$("#btnSave").on('click', function() {
+		
+		if(gagajf.isNull($('#detailForm input[name=productNo]').val())){
+			mcxDialog.alert("사은품 선택 후 저장하세요.");
+			return false;
+		}
+		
+		// 입력 값 체크
+		if (!gagajf.validation('#detailForm'))
+			return false;
+		
+		mcxDialog.confirm('저장하시겠습니까?', {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				gagajf.ajaxFormSubmit($('#detailForm').prop('action'), '#detailForm', function() {debugger;
+					fnDetailFormInit();
+					$('#btnSearch').click();
+				});
+			}
+		});
+	});
+	
+	var fnDetailFormInit = function(){
+		$("#detailForm")[0].reset();
+		$("#bannerPreViewUrl").attr('src', '');
+		$("#imgView").removeClass("on").addClass("off");
+	}
+	
+	$(document).ready(function() {
+		
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', true);
+		
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+	});
+/*]]>*/
+</script>
+
+</html>

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

@@ -1084,7 +1084,7 @@
 			return false;
 		}
 		
-		cfnOpenBrandListPopup('fnSetBrandInfo', $("#searchForm input[name=searchTxt]").val());
+		cfnOpenBrandListPopup('fnSetBrandInfo', 'S', $("#searchForm input[name=searchTxt]").val());
 		
 	});
 	

+ 9 - 19
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsMassRegisterForm.html

@@ -28,11 +28,11 @@
 			<ul class="notice">
 				<li>상품을 대량으로 등록하는 페이지입니다.</li>
 				<li>상품을 등록 할 경우 [승인대기] 상태이며, STYLE 관리자의 [승인완료] 상태 변경 후 FRONT애 노출이 가능합니다.</li>
-				<li><th:block th:if="${erpSyncYn == 'N'}"><em><b>ERP연동여부가 [N]입니다. 관리자에게 문의하세요.</b></em></th:block></li>
+				<li><th:block th:if="${erpSyncYn == 'N'}"><em><b>WMS연동여부가 [N]입니다. 관리자에게 문의하세요.</b></em></th:block></li>
 			</ul>
 			<ul class="panelBar">
 				<li class="center">
-					<th:block th:if="${sessionInfo.roleCd == 'G001_0000' 
+					<!-- <th:block th:if="${sessionInfo.roleCd == 'G001_0000' 
 									or sessionInfo.roleCd == 'G001_A000' 
 									or sessionInfo.roleCd == 'G001_A001' 
 									or sessionInfo.roleCd == 'G001_A100' 
@@ -48,7 +48,7 @@
 									or sessionInfo.roleCd == 'G001_A101'
 									}">
 						<button type="button" class="btn btn-default btn-lg" id="btnInit" onclick="cfnDownloadSampleFile('SF005');">입점상품 등록양식 다운로드</button>
-						<button th:if="${erpSyncYn == 'Y'}" type="button" class="btn btn-primary btn-lg" id="btnGoodsCreate" >입점상품 등록</button>
+						<button th:if="${erpSyncYn == 'Y'}" type="button" class="btn btn-primary btn-lg" id="btnGoodsCreate" >입점상품 등록</button> -->
 					</th:block>
 					<label class="off"><a href="javascript:void(0);" id="excelList" style="display: none;">엑셀다운로드</a></label>
 					<!--  추후 대량 수정 권한-->
@@ -60,7 +60,7 @@
 								}" 
 							th:style="'padding-left:80px;'">
 						<button type="button" class="btn btn-default btn-lg" id="btnInit" onclick="cfnDownloadSampleFile('SF014');">상품대량수정 등록양식 다운로드</button>
-						<button th:if="${erpSyncYn == 'Y'}" type="button" class="btn btn-primary btn-lg" id="btnGoodsUpdate" >입점상품 등록</button>
+						<button th:if="${erpSyncYn == 'Y'}" type="button" class="btn btn-primary btn-lg" id="btnGoodsUpdate" >상품 수정</button>
 					</span>
 				</li>
 			</ul>
@@ -95,7 +95,7 @@
 					</tr>
 				</table>
 				<ul class="panelBar">
-					<li>
+					<li class="center">
 						<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
 						<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
 					</li>
@@ -114,31 +114,21 @@
 						<span class="left aL" style="width:580px;">
 						<!-- class="left" 또는 class="right" -->
 							<em>상품미등록</em><br/>
-							- 상품코드 오류 : 빈값, 길이 11이 아닐경우, '_'가 미존재<br/>
-							- 업체 오류 : 빈값, 'W'나 'F' 가 아닌경우<br/>
+							- 상품코드 오류 : 빈값, 온라인상품코드 미존재<br/>
+							- 업체 오류 : 빈값, 'S0001'나 'S0002' 가 아닌경우<br/>
 							- 상품명 오류 : 빈값<br/>
-							- 제조국 오류 : 빈값<br/>
-							- 제조년월일 오류 : 빈값, 날짜형식이 맞는지<br/>
-							- ERP 미존재 상품코드 : ERP에 상품코드가 존재하는지<br/>
 							- 스타일 연도 오류 : 온라인에서 관리되지 않는 스타일 연도<br/>
 							- 성별 오류 : 온라인에서 관리되지 않는 성별<br/>
 							- 컬러 오류 : 온라인에서 관리되지 않는 컬러<br/>
-							- 상품코드 중복등록요청 : 등록된 상품코드 등록요청<br/>
 							- 품목 오류 : 온라인에서 관리되지 않는 품목<br/>
-							- ERP 브랜드 오류 : 온라인에서 관리되지 않는 ERP 브랜드<br/>
-							- 이미지 유형 오류 : 온라인에서 관리되지 않는 이미지유형<br/>
-							- 상품이미지 필수 오류 : IMG_PATH1
 							- 품목의 고시정보 없음 : 품목의 고시분류 매핑이 안되어 있는 경우<br/>
-							- 고시분류 오류 : 등록요청 고시분류 와 온라인에서 품목과 매핑된 고시분류가 다른 경우<br/>
-							<em>상품등록</em><br/>
-							- ERP 상품 사이즈 정보 없음 : ERP에 상품코드의 사이즈가 없을 경우<br/>
 						</span>
 					</div>
 					<!-- //아이콘 툴팁 -->
 				</li>
-				<!-- <li class="right">
+				<li class="right">
 					<button type="button" class="btn btn-default btn-lg" id="btnGoodsRegExcelDownLoad">엑셀다운로드</button>
-				</li> -->
+				</li>
 			</ul>
 			<!-- //상단버튼 영역  -->
 			<div id="gridList" style="width: 100%; height: 500px;" class="ag-theme-balham"></div>

+ 16 - 9
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsSetForm.html

@@ -30,13 +30,18 @@
 							<i class="fa fa-info" aria-hidden="true"></i>
 							<span class="left" style="width:400px; text-align:left;">
 							<!-- class="left" 또는 class="right" -->
-								- 상품상태 : 정보부족<br/>
-								- 정상가 : 구성상품의 정상가 합<br/>
-								- 판매가 : 구성상품 판매가 입력값의 합<br/>
-								- 브랜드코드 : 구성상품의 기준여부 'Y'상품의 브랜드코드<br/>
-								- 품목코드 : 구성상품의 기준여부 'Y'상품의 품목코드<br/>
-								- 포인트 : 구성상품의 기준여부 'Y'상품의 브랜드 포인트<br/>
-								- 배송비정책 : 구성상품의 기준여부 'Y'상품의 브랜드 배송비정책<br/>
+								* 세트상품 정보<br/>
+								&nbsp;&nbsp;- 상품상태 : 정보부족<br/>
+								&nbsp;&nbsp;- 정상가 : 구성상품의 정상가 합<br/>
+								&nbsp;&nbsp;- 판매가 : 구성상품 판매가 입력값의 합<br/>
+								&nbsp;&nbsp;- 브랜드코드 : 구성상품의 기준여부 'Y'상품의 브랜드코드<br/>
+								&nbsp;&nbsp;- 품목코드 : 구성상품의 기준여부 'Y'상품의 품목코드<br/>
+								&nbsp;&nbsp;- 포인트 : 구성상품의 기준여부 'Y'상품의 브랜드 포인트<br/>
+								&nbsp;&nbsp;- 배송비정책 : 구성상품의 기준여부 'Y'상품의 브랜드 배송비정책<br/>
+								<br/>
+								* 구성상품 정보<br/>
+								&nbsp;&nbsp;- 구상상품판매가 : 구성상품의 수량만큼의 판매가 합 입력<br/>
+								&nbsp;&nbsp;- 구상상품의 기준상품 : 수정 불가<br/>
 							</span>
 						</div>
 						<!-- //아이콘 툴팁 --> 
@@ -158,7 +163,9 @@
 	gridGoodsSetOptions.getRowStyle = function(params) {
 		if ("Y" == params.data.baseYn) {
 			return { background: '#1ab394' };
-		}
+		}else{
+			return { background: '#ffffff' };
+		}	
 	}
 	
 	// Row 
@@ -218,7 +225,7 @@
 				if (goods.goodsCd == rowNode.data.compsGoodsCd){
 					isExist = true;
 				}
-				debugger;
+				
 				//같은 업체만 가능
 				if (goods.supplyCompCd != rowNode.data.supplyCompCd){
 					isExist = true;

+ 74 - 86
style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsWmsInstockForm.html → style24.admin/src/main/webapp/WEB-INF/views/goods/GoodsWmsIncomelotForm.html

@@ -3,7 +3,7 @@
 	xmlns:th="http://www.thymeleaf.org">
 <!--
  *******************************************************************************
- * @source  : GoodsWmsInstockForm.html
+ * @source  : GoodsWmsIncomelotForm.html
  * @desc    : WMS입고상품관리 화면
  *============================================================================
  * SISUN
@@ -22,9 +22,8 @@
 		<!-- 메뉴 설명 -->
 		<div class="infoBox menu-desc">
 		</div>
-		<form id="goodsUnregisterListForm" name="goodsUnregisterListForm" action="#" th:action="@{'/goods/unregister/list'}">
+		<form id="goodsWmsIncomelotForm" name="goodsWmsIncomelotForm" action="#" th:action="@{'/goods/wms/incomelot/list'}">
 		<input type="hidden" id="searchGb" name="searchGb" />
-		<input type="hidden" id="dateGbn" name="dateGbn" value="R" />
  		<!-- 패널 영역1 -->
 		<div class="panelStyle" >
 			<div class="panelTitle">
@@ -49,9 +48,9 @@
 								<option value="">[전체]</option>
 							</select>
 						</td>
-						<th>상품코드<i class="star"></i></th>
+						<th>모델번호<i class="star"></i></th>
 						<td>
-							<input id="goodsCd" name=goodsCd type="text" class="w150"  maxlength="20"/>
+							<input id="modelNo" name=modelNo type="text" class="w150"  maxlength="20"/>
 						</td>
 					</tr>
 					<tr>
@@ -70,6 +69,11 @@
 		</div>
 		<!-- 패널 영역1 -->
 		<div class="panelStyle">
+			<ul class="panelBar">
+				<li class="right">
+					<button type="button" class="btn btn-primary btn-lg"  id="btnCreateFreeGoods">사은품 등록</button>
+				</li>
+			</ul>
 			<!-- 검색결과 영역 -->
 			<div id="gridList" style="width: 100%; height: 500px;" class="ag-theme-balham"></div>
 			<ul class="panelBar">
@@ -86,43 +90,50 @@
 <script th:inline="javascript">
 /*<![CDATA[*/
 	var sessRoleCd = [[${sessionInfo.roleCd}]];
-	var goodsStatList = gagajf.convertToArray([[${goodsStatList}]]);
-	var itemkindList = gagajf.convertToArray([[${itemkindList}]]);
 	var columnDefs = [
-		/* {width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false}, */
+		{width: 40, minWidth: 40, cellClass: 'text-right', headerCheckboxSelection: true, checkboxSelection: true, filter: false}, 
 		{headerName: 'No', width: 60, cellClass: 'text-center', valueGetter: function(params) { return params.node.rowIndex + 1 }},
 		{headerName: "브랜드", field: "brandCd", width: 100, cellClass: 'text-center'},
 		{headerName: "브랜드명", field: "brandEnm", width: 130, cellClass: 'text-center'},
-		{headerName: "상품코드", field: "goodsCd", width: 120, cellClass: 'text-center'},
-		{headerName: "ERP상품명", field: "erpGoodsNm", width: 200, cellClass: 'text-left'},
-		{headerName: "상품명", field: "goodsNm", width: 200, cellClass: 'text-left'},
-		//{headerName: "품목코드", field: "itemkindCd", width: 100, cellClass: 'text-center'},
-		{headerName: "품목명", field: "itemkindCd" , width: 200, cellClass: 'text-left',
-			cellEditorParams: { values: gagaAgGrid.extractValues(itemkindList) },
-			valueFormatter: function (params) { return gagaAgGrid.lookupValue(itemkindList, params.value); },
-			valueParser: function (params) { return gagaAgGrid.lookupKey(itemkindList, params.newValue); }
-		},
+		{headerName: "WMS상품코드", field: "productCode", width: 120, cellClass: 'text-center'},
+		{headerName: "WMS상품명", field: "productName", width: 400, cellClass: 'text-left'},
+		{headerName: "모델번호", field: "modelNo" , width: 200, cellClass: 'text-center'},
 		{headerName: "등록일시", field: "regDt", width: 150, cellClass: 'text-center',
 			cellRenderer: function(params) {
 				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
 			}
 		},
-		{headerName: "등록자", field: "regId", width: 100, cellClass: 'text-center'},
+		{headerName: "등록자", field: "regNm", width: 100, cellClass: 'text-center'
+			,valueFormatter: function(params) {
+				if (params.data.regNo == 0) {
+					return '배치';
+				}else{
+					return params.value;
+				}
+			}
+		},
 		{headerName: "수정일시", field: "updDt", width: 150, cellClass: 'text-center',
 			cellRenderer: function(params) {
 				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
 			}
 		},
-		{headerName: "수정자", field: "updId", width: 100, cellClass: 'text-center'}
+		{headerName: "수정자", field: "updNm", width: 100, cellClass: 'text-center'
+			,valueFormatter: function(params) {
+				if (params.data.updNo == 0) {
+					return '배치';
+				}else{
+					return params.value;
+				}
+			}
+		}
 	];
 	
 	// Get GridOptions
 	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
 
 	// 중복 선택 가능
-	//gridOptions.rowSelection = 'multiple';
+	gridOptions.rowSelection = 'multiple';
 	gridOptions.suppressRowClickSelection = true;
-	//gridOptions.rowHeight = 60; //이미지가 있을경우 높이 지정해야함.
 
 	// 초기화 클릭시
 	$('#btnInit').on('click', function() {
@@ -130,50 +141,48 @@
 	});
 	
 	var fnInit = function(){
-		$('#goodsUnregisterListForm')[0].reset();
-		//$("#goodsUnregisterListForm input[type=radio]").removeClass("checked");
-		$("#goodsUnregisterListForm input[type=checkbox]").removeClass("checked");
-		//$("#goodsUnregisterListForm input[type=radio]").parent("label").removeClass("checked");
-		$("#goodsUnregisterListForm input[type=checkbox]").parent("label").removeClass("checked");
-		$("#goodsUnregisterListForm input[type=radio][checked]").parent("label").addClass("checked");
+		$('#goodsWmsIncomelotForm')[0].reset();
+		//$("#goodsWmsIncomelotForm input[type=radio]").removeClass("checked");
+		$("#goodsWmsIncomelotForm input[type=checkbox]").removeClass("checked");
+		//$("#goodsWmsIncomelotForm input[type=radio]").parent("label").removeClass("checked");
+		$("#goodsWmsIncomelotForm input[type=checkbox]").parent("label").removeClass("checked");
+		$("#goodsWmsIncomelotForm input[type=radio][checked]").parent("label").addClass("checked");
 	}
 	
 	// 조회클릭시
 	$('#btnSearch').on('click', function() {
-		fnGoodsUnregisterListSearch('BASIC');
+		fnGoodsWmsIncomelotListSearch('BASIC');
 	});
 
 	// 조회
-	var fnGoodsUnregisterListSearch = function(gbn) {
+	var fnGoodsWmsIncomelotListSearch = function(gbn) {
 
 		if (typeof(gbn) != 'undefined' &&  gbn == 'EXCEL'){
-			$("#goodsUnregisterListForm input[name=searchGb]").val("EXCEL");
-		}else if (typeof(gbn) != 'undefined' &&  gbn == 'EXCELRESULT'){
-			$("#goodsUnregisterListForm input[name=searchGb]").val("EXCELRESULT");
+			$("#goodsWmsIncomelotForm input[name=searchGb]").val("EXCEL");
 		}else{
-			$("#goodsUnregisterListForm input[name=searchGb]").val("BASIC");
+			$("#goodsWmsIncomelotForm input[name=searchGb]").val("BASIC");
 		}
 		
 		if(!fnConditionCheck()) return;
 		
-		gagaAgGrid.fetch($('#goodsUnregisterListForm').prop('action'), gridOptions, '#goodsUnregisterListForm');
+		gagaAgGrid.fetch($('#goodsWmsIncomelotForm').prop('action'), gridOptions, '#goodsWmsIncomelotForm');
 	}
 
 	//검색 조건 확인
 	var fnConditionCheck = function(){
-		var formId = '#goodsUnregisterListForm';
-		var form = document.goodsUnregisterListForm;
+		var formId = '#goodsWmsIncomelotForm';
+		var form = document.goodsWmsIncomelotForm;
 
-		if($("#goodsUnregisterListForm input[name=searchGb]").val() == "EXCEL" || $("#goodsUnregisterListForm input[name=searchGb]").val() == "EXCELRESULT") {
+		if($("#goodsWmsIncomelotForm input[name=searchGb]").val() == "EXCEL") {
 			return true;
 		}
 		
 		var searchFlag = false;
 		var cnt = 0;
 
-		/* if( !gagajf.isNull($("#goodsUnregisterListForm select[name=supplyCompCd]").val())
-				|| !gagajf.isNull($("#goodsUnregisterListForm input[name=condition]").val())
-				|| (!gagajf.isNull($("#goodsUnregisterListForm input[name=stDate]").val()) && !gagajf.isNull($("#goodsUnregisterListForm input[name=edDate]").val()))
+		/* if( !gagajf.isNull($("#goodsWmsIncomelotForm select[name=supplyCompCd]").val())
+				|| !gagajf.isNull($("#goodsWmsIncomelotForm input[name=condition]").val())
+				|| (!gagajf.isNull($("#goodsWmsIncomelotForm input[name=stDate]").val()) && !gagajf.isNull($("#goodsWmsIncomelotForm input[name=edDate]").val()))
 			){
 			searchFlag = true;
 		}else{ */
@@ -196,8 +205,8 @@
 			return false;
 		}
 		
-		var fromDate = $('#goodsUnregisterListForm input[name=stDate]').val();
-		var toDate = $('#goodsUnregisterListForm input[name=edDate]').val();
+		var fromDate = $('#goodsWmsIncomelotForm input[name=stDate]').val();
+		var toDate = $('#goodsWmsIncomelotForm input[name=edDate]').val();
 		
 		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
 			
@@ -205,7 +214,7 @@
 				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
 					sureBtnText: "확인",
 					sureBtnClick: function() {
-						$('#goodsUnregisterListForm input[name=stDate]').focus();
+						$('#goodsWmsIncomelotForm input[name=stDate]').focus();
 					}
 				});
 				return false;
@@ -215,7 +224,7 @@
 				mcxDialog.alert("노출기간 시작일자는 종료일자 보다 클 수 없습니다.", {
 					sureBtnText: "확인",
 					sureBtnClick: function() {
-						$('#goodsUnregisterListForm input[name=stDate]').focus();
+						$('#goodsWmsIncomelotForm input[name=stDate]').focus();
 					}
 				});
 				return false;
@@ -226,65 +235,44 @@
 	}
 	
 	//업체변경시
-	$('#goodsUnregisterListForm select[name=supplyCompCd]').on('change', function() {
+	$('#goodsWmsIncomelotForm select[name=supplyCompCd]').on('change', function() {
 		var actionUrl = '/renderer/supplyCompany/brand/list/' + $(this).val();
 
 		if(sessRoleCd == "B000"){
 			actionUrl = '/renderer/brand/AuthBrandlist';
 		}
-		$("#goodsUnregisterListForm select[name=brandCd] option:gt(0)").remove();
+		$("#goodsWmsIncomelotForm select[name=brandCd] option:gt(0)").remove();
 
-		cfnCreateCombo(actionUrl, $('#goodsUnregisterListForm select[name=brandCd]'), "[전체]", "");
+		cfnCreateCombo(actionUrl, $('#goodsWmsIncomelotForm select[name=brandCd]'), "[전체]", "");
 	});
 	
-	//엑셀 다운로드 클릭시
-	$('#btnGoodsUnregisterExcelDownLoad').on('click', function() {
-		//gagaAgGrid.exportToExcel('온라인미등록상품', gridOptions);
-		var date = new Date().format("YYYYMMDDHHmmss");
-		var params = {
-			
-			fileName : "온라인미등록상품_"+ date,
-			sheetName: "DATA"
+	
+	// 사은품 등록 클릭시
+	$('#btnCreateFreeGoods').on('click', function() {
+		
+		//선택된 상품
+		var selectedData = gridOptions.api.getSelectedRows();
+		
+		if (selectedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
 		}
-		gridOptions.excelStyles = [
-			{
-				id: 'text-center',
-				dataType: 'string',
-				font: {size : 10, bold: false}
-			},
-			{
-				id: 'text-left',
-				dataType: 'string',
-				font: {size : 10, bold: false}
-			}
-		]
 		
-		gridOptions.api.exportDataAsExcel(params);
-	});
-	
-	//엑셀 상품명/품목코드 저장
-	$('#btnGoodsExcelSave').on('click', function() {
-		cfnExcelUploadPopup('goodsInfoExcelUpload', 'goodsInfoExcelSave');
-	});
-	
-	var goodsInfoExcelSave = function(result){
-		mcxDialog.confirm('상품명/품목코드 저장을 진행하시겠습니까?', {
+		mcxDialog.confirm('사은품 등록을 하시겠습니까?', {
 			cancelBtnText: "취소",
 			sureBtnText: "확인",
 			sureBtnClick: function(){
-				var data = {procJob : result.procJob
-						,excelFileNm : result.excelFileNm
-						};
-			var jsonData = JSON.stringify(data);
-			gagajf.ajaxJsonSubmit('/goods/unregister/excelupload/save', jsonData, fnGoodsInfoExcelSaveCallBack);
+				var jsonData = JSON.stringify(selectedData);
+				gagajf.ajaxJsonSubmit('/goods/free/goods/save', jsonData, fnCreateFreeGoodsCollback);
 			}
-		});	
-	}
+		});
+	});
 	
-	var fnGoodsInfoExcelSaveCallBack = function(result){
-		fnGoodsUnregisterListSearch("EXCELRESULT");
+	var fnCreateFreeGoodsCollback = function(result){
+		fnGoodsWmsIncomelotListSearch('BASIC');
 	}
 	
+	
 	$(document).ready(function() {
 
 		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일');

+ 2 - 2
style24.admin/src/main/webapp/WEB-INF/views/marketing/FreeGoodsPromotionForm.html

@@ -95,7 +95,7 @@
 				<div id="gridList" style="width: 100%; height: 700px;" class="ag-theme-balham lh60"></div>
 			</div>
 		</form>
-<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js"></script>
 <script th:inline="javascript">
 /*<![CDATA[*/
 	var columnDefs = [];
@@ -205,7 +205,7 @@
 
 	// 조회클릭시
 	$('#btnFreeGoodsRegi').on('click', function() {
-		cfnOpenFreeGoodsPromotionSetPopup();
+		cfnOpenFreeGoodsPromotionSetPopup('C');
 	});
 
 

+ 98 - 58
style24.admin/src/main/webapp/WEB-INF/views/marketing/FreeGoodsPromotionRegiForm.html

@@ -29,27 +29,9 @@
 				<input type="hidden" id="exceptGoodsCds" name="exceptGoodsCds"/>		<!-- 제외상품 리스트 -->
 				<input type="hidden" id="freeGoods1Cds" name="freeGoods1Cds"/>			<!-- 적용 사은품1 리스트 -->
 				<input type="hidden" id="freeGoods2Cds" name="freeGoods2Cds"/>			<!-- 적용 사은품2 리스트 -->
+				<input type="hidden" id="extmallIds" name="extmallIds" value=""/>			<!-- 적용 사은품2 리스트 -->
 
 				<div class="panelContent">
-					<ul class="notice">
-						<li>구성상품 등록시 기본값&nbsp;
-							<!-- 아이콘 툴팁 -->
-							<div class="iconTooltip">
-								<i class="fa fa-info" aria-hidden="true"></i>
-								<span class="left" style="width:400px; text-align:left;">
-									<!-- class="left" 또는 class="right" -->
-									- 상품상태 : 정보부족<br/>
-									- 정상가 : 구성상품의 정상가 합<br/>
-									- 판매가 : 구성상품 판매가 입력값의 합<br/>
-									- 브랜드코드 : 구성상품의 기준여부 'Y'상품의 브랜드코드<br/>
-									- 품목코드 : 구성상품의 기준여부 'Y'상품의 품목코드<br/>
-									- 포인트 : 구성상품의 기준여부 'Y'상품의 브랜드 포인트<br/>
-									- 배송비정책 : 구성상품의 기준여부 'Y'상품의 브랜드 배송비정책<br/>
-								</span>
-							</div>
-							<!-- //아이콘 툴팁 -->
-						</li>
-					</ul>
 					<table class="frmStyle">
 						<colgroup>
 							<col width="10%"/>
@@ -61,7 +43,7 @@
 							<th>프로모션명<em class="required" title="필수"></em></th>
 							<td>
 								<!-- 수정시 프로모션명 입력 : before -->
-								<input class="w50p" type="text" id="freegiftNm" name="freegiftNm" maxlength="30"/>
+								<input class="w50p" type="text" id="freegiftNm" name="freegiftNm" minlength="2" maxlength="30" required="required" data-valid-name="프로모션명"/>
 							</td>
 							<th>프로모션ID</th>
 							<td>
@@ -86,8 +68,9 @@
 						<tr>
 							<th>적용 몰 구분<em class="required" title="필수"></em></th>
 							<td colspan="3">
-								<!-- 적용 몰 구분 입력(공통 가져와야할듯?) : before -->
-								<input type="checkbox" id="jasa"/><label for="jasa">자사몰</label>
+								<label class="chkBox"><input type="checkbox" name="mallCds" value="G011_10"/>자사몰</label>
+								<label class="chkBox" id="G011_20"><input type="checkbox" name="mallCds" value="G011_20"/>제휴몰</label>
+								<button type="button" class="btn btnRight btn-success btn-lg" id="btnExtmallPopup">선택</button><span id="extmallCntArea"> 선택 : <span id="extmallCnt">00</span>개</span>
 							</td>
 						</tr>
 					</table>
@@ -122,7 +105,7 @@
 											<div class="padding10 inner-tb-solid">
 												<button type="button" class="btn btnRight btn-success btn-lg" id="btnAddCompany">업체 추가</button>
 												<button type="button" class="btn btnRight btn-success btn-lg" id="btnDeleteCompany">선택삭제</button>
-												<span>선택 : 00개</span>
+												<span>선택 : <span id="companyCnt">00</span>개</span>
 												<br/>
 												<div id="gridFGPromotionCompanyList" style="width:100%; height:200px;" class="ag-theme-balham"></div>
 											</div>
@@ -132,7 +115,7 @@
 											<div class="padding10 inner-tb-solid">
 												<button type="button" class="btn btnRight btn-success btn-lg" id="btnAddBrand">브랜드 추가</button>
 												<button type="button" class="btn btnRight btn-success btn-lg" id="btnDeleteBrand">선택삭제</button>
-												<span>선택 : 00개</span>
+												<span>선택 : <span id="brandCnt">00</span>개</span>
 												<br/>
 												<!-- 브랜드 선택 팝업(단수 선택 팝업... 복수를 새로 만들어야하는지 ? 아니면 변수처리해야하는지 ? -->
 												<div id="gridFGBrandList" style="width:100%; height:200px;" class="ag-theme-balham"></div>
@@ -146,7 +129,7 @@
 										<div class="padding10">
 											<button type="button" class="btn btnRight btn-success btn-lg" id="btnAddApplyGoods">상품 추가</button>
 											<button type="button" class="btn btnRight btn-success btn-lg" id="btnDeleteApplyGoods">선택삭제</button>
-											<span>선택 : 00개</span>
+											<span>선택 : <span id="applyGoodsCnt">00</span>개</span>
 											<br/>
 											<div id="gridFGApplyGoodsList" style="width:100%; height:200px;" class="ag-theme-balham"></div>
 										</div>
@@ -179,7 +162,7 @@
 										<div class="padding10">
 											<button type="button" class="btn btnRight btn-success btn-lg" id="btnAddExceptGoods">상품 추가</button>
 											<button type="button" class="btn btnRight btn-success btn-lg" id="btnDeleteExtGoods">선택삭제</button>
-											<span>선택 : 00개</span>
+											<span>선택 : <span id="exceptGoodsCnt">00</span>개</span>
 											<br/>
 											<div id="gridFGExceptGoodsList" style="width:100%; height:200px;" class="ag-theme-balham"></div>
 										</div>
@@ -210,8 +193,8 @@
 									<th>지급 방법<em class="required" title="필수"></em></th>
 									<td>
 										<div>
-											<span><label class="rdoBtn"><input type="radio" name="sendBox"/>모두 지급 (설정한 사은품을 모두 지급합니다)</label></span>
-											<span><label class="rdoBtn"><input type="radio" name="sendBox"/>선택 사은품 (목록 중 1개를 선택하게 합니다)</label></span>
+											<span><label class="rdoBtn"><input type="radio" name="allYn" value="Y" checked/>모두 지급 (설정한 사은품을 모두 지급합니다)</label></span>
+											<span><label class="rdoBtn"><input type="radio" name="allYn" value="N"/>선택 사은품 (목록 중 1개를 선택하게 합니다)</label></span>
 										</div>
 									</td>
 								</tr>
@@ -226,8 +209,6 @@
 											<span>사은품 목록</span>
 											<button type="button" class="btn btnRight btn-success btn-lg" id="btnAddFreeGoods1">+ 사은품 선택</button>
 											<button type="button" class="btn btnRight btn-success btn-lg" id="btnDeleteFreeGoods1">선택삭제</button>
-											<input type="button" value="+ 사은품 선택" id="goodsList" /> <!-- 선택 시 팝업 노출 -->
-											<input type="button" value="선택삭제" id="deleteGoodsList" />
 											<br/>
 											<div id="gridFreeGoods1List" style="width:100%; height:200px;" class="ag-theme-balham"></div>
 										</div>
@@ -250,8 +231,7 @@
 						</div>
 					</div>
 				</div>
-
-				<div class="panelStyle" style="margin:unset;">
+				<div class="panelStyle" th:if="${#strings.toString(param.gbn) == 'U'}" style="margin:unset;">
 					<!-- //TITLE -->
 					<div class="inner-panelContent">
 						<div class="panelContent">
@@ -362,15 +342,8 @@
 				cellEditorParams: { maxlength: 14, validType: 'numeric'}
 			},
 			{headerName: "한정수량", field: "limitQty" , width: 100, cellClass: 'text-center'
-				,valueFormatter: function(params) {
-					if(params.value && params.value > 0) {
-						return params.value.addComma();
-					} else {
-						return 0;
-					}
-				},
-				cellEditor: 'textCellEditor',
-				cellEditorParams: { maxlength: 14, validType: 'numeric'}
+				,cellEditor: 'textCellEditor'
+				,cellEditorParams: { maxlength: 14, validType: 'numeric'}
 			},
 			{headerName: "잔여수량", field: "leftQty", width: 120, cellClass: 'text-center'
 				,valueFormatter: function(params) {
@@ -460,20 +433,55 @@
 			cfnCreateCalendar('#promotionTerms', 'freegoodsStdt', 'freegoodsEddt', true, '행사기간', 'X');
 		});
 
+		// 제휴몰 체크 상태 확인
+		$("#G011_20").on("click", function() {
+			// 체크여부 확인 (선택되면 자동 checked 추가되는데, 추가되기 전 동작해서 반대로 지정)
+			if($("#G011_20").hasClass("checked")) {
+				$("#btnExtmallPopup").hide();
+				$("#extmallCntArea").hide();
+				$("#extmallCnt").text(0);
+				$("#extmallIds").val("");
+			} else {
+				$("#btnExtmallPopup").show();
+				$("#extmallCntArea").show();
+			}
+		});
+
+		$('#freeGoodsPromotionForm input[name=freegiftNm]').on('focusout', function() {
+			if($('#freeGoodsPromotionForm input[name=freegiftNm]').val().length < 2) {
+				mcxDialog.alert("2자~30자 이상 프로모션명을 입력하세요.");
+				return;
+			}
+		});
+
+		// list 데이터 세팅
+		function setSendGridListVal(gridListOption, key, inputId) {
+			let list = gagaAgGrid.getAllRowData(gridListOption);
+			let cds = [];
+			for(let k = 0 ; k < list.length ; k++) {
+				cds.push(eval("list[k]." + key));
+			}
+
+			var jsonData = JSON.stringify(cds);
+			$("#" + inputId).val(jsonData);
+		}
+
 		// 저장 버튼 클릭시
-		$('#freeGoodsPromotionForm #btnFreegoodsPromotionSave').on('click', function() {
+		$('#btnFreegoodsPromotionSave').on('click', function() {
 			// 각 ag-grid list 수량
 			let supplyCompCnt = gagaAgGrid.getAllRowData(gridOptionsFGCompanyList).length;
 			let brandCnt = gagaAgGrid.getAllRowData(gridOptionsFGBrandList).length;
 			let applyGoodsCnt = gagaAgGrid.getAllRowData(gridOptionsFGApplyGoodsList).length;
-			// let supplyCompCnt = gagaAgGrid.getAllRowData(gridOptionsFGExceptGoodsList).length;
+			let exceptGoodsCnt = gagaAgGrid.getAllRowData(gridOptionsFGExceptGoodsList).length;
 			let freeGoods1Cnt = gagaAgGrid.getAllRowData(gridOptionsFreeGoods1List).length;
 			let freeGoods2Cnt = gagaAgGrid.getAllRowData(gridOptionsFreeGoods2List).length;
 
-			// 프로모션명 확인
-			if(gagajf.isEmpty($("#freeGoodsPromotionForm #freegiftNm").val())) {
-				mcxDialog.alert("프로모션명을 입력해주세요");
-				$("#freeGoodsPromotionForm #freegiftNm").focus();
+			if (!gagajf.validation('#freeGoodsPromotionForm')) {
+				return false;
+			};
+
+			if($('#freeGoodsPromotionForm input[name=freegiftNm]').val().length < 2) {
+				mcxDialog.alert("2자~30자 이상 프로모션명을 입력하세요.");
 				return false;
 			}
 
@@ -481,14 +489,8 @@
 			let fromDate = $('#freeGoodsPromotionForm input[name=freegiftStdt]').val();
 			let toDate = $('#freeGoodsPromotionForm input[name=freegiftEddt]').val();
 
-			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
-				mcxDialog.alert("행사 기간 시작일자와 종료일자를 입력하세요.");
-				$('#freeGoodsPromotionForm input[name=freegiftStdt]').focus();
-				return false;
-			}
-
 			if (fromDate > toDate) {
-				mcxDialog.alert("시작일자는 종료일자 보다  수 없습니다.");
+				mcxDialog.alert("시작일자는 종료일자 보다 늦을 수 없습니다.");
 				$('#freeGoodsPromotionForm input[name=freegiftStdt]').focus();
 				return false;
 			}
@@ -517,7 +519,12 @@
 				return false;
 			}
 
-
+			// 각 리스트 데이터 세팅
+			if(supplyCompCnt > 0) { setSendGridListVal(gridOptionsFGCompanyList, "supplyCompCd", "supplyCompCds"); }		// 공급업체 설정 데이터
+			if(brandCnt > 0) { setSendGridListVal(gridOptionsFGBrandList, "brandCd", "brandCds"); }							// 브랜드 설정 데이터
+			if(applyGoodsCnt > 0) { setSendGridListVal(gridOptionsFGApplyGoodsList, "goodsCd", "applyGoodsCds"); }			// 적용 상품 설정 데이터
+			if(exceptGoodsCnt > 0) { setSendGridListVal(gridOptionsFGExceptGoodsList, "goodsCd", "exceptGoodsCds"); }		// 제외 상품 설정 데이터
+			if(freeGoods1Cnt > 0) { setSendGridListVal(gridOptionsFreeGoods1List, "goodsCd", "freeGoods1Cds"); }			// 사은품 조건 1
 		});
 
 		// 공급업체 설정 / 업체 추가 콜백함수
@@ -535,6 +542,8 @@
 				// 중복되지 않은 데이터 리스트에 추가
 				if(addChk) {	gagaAgGrid.addRowData(gridOptionsFGCompanyList, result[i], "supplyCompCd");	}
 			}
+
+			$("#companyCnt").text(gridOptionsFGCompanyList.api.getDisplayedRowCount());
 		};
 
 		// 브랜드 설정 / 브랜드 추가 콜백함수 (단수로 가져오므로 복수일 경우에 수정 확인 필요)
@@ -550,16 +559,20 @@
 				// 중복되지 않은 데이터 리스트에 추가
 				if(addChk) {	gagaAgGrid.addRowData(gridOptionsFGBrandList, result[i], "brandCd");	}
 			}
+
+			$("#brandCnt").text(gridOptionsFGBrandList.api.getDisplayedRowCount());
 		};
 
 		// 적용 상품 리스트 콜백함수
 		var fnSetPopupApplyGoodsInfo = function(result) {
 			gridAddGoodsList(gridOptionsFGApplyGoodsList, result);
+			$("#applyGoodsCnt").text(gridOptionsFGApplyGoodsList.api.getDisplayedRowCount());
 		};
 
 		// 제외 상품 리스트 콜백함수
 		var fnSetPopupExceptGoodsInfo = function(result) {
 			gridAddGoodsList(gridOptionsFGExceptGoodsList, result);
+			$("#exceptGoodsCnt").text(gridOptionsFGExceptGoodsList.api.getDisplayedRowCount());
 		};
 
 		// 사은품 조건1 상품 리스트 콜백함수
@@ -567,7 +580,7 @@
 			gridAddGoodsList(gridOptionsFreeGoods1List, result);
 		};
 
-		// 사은품 조건1 상품 리스트 콜백함수
+		// 사은품 조건2 상품 리스트 콜백함수
 		var fnSetPopupFreeGoods2Info = function(result) {
 			gridAddGoodsList(gridOptionsFreeGoods2List, result);
 		};
@@ -587,16 +600,39 @@
 			}
 		}
 
+		// 제휴몰 list 콜백함수
+		function fnSetPopupExtmallInfo(result) {
+			let extmallIds = [];
+			if($("#extmallIds").val() != null && $("#extmallIds").val() != "") {
+				extmallIds = JSON.parse($("#extmallIds").val());
+			}
+
+			for(let i = 0 ; i < result.length ; i++) {
+				let addChk = true;
+				for(let j = 0 ; j < extmallIds.length ; j++) {
+					if(result[i].extmallId == extmallIds[j]) {	addChk = false;	}
+				}
+
+				if(addChk) {	extmallIds.push(result[i].extmallId)	};
+			}
+
+			var jsonData = JSON.stringify(extmallIds);
+			$("#extmallIds").val(jsonData);
+			$("#extmallCnt").text(extmallIds.length);
+		}
+
+		// 제휴몰 선택 버튼 클릭시
+		$('#freeGoodsPromotionForm #btnExtmallPopup').on('click', function() {
+			cfnOpenExtmallListPopup("fnSetPopupExtmallInfo");
+		});
 		// 공급업체 설정 업체 추가 버튼 클릭시
 		$('#freeGoodsPromotionForm #btnAddCompany').on('click', function() {
 			cfnOpenCompanyListPopup("fnSetPopupComapnyInfo");
 		});
-
 		// 브랜드 추가 버튼 클릭시 (복수 브랜드때 수정 필요)
 		$('#freeGoodsPromotionForm #btnAddBrand').on('click', function() {
 			cfnOpenBrandListPopup("fnSetPopupBrandInfo", "M");
 		});
-
 		// 적용 상품 추가 버튼 클릭시
 		$('#freeGoodsPromotionForm #btnAddApplyGoods').on('click', function() {
 			cfnOpenGoodsPopup("fnSetPopupApplyGoodsInfo");
@@ -617,18 +653,22 @@
 		// 공급업체 설정 선택삭제 버튼 클릭시
 		$('#freeGoodsPromotionForm #btnDeleteCompany').on('click', function() {
 			gridOptionsFGCompanyList.api.updateRowData({remove:gagaAgGrid.selectedRowData(gridOptionsFGCompanyList)});
+			$("#companyCnt").text(gridOptionsFGCompanyList.api.getDisplayedRowCount());
 		});
 		// 브랜드 설정 선택삭제 버튼 클릭시
 		$('#freeGoodsPromotionForm #btnDeleteBrand').on('click', function() {
 			gridOptionsFGBrandList.api.updateRowData({remove:gagaAgGrid.selectedRowData(gridOptionsFGBrandList)});
+			$("#brandCnt").text(gridOptionsFGBrandList.api.getDisplayedRowCount());
 		});
 		// 적용상품 선택삭제 버튼 클릭시
 		$('#freeGoodsPromotionForm #btnDeleteApplyGoods').on('click', function() {
 			gridOptionsFGApplyGoodsList.api.updateRowData({remove:gagaAgGrid.selectedRowData(gridOptionsFGApplyGoodsList)});
+			$("#applyGoodsCnt").text(gridOptionsFGApplyGoodsList.api.getDisplayedRowCount());
 		});
 		// 제외상품 선택삭제 버튼 클릭시
 		$('#freeGoodsPromotionForm #btnDeleteExtGoods').on('click', function() {
 			gridOptionsFGExceptGoodsList.api.updateRowData({remove:gagaAgGrid.selectedRowData(gridOptionsFGExceptGoodsList)});
+			$("#exceptGoodsCnt").text(gridOptionsFGExceptGoodsList.api.getDisplayedRowCount());
 		});
 		// 사은품조건1 선택삭제 버튼 클릭시
 		$('#freeGoodsPromotionForm #btnDeleteFreeGoods1').on('click', function() {

+ 233 - 0
style24.admin/src/main/webapp/WEB-INF/views/marketing/MorebetterListForm.html

@@ -0,0 +1,233 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : MorebetterListForm.html
+ * @desc    : 다다익선 관리 페이지
+ *============================================================================
+ * SISUN
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.12.28   bin2107   최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+		
+		<!-- 메뉴 설명 -->
+		<!--<div class="infoBox menu-desc">
+		</div>-->
+		<form id="searchForm" name="searchForm" action="#" th:action="@{'/marketing/morebetter/list'}">
+			<input type="hidden" id="searchGb" name="searchGb" />
+			<input type="hidden" id="imageViewYn" name="imageViewYn" />
+			<input type="hidden" id="goodsPriceYn" name="goodsPriceYn" value="Y"/> <!-- 즉시할인판매가 조회 -->
+
+				<!-- 패널 영역1 -->
+			<div class="panelStyle" >
+				<!-- 검색조건 영역 -->
+				<!-- TITLE -->
+				<div class="panelTitle">
+					<!--<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 <font color="red">업체, 키워드, 발생일</font>중 하나를 꼭 입력해 주세요.</h3>-->
+					<h3><i class="fa fa-info-circle"></i>검색조건</h3>
+					<span class="panelControl">
+						<i class="fa fa-chevron-up"></i>
+					</span>
+				</div>
+				<!-- //TITLE -->
+				<div class="panelContent">
+					<table class="frmStyle">
+						<colgroup>
+							<col style="width: 7%;"/>
+							<col/>
+						</colgroup>
+
+						<tr>
+							<th>기간</th>
+							<td id="sellTerms"></td>
+						</tr>
+
+						<tr>
+							<th>프로모션 조회</th>
+							<td>
+								<label class="rdoBtn"><input type="radio" name="searchGubun" id="promotionId" value="tmtbSq"  checked/>프로모션ID</label>
+								<label class="rdoBtn"><input type="radio" name="searchGubun" id="promotionName" value="tmtbNm"/>프로모션명</label>
+								<input type="text" class="w900" name="searchTxt" id="searchTxt" />
+							</td>
+						</tr>
+					</table>
+					<ul class="panelBar">
+						<li class="center">
+							<button type="button" class="btn btn-gray btn-lg" id="btnInit" >초기화</button>
+							<button type="button" class="btn btn-info btn-lg" id="btnSearch" >조회</button>
+						</li>
+					</ul>
+				</div>
+				<!-- //검색조건 영역 -->
+			</div>
+
+			<!-- 패널 영역1 -->
+			<div class="panelStyle">
+				<!-- 상단버튼 영역  -->
+				<ul class="panelBar">
+					<li class="right">
+						검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+						쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+						<select id="pageSize" name="pageSize">
+							<option value="50" selected="selected">50개씩 보기</option>
+							<option value="100">100개씩 보기</option>
+							<option value="500">500개씩 보기</option>
+							<option value="1000">1000개씩 보기</option>
+						</select>
+						<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+					</li>
+				</ul>
+				<div class="panelBar">
+					<div class="right">
+						<button type="button" class="btn btn-info btn-lg" id="btnFreeGoodsRegi" >프로모션등록</button>
+					</div>
+				</div>
+				<!-- 검색결과 영역 -->
+				<!--<div id="gridList" style="width: 100%; height: 700px;" class="ag-theme-balham lh60"></div>-->
+				<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
+			</div>
+		</form>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=2019072202"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var columnDefs = [];
+	columnDefs = [
+		{headerName: "프로모션ID", field: "tmtbSq", width: 80, cellClass: 'text-center'},
+		{headerName: "프로모션명", field: "tmtbNm", width: 130, cellClass: 'text-center'},
+		{headerName: "상태", field: "tmtbStat", width: 140, cellClass: 'text-center'},
+		{headerName: "시작일", field: "tmtbStdt", width: 140, cellClass: 'text-center'},
+		{headerName: "종료일", field: "tmtbEddt", width: 140, cellClass: 'text-center'},
+		{headerName: "등록자", field: "regNm", width: 200, cellClass: 'text-left'
+			,cellRenderer: function(params) {
+				return params.value + "(" + params.data.regDt + ")";
+			}
+		},
+		{headerName: "최종수정자", field: "updNm", width: 200, cellClass: 'text-left'
+			,cellRenderer: function(params) {
+				return params.value + "(" + params.data.updDt + ")";
+			}
+		}
+	];
+
+	// Get GridOptions
+	var gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// Row Click
+	gridOptions.onCellClicked = function(event) {
+		var goodsCd = event.data.goodsCd;
+		if (event.colDef.field == "tmtbNm"){
+			// 수정 필요
+			// cfnOpenGoodsDetailPopup('U',goodsCd);
+		}
+	}
+
+	// 어떤건지 확인 필요
+	/* gridOptions.getRowStyle = function(params) {
+		if ("G008_00" == params.data.goodsStat  || "G008_10" == params.data.goodsStat || "G008_20" == params.data.goodsStat || "G008_30" == params.data.goodsStat) {
+			return { background: '#23c6c8' };
+		}
+	} */
+
+	// 초기화 클릭시
+	$('#btnInit').on('click', function() {
+
+		$('#searchForm')[0].reset();
+		//$("#searchForm input[type=radio]").removeClass("checked");
+		$("#searchForm input[type=checkbox]").removeClass("checked");
+		//$("#searchForm input[type=radio]").parent("label").removeClass("checked");
+		$("#searchForm input[type=checkbox]").parent("label").removeClass("checked");
+		$("#searchForm input[type=radio][checked]").parent("label").addClass("checked");
+	});
+
+	// 조회클릭시
+	$('#btnSearch').on('click', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnMorebetterListSearch();
+	});
+
+	// 조회
+	var fnMorebetterListSearch = function() {
+		if(!fnConditionCheck()) return;
+
+		gagaPaging.init('searchForm', fnSearchCallBack, 'morebetterListPagination', $('#searchForm').find('#pageSize').val());
+		gagaPaging.load($("#searchForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var fromDate = $('#searchForm input[name=tmtbStdt]').val();
+		var toDate = $('#searchForm input[name=tmtbEddt]').val();
+
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("기간 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=tmtbStdt]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("등록 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=tmtbEddt]').focus();
+					}
+				});
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	var fnSearchCallBack = function(result){
+
+		$('#searchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#searchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.morebetterList);
+		gagaPaging.createPagination(result.pageing.pageable);
+		
+	}
+
+	// 조회클릭시
+	$('#btnMorebetterRegi').on('click', function() {
+		cfnOpenMorebetterSetPopup();
+	});
+
+
+	//페이징
+	$('#searchForm select[name=pageSize]').on('change', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnMorebetterListSearch();
+	});
+
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'tmtbStdt', 'tmtbEddt', true, '기간', 'X');
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+/*]]>*/
+</script>
+	</div>
+
+</html>

+ 133 - 0
style24.admin/src/main/webapp/WEB-INF/views/ocm/ExtmallSearchForm.html

@@ -0,0 +1,133 @@
+<!DOCTYPE html>
+<html lang="ko"
+	  xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ExtmallSearchForm.html
+ * @desc    : 제휴몰 리스트 팝업
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.12.28   xodud1202   최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="500" id="popupExtmallList">
+	<div class="panelStyle">
+		<!-- TITLE -->
+		<div class="panelTitle">
+			<strong>공급업체 목록</strong>
+			<button type="button" class="close" onclick="uifnPopupClose('popupExtmallList');"><em class="fa fa-times"></em></button>
+		</div>
+		<!-- //TITLE -->
+
+		<!-- 검색 조건 -->
+		<div class="panelContent">
+			<form id="searchExtmallListForm" name="searchExtmallListForm" action="#" th:action="@{'/ocm/extmall/list'}" onsubmit="$('#btnSearchExtmallList').trigger('click'); return false;">
+
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col style="width:15%;"/>
+						<col/>
+					</colgroup>
+					<tbody>
+					<tr>
+						<th>제휴몰 명</th>
+						<td>
+							<input type="text" name="searchTxt" th:value="${params.searchTxt}" maxlength="20" onkeypress="if (event.keyCode == 13) { $('#btnSearchExtmallList').trigger('click'); }"/>
+						</td>
+					</tr>
+					</tbody>
+				</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearchExtmallList">조회</button>
+					</li>
+				</ul>
+			</form>
+		</div>
+		<!-- //검색 조건 -->
+
+		<!-- 리스트 영역 -->
+		<div class="panelContent">
+			<div id="gridComapanyPopupList" style="width: 100%; height: 470px" class="ag-theme-balham"></div>
+		</div>
+		<!-- //리스트 영역 -->
+
+		<!-- 버튼 배치 영역 -->
+		<ul class="panelBar">
+			<li class="right">
+				<button type="button" class="btn btn-info btn-lg" id="btnConfirmExtmall">확인</button>
+			</li>
+		</ul>
+	</div>
+
+	<script th:inline="javascript">
+		/*<![CDATA[*/
+		let extmallGbList = gagajf.convertToArray([[${extmallGbList}]]);		// 상품 상태 리스트
+		let columnExtmallPopupDefList = [
+			{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
+			{headerName: "제휴몰구분", field: "vendorId" , width: 120, cellClass: 'text-center',
+				cellEditorParams: { values: gagaAgGrid.extractValues(extmallGbList) },
+				valueFormatter: function (params) { return gagaAgGrid.lookupValue(extmallGbList, params.value); },
+				valueParser: function (params) { return gagaAgGrid.lookupKey(extmallGbList, params.newValue); }
+			},
+			{headerName: "제휴몰ID", field: "extmallId", width: 150, cellClass: 'text-center'},
+			{headerName: "제휴몰명", field: "extmallNm", width: 150, cellClass: 'text-center'}
+		];
+
+		let gridOptionsExtmallPopupList = gagaAgGrid.getGridOptions(columnExtmallPopupDefList);
+		gridOptionsExtmallPopupList.rowSelection = "multiple";
+
+		// Row double click
+		gridOptionsExtmallPopupList.onRowDoubleClicked = function(event) {
+			$('#btnConfirmExtmall').trigger('click');
+		}
+
+		// 조회
+		$('#btnSearchExtmallList').on('click', function() {
+			// Fetch data
+			gagaAgGrid.fetch($('#searchExtmallListForm').prop('action'), gridOptionsExtmallPopupList, '#searchExtmallListForm');
+		});
+
+		// 확인
+		$('#btnConfirmExtmall').on('click', function() {
+			var selectedData = gagaAgGrid.selectedRowData(gridOptionsExtmallPopupList);
+
+			if (selectedData.length == 0) {
+				mcxDialog.alert('선택된 공급업체가 없습니다.');
+				return false;
+			}
+
+			var callbackFn = [[${params.callbackFn}]];
+
+			var jsonData = JSON.stringify(selectedData);
+
+			if (typeof callbackFn != 'undefined' && callbackFn) {
+				if (typeof callbackFn == 'function') {
+					callbackFn(jsonData);
+				} else {
+					if (callbackFn) {
+						if (callbackFn.indexOf("(") == -1) {
+							eval(callbackFn + "(" + jsonData + ")");
+						} else {
+							eval(callbackFn(jsonData));
+						}
+					}
+				}
+				uifnPopupClose('popupExtmallList');
+			}
+		});
+
+		$(document).ready(function() {
+			// Create a agGrid
+			gagaAgGrid.createGrid('gridComapanyPopupList', gridOptionsExtmallPopupList);
+		});
+		/*]]>*/
+	</script>
+
+</div>
+
+</html>

+ 248 - 133
style24.admin/src/main/webapp/WEB-INF/views/order/CancelRequestForm.html

@@ -21,13 +21,20 @@
 		</div>
 			
 		<div class="panelContent" style="height:90%; overflow-y:auto; padding:0px 20px !important; ">
-			<form id="cancelRequestFrm">
+			<form id="cancelRequestFrm" name="cancelRequestFrm" action="/order/cancel" method="post" target="hdFrameForOrderCancel">
+				<input type="hidden" name="ordNo" th:value="${ordNo}"/>
+				<input type="hidden" name="chgReason" value=""/>
+				<input type="hidden" name="chgReasonDesc" value=""/>
+				
 				<h3>주문정보</h3>
 				<div id="gridOrderCancelRequestList" style="width:100%; height: 200px;" class="ag-theme-balham"></div>
 
 				<h3>취소정보</h3>
 				<div id="gridOrderCancelRequestToBeList" style="width:100%; height: 200px;" class="ag-theme-balham"></div>
 				
+				<h3>배송비정보</h3>
+				<div id="gridDelvCdList" style="width:100%; height: 140px;" class="ag-theme-balham"></div>
+				
 				<div style="text-align:right; padding-bottom:5px; padding-top:5px;">
 					<button type="button" class="btn btn-success" id="btnCancelRequestEscrow" onclick="fnCancelRequestEscrow();" style="display:none;">에스크로 결제생성</button>
 					<label th:if="${sessionInfo.userId == 'jsshin'
@@ -54,7 +61,7 @@
 							<td>
 								<select name="selectChgReason" onchange="fnChangeChgReason($(this).val());">
 									<option value="">[선택하세요]</option>
-									<option th:if="${chgReasonList}" th:each="oneData, status : ${chgReasonList}" th:value="|${oneData.cd}:${oneData.cdDesc}|" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+									<option th:if="${chgReasonList}" th:each="oneData, status : ${chgReasonList}" th:value="|${oneData.cd}:${oneData.cdNm}|" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
 								</select>
 							</td>
 							<th>귀책사유</th>
@@ -63,12 +70,12 @@
 						<tr>
 							<th>요청메모</th>
 							<td colspan="3">
-								<textarea name="chgMemo" style="height:80px;" placeholder="취소사유를 300자내외로 작성해 주세요"></textarea>
+								<textarea id="chgMemo" name="chgMemo" style="height:80px;" placeholder="취소사유를 300자내외로 작성해 주세요"></textarea>
 							</td>
 						</tr>
 					</tbody>
 				</table>
-
+				
 				<h4>환불예정금액</h4>
 				<table class="frmStyle">
 					<colgroup>
@@ -80,24 +87,40 @@
 					<tbody>
 						<tr>
 							<th>총 결제 금액</th>
-							<td><span id="spanPayAmt"></span>원 (상품 실결제 금액 : <span id="spanSumRealOrdAmt"></span>원, 배송금액 : <span id="spanDeliveryFee"></span>원) </td>
+							<td colspan="3"><span id="spanPayAmt"></span>원 (상품 실결제 금액 : <span id="spanSumRealOrdAmt"></span>원, 배송금액 : <span id="spanSumDeliveryFee"></span>원) </td>
+						</tr>
+						<tr>
+							<th>주문 상품 금액</th>
+							<td><span id="spanOrdAmt"></span>원</td>
 							<th>취소 상품 금액</th>
-							<td><span id="spanCurrPrice"></span>원</td>
+							<td><span id="spanCnclRtnAmt"></span>원</td>
 						</tr>
 						<tr>
 							<th>취소 사용 포인트</th>
-							<td><span id="spanTotPntDcAmt"></span>원 (고객 포인트 : <span id="spanPntDcAmt"></span>원 + 즉시 사용 마일리지 : <span id="spanPrePntDcAmt"></span>원) </td>
+							<td colspan="3"><span id="spanTotPntDcAmt"></span>원 (고객 포인트 : <span id="spanPntDcAmt"></span>원 + 상품 선포인트 : <span id="spanPrePntDcAmt"></span>원) </td>
+						</tr>
+						<tr>
 							<th>취소 사용 쿠폰금액</th>
-							<td><span id="spanTotCpnDcAmt"></span>원</td>
+							<td colspan="3"><span id="spanCpnDcAmt"></span>원 (즉시할인쿠폰 : <span id="spanCpn1DcAmt"></span>원 + 상품쿠폰 : <span id="spanGoodsCpnDcAmt"></span>원 + 장바구니쿠폰 : <span id="spanCartCpnDcAmt"></span>원)</td>
 						</tr>
+						<tr>
+							<th>취소 다다익선 금액</th>
+							<td colspan="3"><span id="spanTmtbDcAmt"></span>원 (수량할인 : <span id="spanTmtb1DcAmt"></span>원 + 금액할인 : <span id="spanTmtb2DcAmt"></span>원)</td>
+						</tr>
+						
+						<tr>
+							<th>취소 고객 상품권 금액</th>
+							<td colspan="3"><span id="spanGfcdUseAmt"></span>원</td>
+						</tr>
+						
 						<tr>
 							<th>취소 상품 실결제 금액</th>
-							<td><span id="spanCancelPayAmt"></span>원</td>
-							<th>환불 배송금액</th>
+							<td><span id="spanRealCnclRtnAmt"></span>원</td>
+							<th>추가 배송 금액</th>
 							<td><span id="spanTotDeliveryFee"></span>원 </td>
 						</tr>
 						<tr>
-							<th>환불금액</th>
+							<th>환불 금액 합계</th>
 							<td colspan="3"><span id="spanRefundAmt"></span>원</td>
 						</tr>
 					</tbody>
@@ -114,25 +137,17 @@
 var cancelRequestTargetList = [[${cancelRequestTargetList}]];
 
 var temp1 = true;
-var temp2 = true;
+var temp2 = false;
 
 // specify the columns
 var columnCancelReqList = [
-	/*
-	{	
-		width						: 40
-		, minWidth					: 40
-		, cellClass					: 'text-center'
-		, headerCheckboxSelection	: true
-		, checkboxSelection			: true
-		, filter					: false
-	},
-	*/
 	{
 		headerName	: "주문상세정보",
 		children	: [
 			{headerName: "주문번호"		, field: "ordNo"			, width: 80		, cellClass: 'text-center', hide: temp1},
 			{headerName: "주문상세"		, field: "ordDtlNo"			, width: 80		, cellClass: 'text-center'},
+			{headerName: "주문상세"		, field: "ordDtlStat"		, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "주문상세상태"		, field: "ordDtlStatNm"		, width: 100	, cellClass: 'text-center', hide: temp1},
 			{headerName: "상품코드"		, field: "goodsCd"			, width: 100	, cellClass: 'text-center', hide: temp1},
 			{headerName: "상품명"			, field: "goodsNm"			, width: 200	, cellClass: 'text-center', hide: temp1},
 			{headerName: "상품타입"		, field: "goodsTypeNm"		, width: 100	, cellClass: 'text-center', hide: temp2}
@@ -141,6 +156,7 @@ var columnCancelReqList = [
 	{
 		headerName	: "주문상세단품정보",
 		children	: [
+			{headerName: "단품번호"		, field: "ordDtlItemSq"		, width: 100	, cellClass: 'text-center', hide: temp2},
 			{headerName: "단품코드"		, field: "itemCd"			, width: 100	, cellClass: 'text-center', hide: temp2},
 			{headerName: "단품명"			, field: "itemNm"			, width: 200	, cellClass: 'text-center', hide: temp2},
 			{headerName: "칼라코드"		, field: "optCd1"			, width: 80		, cellClass: 'text-center', hide: temp1},
@@ -211,7 +227,6 @@ var columnCancelReqList = [
 					strVal += "<select class='ordCanChgQty' name='ordCanChgQty' ordDtlNo='"+params.data.ordDtlNo+"' onChange='fnCalculateRefundAmt(this);'>";
 					
 					for (i=0 ; i<=ordCanChgQty ; i++) {
-						//alert(i + " :::: " +params.data.ordCanChgQty);
 						if (i == params.data.ordCanChgQty) {
 							strVal += "	<option value='"+i+"' selected>"+i+"</option>";
 						} else {
@@ -222,43 +237,6 @@ var columnCancelReqList = [
 					strVal += "</select>";
 					return strVal;
 				}
-				/*
-				, valueGetter	: function(params) {
-					return params.data.ordCanChgQty;
-				}
-				, valueSetter	: function(params) {
-					var ordQty 			= parseInt(params.data.ordQty);
-					var cnclRtnQty 		= parseInt(params.data.cnclRtnQty);
-					var ordReqChgQty 	= parseInt(params.data.ordReqChgQty);
-					var ordCanChgQty 	= ordQty - (cnclRtnQty +  ordReqChgQty);
-					
-					if (params.data.ordCanChgQty != params.newValue) {
-						if (!isNaN(parseInt(params.newValue))) {
-							// 2020.12.24 외부몰 취소건에 대해서는 업무 협의
-							if (orderInfo.mallGb == '20') {
-								if (parseInt(params.newValue) != parseInt(params.data.ordQty)) {
-									mcxDialog.alert('외부몰주문건은 전체취소만 가능합니다.'); return false;
-								} else {
-									params.data.chgQty = parseInt(params.newValue);
-								}
-							} else {
-								if (parseInt(params.newValue) > ordCanChgQty) {
-									mcxDialog.alert('취소가능수량보다 큽니다!'); 
-									return false;
-								} else {
-									alert(parseInt(params.newValue));
-									params.data.ordCanChgQty = parseInt(params.newValue);
-								}
-							}
-						} else {
-							mcxDialog.alert('숫자만 입력이 가능합니다!'); return false;
-						}
-						return true;
-					} else {
-						return false;
-					}
-				}
-				*/
 			}
 		]
 	},
@@ -400,7 +378,8 @@ var columnCancelReqList = [
 					return params.value.addComma();
 				}
 				, hide			: temp2
-			}
+			},
+			{headerName: "전체취소가능"		, field: "allCanYn"			, width: 100	, cellClass: 'text-center', hide: temp2},
 		]
 	}
 ];
@@ -417,6 +396,8 @@ var columnCancelReqToBeList = [
 		children	: [
 			{headerName: "주문번호"		, field: "ordNo"			, width: 80		, cellClass: 'text-center', hide: temp1},
 			{headerName: "주문상세"		, field: "ordDtlNo"			, width: 80		, cellClass: 'text-center'},
+			{headerName: "주문상세"		, field: "ordDtlStat"		, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "주문상세상태"		, field: "ordDtlStatNm"		, width: 100	, cellClass: 'text-center', hide: temp1},
 			{headerName: "상품코드"		, field: "goodsCd"			, width: 100	, cellClass: 'text-center', hide: temp1},
 			{headerName: "상품명"			, field: "goodsNm"			, width: 200	, cellClass: 'text-center', hide: temp1},
 			{headerName: "상품타입"		, field: "goodsTypeNm"		, width: 100	, cellClass: 'text-center', hide: temp2}
@@ -425,6 +406,7 @@ var columnCancelReqToBeList = [
 	{
 		headerName	: "주문상세단품정보",
 		children	: [
+			{headerName: "단품번호"		, field: "ordDtlItemSq"		, width: 100	, cellClass: 'text-center', hide: temp2},
 			{headerName: "단품코드"		, field: "itemCd"			, width: 100	, cellClass: 'text-center', hide: temp2},
 			{headerName: "단품명"			, field: "itemNm"			, width: 200	, cellClass: 'text-center', hide: temp2},
 			{headerName: "칼라코드"		, field: "optCd1"			, width: 80		, cellClass: 'text-center', hide: temp1},
@@ -594,9 +576,133 @@ var columnCancelReqToBeList = [
 				}
 			}
 		]
+	},
+	{
+		headerName	: "주문배송비정보",
+		children	: [
+			{
+				headerName		: "배송비"		
+				, field			: "delvFee"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "업체"			, field: "supplyCompCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{headerName: "배송비코드"		, field: "delvFeeCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "무료배송비"		
+				, field			: "minOrdAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{
+				headerName		: "기본배송비"		
+				, field			: "orgDelvFee"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "전체취소가능"		, field: "allCanYn"			, width: 100	, cellClass: 'text-center', hide: temp2},
+		]
+	}
+];
+var gridOptionsCancelReqToBeList = orderAgGrid.getGridOptions(columnCancelReqToBeList);
+
+//specify the columns
+var columnDelvCdList = [
+	{
+		headerName	: "배송코드기준금액",
+		children	: [
+			{headerName: "업체"			, field: "supplyCompCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{headerName: "배송비코드"		, field: "delvFeeCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "주문"
+				, field			: "ordAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "취소"		
+				, field			: "cnclRtnAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "환불"		
+				, field			: "realOrdAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			}
+		]
+	},
+	{
+		headerName	: "배송비정보",
+		children	: [
+			{
+				headerName		: "배송비"		
+				, field			: "delvFee"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{
+				headerName		: "무료배송비"		
+				, field			: "minOrdAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{
+				headerName		: "기본배송비"		
+				, field			: "orgDelvFee"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "추가배송비여부"		, field: "addDelvFeeYn"		, width: 140	, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "추가배송비"		
+				, field			: "addDelvFee"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "전체취소가능"		, field: "allCanYn"			, width: 100	, cellClass: 'text-center', hide: temp2},
+		]
 	}
 ];
-var gridOptionsCancelReqLToBeist = orderAgGrid.getGridOptions(columnCancelReqToBeList);
+var gridOptionsDelvCdList = orderAgGrid.getGridOptions(columnDelvCdList);
 </script>
 
 <!-- AgGrid 컬럼 세팅 -->
@@ -640,7 +746,7 @@ var orderAgGrid = {
 <script>
 // 취소정보계산
 var fnCalculateRefundAmt = function (obj) {
-	//취소정보담은목록
+	// 취소정보담은목록
 	var cancelRequestTargetToBeList = [];
 
 	if (obj != null) {
@@ -656,87 +762,96 @@ var fnCalculateRefundAmt = function (obj) {
 		gridOptionsCancelReqList.api.setRowData(cancelRequestTargetList);
 	}
 	
-	// 취소정보 초기화
-	for (i=0 ; i<cancelRequestTargetList.length ; i++) {
-		var obj = new Object();
-		
-		var itemQty 		= cancelRequestTargetList[i].itemQty;
-		var ordQty 			= cancelRequestTargetList[i].ordQty;
-		var cnclRtnQty 		= cancelRequestTargetList[i].cnclRtnQty;
-		var ordReqChgQty 	= cancelRequestTargetList[i].ordReqChgQty;
-		var ordCanChgQty 	= cancelRequestTargetList[i].ordCanChgQty;
-		var itemPrice 		= cancelRequestTargetList[i].itemPrice;
-		var optAddPrice 	= cancelRequestTargetList[i].optAddPrice;
-		var ordAmt 			= cancelRequestTargetList[i].ordAmt;
-		
-		var cnclRtnAmt 		= cancelRequestTargetList[i].cnclRtnAmt;
-		var cpn1DcAmt 		= cancelRequestTargetList[i].cpn1DcAmt;
-		var tmtb1DcAmt 		= cancelRequestTargetList[i].tmtb1DcAmt;
-		var tmtb2DcAmt 		= cancelRequestTargetList[i].tmtb2DcAmt;
-		var goodsCpnDcAmt 	= cancelRequestTargetList[i].goodsCpnDcAmt;
-		var cartCpnDcAmt 	= cancelRequestTargetList[i].cartCpnDcAmt;
-		var pntDcAmt 		= cancelRequestTargetList[i].pntDcAmt;
-		var prePntDcAmt 	= cancelRequestTargetList[i].prePntDcAmt;
-		var gfcdUseAmt 		= cancelRequestTargetList[i].gfcdUseAmt;
-		var realOrdAmt 		= cancelRequestTargetList[i].realOrdAmt;
-		
-		obj.ordNo			= cancelRequestTargetList[i].ordNo;
-		obj.ordDtlNo		= cancelRequestTargetList[i].ordDtlNo;
-		obj.goodsCd			= cancelRequestTargetList[i].goodsCd;
-		obj.goodsNm			= cancelRequestTargetList[i].goodsNm;
-		obj.itemCd			= cancelRequestTargetList[i].itemCd;
-		obj.itemNm			= cancelRequestTargetList[i].itemNm;
-		obj.optCd1			= cancelRequestTargetList[i].optCd1;
-		obj.optCd2			= cancelRequestTargetList[i].optCd2;
-		obj.itemQty			= itemQty;
-		obj.ordQty			= ordQty;
-		obj.cnclRtnQty		= cnclRtnQty;
-		obj.ordReqChgQty	= ordReqChgQty;
-		obj.ordCanChgQty	= ordCanChgQty;
-		obj.itemPrice		= itemPrice;
-		obj.optAddPrice		= optAddPrice;
-		obj.ordAmt			= ordAmt;
-		
-		obj.cnclRtnAmt 		= ((itemPrice + optAddPrice) * itemQty) * ordCanChgQty;
-		obj.cpn1DcAmt 		= cpn1DcAmt 		* (ordCanChgQty/ordQty);
-		obj.tmtb1DcAmt 		= tmtb1DcAmt 		* (ordCanChgQty/ordQty);
-		obj.tmtb2DcAmt 		= tmtb2DcAmt 		* (ordCanChgQty/ordQty);
-		obj.goodsCpnDcAmt 	= goodsCpnDcAmt 	* (ordCanChgQty/ordQty);
-		obj.cartCpnDcAmt 	= cartCpnDcAmt 		* (ordCanChgQty/ordQty);
-		obj.pntDcAmt 		= pntDcAmt 			* (ordCanChgQty/ordQty);
-		obj.prePntDcAmt 	= prePntDcAmt 		* (ordCanChgQty/ordQty);
-		obj.gfcdUseAmt 		= gfcdUseAmt 		* (ordCanChgQty/ordQty);
-		
-		obj.realOrdAmt 		= obj.cnclRtnAmt - (obj.cpn1DcAmt  + obj.tmtb1DcAmt + obj.tmtb2DcAmt + obj.goodsCpnDcAmt + obj.cartCpnDcAmt + obj.pntDcAmt + obj.prePntDcAmt + obj.gfcdUseAmt);
-		
-		cancelRequestTargetToBeList[i] = obj;
+	// 환불금액계산호출
+	var jsonData = JSON.stringify(cancelRequestTargetList);
+	gagajf.ajaxJsonSubmit(
+		'/order/cancel/refundAmt'
+		, jsonData
+		, function(result) {
+			gridOptionsCancelReqToBeList.api.setRowData(result.cancelOrderRefundList);
+			gridOptionsDelvCdList.api.setRowData(result.cancelDelvRefundList);
+			
+			$("#spanPayAmt").text(result.spanPayAmt.addComma());					//총 결제 금액
+			$("#spanSumRealOrdAmt").text(result.spanSumRealOrdAmt.addComma());		//상품 실결제 금액
+			$("#spanSumDeliveryFee").text(result.spanSumDeliveryFee.addComma());	//배송금액
+			
+			$("#spanOrdAmt").text(result.spanOrdAmt.addComma());					//주문 상품 금액
+			$("#spanCnclRtnAmt").text(result.spanCnclRtnAmt.addComma());			//취소 상품 금액
+			
+			$("#spanTotPntDcAmt").text(result.spanTotPntDcAmt.addComma());			//취소 사용 포인트
+			$("#spanPntDcAmt").text(result.spanPntDcAmt.addComma());				//고객 포인트
+			$("#spanPrePntDcAmt").text(result.spanPrePntDcAmt.addComma());			//상품 선포인트
+			
+			$("#spanCpnDcAmt").text(result.spanCpnDcAmt.addComma());				//취소 사용 쿠폰금액
+			$("#spanCpn1DcAmt").text(result.spanCpn1DcAmt.addComma());				//즉시할인쿠폰
+			$("#spanGoodsCpnDcAmt").text(result.spanGoodsCpnDcAmt.addComma());		//상품쿠폰
+			$("#spanCartCpnDcAmt").text(result.spanCartCpnDcAmt.addComma());		//장바구니쿠폰
+			
+			$("#spanTmtbDcAmt").text(result.spanTmtbDcAmt.addComma());				//취소 다다익선 금액
+			$("#spanTmtb1DcAmt").text(result.spanTmtb1DcAmt.addComma());			//수량할인
+			$("#spanTmtb2DcAmt").text(result.spanTmtb2DcAmt.addComma());			//금액할인
+			
+			$("#spanGfcdUseAmt").text(result.spanGfcdUseAmt.addComma());			//취소 고객 상품권 금액
+			
+			$("#spanRealCnclRtnAmt").text(result.spanRealCnclRtnAmt.addComma());	//취소 상품 실결제 금액
+			$("#spanTotDeliveryFee").text(result.spanTotDeliveryFee.addComma());	//환불 배송 금액
+			
+			$("#spanRefundAmt").text(result.spanRefundAmt.addComma());				//환불 금액 합계
+		}
+	);
+}
+
+//  사유
+var fnChangeChgReason = function(reasonCd){
+	var arrREasonCd = reasonCd.split(":");
+	
+	// 취소, 반품, 교환 사유 판단
+	if (arrREasonCd[0] == 'G686_10') {
+		$("#imputeReason").text("고객");
+		isImputationCustomers = true;
+	} else {
+		$("#imputeReason").text("회사");
+		isImputationCustomers = false;
 	}
 
-	gridOptionsCancelReqLToBeist.api.setRowData(cancelRequestTargetToBeList);
+	$('#cancelRequestFrm input[name=chgReason]').val(arrREasonCd[0]);
+	$('#cancelRequestFrm input[name=chgReasonDesc]').val(arrREasonCd[1]);
+
+	//fnCalculateRefundAmt();			//환불예정금액 계산.
+}
+
+// 취소요청
+var fnCancelRequestPartOk = function () {
+	var jsonObj = {
+		"ordNo"			: $('#cancelRequestFrm input[name=ordNo]').val()
+		,"chgReason" 	: $('#cancelRequestFrm input[name=chgReason]').val()
+		,"chgMemo"		: $('#chgMemo').val()
+		,"cancelReqList" : cancelRequestTargetList
+	}
+	
+	// 취소, 반품, 교환 신청 정보 목록
+	var jsonData = JSON.stringify(jsonObj);
+	
+	gagajf.ajaxJsonSubmit(
+		'/order/cancel/'
+		, jsonData
+		, function() {
+			
+		}
+	);
 }
 
 $(document).ready(function() {	
 	// Create a agGrid
-	gagaAgGrid.createGrid('gridOrderCancelRequestList', gridOptionsCancelReqList);			// as-is 정보
+	gagaAgGrid.createGrid('gridOrderCancelRequestList'		, gridOptionsCancelReqList);			// 주문정보
 	gridOptionsCancelReqList.api.setRowData(cancelRequestTargetList);
 	
-	gagaAgGrid.createGrid('gridOrderCancelRequestToBeList', gridOptionsCancelReqLToBeist);	// to-be 정보
+	gagaAgGrid.createGrid('gridOrderCancelRequestToBeList'	, gridOptionsCancelReqToBeList);		// 취소정보
+	
+	gagaAgGrid.createGrid('gridDelvCdList'					, gridOptionsDelvCdList);				// 배송비 정보
 	
 	// 취소정보계산
 	fnCalculateRefundAmt(null);
-	
-	/*
-	// 그리드 클릭마다 환불금액 계산
-	gridOptionsCancelReqList.onRowSelected = function(event){
-		fnCalculateRefundAmt();		//환불예정금액 계산.
-	}
-	gridOptionsCancelReqList.onRowClicked = function(event){
-		fnCalculateRefundAmt();		//환불예정금액 계산.
-	}
-	gridOptionsCancelReqList.onCellValueChanged = function(event){
-		fnCalculateRefundAmt();		//환불예정금액 계산.
-	}
-	*/
 });
 </script>
 </html>

+ 1092 - 0
style24.admin/src/main/webapp/WEB-INF/views/order/CancelRequestFormBack.html

@@ -0,0 +1,1092 @@
+<!DOCTYPE html>
+<html lang="ko" xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : CancelRequestForm.html
+ * @desc    : 취소요청 화면
+ *============================================================================
+ * Pastelmall
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2020.12.12   jsh77b       최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="1400" data-height="600">
+	<div class="panelStyle">
+		<div class="panelTitle">
+			<h2>취소요청</h2>
+			<button type="button" class="close" onclick="uifnPopupClose('popupCancelRequestForm');"><i class="fa fa-times"></i></button>
+		</div>
+			
+		<div class="panelContent" style="height:90%; overflow-y:auto; padding:0px 20px !important; ">
+			<form id="cancelRequestFrm" name="cancelRequestFrm" action="/order/cancel" method="post" target="hdFrameForOrderCancel">
+				<input type="hidden" name="chgGb" 		value="30" />
+				<input type="hidden" name="ordDtlNos" 	value="" />
+				<input type="hidden" name="chgQtys" 	value="" />
+				<input type="hidden" name="ordNo" 	 	th:value="${ordNo}" />
+				<input type="hidden" name="mallGb" 		th:value="${orderInfo.mallGb}" />
+				<input type="hidden" name="delvFee" 	value="0" />
+				<input type="hidden" name="pgStat"	 	value="" />
+				<input type="hidden" name="chgReason"	value="" />
+				<input type="hidden" name="chgReasonDesc" value="" />
+				<input type="hidden" name="cncWait" 	th:value="${cncWait}" />
+		
+				<h3>주문정보</h3>
+				<div id="gridOrderCancelRequestList" style="width:100%; height: 200px;" class="ag-theme-balham"></div>
+
+				<h3>취소정보</h3>
+				<div id="gridOrderCancelRequestToBeList" style="width:100%; height: 200px;" class="ag-theme-balham"></div>
+				
+				<h3>배송비정보</h3>
+				<div id="gridDelvCdList" style="width:100%; height: 140px;" class="ag-theme-balham"></div>
+				
+				<div style="text-align:right; padding-bottom:5px; padding-top:5px;">
+					<button type="button" class="btn btn-success" id="btnCancelRequestEscrow" onclick="fnCancelRequestEscrow();" style="display:none;">에스크로 결제생성</button>
+					<label th:if="${sessionInfo.userId == 'jsshin'
+									|| sessionInfo.userId == 'dlffyd7942'
+									|| sessionInfo.userId == 'card007'
+									|| sessionInfo.userId == 'hrkim'
+									|| sessionInfo.userId =='666badboy'
+									|| sessionInfo.userId =='yjyy83'}">
+						<input type="checkbox" name="pgStats" value="N">PG 전문 미전송
+					</label>
+					<button type="button" class="btn btn-success" id="btnCancelRequestPartOk" onclick="fnCancelRequestPartOk();">요청</button>
+				</div>
+				
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:160px;" />
+						<col style="width:320px;" />
+						<col style="width:160px;" />
+						<col />
+					</colgroup>
+					<tbody>
+						<tr>
+							<th>취소사유 <i class="star"></i></th>
+							<td>
+								<select name="selectChgReason" onchange="fnChangeChgReason($(this).val());">
+									<option value="">[선택하세요]</option>
+									<option th:if="${chgReasonList}" th:each="oneData, status : ${chgReasonList}" th:value="|${oneData.cd}:${oneData.cdNm}|" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+								</select>
+							</td>
+							<th>귀책사유</th>
+							<td><span id="imputeReason"></span></td>
+						</tr>
+						<tr>
+							<th>요청메모</th>
+							<td colspan="3">
+								<textarea name="chgMemo" style="height:80px;" placeholder="취소사유를 300자내외로 작성해 주세요"></textarea>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+				
+				<h4>환불예정금액</h4>
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:20%;"/>
+						<col style="width:30%;"/>
+						<col style="width:20%;"/>
+						<col style="width:30%;"/>
+					</colgroup>
+					<tbody>
+						<tr>
+							<th>총 결제 금액</th>
+							<td colspan="3"><span id="spanPayAmt"></span>원 (상품 실결제 금액 : <span id="spanSumRealOrdAmt"></span>원, 배송금액 : <span id="spanSumDeliveryFee"></span>원) </td>
+						</tr>
+						<tr>
+							<th>주문 상품 금액</th>
+							<td><span id="spanOrdAmt"></span>원</td>
+							<th>취소 상품 금액</th>
+							<td><span id="spanCnclRtnAmt"></span>원</td>
+						</tr>
+						<tr>
+							<th>취소 사용 포인트</th>
+							<td colspan="3"><span id="spanTotPntDcAmt"></span>원 (고객 포인트 : <span id="spanPntDcAmt"></span>원 + 상품 선포인트 : <span id="spanPrePntDcAmt"></span>원) </td>
+						</tr>
+						<tr>
+							<th>취소 사용 쿠폰금액</th>
+							<td colspan="3"><span id="spanCpnDcAmt"></span>원 (즉시할인쿠폰 : <span id="spanCpn1DcAmt"></span>원 + 상품쿠폰 : <span id="spanGoodsCpnDcAmt"></span>원 + 장바구니쿠폰 : <span id="spanCartCpnDcAmt"></span>원)</td>
+						</tr>
+						<tr>
+							<th>취소 다다익선 금액</th>
+							<td colspan="3"><span id="spanTmtbDcAmt"></span>원 (수량할인 : <span id="spanTmtb1DcAmt"></span>원 + 금액할인 : <span id="spanTmtb2DcAmt"></span>원)</td>
+						</tr>
+						
+						<tr>
+							<th>취소 고객 상품권 금액</th>
+							<td colspan="3"><span id="spanGfcdUseAmt"></span>원</td>
+						</tr>
+						
+						<tr>
+							<th>취소 상품 실결제 금액</th>
+							<td><span id="spanRealCnclRtnAmt"></span>원</td>
+							<th>추가 배송 금액</th>
+							<td><span id="spanTotDeliveryFee"></span>원 </td>
+						</tr>
+						<tr>
+							<th>환불 금액 합계</th>
+							<td colspan="3"><span id="spanRefundAmt"></span>원</td>
+						</tr>
+					</tbody>
+				</table>
+				
+			</form>
+		</div>
+	</div>
+</div>
+
+<!-- data -->
+<script th:inline="javascript">
+/*<![CDATA[*/
+var cancelRequestTargetList = [[${cancelRequestTargetList}]];
+
+var temp1 = true;
+var temp2 = false;
+
+// specify the columns
+var columnCancelReqList = [
+	{
+		headerName	: "주문상세정보",
+		children	: [
+			{headerName: "주문번호"		, field: "ordNo"			, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "주문상세"		, field: "ordDtlNo"			, width: 80		, cellClass: 'text-center'},
+			{headerName: "주문상세"		, field: "ordDtlStat"		, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "주문상세상태"		, field: "ordDtlStatNm"		, width: 100	, cellClass: 'text-center', hide: temp1},
+			{headerName: "상품코드"		, field: "goodsCd"			, width: 100	, cellClass: 'text-center', hide: temp1},
+			{headerName: "상품명"			, field: "goodsNm"			, width: 200	, cellClass: 'text-center', hide: temp1},
+			{headerName: "상품타입"		, field: "goodsTypeNm"		, width: 100	, cellClass: 'text-center', hide: temp2}
+		]
+	},
+	{
+		headerName	: "주문상세단품정보",
+		children	: [
+			{headerName: "단품코드"		, field: "itemCd"			, width: 100	, cellClass: 'text-center', hide: temp2},
+			{headerName: "단품명"			, field: "itemNm"			, width: 200	, cellClass: 'text-center', hide: temp2},
+			{headerName: "칼라코드"		, field: "optCd1"			, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "사이즈코드"		, field: "optCd2"			, width: 80		, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "단품수량"		
+				, field			: "itemQty"			
+				, width			: 80		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "단품금액"		
+				, field			: "itemPrice"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "단품옵션금액"		
+				, field			: "optAddPrice"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			}
+		]
+	},
+	{
+		headerName	: "주문상세수량",
+		children	: [
+			{
+				headerName		: "주문"		
+				, field			: "ordQty"			
+				, width			: 80		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "취소/요청"		
+				, field			: "cnclRtnQty"			
+				, width			: 80		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					var cnclRtnReqQty = parseInt(params.data.cnclRtnQty) + parseInt(params.data.ordReqChgQty);
+					return cnclRtnReqQty;
+				}
+			},
+			{
+				headerName		: "취소"		
+				, field			: "ordCanChgQty"			
+				, width			: 100		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					var ordQty 			= parseInt(params.data.ordQty);
+					var cnclRtnQty 		= parseInt(params.data.cnclRtnQty);
+					var ordReqChgQty 	= parseInt(params.data.ordReqChgQty);
+					var ordCanChgQty 	= ordQty - (cnclRtnQty +  ordReqChgQty);
+					
+					var strVal 			= "";
+					strVal += "<select class='ordCanChgQty' name='ordCanChgQty' ordDtlNo='"+params.data.ordDtlNo+"' onChange='fnCalculateRefundAmt(this);'>";
+					
+					for (i=0 ; i<=ordCanChgQty ; i++) {
+						if (i == params.data.ordCanChgQty) {
+							strVal += "	<option value='"+i+"' selected>"+i+"</option>";
+						} else {
+							strVal += "	<option value='"+i+"'>"+i+"</option>";
+						}
+					}
+				
+					strVal += "</select>";
+					return strVal;
+				}
+			}
+		]
+	},
+	{
+		headerName	: "주문단품금액",
+		children	: [
+			{
+				headerName		: "주문"
+				, field			: "ordAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "취소"		
+				, field			: "cnclRtnAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "즉시할인"		
+				, field			: "cpn1DcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "다다익선1"		
+				, field			: "tmtb1DcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "다다익선2"		
+				, field			: "tmtb2DcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "상품쿠폰"		
+				, field			: "goodsCpnDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "장바구니쿠폰"		
+				, field			: "cartCpnDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "포인트"		
+				, field			: "pntDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "선포인트"		
+				, field			: "prePntDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "상품권"		
+				, field			: "gfcdUseAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "실결제금액"		
+				, field			: "realOrdAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			}
+		]
+	},
+	{
+		headerName	: "주문배송비정보",
+		children	: [
+			{
+				headerName		: "배송비"		
+				, field			: "delvFee"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "업체"			, field: "supplyCompCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{headerName: "배송비코드"		, field: "delvFeeCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "무료배송비"		
+				, field			: "minOrdAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{
+				headerName		: "기본배송비"		
+				, field			: "orgDelvFee"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "전체취소가능"		, field: "allCanYn"			, width: 100	, cellClass: 'text-center', hide: temp2},
+		]
+	}
+];
+var gridOptionsCancelReqList = orderAgGrid.getGridOptions(columnCancelReqList);
+// Add on options
+gridOptionsCancelReqList.suppressRowClickSelection = true;
+gridOptionsCancelReqList.rowSelection = 'multiple';
+
+
+//specify the columns
+var columnCancelReqToBeList = [
+	{
+		headerName	: "주문상세정보",
+		children	: [
+			{headerName: "주문번호"		, field: "ordNo"			, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "주문상세"		, field: "ordDtlNo"			, width: 80		, cellClass: 'text-center'},
+			{headerName: "주문상세"		, field: "ordDtlStat"		, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "주문상세상태"		, field: "ordDtlStatNm"		, width: 100	, cellClass: 'text-center', hide: temp1},
+			{headerName: "상품코드"		, field: "goodsCd"			, width: 100	, cellClass: 'text-center', hide: temp1},
+			{headerName: "상품명"			, field: "goodsNm"			, width: 200	, cellClass: 'text-center', hide: temp1},
+			{headerName: "상품타입"		, field: "goodsTypeNm"		, width: 100	, cellClass: 'text-center', hide: temp2}
+		]
+	},
+	{
+		headerName	: "주문상세단품정보",
+		children	: [
+			{headerName: "단품코드"		, field: "itemCd"			, width: 100	, cellClass: 'text-center', hide: temp2},
+			{headerName: "단품명"			, field: "itemNm"			, width: 200	, cellClass: 'text-center', hide: temp2},
+			{headerName: "칼라코드"		, field: "optCd1"			, width: 80		, cellClass: 'text-center', hide: temp1},
+			{headerName: "사이즈코드"		, field: "optCd2"			, width: 80		, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "단품수량"		
+				, field			: "itemQty"			
+				, width			: 80		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "단품금액"		
+				, field			: "itemPrice"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "단품옵션금액"		
+				, field			: "optAddPrice"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			}
+		]
+	},
+	{
+		headerName	: "주문상세수량",
+		children	: [
+			{
+				headerName		: "주문"		
+				, field			: "ordQty"			
+				, width			: 80		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "취소/요청"		
+				, field			: "cnclRtnQty"			
+				, width			: 80		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					var cnclRtnReqQty = parseInt(params.data.cnclRtnQty) + parseInt(params.data.ordReqChgQty);
+					return cnclRtnReqQty;
+				}
+			},
+			{
+				headerName		: "취소"		
+				, field			: "ordCanChgQty"			
+				, width			: 100		
+				, cellClass		: 'text-center'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			}
+		]
+	},
+	{
+		headerName	: "주문단품금액",
+		children	: [
+			{
+				headerName		: "주문"
+				, field			: "ordAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "취소"		
+				, field			: "cnclRtnAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "즉시할인"		
+				, field			: "cpn1DcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "다다익선1"		
+				, field			: "tmtb1DcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "다다익선2"		
+				, field			: "tmtb2DcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "상품쿠폰"		
+				, field			: "goodsCpnDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "장바구니쿠폰"		
+				, field			: "cartCpnDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "포인트"		
+				, field			: "pntDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "선포인트"		
+				, field			: "prePntDcAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "상품권"		
+				, field			: "gfcdUseAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "환불금액"		
+				, field			: "realOrdAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			}
+		]
+	},
+	{
+		headerName	: "주문배송비정보",
+		children	: [
+			{
+				headerName		: "배송비"		
+				, field			: "delvFee"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "업체"			, field: "supplyCompCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{headerName: "배송비코드"		, field: "delvFeeCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "무료배송비"		
+				, field			: "minOrdAmt"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{
+				headerName		: "기본배송비"		
+				, field			: "orgDelvFee"			
+				, width			: 80		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "전체취소가능"		, field: "allCanYn"			, width: 100	, cellClass: 'text-center', hide: temp2},
+		]
+	}
+];
+var gridOptionsCancelReqToBeList = orderAgGrid.getGridOptions(columnCancelReqToBeList);
+
+//specify the columns
+var columnDelvCdList = [
+	{
+		headerName	: "배송코드기준금액",
+		children	: [
+			{headerName: "업체"			, field: "supplyCompCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{headerName: "배송비코드"		, field: "delvFeeCd"		, width: 100	, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "주문"
+				, field			: "ordAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "취소"		
+				, field			: "cnclRtnAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			},
+			{
+				headerName		: "환불"		
+				, field			: "realOrdAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+			}
+		]
+	},
+	{
+		headerName	: "배송비정보",
+		children	: [
+			{
+				headerName		: "배송비"		
+				, field			: "delvFee"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{
+				headerName		: "무료배송비"		
+				, field			: "minOrdAmt"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{
+				headerName		: "기본배송비"		
+				, field			: "orgDelvFee"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "추가배송비여부"		, field: "addDelvFeeYn"		, width: 140	, cellClass: 'text-center', hide: temp2},
+			{
+				headerName		: "추가배송비"		
+				, field			: "addDelvFee"			
+				, width			: 100		
+				, cellClass		: 'text-right'
+				, cellRenderer	: function (params) {
+					return params.value.addComma();
+				}
+				, hide			: temp2
+			},
+			{headerName: "전체취소가능"		, field: "allCanYn"			, width: 100	, cellClass: 'text-center', hide: temp2},
+		]
+	}
+];
+var gridOptionsDelvCdList = orderAgGrid.getGridOptions(columnDelvCdList);
+</script>
+
+<!-- AgGrid 컬럼 세팅 -->
+<script>
+// 공통1. 주문상세 그리드 옵션 정보 적용
+var orderAgGrid = {
+	getGridOptions : function(colDefs) {
+		return {
+			columnDefs					: colDefs
+			, detailCellRendererParams	: {
+				detailGridOptions	: {
+					columnDefs				: []
+					, defaultColDef			: {
+						resizable: true
+					}
+					, suppressLoadingOverlay: false
+					, onGridReady			: function (params) {
+						params.api.setDomLayout('autoHeight');
+					}
+					, onFirstDataRendered	: function (params) {
+						params.api.sizeColumnsToFit();
+					}
+				}
+				, getDetailRowData: function (params) {
+					params.successCallback(params.data.orderDetailList);
+				}
+			}
+			, defaultColDef: {
+				resizable: true
+			}
+			, isRowMaster: function (dataItem) {
+				return dataItem ? dataItem.orderDetailList.length > 1 : false;
+			}
+			, suppressRowTransform: true
+			, enableRangeSelection: true
+		};
+	}
+}
+</script>
+
+<script>
+// 취소정보계산
+var fnCalculateRefundAmt = function (obj) {
+	// 취소정보담은목록
+	var cancelRequestTargetToBeList = [];
+
+	if (obj != null) {
+		for (i=0 ; i<cancelRequestTargetList.length ; i++) {
+			var orDtlNo 		= $(obj).attr("ordDtlNo");
+			var ordCanChgQty 	= $(obj).val();
+			
+			if (cancelRequestTargetList[i].ordDtlNo == orDtlNo) {
+				cancelRequestTargetList[i].ordCanChgQty = ordCanChgQty;
+			}
+		}
+		// 주문정보 다시 셋팅 (체크해봐야할문제)
+		gridOptionsCancelReqList.api.setRowData(cancelRequestTargetList);
+	}
+	
+	/*
+	// 취소 후 발생되는 배송정보 설정
+	var delvFeeList 		= [];
+	var delvObj				= new Object();
+	var k					= 0;
+	
+	// 공급업체 와 배송정책코드가 같지안으면 주문금액, 취소금액 RESET
+	delvObj.ordAmt 			= 0;
+	delvObj.cnclRtnAmt 		= 0;
+	delvObj.realOrdAmt 		= 0;
+	delvObj.delvFee 		= cancelRequestTargetList[k].delvFee;
+	delvObj.minOrdAmt 		= cancelRequestTargetList[k].minOrdAmt;
+	delvObj.orgDelvFee 		= cancelRequestTargetList[k].orgDelvFee;
+	delvObj.supplyCompCd 	= cancelRequestTargetList[k].supplyCompCd;
+	delvObj.delvFeeCd 		= cancelRequestTargetList[k].delvFeeCd;
+	delvObj.allCanYn		= cancelRequestTargetList[k].allCanYn;
+
+	delvFeeList[k] 			= delvObj;
+	
+	var spanPayAmt			= 0; // 총 결제 금액
+	var spanSumRealOrdAmt	= 0; // 상품 실결제 금액
+	var spanSumDeliveryFee	= 0; // 배송금액
+	var spanOrdAmt			= 0; // 주문 상품 금액
+	var spanCnclRtnAmt		= 0; // 취소 상품 금액
+	var spanTotPntDcAmt		= 0; // 취소 사용 포인트
+	var spanPntDcAmt		= 0; // 고객 포인트
+	var spanPrePntDcAmt		= 0; // 상품 선포인트
+	var spanCpnDcAmt		= 0; // 취소 사용 쿠폰금액
+	var spanCpn1DcAmt		= 0; // 즉시할인쿠폰
+	var spanGoodsCpnDcAmt	= 0; // 상품쿠폰
+	var spanCartCpnDcAmt	= 0; // 장바구니쿠폰
+	var spanTmtbDcAmt		= 0; // 취소 다다익선 금액
+	var spanTmtb1DcAmt		= 0; // 수량할인
+	var spanTmtb2DcAmt		= 0; // 금액할인
+	var spanGfcdUseAmt		= 0; // 취소 고객 상품권 금액
+	var spanRealCnclRtnAmt	= 0; // 취소 상품 실결제 금액
+	var spanTotDeliveryFee	= 0; // 환불 배송 금액
+	var spanRefundAmt		= 0; // 환불 금액 합계
+
+	// 취소정보 설정
+	for (i=0 ; i<cancelRequestTargetList.length ; i++) {
+		var obj 			= new Object();
+		
+		var itemQty 		= cancelRequestTargetList[i].itemQty;
+		var ordQty 			= cancelRequestTargetList[i].ordQty;
+		var cnclRtnQty 		= cancelRequestTargetList[i].cnclRtnQty;
+		var ordReqChgQty 	= cancelRequestTargetList[i].ordReqChgQty;
+		var ordCanChgQty 	= cancelRequestTargetList[i].ordCanChgQty;
+		var itemPrice 		= cancelRequestTargetList[i].itemPrice;
+		var optAddPrice 	= cancelRequestTargetList[i].optAddPrice;
+		var ordAmt 			= cancelRequestTargetList[i].ordAmt;
+		
+		var cnclRtnAmt 		= cancelRequestTargetList[i].cnclRtnAmt;
+		var cpn1DcAmt 		= cancelRequestTargetList[i].cpn1DcAmt;
+		var tmtb1DcAmt 		= cancelRequestTargetList[i].tmtb1DcAmt;
+		var tmtb2DcAmt 		= cancelRequestTargetList[i].tmtb2DcAmt;
+		var goodsCpnDcAmt 	= cancelRequestTargetList[i].goodsCpnDcAmt;
+		var cartCpnDcAmt 	= cancelRequestTargetList[i].cartCpnDcAmt;
+		var pntDcAmt 		= cancelRequestTargetList[i].pntDcAmt;
+		var prePntDcAmt 	= cancelRequestTargetList[i].prePntDcAmt;
+		var gfcdUseAmt 		= cancelRequestTargetList[i].gfcdUseAmt;
+		var realOrdAmt 		= cancelRequestTargetList[i].realOrdAmt;
+		
+		obj.ordNo			= cancelRequestTargetList[i].ordNo;
+		obj.ordDtlNo		= cancelRequestTargetList[i].ordDtlNo;
+		obj.goodsCd			= cancelRequestTargetList[i].goodsCd;
+		obj.goodsNm			= cancelRequestTargetList[i].goodsNm;
+		obj.itemCd			= cancelRequestTargetList[i].itemCd;
+		obj.itemNm			= cancelRequestTargetList[i].itemNm;
+		obj.optCd1			= cancelRequestTargetList[i].optCd1;
+		obj.optCd2			= cancelRequestTargetList[i].optCd2;
+		obj.itemQty			= itemQty;
+		obj.ordQty			= ordQty;
+		obj.cnclRtnQty		= cnclRtnQty;
+		obj.ordReqChgQty	= ordReqChgQty;
+		obj.ordCanChgQty	= ordCanChgQty;
+		obj.itemPrice		= itemPrice;
+		obj.optAddPrice		= optAddPrice;
+		obj.ordAmt			= ordAmt;
+		
+		obj.cnclRtnAmt 		= ((itemPrice + optAddPrice) * itemQty) * ordCanChgQty;
+		obj.cpn1DcAmt 		= cpn1DcAmt 		* (ordCanChgQty/ordQty);
+		obj.tmtb1DcAmt 		= tmtb1DcAmt 		* (ordCanChgQty/ordQty);
+		obj.tmtb2DcAmt 		= tmtb2DcAmt 		* (ordCanChgQty/ordQty);
+		obj.goodsCpnDcAmt 	= goodsCpnDcAmt 	* (ordCanChgQty/ordQty);
+		obj.cartCpnDcAmt 	= cartCpnDcAmt 		* (ordCanChgQty/ordQty);
+		obj.pntDcAmt 		= pntDcAmt 			* (ordCanChgQty/ordQty);
+		obj.prePntDcAmt 	= prePntDcAmt 		* (ordCanChgQty/ordQty);
+		obj.gfcdUseAmt 		= gfcdUseAmt 		* (ordCanChgQty/ordQty);
+		
+		obj.realOrdAmt 		= obj.cnclRtnAmt - (obj.cpn1DcAmt  + obj.tmtb1DcAmt + obj.tmtb2DcAmt + obj.goodsCpnDcAmt + obj.cartCpnDcAmt + obj.pntDcAmt + obj.prePntDcAmt + obj.gfcdUseAmt);
+		
+		// 배송관련 설정		
+		obj.ordDtlNo		= cancelRequestTargetList[i].ordDtlNo;
+		obj.goodsTypeNm		= cancelRequestTargetList[i].goodsTypeNm;
+		obj.delvFee			= cancelRequestTargetList[i].delvFee;
+		obj.supplyCompCd	= cancelRequestTargetList[i].supplyCompCd;
+		obj.delvFeeCd		= cancelRequestTargetList[i].delvFeeCd;
+		obj.minOrdAmt		= cancelRequestTargetList[i].minOrdAmt;
+		obj.orgDelvFee		= cancelRequestTargetList[i].orgDelvFee;
+		
+		// 주문상세상태
+		obj.ordDtlStat		= cancelRequestTargetList[i].ordDtlSat;
+		obj.ordDtlSatNm		= cancelRequestTargetList[i].ordDtlSatNm;
+		obj.allCanYn		= cancelRequestTargetList[i].allCanYn;
+		
+		cancelRequestTargetToBeList[i] = obj;
+
+		// 배송비 정책 기준으로 조건 처리
+		if (delvFeeList[k].supplyCompCd == obj.supplyCompCd && delvFeeList[k].delvFeeCd == obj.delvFeeCd) {
+			// 공급업체 와 배송정책코드가 같으면 주문금액, 취소금액 SUM
+			delvFeeList[k].ordAmt 		+= obj.ordAmt;
+			delvFeeList[k].cnclRtnAmt 	+= obj.cnclRtnAmt;
+			delvFeeList[k].realOrdAmt 	+= obj.realOrdAmt;
+			
+			if (obj.allCanYn == "N") {
+				delvFeeList[k].allCanYn = "N";
+			}
+		} else {			
+			k++;
+			
+			var delvObj					= new Object();
+			
+			// 공급업체 와 배송정책코드가 같지안으면 주문금액, 취소금액 RESET
+			delvObj.ordAmt 				= obj.ordAmt;
+			delvObj.cnclRtnAmt 			= obj.cnclRtnAmt;
+			delvObj.realOrdAmt 			= obj.realOrdAmt;
+			
+			delvObj.delvFee 			= obj.delvFee;
+			delvObj.minOrdAmt 			= obj.minOrdAmt;			
+			delvObj.orgDelvFee 			= obj.orgDelvFee;
+			delvObj.supplyCompCd 		= obj.supplyCompCd;
+			delvObj.delvFeeCd 			= obj.delvFeeCd;
+			delvObj.allCanYn			= obj.allCanYn;
+			
+			delvFeeList[k] 				= delvObj;
+		}
+		
+		spanSumRealOrdAmt	+= realOrdAmt;
+		spanPntDcAmt		+= obj.pntDcAmt;
+		spanPrePntDcAmt		+= obj.prePntDcAmt;
+		spanCpn1DcAmt		+= obj.cpn1DcAmt;
+		spanGoodsCpnDcAmt	+= obj.goodsCpnDcAmt;
+		spanCartCpnDcAmt	+= obj.cartCpnDcAmt;
+		spanTmtb1DcAmt		+= obj.tmtb1DcAmt;
+		spanTmtb2DcAmt		+= obj.tmtb2DcAmt;
+		spanGfcdUseAmt		+= obj.gfcdUseAmt;
+		spanRealCnclRtnAmt	+= obj.realOrdAmt;
+	}
+	
+	// 추가배송비 발생여부 , 추가배송비, 배송비정책단위 전체취소 여부
+	for (i=0 ; i<delvFeeList.length ; i++) {
+		var obj = delvFeeList[i];
+		
+		// 무료배송비용 > (주문금액 - 취소금액)
+		if (obj.minOrdAmt > (obj.ordAmt - obj.cnclRtnAmt)) {
+			// 2020.12.28 
+			// case : 배송정책 기준으로 1,2 상품 주문 후 1번 출고 후 1번반품 2번취소 할 경우 전체 취소 가 아니므로 배송비 부과 있을지 모르겠음 주문업체 단위로 배송되기 때문에 발생하지 않을것 같음
+			if ((obj.ordAmt - obj.cnclRtnAmt) == 0) {
+				if (obj.allCanYn == "N") {
+					obj.addDelvFeeYn 	= "Y";
+					obj.addDelvFee 		= obj.orgDelvFee;
+				} else {
+					// 전체취소의 경우에 해당
+					obj.addDelvFeeYn 	= "N";
+					obj.addDelvFee 		= 0;
+				}
+			} else {
+				// 취소신청화면에서 대부분 아래의 조건에 해당
+				obj.addDelvFeeYn 	= "Y";
+				obj.addDelvFee 		= obj.orgDelvFee;
+			}
+			
+			//obj.addDelvFeeYn 	= "Y";
+			//obj.addDelvFee 		= obj.orgDelvFee;
+		} else {
+			obj.addDelvFeeYn 	= "N";
+			obj.addDelvFee 		= 0;
+		}
+		
+		spanSumDeliveryFee	+= obj.delvFee;
+		spanOrdAmt			+= obj.ordAmt;
+		spanCnclRtnAmt		+= obj.cnclRtnAmt;
+		spanTotDeliveryFee  += obj.addDelvFee;
+				
+		delvFeeList[i] = obj;
+	}
+
+	gridOptionsCancelReqToBeList.api.setRowData(cancelRequestTargetToBeList);
+	gridOptionsDelvCdList.api.setRowData(delvFeeList);
+	
+	// 환불금액표시
+	spanPayAmt 			= spanSumRealOrdAmt + spanSumDeliveryFee;
+	spanTotPntDcAmt 	= spanPntDcAmt + spanPrePntDcAmt;
+	spanCpnDcAmt 		= spanCpn1DcAmt + spanGoodsCpnDcAmt + spanCartCpnDcAmt;
+	spanTmtbDcAmt 		= spanTmtb1DcAmt + spanTmtb2DcAmt;
+	spanRefundAmt 		= spanRealCnclRtnAmt - spanTotDeliveryFee;
+	
+	$("#spanPayAmt").text(spanPayAmt.addComma());					//총 결제 금액
+	$("#spanSumRealOrdAmt").text(spanSumRealOrdAmt.addComma());		//상품 실결제 금액
+	$("#spanSumDeliveryFee").text(spanSumDeliveryFee.addComma());	//배송금액
+	
+	$("#spanOrdAmt").text(spanOrdAmt.addComma());					//주문 상품 금액
+	$("#spanCnclRtnAmt").text(spanCnclRtnAmt.addComma());			//취소 상품 금액
+	
+	$("#spanTotPntDcAmt").text(spanTotPntDcAmt.addComma());			//취소 사용 포인트
+	$("#spanPntDcAmt").text(spanPntDcAmt.addComma());				//고객 포인트
+	$("#spanPrePntDcAmt").text(spanPrePntDcAmt.addComma());			//상품 선포인트
+	
+	$("#spanCpnDcAmt").text(spanCpnDcAmt.addComma());				//취소 사용 쿠폰금액
+	$("#spanCpn1DcAmt").text(spanCpn1DcAmt.addComma());				//즉시할인쿠폰
+	$("#spanGoodsCpnDcAmt").text(spanGoodsCpnDcAmt.addComma());		//상품쿠폰
+	$("#spanCartCpnDcAmt").text(spanCartCpnDcAmt.addComma());		//장바구니쿠폰
+	
+	$("#spanTmtbDcAmt").text(spanTmtbDcAmt.addComma());				//취소 다다익선 금액
+	$("#spanTmtb1DcAmt").text(spanTmtb1DcAmt.addComma());			//수량할인
+	$("#spanTmtb2DcAmt").text(spanTmtb2DcAmt.addComma());			//금액할인
+	
+	$("#spanGfcdUseAmt").text(spanGfcdUseAmt.addComma());			//취소 고객 상품권 금액
+	
+	$("#spanRealCnclRtnAmt").text(spanRealCnclRtnAmt.addComma());	//취소 상품 실결제 금액
+	$("#spanTotDeliveryFee").text(spanTotDeliveryFee.addComma());	//환불 배송 금액
+	
+	$("#spanRefundAmt").text(spanRefundAmt.addComma());				//환불 금액 합계
+	*/
+	
+	// 환불금액계산호출
+	var jsonData = JSON.stringify(cancelRequestTargetList);
+	gagajf.ajaxJsonSubmit(
+		'/order/cancel/refundAmt'
+		, jsonData
+		, function(result) {
+			gridOptionsCancelReqToBeList.api.setRowData(result.cancelOrderRefundList);
+			gridOptionsDelvCdList.api.setRowData(result.cancelDelvRefundList);
+			
+			$("#spanPayAmt").text(result.spanPayAmt.addComma());					//총 결제 금액
+			$("#spanSumRealOrdAmt").text(result.spanSumRealOrdAmt.addComma());		//상품 실결제 금액
+			$("#spanSumDeliveryFee").text(result.spanSumDeliveryFee.addComma());	//배송금액
+			
+			$("#spanOrdAmt").text(result.spanOrdAmt.addComma());					//주문 상품 금액
+			$("#spanCnclRtnAmt").text(result.spanCnclRtnAmt.addComma());			//취소 상품 금액
+			
+			$("#spanTotPntDcAmt").text(result.spanTotPntDcAmt.addComma());			//취소 사용 포인트
+			$("#spanPntDcAmt").text(result.spanPntDcAmt.addComma());				//고객 포인트
+			$("#spanPrePntDcAmt").text(result.spanPrePntDcAmt.addComma());			//상품 선포인트
+			
+			$("#spanCpnDcAmt").text(result.spanCpnDcAmt.addComma());				//취소 사용 쿠폰금액
+			$("#spanCpn1DcAmt").text(result.spanCpn1DcAmt.addComma());				//즉시할인쿠폰
+			$("#spanGoodsCpnDcAmt").text(result.spanGoodsCpnDcAmt.addComma());		//상품쿠폰
+			$("#spanCartCpnDcAmt").text(result.spanCartCpnDcAmt.addComma());		//장바구니쿠폰
+			
+			$("#spanTmtbDcAmt").text(result.spanTmtbDcAmt.addComma());				//취소 다다익선 금액
+			$("#spanTmtb1DcAmt").text(result.spanTmtb1DcAmt.addComma());			//수량할인
+			$("#spanTmtb2DcAmt").text(result.spanTmtb2DcAmt.addComma());			//금액할인
+			
+			$("#spanGfcdUseAmt").text(result.spanGfcdUseAmt.addComma());			//취소 고객 상품권 금액
+			
+			$("#spanRealCnclRtnAmt").text(result.spanRealCnclRtnAmt.addComma());	//취소 상품 실결제 금액
+			$("#spanTotDeliveryFee").text(result.spanTotDeliveryFee.addComma());	//환불 배송 금액
+			
+			$("#spanRefundAmt").text(result.spanRefundAmt.addComma());				//환불 금액 합계
+			
+			//alert("a");
+			//$('#btnSearch').trigger('click');
+		}
+	);
+}
+
+//  사유
+var fnChangeChgReason = function(reasonCd){
+	var arrREasonCd = reasonCd.split(":");
+	
+	// 취소, 반품, 교환 사유 판단
+	if (arrREasonCd[0] == 'G686_10') {
+		$("#imputeReason").text("고객");
+		isImputationCustomers = true;
+	} else {
+		$("#imputeReason").text("회사");
+		isImputationCustomers = false;
+	}
+
+	$('#cancelRequestFrm input[name=chgReason]').val(arrREasonCd[0]);
+	$('#cancelRequestFrm input[name=chgReasonDesc]').val(arrREasonCd[1]);
+
+	//fnCalculateRefundAmt();			//환불예정금액 계산.
+}
+
+// 에스크로 전체취소, 부분취소 요청
+var fnCancelRequestPartOk = function () {
+	// 취소, 반품, 교환 신청 정보 목록
+	//cancelRequestTargetList;
+	
+	var jsonData = JSON.stringify(cancelRequestTargetList);
+	
+	gagajf.ajaxJsonSubmit(
+		'/order/cancel/'
+		, jsonData
+		, function() {
+			$('#btnSearch').trigger('click');
+		}
+	);
+	
+}
+
+$(document).ready(function() {	
+	// Create a agGrid
+	gagaAgGrid.createGrid('gridOrderCancelRequestList'		, gridOptionsCancelReqList);			// 주문정보
+	gridOptionsCancelReqList.api.setRowData(cancelRequestTargetList);
+	
+	gagaAgGrid.createGrid('gridOrderCancelRequestToBeList'	, gridOptionsCancelReqToBeList);		// 취소정보
+	
+	gagaAgGrid.createGrid('gridDelvCdList'					, gridOptionsDelvCdList);				// 배송비 정보
+	
+	// 취소정보계산
+	fnCalculateRefundAmt(null);
+});
+</script>
+</html>
+
+
+
+
+

+ 1 - 1
style24.admin/src/main/webapp/WEB-INF/views/system/CommoncodeForm.html

@@ -183,8 +183,8 @@
 		$('#detailForm input[name=cdGb]').val(rowData.cdGb);
 		$('#detailForm input[name=cd]').val(rowData.cd);
 		$('#detailForm input[name=cdNm]').val(rowData.cdNm);
-		$('#detailForm input[name=cdDesc]').val(rowData.cdDesc);
 		$('#detailForm input[name=dispOrd]').val(rowData.dispOrd);
+		$('#detailForm textarea[name=cdDesc]').val(rowData.cdDesc);
 		
 		$("#detailForm input[name=useYn]").val(rowData.useYn);
 		if (rowData.useYn == 'Y') {

+ 4 - 3
style24.admin/src/main/webapp/WEB-INF/views/system/MenuForm.html

@@ -284,14 +284,15 @@
 	
 	// specify the columns
 	var columnDefs = [
-		{headerName: "메뉴명", field: "menuNm", width: 200,
+		{
+			headerName: "메뉴명", field: "menuNm", width: 200,
 			cellRenderer: function(params) {
 				return '<a href="javascript:void(0);">' + params.value + '</a>';
 			}
 		},
-		{headerName: "메뉴구분", field: "menuGb", width: 100, cellClass: 'text-center',
+		{
+			headerName: "메뉴구분", field: "menuGb", width: 100, cellClass: 'text-center',
 			cellRenderer: function(params) { return params.value == 'M' ? '메뉴' : '프로그램'; }
-			/* valueFormatter: function(params) { return params.value == 'M' ? '메뉴' : '프로그램'; } */
 		},
 		{headerName: "메뉴권한코드", field: "roleCds", hide: true},
 		{headerName: "메뉴권한", field: "roleNms", width: 400, cellClass: 'text-center'},

+ 22 - 5
style24.admin/src/main/webapp/ux/js/admin.popup.js

@@ -448,9 +448,9 @@ var cfnOpenOneToOneQnaDetailPopup = function(counselSq) {
 /**
  * @type   : function
  * @access : public
- * @desc   : 상품문의상세팝업
- * @since  : 2020/08/14
- * @author : 이대형
+ * @desc   : 상품문의 상세 팝업
+ * @author : gagamel
+ * @since  : 2020/12/24
  */
 var cfnOpenGoodsQnaDetailPopup = function(counselSq) {
 	var actionUrl = '/customer/goods/qna/detail/form/' + counselSq;
@@ -698,8 +698,8 @@ var cfnOpenBrandListPopup = function(callbackfn, multiGb, searchTxt) {
  * @since  : 2020/12/21
  * @author : xodud1202
  */
-var cfnOpenFreeGoodsPromotionSetPopup = function() {
-	var actionUrl = "/marketing/freeGoodsRegiPopup/form?gbn=C";
+var cfnOpenFreeGoodsPromotionSetPopup = function(gbn) {
+	var actionUrl = "/marketing/freeGoodsRegiPopup/form?gbn=" + gbn;
 
 	uifnPopupClose('popupFreeGoodsPromotionRegi');
 	cfnOpenModalPopup(actionUrl, 'popupFreeGoodsPromotionRegi');
@@ -720,4 +720,21 @@ var cfnOpenCompanyListPopup = function(callbackfn) {
 	if (typeof(callbackfn) != 'undefined') actionUrl += "?callbackFn=" + callbackfn;
 	uifnPopupClose('popupCompanyList');
 	cfnOpenModalPopup(actionUrl, 'popupCompanyList');
+}
+
+/**
+ * @type   : function
+ * @access : public
+ * @desc   : 공급업체 조회 팝업
+ * <pre>
+ *     cfnOpenCompanyListPopup();
+ * </pre>
+ * @since  : 2020/12/23
+ * @author : xodud1202
+ */
+var cfnOpenExtmallListPopup = function(callbackfn) {
+	var actionUrl = "/ocm/extmall/search/form";
+	if (typeof(callbackfn) != 'undefined') actionUrl += "?callbackFn=" + callbackfn;
+	uifnPopupClose('popupExtmallList');
+	cfnOpenModalPopup(actionUrl, 'popupExtmallList');
 }

+ 32 - 0
style24.batch/.classpath

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v9.0.22"/>
+	<classpathentry kind="lib" path="/style24.core/target/classes">
+		<attributes>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/classes"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

+ 13 - 1
style24.batch/.gitignore

@@ -1,3 +1,15 @@
 target/
+.settings/
 .classpath
-/target/
+/bin/
+/target/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### MacOS ###
+.DS_Store
+META-INF/context.xml

+ 57 - 0
style24.batch/src/main/java/com/style24/batch/biz/dao/TsbCommonDao.java

@@ -0,0 +1,57 @@
+package com.style24.batch.biz.dao;
+
+import org.springframework.stereotype.Repository;
+
+import com.style24.core.support.annotation.ShopDs;
+
+/**
+ * 공통 Dao
+ *
+ * @author eskim
+ * @since 2021. 01. 04
+ */
+@ShopDs
+@Repository
+public interface TsbCommonDao {
+
+//	/**
+//	 * 시퀀스 조회
+//	 *
+//	 * @param value - 시퀀스명
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2019. 8. 5
+//	 */
+//	String getNextSequence(String value);
+
+	/**
+	 * WMS 연동 여부
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	String getWmsSyncYn();
+
+//	/**
+//	 * 기본답변문구내용 조회
+//	 *
+//	 * @param basicAnswer - 답변일련번호
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 3. 30
+//	 */
+//	TsbBasicAnswer getBasicAnswer(TsbBasicAnswer basicAnswer);
+//
+//	/**
+//	 * 공통코드 목록
+//	 *
+//	 * @param commoncode - 공통코드
+//	 * @return Collection<TsbCommonCode> - 공통코드
+//	 * @author  card007
+//	 * @since  2020. 07. 07
+//	 */
+//	Collection<TsbCommonCode> getCommonCodeList(TsbCommonCode commoncode);
+
+}

+ 52 - 0
style24.batch/src/main/java/com/style24/batch/biz/dao/TsbGoodsDao.java

@@ -5,8 +5,13 @@ import java.util.Collection;
 import com.style24.core.support.annotation.ShopDs;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.Goods;
+import com.style24.persistence.domain.GoodsIfIncomelot;
+import com.style24.persistence.domain.GoodsIfIncomelotitem;
+import com.style24.persistence.domain.GoodsIfMeasurement;
 import com.style24.persistence.domain.GoodsSafeNo;
 import com.style24.persistence.domain.GoodsSummary;
+import com.style24.persistence.domain.IfBrand;
+import com.style24.persistence.domain.IfProvider;
 
 /**
  * 상품 Dao
@@ -239,5 +244,52 @@ public interface TsbGoodsDao {
 	 */
 	void saveGoodsSafeNo(GoodsSafeNo goodsSafeNo);
 
+	/**
+	 * 실측사이즈 저장
+	 *
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	void saveGoodsIfMeasurement(GoodsIfMeasurement goodsMeasurement);
+
+	/**
+	 * 입고 저장
+	 *
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	void saveGoodsIfIncomelot(GoodsIfIncomelot ㅎoodsIfIncomelot);
+
+	/**
+	 * 입고상품 저장
+	 *
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	void saveGoodsIfIncomelotitem(GoodsIfIncomelotitem goodsIfIncomelotitem);
+
+	/**
+	 * 온라인 입고 상품 처리
+	 *
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	void saveWmsGoods(GoodsIfIncomelot goodsIfIncomelot);
+
+	/**
+	 * 공급업체 정보 조회
+	 *
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	Collection<IfProvider> getSupplyCompanyList();
+
+	/**
+	 * 브랜드 정보 조회
+	 *
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	Collection<IfBrand> getBrandList();
 
 }

+ 75 - 0
style24.batch/src/main/java/com/style24/batch/biz/dao/TsbWmsGoodsDao.java

@@ -0,0 +1,75 @@
+package com.style24.batch.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.WmsDs;
+import com.style24.persistence.domain.GoodsIfIncomelot;
+import com.style24.persistence.domain.GoodsIfIncomelotitem;
+import com.style24.persistence.domain.GoodsIfMeasurement;
+import com.style24.persistence.domain.IfBrand;
+import com.style24.persistence.domain.IfProvider;
+
+/**
+ * WMS 상품 연동Dao
+ *
+ * @author eskim
+ * @since 2021. 01. 01
+ */
+@WmsDs
+public interface TsbWmsGoodsDao {
+
+	/**
+	 * 실측사이즈 연동
+	 *
+	 * @param jobdate
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	Collection<GoodsIfMeasurement> getWmsMeasurementList(String jobdate);
+
+	/**
+	 * 입고 목록
+	 *
+	 * @param jobdate
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	Collection<GoodsIfIncomelot> getWmsIncomelotList(String jobdate);
+
+	/**
+	 * 입고 상품목록
+	 *
+	 * @param jobdate
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	Collection<GoodsIfIncomelotitem> getWmsIncomelotitemList(String jobdate);
+
+	/**
+	 * WMS 업체정보 송신
+	 *
+	 * @param ifProvider
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	void saveWmsProvider(IfProvider ifProvider);
+
+	/**
+	 * WMS 브랜드정보 송신
+	 *
+	 * @param ifBrand
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	void saveWmsBrand(IfBrand ifBrand);
+
+	/**
+	 * WMS 브랜드업체관계정보 송신
+	 *
+	 * @param ifBrand
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	void saveWmsBrandProviderXref(IfBrand ifBrand);
+
+}

+ 65 - 0
style24.batch/src/main/java/com/style24/batch/biz/job/goods/TsbGoodsWmsBrandproviderJob.java

@@ -0,0 +1,65 @@
+package com.style24.batch.biz.job.goods;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.style24.batch.biz.job.TsbAbstractJob;
+import com.style24.batch.biz.service.TsbCommonService;
+import com.style24.batch.biz.service.TsbGoodsService;
+import com.style24.persistence.domain.IfBrand;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.util.GagaDateUtil;
+
+/**
+ * WMS 브랜드/업체정보 송신
+ *
+ * @author eskim
+ * @since 2021. 01. 05
+ */
+@Component
+@Slf4j
+public class TsbGoodsWmsBrandproviderJob extends TsbAbstractJob<IfBrand, IfBrand, IfBrand> {
+
+	@Autowired
+	private TsbGoodsService goodsService;
+
+	@Autowired
+	private TsbCommonService commonService;
+
+	private int succCnt = 0;
+	private int failCnt = 0;
+
+	@Override
+	public IfBrand read() throws Exception {
+
+		// WMS 동기화 옵션 여부 확인
+		String wmsSyncYn = commonService.getWmsSyncYn();
+		if ("N".equals(wmsSyncYn)) {
+			log.info("WMS 정보 동기화 미실행 {}, 연동여부 : {}", GagaDateUtil.getToday("yyyy-MM-dd HH:mm:ss"), wmsSyncYn);
+			return null;
+		}
+		IfBrand ifBrand = new IfBrand();
+		return ifBrand;
+	}
+
+	@Override
+	public IfBrand process(IfBrand ifBrand) throws Exception {
+		return ifBrand;
+	}
+
+	@Override
+	public IfBrand write(IfBrand ifBrand) throws Exception {
+
+		goodsService.saveWmsBrandProvider();
+
+		return ifBrand;
+	}
+
+	@Override
+	public void notify(IfBrand ifBrand) throws Exception {
+		super.printResult(succCnt, failCnt);
+	}
+
+}

+ 72 - 0
style24.batch/src/main/java/com/style24/batch/biz/job/goods/TsbGoodsWmsIncomelotJob.java

@@ -0,0 +1,72 @@
+package com.style24.batch.biz.job.goods;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.style24.batch.biz.job.TsbAbstractJob;
+import com.style24.batch.biz.service.TsbCommonService;
+import com.style24.batch.biz.service.TsbGoodsService;
+import com.style24.persistence.domain.GoodsIfIncomelotitem;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.util.GagaDateUtil;
+
+/**
+ * WMS 입고 연용
+ *
+ * @author eskim
+ * @since 2021. 01. 01
+ */
+@Component
+@Slf4j
+public class TsbGoodsWmsIncomelotJob extends TsbAbstractJob<GoodsIfIncomelotitem, GoodsIfIncomelotitem, GoodsIfIncomelotitem> {
+
+	@Autowired
+	private TsbGoodsService goodsService;
+
+	@Autowired
+	private TsbCommonService commonService;
+
+	private int succCnt = 0;
+	private int failCnt = 0;
+	private String jobdate = "";
+
+	@Override
+	public GoodsIfIncomelotitem read() throws Exception {
+
+		// WMS 동기화 옵션 여부 확인
+		String wmsSyncYn = commonService.getWmsSyncYn();
+		if ("N".equals(wmsSyncYn)) {
+			log.info("WMS 정보 동기화 미실행 {}, 연동여부 : {}", GagaDateUtil.getToday("yyyy-MM-dd HH:mm:ss"), wmsSyncYn);
+			return null;
+		}
+		GoodsIfIncomelotitem goodsIfIncomelotitem = new GoodsIfIncomelotitem();
+		return goodsIfIncomelotitem;
+	}
+
+	@Override
+	public GoodsIfIncomelotitem process(GoodsIfIncomelotitem goodsIfIncomelotitem) throws Exception {
+		return goodsIfIncomelotitem;
+	}
+
+	@Override
+	public GoodsIfIncomelotitem write(GoodsIfIncomelotitem goodsIfIncomelotitem) throws Exception {
+
+		jobdate = GagaDateUtil.getOffsetDate(-1);	//전일자
+
+		//wms 입고 정보 처리
+		goodsService.saveGoodsWmsIncomelot(jobdate);
+
+		//온라인 입고 상품 처리
+		goodsService.saveWmsGoods(jobdate);
+
+		return goodsIfIncomelotitem;
+	}
+
+	@Override
+	public void notify(GoodsIfIncomelotitem goodsIfIncomelotitem) throws Exception {
+		super.printResult(succCnt, failCnt);
+	}
+
+}

+ 66 - 0
style24.batch/src/main/java/com/style24/batch/biz/job/goods/TsbGoodsWmsMeasurementJob.java

@@ -0,0 +1,66 @@
+package com.style24.batch.biz.job.goods;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.style24.batch.biz.job.TsbAbstractJob;
+import com.style24.batch.biz.service.TsbCommonService;
+import com.style24.batch.biz.service.TsbGoodsService;
+import com.style24.persistence.domain.GoodsIfMeasurement;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.util.GagaDateUtil;
+
+/**
+ * WMS 실측사이즈 연용
+ *
+ * @author eskim
+ * @since 2020. 12. 31
+ */
+@Component
+@Slf4j
+public class TsbGoodsWmsMeasurementJob extends TsbAbstractJob<GoodsIfMeasurement, GoodsIfMeasurement, GoodsIfMeasurement> {
+
+	@Autowired
+	private TsbGoodsService goodsService;
+
+	@Autowired
+	private TsbCommonService commonService;
+
+	private int succCnt = 0;
+	private int failCnt = 0;
+	private String jobdate = "";
+
+	@Override
+	public GoodsIfMeasurement read() throws Exception {
+
+		// WMS 동기화 옵션 여부 확인
+		String wmsSyncYn = commonService.getWmsSyncYn();
+		if ("N".equals(wmsSyncYn)) {
+			log.info("WMS 정보 동기화 미실행 {}, 연동여부 : {}", GagaDateUtil.getToday("yyyy-MM-dd HH:mm:ss"), wmsSyncYn);
+			return null;
+		}
+		GoodsIfMeasurement goodsIfMeasurement = new GoodsIfMeasurement();
+		return goodsIfMeasurement;
+	}
+
+	@Override
+	public GoodsIfMeasurement process(GoodsIfMeasurement goodsIfMeasurement) throws Exception {
+		return goodsIfMeasurement;
+	}
+
+	@Override
+	public GoodsIfMeasurement write(GoodsIfMeasurement goodsIfMeasurement) throws Exception {
+
+		jobdate = GagaDateUtil.getOffsetDate(-1);	//전일자
+		goodsService.saveGoodsWmsMeasurement(jobdate);
+		return goodsIfMeasurement;
+	}
+
+	@Override
+	public void notify(GoodsIfMeasurement goodsIfMeasurement) throws Exception {
+		super.printResult(succCnt, failCnt);
+	}
+
+}

+ 57 - 0
style24.batch/src/main/java/com/style24/batch/biz/service/TsbCommonService.java

@@ -0,0 +1,57 @@
+package com.style24.batch.biz.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.style24.batch.biz.dao.TsbCommonDao;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 공통 Service
+ *
+ * @author eskim
+ * @since 2021. 01. 04
+ */
+@Service
+@Slf4j
+public class TsbCommonService {
+
+	@Autowired
+	private TsbCommonDao commonDao;
+//
+//	/**
+//	 * 시퀀스 조회
+//	 *
+//	 * @param sequenceName - 시퀀스명
+//	 * @return String
+//	 * @author gagamel
+//	 * @since 2019. 8. 25
+//	 */
+//	public String getNextSequence(String sequenceName) {
+//		return commonDao.getNextSequence(sequenceName);
+//	}
+
+	/**
+	 * ERP Sync 옵션
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	public String getWmsSyncYn() {
+		return commonDao.getWmsSyncYn();
+	}
+
+//	/**
+//	 * 공통코드 목록
+//	 *
+//	 * @param TsbCommonCode - 공통코드
+//	 * @return Collection<TsbCommonCode> - 공통코드
+//	 * @author card007
+//	 * @since 2020. 07. 07
+//	 */
+//	public Collection<TsbCommonCode> getCommonCodeList(TsbCommonCode commonCode) {
+//		return commonDao.getCommonCodeList(commonCode);
+//	}
+}

+ 105 - 1
style24.batch/src/main/java/com/style24/batch/biz/service/TsbGoodsService.java

@@ -13,8 +13,13 @@ import com.style24.core.biz.service.TscEnvsetService;
 import com.style24.core.biz.thirdparty.SafetyKoreaApi;
 import com.style24.persistence.domain.Coupon;
 import com.style24.persistence.domain.Goods;
+import com.style24.persistence.domain.GoodsIfIncomelot;
+import com.style24.persistence.domain.GoodsIfIncomelotitem;
+import com.style24.persistence.domain.GoodsIfMeasurement;
 import com.style24.persistence.domain.GoodsSafeNo;
 import com.style24.persistence.domain.GoodsSummary;
+import com.style24.persistence.domain.IfBrand;
+import com.style24.persistence.domain.IfProvider;
 
 import io.netty.util.internal.StringUtil;
 
@@ -41,6 +46,8 @@ public class TsbGoodsService {
 	@Autowired
 	private SafetyKoreaApi safetyKoreaApi;
 
+	@Autowired
+	private TsbWmsGoodsService wmsGoodsService;
 
 	/**
 	 * 상품 타이틀예약 작업
@@ -323,7 +330,7 @@ public class TsbGoodsService {
 		// 1. 대상 상품 조회
 		Collection<GoodsSafeNo> goodsSafeNoList = goodsDao.getGoodsSafeNoList();
 		// 2. 인증테이블 적용
-		for(GoodsSafeNo goodsSafeNo: goodsSafeNoList) {
+		for (GoodsSafeNo goodsSafeNo : goodsSafeNoList) {
 			try {
 				GagaMap result = safetyKoreaApi.getKoreaCertifyNo(goodsSafeNo.getGoodsNum()); // 품번으로 처리
 				if (result != null || !StringUtil.isNullOrEmpty(result.get("certNum").toString())) {
@@ -341,4 +348,101 @@ public class TsbGoodsService {
 		}
 	}
 
+	/**
+	 * WMS 실측사이즈 연용
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsWmsMeasurement(String jobdate) {
+
+		// wms 대상건 조회 (등록, 수정건 조회)
+		Collection<GoodsIfMeasurement> goodsMeasurementList = wmsGoodsService.getWmsMeasurementList(jobdate);
+
+		for (GoodsIfMeasurement goodsMeasurement : goodsMeasurementList) {
+			goodsDao.saveGoodsIfMeasurement(goodsMeasurement);
+		}
+	}
+
+	/**
+	 * WMS 입고정보 연동
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsWmsIncomelot(String jobdate) {
+
+		// wms 입고목록 조회 (등록, 수정건 조회)
+		Collection<GoodsIfIncomelot> goodsIfIncomelotList = wmsGoodsService.getWmsIncomelotList(jobdate);
+
+		for (GoodsIfIncomelot goodsIfIncomelot : goodsIfIncomelotList) {
+			goodsDao.saveGoodsIfIncomelot(goodsIfIncomelot);
+		}
+
+		// wms 입고상품목록 조회 (등록, 수정건 조회)
+		Collection<GoodsIfIncomelotitem> goodsIfIncomelotitemList = wmsGoodsService.getWmsIncomelotitemList(jobdate);
+
+		for (GoodsIfIncomelotitem goodsIfIncomelotitem : goodsIfIncomelotitemList) {
+			goodsDao.saveGoodsIfIncomelotitem(goodsIfIncomelotitem);
+		}
+	}
+
+	/**
+	 * 온라인 입고 상품 처리
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	@Transactional("shopTxnManager")
+	public void saveWmsGoods(String jobdate) {
+		GoodsIfIncomelot goodsIfIncomelot = new GoodsIfIncomelot();
+		goodsIfIncomelot.setRegNo(TsbConstants.REG_NO);
+		goodsIfIncomelot.setUpdNo(TsbConstants.REG_NO);
+		goodsIfIncomelot.setJobdate(jobdate);
+		goodsDao.saveWmsGoods(goodsIfIncomelot);
+
+	}
+
+	/**
+	 * WMS 브랜드/업체정보 송신
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	//@Transactional("wmsTxnManager")
+	public void saveWmsBrandProvider() {
+
+		//업체정보 송신(수정일 7일)
+		/*
+		 * 매핑 확인건
+		G065_10	자사-제조
+		G065_11	자사-사입
+		G065_12	자사-위탁
+		 */
+
+		Collection<IfProvider> ifProviderList = goodsDao.getSupplyCompanyList();
+
+		for (IfProvider ifProvider : ifProviderList) {
+			ifProvider.setRegNo(TsbConstants.REG_NO);
+			ifProvider.setUpdNo(TsbConstants.REG_NO);
+			wmsGoodsService.saveWmsProvider(ifProvider);
+		}
+
+		//브랜드, 브랜드/업체 관계정보 송신
+		Collection<IfBrand> ifBrandList = goodsDao.getBrandList();
+
+		for (IfBrand ifBrand : ifBrandList) {
+			ifBrand.setRegNo(TsbConstants.REG_NO);
+			ifBrand.setUpdNo(TsbConstants.REG_NO);
+			wmsGoodsService.saveWmsBrand(ifBrand);
+		}
+
+	}
+
 }

+ 89 - 0
style24.batch/src/main/java/com/style24/batch/biz/service/TsbWmsGoodsService.java

@@ -0,0 +1,89 @@
+package com.style24.batch.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.style24.batch.biz.dao.TsbWmsGoodsDao;
+import com.style24.persistence.domain.GoodsIfIncomelot;
+import com.style24.persistence.domain.GoodsIfIncomelotitem;
+import com.style24.persistence.domain.GoodsIfMeasurement;
+import com.style24.persistence.domain.IfBrand;
+import com.style24.persistence.domain.IfProvider;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * WMS 상품 연동  Service
+ *
+ * @author eskim
+ * @since 2021. 01. 01
+ */
+@Service
+@Slf4j
+public class TsbWmsGoodsService {
+
+	@Autowired
+	private TsbWmsGoodsDao wmsGoodsDao;
+
+	/**
+	 * WMS 실측사이즈 연용
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	public Collection<GoodsIfMeasurement> getWmsMeasurementList(String jobdate) {
+		return wmsGoodsDao.getWmsMeasurementList(jobdate);
+	}
+
+	/**
+	 * WMS 입고 목록
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	public Collection<GoodsIfIncomelot> getWmsIncomelotList(String jobdate) {
+		return wmsGoodsDao.getWmsIncomelotList(jobdate);
+	}
+
+	/**
+	 * WMS 입고 상품목록
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 01
+	 */
+	public Collection<GoodsIfIncomelotitem> getWmsIncomelotitemList(String jobdate) {
+		return wmsGoodsDao.getWmsIncomelotitemList(jobdate);
+	}
+
+	/**
+	 * WMS 업체정보 송신
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	//@Transactional("wmsTxnManager")
+	public void saveWmsProvider(IfProvider ifProvider) {
+		wmsGoodsDao.saveWmsProvider(ifProvider);
+	}
+
+	/**
+	 * WMS 업체정보 송신
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 05
+	 */
+	public void saveWmsBrand(IfBrand ifBrand) {
+		//브랜드 정보 송신
+		wmsGoodsDao.saveWmsBrand(ifBrand);
+		//WMS 브랜드업체관계정보 송신
+		wmsGoodsDao.saveWmsBrandProviderXref(ifBrand);
+	}
+
+}

+ 50 - 1
style24.batch/src/main/java/com/style24/batch/biz/task/TsbGoodsTask.java

@@ -12,6 +12,9 @@ import com.style24.batch.biz.job.goods.TsbGoodsRelateScoreJob;
 import com.style24.batch.biz.job.goods.TsbGoodsSnmJob;
 import com.style24.batch.biz.job.goods.TsbGoodsSummaryJob;
 import com.style24.batch.biz.job.goods.TsbGoodsTnmJob;
+import com.style24.batch.biz.job.goods.TsbGoodsWmsBrandproviderJob;
+import com.style24.batch.biz.job.goods.TsbGoodsWmsIncomelotJob;
+import com.style24.batch.biz.job.goods.TsbGoodsWmsMeasurementJob;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -45,6 +48,16 @@ public class TsbGoodsTask {
 	@Autowired
 	private TsbGoodsInfantsSafeNoJob goodsInfantsSafeNoJob;
 
+	@Autowired
+	private TsbGoodsWmsMeasurementJob goodsWmsMeasurementJob;
+
+	@Autowired
+	private TsbGoodsWmsIncomelotJob goodsWmsIncomelotJob;
+
+	@Autowired
+	private TsbGoodsWmsBrandproviderJob goodsWmsBrandproviderJob;
+
+
 
 	/**
 	 * 초 분 시 일 월 주(년)
@@ -148,11 +161,47 @@ public class TsbGoodsTask {
 	 * @throws Exception
 	 */
 	@Scheduled(cron = "${cron.goods.infants.safe}")
-	@Scheduled(fixedDelay = 3500000)
+	//@Scheduled(fixedDelay = 3500000)
 	@Async
 	public void tsbGoodsInfantsSafeNoJob() throws Exception {
 		goodsInfantsSafeNoJob.run("cron.goods.infants.safe");
 	}
 
+	/**
+	 * WMS 실측사이즈 연동 적용 주기 : 일배치 - 03시
+	 *
+	 * @throws Exception
+	 */
+	@Scheduled(cron = "${cron.goods.wms.measurement}")
+	//@Scheduled(fixedDelay = 3500000)
+	@Async
+	public void tsbGoodsWmsMeasurementJob() throws Exception {
+		goodsWmsMeasurementJob.runById("cron.goods.wms.measurement");
+	}
+
+	/**
+	 * WMS 입고상품 연동 적용 주기 : 일배치 - 03시 10분
+	 *
+	 * @throws Exception
+	 */
+	@Scheduled(cron = "${cron.goods.wms.incomelot}")
+	//@Scheduled(fixedDelay = 3500000)
+	@Async
+	public void tsbGoodsWmsIncomelotJob() throws Exception {
+		goodsWmsIncomelotJob.runById("cron.goods.wms.incomelot");
+	}
+
+	/**
+	 * WMS 업체/브랜드 송신 적용 주기 : 일배치 - 03시 12분
+	 *
+	 * @throws Exception
+	 */
+	@Scheduled(cron = "${cron.goods.wms.brandprovider}")
+	//@Scheduled(fixedDelay = 3500000)
+	@Async
+	public void tsbGoodsWmsBrandproviderJob() throws Exception {
+		goodsWmsBrandproviderJob.runById("cron.goods.wms.brandprovider");
+	}
+
 
 }

+ 28 - 0
style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfIncomelot.java

@@ -0,0 +1,28 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 상품 wms 입고정보 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 01
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsIfIncomelot extends TscBaseDomain {
+
+	private Integer lotno;	//입고번호
+	private int purchaseno;	//발주번호
+	private int providerno;	//공급처번호
+	private String providername;	//공급처명
+	private int brandno;	//브랜드번호
+	private String brandname;	//브랜드명
+	private String dateincome;	//wms생성일
+
+
+	private String jobdate; 	// 작업일 YYYYMMDD
+
+}

+ 30 - 0
style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfIncomelotitem.java

@@ -0,0 +1,30 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 상품 wms 입고상품정보 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 01
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsIfIncomelotitem extends TscBaseDomain {
+
+	private Integer lotno;	//입고번호
+	private Integer itemno;	//입고항목번호
+	private int wmsitemno;
+	private String dateincome;	//wms생성일
+	private int productno;	//상품번호
+	private String productcode;	//상품코드
+	private String productname;	//상품명
+	private String skucode;	//옵션번호
+	private int normalqty;	//일반수량
+	private int brokenqty;	//불량수량
+	private int totalqty;	//총수량
+	private String modelno;	//모델번호
+
+}

+ 33 - 0
style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfMeasurement.java

@@ -0,0 +1,33 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 상품 실측사이즈 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 01
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsIfMeasurement extends TscBaseDomain {
+
+	private String skucode;		//옵션번호
+	private int productno;	//상품 번호
+	private int productcode;	//상품 코드
+	private String typecd;	//상하의 타입
+	private String washingmethod;	//세탁방법
+	private float value1;	//치수1
+	private float value2;	//치수2
+	private float value3;	//치수3
+	private float value4;	//치수4
+	private float value5;	//치수5
+	private String memo;	//메모
+	private String dateinserted;	//등록일 yyyy-mm-dd hh:mi:ss
+	private String datelastmodified;	//수정일 yyyy-mm-dd hh:mi:ss
+	private String isuse;	//사용여부(1:Y, 0 N)
+	private int userlastmodified;	//수정자
+
+}

+ 33 - 0
style24.batch/src/main/java/com/style24/persistence/domain/GoodsIfProductsku.java

@@ -0,0 +1,33 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 상품 WMS 옵션재고 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 04
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsIfProductsku extends TscBaseDomain {
+
+	private String skucode;		//옵션번호
+	private String skumodelno;	//옵션모델번호
+	private int productno;		//상품번호
+	private String productcode;	//상품코드
+	private String option1;		//옵션1(색상)
+	private String option2;		//옵션2(사이즈)
+	private String option3;		//옵션3(스타일)-미사용
+	private int sellingstockamount;	//판매재고수량
+	private String sellingstocktypecd;	//판매재고유형
+	private int limitstockamount;		//
+	private String vendorskumodelno;	//업체옵션모델번호
+	private String vendorskucode;		//업체옵션코드
+	private String isvirtualstock;		//
+	private String datevirtualstock;	//
+	private String skucode88;			//88코드
+
+}

+ 28 - 0
style24.batch/src/main/java/com/style24/persistence/domain/IfBrand.java

@@ -0,0 +1,28 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * wms 연동 브랜드 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 05
+ */
+@SuppressWarnings("serial")
+@Data
+public class IfBrand extends TscBaseDomain {
+
+	private Integer brandno;            //브랜드 넘버
+	private String brandname;           //브랜드 명
+	private String datecreated;         //생성일
+	private String statuscd;            //상태
+	private String brandCd;             //브랜드코드
+	private String dateupdateed;        //수정일
+
+	private String supplyCompCd;       //업체코드
+	private int providerNo;            //공급처번호
+
+
+}

+ 30 - 0
style24.batch/src/main/java/com/style24/persistence/domain/IfProvider.java

@@ -0,0 +1,30 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * wms 연동 업체정보 Domain
+ *
+ * @author eskim
+ * @since 2021. 01. 05
+ */
+@SuppressWarnings("serial")
+@Data
+public class IfProvider extends TscBaseDomain {
+
+	private Integer providerno;		//공급처번호
+	private int vendorno;			//벤더번호 --- 대체값 확인
+	private String providername;	//공급저명
+	private String categorytypecd;	//분류코드
+	private String distributioncd;	//유통구분
+	private String chargename;		//처리담당자 이름
+	private String chargecellnum;	//처리담당자 전화번호
+	private String statuscd;		//상태 (Y: 사용, N: 미사용)
+	private String stockmgmttypecd;	//재고관리 유형
+	private String supplyCompCd;	//온라인공급업체코드
+	private String datecreated;		//생성일
+	private String dateLastmodified; //수정일
+
+}

+ 15 - 0
style24.batch/src/main/java/com/style24/persistence/mybatis/shop/TsbCommon.xml

@@ -0,0 +1,15 @@
+<?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.batch.biz.dao.TsbCommonDao">
+	
+	
+	<!-- WMS 연동 여부 -->
+	<select id="getWmsSyncYn" resultType="String">
+		/* TsbCommon.getWmsSyncYn */
+		SELECT UPPER(NVL(USE_YN,'N')) AS WMS_SYNC_YN
+		FROM TB_COMMON_CODE
+		WHERE CD_GB = 'G077'
+		AND CD = 'WMSSYNCYN'
+	</select>
+	
+</mapper>

+ 246 - 1
style24.batch/src/main/java/com/style24/persistence/mybatis/shop/TsbGoods.xml

@@ -4,7 +4,7 @@
 	
 	<!-- 상품 기본정보 이력 생성 -->
 	<insert id="createGoodsHst" parameterType="Goods">
-		/* AdmGoods.createGoodsHst */
+		/* TsbGoods.createGoodsHst */
 		INSERT INTO TB_GOODS_HST 
 		(       GOODS_CD
 		      , PRODUCT_NO
@@ -445,6 +445,7 @@
 	
 	<!-- 사용자검색어가 있는 상품 조회  -->
 	<select id="getGoodsByGooodsSnm1List"  resultType="Goods">
+		/* TsbGoods.getGoodsByGooodsSnm1List */
 		WITH RECURSIVE TMP_COLOR_GOODS AS (
 		    SELECT Z.GOODS_CD
 		         , REPLACE(CONCAT(GROUP_CONCAT(COLOR_GRP_CD),';',GROUP_CONCAT(COLOR_ENM),';',GROUP_CONCAT(CD_NM)),',',';') AS COLOR_INFO
@@ -1066,4 +1067,248 @@
 		     , UPD_DT = NOW()
 	</insert>
 	
+	<!--실측사이즈 저장-->
+	<insert id="saveGoodsIfMeasurement" parameterType="GoodsIfMeasurement">
+		/* TsbGoods.saveGoodsIfMeasurement */
+		INSERT INTO TB_IF_MEASUREMENT (
+		       SKUCODE
+		     , PRODUCTNO
+		     , PRODUCTCODE
+		     , TYPECD
+		     , WASHINGMETHOD
+		     , VALUE1
+		     , VALUE2
+		     , VALUE3
+		     , VALUE4
+		     , VALUE5
+		     , MEMO
+		     , DATEINSERTED
+		     , DATELASTMODIFIED
+		     , ISUSE
+		     , USERLASTMODIFIED
+		     , UPD_DT
+		)
+		VALUES(
+		       #{skucode}
+		     , #{productno}
+		     , #{productcode}
+		     , #{typecd}
+		     , #{washingmethod}
+		     , NVL(#{value1},0)
+		     , NVL(#{value2},0)
+		     , NVL(#{value3},0)
+		     , NVL(#{value4},0)
+		     , NVL(#{value5},0)
+		     , #{memo}
+		     , DATE_FORMAT(#{dateinserted}, '%Y-%m-%d %H:%i:%S')
+		     , DATE_FORMAT(#{datelastmodified}, '%Y-%m-%d %H:%i:%S')
+		     , NVL(#{isuse},'1')
+		     , #{userlastmodified}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       WASHINGMETHOD = #{washingmethod}
+		     , VALUE1 = NVL(#{value1},0)
+		     , VALUE2 = NVL(#{value2},0)
+		     , VALUE3 = NVL(#{value3},0)
+		     , VALUE4 = NVL(#{value4},0)
+		     , VALUE5 = NVL(#{value5},0)
+		     , MEMO = #{memo}
+		     , DATEINSERTED = DATE_FORMAT(#{dateinserted}, '%Y-%m-%d %H:%i:%S')
+		     , DATELASTMODIFIED = DATE_FORMAT(#{datelastmodified}, '%Y-%m-%d %H:%i:%S')
+		     , ISUSE = NVL(#{isuse},'1')
+		     , USERLASTMODIFIED = #{userlastmodified}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!--입고 저장-->
+	<insert id="saveGoodsIfIncomelot" parameterType="GoodsIfIncomelot">
+		/* TsbGoods.saveGoodsIfIncomelot */
+		INSERT INTO TB_IF_INCOMELOT (
+		       LOTNO
+		     , PURCHASENO
+		     , PROVIDERNO
+		     , PROVIDERNAME
+		     , BRANDNO
+		     , BRANDNAME
+		     , DATEINCOME
+		     , UPD_DT
+		)
+		VALUES (
+		       #{lotno}
+		     , #{purchaseno}
+		     , #{providerno}
+		     , #{providername}
+		     , #{brandno}
+		     , #{brandname}
+		     , DATE_FORMAT(#{dateincome}, '%Y-%m-%d %H:%i:%S')
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       PURCHASENO = #{purchaseno}
+		     , PROVIDERNO = #{providerno}
+		     , PROVIDERNAME = #{providername}
+		     , BRANDNO = #{brandno}
+		     , BRANDNAME = #{brandname}
+		     , DATEINCOME = DATE_FORMAT(#{dateincome}, '%Y-%m-%d %H:%i:%S')
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!--입고상품 저장-->
+	<insert id="saveGoodsIfIncomelotitem" parameterType="GoodsIfIncomelotitem">
+		/* TsbGoods.saveGoodsIfIncomelotitem */
+		INSERT INTO TB_IF_INCOMELOTITEM (
+		       LOTNO
+		     , ITEMNO
+		     , WMSITEMNO
+		     , DATEINCOME
+		     , PRODUCTNO
+		     , PRODUCTCODE
+		     , PRODUCTNAME
+		     , SKUCODE
+		     , NORMALQTY
+		     , BROKENQTY
+		     , TOTALQTY
+		     , MODELNO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{lotno}
+		     , #{itemno}
+		     , #{wmsitemno}
+		     , DATE_FORMAT(#{dateincome}, '%Y-%m-%d %H:%i:%S')
+		     , #{productno}
+		     , #{productcode}
+		     , #{productname}
+		     , #{skucode}
+		     , #{normalqty}
+		     , #{brokenqty}
+		     , #{totalqty}
+		     , #{modelno}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       WMSITEMNO = #{wmsitemno}
+		     , DATEINCOME = DATE_FORMAT(#{dateincome}, '%Y-%m-%d %H:%i:%S')
+		     , PRODUCTNO = #{productno}
+		     , PRODUCTCODE = #{productcode}
+		     , PRODUCTNAME = #{productname}
+		     , SKUCODE = #{skucode}
+		     , NORMALQTY = #{normalqty}
+		     , BROKENQTY = #{brokenqty}
+		     , TOTALQTY = #{totalqty}
+		     , MODELNO = #{modelno}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!--WMS 상품 저장-->
+	<insert id="saveWmsGoods" parameterType="GoodsIfIncomelot" >
+		/* TsbGoods.saveWmsGoods */
+		INSERT INTO TB_WMS_GOODS (
+		       PRODUCT_NO 
+		     , PRODUCT_CODE 
+		     , PRODUCT_NAME 
+		     , SKUCODE 
+		     , NORMAL_QTY 
+		     , BROKEN_QTY 
+		     , TOTAL_QTY 
+		     , MODEL_NO 
+		     , PROVIDER_NO
+		     , PROVIDER_NAME
+		     , BRAND_NO
+		     , BRAND_NAME
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT 
+		)
+		SELECT B.PRODUCTNO 
+		     , B.PRODUCTCODE 
+		     , B.PRODUCTNAME 
+		     , B.SKUCODE 
+		     , B.NORMALQTY 
+		     , B.BROKENQTY 
+		     , B.TOTALQTY 
+		     , B.MODELNO 
+		     , A.PROVIDERNO
+		     , A.PROVIDERNAME
+		     , A.BRANDNO
+		     , A.BRANDNAME 
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		FROM TB_IF_INCOMELOT  A
+		INNER JOIN TB_IF_INCOMELOTITEM B ON A.LOTNO = B.LOTNO 
+		WHERE 1 = 1
+		<choose>
+		    <when test='jobdate != null and jobdate != ""'>
+		AND A.DATEINCOME >= DATE_FORMAT(DATE_FORMAT(#{jobdate}, '%Y%m%d'), '%Y%m%d%H%i%S') 
+		<![CDATA[
+		AND A.DATEINCOME < DATE_FORMAT(DATE_ADD(DATE_FORMAT(#{jobdate}, '%Y%m%d'), INTERVAL 1 DAY), '%Y%m%d%H%i%S')
+		]]>
+		    </when>
+		    <otherwise>
+		AND A.DATEINCOME >= DATE_FORMAT(DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -1 DAY), '%Y%m%d'), '%Y%m%d%H%i%S') 
+		<![CDATA[
+		AND A.DATEINCOME < DATE_FORMAT(DATE_ADD(DATE_FORMAT(NOW(), '%Y%m%d'), INTERVAL 1 DAY), '%Y%m%d%H%i%S')
+		]]>
+		    </otherwise>
+		</choose>
+		ON DUPLICATE KEY UPDATE
+		       PRODUCT_NAME = IF(GOODS_REG_GB IS NULL, B.PRODUCTNAME, TB_WMS_GOODS.PRODUCT_NAME)
+		     , NORMAL_QTY = IF(GOODS_REG_GB IS NULL, B.NORMALQTY, TB_WMS_GOODS.NORMAL_QTY)
+		     , BROKEN_QTY = IF(GOODS_REG_GB IS NULL, B.BROKENQTY, TB_WMS_GOODS.BROKEN_QTY)
+		     , TOTAL_QTY = IF(GOODS_REG_GB IS NULL, B.TOTALQTY, TB_WMS_GOODS.TOTAL_QTY)
+		     , MODEL_NO = IF(GOODS_REG_GB IS NULL, B.MODELNO, TB_WMS_GOODS.MODEL_NO)
+		     , PROVIDER_NO = IF(GOODS_REG_GB IS NULL, A.PROVIDERNO, TB_WMS_GOODS.PROVIDER_NO)
+		     , PROVIDER_NAME = IF(GOODS_REG_GB IS NULL, A.PROVIDERNAME, TB_WMS_GOODS.PROVIDER_NAME)
+		     , BRAND_NO = IF(GOODS_REG_GB IS NULL, A.BRANDNO, TB_WMS_GOODS.BRAND_NO)
+		     , BRAND_NAME = IF(GOODS_REG_GB IS NULL, A.BRANDNAME, TB_WMS_GOODS.BRAND_NAME)
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 공급업체 목록 -->
+	<select id="getSupplyCompanyList" resultType="IfProvider">
+		/* TsbGoods.getSupplyCompanyList */
+		SELECT PROVIDER_NO AS PROVIDERNO
+		     , SUPPLY_COMP_NM AS PROVIDERNAME
+		     , '' AS CATEGORYTYPECD
+		     , '자사' AS DISTRIBUTIONCD
+		     , CS_CHARGE_NM AS CHARGENAME
+		     , CS_CHARGE_TELNO AS CHARGECELLNUM
+		     , CASE WHEN USE_YN = 'Y' THEN '정상'
+		            ELSE '사용중지' 
+		       END AS STATUSCD
+		     , 'WMS' AS STOCKMGMTTYPECD
+		     , SUPPLY_COMP_CD
+		FROM   TB_SUPPLY_COMPANY 
+		WHERE  DISTRIBUTION_GB  IN ('G065_10', 'G065_11', 'G065_12')  /* 자사 유통구분*/
+		AND UPD_DT >= DATE_FORMAT(DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -7 DAY), '%Y%m%d'), '%Y%m%d%H%i%S') 
+		<![CDATA[
+		AND UPD_DT < DATE_FORMAT(DATE_FORMAT(NOW(), '%Y%m%d'), '%Y%m%d%H%i%S')
+		]]>
+	</select>
+	
+	<!-- 브랜드 목록 -->
+	<select id="getBrandList" resultType="IfBrand">
+		/* TsbGoods.getBrandList */
+		SELECT A.BRAND_NO AS BRANDNO
+		     , A.BRAND_ENM AS BRANDNAME
+		     , CASE WHEN A.USE_YN = 'Y' THEN '정상'
+		            ELSE '사용안함' 
+		       END AS STATUSCD
+		     , A.BRAND_CD
+		     , A.SUPPLY_COMP_CD
+		     , B.PROVIDER_NO
+		FROM   TB_BRAND A
+		INNER JOIN TB_SUPPLY_COMPANY B ON A.SUPPLY_COMP_CD = B.SUPPLY_COMP_CD
+		WHERE  A.SELF_YN  = 'Y'  /* 자사 */
+		AND A.UPD_DT >= DATE_FORMAT(DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -7 DAY), '%Y%m%d'), '%Y%m%d%H%i%S') 
+		<![CDATA[
+		AND A.UPD_DT < DATE_FORMAT(DATE_FORMAT(NOW(), '%Y%m%d'), '%Y%m%d%H%i%S')
+		]]>
+	</select>
+	
 </mapper>

+ 197 - 0
style24.batch/src/main/java/com/style24/persistence/mybatis/wms/TsbWmsGoods.xml

@@ -0,0 +1,197 @@
+<?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.batch.biz.dao.TsbWmsGoodsDao">
+	
+	<!-- wms 실측 사이즈 목록   -->
+	<select id="getWmsMeasurementList"  resultType="GoodsIfMeasurement">
+		/* TsbWmsGoods.getWmsMeasurementList */
+		SELECT SKUCODE
+		     , PRODUCTNO
+		     , PRODUCTCODE
+		     , TYPECD
+		     , WASHINGMETHOD
+		     , VALUE1
+		     , VALUE2
+		     , VALUE3
+		     , VALUE4
+		     , VALUE5
+		     , MEMO
+		     , CONVERT(CHAR(19),DATEINSERTED,120) AS DATEINSERTED  /* yyyy-mm-dd hh:mi:ss */
+		     , CONVERT(CHAR(19),DATELASTMODIFIED,120) AS DATELASTMODIFIED 
+		     , ISUSE
+		     , USERLASTMODIFIED
+		FROM TB_IF_MEASUREMENT
+		WHERE 1 = 1 
+		<choose>
+		    <when test='jobdate != null and jobdate != ""'>
+		AND CONVERT(CHAR(8),DATELASTMODIFIED,112) = #{jobdate}
+		    </when>
+		    <otherwise>
+		AND CONVERT(CHAR(8),DATELASTMODIFIED,112) = CONVERT(CHAR(8),DATEADD(day,-1, GETDATE()),112)
+		    </otherwise>
+		</choose>
+	</select>
+	
+	<!-- wms 입고 목록   -->
+	<select id="getWmsIncomelotList"  parameterType="String" resultType="GoodsIfIncomelot">
+		/* TsbWmsGoods.getWmsIncomelotList */
+		SELECT LOTNO
+		     , PURCHASENO
+		     , PROVIDERNO
+		     , PROVIDERNAME
+		     , BRANDNO
+		     , BRANDNAME
+		     , CONVERT(CHAR(19),DATEINCOME,120) AS DATEINCOME  /* yyyy-mm-dd hh:mi:ss */
+		FROM TB_IF_INCOMELOT
+		WHERE 1 = 1 
+		<choose>
+		    <when test='jobdate != null and jobdate != ""'>
+		AND CONVERT(CHAR(8),DATEINCOME,112) = #{jobdate}
+		    </when>
+		    <otherwise>
+		AND CONVERT(CHAR(8),DATEINCOME,112) = CONVERT(CHAR(8),DATEADD(day,-1, GETDATE()),112)
+		    </otherwise>
+		</choose>
+	</select>
+	
+	<!-- wms 입고 상품목록   -->
+	<select id="getWmsIncomelotitemList" parameterType="String"  resultType="GoodsIfIncomelotitem">
+		/* TsbWmsGoods.getWmsIncomelotitemList */
+		SELECT LOTNO
+		     , ITEMNO
+		     , WMSITEMNO
+		     , CONVERT(CHAR(19),DATEINCOME,120) AS DATEINCOME  /* yyyy-mm-dd hh:mi:ss */
+		     , PRODUCTNO
+		     , PRODUCTCODE
+		     , PRODUCTNAME
+		     , SKUCODE
+		     , NORMALQTY
+		     , BROKENQTY
+		     , TOTALQTY
+		FROM TB_IF_INCOMELOTITEM
+		WHERE 1 = 1 
+		<choose>
+		    <when test='jobdate != null and jobdate != ""'>
+		AND CONVERT(CHAR(8),DATEINCOME,112) = #{jobdate}
+		    </when>
+		    <otherwise>
+		AND CONVERT(CHAR(8),DATEINCOME,112) = CONVERT(CHAR(8),DATEADD(day,-1, GETDATE()),112)
+		    </otherwise>
+		</choose>
+	</select>
+
+	<!--WMS 업체정보 송신-->
+	<insert id="saveWmsProvider" parameterType="IfProvider" >
+		/* TsbWmsGoods.saveWmsProvider */
+		SET IDENTITY_INSERT test.dbo.TB_IF_Provider ON
+		MERGE TB_IF_PROVIDER 
+		      USING (SELECT 'AA' AS DUAL) AS B
+		         ON (PROVIDERNO = #{providerno})
+		      WHEN MATCHED THEN
+		           UPDATE SET
+		                   PROVIDERNAME = #{providername}
+		                 , CATEGORYTYPECD = #{categorytypecd}
+		                 , DISTRIBUTIONCD = #{distributioncd}
+		                 , CHARGENAME = #{chargename}
+		                 , CHARGECELLNUM = #{chargecellnum}
+		                 , STATUSCD = #{statuscd}
+		                 , STOCKMGMTTYPECD = #{stockmgmttypecd}
+		                 , SUPPLY_COMP_CD = #{supplyCompCd}
+		                 , DATElASTMODIFIED = GETDATE()
+		      WHEN NOT MATCHED THEN
+		           INSERT (
+		                   PROVIDERNO
+		                 , VENDORNO  
+		                 , PROVIDERNAME
+		                 , CATEGORYTYPECD
+		                 , DISTRIBUTIONCD
+		                 , CHARGENAME
+		                 , CHARGECELLNUM
+		                 , STATUSCD
+		                 , STOCKMGMTTYPECD
+		                 , SUPPLY_COMP_CD
+		                 , DATECREATED
+		                 , DATElASTMODIFIED
+		           )
+		           VALUES (
+		                  #{providerno}
+		                , #{vendorno}
+		                , #{providername}
+		                , #{categorytypecd}
+		                , #{distributioncd}
+		                , #{chargename}
+		                , #{statuscd}
+		                , #{chargecellnum}
+		                , #{stockmgmttypecd}
+		                , #{dateLastmodified}
+		                , GETDATE()
+		                , GETDATE()
+		           );
+		SET IDENTITY_INSERT test.dbo.TB_IF_Provider OFF
+	</insert>
+	
+	<!--WMS 브랜드정보 송신-->
+	<insert id="saveWmsBrand" parameterType="IfBrand" >
+		/* TsbWmsGoods.saveWmsBrand */
+		SET IDENTITY_INSERT test.dbo.TB_IF_BRAND ON
+		MERGE TB_IF_BRAND 
+		      USING (SELECT 'AA' AS DUAL) AS B
+		         ON (BRANDNO = #{brandno})
+		      WHEN MATCHED THEN
+		           UPDATE SET
+		                   BRANDNAME = #{brandname}
+		                 , STATUSCD = #{statuscd}
+		                 , BRAND_CD = #{brandCd}
+		                 , DATEUPDATEED = GETDATE()
+		      WHEN NOT MATCHED THEN
+		           INSERT (
+		                   BRANDNO
+		                 , BRANDNAME
+		                 , STATUSCD
+		                 , BRAND_CD
+		                 , DATECREATED
+		                 , DATEUPDATEED
+		           )
+		           VALUES (
+		                  #{brandno}
+		                , #{brandname}
+		                , #{statuscd}
+		                , #{brandCd}
+		                , GETDATE()
+		                , GETDATE()
+		           );
+		SET IDENTITY_INSERT test.dbo.TB_IF_BRAND OFF
+	</insert>
+	
+	<!--WMS 브랜드업체관계정보 송신-->
+	<insert id="saveWmsBrandProviderXref" parameterType="IfBrand" >
+		/* TsbWmsGoods.saveWmsBrandProviderXref */
+		MERGE TB_IF_BRANDPROVIDERXREF 
+		      USING (SELECT 'AA' AS DUAL) AS B
+		         ON (BRANDNO = #{brandno})
+		      WHEN MATCHED THEN
+		           UPDATE SET
+		                   PROVIDERNO = #{providerNo}
+		                 , BRAND_CD = #{brandCd}
+		                 , SUPPLY_COMP_CD = #{supplyCompCd}
+		                 , DATEUPDATEED = GETDATE()
+		      WHEN NOT MATCHED THEN
+		           INSERT (
+		                   BRANDNO
+		                 , PROVIDERNO
+		                 , BRAND_CD
+		                 , SUPPLY_COMP_CD
+		                 , DATECREATED
+		                 , DATEUPDATEED
+		           )
+		           VALUES (
+		                  #{brandno}
+		                , #{providerNo}
+		                , #{brandCd}
+		                , #{supplyCompCd}
+		                , GETDATE()
+		                , GETDATE()
+		           );
+	</insert>
+	
+</mapper>

+ 3 - 0
style24.batch/src/main/resources/config/application-locd.yml

@@ -49,6 +49,9 @@ cron:
         relate.score: 2 22 2 29 2 ?
         summary: 2 22 2 29 2 ?
         infants.safe: 2 22 2 29 2 ?
+        wms.measurement: 2 22 2 29 2 ?
+        wms.incomelot: 2 22 2 29 2 ?
+        wms.brandprovider: 2 22 2 29 2 ?
     
     #통계
     statistics:

+ 11 - 1
style24.core/.gitignore

@@ -2,4 +2,14 @@ target/
 .settings/
 .classpath
 /bin/
-/target/
+/target/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### MacOS ###
+.DS_Store
+META-INF/context.xml

+ 33 - 33
style24.core/src/main/java/com/style24/core/biz/dao/TscAnswerPhaseDao.java

@@ -1,33 +1,33 @@
-package com.style24.core.biz.dao;
-
-import com.style24.core.support.annotation.ShopDs;
-import com.style24.persistence.domain.AnswerPhase;
-
-/**
- * 답변문구 Dao
- * 
- * @author gagamel
- * @since 2020. 10. 29
- */
-@ShopDs
-public interface TscAnswerPhaseDao {
-
-	/**
-	 * 답변문구 조회
-	 * @param ansSq - 답변일련번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 29
-	 */
-	AnswerPhase getAnswerPhase(Integer ansSq);
-
-	/**
-	 * 일대일문의답변문구 조회
-	 * @param ansPhase - 답변문구 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 29
-	 */
-	AnswerPhase getOneToOneAnswerPhase(AnswerPhase ansPhase);
-
-}
+package com.style24.core.biz.dao;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.AnswerPhase;
+
+/**
+ * 답변문구 Dao
+ * 
+ * @author gagamel
+ * @since 2020. 10. 29
+ */
+@ShopDs
+public interface TscAnswerPhaseDao {
+
+	/**
+	 * 답변문구 조회
+	 * @param ansSq - 답변일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	AnswerPhase getAnswerPhase(Integer ansSq);
+
+	/**
+	 * 문의답변문구 조회
+	 * @param ansPhase - 답변문구 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	AnswerPhase getQnaAnswerPhase(AnswerPhase ansPhase);
+
+}

+ 46 - 46
style24.core/src/main/java/com/style24/core/biz/service/TscAnswerPhaseService.java

@@ -1,46 +1,46 @@
-package com.style24.core.biz.service;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import com.style24.core.biz.dao.TscAnswerPhaseDao;
-import com.style24.persistence.domain.AnswerPhase;
-
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 답변문구 Service
- *
- * @author gagamel
- * @since 2020. 10. 29
- */
-@Service
-@Slf4j
-public class TscAnswerPhaseService {
-
-	@Autowired
-	private TscAnswerPhaseDao ansPhaseDao;
-
-	/**
-	 * 답변문구 조회
-	 * @param ansSq - 답변일련번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 29
-	 */
-	public AnswerPhase getAnswerPhase(Integer ansSq) {
-		return ansPhaseDao.getAnswerPhase(ansSq);
-	}
-
-	/**
-	 * 일대일문의 답변 템플릿 조회
-	 * @param ansPhase - 답변문구 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 29
-	 */
-	public AnswerPhase getOneToOneAnswerPhase(AnswerPhase ansPhase) {
-		return ansPhaseDao.getOneToOneAnswerPhase(ansPhase);
-	}
-
-}
+package com.style24.core.biz.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.style24.core.biz.dao.TscAnswerPhaseDao;
+import com.style24.persistence.domain.AnswerPhase;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 답변문구 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 29
+ */
+@Service
+@Slf4j
+public class TscAnswerPhaseService {
+
+	@Autowired
+	private TscAnswerPhaseDao ansPhaseDao;
+
+	/**
+	 * 답변문구 조회
+	 * @param ansSq - 답변일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	public AnswerPhase getAnswerPhase(Integer ansSq) {
+		return ansPhaseDao.getAnswerPhase(ansSq);
+	}
+
+	/**
+	 * 문의용 답변문구 조회
+	 * @param ansPhase - 답변문구 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	public AnswerPhase getQnaAnswerPhase(AnswerPhase ansPhase) {
+		return ansPhaseDao.getQnaAnswerPhase(ansPhase);
+	}
+
+}

+ 174 - 0
style24.core/src/main/java/com/style24/core/support/util/MaskingUtils.java

@@ -0,0 +1,174 @@
+package com.style24.core.support.util;
+
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 개인정보 마스킹 처리 Util Class
+ * @author gagamel
+ * @since 2020. 12. 29
+ */
+@Slf4j
+public class MaskingUtils {
+
+	private static final char DEFAULT_REPLACE = '*';
+
+	/**
+	 * ID 3자 이후 전체 마스킹 처리
+	 * <pre>
+	 * 		예)
+	 * 		abc1234 => abc****
+	 * </pre>
+	 * @param str - 입력문자열
+	 * @return
+	 */
+	public static String id(String str) {
+		String replaceString = str;
+
+		Matcher matcher = Pattern.compile("^(...)(.*)$").matcher(str);
+
+		if (matcher.matches()) {
+			replaceString = "";
+			int gCnt = matcher.groupCount();
+
+			for (int i = 1; i <= gCnt; i++) {
+				String replaceTarget = matcher.group(i);
+
+				if (i == 2) {
+					char[] c = new char[replaceTarget.length()];
+					Arrays.fill(c, DEFAULT_REPLACE);
+					replaceString = replaceString + String.valueOf(c);
+				} else {
+					replaceString = replaceString + replaceTarget;
+				}
+			}
+		}
+
+		return replaceString;
+	}
+
+	/**
+	 * 이름 첫글자와 마지막글자 외 모든 글자 마스킹 처리
+	 * <pre>
+	 * 		예)
+	 * 		환희 => 환*
+	 * 		홍길동 => 홍*동
+	 * 		남궁길동 => 남**동
+	 * </pre>
+	 * @param str - 입력문자열
+	 * @return
+	 */
+	public static String name(String str) {
+		String regex = "^(.)(.+)(.)$";
+		if (str.length() == 2) {
+			regex = "^(.)(.+)$";
+		}
+
+		Matcher matcher = Pattern.compile(regex).matcher(str);
+
+		if (matcher.find()) {
+			String replaceTarget = matcher.group(2);
+			char[] c = new char[replaceTarget.length()];
+			Arrays.fill(c, DEFAULT_REPLACE);
+			return str.replace(replaceTarget, String.valueOf(c));
+		}
+
+		return str;
+	}
+
+	/**
+	 * 성별 전체 문자열로 마스킹 처리
+	 * <pre>
+	 * 		예)
+	 * 		남 => *
+	 * </pre>
+	 * @param str - 입력문자열
+	 * @return
+	 */
+	public static String sex(String str) {
+		return all(str);
+	}
+
+	/**
+	 * 전화번호 중간번호 4자리 마스킹 처리
+	 * <pre>
+	 * 		예)
+	 * 		010-1234-5678 => 010-****-5678
+	 *		01012345678 => 010****5678
+	 * </pre>
+	 * @param str - 입력문자열
+	 * @return
+	 */
+	public static String phoneNo(String str) {
+		Matcher matcher = Pattern.compile("^(\\d{3})-?(\\d{3,4})-?(\\d{4})$").matcher(str);
+
+		if (matcher.find()) {
+			String replaceTarget = matcher.group(2);
+			char[] c = new char[replaceTarget.length()];
+			Arrays.fill(c, DEFAULT_REPLACE);
+			return str.replace(replaceTarget, String.valueOf(c));
+		}
+
+		return str;
+	}
+
+	/**
+	 * 이메일 3자 ~ @전 아이디에 대해 마스킹 처리
+	 * <pre>
+	 * 		예) abc123@style24.com => abc***@style24.com
+	 * </pre>
+	 * @param str - 입력문자열
+	 * @return
+	 */
+	public static String email(String str) {
+		Matcher matcher = Pattern.compile("^(...)(.*)([@]{1})(.*)$").matcher(str);
+
+		if (matcher.find()) {
+			String replaceTarget = matcher.group(2);
+			char[] c = new char[replaceTarget.length()];
+			Arrays.fill(c, DEFAULT_REPLACE);
+			return str.replace(replaceTarget, String.valueOf(c));
+		}
+
+		return str;
+	}
+
+	/**
+	 * 상세주소 전체 문자열로 마스킹 처리
+	 * <pre>
+	 * 		예)
+	 * 		일신빌딩 5,6층 => *********
+	 * </pre>
+	 * @param str - 입력문자열
+	 * @return
+	 */
+	public static String address(String str) {
+		return all(str);
+	}
+
+	/**
+	 * 전체 문자열 마스킹 처리
+	 * <pre>
+	 * 		예)
+	 * 		스타일24 프로젝트 마스킹 => ***************
+	 * </pre>
+	 * @param str - 입력문자열
+	 * @return
+	 */
+	public static String all(String str) {
+		Matcher matcher = Pattern.compile("^(.*)$").matcher(str);
+
+		if (matcher.find()) {
+			String replaceTarget = matcher.group(1);
+			char[] c = new char[replaceTarget.length()];
+			Arrays.fill(c, DEFAULT_REPLACE);
+			return str.replace(replaceTarget, String.valueOf(c));
+		}
+
+		return str;
+	}
+
+}

+ 26 - 26
style24.core/src/main/java/com/style24/persistence/mybatis/shop/TscAnswerPhase.xml

@@ -1,27 +1,27 @@
-<?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.TsaAnswerPhaseDao">
-
-	<!-- 답변문구 조회 -->
-	<select id="getAnswerPhase" parameterType="Integer" resultType="AnswerPhase">
-		/* TsaAnswerPhase.getAnswerPhase */
-		 SELECT ANS_TITLE   --답변제목
-		      , ANS_CONTENT --답변내용
-		FROM    TB_ANS_PHASE
-		WHERE   ANS_SQ = #{ansSq}
-		AND     USE_YN = 'Y'
-	</select>
-
-	<!-- 일대일문의 답변 템플릿 조회 -->
-	<select id="getOneToOneAnswerPhase" parameterType="AnswerPhase" resultType="AnswerPhase">
-		/* TsaAnswerPhase.getOneToOneAnswerPhase */
-		SELECT ANS_SQ      --답변일련번호
-		     , ANS_TITLE   --답변제목
-		     , ANS_CONTENT --답변내용
-		FROM   TB_ANS_PHASE
-		WHERE  ANS_SQ = #{ansSq}
-		AND    ANS_CLSF = #{ansClsf}
-		AND    USE_YN = 'Y'
-	</select>
-
+<?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.TsaAnswerPhaseDao">
+
+	<!-- 답변문구 조회 -->
+	<select id="getAnswerPhase" parameterType="Integer" resultType="AnswerPhase">
+		/* TsaAnswerPhase.getAnswerPhase */
+		 SELECT ANS_TITLE   --답변제목
+		      , ANS_CONTENT --답변내용
+		FROM    TB_ANS_PHASE
+		WHERE   ANS_SQ = #{ansSq}
+		AND     USE_YN = 'Y'
+	</select>
+
+	<!-- 문의용 답변문구 조회 -->
+	<select id="getQnaAnswerPhase" parameterType="AnswerPhase" resultType="AnswerPhase">
+		/* TsaAnswerPhase.getQnaAnswerPhase */
+		SELECT ANS_SQ      --답변일련번호
+		     , ANS_TITLE   --답변제목
+		     , ANS_CONTENT --답변내용
+		FROM   TB_ANS_PHASE
+		WHERE  ANS_SQ = #{ansSq}
+		AND    ANS_CLSF = #{ansClsf}
+		AND    USE_YN = 'Y'
+	</select>
+
 </mapper>

+ 32 - 0
style24.front/.classpath

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v9.0.22"/>
+	<classpathentry kind="lib" path="/style24.core/target/classes">
+		<attributes>
+			<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/classes"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Some files were not shown because too many files changed in this diff