JUSEUNG преди 5 години
ревизия
41f642aa05
променени са 100 файла, в които са добавени 23962 реда и са изтрити 0 реда
  1. 16 0
      .gitignore
  2. 6 0
      WEB-INF/web.xml
  3. 131 0
      pom.xml
  4. 34 0
      src/main/java/com/style24/admin/biz/dao/TsaAnswerPhaseDao.java
  5. 260 0
      src/main/java/com/style24/admin/biz/dao/TsaBusinessDao.java
  6. 51 0
      src/main/java/com/style24/admin/biz/dao/TsaClauseDao.java
  7. 79 0
      src/main/java/com/style24/admin/biz/dao/TsaCommonDao.java
  8. 69 0
      src/main/java/com/style24/admin/biz/dao/TsaCounselDao.java
  9. 42 0
      src/main/java/com/style24/admin/biz/dao/TsaCouponDao.java
  10. 117 0
      src/main/java/com/style24/admin/biz/dao/TsaDeliveryDao.java
  11. 139 0
      src/main/java/com/style24/admin/biz/dao/TsaDisplayDao.java
  12. 52 0
      src/main/java/com/style24/admin/biz/dao/TsaEnvsetDao.java
  13. 34 0
      src/main/java/com/style24/admin/biz/dao/TsaExchDao.java
  14. 43 0
      src/main/java/com/style24/admin/biz/dao/TsaFaqDao.java
  15. 1106 0
      src/main/java/com/style24/admin/biz/dao/TsaGoodsDao.java
  16. 68 0
      src/main/java/com/style24/admin/biz/dao/TsaLoginDao.java
  17. 33 0
      src/main/java/com/style24/admin/biz/dao/TsaMarketingDao.java
  18. 181 0
      src/main/java/com/style24/admin/biz/dao/TsaMorebetterDao.java
  19. 92 0
      src/main/java/com/style24/admin/biz/dao/TsaNoticeDao.java
  20. 72 0
      src/main/java/com/style24/admin/biz/dao/TsaOcmDao.java
  21. 188 0
      src/main/java/com/style24/admin/biz/dao/TsaOrderChangeDao.java
  22. 356 0
      src/main/java/com/style24/admin/biz/dao/TsaOrderDao.java
  23. 33 0
      src/main/java/com/style24/admin/biz/dao/TsaPgDao.java
  24. 71 0
      src/main/java/com/style24/admin/biz/dao/TsaPosDao.java
  25. 35 0
      src/main/java/com/style24/admin/biz/dao/TsaRefundDao.java
  26. 236 0
      src/main/java/com/style24/admin/biz/dao/TsaRendererDao.java
  27. 33 0
      src/main/java/com/style24/admin/biz/dao/TsaReturnDao.java
  28. 59 0
      src/main/java/com/style24/admin/biz/dao/TsaStockDao.java
  29. 325 0
      src/main/java/com/style24/admin/biz/dao/TsaSystemDao.java
  30. 465 0
      src/main/java/com/style24/admin/biz/dao/TsaWithdrawDao.java
  31. 53 0
      src/main/java/com/style24/admin/biz/service/TsaAnswerPhaseService.java
  32. 393 0
      src/main/java/com/style24/admin/biz/service/TsaBusinessService.java
  33. 68 0
      src/main/java/com/style24/admin/biz/service/TsaClauseService.java
  34. 106 0
      src/main/java/com/style24/admin/biz/service/TsaCommonService.java
  35. 97 0
      src/main/java/com/style24/admin/biz/service/TsaCounselService.java
  36. 166 0
      src/main/java/com/style24/admin/biz/service/TsaCouponService.java
  37. 186 0
      src/main/java/com/style24/admin/biz/service/TsaDeliveryService.java
  38. 160 0
      src/main/java/com/style24/admin/biz/service/TsaDisplayService.java
  39. 98 0
      src/main/java/com/style24/admin/biz/service/TsaEnvsetService.java
  40. 66 0
      src/main/java/com/style24/admin/biz/service/TsaFaqService.java
  41. 2710 0
      src/main/java/com/style24/admin/biz/service/TsaGoodsService.java
  42. 234 0
      src/main/java/com/style24/admin/biz/service/TsaKakaoService.java
  43. 111 0
      src/main/java/com/style24/admin/biz/service/TsaLoginService.java
  44. 91 0
      src/main/java/com/style24/admin/biz/service/TsaMarketingService.java
  45. 363 0
      src/main/java/com/style24/admin/biz/service/TsaMorebetterService.java
  46. 153 0
      src/main/java/com/style24/admin/biz/service/TsaNoticeService.java
  47. 106 0
      src/main/java/com/style24/admin/biz/service/TsaOcmService.java
  48. 580 0
      src/main/java/com/style24/admin/biz/service/TsaOrderChangeService.java
  49. 542 0
      src/main/java/com/style24/admin/biz/service/TsaOrderService.java
  50. 48 0
      src/main/java/com/style24/admin/biz/service/TsaPgService.java
  51. 120 0
      src/main/java/com/style24/admin/biz/service/TsaPosService.java
  52. 534 0
      src/main/java/com/style24/admin/biz/service/TsaRendererService.java
  53. 213 0
      src/main/java/com/style24/admin/biz/service/TsaStockService.java
  54. 531 0
      src/main/java/com/style24/admin/biz/service/TsaSystemService.java
  55. 1541 0
      src/main/java/com/style24/admin/biz/service/TsaWithdrawService.java
  56. 242 0
      src/main/java/com/style24/admin/biz/web/TsaBoardController.java
  57. 634 0
      src/main/java/com/style24/admin/biz/web/TsaBusinessController.java
  58. 221 0
      src/main/java/com/style24/admin/biz/web/TsaCommonController.java
  59. 238 0
      src/main/java/com/style24/admin/biz/web/TsaCustomerController.java
  60. 352 0
      src/main/java/com/style24/admin/biz/web/TsaDeliveryController.java
  61. 62 0
      src/main/java/com/style24/admin/biz/web/TsaDextuploadController.java
  62. 211 0
      src/main/java/com/style24/admin/biz/web/TsaDisplayController.java
  63. 325 0
      src/main/java/com/style24/admin/biz/web/TsaEnvsetController.java
  64. 2495 0
      src/main/java/com/style24/admin/biz/web/TsaGoodsController.java
  65. 55 0
      src/main/java/com/style24/admin/biz/web/TsaIndexController.java
  66. 549 0
      src/main/java/com/style24/admin/biz/web/TsaMarketingController.java
  67. 226 0
      src/main/java/com/style24/admin/biz/web/TsaOcmController.java
  68. 292 0
      src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java
  69. 614 0
      src/main/java/com/style24/admin/biz/web/TsaOrderController.java
  70. 75 0
      src/main/java/com/style24/admin/biz/web/TsaPgController.java
  71. 475 0
      src/main/java/com/style24/admin/biz/web/TsaPosController.java
  72. 216 0
      src/main/java/com/style24/admin/biz/web/TsaRendererController.java
  73. 169 0
      src/main/java/com/style24/admin/biz/web/TsaSettleController.java
  74. 91 0
      src/main/java/com/style24/admin/biz/web/TsaShipController.java
  75. 200 0
      src/main/java/com/style24/admin/biz/web/TsaStockController.java
  76. 586 0
      src/main/java/com/style24/admin/biz/web/TsaSystemController.java
  77. 425 0
      src/main/java/com/style24/admin/biz/web/TsaWithdrawController.java
  78. 48 0
      src/main/java/com/style24/admin/support/config/TsaMybatisShopConfig.java
  79. 48 0
      src/main/java/com/style24/admin/support/config/TsaMybatisWmsConfig.java
  80. 100 0
      src/main/java/com/style24/admin/support/config/TsaRedisSessionConfig.java
  81. 70 0
      src/main/java/com/style24/admin/support/config/TsaThymeleafConfig.java
  82. 119 0
      src/main/java/com/style24/admin/support/config/TsaWebMvcConfig.java
  83. 49 0
      src/main/java/com/style24/admin/support/controller/TsaBaseController.java
  84. 65 0
      src/main/java/com/style24/admin/support/controller/TsaErrorController.java
  85. 70 0
      src/main/java/com/style24/admin/support/env/TsaConstants.java
  86. 64 0
      src/main/java/com/style24/admin/support/interceptor/TsaDefaultInterceptor.java
  87. 48 0
      src/main/java/com/style24/admin/support/interceptor/TsaPosInterceptor.java
  88. 90 0
      src/main/java/com/style24/admin/support/security/TsaAuthenticationProvider.java
  89. 97 0
      src/main/java/com/style24/admin/support/security/TsaLoginDetails.java
  90. 117 0
      src/main/java/com/style24/admin/support/security/config/TsaSecurityConfig.java
  91. 73 0
      src/main/java/com/style24/admin/support/security/handler/TsaLoginSuccessHandler.java
  92. 33 0
      src/main/java/com/style24/admin/support/security/handler/TsaLogoutSuccessHandler.java
  93. 85 0
      src/main/java/com/style24/admin/support/security/session/TsaSession.java
  94. 54 0
      src/main/java/com/style24/admin/support/startup/TsaApplication.java
  95. 19 0
      src/main/java/com/style24/admin/support/startup/TsaServletInitializer.java
  96. 58 0
      src/main/java/com/style24/admin/support/util/TsitUtil.java
  97. 123 0
      src/main/java/com/style24/persistence/TsaPageRequest.java
  98. 31 0
      src/main/java/com/style24/persistence/domain/AdKeyword.java
  99. 28 0
      src/main/java/com/style24/persistence/domain/AdKeywordGoods.java
  100. 24 0
      src/main/java/com/style24/persistence/domain/Aflink.java

+ 16 - 0
.gitignore

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

+ 6 - 0
WEB-INF/web.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
+         version="4.0">
+</web-app>

+ 131 - 0
pom.xml

@@ -0,0 +1,131 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.style24</groupId>
+		<artifactId>root</artifactId>
+		<version>0.0.1-SNAPSHOT</version>
+	</parent>
+	<groupId>com.style24.admin</groupId>
+	<artifactId>style24.admin</artifactId>
+	<packaging>war</packaging>
+	<name>style24.admin</name>
+	<description>STYLE24 Admin</description>
+	
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-security</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.security</groupId>
+			<artifactId>spring-security-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-thymeleaf</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>nz.net.ultraq.thymeleaf</groupId>
+			<artifactId>thymeleaf-layout-dialect</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>servlets.com</groupId>
+			<artifactId>cos</artifactId>
+			<version>05Nov2002</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-fileupload</groupId>
+			<artifactId>commons-fileupload</artifactId>
+			<version>1.4</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.6</version>
+		</dependency>
+		
+		<!-- /// dextupload lib -->
+		<dependency>
+			<groupId>devpia.dextuploadnj</groupId>
+			<artifactId>dextuploadnj</artifactId>
+			<version>2.3.2</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/dextuploadnj-2.3.2.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>devpia.dextuploadnj</groupId>
+			<artifactId>devpia.dextuploadnj.support.spring</artifactId>
+			<version>2.3.2</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/dextuploadnj.support.spring-2.3.2.jar</systemPath>
+		</dependency>
+		<!-- \\\ dextupload lib -->
+		
+		<!-- /// WEB-INF lib -->
+		<dependency>
+			<groupId>com.gagaframework</groupId>
+			<artifactId>gagaframework-web-core</artifactId>
+			<version>1.7.1-RELEASE</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gagaframework-web-core-1.7.1-RELEASE.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.gagaframework</groupId>
+			<artifactId>gagaframework-web-security</artifactId>
+			<version>1.7.1-RELEASE</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gagaframework-web-security-1.7.1-RELEASE.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.gagaframework</groupId>
+			<artifactId>gagaframework-web-parameter</artifactId>
+			<version>1.7-RELEASE</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gagaframework-web-parameter-1.7-RELEASE.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.gagaframework</groupId>
+			<artifactId>gagaframework-web-rest</artifactId>
+			<version>1.7.1-RELEASE</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gagaframework-web-rest-1.7-RELEASE.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.gagaframework</groupId>
+			<artifactId>gagaframework-web-util</artifactId>
+			<version>1.7-RELEASE</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gagaframework-web-util-1.7-RELEASE.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>com.gagaframework</groupId>
+			<artifactId>gagaframework-excel</artifactId>
+			<version>1.7.1-RELEASE</version>
+			<scope>system</scope>
+			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/gagaframework-excel-1.7.1-RELEASE.jar</systemPath>
+		</dependency>
+		<!-- \\\ WEB-INF lib -->
+	</dependencies>
+	
+	<build>
+		<finalName>${project.name}</finalName>
+		<resources>
+			<resource>
+				<directory>src/main/java</directory>
+				<includes>
+					<include>**/*.xml</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>src/main/resources</directory>
+				<includes>
+					<include>**/*</include>
+				</includes>
+			</resource>
+		</resources>
+	</build>
+</project>

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

@@ -0,0 +1,34 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.AnswerPhase;
+
+/**
+ * 답변문구 Dao
+ * 
+ * @author gagamel
+ * @since 2020. 10. 29
+ */
+@ShopDs
+public interface TsaAnswerPhaseDao {
+
+	/**
+	 * 답변문구 목록
+	 * @param ansPhase - 답변문구 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	Collection<AnswerPhase> getAnswerPhaseList(AnswerPhase ansPhase);
+
+	/**
+	 * 답변문구 등록/수정
+	 * @param ansPhase - 답변문구 정보
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	void saveAnswerPhase(AnswerPhase ansPhase);
+
+}

+ 260 - 0
src/main/java/com/style24/admin/biz/dao/TsaBusinessDao.java

@@ -0,0 +1,260 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Aflink;
+import com.style24.persistence.domain.Brand;
+import com.style24.persistence.domain.BrandMd;
+import com.style24.persistence.domain.DeliveryLoc;
+import com.style24.persistence.domain.DelvFeePolicy;
+import com.style24.persistence.domain.SellStore;
+import com.style24.persistence.domain.ShipCompany;
+import com.style24.persistence.domain.SiteBrand;
+import com.style24.persistence.domain.StockSyncBase;
+import com.style24.persistence.domain.SupplyCompany;
+
+/**
+ * 영업관리 Dao
+ *
+ * @author gagamel
+ * @since 2020. 10. 14
+ */
+@ShopDs
+public interface TsaBusinessDao {
+
+	/**
+	 * 공급업체 목록
+	 * @param supplyComp - 공급업체 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	Collection<SupplyCompany> getSupplyCompanyList(SupplyCompany supplyComp);
+
+	/**
+	 * 공급업체 생성
+	 * @param supplyComp - 공급업체 정보
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	void createSupplyCompany(SupplyCompany supplyComp);
+
+	/**
+	 * 공급업체 수정
+	 * @param supplyComp - 공급업체 정보
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	void updateSupplyCompany(SupplyCompany supplyComp);
+
+	/**
+	 * 배송비정책 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 24
+	 */
+	Collection<DelvFeePolicy> getDeliveryFeePolicyList(String supplyCompCd);
+
+	/**
+	 * 배송비정책 생성
+	 * @param delvFeePolicy - 배송비정책 정보
+	 * @author gagamel
+	 * @since 2020. 11. 24
+	 */
+	void createDeliveryFeePolicy(DelvFeePolicy delvFeePolicy);
+
+	/**
+	 * 배송비정책 수정
+	 * @param delvFeePolicy - 배송비정책 정보
+	 * @author gagamel
+	 * @since 2020. 11. 24
+	 */
+	void updateDeliveryFeePolicy(DelvFeePolicy delvFeePolicy);
+
+	/**
+	 * 출고처관리 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 16
+	 */
+	Collection<DeliveryLoc> getDeliveryLocList(DeliveryLoc delvLoc);
+
+	/**
+	 * 브랜드 목록
+	 * @param brand - 브랜드 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Collection<Brand> getBrandList(Brand brand);
+
+	/**
+	 * 담당MD 목록
+	 * @param brandMd - 담당MD 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	Collection<BrandMd> getMdList(BrandMd brandMd);
+
+	/**
+	 * 브랜드담당MD 목록
+	 * @param brandCd - 브랜드코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	Collection<BrandMd> getBrandMdList(String brandCd);
+
+	/**
+	 * 브랜드담당MD 삭제
+	 * @param brandCd - 브랜드코드
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	void deleteBrandMd(String brandCd);
+
+	/**
+	 * 브랜드담당MD 등록
+	 * @param brandMd - 브랜드담당MD 정보
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	void createBrandMd(BrandMd brandMd);
+
+	/**
+	 * 브랜드 노출사이트 목록
+	 * @param brandCd - 브랜드코드
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	Collection<SiteBrand> getBrandSiteList(String brandCd);
+
+	/**
+	 * 브랜드 노출사이트 등록/수정
+	 * @param siteBrand - 사이트브랜드 정보
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	void saveBrandSite(SiteBrand siteBrand);
+
+	/**
+	 * 브랜드 등록
+	 * @param brand - 브랜드 정보
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	void createBrand(Brand brand);
+
+	/**
+	 * 브랜드 수정
+	 * @param brand - 브랜드 정보
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	void updateBrand(Brand brand);
+
+	/**
+	 * 출고처관리 저장
+	 * @param delvLoc - 출고처 정보
+	 * @author gagamel
+	 * @since 2020. 10. 16
+	 */
+	void saveDeliveryLoc(DeliveryLoc delvLoc);
+
+	/**
+	 * 재고연계관리 - 출고처 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	Collection<DeliveryLoc> getStockSyncDeliveryLocList(DeliveryLoc delvLoc);
+
+	/**
+	 * 재고연계관리 - 재고연계기준 목록
+	 * @param stockSyncBase - 재고연계기준 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	Collection<StockSyncBase> getStockSyncBaseList(StockSyncBase stockSyncBase);
+
+	/**
+	 * 재고연계관리 - 재고연계기준 저장
+	 * @param stockSyncBase - 재고연계기준 정보
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	void saveStockSyncBase(StockSyncBase stockSyncBase);
+
+	/**
+	 * 판매매장 목록
+	 * @param sellStore - 판매매장 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	Collection<SellStore> getSellStoreList(SellStore sellStore);
+
+	/**
+	 * 판매매장 정보 수정
+	 * @param sellStore - 판매매장 정보
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	void saveSellStore(SellStore sellStore);
+
+	/**
+	 * 제휴링크 목록
+	 * @param aflink - 제휴링크 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	Collection<Aflink> getAflinkList(Aflink aflink);
+
+	/**
+	 * 제휴링크 저장
+	 * @param aflink - 제휴링크 정보
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	void saveAflink(Aflink aflink);
+
+	/**
+	 * 제휴링크 삭제
+	 * @param aflink - 제휴링크 정보
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	void deleteAflink(Aflink aflink);
+
+	/**
+	 * 배송업체 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	Collection<ShipCompany> getShipCompanyList();
+
+	/**
+	 * 배송업체 저장
+	 * @param shipComp - 배송업체 정보
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	void saveShipCompany(ShipCompany shipComp);
+
+	/**
+	 * 배송업체 삭제
+	 * @param shipComp - 배송업체 정보
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	void deleteShipCompany(ShipCompany shipComp);
+
+}

+ 51 - 0
src/main/java/com/style24/admin/biz/dao/TsaClauseDao.java

@@ -0,0 +1,51 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Clause;
+
+/**
+ * 약관 Dao
+ * 
+ * @author gagamel
+ * @since 2020. 10. 29
+ */
+@ShopDs
+public interface TsaClauseDao {
+
+	/**
+	 * 약관 목록
+	 * @param clause - 약관 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	Collection<Clause> getClauseList(Clause clause);
+
+	/**
+	 * 약관 상세
+	 * @param clause - 약관 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	Clause getClauseDetail(Integer clauseSq);
+
+	/**
+	 * 약관 생성
+	 * @param clause - 약관 정보
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	void createClause(Clause clause);
+
+	/**
+	 * 약관 수정
+	 * @param clause - 약관 정보
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	void updateClause(Clause clause);
+
+}

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

@@ -0,0 +1,79 @@
+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
+ *
+ * @author eskim
+ * @since 2020. 10. 22
+ */
+@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 테이블 삭제
+	 *
+	 * @param searchData
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void deleteExceluploadSearCh(SearchData searchData);
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성
+	 *
+	 * @param searchData
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void createExceluploadSearch(SearchData searchData);
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성 - dummy 컬럼 포함
+	 *
+	 * @param searchData
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void createExceluploadSearchByAll(SearchData searchData);
+
+	/**
+	 * 샘플파일 시스템파일명 조회
+	 * @param sampleFileId - 샘플파일ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	String getSampleFileSystemFilename(String sampleFileId);
+
+	/**
+	 * WMS 연동 여부
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 16
+	 */
+	String getWmsSyncYn();
+
+}

+ 69 - 0
src/main/java/com/style24/admin/biz/dao/TsaCounselDao.java

@@ -0,0 +1,69 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Counsel;
+
+/**
+ * 상담(1:1문의) Dao
+ * 
+ * @author gagamel
+ * @since 2020. 12. 24
+ */
+@ShopDs
+public interface TsaCounselDao {
+
+	/**
+	 * 1:1문의 목록
+	 * @param counsel -상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	Collection<Counsel> getOneToOneQnaList(Counsel counsel);
+
+	/**
+	 * 1:1문의 상세
+	 * @param counsel - 상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	Counsel getOneToOneQna(Counsel counsel);
+
+	/**
+	 * 문의 답변 저장
+	 * @param counsel - 상담정보
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	void updateQnaAnswer(Counsel counsel);
+
+	/**
+	 * 상품문의 목록
+	 * @param counsel -상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	Collection<Counsel> getGoodsQnaList(Counsel counsel);
+
+	/**
+	 * 상품문의 상세
+	 * @param counsel - 상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	Counsel getGoodsQna(Counsel counsel);
+
+	/**
+	 * 상품문의 답변의뢰 (입점상품인 경우)
+	 * @param counsel - 상담 정보
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	void updateGoodsQnaAnswerTransfer(Counsel counsel);
+
+}

+ 42 - 0
src/main/java/com/style24/admin/biz/dao/TsaCouponDao.java

@@ -0,0 +1,42 @@
+package com.style24.admin.biz.dao;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.*;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * 쿠폰 DAO
+ * @author xyzp1539
+ * @since  2021-01-11
+ */
+@ShopDs
+public interface TsaCouponDao {
+	/**
+	 * 쿠폰 리스트 조회
+	 * @param  Coupon
+	 * @return ArrayList<Coupon>
+	 * @author xyzp1539
+	 * @since 2020-12-22
+	 */
+	ArrayList<Coupon> getCouponList(Coupon param);
+
+	/**
+	 * 쿠폰 리스트 카운트 조회
+	 * @param  Coupon
+	 * @return int
+	 * @author xyzp1539
+	 * @since 2020-12-22
+	 */
+	int getCouponListCnt(Coupon param);
+
+	/**
+	 * 쿠폰 등록
+	 * @param params
+	 * @author xyzp1539
+	 * @since  2021-01-12
+	 */
+	void couponInsert(Coupon params);
+}

+ 117 - 0
src/main/java/com/style24/admin/biz/dao/TsaDeliveryDao.java

@@ -0,0 +1,117 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Delivery;
+
+
+/**
+ * 배송관리 Dao
+ *
+ * @author moon
+ * @since 2020. 11. 05
+ */
+@ShopDs
+public interface TsaDeliveryDao {
+
+	/**
+	 * 배송 목록
+	 *
+	 * @param delivery - 배송정보
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	Collection<Delivery> getDeliveryList(Delivery delivery);
+
+	/**
+	 * 주문 상세
+	 *
+	 * @param ordDtlNo - 주문상세번호
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	Collection<Delivery> getOrderDetail(long ordDtlNo);	
+	
+	/**
+	 * 주문상세 상태 값 변경
+	 *
+	 * @param delivery 
+	 * @return int
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	int updateOrderDetailStat(Delivery delivery);
+	
+	/**
+	 * 주문 상세 이력 등록
+	 *
+	 * @param delivery
+	 * @return void
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	void createOrderDetailHst(Delivery delivery);	
+	
+	/**
+	 * 출고금지상품 목록
+	 *
+	 * @param delivery
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	Collection<Delivery> getBangoodsList(Delivery delivery);	
+	
+	/**
+	 * 출고금지상품 삭제
+	 *
+	 * @param delivery
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	void deleteBangoods(Delivery delivery);	
+	
+	/**
+	 * 출고금지상품 등록 대상목록
+	 *
+	 * @param delivery
+	 * @return Collection<TsaDelivery>
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	Collection<Delivery> getBangoodsRegistList(Delivery delivery);
+
+	/**
+	 * 출고금지상품 카운트
+	 *
+	 * @param delivery
+	 * @return int
+	 * @author moon
+	 * @since 2020. 11. 06
+	 */
+	int getBangoodsListCnt(Delivery delivery);
+
+	/**
+	 * 출고금지상품 등록
+	 *
+	 * @param delivery
+	 * @author moon
+	 * @since 2020. 11. 06
+	 */
+	void createBangoods(Delivery delivery);
+	
+	/**
+	 * 배송/회수지시 목록
+	 *
+	 * @param Delivery - 배송/회수지시 정보
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 11
+	 */	
+	Collection<Delivery> getDeliveryWithdrawDirectiveList(Delivery delivery);
+
+		
+}

+ 139 - 0
src/main/java/com/style24/admin/biz/dao/TsaDisplayDao.java

@@ -0,0 +1,139 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Category;
+import com.style24.persistence.domain.ItemkindCategory;
+
+/**
+ * 전시 Dao
+ *
+ * @author
+ * @since 2020. 12. 16
+ */
+@ShopDs
+public interface TsaDisplayDao {
+
+	/**
+	 * 카테고리 목록
+	 * @param category - 카테고리 정보
+	 * @return
+	 * @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);
+
+}

+ 52 - 0
src/main/java/com/style24/admin/biz/dao/TsaEnvsetDao.java

@@ -0,0 +1,52 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.CustGradePolicy;
+import com.style24.persistence.domain.Envset;
+
+/**
+ * 환경설정 Dao
+ * 
+ * @author gagamel
+ * @since 2020. 10. 21
+ */
+@ShopDs
+public interface TsaEnvsetDao {
+
+	/**
+	 * 환경설정 저장
+	 * @param envset - 환경설정 정보
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	void createEnvset(Envset envset);
+
+	/**
+	 * 환경설정 목록
+	 * @param envset - 환경설정 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	Collection<Envset> getEnvsetList(Envset envset);
+
+	/**
+	 * 회원등급정책 저장
+	 * @param policy - 회원등급정책 정보
+	 * @author gagamel
+	 * @since 2021. 1. 7
+	 */
+	void createCustomerGradePolicy(CustGradePolicy policy);
+
+	/**
+	 * 회원등급정책 목록
+	 * @param policy - 회원등급정책 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 7
+	 */
+	Collection<CustGradePolicy> getCustomerGradePolicyList(CustGradePolicy policy);
+
+}

+ 34 - 0
src/main/java/com/style24/admin/biz/dao/TsaExchDao.java

@@ -0,0 +1,34 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@ShopDs
+public interface TsaExchDao {
+	
+	
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 43 - 0
src/main/java/com/style24/admin/biz/dao/TsaFaqDao.java

@@ -0,0 +1,43 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Faq;
+
+/**
+ * FAQ Dao
+ * 
+ * @author gagamel
+ * @since 2020. 11. 3
+ */
+@ShopDs
+public interface TsaFaqDao {
+
+	/**
+	 * FAQ 목록
+	 * @param faq - FAQ 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	Collection<Faq> getFaqList(Faq faq);
+
+	/**
+	 * FAQ 등록/수정
+	 * @param faq - FAQ 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	void saveFaq(Faq faq);
+
+	/**
+	 * FAQ 상세
+	 * @param faqSq - FAQ일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	Faq getFaq(Integer faqSq);
+
+}

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

@@ -0,0 +1,1106 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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;
+import com.style24.persistence.domain.GoodsEpSkip;
+import com.style24.persistence.domain.GoodsHst;
+import com.style24.persistence.domain.GoodsImg;
+import com.style24.persistence.domain.GoodsNaverLowestPrice;
+import com.style24.persistence.domain.GoodsNotiInfo;
+import com.style24.persistence.domain.GoodsPriceRes;
+import com.style24.persistence.domain.GoodsResSell;
+import com.style24.persistence.domain.GoodsSafeNo;
+import com.style24.persistence.domain.GoodsSearch;
+import com.style24.persistence.domain.GoodsTnmRes;
+import com.style24.persistence.domain.GoodsVideo;
+import com.style24.persistence.domain.Itemkind;
+import com.style24.persistence.domain.NotiInfo;
+import com.style24.persistence.domain.Notice;
+import com.style24.persistence.domain.NoticeGoods;
+import com.style24.persistence.domain.Option;
+import com.style24.persistence.domain.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;
+
+import com.gagaframework.web.parameter.GagaMap;
+
+/**
+ * 상품관리 Dao
+ *
+ * @author eskim
+ * @since 2020. 10. 16
+ */
+@ShopDs
+public interface TsaGoodsDao {
+
+	/**
+	 * 품목 목록
+	 * @param itemkind
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	Collection<Itemkind> getItemkindList(Itemkind itemkind);
+
+	/**
+	 * 품목 저장(등록/저장)
+	 * @param itemkind - 품목 정보
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	void saveItemkindInfo(Itemkind itemkind);
+
+	/**
+	 * 품목 삭제
+	 * @param itemkind - 품목 정보
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	void deleteItemkindInfo(Itemkind itemkind);
+
+	/**
+	 * 색상목록 조회
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	Collection<Color> getColorList(Color color);
+
+	/**
+	 * 색상 저장
+	 * @param color
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	void saveColor(Color color);
+
+	/**
+	 * 상품정보고시 목록
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	Collection<NotiInfo> getNotiInfoList(NotiInfo notiInfo);
+
+	/**
+	 * 상품정보고시 항목 목록
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	Collection<NotiInfo> getNotiInfoItemList(NotiInfo notiInfo);
+
+	/**
+	 * 상품정보고시 상세 저장
+	 * @param notiInfo
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	void saveNotiInfo(NotiInfo notiInfo);
+
+	/**
+	 * WMS 색상 매핑목록 조회
+	 *
+	 * @param wmsColorMapping
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	Collection<WmsColorMapping> getWmsColorMappingList(WmsColorMapping wmsColorMapping);
+
+	/**
+	 * WMS 색상 매핑 저장
+	 * @param wmsColorMapping
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	void saveWmsColorMapping(WmsColorMapping wmsColorMapping);
+
+	/**
+	 * WMS 스타일년도 매핑목록 조회
+	 *
+	 * @param wmsStyleYearMapping
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	Collection<WmsStyleYearMapping> getWmsStyleYearMappingList(WmsStyleYearMapping wmsStyleYearMapping);
+
+	/**
+	 * WMS 스타일년도 매핑 저장
+	 * @param wmsStyleYearMapping
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	void saveWmsStyleYearMapping(WmsStyleYearMapping wmsStyleYearMapping);
+
+	/**
+	 * WMS 시즌 매핑목록 조회
+	 *
+	 * @param wmsStyleYearMapping
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	Collection<WmsSeasonMapping> getWmsSeasonMappingList(WmsSeasonMapping wmsSeasonMapping);
+
+	/**
+	 * WMS 시즌 매핑 저장
+	 * @param wmsStyleYearMapping
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	void saveWmsSeasonMapping(WmsSeasonMapping wmsSeasonMapping);
+
+	/**
+	 * 상품 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 20
+	 */
+	int getGoodsListCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 20
+	 */
+	Collection<Goods> getGoodsList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 목록 기본정보 엑셀다운로드
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Collection<GagaMap> getGoodsInfoExcelList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 이미지 필수 항목 입력 여부 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Collection<Goods> getGoodsImgsYn(Goods goods);
+
+	/**
+	 * 상품 상세
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Goods getGoods(Goods goods);
+
+	/**
+	 * 상품 상세 정보 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	Collection<GoodsDesc> getGoodsDescList(GoodsDesc goodsDesc);
+
+	/**
+	 * 상품 정보 이력
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2019. 08. 12
+	 */
+	Collection<GoodsHst> getGoodsHstList(Goods goods);
+
+	/**
+	 * 상품 옵션 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 26
+	 */
+	Collection<Option> getGoodsSizeList(Goods goods);
+
+	/**
+	 * 상품 색상목록 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 18
+	 */
+	Collection<GoodsImg> getGoodsColorList(Goods goods);
+
+	/**
+	 * 상품 고시 조회
+	 *
+	 * @param goodsNotiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 12
+	 */
+	Collection<GoodsNotiInfo> getGoodsNotiInfoList(GoodsNotiInfo goodsNotiInfo);
+
+	/**
+	 * 상품의 정보고시 항목 목록
+	 *
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 18
+	 */
+	Collection<NotiInfo> getNotiGoodsInfoList(NotiInfo notiInfo);
+
+	/**
+	 * 구성상품 목록
+	 *
+	 * @param goodsNotiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	Collection<GoodsCompose> getGoodsDetailComposeList(Goods goods);
+
+	/**
+	 * 안전인증대상 상품 저장
+	 *
+	 * @author eskim
+	 * @since 2020. 12. 07
+	 */
+	void saveGoodsSafeNo(GoodsSafeNo goodsSafeNo);
+
+	/**
+	 * 상품 기본 정보 이력 생성
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void createGoodsHst(Goods goods);
+
+	/**
+	 * 상품 수정 항목 일괄변경
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	void updateGoodsState(Goods goods);
+
+	/**
+	 * 상품 품목변경
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void updateGoodItemKindCd(Goods goods);
+
+	/**
+	 * 상품 자동 검색어 조회
+	 *
+	 * @param goodsCd
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	String getGoodsSnm(String goodsCd);
+
+	/**
+	 * 상품검색어 수정
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void updateGoodsSnm(Goods goods);
+
+	/**
+	 * 상품 품목변경 고시정보 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	Collection<GoodsNotiInfo> getNewNotiInfo(Goods goods);
+
+	/**
+	 * 상품 품목변경 고시정보 삭제
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void deleteGoodsNotiInfo(Goods goods);
+
+	/**
+	 * 상품 고시 정보 수정
+	 *
+	 * @param goodsNotiInfo
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	void saveGoodsNotiInfo(GoodsNotiInfo goodsNotiInfo);
+
+	/**
+	 * 상품 기본 정보 수정
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	void updateGoods(Goods goods);
+
+	/**
+	 * 상품 상세정보 삭제
+	 *
+	 * @param godsDesc
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	void deleteGoodsDesc(GoodsDesc godsDesc);
+
+	/**
+	 * 상품 상세 정보 이력 생성
+	 * @param createGoodsDetailDesc
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	public void createGoodsDetailDescHst(GoodsDesc godsDesc);
+
+	/**
+	 * 상품 상세정보 등록
+	 *
+	 * @param godsDesc
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	void createGoodsDesc(GoodsDesc godsDesc);
+
+	/**
+	 * 구성상품 저장
+	 *
+	 * @param goodsCompose
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	void saveGoodsCompose(GoodsCompose goodsCompose);
+
+	/**
+	 * 상품 옵션/재고 정보 이력생성
+	 *
+	 * @param option
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	void createStockHst(Option option);
+
+	/**
+	 * 상품 옵션/재고 정보 수정
+	 *
+	 * @param stock
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	void saveStock(Option option);
+
+	/**
+	 * 상품 기본 정보 등록
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	void createGoods(Goods goods);
+
+	/**
+	 * 상품통계 생성
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	void createGoodsSmmary(Goods goods);
+
+//	/**
+//	 * 상품 품목별 매핑 카테고리 저장
+//	 *
+//	 * @param goods
+//	 * @author eskim
+//	 * @since 2020. 10. 30
+//	 */
+//	void createCategoryGoods(Goods goods);
+
+//	/**
+//	 * 상품 이미지 저장
+//	 *
+//	 * @param goodsImg
+//	 * @author eskim
+//	 * @since 2020. 10. 30
+//	 */
+//	void saveGoodsImgInfo(GoodsImg goodsImg);
+
+	/**
+	 * 상품코드 생성
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	void createGoodsSequence(Goods goods);
+
+	/**
+	 * 상품 타이틀 관리 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	int getGoodsTitleReserveCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 타이틀 관리 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	Collection<GoodsTnmRes> getGoodsTitleReserveList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 타이틀 조회(기간 체크용)
+	 *
+	 * @param goodsTnmRes
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	int getGoodsTnmDupChkCount(GoodsTnmRes goodsTnmRes);
+
+	/**
+	 * 상품 타이틀 예약 등록
+	 *
+	 * @param goodsTnmRes
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	void createGoodTnmRes(GoodsTnmRes goodsTnmRes);
+
+	/**
+	 * 상품 타이틀 수정
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	void updateGoodTnm(Goods goods);
+
+	/**
+	 * 상품 타이틀 예약건 초기화
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	void updateGoodTnmInit(Goods goods);
+
+	/**
+	 * 상품 타이틀 예약 삭제
+	 *
+	 * @param goodsTnmRes
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	void deleteGoodTnmRes(GoodsTnmRes goodsTnmRes);
+
+	/**
+	 * 상품 타이틀 초기값 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	Goods getGoodTnmInit(Goods goods);
+
+	/**
+	 * 상품예약판매 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	int getGoodsResSellCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품예약판매 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<TsaGoodsResSell>
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	Collection<GoodsResSell> getGoodsResSellList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품예약판매 조회(기간 체크용)
+	 *
+	 * @param goodsResSell
+	 * @return int
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	int getGoodsResSellDupChkCount(GoodsResSell goodsResSell);
+
+	/**
+	 * 상품예약판매 등록
+	 *
+	 * @param goodsResSell
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	void createGoodResSell(GoodsResSell goodsResSell);
+
+	/**
+	 * 상품예약판매 등록 시 재고연동 비활성화
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	void updateGoodsErpStockLinkYn(Goods goods);
+
+	/**
+	 * 상품예약판매 삭제
+	 *
+	 * @param goodsResSell
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	void deleteGoodResSell(GoodsResSell goodsResSell);
+
+	/**
+	 * 네이버 EP 제외 상품 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	int getGoodsEpSkipCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 네이버 EP 제외 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<GoodsEpSkip>
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	Collection<GoodsEpSkip> getGoodsEpSkipList(GoodsSearch goodsSearch);
+
+	/**
+	 * 네이버 EP 제외 상품 조회(기간 체크용)
+	 *
+	 * @param GoodsEpSkip
+	 * @return Collection<GoodsEpSkip>
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	int getGoodsEpSkipDupChkCount(GoodsEpSkip GoodsEpSkip);
+
+	/**
+	 * 네이버 EP 제외 상품 예약 등록
+	 *
+	 * @param goodsEpSkip
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	void createGoodEpSkip(GoodsEpSkip goodsEpSkip);
+
+	/**
+	 * 네이버 EP 제외 상품 예약 삭제
+	 *
+	 * @param goodsEpSkip
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	void deleteGoodEpSkip(GoodsEpSkip goodsEpSkip);
+
+	/**
+	 * 상품 상세공지 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 05
+	 */
+	Collection<Notice> getNoticeList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 상세공지 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 06
+	 */
+	Collection<NoticeGoods> getNoticeGoodsList(Notice notice);
+
+	/**
+	 * 상품 상세공지 상품 저장
+	 *
+	 * @param noticeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 06
+	 */
+	void saveNoticeGoods(NoticeGoods noticeGoods);
+
+	/**
+	 * 상품 상세공지 상품 삭제
+	 *
+	 * @param noticeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 06
+	 */
+	void deleteNoticeGoods(NoticeGoods noticeGoods);
+
+	/**
+	 * 상품 가격예약 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	int getGoodsPriceResCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 가격예약 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<GoodsPriceRes>
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	Collection<GoodsPriceRes> getGoodsPriceResList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 가격예약 조회(기간 체크용)
+	 *
+	 * @param goodsPriceRes
+	 * @return int
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	int getGoodsPriceResDupChkCount(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 가격예약 등록(화면)
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	void createGoodPriceRes(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 가격예약 삭제
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	void deleteGoodPriceRes(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	Collection<GoodsVideo> getGoodsVideoList(GoodsVideo goodsVideo);
+
+	/**
+	 * 상품 동영상 사용안함으로 변경
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void updateNotUseGoodsVideo(Video video);
+
+	/**
+	 * 동영상 일련번호 조회
+	 *
+	 * @param video
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	String getVideoSeq(Video video);
+
+	/**
+	 * 동영상 등록
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void createVideo(Video video);
+
+	/**
+	 * 동영상 수정
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void updateVideo(Video video);
+
+	/**
+	 * 동영상 위치 삭제 Y 처리
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void delVideoDispLoc(Video video);
+
+	/**
+	 * 동영상 위치 수정/저장
+	 *
+	 * @param video
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	void saveVideoDispLoc(Video video);
+
+	/**
+	 * 상품 옵션 존재여부 확인
+	 *
+	 * @param option
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	int getGoodsOptionCount(Option option);
+
+	/**
+	 * 상품 가격 승인 목록
+	 *
+	 * @param goodsPriceHst
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	Collection<GoodsPriceRes> getGoodsSupplyPriceList(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 가격수정
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	void updateGoodsPrice(Goods goods);
+
+	/**
+	 * 상품 판매수수료율 수정
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	void updateSellFeeRate(Goods goods);
+
+	/**
+	 * 상품 가격승인 적용일자 변경
+	 *
+	 * @param goodsPriceRes
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	void updateGoodsSupplyPricecfrmDt(GoodsPriceRes goodsPriceRes);
+
+	/**
+	 * 상품 네이버 최저가 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 08
+	 */
+	Collection<GoodsNaverLowestPrice> getGoodsNaverPriceList(GoodsSearch goodsSearch);
+
+	/**
+	 * 상품 네이버 최저가 최종 작업일
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 09
+	 */
+	String getGoodsNaverLowestPriceReqYmd();
+
+	/**
+	 * 상품 네이버 최저가  삭제
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 09
+	 */
+	void deleteGoodsNaverLowestPrice();
+
+	/**
+	 * 상품 네이버 최저가 저장
+	 *
+	 * @param goodsNaverLowestPrice
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 09
+	 */
+	void saveGoodsNaverLowestPrice(GoodsNaverLowestPrice goodsNaverLowestPrice);
+
+	/**
+	 * 상품 구매등급 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 11
+	 */
+	Collection<Goods> getGoodsDetailOrderGradeList(Goods goods);
+
+	/**
+	 * 상품 구매등급 삭제
+	 *
+	 * @param map
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 11
+	 */
+	void deleteGoodsCustGrade(Goods goods);
+
+	/**
+	 * 상품 구매등급 저장
+	 *
+	 * @param map
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 11
+	 */
+	void createGoodsCustGrade(Goods goods);
+
+	/**
+	 * 광고 키워드 목록
+	 *
+	 * @param adKeyword
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 14
+	 */
+	Collection<AdKeyword> getAdKeywordList(AdKeyword adKeyword);
+
+	/**
+	 * 광고 키워드 저장
+	 *
+	 * @param adKeywordGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 14
+	 */
+	void saveAdKeyword(AdKeyword adKeyword);
+
+	/**
+	 * 광고 키워드 상품 목록
+	 *
+	 * @param adKeyword
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 14
+	 */
+	Collection<AdKeywordGoods> getAdKeywordGoodsList(AdKeyword adKeyword);
+
+	/**
+	 * 광고 키워드 상품 저장
+	 *
+	 * @param adKeywordGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 14
+	 */
+	void saveAdKeywordGoods(AdKeywordGoods adKeywordGoods);
+
+	/**
+	 * 광고 키워드 상품 삭제
+	 *
+	 * @param noticeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 14
+	 */
+	void deleteAdKeywordGoods(AdKeywordGoods adKeywordGoods);
+
+	/**
+	 * 재입고알림 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 12. 16
+	 */
+	int getReinboundInformCount(GoodsSearch goodsSearch);
+
+	/**
+	 * 재입고알림 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<ReinboundInform>
+	 * @author eskim
+	 * @since 2020. 12. 16
+	 */
+	Collection<ReinboundInform> getReinboundInformList(GoodsSearch goodsSearch);
+
+	/**
+	 * 재입고 알림톡 발송처리
+	 *
+	 * @param params
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 12. 17
+	 */
+	void updateReinboundInform(ReinboundInform reinboundInform);
+
+	/**
+	 * 상품이미지 목록
+	 *
+	 * @param goodsImg
+	 * @return Collection<GoodsImg>
+	 * @author eskim
+	 * @since 2020. 12. 16
+	 */
+	Collection<GoodsImg> getGoodsImageList(GoodsImg goodsImg);
+
+	/**
+	 * 상품이미지 전체 삭제
+	 * @param goodsImg - 상품이미지 정보
+	 * @throws
+	 * @author eskim
+	 * @since 2020. 12. 21
+	 */
+	public void deleteGoodsImageTotal(GoodsImg goodsImg);
+
+	/**
+	 * 상품이미지 삭제
+	 * @param goodsImg - 상품이미지 정보
+	 * @throws
+	 * @author eskim
+	 * @since 2020. 12. 21
+	 */
+	public void deleteGoodsImage(GoodsImg goodsImg);
+
+	/**
+	 * 상품이미지 등록
+	 * @param goodsImg - 상품이미지 정보
+	 * @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
+	 */
+	int getGoodsWmsIncomelotListCount(WmsGoods wmsGoods);
+
+	/**
+	 * 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);
+
+
+}

+ 68 - 0
src/main/java/com/style24/admin/biz/dao/TsaLoginDao.java

@@ -0,0 +1,68 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.User;
+
+/**
+ * 운영관리 Dao
+ * @author gagamel
+ * @since 2019. 12. 4
+ */
+@ShopDs
+public interface TsaLoginDao {
+
+	/**
+	 * ID로 사용자 정보 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	User getUserById(String userId);
+
+	/**
+	 * 로그인실패 남기기
+	 * @param user - 사용자정보
+	 * @author gagamel
+	 * @date 2020. 10. 5
+	 */
+	void createLoginFail(User user);
+
+	/**
+	 * 로그인 실패건수 조회
+	 * @param user - 사용자정보
+	 * @return 로그인 실패건수
+	 * @author gagamel
+	 * @date 2020. 10. 5
+	 */
+	int getLoginFailCount(User user);
+
+	/**
+	 * 최종로그인일시 Update
+	 * @param userNo - 사용자번호
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	void updateLastLoginDate(Integer userNo);
+
+	/**
+	 * 로그인이력 남기기
+	 * @param user - 사용자정보
+	 * @author gagamel
+	 * @date 2020. 10. 5
+	 */
+	void createLoginHistory(User user);
+
+	/**
+	 * 로그인 메뉴 목록
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	Collection<Menu> getLoginMenuList(Integer userNo);
+
+}

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

@@ -0,0 +1,33 @@
+package com.style24.admin.biz.dao;
+
+import org.springframework.stereotype.Component;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * 마케팅 Dao
+ *
+ * @author xodud1202
+ * @since 2020. 12. 17
+ */
+@ShopDs
+@Component
+public interface TsaMarketingDao {
+	/* xodud1202 진행 */
+
+	/**
+	 * 사은품 프로모션 리스트
+	 * @param marketing
+	 * @return
+	 * @author xodud1202
+	 * @since 2020. 12. 17
+	 */
+	Collection<FreeGoodsPromotion> getFreeGoodsPromotionList(FreeGoodsPromotion marketing);
+
+	/* // xodud1202 진행 */
+
+}

+ 181 - 0
src/main/java/com/style24/admin/biz/dao/TsaMorebetterDao.java

@@ -0,0 +1,181 @@
+package com.style24.admin.biz.dao;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.MoreBetter;
+import com.style24.persistence.domain.MoreBetterBurden;
+import com.style24.persistence.domain.MoreBetterGoods;
+import com.style24.persistence.domain.MoreBetterSection;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+
+/**
+ * 마케팅 다다익선 Dao
+ *
+ * @author bin2107
+ * @since 2021. 1. 12
+ */
+@ShopDs
+@Component
+public interface TsaMorebetterDao {
+    /* CSB 진행 */
+    /**
+     * 다다익선 프로모션 리스트
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2020. 12. 28
+     */
+    Collection<MoreBetter> getMorebetterList(MoreBetter param);
+
+    /**
+     * 다다익선 상세조회
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    MoreBetter getMorebetterMstInfo(Integer tmtbSq);
+
+    /**
+     * 다다익선 구간 조회
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    Collection<MoreBetterSection> getMorebetterSectionValList(Integer tmtbSq);
+
+    /**
+     * 다다익선 구간 조회
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    Collection<MoreBetterGoods> getMorebetterSupplyCompList(MoreBetterGoods merebetterGoods);
+
+    Collection<MoreBetterGoods> getMorebetterBrandList(MoreBetterGoods merebetterGoods);
+
+    Collection<MoreBetterGoods> getMorebetterApplyGoodsList(MoreBetterGoods merebetterGoods);
+
+    Collection<MoreBetterGoods> getMorebetterExceptGoodsList(MoreBetterGoods merebetterGoods);
+
+    /**
+     * 다다익선 구간 조회
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    Collection<MoreBetterBurden> getMorebetterBurdenList(Integer tmtbSq);
+
+    /**
+     * 다다익선 마스터(TB_TMTB) 저장
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2020. 12. 28
+     */
+    void saveMorebetterMst(MoreBetter tmtb);
+
+    /**
+     * 다다익선 적용대상 설정(TB_TMTB_GOODS) 저장
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 7
+     */
+    void saveMorebetterGoods(MoreBetterGoods regSupplyComp);
+
+    /**
+     * 다다익선 할인구간설정 2차조건(TB_TMTB_SECTION) 저장
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 6
+     */
+    void saveMorebetterSection(MoreBetterSection regSection);
+
+    /**
+     * 다다익선 조건에 따른 할인혜택(금액할인) 설정(TB_TMTB_VAL) 저장
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 6
+     */
+    void saveMorebetterVal(MoreBetterSection regSection);
+
+    /**
+     * 다다익선 업체분담율(TB_TMTB_BURDEN) 저장
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2020. 12. 28
+     */
+    void saveMorebetterBurden(MoreBetterBurden regBurden);
+
+    /**
+     * 다다익선 공급업체(TB_TMTB_GOODS) 삭제
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 12
+     */
+    void deleteTmtbSupplyCompanyList(MoreBetterGoods moreBetterGoods);
+
+    /**
+     * 다다익선 브랜드(TB_TMTB_GOODS) 삭제
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 12
+     */
+    void deleteTmtbBrandList(MoreBetterGoods moreBetterGoods);
+
+    /**
+     * 다다익선 적용상품(TB_TMTB_GOODS) 삭제
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 12
+     */
+    void deleteTmtbApplyGoodsList(MoreBetterGoods moreBetterGoods);
+
+    /**
+     * 다다익선 제외상품(TB_TMTB_GOODS) 삭제
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 12
+     */
+    void deleteTmtbExceptGoodsList(MoreBetterGoods moreBetterGoods);
+
+    /**
+     * 다다익선 할인구간설정(TB_TMTB_SECTION) 삭제
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 6
+     */
+    void deleteTmtbSectionList(MoreBetterSection moreBetterSection);
+
+    /**
+     * 다다익선 조건에 따른 할인혜택(금액할인) 설정(TB_TMTB_VAL) 삭제
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 6
+     */
+    void deleteTmtbValList(MoreBetterSection moreBetterSection);
+
+    /**
+     * 다다익선 업체분담율(TB_TMTB_BURDEN) 삭제
+     * @param MoreBetter
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 12
+     */
+    void deleteTmtbBurdenList(MoreBetterBurden moreBetterBurden);
+    /* // CSB 진행 */
+}

+ 92 - 0
src/main/java/com/style24/admin/biz/dao/TsaNoticeDao.java

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

+ 72 - 0
src/main/java/com/style24/admin/biz/dao/TsaOcmDao.java

@@ -0,0 +1,72 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Extmall;
+import com.style24.persistence.domain.ExtmallNoti;
+import com.style24.persistence.domain.ExtmallOrigin;
+import com.style24.persistence.domain.ExtmallPriceSync;
+
+/**
+ * 영업망관리 Dao
+ *
+ * @author gagamel
+ * @since 2020. 11. 5
+ */
+@ShopDs
+public interface TsaOcmDao {
+
+	/**
+	 * 제휴몰 목록
+	 * @param extmall - 제휴몰 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	Collection<Extmall> getExtmallList(Extmall extmall);
+
+	/**
+	 * 제휴몰 등록/수정
+	 * @param extmall - 제휴몰 정보
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	void saveExtmall(Extmall extmall);
+
+	/**
+	 * 제휴몰 고시정보 목록
+	 * @param extmallNoti - 제휴몰고시정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 6
+	 */
+	Collection<ExtmallNoti> getExtmallNotiinfoList(ExtmallNoti extmallNoti);
+
+	/**
+	 * 제휴몰 원산지 목록
+	 * @param extmallOrigin - 제휴몰원산지 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 12
+	 */
+	Collection<ExtmallOrigin> getExtmallOriginList(ExtmallOrigin extmallOrigin);
+
+	/**
+	 * 제휴몰가격연계 목록
+	 * @param extmallPriceSync - 제휴몰가격연계 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	Collection<ExtmallPriceSync> getExtmallPriceSyncList(ExtmallPriceSync extmallPriceSync);
+
+	/**
+	 * 제휴몰가격연계 등록/수정
+	 * @param extmallPriceSync - 제휴몰가격연계 정보
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	void saveExtmallPriceSync(ExtmallPriceSync extmallPriceSync);
+
+}

+ 188 - 0
src/main/java/com/style24/admin/biz/dao/TsaOrderChangeDao.java

@@ -0,0 +1,188 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@ShopDs
+public interface TsaOrderChangeDao {
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문취소,반품,교환 대상목록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	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 updateOrderDetailItem(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문상세단품정보 이력 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createOrderDetailItemHst(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 상품옵션 재고 원복
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2021. 01. 08
+	 */
+	int updateOptionQty(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문상세정보(취소,반품) 이력 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createOrderDetailHstCnclRtn(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문상세정보 수정
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int updateOrderDetail(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문변경정보상세 등록
+	 *
+	 * @param OrderChange - 주문 변경 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createOrderChangeDetail(OrderChange orderChange);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문환불금액정보 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createPayment(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문환불정보 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int createRefund(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문추가배송금액 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2021. 01. 06
+	 */
+	int createDeliveryFee(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문사은품전체취소
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int updateOrdFreegiftDel(Order order);
+	
+
+	
+
+	
+
+	
+	/**
+	 * 주문상세 > 주문취소 > 고객환불계좌정보 조회
+	 *
+	 * @param order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2021. 01. 04
+	 */
+	Collection<Order> getRefundAccount(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소 > 고객환불계좌정보 중복체크
+	 *
+	 * @param order
+	 * @return int
+	 * @author jsh77b
+	 * @since 2021. 01. 05
+	 */
+	int getRefundAccountCheck(Order order);
+	
+	/**
+	 * 주문상세 > 주문취소 > 고객환불계좌정보 등록
+	 *
+	 * @param order
+	 * @return int
+	 * @author jsh77b
+	 * @since 2021. 01. 05
+	 */
+	int saveRefundAccount(Order order);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 356 - 0
src/main/java/com/style24/admin/biz/dao/TsaOrderDao.java

@@ -0,0 +1,356 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@ShopDs
+public interface TsaOrderDao {
+
+	/**
+	 * 주문 목록 카운트
+	 * @param Order
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	int getOrderListCount(Order order);
+
+	/**
+	 * 주문 목록
+	 * @param Order
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderList(Order order);
+
+	/**
+	 * 주문기본정보
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderInfoList(Order order);
+
+	/**
+	 * 주문상품정보 목록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderDetailList(Order order);
+
+	/**
+	 * 주문상세 > 사은품목록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderFreeGiftList(Order order);
+
+	/**
+	 * 배송정보
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getDeliveryAddrList(Order order);
+
+	/**
+	 * 결제내역 > 결제 기본정보
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderPaymentBasicInfoList(Order order);
+
+	/**
+	 * 배송비 정보
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getDeliveryFeeList(Order order);
+
+	/**
+	 * 반품/교환 > 반품/교환 정보
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderChangeList(Order order);
+
+	/**
+	 * 환불정보
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderRefundInfo(Order order);
+
+	/**
+	 * 상담내역
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderCounselInfo(Order order);
+
+	/**
+	 * 변경내역 > 주문요청 관리자 메모
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderMemoList(Order order);
+
+	/**
+	 * 입점업체미발주 주문목록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	Collection<Order> getOrderSellerUnorderList(Order order);
+
+	/**
+	 * 입점업체 엑셀다운용 임시테이블 삭제
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	void deleteEntryExcelDownTmp(Order order);
+
+	/**
+	 * 주문상세상태 수정 - 입점
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	int updateOrderDetailStat(Order order);
+
+	/**
+	 * 주문상세 이력 등록
+	 *
+	 * @param Order
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	int createOrderDetailHst(Order order);
+
+	/**
+	 * 엑셀 다운로드용 임시테이블 데이타 체크
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	int getEntryUploadExcelCheck(Order order);
+
+	/**
+	 * 입점업체 엑셀다운용 임시테이블 생성
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	void createEntryExcelDownTmp(Order order);
+
+	/**
+	 * 입점업체미발주목록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	Collection<Order> getSellerUnorderList(Order order);
+
+	/**
+	 * 주문 엑셀다운로드
+	 *
+	 * @param Order
+	 * @param handler - ResultHandler
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	void getSellerUnorderList(Order order, ResultHandler<Order> handler);
+
+	/**
+	 * 주문상세 정보
+	 *
+	 * @param ordDtlNo - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	Order getOrderDetailInfo(Order order);
+
+	/**
+	 * 주문상세정보 변경 - 송장번호 적용(입점)
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	int updateOrderDetailInvoice(Order order);
+
+	/**
+	 * 주문상세 > 주문메오 > 주문메모정보조회
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	Order getOrderMemoInfo(Order order);
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	int createOrderMemo(Order order);
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모수정
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	int updateOrderMemo(Order order);
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모삭제
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	int deleteOrderMemo(Order order);
+
+	/**
+	 * 주문상품 상세 변경 이력 화면
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	Collection<Order> getOrderDetailHistoryList(Order order);
+
+	/**
+	 * 쿠폰사용 내역 팝업 화면
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	Collection<Order> getOrderDiscountCouponList(Order order);
+
+	/**
+	 * 포인트사용 내역 팝업 화면
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	Collection<Order> getOrderDiscountPointList(Order order);
+
+	/**
+	 * 상품권사용 내역 팝업 화면
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	Collection<Order> getOrderGiftcardHstList(Order order);
+
+	/**
+	 * 다다익선적용 내역 팝업 화면
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	Collection<Order> getOrderTmtbHstList(Order order);
+
+	/**
+	 * 주문상세상태를 변경
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	int changedOrdDtlStat(Order order);
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 33 - 0
src/main/java/com/style24/admin/biz/dao/TsaPgDao.java

@@ -0,0 +1,33 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@ShopDs
+public interface TsaPgDao {
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 71 - 0
src/main/java/com/style24/admin/biz/dao/TsaPosDao.java

@@ -0,0 +1,71 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.gagaframework.web.parameter.GagaMap;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Pos;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 매장POS Dao
+ * 
+ * @author moon
+ * @since 2020. 11. 13
+ */
+@ShopDs
+@Repository
+public interface TsaPosDao {
+
+	/**
+	 * 매장로그인 정보 조회
+	 * 
+	 * @param pos
+	 * @return Pos
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	Pos getStoreLoginInfo(Pos pos);
+
+	/**
+	 * 출고대기목록, 출고목록
+	 * 
+	 * @param pos - 매장
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	Collection<Pos> getPosDeliveryList(Pos pos);
+
+	/**
+	 * 정산내역
+	 * 
+	 * @param pos - 매장
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	Collection<Pos> getPosUsacList(Pos pos);
+
+	/**
+	 * Cnplus엑셀다운로드
+	 * 
+	 * @param pos - 매장
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	Collection<GagaMap> getOrderExcelList(Pos pos);
+
+	/**
+	 * 매장 r/t여부 조회   ???????
+	 * 
+	 * @param pos - 매장
+	 * @return int
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */	
+	int getShopRtCheck(Pos pos);
+
+}

+ 35 - 0
src/main/java/com/style24/admin/biz/dao/TsaRefundDao.java

@@ -0,0 +1,35 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@ShopDs
+public interface TsaRefundDao {
+	
+	
+	
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

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

@@ -0,0 +1,236 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Brand;
+import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.DeliveryLoc;
+import com.style24.persistence.domain.Itemkind;
+import com.style24.persistence.domain.SupplyCompany;
+
+/**
+ * 콤보박스, 체크박스, 라디오버튼 구성 시 필요한 Renderer Dao
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@ShopDs
+public interface TsaRendererDao {
+
+	/**
+	 * 공급업체 목록
+	 * @param supplyComp
+	 * @return 공급업체 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<CommonCode> getSupplyCompanyList(SupplyCompany supplyComp);
+
+	/**
+	 * 공통코드 목록
+	 * @param commoncode - 공통코드 정보
+	 * @return 공통코드 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<CommonCode> getCommonCodeList(CommonCode commoncode);
+
+	/**
+	 * 최상위메뉴 목록
+	 * @param pmenuId - 상위메뉴ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<CommonCode> getTopMenuList(String pmenuId);
+
+	/**
+	 * 전체 메뉴 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<CommonCode> getAllMenuList();
+
+//	/**
+//	 * 벤더외부몰 목록
+//	 * @param vendorId - 벤더ID
+//	 * @return 벤더외부몰 목록
+//	 * @author gagamel
+//	 * @since 2019. 12. 6
+//	 */
+//	Collection<CommonCode> getVendorExtmallList(String vendorId);
+//
+//	/**
+//	 * 벤더외부몰판매매장 목록
+//	 * @param vendorId - 벤더ID
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 4. 28
+//	 */
+//	Collection<CommonCode> getVendorExtmallSellStoreList(String vendorId);
+//
+	/**
+	 * 브랜드 목록
+	 * @param brand --브랜드 정보
+	 * @return 브랜드 목록
+	 * @author eskim
+	 * @since 2020. 10. 20
+	 */
+	Collection<CommonCode> getBrandList(Brand brand);
+
+	/**
+	 * 권한별 브랜드 목록
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author eskim
+	 * @since 2019. 6.17
+	 */
+	Collection<CommonCode> getAuthBrandList(int userNo);
+
+	/**
+	 * 출고처 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return 출고처 목록
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	Collection<CommonCode> getDeliveryLocList(DeliveryLoc delvLoc);
+
+//	/**
+//	 * 정보고시 목록
+//	 * @param goodsCd
+//	 * @return
+//	 * @author jaewonHo
+//	 * @param goodsCd
+//	 * @since 2019. 12. 6
+//	 */
+//	Collection<CommonCode> getCateInfoList(String goodsCd);
+//
+	/**
+	 * 품목 목록
+	 * @param itemkind
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 19
+	 */
+	Collection<CommonCode> getItemkindList(Itemkind itemkind);
+
+//	/**
+//	 * 브랜드그룹 목록
+//	 * @return
+//	 * @author eskim
+//	 * @since 2019. 12. 10
+//	 */
+//	Collection<CommonCode> getBrandGroupList();
+//
+	/**
+	 * 컬러 목록
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	Collection<CommonCode> getColorList(Color color);
+
+//
+//	/**
+//	 * 사용중 대카테고리 목록
+//	 * @param cateGb
+//	 * @return
+//	 * @author sasa004
+//	 * @since 2020. 01. 02
+//	 */
+//	Collection<CommonCode> getTCategoryList(String cateGb);
+//
+	/**
+	 * 브랜드에 등록된 MD 목록
+	 * @return MD 목록
+	 * @author eskim
+	 * @since 2020. 10. 19
+	 */
+	Collection<CommonCode> getBrandMdList();
+
+	/**
+	 * 택배사명 목록 조회
+	 * @return CommonCode
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	Collection<CommonCode> getShipCompanyList();
+//
+//	/**
+//	 * MD별 브랜드 목록 조회
+//	 * @param mdId
+//	 * @return CommonCode
+//	 * @author jaewonHo
+//	 * @since 2020. 02. 04
+//	 */
+//	Collection<CommonCode> getMdBrandList(String mdId);
+//
+//	/**
+//	 * MD별 브랜드 목록 조회
+//	 * @param mdId
+//	 * @return CommonCode
+//	 * @author jaewonHo
+//	 * @since 2020. 02. 04
+//	 */
+//	Collection<CommonCode> getMdBrandGrpList(String mdId);
+//
+//	/**
+//	 * 인스타그램 계정리스트 조회
+//	 * @return Collection<CommonCode>
+//	 * @author 이명철
+//	 * @since 2020. 3. 18.
+//	 */
+//	Collection<CommonCode> getInstaAccount();
+//
+//	/**
+//	 * 판매몰조회
+//	 * @return
+//	 * @author swkim
+//	 * @since 2020. 03. 19
+//	 */
+//	Collection<CommonCode> getSellStoreList();
+
+	/**
+	 * 문의용 답변문구 목록
+	 * @param ansClsf - 답변종류
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	Collection<CommonCode> getQnaAnswerPhaseList(String ansClsf);
+
+//	/**
+//	 * 제휴링크 목록
+//	 * @param afChannel - 제휴채널
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 5. 4
+//	 */
+//	Collection<CommonCode> getAflinkList(String afChannel);
+
+	/**
+	 * 색상그룹코드 RGB 목록
+	 *
+	 * @param
+	 * @return 코드설명 목록
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	Collection<CommonCode> getColorGrpCdRgbList();
+
+	/**
+	 * 업체별 배송비정책 목록
+	 *
+	 * @param supplyCompCd - 업체코드
+	 * @return 배송비정책 목록
+	 * @author eskim
+	 * @since 2020. 11. 24
+	 */
+	Collection<CommonCode> getSupplyDeliveryFeePolicyList(String supplyCompCd);
+
+}

+ 33 - 0
src/main/java/com/style24/admin/biz/dao/TsaReturnDao.java

@@ -0,0 +1,33 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@ShopDs
+public interface TsaReturnDao {
+	
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

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

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

+ 325 - 0
src/main/java/com/style24/admin/biz/dao/TsaSystemDao.java

@@ -0,0 +1,325 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Alarm;
+import com.style24.persistence.domain.AlarmReceiver;
+import com.style24.persistence.domain.Batch;
+import com.style24.persistence.domain.BatchLog;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.MenuAccessHst;
+import com.style24.persistence.domain.MenuRole;
+import com.style24.persistence.domain.SampleFile;
+import com.style24.persistence.domain.User;
+import com.style24.persistence.domain.UserHst;
+import com.style24.persistence.domain.UserMenu;
+
+/**
+ * 시스템 Dao
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@ShopDs
+public interface TsaSystemDao {
+
+	/**
+	 * 사용자 목록
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<User> getUserList(User user);
+
+	/**
+	 * 사용자 정보 조회
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	User getUser(Integer userNo);
+
+	/**
+	 * 사용자 삭제
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteUser(User user);
+
+	/**
+	 * 사용자ID 건수 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	int getUserIdCount(String userId);
+
+	/**
+	 * 사용자 정보 저장 처리
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void saveUser(User user);
+
+	/**
+	 * 임시비밀번호 조회
+	 * @param length - 비밀번호 자릿수
+	 * @return
+	 * @since 2020. 10. 7
+	 */
+	String getTemporaryPassword(int length);
+
+	/**
+	 * 사용자 비밀번호 수정
+	 * @param user - 사용자 정보
+	 * @since 2020. 10. 7
+	 */
+	void updateUserPassword(User user);
+
+	/**
+	 * 사용자 메뉴 목록
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<UserMenu> getUserMenuList(Integer userNo);
+
+	/**
+	 * 사용자정보변경이력 생성
+	 * @param userHst - 사용자이력 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createUserInfoChangeHistory(UserHst userHst);
+
+	/**
+	 * 메뉴 목록
+	 * @param menu - 메뉴정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<Menu> getMenuList(Menu menu);
+
+	/**
+	 * 메뉴 등록/수정
+	 * @param menu - 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void saveMenu(Menu menu);
+
+	/**
+	 * 메뉴권한 삭제
+	 * @param menuId - 메뉴ID
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteMenuRole(String menuId);
+
+	/**
+	 * 메뉴권한 생성
+	 * @param menuRole - 메뉴권한 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createMenuRole(MenuRole menuRole);
+
+	/**
+	 * 전체 사용자 메뉴 삭제
+	 * @param menuRole - 메뉴권한 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteAllUserMenu(MenuRole menuRole);
+
+	/**
+	 * 전체 사용자 메뉴 생성
+	 * @param menuRole - 메뉴권한 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createAllUserMenu(MenuRole menuRole);
+
+	/**
+	 * 사용자 전체 메뉴 삭제
+	 * @param userNo - 사용자번호
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteUserAllMenu(Integer userNo);
+
+	/**
+	 * 사용자 전체 메뉴 생성
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createUserAllMenu(User user);
+
+	/**
+	 * 사용자 메뉴 삭제
+	 * @param userMenu - 사용자 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteAdminUserMenu(UserMenu userMenu);
+
+	/**
+	 * 사용자 메뉴 생성
+	 * @param userMenu - 사용자 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createUserMenu(UserMenu userMenu);
+
+	/**
+	 * 공통코드 목록
+	 * @param commoncode - 공통코드 정보
+	 * @return 공통코드 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<CommonCode> getCommonCodeList(CommonCode commoncode);
+
+	/**
+	 * 메뉴접속이력 생성
+	 * @param menuAccessHst - 메뉴접속 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createMenuAccessHistory(MenuAccessHst menuAccessHst);
+
+	/**
+	 * 공통코드 등록/수정
+	 * @param commoncode - 공통코드 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void saveCommonCode(CommonCode commoncode);
+
+	/**
+	 * 공통코드 삭제
+	 * @param commoncode - 공통코드 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteCommonCode(CommonCode commoncode);
+
+	/**
+	 * 샘플파일 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	Collection<SampleFile> getSampleFileList();
+
+	/**
+	 * 샘플파일 등록
+	 * @param sampleFile - 샘플파일 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	void createSampleFile(SampleFile sampleFile);
+
+	/**
+	 * 샘플파일 수정
+	 * @param sampleFile - 샘플파일 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	void updateSampleFile(SampleFile sampleFile);
+
+	/**
+	 * 알람 목록
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	Collection<Alarm> getAlarmList(Alarm alarm);
+
+	/**
+	 * 알람 저장
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void createAlarm(Alarm alarm);
+
+	/**
+	 * 알람 수정
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void updateAlarm(Alarm alarm);
+
+	/**
+	 * 알람 삭제
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void deleteAlarm(Alarm alarm);
+
+	/**
+	 * 알람수신자 목록
+	 * @param alarmId - 알람ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	Collection<AlarmReceiver> getAlarmReceiverList(String alarmId);
+
+	/**
+	 * 알람수신자 저장
+	 * @param alarmReceiver - 알람수신자 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void saveAlarmReceiver(AlarmReceiver alarmReceiver);
+
+	/**
+	 * 알람수신자 삭제
+	 * @param alarmReceiver - 알람수신자 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void deleteAlarmReceiver(AlarmReceiver alarmReceiver);
+
+	/**
+	 * 배치 목록
+	 * @param batch - 배치 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 2
+	 */
+	Collection<Batch> getBatchList(Batch batch);
+
+	/**
+	 * 배치 생성
+	 * @param batch - 배치 정보
+	 * @author gagamel
+	 * @since 2020. 12. 2
+	 */
+	void saveBatch(Batch batch);
+
+	/**
+	 * 배치 로그 목록
+	 * @param batch - 배치 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 3
+	 */
+	Collection<BatchLog> getBatchLogList(Batch batch);
+
+}

+ 465 - 0
src/main/java/com/style24/admin/biz/dao/TsaWithdrawDao.java

@@ -0,0 +1,465 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import org.springframework.dao.DataAccessException;
+
+//import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.Withdraw;
+import com.style24.core.support.annotation.ShopDs;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 회수관리 Dao
+ * 
+ * @author Daehyoung
+ * @since 2020. 02. 06
+ */
+@ShopDs
+@Repository
+public interface TsaWithdrawDao {
+
+	/**
+	 * 회수등록 - 조회(송장번호용)
+	 * 
+	 * @param Withdraw
+	 * @return Collection<Withdraw>
+	 * @author yujung
+	 * @since 2020. 02. 11
+	 */
+	//Collection<Withdraw> getWithdrawRegisterInvoiceList(Withdraw withdraw);
+
+	/**
+	 * 회수등록 - 조회(상품코드용)
+	 * 
+	 * @param Withdraw
+	 * @return Collection<Withdraw>
+	 * @author yujung
+	 * @since 2020. 02. 12
+	 */
+	//Collection<Withdraw> getWithdrawRegisterGoodsList(Withdraw withdraw);
+
+	/**
+	 * 회수등록 - 회수 마스터 등록처리
+	 * 
+	 * @param Withdraw
+	 * @author yujung
+	 * @since 2020. 02. 12
+	 */
+	//void saveWithdrawInfo(Withdraw withdraw);
+
+	/**
+	 * 회수등록 - 회수 상세 등록처리
+	 * 
+	 * @param Withdraw
+	 * @author yujung
+	 * @since 2020. 02. 12
+	 */
+	//void createWithdrawDetailInfo(Withdraw withdraw);
+
+	/**
+	 * 주문변경 마스터 회수종료일 저장
+	 * 
+	 * @param Withdraw
+	 * @author yujung
+	 * @since 2020. 02. 12
+	 */
+	//void updateOrderChangeInfo(Withdraw withdraw);
+
+	/**
+	 * 회수송장번호 수정
+	 * 
+	 * @param withdraw
+	 * @author yujung
+	 * @since 2020. 02. 27
+	 */
+	//void updateRegisterWdInvoiceNo(Withdraw withdraw);
+
+	/**
+	 * 회수송장번호 조회
+	 * 
+	 * @param withdraw
+	 * @author yujung
+	 * @since 2020. 05. 31
+	 */
+	//Collection<Withdraw> getWdInvoiceNo(Withdraw withdraw);
+
+	/**
+	 * 환불관리 목록
+	 * 
+	 * @param withdraw
+	 * @return Collection<Withdraw>
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Collection<Withdraw> getRefundList(Withdraw withdraw);
+	//Collection<Withdraw> getWithdrawRegisterList(Withdraw withdraw);
+	/**
+	 * 회수관리 회수데이터 삭제처리
+	 * 
+	 * @param withdraw
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	void deleteWithdraw(Withdraw withdraw);
+
+	/**
+	 * 회수관리 회수 상세 데이터 삭제처리
+	 * 
+	 * @param withdraw
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	void deleteWithdrawDetail(Withdraw withdraw);
+
+	/**
+	 * 환불등록 팝업 목록
+	 * 
+	 * @param withdraw
+	 * @return Collection<Withdraw>
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Collection<Withdraw> getRefundRegisterPopupList(Withdraw withdraw);
+	//Collection<Withdraw> getWithdrawRegisterPopupList(Withdraw withdraw);
+	/**
+	 * 회수관리 아웃바운드 수정
+	 * 
+	 * @param withdraw
+	 * @author yujung
+	 * @since 2020. 03. 25
+	 */
+	//void updateWithdrawOutbound(Withdraw withdraw);
+
+	/**
+	 * 주문변경 수정
+	 * 
+	 * @param withdraw
+	 * @author yujung
+	 * @since 2020. 03. 25
+	 */
+	//void updateWithdrawOrderChange(Withdraw withdraw);
+
+	/**
+	 * 회수상세 상품정보 수정
+	 * 
+	 * @param withdraw
+	 * @author yujung
+	 * @since 2020. 03. 25
+	 */
+	//void updateWithdrawDetailGoodsInfo(Withdraw withdraw);
+
+	/**
+	 * 회수상세 정보 수정
+	 * 
+	 * @param withdraw
+	 * @author yujung
+	 * @since 2020. 03. 25
+	 */
+	//void updateWithdrawDetailInfo(Withdraw withdraw);
+
+	/**
+	 * 환불관리 - 상세 정보 조회
+	 * 
+	 * @param withdraw - 주문변경번호
+	 * @return Collection<Withdraw>
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Collection<Withdraw> getRefundDetailList(Withdraw withdraw);
+
+	/**
+	 * 회수배송비 등록
+	 * 
+	 * @param withdraw - 회수배송비 정보
+	 * @author yujung
+	 * @since 2020. 02. 20
+	 */
+	//void createWithdrawDeliveryFeeInfo(Withdraw withdraw);
+
+	/**
+	 * 쿠폰정보 조회
+	 * 
+	 * @param withdraw - 쿠폰정보
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Withdraw getCouponInfo(Withdraw withdraw);
+
+	/**
+	 * 남은주문 리스트
+	 * 
+	 * @param withdraw - 주문번호, 주문변경번호
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Collection<Withdraw> getWithdrawRemainOrderDetailList(Withdraw withdraw);
+
+	/**
+	 * 회원포인트 이력 등록
+	 * 
+	 * @param withdraw - 회원 포인트 정보
+	 * @author yujung
+	 * @since 2020. 02. 24
+	 */
+	//void createWithdrawCustPointHst(Withdraw withdraw);
+
+	/**
+	 * 회원포인트 조회
+	 * 
+	 * @param custNo
+	 * @author yujung
+	 * @since 2020. 02. 24
+	 */
+	//Withdraw getCustPointInfo(int custNo);
+
+	/**
+	 * 회원포인트 수정
+	 * 
+	 * @param withdraw - 포인트정보
+	 * @author yujung
+	 * @since 2020. 02. 24
+	 */
+	//void updateWithdrawCustPoint(Withdraw withdraw);
+
+	/**
+	 * 주문상세정보 수정
+	 * 
+	 * @param withdraw - 주문상세 정보
+	 * @author yujung
+	 * @since 2020. 02. 20
+	 */
+	//void updateWithdrawOrderDetailInfo(Withdraw withdraw);
+
+	/**
+	 * 주문상세이력 등록
+	 * 
+	 * @param withdraw - 주문상세번호
+	 * @author yujung
+	 * @since 2020. 02. 20
+	 */
+	//void createWithdrawOrderDetailHstInfo(Withdraw withdraw);
+
+	/**
+	 * 주문상세이력 등록2
+	 * 
+	 * @param withdraw - 주문상세번호
+	 * @author yujung
+	 * @since 2020. 02. 20
+	 */
+	//void createWithdrawOrderDetailHstInfo2(Withdraw withdraw);
+
+	/**
+	 * 주문변경상세 수정
+	 * 
+	 * @param withdraw - 주문상세번호
+	 * @author yujung
+	 * @since 2020. 02. 20
+	 */
+	//void updateWithdrawOrderChangeDetailInfo(Withdraw withdraw);
+
+	/**
+	 * 정산 등록
+	 * 
+	 * @param withdraw - 정산 정보
+	 * @author yujung
+	 * @since 2020. 02. 21
+	 */
+	//void createWithdrawUsac(Withdraw withdraw);
+
+	/**
+	 * 판매분재고 등록
+	 * 
+	 * @param withdraw - 판매분재고 정보
+	 * @author yujung
+	 * @since 2020. 02. 21
+	 */
+	//void createWithdrawSellQty(Withdraw withdraw);
+
+	/**
+	 * 환불정보 계산
+	 * 
+	 * @param ordNo
+	 * @return Withdraw
+	 * @author yujung
+	 * @since 2020. 02. 21
+	 */
+	//Withdraw getRefundInfo(Long ordNo);
+
+	/**
+	 * 주문마스터 수정
+	 * 
+	 * @param withdraw - 주문상태
+	 * @author yujung
+	 * @since 2020. 02. 24
+	 */
+	//void updateWithdrawOrderInfo(Withdraw withdraw);
+
+	/**
+	 * 환불정보 등록
+	 * 
+	 * @param withdraw - 환불정보
+	 * @author yujung
+	 * @since 2020. 02. 21
+	 */
+	//void createWithdrawRefund(Withdraw withdraw);
+
+	/**
+	 * 결제정보 조회
+	 * 
+	 * @param ordNo - 결제정보
+	 * @return Withdraw
+	 * @author yujung
+	 * @since 2020. 02. 24
+	 */
+	//Withdraw getPaymentInfo(Long ordNo);
+
+	/**
+	 * 기존결제 정보 수정
+	 * 
+	 * @param withdraw - 결제정보
+	 * @author yujung
+	 * @since 2020. 02. 25
+	 */
+	//void updateWithdrawPayment(Withdraw withdraw);
+
+	/**
+	 * 결제정보 등록
+	 * 
+	 * @param withdraw - 결제정보
+	 * @author yujung
+	 * @since 2020. 02. 21
+	 */
+	//void createWithdrawPayment(Withdraw withdraw);
+
+	/**
+	 * 남은 상품 정보
+	 * 
+	 * @param withdraw
+	 * @return Withdraw
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Withdraw getRemainGoodsInfo(Withdraw withdraw);
+
+	/**
+	 * 남은 회수 수량
+	 * 
+	 * @param ordChgSq
+	 * @return 남은회수수량
+	 * @author yujung
+	 * @since 2020. 02. 20
+	 */
+	//int getRemainWithdrawCount(Long ordChgSq);
+
+	/**
+	 * 취소가 아닌 수량
+	 * 
+	 * @param
+	 * @throws DataAccessException
+	 * @author swkim
+	 * @since 2020. 04. 14
+	 */
+	//public int getOrderNotCancelCnt(Long ordNo);
+
+	/**
+	 * 동봉비 수정
+	 * 
+	 * @param
+	 * @throws DataAccessException
+	 * @author swkim
+	 * @since 2020. 04. 14
+	 */
+	//public void updateWithdrawEncloseFee(Withdraw withdraw);
+
+	/**
+	 * 반품 매출반영 차수
+	 * 
+	 * @param delvLocCd
+	 * @return 반품 매출반영 차수
+	 * @author yujung
+	 * @since 2020. 02. 20
+	 */
+	//int getIfOnlineSalesMaxOutSeq(String delvLocCd);
+
+	/**
+	 * 반품 매출반영
+	 * 
+	 * @param
+	 * @throws DataAccessException
+	 * @author swkim
+	 * @since 2020. 05. 11
+	 */
+	//public void createReturnIfOnlineSales(Withdraw withdraw);
+
+	/**
+	 * 주문번호에 대한 합계 금액
+	 * 
+	 * @param withdraw
+	 * @return Withdraw
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Withdraw getOrderDetailSumAmt(String ordNo);
+
+	/**
+	 * 환불완료 목록
+	 * 
+	 * @param 검색조건
+	 * @return Collection<Withdraw>
+	 * @author yujung
+	 * @since 2020. 05. 29
+	 */
+	//Collection<Withdraw> getRefundCompleteList(Withdraw withdraw);
+
+	/**
+	 * 반품신청, 회수수량 비교 데이터
+	 * 
+	 * @param 검색조건
+	 * @return Withdraw
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	Withdraw getSumChgQtyWdQty(Withdraw withdraw);
+
+	/**
+	 * ERP 환입매출 반영
+	 * 
+	 * @param 검색조건
+	 * @return Withdraw
+	 * @author cjs
+	 * @since 2020. 08. 04
+	 */
+	//void createIfEcpTbSalesReturn(Withdraw withdraw);
+
+	/**
+	 * 교환출고처 지정대기를 출고처예정상태로 변경
+	 * 
+	 * @param 검색조건
+	 * @return Withdraw
+	 * @author cjs
+	 * @since 2020. 08. 04
+	 */
+	//void updateExchangeLocAssignStatus(Withdraw withdraw);
+
+	/**
+	 * 아이템 단위 상세정보
+	 * 
+	 * @param 검색조건
+	 * @return Withdraw
+	 * @author cjs
+	 * @since 2020. 08. 04
+	 */
+	//Collection<Withdraw> getWithdrawDetailList2(Withdraw withdraw);
+
+	/**
+	 * 교환배송비 등록
+	 * 
+	 * @param TsaOrder
+	 * @return
+	 * @author cjs
+	 * @since 2020. 08. 23
+	 */
+	//void mergeDeliveryFee(TsaOrder setParams);
+
+}

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

@@ -0,0 +1,53 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaAnswerPhaseDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.persistence.domain.AnswerPhase;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 답변문구 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 29
+ */
+@Service
+@Slf4j
+public class TsaAnswerPhaseService {
+
+	@Autowired
+	private TsaAnswerPhaseDao ansPhaseDao;
+
+	/**
+	 * 답변문구 목록
+	 * @param ansPhase - 답변문구 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	public Collection<AnswerPhase> getAnswerPhaseList(AnswerPhase ansPhase) {
+		return ansPhaseDao.getAnswerPhaseList(ansPhase);
+	}
+
+	/**
+	 * 답변문구 등록/수정
+	 * @param ansPhase - 답변문구 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@Transactional("shopTxnManager")
+	public void saveAnswerPhase(AnswerPhase ansPhase) {
+		ansPhase.setRegNo(TsaSession.getInfo().getUserNo());
+		ansPhase.setUpdNo(TsaSession.getInfo().getUserNo());
+		ansPhaseDao.saveAnswerPhase(ansPhase);
+	}
+
+}

+ 393 - 0
src/main/java/com/style24/admin/biz/service/TsaBusinessService.java

@@ -0,0 +1,393 @@
+package com.style24.admin.biz.service;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import com.style24.admin.biz.dao.TsaBusinessDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Aflink;
+import com.style24.persistence.domain.Brand;
+import com.style24.persistence.domain.BrandMd;
+import com.style24.persistence.domain.DeliveryLoc;
+import com.style24.persistence.domain.DelvFeePolicy;
+import com.style24.persistence.domain.SellStore;
+import com.style24.persistence.domain.ShipCompany;
+import com.style24.persistence.domain.SiteBrand;
+import com.style24.persistence.domain.StockSyncBase;
+import com.style24.persistence.domain.SupplyCompany;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+
+/**
+ * 영업관리 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 14
+ */
+@Service
+@Slf4j
+public class TsaBusinessService {
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaBusinessDao businessDao;
+
+	/**
+	 * 공급업체 목록
+	 * @param supplyComp - 공급업체 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	public Collection<SupplyCompany> getSupplyCompanyList(SupplyCompany supplyComp) {
+		return businessDao.getSupplyCompanyList(supplyComp);
+	}
+
+	/**
+	 * 공급업체 저장 처리
+	 * @param supplyComp - 공급업체 정보
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	public void saveSupplyCompany(SupplyCompany supplyComp) {
+		if (!StringUtils.isEmpty(supplyComp.getSupplyCompCd())) {
+			businessDao.updateSupplyCompany(supplyComp);
+		} else {
+			businessDao.createSupplyCompany(supplyComp);
+		}
+	}
+
+	/**
+	 * 배송비정책 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 24
+	 */
+	public Collection<DelvFeePolicy> getDeliveryFeePolicyList(String supplyCompCd) {
+		return businessDao.getDeliveryFeePolicyList(supplyCompCd);
+	}
+
+	/**
+	 * 배송비정책 저장 처리
+	 * @param supplyComp - 공급업체 정보
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	public void saveDeliveryFeePolicyList(Collection<DelvFeePolicy> delvFeePolicyList) {
+		for (DelvFeePolicy delvFeePolicy : delvFeePolicyList) {
+			delvFeePolicy.setRegNo(TsaSession.getInfo().getUserNo());
+			delvFeePolicy.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if (!StringUtils.isEmpty(delvFeePolicy.getDelvFeeCd())) {
+				businessDao.updateDeliveryFeePolicy(delvFeePolicy);
+			} else {
+				businessDao.createDeliveryFeePolicy(delvFeePolicy);
+			}
+		}
+	}
+
+	/**
+	 * 출고처 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 16
+	 **/
+	public Collection<DeliveryLoc> getDeliveryLocList(DeliveryLoc delvLoc) {
+		return businessDao.getDeliveryLocList(delvLoc);
+	}
+
+	/**
+	 * 출고처 저장
+	 * @param delvLoc - 출고처 정보
+	 * @author gagamel
+	 * @since 2020. 10. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveDeliveryLoc(DeliveryLoc delvLoc) {
+		if (StringUtils.isEmpty(delvLoc.getUseYn())) {
+			delvLoc.setUseYn("N");
+		}
+
+		businessDao.saveDeliveryLoc(delvLoc);
+	}
+
+	/**
+	 * 브랜드 목록
+	 * @param brand - 브랜드 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public Collection<Brand> getBrandList(Brand brand) {
+		return businessDao.getBrandList(brand);
+	}
+
+	/**
+	 * 담당MD 목록
+	 * @param brandMd - 담당MD 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	public Collection<BrandMd> getMdList(BrandMd brandMd) {
+		return businessDao.getMdList(brandMd);
+	}
+
+	/**
+	 * 브랜드담당MD 목록
+	 * @param brandCd - 브랜드코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	public Collection<BrandMd> getBrandMdList(String brandCd) {
+		return businessDao.getBrandMdList(brandCd);
+	}
+
+	/**
+	 * 브랜드담당MD 목록 등록/수정 처리
+	 * @param brandMdList - 브랜드담당MD 목록
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@Transactional("shopTxnManager")
+	public void saveBrandMdList(Collection<BrandMd> brandMdList) {
+		businessDao.deleteBrandMd(brandMdList.iterator().next().getBrandCd());
+
+		for (BrandMd brandMd : brandMdList) {
+			brandMd.setRegNo(TsaSession.getInfo().getUserNo());
+			brandMd.setUpdNo(TsaSession.getInfo().getUserNo());
+			businessDao.createBrandMd(brandMd);
+		}
+	}
+
+	/**
+	 * 브랜드 노출사이트 목록
+	 * @param brandCd - 브랜드코드
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	public Collection<SiteBrand> getBrandSiteList(String brandCd) {
+		return businessDao.getBrandSiteList(brandCd);
+	}
+
+	/**
+	 * 브랜드 노출사이트 등록/수정 처리
+	 * @param siteBrandList - 브랜드사이트 목록
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@Transactional("shopTxnManager")
+	public void saveBrandSiteList(Collection<SiteBrand> siteBrandList) {
+		for (SiteBrand siteBrand : siteBrandList) {
+			siteBrand.setRegNo(TsaSession.getInfo().getUserNo());
+			siteBrand.setUpdNo(TsaSession.getInfo().getUserNo());
+//			siteBrand.setTcateCd(businessDao.getTcateCdByBrand(siteBrand));
+			businessDao.saveBrandSite(siteBrand);
+		}
+	}
+
+	/**
+	 * 브랜드 등록/수정
+	 * @param brand - 브랜드 정보
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	@Transactional("shopTxnManager")
+	public void saveBrand(Brand brand) {
+
+		if (brand.getNewSysFileNm() != null && !"".equals(brand.getNewSysFileNm())) {
+			String brandImgName = "BRAND_" + brand.getBrandCd() + "_" + GagaDateUtil.getTodayDateTime() + "." + StringUtils.getFilenameExtension(brand.getNewSysFileNm());
+
+			String brandUploadPath = env.getProperty("upload.default.target.path");
+			brandUploadPath = GagaFileUtil.getConcatenationPath(brandUploadPath, "display");
+
+			//기존이미지 삭제
+			try {
+				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(brandUploadPath, brand.getLogoFileNm()));
+			} catch (IOException e) {
+				//  nothing
+				log.info("[saveBanner 기존 이미지 삭제중 error]");
+				//e.printStackTrace();
+			}
+
+			File uniqueFile = GagaFileUtil.getUniqueFile(new File(GagaFileUtil.getConcatenationPath(brandUploadPath, brandImgName)));
+
+			File file = new File(GagaFileUtil.getConcatenationPath(brandUploadPath, brand.getNewSysFileNm()));
+
+			// Rename a file
+			file.renameTo(uniqueFile);
+
+			brand.setLogoFileNm(brandImgName);
+
+		}
+
+		if (brand.getMode().equals("N")) { // 신규
+			businessDao.createBrand(brand);
+		} else { // 수정
+			businessDao.updateBrand(brand);
+		}
+	}
+
+	/**
+	 * 재고연계관리 - 출고처 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	public Collection<DeliveryLoc> getStockSyncDeliveryLocList(DeliveryLoc delvLoc) {
+		return businessDao.getStockSyncDeliveryLocList(delvLoc);
+	}
+
+	/**
+	 * 재고연계관리 - 재고연계기준 목록
+	 * @param stockSyncBase - 재고연계기준 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	public Collection<StockSyncBase> getStockSyncBaseList(StockSyncBase stockSyncBase) {
+		return businessDao.getStockSyncBaseList(stockSyncBase);
+	}
+
+	/**
+	 * 재고연계관리 - 재고연계기준 저장
+	 * @param stockSyncBase - 재고연계기준 정보
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	public void saveStockSyncBaseList(Collection<StockSyncBase> stockSyncBaseList) {
+		for (StockSyncBase stockSyncBase : stockSyncBaseList) {
+			stockSyncBase.setRegNo(TsaSession.getInfo().getUserNo());
+			stockSyncBase.setUpdNo(TsaSession.getInfo().getUserNo());
+			businessDao.saveStockSyncBase(stockSyncBase);
+		}
+	}
+
+	/**
+	 * 판매매장 목록
+	 * @param sellStore - 판매매장 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	public Collection<SellStore> getSellStoreList(SellStore sellStore) {
+		return businessDao.getSellStoreList(sellStore);
+	}
+
+	/**
+	 * 판매매장 목록 저장 처리
+	 * @param sellStoreList - 판매매장 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@Transactional("shopTxnManager")
+	public void saveSellStoreList(Collection<SellStore> sellStoreList) {
+		for (SellStore sellStore : sellStoreList) {
+			sellStore.setRegNo(TsaSession.getInfo().getUserNo());
+			sellStore.setUpdNo(TsaSession.getInfo().getUserNo());
+			businessDao.saveSellStore(sellStore);
+		}
+	}
+
+	/**
+	 * 제휴링크 목록
+	 * @param aflink - 제휴링크 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	public Collection<Aflink> getAflinkList(Aflink aflink) {
+		return businessDao.getAflinkList(aflink);
+	}
+
+	/**
+	 * 제휴링크 등록/수정
+	 * @param aflink - 제휴링크 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@Transactional("shopTxnManager")
+	public void saveAflink(Aflink aflink) {
+		aflink.setRegNo(TsaSession.getInfo().getUserNo());
+		aflink.setUpdNo(TsaSession.getInfo().getUserNo());
+		businessDao.saveAflink(aflink);
+	}
+
+	/**
+	 * 제휴링크 목록 삭제 처리
+	 * @param aflinkList - 제휴링크 목록
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteAflinkList(Collection<Aflink> aflinkList) {
+		for (Aflink aflink : aflinkList) {
+			aflink.setUpdNo(TsaSession.getInfo().getUserNo());
+			businessDao.deleteAflink(aflink);
+		}
+	}
+
+	/**
+	 * 배송업체 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	public Collection<ShipCompany> getShipCompanyList() {
+		return businessDao.getShipCompanyList();
+	}
+
+	/**
+	 * 배송업체 목록 저장
+	 * @param shipCompList - 배송업체 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@Transactional("shopTxnManager")
+	public void saveShipCompanyList(Collection<ShipCompany> shipCompList) {
+		for (ShipCompany shipComp : shipCompList) {
+			shipComp.setRegNo(TsaSession.getInfo().getUserNo());
+			shipComp.setUpdNo(TsaSession.getInfo().getUserNo());
+			businessDao.saveShipCompany(shipComp);
+		}
+	}
+
+	/**
+	 * 배송업체 목록 삭제
+	 * @param shipCompList - 배송업체 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteShipCompanyList(Collection<ShipCompany> shipCompList) {
+		for (ShipCompany shipComp : shipCompList) {
+			shipComp.setUpdNo(TsaSession.getInfo().getUserNo());
+			businessDao.deleteShipCompany(shipComp);
+		}
+	}
+
+}

+ 68 - 0
src/main/java/com/style24/admin/biz/service/TsaClauseService.java

@@ -0,0 +1,68 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaClauseDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.persistence.domain.Clause;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 약관 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 29
+ */
+@Service
+@Slf4j
+public class TsaClauseService {
+
+	@Autowired
+	private TsaClauseDao clauseDao;
+
+	/**
+	 * 약관 목록
+	 * @param clause - 약관 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	public Collection<Clause> getClauseList(Clause clause) {
+		return clauseDao.getClauseList(clause);
+	}
+
+	/**
+	 * 약관 상세
+	 * @param clause - 약관 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	public Clause getClauseDetail(Integer clauseSq) {
+		return clauseDao.getClauseDetail(clauseSq);
+	}
+
+	/**
+	 * 약관 생성/수정
+	 * @param clause - 약관 정보
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@Transactional("shopTxnManager")
+	public void saveClause(Clause clause) {
+		clause.setRegNo(TsaSession.getInfo().getUserNo());
+		clause.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		if (clause.getMode().equals("N")) {
+			clauseDao.createClause(clause);
+		} else {
+			clauseDao.updateClause(clause);
+		}
+	}
+
+}

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

@@ -0,0 +1,106 @@
+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;
+
+/**
+ * 공용 Service
+ *
+ * @author eskim
+ * @since 2020. 10. 20
+ */
+@Service
+@Slf4j
+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 테이블 삭제
+	 *
+	 * @param searchData
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public void deleteExceluploadSearCh(SearchData searchData) {
+		commonDao.deleteExceluploadSearCh(searchData);
+	}
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성
+	 *
+	 * @param searchData
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public void createExceluploadSearch(SearchData searchData) {
+		commonDao.createExceluploadSearch(searchData);
+	}
+
+	/**
+	 * 엑셀조회를 위한 SEARCH 테이블 생성 - dummy 컬럼 포함
+	 *
+	 * @param searchData
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public void createExceluploadSearchByAll(SearchData searchData) {
+		commonDao.createExceluploadSearchByAll(searchData);
+	}
+
+	/**
+	 * 샘플파일 시스템파일명 조회
+	 * @param sampleFileId - 샘플파일ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	public String getSampleFileSystemFilename(String sampleFileId) {
+		return commonDao.getSampleFileSystemFilename(sampleFileId);
+	}
+
+	/**
+	 * WMS 연동 여부
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 16
+	 */
+	public String getWmsSyncYn() {
+		return commonDao.getWmsSyncYn();
+	}
+
+}

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

@@ -0,0 +1,97 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaCounselDao;
+import com.style24.persistence.domain.Counsel;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 상담(1:1문의) Service
+ *
+ * @author gagamel
+ * @since 2020. 12. 24
+ */
+@Service
+@Slf4j
+public class TsaCounselService {
+
+	@Autowired
+	private TsaCounselDao counselDao;
+
+	/**
+	 * 1:1문의 목록
+	 * @param counsel -상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	public Collection<Counsel> getOneToOneQnaList(Counsel counsel) {
+		return counselDao.getOneToOneQnaList(counsel);
+	}
+
+	/**
+	 * 1:1문의 상세
+	 * @param counselSq - 상담일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	public Counsel getOneToOneQna(Integer counselSq) {
+		Counsel counsel = new Counsel();
+		counsel.setCounselSq(counselSq);
+		return counselDao.getOneToOneQna(counsel);
+	}
+
+	/**
+	 * 문의 답변 저장
+	 * @param counsel - 상담정보
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@Transactional("shopTxnManager")
+	public void updateQnaAnswer(Counsel counsel) {
+		counselDao.updateQnaAnswer(counsel);
+	}
+
+	/**
+	 * 상품문의 목록
+	 * @param counsel -상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	public Collection<Counsel> getGoodsQnaList(Counsel counsel) {
+		return counselDao.getGoodsQnaList(counsel);
+	}
+
+	/**
+	 * 상품문의 상세
+	 * @param counselSq - 상담일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	public Counsel getGoodsQna(Integer counselSq) {
+		Counsel counsel = new Counsel();
+		counsel.setCounselSq(counselSq);
+		return counselDao.getGoodsQna(counsel);
+	}
+
+	/**
+	 * 상품문의 입점업체에 답변의뢰 (입점상품인 경우)
+	 * @param counsel - 상담 정보
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@Transactional("shopTxnManager")
+	public void updateGoodsQnaAnswerTransfer(Counsel counsel) {
+		counselDao.updateGoodsQnaAnswerTransfer(counsel);
+	}
+
+}

+ 166 - 0
src/main/java/com/style24/admin/biz/service/TsaCouponService.java

@@ -0,0 +1,166 @@
+package com.style24.admin.biz.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.style24.admin.biz.dao.TsaCouponDao;
+import com.style24.admin.biz.dao.TsaMarketingDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.biz.thirdparty.NaverLowestPriceApi;
+import com.style24.core.biz.thirdparty.SafetyKoreaApi;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+
+/**
+ * 쿠폰 Service
+ *
+ * @author xyzp1539
+ * @since 2021. 01. 11
+ */
+@Service
+@Slf4j
+public class TsaCouponService {
+
+	@Autowired
+	private TsaCouponDao couponDao;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+
+
+
+	/**
+	 * 쿠폰 저장
+	 * @param params
+	 * @author xyzp1539
+	 * @since  2021-01-11
+	 */
+	@Transactional("shopTxnManager")
+	public void couponSave(Coupon params) {
+		String cpnId = "";		// 쿠폰ID
+
+		params.setRegNo(TsaSession.getInfo().getUserNo());
+		params.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		// 자동생성이면 시퀀스 가져오기
+		if(params.getCpnId() == null || params.getCpnId().equals("")) {
+			int sequence = commonService.getNextSequence("SEQ_COUPON");
+			cpnId = "CPN"+sequence;
+		} else {
+			cpnId = params.getCpnId();
+		}
+
+		log.info(">>>> CPNID : {}" , cpnId );
+		params.setCpnId(cpnId);
+
+		couponDao.couponInsert(params);
+
+
+		//checkCpnValidation(params);
+
+	}
+
+	/**
+	 * 쿠폰 리스트 조회
+	 * @param  Coupon
+	 * @return ArrayList<Coupon>
+	 * @author xyzp1539
+	 * @since 2020-12-22
+	 */
+	public ArrayList<Coupon> getCouponList(Coupon param) {
+		return couponDao.getCouponList(param);
+	}
+
+	/**
+	 * 쿠폰리스트 카운트 조회
+	 * @param  Coupon
+	 * @return int
+	 * @author xyzp1539
+	 * @since 2020-12-22
+	 */
+	public int getCouponListCnt(Coupon param) {
+		return couponDao.getCouponListCnt(param);
+	}
+
+	/**
+	 * 쿠폰 벨리데이션 체크
+	 * @param Coupon
+	 * @author xyzp1539
+	 * @since  2021-01-12
+	 */
+	public void checkCpnValidation(Coupon params) {
+		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		// 할인율이면  100% 초과 체크하기
+		if(params.getDcWay() != null && params.getDcWay().equals("G240_11")) {
+			if(params.getDcAval() > 100) {
+				throw new IllegalStateException("모바일 앱 할인율은 100을 초과할수 없습니다.");
+			} else if(params.getDcPval() > 100) {
+				throw new IllegalStateException("PC할인율은 100을 초과할수 없습니다.");
+			} else if(params.getDcMval() > 100) {
+				throw new IllegalStateException("모바일 웹 100을 초과할수 없습니다.");
+			}
+		}
+
+		// 기간/일수구분이 일수인 경우 날짜 체크
+		if(params.getPdGb() != null && params.getPdGb().equals("D")) {
+			try {
+				Date date1 = format.parse(params.getAvailStdt());
+				Date date2 = format.parse(params.getAvailEddt());
+
+				log.info("checkCpnValidation params.getAvailEddt() :  {}" , params.getAvailEddt());
+				log.info("checkCpnValidation params.getAvailStdt :  {}" , params.getAvailStdt());
+				if(date2.before(date1)) {
+					throw new IllegalStateException("유효기간 종료날짜가 시작날짜보다 작습니다.");
+				}
+			} catch (ParseException exception) {
+			}
+		}
+
+		// 직접다운로드인 경우 기간 체크
+		if(params.getDnGb() != null && params.getDnGb().equals("G058_20")) {
+			try {
+				Date date1 = format.parse(params.getDownStdt());
+				Date date2 = format.parse(params.getDownEddt());
+
+				log.info("checkCpnValidation params.getDownStdt() :  {}" , params.getDownStdt());
+				log.info("checkCpnValidation params.getDownEddt :  {}" , params.getDownEddt());
+				if(date2.before(date1)) {
+					throw new IllegalStateException("다운로드 종료날짜가 시작날짜보다 작습니다.");
+				}
+			} catch (ParseException exception) {
+			}
+		}
+
+		// 첫구매 적용하는 경우 날짜 체크
+		if(params.getFirstYn() != null && params.getFirstYn().equals("Y")) {
+			try {
+				Date date1 = format.parse(params.getBuyStdt());
+				Date date2 = format.parse(params.getBuyEddt());
+
+				log.info("checkCpnValidation params.getBuyStdt() :  {}" , params.getBuyStdt());
+				log.info("checkCpnValidation params.getBuyEddt :  {}" , params.getBuyEddt());
+				if(date2.before(date1)) {
+					throw new IllegalStateException("첫구매 종료날짜가 시작날짜보다 작습니다.");
+				}
+			} catch (ParseException exception) {
+			}
+		}
+
+		// 신규회원여부 적용하는 경우 날짜 체크
+		if(params.getCustJoinYn() != null && params.getCustJoinYn().equals("Y")) {
+
+		}
+
+	}
+
+}

+ 186 - 0
src/main/java/com/style24/admin/biz/service/TsaDeliveryService.java

@@ -0,0 +1,186 @@
+package com.style24.admin.biz.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.stereotype.Service;
+import org.apache.commons.lang3.StringUtils;
+
+import com.style24.admin.biz.dao.TsaDeliveryDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.admin.support.util.TsitUtil;
+
+import com.style24.persistence.domain.Delivery;
+import com.style24.admin.support.env.TsaConstants.OrderDetailStat;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.core.support.message.TscMessageByLocale;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 배송관리 Service
+ *
+ * @author moon
+ * @since 2020. 11. 05
+ */
+@Service
+@Slf4j
+public class TsaDeliveryService {
+
+	@Autowired
+	private TscMessageByLocale message;
+	
+	@Autowired
+	private TsaDeliveryDao deliveryDao;
+
+	/**
+	 * 배송 목록
+	 *
+	 * @param -Delivery
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	public Collection<Delivery> getDeliveryList(Delivery delivery) {
+		// multi row 검색관련 처리
+		
+		if (StringUtils.isNotBlank(delivery.getCondition())) {
+			TsitUtil tsitUtil = new TsitUtil();
+			String searchCondition = tsitUtil.replaceMultiSelectParamsArr(delivery.getCondition());
+			delivery.setConditions(searchCondition.split(","));
+		}
+
+		// 외부몰권한일 때 외부몰벤더ID 설정
+		if (TsaSession.getInfo().getRoleCd().startsWith("C")) {
+			delivery.setMallGb(TsaConstants.MallGb.EXTMALL.value());
+			delivery.setVendorId(TsaSession.getInfo().getVendorId());
+		}
+		
+		return deliveryDao.getDeliveryList(delivery);
+	}
+	
+	/**
+	 * 주문상세
+	 *
+	 * @param  ordDtlNo
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	public Collection<Delivery> getOrderDetail(long ordDtlNo) {
+		return deliveryDao.getOrderDetail(ordDtlNo);
+	}	
+	
+	/**
+	 * 수기송장등록/수정
+	 *
+	 * @param -Delivery
+	 * @return void
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@Transactional("shopTxnManager")
+	public void saveOrderDetail(Collection<Delivery> deliveryList) {
+	
+		int userId = TsaSession.getInfo().getUserNo();
+
+		for (Delivery oneDelivery : deliveryList) {
+			oneDelivery.setUpdNo(userId);
+			oneDelivery.setRegNo(userId);
+			// 배송 준비중, 배송중이면 해당 상태값으로 업데이트
+			if (OrderDetailStat.DELIVERY_PREPARE.equals(oneDelivery.getOrgOrdDtlStat()) || OrderDetailStat.SHIPPING.equals(oneDelivery.getOrgOrdDtlStat())) {
+				oneDelivery.setOrdDtlStat(oneDelivery.getOrgOrdDtlStat());
+			} else {
+				oneDelivery.setOrdDtlStat(OrderDetailStat.DELIVERY_PREPARE.value());
+			}
+			oneDelivery.setHstMemo("수기송장 수정");
+			// 주문상세수정
+			deliveryDao.updateOrderDetailStat(oneDelivery);
+			// 주문상세이력
+			deliveryDao.createOrderDetailHst(oneDelivery);
+		}
+
+	}	
+	
+	/**
+	 * 출고금지상품 목록
+	 *
+	 * @param  Delivery
+	 * @return Delivery List
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	public Collection<Delivery> getBangoodsList(Delivery delivery) {
+		return deliveryDao.getBangoodsList(delivery);
+	}	
+	
+	/**
+	 * 출고금지상품 삭제
+	 *
+	 * @param -TsaDelivery
+	 * @return void
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteBangoods(Collection<Delivery> bangoodsList) {
+		int userId = TsaSession.getInfo().getUserNo();
+
+		for (Delivery oneBangood : bangoodsList) {
+			oneBangood.setUpdNo(userId);
+			deliveryDao.deleteBangoods(oneBangood);
+		}
+	}
+	
+	/**
+	 * 출고금지상품 등록 대상목록
+	 *
+	 * @param  Delivery
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	public Collection<Delivery> getBangoodsRegistList(Delivery delivery) {
+		return deliveryDao.getBangoodsRegistList(delivery);
+	}
+	
+	/**
+	 * 출고금지상품 등록
+	 *
+	 * @param -TsaDelivery
+	 * @return void
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@Transactional("shopTxnManager")
+	public void createBangoods(Collection<Delivery> bangoodsList) {
+		int userId = TsaSession.getInfo().getUserNo();
+
+		for (Delivery oneBangood : bangoodsList) {
+
+			int cnt = deliveryDao.getBangoodsListCnt(oneBangood);
+			if (cnt > 0) {
+				throw new IllegalStateException(message.getMessage("DELIVERY_0001"));
+			}
+
+			oneBangood.setRegNo(userId);
+			oneBangood.setUpdNo(userId);
+			deliveryDao.createBangoods(oneBangood);
+		}
+	}
+	
+	/**
+	 * 배송/회수지시 목록
+	 *
+	 * @param -Delivery
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 11
+	 */	
+	public Collection<Delivery> getDeliveryWithdrawDirectiveList(Delivery delivery) {
+		return deliveryDao.getDeliveryWithdrawDirectiveList(delivery);
+	}
+	
+}

+ 160 - 0
src/main/java/com/style24/admin/biz/service/TsaDisplayService.java

@@ -0,0 +1,160 @@
+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;
+
+/**
+ * 전시 Service
+ *
+ * @author
+ * @since 2020. 12. 16
+ */
+@Service
+@Slf4j
+public class TsaDisplayService {
+
+	@Autowired
+	private TsaDisplayDao displayDao;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+	/**
+	 * 카테고리 목록
+	 * @param category - 카테고리 정보
+	 * @return
+	 * @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);
+	}
+
+}

+ 98 - 0
src/main/java/com/style24/admin/biz/service/TsaEnvsetService.java

@@ -0,0 +1,98 @@
+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.TsaEnvsetDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.biz.dao.TscEnvsetDao;
+import com.style24.persistence.domain.CustGradePolicy;
+import com.style24.persistence.domain.Envset;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 환경설정 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 21
+ */
+@Service
+@Slf4j
+public class TsaEnvsetService {
+
+	@Autowired
+	private TscEnvsetDao cenvsetDao;
+
+	@Autowired
+	private TsaEnvsetDao envsetDao;
+
+	/**
+	 * 환경설정정보 저장
+	 * 		정책은 중요한 정보로서 캐싱 문제 발생 시 심각해질 수 있으므로 캐싱처리 안 함
+	 * @param envset - 환경설정 정보
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	@Transactional("shopTxnManager")
+	public void createEnvset(Envset envset) {
+		envset.setRegNo(TsaSession.getInfo().getUserNo());
+		envsetDao.createEnvset(envset);
+	}
+
+	/**
+	 * 환경설정정보 - 메타정보 저장. 수정 시 캐싱 삭제
+	 * @param envset - 환경설정 정보
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	@Transactional("shopTxnManager")
+	@CacheEvict(value = "metainfo", allEntries = true)
+	public void createEnvsetMetaInfo(Envset envset) {
+		envset.setRegNo(TsaSession.getInfo().getUserNo());
+		envsetDao.createEnvset(envset);
+	}
+
+	/**
+	 * 환경설정이력 목록
+	 * @param siteCd - 사이트코드
+	 * @param envsetType - 환경설정유형
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	public Collection<Envset> getEnvsetHistoryList(String siteCd, String envsetType) {
+		Envset envset = new Envset();
+		envset.setSiteCd(siteCd);
+		envset.setEnvsetType(envsetType);
+		return envsetDao.getEnvsetList(envset);
+	}
+
+	/**
+	 * 회원등급정책 저장
+	 * @param policy - 회원등급정책 정보
+	 * @author gagamel
+	 * @since 2021. 1. 7
+	 */
+	public void createCustomerGradePolicy(CustGradePolicy policy) {
+		policy.setRegNo(TsaSession.getInfo().getUserNo());
+		policy.setUpdNo(TsaSession.getInfo().getUserNo());
+		envsetDao.createCustomerGradePolicy(policy);
+	}
+
+	/**
+	 * 회원등급정책 목록
+	 * @param policy - 회원등급정책 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 7
+	 */
+	public Collection<CustGradePolicy> getCustomerGradePolicyList(CustGradePolicy policy) {
+		return envsetDao.getCustomerGradePolicyList(policy);
+	}
+
+}

+ 66 - 0
src/main/java/com/style24/admin/biz/service/TsaFaqService.java

@@ -0,0 +1,66 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaFaqDao;
+import com.style24.persistence.domain.Faq;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * FAQ Service
+ *
+ * @author gagamel
+ * @since 2020. 11. 3
+ */
+@Service
+@Slf4j
+public class TsaFaqService {
+
+	@Autowired
+	private TsaFaqDao faqDao;
+
+	/**
+	 * FAQ 목록
+	 * @param faq - FAQ 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	public Collection<Faq> getFaqList(Faq faq) {
+		return faqDao.getFaqList(faq);
+	}
+
+	/**
+	 * FAQ 등록/수정
+	 * @param faq - FAQ 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@Transactional("shopTxnManager")
+	public void saveFaq(Faq faq) {
+		// 내용 유무 확인
+		if (StringUtils.isNotBlank(faq.getAnswer())) {
+			faq.setAnswer(faq.getAnswer().replaceAll("&lt;", "<").replaceAll("&gt;", ">"));
+		}
+
+		faqDao.saveFaq(faq);
+	}
+
+	/**
+	 * FAQ 상세
+	 * @param faqSq - FAQ일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	public Faq getFaq(Integer faqSq) {
+		return faqDao.getFaq(faqSq);
+	}
+
+}

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

@@ -0,0 +1,2710 @@
+package com.style24.admin.biz.service;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.style24.admin.biz.dao.TsaGoodsDao;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.biz.thirdparty.NaverLowestPriceApi;
+import com.style24.core.biz.thirdparty.SafetyKoreaApi;
+import com.style24.core.support.message.TscMessageByLocale;
+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;
+import com.style24.persistence.domain.GoodsEpSkip;
+import com.style24.persistence.domain.GoodsHst;
+import com.style24.persistence.domain.GoodsImg;
+import com.style24.persistence.domain.GoodsNaverLowestPrice;
+import com.style24.persistence.domain.GoodsNotiInfo;
+import com.style24.persistence.domain.GoodsPriceRes;
+import com.style24.persistence.domain.GoodsResSell;
+import com.style24.persistence.domain.GoodsSafeNo;
+import com.style24.persistence.domain.GoodsSearch;
+import com.style24.persistence.domain.GoodsTnmRes;
+import com.style24.persistence.domain.GoodsVideo;
+import com.style24.persistence.domain.Itemkind;
+import com.style24.persistence.domain.NaverLowestPrice;
+import com.style24.persistence.domain.NotiInfo;
+import com.style24.persistence.domain.Notice;
+import com.style24.persistence.domain.NoticeGoods;
+import com.style24.persistence.domain.Option;
+import com.style24.persistence.domain.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;
+
+import io.netty.util.internal.StringUtil;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.excel.env.GagaExcelConstants;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.gagaframework.web.util.GagaStringUtil;
+
+/**
+ *상품관리 Service
+ *
+ * @author eskim
+ * @since 2020. 10. 16
+ */
+@Service
+@Slf4j
+public class TsaGoodsService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaGoodsDao goodsDao;
+
+	@Autowired
+	private TsaBusinessService businessService;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaNoticeService noticeService;
+
+	@Autowired
+	private SafetyKoreaApi safetyKoreaApi;
+
+	@Autowired
+	private NaverLowestPriceApi naverLowestPriceApi;
+
+
+	@Autowired
+	private ObjectMapper mapper;
+
+	private static final String NUMBER_PATTERN = "^[0-9]+$";
+
+	private static final String SELF_GOOODS_AFTER = "STY";
+
+	/**
+	 * 상품 할인율 계산
+	 *
+	 * @param value
+	 * @param len
+	 * @param pad
+	 * @return
+	 */
+	private long getDcRate(int listPrice, int currPrice) {
+		double rate = (double)(currPrice) / (double)(listPrice);
+		return 100 - (long)((Math.round(rate * 100) / 100.0) * 100);
+	}
+
+	/**
+	 * 품목 목록
+	 * @param itemkind
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	public Collection<Itemkind> getItemkindList(Itemkind itemkind) {
+		return goodsDao.getItemkindList(itemkind);
+	}
+
+	/**
+	 * 품목 저장
+	 *
+	 * @param itemkindList - 품목 정보 목록
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveItemkindInfo(Collection<Itemkind> itemkindList) {
+		for (Itemkind itemkind : itemkindList) {
+			itemkind.setRegNo(TsaSession.getInfo().getUserNo());
+			itemkind.setUpdNo(TsaSession.getInfo().getUserNo());
+			itemkind.setItemkindNm(GagaStringUtil.replace(GagaStringUtil.replace(itemkind.getItemkindNm(), "&lt;", "<"),"&gt;", ">"));
+			//itemkind.setItemkindEnm(GagaStringUtil.replace(GagaStringUtil.replace(itemkind.getItemkindEnm(), "&lt;", "<"),"&gt;", ">"));
+			goodsDao.saveItemkindInfo(itemkind);
+		}
+	}
+
+	/**
+	 * 품목 삭제
+	 *
+	 * @param itemkindList - 품목 정보 목록
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteItemkindInfo(Collection<Itemkind> itemkindList) {
+		for (Itemkind itemkind : itemkindList) {
+			goodsDao.deleteItemkindInfo(itemkind);
+		}
+	}
+
+	/**
+	 * 색상목록 조회
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	public Collection<Color> getColorList(Color color) {
+		return goodsDao.getColorList(color);
+	}
+
+	/**
+	 * 색상 저장
+	 *
+	 * @param colorList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveColor(Collection<Color> colorList) {
+
+		for (Color color : colorList) {
+
+			color.setRegNo(TsaSession.getInfo().getUserNo());
+			color.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			goodsDao.saveColor(color);
+		}
+	}
+
+	/**
+	 * 상품정보고시 목록
+	 *
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	public Collection<NotiInfo> getNotiInfoList(NotiInfo notiInfo) {
+		return goodsDao.getNotiInfoList(notiInfo);
+	}
+
+	/**
+	 * 상품정보고시 항목 목록
+	 *
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	public Collection<NotiInfo> getNotiInfoItemList(NotiInfo notiInfo) {
+		return goodsDao.getNotiInfoItemList(notiInfo);
+	}
+
+	/**
+	 * 상품정보고시 항목 저장
+	 *
+	 * @param notiInfoList
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	@Transactional("shopTxnManager")
+	public void saveNotiInfoItem(Collection<NotiInfo> notiInfoList) {
+		if (notiInfoList == null || notiInfoList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		for (NotiInfo notiInfo : notiInfoList) {
+			if (!StringUtils.isEmpty(notiInfo.getNiContent())) {
+				notiInfo.setNiContent(GagaStringUtil.replace(GagaStringUtil.replace(notiInfo.getNiContent(),"&lt;", "<"),"&gt;", ">"));
+			}
+			notiInfo.setRegNo(TsaSession.getInfo().getUserNo());
+			notiInfo.setUpdNo(TsaSession.getInfo().getUserNo());
+			goodsDao.saveNotiInfo(notiInfo);
+		}
+	}
+
+	/**
+	 * WMS 색상 매핑목록 조회
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	public Collection<WmsColorMapping> getWmsColorMappingList(WmsColorMapping wmsColorMapping) {
+		return goodsDao.getWmsColorMappingList(wmsColorMapping);
+	}
+
+	/**
+	 * WMS 색상 매핑 저장
+	 *
+	 * @param colorList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveWmsColorMapping(Collection<WmsColorMapping> wmsColorMappingList) {
+
+		for (WmsColorMapping wmsColorMapping : wmsColorMappingList) {
+
+			wmsColorMapping.setRegNo(TsaSession.getInfo().getUserNo());
+			wmsColorMapping.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			goodsDao.saveWmsColorMapping(wmsColorMapping);
+		}
+	}
+
+	/**
+	 * WMS 스타일년도 매핑목록 조회
+	 *
+	 * @param wmsStyleYearMapping
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	public Collection<WmsStyleYearMapping> getWmsStyleYearMappingList(WmsStyleYearMapping wmsStyleYearMapping) {
+		return goodsDao.getWmsStyleYearMappingList(wmsStyleYearMapping);
+	}
+
+	/**
+	 * WMS 스타일년도 매핑 저장
+	 *
+	 * @param wmsStyleYearMappingList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void saveWmsStyleYearMapping(Collection<WmsStyleYearMapping> wmsStyleYearMappingList) {
+
+		for (WmsStyleYearMapping wmsStyleYearMapping : wmsStyleYearMappingList) {
+
+			wmsStyleYearMapping.setRegNo(TsaSession.getInfo().getUserNo());
+			wmsStyleYearMapping.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			goodsDao.saveWmsStyleYearMapping(wmsStyleYearMapping);
+		}
+	}
+
+	/**
+	 * WMS 시즌 매핑목록 조회
+	 *
+	 * @param wmsSeasonMapping
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	public Collection<WmsSeasonMapping> getWmsSeasonMappingList(WmsSeasonMapping wmsSeasonMapping) {
+		return goodsDao.getWmsSeasonMappingList(wmsSeasonMapping);
+	}
+
+	/**
+	 * WMS 시즌 매핑 저장
+	 *
+	 * @param wmsSeasonMappingList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void saveWmsSeasonMapping(Collection<WmsSeasonMapping> wmsSeasonMappingList) {
+
+		for (WmsSeasonMapping wmsSeasonMapping : wmsSeasonMappingList) {
+
+			wmsSeasonMapping.setRegNo(TsaSession.getInfo().getUserNo());
+			wmsSeasonMapping.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			goodsDao.saveWmsSeasonMapping(wmsSeasonMapping);
+		}
+	}
+
+	/**
+	 * 상품 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 20
+	 */
+	public int getGoodsListCount(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsListCount(goodsSearch);
+	}
+
+	/**
+	 * 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 20
+	 */
+	public Collection<Goods> getGoodsList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsList(goodsSearch);
+	}
+
+	/**
+	 * 상품목록 - 기본정보 엑셀다운로드
+	 *
+	 * @param goodsSearch
+	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 21
+	 */
+	public void getGoodsInfoExcelList(GoodsSearch goodsSearch, String excelFilenameWithPath) {
+
+		if ("Y".equals(goodsSearch.getImageViewYn())) {
+			// 헤더 title 설정
+			String[] listTitles = {"이미지", "상품코드", "업체명", "브랜드명", "상품명", "품목", "재고", "상품상태", "스타일년도", "시즌",
+				"정상가", "판매가", "할인율", "가격변경일", "ERP재고연동여부", "정상이월구분", "반품가능 여부","승인일시"};
+
+			// DB 처리 시 사용되는 파라미터명(셀명) 설정
+			String[] cellNames = {"SYS_IMG_NM", "GOODS_CD", "SUPPLY_COMP_CD", "BRAND_GRP_NM", "GOODS_NM", "ITEMKIND_NM",
+				"STOCK_QTY_SUM", "GOODS_STAT", "STYLE_YEAR", "SEASON_CD",  "LIST_PRICE", "CURR_PRICE",
+				"DC_RATE", "PRICE_UPD_DT", "ERP_STOCK_LINK_YN", "FORMAL_GB", "RETURNABLE_YN", "FRST_CFRM_DT"};
+
+			String[] cellTypes = {GagaExcelConstants.CellType.IMAGE.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
+				GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(),
+				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name()};
+
+			String targetPath = env.getProperty("upload.goods.view");
+			Collection<GagaMap> dataList = goodsDao.getGoodsInfoExcelList(goodsSearch); // map형식으로 조회
+			if (dataList != null && !dataList.isEmpty()) {
+				for (GagaMap gagaMap : dataList) {
+					if (!StringUtils.isEmpty(gagaMap.get("SYS_IMG_NM").toString()) ) {
+						gagaMap.set("SYS_IMG_NM", targetPath + '/' +  gagaMap.get("SYS_IMG_NM").toString());
+					}
+				}
+			}
+
+			try {
+				GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "상품 정보", listTitles, cellNames, cellTypes, TsaConstants.EXCEL_FOOTER_TITLE);
+			} catch (Exception e) {
+				throw new IllegalStateException(e);
+			}
+
+		} else {
+			// 헤더 title 설정
+			String[] listTitles = {"상품코드", "업체명", "브랜드명", "상품명", "품목", "재고", "상품상태", "스타일년도",
+				"시즌",  "정상가", "판매가", "할인율", "가격변경일", "ERP재고연동여부", "정상이월구분", "반품가능 여부", "승인일시"};
+
+			// DB 처리 시 사용되는 파라미터명(셀명) 설정
+			String[] cellNames = {"GOODS_CD", "SUPPLY_COMP_CD", "BRAND_GRP_NM", "GOODS_NM", "ITEMKIND_NM", "STOCK_QTY_SUM", "GOODS_STAT", "STYLE_YEAR",
+				"SEASON_CD",  "LIST_PRICE", "CURR_PRICE", "DC_RATE", "PRICE_UPD_DT", "ERP_STOCK_LINK_YN", "FORMAL_GB", "RETURNABLE_YN", "FRST_CFRM_DT"};
+
+			String[] cellTypes = {
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
+			GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name()};
+
+			Collection<GagaMap> dataList = goodsDao.getGoodsInfoExcelList(goodsSearch);
+
+			try {
+				GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "상품 정보", listTitles, cellNames, cellTypes, TsaConstants.EXCEL_FOOTER_TITLE);
+			} catch (Exception e) {
+				throw new IllegalStateException(e);
+			}
+		}
+	}
+
+	/**
+	 * 상품 이미지 등록여부 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 21
+	 */
+	public Collection<Goods> getGoodsImgsYn(Goods goods) {
+		return goodsDao.getGoodsImgsYn(goods);
+	}
+
+	/**
+	 * 상품 상세
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public Goods getGoods(Goods goods) {
+		// 상품기본정보
+		Goods resultGoods = goodsDao.getGoods(goods);
+
+		// 상품 상세
+		this.getGoodsDesc(resultGoods);
+		return resultGoods;
+	}
+
+	/**
+	 * 상품 상세 조회
+	 *
+	 * @param resultGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	private Goods getGoodsDesc(Goods resultGoods) {
+
+		GoodsDesc goods = new GoodsDesc();
+		goods.setGoodsCd(resultGoods.getGoodsCd());
+
+		// 상품 상세 타이틀
+		goods.setDescGb("10");
+		String goodsTitlesDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsTitlesDesc(goodsTitlesDesc);
+
+		// 상품 상세 내용
+		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("50");
+		String goodsPcDownDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsPcDownDesc(goodsPcDownDesc);
+
+		// 상품 상세 mobile 상단
+		goods.setDescGb("60");
+		String goodsMobileTopDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsMobileTopDesc(goodsMobileTopDesc);
+
+		// 상품 상세 mobile 하단
+		goods.setDescGb("70");
+		String goodsMobileDownDesc = this.getGoodsDescList(goods);
+		resultGoods.setGoodsMobileDownDesc(goodsMobileDownDesc);
+
+		return resultGoods;
+	}
+
+	/**
+	 * 상품 상세구분별 컨텐츠 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	private String getGoodsDescList(GoodsDesc goodsDesc) {
+		Collection<GoodsDesc> goodsDescList = goodsDao.getGoodsDescList(goodsDesc);
+		StringBuilder goodsDescSb = new StringBuilder();
+		if (goodsDescList != null && !goodsDescList.isEmpty()) {
+			for (GoodsDesc tmpGoodsDesc : goodsDescList) {
+				goodsDescSb.append(tmpGoodsDesc.getGoodsDesc());
+			}
+		}else {
+			goodsDescSb.append("");
+		}
+		return goodsDescSb.toString();
+	}
+
+	/**
+	 * 상품 정보 이력 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2019. 12. 12
+	 */
+	public Collection<GoodsHst> getGoodsHstList(Goods goods) {
+		return goodsDao.getGoodsHstList(goods);
+	}
+
+	/**
+	 * 상품 옵션 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 26
+	 */
+	public Collection<Option> getGoodsSizeList(Goods goods) {
+		return goodsDao.getGoodsSizeList(goods);
+	}
+
+	/**
+	 * 상품 색상목록 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 18
+	 */
+	public Collection<GoodsImg> getGoodsColorList(Goods goods) {
+		return goodsDao.getGoodsColorList(goods);
+	}
+
+	/**
+	 * 상품 정보고시 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	public Collection<GoodsNotiInfo> getGoodsNotiInfoList(GoodsNotiInfo goodsNotiInfo) {
+		return goodsDao.getGoodsNotiInfoList(goodsNotiInfo);
+	}
+
+	/**
+	 * 상품의 정보고시 항목 목록
+	 *
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 18
+	 */
+	public Collection<NotiInfo> getNotiGoodsInfoList(NotiInfo notiInfo) {
+		return goodsDao.getNotiGoodsInfoList(notiInfo);
+	}
+
+	/**
+	 * 상품 구매등급 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Goods> getGoodsDetailOrderGradeList(Goods goods) {
+		return goodsDao.getGoodsDetailOrderGradeList(goods);
+	}
+
+	/**
+	 * 구성상품 목록
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	public Collection<GoodsCompose> getGoodsDetailComposeList(Goods goods) {
+		return goodsDao.getGoodsDetailComposeList(goods);
+	}
+
+	/**
+	 * 안전인증번호
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 07
+	 */
+	public GagaMap getGoodsDetailCertNum(String goodsCd) {
+		GagaMap result = new GagaMap();
+		return result;
+	}
+
+	/**
+	 * 안전인증번호 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 07
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsDetailCertNum(Goods goods) {
+		try {
+			GagaMap result = safetyKoreaApi.getKoreaCertifyDetail(goods.getCertNum());
+			if (result != null || !StringUtil.isNullOrEmpty(result.get("certNum").toString())) {
+				GoodsSafeNo goodsSafeNo = new GoodsSafeNo();
+				goodsSafeNo.setGoodsCd(goods.getGoodsCd());
+				goodsSafeNo.setCertDt(result.get("certDt").toString());
+				goodsSafeNo.setCertNum(result.get("certNum").toString());
+				goodsSafeNo.setCertState(result.get("certState").toString());
+				goodsSafeNo.setCertDiv(result.get("certDiv").toString());
+				goodsSafeNo.setRegNo(TsaSession.getInfo().getUserNo());
+				goodsSafeNo.setUpdNo(TsaSession.getInfo().getUserNo());
+				goodsDao.saveGoodsSafeNo(goodsSafeNo);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 상품 수정 항목 일괄변경
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 01. 17
+	 */
+	@Transactional("shopTxnManager")
+	public void updateGoodsState(Goods goods) {
+		if (goods == null || (goods.getArrGoodsCd() == null && goods.getArrGoodsCd().length <= 0)) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		goods.setRegNo(TsaSession.getInfo().getUserNo());
+		goods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		if (goods.getArrGoodsCd().length > 0) {
+			for (String goodsCd : goods.getArrGoodsCd()) {
+
+				goods.setGoodsCd(goodsCd);
+				// 이력생성
+				goodsDao.createGoodsHst(goods);
+
+				if ("formalGb".equals(goods.getProcJob())) {
+					// 상품브랜드 조회
+					Goods originGoods = goodsDao.getGoods(goods);
+					// 브랜드 확인
+					goods.setPntPrate(originGoods.getPntPrate()); // 포인트적립율(PC)
+					goods.setPntMrate(originGoods.getPntMrate()); // 포인트적립율(MOBILE)
+					Brand brand = new Brand();
+					brand.setBrandCd(originGoods.getBrandCd());
+					Collection<Brand> brandList = businessService.getBrandList(brand);
+					if (brandList != null && !brandList.isEmpty()) {
+						float pntPrate = 0;
+						float pntMrate = 0;
+						for (Brand tmpBrand : brandList) {
+							if ("G009_10".equals(goods.getFormalGb())) {
+								pntPrate = tmpBrand.getPntPrate10();
+								pntMrate = tmpBrand.getPntMrate10();
+							} else {
+								pntPrate = tmpBrand.getPntPrate20();
+								pntMrate = tmpBrand.getPntMrate20();
+							}
+						}
+						goods.setPntPrate(pntPrate); // 포인트적립율(PC)
+						goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
+					}
+				} else if ("goodsStat".equals(goods.getProcJob())) {
+					// 상품브랜드 조회
+					Goods originGoods = goodsDao.getGoods(goods);
+
+					// 승인일
+					if (!goods.getGoodsStat().equals(originGoods.getGoodsStat()) && "G008_90".equals(goods.getGoodsStat())) {
+						goods.setChGoodsStatYn("Y");
+					}
+				}
+				// 상품정보 변경
+				goodsDao.updateGoodsState(goods);
+			}
+
+		} else {
+
+			// 이력생성
+			goodsDao.createGoodsHst(goods);
+			if ("formalGb".equals(goods.getProcJob())) {
+				// 상품브랜드 조회
+				Goods originGoods = goodsDao.getGoods(goods);
+				// 브랜드 확인
+				goods.setPntPrate(originGoods.getPntPrate()); // 포인트적립율(PC)
+				goods.setPntMrate(originGoods.getPntMrate()); // 포인트적립율(MOBILE)
+				Brand brand = new Brand();
+				brand.setBrandCd(originGoods.getBrandCd());
+				Collection<Brand> brandList = businessService.getBrandList(brand);
+				if (brandList != null && !brandList.isEmpty()) {
+					float pntPrate = 0;
+					float pntMrate = 0;
+					for (Brand tmpBrand : brandList) {
+						if ("G009_10".equals(goods.getFormalGb())) {
+							pntPrate = tmpBrand.getPntPrate10();
+							pntMrate = tmpBrand.getPntMrate10();
+						} else {
+							pntPrate = tmpBrand.getPntPrate20();
+							pntMrate = tmpBrand.getPntMrate20();
+						}
+					}
+					goods.setPntPrate(pntPrate); // 포인트적립율(PC)
+					goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
+				}
+			}
+			// 상품정보 변경
+			goodsDao.updateGoodsState(goods);
+		}
+	}
+
+	/**
+	 * 엑셀조회용 상품 저장
+	 *
+	 * @param procJob : goodsExcelUpload
+	 * @param goodsList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	@Transactional("shopTxnManager")
+	public void saveExceluploadGoods(Collection<Goods> goodsList, String excelFilename) {
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		if (goodsList == null || goodsList.isEmpty()) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		int index = 0;
+		String goodsCdFlag = "";
+		String goodsNumFlag = "";
+		for (Goods goods : goodsList) {
+
+			if (!StringUtils.isEmpty(goodsCdFlag) && !StringUtils.isEmpty(goodsNumFlag)) {
+				throw new IllegalStateException("상품코드와 원코드 중 한 개의 셀에만 값을 입력해서 조회하세요.");
+			}
+
+			if (!StringUtils.isEmpty(goods.getSupplyCompCd())) {
+				goods.setGoodsCd(goods.getSupplyCompCd());
+			}
+
+			SearchData searchData = new SearchData();
+			searchData.setRegNo(goods.getRegNo());
+			searchData.setSearchCd(goods.getGoodsCd());
+			if (index == 0) {
+				commonService.deleteExceluploadSearCh(searchData);
+			}
+
+			commonService.createExceluploadSearch(searchData);
+			index++;
+		}
+	}
+
+	/**
+	 * 파일 삭제
+	 *
+	 * @param targetPath
+	 * @param excelFilename
+	 * @author eskim
+	 * @since 2020. 10. 22
+	 */
+	private void deleteExceluploadFile(String targetPath, String excelFilename) {
+		// 파일 삭제
+		try {
+			GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, excelFilename));
+		} catch (IOException e) {
+			// Nothing Do
+		}
+	}
+
+	/**
+	 * 상품 품목 변경 저장
+	 *
+	 * @param goodsList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@Transactional("shopTxnManager")
+	//@CacheEvict(value = "cate", allEntries = true)
+	public void saveItemKindChange(Collection<Goods> goodsList) {
+		for (Goods goods : goodsList) {
+			goods.setRegNo(TsaSession.getInfo().getUserNo());
+			goods.setUpdNo(TsaSession.getInfo().getUserNo());
+			goods.setItemkindCd(goods.getItemkindCd().toUpperCase());
+			// 품목확인
+			Itemkind itemkind = new Itemkind();
+			itemkind.setItemkindCd(goods.getItemkindCd());
+			itemkind.setUseYn("Y");
+			Collection<Itemkind> itemkindList = goodsDao.getItemkindList(itemkind);
+			if (itemkindList == null || itemkindList.isEmpty()) {
+				throw new IllegalStateException(goods.getGoodsCd() + " 상품의 품목코드를 확인해주세요.");
+			}
+
+			// 상품이력
+			goodsDao.createGoodsHst(goods);
+			// 품목변경
+			goodsDao.updateGoodItemKindCd(goods);
+
+			// 검색어 변경
+			String goodsSnm = goodsDao.getGoodsSnm(goods.getGoodsCd());
+			Goods tmpGoods = goodsDao.getGoods(goods);
+			if (tmpGoods != null && !StringUtils.isEmpty(tmpGoods.getGoodsSnm1())) {
+				String[] arrGoodsSnm = tmpGoods.getGoodsSnm1().split(";");
+				StringBuilder tempGoodsSnm = new StringBuilder();
+				for (String loopGoodsSnm : arrGoodsSnm) {
+					if (goodsSnm.toUpperCase().indexOf(loopGoodsSnm.toUpperCase()) <= -1) {
+						tempGoodsSnm.append(loopGoodsSnm).append(";");
+					}
+				}
+				goods.setGoodsSnm(tempGoodsSnm.toString() + goodsSnm);
+
+			} else {
+				goods.setGoodsSnm(goodsSnm);
+			}
+			goodsDao.updateGoodsSnm(goods);
+
+			Collection<GoodsNotiInfo> goodsNotiInfoList = goodsDao.getNewNotiInfo(goods);
+			goodsDao.deleteGoodsNotiInfo(goods);
+
+			for (GoodsNotiInfo goodsNotiInfo : goodsNotiInfoList) {
+				goodsNotiInfo.setRegNo(TsaSession.getInfo().getUserNo());
+				goodsNotiInfo.setUpdNo(TsaSession.getInfo().getUserNo());
+				goodsNotiInfo.setGoodsCd(goods.getGoodsCd());
+				goodsDao.saveGoodsNotiInfo(goodsNotiInfo);
+			}
+
+			this.saveGoodsCategory(goods);
+		}
+	}
+
+	/**
+	 * 상품 품목 기준 카테고리 저장
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 4. 21.
+	 */
+	private void saveGoodsCategory(Goods goods) {
+
+//		GoodsCategory goodsCategory = new GoodsCategory();
+//		goodsCategory.setRegNo(TsaSession.getInfo().getUserNo());
+//		goodsCategory.setUpdNo(TsaSession.getInfo().getUserNo());
+//		goodsCategory.setGoodsCd(goods.getGoodsCd());
+//		displayService.deleteGoodsCategory(goodsCategory);
+//
+//		Collection<ItemkindCategory> itemkindCategoryList = displayService.getItemkindCategoryList(goods.getItemkindCd());
+//		for ItemkindCategory itemkindCategory : itemkindCategoryList) {
+//			Category category = new Category();
+//			category.setCateGb(itemkindCategory.getCateGb());
+//			category.setCateCd(itemkindCategory.getCateCd());
+//			category = displayService.getCategory4srch(category);
+//
+//			CategoryGoods categoryGoods = new CategoryGoods();
+//			categoryGoods.setRegNo(TsaSession.getInfo().getUserNo());
+//			categoryGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+//			String[] goodsCdArr = {goods.getGoodsCd()};
+//			categoryGoods.setGoodsCdArr(goodsCdArr);
+//			if (category.getCateGb() != null) {
+//				categoryGoods.setNcateGb(String.valueOf(category.getCateGb()));
+//			}
+//			if (category.getCateType() != null) {
+//				categoryGoods.setNcateType(String.valueOf(category.getCateType()));
+//			}
+//			if (category.getCateCd() != null) {
+//				categoryGoods.setNcateCd(String.valueOf(category.getCateCd()));
+//			}
+//			if (category.getTcateCd() != null) {
+//				categoryGoods.setNtcateCd(String.valueOf(category.getTcateCd()));
+//			}
+//			if (category.getMcateCd() != null) {
+//				categoryGoods.setNmcateCd(String.valueOf(category.getMcateCd()));
+//			}
+//			if (category.getScateCd() != null) {
+//				categoryGoods.setNscateCd(String.valueOf(category.getScateCd()));
+//			}
+//			if (category.getDcateCd() != null) {
+//				categoryGoods.setNdcateCd(String.valueOf(category.getDcateCd()));
+//			}
+//			displayService.moveCategoryGoods(categoryGoods);
+//		}
+	}
+
+	/**
+	 * 상품 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsDetail(Goods goods) {
+
+		// <,> replace 처리
+		goods.setRegNo(TsaSession.getInfo().getUserNo());
+		goods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		goods.setGoodsPcTopDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsPcTopDesc(), "&lt;", "<"), "&gt;", ">"));
+		goods.setGoodsMobileTopDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsMobileTopDesc(), "&lt;", "<"), "&gt;", ">"));
+		goods.setGoodsPcDownDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsPcDownDesc(), "&lt;", "<"), "&gt;", ">"));
+		goods.setGoodsMobileDownDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsMobileDownDesc(), "&lt;", "<"), "&gt;", ">"));
+
+		goods.setGoodsNm(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsNm(), "&lt;", "<"), "&gt;", ">"));
+		goods.setGoodsTnm(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsTnm(), "&lt;", "<"), "&gt;", ">"));
+		goods.setGoodsSnm1(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsSnm1(), "&lt;", "<"), "&gt;", ">"));
+
+		// 딜상품의 대표상품 변경여부 확인
+		if ("G056_D".equals(goods.getGoodsType())) {
+
+			String newRepGoodsCd = "";
+			int newRepGoodsPrice = 0;
+			Collection<GoodsCompose> goodsExtendList = goods.getGoodsComposeListNew();
+			for (GoodsCompose regGoodsExtend : goodsExtendList) {
+				if ("Y".equals(regGoodsExtend.getRepYn())) {
+					newRepGoodsCd = regGoodsExtend.getCompsGoodsCd();
+					newRepGoodsPrice = regGoodsExtend.getCurrPrice();
+				}
+			}
+
+			log.info("newRepGoodsCd = {}, newRepGoodsPrice = {}, goods.getRepGoodsCd = {}", newRepGoodsCd, newRepGoodsPrice, goods.getRepGoodsCd());
+			// 1순 : 대표상품 변경, 2순 : 판매가 변경
+			if (!newRepGoodsCd.equals(goods.getRepGoodsCd())) {
+				goods.setCurrBprice(goods.getCurrPriceOrg());
+				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()) {
+				goods.setCurrBprice(goods.getCurrPriceOrg());
+			} else {
+				goods.setCurrPrice(goods.getCurrPriceOrg());
+			}
+		}
+
+		// 승인일
+		if (!goods.getGoodsStat().equals(goods.getGoodsStatOrg()) && "G008_90".equals(goods.getGoodsStat())) {
+			goods.setChGoodsStatYn("Y");
+		}
+		// 사용자 검색어를 검색어에 적용
+		String goodsSnm = goodsDao.getGoodsSnm(goods.getGoodsCd());
+		if (!StringUtils.isEmpty(goods.getGoodsSnm1())) {
+			goods.setGoodsSnm1(GagaStringUtil.replace(goods.getGoodsSnm1(), " ", "")); // 빈값 삭제
+			String[] arrGoodsSnm = goods.getGoodsSnm1().split(";");
+			StringBuilder tempGoodsSnm = new StringBuilder();
+			for (String loopGoodsSnm : arrGoodsSnm) {
+				if (goodsSnm.toUpperCase().indexOf(loopGoodsSnm.toUpperCase()) <= -1) {
+					tempGoodsSnm.append(loopGoodsSnm).append(";");
+				}
+			}
+			goods.setGoodsSnm(tempGoodsSnm.toString() + goodsSnm);
+
+		} else if (!goodsSnm.equals(goods.getGoodsSnm())) {
+			goods.setGoodsSnm(goodsSnm);
+		}
+
+		goods.setFormalGb(goods.getFormalGb());
+		// 브랜드 확인
+		if (!"G056_N".equals(goods.getGoodsType())) {
+			if (!goods.getFormalGb().equals(goods.getFormalGbOrg())) {
+				Brand brand = new Brand();
+				brand.setBrandCd(goods.getBrandCd());
+				Collection<Brand> brandList = businessService.getBrandList(brand);
+				if (brandList != null && !brandList.isEmpty()) {
+					float pntPrate = 0.0f;
+					float pntMrate = 0.0f;
+					for (Brand tmpBrand : brandList) {
+						if ("G009_10".equals(goods.getFormalGb())) {
+							pntPrate = tmpBrand.getPntPrate10();
+							pntMrate = tmpBrand.getPntMrate10();
+						} else {
+							pntPrate = tmpBrand.getPntPrate20();
+							pntMrate = tmpBrand.getPntMrate20();
+						}
+					}
+					goods.setPntPrate(pntPrate); // 포인트적립율(PC)
+					goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
+				}
+			}
+		}
+
+		// 기본정보 변경
+		if ("Y".equals(goods.getChDataYn())) {
+			goodsDao.createGoodsHst(goods);
+			goodsDao.updateGoods(goods);
+		}
+
+		// 상품상세정보 변경
+		if (!"Y".equals(goods.getChkDescKeep())) {
+			this.saveGoodsDetailDesc(goods);
+		}
+
+		int idx = 1;
+		// 구성상품 변경
+		if (!"G056_N".equals(goods.getGoodsType())) {
+
+			Collection<GoodsCompose> goodsExtendList = goods.getGoodsComposeListNew();
+			for (GoodsCompose regGoodsExtend : goodsExtendList) {
+				regGoodsExtend.setDispOrd(idx);
+				regGoodsExtend.setRegNo(TsaSession.getInfo().getUserNo());
+				regGoodsExtend.setUpdNo(TsaSession.getInfo().getUserNo());
+				goodsDao.saveGoodsCompose(regGoodsExtend); // 구성상품기본 저장
+
+				idx++;
+			}
+		}
+
+		// 옵션/재고 변경
+		if (goods.getOptCd() != null && goods.getOptCd().length > 0 && "Y".equals(goods.getChStockDataYn())) {
+			this.saveStock(goods);
+		}
+
+		// 상품 정보고시 변경
+		this.saveGoodsNotiInfo(goods);
+
+		// 상품 구매등급 적용
+		if (goods.getGoodsOrderGrade() != null && goods.getGoodsOrderGrade().length > 0) {
+			Goods goodsOrderGrade = new Goods();
+			goodsOrderGrade.setGoodsCd(goods.getGoodsCd());
+			goodsOrderGrade.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsDao.deleteGoodsCustGrade(goodsOrderGrade);
+			for(String custGrade : goods.getGoodsOrderGrade()) {
+				goodsOrderGrade.setCustGrade(custGrade);
+				goodsDao.createGoodsCustGrade(goodsOrderGrade);
+			}
+		}else {
+			Goods goodsOrderGrade = new Goods();
+			goodsOrderGrade.setGoodsCd(goods.getGoodsCd());
+			goodsOrderGrade.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsDao.deleteGoodsCustGrade(goodsOrderGrade);
+		}
+
+	}
+
+	/**
+	 * 상품상세정보 변경 - 상품상세
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 27.
+	 */
+	private void saveGoodsDetailDesc(Goods goods) {
+		// 상품상세 구분(10:상품타이틀,20:상품타이틀내용,30:상품특징,40:상위컨텐츠,50:하위컨텐츠,60:하위컨텐츠-모바일,70:상위컨텐츠-모바일)
+		GoodsDesc goodsDesc = new GoodsDesc();
+		goodsDesc.setGoodsCd(goods.getGoodsCd());
+		goodsDesc.setRegNo(goods.getRegNo());
+		goodsDesc.setUpdNo(goods.getUpdNo());
+
+		// AS-IS 상세 정보 이력 처리
+		goodsDao.createGoodsDetailDescHst(goodsDesc);
+
+		// 상세 타이틀
+		goodsDesc.setDescGb("10");
+		goodsDesc.setGoodsDesc(goods.getGoodsTitlesDesc());
+		this.saveGoodsDesc(goodsDesc);
+
+		// 상세 내용
+		goodsDesc.setDescGb("20");
+		goodsDesc.setGoodsDesc(goods.getGoodsContentsDesc());
+		this.saveGoodsDesc(goodsDesc);
+
+		// 상세 특징
+		goodsDesc.setDescGb("30");
+		goodsDesc.setGoodsDesc(goods.getGoodsCharacterDesc());
+		this.saveGoodsDesc(goodsDesc);
+
+		// PC 상단
+		goodsDesc.setDescGb("40");
+		goodsDesc.setGoodsDesc(goods.getGoodsPcTopDesc());
+		this.saveGoodsDesc(goodsDesc);
+
+		// PC 하단
+		goodsDesc.setDescGb("50");
+		goodsDesc.setGoodsDesc(goods.getGoodsPcDownDesc());
+		this.saveGoodsDesc(goodsDesc);
+
+		// MO 상단
+		goodsDesc.setDescGb("60");
+		goodsDesc.setGoodsDesc(goods.getGoodsMobileTopDesc());
+		this.saveGoodsDesc(goodsDesc);
+
+		// MO 하단
+		goodsDesc.setDescGb("70");
+		goodsDesc.setGoodsDesc(goods.getGoodsMobileDownDesc());
+		this.saveGoodsDesc(goodsDesc);
+
+	}
+
+	/**
+	 * 상품 상세 저장
+	 *
+	 * @param goodsDesc
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	private void saveGoodsDesc(GoodsDesc goodsDesc) {
+
+		goodsDao.deleteGoodsDesc(goodsDesc);
+
+		String[] arrProdHtml = null;
+		arrProdHtml = makeArrayToString(goodsDesc.getGoodsDesc(), 3900);
+		if (arrProdHtml.length > 0) {
+			for (int i = 0; i < arrProdHtml.length; i++) {
+				if (!arrProdHtml[i].isEmpty()) {
+					goodsDesc.setSeq(i + 1);
+					goodsDesc.setGoodsDesc(arrProdHtml[i]);
+					goodsDao.createGoodsDesc(goodsDesc);
+				}
+			}
+		}
+	}
+
+	/**
+	 * String => byte array
+	 *
+	 * @param raw
+	 * @param len
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	public static String[] makeArrayToString(String raw, int len) {
+
+		String[] ary = null;
+
+		if (raw == null) {
+			return ary;
+		}
+
+		try {
+
+			// raw 의 byte
+			byte[] rawBytes = raw.getBytes("UTF-8"); // MS949
+			int rawLength = rawBytes.length;
+
+			if (rawLength > len) {
+				int aryLength = (rawLength / len) + (rawLength % len != 0 ? 1 : 0);
+				ary = new String[aryLength];
+
+				int endCharIndex = 0; // 문자열이 끝나는 위치
+				String tmp;
+				for (int i = 0; i < aryLength; i++) {
+
+					if (i == (aryLength - 1)) {
+						tmp = raw.substring(endCharIndex);
+					} else {
+
+						int useByteLength = 0;
+						int rSize = 0;
+						for (; endCharIndex < raw.length(); endCharIndex++) {
+
+							if (raw.charAt(endCharIndex) > 0x007F) {
+								useByteLength += 3;
+							} else {
+								useByteLength++;
+							}
+							if (useByteLength > len) {
+								break;
+							}
+							rSize++;
+						}
+						tmp = raw.substring((endCharIndex - rSize), endCharIndex);
+					}
+
+					ary[i] = tmp;
+				}
+
+			} else {
+				ary = new String[] {raw};
+			}
+
+		} catch (java.io.UnsupportedEncodingException e) {
+		}
+
+		return ary;
+	}
+
+	/**
+	 * 옵션/재고 변경 - 상품상세
+	 *
+	 * @param goods
+	 * @param index
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	private void saveStock(Goods goods) {
+		int index = 0;
+		Option stock = new Option();
+		stock.setGoodsCd(goods.getGoodsCd());
+		stock.setUpdNo(goods.getUpdNo());
+		stock.setRegNo(goods.getRegNo());
+		goodsDao.createStockHst(stock);
+		log.info("saveStock goods={}", goods);
+		for (String optCd : goods.getOptCd()) {
+			log.info("saveStock index={}", index);
+			log.info("saveStock optCd={}", optCd);
+			Option goodsStock = new Option();
+			goodsStock.setGoodsCd(goods.getCompsGoodsCd()[index]); // 구성상품 코드
+			goodsStock.setOptCd(optCd);
+			goodsStock.setOptCd1(goods.getOptCd1()[index]);
+			goodsStock.setOptCd2(goods.getOptCd2()[index]);
+			goodsStock.setBaseStockQty(Integer.parseInt(goods.getBaseStockQty()[index]));
+			goodsStock.setSoldoutYn(goods.getSoldoutYn()[index]);
+			goodsStock.setDispOrd(goods.getDispOrd()[index]);
+			goodsStock.setDispYn(goods.getDispYn()[index]);
+			goodsStock.setRegNo(goods.getRegNo());
+			goodsStock.setUpdNo(goods.getUpdNo());
+
+			if ("N".equals(goods.getSelfGoodsYn())) {
+				goodsStock.setSelfGoodsYn(goods.getSelfGoodsYn());
+				goodsStock.setCurrStockQty(Integer.parseInt(goods.getEditCurrStockQty()[index]));
+			}
+			goodsDao.saveStock(goodsStock);
+			index++;
+		}
+	}
+
+
+	/**
+	 * 상품 사이즈 옵션정보 이력 생성
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	@Transactional("shopTxnManager")
+	public void createStockHst(Option option) {
+		goodsDao.createStockHst(option);
+	}
+
+	/**
+	 * 상품 정보고시 변경 - 상품상세
+	 *
+	 * @param goods
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	private void saveGoodsNotiInfo(Goods goods) {
+		int index;
+		if (goods.getNotiListNew() != null && !goods.getNotiListNew().isEmpty()) {
+			index = 0;
+			for (GoodsNotiInfo goodsNotiInfo : goods.getNotiListNew()) {
+				if (index == 0) {
+					goodsDao.deleteGoodsNotiInfo(goods);
+				}
+				goodsNotiInfo.setNiContent(GagaStringUtil.replace(GagaStringUtil.replace(goodsNotiInfo.getNiContent(), "&lt;", "<"), "&gt;", ">"));
+				goodsNotiInfo.setRegNo(goods.getRegNo());
+				goodsNotiInfo.setUpdNo(goods.getUpdNo());
+				goodsDao.saveGoodsNotiInfo(goodsNotiInfo);
+				index++;
+			}
+		}
+	}
+
+	/**
+	 * 딜상품 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsDeal(Goods goods) {
+
+		Goods regGoods = new Goods();
+
+		// <,> replace 처리
+		regGoods.setRegNo(TsaSession.getInfo().getUserNo());
+		regGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		String goodsCd = this.getGoodsCodeSeq("D", "D");
+		regGoods.setGoodsCd(goodsCd);
+		regGoods.setSupplyGoodsCd(goodsCd);
+		regGoods.setGoodsType("G056_D");
+		regGoods.setSupplyCompCd(goods.getSupplyCompCd());
+		regGoods.setBrandCd(goods.getBrandCd());
+		regGoods.setItemkindCd(goods.getItemkindCd());
+		regGoods.setGoodsNm(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsNm(), "&lt;", "<"), "&gt;", ">"));
+		regGoods.setStyleYear(goods.getStyleYear());
+		regGoods.setSeasonCd(goods.getSeasonCd());
+		regGoods.setSexGb(goods.getSexGb());
+		regGoods.setMainColorCd("00");
+		regGoods.setOriginCd(goods.getOriginCd());
+		regGoods.setMakeYmd(goods.getMakeYmd());
+		regGoods.setSelfMallYn(goods.getSelfMallYn());
+		regGoods.setGoodsStat("G008_20"); // 정보부족
+		regGoods.setFormalGb("G009_10"); // 정상 기본값 처리
+		regGoods.setGoodsGb("G073_11"); // 자사상품은 신규
+		regGoods.setDistributionGb("G065_12"); // 유통구분
+		regGoods.setTaxGb("10"); // 과세구분
+		regGoods.setGoodsNum(goodsCd);
+
+		regGoods.setListPrice(goods.getCurrPrice());
+		regGoods.setCurrPrice(goods.getCurrPrice());
+		regGoods.setDcRate((int)(this.getDcRate(goods.getCurrPrice(), goods.getCurrPrice())));
+
+		Collection<GoodsCompose> goodsComposeList = null;
+		try {
+			goodsComposeList = mapper.readValue(goods.getGoodsComposeList(), new TypeReference<Collection<GoodsCompose>>() {
+			});
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new IllegalStateException(message.getMessage("딜상품 저장 중 오류로 인해 저장되지 않았습니다."));
+		}
+
+		for (GoodsCompose goodsCompose : goodsComposeList) {
+			goodsCompose.setGoodsCd(regGoods.getGoodsCd());
+			goodsCompose.setGoodsType(regGoods.getGoodsType());
+			goodsCompose.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsCompose.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			Goods extendGoods = new Goods();
+			extendGoods.setGoodsCd(goodsCompose.getCompsGoodsCd());
+			extendGoods = goodsDao.getGoods(extendGoods);
+			if (StringUtils.isEmpty(extendGoods.getBrandCd())) {
+				throw new IllegalStateException(message.getMessage("구성상품 중 " + goodsCompose.getCompsGoodsCd() + " 상품 정보를 확인해 주세요."));
+			}
+
+			if ("Y".equals(goodsCompose.getBaseYn())) {
+				regGoods.setBrandCd(extendGoods.getBrandCd());
+				regGoods.setItemkindCd(extendGoods.getItemkindCd());
+				regGoods.setSupplyCompCd(extendGoods.getSupplyCompCd());
+				regGoods.setFormalGb(extendGoods.getFormalGb());
+			}
+		}
+
+		this.createGoodsExtend(regGoods, goodsComposeList); // 딜상품 관련 정보 저장
+	}
+
+	/**
+	 * 세트상품 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 04
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsSet(Goods goods) {
+
+		Goods regGoods = new Goods();
+
+		// <,> replace 처리
+		regGoods.setRegNo(TsaSession.getInfo().getUserNo());
+		regGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		String goodsCd = this.getGoodsCodeSeq("S", "S");
+		regGoods.setGoodsCd(goodsCd);
+		regGoods.setSupplyGoodsCd(goodsCd);
+		regGoods.setGoodsType("G056_S");
+		regGoods.setSupplyCompCd(goods.getSupplyCompCd());
+		regGoods.setBrandCd(goods.getBrandCd());
+		regGoods.setItemkindCd(goods.getItemkindCd());
+		regGoods.setGoodsNm(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsNm(), "&lt;", "<"), "&gt;", ">"));
+		regGoods.setStyleYear(goods.getStyleYear());
+		regGoods.setSeasonCd(goods.getSeasonCd());
+		regGoods.setSexGb(goods.getSexGb());
+		regGoods.setMainColorCd("00");
+		regGoods.setOriginCd(goods.getOriginCd());
+		regGoods.setMakeYmd(goods.getMakeYmd());
+		regGoods.setSelfMallYn(goods.getSelfMallYn());
+		regGoods.setGoodsStat("G008_20"); // 정보부족
+		regGoods.setFormalGb("G009_10"); // 정상 기본값 처리
+		regGoods.setGoodsGb("G073_11"); // 자사상품은 신규
+		regGoods.setDistributionGb("G065_12"); // 유통구분
+		regGoods.setTaxGb("10"); // 과세구분
+		regGoods.setGoodsNum(goodsCd);
+
+		Collection<GoodsCompose> goodsComposeList = null;
+		try {
+			goodsComposeList = mapper.readValue(goods.getGoodsComposeList(), new TypeReference<Collection<GoodsCompose>>() {
+			});
+		} catch (Exception e) {
+			throw new IllegalStateException(message.getMessage("세트상품 저장 중 오류로 인해 저장되지 않았습니다."));
+		}
+
+		int listPriceSum = 0;
+		int currPriceSum = 0;
+		for (GoodsCompose goodsCompose : goodsComposeList) {
+			goodsCompose.setGoodsCd(regGoods.getGoodsCd());
+			goodsCompose.setGoodsType(regGoods.getGoodsType());
+			goodsCompose.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsCompose.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			Goods extendGoods = new Goods();
+			extendGoods.setGoodsCd(goodsCompose.getCompsGoodsCd());
+			extendGoods = goodsDao.getGoods(extendGoods);
+			if (StringUtils.isEmpty(extendGoods.getBrandCd())) {
+				throw new IllegalStateException(message.getMessage("구성상품 중 " + goodsCompose.getCompsGoodsCd() + " 상품 정보를 확인해 주세요."));
+			}
+			listPriceSum += extendGoods.getListPrice() * goodsCompose.getQty() ;
+			currPriceSum += goodsCompose.getCompsCurrPrice(); // 입력값
+
+			if ("Y".equals(goodsCompose.getBaseYn())) {
+				regGoods.setBrandCd(extendGoods.getBrandCd());
+				regGoods.setItemkindCd(extendGoods.getItemkindCd());
+				regGoods.setGoodsNum(extendGoods.getGoodsNum());
+				regGoods.setSupplyCompCd(extendGoods.getSupplyCompCd());
+				regGoods.setFormalGb(extendGoods.getFormalGb());
+			}
+		}
+
+		regGoods.setListPrice(listPriceSum);
+		regGoods.setCurrPrice(currPriceSum);
+		regGoods.setCostPrice(0);	// 원가 0원처리
+		regGoods.setDcRate((int)(this.getDcRate(listPriceSum, currPriceSum)));
+
+		this.createGoodsExtend(regGoods, goodsComposeList); // 세트상품 관련 정보 저장
+	}
+
+	/**
+	 * 세트/딜 상품 관련 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	private void createGoodsExtend(Goods regGoods, Collection<GoodsCompose> goodsComposeList) {
+		// 브랜드 확인
+		Brand brand = new Brand();
+		brand.setBrandCd(regGoods.getBrandCd());
+		brand.setSupplyCompCd(regGoods.getSupplyCompCd());
+		Collection<Brand> brandList = businessService.getBrandList(brand);
+		if (brandList == null || brandList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("구성상품 중 기준 상품의 브랜드를 확인해 주세요."));
+		}
+
+		float pntPrate = 0.0f;
+		float pntMrate = 0.0f;
+		float sellFeeRate = 0.0f;
+		String delvFeeCd = "";
+		for (Brand tmpBrand : brandList) {
+
+			if ("10".equals(regGoods.getFormalGb())) {
+				pntPrate = tmpBrand.getPntPrate10();
+				pntMrate = tmpBrand.getPntMrate10();
+			} else {
+				pntPrate = tmpBrand.getPntPrate20();
+				pntMrate = tmpBrand.getPntMrate20();
+			}
+			sellFeeRate = tmpBrand.getSellFeeRate();
+			delvFeeCd = tmpBrand.getDelvFeeCd();
+		}
+		regGoods.setDelvFeeCd(delvFeeCd);// 배송비전책코드
+		regGoods.setPntPrate(pntPrate); // 포인트적립율(PC)
+		regGoods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
+		regGoods.setSellFeeRate(sellFeeRate); // 판매수수료율
+		regGoods.setSelfGoodsYn("Y");
+
+		// 스타일 연도
+		regGoods.setStyleYear(regGoods.getStyleYear());
+
+		goodsDao.createGoods(regGoods); // 상품기본 저장
+		goodsDao.createGoodsSmmary(regGoods); // 상품통계 생성
+
+		StringBuilder goodsDescSb = new StringBuilder(); // 상품상세
+
+		int dispOrd = 1;
+		for (GoodsCompose regGoodsExtend : goodsComposeList) {
+			regGoodsExtend.setDispOrd(dispOrd);
+			goodsDao.saveGoodsCompose(regGoodsExtend); // 구성상품기본 저장
+			dispOrd++;
+		}
+
+		// 사용자 검색어를 검색어에 적용
+		String goodsSnm = goodsDao.getGoodsSnm(regGoods.getGoodsCd());
+		regGoods.setGoodsSnm(goodsSnm);
+		goodsDao.updateGoodsSnm(regGoods);
+
+		// 카테고리 전시
+		// 추후 작업 해야함 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		//goodsDao.createCategoryGoods(regGoods);
+
+	}
+
+//	/**
+//	 * 품 이미지 경로생성
+//	 *
+//	 * @param goodsCd
+//	 * @param brandCd
+//	 * @return String
+//	 * @author eskim
+//	 * @since 2020. 10. 30
+//	 */
+//	private String getGoodsImgPath(String goodsCd, String brandCd) {
+//		return "/" + goodsCd.substring(0, 1) + "/" + goodsCd.substring(0, 3) + "/" + goodsCd + "/1000/" + goodsCd + "_";
+//	}
+
+	/**
+	 * 상품 코드 생성
+	 *
+	 * @param goodsType - 상품타입
+	 * @param goodsCdAfter - 상품시퀀스 앞에 붙는명
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	public String getGoodsCodeSeq(String goodsType, String goodsCdAfter) {
+
+		//상품코드 12자리
+		String goodsCd = "";
+		Goods goods = new Goods();
+		goodsDao.createGoodsSequence(goods);
+		String goodsSeq = GagaStringUtil.getLPadding(Integer.toString(goods.getGoodsSq()), 9, "0");
+		if ("S".equals(goodsType) || "D".equals(goodsType)) {
+			goodsCd = SELF_GOOODS_AFTER + goodsCdAfter + goodsSeq;
+
+		} else {
+			goodsCd = goodsCdAfter + goodsSeq; // 입점 : 브랜드코드
+		}
+		return goodsCd;
+	}
+
+	/**
+	 * 상품 타이틀 관리 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11 .02
+	 */
+	public int getGoodsTitleReserveCount(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsTitleReserveCount(goodsSearch);
+	}
+
+	/**
+	 * 상품 타이틀 관리 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11 .02
+	 */
+	public Collection<GoodsTnmRes> getGoodsTitleReserveList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsTitleReserveList(goodsSearch);
+	}
+
+	/**
+	 * 상품 타이틀 예약 등록
+	 *
+	 * @param goodsTnmRes
+	 * @author eskim
+	 * @since 2020. 11 .02
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsRsvtTnm(GoodsTnmRes goodsTnmRes) {
+		if (goodsTnmRes.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		goodsTnmRes.setGoodsTnm(GagaStringUtil.replace(GagaStringUtil.replace(goodsTnmRes.getGoodsTnm(), "&lt;", "<"), "&gt;", ">"));
+
+		for (String goodsCd : goodsTnmRes.getArrGoodsCd()) {
+
+			goodsTnmRes.setGoodsCd(goodsCd);
+			goodsTnmRes.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsTnmRes.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if (goodsDao.getGoodsTnmDupChkCount(goodsTnmRes) > 0) {
+				throw new IllegalStateException("이미 등록된 상품 타이틀예약이 등록하려는 예약기간내에 존재합니다. \n(상품코드 : " + goodsCd + ")");
+			}
+
+			goodsDao.createGoodTnmRes(goodsTnmRes);
+
+			// 현재일자가 예약기간에 포함되어 있으면 바로 적용한다.
+			String toDaytime = GagaDateUtil.getTodayDateTime();
+			if (Long.parseLong(toDaytime) >= Long.parseLong(goodsTnmRes.getApplyStdt()) && Long.parseLong(toDaytime) <= Long.parseLong(goodsTnmRes.getApplyEddt())) {
+
+				// 이력생성 및 상품타이틀 수정
+				Goods goods = new Goods();
+				goods.setGoodsCd(goodsCd);
+				goods.setGoodsTnm(goodsTnmRes.getGoodsTnm());
+				goods.setRegNo(TsaSession.getInfo().getUserNo());
+				goods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+				goodsDao.createGoodsHst(goods);
+				goodsDao.updateGoodTnm(goods);
+			}
+
+		}
+	}
+
+	/**
+	 * 상품 타이틀 예약 삭제
+	 *
+	 * @param goodsTnmRes
+	 * @author eskim
+	 * @since 2020. 11 .02
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteGoodsRsvtTnm(GoodsTnmRes goodsTnmRes) {
+		if (goodsTnmRes.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		int idx = 0;
+		for (String goodsCd : goodsTnmRes.getArrGoodsCd()) {
+
+			// 상품 타이틀 예약 삭제
+			goodsTnmRes.setGoodsTnmResSq(goodsTnmRes.getArrGoodsTnmResSq()[idx]);
+			goodsDao.deleteGoodTnmRes(goodsTnmRes);
+
+			// 상품 타이틀 예약건 초기화
+			Goods goods = new Goods();
+			goods.setGoodsCd(goodsCd);
+			goods = goodsDao.getGoodTnmInit(goods);
+			goods.setRegNo(TsaSession.getInfo().getUserNo());
+			goods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if (!StringUtils.isEmpty(goods.getGoodsTnm()) && !goods.getGoodsTnm().equals(goods.getGoodTnmInit())) {
+
+				// 상품이력 먼저 쌓기
+				goodsDao.createGoodsHst(goods);
+				// 정보수정
+				goods.setGoodsTnm(goods.getGoodTnmInit());
+				goodsDao.updateGoodTnm(goods);
+
+			}
+			idx++;
+		}
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return int
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	public int getGoodsEpSkipCount(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsEpSkipCount(goodsSearch);
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<TsaGoodsEpSkip>
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	public Collection<GoodsEpSkip> getGoodsEpSkipList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsEpSkipList(goodsSearch);
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 등록
+	 *
+	 * @param goodsEpSkip
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsRsvtEpSkip(GoodsEpSkip goodsEpSkip) {
+		if (goodsEpSkip.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		for (String goodsCd : goodsEpSkip.getArrGoodsCd()) {
+
+			goodsEpSkip.setGoodsCd(goodsCd);
+			goodsEpSkip.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsEpSkip.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if (goodsDao.getGoodsEpSkipDupChkCount(goodsEpSkip) > 0) {
+				throw new IllegalStateException("비노출예약이 중복된 상품이 존재합니다.<br/>(상품코드 : " + goodsCd + ")");
+			}
+			goodsDao.createGoodEpSkip(goodsEpSkip);
+		}
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 삭제
+	 *
+	 * @param goodsEpSkip
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteGoodsEpSkip(GoodsEpSkip goodsEpSkip) {
+		if (goodsEpSkip.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		int idx = 0;
+		for (String goodsCd : goodsEpSkip.getArrGoodsCd()) {
+			goodsEpSkip.setGoodsEpSkipSq(goodsEpSkip.getArrGoodsEpSkipSq()[idx]);
+			goodsDao.deleteGoodEpSkip(goodsEpSkip);
+			idx++;
+		}
+	}
+
+	/**
+	 * 상품예약판매 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	public int getGoodsResSellCount(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsResSellCount(goodsSearch);
+	}
+
+	/**
+	 * 상품예약판매 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<TsaGoodsResSell>
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	public Collection<GoodsResSell> getGoodsResSellList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsResSellList(goodsSearch);
+	}
+
+	/**
+	 * 상품예약판매 등록
+	 *
+	 * @param goodsResSell
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsResSell(GoodsResSell goodsResSell) {
+		if (goodsResSell.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		for (String goodsCd : goodsResSell.getArrGoodsCd()) {
+
+			goodsResSell.setGoodsCd(goodsCd);
+			goodsResSell.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsResSell.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if(goodsDao.getGoodsResSellDupChkCount(goodsResSell) > 0 ) {
+				throw new IllegalStateException("이미 등록된 상품예약판매가 존재합니다. \n(상품코드 : " + goodsCd + ")");
+			}
+
+			goodsDao.createGoodResSell(goodsResSell);
+
+			Goods goods = new Goods();
+			goods.setRegNo(TsaSession.getInfo().getUserNo());
+			goods.setUpdNo(TsaSession.getInfo().getUserNo());
+			goods.setGoodsCd(goodsResSell.getGoodsCd());
+
+			// 재고연동 비활성화
+			goodsDao.createGoodsHst(goods);
+			goodsDao.updateGoodsErpStockLinkYn(goods);
+
+		}
+	}
+
+	/**
+	 * 상품예약판매 삭제
+	 *
+	 * @param goodsResSell
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteGoodsResSell(GoodsResSell goodsResSell) {
+		if (goodsResSell.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		int idx = 0;
+		for (String goodsCd : goodsResSell.getArrGoodsCd()) {
+			goodsResSell.setGoodsResSellSq(goodsResSell.getArrGoodsResSellSq()[idx]);
+			goodsDao.deleteGoodResSell(goodsResSell);
+			idx++;
+		}
+	}
+
+	/**
+	 * 상품 상세공지 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 05
+	 */
+	public Collection<Notice> getNoticeList(GoodsSearch goodsSearch) {
+		return goodsDao.getNoticeList(goodsSearch);
+	}
+
+	/**
+	 * 상품 상세공지 상품 목록
+	 *
+	 * @param notice
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 06
+	 */
+	public Collection<NoticeGoods> getNoticeGoodsList(Notice notice) {
+		return goodsDao.getNoticeGoodsList(notice);
+	}
+
+	/**
+	 * 공지사항 저장
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 05
+	 */
+	@Transactional("shopTxnManager")
+	public void saveNotice(Notice notice) {
+		notice.setRegNo(TsaSession.getInfo().getUserNo());
+		notice.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		// 신규 일때
+		if (notice.getNoticeSq() == null) {
+			// 공지사항 저장
+			noticeService.createNotice(notice);
+
+			// 등록된 사용자번호 값 가져오기
+			Integer noticeSq = notice.getNoticeSq();
+
+			notice.setNoticeSq(noticeSq);
+
+		} else {
+			// 공지사항 수정
+			noticeService.updateNotice(notice);
+		}
+
+		if (!StringUtils.isEmpty(notice.getGoodsList())) {
+			Collection<NoticeGoods> noticeGoodsList = null;
+			try {
+				noticeGoodsList = mapper.readValue(notice.getGoodsList(), new TypeReference<Collection<NoticeGoods>>() {
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new IllegalStateException(message.getMessage("상품상세공지 저장 중 오류로 인해 저장되지 않았습니다."));
+			}
+			log.info("noticeGoodsList: {}", noticeGoodsList);
+			for (NoticeGoods noticeGoods : noticeGoodsList) {
+				noticeGoods.setNoticeSq(notice.getNoticeSq());
+				noticeGoods.setRegNo(TsaSession.getInfo().getUserNo());
+				noticeGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+				goodsDao.saveNoticeGoods(noticeGoods);
+			}
+
+		}
+	}
+
+	/**
+	 * 공지사항 상품 삭제
+	 * @param noticeGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 06
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteNoticeGoods(NoticeGoods noticeGoods) {
+
+		if (noticeGoods == null || (noticeGoods.getArrGoodsCd() == null && noticeGoods.getArrGoodsCd().length <= 0)) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		if (noticeGoods.getArrGoodsCd().length > 0) {
+			for (String goodsCd : noticeGoods.getArrGoodsCd()) {
+				noticeGoods.setGoodsCd(goodsCd);
+				noticeGoods.setRegNo(TsaSession.getInfo().getUserNo());
+				noticeGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+				goodsDao.deleteNoticeGoods(noticeGoods);
+			}
+		}
+
+	}
+
+	/**
+	 * 상품 가격예약 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	public int getGoodsPriceResCount(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsPriceResCount(goodsSearch);
+	}
+
+	/**
+	 * 상품 가격예약 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<TsaGoodsResSell>
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	public Collection<GoodsPriceRes> getGoodsPriceResList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsPriceResList(goodsSearch);
+	}
+
+	/**
+	 * 상품 가격예약 등록
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void createGoodPriceRes(GoodsPriceRes goodsPriceRes) {
+		if (goodsPriceRes.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		int idx = 0;
+		for (String goodsCd : goodsPriceRes.getArrGoodsCd()) {
+
+			goodsPriceRes.setGoodsCd(goodsCd);
+			goodsPriceRes.setEndGoodsPrice(goodsPriceRes.getArrEndGoodsPrice()[idx]);
+			goodsPriceRes.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsPriceRes.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			if(goodsDao.getGoodsPriceResDupChkCount(goodsPriceRes) > 0 ) {
+				throw new IllegalStateException("이미 등록된 상품 가격예약이 존재합니다. \n(상품코드 : " + goodsCd + ")");
+			}
+
+			goodsDao.createGoodPriceRes(goodsPriceRes);
+
+			Goods goods = new Goods();
+			goods.setRegNo(TsaSession.getInfo().getUserNo());
+			goods.setUpdNo(TsaSession.getInfo().getUserNo());
+			goods.setGoodsCd(goodsPriceRes.getGoodsCd());
+			idx++;
+		}
+	}
+
+	/**
+	 * 상품 가격예약 삭제
+	 *
+	 * @param goodsPriceRes
+	 * @return void
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteGoodsPriceRes(GoodsPriceRes goodsPriceRes) {
+		if (goodsPriceRes.getArrGoodsCd().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+		int idx = 0;
+		for (String goodsCd : goodsPriceRes.getArrGoodsCd()) {
+			goodsPriceRes.setGoodsPriceResSq(goodsPriceRes.getArrGoodsPriceResSq()[idx]);
+			goodsDao.deleteGoodPriceRes(goodsPriceRes);
+			idx++;
+		}
+	}
+
+	/**
+	 * 상품 가격예약 저장
+	 *
+	 * @param goodsPriceList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsPriceExcelupload(Collection<GoodsPriceRes> goodsPriceList, String excelFilename) {
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		if (goodsPriceList == null || goodsPriceList.isEmpty()) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		// 입력값 확인
+		String goodsPriceResvCheck = getGoodsPriceResvCheck(goodsPriceList);
+		if (!"SUCC".equals(goodsPriceResvCheck)) {
+			this.deleteExceluploadFile(targetPath, excelFilename);
+			throw new IllegalStateException(goodsPriceResvCheck);
+		}
+
+		int index = 0;
+		for (GoodsPriceRes goodsPriceRes : goodsPriceList) {
+			goodsPriceRes.setUpdNo(TsaSession.getInfo().getUserNo());
+			goodsPriceRes.setRegNo(TsaSession.getInfo().getUserNo());
+
+			// 엑셀조회를 위한 SEARCH 테이블 생성
+			SearchData searchData = new SearchData();
+			searchData.setRegNo(goodsPriceRes.getRegNo());
+			searchData.setSearchCd(goodsPriceRes.getGoodsCd());
+			searchData.setDispOrd(index);
+			if (index == 0) {
+				commonService.deleteExceluploadSearCh(searchData);
+			}
+
+			commonService.createExceluploadSearch(searchData);
+
+			goodsDao.createGoodPriceRes(goodsPriceRes);
+
+			index++;
+		}
+	}
+
+	/*
+	 * 상품 가격예약 엑셀조회용 상품 저장 - 입력값 확인
+	 */
+	private String getGoodsPriceResvCheck(Collection<GoodsPriceRes> goodsPriceList) {
+
+		int cnt = 0;
+		for (GoodsPriceRes goodsPriceRes : goodsPriceList) {
+
+			if (StringUtils.isEmpty(goodsPriceRes.getGoodsCd())) {
+				return (cnt + 2) + "행의 상품코드를 확인해주세요";
+			}
+			if (StringUtils.isEmpty(goodsPriceRes.getResGoodsPrice())) {
+				return (cnt + 2) + "행의 예약가격을 확인해주세요.";
+			}
+			if (goodsPriceRes.getResGoodsPrice() <= 0) {
+				return (cnt + 2) + "행의 예약가격을 확인해주세요.";
+			}
+
+			String nowDate = GagaDateUtil.getToday();	//yyyyMMdd
+			SimpleDateFormat dateFormatParser = new SimpleDateFormat("yyyyMMdd");
+			dateFormatParser.setLenient(false);
+			try {
+				dateFormatParser.parse(goodsPriceRes.getApplyStdt() );
+			} catch (Exception e) {
+				return (cnt + 2) + "행의 예약시작일을 확인해주세요.";
+			}
+			try {
+				dateFormatParser.parse(goodsPriceRes.getApplyEddt() );
+			} catch (Exception e) {
+				return (cnt + 2) + "행의 예약종료일을 확인해주세요.";
+			}
+
+			if (Integer.parseInt(goodsPriceRes.getApplyStdt()) > Integer.parseInt(goodsPriceRes.getApplyEddt())) {
+				return (cnt + 2) + "행의 예약 시작일은 종료일보다 보다 클 수 없습니다.";
+			}
+
+			if (Integer.parseInt(goodsPriceRes.getApplyStdt()) <= Integer.parseInt(nowDate)) {
+				return (cnt + 2) + "행의 예약 시작일자는 현재일자 보다 작거나 같을 수 없습니다.";
+			}
+
+			//정상가와 비교
+			Goods searchGoods = new Goods();
+			searchGoods.setGoodsCd(goodsPriceRes.getGoodsCd());
+			Goods goods = goodsDao.getGoods(searchGoods);
+			if (goods == null) {
+				return (cnt + 2) + "행의 상품코드를 확인해주세요";
+			}
+			if (goods.getListPrice() < goodsPriceRes.getResGoodsPrice()) {
+				return (cnt + 2) + "행의 상품 정상가보다 예약판매가가 더 큽니다.";
+			}
+			if (!"Y".equals(goods.getSelfGoodsYn())) {
+				return (cnt + 2) + "행의 상품은 자사상품이 아닙니다.";
+			}
+
+			if(goodsDao.getGoodsPriceResDupChkCount(goodsPriceRes) > 0 ) {
+				return (cnt + 2) + "행은 이미 등록된 상품 가격예약이 존재합니다. \n(상품코드 : " + goodsPriceRes.getGoodsCd() + ")";
+			}
+
+
+			cnt++;
+		}
+
+		return "SUCC";
+	}
+
+
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	public Collection<GoodsVideo> getGoodsVideoList(GoodsVideo goodsVideo) {
+		return goodsDao.getGoodsVideoList(goodsVideo);
+	}
+
+	/**
+	 * 상품 동영상 삭제로 변경
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void updateNotUseGoodsVideo(Collection<GoodsVideo> goodsVideos) {
+		for (GoodsVideo goodsVideo : goodsVideos) {
+			Video video = new Video();
+			video.setUpdNo(TsaSession.getInfo().getUserNo());
+			video.setVideoSq(goodsVideo.getVideoSq());
+			goodsDao.updateNotUseGoodsVideo(video);
+		}
+	}
+
+	/**
+	 * 상품동영상 수정/저장
+	 *
+	 * @param video
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsVideo(Video video) {
+		video.setRegNo(TsaSession.getInfo().getUserNo());
+		video.setUpdNo(TsaSession.getInfo().getUserNo());
+		if (video.getVideoSq() == null ||  video.getVideoSq() == 0) {
+
+			String videoSeq = goodsDao.getVideoSeq(video);
+			if (StringUtils.isEmpty(videoSeq)) {
+				goodsDao.createVideo(video);
+			}else {
+				//video.setVideoSq(Integer.parseInt(videoSeq));  //why?
+				//goodsDao.updateVideo(video);
+			}
+		}
+
+		if (video.getVideoSq() == null ||  video.getVideoSq() == 0) {
+			String videoSeq = goodsDao.getVideoSeq(video);
+
+			if (!StringUtils.isEmpty(videoSeq)) {
+				video.setVideoSq(Integer.parseInt(videoSeq));
+			}
+		}
+
+		//goodsDao.delVideoDispLoc(video);  why?
+		String[] displocValArr = video.getDisplocValArr();
+		for (String displocVal : displocValArr) {
+			video.setDisplocVal(displocVal);
+			goodsDao.saveVideoDispLoc(video);
+		}
+	}
+
+	/**
+	 * 상품동영상 엑셀파일 등록
+	 *
+	 * @param dataList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public int saveExcelGoodsVideo(Collection<GagaMap> dataList) {
+
+		int cnt = 0;
+
+		for (GagaMap map : dataList) {
+			Video video = mapper.convertValue(map, Video.class);
+			video.setUpdNo(TsaSession.getInfo().getUserNo());
+			video.setRegNo(TsaSession.getInfo().getUserNo());
+			video.setDisplocGb("G");
+			video.setDispYn("Y");
+			String videoVal = video.getVideoVal();
+			if (videoVal.contains("http")) {
+				video.setVideoGb("M");
+			} else {
+				video.setVideoGb("Y");
+			}
+			String videoSeq = goodsDao.getVideoSeq(video);
+
+			if (StringUtils.isEmpty(videoSeq)) {
+				goodsDao.createVideo(video);
+			}
+
+			videoSeq = goodsDao.getVideoSeq(video);
+			if (!StringUtils.isEmpty(videoSeq)) {
+				video.setVideoSq(Integer.parseInt(videoSeq));
+			}
+			goodsDao.saveVideoDispLoc(video);
+			cnt++;
+		}
+
+		return cnt;
+	}
+
+	/**
+	 * 상품별 옵션 등록 여부 확인
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 17
+	 */
+	public int getGoodsOptionCount(Option option) {
+
+		return goodsDao.getGoodsOptionCount(option);
+	}
+
+	/**
+	 * 상품 가격승인관리 목록 조회
+	 *
+	 * @param goodsPriceHst
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	public Collection<GoodsPriceRes> getGoodsSupplyPriceList(GoodsPriceRes goodsPriceHst) {
+
+		return goodsDao.getGoodsSupplyPriceList(goodsPriceHst);
+	}
+
+	/**
+	 * 상품 가격승인관리 승인 처리
+	 *
+	 * @param goodsPriceHstList - 상품 가격 승인 목록
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsSupplyPrice(Collection<GoodsPriceRes> goodsPriceHstList) {
+
+		for (GoodsPriceRes goodsPriceRes : goodsPriceHstList) {
+			goodsPriceRes.setRegNo(TsaSession.getInfo().getUserNo());
+			goodsPriceRes.setUpdNo(TsaSession.getInfo().getUserNo());
+
+
+			Goods goods = new Goods();
+			goods.setRegNo(TsaSession.getInfo().getUserNo());
+			goods.setUpdNo(TsaSession.getInfo().getUserNo());
+			goods.setGoodsCd(goodsPriceRes.getGoodsCd());
+
+			goodsDao.createGoodsHst(goods);
+
+			// 판매가 변경
+			if (goodsPriceRes.getResGoodsPrice() > 0) {
+				log.info("goodsPriceRes.getTagPrice() ={}", goodsPriceRes.getListPrice());
+				log.info("goodsPriceRes.getResGoodsPrice() ={}", goodsPriceRes.getResGoodsPrice());
+				goods.setDcRate((int)(this.getDcRate(goodsPriceRes.getListPrice(), goodsPriceRes.getResGoodsPrice())));
+				goods.setCurrBprice(goodsPriceRes.getCurrPrice());
+				goods.setCurrPrice(goodsPriceRes.getResGoodsPrice());
+				goodsDao.updateGoodsPrice(goods);
+			}
+
+			// 판매수수료율 변경
+			if (goodsPriceRes.getSellFeeRate() != null) {
+				goods.setSellFeeRate(goodsPriceRes.getSellFeeRate());
+				goodsDao.updateSellFeeRate(goods);
+			}
+
+			goodsDao.updateGoodsSupplyPricecfrmDt(goodsPriceRes);
+		}
+	}
+
+	/**
+	 * 상품 네이버 최저가 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 08
+	 */
+	public Collection<GoodsNaverLowestPrice> getGoodsNaverPriceList(GoodsSearch goodsSearch) {
+		return goodsDao.getGoodsNaverPriceList(goodsSearch);
+	}
+
+	/**
+	 * 상품 네이버 최저가 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 08
+	 */
+	@Transactional("shopTxnManager")
+	public Collection<GoodsNaverLowestPrice> saveGoodsNaverPrice(GoodsSearch goodsSearch) {
+
+		// 1. 조회 상품 TB_SEARCH_DATA 담기
+		int index = 0;
+		for (String goodsCd : goodsSearch.getConditionList()) {
+
+			SearchData searchData = new SearchData();
+			searchData.setRegNo(TsaSession.getInfo().getUserNo());
+			searchData.setSearchCd(goodsCd);
+			if (index == 0) {
+				commonService.deleteExceluploadSearCh(searchData);
+			}
+
+			commonService.createExceluploadSearch(searchData);
+			index++;
+		}
+
+		// 2. 일 최초 조회이면 테이블 삭제
+		String regYmd  = goodsDao.getGoodsNaverLowestPriceReqYmd();
+		if (!StringUtils.isEmpty(regYmd) && !regYmd.equals(GagaDateUtil.getToday())) {
+			goodsDao.deleteGoodsNaverLowestPrice();
+		}
+
+		// 3. 네이버 최저가 조회 저장
+		saveGoodsNaverLowestPrice(goodsSearch);
+
+		// 4. 최저가 상품 조회
+		goodsSearch.setSearchGb("EXCEL");
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		return goodsDao.getGoodsNaverPriceList(goodsSearch);
+	}
+
+	/**
+	 * 상품 네이버 최저가 목록
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 08
+	 */
+	private void saveGoodsNaverLowestPrice(GoodsSearch goodsSearch) {
+
+		for (String goodsCd : goodsSearch.getConditionList()) {
+			try {
+				log.info("saveGoodsNaverLowestPrice  11 =  {}", GagaDateUtil.getTodayDateTime());
+				TaskSleeep();
+				log.info("saveGoodsNaverLowestPrice  22 =  {}", GagaDateUtil.getTodayDateTime());
+				NaverLowestPrice naverLowestPrice = naverLowestPriceApi.getLowestPrice(goodsCd);
+
+				log.info("[saveGoodsNaverLowestPrice] naverLowestPrice= {}",naverLowestPrice);
+				if (naverLowestPrice != null) {
+					GoodsNaverLowestPrice goodsNaverLowestPrice = new GoodsNaverLowestPrice();
+					goodsNaverLowestPrice.setReqYmd(GagaDateUtil.getToday());
+					goodsNaverLowestPrice.setGoodsCd(goodsCd);
+					goodsNaverLowestPrice.setMallNm(naverLowestPrice.getItems().iterator().next().getMallName());
+					goodsNaverLowestPrice.setMallLink(naverLowestPrice.getItems().iterator().next().getLink());
+					goodsNaverLowestPrice.setLowestPrice(naverLowestPrice.getItems().iterator().next().getLprice());
+					goodsNaverLowestPrice.setRegNo(TsaSession.getInfo().getUserNo());
+					goodsNaverLowestPrice.setUpdNo(TsaSession.getInfo().getUserNo());
+					log.info("[saveGoodsNaverLowestPrice] goodsNaverLowestPrice= {}", goodsNaverLowestPrice);
+					goodsDao.saveGoodsNaverLowestPrice(goodsNaverLowestPrice);
+
+				}
+
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+
+		}
+
+	}
+
+	/**
+	 *
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 08
+	 */
+	static void TaskSleeep() {
+		try {
+			Thread.sleep(100);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 광고 키워드 목록
+	 *
+	 * @param adKeyword
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	public Collection<AdKeyword> getAdKeywordList(AdKeyword adKeyword) {
+		return goodsDao.getAdKeywordList(adKeyword);
+	}
+
+	/**
+	 * 광고 키워드 상품 목록
+	 *
+	 * @param adKeyword
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	public Collection<AdKeywordGoods> getAdKeywordGoodsList(AdKeyword adKeyword) {
+		return goodsDao.getAdKeywordGoodsList(adKeyword);
+	}
+
+	/**
+	 * 광고 키워드 저장
+	 * @param adKeyword
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	@Transactional("shopTxnManager")
+	public void saveAdKeywordGoods(AdKeyword adKeyword) {
+		adKeyword.setRegNo(TsaSession.getInfo().getUserNo());
+		adKeyword.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		// 신규 일때
+		if (adKeyword.getAdKeywordSq() == null) {
+			// 공지사항 저장
+			goodsDao.saveAdKeyword(adKeyword);
+
+			// 등록된 사용자번호 값 가져오기
+			Integer noticeSq = adKeyword.getAdKeywordSq();
+
+			adKeyword.setAdKeywordSq(noticeSq);
+
+		} else {
+			// 공지사항 수정
+			goodsDao.saveAdKeyword(adKeyword);
+		}
+
+		if (!StringUtils.isEmpty(adKeyword.getGoodsList())) {
+			Collection<AdKeywordGoods> adKeywordGoodsList = null;
+			try {
+				adKeywordGoodsList = mapper.readValue(adKeyword.getGoodsList(), new TypeReference<Collection<AdKeywordGoods>>() {
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new IllegalStateException(message.getMessage("광고 키워드 저장 중 오류로 인해 저장되지 않았습니다."));
+			}
+			log.info("adKeywordGoodsList: {}", adKeywordGoodsList);
+
+			int idx = 0;
+			for (AdKeywordGoods adKeywordGoods : adKeywordGoodsList) {
+				if (idx == 0) goodsDao.deleteAdKeywordGoods(adKeywordGoods); // 전체 상품 삭제
+				adKeywordGoods.setAdKeywordSq(adKeyword.getAdKeywordSq());
+				adKeywordGoods.setRegNo(TsaSession.getInfo().getUserNo());
+				adKeywordGoods.setUpdNo(TsaSession.getInfo().getUserNo());
+
+				goodsDao.saveAdKeywordGoods(adKeywordGoods);
+				idx++;
+			}
+		}
+	}
+
+	/**
+	 * 광고 키워드 상품 삭제
+	 * @param adKeywordGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteAdKeywordGoods(AdKeywordGoods adKeywordGoods) {
+
+		if (adKeywordGoods == null || (adKeywordGoods.getArrGoodsCd() == null && adKeywordGoods.getArrGoodsCd().length <= 0)) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		if (adKeywordGoods.getArrGoodsCd().length > 0) {
+			goodsDao.deleteAdKeywordGoods(adKeywordGoods);
+		}
+	}
+
+	/**
+	 * 재입고알림 목록 건수
+	 *
+	 * @param goodsSearch
+	 * @return Integer
+	 * @author eskim
+	 * @since 2020. 12. 16
+	 */
+	public int getReinboundInformCount(GoodsSearch goodsSearch) {
+		return goodsDao.getReinboundInformCount(goodsSearch);
+	}
+
+	/**
+	 * 재입고알림 목록
+	 *
+	 * @param goodsSearch
+	 * @return Collection<ReinboundInform>
+	 * @author eskim
+	 * @since 2020. 12. 16
+	 */
+	public Collection<ReinboundInform> getReinboundInformList(GoodsSearch goodsSearch) {
+		return goodsDao.getReinboundInformList(goodsSearch);
+	}
+
+
+	/**
+	 * 재입고알림 발송 처리
+	 *
+	 * @param params
+	 * @return void
+	 * @author daehyoung
+	 * @since 2020. 07 .21
+	 */
+	@Transactional("shopTxnManager")
+	public void sendReinboundInform(ReinboundInform reinboundInform) {
+
+		if (reinboundInform.getArrRinbdInfoSq().length <= 0) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		int idx = 0;
+		for (String rinbdInfoSq : reinboundInform.getArrRinbdInfoSq()) {
+
+			GoodsSearch goodsSearch = new GoodsSearch();
+			goodsSearch.setRinbdInfoSq(Integer.parseInt(rinbdInfoSq));
+
+			Collection<ReinboundInform> list = goodsDao.getReinboundInformList(goodsSearch);
+			ReinboundInform oneParam = null;
+			if (list.size() == 1) {
+				oneParam = list.iterator().next();
+			} else {
+				continue;
+			}
+
+			// 재고체크
+			if (oneParam.getCurrStockQty() < 1 || "Y".equals(oneParam.getSoldoutYn())) {
+				throw new IllegalStateException(oneParam.getGoodsCd() + "상품( 사이즈 : " + oneParam.getOptCd1() + " )은 가용재고가 없습니다.");
+			}
+
+			oneParam.setRegNo(TsaSession.getInfo().getUserNo());
+			oneParam.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			// **** 알림톡 발송 start ****
+			try {
+				log.info("[카카오 알림톡 발송 정보] - 재입고알림 발송: " + oneParam.toString());
+				/////////////////////////////////////////////////////
+				//kakaoService.sendGoodsRestock(oneParam);	//나중에 수정해요 eskim
+				/////////////////////////////////////////////////////
+			} catch (Exception e) {
+				e.getStackTrace();
+				throw new IllegalStateException("재입고알림 알림톡 발송을 실패하였습니다.");
+			}
+			// **** 알림톡 발송 end ****
+
+			// 재입고알림 발송처리
+			goodsDao.updateReinboundInform(oneParam);
+			idx++;
+		}
+	}
+
+	/**
+	 * 상품이미지 목록
+	 *
+	 * @param goodsImg
+	 * @return Collection<GoodsImg>
+	 * @author eskim
+	 * @since 2020. 12. 18
+	 */
+	public Collection<GoodsImg> getGoodsImgList(GoodsImg goodsImg) {
+		return goodsDao.getGoodsImageList(goodsImg);
+	}
+
+	/**
+	 * 상품이미지 저장 처리
+	 * @param goodsImgList - 상품이미지 목록
+	 * @throws AdmBizException
+	 * @author eskim
+	 * @since 2020. 12. 21
+	 */
+	@Transactional("shopTxnManager")
+	public void saveGoodsImageList(Collection<GoodsImg> goodsImgList){
+		int index = 0;
+		for (GoodsImg goodsImg : goodsImgList) {
+			// 상품이미지 전체 삭제
+			if (index++ == 0) {
+				goodsDao.deleteGoodsImageTotal(goodsImg);
+			}
+
+			if (!goodsImg.getMode().equals("D")) {
+				// 상품이미지 등록
+				goodsImg.setRegNo(TsaSession.getInfo().getUserNo());
+				goodsDao.createGoodsImage(goodsImg);
+			}
+		}
+	}
+
+	/**
+	 * 사은품 목록
+	 *
+	 * @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 int getGoodsWmsIncomelotListCount(WmsGoods wmsGoods) {
+		return goodsDao.getGoodsWmsIncomelotListCount(wmsGoods);
+	}
+
+	/**
+	 * 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);
+		}
+	}
+
+}

+ 234 - 0
src/main/java/com/style24/admin/biz/service/TsaKakaoService.java

@@ -0,0 +1,234 @@
+package com.style24.admin.biz.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.style24.core.biz.thirdparty.SsgKakaoSender;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 카카오알림톡 Service. 모든 카카오알림톡 발송은 여기에서 처리한다.
+ *
+ * @author gagamel
+ * @since 2020. 11. 9
+ */
+@Service
+@Slf4j
+public class TsaKakaoService {
+
+	@Autowired
+	private SsgKakaoSender kakaoSender;
+
+//	/**
+//	 * 고객 임시비밀번호 알림톡 발송
+//	 * @param counsel - 상담 정보
+//	 * @author gagamel
+//	 * @since 2020. 11. 9
+//	 */
+//	@Transactional("shopTxnManager")
+//	public void sendCustomerTempPassword(AdmCustomer customer) {
+//		SsgDirectMessage dm = new SsgDirectMessage();
+//		dm.setFuserid(String.valueOf(TsaSession.getInfo().getUserNo())); // 발송자ID
+//		dm.setFdestine(customer.getCellPhnno());
+//		dm.setFkkoresendtype("LMS");
+//
+//		GagaMap replaceInfo = new GagaMap();
+//		replaceInfo.setString("siteNm", customer.getSiteNm());
+//		replaceInfo.setString("custNm", customer.getCustNm());
+//		replaceInfo.setString("passwd", customer.getPasswd());
+//
+//		kakaoSender.send(SsgKakaoSender.KakaoAnswerSq.TempPasswd.value(), dm, replaceInfo);
+//
+//		try {
+//			// 고객접촉이력 정보
+//			customer.setContactType("203"); // 접촉유형:임시비밀번호발급(공통코드G054)
+//			customer.setContactMethod(TscConstants.ContactMethod.KAKAOTALK.value()); // 접촉방법:알림톡+문자(공통코드G055)
+//			customer.setContactContents("고객 임시비밀번호 발송");
+//			customer.setReceiverId(customer.getCustNo());
+//			customerService.createCustomerContactHistory(customer);
+//		} catch (Exception e) {
+//			log.error("error", e);
+//			// Do nothing
+//		}
+//	}
+//
+//	/**
+//	 * 일대일문의 답변 알림톡 발송
+//	 * @param counsel - 상담 정보
+//	 * @author gagamel
+//	 * @since 2020. 4. 6
+//	 */
+//	@Transactional("shopTxnManager")
+//	public void sendOnetoOneAnswer(AdmCounsel counsel) {
+//		SsgDirectMessage dm = new SsgDirectMessage();
+//		dm.setFdestine(counsel.getCellPhnno());
+//		dm.setFkkoresendtype("LMS");
+//		dm.setButtonNm("마이페이지 > 1:1문의");
+//		dm.setButtonUrl("/mypage/counsel/detail/form/" + counsel.getCounselSq());
+//
+//		GagaMap replaceInfo = new GagaMap();
+//		replaceInfo.setString("siteNm", systemService.getSiteName(AdmConstants.SITE_CD));
+//		replaceInfo.setString("custNm", counsel.getCustNm());
+//
+//		kakaoSender.send(SsgKakaoSender.KakaoAnswerSq.OtoAnswer.value(), dm, replaceInfo);
+//
+//		try {
+//			// 고객접촉이력 정보
+//			AdmCustomer customer = new AdmCustomer();
+//			customer.setContactType("204"); // 접촉유형:1:1문의답변(공통코드G054)
+//			customer.setContactMethod(TscConstants.ContactMethod.KAKAOTALK.value()); // 접촉방법:알림톡+문자(공통코드G055)
+//			customer.setContactContents("1:1 문의 답변 발송");
+//			customer.setReceiverId(counsel.getCustNo());
+//			customerService.createCustomerContactHistory(customer);
+//		} catch (Exception e) {
+//			log.error("error", e);
+//			// Do nothing
+//		}
+//	}
+//
+//	/**
+//	 * 인증번호발송
+//	 * @param customer - 인증번호 발송
+//	 * @author jsshin
+//	 * @since 2020. 4. 8
+//	 */
+//	public void sendCustomerCertNo(AdmCustomer customer) {
+//		SsgDirectMessage dm = new SsgDirectMessage();
+//		dm.setFdestine(customer.getCellPhnno());
+//		dm.setFkkoresendtype("LMS");
+//
+//		GagaMap replaceInfo = new GagaMap();
+//		replaceInfo.setString("siteNm", customer.getSiteNm());
+//		replaceInfo.setString("custNm", customer.getCustNm());
+//		replaceInfo.setString("certNo", customer.getCertNo());
+//
+//		kakaoSender.send(SsgKakaoSender.KakaoAnswerSq.CertNoSend.value(), dm, replaceInfo);
+//
+//		try {
+//			// 고객접촉이력 정보
+//			customer.setContactType("209"); // 접촉유형:1:1문의답변(공통코드G054)
+//			customer.setContactMethod(TscConstants.ContactMethod.KAKAOTALK.value()); // 접촉방법:알림톡+문자(공통코드G055)
+//			customer.setContactContents("인증번호");
+//			customer.setReceiverId(customer.getCustNo());
+//			customerService.createCustomerContactHistory(customer);
+//		} catch (Exception e) {
+//			log.error("error", e);
+//			// Do nothing
+//		}
+//	}
+//
+//	/**
+//	 * 품절에의한 주문취소 안내
+//	 * @param delivery
+//	 * @author yujung
+//	 * @since 2020. 4. 23
+//	 */
+//	public void sendCancelBySoldout(String payMeans, AdmDelivery delivery) {
+//		SsgDirectMessage dm = new SsgDirectMessage();
+//		dm.setFdestine(delivery.getOrderPhnno());
+//		dm.setFkkoresendtype("LMS");
+//
+//		GagaMap replaceInfo = new GagaMap();
+//		replaceInfo.setString("siteNm", systemService.getSiteName(AdmConstants.SITE_CD));
+//		replaceInfo.setString("custNm", delivery.getOrderNm());
+//		replaceInfo.setString("goodsNm", delivery.getGoodsNm());
+//		replaceInfo.setString("callcenterTelNo", TscConstants.CALLCENTER_TEL_NO);
+//
+//		Integer KakaoAnswerSq = null;
+//		if (payMeans.equals(TscConstants.PayMeans.CREDIT_CARD.value())) { // 신용카드
+//			KakaoAnswerSq = SsgKakaoSender.KakaoAnswerSq.CardCancelBySoldout.value();
+//		} else if (payMeans.equals(TscConstants.PayMeans.ACCOUNT_TRANSFER.value())) { // 실시간계좌이체
+//			KakaoAnswerSq = SsgKakaoSender.KakaoAnswerSq.AtCancelBySoldout.value();
+//		} else if (payMeans.equals(TscConstants.PayMeans.BANK_DEPOSIT.value())) { // 무통장입금
+//			KakaoAnswerSq = SsgKakaoSender.KakaoAnswerSq.VaCancelBySoldout.value();
+//		}
+//
+//		kakaoSender.send(KakaoAnswerSq, dm, replaceInfo);
+//
+//		try {
+//			// 고객접촉이력 정보
+//			AdmCustomer customer = new AdmCustomer();
+//			customer.setContactType("304"); // 접촉유형 : 주문-품절안내(공통코드G054)
+//			customer.setContactMethod(TscConstants.ContactMethod.KAKAOTALK.value()); // 접촉방법 : 알림톡+문자(공통코드G055)
+//			customer.setContactContents("품절에의한 주문취소 안내");
+//			customer.setReceiverId(delivery.getCustNo());
+//			customerService.createCustomerContactHistory(customer);
+//		} catch (Exception e) {
+//			log.error("error", e);
+//			// Do nothing
+//		}
+//	}
+//
+//	/**
+//	 * 주문취소안내 알림톡
+//	 * @param customer - 고객 정보
+//	 * @author gagamel
+//	 * @since 2020. 11. 9
+//	 */
+//	@Transactional("shopTxnManager")
+//	public void sendOrderCancel(AdmCustomer customer, AdmOrder order) {
+//		SsgDirectMessage dm = new SsgDirectMessage();
+//		dm.setFdestine(customer.getCellPhnno());
+//		dm.setFkkoresendtype("LMS");
+//
+//		dm.setButtonNm("마이페이지 > 주문내역");
+//		dm.setButtonUrl("/mypage/order/list/form");
+//
+//		GagaMap replaceInfo = new GagaMap();
+//		replaceInfo.setString("siteNm", systemService.getSiteName(AdmConstants.SITE_CD));
+//		replaceInfo.setString("custNm", customer.getCustNm());
+//
+//		if (order.getPayMeans().equals(TscConstants.PayMeans.CREDIT_CARD.value())) { // 신용카드
+//			kakaoSender.send(SsgKakaoSender.KakaoAnswerSq.CardCancelRefund.value(), dm, replaceInfo);
+//		} else if (order.getPayMeans().equals(TscConstants.PayMeans.ACCOUNT_TRANSFER.value())) { // 실시간계좌이체
+//			kakaoSender.send(SsgKakaoSender.KakaoAnswerSq.AtCancelRefund.value(), dm, replaceInfo);
+//		} else if (order.getPayMeans().equals(TscConstants.PayMeans.BANK_DEPOSIT.value())) { // 무통장입금
+//			kakaoSender.send(SsgKakaoSender.KakaoAnswerSq.VaCancelRefund.value(), dm, replaceInfo);
+//		}
+//
+//		try {
+//			// 고객접촉이력 정보
+//			customer.setContactType("305"); // 접촉유형:주문안내(공통코드G054)
+//			customer.setContactMethod(TscConstants.ContactMethod.KAKAOTALK.value()); // 접촉방법:알림톡+문자(공통코드G055)
+//			customer.setContactContents("주문-취소안내");
+//			customer.setReceiverId(customer.getCustNo());
+//			customerService.createCustomerContactHistory(customer);
+//		} catch (Exception e) {
+//			log.error("error", e);
+//			// Do nothing
+//		}
+//	}
+//
+//	/**
+//	 * 기본 LMS 발송
+//	 * @param customer - LMS 정보
+//	 * @author gagamel
+//	 * @since 2020. 11. 9
+//	 */
+//	@Transactional("shopTxnManager")
+//	public void sendCustomerBasicLms(AdmCustomer customer) {
+//		SsgDirectMessage dm = new SsgDirectMessage();
+//		dm.setFdestine(customer.getCellPhnno());
+//
+//		GagaMap replaceInfo = new GagaMap();
+//		replaceInfo.setString("siteNm", customer.getSiteNm());
+//		replaceInfo.setString("custNm", customer.getCustNm());
+//		replaceInfo.setString("content", customer.getContent());
+//		replaceInfo.setString("callcenterTelNo", TscConstants.CALLCENTER_TEL_NO);
+//		kakaoSender.sendLms(SsgKakaoSender.KakaoAnswerSq.BasicLms.value(), dm, replaceInfo);
+//
+//		try {
+//			// 고객접촉이력 정보
+//			customer.setContactType("207"); // 접촉유형:회원-기본LMS안내발송
+//			customer.setContactMethod(TscConstants.ContactMethod.LMS.value()); // 접촉방법:LMS(공통코드G055)
+//			customer.setContactContents("기본LMS안내발송");
+//			customer.setReceiverId(customer.getCustNo());
+//			customerService.createCustomerContactHistory(customer);
+//		} catch (Exception e) {
+//			log.error("error", e);
+//			// Do nothing
+//		}
+//	}
+
+}

+ 111 - 0
src/main/java/com/style24/admin/biz/service/TsaLoginService.java

@@ -0,0 +1,111 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaLoginDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.User;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 운영관리 Service
+ *
+ * @author gagamel
+ * @since 2019. 12. 4
+ */
+@Service
+@Slf4j
+public class TsaLoginService {
+
+	@Autowired
+	private TsaLoginDao loginDao;
+
+	@Autowired
+	private Environment env;
+
+	/**
+	 * 사용자ID로 사용자 정보 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	public User getUserById(String userId) {
+		return loginDao.getUserById(userId);
+	}
+
+	/**
+	 * 로그인실패 남기기. 로그인실패여부가 "N:성공"이면 실패건수 0으로 초기화
+	 * @param userNo - 사용자번호
+	 * @param loginFailYn - 로그인실패여부(Y:실패, N:성공)
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	@Transactional("shopTxnManager")
+	public void createLoginFail(Integer userNo, String loginFailYn) {
+		User user = new User();
+		user.setUserNo(userNo);
+		user.setIpAddr(TsaSession.getIpAddress());
+		user.setLoginFailYn(loginFailYn);
+		loginDao.createLoginFail(user);
+	}
+
+	/**
+	 * 로그인 실패건수 조회
+	 * @param userNo - 사용자번호
+	 * @return 로그인 실패건수
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	public int getLoginFailCount(Integer userNo) {
+		User user = new User();
+		user.setUserNo(userNo);
+		user.setIpAddr(TsaSession.getIpAddress());
+		return loginDao.getLoginFailCount(user);
+	}
+
+	/**
+	 * 최종로그인일시 Update
+	 * @param userNo - 사용자번호
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	@Transactional("shopTxnManager")
+	public void updateLastLoginDate(Integer userNo) {
+		loginDao.updateLastLoginDate(userNo);
+	}
+
+	/**
+	 * 로그인이력 남기기
+	 * @param userNo - 사용자번호
+	 * @author gagamel
+	 * @date 2020. 10. 5
+	 */
+	@Transactional("shopTxnManager")
+	public void createLoginHistory(Integer userNo) {
+		User user = new User();
+		user.setUserNo(userNo);
+		user.setIpAddr(TsaSession.getIpAddress());
+
+		loginDao.createLoginHistory(user);
+	}
+
+	/**
+	 * 로그인 메뉴 목록
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	public Collection<Menu> getLoginMenuList(Integer userNo) {
+		return loginDao.getLoginMenuList(userNo);
+	}
+
+}

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

@@ -0,0 +1,91 @@
+package com.style24.admin.biz.service;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.excel.env.GagaExcelConstants;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.gagaframework.web.util.GagaStringUtil;
+import com.style24.admin.biz.dao.TsaGoodsDao;
+import com.style24.admin.biz.dao.TsaMarketingDao;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.biz.thirdparty.NaverLowestPriceApi;
+import com.style24.core.biz.thirdparty.SafetyKoreaApi;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.*;
+import io.netty.util.internal.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ *상품관리 Service
+ *
+ * @author xodud1202
+ * @since 2020. 12. 17
+ */
+@Service
+@Slf4j
+public class TsaMarketingService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaMarketingDao marketingDao;
+
+	@Autowired
+	private TsaBusinessService businessService;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaNoticeService noticeService;
+
+	@Autowired
+	private SafetyKoreaApi safetyKoreaApi;
+
+	@Autowired
+	private NaverLowestPriceApi naverLowestPriceApi;
+
+	@Autowired
+	private ObjectMapper mapper;
+
+	private static final String NUMBER_PATTERN = "^[0-9]+$";
+
+	private static final String SELF_GOOODS_AFTER = "STY";
+
+	/* xodud1202 진행 */
+
+	/**
+	 * 사은품 프로모션 리스트
+	 * @param param
+	 * @return
+	 * @author xodud1202
+	 * @since 2020. 12. 17
+	 */
+	public Collection<FreeGoodsPromotion> getFreeGoodsPromotionList(FreeGoodsPromotion param) {
+		return marketingDao.getFreeGoodsPromotionList(param);
+	}
+
+	/* // xodud1202 진행 */
+
+}

+ 363 - 0
src/main/java/com/style24/admin/biz/service/TsaMorebetterService.java

@@ -0,0 +1,363 @@
+package com.style24.admin.biz.service;
+
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.MoreBetter;
+import com.style24.persistence.domain.MoreBetterBurden;
+import com.style24.persistence.domain.MoreBetterGoods;
+import com.style24.persistence.domain.MoreBetterSection;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import com.style24.admin.biz.dao.TsaMorebetterDao;
+
+import java.util.Collection;
+
+/**
+ *마케팅>다다익선 Service
+ *
+ * @author bin2107
+ * @since 2021. 1. 12
+ */
+@Service
+@Slf4j
+public class TsaMorebetterService {
+    @Autowired
+    private TscMessageByLocale message;
+
+    @Autowired
+    private Environment env;
+
+    @Autowired
+    private TsaMorebetterDao morebetterDao;
+
+    @Autowired
+    private TsaCommonService commonService;
+
+    /* CSB 진행 */
+    /**
+     * 다다익선 리스트
+     * @param param
+     * @return
+     * @author bin2107
+     * @since 2020. 12. 28
+     */
+    public Collection<MoreBetter> getMorebetterList(MoreBetter param) {
+        return morebetterDao.getMorebetterList(param);
+    }
+
+    /**
+     * 다다익선 마스터 조회
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    public MoreBetter getMorebetterMstInfo(Integer tmtbSq){
+        return morebetterDao.getMorebetterMstInfo(tmtbSq);
+    }
+
+    /**
+     * 다다익선 구간 조회
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    public Collection<MoreBetterSection> getMorebetterSectionValList(Integer tmtbSq) {
+        return morebetterDao.getMorebetterSectionValList(tmtbSq);
+    }
+
+    /**
+     * 다다익선 구간 조회
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    public Collection<MoreBetterGoods> getMorebetterSupplyCompList(Integer tmtbSq, String targetGb) {
+        MoreBetterGoods merebetterGoods = new MoreBetterGoods();
+        merebetterGoods.setTmtbSq(tmtbSq);
+        merebetterGoods.setTargetGb(targetGb);
+        return morebetterDao.getMorebetterSupplyCompList(merebetterGoods);
+    }
+
+    public Collection<MoreBetterGoods> getMorebetterBrandList(Integer tmtbSq, String targetGb) {
+        MoreBetterGoods merebetterGoods = new MoreBetterGoods();
+        merebetterGoods.setTmtbSq(tmtbSq);
+        merebetterGoods.setTargetGb(targetGb);
+        return morebetterDao.getMorebetterBrandList(merebetterGoods);
+    }
+
+    public Collection<MoreBetterGoods> getMorebetterApplyGoodsList(Integer tmtbSq, String targetGb) {
+        MoreBetterGoods merebetterGoods = new MoreBetterGoods();
+        merebetterGoods.setTmtbSq(tmtbSq);
+        merebetterGoods.setTargetGb(targetGb);
+        return morebetterDao.getMorebetterApplyGoodsList(merebetterGoods);
+    }
+
+    public Collection<MoreBetterGoods> getMorebetterExceptGoodsList(Integer tmtbSq, String targetGb) {
+        MoreBetterGoods merebetterGoods = new MoreBetterGoods();
+        merebetterGoods.setTmtbSq(tmtbSq);
+        merebetterGoods.setTargetGb(targetGb);
+        return morebetterDao.getMorebetterExceptGoodsList(merebetterGoods);
+    }
+
+    /**
+     * 다다익선 구간 조회
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 8
+     */
+    public Collection<MoreBetterBurden> getMorebetterBurdenList(Integer tmtbSq) {
+        return morebetterDao.getMorebetterBurdenList(tmtbSq);
+    }
+
+    /**
+     * 다다익선 저장
+     * @param tmtb
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 5
+     */
+    @Transactional("shopTxnManager")
+    public void saveMoreBetterDetail(MoreBetter tmtb) {
+        // <,> replace 처리
+        tmtb.setRegNo(TsaSession.getInfo().getUserNo());
+        tmtb.setUdpNo(TsaSession.getInfo().getUserNo());
+
+        // TMTB 마스터(TB_TMTB) 저장
+        morebetterDao.saveMorebetterMst(tmtb);
+
+        // 다다익선 적용대상 설정
+        // 공급업체
+        Collection<MoreBetterGoods> supplyCompList = tmtb.getSupplyCompListNew();
+        for(MoreBetterGoods regSupplyComp : supplyCompList){
+            // 다다익선 적용대상 설정(TB_TMTB_GOODS) 저장
+            // tmtbGoodsSq 생성
+            log.info("regSupplyComp.getTmtbGoodsSq = {}",regSupplyComp.getTmtbGoodsSq());
+            if("".equals(regSupplyComp.getTmtbGoodsSq())){
+                Integer tmtbGoodsSq =  commonService.getNextSequence("SEQ_TMTB_GOODS");
+                regSupplyComp.setTmtbGoodsSq(tmtbGoodsSq);
+            }
+            regSupplyComp.setTmtbSq(tmtb.getTmtbSq());
+            regSupplyComp.setGoodsGb("G800_20");
+            regSupplyComp.setTargetVal(regSupplyComp.getSupplyCompCd());
+            regSupplyComp.setRegNo(tmtb.getRegNo());
+            regSupplyComp.setUdpNo(tmtb.getUdpNo());
+
+            morebetterDao.saveMorebetterGoods(regSupplyComp);
+        }
+
+        // 브랜드
+        Collection<MoreBetterGoods> brandList = tmtb.getBrandListNew();
+        for(MoreBetterGoods regBrand : brandList){
+            // 다다익선 적용대상 설정(TB_TMTB_GOODS) 저장
+            // tmtbGoodsSq 생성
+            log.info("regBrand.getTmtbGoodsSq = {}",regBrand.getTmtbGoodsSq());
+            if("".equals(regBrand.getTmtbGoodsSq())){
+                Integer tmtbGoodsSq =  commonService.getNextSequence("SEQ_TMTB_GOODS");
+                regBrand.setTmtbGoodsSq(tmtbGoodsSq);
+            }
+            regBrand.setTmtbSq(tmtb.getTmtbSq());
+            regBrand.setGoodsGb("G800_20");
+            regBrand.setTargetVal(regBrand.getBrandCd());
+            regBrand.setRegNo(tmtb.getRegNo());
+            regBrand.setUdpNo(tmtb.getUdpNo());
+
+            morebetterDao.saveMorebetterGoods(regBrand);
+        }
+
+        // 적용상품
+        Collection<MoreBetterGoods> applyGoodsList = tmtb.getApplyGoodsListNew();
+        for(MoreBetterGoods regApplyGoods : applyGoodsList){
+            // 다다익선 적용대상 설정(TB_TMTB_GOODS) 저장
+            // tmtbGoodsSq 생성
+            log.info("regApplyGoods.getTmtbGoodsSq = {}",regApplyGoods.getTmtbGoodsSq());
+            if("".equals(regApplyGoods.getTmtbGoodsSq())){
+                Integer tmtbGoodsSq =  commonService.getNextSequence("SEQ_TMTB_GOODS");
+                regApplyGoods.setTmtbGoodsSq(tmtbGoodsSq);
+            }
+            regApplyGoods.setTmtbSq(tmtb.getTmtbSq());
+            regApplyGoods.setTargetVal(regApplyGoods.getGoodsCd());
+            regApplyGoods.setRegNo(tmtb.getRegNo());
+            regApplyGoods.setUdpNo(tmtb.getUdpNo());
+
+            morebetterDao.saveMorebetterGoods(regApplyGoods);
+        }
+
+        // 제외상품
+        Collection<MoreBetterGoods> exceptGoodsList = tmtb.getExceptGoodsListNew();
+        for(MoreBetterGoods regExceptGoods : exceptGoodsList){
+            // 다다익선 적용대상 설정(TB_TMTB_GOODS) 저장
+            // tmtbGoodsSq 생성
+            log.info("regExceptGoods.getTmtbGoodsSq = {}",regExceptGoods.getTmtbGoodsSq());
+            if("".equals(regExceptGoods.getTmtbGoodsSq())){
+                Integer tmtbGoodsSq =  commonService.getNextSequence("SEQ_TMTB_GOODS");
+                regExceptGoods.setTmtbGoodsSq(tmtbGoodsSq);
+            }
+            regExceptGoods.setTmtbSq(tmtb.getTmtbSq());
+            regExceptGoods.setTargetVal(regExceptGoods.getGoodsCd());
+            regExceptGoods.setRegNo(tmtb.getRegNo());
+            regExceptGoods.setUdpNo(tmtb.getUdpNo());
+
+            morebetterDao.saveMorebetterGoods(regExceptGoods);
+        }
+
+        // 다다익선 할인구간 저장
+        Collection<MoreBetterSection> sectionGbList = tmtb.getSectionGbListNew();
+        for(MoreBetterSection regSection : sectionGbList){
+            log.info("regSection.getTmtbSectionSq = {}",regSection.getTmtbSectionSq());
+            log.info("regSection.getTmtbValSq = {}",regSection.getTmtbValSq());
+            // 다다익선 할인구간설정 2차조건(TB_TMTB_SECTION) 저장
+            // tmtbSectionSq 생성
+            if("".equals(regSection.getTmtbSectionSq()) || regSection.getTmtbSectionSq() == null){
+                Integer tmtbSectionSq =  commonService.getNextSequence("SEQ_TMTB_SECTION");
+                regSection.setTmtbSectionSq(tmtbSectionSq);
+            }
+            // 다다익선 조건에 따른 할인혜택(금액할인) 설정(TB_TMTB_VAL) 저장
+            // tmtbValSq 생성
+            if("".equals(regSection.getTmtbValSq()) || regSection.getTmtbValSq() == null){
+                Integer tmtbValSq =  commonService.getNextSequence("SEQ_TMTB_VAL");
+                regSection.setTmtbValSq(tmtbValSq);
+            }
+            regSection.setTmtbSq(tmtb.getTmtbSq());
+            regSection.setRegNo(tmtb.getRegNo());
+            regSection.setUdpNo(tmtb.getUdpNo());
+
+            morebetterDao.saveMorebetterSection(regSection);
+            morebetterDao.saveMorebetterVal(regSection);
+        }
+
+        // 다다익선 업체분담율(TB_TMTB_BURDEN) 저장
+        Collection<MoreBetterBurden> burdenList = tmtb.getBurdenListNew();
+        for (MoreBetterBurden regBurden : burdenList) {
+            // tmtbBurdenSq 생성
+            log.info("regBurden.getTmtbBurdenSq = {}",regBurden.getTmtbBurdenSq());
+            if("".equals(regBurden.getTmtbBurdenSq())){
+                Integer tmtbBurdenSq =  commonService.getNextSequence("SEQ_TMTB_BURDEN");
+                regBurden.setTmtbBurdenSq(tmtbBurdenSq);
+            }
+            regBurden.setTmtbSq(tmtb.getTmtbSq());
+            regBurden.setRegNo(tmtb.getRegNo());
+            regBurden.setUdpNo(tmtb.getUdpNo());
+
+            morebetterDao.saveMorebetterBurden(regBurden);
+        }
+
+        log.info("newBurdenSq = {}, newTmtbSq = {}, newSupplyCd = {}, newBurdenRate = {} , newUseYn = {}");
+    }
+
+    /**
+     * 다다익선 공급업체 삭제
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 5
+     */
+    @Transactional("shopTxnManager")
+    public void deleteTmtbSupplyCompanyList(MoreBetterGoods moreBetterGoods) {
+        if (moreBetterGoods == null || (moreBetterGoods.getArrCompanySq() == null && moreBetterGoods.getArrCompanySq().length <= 0)) {
+            throw new IllegalStateException(message.getMessage("FAIL_1001"));
+        }
+
+        if (moreBetterGoods.getArrCompanySq().length > 0) {
+            morebetterDao.deleteTmtbSupplyCompanyList(moreBetterGoods);
+        }
+    }
+
+    /**
+     * 다다익선 브랜드 삭제
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 16
+     */
+    @Transactional("shopTxnManager")
+    public void deleteTmtbBrandList(MoreBetterGoods moreBetterGoods) {
+        if (moreBetterGoods == null || (moreBetterGoods.getArrBrandSq() == null && moreBetterGoods.getArrBrandSq().length <= 0)) {
+            throw new IllegalStateException(message.getMessage("FAIL_1001"));
+        }
+
+        if (moreBetterGoods.getArrBrandSq().length > 0) {
+            morebetterDao.deleteTmtbBrandList(moreBetterGoods);
+        }
+    }
+
+    /**
+     * 다다익선 적용상품 삭제
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 16
+     */
+    @Transactional("shopTxnManager")
+    public void deleteTmtbApplyGoodsList(MoreBetterGoods moreBetterGoods) {
+        if (moreBetterGoods == null || (moreBetterGoods.getArrApplyGoodsSq() == null && moreBetterGoods.getArrApplyGoodsSq().length <= 0)) {
+            throw new IllegalStateException(message.getMessage("FAIL_1001"));
+        }
+
+        if (moreBetterGoods.getArrApplyGoodsSq().length > 0) {
+            morebetterDao.deleteTmtbApplyGoodsList(moreBetterGoods);
+        }
+    }
+
+    /**
+     * 다다익선 제외상품 삭제
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 16
+     */
+    @Transactional("shopTxnManager")
+    public void deleteTmtbExceptGoodsList(MoreBetterGoods moreBetterGoods) {
+        if (moreBetterGoods == null || (moreBetterGoods.getArrExceptGoodsSq() == null && moreBetterGoods.getArrExceptGoodsSq().length <= 0)) {
+            throw new IllegalStateException(message.getMessage("FAIL_1001"));
+        }
+
+        if (moreBetterGoods.getArrExceptGoodsSq().length > 0) {
+            morebetterDao.deleteTmtbExceptGoodsList(moreBetterGoods);
+        }
+    }
+
+    /**
+     * 다다익선 다다익선 할인구간 삭제
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 5
+     */
+    @Transactional("shopTxnManager")
+    public void deleteTmtbSectionValList(MoreBetterSection moreBetterSection) {
+        if (moreBetterSection == null || (moreBetterSection.getArrSectionSq() == null && moreBetterSection.getArrSectionSq().length <= 0)) {
+            throw new IllegalStateException(message.getMessage("FAIL_1001"));
+        }
+
+        if (moreBetterSection.getArrSectionSq().length > 0) {
+            morebetterDao.deleteTmtbSectionList(moreBetterSection);
+            morebetterDao.deleteTmtbValList(moreBetterSection);
+        }
+    }
+
+    /**
+     * 다다익선 제외상품 삭제
+     * @param
+     * @return
+     * @author bin2107
+     * @since 2021. 1. 16
+     */
+    @Transactional("shopTxnManager")
+    public void deleteTmtbBurdenList(MoreBetterBurden moreBetterBurden) {
+        if (moreBetterBurden == null || (moreBetterBurden.getArrBurdenSq() == null && moreBetterBurden.getArrBurdenSq().length <= 0)) {
+            throw new IllegalStateException(message.getMessage("FAIL_1001"));
+        }
+
+        if (moreBetterBurden.getArrBurdenSq().length > 0) {
+            morebetterDao.deleteTmtbBurdenList(moreBetterBurden);
+        }
+    }
+    /* // CSB 진행 */
+}

+ 153 - 0
src/main/java/com/style24/admin/biz/service/TsaNoticeService.java

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

+ 106 - 0
src/main/java/com/style24/admin/biz/service/TsaOcmService.java

@@ -0,0 +1,106 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaOcmDao;
+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;
+
+/**
+ * 영업망관리 Service
+ *
+ * @author gagamel
+ * @since 2020. 11. 4
+ */
+@Service
+@Slf4j
+public class TsaOcmService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaOcmDao ocmDao;
+
+	/**
+	 * 제휴몰 목록
+	 * @param extmall - 제휴몰 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	public Collection<Extmall> getExtmallList(Extmall extmall) {
+		return ocmDao.getExtmallList(extmall);
+	}
+
+	/**
+	 * 제휴몰 등록/수정 처리
+	 * @param extmall - 제휴몰 정보
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	@Transactional("shopTxnManager")
+	public void saveExtmall(Extmall extmall) {
+		extmall.setRegNo(TsaSession.getInfo().getUserNo());
+		extmall.setUpdNo(TsaSession.getInfo().getUserNo());
+		ocmDao.saveExtmall(extmall);
+	}
+
+	/**
+	 * 제휴몰 고시정보 목록
+	 * @param extmallNoti - 제휴몰고시정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 6
+	 */
+	public Collection<ExtmallNoti> getExtmallNotiinfoList(ExtmallNoti extmallNoti) {
+		return ocmDao.getExtmallNotiinfoList(extmallNoti);
+	}
+
+	/**
+	 * 제휴몰 원산지 목록
+	 * @param extmallOrigin - 제휴몰원산지 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 12
+	 */
+	public Collection<ExtmallOrigin> getExtmallOriginList(ExtmallOrigin extmallOrigin) {
+		return ocmDao.getExtmallOriginList(extmallOrigin);
+	}
+
+	/**
+	 * 제휴몰가격연계 목록
+	 * @param extmallPriceSync - 제휴몰가격연계 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	public Collection<ExtmallPriceSync> getExtmallPriceSyncList(ExtmallPriceSync extmallPriceSync) {
+		return ocmDao.getExtmallPriceSyncList(extmallPriceSync);
+	}
+
+	/**
+	 * 제휴몰가격연계 등록/수정
+	 * @param extmallPriceSyncList - 제휴몰가격연계 목록
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	public void saveExtmallPriceSync(Collection<ExtmallPriceSync> extmallPriceSyncList) {
+		for (ExtmallPriceSync extmallPriceSync : extmallPriceSyncList) {
+			extmallPriceSync.setRegNo(TsaSession.getInfo().getUserNo());
+			extmallPriceSync.setUpdNo(TsaSession.getInfo().getUserNo());
+			ocmDao.saveExtmallPriceSync(extmallPriceSync);
+		}
+	}
+
+}

+ 580 - 0
src/main/java/com/style24/admin/biz/service/TsaOrderChangeService.java

@@ -0,0 +1,580 @@
+package com.style24.admin.biz.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.web.parameter.GagaMap;
+import com.style24.admin.biz.dao.TsaOrderChangeDao;
+import com.style24.admin.biz.dao.TsaOrderDao;
+import com.style24.admin.biz.dao.TsaRefundDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.OrderChange;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 취소관리 Service
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@Service
+@Slf4j
+public class TsaOrderChangeService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaOrderDao orderDao;
+	
+	@Autowired
+	private TsaOrderChangeDao orderChangeDao;
+
+	@Autowired
+	private ObjectMapper mapper;
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문취소,반품,교환 대상목록
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public Collection<Order> getCancelRequestTargetList(Order order) {
+		return orderChangeDao.getCancelRequestTargetList(order);
+	}
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문취소, 반품 환불 금액 계산
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public GagaMap orderCancelRefundAmt(List<Order> cancelReqList) {
+		GagaMap mav = new GagaMap();
+		
+		// 1. 변수설정
+		int spanPayAmt				= 0; // 총 결제 금액
+		int spanSumRealOrdAmt		= 0; // 상품 실결제 금액
+		int spanSumDeliveryFee		= 0; // 배송금액
+		int spanRtnSumDeliveryFee 	= 0; // 반품배송금액
+		int spanExcSumDeliveryFee 	= 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; // 환불 금액 합계
+		
+		int sumDeliveryFee			= 0; // 배송금액 (전체 취소시에 배송금액도 같이 환불)
+		
+		List<Order> cancelOrderRefundList 	= new ArrayList<Order>();	// 주문환불금액목록
+		List<Order> cancelDelvRefundList 	= new ArrayList<Order>();	// 주문환불배송금액목록
+		
+		Order orderObj	= new Order();
+		Order delvObj	= new Order();
+		int k 			= 0 ;
+		
+		// 2. 초기 배송정보 설정
+		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.setRtnDelvFee(cancelReqList.get(k).getRtnDelvFee());
+		delvObj.setExcDelvFee(cancelReqList.get(k).getExcDelvFee());
+		delvObj.setSupplyCompCd(cancelReqList.get(k).getSupplyCompCd());
+		delvObj.setDelvFeeCd(cancelReqList.get(k).getDelvFeeCd());
+		delvObj.setAllCanYn(cancelReqList.get(k).getAllCanYn());
+		cancelDelvRefundList.add(delvObj);
+		
+		// 3. 취소신청수량 정보를 취소 환불 금액 계산
+		for (Order oneData : cancelReqList) {
+			orderObj	= new Order();
+			
+			// 3.1 주문기본정보 설정
+			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());
+			
+			// 3.2 주문취소수량으로 취소율 정보 설정
+			int ordQty 			= oneData.getOrdQty();
+			int itemQty 		= oneData.getItemQty();
+			int ordCanChgQty 	= oneData.getOrdCanChgQty();
+			
+			float _appQty		= (float)ordCanChgQty / (float)ordQty;
+			
+			// 3.3 주문취소금액 & 취소할인금액 계산
+			orderObj.setCnclRtnAmt(((oneData.getItemPrice() + oneData.getOptAddPrice()) * itemQty) * ordCanChgQty);
+			orderObj.setCpn1DcAmt((int)(oneData.getCpn1DcAmt() 				* _appQty));
+			orderObj.setTmtb1DcAmt((int)(oneData.getTmtb1DcAmt() 			* _appQty));
+			orderObj.setTmtb2DcAmt((int)(oneData.getTmtb2DcAmt() 			* _appQty));
+			orderObj.setGoodsCpnDcAmt((int)(oneData.getGoodsCpnDcAmt() 		* _appQty));
+			orderObj.setCartCpnDcAmt((int)(oneData.getCartCpnDcAmt() 		* _appQty));
+			orderObj.setPntDcAmt((int)(oneData.getPntDcAmt() 				* _appQty));
+			orderObj.setPrePntDcAmt((int)(oneData.getPrePntDcAmt() 			* _appQty));
+			orderObj.setSavePntAmt((int)(oneData.getSavePntAmt() 			* _appQty));
+			orderObj.setGfcdUseAmt((int)(oneData.getGfcdUseAmt() 			* _appQty));
+			
+			// 3.4 취소할인합계금액 적용
+			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();
+			
+			// 3.5 주문취소환불금액 계산
+			orderObj.setRealOrdAmt(orderObj.getCnclRtnAmt() - dcTotAmt);
+			
+			// 3.6 배송정보 관련 설정		
+			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.setRtnDelvFee(oneData.getRtnDelvFee());
+			orderObj.setExcDelvFee(oneData.getExcDelvFee());
+			
+			// 3.7 주문상세상태체크
+			orderObj.setOrdDtlStat(oneData.getOrdDtlStat());
+			orderObj.setOrdDtlStatNm(oneData.getOrdDtlStatNm());
+			orderObj.setAllCanYn(oneData.getAllCanYn()); // 전체취소 여부 (기존의 취소 또는 출고, 반품, 교환 의 경우에는 전체취소 불가능)
+			
+			cancelOrderRefundList.add(orderObj);
+			
+			// 3.8 배송업체 & 배송비정책 조건으로 추가 배송비 금액 설정
+			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.setRtnDelvFee(orderObj.getRtnDelvFee());
+				delvObj.setExcDelvFee(orderObj.getExcDelvFee());
+				delvObj.setSupplyCompCd(orderObj.getSupplyCompCd());
+				delvObj.setDelvFeeCd(orderObj.getDelvFeeCd());
+				delvObj.setAllCanYn(orderObj.getAllCanYn());
+				
+				cancelDelvRefundList.add(delvObj);
+			}
+			
+			// 3.9 FRONT 화면에서 사용 하는 변수 값 설정 & 계산
+			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();
+		}
+		
+		// 4. 추가배송비 발생여부, 추가배송비, 배송비정책단위 전체취소 여부 체크
+		for (int i=0 ; i<cancelDelvRefundList.size() ; i++) {
+			Order obj = cancelDelvRefundList.get(i);
+			
+			// 취소금액이 있을때 처리
+			if (obj.getCnclRtnAmt() > 0) {
+			
+				// 4.1 무료배송비용 > (주문금액 - 취소금액)
+				if (obj.getMinOrdAmt() > (obj.getOrdAmt() - obj.getCnclRtnAmt())) {
+					
+					// 4.2 주문시 배송비가 존재하면 추가 배송비 없음
+					if (obj.getDelvFee() > 0) {
+						obj.setAddDelvFeeYn("N");
+						obj.setAddDelvFee(0);
+						
+						// 4.2.1 전체취소시 배송비 환불
+						if ((obj.getOrdAmt() - obj.getCnclRtnAmt()) == 0) {
+							if ("Y".equals(obj.getAllCanYn())) {
+								sumDeliveryFee += obj.getDelvFee(); // 전체취소시 배송금액도 같이 환불
+							}
+						}
+					} else {
+						// 4.3 주문금액 - 취소금액 == 0 이면 전체취소 이므로 배송비 발생 안함
+						// * 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 {
+								// 4.4 전체취소의 경우에 해당
+								obj.setAddDelvFeeYn("N");
+								obj.setAddDelvFee(0);
+							}
+						} else {
+							// 4.5 추가배송비 발생 (취소신청화면에서 대부분 아래의 조건에 해당)
+							obj.setAddDelvFeeYn("Y");
+							obj.setAddDelvFee(obj.getOrgDelvFee());
+						}
+					}
+				} else {
+					obj.setAddDelvFeeYn("N");
+					obj.setAddDelvFee(0);
+				}
+			}
+				
+			spanSumDeliveryFee		+= obj.getDelvFee();
+			spanRtnSumDeliveryFee	+= obj.getRtnDelvFee();
+			spanExcSumDeliveryFee	+= obj.getExcDelvFee();
+			spanOrdAmt				+= obj.getOrdAmt();
+			spanCnclRtnAmt			+= obj.getCnclRtnAmt();
+			spanTotDeliveryFee  	+= obj.getAddDelvFee();
+			
+			cancelDelvRefundList.set(i, obj);
+		}
+		
+		// 5. FRONT 화면엣 필요한 금액 설정
+		// 2020.12.30 프론트에서 필요한 부분 작업 필여
+		// 관리자 화면에서 사용하는 환불 칼럼 정보
+		// 환불금액표시
+		spanPayAmt 			= spanSumRealOrdAmt + spanSumDeliveryFee;
+		spanTotPntDcAmt 	= spanPntDcAmt + spanPrePntDcAmt;
+		spanCpnDcAmt 		= spanCpn1DcAmt + spanGoodsCpnDcAmt + spanCartCpnDcAmt;
+		spanTmtbDcAmt 		= spanTmtb1DcAmt + spanTmtb2DcAmt;
+		spanRefundAmt 		= (spanRealCnclRtnAmt + sumDeliveryFee) - spanTotDeliveryFee;
+
+		mav.set("cancelReqList"			, cancelReqList);			//주문 취소 신청 목록
+		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("sumDeliveryFee"		, sumDeliveryFee);			//배송비 합계 금액
+		mav.set("spanTotDeliveryFee"	, spanTotDeliveryFee);		//추가 배송 금액
+		mav.set("spanTotRtnDelvFee"		, spanRtnSumDeliveryFee);	//추가 반품 배송 금액
+		mav.set("spanTotExcDelvFee"		, spanExcSumDeliveryFee);	//추가 교환 배송 금액
+		mav.set("spanRefundAmt"			, spanRefundAmt);			//환불 금액 합계
+		
+		return mav;
+	}
+	
+	/**
+	 * 주문상세 > 주문취소신청 > 주문취소
+	 * @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> cancelReqList		 	= (List<Order>) mav.get("cancelReqList");			//주문 취소 신청 목록
+		List<Order> cancelOrderRefundList 	= (List<Order>) mav.get("cancelOrderRefundList");	//주문 환불 금액 목록
+		List<Order> cancelDelvRefundList 	= (List<Order>) mav.get("cancelDelvRefundList");	//주문 환불 배송 금액 목록
+				
+		// 3. 취소신청정보
+		int ordNo 			= Integer.parseInt(mav.getString("ordNo").toString());
+		String chgReason 	= mav.getString("chgReason").toString();
+		String chgMemo 		= mav.getString("chgMemo").toString();
+		String allCanYn		= mav.getString("allCanYn").toString();
+		String isCustomer	= mav.getString("isCustomer").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);
+		
+		orderChangeDao.createOrderChange(orderChange);
+		
+		List<Order> cancelOrderDetailList = new ArrayList<Order>();
+		
+		// 4.2 주문변경 상세 단품 정보 등록 (단품단위)
+		for (int i=0 ; i<cancelOrderRefundList.size() ; i++) {
+			Order cancelOrderRefundPo = cancelOrderRefundList.get(i);
+			cancelOrderRefundPo.setRegNo(userNo);
+			cancelOrderRefundPo.setUpdNo(userNo);
+			
+			// 2020.01.05 추후 무통장입금전 전체 취소시 분기로직 추가 예정
+			if ("Y".equals(allCanYn)) {
+				cancelOrderRefundPo.setOrdDtlStat("G013_98"); // 결제전주문취소 : 공통코드로관리예정
+			} else {
+				cancelOrderRefundPo.setOrdDtlStat("G013_99"); // 결제후주문취소 : 공통코드로관리예정
+			}
+
+			// 4.2.1 취소수량이 존재하면 주문정보 수정 및 주문변경정보 등록
+			if (cancelOrderRefundPo.getOrdCanChgQty() > 0) {
+				// 4.2.3 주문상세단품정보 수정
+				orderChangeDao.updateOrderDetailItem(cancelOrderRefundPo);
+				
+				// 4.2.4 주문상세단품정보 이력 등록
+				orderChangeDao.createOrderDetailItemHst(cancelOrderRefundPo);
+				
+				// 4.3 주문변경 상세 단위로 데이타 등록 (ORD_DTL_NO)
+				Boolean temp = false;
+				
+				if (cancelOrderDetailList.size() > 0) {
+					for (int j=0 ; j<cancelOrderDetailList.size() ; j++) {
+						if (cancelOrderRefundPo.getOrdDtlNo() == cancelOrderDetailList.get(j).getOrdDtlNo()) {
+							temp = true;
+						}
+					}
+				}
+				
+				// 4.4 주문상세단위 데이타 저장
+				if (!temp) {
+					cancelOrderDetailList.add(cancelOrderRefundPo);
+				}
+				
+				// 4.5 상품옵션 재고 원복
+				orderChangeDao.updateOptionQty(cancelOrderRefundPo);
+			}
+		}
+		
+		// 5. 주문상세단위 취소 데이타 처리
+		for (int i=0 ; i<cancelOrderDetailList.size() ; i++) {			
+			Order vo = cancelOrderRefundList.get(i);
+			vo.setRegNo(userNo);
+			vo.setUpdNo(userNo);
+			
+			// 2020.01.05 추후 무통장입금전 전체 취소시 분기로직 추가 예정
+			if ("Y".equals(allCanYn)) {
+				vo.setOrdDtlStat("G013_98"); // 결제전주문취소 : 공통코드로관리예정
+			} else {
+				vo.setOrdDtlStat("G013_99"); // 결제후주문취소 : 공통코드로관리예정
+			}
+			
+			// 5.1 주문변경상세정보 이력 등록
+			orderChangeDao.createOrderDetailHstCnclRtn(vo);
+			
+			// 4.2 주문변경상세정보 수정
+			orderChangeDao.updateOrderDetail(vo);
+			
+			// * 주문상세단위가 아닌 주문상세단품단위로 데이타가 처리되고 있었음
+			// 5.3 주문변경상세정보 등록
+			OrderChange changeDetailPo = new OrderChange();
+			changeDetailPo.setOrdChgSq(orderChange.getOrdChgSq());
+			changeDetailPo.setOrdDtlNo(vo.getOrdDtlNo());
+			changeDetailPo.setChgQty(vo.getOrdCanChgQty());
+			changeDetailPo.setChgStat("G685_21"); // 취소완료 : 공통코드로관리예정
+			changeDetailPo.setRegNo(userNo);
+			changeDetailPo.setUpdNo(userNo);
+			
+			orderChangeDao.createOrderChangeDetail(changeDetailPo);
+		}
+		
+		// To Do List
+		// 취소, 반품 사유에 따른 추가배송비, 반품배송비를 환불금액에서 추가, 제외 할 수 있다.
+		int spanRealCnclRtnAmt 		= Integer.parseInt(mav.get("spanRealCnclRtnAmt").toString());		// 취소금액합계
+		int sumDeliveryFee 			= Integer.parseInt(mav.get("sumDeliveryFee").toString());			// 배송비합계
+		int spanTotDeliveryFee 		= Integer.parseInt(mav.get("spanTotDeliveryFee").toString());		// 추가배송비합계
+		int spanTotRtnDelvFee 		= Integer.parseInt(mav.get("spanTotRtnDelvFee").toString());		// 반품배송비합계
+		int spanRefundAmt			= 0;
+		
+		// 고객사유 : 환불금액계산 = (취소금액 + 배송비) - 추가배송비
+		if ("true".equals(isCustomer)) {
+			spanRefundAmt = (spanRealCnclRtnAmt + sumDeliveryFee) - spanTotDeliveryFee - spanTotRtnDelvFee;
+			//Integer.parseInt(mav.get("spanRefundAmt").toString());
+		}
+		// 회사사유 : 환불금액계산 = (취소금액 + 배송비)
+		else {
+			spanRefundAmt = (spanRealCnclRtnAmt + sumDeliveryFee);
+		}
+		mav.set("spanRefundAmt", spanRefundAmt);
+		
+		// 6. 환불결제 정보 등록
+		Order paymentOrder = new Order();
+		paymentOrder.setOrdNo(ordNo);
+		paymentOrder.setPayAmt(Integer.parseInt(mav.get("spanRefundAmt").toString()) * -1);
+		paymentOrder.setPayStat("G016_99");
+		paymentOrder.setOrdChgSq(orderChange.getOrdChgSq());
+		paymentOrder.setRegNo(userNo);
+		paymentOrder.setUpdNo(userNo);
+		
+		orderChangeDao.createPayment(paymentOrder);
+		
+		// 7. 환불금액 등록
+		Order refundOrder = new Order();
+		refundOrder.setOrdNo(ordNo);
+		refundOrder.setPaySq(paymentOrder.getPaySq());
+		refundOrder.setOrdChgSq(orderChange.getOrdChgSq());
+		refundOrder.setRegNo(userNo);
+		
+		refundOrder.setRefundAmt(Integer.parseInt(mav.get("spanRefundAmt").toString()));
+		refundOrder.setRfCpn1Amt(Integer.parseInt(mav.get("spanCpn1DcAmt").toString()));
+		refundOrder.setRfTmtb1Amt(Integer.parseInt(mav.get("spanTmtb1DcAmt").toString()));
+		refundOrder.setRfTmtb2Amt(Integer.parseInt(mav.get("spanTmtb2DcAmt").toString()));
+		refundOrder.setRfGoodsCpnAmt(Integer.parseInt(mav.get("spanGoodsCpnDcAmt").toString()));
+		refundOrder.setRfCartCpnAmt(Integer.parseInt(mav.get("spanCartCpnDcAmt").toString()));
+		refundOrder.setRfPntAmt(Integer.parseInt(mav.get("spanPntDcAmt").toString()));
+		refundOrder.setRfPrePntAmt(Integer.parseInt(mav.get("spanPrePntDcAmt").toString()));
+		refundOrder.setRfGfcdUseAmt(Integer.parseInt(mav.get("spanGfcdUseAmt").toString()));
+		
+		refundOrder.setRaNo(mav.get("accountNo").toString());
+		refundOrder.setRaNm(mav.get("accountNm").toString());
+		refundOrder.setRaBank(mav.get("bankCd").toString());
+		
+		orderChangeDao.createRefund(refundOrder);
+		
+		// 8. 결제금액이 무료배송금액보다 작으면 배송비 신규 등록
+		for (int i=0 ; i<cancelDelvRefundList.size() ; i++) {
+			Order vo = cancelDelvRefundList.get(i);
+			
+			if (vo.getAddDelvFee() > 0) {
+				Order delvFeeOrder = new Order();
+				
+				delvFeeOrder.setPaySq(paymentOrder.getPaySq());
+				delvFeeOrder.setOrdNo(ordNo);
+				delvFeeOrder.setDelvFeeGb("G018_10");
+				delvFeeOrder.setDelvFeeCd(vo.getDelvFeeCd());
+				delvFeeOrder.setDelvFee(vo.getAddDelvFee());
+				delvFeeOrder.setRealDelvAmt(vo.getDelvFee());
+				delvFeeOrder.setOrdChgSq(orderChange.getOrdChgSq());
+				delvFeeOrder.setSupplyCompCd(vo.getSupplyCompCd());
+				delvFeeOrder.setRegNo(userNo);
+				delvFeeOrder.setUpdNo(userNo);
+				
+				orderChangeDao.createDeliveryFee(delvFeeOrder);
+			}
+		}
+		
+		// To Do List
+		// 9. 포인트원복 (사용포인트, 주문상세단위)
+		
+		// To Do List
+		// 10. 쿠폰원복 (상품쿠폰, 주문상세단위) (전체취소시 장바구니쿠폰, 배송비쿠폰)
+		
+		// To Do List
+		// 11. 상품권원복
+		
+		// 12. 사은품 전체 취소 (전체취소시 적용) 추후 사은품 관련 취소 로직 개발 예정
+		Order freegiftOrder = new Order();
+		freegiftOrder.setOrdNo(ordNo);
+		freegiftOrder.setUpdNo(userNo);
+		orderChangeDao.updateOrdFreegiftDel(freegiftOrder);
+		
+		// To Do List
+		// 13. PG 연동
+		
+		// To Do List
+		// 14. 취소 완료 알림톡 발송 에정
+		
+		//int a = 100/0;
+	}
+	
+	
+	
+	
+	
+	
+	/**
+	 * 주문 환불계좌
+	 *
+	 * @param order - 주문정보
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2021. 01. 04.
+	 */
+	public Collection<Order> getRefundAccount(Order order) {
+		return orderChangeDao.getRefundAccount(order);
+	}
+	
+	/**
+	 * 환불계좌 저장
+	 *
+	 * @param order - 주문정보
+	 * @return TsaOrder
+	 * @author jsh77b
+	 * @since 2021. 01. 05.
+	 */
+	public int saveRefundAccount(Order order) {
+		
+		// 환불계좌 유무 체크 후 등록
+		if (orderChangeDao.getRefundAccountCheck(order) < 1) {
+			orderChangeDao.saveRefundAccount(order);
+		}
+		
+		return 1;
+	}
+	
+}

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

@@ -0,0 +1,542 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.excel.env.GagaExcelConstants;
+import com.gagaframework.excel.xssf.GagaExcelResultHandler;
+import com.style24.admin.biz.dao.TsaOrderDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Order;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 주문관리 Service
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@Service
+@Slf4j
+public class TsaOrderService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaOrderDao orderDao;
+
+	@Autowired
+	private ObjectMapper mapper;
+
+	/**
+	 * 주문목록 카운트
+	 * @param Order
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public int getOrderListCount(Order order) {
+		return orderDao.getOrderListCount(order);
+	}
+
+	/**
+	 * 주문목록
+	 * @param Order
+	 * @return
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderList(Order order) {
+		return orderDao.getOrderList(order);
+	}
+
+	/**
+	 * 주문기본정보
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderInfoList(Order order) {
+		return orderDao.getOrderInfoList(order);
+	}
+
+	/**
+	 * 주문상품정보 목록
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderDetailList(Order order) {
+		return orderDao.getOrderDetailList(order);
+	}
+
+	/**
+	 * 사은품목록
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderFreeGiftList(Order order) {
+		return orderDao.getOrderFreeGiftList(order);
+	}
+
+	/**
+	 * 배송정보
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getDeliveryAddrList(Order order) {
+		return orderDao.getDeliveryAddrList(order);
+	}
+
+	/**
+	 * 결제정보
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderPaymentBasicInfoList(Order order) {
+		return orderDao.getOrderPaymentBasicInfoList(order);
+	}
+
+	/**
+	 * 배송비정보
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getDeliveryFeeList(Order order) {
+		return orderDao.getDeliveryFeeList(order);
+	}
+
+	/**
+	 * 취소/반품/교환 요청 정보
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderChangeList(Order order) {
+		return orderDao.getOrderChangeList(order);
+	}
+
+	/**
+	 * 환불정보
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderRefundInfo(Order order) {
+		return orderDao.getOrderRefundInfo(order);
+	}
+
+	/**
+	 * 상담내역
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderCounselInfo(Order order) {
+		return orderDao.getOrderCounselInfo(order);
+	}
+
+	/**
+	 * 주문요청 관리자 메모 목록 조회
+	 *
+	 * @param order - 주문 정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 18
+	 */
+	public Collection<Order> getOrderMemoList(Order order) {
+		order.setDelYn("N");
+		return orderDao.getOrderMemoList(order);
+	}
+
+	/**
+	 * 입점업체미발주 주문목록
+	 * @param Order
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	public Collection<Order> getOrderSellerUnorderList(Order order) {
+		return orderDao.getOrderSellerUnorderList(order);
+	}
+
+	/**
+	 * 입점업체미발주목록 - 엑셀다운로드시 주문상태값 변경(상품준비중)
+	 *
+	 * @param orderList - 주문 정보
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	@Transactional("shopTxnManager")
+	public void saveUnorderStatus(Collection<Order> orderList) {
+
+		// 1. 임시테이블 삭제
+		Order deleteOrder = new Order();
+		deleteOrder.setRegNo(TsaSession.getInfo().getUserNo());
+		orderDao.deleteEntryExcelDownTmp(deleteOrder);
+
+		for (Order oneData : orderList) {
+
+			Order updateData = new Order();
+
+			updateData.setOrdNo(oneData.getOrdNo());
+			updateData.setOrdDtlNo(oneData.getOrdDtlNo());
+			updateData.setBrandCd(oneData.getBrandCd());
+			updateData.setSupplyCompCd(oneData.getSupplyCompCd());
+			updateData.setRegNo(TsaSession.getInfo().getUserNo());
+			updateData.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			// 2. 주문상세상태값 변경
+			// 2.1 2020.12.15 주문상태체크추가 (결제완료 상태만 상품준비중 변경)
+			int result = orderDao.updateOrderDetailStat(updateData);
+
+			if (result > 0) {
+				// 3. 주문상세상태 변경 이력생성
+				orderDao.createOrderDetailHst(updateData);
+			}
+
+			// 4. 엑셀 다운로드용 임시테이블 데이타 체크
+			result = orderDao.getEntryUploadExcelCheck(updateData);
+			if (result < 1) {
+
+				// 5. 엑셀 다운로드용 임시테이블 저장
+				orderDao.createEntryExcelDownTmp(updateData);
+			}
+		}
+	}
+
+	/**
+	 * 입점업체미발주목록 엑셀다운로드
+	 *
+	 * @param order - 주문정보
+	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	public void geSellerUnorderExcelList(Order order, String excelFilenameWithPath) {
+
+		// 헤더 title 설정 (23)
+		String[] listTitles = {
+				"입점업체"
+				, "브랜드"
+				, "상품타입"
+				, "상품코드"
+				, "상품명"
+				, "주문번호"
+				, "주문상세번호"
+				, "주문상세상태"
+				, "주문자명"
+				, "주문일시"
+				, "결제수단"
+				, "주문자휴대전화"
+				, "수령자명"
+				, "수령자휴대전화"
+				, "수령자우편번호"
+				, "수령자기본주소"
+				, "수령자상세주소"
+				, "업체상품코드"
+				, "단품코드"
+				, "단품상품명"
+				, "칼라"
+				, "사이즈"
+				, "주문수량"
+				, "주문금액"
+				, "할인금액"
+				, "실결제금액"
+				, "송장"
+		};
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정 (23)
+		String[] cellNames = {
+				"supplyCompNm"
+				, "brandKnm"
+				, "goodsTypeNm"
+				, "goodsCd"
+				, "goodsNm"
+				, "ordNo"
+				, "ordDtlNo"
+				, "ordDtlStatNm"
+				, "ordNm"
+				, "ordDt"
+				, "payMeansNm"
+				, "ordPhnno"
+				, "recipNm"
+				, "recipPhnno"
+				, "recipZipNo"
+				, "recipBaseAddr"
+				, "recipDtlAddr"
+				, "supplyGoodsCd"
+				, "itemCd"
+				, "itemNm"
+				, "optCd1"
+				, "optCd2"
+				, "itemOrdQty"
+				, "ordAmt"
+				, "totDcAmt"
+				, "realOrdAmt"
+				, "invoiceNo"
+		};
+
+		String[] cellTypes = {
+				GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+				, GagaExcelConstants.CellType.CHAR_CENTER.name()
+		};
+
+		GagaExcelResultHandler<Order> handler = new GagaExcelResultHandler<>(excelFilenameWithPath, "출고배송목록(입점)", listTitles, cellNames, cellTypes);
+
+		orderDao.getSellerUnorderList(order, handler);
+
+		handler.close();
+	}
+
+	/**
+	 * 입점업체미발주목록 - 송장번호 입력(출고완료)
+	 *
+	 * @param orderList - 주문 정보
+	 * @return String - 결과메시지
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	@Transactional("shopTxnManager")
+	public String saveUnorderInvoice(Collection<Order> orderList) {
+		String resultMsg;
+		int totalCount 			= 0;	// 전체 카운트
+		int failedCount 		= 0;	// 몰 실패 카운트
+		int successCount 		= 0;	// 몰 성공 카운트
+		String failedGoodCdStr 	= "";	// 실패 상품 리스트
+
+		// 1. 송장번호 등록 대상 목록 처리
+		for (Order oneData : orderList) {
+
+			// 2. 송장번호, 업체코드 체크
+			if (!StringUtils.isEmpty(oneData.getInvoiceNo()) && !StringUtils.isEmpty(oneData.getShipCompCd())) {
+				totalCount++;
+
+				Order updateData = new Order();
+				updateData.setOrdNo(oneData.getOrdNo());
+				updateData.setOrdDtlNo(oneData.getOrdDtlNo());
+				updateData.setBrandCd(oneData.getBrandCd());
+				updateData.setSupplyCompCd(oneData.getSupplyCompCd());
+				updateData.setRegNo(TsaSession.getInfo().getUserNo());
+				updateData.setUpdNo(TsaSession.getInfo().getUserNo());
+				updateData.setItemCd(oneData.getItemCd());
+				updateData.setOptCd2(oneData.getOptCd2());
+				updateData.setShipCompCd(oneData.getShipCompCd());
+				updateData.setInvoiceNo(oneData.getInvoiceNo().replace("-", ""));
+
+				// 3. 원주문 상세정보 조회
+				// 2020.12.15 세트상품의 경우에는 2개 이상의 row 가 표시됨 (주문상세번호 + 상풐코드로 + 사이즈코드) 변경
+				Order orgOrder = orderDao.getOrderDetailInfo(oneData);
+				if (orgOrder == null) {
+					failedGoodCdStr += updateData.getItemCd() + " /  " + updateData.getOptCd2() + "(Error1)<br/>"; // 상품정보 (상품명 + 칼라명) / 사이즈코드
+					failedCount++;
+					continue;
+				}
+
+				// 4. 상품코드, 사이즈, 주문수량 체크 (세트상품도 단품 단위로 업로드 요청)
+				// 2020.12.15 세트상품 때문에 단품단위로 비교
+				if (!orgOrder.getItemCd().equals(updateData.getItemCd())
+						|| !orgOrder.getOptCd2().equals(updateData.getOptCd2()) ) {
+					failedGoodCdStr += updateData.getItemCd() + " /  " + updateData.getOptCd2() + "(Error2)<br/>";
+					failedCount++;
+					continue;
+				}
+
+				// 5. 업체코드설정
+				updateData.setSupplyCompCd(orgOrder.getSupplyCompCd());
+
+				// 6. 송장번호등록
+				int result = orderDao.updateOrderDetailInvoice(updateData);
+
+				// 7. 주문상세상태 변경 이력 등록
+				if (result > 0) {
+					successCount++;
+					orderDao.createOrderDetailHst(updateData);
+				} else {
+					failedGoodCdStr += updateData.getItemCd() + " /  " + updateData.getOptCd2() + "(Error3)<br/>";
+					failedCount++;
+				}
+			}
+		}
+
+		resultMsg = "출고완료 : " + totalCount + "건 / 실패 : " + failedCount + "건 / 성공 : " + successCount + "건 <br/>" + "실패 목록 : " + failedGoodCdStr;
+
+		return resultMsg;
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모정보조회
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public Order getOrderMemoInfo(Order order) {
+		return orderDao.getOrderMemoInfo(order);
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모등록
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public void createOrderMemo(Order order) {
+		orderDao.createOrderMemo(order);
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모수정
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public void updateOrderMemo(Order order) {
+		orderDao.updateOrderMemo(order);
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모삭제
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public void deleteOrderMemo(Order order) {
+		orderDao.deleteOrderMemo(order);
+	}
+
+	/**
+	 * 주문상품 상세 변경 이력 화면
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public Collection<Order> getOrderDetailHistoryList(Order order) {
+		return orderDao.getOrderDetailHistoryList(order);
+	}
+
+	/**
+	 * 쿠폰사용 내역 팝업 화면
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public Collection<Order> getOrderDiscountCouponList(Order order) {
+		return orderDao.getOrderDiscountCouponList(order);
+	}
+
+	/**
+	 * 포인트사용 내역 팝업 화면
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public Collection<Order> getOrderDiscountPointList(Order order) {
+		return orderDao.getOrderDiscountPointList(order);
+	}
+
+	/**
+	 * 상품권사용 내역 팝업 화면
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public Collection<Order> getOrderGiftcardHstList(Order order) {
+		return orderDao.getOrderGiftcardHstList(order);
+	}
+
+	/**
+	 * 다다익선적용 내역 팝업 화면
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public Collection<Order> getOrderTmtbHstList(Order order) {
+		return orderDao.getOrderTmtbHstList(order);
+	}
+
+	/**
+	 * 주문상세상태를 변경
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	public void changedOrdDtlStat(Order order) {
+		// 1. 주문상세상태변경
+		int resultInt = orderDao.changedOrdDtlStat(order);
+
+		// 2. 주문상세상태변경 성공 후 주문상세 이력을 등록
+		if (resultInt > 0) {
+			orderDao.createOrderDetailHst(order);
+		}
+	}
+
+}

+ 48 - 0
src/main/java/com/style24/admin/biz/service/TsaPgService.java

@@ -0,0 +1,48 @@
+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;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+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;
+
+/**
+ * PG 연동 Service
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@Service
+@Slf4j
+public class TsaPgService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaOrderDao orderDao;
+
+	@Autowired
+	private ObjectMapper mapper;
+	
+}

+ 120 - 0
src/main/java/com/style24/admin/biz/service/TsaPosService.java

@@ -0,0 +1,120 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.excel.env.GagaExcelConstants;
+import com.gagaframework.web.parameter.GagaMap;
+
+import com.style24.admin.biz.dao.TsaPosDao;
+import com.style24.persistence.domain.Pos;
+
+/**
+ * 매장POS Service
+ * 
+ * @author moon
+ * @since 2020. 11. 13
+ */
+@Service
+@Slf4j
+public class TsaPosService {
+
+	@Autowired
+	private TsaPosDao posDao;
+
+	/**
+	 * 매장로그인 정보 조회
+	 * 
+	 * @param pos - 매장정보
+	 * @return Pos
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	public Pos getStoreLoginInfo(Pos pos) {
+		return posDao.getStoreLoginInfo(pos);
+	}
+
+	/**
+	 * 출고대기/출고목록
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	public Collection<Pos> getPosDeliveryList(Pos pos) {
+		return posDao.getPosDeliveryList(pos);
+	}
+
+	/**
+	 * 정산내역
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	public Collection<Pos> getPosUsacList(Pos pos) {
+		return posDao.getPosUsacList(pos);
+	}
+
+	/**
+	 * CNPlus 엑셀다운로드
+	 * 
+	 * @param pos - 매장정보
+	 * @return Pos
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	public void getOrderExcelList(Pos pos, String excelFilenameWithPath) {
+
+		// 헤더 title 설정
+
+		String[] listTitles = {"예약구분", "집하예정일", "받는분성명"  //3
+			, "받는분전화번호", "받는분기타연락처", "받는분우편번호" //3
+			, "받는분주소(전체, 분할)", "운송장번호", "고객주문번호" //3
+			, "품목명", "박스수량", "박스타입", "기본운임"  //4
+			, "배송메세지1", "배송메세지2", "품목명"};  //3
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellNames = {"RSRVT_GB", "SCHDL_CLDT", "RECIP_NM"  //3
+			, "RECIP_PHNNO", "RECIP_TELNO", "RECIP_POST_NO" //3
+			, "RECIP_ADDR", "INVOICE_NO", "ORD_NO"  //3
+			, "GOODS_NM", "BOX_QTY", "BOX_TYPE", "FEE" //4
+			, "DELV_MEMO", "DELV_MEMO2", "GOODS_CD"}; //3
+
+		String[] cellTypes = {GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name()
+		};
+		Collection<GagaMap> dataList = posDao.getOrderExcelList(pos); // map형식으로 조회
+		try {
+			GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, cellNames, cellTypes);
+
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+	
+	public GagaMap getChkShopRt(Pos tsaPos) {
+		GagaMap result = new GagaMap();
+		int cnt = posDao.getShopRtCheck(tsaPos);
+		if(cnt > 0) {
+			result.set("chk", "Y");
+		} else {
+			result.set("chk", "N");
+		}
+		return result;
+	}
+
+}

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

@@ -0,0 +1,534 @@
+package com.style24.admin.biz.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.style24.admin.biz.dao.TsaRendererDao;
+import com.style24.persistence.domain.Brand;
+import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.DeliveryLoc;
+import com.style24.persistence.domain.Itemkind;
+import com.style24.persistence.domain.SupplyCompany;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 콤보박스, 체크박스, 라디오버튼 구성 시 필요한 Renderer Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@Service
+@Slf4j
+public class TsaRendererService {
+
+	@Autowired
+	private TsaRendererDao rendererDao;
+
+	/**
+	 * 연도 목록
+	 * @param startYear - 시작연도
+	 * @param startOffset - Start offset. 시작연도
+	 * @param endOffset - End offset. 종료연도
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 22.
+	 */
+	public Collection<CommonCode> getYearList(int startYear, int startOffset, int endOffset) {
+		Collection<CommonCode> yearList = new ArrayList<>();
+
+		int start = startYear + startOffset;
+		int end = startYear + endOffset;
+
+		for (int year = start; year <= end; year++) {
+			CommonCode commonCode = new CommonCode();
+
+			commonCode.setCd(String.valueOf(year));
+			commonCode.setCdNm(String.valueOf(year));
+
+			yearList.add(commonCode);
+		}
+
+		return yearList;
+	}
+
+	/**
+	 * 공급업체 목록
+	 * @param supplyCompany - 공급업체 정보
+	 * @return 공급업체 목록
+	 * @author Daehyoung
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getSupplyCompanyList(SupplyCompany supplyCompany) {
+		return rendererDao.getSupplyCompanyList(supplyCompany);
+	}
+
+	/**
+	 * 공급업체 목록
+	 * @return 공급업체 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getSupplyCompanyList() {
+		return this.getSupplyCompanyList(new SupplyCompany());
+	}
+
+	/**
+	 * 공급업체 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return 공급업체 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getSupplyCompanyList(String supplyCompCd) {
+		SupplyCompany supplyCompany = new SupplyCompany();
+		supplyCompany.setSupplyCompCd(supplyCompCd);
+		return this.getSupplyCompanyList(supplyCompany);
+	}
+
+	/**
+	 * 공급업체 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @param selfYn - 자사여부
+	 * @return 공급업체 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getSupplyCompanyList(String supplyCompCd, String selfYn) {
+		SupplyCompany supplyCompany = new SupplyCompany();
+		supplyCompany.setSupplyCompCd(supplyCompCd);
+		supplyCompany.setSelfYn(selfYn);
+		return this.getSupplyCompanyList(supplyCompany);
+	}
+
+	/**
+	 * 자사공급업체 목록
+	 * @return 자사공급업체 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getSelfSupplyCompanyList() {
+		SupplyCompany supplyCompany = new SupplyCompany();
+		supplyCompany.setSelfYn("Y");
+		return this.getSupplyCompanyList(supplyCompany);
+	}
+
+	/**
+	 * 입점공급업체 목록
+	 * @return 입점공급업체 목록
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	public Collection<CommonCode> getEntrSupplyCompanyList() {
+		SupplyCompany supplyCompany = new SupplyCompany();
+		supplyCompany.setSelfYn("N");
+		return this.getSupplyCompanyList(supplyCompany);
+	}
+
+	/**
+	 * 공통코드 목록 - 어드민 공통코드 캐시 미적용 - 상품등록시 시즌년도 캐쉬로 인한 정보 오류로 수정 2020.06.02
+	 * @param commoncode - 공통코드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+//	@Cacheable(value = "common", key = "'commoncode-'.concat(#commoncode.cdGb)")
+	public Collection<CommonCode> getCommonCodeList(CommonCode commoncode) {
+		return rendererDao.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @param cdGb - 코드구분
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList(String cdGb) {
+		CommonCode commoncode = new CommonCode();
+		commoncode.setCdGb(cdGb);
+		return this.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @param grpCodeId - 코드구분
+	 * @param useYn     - 사용여부
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList(String cdGb, String useYn) {
+		CommonCode commoncode = new CommonCode();
+		commoncode.setCdGb(cdGb);
+		commoncode.setUseYn(useYn);
+		return this.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 현재 유효한 공통코드 목록
+	 * @param cdGb - 코드구분
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getAvailCommonCodeList(String cdGb) {
+		return this.getCommonCodeList(cdGb, "Y");
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @param cdGb   -코드구분
+	 * @param useYn  - 사용여부
+	 * @param cdDesc - 코드설명
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList(String cdGb, String useYn, String cdDesc) {
+		CommonCode commoncode = new CommonCode();
+		commoncode.setCdGb(cdGb);
+		commoncode.setUseYn(useYn);
+		commoncode.setCdDesc(cdDesc);
+		return this.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @param cdGb      -코드구분
+	 * @param useYn     - 사용여부
+	 * @param exceptCds - 제외코드배열
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList(String cdGb, String useYn, String[] exceptCds) {
+		CommonCode commoncode = new CommonCode();
+		commoncode.setCdGb(cdGb);
+		commoncode.setUseYn(useYn);
+		commoncode.setExceptCds(exceptCds);
+		return this.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 최상위메뉴 목록
+	 * @param menuId - 메뉴ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getTopMenuList(String menuId) {
+		return rendererDao.getTopMenuList(menuId);
+	}
+
+	/**
+	 * 전체 메뉴 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getAllMenuList() {
+		return rendererDao.getAllMenuList();
+	}
+
+//	/**
+//	 * 벤더외부몰 목록
+//	 * @param vendorId - 벤더ID
+//	 * @return 벤더외부몰 목록
+//	 * @author gagamel
+//	 * @since 2019. 8. 11
+//	 */
+//	public Collection<CommonCode> getVendorExtmallList(String vendorId) {
+//		return rendererDao.getVendorExtmallList(vendorId);
+//	}
+//
+//	/**
+//	 * 벤더외부몰판매매장 목록
+//	 * @param vendorId - 벤더ID
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 4. 28
+//	 */
+//	public Collection<CommonCode> getVendorExtmallSellStoreList(String vendorId) {
+//		return rendererDao.getVendorExtmallSellStoreList(vendorId);
+//	}
+//
+//	//
+//	//	/**
+//	//	 * 유효한 브랜드 목록
+//	//	 * @param
+//	//	 * @return
+//	//	 * @author qkwlstktma
+//	//	 * @since 2019. 8. 25
+//	//	 */
+//	//	public Collection<CommonCode> getAvailableBrandList() {
+//	//		AdmBrand brand = new AdmBrand();
+//	//		brand.setUseYn("Y");
+//	//		return rendererDao.getBrandList(brand);
+//	//	}
+//	//
+	/**
+	 * 공급업체 브랜드 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return
+	 * @author gagamel
+	 * @since 2019. 10. 20
+	 */
+	public Collection<CommonCode> getSupplyCompanyBrandList(String supplyCompCd) {
+		Brand brand = new Brand();
+		brand.setSupplyCompCd(supplyCompCd);
+		return rendererDao.getBrandList(brand);
+	}
+
+//
+//	/**
+//	 * 브랜드그룹별 브랜드 목록
+//	 * @param brandGrpNm - 브랜드그룹명
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 1. 10
+//	 */
+//	public Collection<CommonCode> getGroupBrandList(String brandGrpNm) {
+//		AdmBrand brand = new AdmBrand();
+//		brand.setBrandGrpNm(brandGrpNm);
+//		return rendererDao.getBrandList(brand);
+//	}
+//
+	/**
+	 * 권한별 브랜드 목록
+	 * @param adminId - 사용자ID
+	 * @return
+	 * @author eskim
+	 * @since 2019. 6. 17
+	 */
+	public Collection<CommonCode> getAuthBrandList(int userNo) {
+		return rendererDao.getAuthBrandList(userNo);
+	}
+
+	/**
+	 * 출고처 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return 출고처 목록
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	public Collection<CommonCode> getDeliveryLocList(DeliveryLoc delvLoc) {
+		return rendererDao.getDeliveryLocList(delvLoc);
+	}
+
+//	/**
+//	 * 출고처 목록
+//	 * @return 출고처 목록
+//	 * @author gagamel
+//	 * @since 2019. 12. 12
+//	 */
+//	public Collection<CommonCode> getDeliveryLocList() {
+//		AdmDeliveryLoc params = new AdmDeliveryLoc();
+//		return this.getDeliveryLocList(params);
+//	}
+
+	/**
+	 * 출고처 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return 출고처 목록
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	public Collection<CommonCode> getDeliveryLocList(String supplyCompCd) {
+		DeliveryLoc delvLoc = new DeliveryLoc();
+		delvLoc.setSupplyCompCd(supplyCompCd);
+		return this.getDeliveryLocList(delvLoc);
+	}
+
+	/**
+	 * 배송비정책 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return 배송비정책 목록
+	 * @author eskim
+	 * @since 2020. 11. 24
+	 */
+	public Collection<CommonCode> getSupplyDeliveryFeePolicyList(String supplyCompCd) {
+		return rendererDao.getSupplyDeliveryFeePolicyList(supplyCompCd);
+	}
+
+//	/**
+//	 * 직송매장 목록
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 5. 4
+//	 */
+//	public Collection<CommonCode> getDirectStoreList() {
+//		AdmDeliveryLoc params = new AdmDeliveryLoc();
+//		params.setDelvLocClsf("21"); // 직송매장
+//		return this.getDeliveryLocList(params);
+//	}
+//
+//	//	/**
+//	//	 * 정보고시 목록
+//	//	 * @param goodsCd - 상품코드
+//	//	 * @return
+//	//	 * @author jaewonHo
+//	//	 * @param supplyCompCd
+//	//	 * @since 2019. 10. 24
+//	//	 */
+//	//	public Collection<CommonCode> getCateInfoList(String goodsCd) {
+//	//		return rendererDao.getCateInfoList(goodsCd);
+//	//	}
+//
+	/**
+	 * 품목 목록
+	 * @return 품목 목록
+	 * @author eskim
+	 * @since 2020. 10. 19
+	 */
+	public Collection<CommonCode> getAllItemkindList() {
+		Itemkind itemkind = new Itemkind();
+		return this.getItemkindList(itemkind);
+	}
+
+	/**
+	 * 품목 목록
+	 * @param itemkind - 품목 정보
+	 * @return 품목 목록
+	 * @author eskim
+	 * @since 2020. 10. 19
+	 */
+	public Collection<CommonCode> getItemkindList(Itemkind itemkind) {
+		return rendererDao.getItemkindList(itemkind);
+	}
+
+//	/**
+//	 * 브랜드그룹 목록
+//	 * @return 브랜드그룹 목록
+//	 * @author eskim
+//	 * @since 2019. 12. 10
+//	 */
+//	public Collection<CommonCode> getBrandGroupList() {
+//		return rendererDao.getBrandGroupList();
+//	}
+//
+	/**
+	 * 컬러 목록
+	 * @param color - 색상 정보
+	 * @return 컬러 목록
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	public Collection<CommonCode> getColorList(Color color) {
+		return rendererDao.getColorList(color);
+	}
+
+//
+//	/**
+//	 * 사용중 대카테고리 목록
+//	 * @param cateGb - 카테고리구분
+//	 * @return 대카테고리 목록
+//	 * @author sasa004
+//	 * @since 2020. 01. 02
+//	 */
+//	public Collection<CommonCode> getTCategoryList(String cateGb) {
+//		return rendererDao.getTCategoryList(cateGb);
+//	}
+//
+	/**
+	 * 브랜드에 등록된 MD 목록
+	 * @return MD 목록
+	 * @author eskim
+	 * @since 2020. 10. 19
+	 */
+	public Collection<CommonCode> getBrandMdList() {
+		return rendererDao.getBrandMdList();
+	}
+
+	/**
+	 * 택배사명 목록 조회
+	 * @return CommonCode
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	public Collection<CommonCode> getShipCompanyList() {
+		return rendererDao.getShipCompanyList();
+	}
+//
+//	/**
+//	 * MD 별 브랜드 목록 조회
+//	 * @param mdId - 담당MD아이디
+//	 * @return CommonCode
+//	 * @author jaewonHo
+//	 * @since 2020. 02. 11
+//	 */
+//	public Collection<CommonCode> getMdBrandList(String mdId) {
+//		return rendererDao.getMdBrandList(mdId);
+//	}
+//
+//	/**
+//	 * MD 별 브랜드 목록 조회
+//	 * @param mdId - 담당MD아이디
+//	 * @return CommonCode
+//	 * @author jaewonHo
+//	 * @since 2020. 02. 11
+//	 */
+//	public Collection<CommonCode> getMdBrandGrpList(String mdId) {
+//		return rendererDao.getMdBrandGrpList(mdId);
+//	}
+//
+//	/**
+//	 * 인스타그램 계정리스트 조회
+//	 * @return
+//	 * @since : 2020. 3. 18.
+//	 * @authur 이명철
+//	 */
+//	public Collection<CommonCode> getInstaAccount() {
+//		return rendererDao.getInstaAccount();
+//	}
+//
+//	/**
+//	 * 판매몰조회
+//	 * @param
+//	 * @return CommonCode
+//	 * @author swkim
+//	 * @since 2020. 03. 19
+//	 */
+//	public Collection<CommonCode> getSellStoreList() {
+//		return rendererDao.getSellStoreList();
+//	}
+
+	/**
+	 * 문의용 답변문구 목록
+	 * @param ansClsf - 답변종류
+	 * @return CommonCode
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	public Collection<CommonCode> getQnaAnswerPhaseList(String ansClsf) {
+		return rendererDao.getQnaAnswerPhaseList(ansClsf);
+	}
+
+//	/**
+//	 * 제휴링크 목록
+//	 * @param afChannel - 제휴채널
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 5. 4
+//	 */
+//	public Collection<CommonCode> getAflinkList(String afChannel) {
+//		return rendererDao.getAflinkList(afChannel);
+//	}
+
+	/**
+	 * 색상그룹코드 RGB 목록
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	public Collection<CommonCode> getColorGrpCdRgbList() {
+		return rendererDao.getColorGrpCdRgbList();
+	}
+
+}

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

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

+ 531 - 0
src/main/java/com/style24/admin/biz/service/TsaSystemService.java

@@ -0,0 +1,531 @@
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaSystemDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Alarm;
+import com.style24.persistence.domain.AlarmReceiver;
+import com.style24.persistence.domain.Batch;
+import com.style24.persistence.domain.BatchLog;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.MenuRole;
+import com.style24.persistence.domain.SampleFile;
+import com.style24.persistence.domain.User;
+import com.style24.persistence.domain.UserHst;
+import com.style24.persistence.domain.UserMenu;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 시스템 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@Service
+@Slf4j
+public class TsaSystemService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaSystemDao systemDao;
+
+	/**
+	 * 사용자 목록
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<User> getUserList(User user) {
+		return systemDao.getUserList(user);
+	}
+
+	/**
+	 * 사용자 목록 삭제 처리
+	 * @param userList - 사용자 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteUserList(Collection<User> userList) {
+		for (User user : userList) {
+			user.setUpdNo(TsaSession.getInfo().getUserNo());
+			systemDao.deleteUser(user);
+			this.deleteUserAccount(user); // 계정말소
+		}
+	}
+
+	/**
+	 * 사용자 정보 조회
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public User getUser(Integer userNo) {
+		return systemDao.getUser(userNo);
+	}
+
+	/**
+	 * 사용자ID 건수 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public int getUserIdCount(String userId) {
+		return systemDao.getUserIdCount(userId);
+	}
+
+	/**
+	 * 사용자 정보 저장 처리
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveUser(User user) {
+		user.setRegNo(TsaSession.getInfo().getUserNo());
+		user.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		// 사용자 저장 처리
+		systemDao.saveUser(user);
+
+		// 등록된 사용자번호 값 가져오기
+		Integer userNo = user.getUserNo();
+		log.info("userNo: {}", userNo);
+		user.setUserNo(userNo);
+
+		if (user.getMode().equals("N")) {
+			this.createUserAccount(user); // 계정생성
+		} else if (user.getMode().equals("U")) {
+			if (user.getUseYn().equals("N")) {
+				this.deleteUserAccount(user); // 계정말소
+			} else {
+				this.restoreUserAccount(user); // 계정복원
+			}
+		}
+
+		// 권한이 변경되었으면
+		if (user.getRoleChangeYn().equals("Y")) {
+			// 사용자 전체메뉴 삭제
+			systemDao.deleteUserAllMenu(user.getUserNo());
+
+			// 사용자 전체메뉴 생성
+			systemDao.createUserAllMenu(user);
+
+			if (user.getMode().equals("U")) {
+				this.createUserRoleChange(user); // 권한변경
+			}
+		}
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 계정생성
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void createUserAccount(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_10"); // 계정생성
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 계정말소
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void deleteUserAccount(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_11"); // 계정말소
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 계정복원
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void restoreUserAccount(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_12"); // 계정복원
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 권한변경
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void createUserRoleChange(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_20"); // 권한변경
+		userHst.setOrgRoleCd(TsaSession.getInfo().getRoleCd());
+		userHst.setRoleCd(user.getRoleCd());
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 임시비밀번호 조회
+	 * @param length - 비밀번호 자릿수
+	 * @return 임시비밀번호
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public String getTemporaryPassword(int length) {
+		return systemDao.getTemporaryPassword(length);
+	}
+
+	/**
+	 * 사용자 비밀번호 수정
+	 * @param user - 사용자 정보
+	 * @since 2020. 10. 7
+	 */
+	public void updateUserPassword(User user) {
+		systemDao.updateUserPassword(user);
+
+		// 사용자정보변경이력 생성 - 비밀번호변경
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_30"); // 비밀번호변경
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자 메뉴 목록
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<UserMenu> getUserMenuList(Integer userNo) {
+		return systemDao.getUserMenuList(userNo);
+	}
+
+	/**
+	 * 사용자 메뉴 목록 저장 처리
+	 * @param userMenuList - 사용자 메뉴 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveUserMenuList(Collection<UserMenu> userMenuList) {
+		if (userMenuList == null || userMenuList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		int cnt = 0;
+		log.info("saveUserMenuList userMenuList={}", userMenuList);
+
+		for (UserMenu adminMenu : userMenuList) {
+			if (cnt++ == 0) {
+				// 사용자 전체메뉴 삭제
+				systemDao.deleteUserAllMenu(adminMenu.getUserNo());
+			}
+
+			adminMenu.setRegNo(TsaSession.getInfo().getUserNo());
+			adminMenu.setUpdNo(TsaSession.getInfo().getUserNo());
+			adminMenu.setUseRole("RCUD");
+
+			// 사용자 메뉴 생성
+			systemDao.createUserMenu(adminMenu);
+		}
+	}
+
+	/**
+	 * 메뉴 목록
+	 * @param pmenuId - 상위메뉴ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<Menu> getMenuList(String pmenuId) {
+		Menu menu = new Menu();
+		menu.setPmenuId(pmenuId);
+		return systemDao.getMenuList(menu);
+	}
+
+	/**
+	 * 메뉴 목록 저장 처리
+	 * @param menuList - 메뉴 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveMenuList(Collection<Menu> menuList) {
+		if (menuList == null || menuList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		for (Menu menu : menuList) {
+			menu.setRegNo(TsaSession.getInfo().getUserNo());
+			menu.setUpdNo(TsaSession.getInfo().getUserNo());
+			systemDao.saveMenu(menu);
+		}
+	}
+
+	/**
+	 * 메뉴 등록/수정 및 메뉴권한 생성
+	 * @param menu - 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+//	@CacheEvict(value = "menu", allEntries = true)
+	public void saveMenu(Menu menu) {
+		menu.setRegNo(TsaSession.getInfo().getUserNo());
+		menu.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		// 메뉴 등록/수정
+		systemDao.saveMenu(menu);
+
+		if (StringUtils.isNotBlank(menu.getRoleCds())) {
+			// 메뉴권한 삭제
+			systemDao.deleteMenuRole(menu.getMenuId());
+
+			String[] roleCds = menu.getRoleCds().split(",");
+
+			for (String roleCd : roleCds) {
+				MenuRole menuRole = new MenuRole();
+				menuRole.setRoleCd(roleCd);
+				menuRole.setMenuId(menu.getMenuId());
+				menuRole.setRegNo(TsaSession.getInfo().getUserNo());
+				menuRole.setUpdNo(TsaSession.getInfo().getUserNo());
+
+				// 메뉴권한 생성
+				systemDao.createMenuRole(menuRole);
+
+				// 전체 어드민사용자 메뉴 생성
+				systemDao.deleteAllUserMenu(menuRole);
+
+				// 전체 어드민사용자 메뉴 생성
+				systemDao.createAllUserMenu(menuRole);
+			}
+		}
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList() {
+		return this.getCommonCodeList(new CommonCode());
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @param commoncode - 공통코드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList(CommonCode commoncode) {
+		return systemDao.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 공통코드 목록 저장 처리
+	 * @param dataList - 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveCommonCodeList(Collection<CommonCode> dataList) {
+		if (dataList == null || dataList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		for (CommonCode commoncode : dataList) {
+			commoncode.setRegNo(TsaSession.getInfo().getUserNo());
+			commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
+			commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
+			systemDao.saveCommonCode(commoncode);
+		}
+	}
+
+	/**
+	 * 공통코드 저장 처리
+	 * @param commoncode - 공통코드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveCommonCode(CommonCode commoncode) {
+		commoncode.setRegNo(TsaSession.getInfo().getUserNo());
+		commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
+		commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
+		systemDao.saveCommonCode(commoncode);
+	}
+
+	/**
+	 * 공통코드 삭제처리
+	 * @param commoncode - 공통코드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteCommonCode(CommonCode commoncode) {
+		systemDao.deleteCommonCode(commoncode);
+	}
+
+	/**
+	 * 샘플파일 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	public Collection<SampleFile> getSampleFileList() {
+		return systemDao.getSampleFileList();
+	}
+
+	/**
+	 * 샘플파일 등록/수정
+	 * @param sampleFile - 샘플파일 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@Transactional("shopTxnManager")
+	public void saveSampleFile(SampleFile sampleFile) {
+		if (sampleFile.getMode().equals("N")) {
+			systemDao.createSampleFile(sampleFile);
+		} else {
+			systemDao.updateSampleFile(sampleFile);
+		}
+	}
+
+	/**
+	 * 알람 목록
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	public Collection<Alarm> getAlarmList(Alarm alarm) {
+		return systemDao.getAlarmList(alarm);
+	}
+
+	/**
+	 * 알람 저장
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void saveAlarm(Alarm alarm) {
+		if (alarm.getMode().equals("N")) {
+			systemDao.createAlarm(alarm);
+		} else {
+			systemDao.updateAlarm(alarm);
+		}
+	}
+
+	/**
+	 * 알람 삭제
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteAlarm(Alarm alarm) {
+		systemDao.deleteAlarm(alarm);
+	}
+
+	/**
+	 * 알람수신자 목록
+	 * @param alarmId - 알람ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	public Collection<AlarmReceiver> getAlarmReceiverList(String alarmId) {
+		return systemDao.getAlarmReceiverList(alarmId);
+	}
+
+	/**
+	 * 알람수신자 목록 저장
+	 * @param alarmReceiverList - 알람수신자 목록
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void saveAlarmReceiverList(Collection<AlarmReceiver> alarmReceiverList) {
+		for (AlarmReceiver alarmReceiver : alarmReceiverList) {
+			alarmReceiver.setRegNo(TsaSession.getInfo().getUserNo());
+			alarmReceiver.setUpdNo(TsaSession.getInfo().getUserNo());
+			systemDao.saveAlarmReceiver(alarmReceiver);
+		}
+	}
+
+	/**
+	 * 알람수신자 목록 삭제
+	 * @param alarmReceiverList - 알람수신자 목록
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteAlarmReceiverList(Collection<AlarmReceiver> alarmReceiverList) {
+		for (AlarmReceiver alarmReceiver : alarmReceiverList) {
+			systemDao.deleteAlarmReceiver(alarmReceiver);
+		}
+	}
+
+	/**
+	 * 배치 목록
+	 * @param batch - 배치 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 2
+	 */
+	public Collection<Batch> getBatchList(Batch batch) {
+		return systemDao.getBatchList(batch);
+	}
+
+	/**
+	 * 배치 생성
+	 * @param batch - 배치 정보
+	 * @author gagamel
+	 * @since 2020. 12. 2
+	 */
+	public void saveBatch(Batch batch) {
+		systemDao.saveBatch(batch);
+	}
+
+	/**
+	 * 배치 로그 목록
+	 * @param batch - 배치 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 3
+	 */
+	public Collection<BatchLog> getBatchLogList(Batch batch) {
+		return systemDao.getBatchLogList(batch);
+	}
+
+}

+ 1541 - 0
src/main/java/com/style24/admin/biz/service/TsaWithdrawService.java

@@ -0,0 +1,1541 @@
+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;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaDateUtil;
+
+import com.style24.admin.biz.dao.TsaDeliveryDao;
+//import com.style24.admin.biz.dao.TsaOrderDao;
+import com.style24.admin.biz.dao.TsaWithdrawDao;
+//import com.style24.admin.biz.dao.TsaWmsWithdrawDao;
+
+
+
+//import com.style24.persistence.domain.Coupon;
+import com.style24.persistence.domain.Delivery;
+//import com.style24.persistence.domain.Order;
+//import com.style24.persistence.domain.PayGate;
+//import com.style24.persistence.domain.Point;
+import com.style24.persistence.domain.Withdraw;
+
+
+
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.admin.support.env.TsaConstants.OrderDetailStat;
+//import com.style24.admin.support.env.TsaConstants.OrderStat;
+//import com.style24.admin.support.env.TsaConstants.PayMeans;
+//import com.style24.admin.support.env.TsaConstants.PaymentStat;
+//import com.style24.admin.support.env.TsaConstants.PurchaseReturnGb;
+//import com.style24.admin.support.env.TsaConstants.UsacGb;
+
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.admin.support.security.session.TsaSession;
+
+/**
+ * 회수관리 Service
+ *
+ * @author moon
+ * @since 2020. 11. 16
+ */
+@Service
+@Slf4j
+public class TsaWithdrawService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaWithdrawDao withdrawDao;
+
+	@Autowired
+	private TsaDeliveryDao deliveryDao;
+
+	//@Autowired
+	//private TsaOrderDao orderDao;
+
+	//@Autowired
+	//private TsaOrderService orderService;
+
+	//@Autowired
+	//private TsaWmsWithdrawDao wmsWithdrawDao;
+
+	@Autowired
+	private TsaKakaoService kakaoService;
+
+	/**
+	 * 회수등록 - 조회(송장번호용)
+	 *
+	 * @param withdraw
+	 * @return Collection<Withdraw>
+	 * @author rladbwnd5
+	 * @since 2020. 02. 11
+	 */
+//	public Collection<Withdraw> getWithdrawRegisterInvoiceList(Withdraw withdraw) {
+//		Collection<Withdraw> dataList = withdrawDao.getWithdrawRegisterInvoiceList(withdraw);
+//		return dataList;
+//	}
+
+	/**
+	 * 회수등록 - 조회(상품코드용)
+	 *
+	 * @param withdraw
+	 * @return Withdraw List
+	 * @author rladbwnd5
+	 * @since 2020. 02. 12
+	 */
+//	public Collection<Withdraw> getWithdrawRegisterGoodsList(Withdraw withdraw) {
+//		return withdrawDao.getWithdrawRegisterGoodsList(withdraw);
+//	}
+
+	/**
+	 * 회수등록 - 등록처리
+	 *
+	 * @param withdrawList
+	 * @return Withdraw List
+	 * @author rladbwnd5
+	 * @since 2020. 02. 12
+	 */
+//	@Transactional("shopTxnManager")
+//	public void createWithdrawInfo(Collection<Withdraw> withdrawList) {
+//		String uesrId = TsaSession.getInfo().getUserId();
+//
+//		// 회수 마스터 등록 정보
+//		Withdraw withdrawInfo = withdrawList.iterator().next();
+//
+//		// 주문변경번호
+//		Long ordChgSq = withdrawInfo.getOrdChgSq();
+//
+//		// 기존 회수 수량
+//		int wdQty = withdrawInfo.getSumWdQty();
+//
+//		// 1. 회수 상세 등록 (동일 여부 판단 위해 상세 먼저 등록)
+//		for (Withdraw withdrawDetailInfo : withdrawList) {
+//			if (ordChgSq > 0) {
+//				wdQty += withdrawDetailInfo.getWdQty(); // 기존 회수 수량 + 회수 수량
+//
+//				// 회수 완료 확인
+//				if (withdrawInfo.getSumChgQty() == wdQty) {
+//					withdrawInfo.setSameYn("Y");
+//				}
+//			} else {
+//				withdrawInfo.setSameYn("N");
+//			}
+//
+//			withdrawDetailInfo.setRegId(uesrId);
+//			withdrawDetailInfo.setUpdId(uesrId);
+//			withdrawDao.createWithdrawDetailInfo(withdrawDetailInfo);
+//		}
+//
+//		// 2. 회수 마스터 등록 처리
+//		withdrawInfo.setRegId(uesrId);
+//		withdrawInfo.setUpdId(uesrId);
+//		withdrawDao.saveWithdrawInfo(withdrawInfo);
+//	}
+
+	/**
+	 * 회수송장번호 변경
+	 *
+	 * @param
+	 * @return
+	 * @author rladbwnd5
+	 * @since 2020. 02. 27
+	 */
+//	@Transactional("shopTxnManager")
+//	public void updateRegisterWdInvoiceNo(Withdraw withdraw) {
+//		withdraw.setUpdId(TsaSession.getInfo().getUserId());
+//		withdrawDao.updateRegisterWdInvoiceNo(withdraw);
+//	}
+
+	/**
+	 * 회수송장번호 조회
+	 *
+	 * @param
+	 * @return
+	 * @author yujung
+	 * @since 2020. 05. 31
+	 */
+//	public Collection<Withdraw> getWdInvoiceNo(Withdraw withdraw) {
+//		return withdrawDao.getWdInvoiceNo(withdraw);
+//	}
+
+	/**
+	 * 환불관리 목록
+	 *
+	 * @param withdraw
+	 * @return Collection<Withdraw>
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	public Collection<Withdraw> getRefundList(Withdraw withdraw) {
+		return withdrawDao.getRefundList(withdraw);
+	}
+
+	/**
+	 * 환불관리 회수데이터 삭제처리
+	 *
+	 * @param
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteWithdrawInfo(Withdraw withdraw) {
+		Withdraw search = new Withdraw();
+		search.setWdInvoiceNo(withdraw.getWdInvoiceNo());
+		Collection<Withdraw> withdrawList = withdrawDao.getRefundList(search);
+		// 마지막 회수 리스트 일 때 마스터 정보 삭제
+		if (withdrawList.size() == 1) {
+			withdrawDao.deleteWithdraw(withdraw);
+		}
+
+		withdrawDao.deleteWithdrawDetail(withdraw);
+	}
+
+	/**
+	 * 회수마스터 삭제처리
+	 *
+	 * @param
+	 * @return
+	 * @author yujung
+	 * @since 2020. 06. 01
+	 */
+//	@Transactional("shopTxnManager")
+//	public void deleteWithdraw(Withdraw withdraw) {
+//		withdrawDao.deleteWithdraw(withdraw);
+//	}
+
+	/**
+	 * 회수상세 삭제처리
+	 *
+	 * @param
+	 * @return
+	 * @author yujung
+	 * @since 2020. 06. 01
+	 */
+//	@Transactional("shopTxnManager")
+//	public void deleteWithdrawDetail(Withdraw withdraw) {
+//		withdrawDao.deleteWithdrawDetail(withdraw);
+//	}
+
+	/**
+	 * 회수등록 팝업 목록
+	 *
+	 * @param
+	 * @return
+	 * @author rladbwnd5
+	 * @since 2020. 03. 03
+	 */
+//	public Collection<Withdraw> getWithdrawRegisterPopupList(Withdraw withdraw) {
+//		return withdrawDao.getWithdrawRegisterPopupList(withdraw);
+//	}
+
+	/**
+	 * 회수등록팝업 주문매핑(송장번호 수정)
+	 *
+	 * @param
+	 * @return
+	 * @author yujung
+	 * @since 2020. 03. 25
+	 */
+//	@Transactional("shopTxnManager")
+//	public void updateOrderChangeWdInvoiceNo(Withdraw withdraw) {
+//		String userId = TsaSession.getInfo().getUserId();
+//
+//		// 주문변경 회수송장번호 변경
+//		Withdraw orderChangeParam = new Withdraw();
+//		orderChangeParam.setOrdChgSq(withdraw.getOrdChgSq());
+//		orderChangeParam.setWdInvoiceNo(withdraw.getWdInvoiceNo());
+//		orderChangeParam.setUpdId(userId);
+//		withdrawDao.updateRegisterWdInvoiceNo(orderChangeParam);
+//
+//		// 회수상세 변경
+//		Withdraw withdrawDetailInfo = new Withdraw();
+//		withdrawDetailInfo.setWdInvoiceNo(withdraw.getWdInvoiceNo());
+//		withdrawDetailInfo.setGoodsCd(withdraw.getGoodsCd());
+//		withdrawDetailInfo.setSizeCd(withdraw.getSizeCd());
+//		withdrawDetailInfo.setOrdDtlNo(withdraw.getOrdDtlNo());
+//		withdrawDetailInfo.setUpdId(userId);
+//		withdrawDao.updateWithdrawDetailInfo(withdrawDetailInfo);
+//
+//		// 회수송장번호 등록
+//		Withdraw wdInvoiceInfo = new Withdraw();
+//		wdInvoiceInfo.setWdInvoiceNo(withdraw.getWdInvoiceNo());
+//		wdInvoiceInfo.setOrdChgSq(withdraw.getOrdChgSq());
+//		wdInvoiceInfo.setUpdId(userId);
+//		withdrawDao.updateWithdrawOrderChange(wdInvoiceInfo);
+//	}
+
+	/**
+	 * 회수등록팝업 주문매핑(주문상세일련번호 수정)
+	 *
+	 * @param
+	 * @return
+	 * @author yujung
+	 * @since 2020. 03. 25
+	 */
+//	@Transactional("shopTxnManager")
+//	public void updateWithdrawOrdDtlNo(Withdraw withdraw) {
+//		// 아웃바운드 정보 업데이트
+//		Withdraw outboundInfo = new Withdraw();
+//		outboundInfo.setWdInvoiceNo(withdraw.getWdInvoiceNo());
+//		outboundInfo.setCsObYn("Y");
+//		outboundInfo.setCsObId(TsaSession.getInfo().getUserId());
+//		withdrawDao.updateWithdrawOutbound(outboundInfo);
+//
+//		// 회수상세 변경
+//		Withdraw withdrawDetailInfo = new Withdraw();
+//		withdrawDetailInfo.setWdInvoiceNo(withdraw.getWdInvoiceNo());
+//		withdrawDetailInfo.setGoodsCd(withdraw.getGoodsCd());
+//		withdrawDetailInfo.setSizeCd(withdraw.getSizeCd());
+//		withdrawDetailInfo.setOrdDtlNo(withdraw.getOrdDtlNo());
+//		withdrawDetailInfo.setUpdId(TsaSession.getInfo().getUserId());
+//		withdrawDao.updateWithdrawDetailInfo(withdrawDetailInfo);
+//
+//		// 회수관리 주문상세번호 및 상품 정보 변경
+//		Withdraw withdrawInfo = new Withdraw();
+//		withdrawInfo.setOrgOrdDtlNo(withdraw.getOrgOrdDtlNo()); // 원주문상세번호
+//		withdrawInfo.setGoodsCd(withdraw.getGoodsCd());
+//		withdrawInfo.setSizeCd(withdraw.getSizeCd());
+//		withdrawInfo.setOrdDtlNo(withdraw.getOrdDtlNo()); // 변경 될 주문번호
+//		withdrawInfo.setWdInvoiceNo(withdraw.getWdInvoiceNo());
+//		withdrawInfo.setUpdId(TsaSession.getInfo().getUserId());
+//		withdrawDao.updateWithdrawDetailGoodsInfo(withdrawInfo);
+//
+//		// withdrawDao.updateWithdrawOrdDtlNo(withdraw);
+//		// return super.ok(message.getMessage("SUCC_0002"));
+//	}
+
+	/**
+	 * 환불관리 상세정보
+	 *
+	 * @param withdraw - 변경주문번호
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	public Collection<Withdraw> getRefundDetailList(Withdraw withdraw) {
+		return withdrawDao.getRefundDetailList(withdraw);
+	}
+
+	/**
+	 * 환불관리 남은상품정보
+	 *
+	 * @param withdraw - 변경주문번호, 주문번호
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	public Withdraw getRemainGoodsInfo(Withdraw withdraw) {
+		return withdrawDao.getRemainGoodsInfo(withdraw);
+	}
+
+	/**
+	 * 환불관리 남은상품리스트
+	 *
+	 * @param withdraw - 변경주문번호, 주문번호
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	public Collection<Withdraw> getWithdrawRemainOrderDetailList(Withdraw withdraw) {
+		return withdrawDao.getWithdrawRemainOrderDetailList(withdraw);
+	}
+
+	/**
+	 * 회수관리 쿠폰정보
+	 *
+	 * @param withdraw - 변경주문번호, 주문번호
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 15
+	 */
+	public Withdraw getCouponInfo(Withdraw withdraw) {
+		return withdrawDao.getCouponInfo(withdraw);
+	}
+
+
+	/**
+	 * 회수관리 - 회수처리
+	 *
+	 * @param params
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@Transactional("shopTxnManager")
+	public void refundDetailConfirm(Withdraw params) {
+//		// 기본값 설정
+//		String userId = TsaSession.getInfo().getUserId();
+//		int custNo = params.getCustNo();		// 회원번호
+//		Long ordNo = params.getOrdNo();		// 주문번호
+//		Long ordDtlNo = params.getOrdDtlNo();	// 주문상세번호
+//		Long ordChgSq = params.getOrdChgSq();	// 주문변경번호
+//		int cnclRtnQty = params.getCnclRtnQty();	// 취소반품 수량
+//		int custShipAmt = params.getCustShipAmt();	// 고객부담배송비
+//		String chgGb = params.getChgGb();	// 변경요청구분
+//		String supplyCompCd = params.getSupplyCompCd();
+//		String pgStat = params.getPgStats();
+//		String mallGb = params.getMallGb();
+//		String chgReason = params.getChgReason();
+//		String orgChgReason = params.getOrgChgReason();
+//		int orgEncloseFee = params.getOrgEncloseFee();
+//		int encloseFee = params.getEncloseFee();
+//		String delvLocCd = params.getDelvLocCd();	// 반품처코드
+//
+//		if (!chgReason.equals(orgChgReason)) {
+//			Withdraw chgParams = new Withdraw();
+//			chgParams.setUpdId(userId);
+//			chgParams.setChgReason(chgReason);
+//			chgParams.setOrdChgSq(ordChgSq);
+//			withdrawDao.updateWithdrawOrderChange(chgParams);
+//		}
+//
+//		if (encloseFee != orgEncloseFee) {
+//			Withdraw withdrawParams = new Withdraw();
+//			withdrawParams.setEncloseFee(encloseFee);
+//			withdrawParams.setUpdId(userId);
+//			withdrawParams.setWdInvoiceNo(params.getWdInvoiceNo());
+//			withdrawDao.updateWithdrawEncloseFee(withdrawParams);
+//		}
+//
+//		Withdraw ordChgDtlParams = new Withdraw();
+//		ordChgDtlParams.setOrdChgSq(ordChgSq);
+//		ordChgDtlParams.setOrdDtlNo(ordDtlNo);
+//		if (TsaConstants.OrderChangeGb.EXCHANGE.value().equals(params.getChgGb())) {	// 교환인 경우
+//			ordChgDtlParams.setChgStat(TsaConstants.OrderChangeStat.EXCHANGE_COMPLETE.value());
+//		} else {
+//			ordChgDtlParams.setChgStat(TsaConstants.OrderChangeStat.RETURN_COMPLETE.value());
+//		}
+//		ordChgDtlParams.setUpdId(userId);
+//		withdrawDao.updateWithdrawOrderChangeDetailInfo(ordChgDtlParams);
+//
+//		int remainCount = withdrawDao.getRemainWithdrawCount(ordChgSq);	// 회수컨펌 남은 개수
+//
+//		if (remainCount == 0) {
+//			// 주문 변경 회수 종료 일시 업데이트
+//			Withdraw orderChangeInfo = new Withdraw();
+//			orderChangeInfo.setOrdChgSq(ordChgSq);
+//			orderChangeInfo.setUpdId(userId);
+//			withdrawDao.updateOrderChangeInfo(orderChangeInfo);
+//
+//			int orgDelvFee = 0;	// 원주문배송비
+//			int refundAmt = 0;	// 환불금액
+//			int refundPntAmt = 0;
+//			int refundPrePntAmt = 0;
+//			int refundGoodsCpnAmt = 0;
+//			int refundCartCpnAmt = 0;
+//			int refundCancelCartCpnAmt = 0;
+//			int refundPlusCpnAmt = 0;
+//			int refundSavePntAmt = 0;
+//			Long usedCartCpnSq = null;
+//
+//			Collection<TsaPoint> pointList = new ArrayList<TsaPoint>();
+//			Collection<TsaPoint> prePointList = new ArrayList<TsaPoint>();
+//			Collection<TsaPoint> savePointList = new ArrayList<TsaPoint>();
+//
+//			// ORD_CHG_SQ 별 ITEM_CD 단위의 리스트
+//			Collection<Withdraw> withdrawList = withdrawDao.getWithdrawDetailList(params);
+//
+//			// 쿠폰정보
+//			String couponCartCpnSq = withdrawList.iterator().next().getCartCpnSq();
+//			Withdraw couponInfo = null;
+//			if (StringUtils.isNotBlank(couponCartCpnSq)) {
+//				Withdraw searchCoupon = new Withdraw();
+//				searchCoupon.setCartCpnSq(couponCartCpnSq);
+//				searchCoupon.setCustNo(custNo);
+//				couponInfo = withdrawDao.getCouponInfo(searchCoupon);
+//			}
+//
+//			List<Withdraw> ifOnilneSales = new ArrayList();
+//			GagaMap setOrdDtlNos = new GagaMap();
+//			int cancelRequestAmt = 0;                            // 취소요청금액 cancelRequestAmt
+//
+//			for (Withdraw withdraw : withdrawList) {
+//				// 세트상품인 경우 회수컨펌 처리건이 있으면 스킵
+//				if ("S".equals(withdraw.getGoodsType()) && setOrdDtlNos.getInt(withdraw.getOrdDtlNo()) > 1) {
+//					continue;
+//				}
+//				orgDelvFee = withdraw.getOrgDelvFee();
+//				String goodsCpnSq = withdraw.getGoodsCpnSq();
+//				String cartCpnSq = withdraw.getCartCpnSq();
+//				int cnclReturnRealOrdAmt = 0;
+//				int orgOrdAmt = withdraw.getOrdAmt();
+//				int orgCurrPrice = withdraw.getCurrPrice();
+//				int orgRealOrdAmt = withdraw.getRealOrdAmt();
+//				int ordQty = withdraw.getOrdQty();
+//				int orgCnclRtnQty = withdraw.getCnclRtnQty();
+//				int wdQty = withdraw.getWdQty();
+//				int realOrdQty = ordQty - orgCnclRtnQty;
+//				int orgCnclRtnAmt = withdraw.getCnclRtnAmt();
+//				int orgGoodsCpnDcAmt = withdraw.getGoodsCpnDcAmt();
+//				int orgCartCpnDcAmt = withdraw.getCartCpnDcAmt();
+//				int orgPntDcAmt = withdraw.getPntDcAmt();
+//				int orgPrePntDcAmt = withdraw.getPrePntDcAmt();
+//				int orgSavePntAmt = withdraw.getSavePntAmt();
+//				String plusCpnSq = withdraw.getPlusCpnSq();
+//				int orgPlusCpnDcAmt = withdraw.getPlusCpnDcAmt();
+//
+//				/* 정산,환불 처리용 */
+//				int rfPntAmt = (int)((double)orgPntDcAmt / realOrdQty * wdQty);				// 환원 포인트
+//				int rfPrePntAmt = (int)((double)orgPrePntDcAmt / realOrdQty * wdQty);		// 취소 선포인트
+//				int rfGoodsCpnAmt = (int)((double)orgGoodsCpnDcAmt / realOrdQty * wdQty);	// 취소 상품쿠폰금액
+//				int rfCartCpnAmt = (int)((double)orgCartCpnDcAmt / realOrdQty * wdQty);		// 취소 장바구니쿠폰금액
+//				int rfPlusCpnAmt = (int)((double)orgPlusCpnDcAmt / realOrdQty * wdQty);		// 취소 플러스쿠폰금액
+//				int rfSavePntAmt = (int)((double)orgSavePntAmt / realOrdQty * wdQty);
+//
+//				refundPntAmt += rfPntAmt;
+//				refundPrePntAmt += rfPrePntAmt;
+//				refundGoodsCpnAmt += rfGoodsCpnAmt;
+//				refundCartCpnAmt += rfCartCpnAmt;
+//				refundPlusCpnAmt += rfPlusCpnAmt;
+//				refundSavePntAmt += rfSavePntAmt;
+//
+//				int cnclRtnAmt = 0;
+//				int erpCnclRtnAmt = 0;
+//				int goodsCpnDcAmt = orgGoodsCpnDcAmt - rfGoodsCpnAmt;
+//				int cartCpnDcAmt = orgCartCpnDcAmt - rfCartCpnAmt;
+//				int plusCpnDcAmt = orgPlusCpnDcAmt - rfPlusCpnAmt;
+//				int pntDcAmt = orgPntDcAmt - rfPntAmt;
+//				int prePntDcAmt = orgPrePntDcAmt - rfPrePntAmt;
+//				int savePntAmt = orgSavePntAmt - (orgSavePntAmt / realOrdQty * wdQty);
+//				cnclRtnQty = orgCnclRtnQty + wdQty;
+//
+//				log.info("orgRealOrdAmt = " + orgRealOrdAmt);
+//				log.info("wdQty = " + wdQty);
+//				log.info("cnclRtnAmt = " + cnclRtnAmt);
+//
+//				cnclRtnAmt += orgCnclRtnAmt + (orgCurrPrice * wdQty);
+//				erpCnclRtnAmt = (orgCurrPrice * wdQty);
+//				cnclReturnRealOrdAmt = (orgCurrPrice * wdQty) - rfPntAmt - rfPrePntAmt - rfGoodsCpnAmt - rfCartCpnAmt - rfPlusCpnAmt;
+//
+//				log.info("orgCnclRtnAmt = " + orgCnclRtnAmt);
+//				log.info("orgRealOrdAmt = " + orgRealOrdAmt);
+//				log.info("orgOrdAmt = " + orgOrdAmt);
+//				log.info("ordQty = " + ordQty);
+//				log.info("orgCnclRtnQty = " + orgCnclRtnQty);
+//				log.info("(orgOrdAmt / (ordQty - orgCnclRtnQty)) = " + (orgOrdAmt / (ordQty - orgCnclRtnQty)));
+//				log.info("refundPntAmt = " + refundPntAmt);
+//				log.info("refundPrePntAmt = " + refundPrePntAmt);
+//				log.info("refundGoodsCpnAmt = " + refundGoodsCpnAmt);
+//				log.info("refundCartCpnAmt = " + refundCartCpnAmt);
+//				log.info("refundPlusCpnAmt = " + refundPlusCpnAmt);
+//				log.info("cnclReturnRealOrdAmt = " + cnclReturnRealOrdAmt);
+//
+//				int realOrdAmt = orgRealOrdAmt - cnclReturnRealOrdAmt;
+//				refundAmt += cnclReturnRealOrdAmt;
+//
+//				log.info("realOrdAmt = " + realOrdAmt);
+//				log.info("cnclRtnQty = " + cnclRtnQty);
+//				log.info("cnclRtnAmt = " + cnclRtnAmt);
+//				log.info("goodsCpnDcAmt = " + goodsCpnDcAmt);
+//				log.info("goodsCpnSq = " + goodsCpnSq);
+//				log.info("cartCpnDcAmt = " + cartCpnDcAmt);
+//				log.info("cartCpnSq = " + cartCpnSq);
+//				log.info("pntDcAmt = " + pntDcAmt);
+//				log.info("prePntDcAmt = " + prePntDcAmt);
+//				log.info("savePntAmt = " + savePntAmt);
+//				log.info("plusCpnDcAmt = " + plusCpnDcAmt);
+//				log.info("plusCpnSq = " + plusCpnSq);
+//
+//				// 주문상세 업데이트
+//				log.info("============== 주문상세 업데이트 ==============");
+//
+//				Withdraw updParams = new Withdraw();
+//				updParams.setUpdId(userId);
+//				updParams.setOrdDtlNo(withdraw.getOrdDtlNo());
+//				if (cnclRtnQty == ordQty) {
+//					updParams.setOrdDtlStat(OrderDetailStat.PAYMENT_AFTER_CANCEL.value());
+//				}
+//				updParams.setRealOrdAmt(realOrdAmt);
+//				updParams.setCnclRtnQty(cnclRtnQty);
+//				updParams.setCnclRtnAmt(cnclRtnAmt);
+//				updParams.setGoodsCpnDcAmt(goodsCpnDcAmt);
+//				updParams.setGoodsCpnSq(goodsCpnSq);
+//				updParams.setCartCpnDcAmt(cartCpnDcAmt);
+//				updParams.setCartCpnSq(cartCpnSq);
+//				updParams.setPlusCpnDcAmt(plusCpnDcAmt);
+//				updParams.setPlusCpnSq(plusCpnSq);
+//				updParams.setPntDcAmt(pntDcAmt);
+//				updParams.setPrePntDcAmt(prePntDcAmt);
+//				updParams.setSavePntAmt(savePntAmt);
+//				updParams.setRegId(userId);
+//				withdrawDao.updateWithdrawOrderDetailInfo(updParams);
+//				withdrawDao.createWithdrawOrderDetailHstInfo(updParams);
+//
+//				// 주문상세 업데이트
+//				log.info("============== 매출반영 ==============");
+//
+//				Withdraw ifData = new Withdraw();
+//				ifData.setOrdDtlNo(withdraw.getOrdDtlNo());
+//				ifData.setOrdNo(ordNo);
+//				ifData.setWdQty(wdQty);
+//				ifData.setCnclRtnAmt(cnclRtnAmt);
+//				ifData.setGoodsCd(withdraw.getGoodsCd());
+//				ifData.setRealOrdAmt(cnclReturnRealOrdAmt);
+//				ifData.setRealOrdQty(realOrdQty);
+//				ifData.setRfGoodsCpnAmt(rfGoodsCpnAmt);
+//				ifData.setRfCartCpnAmt(rfCartCpnAmt);
+//				ifData.setRfPlusCpnAmt(rfPlusCpnAmt);
+//				ifData.setRfPntAmt(rfPntAmt);
+//				ifData.setRfPrePntAmt(rfPrePntAmt);
+//				ifData.setRfSavePntAmt(rfSavePntAmt);
+//				ifData.setGoodsType(withdraw.getGoodsType());
+//				ifData.setOrdAmt(erpCnclRtnAmt);
+//				ifData.setCartCpnSq(cartCpnSq);
+//				ifData.setGoodsCpnSq(goodsCpnSq);
+//				ifData.setPlusCpnSq(plusCpnSq);
+//				ifData.setOrderNm(withdraw.getOrderNm());
+//				ifData.setOrderPhnno(withdraw.getOrderPhnno());
+//				ifOnilneSales.add(ifData);
+//
+//				// 자사몰이면서 반품이면 포인트,쿠폰 반환
+//				if (TsaConstants.MallGb.SELFMALL.value().equals(mallGb) && TsaConstants.OrderChangeGb.RETURN.value().equals(chgGb)) {
+//
+//					if (rfPntAmt > 0) {
+//						TsaPoint point = new TsaPoint();
+//						point.setPntAmt(rfPntAmt);
+//						point.setOrdNo((int)(long)ordNo);
+//						point.setOrdDtlNo((int)(long)ordDtlNo);
+//						pointList.add(point);
+//					}
+//
+//					if (rfPrePntAmt > 0) {
+//						TsaPoint point = new TsaPoint();
+//						point.setPntAmt(rfPrePntAmt);
+//						point.setOrdNo((int)(long)ordNo);
+//						point.setOrdDtlNo((int)(long)ordDtlNo);
+//						prePointList.add(point);
+//					}
+//
+//					if (savePntAmt > 0) {
+//						TsaPoint point = new TsaPoint();
+//						point.setPntAmt(-rfSavePntAmt);
+//						point.setOrdNo((int)(long)ordNo);
+//						point.setOrdDtlNo((int)(long)ordDtlNo);
+//						savePointList.add(point);
+//					}
+//
+//					if (StringUtils.isNotBlank(withdraw.getGoodsCpnSq())) {
+//						TsaOrder goodsCpnParam = new TsaOrder();
+//						goodsCpnParam.setCustCpnSq(Long.parseLong(withdraw.getGoodsCpnSq()));
+//						goodsCpnParam.setUpdId(userId);
+//
+//						TsaCoupon goodsCpnInfo = orderDao.getCustCouponInfo(goodsCpnParam.getCustCpnSq());
+//						if (goodsCpnInfo != null) {
+//							goodsCpnInfo = orderDao.getCouponInfo(goodsCpnInfo.getCpnId());
+//
+//							if (goodsCpnInfo != null && ("10".equals(goodsCpnInfo.getReissuance()) || "30".equals(goodsCpnInfo.getReissuance()))) {
+//								orderDao.updateCustCouponCancel(goodsCpnParam);
+//							}
+//						}
+//					}
+//
+//					if (StringUtils.isNotBlank(withdraw.getPlusCpnSq())) {
+//						TsaOrder plusCpnParam = new TsaOrder();
+//						plusCpnParam.setCustCpnSq(Long.parseLong(withdraw.getPlusCpnSq()));
+//						plusCpnParam.setUpdId(userId);
+//
+//						TsaCoupon plusCpnInfo = orderDao.getCustCouponInfo(plusCpnParam.getCustCpnSq());
+//						if (plusCpnInfo != null) {
+//							plusCpnInfo = orderDao.getCouponInfo(plusCpnInfo.getCpnId());
+//
+//							if (plusCpnInfo != null && ("10".equals(plusCpnInfo.getReissuance()) || "30".equals(plusCpnInfo.getReissuance()))) {
+//								orderDao.updateCustCouponCancel(plusCpnParam);
+//							}
+//						}
+//					}
+//
+//					if (StringUtils.isNotBlank(withdraw.getCartCpnSq())) {
+//						usedCartCpnSq = Long.parseLong(withdraw.getCartCpnSq());
+//					}
+//				}
+//
+//				// 반품요청에 대한 컨펌시 환입 정산정보 생성
+//				if (TsaConstants.OrderChangeGb.RETURN.value().equals(chgGb)) {
+//					Withdraw paramUsac = new Withdraw();
+//					paramUsac.setUsacGb(UsacGb.PURCHASE_RETURN.value());
+//					paramUsac.setPrtnGb(PurchaseReturnGb.RETURN.value());
+//					paramUsac.setOrdDtlNo(withdraw.getOrdDtlNo());
+//					paramUsac.setOrgUsacGb(UsacGb.SELL.value());
+//					paramUsac.setUsacQty(wdQty);
+//					paramUsac.setGoodsCpnDcAmt(rfGoodsCpnAmt);
+//					paramUsac.setCartCpnDcAmt(rfCartCpnAmt);
+//					paramUsac.setPlusCpnDcAmt(rfPlusCpnAmt);
+//					paramUsac.setPntDcAmt(rfPntAmt);
+//					paramUsac.setPrePntDcAmt(rfPrePntAmt);
+//					paramUsac.setRegId(userId);
+//					withdrawDao.createWithdrawUsac(paramUsac);
+//				}
+//
+//				// 세트상품인 경우 상세번호를 저장
+//				if ("S".equals(withdraw.getGoodsType())) {
+//					setOrdDtlNos.setInt(withdraw.getOrdDtlNo(), setOrdDtlNos.getInt(withdraw.getOrdDtlNo()) < 1 ? 1 : setOrdDtlNos.getInt(withdraw.getOrdDtlNo()) + 1);
+//				}
+//			}
+//
+//			// 쿠폰 처리
+//			String chgReasonCds = "10,11,12,13,15,21,30";	// 고객 귀책
+//			if (chgReasonCds.contains(chgReason) && TsaConstants.OrderChangeGb.RETURN.value().equals(chgGb)) {
+//				if (couponInfo != null) {
+//					if (StringUtils.isNotBlank(couponCartCpnSq) && couponInfo.getBuyLimitAmt() > 0) {
+//						refundCancelCartCpnAmt += orderDetailCouponCancel(ordNo, ordChgSq, couponInfo.getBuyLimitAmt());
+//					}
+//				}
+//			}
+//
+//			Withdraw orderDetailSumAmtInfo = withdrawDao.getOrderDetailSumAmt(ordNo.toString());
+//
+//			// 마지막에 처리 할 것. 장바구니 쿠폰 사용 여부 처리( 추후 구매제한에 대한 것도 처리 필요)
+//			if (StringUtils.isNotBlank(couponCartCpnSq) && orderDetailSumAmtInfo.getTotCartCpnDcAmt() == 0 && TsaConstants.OrderChangeGb.RETURN.value().equals(chgGb)) {
+//				TsaCoupon cartCpnInfo = new TsaCoupon();
+//				if (usedCartCpnSq != null) {
+//					cartCpnInfo = orderDao.getCustCouponInfo(usedCartCpnSq);
+//				}
+//				if (cartCpnInfo != null) {
+//					cartCpnInfo = orderDao.getCouponInfo(cartCpnInfo.getCpnId());
+//
+//					if (cartCpnInfo != null && ("10".equals(cartCpnInfo.getReissuance()) || "30".equals(cartCpnInfo.getReissuance()))) {
+//						TsaOrder paramCpn = new TsaOrder();
+//						paramCpn.setUpdId(userId);
+//						paramCpn.setCustCpnSq(Long.parseLong(couponCartCpnSq));
+//						orderDao.updateCustCouponCancel(paramCpn);
+//					}
+//				}
+//			}
+//
+//			int remainOrdCnt = withdrawDao.getOrderNotCancelCnt(ordNo);
+//
+//			TsaDelivery paramOrder = new TsaDelivery();
+//			paramOrder.setOrdNo(ordNo);
+//
+//			if (remainOrdCnt == 0 && TsaConstants.OrderChangeGb.RETURN.value().equals(chgGb)) {
+//				paramOrder.setUpdId(userId);
+//				paramOrder.setOrdStat(OrderStat.PAYMENT_AFTER_CANCEL.value());
+//				deliveryDao.updateOrder(paramOrder);
+//			}
+//
+//			/* 포인트 처리 */
+//			TsaOrder ordPnt = new TsaOrder();
+//			ordPnt.setOrdNo(Long.toString(ordNo));
+//			ordPnt.setCustNo(Integer.toString(custNo));
+//			ordPnt.setOccurGb(TsaConstants.PointOccurGb.USE_POINT.value());
+//			int ordUsedCustPointHstSq = orderDao.getOrderCustPointHstSq(ordPnt);	// 사용한 포인트 정보
+//
+//			if (ordUsedCustPointHstSq > 0 && TsaConstants.OrderChangeGb.RETURN.value().equals(chgGb)) {
+//
+//				// 환불 포인트 만료일
+//				String expireDt = orderDao.getOrderAccountExpireDt(ordUsedCustPointHstSq);
+//				String toDay = GagaDateUtil.getToday();
+//
+//				if (StringUtils.isNotBlank(expireDt)) {
+//
+//					// 만료일이 지났으면 오늘 + 7일로 셋팅
+//					long longSwitchDueDt = Long.parseLong(expireDt);
+//					long longToDay = Long.parseLong(toDay);
+//
+//					if (longSwitchDueDt < longToDay) {
+//						expireDt = GagaDateUtil.getOffsetDate(toDay, 7, "yyyyMMdd");
+//					}
+//
+//					// 사용 포인트 반환
+//					if (refundPntAmt > 0) {
+//						TsaPoint point = new TsaPoint();
+//						point.setCustNo(Integer.toString(custNo));
+//						point.setOccurGb(TsaConstants.PointOccurGb.USE_POINT_CANCEL.value());
+//						point.setGivenPntAmt(refundPntAmt);
+//						point.setAvailPntAmt(refundPntAmt);
+//						point.setUsePntAmt(0);
+//						point.setExpireDt(expireDt);
+//						point.setOrdNo(Integer.parseInt(Long.toString(ordNo)));
+//						point.setSwitchDueDt(GagaDateUtil.getTodayDateTime());
+//						point.setPntUploadStat(TsaConstants.PointOccurStat.APPLY_COMPLETE.value());
+//						point.setPntUploadDt(point.getSwitchDueDt());
+//						point.setRegId(userId);
+//						point.setUpdId(userId);
+//						orderDao.createPointAccount(point);
+//
+//						point.setPntAmt(point.getGivenPntAmt());
+//						orderDao.createCustPointHst(point);
+//
+//						orderDao.createPointDetail(point);
+//
+//						for (TsaPoint paramPnt : pointList) {
+//							paramPnt.setCustPointHstSq(point.getCustPointHstSq());
+//							paramPnt.setRegId(userId);
+//							orderDao.createOrderPoint(paramPnt);
+//						}
+//					}
+//
+//					// 적립 예정 포인트 취소
+//					if (refundSavePntAmt > 0) {
+//						TsaPoint point = new TsaPoint();
+//
+//						point.setOrdNo(Integer.parseInt(Long.toString(ordNo)));
+//						point.setOccurGb(TsaConstants.PointOccurGb.EXPECT_POINT.value());
+//						String switchDueDt = orderDao.getPointAccountSwitchDueDt(point);
+//						expireDt = orderDao.getPointAccountExpireDt(point);
+//						String pntUploadStat = orderDao.getPointAccountPntUploadStat(point);
+//						
+//						int availPntAmt = 0;
+//						String uploadDt = "";
+//						String uploadStat = TsaConstants.PointOccurStat.APPLY_EXPECT.value();
+//						String toDayTime = GagaDateUtil.getTodayDateTime();
+//
+//						// 예정일이 지났으면 오늘로 셋팅
+//						if (TsaConstants.PointOccurStat.APPLY_COMPLETE.value().equals(pntUploadStat)) {
+//							availPntAmt = -refundSavePntAmt;
+//							switchDueDt = toDayTime;
+//							uploadDt = switchDueDt;
+//							uploadStat = TsaConstants.PointOccurStat.APPLY_COMPLETE.value();
+//						}
+//
+//						point.setCustNo(Integer.toString(custNo));
+//						point.setOccurGb(TsaConstants.PointOccurGb.EXPECT_POINT_CANCEL.value());
+//						point.setGivenPntAmt(-refundSavePntAmt);
+//						point.setAvailPntAmt(availPntAmt);
+//						point.setUsePntAmt(0);
+//						point.setExpireDt(expireDt);
+//						point.setSwitchDueDt(GagaDateUtil.getTodayDateTime());
+//						point.setPntUploadStat(uploadStat);
+//						point.setPntUploadDt(uploadDt);
+//						point.setRegId(userId);
+//						point.setUpdId(userId);
+//						orderDao.createPointAccount(point);
+//
+//						point.setPntAmt(point.getGivenPntAmt());
+//						orderDao.createCustPointHst(point);
+//
+//						orderDao.createPointDetail(point);
+//
+//						for (TsaPoint paramPnt : savePointList) {
+//							paramPnt.setCustPointHstSq(point.getCustPointHstSq());
+//							paramPnt.setRegId(userId);
+//							orderDao.createOrderPoint(paramPnt);
+//						}
+//					}
+//				}
+//			}
+//
+//			if (TsaConstants.OrderChangeGb.RETURN.value().equals(chgGb)) {	// 반품인경우
+//				// 결제 정보
+//				TsaOrder paramPay = new TsaOrder();
+//				paramPay.setOrdNo(ordNo.toString());
+//				paramPay.setPayStat(PaymentStat.PAYMENT_COMPLETE.value());
+//				paramPay.setDelvPayGb("O");
+//				TsaOrder pay = orderDao.getPayment(paramPay);
+//
+//				pay.setOrgPayStat(PaymentStat.PAYMENT_COMPLETE.value());
+//
+//				int orgPaySq = pay.getPaySq();
+//				int paySq = orgPaySq + 1;
+//				int orgPayAmt = pay.getPayAmt();
+//				int devlFeePaySq = orgPaySq;
+//
+//				// 원 결제 정보 업데이트
+//				pay.setOrdNo(ordNo.toString());
+//				pay.setPayStat(PaymentStat.PAYMENT_CANCEL.value());
+//				pay.setUpdId(userId);
+//
+//				/* 9.배송비 등록 */
+//				GagaMap delvMap = deliveryFeeProcess(params, orgPaySq, chgReasonCds);
+//				int totRfDelvFee = delvMap.getInt("totDelvFee");	// 총환불배송비
+//				int rfDelvCpnAmt = delvMap.getInt("rfDelvCpnAmt");
+//
+//				// 환불금액
+//				log.info("============== 환불 금액 ==============");
+//
+//				if (TsaConstants.MallGb.SELFMALL.value().equals(mallGb)) {	// 자사몰인경우
+//					refundAmt = refundAmt + totRfDelvFee - refundCancelCartCpnAmt;
+//				}
+//
+//				log.info("refundAmt = " + refundAmt);
+//				log.info("custShipAmt = " + custShipAmt);
+//				log.info("orgDelvFee = " + orgDelvFee);
+//				log.info("refundGoodsCpnAmt = " + refundGoodsCpnAmt);
+//				log.info("refundCartCpnAmt = " + (refundCartCpnAmt + refundCancelCartCpnAmt));
+//				log.info("refundPntAmt = " + refundPntAmt);
+//				log.info("refundPrePntAmt = " + refundPrePntAmt);
+//				log.info("refundCancelCartCpnAmt = " + refundCancelCartCpnAmt);
+//				log.info("refundPlusCpnAmt = " + refundPlusCpnAmt);
+//				log.info("totRfDelvFee = " + totRfDelvFee);
+//				log.info("rfDelvCpnAmt = " + rfDelvCpnAmt);
+//
+//				// 환불정보
+//				if (TsaConstants.MallGb.SELFMALL.value().equals(mallGb)) {	// 자사몰만 환불정보 등록
+//					if (PayMeans.ACCOUNT_DEPOSIT.value().equals(pay.getPayMeans())) {
+//						pay.setOrdChgSq(ordChgSq);
+//						TsaOrder paramRefund = orderDao.getRefundAccount(pay);
+//
+//						if (paramRefund != null) {
+//							pay.setRaBnk(paramRefund.getRaBnk());
+//							pay.setRaNm(paramRefund.getRaNm());
+//							pay.setRaNo(paramRefund.getRaNo());
+//						} else {
+//							paramRefund = orderDao.getCustomerDefaultAccount(Integer.toString(custNo));
+//							if (paramRefund != null) {
+//								pay.setRaNo(paramRefund.getRaNo());
+//								pay.setRaNm(paramRefund.getRaNm());
+//								pay.setRaBnk(paramRefund.getRaBnk());
+//							}
+//						}
+//						if (paramRefund == null) {
+//							throw new IllegalStateException("환불계좌정보가 없습니다.");
+//						}
+//						paramRefund.setOrdNo(Long.toString(ordNo));
+//						paramRefund.setPaySq(pay.getPaySq());
+//						paramRefund.setOrdChgSq(ordChgSq);
+//						paramRefund.setRefundAmt(refundAmt);
+//						paramRefund.setRfGoodsCpnAmt(refundGoodsCpnAmt + refundPlusCpnAmt + rfDelvCpnAmt);
+//						paramRefund.setRfCartCpnAmt(refundCartCpnAmt + refundCancelCartCpnAmt);
+//						paramRefund.setRfPntAmt(refundPntAmt);
+//						paramRefund.setRfPrePntAmt(refundPrePntAmt);
+//						paramRefund.setRegId(userId);
+//						orderDao.createRefund(paramRefund);
+//					} else {
+//						TsaOrder paramRefund = new TsaOrder();
+//						paramRefund.setOrdNo(Long.toString(ordNo));
+//						paramRefund.setPaySq(pay.getPaySq());
+//						paramRefund.setOrdChgSq(ordChgSq);
+//						paramRefund.setRefundAmt(refundAmt);
+//						paramRefund.setRfGoodsCpnAmt(refundGoodsCpnAmt + refundPlusCpnAmt + rfDelvCpnAmt);
+//						paramRefund.setRfCartCpnAmt(refundCartCpnAmt + refundCancelCartCpnAmt);
+//						paramRefund.setRfPntAmt(refundPntAmt);
+//						paramRefund.setRfPrePntAmt(refundPrePntAmt);
+//						paramRefund.setRegId(userId);
+//						orderDao.createRefund(paramRefund);
+//					}
+//				}
+//
+//				int payAmt = orgPayAmt - refundAmt;
+//
+//				String partCancelYn = "N";
+//
+//				if (orgPaySq > 1) {
+//					partCancelYn = "Y";
+//				}
+//
+//				if (payAmt > 0) {
+//					paramPay.setPaySq(paySq);
+//					paramPay.setPayAmt(payAmt);
+//					paramPay.setPayStat(PaymentStat.PAYMENT_COMPLETE.value());
+//					paramPay.setRegId(userId);
+//					paramPay.setUpdId(userId);
+//					paramPay.setOrgPaySq(pay.getPaySq());
+//					orderDao.createPayment(paramPay);
+//
+//					partCancelYn = "Y";
+//					devlFeePaySq = paySq;
+//				}
+//
+//				// 매출반영
+//				// ERP 판매반영 생성
+//				for (Withdraw withdraw : ifOnilneSales) {
+//					withdraw.setPayAmt(payAmt);
+//					withdraw.setRefundAmt(refundAmt);
+//					withdraw.setRegId(userId);
+//					createIfEcpTbSalesReturn(withdraw);
+//				}
+//
+//				boolean checkPay = orgPayAmt - payAmt < 0 ? true : false;
+//				if (checkPay) {
+//					throw new IllegalStateException("결제금액과 환불정보가 맞지 않습니다.");
+//				}
+//
+//				/* PG결제취소 */
+//
+//				TsaPayGate paramPg = new TsaPayGate();
+//				paramPg.setPgShopId(pay.getPgShopId());	// 상점아이디
+//				paramPg.setPgGb(pay.getPgGb());    // pg구분
+//				paramPg.setTid(pay.getPgTid());    // 거래번호
+//				paramPg.setCancelAmt(refundAmt);    // 취소금액
+//				paramPg.setPartCancelYn(partCancelYn);    // 부분취소여부
+//
+//				if (TsaConstants.PayMeans.ACCOUNT_DEPOSIT.value().equals(pay.getPayMeans())) {        // 무통입금일때
+//					paramPg.setRefundYn("Y");
+//					paramPg.setRefundBankCd(pay.getRaBnk());    // 환불은행코드
+//					paramPg.setRefundAcctNo(pay.getRaNo());    // 환불계좌번호
+//					paramPg.setRefundAcctNm(pay.getRaNm());    // 환불계좌주명
+//				}
+//
+//				// 자사몰이고 결제완료이고 PG점프가 아닌경우 PG와 통신한다.
+//				if (TsaConstants.MallGb.SELFMALL.value().equals(mallGb)
+//					&& TsaConstants.PaymentStat.PAYMENT_COMPLETE.value().equals(pay.getOrgPayStat()) && "N".equals(pgStat)) {
+//
+//					GagaMap result = orderService.cancelPgPayment(paramPg);
+//
+//					if (result.getBoolean("success")) {        // 00:취소성공
+//						result.put("resultCd", "00");
+//						result.put("resultMsg", "결제취소가 완료되었습니다.");
+//						pay.setPgCnclTid(result.getString("TID"));
+//					} else {
+//						throw new IllegalStateException(result.getString("ResultMsg"));        // PG처리 실패시 전체 ROLLBACK 처리함.
+//					}
+//
+//				}
+//
+//				if (payAmt == 0) {
+//					paySq = orgPaySq;
+//					pay.setPayStat(TsaConstants.PaymentStat.PAYMENT_CANCEL.value());
+//				}
+//
+//				orderDao.updatePayment(pay);
+//
+//				// 카카오 알림톡 전송
+//				try {
+//					if (TsaConstants.MallGb.SELFMALL.value().equals(mallGb)) {
+//						kakaoService.sendReturnComplete(params, withdrawList);
+//					}
+//				} catch (Exception e) {
+//					e.fillInStackTrace();
+//				}
+//
+//			} else {// 교환인 경우
+//
+//				// 교환출고처 지정대기(26) 상태인 놈을 출고처 예정(34) 으로 업데이트
+//				for (Withdraw withdraw : ifOnilneSales) {
+//					withdrawDao.updateExchangeLocAssignStatus(withdraw);
+//					withdraw.setUpdId(userId);
+//					withdraw.setRegId(userId);
+//					withdrawDao.createWithdrawOrderDetailHstInfo(withdraw); // 원주문상세번호에 대한 이력
+//					withdrawDao.createWithdrawOrderDetailHstInfo2(withdraw); // 교환 주문상세번호에 대한 이력
+//				}
+//
+//				// 매출반영 환입 ERP 판매반영 생성
+//				for (Withdraw withdraw : ifOnilneSales) {
+//					withdraw.setRegId(userId);
+//					createIfEcpTbSalesReturn(withdraw);
+//				}
+//				// 카카오 알림톡 전송
+//				try {
+//					if (TsaConstants.MallGb.SELFMALL.value().equals(mallGb)) {
+//						kakaoService.sendWithdrawConfirm(params, withdrawList);
+//					}
+//				} catch (Exception e) {
+//					e.fillInStackTrace();
+//				}
+//			}
+//
+//		}
+//
+	}
+
+	/**
+	 * ERP 환입반영처리
+	 *
+	 * @param withdraw - 주문 정보
+	 * @return
+	 * @author yh98kim
+	 * @since 2020. 05. 13
+	 */
+//	@Transactional("shopTxnManager")
+//	public void createIfEcpTbSalesReturn(Withdraw withdraw) {
+//		if ("S".equals(withdraw.getGoodsType())) {
+//			// 세트의 단품별 비중을 구한다.
+//			Collection<Withdraw> withdrawList = withdrawDao.getWithdrawDetailList2(withdraw);
+//			int totCnt = withdrawList.size();
+//			int cnt = 0;
+//
+//			int sumDivRfPntAmt = 0;
+//			int sumDivRfPrePntAmt = 0;
+//			int sumDivRfGoodsCpnAmt = 0;
+//			int sumDivRfCartCpnAmt = 0;
+//			int sumDivRfPlusCpnAmt = 0;
+//			int sumDivRfSavePntAmt = 0;
+//
+//			int rfPntAmt = withdraw.getRfPntAmt();
+//			int rfPrePntAmt = withdraw.getRfPrePntAmt();
+//			int rfGoodsCpnAmt = withdraw.getRfGoodsCpnAmt();
+//			int rfCartCpnAmt = withdraw.getRfCartCpnAmt();
+//			int rfPlusCpnAmt = withdraw.getRfPlusCpnAmt();
+//			int rfSavePntAmt = withdraw.getSavePntAmt();
+//
+//			int wdQty = withdraw.getWdQty();	// 회수수량
+//			int realOrdAmt = withdraw.getRealOrdAmt();	// 실주문금액
+//
+//			GagaMap gMap = new GagaMap();
+//
+//			for (Withdraw wd : withdrawList) {
+//				int divRfPntAmt = 0;
+//				int divRfPrePntAmt = 0;
+//				int divRfGoodsCpnAmt = 0;
+//				int divRfCartCpnAmt = 0;
+//				int divRfPlusCpnAmt = 0;
+//				int divRfSavePntAmt = 0;
+//
+//				// item 별 비중: 회수수량 * itemQty * itemPrice / realOrdAmt
+//				// 소수점 2째짜리까지 비중을 구한다.
+//				Double rate = Math.round(wdQty * wd.getItemQty() * wd.getItemPrice() / realOrdAmt * 100) / 100.0;
+//
+//				if (totCnt > 1 && cnt == totCnt - 1) {	// 마지막 건인 경우 쿠폰 포인트는 총계에서 나머지 합계를 빼서 구한다.
+//					divRfPntAmt = rfPntAmt - sumDivRfPntAmt;
+//					divRfPrePntAmt = rfPrePntAmt - sumDivRfPrePntAmt;
+//					divRfGoodsCpnAmt = rfGoodsCpnAmt - sumDivRfPrePntAmt;
+//					divRfCartCpnAmt = rfCartCpnAmt - sumDivRfGoodsCpnAmt;
+//					divRfPlusCpnAmt = rfPlusCpnAmt - sumDivRfPlusCpnAmt;
+//					divRfSavePntAmt = rfSavePntAmt - sumDivRfSavePntAmt;
+//				} else {
+//					divRfPntAmt = (int)Math.round(rfPntAmt * rate);
+//					divRfPrePntAmt = (int)Math.round(rfPrePntAmt * rate);
+//					divRfGoodsCpnAmt = (int)Math.round(rfGoodsCpnAmt * rate);
+//					divRfCartCpnAmt = (int)Math.round(rfCartCpnAmt * rate);
+//					divRfPlusCpnAmt = (int)Math.round(rfPlusCpnAmt * rate);
+//					divRfSavePntAmt = (int)Math.round(rfSavePntAmt * rate);
+//
+//					sumDivRfPntAmt += divRfPntAmt;
+//					sumDivRfPrePntAmt += divRfPrePntAmt;
+//					sumDivRfGoodsCpnAmt += divRfGoodsCpnAmt;
+//					sumDivRfCartCpnAmt += divRfCartCpnAmt;
+//					sumDivRfPlusCpnAmt += divRfPlusCpnAmt;
+//					sumDivRfSavePntAmt += divRfSavePntAmt;
+//				}
+//				wd.setRfPntAmt(divRfPntAmt);
+//				wd.setRfPrePntAmt(divRfPrePntAmt);
+//				wd.setRfGoodsCpnAmt(divRfGoodsCpnAmt);
+//				wd.setRfCartCpnAmt(divRfCartCpnAmt);
+//				wd.setRfPlusCpnAmt(divRfPlusCpnAmt);
+//				wd.setRfSavePntAmt(divRfSavePntAmt);
+//				wd.setOrdAmt(wdQty * wd.getItemQty() * wd.getItemPrice());
+//				int tmpRealOrdAmt = wdQty * wd.getItemQty() * wd.getItemPrice() - (divRfPntAmt - divRfPrePntAmt - divRfGoodsCpnAmt - divRfCartCpnAmt - divRfPlusCpnAmt);
+//				wd.setRealOrdAmt(tmpRealOrdAmt);
+//
+//				withdrawDao.createIfEcpTbSalesReturn(withdraw);
+//
+//				cnt++;
+//			}
+//		} else {
+//			withdrawDao.createIfEcpTbSalesReturn(withdraw);
+//		}
+//	}
+
+	/**
+	 * 배송비 처리
+	 *
+	 * @param params - 주문 정보
+	 * @return
+	 * @author yh98kim
+	 * @since 2020. 05. 13
+	 */
+//	@Transactional("shopTxnManager")
+//	public GagaMap deliveryFeeProcess(Withdraw params, int paySq, String chgReasonCds) {
+//		GagaMap resultMap = new GagaMap();
+//		TsaOrder order = new TsaOrder();
+//		order.setOrdNo(Long.toString(params.getOrdNo()));
+//		Collection<TsaOrder> delvFeeList = orderDao.getSupplyCompDelvFeeList(order);
+//		String regId = TsaSession.getInfo().getUserId();
+//		String ordNo = order.getOrdNo();
+//		String chgReasonDesc = order.getChgReasonDesc();
+//		int totDelvFee = 0;                    // 환불할 총배송비
+//		int selfYCnt = 0;                    // 자사상품 카운트
+//		String selfYSupplyCompCd = "";        // 자사상품 대표업체코드
+//		int selfYDelvFee = 0;                // 자사상품 결제한배송비
+//		int selfYAddDelvFee = 0;
+//		int selfYMinOrdAmt = 9999999;        // 자사상품 무료배송 최소주문금액
+//		int selfYSumRealOrdAmt = 0;            // 자사상품 총결제금액
+//		Long selfYdelvCpnSq = null;			// 배송비쿠폰
+//		int selfYDelvCpnAmt = 0;
+//		int rfDelvCpnAmt = 0;
+//
+//		TsaOrder setParams = new TsaOrder();
+//		setParams.setOrdNo(ordNo);
+//		setParams.setPaySq(paySq);
+//		setParams.setOrdChgSq(params.getOrdChgSq());
+//
+//		// 교환배송비 부과여부
+//		boolean bExchDelvFee = false; // true: 교환배송비 부과, false: 교환배송비 부과안함
+//
+//		String delvFeeGb = TsaConstants.DeliveryFeeGb.RETURN_DELIVERY_FEE.value();
+//		if (TsaConstants.OrderChangeGb.EXCHANGE.value().equals(params.getChgGb())) {
+//			delvFeeGb = TsaConstants.DeliveryFeeGb.EXCHANGE_DELIVERY_FEE.value();	// 교환
+//			if (chgReasonCds.contains(params.getChgReason())) {	// 고객귀책인 경우
+//				bExchDelvFee = true;
+//			}
+//		}
+//		setParams.setDelvFeeGb(delvFeeGb);
+//		setParams.setDelvUsacYn("N");
+//		setParams.setRegId(regId);
+//		setParams.setUpdId(regId);
+//
+//		// 회수비(반품배송비) 부과여부
+//		boolean bRtnDelvFee = true;	// true: 회수비 부과, false: 회수비 부과안함
+//		// 주문당 변경건수
+//		int chgCnt = deliveryDao.getOrdReturnChgCnt(params.getOrdNo());
+//		// 회원이고 고객귀책인 경우에 주문당 1회만 회수비 무료
+//		if (params.getCustNo() != 0 && chgReasonCds.contains(params.getChgReason())) {	// 고객귀책
+//			if (chgCnt == 1) {
+//				bRtnDelvFee = false;
+//			}
+//		}
+//
+//		for (TsaOrder oneData : delvFeeList) {
+//
+//			String selfYn = oneData.getSelfYn();
+//			String supplyCompCd = oneData.getSupplyCompCd();
+//
+//			int payDelvFee = oneData.getPayDelvFee();
+//			int delvFee = oneData.getDelvFee();
+//			int sumRealOrdAmt = oneData.getSumRealOrdAmt();
+//			int sumCnclRtnAmt = oneData.getSumCnclRtnAmt();
+//			int minOrdAmt = oneData.getMinOrdAmt();
+//			int delvCpnAmt = oneData.getDelvCpnAmt();
+//			Long delvCpnSq = oneData.getDelvCpnSq();
+//
+//			log.debug("################# sumRealOrdAmt : {}", sumRealOrdAmt);
+//			log.debug("################# sumCnclRtnAmt : {}", sumCnclRtnAmt);
+//
+//			if (selfYn.equals("Y")) {    // 자사
+//				if (selfYCnt == 0) {    // 자사 대표업체코드 : 업체코드로 DESC 해서 가져옴 - 파스텔(W), 플라인타이거(F)
+//					selfYSupplyCompCd = supplyCompCd;
+//					selfYDelvFee = payDelvFee;
+//					selfYAddDelvFee = delvFee;
+//				}
+//				if (minOrdAmt < selfYMinOrdAmt) {
+//					selfYMinOrdAmt = minOrdAmt;
+//				}
+//
+//				if (selfYDelvCpnAmt == 0) {
+//					selfYDelvCpnAmt = delvCpnAmt;
+//					selfYdelvCpnSq = delvCpnSq;
+//				}
+//
+//				selfYSumRealOrdAmt += sumRealOrdAmt;
+//				selfYCnt++;
+//			} else {    // 입점업체
+//
+//				if (TsaConstants.OrderChangeGb.EXCHANGE.value().equals(params.getChgGb())) {	// 교환인 경우
+//					if (bExchDelvFee) {	// 교환배송비 부과
+//						setParams.setDelvFee(delvFee * 2 - params.getEncloseFee());
+//						totDelvFee += delvFee * 2 - params.getEncloseFee();
+//						// TB_DELIVERY_FEE 에서 ORD_NO, ORD_CHG_SQ 조건으로 Update
+//						setParams.setSupplyCompCd(supplyCompCd);
+//						withdrawDao.mergeDeliveryFee(setParams);
+//					}
+//				} else {	// 반품인 경우
+//					if (payDelvFee > 0) {    // 결제한배송비가 있을경우
+//
+//						if (sumRealOrdAmt == 0) {    // 전체취소한경우 배송비 환불
+//
+//							// 귀책사유에 따라 배송비 환불
+//							if (!chgReasonCds.contains(params.getChgReason())) {	// 회사귀책
+//								setParams.setDelvFee(-payDelvFee - params.getEncloseFee());
+//								totDelvFee += payDelvFee - delvCpnAmt + params.getEncloseFee();
+//							} else {	// 고객귀책
+//								if (bRtnDelvFee) {	// 회수비 부과
+//									setParams.setDelvFee(delvFee - params.getEncloseFee());	// 회수배송비(delvFee) - 동봉비
+//									// 총환불배송비 = 동봉비 - 배송쿠폰금액 - 고객부담배송비
+//									totDelvFee += params.getEncloseFee() - delvCpnAmt - delvFee;
+//								} else {
+//									setParams.setDelvFee(0 - params.getEncloseFee());	// 회수배송비(delvFee) - 동봉비
+//									// 총환불배송비 = 동봉비 - 배송쿠폰금액 - 고객부담배송비(0)
+//									totDelvFee += params.getEncloseFee() - delvCpnAmt;
+//								}
+//							}
+//
+//							setParams.setSupplyCompCd(supplyCompCd);
+//							orderDao.createDeliveryFee(setParams);
+//
+//							if (delvCpnSq != null && delvCpnSq > 0L) {
+//								TsaCoupon delvCpnInfo = orderDao.getCustCouponInfo(delvCpnSq);
+//								delvCpnInfo = orderDao.getCouponInfo(delvCpnInfo.getCpnId());
+//
+//								if ("10".equals(delvCpnInfo.getReissuance()) || "30".equals(delvCpnInfo.getReissuance())) {
+//									TsaOrder delvCpnParam = new TsaOrder();
+//									delvCpnParam.setUpdId(regId);
+//									delvCpnParam.setCustCpnSq(delvCpnSq);
+//									orderDao.updateCustCouponCancel(delvCpnParam);
+//								}
+//								rfDelvCpnAmt += delvCpnAmt;
+//							}
+//						}
+//					} else {
+//						if (delvCpnAmt == 0) {    // 결제한배송비가 없었을경우(배송비 쿠폰 사용시 계산 필요없음)
+//							if (chgReasonCds.contains(params.getChgReason())) {	// 고객귀책
+//								if (sumRealOrdAmt < minOrdAmt) {    // 무료배송최소주문금액보다 작을경우 배송비 발생
+//									if (bRtnDelvFee) {	// 회수비 부과
+//										setParams.setDelvFee(delvFee * 2);	// 회수배송비+원주문배송비
+//										totDelvFee -= delvFee * 2;
+//									} else {
+//										setParams.setDelvFee(0);
+//									}
+//								} else {
+//									if (bRtnDelvFee) {	// 회수비 부과
+//										setParams.setDelvFee(delvFee);	// 회수배송비
+//										totDelvFee -= delvFee;
+//									} else {
+//										setParams.setDelvFee(0);	// 회수배송비
+//									}
+//								}
+//								setParams.setSupplyCompCd(supplyCompCd);
+//								orderDao.createDeliveryFee(setParams);
+//							}
+//						}
+//					}
+//				}
+//			}
+//
+//		} /* ~for */
+//
+//		/* 자사상품 배송비 등록 */
+//		if (selfYCnt > 0) {
+//
+//			if (TsaConstants.OrderChangeGb.EXCHANGE.value().equals(params.getChgGb())) {	// 교환인 경우
+//				if (bExchDelvFee) {	// 교환배송비 부과
+//					setParams.setDelvFee(selfYAddDelvFee * 2 - params.getEncloseFee());
+//					totDelvFee += selfYAddDelvFee * 2 - params.getEncloseFee();
+//					// TB_DELIVERY_FEE 에서 ORD_NO, ORD_CHG_SQ 조건으로 Update
+//					setParams.setSupplyCompCd(selfYSupplyCompCd);
+//					withdrawDao.mergeDeliveryFee(setParams);
+//				}
+//
+//			} else {
+//
+//				if (selfYDelvFee > 0) {    // 결제한배송비가 있을경우
+//
+//					if (selfYSumRealOrdAmt == 0) {    // 전체취소한경우 배송비 환불
+//						// 귀책사유에 따라 배송비 환불
+//						if (!chgReasonCds.contains(params.getChgReason())) {	// 회사귀책
+//							setParams.setDelvFee(selfYDelvFee * -1 - params.getEncloseFee());
+//							totDelvFee += selfYDelvFee - selfYDelvCpnAmt + params.getEncloseFee();
+//						} else {
+//							if (bRtnDelvFee) {	// 회수비 부과
+//								setParams.setDelvFee(selfYDelvFee * -1 - params.getEncloseFee());
+//								totDelvFee += params.getEncloseFee() - selfYDelvCpnAmt - selfYDelvFee;
+//							} else {
+//								setParams.setDelvFee(-params.getEncloseFee());
+//								totDelvFee += params.getEncloseFee() - selfYDelvCpnAmt;
+//							}
+//						}
+//						setParams.setSupplyCompCd(selfYSupplyCompCd);
+//						orderDao.createDeliveryFee(setParams);
+//
+//						if (selfYdelvCpnSq != null && selfYdelvCpnSq > 0L) {
+//							TsaCoupon delvCpnInfo = orderDao.getCustCouponInfo(selfYdelvCpnSq);
+//							delvCpnInfo = orderDao.getCouponInfo(delvCpnInfo.getCpnId());
+//
+//							if ("10".equals(delvCpnInfo.getReissuance()) || "30".equals(delvCpnInfo.getReissuance())) {
+//								TsaOrder delvCpnParam = new TsaOrder();
+//								delvCpnParam.setUpdId(regId);
+//								delvCpnParam.setCustCpnSq(selfYdelvCpnSq);
+//								orderDao.updateCustCouponCancel(delvCpnParam);
+//							}
+//
+//							rfDelvCpnAmt += selfYDelvCpnAmt;
+//						}
+//
+//					} else {
+//						if (bRtnDelvFee) {	// 회수비 부과
+//							setParams.setDelvFee(-selfYDelvFee);
+//						} else {
+//							setParams.setDelvFee(0);
+//						}
+//						setParams.setSupplyCompCd(selfYSupplyCompCd);
+//						orderDao.createDeliveryFee(setParams);
+//						totDelvFee -= selfYDelvCpnAmt;
+//					}
+//
+//				} else {
+//					if (selfYDelvCpnAmt == 0) {							// 결제한배송비가 없었을경우(배송비 쿠폰 사용시 계산 필요없음)
+//						if (chgReasonCds.contains(params.getChgReason())) {	// 고객귀책
+//							if (selfYSumRealOrdAmt < selfYMinOrdAmt) {		// 무료배송최소주문금액보다 작을경우 배송비 발생
+//								if (bRtnDelvFee) {	// 회수비 부과
+//									setParams.setDelvFee(selfYAddDelvFee * 2);
+//									totDelvFee -= selfYAddDelvFee * 2;
+//								} else {
+//									setParams.setDelvFee(0);
+//									totDelvFee -= 0;
+//								}
+//								setParams.setSupplyCompCd(selfYSupplyCompCd);
+//								orderDao.createDeliveryFee(setParams);
+//							} else {									// 무료배송금액보다 큰 경우에는 회수비만 부과
+//								if (bRtnDelvFee) {	// 회수비 부과
+//									setParams.setDelvFee(selfYAddDelvFee);
+//									totDelvFee -= selfYAddDelvFee;
+//									setParams.setSupplyCompCd(selfYSupplyCompCd);
+//									orderDao.createDeliveryFee(setParams);
+//								}
+//							}
+//						}
+//					}
+//				}
+//			}
+//		}
+//
+//		resultMap.setInt("totDelvFee", totDelvFee);
+//		resultMap.setInt("rfDelvCpnAmt", rfDelvCpnAmt);
+//
+//		return resultMap;
+//	}
+
+	/**
+	 * 회수관리 - 주문상세 남은상품에 대한 장바구니쿠폰 처리
+	 *
+	 * @param ordNo
+	 * @param ordChgSq
+	 * @param buyLimitAmt
+	 * @return int
+	 * @author rladbwnd5
+	 * @since 2020. 02. 17
+	 */
+//	@Transactional("shopTxnManager")
+//	private int orderDetailCouponCancel(Long ordNo, Long ordChgSq, int buyLimitAmt) {
+//		int refundCancelCartCpnAmt = 0;
+//		String userId = TsaSession.getInfo().getUserId();
+//
+//		Withdraw searchParam = new Withdraw();
+//		searchParam.setOrdNo(ordNo);
+//		searchParam.setOrdChgSq(ordChgSq);
+//		Withdraw remianGoodsInfo = withdrawDao.getRemainGoodsInfo(searchParam);
+//
+//		if (remianGoodsInfo.getRealOrdAmt() < buyLimitAmt) {
+//			Collection<Withdraw> remainOrderDetailList = withdrawDao.getWithdrawRemainOrderDetailList(searchParam);
+//
+//			for (Withdraw orderDetail : remainOrderDetailList) {
+//				// 기존 정산 취소
+//				Withdraw paramCancelUsac = new Withdraw();
+//				paramCancelUsac.setUsacGb(UsacGb.PURCHASE_RETURN.value());
+//				paramCancelUsac.setPrtnGb("40"); // 해택할인취소 PurchaseReturnGb.CANCEL.value() 명칭 필요할 듯
+//				paramCancelUsac.setOrdDtlNo(orderDetail.getOrdDtlNo());
+//				paramCancelUsac.setOrgUsacGb(UsacGb.SELL.value());
+//				paramCancelUsac.setUsacQty(orderDetail.getOrdQty());
+//				paramCancelUsac.setGoodsCpnDcAmt(orderDetail.getGoodsCpnDcAmt());
+//				paramCancelUsac.setCartCpnDcAmt(orderDetail.getCartCpnDcAmt());
+//				paramCancelUsac.setPlusCpnDcAmt(orderDetail.getPlusCpnDcAmt());
+//				paramCancelUsac.setPntDcAmt(orderDetail.getPntDcAmt());
+//				paramCancelUsac.setPrePntDcAmt(orderDetail.getPrePntDcAmt());
+//				paramCancelUsac.setRegId(userId);
+//				paramCancelUsac.setPlusCpnDcAmt(orderDetail.getPlusCpnDcAmt());
+//				withdrawDao.createWithdrawUsac(paramCancelUsac);
+//
+//				refundCancelCartCpnAmt += orderDetail.getCartCpnDcAmt();
+//				orderDetail.setRealOrdAmt(orderDetail.getRealOrdAmt() + orderDetail.getCartCpnDcAmt());
+//				orderDetail.setCartCpnDcAmt(0);
+//				orderDetail.setCartCpnSq(null);
+//				orderDetail.setUpdId(userId);
+//				orderDetail.setRegId(userId);
+//				withdrawDao.updateWithdrawOrderDetailInfo(orderDetail);
+//				withdrawDao.createWithdrawOrderDetailHstInfo(orderDetail);
+//
+//				// 재정산
+//				Withdraw paramUsac = new Withdraw();
+//				paramUsac.setUsacGb(UsacGb.SELL.value());
+//				paramUsac.setPrtnGb(null);
+//				paramUsac.setOrdDtlNo(orderDetail.getOrdDtlNo());
+//				paramUsac.setOrgUsacGb(UsacGb.SELL.value());
+//				paramUsac.setUsacQty(orderDetail.getOrdQty());
+//				paramUsac.setGoodsCpnDcAmt(orderDetail.getGoodsCpnDcAmt());
+//				paramUsac.setCartCpnDcAmt(orderDetail.getCartCpnDcAmt());
+//				paramUsac.setPlusCpnDcAmt(orderDetail.getPlusCpnDcAmt());
+//				paramUsac.setPntDcAmt(orderDetail.getPntDcAmt());
+//				paramUsac.setPrePntDcAmt(orderDetail.getPrePntDcAmt());
+//				paramUsac.setPlusCpnDcAmt(orderDetail.getPlusCpnDcAmt());
+//				paramUsac.setRegId(userId);
+//				withdrawDao.createWithdrawUsac(paramUsac);
+//			}
+//		}
+//
+//		return refundCancelCartCpnAmt;
+//	}
+
+	/**
+	 * 환불관리 - 주문번호 전체 금액
+	 *
+	 * @param ordNo
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	public Withdraw getOrderDetailSumAmt(String ordNo) {
+		return withdrawDao.getOrderDetailSumAmt(ordNo);
+	}
+
+	/**
+	 * 환불목록
+	 *
+	 * @param withdraw
+	 * @return Withdraw List
+	 * @author yujung
+	 * @since 2020. 05. 29
+	 */
+//	public Collection<Withdraw> getRefundCompleteList(Withdraw withdraw) {
+//		return withdrawDao.getRefundCompleteList(withdraw);
+//	}
+
+	/**
+	 * 반품신청, 회수수량 비교 데이터
+	 *
+	 * @param withdraw
+	 * @return Withdraw
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	public Withdraw getSumChgQtyWdQty(Withdraw withdraw) {
+		return withdrawDao.getSumChgQtyWdQty(withdraw);
+	}
+
+	/**
+	 * wms 회수요청
+	 *
+	 * @param
+	 * @return
+	 * @author cjs
+	 * @since 2020. 07. 14
+	 */
+//	@Transactional("wmsTxnManager")
+//	public void saveWmsWithdrawRequest(TsaOrder order) {
+//
+//		String userId = TsaSession.getInfo().getUserId();
+//
+//		String reqSn = wmsWithdrawDao.getRequestSn();
+//		order.setSeq(reqSn);
+//
+//		order.setInvoiceNo("123412341");
+//		order.setOrdChgSq(3);
+//		order.setRecipNm("반품자");
+//		order.setRecipTelno("010-111-1111");
+//		order.setRecipPhnno("010-2222-2222");
+//		order.setRecipPostNo("12345");
+//		order.setRecipBaseAddr("서울시 강남구 논현로 323");
+//		order.setRecipDtlAddr("MTU 빌딩 6층 전산실");
+//		order.setChgMemo("사이즈가 작아요");
+//		order.setChgerRtnMemo("물류메모");
+//		order.setChgGb("40");
+//		order.setChgReason("13");
+//		order.setRegDt("20200505121212");
+//		order.setChgQty(1);
+//		order.setChgRegDt("20200505121212");
+//		order.setChgerNm("변경자");
+//		if (order.getSellStoreCd() == null || order.getSellStoreCd().isEmpty()) {
+//			order.setSellStoreCd("PASTEL");
+//		}
+//		order.setOrdDtlNos(order.getOrdDtlNo());
+//		order.setChgQtys(Integer.toString(order.getChgQty()));
+//
+//		/* 1.회수요청 Header 등록 */
+//		wmsWithdrawDao.createWithdrawHeader(order);
+//
+//		/* 2.회수요청 Detail 등록 */
+//		int cnt = 0;
+//		order.setChgStat(TsaConstants.OrderChangeStat.RETURN.value());
+//		String[] ordDtlNoArr = order.getOrdDtlNos().split(",");
+//		String[] chgQtyArr = order.getChgQtys().split(",");
+//
+//		for (String ordDtlNo : ordDtlNoArr) {
+//			if (!StringUtils.isBlank(ordDtlNo)) {
+//				order.setOrdDtlNo(ordDtlNo);
+//				order.setChgQty(Integer.parseInt(chgQtyArr[cnt]));
+//				wmsWithdrawDao.createWithdrawDetail(order);
+//			}
+//			cnt++;
+//		}
+//	}
+}

+ 242 - 0
src/main/java/com/style24/admin/biz/web/TsaBoardController.java

@@ -0,0 +1,242 @@
+package com.style24.admin.biz.web;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaFaqService;
+import com.style24.admin.biz.service.TsaNoticeService;
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Faq;
+import com.style24.persistence.domain.Notice;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.util.GagaFileUtil;
+
+/**
+ * 게시판 Controller
+ *
+ * @author gagamel
+ * @since 2020. 10. 30
+ */
+@Controller
+@RequestMapping("/board")
+@Slf4j
+public class TsaBoardController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaNoticeService noticeService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Value("${upload.default.target.path}")
+	private String uploadTargetPath;
+
+	@Autowired
+	private TsaFaqService faqService;
+
+	/**
+	 * 공지사항 화면
+	 * @param noticeType - 공지유형(10:사이트공지, 20:내부공지)
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	@GetMapping("/notice/form/{noticeType}")
+	public ModelAndView noticeForm(@PathVariable String noticeType) {
+		ModelAndView mav = new ModelAndView();
+
+		// 공지유형
+		mav.addObject("noticeType", noticeType);
+
+		// 수신자 목록
+		// 공지유형이 "10:사이트공지"일 때는 사이트 목록
+		// 공지유형이 "20:내부공지"일 때는 공지수신자-조직 목록
+		if (noticeType.equals(TsaConstants.NoticeType.SITE.value())) {
+			mav.addObject("noticeReceiverList", rendererService.getAvailCommonCodeList("G000"));
+		} else if (noticeType.equals(TsaConstants.NoticeType.INNER.value())) {
+			mav.addObject("noticeReceiverList", rendererService.getAvailCommonCodeList("G048"));
+		}
+
+		mav.setViewName("board/NoticeForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사이트 공지 목록
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	@PostMapping("/notice/list")
+	@ResponseBody
+	public Collection<Notice> getNoticeList(@RequestBody Notice notice) {
+		return noticeService.getNoticeList(notice);
+	}
+
+	/**
+	 * 공지사항 수신자 목록
+	 * @param noticeSq - 공지사항일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	@GetMapping("/notice/receiver/list/{noticeSq}")
+	@ResponseBody
+	public Collection<Notice> getNoticeReceiverList(@PathVariable Integer noticeSq) {
+		return noticeService.getNoticeReceiverList(noticeSq);
+	}
+
+	/**
+	 * 공지사항 파일목록 조회
+	 * @param noticeSq - 공지사항일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	@GetMapping("/notice/file/list/{noticeSq}")
+	@ResponseBody
+	public Collection<Notice> getNoticeFileList(@PathVariable Integer noticeSq) {
+		return noticeService.getNoticeFileList(noticeSq);
+	}
+
+	/**
+	 * 공지사항 저장
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	@PostMapping("/notice/save")
+	@ResponseBody
+	public GagaResponse saveNotice(@RequestBody Notice notice) {
+		noticeService.saveNotice(notice);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 첨부파일 삭제
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @throws IOException
+	 * @author gagamel
+	 * @since 2020. 3. 24
+	 */
+	@PostMapping("/notice/file/delete")
+	@ResponseBody
+	public GagaResponse deleteNoticeFile(@RequestBody Notice notice) throws IOException {
+		// 파일 삭제
+		String fileName = GagaFileUtil.getConcatenationPath(uploadTargetPath, "board", notice.getSysFileNm());
+
+		GagaFileUtil.deleteFile(fileName);
+
+		// 삭제된 파일 DB 처리
+		noticeService.deleteNoticeFile(notice);
+
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * FAQ 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@GetMapping("/faq/form")
+	public ModelAndView faqForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// FAQ유형
+		mav.addObject("faqTypeList", rendererService.getAvailCommonCodeList("G046"));
+
+		mav.setViewName("board/FaqForm");
+
+		return mav;
+	}
+
+	/**
+	 * FAQ 목록
+	 * @param faq - FAQ 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@PostMapping("/faq/list")
+	@ResponseBody
+	public Collection<Faq> getFaqList(@RequestBody Faq faq) {
+		return faqService.getFaqList(faq);
+	}
+
+	/**
+	 * FAQ 등록/수정
+	 * @param faq - FAQ 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@PostMapping("/faq/save")
+	@ResponseBody
+	public GagaResponse saveFaq(@RequestBody Faq faq) {
+		faq.setRegNo(TsaSession.getInfo().getUserNo());
+		faq.setUpdNo(TsaSession.getInfo().getUserNo());
+		faqService.saveFaq(faq);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * FAQ 상세
+	 * @param mode - 모드(N:신규, U:상세)
+	 * @param faqSq - FAQ일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@GetMapping("/faq/detail/form")
+	public ModelAndView faqDetailForm(@RequestParam(value = "mode") String mode, @RequestParam(value = "faqSq", required = false) Integer faqSq) {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// FAQ유형
+		mav.addObject("faqTypeList", rendererService.getAvailCommonCodeList("G046"));
+
+		// 모드 값
+		mav.addObject("mode", mode);
+
+		if ("U".equals(mode)) {
+			mav.addObject("faqInfo", faqService.getFaq(faqSq));
+		}
+
+		mav.setViewName("board/FaqDetailForm");
+
+		return mav;
+	}
+
+}

+ 634 - 0
src/main/java/com/style24/admin/biz/web/TsaBusinessController.java

@@ -0,0 +1,634 @@
+package com.style24.admin.biz.web;
+
+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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaBusinessService;
+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.TscEnvsetService;
+import com.style24.core.support.env.TscConstants;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Aflink;
+import com.style24.persistence.domain.Brand;
+import com.style24.persistence.domain.BrandMd;
+import com.style24.persistence.domain.DeliveryLoc;
+import com.style24.persistence.domain.DelvFeePolicy;
+import com.style24.persistence.domain.SellStore;
+import com.style24.persistence.domain.ShipCompany;
+import com.style24.persistence.domain.SiteBrand;
+import com.style24.persistence.domain.StockSyncBase;
+import com.style24.persistence.domain.SupplyCompany;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+
+/**
+ * 영업관리 Controller
+ *
+ * @author gagamel
+ * @since 2020. 10. 14
+ */
+@Controller
+@RequestMapping("/business")
+@Slf4j
+public class TsaBusinessController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaBusinessService businessService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TscEnvsetService cenvsetService;
+
+	/**
+	 * 공급업체관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	@GetMapping("/supply/company/form")
+	public ModelAndView supplyCompanyForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 입점상태
+		mav.addObject("supplyStatList", rendererService.getAvailCommonCodeList("G010"));
+
+		// 유통구분
+		mav.addObject("distributionGbList", rendererService.getAvailCommonCodeList("G065"));
+
+		// 은행
+		mav.addObject("bankList", rendererService.getAvailCommonCodeList("G940"));
+
+		// 정산일
+		mav.addObject("settleDayList", rendererService.getAvailCommonCodeList("G075"));
+
+		mav.setViewName("/business/SupplyCompanyForm");
+
+		return mav;
+	}
+
+	/**
+	 * 공급업체관리 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	@PostMapping("/supply/company/list")
+	@ResponseBody
+	public Collection<SupplyCompany> getCompanyList(@RequestBody SupplyCompany supplyComp) {
+		return businessService.getSupplyCompanyList(supplyComp);
+	}
+
+	/**
+	 * 공급업체관리 저장 처리
+	 * @param supplyComp - 공급업체 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 14
+	 */
+	@PostMapping("/supply/company/save")
+	@ResponseBody
+	public GagaResponse saveSupplyInfo(@RequestBody SupplyCompany supplyComp) {
+		supplyComp.setRegNo(TsaSession.getInfo().getUserNo());
+		supplyComp.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		businessService.saveSupplyCompany(supplyComp);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 공급업체출고처관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 16
+	 **/
+	@GetMapping("/supply/company/delvloc/form")
+	public ModelAndView deliveryLocForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 출고처분류
+		mav.addObject("delvLocClsfList", rendererService.getAvailCommonCodeList("G024"));
+
+		// 송장출력형태
+		mav.addObject("invoicePrintTypeList", rendererService.getAvailCommonCodeList("G025"));
+
+		mav.setViewName("business/DeliveryLocForm");
+
+		return mav;
+	}
+
+	/**
+	 * 공급업체출고처 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 16
+	 **/
+	@PostMapping("/supply/company/delvloc/list")
+	@ResponseBody
+	public Collection<DeliveryLoc> getDeliveryLocList(@RequestBody DeliveryLoc delvLoc) {
+		return businessService.getDeliveryLocList(delvLoc);
+	}
+
+	/**
+	 * 공급업체출고처 저장 처리
+	 * @param delvLoc - 출고처 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 16
+	 */
+	@PostMapping("/supply/company/delvloc/save")
+	@ResponseBody
+	public GagaResponse saveDeliveryLoc(@RequestBody DeliveryLoc delvLoc) {
+		delvLoc.setRegNo(TsaSession.getInfo().getUserNo());
+		delvLoc.setUpdNo(TsaSession.getInfo().getUserNo());
+		businessService.saveDeliveryLoc(delvLoc);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 배송비정책 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 24
+	 **/
+	@GetMapping("/delivery/fee/policy/list/{supplyCompCd}")
+	@ResponseBody
+	public Collection<DelvFeePolicy> getDeliveryFeePolicyList(@PathVariable String supplyCompCd) {
+		return businessService.getDeliveryFeePolicyList(supplyCompCd);
+	}
+
+	/**
+	 * 배송비정책 등록/수정 처리
+	 * @param delvFeePolicyList - 배송비정책 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 24
+	 */
+	@PostMapping("/delivery/fee/policy/list/save")
+	@ResponseBody
+	public GagaResponse saveDeliveryFeePolicyList(@RequestBody Collection<DelvFeePolicy> delvFeePolicyList) {
+		if (delvFeePolicyList == null || delvFeePolicyList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		businessService.saveDeliveryFeePolicyList(delvFeePolicyList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 브랜드관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@GetMapping("/brand/form")
+	public ModelAndView supplyCompanyBrandForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 유통구분
+		mav.addObject("distributionGbList", rendererService.getAvailCommonCodeList("G065"));
+
+		// 사이트
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 구매적립포인트율
+		mav.addObject("pntInfo", cenvsetService.getEnvset(TscConstants.Site.STYLE24.value(), "C15"));
+
+		mav.setViewName("business/BrandForm");
+
+		return mav;
+	}
+
+	/**
+	 * 브랜드 목록
+	 * @param brand - 브랜드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@PostMapping("/brand/list")
+	@ResponseBody
+	public Collection<Brand> getBrandList(@RequestBody Brand brand) {
+		return businessService.getBrandList(brand);
+	}
+
+	/**
+	 * 담당MD 목록 화면
+	 * @param brandMd - 담당MD 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@GetMapping("/md/list/form")
+	public ModelAndView mdListForm(BrandMd brandMd) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("params", brandMd);
+
+		mav.setViewName("business/MdListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 브랜드담당MD 목록
+	 * @param brandCd - 브랜드코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@PostMapping("/md/list")
+	@ResponseBody
+	public Collection<BrandMd> getMdList(@RequestBody BrandMd brandMd) {
+		return businessService.getMdList(brandMd);
+	}
+
+	/**
+	 * 브랜드담당MD 목록
+	 * @param brandCd - 브랜드코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@GetMapping("/brand/md/list/{brandCd}")
+	@ResponseBody
+	public Collection<BrandMd> getBrandMdList(@PathVariable String brandCd) {
+		return businessService.getBrandMdList(brandCd);
+	}
+
+	/**
+	 * 브랜드 담당MD 등록/수정 처리
+	 * @param brandMdList - 브랜드담당MD 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@PostMapping("/brand/md/save")
+	@ResponseBody
+	public GagaResponse saveBrandMdList(@RequestBody Collection<BrandMd> brandMdList) {
+		if (brandMdList == null || brandMdList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		businessService.saveBrandMdList(brandMdList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 브랜드 노출사이트 목록
+	 * @param brandCd - 브랜드코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@GetMapping("/brand/site/list/{brandCd}")
+	@ResponseBody
+	public Collection<SiteBrand> getBrandSiteList(@PathVariable String brandCd) {
+		return businessService.getBrandSiteList(brandCd);
+	}
+
+	/**
+	 * 브랜드 노출사이트 등록/수정 처리
+	 * @param brandSiteList - 브랜드사이트 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@PostMapping("/brand/site/save")
+	@ResponseBody
+	public GagaResponse saveBrandSiteList(@RequestBody Collection<SiteBrand> brandSiteList) {
+		if (brandSiteList == null || brandSiteList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		businessService.saveBrandSiteList(brandSiteList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 브랜드 등록/수정 처리
+	 * @param brand - 브랜드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	@PostMapping("/brand/save")
+	@ResponseBody
+	public GagaResponse saveBrand(@RequestBody Brand brand) {
+		brand.setRegNo(TsaSession.getInfo().getUserNo());
+		brand.setUpdNo(TsaSession.getInfo().getUserNo());
+		businessService.saveBrand(brand);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 재고연계관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	@GetMapping("/stock/sync/form")
+	public ModelAndView stockSyncForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 자사공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd(), "Y"));
+
+		// 출고처 분류
+		String[] exceptCds = {"G024_20", "G024_30"};
+		mav.addObject("delvLocClsfList", rendererService.getCommonCodeList("G024", "Y", exceptCds));
+
+		// 정상이월구분
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+
+		mav.setViewName("business/StockSyncForm");
+
+		return mav;
+	}
+
+	/**
+	 * 재고연계관리 - 출고처 목록
+	 * @param delvLoc - 출고처 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	@PostMapping("/stock/sync/delvloc/list")
+	@ResponseBody
+	public Collection<DeliveryLoc> getStockSyncDeliveryLocList(@RequestBody DeliveryLoc delvLoc) {
+		return businessService.getStockSyncDeliveryLocList(delvLoc);
+	}
+
+	/**
+	 * 재고연계관리 - 재고연계기준 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @param delvLocCd - 출고처코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	@GetMapping("/stock/sync/base/list/{supplyCompCd}/{delvLocCd}")
+	@ResponseBody
+	public Collection<StockSyncBase> getStockSyncBaseList(@PathVariable String supplyCompCd, @PathVariable String delvLocCd) {
+		StockSyncBase stockSyncBase = new StockSyncBase();
+		stockSyncBase.setSupplyCompCd(supplyCompCd);
+		stockSyncBase.setDelvLocCd(delvLocCd);
+		return businessService.getStockSyncBaseList(stockSyncBase);
+	}
+
+	/**
+	 * 재고연계관리 - 재고연계기준 목록 저장 처리
+	 * @param stockSyncBaseList - 재고연계기준 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	@PostMapping("/stock/sync/base/save")
+	@ResponseBody
+	public GagaResponse saveStockSyncBaseList(@RequestBody Collection<StockSyncBase> stockSyncBaseList) {
+		if (stockSyncBaseList == null || stockSyncBaseList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		businessService.saveStockSyncBaseList(stockSyncBaseList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 판매매장관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@GetMapping("/sellstore/form")
+	public ModelAndView sellStoreForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		mav.setViewName("business/SellStoreForm");
+
+		return mav;
+	}
+
+	/**
+	 * 판매매장 목록
+	 * @param sellStore - 판매매장 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/sellstore/list")
+	@ResponseBody
+	public Collection<SellStore> getSellStoreList(@RequestBody SellStore sellStore) {
+		return businessService.getSellStoreList(sellStore);
+	}
+
+	/**
+	 * 판매매장 목록 저장 처리
+	 * @param sellStoreList - 판매매장 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/sellstore/list/save")
+	@ResponseBody
+	public GagaResponse saveSellStoreList(@RequestBody Collection<SellStore> sellStoreList) {
+		if (sellStoreList == null || sellStoreList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		businessService.saveSellStoreList(sellStoreList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 제휴채널관리
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@GetMapping("/aflink/form")
+	public ModelAndView aflinkForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 제휴채널 콤보박스 목록
+		mav.addObject("afChannelList", rendererService.getCommonCodeList("G053"));
+
+		mav.setViewName("business/AflinkForm");
+
+		return mav;
+	}
+
+	/**
+	 * 제휴채널 목록
+	 * @param afChannel - 제휴채널
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/aflink/list")
+	@ResponseBody
+	public Collection<Aflink> getAflinkList(@RequestParam(value = "afChannel", required = false) String afChannel) {
+		Aflink aflink = new Aflink();
+		aflink.setAfChannel(afChannel);
+		return businessService.getAflinkList(aflink);
+	}
+
+	/**
+	 * 제휴채널 저장 처리
+	 * @param aflink - 제휴링크 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/aflink/save")
+	@ResponseBody
+	public GagaResponse saveAflink(@RequestBody Aflink aflink) {
+		businessService.saveAflink(aflink);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 제휴채널 목록 사용안함 처리
+	 * @param aflinkList - 제휴링크 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/aflink/list/delete")
+	@ResponseBody
+	public GagaResponse deleteAflinkList(@RequestBody Collection<Aflink> aflinkList) {
+		if (aflinkList == null || aflinkList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		businessService.deleteAflinkList(aflinkList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 배송업체관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@GetMapping("/ship/company/form")
+	public ModelAndView deliveryCompanyForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("business/ShipCompanyForm");
+
+		return mav;
+	}
+
+	/**
+	 * 배송업체 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@GetMapping("/ship/company/list")
+	@ResponseBody
+	public Collection<ShipCompany> getShipCompanyList() {
+		return businessService.getShipCompanyList();
+	}
+
+	/**
+	 * 배송업체 목록 저장
+	 * @param shipCompList - 배송업체 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/ship/company/list/save")
+	@ResponseBody
+	public GagaResponse saveShipCompanyList(@RequestBody Collection<ShipCompany> shipCompList) {
+		if (shipCompList == null || shipCompList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		businessService.saveShipCompanyList(shipCompList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 배송업체 목록 삭제
+	 * @param shipCompList - 배송업체 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/ship/company/list/delete")
+	@ResponseBody
+	public GagaResponse deleteShipCompanyList(@RequestBody Collection<ShipCompany> shipCompList) {
+		if (shipCompList == null || shipCompList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1004"));
+		}
+
+		businessService.deleteShipCompanyList(shipCompList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 브랜드 목록 화면(팝업)
+	 * @param brand - 담당MD 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@GetMapping("/brand/search/form")
+	public ModelAndView brandSearchForm(Brand brand) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("params", brand);
+		mav.setViewName("business/BrandSearchForm");
+		return mav;
+	}
+
+	/**
+	 * 공급업체 목록 화면(팝업)
+	 * @param brandMd - 담당MD 정보
+	 * @return
+	 * @author xodud1202
+	 * @since 2020. 12. 23
+	 */
+	@GetMapping("/comapny/search/form")
+	public ModelAndView companySearchForm(SupplyCompany company) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("params", company);
+		mav.setViewName("business/SupplyCompanySearchForm");
+		return mav;
+	}
+}

+ 221 - 0
src/main/java/com/style24/admin/biz/web/TsaCommonController.java

@@ -0,0 +1,221 @@
+package com.style24.admin.biz.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaCommonService;
+import com.style24.admin.support.controller.TsaBaseController;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaFileUploadUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.gagaframework.web.util.GagaFtpUtil;
+import com.gagaframework.web.util.GagaUploadedFileInfo;
+
+/**
+ * 공통 Controller
+ *
+ * @author renderer
+ * @since 2020. 10. 22
+ */
+@Controller
+@RequestMapping("/common")
+@Slf4j
+public class TsaCommonController extends TsaBaseController {
+
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+
+	@Value("${upload.default.target.path}")
+	private String uploadTargetPath;
+
+	/**
+	 * Download a file
+	 *
+	 * @param request - HttpServletRequest
+	 * @param downloadFile - 다운로드할 파일
+	 * @return
+	 * @throws IOException
+	 * @author gagamel
+	 * @since 2019. 12. 6
+	 */
+	@GetMapping("/file/download")
+	@ResponseBody
+	public ResponseEntity<InputStreamResource> downloadFile(HttpServletRequest request, @RequestParam("downloadFile") String downloadFile) throws IOException {
+		String fileName = StringUtils.replace(downloadFile, "../", "");
+		log.debug("fileName: {}", fileName);
+
+		String downloadPath = env.getProperty("download.path");
+		log.debug("downLoadPath :{}", downloadPath);
+
+		String fileNameWithPath = GagaFileUtil.getConcatenationPath(downloadPath, fileName);
+		log.debug("fileNameWithPath: {}", fileNameWithPath);
+
+		return GagaFileUtil.writeFile(request, fileNameWithPath);
+	}
+
+	/**
+	 * Upload a file
+	 *
+	 * @param subDir - 업로드 하위 디렉토리
+	 * @param policy - 업로드 정책
+	 * @param file - MultipartFile
+	 * @return 업로드한 파일의 정보
+	 * @throws IOException
+	 * @author gagamel
+	 * @since 2019. 12. 6
+	 */
+	@PostMapping("/file/upload")
+	@ResponseBody
+	public GagaUploadedFileInfo uploadFile(@RequestParam(value = "subDir") String subDir, @RequestParam(value = "policy", required = false) String policy, MultipartFile file) throws IOException {
+		if (StringUtils.isEmpty(policy)) {
+			policy = "default";
+		}
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload." + policy + ".target.path"), subDir);
+
+		GagaFileUploadUtil fuUtil = new GagaFileUploadUtil(targetPath, Long.parseLong(env.getProperty("upload." + policy + ".max.size")), env.getProperty("upload." + policy + ".allow.extension"), env.getProperty("upload." + policy + ".view"));
+
+		GagaUploadedFileInfo ufInfo = fuUtil.uploadFile(file);
+		if (!"excel".equals(policy)) {
+			// 운영서버에서만 FTP로 파일 업로드
+			String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+			if ("run".equals(profiles) || "locp".equals(profiles)) {
+				GagaFtpUtil ftpUtil = new GagaFtpUtil(env.getProperty("speedy.ftp.host"), env.getProperty("speedy.ftp.port"), env.getProperty("speedy.ftp.username"), env.getProperty("speedy.ftp.pwd"));
+
+				File srcFile = new File(GagaFileUtil.getConcatenationPath(targetPath, ufInfo.getNewFileName()));
+				ftpUtil.upload(srcFile, "/" + subDir);
+				ftpUtil.close();
+			}
+		}
+		return ufInfo;
+	}
+
+	/**
+	 * Delete a file
+	 *
+	 * @param subDir - 업로드 하위 디렉토리
+	 * @param fileNm - 파일명
+	 * @return
+	 * @throws IOException
+	 * @author sasa004
+	 * @since 2020. 04. 06
+	 */
+	@PostMapping("/file/delete")
+	@ResponseBody
+	public void deleteFile(@RequestParam(value = "subDir") String subDir, @RequestParam(value = "fileNm", required = false) String fileNm) throws IOException {
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.default.target.path"), subDir);
+
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, fileNm));
+
+		// 운영서버이면 FTP 파일 삭제
+		String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		if ("run".equals(profiles) || "locp".equals(profiles)) {
+			GagaFtpUtil ftpUtil = new GagaFtpUtil(env.getProperty("speedy.ftp.host"), env.getProperty("speedy.ftp.port"), env.getProperty("speedy.ftp.username"), env.getProperty("speedy.ftp.pwd"));
+			log.debug("targetPath : " + targetPath);
+			ftpUtil.delete("/" + subDir, fileNm);
+			ftpUtil.close();
+		}
+	}
+
+	/**
+	 * Upload files
+	 *
+	 * @param subDir - 업로드 하위 디렉토리
+	 * @param files - MultipartFile List
+	 * @return 업로드한 파일의 정보
+	 * @throws IOException
+	 * @author gagamel
+	 * @since 2019. 12. 6
+	 */
+	@PostMapping("/files/upload")
+	@ResponseBody
+	public Collection<GagaUploadedFileInfo> uploadFiles(@RequestParam(value = "subDir") String subDir, List<MultipartFile> files) throws IOException {
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.default.target.path"), subDir);
+		GagaFileUploadUtil fuUtil = new GagaFileUploadUtil(targetPath);
+
+		Collection<GagaUploadedFileInfo> ufList = fuUtil.uploadFiles(files);
+		log.debug("ufList: {}", ufList);
+
+		// 운영서버에서만 FTP로 파일 업로드
+		String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		if ("run".equals(profiles) || "locp".equals(profiles)) {
+			if (ufList != null && !ufList.isEmpty()) {
+				GagaFtpUtil ftpUtil = new GagaFtpUtil(env.getProperty("speedy.ftp.host"), env.getProperty("speedy.ftp.port"), env.getProperty("speedy.ftp.username"), env.getProperty("speedy.ftp.pwd"));
+
+				for (GagaUploadedFileInfo ufInfo : ufList) {
+					File srcFile = new File(GagaFileUtil.getConcatenationPath(targetPath, ufInfo.getNewFileName()));
+					ftpUtil.upload(srcFile, "/" + subDir);
+				}
+
+				ftpUtil.close();
+			}
+		}
+
+		return ufList;
+	}
+
+	/**
+	 * 엑셀 업로드 팝업
+	 *
+	 * @param procJob - 업무명
+	 * @param callBackFun - 콜백함수
+	 * @return
+	 * @author eskim
+	 * @since 2019. 12. 6
+	 */
+	@GetMapping("/excel/upload/popup/form")
+	public ModelAndView excelUploadPopupForm(@RequestParam(value = "procJob") String procJob, @RequestParam(value = "callBackFun", required = false) String callBackFun) {
+		ModelAndView mav = new ModelAndView();
+
+		GagaMap params = new GagaMap();
+		params.setString("procJob", procJob);
+		params.setString("callBackFun", callBackFun);
+
+		mav.addObject("params", params);
+
+		mav.setViewName("common/ExcelUploadPopupForm");
+
+		return mav;
+	}
+
+	/**
+	 * 샘플파일 시스템파일명 조회
+	 * @param sampleFileId - 샘플파일ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@GetMapping("/sample/file/{sampleFileId}")
+	@ResponseBody
+	public String getSampleFileSystemFilename(@PathVariable("sampleFileId") String sampleFileId) {
+		return commonService.getSampleFileSystemFilename(sampleFileId);
+	}
+}

+ 238 - 0
src/main/java/com/style24/admin/biz/web/TsaCustomerController.java

@@ -0,0 +1,238 @@
+package com.style24.admin.biz.web;
+
+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.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;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+
+/**
+ * 고객 Controller
+ *
+ * @author gagamel
+ * @since 2020. 12. 28
+ */
+@Controller
+@RequestMapping("/customer")
+@Slf4j
+public class TsaCustomerController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaCounselService counselService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TscAnswerPhaseService ansPhaseService;
+
+	/**
+	 * 1:1문의관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@GetMapping("/onetoone/qna/form")
+	public ModelAndView oneToOneQnaForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트 목록
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 상담분류
+		mav.addObject("counselClsfList", rendererService.getCommonCodeList("G059", "Y", new String[] {"G596"}));
+
+		// 상담상태 목록
+		mav.addObject("ansStatList", rendererService.getAvailCommonCodeList("G060"));
+
+		mav.setViewName("customer/OneToOneQnaForm");
+
+		return mav;
+	}
+
+	/**
+	 * 1:1문의 목록
+	 * @param counsel - 상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@PostMapping("/onetoone/qna/list")
+	@ResponseBody
+	public Collection<Counsel> getOneToOneQnaList(@RequestBody Counsel counsel) {
+		return counselService.getOneToOneQnaList(counsel);
+	}
+
+	/**
+	 * 1:1문의상세 화면
+	 * @param counselSq -상담일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@GetMapping("/onetoone/qna/detail/form/{counselSq}")
+	public ModelAndView oneToOneQnaDetailForm(@PathVariable Integer counselSq) {
+		ModelAndView mav = new ModelAndView();
+
+		// 1:1문의 상세 정보
+		mav.addObject("counselInfo", counselService.getOneToOneQna(counselSq));
+
+		// 문의용 답변문구
+		mav.addObject("ansPhaseList", rendererService.getQnaAnswerPhaseList("G061_20"));
+
+		mav.setViewName("customer/OneToOneQnaDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 문의용 답변문구 조회
+	 * @param ansSq - 답변일련번호
+	 * @param ansClsf - 답변종류
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@GetMapping("/qna/answerphase/{ansSq}/{ansClsf}")
+	@ResponseBody
+	public AnswerPhase getQnaAnswerPhase(@PathVariable Integer ansSq, @PathVariable String ansClsf) {
+		AnswerPhase ansPhase = new AnswerPhase();
+		ansPhase.setAnsSq(ansSq);
+		ansPhase.setAnsClsf(ansClsf);
+		return ansPhaseService.getQnaAnswerPhase(ansPhase);
+	}
+
+	/**
+	 * 문의 답변 저장
+	 * @param counsel -상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@PostMapping("/qna/answer/save")
+	@ResponseBody
+	public GagaResponse saveQnaAnswer(@RequestBody Counsel counsel) {
+		counsel.setAnsNo(TsaSession.getInfo().getUserNo());
+		counsel.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		counselService.updateQnaAnswer(counsel);
+
+		// 일대일문의상세 조회
+		Counsel tCounsel = counselService.getOneToOneQna(counsel.getCounselSq());
+
+//		// TODO. 고객이 SMS답변수신을 요청했을 때
+//		if (counsel.getSmsReqYn().equals("Y")) {
+//			try {
+//				// 문의답변완료안내 카카오알림톡 발송
+//				kakaoService.sendQnaAnswer(tCounsel);
+//			} catch (Exception e) {
+//				// Do nothing
+//			}
+//		}
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품문의관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@GetMapping("/goods/qna/form")
+	public ModelAndView goodsQnaForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트 목록
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 답변의뢰업체 목록
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd(), "N"));
+
+		// 상담상태 목록
+		mav.addObject("ansStatList", rendererService.getAvailCommonCodeList("G060"));
+
+		mav.setViewName("customer/GoodsQnaForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품문의 목록
+	 * @param counsel - 상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@PostMapping("/goods/qna/list")
+	@ResponseBody
+	public Collection<Counsel> getGoodsQnaList(@RequestBody Counsel counsel) {
+		return counselService.getGoodsQnaList(counsel);
+	}
+
+	/**
+	 * 상품문의상세 화면
+	 * @param counselSq -상담일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@GetMapping("/goods/qna/detail/form/{counselSq}")
+	public ModelAndView goodsQnaDetailForm(@PathVariable Integer counselSq) {
+		ModelAndView mav = new ModelAndView();
+
+		// 답변의뢰업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd(), "N"));
+
+		// 상품문의 상세
+		mav.addObject("counselInfo", counselService.getGoodsQna(counselSq));
+
+		// 문의용 답변문구
+		mav.addObject("ansPhaseList", rendererService.getQnaAnswerPhaseList("G061_20"));
+
+		mav.setViewName("customer/GoodsQnaDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품문의 입점업체에 답변의뢰 (입점상품일 경우)
+	 * @param counsel -상담정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 24
+	 */
+	@PostMapping("/goods/qna/answer/transfer/save")
+	@ResponseBody
+	public GagaResponse saveGoodsQnaAnswerTransfer(@RequestBody Counsel counsel) {
+		counsel.setAnsTransNo(TsaSession.getInfo().getUserNo());
+		counsel.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		counselService.updateGoodsQnaAnswerTransfer(counsel);
+
+		return super.ok(message.getMessage("SUCC_0004"));
+	}
+
+}

+ 352 - 0
src/main/java/com/style24/admin/biz/web/TsaDeliveryController.java

@@ -0,0 +1,352 @@
+package com.style24.admin.biz.web;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaDeliveryService;
+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.Delivery;
+import com.style24.persistence.domain.DeliveryLoc;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+
+/**
+ * 배송 Controller
+ *
+ * @author moon
+ * @since 2020. 11. 05
+ */
+@Controller
+@RequestMapping("/delivery")
+@Slf4j
+public class TsaDeliveryController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaDeliveryService deliveryService;
+
+	
+	
+	
+	@Value("${upload.default.target.path}")
+	private String uploadTargetPath;
+
+	/**
+	 * 배송 목록 화면
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@GetMapping("/list/form")
+	public ModelAndView deliveryListForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 몰구분
+		//mav.addObject("mallGbList", rendererService.getMallGbCommonCodeList(TsaSession.getInfo().getRoleCd()));
+		mav.addObject("mallGbList", rendererService.getAvailCommonCodeList("G011"));
+		// 주문상세상태코드
+		mav.addObject("ordDtlStatList", rendererService.getAvailCommonCodeList("G013"));
+		// 출고처
+		mav.addObject("deliveryLocList", rendererService.getDeliveryLocList(""));
+		// 사이트구분
+		mav.addObject("siteCdList", rendererService.getAvailCommonCodeList("G000"));
+		// 택배사명 목록
+		mav.addObject("shipCompanyList", rendererService.getShipCompanyList());
+		// 출고처분류
+		mav.addObject("delvTypeList", rendererService.getAvailCommonCodeList("G024"));
+		
+		String supplyCompCd = "";
+		if ("B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd));
+        //mav.addObject("vendorList", rendererService.getVendorCommonCodeList(TsaSession.getInfo().getRoleCd()));
+
+		mav.setViewName("delivery/DeliveryListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 배송 목록 화면 - 배송 목록
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/list")
+	@ResponseBody
+	public Collection<Delivery> getDeliveryList(@RequestBody Delivery delivery) throws Exception {
+		Collection<Delivery> dataList = deliveryService.getDeliveryList(delivery);
+		return dataList;
+	}
+
+	/**
+	 * 배송 목록 화면 - 품절처리
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/list/soldout")
+	@ResponseBody
+	public GagaResponse soldoutDeliveryList(@RequestBody Collection<Delivery> deliveryList) throws Exception {
+		if (deliveryList == null || deliveryList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1002"));
+		}
+		// 세트상품일경우 주문번호, 주문상세기준으로 data 정비 
+		Collection<Delivery> orderDtlList = new ArrayList<Delivery>();
+
+		int orderDtlListCnt = 0;
+		for (Delivery delivery : deliveryList) {
+			Delivery dtlno = new Delivery();
+			dtlno.setOrdNo(delivery.getOrdNo());
+			dtlno.setOrdDtlNo(delivery.getOrdDtlNo());
+			dtlno.setSaleQty(delivery.getSaleQty());
+			dtlno.setCustNo(delivery.getCustNo());
+			dtlno.setDelvLocClsf(delivery.getDelvLocClsf());
+			if (orderDtlListCnt == 0) {
+				orderDtlList.add(dtlno);
+			} else {
+				int dupChk = 0;
+				for (Delivery param : orderDtlList) {
+					if (delivery.getOrdNo().equals(param.getOrdNo()) && delivery.getOrdDtlNo().equals(param.getOrdDtlNo())) {
+						dupChk++;
+					}
+				}
+				if (dupChk == 0) {
+					orderDtlList.add(dtlno);
+				}
+				orderDtlListCnt++;
+			}
+		}
+		/*
+		// 주문 취소 형식에 맞게 data 정비 
+		Collection<TsaOrder> orderlist = new ArrayList<TsaOrder>();
+
+		for (TsaDelivery delivery : orderDtlList) {
+			TsaOrder param = new TsaOrder();
+			param.setOrdNo(delivery.getOrdNo() + "");
+			param.setOrdDtlNo(delivery.getOrdDtlNo() + "");
+			param.setOrdDtlNos(delivery.getOrdDtlNo() + "");
+			param.setCustNo(delivery.getCustNo());
+			param.setChgQty(delivery.getSaleQty());
+			param.setChgQtys(delivery.getSaleQty() + "");  // getChgQtys
+			param.setDelvLocClsf(delivery.getDelvLocClsf());
+
+			if (orderlist == null || orderlist.isEmpty()) {
+				orderlist.add(param);
+			} else {
+				int cnt = 0;
+				for (TsaOrder order : orderlist) {
+					if (delivery.getOrdNo().equals(order.getOrdNo())) {
+						order.setOrdDtlNos(order.getOrdDtlNos() + "," + param.getOrdDtlNo());
+						order.setChgQtys(order.getChgQtys() + "," + param.getChgQty());
+						cnt = 1;
+					}
+				}
+				if (cnt == 0) {
+					orderlist.add(param);
+				}
+			}
+		}
+
+		for (TsaOrder order : orderlist) {
+			deliveryService.saveGoodsSoldout(order);
+		}
+		*/
+		return super.ok(message.getMessage("SUCC_0004"));
+	}
+	
+	/**
+	 * 배송 목록 화면 - 송장번호변경(팝업)
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@GetMapping("/save/invoice/form")
+	public ModelAndView saveInvoiceForm(@RequestParam(value = "ordDtlNo", required = true)long ordDtlNo) {
+		ModelAndView mav = new ModelAndView();
+		Collection<Delivery> ordDeliveryList = deliveryService.getOrderDetail(ordDtlNo);
+		Delivery ordDelivery = ordDeliveryList.iterator().next();
+		// 택배사명 목록
+		mav.addObject("shipCompanyList", rendererService.getShipCompanyList());
+		mav.addObject("ordDelivery", ordDelivery);
+		
+		mav.setViewName("delivery/SaveInvoiceForm");
+		return mav;
+	} 
+	
+	/**
+	 * 배송 목록 화면 - 송장번호변경(팝업) - 송장번호수정
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/orderDetail/save")
+	@ResponseBody
+	public GagaResponse saveOrderDetail(@RequestBody Collection<Delivery> deliveryList) throws Exception {
+
+		if (deliveryList == null) {
+			throw new IllegalStateException(message.getMessage("FAIL_1002"));
+		}
+
+		deliveryService.saveOrderDetail(deliveryList);
+
+		return super.ok(message.getMessage("SUCC_0004"));
+	}
+	
+	/**
+	 * 출고금지상품관리 화면
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@GetMapping("/ban/goods/form")
+	@ResponseBody
+	public ModelAndView bangoodsListForm() throws Exception {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList());
+		// 출고처 목록
+		DeliveryLoc deliLoc = new DeliveryLoc(); 
+		mav.addObject("getDeliveryLocList", rendererService.getDeliveryLocList(deliLoc));
+		mav.setViewName("delivery/BangoodsListForm");
+
+		return mav;
+	}
+	
+	/**
+	 * 출고금지상품관리 화면 - 출고금지상품목록
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/bangoods/list")
+	@ResponseBody
+	public Collection<Delivery> getBangoodsList(@RequestBody Delivery delivery) throws Exception {
+		Collection<Delivery> dataList = deliveryService.getBangoodsList(delivery);
+		return dataList;
+	}	
+	
+	/**
+	 * 출고금지상품관리 화면 - 출고금지상품 삭제
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/bangoods/delete")
+	@ResponseBody
+	public GagaResponse deleteBangoods(@RequestBody Collection<Delivery> deliveryList) throws Exception {
+		deliveryService.deleteBangoods(deliveryList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+	
+	/**
+	 * 출고금지상품관리 화면 - 출고금지상품 등록 화면(팝업)
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@GetMapping("/bangoods/regist/form")
+	@ResponseBody
+	public ModelAndView registBangoodsForm() throws Exception {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList());
+		// 출고처 목록
+		DeliveryLoc deliLoc = new DeliveryLoc();
+		mav.addObject("getDeliveryLocList", rendererService.getDeliveryLocList(deliLoc));
+		// 상품상태
+		mav.addObject("goodsStatList", rendererService.getAvailCommonCodeList("G008"));
+
+		mav.setViewName("delivery/BanGoodsRegistForm");
+
+		return mav;
+	}	
+
+	/**
+	 * 출고금지상품관리 화면 - 출고금지상품 등록 화면(팝업) - 출고금지상품 등록 대상목록
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/bangoods/regist/list")
+	@ResponseBody
+	public Collection<Delivery> getBangoodsRegistList(@RequestBody Delivery delivery) throws Exception {
+		Collection<Delivery> dataList = deliveryService.getBangoodsRegistList(delivery);
+		return dataList;
+	}
+
+	/**
+	 * 출고금지상품관리 화면 - 출고금지상품 등록 화면(팝업) - 출고금지상품 등록
+	 *
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/bangoods/regist/save")
+	@ResponseBody
+	public GagaResponse createBangoods(@RequestBody Collection<Delivery> deliveryList) throws Exception {
+		deliveryService.createBangoods(deliveryList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+	
+}

+ 62 - 0
src/main/java/com/style24/admin/biz/web/TsaDextuploadController.java

@@ -0,0 +1,62 @@
+package com.style24.admin.biz.web;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.core.support.message.TscMessageByLocale;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.util.GagaFileUploadUtil;
+import com.gagaframework.web.util.GagaUploadedFileInfo;
+
+/**
+ * Dextupload Controller
+ * 
+ * @author gagamel
+ * @since 2020. 12. 4
+ */
+@Controller
+@RequestMapping("/dext")
+@Slf4j
+public class TsaDextuploadController extends TsaBaseController {
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	/**
+	 * dextupload를 이용한 파일 업로드
+	 * @param policy - 업로드정책
+	 * @param files - 파일 목록 (dx5는 DEXTUploadX5_FileData 명칭으로 넘어옴)
+	 * @return 업로드된 파일 목록
+	 * @throws Exception
+	 * @author gagamel
+	 * @since 2020. 12. 4
+	 */
+	@PostMapping("/files/upload/{policy}")
+	@ResponseBody
+	public Collection<GagaUploadedFileInfo> uploadFiles(@PathVariable("policy") String policy, @RequestParam(value = "DEXTUploadX5_FileData") List<MultipartFile> files) throws Exception {
+		if (files == null || files.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		GagaFileUploadUtil fuUtil = new GagaFileUploadUtil(env.getProperty("upload.dext.target.path"), Long.parseLong(env.getProperty("upload." + policy + ".max.size")), env.getProperty("upload." + policy + ".allow.extension"), env.getProperty("upload." + policy + ".view"));
+
+		return fuUtil.uploadFiles(files);
+	}
+
+}

+ 211 - 0
src/main/java/com/style24/admin/biz/web/TsaDisplayController.java

@@ -0,0 +1,211 @@
+package com.style24.admin.biz.web;
+
+import java.util.Collection;
+
+import com.style24.persistence.domain.Brand;
+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
+ *
+ * @author
+ * @since 2020. 12. 16
+ */
+@Controller
+@RequestMapping("/display")
+@Slf4j
+public class TsaDisplayController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaDisplayService displayService;
+
+	/**
+	 * 카테고리관리 화면
+	 * @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 gagamel
+	 * @since 2021. 1. 4
+	 */
+	@PostMapping("/category/list")
+	@ResponseBody
+	public Collection<Category> getCategoryList(@RequestBody Category category) {
+		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);
+	}
+
+	/**
+	 * 카테고리 목록 화면(팝업)
+	 * @param Category
+	 * @return
+	 * @author xyzp1539
+	 * @since 2021. 01. 11
+	 */
+	@GetMapping("/category/popup/form")
+	public ModelAndView categorySearchForm(Category category) {
+		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.addObject("params", category);
+
+		mav.setViewName("display/CategorySearchForm");
+		return mav;
+	}
+
+}

+ 325 - 0
src/main/java/com/style24/admin/biz/web/TsaEnvsetController.java

@@ -0,0 +1,325 @@
+package com.style24.admin.biz.web;
+
+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.RequestParam;
+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.TsaClauseService;
+import com.style24.admin.biz.service.TsaEnvsetService;
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.core.biz.service.TscEnvsetService;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.AnswerPhase;
+import com.style24.persistence.domain.Clause;
+import com.style24.persistence.domain.CustGradePolicy;
+import com.style24.persistence.domain.Envset;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+
+/**
+ * 환경설정 Controller
+ *
+ * @author gagamel
+ * @since 2020. 10. 21
+ */
+@Controller
+@RequestMapping("/envset")
+@Slf4j
+public class TsaEnvsetController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TscEnvsetService cenvsetService;
+
+	@Autowired
+	private TsaEnvsetService envsetService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaClauseService clauseService;
+
+	@Autowired
+	private TsaAnswerPhaseService ansPhaseService;
+
+	/**
+	 * 기본환경설정 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	@GetMapping("/basic/form")
+	public ModelAndView basicSetForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트 목록
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		mav.setViewName("envset/BasicEnvsetForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사이트별 환경설정유형에 따른 환경설정 정보
+	 * @param siteCd - 사이트코드
+	 * @param envsetType - 환경설정유형
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	@GetMapping("/{siteCd}/{envsetType}")
+	@ResponseBody
+	public Envset getEnvset(@PathVariable String siteCd, @PathVariable String envsetType) {
+		return cenvsetService.getEnvset(siteCd, envsetType);
+	}
+
+	/**
+	 * 환경설정 정보 저장
+	 * @param envset - 환경설정 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	@PostMapping("/create")
+	@ResponseBody
+	public GagaResponse createEnvset(@RequestBody Envset envset) {
+		if (envset.getEnvsetType().equals("B10")) {
+			// 메타 정보 수정 시는 캐싱 삭제되도록
+			// 중요하지 않은 정보로서 캐싱 삭제해도 됨.
+			envsetService.createEnvsetMetaInfo(envset);
+		} else {
+			// 그 외는 캐싱 삭제 안 함
+			// 정책은 중요한 정보로서 캐싱 문제 발생 시 심각해질 수 있으므로 캐싱처리 안 함(2020.05.14. gagamel)
+			envsetService.createEnvset(envset);
+		}
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 사이트별 환경설정유형에 따른 환경설정이력 화면
+	 * @param siteCd - 사이트코드
+	 * @param envsetType - 환경설정유형
+	 * @param envsetTypeNm - 환경설정유형명
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	@GetMapping("/history/form")
+	public ModelAndView basicSetForm(@RequestParam(value = "siteCd", required = true) String siteCd, @RequestParam(value = "envsetType", required = true) String envsetType, @RequestParam(value = "envsetTypeNm", required = true) String envsetTypeNm) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("siteCd", siteCd);
+		mav.addObject("envsetType", envsetType);
+		mav.addObject("envsetTypeNm", envsetTypeNm);
+
+		mav.setViewName("envset/EnvsetHistoryForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사이트별 환경설정유형에 따른 환경설정이력 목록
+	 * @param siteCd - 사이트코드
+	 * @param envsetType - 환경설정유형
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 21
+	 */
+	@GetMapping("/history/{siteCd}/{envsetType}")
+	@ResponseBody
+	public Collection<Envset> getEnvsetHistoryList(@PathVariable String siteCd, @PathVariable String envsetType) {
+		return envsetService.getEnvsetHistoryList(siteCd, envsetType);
+	}
+
+	/**
+	 * 회원등급정책관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 6
+	 */
+	@GetMapping("/customer/grade/policy/form")
+	public ModelAndView customerGradePolicyForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 회원등급
+		mav.addObject("custGradeList", rendererService.getAvailCommonCodeList("G110"));
+
+		mav.setViewName("envset/CustomerGradePolicyForm");
+
+		return mav;
+	}
+
+	/**
+	 * 회원등급정책 목록
+	 * @param policy - 회원등급정책 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 7
+	 */
+	@PostMapping("/customer/grade/policy/list")
+	@ResponseBody
+	public Collection<CustGradePolicy> getCustomerGradePolicyList(@RequestBody CustGradePolicy policy) {
+		return envsetService.getCustomerGradePolicyList(policy);
+	}
+
+	/**
+	 * 회원등급정책 저장
+	 * @param policy - 회원등급정책 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2021. 1. 7
+	 */
+	@PostMapping("/customer/grade/policy/create")
+	@ResponseBody
+	public GagaResponse createCustomerGradePolicy(@RequestBody CustGradePolicy policy) {
+		envsetService.createCustomerGradePolicy(policy);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 약관관리 화면
+	 * @return ModelAndView
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@GetMapping("/clause/form")
+	public ModelAndView clauseForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트 목록
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 약관유형 목록
+		mav.addObject("clauseTypeList", rendererService.getAvailCommonCodeList("G057"));
+
+		mav.setViewName("envset/ClauseForm");
+
+		return mav;
+	}
+
+	/**
+	 * 약관관리 목록
+	 * @param clause - 약관 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@PostMapping("/clause/list")
+	@ResponseBody
+	public Collection<Clause> getClauseList(@RequestBody Clause clause) {
+		return clauseService.getClauseList(clause);
+	}
+
+	/**
+	 * 약관관리상세 화면
+	 * @param mode - 모드(N:신규, U:상세)
+	 * @param clauseSq - 약관일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@GetMapping("/clause/detail/form")
+	public ModelAndView clauseDetailForm(@RequestParam(value = "mode") String mode, @RequestParam(value = "clauseSq", required = false) Integer clauseSq) {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트 목록
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 약관유형 목록
+		mav.addObject("clauseTypeList", rendererService.getAvailCommonCodeList("G057"));
+
+		// 모드 값
+		mav.addObject("mode", mode);
+
+		if ("U".equals(mode)) {
+			mav.addObject("clauseInfo", clauseService.getClauseDetail(clauseSq));
+		}
+
+		mav.setViewName("envset/ClauseDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 약관 생성/수정
+	 * @param clause - 약관 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@PostMapping("/clause/save")
+	@ResponseBody
+	public GagaResponse saveClause(@RequestBody Clause clause) {
+		clauseService.saveClause(clause);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 답변문구관리
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@GetMapping("/answer/phase/form")
+	public ModelAndView answerPhaseForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트콤보
+		mav.addObject("siteList", rendererService.getAvailCommonCodeList("G000"));
+
+		// 답변종류콤보
+		mav.addObject("ansClsfList", rendererService.getAvailCommonCodeList("G061"));
+
+		mav.setViewName("envset/AnswerPhaseForm");
+
+		return mav;
+	}
+
+	/**
+	 * 답변문구 목록
+	 * @param ansPhase - 답변문구 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@PostMapping("/answer/phase/list")
+	@ResponseBody
+	public Collection<AnswerPhase> getAnswerPhaseList(@RequestBody AnswerPhase ansPhase) {
+		return ansPhaseService.getAnswerPhaseList(ansPhase);
+	}
+
+	/**
+	 * 답변문구 저장
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 29
+	 */
+	@PostMapping("/answer/phase/save")
+	@ResponseBody
+	public GagaResponse saveAnswerPhase(@RequestBody AnswerPhase ansPhase) {
+		ansPhaseService.saveAnswerPhase(ansPhase);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+}

+ 2495 - 0
src/main/java/com/style24/admin/biz/web/TsaGoodsController.java

@@ -0,0 +1,2495 @@
+package com.style24.admin.biz.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.style24.admin.biz.service.TsaCommonService;
+import com.style24.admin.biz.service.TsaGoodsService;
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaSystemService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+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;
+import com.style24.persistence.domain.GoodsHst;
+import com.style24.persistence.domain.GoodsImg;
+import com.style24.persistence.domain.GoodsNaverLowestPrice;
+import com.style24.persistence.domain.GoodsNotiInfo;
+import com.style24.persistence.domain.GoodsPriceRes;
+import com.style24.persistence.domain.GoodsResSell;
+import com.style24.persistence.domain.GoodsSearch;
+import com.style24.persistence.domain.GoodsTnmRes;
+import com.style24.persistence.domain.GoodsVideo;
+import com.style24.persistence.domain.Itemkind;
+import com.style24.persistence.domain.NotiInfo;
+import com.style24.persistence.domain.Notice;
+import com.style24.persistence.domain.NoticeGoods;
+import com.style24.persistence.domain.Option;
+import com.style24.persistence.domain.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;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.rest.server.GagaResponseStatus;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.gagaframework.web.util.GagaStringUtil;
+
+/**
+ * 상품관리 Controller
+ *
+ * @author eskim
+ * @since 2020. 10. 16
+ */
+@Controller
+@RequestMapping("/goods")
+@Slf4j
+public class TsaGoodsController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaGoodsService goodsService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+	@Autowired
+	private TsaSystemService systemService;
+
+	/**
+	 * 품목관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/itemkind/base/form")
+	public ModelAndView itemkindBaseForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 정보고시 목록
+		mav.addObject("niClsfCdList", rendererService.getAvailCommonCodeList("G004"));
+
+		mav.setViewName("goods/ItemkindBaseForm");
+
+		return mav;
+	}
+
+	/**
+	 * 품목관리 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@PostMapping("/itemkind/base/list")
+	@ResponseBody
+	public Collection<Itemkind> getItemkindList(@RequestBody Itemkind itemkind) {
+		return goodsService.getItemkindList(itemkind);
+	}
+
+	/**
+	 * 품목 관리 저장/등록
+	 *
+	 * @param itemkindList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@PostMapping("/itemkind/save")
+	@ResponseBody
+	public GagaResponse saveItemkindInfo(@RequestBody Collection<Itemkind> itemkindList) {
+		goodsService.saveItemkindInfo(itemkindList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 품목관리 삭제
+	 *
+	 * @param itemkindList
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@PostMapping("/itemkind/delete")
+	@ResponseBody
+	public GagaResponse deleteItemkindInfo(@RequestBody Collection<Itemkind> itemkindList) {
+		goodsService.deleteItemkindInfo(itemkindList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 색상관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/color/form")
+	public ModelAndView colorForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 대표컬러목록
+		mav.addObject("groupColorCodeList", rendererService.getColorGrpCdRgbList());
+		// 대표컬러명목록
+		mav.addObject("groupColorCodeNmList", rendererService.getCommonCodeList("G072"));
+
+		mav.setViewName("goods/ColorForm");
+
+		return mav;
+	}
+
+	/**
+	 * 색상 조회
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@PostMapping("/color/list")
+	@ResponseBody
+	public Collection<Color> getColorList(@RequestBody Color color) {
+		return goodsService.getColorList(color);
+	}
+
+	/**
+	 * 색상 저장
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@PostMapping("/color/save")
+	@ResponseBody
+	public GagaResponse saveColor(@RequestBody Collection<Color> colorList) {
+
+		goodsService.saveColor(colorList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * WMS 시즌매핑 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/wms/season/form")
+	public ModelAndView seasonForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+
+		mav.setViewName("goods/WmsSeasonMappingForm");
+
+		return mav;
+	}
+
+	/**
+	 * WMS 시즌 매핑 조회
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/wms/season/mapping/list")
+	@ResponseBody
+	public Collection<WmsSeasonMapping> getWmsSeasonMappingList(@RequestBody WmsSeasonMapping wmsSeasonMapping) {
+		return goodsService.getWmsSeasonMappingList(wmsSeasonMapping);
+	}
+
+	/**
+	 * WMS 시즌 매핑 저장
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/wms/season/mapping/save")
+	@ResponseBody
+	public GagaResponse saveWmsSeasonMapping(@RequestBody Collection<WmsSeasonMapping> wmsSeasonMappingList) {
+
+		goodsService.saveWmsSeasonMapping(wmsSeasonMappingList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 고시정보관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/notiinfo/form")
+	public ModelAndView notiinfoForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 정보고시 분류별 항목
+		mav.addObject("niItemCdList", rendererService.getAvailCommonCodeList("G005"));
+
+		mav.setViewName("goods/NotiinfoForm");
+
+		return mav;
+	}
+
+	/**
+	 * 정보고시관리 조회
+	 *
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	@PostMapping("/notiInfo/list")
+	@ResponseBody
+	public Collection<NotiInfo> getNotiInfoList(@RequestBody NotiInfo notiInfo) {
+		return goodsService.getNotiInfoList(notiInfo);
+	}
+
+	/**
+	 * 정보고시 항목 목록
+	 *
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	@PostMapping("/notiInfo/item/list")
+	@ResponseBody
+	public Collection<NotiInfo> getNotiInfoItemList(@RequestBody NotiInfo notiInfo) {
+		return goodsService.getNotiInfoItemList(notiInfo);
+	}
+
+	/**
+	 * 정보고시 상세 저장
+	 *
+	 * @param notiInfoList
+	 * @return
+	 * @author eskim
+	 * @since 2010. 10. 19
+	 */
+	@PostMapping("/notiInfo/item/save")
+	@ResponseBody
+	public GagaResponse saveNotiInfoItem(@RequestBody Collection<NotiInfo> notiInfoList) {
+
+		goodsService.saveNotiInfoItem(notiInfoList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * WMS 색상 매핑 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@GetMapping("/wms/color/form")
+	public ModelAndView wmsColorForm() {
+		ModelAndView mav = new ModelAndView();
+
+		Color color = new Color();
+		mav.addObject("colorList", rendererService.getColorList(color));
+
+		mav.setViewName("goods/WmsColorMappingForm");
+
+		return mav;
+	}
+
+	/**
+	 * WMS 색상 매핑 조회
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@PostMapping("/wms/color/mapping/list")
+	@ResponseBody
+	public Collection<WmsColorMapping> getWmsColorMappingList(@RequestBody WmsColorMapping wmsColorMapping) {
+		return goodsService.getWmsColorMappingList(wmsColorMapping);
+	}
+
+	/**
+	 * WMS 색상 매핑 저장
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@PostMapping("/wms/color/mapping/save")
+	@ResponseBody
+	public GagaResponse saveWmsColorMapping(@RequestBody Collection<WmsColorMapping> wmsColorMappingList) {
+
+		goodsService.saveWmsColorMapping(wmsColorMappingList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * WMS 스타일년도 매핑 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@GetMapping("/wms/styleYear/form")
+	public ModelAndView wmsStyleYearForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 년도
+		int fromYear = Integer.parseInt("2008");
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy"));
+		mav.addObject("styleYearList", rendererService.getYearList(fromYear, 0, toYear - fromYear + 3));
+
+		mav.setViewName("goods/WmsStyleYearMappingForm");
+
+		return mav;
+	}
+
+	/**
+	 * WMS 스타일년도 매핑 조회
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/wms/styleYear/mapping/list")
+	@ResponseBody
+	public Collection<WmsStyleYearMapping> getWmsStyleYearMappingList(@RequestBody WmsStyleYearMapping wmsStyleYearMapping) {
+		return goodsService.getWmsStyleYearMappingList(wmsStyleYearMapping);
+	}
+
+	/**
+	 * WMS 스타일년도 매핑 저장
+	 *
+	 * @param color
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/wms/styleYear/mapping/save")
+	@ResponseBody
+	public GagaResponse saveWmsStyleYearMapping(@RequestBody Collection<WmsStyleYearMapping> wmsStyleYearMappingList) {
+
+		goodsService.saveWmsStyleYearMapping(wmsStyleYearMappingList);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품목록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/list/form")
+	public ModelAndView listForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		String selfYn = "Y";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+			selfYn = "N";
+		}
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, selfYn));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 성별
+		mav.addObject("sexGbList", rendererService.getAvailCommonCodeList("G007"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 연령대
+		mav.addObject("ageGrpCdList", rendererService.getAvailCommonCodeList("G023"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// 상품유형
+		mav.addObject("goodsTypeList", rendererService.getAvailCommonCodeList("G056"));
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+
+		mav.setViewName("goods/GoodsListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품목록 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/list")
+	@ResponseBody
+	public GagaMap getGoodsList(@RequestBody GoodsSearch goodsSearch) {
+
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+
+			if ("searchExtendGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("EXTEND");
+			} else if ("searchMasterGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("MASTER");
+			}
+		}
+		log.info("[getGoodsList] goodsSearch=>{}", goodsSearch);
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsListCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsList", goodsService.getGoodsList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 상품목록 - 기본정보 엑셀다운로드
+	 *
+	 * @param goodsSearch
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 21
+	 */
+	@GetMapping("/info/excel/list")
+	public ResponseEntity<InputStreamResource> downloadGoodsInfoExcelList(HttpServletRequest request, GoodsSearch goodsSearch) throws Exception {
+		String excelfileName = "상품_기본정보_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilenameWithPath = GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+
+			if ("searchExtendGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("EXTEND");
+			} else if ("searchMasterGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("MASTER");
+			}
+		}
+
+		// 대용량엑셀파일다운로드는 이런 식으로 ...
+		goodsService.getGoodsInfoExcelList(goodsSearch, excelFilenameWithPath);
+
+		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
+	}
+
+	/**
+	 * 상품 수정 항목 일괄변경
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 17
+	 */
+	@PostMapping("/state/update")
+	@ResponseBody
+	public GagaMap updateGoodsState(@RequestBody Goods goods) {
+
+		GagaMap result = new GagaMap();
+		result.set("status", GagaResponseStatus.SUCCESS.getCode()); // 200
+		result.set("procJob", goods.getProcJob());
+		// result.set("message", message.getMessage("SUCC_0001"));
+
+		String returnGoods = "";
+		String resultFlag = "SUCC";
+
+		if (!"G001_0000".equals(TsaSession.getInfo().getRoleCd()) && !"G001_A000".equals(TsaSession.getInfo().getRoleCd())
+			&& !"G001_A001".equals(TsaSession.getInfo().getRoleCd()) && !"G001_A100".equals(TsaSession.getInfo().getRoleCd())
+			&& !"G001_A101".equals(TsaSession.getInfo().getRoleCd())) {
+			throw new IllegalStateException("권한이 없습니다.");
+		}
+
+		// 상품 상태 변경일 경우 체크
+		if ("goodsStat".equals(goods.getProcJob()) && ("G008_40".equals(goods.getGoodsStat()) || "G008_90".equals(goods.getGoodsStat()))) {
+
+			// 이미지
+			Collection<Goods> goodsList = goodsService.getGoodsImgsYn(goods);
+
+			for (Goods tmpGoods : goodsList) {
+				if ("N".equals(tmpGoods.getGoodsImageYn())) {
+					returnGoods += tmpGoods.getGoodsCd() + ",";
+				} else {
+
+					// 택가/판매가 입력 여부 확인
+					Goods dataGoods = goodsService.getGoods(tmpGoods);
+					if (dataGoods == null) {
+						returnGoods += tmpGoods.getGoodsCd() + ",";
+						continue;
+					}
+					if (dataGoods.getListPrice() <= 0 || dataGoods.getCurrPrice() <= 0) {
+						returnGoods += tmpGoods.getGoodsCd() + ",";
+						continue;
+					}
+					// 옵션 등록 여부 확인 - 일반상품만 확인
+					if ("G056_N".equals(dataGoods.getGoodsType())) {
+						Option stock = new Option();
+						stock.setGoodsCd(tmpGoods.getGoodsCd());
+						int stockCnt = goodsService.getGoodsOptionCount(stock);
+						if (stockCnt <= 0) {
+							returnGoods += tmpGoods.getGoodsCd() + ",";
+							continue;
+						}
+
+					}
+
+					//고시정보
+					GoodsNotiInfo goodsNotiInfo = new GoodsNotiInfo();
+					goodsNotiInfo.setGoodsCd(tmpGoods.getGoodsCd());
+					goodsNotiInfo.setSupplyCompCd(tmpGoods.getSupplyCompCd());
+					goodsNotiInfo.setNiClsfCd(tmpGoods.getNiClsfCd());
+					Collection<GoodsNotiInfo> goodsNotiInfoList = goodsService.getGoodsNotiInfoList(goodsNotiInfo);
+					if (goodsNotiInfoList == null || goodsNotiInfoList.isEmpty()) {
+						returnGoods += tmpGoods.getGoodsCd() + ",";
+					} else {
+						for (GoodsNotiInfo tmpGoodsNotiInfo : goodsNotiInfoList) {
+							if ("Y".equals(tmpGoodsNotiInfo.getReqYn()) || "Y".equals(tmpGoodsNotiInfo.getDispYn())) {
+								if (StringUtils.isEmpty(tmpGoodsNotiInfo.getNiContent())) {
+									returnGoods += tmpGoods.getGoodsCd() + ",";
+									break;
+								}
+							}
+						}
+					}
+				}
+			}
+
+			if (returnGoods.length() > 0) {
+				returnGoods = returnGoods.substring(0, returnGoods.lastIndexOf(","));
+				returnGoods = returnGoods.replaceAll(",", ",<br/>");
+				resultFlag = "FAIL";
+				result.set("resultFlag", resultFlag);
+				result.set("returnGoods", returnGoods);
+				return result;
+			}
+		}
+
+		goodsService.updateGoodsState(goods);
+
+		result.set("resultFlag", resultFlag);
+		result.set("returnGoods", returnGoods);
+		return result;
+	}
+
+	/**
+	 * 엑셀조회용 상품 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 10. 20
+	 */
+	@PostMapping("/search/excelupload/save")
+	@ResponseBody
+	public GagaResponse saveExceluploadGoods(@RequestBody Goods goods) throws Exception {
+
+		int cnt = 0;
+		ObjectMapper mapper = new ObjectMapper();
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellName = {"goodsCd", "supplyGoodsCd"};
+
+		Collection<GagaMap> ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()), 0, cellName, 0);
+
+		Collection<Goods> goodsList = new ArrayList<>();
+		for (GagaMap map : ecxelGoodsList) {
+			Goods tmpGoods = mapper.convertValue(map, Goods.class);
+			tmpGoods.setRegNo(TsaSession.getInfo().getUserNo());
+			tmpGoods.setProcJob(goods.getProcJob());
+			goodsList.add(tmpGoods);
+			cnt++;
+		}
+
+		goodsService.saveExceluploadGoods(goodsList, goods.getExcelFileNm());
+
+		// 파일 삭제
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()));
+
+		return super.ok("");
+	}
+
+	/**
+	 * 엑셀 업로드 상품 조회
+	 *
+	 * @param
+	 * @return GagaMap
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	@PostMapping("/excel/upload/goods/list")
+	@ResponseBody
+	public GagaMap getExcelUploadGoodsList() {
+		GagaMap result = new GagaMap();
+		GoodsSearch goodsSearch = new GoodsSearch();
+		goodsSearch.setSearchGb("EXCEL");
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		result.set("goodsExcelList", goodsService.getGoodsList(goodsSearch));
+		return result;
+	}
+
+	/**
+	 * 상품 상세 화면
+	 *
+	 * @param goodsCode - 상품코드
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@GetMapping("/detail/form")
+	@ResponseBody
+	public ModelAndView detailForm(Goods goods) {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd));
+//		String selfYn = "Y";
+//		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+//			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+//			selfYn = "N";
+//		}
+//		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, selfYn));
+
+		String[] goodsStatExceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", goodsStatExceptCds));
+
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 성별
+		mav.addObject("sexGbList", rendererService.getAvailCommonCodeList("G007"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// 정보고시 분류
+		mav.addObject("niClsfCdList", rendererService.getAvailCommonCodeList("G004"));
+		// 사용자 브랜드 조회
+		mav.addObject("authBrandList", rendererService.getAuthBrandList(TsaSession.getInfo().getUserNo()));
+		// 상품타입
+		mav.addObject("goodsTypeList", rendererService.getAvailCommonCodeList("G056"));
+		// 상품구분
+		mav.addObject("goodsGbList", rendererService.getAvailCommonCodeList("G073"));
+		// 유통구분
+		//String[] distributionGbExceptCds = {"G065_20"};
+		//mav.addObject("distributionGbList", rendererService.getCommonCodeList("G065", "Y", distributionGbExceptCds));
+		mav.addObject("distributionGbList", rendererService.getCommonCodeList("G065", "Y"));
+		// 상품연령대
+		mav.addObject("ageGrpCdList", rendererService.getAvailCommonCodeList("G023"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 회원등급
+		//mav.addObject("custGradeList", rendererService.getAvailCommonCodeList("G101"));
+
+		mav.addObject("params", goods);
+
+		mav.setViewName("goods/GoodsDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 상세 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@PostMapping("/detail")
+	@ResponseBody
+	public Goods getGoodsDetail(Goods goods) {
+		return goodsService.getGoods(goods);
+	}
+
+	/**
+	 * 상품 이력 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@GetMapping("/detail/hst/list")
+	@ResponseBody
+	public Collection<GoodsHst> getGoodsDetailHstList(Goods goods) {
+		return goodsService.getGoodsHstList(goods);
+	}
+
+	/**
+	 * 컬러 옵셥 재고
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 26
+	 */
+	@PostMapping("/detail/sizeStock/form")
+	public ModelAndView getGoodsDetailSizeStockForm(Goods goods) {
+
+		ModelAndView mav = new ModelAndView();
+		mav.addObject("goods", goodsService.getGoods(goods));
+		mav.addObject("goodsSizeList", goodsService.getGoodsSizeList(goods));
+		mav.addObject("goodsColorList", goodsService.getGoodsColorList(goods));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+
+		mav.setViewName("goods/GoodsDetailSizeStockForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 정보고시 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 26
+	 */
+	@PostMapping("/detail/notiInfo/list")
+	@ResponseBody
+	public Collection<GoodsNotiInfo> getGoodsDetailNotiInfoList(Goods goods) {
+
+		GoodsNotiInfo goodsInfo = new GoodsNotiInfo();
+		goodsInfo.setGoodsCd(goods.getGoodsCd());
+		goodsInfo.setNiClsfCd(goods.getNiClsfCd());
+		goodsInfo.setSupplyCompCd(goods.getSupplyCompCd());
+
+		return goodsService.getGoodsNotiInfoList(goodsInfo);
+	}
+
+	/**
+	 * 상품의 정보고시 항목 목록
+	 *
+	 * @param notiInfo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 26
+	 */
+	@PostMapping("/noti/goodsInfo/list")
+	@ResponseBody
+	public Collection<NotiInfo> getNotiGoodsInfoList(NotiInfo notiInfo) {
+		return goodsService.getNotiGoodsInfoList(notiInfo);
+	}
+
+	/**
+	 * 상품 구매등급 조회
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 11
+	 */
+	@PostMapping("/detail/order/grade/list")
+	@ResponseBody
+	public Collection<Goods> getGoodsDetailOrderGradeList(Goods goods) {
+		return goodsService.getGoodsDetailOrderGradeList(goods);
+	}
+
+	/**
+	 * 구성상품 목록
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	@GetMapping("/detail/compose/list")
+	@ResponseBody
+	public Collection<GoodsCompose> getGoodsDetailComposeList(Goods goods) {
+		return goodsService.getGoodsDetailComposeList(goods);
+	}
+
+	/**
+	 * 상품 안전인증번호 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 07
+	 */
+	@PostMapping("/detail/certNum/save")
+	@ResponseBody
+	public GagaResponse saveGoodsDetailCertNum(@RequestBody Goods goods) {
+		goodsService.saveGoodsDetailCertNum(goods);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 상세 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 27
+	 */
+	@PostMapping("/detail/save")
+	@ResponseBody
+	public GagaResponse saveGoodsDetail(@RequestBody Goods goods) {
+
+		// 상품상태에 따른 이미지 정보 확인 - 상품상태가 승인대기나 승인 완료일 경우
+		if ("G008_40".equals(goods.getGoodsStat()) || "G008_90".equals(goods.getGoodsStat())) {
+			Collection<Goods> goodsList = goodsService.getGoodsImgsYn(goods);
+			String goodsImageYn = "N";
+			for (Goods tmpGoods : goodsList) {
+				goodsImageYn = tmpGoods.getGoodsImageYn();
+			}
+			if ("N".equals(goodsImageYn)) {
+				throw new IllegalStateException("필수 이미지나 고시정보가 등록되지 않은 상품은 <br/>'승인대기'나 '승인완료' 상태로 변경할 수 없습니다.");
+			}
+		}
+
+		Collection<GoodsNotiInfo> notiList = null;
+		Collection<GoodsCompose> goodComposeList = null;
+		ObjectMapper mapper = new ObjectMapper();
+		try {
+			if (goods.getNotiList() != null) {
+				notiList = mapper.readValue(goods.getNotiList(), new TypeReference<Collection<GoodsNotiInfo>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		try {
+			if (goods.getGoodsComposeList() != null) {
+				goodComposeList = mapper.readValue(goods.getGoodsComposeList(), new TypeReference<Collection<GoodsCompose>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		goods.setNotiListNew(notiList);
+		goods.setGoodsComposeListNew(goodComposeList);
+
+		goodsService.saveGoodsDetail(goods);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 이미지 보기 화면
+	 *
+	 * @param goodsCode - 상품코드
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 09
+	 */
+	@GetMapping("/image/form")
+	@ResponseBody
+	public ModelAndView imageMassForm(GoodsImg goodsImg) {
+		ModelAndView mav = new ModelAndView();
+
+		Collection<GoodsImg> goodsImgList = goodsService.getGoodsImgList(goodsImg);
+
+		if (goodsImgList != null && !goodsImgList.isEmpty()) {
+
+			mav.addObject("goodsImgList", goodsImgList);
+
+			for (GoodsImg goodsImgInfo : goodsImgList) {
+				if (goodsImgInfo.getDefaultImgYn().equals("Y")) {
+					mav.addObject("defaultImgOrd", goodsImgInfo.getDispOrd());
+				}
+			}
+		} else { // 대표이미지와 마우스오버이미지가 없으면
+			mav.addObject("goodsImgList", new ArrayList<GoodsImg>());
+			mav.addObject("defaultImgOrd", "1");
+		}
+
+		mav.addObject("goodsImg", goodsImg);
+		mav.setViewName("goods/GoodsImageForm");
+		return mav;
+	}
+
+	/**
+	 * 상품 썸네일 이미지 저장 처리
+	 * @param goodsImgList - 상품이미지 목록
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 12. 21
+	 */
+	@RequestMapping(value = "/thumbnail/image/save", method = RequestMethod.POST)
+	@ResponseBody
+	public GagaResponse saveGoodsThumbnailImageList(@RequestBody Collection<GoodsImg> goodsImgList) throws Exception {
+		if (goodsImgList == null || goodsImgList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		String dextUploadPath = env.getProperty("upload.dext.target.path");
+		String goodsTargetPath = env.getProperty("upload.goods.target.path");
+
+		int index = 1;
+		String strBrandNo = "";
+
+		// 오류 파일 목록
+		Collection<File> errorFileList = new ArrayList<File>();
+
+		// 1.업로드된 파일 rename 및 순서 재정렬
+		for (GoodsImg goodsImg : goodsImgList) {
+			// dx5에서 삭제한 파일은 skip
+			if (goodsImg.getMode().equals("D")) {
+				continue;
+			}
+
+			// 상품의 브랜드 번호 추출
+			if (strBrandNo.isEmpty()) {
+				Goods goods = new Goods();
+				goods.setGoodsCd(goodsImg.getGoodsCd());
+				Goods goodsInfo = goodsService.getGoods(goods);
+				if (goodsInfo == null || goodsInfo.getGoodsCd().isEmpty())
+					throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+				strBrandNo = String.valueOf(goodsInfo.getBrandNo());
+			}
+			String brandDir = GagaStringUtil.getLPadding(strBrandNo, 10, "0");
+
+			if (goodsImg.getMode().equals("C")) { // 업로드 된 파일 rename 처리
+//				String newFilename = goodsImg.getGoodsCd()
+//						+ "_" + goodsImg.getColorCd()
+//						+ "_" + String.valueOf(index)
+//						+ "(" + GagaDateUtil.getTodayTime() + ")"
+//						+ "." + StringUtils.getFilenameExtension(goodsImg.getSysImgNm());
+				String newFilename = goodsImg.getSysImgNm();
+
+				//브랜드 폴더 확인
+				String goodsUploadPath = GagaFileUtil.getConcatenationPath(goodsTargetPath, brandDir); // 브랜드 폴더
+				File brandPath = new File(goodsUploadPath);
+				if (!brandPath.exists()) {
+					brandPath.mkdir();
+				}
+
+				goodsUploadPath = GagaFileUtil.getConcatenationPath(goodsUploadPath, GagaDateUtil.getToday());		//브랜드+/+YYYYMMDD(UPLOAD 일 )
+				String brandYmdDir = GagaFileUtil.getConcatenationPath(brandDir, GagaDateUtil.getToday());	//디비 저장용
+
+				File uniqueFile = GagaFileUtil.getUniqueFile(new File(GagaFileUtil.getConcatenationPath(goodsUploadPath, newFilename)));
+				File newFile = new File(GagaFileUtil.getConcatenationPath(goodsUploadPath,  uniqueFile.getName()));
+				log.info("newFile.getPath(): {}", newFile.getPath());
+
+				// resizing 처리 시 오류가 발생할 경우 삭제하기 위해 설정
+				errorFileList.add(newFile);
+
+				File oldFile = new File(GagaFileUtil.getConcatenationPath(dextUploadPath, goodsImg.getSysImgNm()));
+				log.info("oldFile.getPath(): {}", oldFile.getPath());
+
+				File path = new File(goodsUploadPath);
+				if (!path.exists()) {
+					log.info("mkdir ={}", goodsUploadPath);
+					path.mkdir();
+				}
+
+				boolean copyFlag = GagaFileUtil.copyFile(oldFile, newFile);
+				if (copyFlag) {
+					//기존이미지 삭제
+					GagaFileUtil.deleteFile(oldFile.getPath());
+				}
+
+				goodsImg.setDispOrd(index++);
+				goodsImg.setOrgImgNm(GagaFileUtil.getConcatenationPath(brandYmdDir,newFile.getName()));
+				goodsImg.setSysImgNm(GagaFileUtil.getConcatenationPath(brandYmdDir,newFile.getName()));
+			} else {
+				goodsImg.setOrgImgNm(GagaFileUtil.getConcatenationPath(goodsImg.getSysImgUrl() ,goodsImg.getSysImgNm()));
+				goodsImg.setSysImgNm(GagaFileUtil.getConcatenationPath(goodsImg.getSysImgUrl() ,goodsImg.getSysImgNm()));
+				goodsImg.setDispOrd(index++);
+			}
+		}
+
+		// 2.dx5에서 삭제한 파일 실제 삭제 처리
+		for (GoodsImg goodsImg : goodsImgList) {
+			if (goodsImg.getMode().equals("D")) {
+				log.info("Original file to delete: {}", GagaFileUtil.getConcatenationPath(goodsTargetPath, goodsImg.getSysImgUrl(), goodsImg.getSysImgNm()));
+
+				// 상품이미지 삭제
+				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(goodsTargetPath, goodsImg.getSysImgUrl(), goodsImg.getSysImgNm()));
+
+			}
+		}
+
+		// 상품이미지 저장 처리
+		goodsService.saveGoodsImageList(goodsImgList);
+
+		return super.ok(message.getMessage("SUCC_0007"));
+	}
+
+	/**
+	 * 세트상품구성 화면
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 05. 26
+	 */
+	@GetMapping("/set/form")
+	@ResponseBody
+	public ModelAndView setForm(Goods goods) {
+		ModelAndView mav = new ModelAndView();
+
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 성별
+		mav.addObject("sexGbList", rendererService.getAvailCommonCodeList("G007"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 스타일년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 원산지
+		mav.addObject("originCdList", rendererService.getAvailCommonCodeList("G076"));
+
+		mav.addObject("params", goods);
+		mav.setViewName("goods/GoodsSetForm");
+		return mav;
+	}
+
+	/**
+	 * 세트 상품 등록
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 04
+	 */
+	@PostMapping("/set/save")
+	@ResponseBody
+	public GagaResponse saveGoodsSet(@RequestBody Goods goods) {
+		goodsService.saveGoodsSet(goods);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 딜상품구성 화면
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 29
+	 */
+	@GetMapping("/deal/form")
+	@ResponseBody
+	public ModelAndView dealForm(Goods goods) {
+		ModelAndView mav = new ModelAndView();
+
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 성별
+		mav.addObject("sexGbList", rendererService.getAvailCommonCodeList("G007"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 스타일년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 매입유형
+		mav.addObject("buyingTypeList", rendererService.getAvailCommonCodeList("G035"));
+		// 색상
+//		Color color = new Color();
+//		mav.addObject("colorCdList", rendererService.getColorList(color));
+		// 상품상태
+		// mav.addObject("goodsStatList",
+		// rendererService.getAvailCommonCodeList("G008"));
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 원산지
+		mav.addObject("makOriginList", rendererService.getAvailCommonCodeList("G076"));
+
+		mav.addObject("params", goods);
+		mav.setViewName("goods/GoodsDealForm");
+		return mav;
+	}
+
+	/**
+	 * 딜 상품 등록
+	 *
+	 * @param goods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	@PostMapping("/deal/save")
+	@ResponseBody
+	public GagaResponse saveGoodsDeal(@RequestBody Goods goods) {
+		goodsService.saveGoodsDeal(goods);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 대량 등록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/mass/register/form")
+	public ModelAndView massRegisterForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 상품상태
+		mav.addObject("goodsStatList", rendererService.getAvailCommonCodeList("G008"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// WMS 연동여부
+		mav.addObject("wmsSyncYn", commonService.getWmsSyncYn());
+		// 정보고시 목록
+		mav.addObject("niClsfCdList", rendererService.getAvailCommonCodeList("G004"));
+		// 사용자 업체
+		User loginInfo = systemService.getUser(TsaSession.getInfo().getUserNo());
+		String supplyCompCd = "NONE";
+		if (loginInfo != null) {
+			supplyCompCd = loginInfo.getSupplyCompCd();
+		}
+		mav.addObject("supplyCompCd", supplyCompCd);
+		mav.setViewName("goods/GoodsMassRegisterForm");
+
+		return mav;
+	}
+
+	/**
+	 * WMS입고상품관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/wms/incomelot/form")
+	public ModelAndView wmsInstockForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+
+		mav.setViewName("goods/GoodsWmsIncomelotForm");
+
+		return mav;
+	}
+
+	/**
+	 * WMS입고상품관리 목록 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2021. 01. 04
+	 */
+	@PostMapping("/wms/incomelot/list")
+	@ResponseBody
+	public GagaMap getGoodsWmsIncomelotList(@RequestBody WmsGoods wmsGoods) {
+
+		GagaMap result = new GagaMap();
+
+		wmsGoods.setPageable(new TsaPageRequest(wmsGoods.getPageNo() - 1, wmsGoods.getPageSize()));
+		wmsGoods.getPageable().setTotalCount(goodsService.getGoodsWmsIncomelotListCount(wmsGoods));
+
+		result.set("pageing", wmsGoods);
+		result.set("goodsList", goodsService.getGoodsWmsIncomelotList(wmsGoods));
+
+		return result;
+	}
+
+	/**
+	 * 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"));
+	}
+
+	/**
+	 * 상품품목변경관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	@GetMapping("/itemkind/form")
+	public ModelAndView itemkindForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		String selfYn = "Y";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+			selfYn = "N";
+		}
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, selfYn));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// 카테고리 구분
+		mav.addObject("cateGbList", rendererService.getAvailCommonCodeList("G032"));
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+
+		mav.setViewName("goods/GoodsItemkindForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 품목 변경 저장
+	 *
+	 * @param goodsList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 23
+	 */
+	@PostMapping("/itemKind/change/save")
+	@ResponseBody
+	public GagaResponse saveItemKindChange(@RequestBody Collection<Goods> goodsList) {
+		goodsService.saveItemKindChange(goodsList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 입점 가격 관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/supply/price/form")
+	public ModelAndView priceForm() {
+		ModelAndView mav = new ModelAndView();
+		// 공급업체
+		String supplyCompCd = "";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "N"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		mav.setViewName("goods/GoodsSupplyPriceForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 가격승인관리 목록 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	@PostMapping("/supply/price/list")
+	@ResponseBody
+	public Collection<GoodsPriceRes> getGoodsSupplyPriceList(@RequestBody GoodsPriceRes goodsPriceRes) {
+
+		return goodsService.getGoodsSupplyPriceList(goodsPriceRes);
+	}
+
+	/**
+	 * 상품 가격승인관리 승인 처리
+	 *
+	 * @param itemkindList
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 26
+	 */
+	@PostMapping("/supply/price/save")
+	@ResponseBody
+	public GagaResponse saveGoodsSupplyPrice(@RequestBody Collection<GoodsPriceRes> goodsPriceResList) {
+
+		if (!"G001_0000".equals(TsaSession.getInfo().getRoleCd()) && !"G001_A000".equals(TsaSession.getInfo().getRoleCd())
+			&& !"G001_A001".equals(TsaSession.getInfo().getRoleCd()) && !"G001_A100".equals(TsaSession.getInfo().getRoleCd())
+			&& !"G001_A101".equals(TsaSession.getInfo().getRoleCd())) {
+			throw new IllegalStateException("권한이 없습니다.");
+		}
+		goodsService.saveGoodsSupplyPrice(goodsPriceResList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 타이틀예약관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	@GetMapping("/title/reserve/form")
+	public ModelAndView titleReserveForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트
+		String supplyCompCd = "";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+		}
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 상품상태
+		// mav.addObject("goodsStatList",
+		// rendererService.getAvailCommonCodeList("G008"));
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 스타일년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+
+		mav.setViewName("goods/GoodsTitleReserveForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 타이틀 관리 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 30
+	 */
+	@PostMapping("/title/reserve/list")
+	@ResponseBody
+	public GagaMap goodsTitleReserveList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+		}
+
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsTitleReserveCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsTnmList", goodsService.getGoodsTitleReserveList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 상품등록 타이틀 예약등록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	@GetMapping("/title/reserve/popup/form")
+	@ResponseBody
+	public ModelAndView goodsRsvtTnmListForm(GoodsTnmRes goodsTnmRes) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsTitleReservePopupForm");
+		return mav;
+	}
+
+	/**
+	 * 상품 타이틀 예약 저장
+	 *
+	 * @param goodsTnmRes
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	@PostMapping("/title/reserve/save")
+	@ResponseBody
+	public GagaResponse saveGoodsRsvtTnm(@RequestBody GoodsTnmRes goodsTnmRes) {
+		goodsService.saveGoodsRsvtTnm(goodsTnmRes);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 타이틀 예약 삭제
+	 *
+	 * @param goodsTnmRes
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 02
+	 */
+	@PostMapping("/title/reserve/delete")
+	@ResponseBody
+	public GagaResponse deleteGoodsRsvtTnm(@RequestBody GoodsTnmRes goodsTnmRes) {
+		goodsService.deleteGoodsRsvtTnm(goodsTnmRes);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 상품 동영상관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@GetMapping("/video/form")
+	public ModelAndView videoForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsVideoForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 동영상 목록 조회
+	 *
+	 * @param goodsVideo
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/list")
+	@ResponseBody
+	public Collection<GoodsVideo> getGoodsVideoList(@RequestBody GoodsVideo goodsVideo) {
+		return goodsService.getGoodsVideoList(goodsVideo);
+	}
+
+	/**
+	 * 상품 동영상 미노출 변경
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/update/notUse")
+	@ResponseBody
+	public GagaResponse updateNotUseGoodsVideo(@RequestBody Collection<GoodsVideo> goodsVideos) {
+		goodsService.updateNotUseGoodsVideo(goodsVideos);
+		return super.ok(message.getMessage("SUCC_0009"));
+	}
+
+	/**
+	 * 상품동영상 수정/저장
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/save")
+	@ResponseBody
+	public GagaResponse saveGoodsVideo(@RequestBody Video video) {
+		goodsService.saveGoodsVideo(video);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품동영상 엑셀 저장
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/video/excel/save")
+	@ResponseBody
+	public GagaResponse saveExcelGoodsVideo(@RequestBody Video video) throws Exception {
+		String[] cellName = null;
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		cellName = new String[2];
+		cellName[0] = "displocVal";
+		cellName[1] = "videoVal";
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.default.target.path"), "excel");
+		Collection<GagaMap> dataList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, video.getExcelFileNm()), 0, cellName);
+
+		int cnt = goodsService.saveExcelGoodsVideo(dataList);
+
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, video.getExcelFileNm()));
+
+		return super.ok(cnt + " 건 처리되었습니다.");
+	}
+
+	/**
+	 * 상품 EP제외상품관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@GetMapping("/ep/skip/form")
+	public ModelAndView epSkipForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 상품상태
+		String[] exceptCds = {"G001_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+
+		mav.setViewName("goods/GoodsEpSkipForm");
+
+		return mav;
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@PostMapping("/ep/skip/list")
+	@ResponseBody
+	public GagaMap goodsEpSkipList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+		}
+
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsEpSkipCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsEpSkipList", goodsService.getGoodsEpSkipList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약등록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@GetMapping("/ep/skip/popup/form")
+	@ResponseBody
+	public ModelAndView goodsEpSkipPopupForm(GoodsEpSkip goodsEpSkip) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsEpSkipPopupForm");
+		return mav;
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 저장
+	 *
+	 * @param goodsEpSkip
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@PostMapping("/rsvt/ep/skip/save")
+	@ResponseBody
+	public GagaResponse saveGoodsRsvtEpSkip(@RequestBody GoodsEpSkip goodsEpSkip) {
+		goodsService.saveGoodsRsvtEpSkip(goodsEpSkip);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 네이버 EP 제외 상품 예약 삭제
+	 *
+	 * @param goodsEpSkip
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 03
+	 */
+	@PostMapping("/rsvt/ep/skip/delete")
+	@ResponseBody
+	public GagaResponse deleteGoodsEpSkip(@RequestBody GoodsEpSkip goodsEpSkip) {
+		goodsService.deleteGoodsEpSkip(goodsEpSkip);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 상품 재입고알림관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/reinbound/inform/form")
+	public ModelAndView reinboundInformForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 카테고리 구분
+		mav.addObject("cateGbList", rendererService.getAvailCommonCodeList("G032"));
+		// 상품상태
+		mav.addObject("goodsStatList", rendererService.getAvailCommonCodeList("G008"));
+
+		mav.setViewName("goods/GoodsReinboundInformForm");
+
+		return mav;
+	}
+
+	/**
+	 * 재입고알림 목록 조회
+	 *
+	 * @param goodsSearch
+	 * @return GagaMap
+	 * @author daehyoung
+	 * @since 2020. 07. 16
+	 */
+	@PostMapping("/reinbound/inform/list")
+	@ResponseBody
+	public GagaMap getReinboundInformList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getReinboundInformCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("reinboundInformList", goodsService.getReinboundInformList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 재입고알림 발송 처리
+	 *
+	 * @param params
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 12. 17
+	 */
+	@PostMapping("/reinbound/inform/send")
+	@ResponseBody
+	public GagaResponse sendReinboundInform(@RequestBody ReinboundInform reinboundInform) {
+		goodsService.sendReinboundInform(reinboundInform);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 예약판매관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/reserve/sell/form")
+	public ModelAndView reserveSellForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+
+		mav.setViewName("goods/GoodsReserveSellForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품예약판매 목록 조회
+	 *
+	 * @param goodsSearch
+	 * @return GagaMap
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@PostMapping("/reserve/sell/list")
+	@ResponseBody
+	public GagaMap goodsReserveSellList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001-B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsResSellCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsResSellList", goodsService.getGoodsResSellList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 상품예약판매 등록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@GetMapping("/reserve/sell/popup/form")
+	@ResponseBody
+	public ModelAndView goodsReserveSellRegistForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsReserveSellPopupForm");
+		return mav;
+	}
+
+	/**
+	 * 상품예약판매 저장
+	 *
+	 * @param goodsResSell
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@PostMapping("/reserve/sell/regist/save")
+	@ResponseBody
+	public GagaResponse saveGoodsResSell(@RequestBody GoodsResSell goodsResSell) {
+		goodsService.saveGoodsResSell(goodsResSell);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품예약판매 삭제
+	 *
+	 * @param goodsResSell
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 12
+	 */
+	@PostMapping("/reserve/sell/delete")
+	@ResponseBody
+	public GagaResponse deleteGoodsResSell(@RequestBody GoodsResSell goodsResSell) {
+		goodsService.deleteGoodsResSell(goodsResSell);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 상품 상세공지 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 16
+	 */
+	@GetMapping("/notice/form")
+	public ModelAndView detailNoticeForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+
+		mav.setViewName("goods/GoodsNoticeForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 상세공지 목록
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/notice/list")
+	@ResponseBody
+	public Collection<Notice> getNoticeList(@RequestBody GoodsSearch goodsSearch) {
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+		}
+
+		return goodsService.getNoticeList(goodsSearch);
+	}
+
+	/**
+	 * 상품 상세공지 상품목록
+	 * @param notice - 공지사항 정보
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 06
+	 */
+	@GetMapping("/notice/goods/list/{noticeSq}")
+	@ResponseBody
+	public Collection<NoticeGoods> getNoticeGoodsList(@PathVariable Integer noticeSq) {
+		Notice notice = new Notice();
+		notice.setNoticeSq(noticeSq);
+		return goodsService.getNoticeGoodsList(notice);
+	}
+
+	/**
+	 * 상품 상세공지 저장/등록
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 05
+	 */
+	@PostMapping("/notice/save")
+	@ResponseBody
+	public GagaResponse saveNotice(@RequestBody Notice notice) {
+		goodsService.saveNotice(notice);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 상세공지상품 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 09
+	 */
+	@PostMapping("/notice/goods/delete")
+	@ResponseBody
+	public GagaResponse deleteNoticeGoods(@RequestBody NoticeGoods noticeGoods) {
+		goodsService.deleteNoticeGoods(noticeGoods);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 상품조회 팝업
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 26
+	 */
+	@GetMapping("/popup/list/form")
+	@ResponseBody
+	public ModelAndView relationListForm(GoodsSearch goodsSearch) {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		String selfYn = "Y";
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			supplyCompCd = TsaSession.getInfo().getSupplyCompCd();
+			selfYn = "N";
+		}
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, selfYn));
+		//mav.addObject("supplyCompList", rendererService.getSupplyCompanyList());
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 성별
+		mav.addObject("sexGbList", rendererService.getAvailCommonCodeList("G007"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 연령대
+		mav.addObject("ageGrpCdList", rendererService.getAvailCommonCodeList("G023"));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// 상품유형
+		mav.addObject("goodsTypeList", rendererService.getAvailCommonCodeList("G056"));
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+
+		mav.addObject("params", goodsSearch);
+
+		mav.setViewName("goods/GoodsPopupListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품조회 팝업 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 26
+	 */
+	@PostMapping("/popup/list")
+	@ResponseBody
+	public GagaMap getPopupGoodsList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+
+			if ("searchExtendGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("EXTEND");
+			} else if ("searchMasterGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("MASTER");
+			}
+		}
+		log.info("[getPopupGoodsList] goodsSearch=>{}", goodsSearch);
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsListCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsList", goodsService.getGoodsList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 상품 가격예약관리 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/price/reserve/form")
+	public ModelAndView priceReserveForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+		// 정상이월
+		mav.addObject("formalGbList", rendererService.getAvailCommonCodeList("G009"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+		// 사용여부
+		mav.addObject("useYnList", rendererService.getAvailCommonCodeList("G002"));
+		// 품목
+		mav.addObject("itemkindList", rendererService.getAllItemkindList());
+		// MD
+		mav.addObject("brandMdList", rendererService.getBrandMdList());
+
+		mav.setViewName("goods/GoodsPriceReserveForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품 가격예약 목록 조회
+	 *
+	 * @param goodsSearch
+	 * @return GagaMap
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/price/reserve/list")
+	@ResponseBody
+	public GagaMap goodsPriceReserveList(@RequestBody GoodsSearch goodsSearch) {
+
+		GagaMap result = new GagaMap();
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001-B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		goodsSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		goodsSearch.setPageable(new TsaPageRequest(goodsSearch.getPageNo() - 1, goodsSearch.getPageSize()));
+		goodsSearch.getPageable().setTotalCount(goodsService.getGoodsPriceResCount(goodsSearch));
+
+		result.set("pageing", goodsSearch);
+		result.set("goodsPriceResList", goodsService.getGoodsPriceResList(goodsSearch));
+
+		return result;
+	}
+
+	/**
+	 * 상품 가격예약 등록 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/price/reserve/popup/form")
+	@ResponseBody
+	public ModelAndView goodsPriceReserveRegistForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsPriceReservePopupForm");
+		return mav;
+	}
+
+	/**
+	 * 상품 가격예약 저장
+	 *
+	 * @param goodsResSell
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/price/reserve/save")
+	@ResponseBody
+	public GagaResponse saveGoodsPriceRes(@RequestBody GoodsPriceRes goodsPriceRes) {
+		goodsService.createGoodPriceRes(goodsPriceRes);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 상품 가격예약 삭제
+	 *
+	 * @param goodsResSell
+	 * @return GagaResponse
+	 * @author eskim
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/price/reserve/delete")
+	@ResponseBody
+	public GagaResponse deleteGoodsPriceRes(@RequestBody GoodsPriceRes goodsPriceRes) {
+		goodsService.deleteGoodsPriceRes(goodsPriceRes);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 상품 가격예약 변경
+	 *
+	 * @param goods
+	 * @return
+	 * @throws Exception
+	 * @author eskim
+	 * @since 2020. 02. 20
+	 */
+	@PostMapping("/price/excelupload/save")
+	@ResponseBody
+	public GagaResponse saveGoodsPriceResvExcelupload(@RequestBody Goods goods) throws Exception {
+
+		ObjectMapper mapper = new ObjectMapper();
+
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellName = {"goodsCd", "resGoodsPrice", "applyStdt", "applyEddt"};
+
+		Collection<GagaMap> ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()), 0, cellName, 0);
+
+		Collection<GoodsPriceRes> goodsPriceList = new ArrayList<>();
+		for (GagaMap map : ecxelGoodsList) {
+			GoodsPriceRes goodsPriceRes = mapper.convertValue(map, GoodsPriceRes.class);
+			goodsPriceList.add(goodsPriceRes);
+		}
+
+		goodsService.saveGoodsPriceExcelupload(goodsPriceList, goods.getExcelFileNm());
+
+		// 파일 삭제
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, goods.getExcelFileNm()));
+
+		return super.ok("");
+	}
+
+	/**
+	 * 네이버 최저가 조회 화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 03
+	 */
+	@GetMapping("/naver/price/form")
+	@ResponseBody
+	public ModelAndView goodsNaverPriceForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		String supplyCompCd = "";
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(supplyCompCd, "Y"));
+		// 시즌
+		mav.addObject("seasonList", rendererService.getAvailCommonCodeList("G006"));
+		// 년도
+		int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) - 4;
+		mav.addObject("styleYearList", rendererService.getYearList(toYear, 0, 5));
+
+		mav.setViewName("goods/GoodsNaverPriceForm");
+		return mav;
+	}
+
+	/**
+	 * 상품 네이버 최저가 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 03
+	 */
+	@PostMapping("/naver/price/list")
+	@ResponseBody
+	public Collection<GoodsNaverLowestPrice> getGoodsNaverPriceList(@RequestBody GoodsSearch goodsSearch) {
+
+		// 입점업체담당자는 업체코드 설정
+		if ("G001_B000".equals(TsaSession.getInfo().getRoleCd())) {
+			goodsSearch.setSupplyCompCd(TsaSession.getInfo().getSupplyCompCd());
+			goodsSearch.setMdNo(TsaSession.getInfo().getUserNo().toString());
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+
+			if ("searchExtendGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("EXTEND");
+			} else if ("searchMasterGoodsCd".equals(goodsSearch.getSearch())) {
+				goodsSearch.setSearchGb("MASTER");
+			}
+		}
+
+		return goodsService.getGoodsNaverPriceList(goodsSearch);
+	}
+
+	/**
+	 * 네이버 최저가 상품 정보 조회
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 10. 03
+	 */
+	@PostMapping("/naver/lowest/price/save")
+	@ResponseBody
+	public Collection<GoodsNaverLowestPrice> saveGoodsNaverPrice(@RequestBody GoodsSearch goodsSearch) {
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isEmpty(goodsSearch.getCondition())) {
+			goodsSearch.setConditionList(goodsSearch.getCondition().replaceAll("\r", "").split("\n"));
+		}
+
+		return goodsService.saveGoodsNaverPrice(goodsSearch);
+	}
+
+	/**
+	 * 광고 키워드 관리  화면
+	 *
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 11
+	 */
+	@GetMapping("/ad/keyword/form")
+	@ResponseBody
+	public ModelAndView goodsAdForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("goods/GoodsAdKeywordForm");
+		return mav;
+	}
+
+	/**
+	 * 광고 키워드 목록
+	 * @param adKeyword
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	@PostMapping("/ad/keyword/list")
+	@ResponseBody
+	public Collection<AdKeyword> getAdKeywordList(@RequestBody AdKeyword adKeyword) {
+		return goodsService.getAdKeywordList(adKeyword);
+	}
+
+	/**
+	 * 광고 키워드 상품목록
+	 * @param adKeywordSq
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	@GetMapping("/ad/keyword/goods/list/{adKeywordSq}")
+	@ResponseBody
+	public Collection<AdKeywordGoods> getAdKeywordGoodsList(@PathVariable Integer adKeywordSq) {
+		AdKeyword adKeyword = new AdKeyword();
+		adKeyword.setAdKeywordSq(adKeywordSq);
+		return goodsService.getAdKeywordGoodsList(adKeyword);
+	}
+
+	/**
+	 * 광고 키워드 저장/등록
+	 *
+	 * @param adKeyword
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	@PostMapping("/ad/keyword/save")
+	@ResponseBody
+	public GagaResponse saveAdKeywordGoods(@RequestBody AdKeyword adKeyword) {
+		goodsService.saveAdKeywordGoods(adKeyword);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 광고 키워드 상품 삭제
+	 *
+	 * @param adKeywordGoods
+	 * @return
+	 * @author eskim
+	 * @since 2020. 12. 15
+	 */
+	@PostMapping("/ad/keyword/goods/delete")
+	@ResponseBody
+	public GagaResponse deleteAdKeywordGoods(@RequestBody AdKeywordGoods adKeywordGoods) {
+		goodsService.deleteAdKeywordGoods(adKeywordGoods);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 상품고시정보 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 8
+	 */
+	@GetMapping("/noti/info/form")
+	public ModelAndView goodsNotiInfoForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 고시분류
+		mav.addObject("niClsfCdList", rendererService.getAvailCommonCodeList("G004"));
+
+		mav.setViewName("goods/GoodsNotiInfoForm");
+
+		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"));
+	}
+}

+ 55 - 0
src/main/java/com/style24/admin/biz/web/TsaIndexController.java

@@ -0,0 +1,55 @@
+package com.style24.admin.biz.web;
+
+import javax.servlet.http.HttpSession;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.admin.support.security.session.TsaSession;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Index Controller
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Controller
+@Slf4j
+public class TsaIndexController extends TsaBaseController {
+
+	/**
+	 * 첫 페이지. 로그인 된 상태이면 대쉬보드 화면으로 아니면 로그인 페이지로
+	 * @param error - 로그인 오류 정보
+	 * @param session - HttpSession
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 5
+	 */
+	@GetMapping({"/", "/index"})
+	public ModelAndView index(@RequestParam(value = "error", required = false) boolean isError, HttpSession session) {
+		ModelAndView mav = new ModelAndView();
+
+		if (TsaSession.isLogin()) {
+			mav.setViewName("dashboard");
+			return mav;
+		}
+
+		log.info("isError: {}", isError);
+		if (isError) {
+			Exception e = (Exception)session.getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
+			log.info("e.getMessage(): {}", e.getMessage());
+			mav.addObject("error", e.getMessage());
+		}
+
+		// 로그인 페이지로
+		mav.setViewName("signin");
+
+		return mav;
+	}
+
+}

+ 549 - 0
src/main/java/com/style24/admin/biz/web/TsaMarketingController.java

@@ -0,0 +1,549 @@
+package com.style24.admin.biz.web;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.style24.admin.biz.service.*;
+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.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+/**
+ * 마케팅 Controller
+ * @author xodud1202
+ * @since 2020. 12.16
+ */
+@Controller
+@RequestMapping("/marketing")
+@Slf4j
+public class TsaMarketingController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaMarketingService marketingService;
+
+	@Autowired
+	private TsaBusinessService businessService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+	@Autowired
+	private TsaSystemService systemService;
+
+	@Autowired
+	private TsaMorebetterService morebetterService;
+
+	@Autowired
+	private TsaCouponService couponService;
+
+	/* xodud1202 진행 */
+	/**
+	 * 사은품 프로모션 관리 화면
+	 * @author xodud1202
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/freeGoods/promotion/form")
+	public ModelAndView freeGoodsPromotionForm() {
+		ModelAndView mav = new ModelAndView();
+		mav.setViewName("marketing/FreeGoodsPromotionForm");
+		return mav;
+	}
+
+	/**
+	 * 사은품 프로모션 목록 조회
+	 * @author xodud1202
+	 * @since 2020. 12. 16
+	 */
+	@PostMapping("/freeGoodsPromotion/list")
+	@ResponseBody
+	public GagaMap getFreeGoodsPromotionList(@RequestBody FreeGoodsPromotion param) {
+		GagaMap result = new GagaMap();
+
+		List<FreeGoodsPromotion> marketingList = (ArrayList<FreeGoodsPromotion>) marketingService.getFreeGoodsPromotionList(param);
+
+		param.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		param.setPageable(new TsaPageRequest(param.getPageNo() - 1, param.getPageSize()));
+		param.getPageable().setTotalCount(marketingList.size());
+
+		result.set("pageing", param);
+		result.set("freeGoodsList", marketingList);
+
+		return result;
+	}
+
+
+	/**
+	 * 사은품 프로모션 등록 팝업창
+	 * @param param
+	 * @return ModelAndView
+	 * @author xodud1202
+	 * @since 2020. 12. 23
+	 */
+	@ResponseBody
+	@GetMapping("/freeGoodsRegiPopup/form")
+	public ModelAndView freeGoodsRegiForm(FreeGoodsPromotion param) {
+		ModelAndView mav = new ModelAndView();
+
+		// 상품상태
+		String[] exceptCds = {"G008_00"};
+		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;
+	}
+
+
+	/* // xodud1202 진행 */
+
+	/* JSM 진행 */
+	/**
+	 * 쿠폰 리스트 목록 화면
+	 * @author xyzp1539
+	 * @since 2020-12-21
+	 */
+	@GetMapping("/coupon/form")
+	public ModelAndView couponListForm(){
+		ModelAndView mav = new ModelAndView();
+
+		// 쿠폰 유형 조회
+		mav.addObject("cpnTypeList" ,  rendererService.getCommonCodeList("G230"));
+		// 할인 유형 조회
+		mav.addObject("dcWayList" , rendererService.getCommonCodeList("G240"));
+		// 사이트 조회
+		mav.addObject("siteCdList" , rendererService.getCommonCodeList("G000"));
+
+		mav.setViewName("marketing/CouponListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 쿠폰 리스트 조회
+	 * @param  Coupon
+	 * @return GagaMap
+	 * @author xyzp1539
+	 * @since 2020-12-22
+	 */
+	@PostMapping("/coupon/list")
+	@ResponseBody
+	public GagaMap getCouponList(@RequestBody Coupon param){
+		GagaMap result =  new GagaMap();
+
+		ArrayList<Coupon> cpnList = couponService.getCouponList(param);
+		int cpnTotCnt = couponService.getCouponListCnt(param);
+
+		param.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		param.setPageable(new TsaPageRequest(param.getPageNo() - 1, param.getPageSize()));
+		param.getPageable().setTotalCount(cpnTotCnt);
+
+		result.set("pageing" , param);
+		result.set("cpnTotCnt" , cpnTotCnt);
+		result.set("cpnList" , cpnList);
+
+		return result;
+	}
+
+	/**
+	 * 쿠폰 등록 팝업 화면
+	 * @return ModelAndView
+	 * @author xyzp1539
+	 * @since 2020-12-23
+	 */
+	@GetMapping("/coupon/popup/form")
+	@ResponseBody
+	public ModelAndView couponCreatePopup() {
+		ModelAndView mav = new ModelAndView();
+		String num = "";
+
+		// 일시 시 리스트 세팅
+		Collection<CommonCode> hhList = new ArrayList<CommonCode>();
+		for(int i = 0; i < 24; i++) {
+			num = "";
+			CommonCode temp = new CommonCode();
+			if(i < 10) {
+				num = "0" + i;
+			} else {
+				num = String.valueOf(i);
+			}
+
+			// 상품상태
+			String[] exceptCds = {"G008_00"};
+			mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+
+			temp.setCd(num);
+			temp.setCdNm(num+"시");
+
+			hhList.add(temp);
+		}
+		// 일시 분 리스트 세팅
+		Collection<CommonCode> mmList = new ArrayList<CommonCode>();
+		for(int i = 0 ; i < 60; i++) {
+			num = "";
+			CommonCode temp = new CommonCode();
+			if(i < 10) {
+				num = "0" + i;
+			} else {
+				num = String.valueOf(i);
+			}
+			temp.setCd(num);
+			temp.setCdNm(num+"분");
+
+			mmList.add(temp);
+		}
+
+		// 쿠폰 유형 조회
+		mav.addObject("cpnTypeList" ,  rendererService.getCommonCodeList("G230"));
+		// 사용가능 고객구분 조회
+		mav.addObject("usableCustGbList", rendererService.getCommonCodeList("G100"));
+		// 사용가능 고객등급 조회
+		mav.addObject("usableCustGradeList", rendererService.getCommonCodeList("G101"));
+		// 사이트코드 조회
+		mav.addObject("siteCdList" , rendererService.getCommonCodeList("G000"));
+		// 재발급 여부 조회
+		mav.addObject("reissuanceList" , rendererService.getCommonCodeList("G231"));
+		// 할인방식 조회
+		mav.addObject("dcWayList" , rendererService.getCommonCodeList("G240"));
+		// 쿠폰다운로드 방식 조회
+		mav.addObject("dnGbList" , rendererService.getCommonCodeList("G058"));
+		// 결제수단 조회
+		mav.addObject("payTypeList" , rendererService.getCommonCodeList("G015"));
+		// 결제수단 조회
+		mav.addObject("cpnStatList" , rendererService.getCommonCodeList("G232"));
+		// 시간 분 리스트 세팅
+		mav.addObject("mmList" , mmList);
+		// 시간 시 리스트 세팅
+		mav.addObject("hhList" , hhList);
+		// 입점업체 조회
+		mav.addObject("ibSupplyCompList" , rendererService.getSupplyCompanyList("","N"));
+
+		mav.setViewName("marketing/CouponCreatePopupForm");
+		return mav;
+	}
+
+	/**
+	 * 쿠폰 저장
+	 * @param Coupon - 쿠폰 정보
+	 * @return
+	 * @author xyzp1539
+	 * @since 2021. 1. 11
+	 */
+	@PostMapping("/coupon/save")
+	@ResponseBody
+	public GagaResponse couponSave(@RequestBody Coupon coupon) {
+		log.info("couponSave : {}" , coupon);
+
+		couponService.couponSave(coupon);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+	/* // 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>) morebetterService.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;
+	}
+
+	/**
+	 * 다다익선 등록 화면
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2020. 12. 29
+	 */
+	@ResponseBody
+	@GetMapping("/morebetterRegPopup/form")
+	public ModelAndView morebetterRegForm(@RequestParam(value = "mode") String mode, @RequestParam(value = "tmtbSeq", required = false) Integer tmtbSeq,MoreBetter tmtb) {
+		ModelAndView mav = new ModelAndView();
+
+		// 상품상태 : 등록일때는 '대기'
+		String[] exceptCds = {"G008_00"};
+		mav.addObject("goodsStatList", rendererService.getCommonCodeList("G008", "Y", exceptCds));
+
+		// 할인구간 목록
+		mav.addObject("sectionGbList", rendererService.getAvailCommonCodeList("G810"));
+
+		// 할인구분 목록
+		mav.addObject("dcWayList", rendererService.getAvailCommonCodeList("G240"));
+
+		// 적용 상품구분 목록
+		String[] exceptGoodsCds = {"G800_30","G800_40"};
+		mav.addObject("applyGoodsGbList", rendererService.getCommonCodeList("G800", "Y", exceptGoodsCds));
+
+		// 제외 상품구분 목록
+		mav.addObject("exceptGoodsGbList", rendererService.getAvailCommonCodeList("G800"));
+
+		// 다다익선 상태 목록
+		mav.addObject("tmtbStatList", rendererService.getAvailCommonCodeList("G232"));
+
+		//tmtb sq 자동생성
+		Integer tmtbSq;
+		if("N".equals(mode)){
+			tmtbSq =  commonService.getNextSequence("SEQ_TMTB");
+			tmtb.setTmtbSq(tmtbSq);
+		}
+
+		if("U".equals(mode)){
+			// 다다익선 정보
+			mav.addObject("tmtbMstInfo", morebetterService.getMorebetterMstInfo(tmtbSeq));
+			mav.addObject("tmtbSupplyCompList", morebetterService.getMorebetterSupplyCompList(tmtbSeq,"G260_13"));
+			mav.addObject("tmtbBrandList", morebetterService.getMorebetterBrandList(tmtbSeq,"G260_12"));
+			mav.addObject("tmtbApplyGoodsList", morebetterService.getMorebetterApplyGoodsList(tmtbSeq,"G260_10"));
+			mav.addObject("tmtbExceptGoodsList", morebetterService.getMorebetterExceptGoodsList(tmtbSeq,"G260_10"));
+			mav.addObject("tmtbSectionValList", morebetterService.getMorebetterSectionValList(tmtbSeq));
+			mav.addObject("tmtbBurdenList", morebetterService.getMorebetterBurdenList(tmtbSeq));
+		}else{
+			mav.addObject("tmtbMstInfo", new MoreBetter());
+			mav.addObject("tmtbSupplyCompList", new MoreBetterGoods());
+			mav.addObject("tmtbBrandList", new MoreBetterGoods());
+			mav.addObject("tmtbApplyGoodsList", new MoreBetterGoods());
+			mav.addObject("tmtbExceptGoodsList", new MoreBetterGoods());
+			mav.addObject("tmtbSectionValList", new MoreBetterSection());
+			mav.addObject("tmtbBurdenList", new MoreBetterBurden());
+		}
+
+		mav.addObject("mode", mode);
+		mav.addObject("tmtbSeq", tmtbSeq);
+		mav.addObject("params", tmtb);
+		log.info("CHECK param tmtbSq::{}", tmtb.getTmtbSq());
+		mav.setViewName("marketing/MorebetterRegForm");
+		return mav;
+	}
+
+	/**
+	 * 다다익선 등록
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 1. 5
+	 */
+	@PostMapping("/morebetter/save")
+	@ResponseBody
+	public GagaResponse saveMorebetterDetail(@RequestBody MoreBetter tmtb) {
+		Collection<MoreBetterGoods> tmtbSupplyCompList = null;
+		Collection<MoreBetterGoods> tmtbBrandList = null;
+		Collection<MoreBetterGoods> tmtbApplyGoodsList = null;
+		Collection<MoreBetterGoods> tmtbExceptGoodsList = null;
+		Collection<MoreBetterBurden> tmtbBurdenList = null;
+		Collection<MoreBetterSection> tmtbSectionGbList = null;
+		ObjectMapper mapper = new ObjectMapper();
+
+		// 공급업체
+		try {
+			if (tmtb.getSupplyCompList() != null) {
+				tmtbSupplyCompList = mapper.readValue(tmtb.getSupplyCompList(), new TypeReference<Collection<MoreBetterGoods>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 브랜드
+		try {
+			if (tmtb.getBrandList() != null) {
+				tmtbBrandList = mapper.readValue(tmtb.getBrandList(), new TypeReference<Collection<MoreBetterGoods>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 적용상품
+		try {
+			if (tmtb.getApplyGoodsList() != null) {
+				tmtbApplyGoodsList = mapper.readValue(tmtb.getApplyGoodsList(), new TypeReference<Collection<MoreBetterGoods>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		// 적용상품
+		try {
+			if (tmtb.getExceptGoodsList() != null) {
+				tmtbExceptGoodsList = mapper.readValue(tmtb.getExceptGoodsList(), new TypeReference<Collection<MoreBetterGoods>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 할인구간
+		try {
+			if (tmtb.getSectionGbList() != null) {
+				tmtbSectionGbList = mapper.readValue(tmtb.getSectionGbList(), new TypeReference<Collection<MoreBetterSection>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 업체분담율
+		try {
+			if (tmtb.getBurdenList() != null) {
+				tmtbBurdenList = mapper.readValue(tmtb.getBurdenList(), new TypeReference<Collection<MoreBetterBurden>>() {
+				});
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		log.info("tmtb::{}", tmtb);
+
+		tmtb.setSupplyCompListNew(tmtbSupplyCompList);
+		tmtb.setBrandListNew(tmtbBrandList);
+		tmtb.setApplyGoodsListNew(tmtbApplyGoodsList);
+		tmtb.setExceptGoodsListNew(tmtbExceptGoodsList);
+		tmtb.setSectionGbListNew(tmtbSectionGbList);
+		tmtb.setBurdenListNew(tmtbBurdenList);
+
+		morebetterService.saveMoreBetterDetail(tmtb);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+	/**
+	 * 다다익선 공급업체 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 1. 12
+	 */
+	@PostMapping("/morebetter/supplyCompany/delete")
+	@ResponseBody
+	public GagaResponse deleteTmtbSupplyCompanyList(@RequestBody MoreBetterGoods moreBetterGoods) {
+		morebetterService.deleteTmtbSupplyCompanyList(moreBetterGoods);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 다다익선 브랜드 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 1. 12
+	 */
+	@PostMapping("/morebetter/brand/delete")
+	@ResponseBody
+	public GagaResponse deleteTmtbBrandList(@RequestBody MoreBetterGoods moreBetterGoods) {
+		morebetterService.deleteTmtbBrandList(moreBetterGoods);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 다다익선 적용상품 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 1. 12
+	 */
+	@PostMapping("/morebetter/applyGoods/delete")
+	@ResponseBody
+	public GagaResponse deleteTmtbApplyGoodsList(@RequestBody MoreBetterGoods moreBetterGoods) {
+		morebetterService.deleteTmtbApplyGoodsList(moreBetterGoods);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 다다익선 제외상품 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 1. 12
+	 */
+	@PostMapping("/morebetter/exceptGoods/delete")
+	@ResponseBody
+	public GagaResponse deleteTmtbExceptGoodsList(@RequestBody MoreBetterGoods moreBetterGoods) {
+		morebetterService.deleteTmtbExceptGoodsList(moreBetterGoods);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 다다익선 할인구간 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 1. 5
+	 */
+	@PostMapping("/morebetter/sectionVal/delete")
+	@ResponseBody
+	public GagaResponse deleteTmtbSectionValList(@RequestBody MoreBetterSection moreBetterSection) {
+		morebetterService.deleteTmtbSectionValList(moreBetterSection);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 다다익선 업체분담율 삭제
+	 *
+	 * @param
+	 * @return
+	 * @author bin2107
+	 * @since 2021. 1. 12
+	 */
+	@PostMapping("/morebetter/burden/delete")
+	@ResponseBody
+	public GagaResponse deleteTmtbBurdenList(@RequestBody MoreBetterBurden moreBetterBurden) {
+		morebetterService.deleteTmtbBurdenList(moreBetterBurden);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+	/* // CSB 진행 */
+}

+ 226 - 0
src/main/java/com/style24/admin/biz/web/TsaOcmController.java

@@ -0,0 +1,226 @@
+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;
+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.TsaOcmService;
+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 lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+
+/**
+ * 영업망관리 Controller
+ *
+ * @author gagamel
+ * @since 2020. 11. 5
+ */
+@Controller
+@RequestMapping("/ocm")
+@Slf4j
+public class TsaOcmController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaOcmService ocmService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	/**
+	 * 제휴몰관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	@GetMapping("/extmall/form")
+	public ModelAndView extmallForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 제휴몰벤더
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		mav.setViewName("ocm/ExtmallForm");
+
+		return mav;
+	}
+
+	/**
+	 * 제휴몰 목록
+	 * @param extmall - 제휴몰 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	@PostMapping("/extmall/list")
+	@ResponseBody
+	public Collection<Extmall> getExtmallList(@RequestBody Extmall extmall) {
+		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 - 제휴몰 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 5
+	 */
+	@PostMapping("/extmall/save")
+	@ResponseBody
+	public GagaResponse saveExtmall(@RequestBody Extmall extmall) {
+		ocmService.saveExtmall(extmall);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 제휴몰고시정보관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 6
+	 */
+	@GetMapping("/extmall/notiinfo/form")
+	public ModelAndView extmallNotiinfoForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 제휴몰벤더
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		mav.setViewName("ocm/ExtmallNotiinfoForm");
+
+		return mav;
+	}
+
+	/**
+	 * 제휴몰고시정보 목록
+	 * @param extmallNoti - 제휴몰고시정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 6
+	 */
+	@PostMapping("/extmall/notiinfo/list")
+	@ResponseBody
+	public Collection<ExtmallNoti> getExtmallNotiinfoList(@RequestBody ExtmallNoti extmallNoti) {
+		return ocmService.getExtmallNotiinfoList(extmallNoti);
+	}
+
+	/**
+	 * 제휴몰원산지 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 12
+	 */
+	@GetMapping("/extmall/origin/form")
+	public ModelAndView extmallOriginForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 제휴몰벤더
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		mav.setViewName("ocm/ExtmallOriginForm");
+
+		return mav;
+	}
+
+	/**
+	 * 제휴몰원산지 목록
+	 * @param extmallOrigin - 제휴몰원산지 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 12
+	 */
+	@PostMapping("/extmall/origin/list")
+	@ResponseBody
+	public Collection<ExtmallOrigin> getExtmallOriginList(@RequestBody ExtmallOrigin extmallOrigin) {
+		return ocmService.getExtmallOriginList(extmallOrigin);
+	}
+
+	/**
+	 * 제휴몰가격연계관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	@GetMapping("/extmall/price/sync/form")
+	public ModelAndView extmallPriceSyncForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 제휴몰벤더
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		mav.setViewName("ocm/ExtmallPriceSyncForm");
+
+		return mav;
+	}
+
+	/**
+	 * 제휴몰가격연계 목록
+	 * @param extmallPriceSync - 제휴몰가격연계 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	@PostMapping("/extmall/price/sync/list")
+	@ResponseBody
+	public Collection<ExtmallPriceSync> getExtmallPriceSyncList(@RequestBody ExtmallPriceSync extmallPriceSync) {
+		return ocmService.getExtmallPriceSyncList(extmallPriceSync);
+	}
+
+	/**
+	 * 제휴몰가격연계 등록/수정 처리
+	 * @param extmallPriceSyncList - 제휴몰가격연계 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 7
+	 */
+	@PostMapping("/extmall/price/sync/save")
+	@ResponseBody
+	public GagaResponse saveExtmallPriceSync(@RequestBody Collection<ExtmallPriceSync> extmallPriceSyncList) {
+		if (extmallPriceSyncList == null || extmallPriceSyncList.isEmpty()) {
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+		}
+
+		ocmService.saveExtmallPriceSync(extmallPriceSyncList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+}

+ 292 - 0
src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java

@@ -0,0 +1,292 @@
+package com.style24.admin.biz.web;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.style24.admin.biz.service.TsaOrderChangeService;
+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.domain.Order;
+import com.style24.persistence.domain.OrderChange;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 취소관리 Controller
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@Controller
+@RequestMapping("/orderChange")
+@Slf4j
+public class TsaOrderChangeController extends TsaBaseController {
+	
+	@Autowired
+	private TscMessageByLocale message;
+	
+	@Autowired
+	private Environment env;
+	
+	@Autowired
+	private TsaRendererService rendererService;
+	
+	@Autowired
+	private TsaOrderService orderService;
+	
+	@Autowired
+	private TsaOrderChangeService orderChangeService;
+	
+	/**
+	 * 취소요청 화면
+	 * 
+	 * @param ordNo - 주문번호
+	 * @param cncWait - 취소대기요청 구분
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	@GetMapping("/cancel/request/form")
+	public ModelAndView cancelRequestFrom(@RequestParam(value = "ordNo") int ordNo) {
+
+		Order order = new Order();
+		ModelAndView mav = new ModelAndView();
+		
+		order.setOrdNo(ordNo);
+		
+		// 취소가능 주문상세상탭값 설정
+		String[] ordDtlStatArr = new String[4];
+		ordDtlStatArr[0] = "G013_10";
+		ordDtlStatArr[1] = "G013_20";
+		ordDtlStatArr[2] = "G013_30";
+		ordDtlStatArr[3] = "G013_40";
+		
+		Collection<Order> cancelRequestTargetList = orderChangeService.getCancelRequestTargetList(order);
+
+		Collection<Order> orderInfoList = orderService.getOrderInfoList(order);
+
+		mav.addObject("chgReasonList"				, rendererService.getAvailCommonCodeList("G686"));	// 취소사유
+		mav.addObject("cancelRequestTargetList"		, cancelRequestTargetList);							// 취소요청대상 목록
+		mav.addObject("orderInfoList"				, orderInfoList);									// 주문정보
+		mav.addObject("ordNo"						, ordNo);
+
+		mav.setViewName("order/CancelRequestForm");
+		
+		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(); // 취소요청정보
+		
+		// To Do List
+		// @ 결품취소로직 현재는 일반취소로직만존재
+		// @ 주문취소 취소시 상태값 체크
+		// @ 취소, 반품시 배송비 체크 로직 
+		
+		// 1. 환불금액정보 계산 & 조회
+		mav = orderChangeService.orderCancelRefundAmt(cancelReqList);
+		
+		// 2. 주문변경기본정보 설정
+		mav.set("ordNo"			, cancelReq.getOrdNo());
+		mav.set("chgReason"		, cancelReq.getChgReason());
+		mav.set("chgMemo"		, cancelReq.getChgMemo());
+		
+		mav.set("accountNo"		, cancelReq.getAccountNo());
+		mav.set("accountNm"		, cancelReq.getAccountNm());
+		mav.set("bankCd"		, cancelReq.getBankCd());
+		
+		mav.set("allCanYn"		, cancelReq.getAllCanYn());
+		mav.set("isCustomer"	, cancelReq.getIsCustomer());
+		
+		// 3. 주문변경 DB 등록 (주문정보, 배송정보)
+		orderChangeService.orderCancel(mav);
+		
+		return super.ok("성공");
+	}
+	
+	/**
+	 * 주문 취소/반품 신청환불금액 계산
+	 * @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 = orderChangeService.orderCancelRefundAmt(cancelReqList);
+		
+		return mav;
+	}
+	
+	/**
+	 * 반품요청 화면
+	 * 
+	 * @param ordNo - 주문번호
+	 * @param cncWait - 취소대기요청 구분
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 22
+	 */
+	@GetMapping("/return/request/form")
+	public ModelAndView returnRequestFrom(@RequestParam(value = "ordNo") int ordNo) {
+
+		Order order = new Order();
+		ModelAndView mav = new ModelAndView();
+		
+		order.setOrdNo(ordNo);
+		
+		// 취소가능 주문상세상탭값 설정
+		String[] ordDtlStatArr = new String[3];
+		ordDtlStatArr[0] = "G013_50";
+		ordDtlStatArr[1] = "G013_55";
+		ordDtlStatArr[2] = "G013_60";
+		order.setOrdDtlStatArr(ordDtlStatArr);
+		
+		Collection<Order> cancelRequestTargetList = orderChangeService.getCancelRequestTargetList(order);
+
+		Collection<Order> orderInfoList = orderService.getOrderInfoList(order);
+
+		mav.addObject("chgReasonList"				, rendererService.getAvailCommonCodeList("G686"));	// 반품사유
+		mav.addObject("cancelRequestTargetList"		, cancelRequestTargetList);							// 반품요청대상 목록
+		mav.addObject("orderInfoList"				, orderInfoList);									// 주문정보
+		mav.addObject("ordNo"						, ordNo);
+		mav.addObject("orderDelvRtnAddrInfo"		, orderService.getDeliveryAddrList(order));			// 배송정보
+
+		mav.setViewName("order/ReturnRequestForm");
+		
+		return mav;
+	}
+	
+	
+	
+	/**
+	 * 환불계좌목록
+	 *
+	 * @param ordNo - 주문번호
+	 * @param custNo - 고객고유번호
+	 * @return Collection<TsaOrder>
+	 * @author jsshin
+	 * @since 2020. 10. 16.
+	 */
+	@GetMapping("/refund/account/info/list")
+	@ResponseBody
+	public Collection<Order> getRefundAccountInfoList(@RequestParam(value = "ordNo") int ordNo) {
+		Order order = new Order();
+		order.setOrdNo(ordNo);
+
+		Collection<Order> orderRfAccountInfo = orderChangeService.getRefundAccount(order);
+
+		return orderRfAccountInfo;
+	}
+	
+	/**
+	 * 환불계좌등록 화면
+	 *
+	 * @param ordNo - 주문번호
+	 * @param custNo - 고객고유번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2021. 01. 04.
+	 */
+	@GetMapping("/refund/account/create/form")
+	public ModelAndView refundAccountCreateForm(@RequestParam(value = "ordNo") int ordNo) {
+		ModelAndView mav = new ModelAndView();
+		Order order = new Order();
+		order.setOrdNo(ordNo);
+
+		Collection<Order> orderBasic 			= orderService.getOrderInfoList(order);
+		Collection<Order> orderRfAccountInfo 	= orderChangeService.getRefundAccount(order);
+
+		mav.addObject("bankList"				, rendererService.getCommonCodeList("G940"));
+		mav.addObject("orderRfAccountInfo"		, orderRfAccountInfo);
+		mav.addObject("orderBasic"				, orderBasic);
+
+		mav.setViewName("order/RefundAccountRegistForm");
+		
+		return mav;
+	}
+	
+	/**
+	 * 환불계좌등록
+	 *
+	 * @param order - 환불계좌정보
+	 * @return GagaResponse
+	 * @author jsh77b
+	 * @since 2021. 01. 04.
+	 */
+	@PostMapping("/account/save")
+	@ResponseBody
+	public GagaResponse saveRefundAccount(@RequestBody Order order) {
+		
+		int userNo = TsaSession.getInfo().getUserNo();
+		order.setUpdNo(userNo);
+		order.setRegNo(userNo);
+		
+		String accountCheck = "Y";
+		
+		// To Do List
+		// @ 환불계좌인증
+		
+		
+		if ("Y".equals(accountCheck)) {
+			orderChangeService.saveRefundAccount(order);
+		} else {
+			throw new IllegalStateException("환불계좌정보가 맞지 않습니다!");
+		}
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+	
+	
+}
+
+
+
+
+
+
+
+
+
+

+ 614 - 0
src/main/java/com/style24/admin/biz/web/TsaOrderController.java

@@ -0,0 +1,614 @@
+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;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+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.Order;
+import com.style24.persistence.domain.OrderChange;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 주문관리 Controller
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@Controller
+@RequestMapping("/order")
+@Slf4j
+public class TsaOrderController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaOrderService orderService;
+
+	/**
+	 * 주문목록조회
+	 *
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 11. 16
+	 */
+	@GetMapping("/list/form")
+	public ModelAndView orderListForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("siteCdList"		, rendererService.getAvailCommonCodeList("G012"));		// 사이트구분
+		mav.addObject("mallGbList"		, rendererService.getAvailCommonCodeList("G011"));		// 몰구분		
+		mav.addObject("supplyCompList"	, rendererService.getSupplyCompanyList());				// 공급업제목록
+		mav.addObject("ordStatList"		, rendererService.getAvailCommonCodeList("G012"));		// 주문상태코드
+		mav.addObject("ordDtlStatList"	, rendererService.getAvailCommonCodeList("G013"));		// 주문상세상태코드
+
+		mav.addObject("chgStatList"		, rendererService.getAvailCommonCodeList("G685"));		// 주문변경요청상태코드
+		mav.addObject("chgGbList"		, rendererService.getAvailCommonCodeList("G680"));		// 주문변경구분코드
+		mav.addObject("payMeansList"	, rendererService.getAvailCommonCodeList("G014"));		// 결제수단
+		mav.addObject("siteCdList"		, rendererService.getAvailCommonCodeList("G000"));		// 사이트구분
+		mav.addObject("formalGbList"	, rendererService.getAvailCommonCodeList("G009"));		// 정상/이월
+
+		mav.setViewName("order/OrderListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 주문목록
+	 *
+	 * @param order - 주문정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/list")
+	@ResponseBody
+	public GagaMap getOrderList(@RequestBody Order order) throws Exception {
+		GagaMap result = new GagaMap();
+
+		order.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		order.setPageable(new TsaPageRequest(order.getPageNo() - 1, order.getPageSize()));
+
+		// 주문상태 CD_GB 변경
+		if (order.getMultiOrdStat() != null) {
+			for (int i=0 ; i<order.getMultiOrdStat().length ; i++) {
+				String ordStat = order.getMultiOrdStat()[i].replace("G012", "G013");
+				order.getMultiOrdStat()[i] = ordStat;
+			}
+		}
+
+		// 주문취소상태 CD_GB 변경
+		if (order.getChgGb() != null) {
+			String chgDtlStat = order.getChgGb().replace("G680", "G685");
+			order.setChgGb(chgDtlStat);
+		}
+
+		// 주문전체건수 조회
+		int totalCount = orderService.getOrderListCount(order);
+		order.getPageable().setTotalCount(totalCount);
+
+		// 주문목록 페이지 조회
+		Collection<Order> orderList = orderService.getOrderList(order);
+
+		result.set("pageing"	, order);
+		result.set("orderList"	, orderList);
+
+		return result;
+	}
+
+	/**
+	 * 주문목록엑셀조회
+	 *
+	 * @param order - 주문정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/excel/search")
+	@ResponseBody
+	public Collection<Order> getOrderListSearchExcel(@RequestBody Order order) throws Exception {
+		ObjectMapper mapper = new ObjectMapper();
+
+		// 1. 엑셀업로드경로설정
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "");
+		String[] cellName = new String[1];
+
+		// 2. DB 처리 시 사용되는 파라미터명(셀명) 설정
+		cellName[0] = "ordNo";
+		Collection<GagaMap> dataList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()), 0, cellName);
+
+		Order searchOrder = new Order();
+		int[] ordNoList = new int[dataList.size()];
+		int cnt = 0;
+
+		for (GagaMap map : dataList) {
+			Order tmpOrder = mapper.convertValue(map, Order.class);
+			ordNoList[cnt] = tmpOrder.getOrdNo();
+			cnt++;
+		}
+
+		// 3. 주문번호 배열에 담고 주문목록 조회
+		searchOrder.setOrdNoList(ordNoList);
+		Collection<Order> orderList = orderService.getOrderList(searchOrder);
+
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()));
+
+		return orderList;
+	}
+
+	/**
+	 * 주문상세 화면
+	 *
+	 * @param ordNo - 주문번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 11. 26
+	 */
+	@GetMapping("/detail/info")
+	@ResponseBody
+	public ModelAndView orderDetailForm(@RequestParam(value = "ordNo") int ordNo) {
+		ModelAndView mav = new ModelAndView();
+
+		Order order = new Order();
+		order.setOrdNo(ordNo);
+		order.setDelYn("N");
+
+		// 1. 주문기본정보
+		mav.addObject("ordNo"					, ordNo);												// 주문번호
+		mav.addObject("userNo"					, TsaSession.getInfo().getUserNo());					// 관리자번호
+
+		mav.addObject("orderInfo"				, orderService.getOrderInfoList(order));				// 주문기본정보
+		mav.addObject("orderGoodsInfo"			, orderService.getOrderDetailList(order));				// 주문상품정보
+		mav.addObject("orderFreeGiftInfo"		, orderService.getOrderFreeGiftList(order));			// 주문사은품정보 2020.12.16 추가
+		mav.addObject("orderDeliveryAddrInfo"	, orderService.getDeliveryAddrList(order));				// 배송정보
+		mav.addObject("orderPaymentInfo"		, orderService.getOrderPaymentBasicInfoList(order));	// 결제정보
+		mav.addObject("orderDeliveryFeeInfo"	, orderService.getDeliveryFeeList(order));				// 배송비정보
+
+		// 2. 클레임정보
+		mav.addObject("orderChangeInfo"			, orderService.getOrderChangeList(order));				// 취소/반품/교환 요청 정보
+		mav.addObject("orderRefundInfo"			, orderService.getOrderRefundInfo(order));				// 환불정보
+
+		// 3. 주문메모정보
+		mav.addObject("orderCounselInfo"		, orderService.getOrderCounselInfo(order));				// 상담내역
+		mav.addObject("orderAdminMemoInfo"		, orderService.getOrderMemoList(order));				// 관리자메모목록
+
+		mav.setViewName("order/OrderDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 입점업체미발주목록화면
+	 *
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 11. 30
+	 */
+	@GetMapping("/seller/unorder/list/form")
+	public ModelAndView orderSellerUnorderListForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("supplyCompList"	, rendererService.getSupplyCompanyList());				// 공급업제목록
+		mav.addObject("ordStatList"		, rendererService.getAvailCommonCodeList("G012"));		// 주문상태코드
+		mav.addObject("ordDtlStatList"	, rendererService.getAvailCommonCodeList("G013"));		// 주문상세상태코드
+		mav.addObject("shipCompanyList"	, rendererService.getShipCompanyList());				// 택배사 목록
+
+		mav.setViewName("order/OrderSellerListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 입점업체미발주 주문목록 조회
+	 *
+	 * @param order - 주문정보
+	 * @return Collection<Order>
+	 * @author jsh77b
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/seller/unorder/list")
+	@ResponseBody
+	public Collection<Order> getOrderSellerUnorderList(@RequestBody Order order) throws Exception {
+		Collection<Order> orderList = orderService.getOrderSellerUnorderList(order);
+		return orderList;
+	}
+
+	/**
+	 * 입점업체미발주목록 - 엑셀다운로드시 주문상태값 변경(출고완료)
+	 *
+	 * @param orderList - 미발주목록
+	 * @return GagaResponse
+	 * @author jsh77b
+	 * @since 2020. 12. 01
+	 */
+	@PostMapping("/seller/unorder/status/save")
+	@ResponseBody
+	public GagaResponse saveUnorderStatus(@RequestBody Collection<Order> orderList) {
+		orderService.saveUnorderStatus(orderList);
+		return super.ok("");
+	}
+
+	/**
+	 * 입점업체미발주목록 - 엑셀다운로드
+	 *
+	 * @param request - request
+	 * @return ResponseEntity<InputStreamResource>
+	 * @throws Exception - exception
+	 * @author jsh77b
+	 * @since 2020. 12. 01
+	 */
+	@GetMapping("/seller/unorder/excel/list")
+	public ResponseEntity<InputStreamResource> downloadPickingGoodsExcelList(HttpServletRequest request) throws Exception {
+		String excelfileName 	= "입점출고목록_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilePath 	= GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+
+		Order order = new Order();
+		order.setRegNo(TsaSession.getInfo().getUserNo());
+		order.setSearch("EXCEL");
+
+		orderService.geSellerUnorderExcelList(order, excelFilePath);
+
+		return GagaFileUtil.writeFile(request, excelFilePath);
+	}
+
+	/**
+	 * 입점 송장 엑셀 업로드
+	 *
+	 * @param order - 주문정보
+	 * @return GagaMap
+	 * @throws Exception - exception
+	 * @author jsh77b
+	 * @since 2020. 12. 01
+	 */
+	@PostMapping("/seller/unorder/invoice/excelupload/save")
+	@ResponseBody
+	public GagaMap saveSellerUnorderInvoiceExcelupload(@RequestBody Order order) throws Exception {
+
+		ObjectMapper mapper = new ObjectMapper();
+
+		// 1. UPLOAD 경로 조회
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+
+		// 2. DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellName = {
+				"ordNo"
+				, "ordDtlNo"
+				, "itemCd"
+				, "optCd2"
+				, "itemOrdQty"
+				, "shipCompCd"
+				, "invoiceNo"
+		};
+
+		Collection<GagaMap> ecxelList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()), 0, cellName, 0);
+
+		// 3. 주문목록 매퍼 등록
+		Collection<Order> orderList = new ArrayList<>();
+		for (GagaMap map : ecxelList) {
+			Order tmpGoods = mapper.convertValue(map, Order.class);
+			orderList.add(tmpGoods);
+		}
+
+		// 4. 업로드된 임시 엑셀파일 삭제
+		if (CollectionUtils.isEmpty(orderList)) {
+			try {
+				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()));
+			} catch (IOException e) {
+				// Nothing Do
+			}
+			//throw new IllegalStateException(message.getMessage("FAIL_1001"));
+			throw new IllegalStateException("실패 했습니다.");
+		}
+
+		// 4. 주문상세번호 기준으로 송장번호 등록
+		String result = orderService.saveUnorderInvoice(orderList);
+		GagaMap map = new GagaMap();
+		map.set("msg", result);
+
+		// 5. 파일 삭제 (중복처리?)
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()));
+
+		return map;
+	}
+
+	/**
+	 * 입점업체미발주목록 - 송장번호 입력(출고완료)
+	 *
+	 * @param orderList - 송방번호 입력된 주문리스트
+	 * @return GagaMap
+	 * @author jsh77b
+	 * @since 2020. 12. 01
+	 */
+	@PostMapping(value = "/seller/unorder/invoice/save")
+	@ResponseBody
+	public GagaMap saveUnorderInvoice(@RequestBody Collection<Order> orderList) {
+		// 1. 송장번호 개별 등록
+		String result = orderService.saveUnorderInvoice(orderList);
+		GagaMap map = new GagaMap();
+		map.set("msg", result);
+		return map;
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 등록폼
+	 *
+	 * @param ordNo - 주문번호
+	 * @param seq - 시퀀스
+	 * @param mode - 신규/수정 구분
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/memo/create/form")
+	@ResponseBody
+	public ModelAndView orderMemoCreateFrom(@RequestParam(value = "ordNo") int ordNo, @RequestParam(value = "seq") int seq, @RequestParam(value = "mode") String mode) {
+		ModelAndView mav = new ModelAndView();
+		int userNo 		= TsaSession.getInfo().getUserNo();
+		String userNm 	= TsaSession.getInfo().getUserNm();
+
+		if ("U".equals(mode)) {
+			Order order = new Order();
+			order.setSeq(seq);
+			order.setOrdNo(ordNo);
+			order.setDelYn("N");
+
+			Order orderMemo = orderService.getOrderMemoInfo(order);
+
+			mav.addObject("orderMemo", orderMemo);
+		}
+
+		mav.addObject("userNo"	, userNo);
+		mav.addObject("userNm"	, userNm);
+		mav.addObject("ordNo"	, ordNo);
+		mav.addObject("seq"		, seq);
+		mav.addObject("mode"	, mode);
+
+		mav.setViewName("order/OrderMemoRegistForm");
+		return mav;
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모저장
+	 *
+	 * @param order - 주문정보
+	 * @return GagaResponse
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@PostMapping("/memo/save")
+	@ResponseBody
+	public GagaResponse createOrderMemo(@RequestBody Order order) {
+		int userNo = TsaSession.getInfo().getUserNo();
+		order.setRegNo(userNo);
+		order.setUpdNo(userNo);
+
+		// 신규
+		if ("N".equals(order.getMode())) {
+			orderService.createOrderMemo(order);
+		}
+		// 변경
+		else if ("U".equals(order.getMode())) {
+			orderService.updateOrderMemo(order);
+		}
+
+		return super.ok("저장이 완료되었습니다.");
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모삭제
+	 *
+	 * @param order - 주문정보
+	 * @return GagaResponse
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@PostMapping("memo/delete")
+	@ResponseBody
+	public GagaResponse deleteOrderMemo(@RequestBody Order order) {
+		int userNo = TsaSession.getInfo().getUserNo();
+		order.setRegNo(userNo);
+		order.setUpdNo(userNo);
+
+		orderService.deleteOrderMemo(order);
+
+		return super.ok("저장이 완료되었습니다.");
+	}
+
+	/**
+	 * 주문상세 > 주문요청 관리자 메모 > 메모삭제 > 새로고침
+	 *
+	 * @param ordNo - 주문번호
+	 * @return Collection<TsaOrder>
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/admin/memo/list/{ordNo}")
+	@ResponseBody
+	public Collection<Order> getOrderTsainMemoList(@PathVariable(value = "ordNo") int ordNo) {
+		Order order = new Order();
+		order.setOrdNo(ordNo);
+		return orderService.getOrderMemoList(order);
+	}
+
+	/**
+	 * 주문상품 상세 변경 이력 화면
+	 *
+	 * @param ordDtlNo - 주문상세번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/detail/change/hst/form/{ordDtlNo}")
+	@ResponseBody
+	public ModelAndView detailChangeHstFrom(@PathVariable(value = "ordDtlNo") int ordDtlNo) {
+
+		Order order = new Order();
+		ModelAndView mav = new ModelAndView();
+
+		order.setOrdDtlNo(ordDtlNo);
+		Collection<Order> orderDetailHstList = orderService.getOrderDetailHistoryList(order);
+
+		mav.addObject("orderDetailHstList", orderDetailHstList);
+		mav.setViewName("order/OrderDetailChangeHst");
+		return mav;
+	}
+
+	/**
+	 * 쿠폰사용 내역 팝업 화면
+	 *
+	 * @param ordNo - 주문번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/detail/coupon/hst/form/{ordNo}")
+	@ResponseBody
+	public ModelAndView detailCouponHstFrom(@PathVariable(value = "ordNo") int ordNo) {
+
+		Order order = new Order();
+		ModelAndView mav = new ModelAndView();
+
+		order.setOrdNo(ordNo);
+		Collection<Order> orderCouponHstList = orderService.getOrderDiscountCouponList(order);
+
+		mav.addObject("orderCouponHstList", orderCouponHstList);
+		mav.setViewName("order/OrderDetailCouponHst");
+		return mav;
+	}
+
+	/**
+	 * 포인트사용 내역 팝업 화면
+	 *
+	 * @param ordNo - 주문번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/detail/point/hst/form/{ordNo}")
+	@ResponseBody
+	public ModelAndView detailPointHstFrom(@PathVariable(value = "ordNo") int ordNo) {
+
+		Order order = new Order();
+		ModelAndView mav = new ModelAndView();
+
+		order.setOrdNo(ordNo);
+		Collection<Order> orderPointHstList = orderService.getOrderDiscountPointList(order);
+
+		mav.addObject("orderPointHstList", orderPointHstList);
+		mav.setViewName("order/OrderDetailPointHst");
+		return mav;
+	}
+
+	/**
+	 * 상품권사용 내역 팝업 화면
+	 *
+	 * @param ordNo - 주문번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/detail/giftcard/hst/form/{ordNo}")
+	@ResponseBody
+	public ModelAndView detailGiftcardHstFrom(@PathVariable(value = "ordNo") int ordNo) {
+
+		Order order = new Order();
+		ModelAndView mav = new ModelAndView();
+
+		order.setOrdNo(ordNo);
+		Collection<Order> orderGiftcardHstList = orderService.getOrderGiftcardHstList(order);
+
+		mav.addObject("orderGiftcardHstList", orderGiftcardHstList);
+		mav.setViewName("order/OrderDetailGiftcardHst");
+		return mav;
+	}
+
+	/**
+	 * 다다익선적용 내역 팝업 화면
+	 *
+	 * @param ordNo - 주문번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 12. 16
+	 */
+	@GetMapping("/detail/tmtb/hst/form/{ordNo}")
+	@ResponseBody
+	public ModelAndView detailTmtbHstFrom(@PathVariable(value = "ordNo") int ordNo) {
+
+		Order order = new Order();
+		ModelAndView mav = new ModelAndView();
+
+		order.setOrdNo(ordNo);
+		Collection<Order> orderTmtbHstList = orderService.getOrderTmtbHstList(order);
+
+		mav.addObject("orderTmtbHstList", orderTmtbHstList);
+		mav.setViewName("order/OrderDetailTmtbHst");
+		return mav;
+	}
+
+	/**
+	 * 주문상세상태를 변경
+	 *
+	 * @param order - 주문정보
+	 * @return GagaResponse
+	 * @author jsh77b
+	 * @since 2020. 12. 22.
+	 */
+	@PostMapping("/detail/ordDtlStat/changed")
+	@ResponseBody
+	public GagaResponse changedOrdDtlStat(@RequestBody Order order) {
+		int userNo = TsaSession.getInfo().getUserNo();
+		order.setUpdNo(userNo);
+		order.setRegNo(userNo);
+
+		orderService.changedOrdDtlStat(order);
+
+		return super.ok("성공");
+	}
+}
+
+
+
+
+
+
+
+
+
+

+ 75 - 0
src/main/java/com/style24/admin/biz/web/TsaPgController.java

@@ -0,0 +1,75 @@
+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;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+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.Order;
+import com.style24.persistence.domain.OrderChange;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * PG관리 Controller
+ *
+ * @author jsh77b
+ * @since 2020. 11. 16
+ */
+@Controller
+@RequestMapping("/pg")
+@Slf4j
+public class TsaPgController extends TsaBaseController {
+	
+	@Autowired
+	private TscMessageByLocale message;
+	
+	@Autowired
+	private Environment env;
+	
+	@Autowired
+	private TsaRendererService rendererService;
+	
+	@Autowired
+	private TsaOrderService orderService;
+	
+}
+
+
+
+
+
+
+
+
+
+

+ 475 - 0
src/main/java/com/style24/admin/biz/web/TsaPosController.java

@@ -0,0 +1,475 @@
+package com.style24.admin.biz.web;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+
+import com.style24.persistence.domain.CommonCode;
+//import com.style24.admin.biz.persistence.domain.TsaDeliveryAssign;
+import com.style24.persistence.domain.DeliveryLoc;
+
+import com.style24.persistence.domain.Delivery;
+import com.style24.persistence.domain.Pos;
+
+import com.style24.admin.biz.service.TsaDeliveryService;
+import com.style24.admin.biz.service.TsaPosService;
+import com.style24.admin.biz.service.TsaRendererService;
+//import com.style24.admin.biz.service.TsaStatisticsService;
+
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.admin.support.security.session.TsaSession;
+
+/**
+ * 매장 Controller
+ * 
+ * @author moon
+ * @since 2020. 11. 13
+ */
+@Controller
+@RequestMapping("/pos")
+@Slf4j
+public class TsaPosController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaPosService posService;
+
+	@Autowired
+	private TsaDeliveryService deliveryService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	//@Autowired
+	//private TsaStatisticsService statisticsService;
+
+	/**
+	 * 매장POS 로그인 처리
+	 * 
+	 * @param sellStoreCd - 매장코드
+	 * @param session - HttpSession
+	 * @return String - 포스메인화면이동
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/login")
+	public String posLogin(@RequestParam("delvLocCd") String delvLocCd, HttpSession session) {
+		String returnUrl = "forward:/pos/main";
+		if (TsaSession.isStoreLogin()) {
+			// 로그인 정보와 다른 매장코드로 접근시 기존 로그인 세션 삭제
+			log.info("delvLocCd {}", delvLocCd);
+			log.info("TsaSession.getPosInfo() {}", TsaSession.getPosInfo());
+			if (!delvLocCd.equals(TsaSession.getPosInfo().getDelvLocCd())) {
+				session.removeAttribute("sessionPosInfo");
+			}
+		}
+
+		Pos posParam = new Pos();
+		posParam.setDelvLocCd(delvLocCd);
+		Pos posInfo = posService.getStoreLoginInfo(posParam);
+
+		if (posInfo == null) {
+			log.debug(String.format("StoreCode={} was not found!", delvLocCd));
+			throw new UsernameNotFoundException(message.getMessage("LOGN_0001"));
+		}
+		// 세션 설정
+		session.setAttribute("sessionPosInfo", posInfo);
+
+		log.info("posInfo{}", posInfo);
+
+		return returnUrl;
+	}
+
+	/**
+	 * 매장POS 메인
+	 * 
+	 * @return ModelAndView
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/main")
+	public ModelAndView posMain() {
+		ModelAndView mav = new ModelAndView();
+		mav.addObject("delvLocNm", TsaSession.getPosInfo().getDelvLocNm());
+		mav.addObject("delvLocCd", TsaSession.getPosInfo().getDelvLocCd());
+
+		// 택배사명 목록
+		mav.addObject("shipCompanyList", rendererService.getShipCompanyList());
+
+		// 주문상세상태 
+		mav.addObject("orderDtlSateList", rendererService.getCommonCodeList("G013"));
+
+		mav.addObject("g017List", rendererService.getCommonCodeList("G017"));
+
+		mav.setViewName("pos/PosMainForm");
+		return mav;
+	}
+
+	/**
+	 * 출고대기목록 / 출고목록
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/wait/order/list")
+	@ResponseBody
+	public Collection<Pos> getPosWaitOrderList(@RequestBody Pos pos) {
+		pos.setDelvLocCd(TsaSession.getPosInfo().getDelvLocCd());
+		pos.setSupplyCompCd(TsaSession.getPosInfo().getSupplyCompCd());
+		return posService.getPosDeliveryList(pos);
+	}
+
+	/**
+	 * 출고목록
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/delivery/order/list")
+	@ResponseBody
+	public Collection<Pos> getPosDeliveryList(@RequestBody Pos pos) {
+		pos.setDelvLocCd(TsaSession.getPosInfo().getDelvLocCd());
+		pos.setSupplyCompCd(TsaSession.getPosInfo().getSupplyCompCd());
+		return posService.getPosDeliveryList(pos);
+	}
+
+	/**
+	 * 출고수락 / 출고거부 처리
+	 * 
+	 * @param pos - 매장정보
+	 * @return GagaResponse
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/delivery/assign/save")
+	@ResponseBody
+	public GagaResponse savePosDeliveryAssign(@RequestBody Pos pos) {
+		Delivery delivery = new Delivery();
+		delivery.setOrdNo(pos.getOrdNo());
+		delivery.setOrdDtlNo(pos.getOrdDtlNo());
+		delivery.setDelvLocCd(TsaSession.getPosInfo().getDelvLocCd());
+		delivery.setDelvArGb(pos.getDelvArGb());
+		delivery.setRejectReason(pos.getRejectReason());
+
+		String rtn = "";
+		if ("Y".equals(pos.getDelvArGb())) { //출고수락
+			//rtn = deliveryService.savePosDeliveryLocAssign(delivery);
+		} else {
+			//rtn = deliveryService.savePosDeliveryLocReject(delivery);
+		}
+		if ("S".equals(rtn)) {
+			return super.ok(message.getMessage("SUCC_0001"));
+		} else {
+			return super.ok("다른 출고처로 지정되었습니다.");
+		}
+	}
+
+	/**
+	 * 수락취소
+	 * 
+	 * @param pos - 매장정보
+	 * @return GagaResponse
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/delivery/assign/save/cancel")
+	@ResponseBody
+	public GagaResponse savePosDeliveryAssignCancel(@RequestBody Pos pos) {
+		Delivery delivery = new Delivery();
+		delivery.setOrdNo(pos.getOrdNo());
+		delivery.setOrdDtlNo(pos.getOrdDtlNo());
+		delivery.setDelvLocCd(TsaSession.getPosInfo().getDelvLocCd());
+		delivery.setDelvArGb(pos.getDelvArGb());
+		delivery.setRejectReason(pos.getRejectReason());
+
+		//deliveryService.savePosDeliveryLocRejectCancel(delivery);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 정산내역
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/usac/list")
+	@ResponseBody
+	public Collection<Pos> getPosUsacList(@RequestBody Pos pos) {
+		pos.setDelvLocCd(TsaSession.getPosInfo().getDelvLocCd());
+		return posService.getPosUsacList(pos);
+	}
+
+	/**
+	 * 출고거부이력 목록
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Delivery>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/ban/delivery/list")
+	@ResponseBody
+	public Collection<Delivery> getPosBanDeliveryList(@RequestBody Pos pos) {
+		Delivery delivery = new Delivery();
+		delivery.setDelvLocCd(TsaSession.getPosInfo().getDelvLocCd());
+		delivery.setGoodsGb("goodsCd");
+		delivery.setSearchTxt(pos.getGoodsCd());
+		Collection<Delivery> rejectList = new ArrayList<Delivery>();
+		return rejectList; //deliveryService.getDeliveryAssignList(delivery);
+	}
+
+	/**
+	 * 출고수락목록 배송준비중
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/invoice/save")
+	@ResponseBody
+	public Collection<GagaMap> saveInvoice(@RequestBody Collection<Pos> posList) {
+		String delvLocCd = TsaSession.getPosInfo().getDelvLocCd();
+		Double delvFeeRate = TsaSession.getPosInfo().getDelvFeeRate();
+
+		Collection<GagaMap> resultList = new ArrayList<>();
+		Collection<Pos> dtlNoList = new ArrayList<Pos>();
+
+		for (Pos posParam : posList) {
+
+			// 세트상품일경우 주문상세번호 중복제거 
+			String chk = "N";
+			for (Pos param : dtlNoList) {
+				if (param.getOrdDtlNo() == posParam.getOrdDtlNo()) {
+					chk = "Y";
+				}
+			}
+			if (!"Y".equals(chk)) {
+				Delivery delivery = new Delivery();
+				delivery.setOrdNo(posParam.getOrdNo());
+				delivery.setOrdDtlNo(posParam.getOrdDtlNo());
+				// TODO: 매장코드는 id 생성후 매핑???
+				//delivery.setUpdNo(delvLocCd);
+				//delivery.setRegNo(delvLocCd);
+				delivery.setDelvFeeRate(delvFeeRate);
+
+
+				GagaMap result = null;//deliveryService.savePos(delivery);
+
+				dtlNoList.add(posParam);
+				resultList.add(result);
+			}
+
+		}
+		return resultList;
+	}
+
+	/**
+	 * 출고수락목록 송상등록
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/invoice/save/invoiceno")
+	@ResponseBody
+	public Collection<GagaMap> savePosInvoice(@RequestBody Collection<Pos> posList) {
+		String delvLocCd = TsaSession.getPosInfo().getDelvLocCd();
+		Double delvFeeRate = TsaSession.getPosInfo().getDelvFeeRate();
+
+		Collection<GagaMap> resultList = new ArrayList<>();
+		Collection<Pos> dtlNoList = new ArrayList<Pos>();
+
+		for (Pos posParam : posList) {
+
+			// 세트상품일경우 주문상세번호 중복제거 
+			String chk = "N";
+			for (Pos param : dtlNoList) {
+				if (param.getOrdDtlNo() == posParam.getOrdDtlNo()) {
+					chk = "Y";
+				}
+			}
+			if (!"Y".equals(chk)) {
+				Delivery delivery = new Delivery();
+				delivery.setOrdNo(posParam.getOrdNo());
+				delivery.setOrdDtlNo(posParam.getOrdDtlNo());
+				// TOTO : 추후 
+				//delivery.setUpdId(delvLocCd);
+				//delivery.setRegId(delvLocCd);
+				delivery.setDelvFeeRate(delvFeeRate);
+				delivery.setInvoiceNo(posParam.getInvoiceNo());
+				delivery.setShipCompCd(posParam.getShipCompCd());
+
+				GagaMap result = null; //deliveryService.savePosInvoice(delivery);
+
+				dtlNoList.add(posParam);
+				resultList.add(result);
+			}
+
+		}
+		return resultList;
+	}
+
+	/**
+	 * 엑셀다운로드
+	 * 
+	 * @param pos - 매장정보
+	 * @return Collection<Pos>
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */	
+	@GetMapping("/order/excel/list")
+	public ResponseEntity<InputStreamResource> downloadOrderExcelList(HttpServletRequest request, Pos pos) throws Exception {
+		if (StringUtils.isBlank(pos.getOrdDtlNos())) {
+			throw new IllegalStateException(message.getMessage("FAIL_1003"));
+		}
+		String excelfileName = "CNPlus 엑셀양식_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilenameWithPath = GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+		log.info("pos {}", pos.getOrdDtlNos());
+		if (StringUtils.isNotBlank(pos.getOrdDtlNos())) {
+			pos.setOrdDtlNoArr(pos.getOrdDtlNos().split(","));
+		}
+		// 대용량엑셀파일다운로드는 이런 식으로 ...
+		posService.getOrderExcelList(pos, excelFilenameWithPath);
+
+		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
+	}
+
+	/**
+	 * 매장 출고처지정 수략율 통계화면
+	 *
+	 * @author card007
+	 * @since 2020. 09. 16
+	 */
+	/*
+	@GetMapping("/delivery/assign/statistics/form")
+	public ModelAndView storeDeliveryAssignStatisticsForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList());
+
+		mav.setViewName("statistics/DeliveryAssignForm");
+
+		return mav;
+	}
+	*/
+
+	/**
+	 * 매장 출고처지정 수략율 통계 조회
+	 *
+	 * @param TsaDeliveryAssign - 출고처지정
+	 * @return Collection<TsaDeliveryAssign>
+	 * @author card007
+	 * @since 2020. 09. 16
+	 */
+	/*
+	@PostMapping("/delivery/assign/statistics/list")
+	@ResponseBody
+	public Collection<TsaDeliveryAssign> getStoreDeliveryAssignStatistics(@RequestBody TsaDeliveryAssign deliveryAssign) {
+		return statisticsService.getStoreDeliveryAssignStatistics(deliveryAssign);
+	}
+	*/
+	/**
+	 * 매장 출고처지정 상세 데이터 조회
+	 *
+	 * @param TsaDeliveryAssign - 출고처지정
+	 * @return Collection<TsaDeliveryAssign>
+	 * @author card007
+	 * @since 2020. 09. 16
+	 */
+	/*
+	@GetMapping("/delivery/assign/statistics/detail/{delvLocCd}")
+	@ResponseBody
+	public ModelAndView storeDeliveryAssignDetailForm(@PathVariable String delvLocCd, @RequestParam(value = "stDate", required = false) String stDate, @RequestParam(value = "edDate", required = false) String edDate, @RequestParam(value = "brandCd", required = false) String brandCd) {
+		ModelAndView mav = new ModelAndView();
+
+		TsaDeliveryAssign deliveryAssign = new TsaDeliveryAssign();
+		deliveryAssign.setDelvLocCd(delvLocCd);
+		deliveryAssign.setBrandCd(brandCd);
+		deliveryAssign.setStDate(stDate);
+		deliveryAssign.setEdDate(edDate);
+
+		Collection<TsaDeliveryAssign> dataList = statisticsService.getStoreDeliveryAssignDetailList(deliveryAssign);
+
+		mav.addObject("dataList", dataList);
+
+		// 출고거부사유
+		mav.addObject("noList", rendererService.getAvailCommonCodeList("G017"));
+
+		mav.setViewName("statistics/DeliveryAssignDetailPopupForm");
+
+		return mav;
+	}
+	*/
+
+	/**
+	 * 입점업체브랜드 목록
+	 *
+	 * @param supplyCompCd - 입점업체관리일련번호
+	 * @return
+	 * @author moon
+	 * @since 2019. 11. 13
+	 */
+	@GetMapping("/delivery/assign/statistics/brand/list/{supplyCompCd}")
+	@ResponseBody
+	public Collection<CommonCode> getSupplyCompanyBrandList(@PathVariable String supplyCompCd) {
+		return rendererService.getSupplyCompanyBrandList(supplyCompCd);
+	}
+
+	/**
+	 * 출고처 목록
+	 *
+	 * @param deliveryLoc - 출고처 정보
+	 * @return
+	 * @author moon
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/delivery/assign/statistics/store/stock/link/list/{supplyCompCd}")
+	@ResponseBody
+	public Collection<CommonCode> getStoreStockLinkList(@PathVariable String supplyCompCd) {
+		DeliveryLoc deliveryLoc = new DeliveryLoc();
+		deliveryLoc.setSupplyCompCd(supplyCompCd);
+		deliveryLoc.setDelvLocClsf("21");
+		return rendererService.getDeliveryLocList(deliveryLoc);
+	}
+}

+ 216 - 0
src/main/java/com/style24/admin/biz/web/TsaRendererController.java

@@ -0,0 +1,216 @@
+package com.style24.admin.biz.web;
+
+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.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.persistence.domain.Color;
+import com.style24.persistence.domain.CommonCode;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 콤보박스, 체크박스, 라디오버튼 구성 시 필요한 Renderer Controller
+ *
+ * @author renderer
+ * @since 2020. 10. 20
+ */
+@Controller
+@RequestMapping("/renderer")
+@Slf4j
+public class TsaRendererController extends TsaBaseController {
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	/**
+	 * 공급업체 목록
+	 * @param brandGb - 브랜드구분(S:자사브랜드, E:입점브랜드)
+	 * @return
+	 * @author gagamel
+	 * @since 2019. 11. 4
+	 */
+	@GetMapping("/supply/company/list/{brandGb}")
+	@ResponseBody
+	public Collection<CommonCode> getSupplyCompanyList(@PathVariable String brandGb) {
+		return brandGb.equals("S") ? rendererService.getSelfSupplyCompanyList() : rendererService.getEntrSupplyCompanyList();
+	}
+
+	/**
+	 * 입점업체브랜드 목록
+	 * @param supplyCompCd - 입점업체관리일련번호
+	 * @return
+	 * @author gagamel
+	 * @since 2019. 6. 7
+	 */
+	@GetMapping("/supplyCompany/brand/list/{supplyCompCd}")
+	@ResponseBody
+	public Collection<CommonCode> getSupplyCompanyBrandList(@PathVariable String supplyCompCd) {
+		return rendererService.getSupplyCompanyBrandList(supplyCompCd);
+	}
+
+//
+//	/**
+//	 * 브랜드그룹별 브랜드 목록
+//	 * @param brandGrpNm - 브랜드그룹명
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 1. 10
+//	 */
+//	@GetMapping("/group/brand/list/{brandGrpNm}")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getGroupBrandList(@PathVariable String brandGrpNm) {
+//		return rendererService.getGroupBrandList(brandGrpNm);
+//	}
+//
+//	/**
+//	 * 권한별 브랜드 목록
+//	 * @return
+//	 * @author eskim
+//	 * @since 2019. 6.17
+//	 */
+//	@GetMapping("/brand/AuthBrandlist")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getAuthBrandList() {
+//		return rendererService.getAuthBrandList(AdmSession.getInfo().getUserId());
+//	}
+
+	/**
+	 * 출고처 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 4
+	 */
+	@GetMapping("/delvloc/list/{supplyCompCd}")
+	@ResponseBody
+	public Collection<CommonCode> getDeliveryLocList(@PathVariable String supplyCompCd) {
+		return rendererService.getDeliveryLocList(supplyCompCd);
+	}
+
+	/**
+	 * 배송비정책 목록
+	 * @param supplyCompCd - 공급업체코드
+	 * @return
+	 * @author eskim
+	 * @since 2020. 11. 25
+	 */
+	@GetMapping("/delvFee/list/{supplyCompCd}")
+	@ResponseBody
+	public Collection<CommonCode> getDeliveryFeeList(@PathVariable String supplyCompCd) {
+		return rendererService.getSupplyDeliveryFeePolicyList(supplyCompCd);
+	}
+
+//	/**
+//	 * 벤더외부몰 목록
+//	 * @param vendorId - 벤더ID
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2019. 8. 11
+//	 */
+//	@GetMapping("/vendor/extmall/list/{vendorId}")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getVendorExtmallList(@PathVariable String vendorId) {
+//		return rendererService.getVendorExtmallList(vendorId);
+//	}
+//
+//	/**
+//	 * 벤더외부몰판매매장 목록
+//	 * @param vendorId - 벤더ID
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 4. 28
+//	 */
+//	@GetMapping("/vendor/extmall/sellStore/list/{vendorId}")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getVendorExtmallSellStoreList(@PathVariable String vendorId) {
+//		return rendererService.getVendorExtmallSellStoreList(vendorId);
+//	}
+//
+	/**
+	 * 현재 유효한 공통코드 목록
+	 * @param cdGb - 공통그룹코드
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 22
+	 */
+	@GetMapping("/avail/commonCode/list/{cdGb}")
+	@ResponseBody
+	public Collection<CommonCode> getAvailCommonCodeList(@PathVariable String cdGb) {
+		return rendererService.getAvailCommonCodeList(cdGb);
+	}
+
+	/**
+	 * 업체별 색상 목록
+	 * @param cdGb - 공통그룹코드
+	 * @return
+	 * @author eskim
+	 * @since 2020. 01. 22
+	 */
+	@GetMapping("/avail/color/list")
+	@ResponseBody
+	public Collection<CommonCode> getColorList() {
+		Color color = new Color();
+		return rendererService.getColorList(color);
+	}
+//
+//	/**
+//	 * MD별 브랜드 목록
+//	 * @param mdId - 엠디아이디
+//	 * @return
+//	 * @author jaewonho
+//	 * @since 2020. 02. 11
+//	 */
+//	@GetMapping("/md/brand/list/{mdId}")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getMdBrandList(@PathVariable String mdId) {
+//		return rendererService.getMdBrandList(mdId);
+//	}
+//
+//	/**
+//	 * MD별 브랜드그룹 목록
+//	 * @param mdId - 엠디아이디
+//	 * @return
+//	 * @author jaewonho
+//	 * @since 2020. 02. 11
+//	 */
+//	@GetMapping("/md/brand/grp/list/{mdId}")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getMdBrandGrpList(@PathVariable String mdId) {
+//		return rendererService.getMdBrandGrpList(mdId);
+//	}
+//
+//	/**
+//	 * 판매몰 목록
+//	 * @param
+//	 * @return
+//	 * @author swkim
+//	 * @since 2020. 03. 19
+//	 */
+//	@GetMapping("/sellStore/list")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getSellStoreList() {
+//		return rendererService.getSellStoreList();
+//	}
+//
+//	/**
+//	 * 제휴링크 목록
+//	 * @param afChannel - 제휴채널
+//	 * @return
+//	 * @author gagamel
+//	 * @since 2020. 5. 4
+//	 */
+//	@GetMapping("/aflink/list/{afChannel}")
+//	@ResponseBody
+//	public Collection<AdmCommonCode> getAflinkList(@PathVariable String afChannel) {
+//		return rendererService.getAflinkList(afChannel);
+//	}
+
+}

+ 169 - 0
src/main/java/com/style24/admin/biz/web/TsaSettleController.java

@@ -0,0 +1,169 @@
+package com.style24.admin.biz.web;
+
+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.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaBusinessService;
+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 lombok.extern.slf4j.Slf4j;
+
+/**
+ * 정산 Controller
+ *
+ * @author jaewonHo
+ * @since 2020. 10. 22
+ */
+@Controller
+@RequestMapping("/settle")
+@Slf4j
+public class TsaSettleController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaBusinessService businessService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	/**
+	 * 상품정산 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 22
+	 */
+	@GetMapping("/goods/form")
+	public ModelAndView goodsSettleForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 유통구분
+		mav.addObject("distributionGbList", rendererService.getCommonCodeList("G065"));
+
+		mav.setViewName("settle/GoodsSettleForm");
+
+		return mav;
+	}
+
+	/**
+	 * 배송비정산 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 22
+	 **/
+	@GetMapping("/delivery/fee/form")
+	public ModelAndView deliveryFeeSettleForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 유통구분
+		mav.addObject("distributionGbList", rendererService.getCommonCodeList("G065"));
+
+		mav.setViewName("settle/DeliveryFeeSettleForm");
+
+		return mav;
+	}
+
+	/**
+	 * 정산확정관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 22
+	 */
+	@GetMapping("/confirm/form")
+	public ModelAndView settleConfirmForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 유통구분
+		mav.addObject("distributionGbList", rendererService.getCommonCodeList("G065"));
+
+		// 은행
+		mav.addObject("bankList", rendererService.getCommonCodeList("G940"));
+
+		mav.setViewName("settle/SettleConfirmForm");
+
+		return mav;
+	}
+
+	/**
+	 * 업체별정산내역 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 22
+	 */
+	@GetMapping("/supply/company/form")
+	public ModelAndView supplyCompanySettleForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		mav.setViewName("settle/SupplyCompanySettleForm");
+
+		return mav;
+	}
+
+	/**
+	 * PG입금정산 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 22
+	 */
+	@GetMapping("/pg/deposit/form")
+	public ModelAndView paygateDepositForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// PG구분
+		mav.addObject("pgGbList", rendererService.getCommonCodeList("G015"));
+
+		// 결제수단
+		mav.addObject("payMeansList", rendererService.getCommonCodeList("G014"));
+
+		mav.setViewName("settle/PgDepositSettleForm");
+
+		return mav;
+	}
+
+	/**
+	 * 상품권정산 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 22
+	 */
+	@GetMapping("/giftcard/form")
+	public ModelAndView giftcardForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// PG구분
+		mav.addObject("pgGbList", rendererService.getCommonCodeList("G015"));
+
+		// 결제수단
+		mav.addObject("payMeansList", rendererService.getCommonCodeList("G014"));
+
+		mav.setViewName("settle/GiftcardSettleForm");
+
+		return mav;
+	}
+
+}

+ 91 - 0
src/main/java/com/style24/admin/biz/web/TsaShipController.java

@@ -0,0 +1,91 @@
+package com.style24.admin.biz.web;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaDeliveryService;
+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.Delivery;
+import com.style24.persistence.domain.DeliveryLoc;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+
+/**
+ * 택배 Controller
+ *
+ * @author moon
+ * @since 2020. 11. 17
+ */
+@Controller
+@RequestMapping("/ship")
+@Slf4j
+public class TsaShipController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaDeliveryService deliveryService;
+
+	@Value("${upload.default.target.path}")
+	private String uploadTargetPath;
+
+	/**
+	 * 배송/회수지시목록 화면
+	 * 
+	 * @return ModelAndView
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 17
+	 */
+	@RequestMapping(value = "/dwdirect/list/form")
+	public ModelAndView deliveryWithdrawDirectiveListForm() throws Exception {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트구분
+		mav.addObject("siteCdList", rendererService.getAvailCommonCodeList("G000"));
+
+		mav.setViewName("delivery/DeliveryWithdrawDirectiveListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 배송/회수지시 목록
+	 * 
+	 * @param dwDirective - 배송/회수지시 정보
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 17
+	 */
+	@RequestMapping(value = "/dwdirect/list", method = RequestMethod.POST)
+	@ResponseBody
+	public Collection<Delivery> getDeliveryWithdrawDirectiveList(@RequestBody Delivery dwDirective) throws Exception {
+		return deliveryService.getDeliveryWithdrawDirectiveList(dwDirective);
+	}	
+}

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

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

+ 586 - 0
src/main/java/com/style24/admin/biz/web/TsaSystemController.java

@@ -0,0 +1,586 @@
+package com.style24.admin.biz.web;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaSystemService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Alarm;
+import com.style24.persistence.domain.AlarmReceiver;
+import com.style24.persistence.domain.Batch;
+import com.style24.persistence.domain.BatchLog;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.SampleFile;
+import com.style24.persistence.domain.User;
+import com.style24.persistence.domain.UserMenu;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+import com.gagaframework.web.security.GagaPasswordEncoder;
+
+/**
+ * 운영관리 Controller
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@Controller
+@RequestMapping("/system")
+@Slf4j
+public class TsaSystemController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaSystemService systemService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private GagaPasswordEncoder passwordEncoder;
+
+	@Value("${upload.default.target.path}")
+	private String uploadTargetPath;
+
+	/**
+	 * 사용자관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/form")
+	public ModelAndView userForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체 콤보박스 목록
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 권한 콤보박스 목록
+		mav.addObject("roleList", rendererService.getCommonCodeList("G001"));
+
+		mav.setViewName("system/UserForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사용자 목록
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/list")
+	@ResponseBody
+	public Collection<User> getUserList(@RequestBody User user) {
+		return systemService.getUserList(user);
+	}
+
+	/**
+	 * 사용자 목록 삭제 처리
+	 * @param userList - 사용자 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/list/delete")
+	@ResponseBody
+	public GagaResponse deleteUserList(@RequestBody Collection<User> userList) {
+		if (userList == null || userList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		systemService.deleteUserList(userList);
+
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 사용자 정보 조회
+	 * @param mode   - 모드(N:신규, U:상세/수정, C:복사)
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/info/form")
+	public ModelAndView getUser(@RequestParam(value = "mode") String mode,
+		@RequestParam(value = "userNo", required = false) Integer userNo) {
+		ModelAndView mav = new ModelAndView();
+
+		// 권한 콤보박스 목록
+		if (!TsaSession.getInfo().getRoleCd().equals("0000")) {
+			mav.addObject("roleList", rendererService.getCommonCodeList("G001", "Y", new String[] {"0000"}));
+		} else {
+			mav.addObject("roleList", rendererService.getAvailCommonCodeList("G001"));
+		}
+
+		// 공급업체 콤보박스 목록
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 외부몰벤더 콤보박스 목록
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		if (mode.equals("U")) {
+			// 어드민사용자정보
+			mav.addObject("userInfo", systemService.getUser(userNo));
+		} else {
+			mav.addObject("userInfo", new User());
+		}
+
+		mav.addObject("mode", mode);
+
+		mav.setViewName("system/UserDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사용자ID 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/id/{userId}")
+	@ResponseBody
+	public int getUserIdCount(@PathVariable("userId") String userId) {
+		return systemService.getUserIdCount(userId);
+	}
+
+	/**
+	 * 사용자 저장 처리
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/save")
+	@ResponseBody
+	public GagaResponse saveUser(@RequestBody User user) {
+		if (user.getMode().equals("N")) { // 신규등록
+			user.setPasswd(passwordEncoder.encode(user.getPasswd()));
+		}
+
+		systemService.saveUser(user);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 사용자 비밀번호 변경
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/password/change")
+	@ResponseBody
+	public GagaResponse changePassword(@RequestBody User user) {
+		user.setPasswd(passwordEncoder.encode(user.getPasswd()));
+		user.setUpdNo(TsaSession.getInfo().getUserNo());
+		log.info("user: {}", user);
+
+		// 어드민사용자 비밀번호 수정
+		systemService.updateUserPassword(user);
+
+		return super.ok(message.getMessage("SUCC_0009"));
+	}
+
+	/**
+	 * 사용자 메뉴 관리 화면
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/menu/{userNo}")
+	public ModelAndView getAdminUserMenu(@PathVariable("userNo") Integer userNo) {
+		ModelAndView mav = new ModelAndView();
+
+		// 사용자 메뉴 목록
+		mav.addObject("userMenuList", systemService.getUserMenuList(userNo));
+
+		mav.setViewName("system/UserMenuForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사용자 메뉴 목록 저장 처리
+	 * @param menuList - 사용자 메뉴 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/menu/list/save")
+	@ResponseBody
+	public GagaResponse saveUserMenuList(@RequestBody Collection<UserMenu> menuList) {
+		systemService.saveUserMenuList(menuList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 비밀번호 변경 팝업
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	@GetMapping("/password/change/form")
+	public ModelAndView passwordChangeForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("system/PasswordChangeForm");
+
+		return mav;
+	}
+
+	/**
+	 * 메뉴관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/menu/form")
+	public ModelAndView menuListForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 최상위메뉴 콤보박스 목록
+		mav.addObject("topMenuList", rendererService.getTopMenuList(""));
+
+		// 전체메뉴 콤보박스 목록
+		mav.addObject("allMenuList", rendererService.getAllMenuList());
+
+		// 권한 콤보박스 목록
+		mav.addObject("roleList", rendererService.getCommonCodeList("G001"));
+
+		mav.setViewName("system/MenuForm");
+
+		return mav;
+	}
+
+	/**
+	 * 메뉴 목록
+	 * @param pmenuId - 상위메뉴ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/menu/list")
+	@ResponseBody
+	public Collection<Menu> getMenuList(@RequestParam(value = "pmenuId", required = false) String pmenuId) {
+		return systemService.getMenuList(pmenuId);
+	}
+
+	/**
+	 * 메뉴 사용안함 처리
+	 * @param menuList - 메뉴 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/menu/list/save")
+	@ResponseBody
+	public GagaResponse saveMenuList(@RequestBody Collection<Menu> menuList) {
+		systemService.saveMenuList(menuList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 메뉴 등록/수정 처리
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/menu/save")
+	@ResponseBody
+	public GagaResponse saveMenu(@RequestBody Menu menu) {
+		systemService.saveMenu(menu);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 공통코드관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/commoncode/form")
+	public ModelAndView commoncodeListForm() {
+		ModelAndView mav = new ModelAndView();
+
+//		// 코드구분 콤보박스 목록
+//		mav.addObject("cdGbList", rendererService.getCommonCodeList("ROOT"));
+
+		mav.setViewName("system/CommoncodeForm");
+
+		return mav;
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/commoncode/list")
+	@ResponseBody
+	public Collection<CommonCode> getCommonCodeList(@RequestParam(value = "cdGb", required = false) String cdGb) {
+		CommonCode commoncode = new CommonCode();
+		commoncode.setCdGb(cdGb);
+		return systemService.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 공통코드 목록 저장 처리
+	 * @param commonCodeList - 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/commoncode/list/save")
+	@ResponseBody
+	public GagaResponse saveCommonCodeList(@RequestBody Collection<CommonCode> commonCodeList) {
+		systemService.saveCommonCodeList(commonCodeList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 공통코드 저장 처리
+	 * @param commonCode - 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/commoncode/save")
+	@ResponseBody
+	public GagaResponse saveCommonCode(@RequestBody CommonCode commonCode) {
+		systemService.saveCommonCode(commonCode);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 샘플양식관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@GetMapping("/sample/file/form")
+	public ModelAndView sampleFileForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("system/SampleFileForm");
+
+		return mav;
+	}
+
+	/**
+	 * 샘플파일 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@GetMapping("/sample/file/list")
+	@ResponseBody
+	public Collection<SampleFile> getSampleFileList() {
+		return systemService.getSampleFileList();
+	}
+
+	/**
+	 * 샘플파일 등록/수정 처리
+	 * @param sampleFile - 샘플파일 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@PostMapping("/sample/file/save")
+	@ResponseBody
+	public GagaResponse saveSampleFile(@RequestBody SampleFile sampleFile) {
+		sampleFile.setRegNo(TsaSession.getInfo().getUserNo());
+		sampleFile.setUpdNo(TsaSession.getInfo().getUserNo());
+		systemService.saveSampleFile(sampleFile);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 시스템알람관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/alarm/form")
+	public ModelAndView systemAlarmForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("system/SystemAlarmForm");
+
+		return mav;
+	}
+
+	/**
+	 * 시스템알람 목록
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/list")
+	@ResponseBody
+	public Collection<Alarm> getAlarmList(@RequestBody Alarm alarm) {
+		return systemService.getAlarmList(alarm);
+	}
+
+	/**
+	 * 알람 저장
+	 * @param alarm - 시스템알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/save")
+	@ResponseBody
+	public GagaResponse saveAlarm(@RequestBody Alarm alarm) {
+		alarm.setRegNo(TsaSession.getInfo().getUserNo());
+		alarm.setUpdNo(TsaSession.getInfo().getUserNo());
+		systemService.saveAlarm(alarm);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 알람 삭제
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/delete")
+	@ResponseBody
+	public GagaResponse deleteAlarm(@RequestBody Alarm alarm) {
+		alarm.setUpdNo(TsaSession.getInfo().getUserNo());
+		systemService.deleteAlarm(alarm);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 알람수신자 목록
+	 * @param alarmId - 알람ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/alarm/receiver/list/{alarmId}")
+	@ResponseBody
+	public Collection<AlarmReceiver> getAlarmReceiverList(@PathVariable String alarmId) {
+		return systemService.getAlarmReceiverList(alarmId);
+	}
+
+	/**
+	 * 알람수신자 목록 저장
+	 * @param alarmReceiverList - 알람수신자 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/receiver/list/save")
+	@ResponseBody
+	public GagaResponse saveAlarmReceiverList(@RequestBody Collection<AlarmReceiver> alarmReceiverList) {
+		systemService.saveAlarmReceiverList(alarmReceiverList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 알람수신자 삭제
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/receiver/delete")
+	@ResponseBody
+	public GagaResponse deleteAlarmReceiverList(@RequestBody Collection<AlarmReceiver> alarmReceiverList) {
+		systemService.deleteAlarmReceiverList(alarmReceiverList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 배치관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 2
+	 */
+	@GetMapping("/batch/form")
+	public ModelAndView batchForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 업무구분
+		mav.addObject("bizGbList", rendererService.getTopMenuList(""));
+
+		mav.setViewName("system/BatchForm");
+
+		return mav;
+	}
+
+	/**
+	 * 배치 목록
+	 * @param batch - 배치 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 2
+	 */
+	@PostMapping("/batch/list")
+	@ResponseBody
+	public Collection<Batch> getBatchList(@RequestBody Batch batch) {
+		return systemService.getBatchList(batch);
+	}
+
+	/**
+	 * 배치 저장
+	 * @param batch - 배치 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 2
+	 */
+	@PostMapping("/batch/save")
+	@ResponseBody
+	public GagaResponse saveBatch(@RequestBody Batch batch) {
+		batch.setRegNo(TsaSession.getInfo().getUserNo());
+		batch.setUpdNo(TsaSession.getInfo().getUserNo());
+		systemService.saveBatch(batch);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 배치 로그 목록
+	 * @param batch - 배치 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 12. 3
+	 */
+	@PostMapping("/batch/log/list")
+	@ResponseBody
+	public Collection<BatchLog> getBatchLogList(@RequestBody Batch batch) {
+		return systemService.getBatchLogList(batch);
+	}
+
+}

+ 425 - 0
src/main/java/com/style24/admin/biz/web/TsaWithdrawController.java

@@ -0,0 +1,425 @@
+package com.style24.admin.biz.web;
+
+import java.util.Collection;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+//import org.apache.commons.collections.CollectionUtils;
+//import org.apache.commons.lang.StringUtils;
+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.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 lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponse;
+
+import com.style24.persistence.domain.Withdraw;
+import com.style24.admin.biz.service.TsaDeliveryService;
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaWithdrawService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+
+/**
+ * 회수관리 Controller
+ * 
+ * @author moon
+ * @since 2020. 11. 16
+ */
+@Controller
+@RequestMapping("/withdraw")
+@Slf4j
+public class TsaWithdrawController extends TsaBaseController {
+
+	@Autowired
+	private TsaWithdrawService withdrawService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private TsaDeliveryService deliveryService;
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	/**
+	 * 회수등록 화면
+	 * 
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 02. 10
+	 */
+//	@RequestMapping(value = "/register/form")
+//	public ModelAndView withdrawRegisterForm() throws Exception {
+//		ModelAndView mav = new ModelAndView();
+//
+//		// 택배사명 목록
+//		mav.addObject("shipCompanyList", rendererService.getShipCompanyList());
+//
+//		// 회수요청사유
+//		mav.addObject("wdReqReasonList", rendererService.getAvailCommonCodeList("G688"));
+//
+//		mav.setViewName("withdraw/WithdrawRegisterTriForm");
+//
+//		return mav;
+//	}
+
+	/**
+	 * 회수등록 - 조회(송장번호용)
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 02. 11
+	 */
+//	@PostMapping("/register/invoicelist")
+//	@ResponseBody
+//	public Collection<Withdraw> getWithdrawRegisterInvoiceList(@RequestBody Withdraw withdraw) {
+//		Collection<Withdraw> dataList = withdrawService.getWithdrawRegisterInvoiceList(withdraw);
+//		return dataList;
+//	}
+
+	/**
+	 * 회수등록 - 조회(상품코드용)
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 02. 12
+	 */
+//	@PostMapping("/register/goodslist")
+//	@ResponseBody
+//	public Collection<Withdraw> getWithdrawRegisterGoodsList(@RequestBody Withdraw withdraw) {
+//
+//		log.debug("goodsCd = {} ", withdraw.getGoodsCd());
+//		Collection<Withdraw> dataList = withdrawService.getWithdrawRegisterGoodsList(withdraw);
+//		return dataList;
+//	}
+
+	/**
+	 * 회수등록 - 등록처리
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 02. 12
+	 */
+//	@PostMapping("/register/create")
+//	@ResponseBody
+//	public GagaResponse createWithdrawInfo(@RequestBody Collection<Withdraw> withdrawList) {
+//		Withdraw withdraw = withdrawList.iterator().next();
+//		String goodsCd = withdraw.getGoodsCd();
+//		withdraw.setGoodsCd(null);
+//		//withdraw.setOrdNo(null);
+//		Collection<Withdraw> withdrawCount = withdrawService.getWithdrawRegisterList(withdraw);
+//		withdraw.setGoodsCd(goodsCd);
+//
+//		if (CollectionUtils.isEmpty(withdrawCount)) {
+//			withdrawService.createWithdrawInfo(withdrawList);
+//		} else {
+//			return super.error("이미 등록된 회수송장번호가 존재합니다.");
+//		}
+//
+//		log.debug("withdraw = {}", withdrawList);
+//
+//		return super.ok(message.getMessage("SUCC_0001"));
+//	}
+
+	/**
+	 * 회수송장번호 변경 팝업 화면
+	 * 
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 02. 27
+	 */
+//	@RequestMapping(value = "/register/wdinvoicenochange/form")
+//	public ModelAndView wdInvoiceNoChangeForm() throws Exception {
+//		ModelAndView mav = new ModelAndView();
+//
+//		mav.setViewName("withdraw/WdInvoiceNoChange");
+//
+//		return mav;
+//	}
+
+	/**
+	 * 회수송장번호 변경
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 02. 27
+	 */
+//	@PostMapping("/register/withdrawinvoiceno/update")
+//	@ResponseBody
+//	public GagaResponse updateRegisterWdInvoiceNo(@RequestBody Withdraw withdraw) {
+//		withdrawService.updateRegisterWdInvoiceNo(withdraw);
+//		return super.ok(message.getMessage("SUCC_0002"));
+//	}
+
+	/**
+	 * 환불관리 목록 화면
+	 * 
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@RequestMapping(value = "/refund/form")
+	public ModelAndView withdrawRefundForm() throws Exception {
+		ModelAndView mav = new ModelAndView();
+
+		// 사이트구분
+		mav.addObject("siteCdList", rendererService.getAvailCommonCodeList("G000"));
+
+		mav.setViewName("withdraw/RefundRegisterListForm");
+
+		return mav;
+	}
+
+	/**
+	 * 환불관리 목록
+	 * 
+	 * @param  withdraw
+	 * @return Collection<Withdraw>
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/refund/list")
+	@ResponseBody
+	public Collection<Withdraw> getRefundList(@RequestBody Withdraw withdraw) {
+		return withdrawService.getRefundList(withdraw);
+	}
+
+	/**
+	 * 환불관리 회수 데이터 삭제처리
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping(value = "/refund/Withdraw/delete")
+	@ResponseBody
+	public GagaResponse deleteWithdrawInfo(@RequestBody Withdraw withdraw) {
+		withdrawService.deleteWithdrawInfo(withdraw);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 회수등록 팝업 화면
+	 * 
+	 * @param
+	 * @return 회수등록 팝업 화면
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 03. 03
+	 */
+//	@GetMapping("/register/popup/form")
+//	@ResponseBody
+//	public ModelAndView withdrawRegisterPopupForm(Withdraw withdraw) {
+//		ModelAndView mav = new ModelAndView();
+//
+//		mav.addObject("wdInvoiceNo", withdraw.getWdInvoiceNo());
+//
+//		mav.addObject("goodsCd", withdraw.getGoodsCd());
+//
+//		mav.addObject("sizeCd", withdraw.getSizeCd());
+//
+//		if (StringUtils.isNotBlank(withdraw.getOrdDtlNo().toString())) {
+//			mav.addObject("ordDtlNo", withdraw.getOrdDtlNo());
+//		}
+//
+//		// 주문상세 상태
+//		mav.addObject("ordDtlStatList", rendererService.getAvailCommonCodeList("G013"));
+//
+//		mav.setViewName("withdraw/WithdrawRegisterPopupForm");
+//		return mav;
+//	}
+
+
+	/**
+	 * 회수등록 팝업 목록
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 03. 03
+	 */
+//	@PostMapping("/register/popup/list")
+//	@ResponseBody
+//	public Collection<Withdraw> getWithdrawRegisterPopupList(@RequestBody Withdraw withdraw) {
+//		Collection<Withdraw> dataList = withdrawService.getWithdrawRegisterPopupList(withdraw);
+//		return dataList;
+//	}
+
+
+	/**
+	 * 회수등록팝업 주문매핑(송장번호 수정)
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 03. 03
+	 */
+//	@PostMapping("/register/popup/wdinvoiceno/update")
+//	@ResponseBody
+//	public GagaResponse updateOrderChangeWdInvoiceNo(@RequestBody Withdraw withdraw) {
+//		withdrawService.updateOrderChangeWdInvoiceNo(withdraw);
+//		return super.ok(message.getMessage("SUCC_0002"));
+//	}
+
+	/**
+	 * 회수등록팝업 주문매핑(주문상세일련번호 수정)
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author rladbwnd5
+	 * @since 2020. 03. 03
+	 */
+//	@PostMapping("/register/popup/orddtlno/update")
+//	@ResponseBody
+//	public GagaResponse updateWithdrawOrdDtlNo(@RequestBody Withdraw withdraw) {
+//		withdrawService.updateWithdrawOrdDtlNo(withdraw);
+//		return super.ok(message.getMessage("SUCC_0002"));
+//	}
+
+	/**
+	 * 환불관리 상세 화면
+	 * 
+	 * @param ordNo
+	 * @return 회수 상세 화면
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@GetMapping("/refund/detail/form")
+	@ResponseBody
+	public ModelAndView refundDetailForm(Withdraw withdraw) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.addObject("ordChgSq", withdraw.getOrdChgSq());
+
+		// 남은 상품 정보
+		mav.addObject("remainGoodsInfo", withdrawService.getRemainGoodsInfo(withdraw));
+
+		// 남은 상품 목록
+		mav.addObject("remainGoodsList", withdrawService.getWithdrawRemainOrderDetailList(withdraw));
+
+		// 장바구니 쿠폰 정보
+		mav.addObject("couponInfo", withdrawService.getCouponInfo(withdraw));
+
+		// 주문전체 금액
+		mav.addObject("orderDetailSumAmt", withdrawService.getOrderDetailSumAmt(withdraw.getOrdNo().toString()));
+
+		//
+		mav.addObject("sumQty", withdrawService.getSumChgQtyWdQty(withdraw));
+
+		// TODO: 아래 확인후 구현 (.. ) ( ..)
+		//mav.addObject("ordChgCnt", deliveryService.getOrdChgCnt(withdraw.getOrdNo()));
+		mav.setViewName("withdraw/WithdrawDetailForm");
+		return mav;
+	}
+
+	/**
+	 * 환불관리상세 정보
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/detail/list")
+	@ResponseBody
+	public Collection<Withdraw> getRefundDetailList(@RequestBody Withdraw withdraw) {
+		Collection<Withdraw> dataList = withdrawService.getRefundDetailList(withdraw);
+		return dataList;
+	}
+
+	/**
+	 * 환불관리상세 - 회수처리
+	 * 
+	 * @param withdraw
+	 * @return GagaResponse
+	 * @author moon
+	 * @since 2020. 11. 16
+	 */
+	@PostMapping("/detail/confirm")
+	@ResponseBody
+	public GagaResponse refundDetailConfirm(@RequestBody Withdraw withdraw) {
+		withdrawService.refundDetailConfirm(withdraw);
+		return super.ok(message.getMessage("SUCC_0004"));
+	}
+
+	/**
+	 * 회수송장전송목록 화면
+	 * 
+	 * @return ModelAndView
+	 * @throws Exception
+	 * @author Daehyoung
+	 * @since 2020. 02. 25
+	 */
+//	@RequestMapping(value = "/invoice/send/list/form")
+//	public ModelAndView invoiceSendListForm() throws Exception {
+//		ModelAndView mav = new ModelAndView();
+//
+//		// 사이트구분
+//		mav.addObject("siteCdList", rendererService.getAvailCommonCodeList("G000"));
+//
+//		mav.setViewName("withdraw/InvoiceSendListForm");
+//
+//		return mav;
+//	}
+
+	/**
+	 * 환불완료 화면
+	 * 
+	 * @return ModelAndView
+	 * @throws Exception
+	 * @author yujung
+	 * @since 2020. 05. 29
+	 */
+//	@RequestMapping(value = "/refundcomplete/list/form")
+//	public ModelAndView refundCompleteListListForm() throws Exception {
+//		ModelAndView mav = new ModelAndView();
+//
+//		mav.setViewName("withdraw/RefundCompleteListForm");
+//
+//		return mav;
+//	}
+
+	/**
+	 * 환불완료 목록
+	 * 
+	 * @param
+	 * @return
+	 * @throws Exception
+	 * @author yujung
+	 * @since 2020. 05. 29
+	 */
+//	@PostMapping("/refundcomplete/list")
+//	@ResponseBody
+//	public Collection<Withdraw> getRefundCompleteList(@RequestBody Withdraw withdraw) {
+//		Collection<Withdraw> dataList = withdrawService.getRefundCompleteList(withdraw);
+//		return dataList;
+//	}
+
+}

+ 48 - 0
src/main/java/com/style24/admin/support/config/TsaMybatisShopConfig.java

@@ -0,0 +1,48 @@
+package com.style24.admin.support.config;
+
+import javax.sql.DataSource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.core.support.env.TscConstants;
+
+/**
+ * shopDs용 Mybatis Configuration
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Configuration
+@MapperScan(basePackages = TscConstants.BASE_PACKAGE, annotationClass = ShopDs.class, sqlSessionFactoryRef = "shopSqlSessionFactory")
+public class TsaMybatisShopConfig {
+
+	@Autowired
+	private ApplicationContext applicationContext;
+
+	@Bean(name = "shopSqlSessionFactory")
+	public SqlSessionFactory shopSqlSessionFactory(@Qualifier("shopDataSource") DataSource dataSource) throws Exception {
+		SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
+
+		sessionFactoryBean.setDataSource(dataSource);
+		sessionFactoryBean.setTypeAliasesPackage(TscConstants.DOMAIN_PACKAGE);
+		sessionFactoryBean.setConfigLocation(applicationContext.getResource("classpath:persistence/mybatis-shop-config.xml"));
+		sessionFactoryBean.setMapperLocations(applicationContext.getResources(TscConstants.MAPPER_LOCATION_PATH + "/shop/*.xml"));
+
+		return sessionFactoryBean.getObject();
+	}
+
+	@Bean(name = "shopSqlSessionTemplate")
+	public SqlSessionTemplate shopSqlSessionTemplate(@Qualifier("shopSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+		return new SqlSessionTemplate(sqlSessionFactory);
+	}
+
+}

+ 48 - 0
src/main/java/com/style24/admin/support/config/TsaMybatisWmsConfig.java

@@ -0,0 +1,48 @@
+package com.style24.admin.support.config;
+
+import javax.sql.DataSource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.style24.core.support.annotation.WmsDs;
+import com.style24.core.support.env.TscConstants;
+
+/**
+ * wmsDs용 Mybatis Configuration
+ * 
+ * @author gagamel
+ * @since 2020. 11. 26
+ */
+@Configuration
+@MapperScan(basePackages = TscConstants.BASE_PACKAGE, annotationClass = WmsDs.class, sqlSessionFactoryRef = "wmsSqlSessionFactory")
+public class TsaMybatisWmsConfig {
+
+	@Autowired
+	private ApplicationContext applicationContext;
+
+	@Bean(name = "wmsSqlSessionFactory")
+	public SqlSessionFactory wmsSqlSessionFactory(@Qualifier("wmsDataSource") DataSource dataSource) throws Exception {
+		SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
+
+		sessionFactoryBean.setDataSource(dataSource);
+		sessionFactoryBean.setTypeAliasesPackage(TscConstants.DOMAIN_PACKAGE);
+		sessionFactoryBean.setConfigLocation(applicationContext.getResource("classpath:persistence/mybatis-wms-config.xml"));
+		sessionFactoryBean.setMapperLocations(applicationContext.getResources(TscConstants.MAPPER_LOCATION_PATH + "/wms/*.xml"));
+
+		return sessionFactoryBean.getObject();
+	}
+
+	@Bean(name = "wmsSqlSessionTemplate")
+	public SqlSessionTemplate wmsSqlSessionTemplate(@Qualifier("wmsSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+		return new SqlSessionTemplate(sqlSessionFactory);
+	}
+
+}

+ 100 - 0
src/main/java/com/style24/admin/support/config/TsaRedisSessionConfig.java

@@ -0,0 +1,100 @@
+package com.style24.admin.support.config;
+
+import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.security.jackson2.SecurityJackson2Modules;
+import org.springframework.session.data.redis.config.ConfigureRedisAction;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
+import org.springframework.session.web.http.CookieSerializer;
+import org.springframework.session.web.http.DefaultCookieSerializer;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Spring Session을 JSON 형태로 Redis에 저장하기 위한 Configuration
+ * HttpSession 구현체를 대체하는 서블릿 필터를 생성
+ *
+ * @EnableRedisHttpSession 어노테이션은 SpringSessionRepositoryFilter(Filter의 구현체)라는 빈을 생성하는데,
+ * yml 파일의 "spring.session.store-type: redis"와 같다.
+ * 이 필터는 HttpSession의 구현체를 바꾸는 역할을 한다.
+ * @EnableRedisHttpSession 어노테이션을 하고
+ * "spring.data.redis.repositories.enabled: true" 속성을 application.yml 파일에 추가한다.
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Configuration
+@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
+public class TsaRedisSessionConfig
+	extends AbstractHttpSessionApplicationInitializer implements BeanClassLoaderAware {
+
+	private ClassLoader classLoader;
+
+	@Override
+	public void setBeanClassLoader(ClassLoader classLoader) {
+		this.classLoader = classLoader;
+	}
+
+	/**
+	 * Redis Keyspace Notification 역시 받을 필요가 없도록 처리
+	 *
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 5. 31.
+	 */
+	@Bean
+	public static ConfigureRedisAction configureRedisAction() {
+		return ConfigureRedisAction.NO_OP;
+	}
+
+	/**
+	 * Serialize 수행 방법을 스프링에 알려준다.
+	 *
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 5. 29.
+	 */
+	@Bean
+	public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
+		return new GenericJackson2JsonRedisSerializer(objectMapper());
+	}
+
+	/**
+	 * Spring Security 관련 변수 및 매개 변수를 저장하기 위해 SecurityJackson2Modules를 사용
+	 *
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 5. 29.
+	 */
+	private ObjectMapper objectMapper() {
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.registerModules(SecurityJackson2Modules.getModules(this.classLoader));
+		return mapper;
+	}
+
+	/**
+	 * @EnableRedisHttpSession 어노테이션을 통해 redis-session을 처리할 경우
+	 * 결제, 본인인증 후 콜백시 로그인이 풀림
+	 * SAME_SITE = NONE 그리고 SECURE 를 하기위해서 해당 메소드가 필요함
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 5. 21.
+	 */
+	@Bean
+	public CookieSerializer cookieSerializer() {
+		DefaultCookieSerializer serializer = new DefaultCookieSerializer();
+		serializer.setCookiePath("/");
+		serializer.setUseBase64Encoding(false);
+
+		// SSL인증서 적용 시 주석 제거
+//		serializer.setUseSecureCookie(true);
+//		serializer.setSameSite("NONE");
+
+		return serializer;
+	}
+
+}

+ 70 - 0
src/main/java/com/style24/admin/support/config/TsaThymeleafConfig.java

@@ -0,0 +1,70 @@
+package com.style24.admin.support.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.env.Environment;
+import org.springframework.web.servlet.ViewResolver;
+import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
+import org.thymeleaf.spring5.SpringTemplateEngine;
+import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
+import org.thymeleaf.spring5.view.ThymeleafViewResolver;
+import org.thymeleaf.templatemode.TemplateMode;
+
+import nz.net.ultraq.thymeleaf.LayoutDialect;
+
+/**
+ * THYMELEAF Configuration
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Configuration
+public class TsaThymeleafConfig {
+
+	@Autowired
+	private ApplicationContext applicationContext;
+
+	@Autowired
+	private Environment env;
+
+	@Bean
+	public SpringResourceTemplateResolver templateResolver() {
+		SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
+		templateResolver.setApplicationContext(applicationContext);
+		templateResolver.setPrefix(env.getProperty("spring.thymeleaf.prefix"));
+		templateResolver.setSuffix(env.getProperty("spring.thymeleaf.suffix"));
+		templateResolver.setTemplateMode(TemplateMode.HTML);
+		templateResolver.setCharacterEncoding("UTF-8");
+		templateResolver.setCacheable(false);
+
+		return templateResolver;
+	}
+
+	@Bean
+	public SpringTemplateEngine templateEngine() {
+		SpringTemplateEngine templateEngine = new SpringTemplateEngine();
+		templateEngine.setTemplateResolver(templateResolver());
+		templateEngine.setEnableSpringELCompiler(true);
+		templateEngine.addDialect(new LayoutDialect());
+		templateEngine.addDialect(new Java8TimeDialect());
+		return templateEngine;
+	}
+
+	@Bean
+	public ViewResolver thymeleafViewResolver() {
+		ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
+
+		viewResolver.setTemplateEngine(templateEngine());
+		viewResolver.setCharacterEncoding("UTF-8");
+		viewResolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
+
+		// below views will not be handled by this reslover.
+		viewResolver.setExcludedViewNames(new String[] {"common/**/*"});
+
+		return viewResolver;
+	}
+
+}

+ 119 - 0
src/main/java/com/style24/admin/support/config/TsaWebMvcConfig.java

@@ -0,0 +1,119 @@
+package com.style24.admin.support.config;
+
+import java.nio.charset.Charset;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.multipart.support.MultipartFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.style24.admin.support.interceptor.TsaDefaultInterceptor;
+import com.style24.admin.support.interceptor.TsaPosInterceptor;
+
+import com.gagaframework.web.core.filter.GagaXssServletFilter;
+import com.gagaframework.web.rest.client.GagaRequestStringTrim;
+
+/**
+ * Web MVC Configuration
+ *
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Configuration
+public class TsaWebMvcConfig implements WebMvcConfigurer {
+
+	@Autowired
+	private TsaDefaultInterceptor defaultInterceptor;
+
+	@Autowired
+	private TsaPosInterceptor posInterceptor;
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		final String[] excludePathPatterns = new String[] {
+			"/", "/index", "/signin", "/image/**", "/ux/**", "/smartEditor/**",
+			"/error/**", "/data/**", "/login", "/logout",
+			"/pos/**", "/goods/naverEP/download", "/shoplinker/**"
+		};
+
+		registry.addInterceptor(defaultInterceptor)
+			.addPathPatterns("/**/*")
+			.excludePathPatterns(excludePathPatterns);
+
+		registry.addInterceptor(posInterceptor)
+			.addPathPatterns("/pos/**")
+			.excludePathPatterns("/pos/login/**");
+	}
+
+	/**
+	 * @RequestBody annotation 이용 시 json data 형식의 모든 문자열의 앞, 뒤 공백을 제거
+	 */
+	@Bean
+	public GagaRequestStringTrim stringTrim() {
+		return new GagaRequestStringTrim();
+	}
+
+	/**
+	 * XSS(Cross Site Script) Prevention Filter
+	 *
+	 * @return
+	 */
+	@SuppressWarnings({"rawtypes", "unchecked"})
+	@Bean
+	public FilterRegistrationBean xssFilterRegistrationBean() {
+		FilterRegistrationBean bean = new FilterRegistrationBean();
+		bean.setFilter(new GagaXssServletFilter());
+		bean.setOrder(2);
+		bean.addUrlPatterns("/*");
+		return bean;
+	}
+
+	/**
+	 * Multipart Filter
+	 * 파일 업로드 구현 시 MultipartRequest를 처리함에 따라 해당 부분은 불필요 하나,
+	 * com.oreilly.servlet.MultipartRequest 같은 걸 이용 시
+	 * "Corrupt form data: premature ending" exception이 발생한다.
+	 * 이를 해결하고자 Filter를 구성
+	 *
+	 * @return
+	 */
+	@SuppressWarnings({"rawtypes", "unchecked"})
+	@Bean
+	public FilterRegistrationBean springMultipartRegistrationBean() {
+		FilterRegistrationBean bean = new FilterRegistrationBean();
+		bean.setName("springMultipartResolver");
+		bean.setFilter(new MultipartFilter());
+		bean.setOrder(1);
+		bean.addUrlPatterns(new String[] {
+			"/common/file/upload/**",
+			"/common/files/upload/**"
+		});
+		return bean;
+	}
+
+	/**
+	 * API 호출을 위한 RestTemplate 설정
+	 *
+	 * @return
+	 */
+	@Bean
+	public RestTemplate restTemplate() {
+		HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
+		factory.setConnectTimeout(300000);
+		factory.setReadTimeout(300000);
+
+		RestTemplate restTemplate = new RestTemplate(factory);
+
+		// Convert the message to UTF-8
+		restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
+
+		return restTemplate;
+	}
+
+}

+ 49 - 0
src/main/java/com/style24/admin/support/controller/TsaBaseController.java

@@ -0,0 +1,49 @@
+package com.style24.admin.support.controller;
+
+import java.util.Collection;
+
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ModelAttribute;
+
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.controller.TscBaseController;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.User;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Controller Advice
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@ControllerAdvice
+@Slf4j
+public class TsaBaseController extends TscBaseController {
+
+	/**
+	 * Get 세션 정보
+	 * 1.View 단에서 사용법
+	 * th:value="${sessionInfo.userId}"
+	 * 2.Java 단에서 사용법
+	 * super.getSession().getUserId()
+	 * 
+	 * @return
+	 */
+	@ModelAttribute("sessionInfo")
+	public User getSession() {
+		return TsaSession.getInfo();
+	}
+
+	/**
+	 * Get 로그인 메뉴 목록
+	 * 
+	 * @return
+	 */
+	@ModelAttribute("loginMenuList")
+	public Collection<Menu> getLoginMenuList() {
+		return TsaSession.getLoginMenuList();
+	}
+
+}

+ 65 - 0
src/main/java/com/style24/admin/support/controller/TsaErrorController.java

@@ -0,0 +1,65 @@
+package com.style24.admin.support.controller;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.rest.server.GagaResponseStatus;
+
+/**
+ * Error Controller
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Controller
+@Slf4j
+@RequestMapping(value = "/error")
+public class TsaErrorController extends TsaBaseController {
+
+	/**
+	 * Error
+	 */
+	@GetMapping("/500")
+	public ModelAndView error(HttpServletRequest request) throws HttpRequestMethodNotSupportedException {
+		ModelAndView mav = new ModelAndView("error/500");
+
+		Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
+
+		if (status != null) {
+			Integer statusCode = Integer.valueOf(status.toString());
+			log.debug("statusCode: {}", statusCode);
+
+			if (statusCode == GagaResponseStatus.NOT_FOUND.getCode()) {
+				mav.addObject("status", GagaResponseStatus.NOT_FOUND.getCode());
+				mav.addObject("message", "No mapping found for HTTP request with URI ["
+					+ String.valueOf(request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI)) + "]");
+
+				return mav;
+			}
+		}
+
+		mav.addObject("status", GagaResponseStatus.INTERNAL_SERVER_ERROR.getCode());
+		mav.addObject("message", String.valueOf(request.getAttribute(RequestDispatcher.ERROR_MESSAGE)));
+
+		return mav;
+	}
+
+	@GetMapping("/noSession")
+	public ModelAndView noSession(HttpServletRequest request) throws HttpRequestMethodNotSupportedException {
+		ModelAndView mav = new ModelAndView("error/500");
+
+		mav.addObject("status", GagaResponseStatus.UNAUTHORIZED.getCode());
+		mav.addObject("message", String.valueOf(request.getAttribute(RequestDispatcher.ERROR_MESSAGE)));
+
+		return mav;
+	}
+
+}

+ 70 - 0
src/main/java/com/style24/admin/support/env/TsaConstants.java

@@ -0,0 +1,70 @@
+package com.style24.admin.support.env;
+
+/**
+ * 변경될 소지가 있는 변수 값을 정의
+ *
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+public class TsaConstants {
+
+	public static final String EXCEL_FOOTER_TITLE = "Copyright(c) 2020 STYLE24, All rights reserved.";
+
+	// 공지유형
+	public enum NoticeType {
+		SITE("G047_10"),
+		INNER("G047_20");
+
+		private String value;
+
+		private NoticeType(String value) {
+			this.value = value;
+		}
+
+		public String value() {
+			return value;
+		}
+	}
+
+	// 주문상세상태
+	public enum OrderDetailStat {
+		DEPOSIT_WAIT("G013_10"),			// 입금대기
+		ORDER_WAIT_PRICE("G013_18"),		// 발주대기-가격차이
+		ORDER_WAIT_POST("G013_19"),			// 발주대기-우편번호상이
+		PAYMENT_COMPLETE("G013_20"),		// 결제완료
+		GOODS_PREPARE("G013_30"),			// 상품준비중
+		DELIVERY_PREPARE("G013_40"),		// 배송준비중
+		SHIPPING("G013_50"),				// 배송중
+		SHIP_COMPLETE("G013_55"),			// 출고완료
+		DELIVERY_COMPLETE("G013_60"),		// 배송완료
+		//PURCHASE_CONFIRM("70"),			// 구매확정
+		PAYMENT_BEFORE_CANCEL("G013_98"),	// 결제전주문취소
+		PAYMENT_AFTER_CANCEL("G013_99");	// 결제후주문취소
+
+		private String value;
+
+		private OrderDetailStat(String value) {
+			this.value = value;
+		}
+
+		public String value() {
+			return value;
+		}
+	}
+	
+	// 몰구분
+	public enum MallGb {
+		SELFMALL("G011_10"),			// 자사몰
+		EXTMALL("G011_20");				// 제휴몰몰
+
+		private String value;
+
+		private MallGb(String value) {
+			this.value = value;
+		}
+
+		public String value() {
+			return value;
+		}
+	}	
+}

+ 64 - 0
src/main/java/com/style24/admin/support/interceptor/TsaDefaultInterceptor.java

@@ -0,0 +1,64 @@
+package com.style24.admin.support.interceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.exception.TscNoSessionException;
+import com.style24.core.support.message.TscMessageByLocale;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 모든 Request에 대해 세션 확인
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Component
+@Slf4j
+public class TsaDefaultInterceptor extends HandlerInterceptorAdapter {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+		log.info("request.isSecure(): [{}]", request.isSecure());
+		log.info("request.getServerName(): [{}]", request.getServerName());
+		log.info("request.getRequestURI(): [{}]", request.getRequestURI());
+		log.info("request.getRequestURL(): [{}]", request.getRequestURL());
+		log.info("request.getQueryString(): [{}]", request.getQueryString());
+
+		boolean isLogin = TsaSession.isLogin();
+		log.info("isLogin: [{}]", isLogin);
+
+		if (!isLogin) {
+			boolean isAjaxCall = Boolean.parseBoolean(request.getHeader("AJAX"));
+			log.info("isAjaxCall: {}", isAjaxCall);
+
+			if (isAjaxCall) { // ajax call
+				// Ajax call은 status 세팅 후 ajax.status == 901일 경우 로그인 페이지로 이동 처리
+				response.setStatus(901); // No Session
+			} else { // Submit
+				throw new TscNoSessionException(message.getMessage("LOGN_0003"));
+			}
+
+			return false;
+		}
+
+		return super.preHandle(request, response, handler);
+	}
+
+	@Override
+	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+		ModelAndView modelAndView) throws Exception {
+		// Do nothing
+	}
+
+}

+ 48 - 0
src/main/java/com/style24/admin/support/interceptor/TsaPosInterceptor.java

@@ -0,0 +1,48 @@
+package com.style24.admin.support.interceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.exception.TscNoSessionException;
+import com.style24.core.support.message.TscMessageByLocale;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 매장POS 접근 시 매장로그인 세션 확인
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Component
+@Slf4j
+public class TsaPosInterceptor extends HandlerInterceptorAdapter {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+		boolean isStoreLogin = TsaSession.isStoreLogin();
+		log.info("isStoreLogin: [{}]", isStoreLogin);
+
+		if (!isStoreLogin) {
+			throw new TscNoSessionException(message.getMessage("LOGN_0003"));
+		}
+
+		return super.preHandle(request, response, handler);
+	}
+
+	@Override
+	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+		ModelAndView modelAndView) throws Exception {
+		// Do nothing
+	}
+
+}

+ 90 - 0
src/main/java/com/style24/admin/support/security/TsaAuthenticationProvider.java

@@ -0,0 +1,90 @@
+package com.style24.admin.support.security;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import com.style24.admin.biz.service.TsaLoginService;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.User;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.security.GagaPasswordEncoder;
+import com.gagaframework.web.util.GagaCryptoUtil;
+
+/**
+ * 로그인 인증 처리
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Component
+@Slf4j
+public class TsaAuthenticationProvider implements AuthenticationProvider {
+
+	@Autowired
+	private TsaLoginService loginService;
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private GagaPasswordEncoder passwordEncoder;
+
+	@Override
+	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+		String userId = authentication.getName();
+		String passwd = authentication.getCredentials().toString();
+		log.info("userId: {}, passwd: {}", userId, passwd);
+
+		// 로그인 정보
+		User loginInfo = loginService.getUserById(authentication.getName());
+		log.info("loginInfo: {}", loginInfo);
+
+		if (loginInfo == null) {
+			log.error(String.format("User with ID=%s was not found!", userId));
+			throw new BadCredentialsException(message.getMessage("LOGN_0001"));
+		}
+
+		// 로그인 실패누적건수가 5이면
+		if (loginInfo.getLoginFailCnt() == 5) {
+			throw new BadCredentialsException(message.getMessage("LOGN_0005"));
+		}
+
+		log.info("encoded password: {}", GagaCryptoUtil.encryptSha512(passwd));
+		boolean isMatch = passwordEncoder.matches(passwd, loginInfo.getPasswd());
+		log.info("isMatch: {}", isMatch);
+
+		if (!isMatch) {
+			// 로그인 실패 남기기
+			loginService.createLoginFail(loginInfo.getUserNo(), "Y");
+			throw new BadCredentialsException(message.getMessage("LOGN_0002"));
+		}
+
+		// 권한 설정
+		List<SimpleGrantedAuthority> authorities = new ArrayList<>();
+		authorities.add(new SimpleGrantedAuthority(loginInfo.getRoleCd()));
+
+		// 인증 토큰 생성
+		UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
+			loginInfo.getUserId(), loginInfo.getPasswd(), authorities);
+		authToken.setDetails(new TsaLoginDetails(loginInfo, authorities));
+
+		return authToken;
+	}
+
+	@Override
+	public boolean supports(Class<?> authentication) {
+		return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
+	}
+
+}

+ 97 - 0
src/main/java/com/style24/admin/support/security/TsaLoginDetails.java

@@ -0,0 +1,97 @@
+package com.style24.admin.support.security;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.User;
+
+/**
+ * 로그인 상세 정보
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@SuppressWarnings("serial")
+@JsonSerialize
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TsaLoginDetails implements UserDetails {
+
+	private User loginInfo = null;
+
+	private Collection<SimpleGrantedAuthority> authorities = null;
+
+	// 메뉴 목록 (로그인 시 설정)
+	private Collection<Menu> menuList;
+
+	public TsaLoginDetails() {
+
+	}
+
+	public TsaLoginDetails(User loginInfo, Collection<SimpleGrantedAuthority> authorities) {
+		this.loginInfo = loginInfo;
+		this.authorities = authorities;
+
+//		if (authorities != null && !authorities.isEmpty()) {
+//			isLogin = true;
+//		}
+	}
+
+	@Override
+	public Collection<? extends GrantedAuthority> getAuthorities() {
+		return authorities;
+	}
+
+	@Override
+	public String getPassword() {
+		return loginInfo.getPasswd();
+	}
+
+	@Override
+	public String getUsername() {
+		return loginInfo.getUserId();
+	}
+
+	@Override
+	public boolean isAccountNonExpired() {
+		return true;
+	}
+
+	@Override
+	public boolean isAccountNonLocked() {
+		return true;
+	}
+
+	@Override
+	public boolean isCredentialsNonExpired() {
+		return true;
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return true;
+	}
+
+	public boolean isLogin() {
+		return (StringUtils.isNotBlank(loginInfo.getUserId())) ? true : false;
+	}
+
+	public User getLoginInfo() {
+		return loginInfo;
+	}
+
+	public void setLoginMenuList(Collection<Menu> menuList) {
+		this.menuList = menuList;
+	}
+
+	public Collection<Menu> getLoginMenuList() {
+		return menuList;
+	}
+
+}

+ 117 - 0
src/main/java/com/style24/admin/support/security/config/TsaSecurityConfig.java

@@ -0,0 +1,117 @@
+package com.style24.admin.support.security.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+
+import com.style24.admin.support.security.TsaAuthenticationProvider;
+import com.style24.admin.support.security.handler.TsaLoginSuccessHandler;
+import com.style24.admin.support.security.handler.TsaLogoutSuccessHandler;
+
+/**
+ * Java Security를 이용한 Login 처리
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Configuration
+@EnableWebSecurity
+//@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
+//@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
+public class TsaSecurityConfig extends WebSecurityConfigurerAdapter {
+
+	private static final String[] UNAUTHORIZED_RESOURCE_LIST = new String[] {"/*", "/index"};
+
+	private static final String[] UNSECURED_RESOURCE_LIST = new String[] {"/image/**", "/ux/**", "/data/**", "/smartEditor/**"};
+
+	@Autowired
+	private TsaAuthenticationProvider authenticationProvider;
+
+	/**
+	 * Register the Authentication Provider
+	 */
+	@Override
+	public void configure(AuthenticationManagerBuilder auth) throws Exception {
+		auth.authenticationProvider(authenticationProvider);
+	}
+
+	@Override
+	protected void configure(HttpSecurity httpSecurity) throws Exception {
+		// static resources
+		httpSecurity.authorizeRequests()
+			.antMatchers(UNAUTHORIZED_RESOURCE_LIST).permitAll()
+//			.anyRequest().authenticated()
+//				.antMatchers("/backoffice/**").hasAnyAuthority(FccConstants.ROLE.ADMIN.value())
+//				.antMatchers(new String[] { "/backoffice/*", "/backoffice/chairman/**" }).hasAnyAuthority(FccConstants.ROLE.CC_CHIEF.value())
+//				.antMatchers(new String[] { "/backoffice/*", "/backoffice/evaluator/**" }).hasAnyAuthority(FccConstants.ROLE.COUNSELOR.value())
+			.and()
+			.formLogin()
+			.usernameParameter("userId")
+			.passwordParameter("passwd")
+			.loginPage("/signin")
+			.loginProcessingUrl("/login")
+			.successHandler(loginSuccessHandler())
+			.failureUrl("/?error=true")
+			.and()
+			.logout()
+			.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
+			.logoutSuccessHandler(logoutSuccessHandler())
+			.and()
+			.csrf().disable() // CSRF(Cross Site Request Forgery) 해제
+//			.csrf().requireCsrfProtectionMatcher(requireCsrfProtectionMatcher())
+			.exceptionHandling()
+			.accessDeniedPage("/403")
+			.and()
+			.headers().frameOptions().disable() // iframe deny 설정 제거(네이버스마트에디터 사용 때문에 추가)
+//			.and()
+//			.rememberMe().tokenRepository(persistentTokenRepository())
+//				.tokenValiditySeconds(60 * 60 * 24 * 10) // 10 days
+//				.useSecureCookie(true)
+//				.key("sisunTsa")
+//			.and()
+//			.sessionManagement()
+//				.maximumSessions(1)
+//				.maxSessionsPreventsLogin(false)
+//				.maxSessionsPreventsLogin(true)
+//				.sessionRegistry(sessionRegistry())
+//				.expiredUrl("/index")
+		;
+	}
+
+	@Override
+	public void configure(WebSecurity webSecurity) throws Exception {
+		webSecurity
+			.ignoring()
+			.antMatchers(UNSECURED_RESOURCE_LIST);
+	}
+
+	@Bean
+	public TsaLoginSuccessHandler loginSuccessHandler() {
+		return new TsaLoginSuccessHandler();
+	}
+
+	@Bean
+	public TsaLogoutSuccessHandler logoutSuccessHandler() {
+		return new TsaLogoutSuccessHandler();
+	}
+
+//	@Bean
+//	public RequestMatcher requireCsrfProtectionMatcher() {
+//		GagaCsrfSecurityRequestMatcher bean = new GagaCsrfSecurityRequestMatcher();
+//
+//		bean.setDisableUrls(new String[] {
+//				"/",
+//				"/index",
+//				"/customer/post/find/form"
+//		});
+//
+//		return bean;
+//	}
+
+}

+ 73 - 0
src/main/java/com/style24/admin/support/security/handler/TsaLoginSuccessHandler.java

@@ -0,0 +1,73 @@
+package com.style24.admin.support.security.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+import org.springframework.stereotype.Component;
+
+import com.style24.admin.biz.service.TsaLoginService;
+import com.style24.admin.support.security.TsaLoginDetails;
+import com.style24.admin.support.security.session.TsaSession;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 로그인 성공 시 호출되는 Handler
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Component
+@Slf4j
+public class TsaLoginSuccessHandler implements AuthenticationSuccessHandler {
+
+	@Autowired
+	private TsaLoginService loginService;
+
+	@Override
+	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
+		// 로그인 상세 정보
+		TsaLoginDetails loginDetails = (TsaLoginDetails)authentication.getDetails();
+
+		Integer userNo = loginDetails.getLoginInfo().getUserNo();
+		log.info("userNo: {}", userNo);
+
+		// 로그인 성공 시 로그인실패수가 0보다 크면 로그인실패수 reset
+		int failCnt = loginService.getLoginFailCount(userNo);
+		if (failCnt > 0) {
+			loginService.createLoginFail(userNo, "N");
+		}
+
+		// 로그인 메뉴 목록
+		loginDetails.setLoginMenuList(loginService.getLoginMenuList(userNo));
+
+		// 최종로그인일시 Update
+		loginService.updateLastLoginDate(userNo);
+
+		// 로그인이력 남기기
+		loginService.createLoginHistory(userNo);
+
+		// 세션 생성
+		this.createSession(request, loginDetails);
+
+		response.sendRedirect("/");
+	}
+
+	/**
+	 * Session 생성
+	 * 
+	 * @param request - HttpServletRequest
+	 * @param loginDetails - 로그인 상세 정보
+	 */
+	private void createSession(HttpServletRequest request, TsaLoginDetails loginDetails) {
+		TsaSession.getNewSess(request, -1);
+		TsaSession.setAttribute(request, loginDetails);
+	}
+
+}

+ 33 - 0
src/main/java/com/style24/admin/support/security/handler/TsaLogoutSuccessHandler.java

@@ -0,0 +1,33 @@
+package com.style24.admin.support.security.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
+import org.springframework.stereotype.Component;
+
+import com.style24.admin.support.security.session.TsaSession;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 로그아웃 성공 시 호출되는 Handler
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Component
+@Slf4j
+public class TsaLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
+
+	@Override
+	public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
+		TsaSession.invalidate(request);
+		response.sendRedirect("/");
+	}
+
+}

+ 85 - 0
src/main/java/com/style24/admin/support/security/session/TsaSession.java

@@ -0,0 +1,85 @@
+package com.style24.admin.support.security.session;
+
+import java.util.Collection;
+
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import com.style24.admin.support.security.TsaLoginDetails;
+import com.style24.core.support.session.TscSession;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.Pos;
+import com.style24.persistence.domain.User;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Session
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@Slf4j
+public class TsaSession extends TscSession {
+
+	/**
+	 * Get Session Info.
+	 * @return 세션 정보
+	 */
+	public static User getInfo() {
+		TsaLoginDetails loginDetails = (TsaLoginDetails)RequestContextHolder.currentRequestAttributes().getAttribute("session", RequestAttributes.SCOPE_SESSION);
+
+		if (loginDetails == null)
+			return null;
+
+		return loginDetails.getLoginInfo();
+	}
+
+	/**
+	 * 로그인 여부
+	 * @return true/false
+	 */
+	public static boolean isLogin() {
+		TsaLoginDetails loginDetails = (TsaLoginDetails)RequestContextHolder.currentRequestAttributes().getAttribute("session", RequestAttributes.SCOPE_SESSION);
+
+		if (loginDetails == null)
+			return false;
+
+		return loginDetails.isLogin();
+	}
+
+	/**
+	 * Get the login menu list.
+	 * @return 로그인 메뉴 목록
+	 */
+	public static Collection<Menu> getLoginMenuList() {
+		TsaLoginDetails loginDetails = (TsaLoginDetails)RequestContextHolder.currentRequestAttributes().getAttribute("session", RequestAttributes.SCOPE_SESSION);
+
+		if (loginDetails == null)
+			return null;
+
+		return loginDetails.getLoginMenuList();
+	}
+
+	/**
+	 * 매장 세션 정보
+	 * @return 매장 세션 정보
+	 */
+	public static Pos getPosInfo() {
+		return (Pos)RequestContextHolder.currentRequestAttributes().getAttribute("sessionPosInfo", RequestAttributes.SCOPE_SESSION);
+	}
+
+	/**
+	 * 매장로그인 여부
+	 * @return true/false
+	 */
+	public static boolean isStoreLogin() {
+		Pos posInfo = (Pos)RequestContextHolder.currentRequestAttributes().getAttribute("sessionPosInfo", RequestAttributes.SCOPE_SESSION);
+
+		if (posInfo == null)
+			return false;
+
+		return true;
+	}
+
+}

+ 54 - 0
src/main/java/com/style24/admin/support/startup/TsaApplication.java

@@ -0,0 +1,54 @@
+package com.style24.admin.support.startup;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+
+import com.style24.core.support.env.TscConstants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.core.GagaConstants;
+
+/**
+ * Application
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@EnableCaching
+@Configuration
+@EnableAutoConfiguration(exclude = {DataSourceTransactionManagerAutoConfiguration.class, DataSourceAutoConfiguration.class})
+@ComponentScan(basePackages = {GagaConstants.GAGA_PACKAGE, TscConstants.BASE_PACKAGE})
+@Slf4j
+public class TsaApplication {
+
+	@Autowired
+	private Environment env;
+
+	@PostConstruct
+	public void initApplication() throws IOException {
+		log.info("Running with Spring Profiles: {}", Arrays.toString(env.getActiveProfiles()));
+		if (env.getActiveProfiles().length == 0) {
+			log.warn("No spring profile configured, running with default configuration.");
+		} else if (env.getActiveProfiles().length > 1) {
+			log.error("You have misconfigured your application! It should not run with both Spring Profiles at the same time.");
+		}
+	}
+
+	public static void main(String[] args) {
+		SpringApplication.run(TsaApplication.class, args);
+	}
+
+}

+ 19 - 0
src/main/java/com/style24/admin/support/startup/TsaServletInitializer.java

@@ -0,0 +1,19 @@
+package com.style24.admin.support.startup;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * ServletInitializer
+ * 
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+public class TsaServletInitializer extends SpringBootServletInitializer {
+
+	@Override
+	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+		return application.sources(TsaApplication.class);
+	}
+
+}

+ 58 - 0
src/main/java/com/style24/admin/support/util/TsitUtil.java

@@ -0,0 +1,58 @@
+package com.style24.admin.support.util;
+
+public class TsitUtil {
+	public String replaceMultiSelectParams(String param) {
+		String[] multiParams = param.replaceAll("\r", "").split("\n");
+		StringBuilder multiParam = new StringBuilder();
+		multiParam.append("(");
+		for (int i = 0; i < multiParams.length; i++) {
+			if (!multiParams[i].trim().equals("")) {
+				if (i > 0) {
+					multiParam.append("|");
+				}
+				multiParam.append(multiParams[i]);
+			}
+		}
+		multiParam.append(")");
+
+		return multiParam.toString();
+	}
+
+	public String replaceMultiSelectParamsArr(String param) {
+		String[] multiParams = param.replaceAll("\r", "").split("\n");
+		StringBuilder multiParam = new StringBuilder();
+		for (int i = 0; i < multiParams.length; i++) {
+			if (!multiParams[i].trim().equals("")) {
+				if (i > 0) {
+					if (i % 20 == 0) {
+						multiParam.append(",");
+					} else {
+						multiParam.append("|");
+					}
+				}
+				multiParam.append(multiParams[i]);
+			}
+		}
+
+		return multiParam.toString();
+	}
+
+	public String replaceMultiSelectCommaParamsArr(String param) {
+		String[] multiParams = param.replaceAll("\r", "").split(",");
+		StringBuilder multiParam = new StringBuilder();
+		for (int i = 0; i < multiParams.length; i++) {
+			if (!multiParams[i].trim().equals("")) {
+				if (i > 0) {
+					if (i % 20 == 0) {
+						multiParam.append(",");
+					} else {
+						multiParam.append("|");
+					}
+				}
+				multiParam.append(multiParams[i]);
+			}
+		}
+
+		return multiParam.toString();
+	}
+}

+ 123 - 0
src/main/java/com/style24/persistence/TsaPageRequest.java

@@ -0,0 +1,123 @@
+package com.style24.persistence;
+
+import java.io.Serializable;
+
+import lombok.Data;
+
+/**
+ * Paging
+ *
+ * @author gagamel
+ * @since 2020. 10. 5
+ */
+@SuppressWarnings("serial")
+@Data
+public class TsaPageRequest implements Serializable {
+
+	private final int pageNo;   // 페이지번호
+	private final int pageSize; // 조회할 row수
+	private final int pageUnit; // 그룹핑 페이지 단위
+	private int totalCount = 0; // 전체 row 건수
+
+	public TsaPageRequest(int pageNo, int pageSize) {
+		this(pageNo, pageSize, 10);
+	}
+
+	public TsaPageRequest(int pageNo, int pageSize, int pageUnit) {
+		if (pageNo < 0) {
+			throw new IllegalArgumentException("Current page index must not be less than zero!");
+		}
+
+		if (pageSize < 1) {
+			throw new IllegalArgumentException("Page size must not be less than one!");
+		}
+
+		if (pageUnit < 1) {
+			throw new IllegalArgumentException("Page unit must not be less than one!");
+		}
+
+		this.pageNo = pageNo;
+		this.pageSize = pageSize;
+		this.pageUnit = pageUnit;
+	}
+
+	public int getPageNo() {
+		return pageNo + 1;
+	}
+
+	public int getOffset() {
+		return pageNo * pageSize;
+	}
+
+	public int getStartRow() {
+		return pageNo * pageSize + 1;
+	}
+
+	public int getEndRow() {
+		return getOffset() + pageSize;
+	}
+
+	public int getPageGroup() {
+		return pageNo / pageUnit + 1;
+	}
+
+	public void setTotalCount(int totalCount) {
+		this.totalCount = totalCount;
+	}
+
+	public int getTotalPage() {
+		int totalPage = totalCount / pageSize;
+		if (totalCount % pageSize > 0) {
+			totalPage++;
+		}
+		return totalPage;
+	}
+
+	public String getGeneratedPagination() {
+		int firstCount = (getPageGroup() - 1) * pageUnit + 1;
+		int loopCount = firstCount + pageUnit;
+		if (loopCount > getTotalPage()) {
+			loopCount = getTotalPage() + 1;
+		}
+
+		StringBuffer pageTag = new StringBuffer();
+		if (!(firstCount == 1 && loopCount == 1)) {
+			if (getPageNo() == 1) {
+				pageTag.append("<a class=\"arrow\" href=\"#\"><i class=\"fa fa-angle-double-left\" alt=\"맨처음\"></i></a>\n");
+			} else {
+				pageTag.append("<a class=\"arrow\" href=\"#pageNo=1\"><i class=\"fa fa-angle-double-left\" alt=\"맨처음\"></i></a>\n");
+			}
+
+			if (getPageGroup() == 1) {
+				pageTag.append("<a class=\"arrow\" href=\"#\"><i class=\"fa fa-angle-left\" alt=\"이전페이지\"></i></a>\n");
+			} else {
+				pageTag.append("<a class=\"arrow\" href=\"#pageNo=").append((getPageGroup() - 1) * pageUnit).append("\"><i class=\"fa fa-angle-left\" alt=\"이전페이지\"></i></a>\n");
+			}
+
+			for (int i = firstCount; i < loopCount; i++) {
+				if (getPageNo() == i) {
+					pageTag.append("<a class=\"num on\" href=\"#\">").append(i).append("</a>\n");
+				} else {
+					pageTag.append("<a class=\"num\" href=\"#pageNo=").append(i).append("\">").append(i).append("</a>\n");
+				}
+			}
+
+			if (loopCount <= (getTotalPage() + 1)) {
+				if (getPageNo() == getTotalPage()) {
+					pageTag.append("<a class=\"arrow\" href=\"#\"><i class=\"fa fa-angle-right\" alt=\"다음페이지\"></i></a>\n");
+					pageTag.append("<a class=\"arrow\" href=\"#\"><i class=\"fa fa-angle-double-right\" alt=\"맨마지막\"></i></a>\n");
+				} else {
+					pageTag.append("<a class=\"arrow\" href=\"#pageNo=").append(getPageGroup() * pageUnit + 1).append("\"><i class=\"fa fa-angle-right\" alt=\"다음페이지\"></i></a>\n");
+					pageTag.append("<a class=\"arrow\" href=\"#pageNo=").append(getTotalPage()).append("\"><i class=\"fa fa-angle-double-right\" alt=\"맨마지막\"></i></a>\n");
+				}
+			}
+		}
+		return pageTag.toString();
+	}
+
+	@Override
+	public String toString() {
+		return String.format("Page request [pageNo: %d, pageSize %d, pageUnit %d]", getPageNo(), pageSize, pageUnit);
+	}
+
+}

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

@@ -0,0 +1,31 @@
+package com.style24.persistence.domain;
+
+import java.util.Collection;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 광고 키워드 Domain
+ *
+ * @author eskim
+ * @since 2020. 12. 14
+ */
+@SuppressWarnings("serial")
+@Data
+public class AdKeyword extends TscBaseDomain {
+
+	private Integer adKeywordSq;
+	private String adKeyword;
+	private String adKeywordStdt;
+	private String adKeywordEddt;
+	private String useYn;
+
+	private String goodsCd;
+	private String stDate;
+	private String edDate;
+
+	private String goodsList;
+	private Collection<AdKeywordGoods> goodsListNew;
+}

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

@@ -0,0 +1,28 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 광고 키워드 Domain
+ *
+ * @author eskim
+ * @since 2020. 12. 14
+ */
+@SuppressWarnings("serial")
+@Data
+public class AdKeywordGoods extends TscBaseDomain {
+
+	private Integer adKeywordSq;
+	private String goodsCd;
+	private int dispOrd;
+	private String delYn;
+
+	private String goodsNm;
+	private String crud;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] arrGoodsCd;
+}

+ 24 - 0
src/main/java/com/style24/persistence/domain/Aflink.java

@@ -0,0 +1,24 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 제휴채널 Domain
+ *
+ * @author gagamel
+ * @since 2020. 10. 20
+ */
+@SuppressWarnings("serial")
+@Data
+public class Aflink extends TscBaseDomain {
+
+	private String afLinkCd;	// 제휴링크코드
+	private String afLinkNm;	// 제휴링크명
+	private String afChannel;	// 제휴채널
+	private float feeRate;		// 수수료율(마진율)
+	private int dispOrd;		// 표시순서
+	private String useYn;		// 사용여부
+
+}

Някои файлове не бяха показани, защото твърде много файлове са промени