Просмотр исходного кода

Merge remote-tracking branch 'origin/bin2107' into card007

card007 4 лет назад
Родитель
Сommit
617846beed
36 измененных файлов с 3759 добавлено и 785 удалено
  1. 0 327
      src/main/java/com/style24/admin/biz/dao/TsaOcmDao.java
  2. 233 0
      src/main/java/com/style24/admin/biz/dao/TsaShoplinkerDao.java
  3. 12 0
      src/main/java/com/style24/admin/biz/service/TsaCustomerService.java
  4. 1 1
      src/main/java/com/style24/admin/biz/service/TsaDisplayService.java
  5. 7 1
      src/main/java/com/style24/admin/biz/service/TsaGoodsService.java
  6. 0 11
      src/main/java/com/style24/admin/biz/service/TsaOcmService.java
  7. 1233 0
      src/main/java/com/style24/admin/biz/service/TsaShoplinkerService.java
  8. 31 0
      src/main/java/com/style24/admin/biz/web/TsaCustomerController.java
  9. 1 1
      src/main/java/com/style24/admin/biz/web/TsaOcmController.java
  10. 34 0
      src/main/java/com/style24/admin/biz/web/TsaOrderChangeController.java
  11. 226 96
      src/main/java/com/style24/admin/biz/web/TsaShoplinkerController.java
  12. 1 0
      src/main/java/com/style24/persistence/domain/Extmall.java
  13. 2 0
      src/main/java/com/style24/persistence/domain/Goods.java
  14. 6 6
      src/main/java/com/style24/persistence/mybatis/shop/TsaCustomer.xml
  15. 16 0
      src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml
  16. 4 0
      src/main/java/com/style24/persistence/mybatis/shop/TsaOcm.xml
  17. 806 0
      src/main/java/com/style24/persistence/mybatis/shop/TsaShoplinker.xml
  18. 2 2
      src/main/java/com/style24/persistence/mybatis/shop/TsaSocial.xml
  19. 5 5
      src/main/java/com/style24/persistence/mybatis/shop/TsaWithdraw.xml
  20. 4 4
      src/main/webapp/WEB-INF/views/board/FaqDetailForm.html
  21. 3 1
      src/main/webapp/WEB-INF/views/customer/CustomerDormantListForm.html
  22. 108 83
      src/main/webapp/WEB-INF/views/customer/CustomerSecedeListForm.html
  23. 7 1
      src/main/webapp/WEB-INF/views/display/MainContentsPopupForm.html
  24. 106 9
      src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html
  25. 1 0
      src/main/webapp/WEB-INF/views/goods/GoodsPopupListForm.html
  26. 12 2
      src/main/webapp/WEB-INF/views/ocm/ExtmallForm.html
  27. 32 9
      src/main/webapp/WEB-INF/views/ocm/ExtmallOrderRegisterForm.html
  28. 411 0
      src/main/webapp/WEB-INF/views/order/CnclCompleteView.html
  29. 1 1
      src/main/webapp/WEB-INF/views/order/CnclReqForm.html
  30. 38 14
      src/main/webapp/WEB-INF/views/order/OrderDetailForm.html
  31. 93 65
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerGoodsSendForm.html
  32. 104 61
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerInvoiceSendForm.html
  33. 5 0
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerOrderDetailForm.html
  34. 80 31
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerOrderForm.html
  35. 124 53
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerStockForm.html
  36. 10 1
      src/main/webapp/WEB-INF/views/withdraw/WithdrawExceptionListForm.html

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

@@ -5,11 +5,8 @@ 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.ExtmallOrder;
 import com.style24.persistence.domain.ExtmallOrigin;
 import com.style24.persistence.domain.ExtmallPriceSync;
-import com.style24.persistence.domain.GoodsStock;
-import com.style24.persistence.domain.Payment;
 
 /**
  * 영업망관리 Dao
@@ -72,328 +69,4 @@ public interface TsaOcmDao {
 	 */
 	void saveExtmallPriceSync(ExtmallPriceSync extmallPriceSync);
 
-
-
-
-	/**
-	 * 제휴몰주문등록 - 주문업로드 그룹별 목록
-	 *
-	 * @param extmallOrder
-	 * @return
-	 * @author jmh
-	 * @since 2021. 5. 31
-	 */
-	Collection<ExtmallOrder> getExtmallMasterOrderList(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰주문등록 - 주문업로드 전체 목록
-	 *
-	 * @param extmallOrder
-	 * @return
-	 * @author jmh
-	 * @since 2021. 5. 31
-	 */
-	Collection<ExtmallOrder> getExtmallOrderList(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰주문등록 - 주문등록
-	 *
-	 * @param extmallOrder
-	 * @return
-	 * @author jmh
-	 * @since 2021. 5. 31
-	 */
-	void insertExtmallOrder(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰주문등록 - 주문등록 상태값 업데이트
-	 * @param extmallOrder
-	 * @return
-	 * @author xodud1202
-	 * @since 2021. 01. 28
-	 */
-	void updateExtmallOrder(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰주문등록 - 주문등록체크정보
-	 * @param extmallOrder
-	 * @return
-	 * @author jmh
-	 * @since 2021. 5. 31
-	 */
-	ExtmallOrder getExtmallOrderInfo(ExtmallOrder extmallOrder);
-
-
-	// ------------------------- 주문등록 소스 -------------------------------------------//
-	// ------------------------- 주문등록 소스 -------------------------------------------//
-	/**
-	 * 1. 주문기본정보 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createOrder(ExtmallOrder extmallOrder);
-
-	/**
-	 * 2. 주문배송지정보 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createDeliveryAddr(ExtmallOrder extmallOrder);
-
-	/**
-	 * 3. 주문배송비정보등록 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createDeliveryFee(ExtmallOrder extmallOrder);
-
-	/**
-	 * 4. 주문상세정보등록 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createOrderDetail(ExtmallOrder extmallOrder);
-
-	/**
-	 * 4-2 주문상세 이력 등록
-	 *
-	 * @param extmallOrder
-	 * @return
-	 * @author jmh
-	 * @since 2020. 11. 30
-	 */
-	int createOrderDetailHst(ExtmallOrder extmallOrder);
-
-	/**
-	 * 5. 주문상세단품정보등록 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	Collection<ExtmallOrder> getOrderDetailItem(ExtmallOrder extmallOrder);
-
-	/**
-	 * 6. 주문상세단품정보등록 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createOrderDetailItem(ExtmallOrder extmallOrder);
-
-	/**
-	 * 7. 주문상세단품이력정보등록 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createOrderDetailItemHst(ExtmallOrder extmallOrder);
-
-	/**
-	 * 8. 주문사은품 마스터 정보 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createOrdFreegift(ExtmallOrder extmallOrder);
-
-	/**
-	 * 9. 주문사은품 상품 정보 등록
-	 *
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createOrdFreegiftVal(ExtmallOrder extmallOrder);
-
-	/**
-	 * 10. 주문사은품 주문상세 정보 등록
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createOrdFreegiftDtl(ExtmallOrder extmallOrder);
-
-	/**
-	 * 11. PAYMENT INSERT
-	 * @param param
-	 * @return
-	 */
-	int insertPayment(Payment param);
-
-	/**
-	 * 12. 재고정보등록
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 03. 09
-	 */
-	int createSellQty(ExtmallOrder extmallOrder);
-
-	/**
-	 * 13. 사은품 남은수량 업데이트
-	 * @param extmallOrder - 주문 정보
-	 * @return
-	 * @author jmh
-	 * @since 2021. 04. 13
-	 */
-	int updateFreegiftValLeftQty(ExtmallOrder extmallOrder);
-
-	/**
-	 * 상품 재고 조회
-	 * @param goodsStock
-	 * @return
-	 * @author xodud1202
-	 * @since 2021. 01. 28
-	 */
-	GoodsStock getGoodsStockInfo(GoodsStock goodsStock);
-
-	/**
-	 * 사은품 : 1차조건 적용된 사음품 정보, 상품 금액 조회
-	 *
-	 * @param Order
-	 * @author jsh77b
-	 * @since 2021. 02. 02
-	 */
-	Collection<ExtmallOrder> getFreeGiftGoodsApplyAmt(ExtmallOrder extmallOrder);
-
-	/**
-	 * 사은품 : 2차조건 적용된 사은품상품금액 구간정보조회
-	 *
-	 * @param Order
-	 * @author jsh77b
-	 * @since 2021. 02. 02
-	 */
-	Collection<ExtmallOrder> getFreeGiftGoodsApplySection(ExtmallOrder extmallOrder);
-
-	/**
-	 * 사은품 : 3차조건 적용된 구간정보의 사은품정보조회
-	 *
-	 * @param Order
-	 * @author jsh77b
-	 * @since 2021. 02. 02
-	 */
-	Collection<ExtmallOrder> getFreeGiftGoodsApplyVal(ExtmallOrder extmallOrder);
-	// ------------------------- 주문등록 소스 끝 -------------------------------------------//
-	// ------------------------- 주문등록 소스 끝 -------------------------------------------//
-
-
-
-
-
-
-
-	/**
-	 * 제휴몰주문 임시 테이블 삭제
-	 *
-	 * @param userNo - 사용자아이디
-	 * @return int
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	int deleteExtmallOrderUploadTmp(int userNo);
-
-	/**
-	 * 외부몰주문등록 테이블 실패목록 데이터 삭제
-	 *
-	 * @param userNo - 사용자아이디
-	 * @return int
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	int deleteExtmallOrderUploadFail(int userNo);
-
-	/**
-	 * 제휴몰주문등록 (TB_EXTMALL_ORDER_UPLOAD_TMP)
-	 *
-	 * @param extmallOrderUpload - 제휴몰주문업로드정보
-	 * @return int
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	int createExtmallOrderUploadTmp(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰주문등록 업로드 후 목록
-	 *
-	 * @param extmallOrder - 제휴몰주문업로드정보
-	 * @return Collection<ExtmallOrder>
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	Collection<ExtmallOrder> getExtmallOrderUploadTmpList(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰주문업로드 생성 - 제휴몰 벤더ID 가져오기
-	 *
-	 * @param regId -
-	 * @return String
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	String getVendorId(String regId);
-
-	/**
-	 * 제휴몰주문등록 업로드 후 주문업로드 생성
-	 *
-	 * @param extmallOrderUpload - 제휴몰주문업로드정보
-	 * @return int
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	int createExtmallOrderUploadSecond(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰주문등록 주문업로드 후 목록
-	 *
-	 * @param extmallOrder - 제휴몰주문업로드정보
-	 * @return Collection<ExtmallOrder>
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	Collection<ExtmallOrder> getExtmallOrderUploadSecondList(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰 주문 업로드 목록
-	 *
-	 * @param extmallOrder - 외부몰주문업로드 정보
-	 * @return Collection<ExtmallOrder>
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	Collection<ExtmallOrder> getExtmallOrderUploadList(ExtmallOrder extmallOrder);
-
-	/**
-	 * 제휴몰 주문 업로드 결과정보
-	 *
-	 * @param extmallOrder - 외부몰주문업로드 정보
-	 * @return Collection<ExtmallOrder>
-	 * @author jmh
-	 * @since 2021. 06. 17
-	 */
-	ExtmallOrder getExtmallOrderUploadResultInfo(ExtmallOrder extmallOrder);
-
-
-	void insertTestNotiInfo(ExtmallOrder extmallOrder);
 }

+ 233 - 0
src/main/java/com/style24/admin/biz/dao/TsaShoplinkerDao.java

@@ -0,0 +1,233 @@
+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.ExtmallOrder;
+import com.style24.persistence.domain.ShoplinkerGoods;
+import com.style24.persistence.domain.ShoplinkerInvoice;
+import com.style24.persistence.domain.ShoplinkerOrder;
+import com.style24.persistence.domain.ShoplinkerSearch;
+
+/**
+ * 샵링커 Dao
+ *
+ * @author jmh
+ * @since 2021. 5. 20
+ */
+@ShopDs
+public interface TsaShoplinkerDao {
+
+	/**
+	 * 상품등록-단품 목록 조회
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerGoods> getOptionList(ShoplinkerGoods shoplinkerSearch);
+
+	/**
+	 * 상품등록-상품 상세
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	ShoplinkerGoods getGoods(ShoplinkerGoods shoplinkerSearch);
+
+	/**
+	 * 상품등록-상품 이미지 조회
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerGoods> getGoodsImageList(ShoplinkerGoods shoplinkerSearch);
+
+	/**
+	 * 상품등록-상품 사이즈 조회
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerGoods> getGoodsSizeList(ShoplinkerGoods shoplinkerSearch);
+
+	/**
+	 * 상품등록-고시정보
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerGoods> getGoodsNotiList(ShoplinkerGoods shoplinkerSearch);
+
+	/**
+	 * 상품등록-인증정보
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	ShoplinkerGoods getCert(ShoplinkerGoods shoplinkerSearch);
+
+	/**
+	 * 상품등록-상품 목록 건수
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int getGoodsSendListCount(ShoplinkerSearch shoplinkerSearch);
+
+	/**
+	 * 상품등록-상품 목록
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerGoods> getGoodsSendList(ShoplinkerSearch shoplinkerSearch);
+
+	/**
+	 * 상품등록-상품 목록 엑셀
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<GagaMap> getGoodsSendExcelList(ShoplinkerSearch shoplinkerSearch);
+
+	/**
+	 * 재고-단품 등록
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	void insertStockOption(ShoplinkerGoods shoplinkerGoods);
+
+	/**
+	 * 재고전송-목록 건수
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int getStockListCount(ShoplinkerSearch shoplinkerSearch);
+
+	/**
+	 * 재고전송-목록
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerGoods> getStockList(ShoplinkerSearch shoplinkerSearch);
+
+	/**
+	 * 재고- 목록 엑셀
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<GagaMap> getStockExcelList(ShoplinkerSearch shoplinkerSearch);
+
+
+	/**
+	 * 샵링커주문수집-목록 건수
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int getShoplinkerOrderListCount(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 샵링커주문수집-목록
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerOrder> getShoplinkerOrderList(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 샵링커주문수집-상세
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	ShoplinkerOrder getShoplinkerOrderInfo(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 샵링커주문수집-제휴몰 주문등록 상세
+	 *
+	 * @param extmallOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 31
+	 */
+	ExtmallOrder getExtmallOrderInfo(String extmallOrder);
+
+	/**
+	 * 샵링커주문수집- 엑셀
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<GagaMap> getOrderExcelList(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 송장전송-전송 목록 건수
+	 *
+	 * @param shoplinkerInvoice
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int getSendInvoiceListCount(ShoplinkerInvoice shoplinkerInvoice);
+
+	/**
+	 * 송장전송-전송 목록
+	 *
+	 * @param shoplinkerInvoice
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerInvoice> getSendInvoiceList(ShoplinkerInvoice shoplinkerInvoice);
+
+	/**
+	 * 송장- 목록 엑셀
+	 *
+	 * @param shoplinkerInvoice
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<GagaMap> getInvoiceExcelList(ShoplinkerInvoice shoplinkerInvoice);
+
+}

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

@@ -485,6 +485,18 @@ public class TsaCustomerService {
 		return coreCustomerService.getCustomerInfo(customer);
 	}
 
+	/**
+	 * 탈퇴처리
+	 *
+	 * @param custNo - 고객번호
+	 * @return GagaMap - 결과정보
+	 * @author jsshin
+	 * @since 2021. 03. 08
+	 */
+	@Transactional("shopTxnManager")
+	public boolean deleteSecedeCustomer(Integer custNo) {
+		return coreCustomerService.deleteSecedeCustomer(custNo);
+	}
 
 
 

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

@@ -604,7 +604,7 @@ public class TsaDisplayService {
 
 		int ind = 1;
 		for (Contents contents : contentsList) {
-			contents.setContentsSq(null);
+//			contents.setContentsSq(null);
 			if (contents != null && contents.getDispStdt() != null && !contents.getDispStdt().equals("")) {
 				// 브랜드 이미지 변경이 일어났을 경우
 				String brandGroupImg = contents.getBrandGroupImg();

+ 7 - 1
src/main/java/com/style24/admin/biz/service/TsaGoodsService.java

@@ -1054,7 +1054,13 @@ public class TsaGoodsService {
 		// 판매기간설정 eskim
 		goods.setSellStdt(goods.getSellStYMD().replaceAll("-", "") + goods.getSellStHH() + "0000");
 		goods.setSellEddt(goods.getSellEdYMD().replaceAll("-", "") + goods.getSellEdHH() + "5959");
-
+		
+		// 신규가입기간
+		if (!StringUtils.isEmpty(goods.getNewCustOrdStdt())) {
+			goods.setNewCustOrdStdt(goods.getNewCustOrdStdt().replaceAll("-", "") + "000000");
+			goods.setNewCustOrdEddt(goods.getNewCustOrdEddt().replaceAll("-", "") + "235959");	
+		}
+		
 		// 기본정보 변경
 		if ("Y".equals(goods.getChDataYn())) {
 			goodsDao.createGoodsHst(goods);

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

@@ -3,14 +3,11 @@ 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.fasterxml.jackson.databind.ObjectMapper;
 import com.style24.admin.biz.dao.TsaOcmDao;
 import com.style24.admin.support.security.session.TsaSession;
-import com.style24.core.biz.service.TscKakaotalkService;
 import com.style24.core.support.message.TscMessageByLocale;
 import com.style24.persistence.domain.Extmall;
 import com.style24.persistence.domain.ExtmallNoti;
@@ -32,17 +29,9 @@ public class TsaOcmService {
     @Autowired
     private TscMessageByLocale message;
 
-    @Autowired
-	private TscKakaotalkService kakaotalkService;
-
-    @Autowired
-	private Environment env;
-
     @Autowired
     private TsaOcmDao ocmDao;
 
-    @Autowired
-	private ObjectMapper mapper;
 
     /**
      * 제휴몰 목록

+ 1233 - 0
src/main/java/com/style24/admin/biz/service/TsaShoplinkerService.java

@@ -0,0 +1,1233 @@
+package com.style24.admin.biz.service;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.excel.env.GagaExcelConstants;
+import com.gagaframework.shoplinker.GagaShoplinkertUtil;
+import com.gagaframework.shoplinker.env.GagaShoplinkerConstants;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.style24.admin.biz.dao.TsaShoplinkerDao;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.core.biz.dao.TscShoplinkerDao;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.ExtmallOrder;
+import com.style24.persistence.domain.ShoplinkerGoods;
+import com.style24.persistence.domain.ShoplinkerInvoice;
+import com.style24.persistence.domain.ShoplinkerOrder;
+import com.style24.persistence.domain.ShoplinkerSearch;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 영업망관리 샵링커 Service
+ *
+ * @author gagamel
+ * @since 2020. 11. 4
+ */
+@Service
+@Slf4j
+@SuppressWarnings("deprecation")
+public class TsaShoplinkerService {
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaShoplinkerDao admShoplinkerDao;
+
+	@Autowired
+	private TscShoplinkerDao tscShoplinkerDao;
+
+	private String fileAddNm; // 유저번호_년월일시분초
+
+	/**
+	 * 샵링커 상품등록
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public GagaMap createShoplinkerXml(Collection<GagaMap> ecxelGoodsList, ShoplinkerGoods shoplinkerGoods)throws IOException {
+		// 파일명 추가 네이밍 규칙
+		fileAddNm = shoplinkerGoods.getRegNo() +"_"+ GagaDateUtil.getTodayDateTime();
+
+		GagaMap rtnMap = new GagaMap();
+		int optionAll=0, optionSucc=0;
+		int excelCnt= ecxelGoodsList.size();
+		int tProdSucc = 0, productSucc=0, goodsNotiSucc=0, certSucc=0, imageSucc=0;
+
+		for (GagaMap gagaMap : ecxelGoodsList) {
+			if( !"".equals(gagaMap.getString("goodsCd").trim())) {
+				shoplinkerGoods.setGoodsCd(gagaMap.getString("goodsCd"));
+
+				// 1. 단품생성
+				rtnMap = createOptionRegisterXml(shoplinkerGoods);
+				optionAll += rtnMap.getInt("allCnt");
+				optionSucc += rtnMap.getInt("succCnt");
+
+				// 2. 상품생성
+				tProdSucc = createGoodsRegisterXml(shoplinkerGoods);
+				productSucc += tProdSucc;
+
+				// 3. 고시정보(품목정보)
+				goodsNotiSucc += createGoodsNotiRegisterXml(shoplinkerGoods);
+
+				// 4. 인증정보
+				certSucc += createCertRegisterXml(shoplinkerGoods);
+
+				// 5. 상품이미지정보
+				imageSucc += createImageRegisterXml(shoplinkerGoods);
+			}
+		}
+
+		rtnMap = new GagaMap();
+		rtnMap.setInt("excelCnt", excelCnt);
+		rtnMap.setInt("optionAll", optionAll);
+		rtnMap.setInt("optionSucc", optionSucc);
+		rtnMap.setInt("productSucc", productSucc);
+		rtnMap.setInt("goodsNotiSucc", goodsNotiSucc);
+		rtnMap.setInt("certSucc", certSucc);
+		rtnMap.setInt("imageSucc", imageSucc);
+
+		return rtnMap;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 1. 단품생성
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	private GagaMap createOptionRegisterXml(ShoplinkerGoods shoplinkerGoods) throws IOException {
+
+		GagaMap returnMap = new GagaMap();
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+		regMap.setApiType("OPTION");
+		regMap.setApiSubUrl(env.getProperty("shoplinker.url.option"));
+		regMap.setGoodsCd(shoplinkerGoods.getGoodsCd());
+		regMap.setRegNo(shoplinkerGoods.getRegNo());
+		regMap.setXmlPath(shoplinkerGoods.getXmlPath());
+		regMap.setDomainUrl(shoplinkerGoods.getDomainUrl());
+
+		int succCnt = 0;
+		int allCnt = 0;
+
+		try {
+			// 옵션 목록조회
+			Collection<ShoplinkerGoods> list = admShoplinkerDao.getOptionList(shoplinkerGoods);
+			if( null != list && !list.isEmpty()) {
+				allCnt = list.size();
+
+				StringBuilder sbRequest;
+				int opCnt = 0;
+				for (ShoplinkerGoods map : list) {
+					opCnt ++;
+
+					// xml 데이터 세팅
+					sbRequest = new StringBuilder();
+					sbRequest.append("<?xml version=\"1.0\" encoding=\"euc-kr\"?>\n");
+					sbRequest.append("<shoplinker>\n");
+					sbRequest.append("	<productInfo>\n");
+					sbRequest.append("		<product>\n");
+
+					sbRequest.append("			<customer_id>").append(shoplinkerGoods.getCustomerId()).append("</customer_id>\n");
+					sbRequest.append("			<partner_product_id><![CDATA[").append(map.getPartnerProductId()).append("]]></partner_product_id>\n");
+					sbRequest.append("			<attribute_code><![CDATA[").append("999999999").append("]]></attribute_code>\n");
+					sbRequest.append("			<product_name><![CDATA[").append(map.getOptCd1()+"_"+map.getOptCd2()).append("]]></product_name>\n");
+					sbRequest.append("			<quantity>").append(map.getQuantity()).append("</quantity>\n");
+
+					sbRequest.append("		</product>\n");
+					sbRequest.append("	</productInfo>\n");
+					sbRequest.append("</shoplinker>\n");
+
+					regMap.setOptCd(map.getPartnerProductId());
+					regMap.setQuantity(map.getQuantity());
+
+					// api 호출 및 결과 history 저장
+					succCnt += callGoodsRegApi(regMap , sbRequest, "option_"+opCnt);
+				}
+			}
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			regMap.setApiResult("error");
+			regMap.setApiMessage("xml 생성오류");
+			tscShoplinkerDao.insertShoplinerApiHst(regMap);
+		}
+
+		returnMap.setInt("allCnt", allCnt);
+		returnMap.setInt("succCnt", succCnt);
+
+		return returnMap;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 2. 상품생성
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public int createGoodsRegisterXml(ShoplinkerGoods shoplinkerGoods) throws IOException {
+
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+		regMap.setApiType("PRODUCT");
+		regMap.setApiSubUrl(env.getProperty("shoplinker.url.product"));
+		regMap.setGoodsCd(shoplinkerGoods.getGoodsCd());
+		regMap.setRegNo(shoplinkerGoods.getRegNo());
+		regMap.setXmlPath(shoplinkerGoods.getXmlPath());
+		regMap.setDomainUrl(shoplinkerGoods.getDomainUrl());
+
+		int succCnt = 0;
+
+		try {
+			// 상품기본정보
+			ShoplinkerGoods goodsMap = admShoplinkerDao.getGoods(shoplinkerGoods);
+
+			// 상품상세(퍼블) 세팅
+			String detailDesc = this.setDetailDesc(shoplinkerGoods, goodsMap);
+
+			// xml 데이터 세팅
+			StringBuilder sbRequest = new StringBuilder();
+			sbRequest.append("<?xml version=\"1.0\" encoding=\"euc-kr\"?>\n");
+			sbRequest.append("<shoplinker>\n");
+			sbRequest.append("	<productInfo>\n");
+			sbRequest.append("		<product>\n");
+
+			sbRequest.append("			<customer_id>").append(shoplinkerGoods.getCustomerId()).append("</customer_id>\n");
+			sbRequest.append("			<partner_product_id>").append(goodsMap.getGoodsCd()).append("</partner_product_id>\n");
+			sbRequest.append("			<attribute_title_code>").append("999999999").append("</attribute_title_code>\n");
+			sbRequest.append("			<attribute_partner_product_id>").append(goodsMap.getAttributePartnerProductId()).append("</attribute_partner_product_id>\n");
+			sbRequest.append("			<product_name>").append(goodsMap.getProductName()).append("</product_name>\n");
+			sbRequest.append("			<detail_desc>").append(detailDesc).append("</detail_desc>\n");
+
+			// 가격연계
+			if( "Y".equals(goodsMap.getSyncYn())) {
+				//sbRequest.append("			<new_desc_top>").append(goodsMap.getNewDescTop()).append("</new_desc_top>\n");
+				//sbRequest.append("			<market_price>").append(goodsMap.getMarketPrice()).append("</market_price>\n");
+				sbRequest.append("			<sale_price>").append(goodsMap.getSalePrice()).append("</sale_price>\n");
+				sbRequest.append("			<supply_price>").append(goodsMap.getSupplyPrice()).append("</supply_price>\n");
+				//sbRequest.append("			<market_price_p>").append(goodsMap.getMarketPriceP()).append("</market_price_p>\n");
+				//sbRequest.append("			<sale_price_p>").append(goodsMap.getSalePriceP()).append("</sale_price_p>\n");
+				//sbRequest.append("			<supply_price_p>").append(goodsMap.getSupplyPriceP()).append("</supply_price_p>\n");
+			}else{
+				//sbRequest.append("			<new_desc_top>").append(goodsMap.getNewDescTop()).append("</new_desc_top>\n");
+				//sbRequest.append("			<market_price>").append(goodsMap.getMarketPrice()).append("</market_price>\n");
+				sbRequest.append("			<sale_price>").append(0).append("</sale_price>\n");
+				sbRequest.append("			<supply_price>").append(0).append("</supply_price>\n");
+				//sbRequest.append("			<market_price_p>").append(goodsMap.getMarketPriceP()).append("</market_price_p>\n");
+				//sbRequest.append("			<sale_price_p>").append(goodsMap.getSalePriceP()).append("</sale_price_p>\n");
+				//sbRequest.append("			<supply_price_p>").append(goodsMap.getSupplyPriceP()).append("</supply_price_p>\n");
+			}
+
+			sbRequest.append("			<sale_status>").append("001").append("</sale_status>\n"); // 판매중
+			sbRequest.append("			<tax_yn>").append("001").append("</tax_yn>\n"); // 과세
+			sbRequest.append("			<salearea>전국</salearea>\n");
+			sbRequest.append("			<sex>").append(goodsMap.getSex()).append("</sex>\n");
+			sbRequest.append("			<model>").append(goodsMap.getModel()).append("</model>\n");
+			sbRequest.append("			<model_no>").append(goodsMap.getModelNo()).append("</model_no>\n");
+			sbRequest.append("			<brand>").append(goodsMap.getBrand()).append("</brand>\n");
+			sbRequest.append("			<auth_no>").append(goodsMap.getAuthNo()).append("</auth_no>\n");
+			sbRequest.append("			<expirydate>20991231</expirydate>\n");
+			sbRequest.append("			<maker>").append(goodsMap.getMaker()).append("</maker>\n");
+			sbRequest.append("			<origin>").append(goodsMap.getOrigin()).append("</origin>\n");
+			sbRequest.append("			<adult_info>").append(goodsMap.getAdultInfo()).append("</adult_info>\n");
+			sbRequest.append("			<ccategory_l>").append(goodsMap.getCcategoryL()).append("</ccategory_l>\n");
+			sbRequest.append("			<ccategory_m>").append(goodsMap.getCcategoryM()).append("</ccategory_m>\n");
+			sbRequest.append("			<ccategory_s>").append(goodsMap.getCcategoryS()).append("</ccategory_s>\n");
+			sbRequest.append("			<ccategory_d>").append(goodsMap.getCcategoryD()).append("</ccategory_d>\n");
+
+			sbRequest.append("		</product>\n");
+			sbRequest.append("	</productInfo>\n");
+			sbRequest.append("</shoplinker>\n");
+
+			if( null != goodsMap.getShoplinkerItemkindNm()) {
+				// api 호출 및 결과 history 저장
+				succCnt = callGoodsRegApi(regMap , sbRequest, "product");
+
+			}else {
+				// 품목매핑정보 없음. 전송 안함
+				regMap.setXmlTxt(sbRequest.toString());
+				regMap.setApiResult("error");
+				regMap.setApiMessage("API 전송안함=>샵링커 품목매핑정보가 없습니다. (자사품목코드: "+goodsMap.getItemkindCd()+")");
+				tscShoplinkerDao.insertShoplinerApiHst(regMap);
+			}
+
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			regMap.setApiResult("error");
+			regMap.setApiMessage("xml 생성오류");
+			tscShoplinkerDao.insertShoplinerApiHst(regMap);
+		}
+
+		return succCnt;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 상세내용 세팅
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	private String setDetailDesc(ShoplinkerGoods shoplinkerGoods, ShoplinkerGoods goodsMap) {
+
+		String htmlDesc = "";
+
+		// 상세폼신규사용여부 N: 기존 정보 / Y : html 형식
+		if( "N".equals(goodsMap.getTobeFormYn())){
+			String descStr = goodsMap.getDetailDesc();
+			descStr = descStr.replace("http://www.istyle24.com/Upload/", "http://image.istyle24.com/Local/")
+					.replace("/Upload", "http://image.istyle24.com/Local")
+					.replace("http://www.istyle24.com/Images", "http://image.istyle24.com/Statics/design/Images");
+
+			htmlDesc = descStr;
+
+		}else {
+
+			String imgPath = env.getProperty("upload.goods.view");
+			imgPath = imgPath.replace("/Upload", "/Local")
+					.replace("http://www.istyle24.com/Upload/", "http://image.istyle24.com/Local/")
+					.replace("http://www.istyle24.com/Images", "http://image.istyle24.com/Statics/design/Images");
+
+			Collection<ShoplinkerGoods> imgList = admShoplinkerDao.getGoodsImageList(shoplinkerGoods);
+
+			String dColor = goodsMap.getMainColorEnm(); //대표컬러
+			String dImgFront = "";	//대표상품 앞판컷
+			String dImgBack = ""; 	//대표상품 뒷판컷
+			String dMaterial = ""; //대표상품 패브릭(소재컷?)
+			ArrayList<String> dImgModelList = new ArrayList<String>(); //대표상품 모델컷
+			ArrayList<String> dImgDetailList = new ArrayList<String>(); //대표상품 디테일컷(상세컷)
+			ArrayList<String> dLabelList = new ArrayList<String>(); //대표상품 케어라벨
+			ArrayList<String> dImgOtherList = new ArrayList<String>(); //상품외부몰용
+
+			// 이미지 정보
+			for(ShoplinkerGoods map : imgList) {
+
+				if( -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_01.jpg")) { //대표상품 앞판컷
+					dImgFront = imgPath +"/"+ map.getSysImgNm();
+		        }
+				if( -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_02.jpg")) { //대표상품 뒷판컷
+					dImgBack = imgPath +"/"+ map.getSysImgNm();
+		        }
+				if( -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_C")) { //대표상품 모델컷
+					dImgModelList.add(imgPath +"/"+ map.getSysImgNm());
+		        }
+				if( -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_D")) { //대표상품 디테일컷(상세컷)
+					dImgDetailList.add(imgPath +"/"+ map.getSysImgNm());
+		        }
+				if( -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_F")) { //대표상품 패브릭(소재컷?)
+					dMaterial = imgPath +"/"+ map.getSysImgNm();
+		        }
+				if( -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_L")) { //대표상품 케어라벨
+					dLabelList.add(imgPath +"/"+ map.getSysImgNm());
+		        }
+				if( -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_X")) { //대표상품 디테일컷(상세컷)
+					dImgOtherList.add(imgPath +"/"+ map.getSysImgNm());
+		        }
+			}
+
+			// 제대로된 정보 없을 경우, 기존 상세내용으로 보냄
+			if( "".equals(dImgFront) || "".equals(dImgBack)) {
+				String descStr = goodsMap.getDetailDesc();
+				descStr = descStr.replace("http://www.istyle24.com/Upload/", "http://image.istyle24.com/Local/")
+						.replace("/Upload", "http://image.istyle24.com/Local")
+						.replace("http://www.istyle24.com/Images", "http://image.istyle24.com/Statics/design/Images");
+
+				htmlDesc = descStr;
+
+			}else {
+
+				// 1) 상세내용 - 상품설명
+				htmlDesc = "<div class='st_descrp_box' style='max-height:1100px; overflow:hidden;'>";
+				htmlDesc += "<div class='st_desc_simple' style='position:relative; margin-top:0px; margin-left:auto; margin-right:auto;'>";
+				htmlDesc += "<span class='st_tit_desc' style='display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;'>"+goodsMap.getDetailDescNew10()+"</span>";
+				htmlDesc += "<p class='st_ptxt01' style='font-size:16px;font-weight:200;line-height:1.5;word-break:keep-all;color:#666666;'>";
+				htmlDesc += goodsMap.getDetailDescNew20();
+				htmlDesc += "</p>";
+				htmlDesc += "</div>";
+				htmlDesc += "<div class='st_desc_character' style='position:relative; margin-top:40px; margin-left:auto; margin-right:auto;'>";
+				htmlDesc += "<span class='st_tit_desc' style='display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;'>상품특징</span>";
+				htmlDesc += "<p class='st_ptxt01' style='font-size:16px;font-weight:200;line-height:1.5;word-break:keep-all;color:#666666;'>";
+				htmlDesc += goodsMap.getDetailDescNew30();
+		        htmlDesc += "</p>";
+        		htmlDesc += "</div>";
+				htmlDesc += "</div>";
+
+				// 2) 상세내용 - 상품옵션별 색상
+				String colorDesc = "";
+				shoplinkerGoods.setColorListYn("Y"); // 상품이미지정보 색상별
+				Collection<ShoplinkerGoods> imgColorList = admShoplinkerDao.getGoodsImageList(shoplinkerGoods);
+				colorDesc = "<div class='st_view_option_box' style='margin-top: 100px;text-align: center;'>";
+				String tmpColor = "";
+				for(ShoplinkerGoods ic : imgColorList ) {
+
+					if( !tmpColor.equals(ic.getColorCd())) {
+						colorDesc += "<span class='st_tit_desc' style='display:block; margin-bottom:10px; font-size:18px; font-weight:500; letter-spacing:-0.025em;'>컬러 : ";
+						colorDesc += "<span>"+ ic.getColorKnm() +"</span></span>";
+					}
+					colorDesc += "<div class='st_view' style='margin-top: 40px;'>";
+					colorDesc += "<img src='"+ imgPath+"/"+ic.getSysImgNm()+"' alt='' style='max-width:100%;margin: 10px auto 0;margin-top: 0;display: block;'>";
+					colorDesc += "<img src='"+ imgPath+"/"+ic.getSysImgNm()+"' alt='' style='max-width:100%;display: block;margin: 10px auto 0;'>";
+	                colorDesc += "</div>";
+		            if( !tmpColor.equals(ic.getColorCd())) {
+		            	colorDesc += "<div style='height:100px;'></div>";
+		            	tmpColor = ic.getColorCd();
+					}
+				}
+				colorDesc += "</div>";
+				htmlDesc += colorDesc;
+
+				// 3) 상세내용 - 모델 착용컷
+				String dtlDesc = "";
+				dtlDesc += "<div class='st_view_outfit_box' style='margin-top: 100px;text-align: center;'>";
+				dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>OUTFIT VIEW</span>";
+				dtlDesc += "<span class='st_model_info' style='display: block;margin-top: 20px;color: #666;font-size: 16px;font-weight: 200;text-align: center;'>"+goodsMap.getModelInfo()+"</span>";
+				dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+				for(String img : dImgModelList) {
+					dtlDesc += "<img src='"+ img +"' alt='' style='display: block;margin: 10px auto 0;'>";
+				}
+				dtlDesc += "</div>";
+				dtlDesc += "</div>";
+
+				// 4) 상세내용 - 상품컷
+				dtlDesc += "<div class='st_view_detail_box' style='margin-top: 100px;text-align: center;'>";
+				dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>PRODUCT VIEW</span>";
+				dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+				for(String img : dImgDetailList) {
+					dtlDesc += "<img src='"+ img +"' alt='' style='display: block;margin: 10px auto 0;'>";
+				}
+                dtlDesc += "</div>";
+        		dtlDesc += " </div>";
+
+        		// 5) 상세내용 - 원단
+        		dtlDesc += "<div class='st_view_fabric_box' style='margin-top: 100px;text-align: center;'>";
+        		dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>FABRIC</span>";
+        		dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+        		dtlDesc += "<img src='"+dMaterial +"' alt='' style='display: block;margin: 10px auto 0;margin-top: 0;'>";
+                dtlDesc += "</div>";
+                dtlDesc += "</div>";
+
+                // 6) 상세내용 - 라벨
+                dtlDesc += "<div class='st_view_label_box' style='margin-top: 100px;text-align: center;'>";
+                dtlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>LABEL INFO</span>";
+                dtlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+                dtlDesc += "<span style='display:inline-block;'>";
+                for(String img : dLabelList) {
+					dtlDesc += "<img src='"+ img +"' alt='' style='float:left; margin-top:0; margin-left:20px;'>";
+				}
+                dtlDesc += "</span>";
+                dtlDesc += "</div>";
+                dtlDesc += "</div>";
+                htmlDesc += dtlDesc;
+
+                // 7) 상세내용 - 사이즈
+                Collection<ShoplinkerGoods> sizeList = admShoplinkerDao.getGoodsSizeList(shoplinkerGoods);
+                if (sizeList == null || sizeList.isEmpty()) {
+                	//대표상품 실측정사이즈표 없을경우 > 브랜드 별 표준 이미지
+                	htmlDesc += "<div class='st_view_size_box' style='margin-top: 100px;text-align: center;'>";
+                	htmlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>사이즈정보</span>";
+                	htmlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+
+                	String brandSizeImg = env.getProperty("upload.image.view") + "/Upload/brandSizeImg/";
+                	if( "Y".equals(goodsMap.getKidsYn())){
+                		brandSizeImg += "kids/"+goodsMap.getBrandEnm() +".jpg";
+                		htmlDesc += "<img src='"+ brandSizeImg +"' alt='ANDEW 표준 사이즈' style='display: block;margin: 10px auto 0;'>";
+                	}else {
+                		brandSizeImg += "casuals/"+goodsMap.getBrandEnm() +".jpg";
+                		htmlDesc += "<img src='"+ brandSizeImg +"' alt='ANDEW 표준 사이즈' style='display: block;margin: 10px auto 0;'>";
+                	}
+                    htmlDesc += "</div>";
+                    htmlDesc += "</div>";
+
+                }else {
+
+                	htmlDesc += "<div class='st_view_size_box' style='margin-top: 100px;text-align: center;'>";
+                	htmlDesc += "<span class='st_tit_view' style='display: block;color: #222;font-size: 32px;font-weight: 300;text-align: center;'>사이즈정보</span>";
+                	htmlDesc += "<div class='st_view' style='margin-top: 40px;'>";
+
+                	htmlDesc += "<div class='st_tbl' style='padding:0; border-top:1px solid #000;'>";
+                	htmlDesc += "<table style='margin:0;padding:0;border-collapse:collapse;border-spacing:0;width:100%;border-top:1px solid #000;word-break:keep-all;'>";
+                	htmlDesc += "<thead style=''>";
+                	htmlDesc += "<tr style=''>";
+
+                	int cnt = 0;
+                	for(ShoplinkerGoods size : sizeList) {
+
+                		if( 0 == cnt ) {
+                			if( "하의".equals(size.getSizeTypecd())) {
+                				htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'></th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>허리둘레(cm)</th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>밑위(cm)</th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>엉덩이둘레(cm)</th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>허벅지둘레(cm)</th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>총길이(cm)</th>";
+                			}else {
+                				htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'></th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>가슴둘레(cm)</th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>어깨너비(cm)</th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>팔길이(cm)</th>";
+        	                	htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>총길이(cm)</th>";
+                			}
+                			htmlDesc += "</tr>";
+    	                	htmlDesc += "</thead>";
+    	                	htmlDesc += "<tbody style=''>";
+                		}
+
+                		htmlDesc += "<tr style=''>";
+                		htmlDesc += "<th style='position:relative;padding:20px 0;border-bottom:1px solid #ddd;font-weight:500;font-size:16px;letter-spacing:-0.025em;text-align:center;'>"+ size.getOptCd2() +"</th>";
+        				htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue1() +"</td>";
+						htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue2() +"</td>";
+						htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue3() +"</td>";
+						htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue4() +"</td>";
+						if( "하의".equals(size.getSizeTypecd())) {
+							htmlDesc += "<td style='position:relative; padding:20px 0; border-bottom:1px solid #ddd; font-weight:200; font-size:16px; letter-spacing:-0.025em; text-align:center;'>"+ size.getSizeValue5() +"</td>";
+						}
+                		cnt ++;
+                	}
+
+                	htmlDesc += "</tbody>";
+                	htmlDesc += "</table>";
+        			htmlDesc += "</div>";
+					htmlDesc += "</div>";
+					htmlDesc += " </div>";
+                }
+
+
+                // 8) 상세내용 - 상품필수정보
+                ShoplinkerGoods certInfo = admShoplinkerDao.getCert(shoplinkerGoods);
+                if( null != certInfo) {
+                	if( "G083_1".equals(certInfo.getCertTargetGb())) {	// 인증대상
+
+                		if( "".equals(certInfo.getCertNum())) {
+
+                			htmlDesc += "<div class='st_required_box' style='margin-bottom:80px;'>";
+                			htmlDesc += "<div class='st_area_kcl' style='color:#222;display:block; position:relative; min-height:160px; margin-top:100px; padding:40px 40px 40px 160px; box-sizing:border-box; background:#f5f5f5;'>";
+                			htmlDesc += "<i class='st_ico_kcl' style='position:absolute;left:64px;top:50%;transform:translateY(-50%);z-index:2;background-image: url(/images/pc/ico_kcl.png);width: 32px;height: 50px;display: inline-block;vertical-align: middle;background-repeat: no-repeat;background-size: contain;background-position: 0% 0%;'></i>";
+                			htmlDesc += "<p class='st_tit' style='margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                			htmlDesc += certInfo.getCertTargetNm() +"/"+ certInfo.getCertOrganName();
+                            htmlDesc += "</p>";
+                            htmlDesc += "<p style='margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;'>";
+                        	htmlDesc += certInfo.getCertDiv();
+                        	htmlDesc += "</p>";
+                            htmlDesc += "<p class='st_dot_info' style='color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                            htmlDesc += "<span style='color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;'></span>";
+                            htmlDesc += "해당 인증정보는 판매자가 등록한 것으로 등록정보에 대한 일체의 책임은 판매자에게 있습니다.";
+                            htmlDesc += "</p>";
+                            htmlDesc += "</div>";
+                            htmlDesc += "</div>";
+                		}else {
+                			htmlDesc += "<div class='st_required_box' style='margin-bottom:80px;'>";
+                			htmlDesc += "<div class='st_area_kcl' style='display:block; position:relative; min-height:160px; margin-top:100px; padding:40px 40px 40px 160px; box-sizing:border-box; background:#f5f5f5;'>";
+                			htmlDesc += "<i class='st_ico_kcl' style='position:absolute;left:64px;top:50%;transform:translateY(-50%);z-index:2;background-image: url(/images/pc/ico_kcl.png);width: 32px;height: 50px;display: inline-block;vertical-align: middle;background-repeat: no-repeat;background-size: contain;background-position: 0% 0%;'></i>";
+                			htmlDesc += "<p class='st_tit' style='margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                			htmlDesc += certInfo.getCertDiv() +"/"+ certInfo.getCertOrganName();
+                            htmlDesc += "</p>";
+                            htmlDesc += "<p style='margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;'>";
+                            htmlDesc += "인증번호: "+ certInfo.getCertNum();
+                            htmlDesc += "<a href='http://www.safetykorea.kr/search/searchPop?certNum=XX00000-0000' target='_blank' class='st_linktxt3' style='margin-left:20px; color:#888; font-weight:200; text-decoration:none !important;'>상세보기</a>";
+                            htmlDesc += "</p>";
+                            htmlDesc += "<p class='st_dot_info' style='color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                            htmlDesc += "<span style='color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;'></span>";
+                            htmlDesc += "해당 인증정보는 판매자가 등록한 것으로 등록정보에 대한 일체의 책임은 판매자에게 있습니다.";
+                            htmlDesc += "</p>";
+                            htmlDesc += "</div>";
+                            htmlDesc += "</div>";
+                		}
+
+                	}else if( "G083_3".equals(certInfo.getCertTargetGb())) {	// 상세설명별도표기
+                		htmlDesc += "<div class='st_required_box' style='margin-bottom:80px;'>";
+                		htmlDesc += "<div class='st_area_kcl st_no-mark' style='display:block;position:relative;min-height:160px;margin-top:100px;padding:40px 40px 40px 160px;box-sizing:border-box;background:#f5f5f5;padding-left:65px;'>";
+                		htmlDesc += "<p class='st_tit' style='margin-top:0;color:#222;font-size:16px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                		htmlDesc += certInfo.getCertTargetNm();
+                        htmlDesc += "</p>";
+                        htmlDesc += "<p style='margin-top:20px; color:#222; font-size:13px; font-weight: 300; line-height:1; letter-spacing:-0.025em;'>";
+                        htmlDesc += "제품 상세정보 내 표기되어 있습니다. 상품 정보를 확인해주세요.";
+                        htmlDesc += "</p>";
+                        htmlDesc += "<p class='st_dot_info' style='color: #888888;position:relative;margin-top:20px;font-size:13px;font-weight:300;line-height:1;letter-spacing:-0.025em;'>";
+                        htmlDesc += "<span style='color: #888888 !important;background: #888888 !important;display: inline-block;width: 2px;height: 2px;position: relative;top: -4px;left: 0px;margin-right: 4px;'></span>";
+                        htmlDesc += "해당 인증정보는 판매자가 등록한 것으로 등록정보에 대한 일체의 책임은 판매자에게 있습니다.";
+                        htmlDesc += "</p>";
+                        htmlDesc += "</div>";
+                        htmlDesc += "</div>";
+                	}else {
+                		// G083_2 - 인증대상아님
+                	}
+                }
+			}
+		}
+		return htmlDesc;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 3. 품목(고시)정보
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	private int createGoodsNotiRegisterXml(ShoplinkerGoods shoplinkerGoods) throws IOException {
+
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+		regMap.setApiType("NOTI");
+		regMap.setApiSubUrl(env.getProperty("shoplinker.url.good_noti"));
+		regMap.setGoodsCd(shoplinkerGoods.getGoodsCd());
+		regMap.setRegNo(shoplinkerGoods.getRegNo());
+		regMap.setXmlPath(shoplinkerGoods.getXmlPath());
+		regMap.setDomainUrl(shoplinkerGoods.getDomainUrl());
+
+		int succCnt = 0;
+
+		try {
+
+			Collection<ShoplinkerGoods> list = admShoplinkerDao.getGoodsNotiList(shoplinkerGoods);
+
+			if(null != list ) {
+				if( 0 < list.size()) {
+
+					// xml 데이터 세팅
+					StringBuilder sbRequest = new StringBuilder();
+					sbRequest.append("<?xml version=\"1.0\" encoding=\"euc-kr\"?>\n");
+					sbRequest.append("<openMarket>\n");
+					sbRequest.append("	<goodsinfo>\n");
+
+					sbRequest.append("		<customer_id>").append(shoplinkerGoods.getCustomerId()).append("</customer_id>\n");
+					sbRequest.append("		<product_id />\n");
+
+					int cnt = 0;
+					for (ShoplinkerGoods map : list) {
+						if( 0 == cnt) {
+							sbRequest.append("		<partner_product_id>").append(map.getPartnerProductId()).append("</partner_product_id>\n");
+							sbRequest.append("		<lclass_id>").append(map.getLclassId()).append("</lclass_id>\n");
+						}
+						cnt ++;
+
+						sbRequest.append("		<item>\n");
+						sbRequest.append("			<item_seq>").append(map.getItemSeq()).append("</item_seq>\n");
+						sbRequest.append("			<item_info><![CDATA[").append(map.getItemInfo()).append("]]></item_info>\n");
+						sbRequest.append("		</item>\n");
+					}
+
+					sbRequest.append("	</goodsinfo>\n");
+					sbRequest.append("</openMarket>\n");
+
+					// api 호출 및 결과 history 저장
+					succCnt = callGoodsRegApi(regMap , sbRequest, "goods");
+				}
+			}
+
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			regMap.setApiResult("error");
+			regMap.setApiMessage("xml 생성오류");
+			tscShoplinkerDao.insertShoplinerApiHst(regMap);
+		}
+		return succCnt;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 4. 인증정보
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	private int createCertRegisterXml(ShoplinkerGoods shoplinkerGoods) throws IOException {
+
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+		regMap.setApiType("CERT");
+		regMap.setApiSubUrl(env.getProperty("shoplinker.url.cert"));
+		regMap.setGoodsCd(shoplinkerGoods.getGoodsCd());
+		regMap.setRegNo(shoplinkerGoods.getRegNo());
+		regMap.setXmlPath(shoplinkerGoods.getXmlPath());
+		regMap.setDomainUrl(shoplinkerGoods.getDomainUrl());
+
+		int succCnt = 0;
+
+		try {
+
+			ShoplinkerGoods map = admShoplinkerDao.getCert(shoplinkerGoods);
+
+			if(null == map ) {
+				map = new ShoplinkerGoods();
+				map.setPartnerProductId(shoplinkerGoods.getGoodsCd());
+				map.setCertNo("");
+				map.setCertOrgan(".");
+			}
+
+			// xml 데이터 세팅
+			StringBuilder sbRequest = new StringBuilder();
+			sbRequest.append("<?xml version=\"1.0\" encoding=\"euc-kr\"?>\n");
+			sbRequest.append("<shoplinker>\n");
+			sbRequest.append("	<product>\n");
+
+			sbRequest.append("		<customer_id>").append(shoplinkerGoods.getCustomerId()).append("</customer_id>\n");
+			sbRequest.append("		<partner_product_id>").append(map.getPartnerProductId()).append("</partner_product_id>\n");
+			sbRequest.append("		<certinfo>\n");
+			sbRequest.append("			<cert>\n");
+
+			//cert_item 의 경우 인증코드 값이 있으면 'C011', 없으면 'C010'
+			if("".equals(map.getCertNo())){
+				sbRequest.append("				<cert_item>").append("C010").append("</cert_item>\n");
+			}else {
+				sbRequest.append("				<cert_item>").append("C011").append("</cert_item>\n");
+			}
+
+			sbRequest.append("				<cert_organ><![CDATA[").append(map.getCertOrgan()).append("]]></cert_organ>\n");
+			sbRequest.append("				<cert_no><![CDATA[").append(map.getCertNo()).append("]]></cert_no>\n");
+			sbRequest.append("			</cert>\n");
+			sbRequest.append("		</certinfo>\n");
+			sbRequest.append("	</product>\n");
+			sbRequest.append("</shoplinker>\n");
+
+			// api 호출 및 결과 history 저장
+			succCnt = callGoodsRegApi(regMap , sbRequest, "cert");
+
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			regMap.setApiResult("error");
+			regMap.setApiMessage("xml 생성오류");
+			tscShoplinkerDao.insertShoplinerApiHst(regMap);
+		}
+
+		return succCnt;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 5. 상품이미지정보
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	private int createImageRegisterXml(ShoplinkerGoods shoplinkerGoods) throws IOException {
+
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+		regMap.setApiType("IMAGE");
+		regMap.setApiSubUrl(env.getProperty("shoplinker.url.image"));
+		regMap.setGoodsCd(shoplinkerGoods.getGoodsCd());
+		regMap.setRegNo(shoplinkerGoods.getRegNo());
+		regMap.setXmlPath(shoplinkerGoods.getXmlPath());
+		regMap.setDomainUrl(shoplinkerGoods.getDomainUrl());
+
+		int succCnt = 0;
+
+		try {
+
+			// 상품이미지정보
+			shoplinkerGoods.setExtmallImgYn("Y");
+			Collection<ShoplinkerGoods> list = admShoplinkerDao.getGoodsImageList(shoplinkerGoods);
+
+			if(null != list) {
+
+				String imgUrl = "";
+				for (ShoplinkerGoods map : list) {
+					imgUrl = map.getSysImgNm();
+					// extmall_yn 이미지를 가져오되, 없는 경우 default 이미지를 가져온다.
+					if( "Y".equals(map.getExtmallImgYn()) && !"".equals(map.getSysImgNm())){
+						break;
+					}
+				}
+
+				// xml 데이터 세팅
+				StringBuilder sbRequest = new StringBuilder();
+				sbRequest.append("<?xml version=\"1.0\" encoding=\"euc-kr\"?>\n");
+				sbRequest.append("<Shoplinker>\n");
+				sbRequest.append("	<product>\n");
+
+				sbRequest.append("		<customer_id>").append(shoplinkerGoods.getCustomerId()).append("</customer_id>\n");
+				sbRequest.append("		<partner_product_id>").append(shoplinkerGoods.getGoodsCd()).append("</partner_product_id>\n");
+				sbRequest.append("		<image_type><![CDATA[").append("URL").append("]]></image_type>\n");
+				sbRequest.append("		<image_info>\n");
+				sbRequest.append("			<image>\n");
+				sbRequest.append("				<image_kind><![CDATA[").append("IMG1").append("]]></image_kind>\n");
+
+				String img_url = env.getProperty("upload.goods.view");
+				if( img_url.toLowerCase().indexOf("http") < 0) {
+					img_url = img_url.replace("//image", "http://image");
+				}
+				sbRequest.append("				<image_content>").append(img_url+"/"+imgUrl).append("</image_content>\n");
+				sbRequest.append("			</image>\n");
+				sbRequest.append("		</image_info>\n");
+
+				sbRequest.append("	</product>\n");
+				sbRequest.append("</Shoplinker>\n");
+
+				// api 호출 및 결과 history 저장
+				succCnt = callGoodsRegApi(regMap , sbRequest, "image");
+			}
+
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			regMap.setApiResult("error");
+			regMap.setApiMessage("xml 생성오류");
+			tscShoplinkerDao.insertShoplinerApiHst(regMap);
+		}
+
+		return succCnt;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 공통 api 호출 & 결과 확인
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	private int callGoodsRegApi(ShoplinkerGoods map, StringBuilder sbRequest, String fileNm) throws IOException {
+
+		int succCnt = 0;
+		com.gagaframework.shoplinker.domain.goods.result.Shoplinker shoplinkerResult;
+		com.gagaframework.shoplinker.domain.goods.result.ResultMessage resultMsg;
+
+		StringBuilder xmlFileName = new StringBuilder();
+
+		try {
+			GagaShoplinkertUtil shoplinkerUtil = new GagaShoplinkertUtil("MS949");
+
+			// XML 파일 생성
+			xmlFileName = new StringBuilder();
+			xmlFileName.append(fileNm+"_"+fileAddNm).append(".xml");
+			String xmlPath = GagaFileUtil.getConcatenationPath(map.getXmlPath(), xmlFileName.toString());
+			shoplinkerUtil.makeRequestXmlFile(sbRequest.toString(), xmlPath);
+			String xmlUrl = GagaFileUtil.getConcatenationPath(map.getDomainUrl(), xmlFileName.toString());
+
+			// API 호출 URL
+			String apiUrl = GagaShoplinkerConstants.API_DOMAIN + map.getApiSubUrl() + URLEncoder.encode(xmlUrl);
+
+			// API 호출결과
+			String responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(apiUrl, "");
+
+			// response 결과
+			shoplinkerResult = (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+
+			String slFolder = GagaFileUtil.getConcatenationPath(env.getProperty("shoplinker.xml.path"));
+			File slPath = new File(slFolder);
+
+			map.setXmlTxt(slPath.exists()+"\n"+xmlPath+"\n"+xmlUrl+"\n\n"+sbRequest.toString());
+			map.setApiProductId(resultMsg.getProductId());
+			map.setApiResult(resultMsg.getResult());
+			map.setApiMessage(resultMsg.getMessage());
+
+			if( "true".equals(resultMsg.getResult())){
+				succCnt = 1;
+
+				// 재고 단품 생성
+				if( "OPTION".equals(map.getApiType())) {
+					admShoplinkerDao.insertStockOption(map);
+				}
+			}
+
+		} catch (Exception e) {
+			log.error("error", e);
+			map.setXmlTxt(sbRequest.toString());
+			map.setApiResult("error");
+			map.setApiMessage("API 통신오류");
+		}
+
+		// 생성 파일삭제
+		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(map.getXmlPath(), xmlFileName.toString()));
+
+		// 전송이력 저장
+		tscShoplinkerDao.insertShoplinerApiHst(map);
+
+		return succCnt;
+	}
+
+	/**
+	 * 상품등록-상품 목록 건수
+	 *
+	 * @param getGoodsSendListCount
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getGoodsSendListCount(ShoplinkerSearch shoplinkerSearch) {
+		return admShoplinkerDao.getGoodsSendListCount(shoplinkerSearch);
+	}
+
+	/**
+	 * 상품등록-상품 목록
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerGoods> getGoodsSendList(ShoplinkerSearch shoplinkerSearch) {
+		return admShoplinkerDao.getGoodsSendList(shoplinkerSearch);
+	}
+
+	/**
+	 * 상품등록-상품 목록 엑셀다운로드
+	 *
+	 * @param shoplinkerSearch
+	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	public void getGoodsSendExcelList(ShoplinkerSearch shoplinkerSearch, String excelFilenameWithPath) {
+
+		// 헤더 title 설정
+		String[] listTitles = {"샵링커상품코드", "API구분", "IF결과", "IF결과메세지", "자사상품코드", "자사옵션코드", "등록자", "전송일자"};
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellNames = {"API_PRODUCT_ID", "API_TYPE", "API_RESULT", "API_MESSAGE", "GOODS_CD", "OPT_CD", "REG_NM", "REG_DT"};
+
+		String[] cellTypes = {
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name()};
+
+		Collection<GagaMap> dataList = admShoplinkerDao.getGoodsSendExcelList(shoplinkerSearch);
+
+		try {
+
+			GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "샵링커 상품 정보", listTitles, cellNames, cellTypes, TsaConstants.EXCEL_FOOTER_TITLE);
+
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+
+	/**
+	 * 재고전송-목록 건수
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getStockListCount(ShoplinkerSearch shoplinkerSearch) {
+		return admShoplinkerDao.getStockListCount(shoplinkerSearch);
+	}
+
+	/**
+	 * 재고전송-목록
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerGoods> getStockList(ShoplinkerSearch shoplinkerSearch) {
+		return admShoplinkerDao.getStockList(shoplinkerSearch);
+	}
+
+	/**
+	 * 재고전송-목록 엑셀다운로드
+	 *
+	 * @param shoplinkerSearch
+	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	public void getStockExcelList(ShoplinkerSearch shoplinkerSearch, String excelFilenameWithPath) {
+
+		// 헤더 title 설정
+		String[] listTitles = {"IF결과", "IF결과메세지", "상품코드", "상품명", "옵션코드", "옵션1", "옵션2", "재고", "전송일자"};
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellNames = {"API_RESULT", "API_MESSAGE", "GOODS_CD", "GOODS_NM", "OPT_CD", "OPT_CD1", "OPT_CD2", "QUANTITY", "REG_DT"};
+
+		String[] cellTypes = {
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_LEFT.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_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name()};
+
+		Collection<GagaMap> dataList = admShoplinkerDao.getStockExcelList(shoplinkerSearch);
+
+		try {
+
+			GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "샵링커 재고 정보", listTitles, cellNames, cellTypes, TsaConstants.EXCEL_FOOTER_TITLE);
+
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	/**
+	 * 샵링커주문수집-목록 건수
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getShoplinkerOrderListCount(ShoplinkerOrder shoplinkerOrder) {
+		return admShoplinkerDao.getShoplinkerOrderListCount(shoplinkerOrder);
+	}
+
+	/**
+	 * 샵링커주문수집-목록
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerOrder> getShoplinkerOrderList(ShoplinkerOrder shoplinkerOrder) {
+		return admShoplinkerDao.getShoplinkerOrderList(shoplinkerOrder);
+	}
+
+	/**
+	 * 샵링커주문수집-상세
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 28
+	 */
+	public ShoplinkerOrder getShoplinkerOrderInfo(ShoplinkerOrder shoplinkerOrder) {
+		return admShoplinkerDao.getShoplinkerOrderInfo(shoplinkerOrder);
+	}
+
+	/**
+	 * 샵링커주문수집-제휴몰 주문수집 상세
+	 *
+	 * @param extmallOrder
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 28
+	 */
+	public ExtmallOrder getExtmallOrderInfo(String extmallOrder) {
+		return admShoplinkerDao.getExtmallOrderInfo(extmallOrder);
+	}
+
+	/**
+	 * 주문수집-목록 엑셀다운로드
+	 *
+	 * @param shoplinkerOrder
+	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	public void getOrderExcelList(ShoplinkerOrder shoplinkerOrder, String excelFilenameWithPath) {
+
+		// 헤더 title 설정
+		String[] listTitles = { "제휴몰주문등록상태", "실패사유", "업로드실패사유", "스타일24 주문번호", "샵링커 주문번호", "쇼핑몰 주문번호", "쇼핑몰 명", "배송상태[발주확인]"
+				,"주문 상품번호", "샵링커 상품번호", "자사 상품코드", "상품명", "주문수량", "주문금액", "판매단가", "공급가", "옵션명", "주문수집일자", "제휴몰등록일"};
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellNames = {"UPLOAD_STAT", "UPLOAD_FAIL_CD", "UPLOAD_FAIL_REASON", "ORD_NO", "SHOPLINKER_ORDER_ID", "EXTMALL_ORDER_ID", "MALL_NAME", "BAESONG_STATUS"
+				, "ORDER_PRODUCT_ID", "SHOPLINKER_PRODUCT_ID", "PARTNER_PRODUCT_ID", "PRODUCT_NAME", "QUANTITY", "ORDER_PRICE", "SALE_PRICE", "SUPPLY_PRICE", "SKU", "ORDER_REG_DATE", "EXTMALL_REG_DT"};
+
+		String[] cellTypes = {
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
+			GagaExcelConstants.CellType.CHAR_LEFT.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_LEFT.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()};
+
+		Collection<GagaMap> dataList = admShoplinkerDao.getOrderExcelList(shoplinkerOrder);
+
+		try {
+
+			GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "샵링커 주문 정보", listTitles, cellNames, cellTypes, TsaConstants.EXCEL_FOOTER_TITLE);
+
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	/**
+	 * 송장전송-전송 (엑셀용)
+	 *
+	 * @param shoplinkerInvoice
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	/*********************************************************************************************
+	public void createShoplinkerInvoiceXml(Collection<GagaMap> ecxelGoodsList, ShoplinkerInvoice shoplinkerInvoice) throws IOException {
+		// 파일명 뒤에 붙일 시간
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
+		fileAddNm = sdf.format(cal.getTime());
+
+		ShoplinkerGoods apiHstMap = new ShoplinkerGoods();
+
+		GagaMap returnMap = new GagaMap();
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+		regMap.setApiType("INVOICE");
+		regMap.setApiSubUrl(env.getProperty("shoplinker.url.invoice"));
+		regMap.setRegNo(shoplinkerInvoice.getRegNo());
+		regMap.setXmlPath(shoplinkerInvoice.getXmlPath());
+		regMap.setDomainUrl(shoplinkerInvoice.getDomainUrl());
+
+		StringBuilder sbRequest;
+		com.gagaframework.shoplinker.domain.invoice.ResultMessage resultMsg_tmp;
+
+		for (GagaMap gagaMap : ecxelGoodsList) {
+			if( !"".equals(gagaMap.getString("ordNo").trim())) {
+				shoplinkerInvoice.setOrdNo(gagaMap.getInt("ordNo"));
+
+				Collection<ShoplinkerInvoice> list = shoplinkerDao.getShoplinkerInvoiceOrdDtlSendList(shoplinkerInvoice);
+				for(ShoplinkerInvoice info : list) {
+					apiHstMap = new ShoplinkerGoods();
+
+					// xml 데이터 세팅
+					sbRequest = new StringBuilder();
+					sbRequest.append("<?xml version=\"1.0\" encoding=\"euc-kr\"?>\n");
+					sbRequest.append("<Shoplinker>\n");
+					sbRequest.append("	<Delivery>\n");
+
+					sbRequest.append("		<customer_id>").append(shoplinkerInvoice.getCustomerId()).append("</customer_id>\n");
+					sbRequest.append("		<order_id>").append(info.getAgentOrderId()).append("</order_id>\n");
+					sbRequest.append("		<delivery_name><![CDATA[").append(info.getDeliveryName()).append("]]></delivery_name>\n");
+					sbRequest.append("		<delivery_invoice><![CDATA[").append(info.getDeliveryInvoice()).append("]]></delivery_invoice>\n");
+
+					sbRequest.append("	</Delivery>\n");
+					sbRequest.append("</Shoplinker>\n");
+
+					// api 호출 및 결과 history 저장
+					try {
+
+						GagaShoplinkertUtil shoplinkerUtil = new GagaShoplinkertUtil("MS949");
+
+						// XML 파일 생성
+						StringBuilder xmlFileName = new StringBuilder();
+						xmlFileName.append("invoice_"+info.getOrdDtlNo()+"_"+fileAddNm).append(".xml");
+						String xmlPath = GagaFileUtil.getConcatenationPath(shoplinkerInvoice.getXmlPath(), xmlFileName.toString());
+						shoplinkerUtil.makeRequestXmlFile(sbRequest.toString(), xmlPath);
+						String xmlUrl = GagaFileUtil.getConcatenationPath(shoplinkerInvoice.getDomainUrl(), xmlFileName.toString());
+
+						// API 호출
+						xmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/invoice.xml";
+						String apiUrl = GagaShoplinkerConstants.API_DOMAIN + regMap.getApiSubUrl() + URLEncoder.encode(xmlUrl);
+						String responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(apiUrl, "");
+
+						log.info(shoplinkerInvoice.getApiType()+" ####xmlUrl "+xmlUrl);
+						log.info(shoplinkerInvoice.getApiType()+" ####apiUrl "+apiUrl);
+
+						// response 결과
+						com.style24.admin.support.util.ResultMessage22 resultMsg;
+						resultMsg = (com.style24.admin.support.util.ResultMessage22)shoplinkerUtil.unmarshal(com.style24.admin.support.util.ResultMessage22.class, responseXmlData);
+						System.out.println(" ##### invoice2 : "+resultMsg);
+						System.out.println(" ##### invoice3 : "+resultMsg.getResult());
+						System.out.println(" ##### invoice4 : "+resultMsg.getMessage());
+						System.out.println(" ##### invoice5 : "+resultMsg.getId());
+
+						//resultMsg = (com.gagaframework.shoplinker.domain.invoice.ResultMessage)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.invoice.ResultMessage.class, responseXmlData);
+						apiHstMap.setApiType("INVOICE");
+						apiHstMap.setXmlTxt(sbRequest.toString());
+						apiHstMap.setOrdDtlNo(info.getOrdDtlNo());
+						apiHstMap.setApiResult(resultMsg.getResult());
+						apiHstMap.setApiMessage(resultMsg.getMessage());
+
+						// 생성 파일삭제
+						GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(shoplinkerInvoice.getXmlPath(), xmlFileName.toString()));
+
+					} catch (Exception e) {
+						log.error("error", e);
+						apiHstMap.setApiType("INVOICE");
+						apiHstMap.setXmlTxt(sbRequest.toString());
+						apiHstMap.setOrdDtlNo(info.getOrdDtlNo());
+						apiHstMap.setApiResult("error");
+						apiHstMap.setApiMessage("API 통신오류");
+					}
+
+					// 전송이력 저장
+					shoplinkerDao.insertShoplinerApiHst(apiHstMap);
+				}
+			}
+		}
+	}
+	*******************************************************************************************/
+
+	/**
+	 * 송장전송-목록 건수
+	 *
+	 * @param shoplinkerInvoice
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getSendInvoiceListCount(ShoplinkerInvoice shoplinkerInvoice) {
+		return admShoplinkerDao.getSendInvoiceListCount(shoplinkerInvoice);
+	}
+
+	/**
+	 * 송장전송-목록
+	 *
+	 * @param shoplinkerInvoice
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerInvoice> getSendInvoiceList(ShoplinkerInvoice shoplinkerInvoice) {
+		return admShoplinkerDao.getSendInvoiceList(shoplinkerInvoice);
+	}
+
+	/**
+	 * 송장전송-목록 엑셀다운로드
+	 *
+	 * @param shoplinkerInvoice
+	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	public void getInvoiceExcelList(ShoplinkerInvoice shoplinkerInvoice, String excelFilenameWithPath) {
+
+		// 헤더 title 설정
+		String[] listTitles = {"IF결과", "IF결과메세지", "샵링커 주문번호", "쇼핑몰 주문번호", "스타일24 주문번호", "주문상세번호", "배송업체", "송장번호", "전송일시"};
+
+		// DB 처리 시 사용되는 파라미터명(셀명) 설정
+		String[] cellNames = {"API_RESULT", "API_MESSAGE", "AGENT_ORDER_ID", "EXTMALL_ORDER_ID", "ORD_NO", "ORD_DTL_NO", "SHIP_COMP_NM", "DELIVERY_INVOICE", "REG_DT"};
+
+		String[] cellTypes = {
+			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_LEFT.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_LEFT.name(),
+			GagaExcelConstants.CellType.CHAR_CENTER.name()};
+
+		Collection<GagaMap> dataList = admShoplinkerDao.getInvoiceExcelList(shoplinkerInvoice);
+
+		try {
+
+			GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "샵링커 송장 정보", listTitles, cellNames, cellTypes, TsaConstants.EXCEL_FOOTER_TITLE);
+
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+
+}

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

@@ -1049,5 +1049,36 @@ public class TsaCustomerController extends TsaBaseController {
 		return result;
 	}
 
+	/**
+	 * 탈퇴이력 삭제
+	 *
+	 * @param  customerCollection - 탈퇴이력 삭제
+	 * @return GagaMap - 결과
+	 * @author jsshin
+	 * @since 2020. 01. 14
+	 */
+	@PostMapping("/secede/delete")
+	@ResponseBody
+	public GagaMap deleteSecedCustomer(@RequestBody Collection<Customer> customerCollection) {
+		GagaMap result = new GagaMap();
+		int totalCnt = customerCollection.size();
+		int succCnt = 0;
+		int failCnt = 0;
+		for (Customer customer : customerCollection) {
+			try {
+				customerService.deleteSecedeCustomer(customer.getCustNo());
+				succCnt ++;
+			} catch (Exception e) {
+				log.error(e.getMessage());
+				failCnt ++;
+			}
+		}
+		result.setInt("totalCnt", totalCnt);
+		result.setInt("succCnt", succCnt);
+		result.setInt("failCnt", failCnt);
+
+		return result;
+	}
+
 
 }

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

@@ -282,7 +282,7 @@ public class TsaOcmController extends TsaBaseController {
 		// 외부몰주문등록
 		if ("createExtmallOrder".equals(extmallOrder.getProcJob())) {
 			// DB 처리 시 사용되는 파라미터명(셀명) 설정
-			String[] extMallOrderNames = {"ordDt", "extmallId", "extmallOrderId", "agentOrderId", "extmallProdId", "goodsCd", "sku", "optCd", "currPrice", "cpnDcAmt", "ordQty", "delvFee", "ordNm", "ordTelno", "ordPhnno", "ordEmail", "recipNm", "recipTelno", "recipPhnno", "recipZipcode", "recipBaseAddr", "recipDtlAddr", "delvMemo"};
+			String[] extMallOrderNames = {"ordDt", "extmallId", "extmallOrderId", "agentOrderId", "extmallProdId", "goodsCd", "sku", "optCd", "currPrice", "ordQty", "delvFee", "ordNm", "ordTelno", "ordPhnno", "ordEmail", "recipNm", "recipTelno", "recipPhnno", "recipZipcode", "recipBaseAddr", "recipDtlAddr", "delvMemo"};
 
 			ecxelGoodsList = GagaExcelUtil.getList(
 				GagaFileUtil.getConcatenationPath(targetPath, extmallOrder.getExcelFileNm()), 0, extMallOrderNames, 0);

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

@@ -299,6 +299,40 @@ public class TsaOrderChangeController extends TsaBaseController {
 		return super.ok("성공");
 	}
 	
+	/**
+	 * 취소완료 상세 화면 (관리자)
+	 * 
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2021. 06. 30
+	 */
+	@GetMapping("/cnclRtn/complete/view")
+	public ModelAndView cnclCompleteView(@RequestParam(value = "ordNo") int ordNo, @RequestParam(value = "ordDtlNo") int ordDtlNo
+			, @RequestParam(value = "delvFeeCd") String delvFeeCd, @RequestParam(value = "delvFeeCdGrp") String delvFeeCdGrp
+			, @RequestParam(value = "chgStat") String chgStat, @RequestParam(value = "ordChgSq") int ordChgSq) {
+		
+		ModelAndView mav = new ModelAndView();
+		
+		// 2021.01.26 취소요청 화면, 취소요청정보확인 화면 통합
+		Order order = new Order();
+		order.setOrdChgSq(ordChgSq);
+		order.setOrdNo(ordNo);
+		
+		// 결제전취소, 결제후취소 일때 상태값 환입 취소완료 변경
+		if ("G685_17".equals(chgStat) || "G685_18".equals(chgStat)) {
+			order.setChgStat("G720_30");
+		}
+		
+		List<Order> cnclRtnCompleteList 	= coreOrderChangeService.getCnclRtnCompleteList(order);
+		Collection<Order> orderInfoList 	= coreOrderService.getOrderInfoList(order);
+		
+		mav.addObject("cnclRtnCompleteList"		, cnclRtnCompleteList);			// 취소완료목록
+		mav.addObject("orderInfoList"			, orderInfoList);				// 주문기본정보
+		mav.setViewName("order/CnclCompleteView");
+		
+		return mav;
+	}
+	
 	/**
 	 * 반품신청화면 (관리자)
 	 * 

+ 226 - 96
src/main/java/com/style24/admin/biz/web/TsaShoplinkerController.java

@@ -8,9 +8,13 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 
+import javax.servlet.http.HttpServletRequest;
+
 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.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -31,6 +35,7 @@ import com.gagaframework.web.util.GagaDateUtil;
 import com.gagaframework.web.util.GagaFileUtil;
 import com.style24.admin.biz.service.TsaOcmService;
 import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaShoplinkerService;
 import com.style24.admin.support.controller.TsaBaseController;
 import com.style24.admin.support.security.session.TsaSession;
 import com.style24.core.biz.service.TscOrderOcmService;
@@ -65,7 +70,10 @@ public class TsaShoplinkerController extends TsaBaseController {
 	private Environment env;
 
 	@Autowired
-	private TscShoplinkerService shoplinkerService;
+	private TscShoplinkerService tscShoplinkerService;
+
+	@Autowired
+	private TsaShoplinkerService admShoplinkerService;
 
 	@Autowired
 	private TsaOcmService ocmService;
@@ -79,7 +87,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 	@Autowired
 	private ObjectMapper mapper;
 
-	private static final int EXCEL_ROW_COUNT = 1000;
+	private static final int EXCEL_ROW_COUNT = 500;
 
 
 
@@ -102,7 +110,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 	/**
 	 * 샵링커상품등록-전송목록조회
 	 *
-	 * @return
+	 * @return shoplinkerSearch
 	 * @author jmh
 	 * @since 2021. 5. 20
 	 */
@@ -129,10 +137,10 @@ public class TsaShoplinkerController extends TsaBaseController {
 
 		shoplinkerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
 		shoplinkerSearch.setPageable(new TscPageRequest(shoplinkerSearch.getPageNo() - 1, shoplinkerSearch.getPageSize()));
-		shoplinkerSearch.getPageable().setTotalCount(shoplinkerService.getGoodsSendListCount(shoplinkerSearch));
+		shoplinkerSearch.getPageable().setTotalCount(admShoplinkerService.getGoodsSendListCount(shoplinkerSearch));
 
 		result.set("pageing", shoplinkerSearch);
-		result.set("goodsList", shoplinkerService.getGoodsSendList(shoplinkerSearch));
+		result.set("goodsList", admShoplinkerService.getGoodsSendList(shoplinkerSearch));
 
 		return result;
 	}
@@ -140,7 +148,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 	/**
 	 * 샵링커상품등록-상품등록엑셀업로드
 	 *
-	 * @param shoplinkerGoods
+	 * @param paramMap
 	 * @return GagaMap
 	 * @throws Exception
 	 * @author jmh
@@ -161,14 +169,14 @@ public class TsaShoplinkerController extends TsaBaseController {
 		// API 호출 중인건수 있는지 확인
 		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
 		slkSearch.setApiType("GOODS");
-		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		ShoplinkerSearch runMap = tscShoplinkerService.getCallRunableInfo(slkSearch);
 
 		if( runMap.getRunCnt() < 1 ) {
 			try {
 				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
 				slkSearch.setSid(GagaDateUtil.getTodayDateTime());
 				slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
 
 				// 2. 엑셀데이터 확인 및 xml 관련 위치 확인
 				String[] goodsNames = {"goodsCd"};
@@ -199,7 +207,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 				// 3. xml 데이터 생성
 				shoplinkerGoods.setCustomerId(env.getProperty("shoplinker.customer_id"));
 				shoplinkerGoods.setRegNo(TsaSession.getInfo().getUserNo());
-				rtnMap = shoplinkerService.createShoplinkerXml(ecxelGoodsList, shoplinkerGoods);
+				rtnMap = admShoplinkerService.createShoplinkerXml(ecxelGoodsList, shoplinkerGoods);
 
 				// 4. 파일 삭제
 				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, shoplinkerGoods.getExcelFileNm()));
@@ -216,9 +224,138 @@ public class TsaShoplinkerController extends TsaBaseController {
 			}finally {
 				// 4. API 호출 이력 저장 종료
 				slkSearch.setRunStat("END");
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
+			}
+		}
+	}
+
+	/**
+	 * 샵링커상품등록- 엑셀다운로드
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	@GetMapping("/goods/excel/list")
+	public ResponseEntity<InputStreamResource> downloadGoodsInfoExcelList(HttpServletRequest request, ShoplinkerSearch shoplinkerSearch) throws Exception {
+		String excelfileName = "샵링커_상품_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilenameWithPath = GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+
+		if (!StringUtils.isBlank(shoplinkerSearch.getBrandList())) {
+			try {
+				String[] arrBrandCd = mapper.readValue(shoplinkerSearch.getBrandList(), String[].class);
+				shoplinkerSearch.setMultiBrand(arrBrandCd);
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new IllegalStateException("브랜드코드 검색중 오류로 인해 조회되지 않았습니다.");
+			}
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isBlank(shoplinkerSearch.getCondition())) {
+			shoplinkerSearch.setConditionList(shoplinkerSearch.getCondition().replaceAll("\r", "").trim().split("\n"));
+		}
+
+		shoplinkerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerSearch.setPageable(new TscPageRequest(shoplinkerSearch.getPageNo() - 1, shoplinkerSearch.getPageSize()));
+		shoplinkerSearch.getPageable().setTotalCount(admShoplinkerService.getGoodsSendListCount(shoplinkerSearch));
+
+		admShoplinkerService.getGoodsSendExcelList(shoplinkerSearch, excelFilenameWithPath);
+
+		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
+	}
+
+
+	/**
+	 * 재고이력-화면
+	 * @return ModelAndView
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@GetMapping("/stock/result/form")
+	public ModelAndView stockHistoryForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("shoplinker/ShoplinkerStockForm");
+
+		return mav;
+	}
+
+	/**
+	 * 재고이력-목록조회
+	 *
+	 * @param shoplinkerSearch
+	 * @return GagaMap
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@PostMapping("/stock/result/list")
+	@ResponseBody
+	public GagaMap getStockHistoryList(@RequestBody ShoplinkerSearch shoplinkerSearch) {
+
+		GagaMap result = new GagaMap();
+
+		if (!StringUtils.isBlank(shoplinkerSearch.getBrandList())) {
+			try {
+				String[] arrBrandCd = mapper.readValue(shoplinkerSearch.getBrandList(), String[].class);
+				shoplinkerSearch.setMultiBrand(arrBrandCd);
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new IllegalStateException("브랜드코드 검색중 오류로 인해 조회되지 않았습니다.");
+			}
+		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isBlank(shoplinkerSearch.getCondition())) {
+			shoplinkerSearch.setConditionList(shoplinkerSearch.getCondition().replaceAll("\r", "").trim().split("\n"));
+		}
+
+		shoplinkerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerSearch.setPageable(new TscPageRequest(shoplinkerSearch.getPageNo() - 1, shoplinkerSearch.getPageSize()));
+		shoplinkerSearch.getPageable().setTotalCount(admShoplinkerService.getStockListCount(shoplinkerSearch));
+
+		result.set("pageing", shoplinkerSearch);
+		result.set("stockList", admShoplinkerService.getStockList(shoplinkerSearch));
+
+		return result;
+	}
+
+	/**
+	 * 재고이력-엑셀다운로드
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	@GetMapping("/stock/excel/list")
+	public ResponseEntity<InputStreamResource> downloadStockInfoExcelList(HttpServletRequest request, ShoplinkerSearch shoplinkerSearch) throws Exception {
+		String excelfileName = "샵링커_재고_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilenameWithPath = GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+
+		if (!StringUtils.isBlank(shoplinkerSearch.getBrandList())) {
+			try {
+				String[] arrBrandCd = mapper.readValue(shoplinkerSearch.getBrandList(), String[].class);
+				shoplinkerSearch.setMultiBrand(arrBrandCd);
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new IllegalStateException("브랜드코드 검색중 오류로 인해 조회되지 않았습니다.");
 			}
 		}
+
+		// multi row 검색관련 처리
+		if (!StringUtils.isBlank(shoplinkerSearch.getCondition())) {
+			shoplinkerSearch.setConditionList(shoplinkerSearch.getCondition().replaceAll("\r", "").trim().split("\n"));
+		}
+
+		shoplinkerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerSearch.setPageable(new TscPageRequest(shoplinkerSearch.getPageNo() - 1, shoplinkerSearch.getPageSize()));
+		shoplinkerSearch.getPageable().setTotalCount(admShoplinkerService.getStockListCount(shoplinkerSearch));
+
+		admShoplinkerService.getStockExcelList(shoplinkerSearch, excelFilenameWithPath);
+
+		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
 	}
 
 
@@ -258,7 +395,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 	/**
 	 * 주문수집관리-목록조회
 	 *
-	 * @return
+	 * @return shoplinkerOrder
 	 * @author jmh
 	 * @since 2021. 5. 20
 	 */
@@ -275,10 +412,10 @@ public class TsaShoplinkerController extends TsaBaseController {
 
 		shoplinkerOrder.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
 		shoplinkerOrder.setPageable(new TscPageRequest(shoplinkerOrder.getPageNo() - 1, shoplinkerOrder.getPageSize()));
-		shoplinkerOrder.getPageable().setTotalCount(shoplinkerService.getShoplinkerOrderListCount(shoplinkerOrder));
+		shoplinkerOrder.getPageable().setTotalCount(admShoplinkerService.getShoplinkerOrderListCount(shoplinkerOrder));
 
 		result.set("pageing", shoplinkerOrder);
-		result.set("shoplinkerOrderList", shoplinkerService.getShoplinkerOrderList(shoplinkerOrder));
+		result.set("shoplinkerOrderList", admShoplinkerService.getShoplinkerOrderList(shoplinkerOrder));
 
 		return result;
 	}
@@ -288,8 +425,8 @@ public class TsaShoplinkerController extends TsaBaseController {
 	 *
 	 * @param ordNo - 주문번호
 	 * @return ModelAndView
-	 * @author jsh77b
-	 * @since 2020. 11. 26
+	 * @author jmh
+	 * @since 2021. 5. 20
 	 */
 	@GetMapping("/order/collection/info")
 	@ResponseBody
@@ -299,8 +436,8 @@ public class TsaShoplinkerController extends TsaBaseController {
 		ShoplinkerOrder order = new ShoplinkerOrder();
 		order.setShoplinkerOrderId(shoplinkerOrderId);
 
-		mav.addObject("slkOrderInfo", shoplinkerService.getShoplinkerOrderInfo(order));
-		mav.addObject("extOrderInfo", shoplinkerService.getExtmallOrderInfo(shoplinkerOrderId));
+		mav.addObject("slkOrderInfo", admShoplinkerService.getShoplinkerOrderInfo(order));
+		mav.addObject("extOrderInfo", admShoplinkerService.getExtmallOrderInfo(shoplinkerOrderId));
 
 		mav.setViewName("shoplinker/ShoplinkerOrderDetailForm");
 
@@ -309,7 +446,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 
 	/**
 	 * 주문수집관리-주문수집 api 호출
-	 * @return
+	 * @param apiStDate
 	 * @author jmh
 	 * @throws IOException
 	 * @since 2021. 5. 20
@@ -343,13 +480,13 @@ public class TsaShoplinkerController extends TsaBaseController {
 		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
 		slkSearch.setApiType("ORDER");
 		slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
-		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		ShoplinkerSearch runMap = tscShoplinkerService.getCallRunableInfo(slkSearch);
 
 		if( runMap.getRunCnt() < 1 ) {
 			try {
 				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
 				slkSearch.setSid(GagaDateUtil.getTodayDateTime());
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
 
 				// 2. 샵링커 api 호출 샵링커주문수집 등록
 				shoplinkerOrder.setSid(slkSearch.getSid());
@@ -358,16 +495,16 @@ public class TsaShoplinkerController extends TsaBaseController {
 				shoplinkerOrder.setShoplinkerId(env.getProperty("shoplinker.shoplinker_id"));
 				shoplinkerOrder.setRegNo(TsaSession.getInfo().getUserNo());
 				shoplinkerOrder.setAcType("ADMMIN");
-				rtnMap = shoplinkerService.insertShoplinkerOrderStep1(shoplinkerOrder);
+				rtnMap = tscShoplinkerService.insertShoplinkerOrderStep1(shoplinkerOrder);
 
 				// 3. 제휴몰 주문등록
 				slkSearch.setTxt("=>제휴몰");
-				shoplinkerService.updateCallApiRunable(slkSearch);
-				shoplinkerService.insertShoplinkerOrderStep2(shoplinkerOrder);
+				tscShoplinkerService.updateCallApiRunable(slkSearch);
+				tscShoplinkerService.insertShoplinkerOrderStep2(shoplinkerOrder);
 
 				// 4. 스타일24 주문등록 (제휴몰 - 대기상태인 것들)
 				slkSearch.setTxt("=>스타일24");
-				shoplinkerService.updateCallApiRunable(slkSearch);
+				tscShoplinkerService.updateCallApiRunable(slkSearch);
 				orderOcmService.createShoplinkerOrder("S", TsaSession.getInfo().getUserNo());
 
 			}catch (Exception e) {
@@ -386,15 +523,37 @@ public class TsaShoplinkerController extends TsaBaseController {
 					slkSearch.setRunStat("END");
 					slkSearch.setTxt("=>FINISH");
 				}
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
 			}
 		}
+	}
+
+	/**
+	 * 주문수집관리-엑셀다운로드
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	@GetMapping("/order/excel/list")
+	public ResponseEntity<InputStreamResource> downloadOrderInfoExcelList(HttpServletRequest request, ShoplinkerOrder shoplinkerOrder) throws Exception {
+		String excelfileName = "샵링커_주문_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilenameWithPath = GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+
+		shoplinkerOrder.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerOrder.setPageable(new TscPageRequest(shoplinkerOrder.getPageNo() - 1, shoplinkerOrder.getPageSize()));
+		shoplinkerOrder.getPageable().setTotalCount(admShoplinkerService.getShoplinkerOrderListCount(shoplinkerOrder));
 
+		admShoplinkerService.getOrderExcelList(shoplinkerOrder, excelFilenameWithPath);
+
+		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
 	}
 
+
 	/**
 	 * 송장전송관리-화면
-	 * @return
+	 * @return ModelAndView
 	 * @author jmh
 	 * @since 2021. 5. 20
 	 */
@@ -418,7 +577,8 @@ public class TsaShoplinkerController extends TsaBaseController {
 	/**
 	 * 송장전송관리-전송목록조회
 	 *
-	 * @return
+	 * @param shoplinkerInvoice
+	 * @return GagaMap
 	 * @author jmh
 	 * @since 2021. 5. 20
 	 */
@@ -435,10 +595,10 @@ public class TsaShoplinkerController extends TsaBaseController {
 
 		shoplinkerInvoice.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
 		shoplinkerInvoice.setPageable(new TscPageRequest(shoplinkerInvoice.getPageNo() - 1, shoplinkerInvoice.getPageSize()));
-		shoplinkerInvoice.getPageable().setTotalCount(shoplinkerService.getSendInvoiceListCount(shoplinkerInvoice));
+		shoplinkerInvoice.getPageable().setTotalCount(admShoplinkerService.getSendInvoiceListCount(shoplinkerInvoice));
 
 		result.set("pageing", shoplinkerInvoice);
-		result.set("invoiceList", shoplinkerService.getSendInvoiceList(shoplinkerInvoice));
+		result.set("invoiceList", admShoplinkerService.getSendInvoiceList(shoplinkerInvoice));
 
 		return result;
 	}
@@ -446,8 +606,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 	/**
 	 * 송장전송관리-송장전송
 	 *
-	 * @param shoplinkerGoods
-	 * @return GagaMap
+	 * @param
 	 * @throws Exception
 	 * @author jmh
 	 * @since 2021.5.20
@@ -460,14 +619,14 @@ public class TsaShoplinkerController extends TsaBaseController {
 		// API 호출 중인건수 있는지 확인
 		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
 		slkSearch.setApiType("INVOICE");
-		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		ShoplinkerSearch runMap = tscShoplinkerService.getCallRunableInfo(slkSearch);
 
 		if( runMap.getRunCnt() < 1 ) {
 			try {
 				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
 				slkSearch.setSid(GagaDateUtil.getTodayDateTime());
 				slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
 
 				ShoplinkerInvoice shoplinkerInvoice = new ShoplinkerInvoice();
 				shoplinkerInvoice.setStDate(stDate);
@@ -493,8 +652,8 @@ public class TsaShoplinkerController extends TsaBaseController {
 
 				// 2. xml 데이터 생성
 				shoplinkerInvoice.setCustomerId(env.getProperty("shoplinker.customer_id"));
-				Collection<ShoplinkerInvoice> sendList = shoplinkerService.getShoplinkerInvoiceOrdDtlList();
-				shoplinkerService.createShoplinkerInvoiceXml(shoplinkerInvoice, sendList);
+				Collection<ShoplinkerInvoice> sendList = tscShoplinkerService.getShoplinkerInvoiceOrdDtlSendList();
+				tscShoplinkerService.createShoplinkerInvoiceXml(shoplinkerInvoice, sendList);
 
 				rtnMap.setString("RESULT_TYPE", "TRUE");
 
@@ -514,13 +673,37 @@ public class TsaShoplinkerController extends TsaBaseController {
 					slkSearch.setRunStat("END");
 					slkSearch.setTxt("=>FINISH");
 				}
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
 			}
 		}
 	}
 
 	/**
-	 * 송장전송관리-송장전송(엑셀용)
+	 * 송장전송- 엑셀다운로드
+	 *
+	 * @param shoplinkerInvoice
+	 * @return
+	 * @author jmh
+	 * @since 2021. 06. 29
+	 */
+	@GetMapping("/invoice/excel/list")
+	public ResponseEntity<InputStreamResource> downloadOrderInfoExcelList(HttpServletRequest request, ShoplinkerInvoice shoplinkerInvoice) throws Exception {
+		String excelfileName = "샵링커_송장_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
+		String excelFilenameWithPath = GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
+
+
+
+		shoplinkerInvoice.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerInvoice.setPageable(new TscPageRequest(shoplinkerInvoice.getPageNo() - 1, shoplinkerInvoice.getPageSize()));
+		shoplinkerInvoice.getPageable().setTotalCount(admShoplinkerService.getSendInvoiceListCount(shoplinkerInvoice));
+
+		admShoplinkerService.getInvoiceExcelList(shoplinkerInvoice, excelFilenameWithPath);
+
+		return GagaFileUtil.writeFile(request, excelFilenameWithPath);
+	}
+
+	/**
+	 * 송장전송관리-송장전송(업로드엑셀용)
 	 *
 	 * @param shoplinkerGoods
 	 * @return GagaMap
@@ -559,7 +742,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
 				slkSearch.setSid(datestr);
 				slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
 
 				// 2. 엑셀데이터 확인 및 xml 관련 위치 확인
 				String[] goodsNames = {"ordNo", "supplyCompCd"};
@@ -612,7 +795,7 @@ public class TsaShoplinkerController extends TsaBaseController {
 					slkSearch.setRunStat("END");
 					slkSearch.setTxt("=>FINISH");
 				}
-				shoplinkerService.saveCallApiRunable(slkSearch);
+				tscShoplinkerService.saveCallApiRunable(slkSearch);
 			}
 		}
 
@@ -620,64 +803,12 @@ public class TsaShoplinkerController extends TsaBaseController {
 	}
 	 ******************************************************************************************/
 
-	/**
-	 * 재고이력-화면
-	 * @return
-	 * @author jmh
-	 * @since 2021. 5. 20
-	 */
-	@GetMapping("/stock/result/form")
-	public ModelAndView stockHistoryForm() {
-		ModelAndView mav = new ModelAndView();
-
-		mav.setViewName("shoplinker/ShoplinkerStockForm");
-
-		return mav;
-	}
-
-	/**
-	 * 재고이력-목록조회
-	 *
-	 * @return
-	 * @author jmh
-	 * @since 2021. 5. 20
-	 */
-	@PostMapping("/stock/result/list")
-	@ResponseBody
-	public GagaMap getStockHistoryList(@RequestBody ShoplinkerSearch shoplinkerSearch) {
-
-		GagaMap result = new GagaMap();
-
-		if (!StringUtils.isBlank(shoplinkerSearch.getBrandList())) {
-			try {
-				String[] arrBrandCd = mapper.readValue(shoplinkerSearch.getBrandList(), String[].class);
-				shoplinkerSearch.setMultiBrand(arrBrandCd);
-			} catch (Exception e) {
-				e.printStackTrace();
-				throw new IllegalStateException("브랜드코드 검색중 오류로 인해 조회되지 않았습니다.");
-			}
-		}
-
-		// multi row 검색관련 처리
-		if (!StringUtils.isBlank(shoplinkerSearch.getCondition())) {
-			shoplinkerSearch.setConditionList(shoplinkerSearch.getCondition().replaceAll("\r", "").trim().split("\n"));
-		}
-
-		shoplinkerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
-		shoplinkerSearch.setPageable(new TscPageRequest(shoplinkerSearch.getPageNo() - 1, shoplinkerSearch.getPageSize()));
-		shoplinkerSearch.getPageable().setTotalCount(shoplinkerService.getStockListCount(shoplinkerSearch));
-
-		result.set("pageing", shoplinkerSearch);
-		result.set("stockList", shoplinkerService.getStockList(shoplinkerSearch));
-
-		return result;
-	}
 
 	/**
 	 * 공통-api 실행여부확인
 	 *
 	 * @param slkSearch - 주문번호
-	 * @return ModelAndView
+	 * @return ShoplinkerSearch
 	 * @author jmh
 	 * @since 2020. 11. 26
 	 */
@@ -686,13 +817,12 @@ public class TsaShoplinkerController extends TsaBaseController {
 	public ShoplinkerSearch apiRunable(@RequestBody ShoplinkerSearch slkSearch) throws IOException {
 
 		slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
-		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		ShoplinkerSearch runMap = tscShoplinkerService.getCallRunableInfo(slkSearch);
 		return runMap;
 	}
 
 
 
-
 	/*
 	 *
 	 * api test
@@ -838,10 +968,10 @@ System.out.println("####### : "+re.getResult());
 			com.gagaframework.shoplinker.domain.orderlist.Header rHeader;
 			com.gagaframework.shoplinker.domain.orderlist.Shoplinker shoplinkerOrdResult;
 
-			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order/order_time.xml";
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order/order_time.xml"; // 20210401  143000 ~ 150000
 			//testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order/0528/order_real_1.xml";	// 28~31일 15시~07시
 			//testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order/0528/order_real_28.xml";	// 28 15시~235959  7개
-			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order/0528/order_real_31.xml";	// 31일 000000시~07시  5582개
+			//testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order/0528/order_real_31.xml";	// 31일 000000시~07시  5582개
 			responseXmlData =   shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Order/orderlist.php?iteminfo_url="+testXmlUrl, "");
 
 

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

@@ -18,6 +18,7 @@ public class Extmall extends TscBaseDomain {
 	private String extmallId;		// 제휴몰ID
 	private String extmallUserId;	// 제휴몰사용자ID
 	private String extmallNm;		// 제휴몰명
+	private String extmallTel;		// 고객센터연락처
 	private String supplyCompCd;	// 공급업체코드
 	private String sellStoreCd;		// 판매매장코드
 	private float stockSellRate;	// 재고판매비율

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

@@ -75,6 +75,8 @@ public class Goods extends TscBaseDomain {
 	private String erpPriceLinkYn;		//ERP가격연계여부(자사상품만 사용. Y:연계)
 	private String erpStockLinkYn;		//ERP재고연계여부(자사상품만 사용. Y:연계)
 	private String newCustOrdYn;		//신규고객 구매가능여부(Y:신규고객만 구매가능)
+	private String newCustOrdStdt;		//신규고객 시작일
+	private String newCustOrdEddt;		//신규고객 종료일
 	private int costPrice;		//원가
 	private String adultYn;		//성인용품여부
 	private String tobeFormYn;		//상품상세신규폼사용여부

+ 6 - 6
src/main/java/com/style24/persistence/mybatis/shop/TsaCustomer.xml

@@ -685,8 +685,8 @@
 		    <if test="searchGb == 'email'">
 		AND    LOWER(EMAIL) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
 		    </if>
-		    <if test="searchGb == 'custNo'">
-		AND    LOWER(CUST_NO) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    <if test="searchGb == 'custId'">
+		AND    CUST_ID LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
 		    </if>
 		</if>
 		<if test="siteCd != null and siteCd != ''">
@@ -767,8 +767,8 @@
 		    <if test="searchGb == 'email'">
 		AND    LOWER(EMAIL) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
 		    </if>
-		    <if test="searchGb == 'custNo'">
-		AND    LOWER(CUST_NO) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    <if test="searchGb == 'custId'">
+		AND    LOWER(CUST_ID) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
 		    </if>
 		</if>
 		<if test="siteCd != null and siteCd != ''">
@@ -808,8 +808,8 @@
 		    <if test="searchGb == 'email'">
 		AND    LOWER(EMAIL) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
 		    </if>
-		    <if test="searchGb == 'custNo'">
-		AND    LOWER(CUST_NO) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    <if test="searchGb == 'custId'">
+		AND    LOWER(CUST_ID) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
 		    </if>
 		</if>
 		<if test="siteCd != null and siteCd != ''">

+ 16 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsaGoods.xml

@@ -939,6 +939,8 @@
 		     , G.ERP_STOCK_LINK_YN
 		     , G.ERP_PRICE_LINK_YN
 		     , G.NEW_CUST_ORD_YN
+		     , DATE_FORMAT(G.NEW_CUST_ORD_STDT, '%Y%m%d%') AS NEW_CUST_ORD_STDT
+		     , DATE_FORMAT(G.NEW_CUST_ORD_EDDT, '%Y%m%d%') AS NEW_CUST_ORD_EDDT
 		     , G.ADULT_YN
 		     , G.TOBE_FORM_YN
 		     , FN_GET_CODE_NM('G076', G.ORIGIN_CD) AS ORIGIN_NM
@@ -1124,6 +1126,8 @@
 		      , ERP_PRICE_LINK_YN
 		      , ERP_STOCK_LINK_YN
 		      , NEW_CUST_ORD_YN
+		      , NEW_CUST_ORD_STDT
+		      , NEW_CUST_ORD_EDDT
 		      , ADULT_YN
 		      , TOBE_FORM_YN
 		      , REG_NO
@@ -1186,6 +1190,8 @@
 		     , ERP_PRICE_LINK_YN   
 		     , ERP_STOCK_LINK_YN   
 		     , NEW_CUST_ORD_YN
+		     , NEW_CUST_ORD_STDT
+		     , NEW_CUST_ORD_EDDT
 		     , ADULT_YN
 		     , TOBE_FORM_YN
 		     , #{regNo}              
@@ -1725,6 +1731,16 @@
 		  , GIFT_PACK_YN = #{giftPackYn}
 		  , MAIN_COLOR_CD = #{mainColorCd}
 		  , NEW_CUST_ORD_YN = #{newCustOrdYn}
+		  <choose>
+		  <when test="newCustOrdStdt != null and newCustOrdStdt != ''">
+		  , NEW_CUST_ORD_STDT = STR_TO_DATE(#{newCustOrdStdt},'%Y%m%d%H%i%S')
+		  , NEW_CUST_ORD_EDDT = STR_TO_DATE(#{newCustOrdEddt},'%Y%m%d%H%i%S')
+		  </when>
+		  <otherwise>
+		  , NEW_CUST_ORD_STDT = null
+		  , NEW_CUST_ORD_EDDT = null
+		  </otherwise>
+		  </choose>
 		  , ADULT_YN = #{adultYn}
 		  , TOBE_FORM_YN = #{tobeFormYn}
 		  , SELL_STDT = STR_TO_DATE(#{sellStdt},'%Y%m%d%H%i%S')

+ 4 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsaOcm.xml

@@ -9,6 +9,7 @@
 		     , EXTMALL_ID        /*외부몰ID*/
 		     , EXTMALL_USER_ID   /*외부몰사용자ID*/
 		     , EXTMALL_NM        /*외부몰명*/
+		     , EXTMALL_TEL		 /*고객센터연락처*/
 		     , SUPPLY_COMP_CD    /*업체코드*/
 		     , SELL_STORE_CD     /*판매매장코드*/
 		     , STOCK_SELL_RATE   /*재고판매비율*/
@@ -41,6 +42,7 @@
 		     , PRICE_ACCEPT_RATE
 		     , DWDP_YN
 		     , CNCLSMS_SEND_YN
+		     , EXTMALL_TEL
 		     , USE_YN
 		     , REG_NO
 		     , REG_DT
@@ -58,6 +60,7 @@
 		     , IFNULL(#{priceAcceptRate},0)
 		     , #{dwdpYn}
 		     , #{cnclsmsSendYn}
+		     , #{extmallTel}
 		     , #{useYn}
 		     , #{regNo}
 		     , NOW()
@@ -73,6 +76,7 @@
 		     , PRICE_ACCEPT_RATE = IFNULL(#{priceAcceptRate},0)
 		     , DWDP_YN = #{dwdpYn}
 		     , CNCLSMS_SEND_YN = #{cnclsmsSendYn}
+		     , EXTMALL_TEL = #{extmallTel}
 		     , USE_YN = #{useYn}
 		     , UPD_NO = #{updNo}
 		     , UPD_DT = NOW()

+ 806 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsaShoplinker.xml

@@ -0,0 +1,806 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.style24.admin.biz.dao.TsaShoplinkerDao">
+
+	<!-- 상품등록-단품 목록 조회 -->
+	<select id="getOptionList" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getOptionList */
+		SELECT
+			A.GOODS_CD
+			, B.OPT_CD AS PARTNER_PRODUCT_ID
+			, B.OPT_CD
+			, B.OPT_CD1
+			, B.OPT_CD2
+		   /*, IF(B.CURR_STOCK_QTY - B.BASE_STOCK_QTY <![CDATA[<]]> 1, 1 , B.CURR_STOCK_QTY - B.BASE_STOCK_QTY) AS QUANTITY -- 기준재고(안전재고)수량
+		   , B.STORE_STOCK_QTY -- 매장재고수량
+		   , B.CURR_STOCK_QTY -- 현재고수량
+		   */
+			, A.SELF_GOODS_YN
+			, IF(VS.CURR_STOCK_QTY <![CDATA[<]]> 1, 1, VS.CURR_STOCK_QTY) AS QUANTITY   	-- 현재고
+			, VS.BASE_STOCK_QTY 	-- 안전재고
+		FROM VW_STOCK VS inner join tb_goods A on VS.GOODS_CD = A.GOODS_CD
+		INNER JOIN tb_option B on VS.GOODS_CD = B.GOODS_CD AND A.GOODS_CD = B.GOODS_CD and VS.OPT_CD = B.OPT_CD
+		WHERE VS.GOODS_CD = #{goodsCd}
+
+		ORDER BY cast(REPLACE(B.OPT_CD, '-', '') as unsigned)
+	</select>
+
+	<!-- 상품등록-상품 상세 -->
+	<select id="getGoods" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getGoods */
+		SELECT
+			GOODS_CD
+			, A.BRAND_CD
+			, IFNULL((SELECT S.SYNC_YN FROM TB_EXTMALL_PRICE_SYNC S WHERE S.VENDOR_ID = 'G003_V001' and S.BRAND_CD = A.BRAND_CD), 'N') as SYNC_YN
+			, (SELECT REPLACE(REPLACE(BRAND_ENM, ' ', '_'), '\'', '') FROM TB_BRAND S WHERE S.BRAND_CD = A.BRAND_CD AND S.USE_YN = 'Y') AS BRAND_ENM
+			, '999999999' AS ATTRIBUTE_TITLE_CODE
+			, (SELECT GROUP_CONCAT(OPT_CD ORDER BY CAST(REPLACE(OPT_CD, '-', '') AS UNSIGNED) SEPARATOR ',')  FROM TB_OPTION S WHERE A.GOODS_CD = S.GOODS_CD) AS ATTRIBUTE_PARTNER_PRODUCT_ID
+			, GOODS_NM AS PRODUCT_NAME
+
+			, TOBE_FORM_YN
+			, (SELECT GOODS_DESC FROM TB_GOODS_DESC S WHERE A.GOODS_CD = S.GOODS_CD AND DESC_GB= '80' LIMIT 1) AS DETAIL_DESC
+			, (SELECT GOODS_DESC FROM TB_GOODS_DESC S WHERE A.GOODS_CD = S.GOODS_CD AND DESC_GB= '10' LIMIT 1) AS DETAIL_DESC_NEW_10
+			, (SELECT GOODS_DESC FROM TB_GOODS_DESC S WHERE A.GOODS_CD = S.GOODS_CD AND DESC_GB= '20' LIMIT 1) AS DETAIL_DESC_NEW_20
+			, (SELECT GOODS_DESC FROM TB_GOODS_DESC S WHERE A.GOODS_CD = S.GOODS_CD AND DESC_GB= '30' LIMIT 1) AS DETAIL_DESC_NEW_30
+			, (SELECT S.MODEL_INFO FROM TB_GOODS_MODEL_INFO S WHERE S.GOODS_CD = A.GOODS_CD) AS MODEL_INFO
+
+			, '' AS MARKET_PRICE -- 쇼핑몰시중가(도서정가)
+			, CURR_PRICE AS SALE_PRICE -- 쇼핑몰판매가
+			, LIST_PRICE AS SUPPLY_PRICE -- 쇼핑몰공급가
+			, '' AS MARKET_PRICE_P -- 매입처 시중가(도서정가)
+			, '' AS SALE_PRICE_P -- 매입처 판매가
+			, '' AS SUPPLY_PRICE_P -- 매입처 공급가
+			, '001' AS SALE_STATUS -- 상품판매상태
+			, MAKE_YMD AS MAKER_DT -- 발행일(제조일)
+			, '001' AS TAX_YN -- 과세
+			, '' AS NEW_DESC_TOP -- 신상세설명
+			, '전국' AS SALEAREA
+			-- , SEX_GB
+			-- , FN_GET_CODE_NM('G007', SEX_GB) AS SEX_NM
+			, (CASE SEX_GB WHEN 'G007_M' THEN '002' WHEN 'G007_F' THEN '003' ELSE '001' END) AS SEX -- 샵링커 성별
+			, GOODS_CD AS MODEL -- 모델명
+			, GOODS_CD AS MODEL_NO -- 모델NO
+			, (SELECT BRAND_ENM FROM TB_BRAND S WHERE A.BRAND_CD = S.BRAND_CD AND USE_YN = 'Y') AS BRAND -- 브랜드명
+			, ( SELECT CERT_NUM FROM TB_GOODS_SAFE_NO S WHERE A.GOODS_CD = S.GOODS_CD ) AS AUTH_NO -- 인증번호
+			, '20991231' AS EXPIRYDATE -- 유효일
+			, (SELECT NI_CONTENT FROM TB_GOODS_NOTI_INFO S WHERE A.GOODS_CD = S.GOODS_CD AND NI_ITEM_CD = 'G005_005') AS MAKER -- 제조업체
+			, IFNULL((select S.EXTMALL_ORIGIN_NM from TB_EXTMALL_ORIGIN S where S.ORIGIN_CD = A.ORIGIN_CD), '') AS ORIGIN -- 원산지명 OR 코드
+			, ADULT_YN AS ADULT_INFO -- 성인상품
+
+			, A.ITEMKIND_CD
+			, C.ITEMKIND_NM AS SHOPLINKER_ITEMKIND_NM
+			, C.SL_CATE1_CD AS CCATEGORY_L
+			, C.SL_CATE2_CD AS CCATEGORY_M
+			, C.SL_CATE3_CD AS CCATEGORY_S
+			, C.SL_CATE4_CD AS CCATEGORY_D
+
+			, MAIN_COLOR_CD
+			, SELF_GOODS_YN
+			, (SELECT COLOR_ENM FROM TB_COLOR WHERE COLOR_CD = MAIN_COLOR_CD) AS MAIN_COLOR_ENM
+			, (SELECT GROUP_CONCAT(opt_cd1 order BY cast(REPLACE(OPT_CD, '-', '') as unsigned) SEPARATOR ',')
+				FROM (
+				    SELECT
+				        GOODS_CD, opt_cd, opt_cd1
+				        , ROW_NUMBER() OVER (PARTITION BY opt_cd1 ORDER BY opt_cd ) AS RankNo
+				    FROM tb_option WHERE GOODS_CD = a.GOODS_CD
+				) T WHERE RankNo = 1
+			 ) as all_opt_cd1
+			, CASE
+				WHEN SUBSTRING(A.ITEMKIND_CD, 1, 2) = '08' || SUBSTRING(A.ITEMKIND_CD, 1, 2) = '09'
+					|| SUBSTRING(A.ITEMKIND_CD, 1, 2) = '10' || SUBSTRING(A.ITEMKIND_CD, 1, 2) = '11'
+					|| SUBSTRING(A.ITEMKIND_CD, 1, 2) = '12' || SUBSTRING(A.ITEMKIND_CD, 1, 2) = '13'
+			  	THEN 'Y'
+			  	ELSE 'N'
+			  END KIDS_YN
+		FROM TB_GOODS A
+			LEFT OUTER JOIN TB_ITEMKIND B ON A.ITEMKIND_CD = B.ITEMKIND_CD
+ 			LEFT OUTER JOIN SHOPLINKER_CATE C ON B.ITEMKIND_CD = C.ITEMKIND_CD AND A.BRAND_CD = C.BRAND_CD
+		WHERE A.GOODS_CD = #{goodsCd}
+		AND A.SELF_GOODS_YN = 'Y'
+		limit 1
+
+	</select>
+
+	<!-- 상품등록-상품 이미지 조회 -->
+	<select id="getGoodsImageList" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getGoodsImageList */
+		SELECT
+			B.GOODS_CD
+		     , B.COLOR_CD
+		     , C.COLOR_KNM
+		     , B.DISP_ORD
+		     , B.SYS_IMG_NM
+		     , B.DEFAULT_IMG_YN
+		     , B.EXTMALL_IMG_YN
+		FROM   TB_GOODS A INNER JOIN TB_GOODS_IMG B ON A.GOODS_CD = B.GOODS_CD
+				LEFT OUTER JOIN TB_COLOR C ON B.COLOR_CD = C.COLOR_CD
+		WHERE A.GOODS_CD = #{goodsCd}
+		<if test='extmallImgYn != null and extmallImgYn == "Y"'>
+			AND A.MAIN_COLOR_CD = B.COLOR_CD
+        	AND (B.DEFAULT_IMG_YN = 'Y' OR B.EXTMALL_IMG_YN = 'Y')
+        </if>
+        <if test='colorListYn != null and colorListYn == "Y"'>
+
+        </if>
+		ORDER BY B.COLOR_CD, B.DISP_ORD
+	</select>
+
+	<!-- 상품등록-상품 사이즈 조회 -->
+	<select id="getGoodsSizeList" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getGoodsSizeList */
+		SELECT
+			 A.OPT_CD2
+			, B.TYPECD as SIZE_TYPECD
+			, B.VALUE1 as SIZE_VALUE1
+			, B.VALUE2 as SIZE_VALUE2
+			, B.VALUE3 as SIZE_VALUE3
+			, B.VALUE4 as SIZE_VALUE4
+			, B.VALUE5 as SIZE_VALUE5
+
+		FROM TB_OPTION A INNER JOIN TB_IF_MEASUREMENT B ON A.OPT_CD = B.SKUCODE /*A.PRODUCT_NO = B.PRODUCTNO*/
+		WHERE A.GOODS_CD = #{goodsCd}
+		GROUP BY A.OPT_CD2, B.TYPECD, B.VALUE1, B.VALUE2, B.VALUE3, B.VALUE4, B.VALUE5
+		ORDER BY A.OPT_CD2
+	</select>
+
+	<!-- 상품등록-고시정보 -->
+	<select id="getGoodsNotiList" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getGoodsNotiList */
+		SELECT
+			A.GOODS_CD as partner_product_id
+			, A.GOODS_NM
+			/*, B.NI_CLSF_CD
+			, B.NI_ITEM_CD */
+			, C.NI_CLSF_CD
+			, C.NI_ITEM_CD
+			, C.EXTMALL_NI_CLSF_CD as lclass_id
+			, C.EXTMALL_NI_ITEM_CD as item_seq
+			, B.NI_CONTENT as item_info
+			, FN_GET_CODE_NM('G005', C.NI_ITEM_CD) AS NI_CONTENT_INFO
+			, A.SELF_GOODS_YN = 'Y'
+		FROM TB_GOODS A INNER JOIN TB_GOODS_NOTI_INFO B INNER JOIN TB_EXTMALL_NOTI_INFO C
+		ON A.GOODS_CD = B.GOODS_CD
+		AND B.NI_CLSF_CD = C.NI_CLSF_CD
+		AND B.NI_ITEM_CD = C.NI_ITEM_CD
+		AND A.GOODS_CD = #{goodsCd}
+	</select>
+
+	<!-- 상품등록-인증정보 -->
+	<select id="getCert" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getCert */
+		SELECT
+			B.GOODS_CD AS PARTNER_PRODUCT_ID
+			, CASE B.CERT_ORGAN_NAME
+				WHEN NULL THEN '.' WHEN '' THEN '.'
+				ELSE B.CERT_ORGAN_NAME
+			 END AS CERT_ORGAN
+			, IFNULL(B.CERT_NUM, '') AS CERT_NO
+			, A.SELF_GOODS_YN
+
+			, B.CERT_TARGET_GB
+			, FN_GET_CODE_NM('G083', CERT_TARGET_GB) AS CERT_TARGET_NM
+			, CERT_FORM_GB
+			, FN_GET_CODE_NM('G084', CERT_FORM_GB) AS CERT_FORM_NM
+			, CERT_TYPE
+			, FN_GET_CODE_NM('G081', CERT_TYPE) AS CERT_TYPE_NM
+			, CERT_NUM
+			, CERT_STATE
+			, CERT_DIV
+			, CERT_ORGAN_NAME
+			, CERT_DT
+		FROM TB_GOODS A INNER JOIN TB_GOODS_SAFE_NO B
+		ON A.GOODS_CD = B.GOODS_CD
+		WHERE A.GOODS_CD = #{goodsCd}
+	</select>
+
+	<!-- 상품등록-상품 목록 건수 -->
+	<select id="getGoodsSendListCount" parameterType="ShoplinkerSearch" resultType="int">
+		/* TsaShoplinker.getGoodsSendListCount */
+		SELECT COUNT(1) FROM
+		(
+			SELECT
+				 B.GOODS_NM
+				, B.BRAND_CD
+				, A.*
+				, fn_get_user_nm(A.REG_NO) AS REG_NM
+			FROM SHOPLINKER_SYNC_HST A
+				LEFT OUTER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+
+			WHERE 1=1
+			<include refid="getListCondition_sql"/>
+		) A
+
+
+	</select>
+
+	<!-- 상품등록-상품 목록 -->
+	<select id="getGoodsSendList" parameterType="ShoplinkerSearch" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getGoodsSendList */
+		SELECT * FROM
+		(
+			SELECT
+				 B.GOODS_NM
+				, B.BRAND_CD
+				, A.*
+				, fn_get_user_nm(A.REG_NO) AS REG_NM
+			FROM SHOPLINKER_SYNC_HST A
+				LEFT OUTER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+
+			WHERE 1=1
+			<include refid="getListCondition_sql"/>
+		) A
+
+		ORDER BY REG_DT DESC
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+	</select>
+
+	<!-- 상품등록-상품 목록 엑셀 -->
+	<select id="getGoodsSendExcelList" parameterType="ShoplinkerSearch" resultType="paramMap">
+		/* TsaShoplinker.getGoodsSendExcelList */
+		SELECT
+			 IFNULL(B.GOODS_NM, '') AS GOODS_NM
+			, IFNULL(B.BRAND_CD, '') AS BRAND_CD
+			, CASE WHEN 'OPTION' = A.API_TYPE THEN '단품'
+				  WHEN 'PRODUCT' =  A.API_TYPE THEN '상품'
+				  WHEN 'NOTI' =  A.API_TYPE THEN '품목(고시)'
+				  WHEN 'CERT' =  A.API_TYPE THEN '인증'
+				  WHEN 'IMAGE' =  A.API_TYPE THEN '이미지'
+			  END API_TYPE
+			, IFNULL(A.API_RESULT, '') AS API_RESULT
+			, IFNULL(A.API_MESSAGE, '') AS API_MESSAGE
+			, IFNULL(A.API_PRODUCT_ID, '') AS API_PRODUCT_ID
+			, IFNULL(A.GOODS_CD, '') AS GOODS_CD
+			, IFNULL(A.OPT_CD, '') AS OPT_CD
+			, IFNULL(A.QTY, '') AS QTY
+			, IFNULL(A.ORD_DTL_NO, '') AS ORD_DTL_NO
+			, IFNULL(A.REG_DT, '') AS REG_DT
+			, fn_get_user_nm(A.REG_NO) AS REG_NM
+		FROM SHOPLINKER_SYNC_HST A
+		LEFT OUTER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+
+		WHERE 1=1
+		<include refid="getListCondition_sql"/>
+
+		ORDER BY REG_DT DESC
+	</select>
+
+	<!-- 재고-단품 등록 -->
+	<insert id="insertStockOption" parameterType="ShoplinkerGoods">
+		/* TsaShoplinker.insertStockOption */
+		INSERT INTO SHOPLINKER_STOCK (
+		    GOODS_CD
+			, OPT_CD
+			, STOCK_QTY
+			, SEND_YN
+			, SEND_DT
+			, REG_DT
+			, UPD_DT
+		)
+		VALUES (
+			#{goodsCd}
+			, #{optCd}
+			, #{quantity}
+			, 'Y'
+			, now()
+			, now()
+			, now()
+		) ON DUPLICATE KEY UPDATE
+		  	UPD_DT = now()
+	</insert>
+
+	<!-- 재고전송-목록 건수 -->
+	<select id="getStockListCount" parameterType="ShoplinkerSearch" resultType="int">
+		/* TsaShoplinker.getStockListCount */
+		SELECT COUNT(1) FROM (
+			SELECT
+				A.*
+				, B.GOODS_NM
+				, B.BRAND_CD
+				, C.OPT_CD1
+				, C.OPT_CD2
+			FROM
+				SHOPLINKER_SYNC_HST A
+				INNER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+				INNER JOIN TB_OPTION C ON A.GOODS_CD = C.GOODS_CD AND A.OPT_CD = C.OPT_CD
+			WHERE A.API_TYPE = 'STOCK'
+
+			<include refid="getListCondition_sql"/>
+		) A
+	</select>
+
+	<!-- 재고전송-목록 -->
+	<select id="getStockList" parameterType="ShoplinkerSearch" resultType="ShoplinkerGoods">
+		/* TsaShoplinker.getStockList */
+		SELECT * FROM
+		(
+			SELECT
+				A.API_TYPE
+				, A.API_RESULT
+				, A.API_MESSAGE
+				, A.GOODS_CD
+				, A.OPT_CD
+				, A.QTY as QUANTITY
+				, A.REG_DT
+				, B.GOODS_NM
+				, B.BRAND_CD
+				, C.OPT_CD1
+				, C.OPT_CD2
+			FROM
+				SHOPLINKER_SYNC_HST A
+				INNER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+				INNER JOIN TB_OPTION C ON A.GOODS_CD = C.GOODS_CD AND A.OPT_CD = C.OPT_CD
+			WHERE A.API_TYPE = 'STOCK'
+
+			<include refid="getListCondition_sql"/>
+		) A
+		ORDER BY A.REG_DT DESC, A.GOODS_CD, A.OPT_CD
+
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+	</select>
+
+	<!-- 재고- 목록 엑셀 -->
+	<select id="getStockExcelList" parameterType="ShoplinkerSearch" resultType="paramMap">
+	/* TsaShoplinker.getStockList */
+		SELECT
+			A.API_TYPE
+			, A.API_RESULT
+			, A.API_MESSAGE
+			, A.GOODS_CD
+			, A.OPT_CD
+			, A.QTY as QUANTITY
+			, A.REG_DT
+			, B.GOODS_NM
+			, B.BRAND_CD
+			, C.OPT_CD1
+			, C.OPT_CD2
+		FROM
+			SHOPLINKER_SYNC_HST A
+			INNER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+			INNER JOIN TB_OPTION C ON A.GOODS_CD = C.GOODS_CD AND A.OPT_CD = C.OPT_CD
+		WHERE A.API_TYPE = 'STOCK'
+		<include refid="getListCondition_sql"/>
+
+		ORDER BY A.REG_DT DESC, A.GOODS_CD, A.OPT_CD
+
+	</select>
+
+	<!-- 상품/재고 목록 조건 정보 -->
+	<sql id="getListCondition_sql">
+
+		        <if test="goodsCd != null and goodsCd != ''">
+		        AND UPPER(A.GOODS_CD) LIKE CONCAT('%',UPPER(#{goodsCd}),'%')
+		        </if>
+		    	<if test="conditionList != null and conditionList.length>0">
+		        AND UPPER(A.GOODS_CD) IN
+		            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+		       		UPPER(#{item})
+		            </foreach>
+		        </if>
+
+		        <if test="goodsNm != null and goodsNm != ''">
+		        AND UPPER(B.GOODS_NM) LIKE CONCAT('%',UPPER(#{goodsNm}),'%')
+		        </if>
+		        <if test="brandCd != null and brandCd != ''">
+		        AND BRAND_CD = #{brandCd}
+		        </if>
+		        <if test="multiBrand != null and multiBrand != ''">
+		        AND BRAND_CD IN
+		            <foreach collection="multiBrand" item="item" index="index"  open="(" close=")" separator=",">
+		        #{item}
+		            </foreach>
+		        </if>
+
+	            <if test="stDate != null and stDate != ''">
+		        AND A.REG_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+	            </if>
+	            <if test="edDate != null and edDate != ''">
+	            <![CDATA[
+		        AND A.REG_DT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+	            ]]>
+	            </if>
+
+		        <if test="apiType != null and apiType != ''">
+		        AND API_TYPE = #{apiType}
+		        </if>
+		        <if test="apiType == null or apiType == ''">
+		        AND API_TYPE in ('OPTION','PRODUCT','NOTI','CERT','IMAGE')
+		        </if>
+
+		        <if test="apiResult != null and apiResult != ''">
+		        AND API_RESULT = #{apiResult}
+		        </if>
+
+	</sql>
+
+	<!-- 샵링커주문수집-목록 건수 cnt -->
+	<select id="getShoplinkerOrderListCount" parameterType="ShoplinkerOrder" resultType="int">
+		/* TsaShoplinker.getShoplinkerOrderListCount */
+		select count(1) from (
+			SELECT
+				A.*
+				, B.VENDOR_ID
+				, B.EXTMALL_ID
+				, B.EXTMALL_NM
+				, B.AGENT_ORDER_ID
+				, B.EXTMALL_ORDER_ID
+				, IFNULL(B.UPLOAD_STAT, 'G021_50') AS UPLOAD_STAT
+				, B.UPLOAD_FAIL_CD
+				, B.UPLOAD_FAIL_REASON
+				, IFNULL(B.ORD_NO, '') AS ORD_NO
+				, B.DELV_ADDR_SQ
+			FROM SHOPLINKER_ORDER A
+				LEFT OUTER JOIN TB_EXTMALL_ORDER_UPLOAD B
+					ON A.SHOPLINKER_ORDER_ID = B.AGENT_ORDER_ID
+
+			WHERE 1=1
+			<include refid="getSlkOrderListCondition_sql"/>
+		) A
+
+	</select>
+
+	<!-- 샵링커주문수집-목록 -->
+	<select id="getShoplinkerOrderList" parameterType="ShoplinkerOrder" resultType="ShoplinkerOrder">
+		/* TsaShoplinker.getShoplinkerOrderList */
+		SELECT * FROM
+		(
+			SELECT
+				A.*
+				, B.VENDOR_ID
+				, B.EXTMALL_ID
+				, B.EXTMALL_NM
+				, B.AGENT_ORDER_ID
+				, B.EXTMALL_ORDER_ID
+				, IFNULL(B.UPLOAD_STAT, 'G021_50') AS UPLOAD_STAT
+				, B.UPLOAD_FAIL_CD
+				, B.UPLOAD_FAIL_REASON
+				, IFNULL(B.ORD_NO, '') AS ORD_NO
+				, B.DELV_ADDR_SQ
+				, B.REG_DT AS EXTMALL_REG_DT
+			FROM SHOPLINKER_ORDER A
+				LEFT OUTER JOIN TB_EXTMALL_ORDER_UPLOAD B
+					ON A.SHOPLINKER_ORDER_ID = B.AGENT_ORDER_ID
+			WHERE 1=1
+
+			<include refid="getSlkOrderListCondition_sql"/>
+		) A
+
+		ORDER BY EXTMALL_REG_DT, REG_DT DESC
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+
+	</select>
+
+	<!-- 샵링커주문수집-상세 -->
+	<select id="getShoplinkerOrderInfo" parameterType="ShoplinkerOrder" resultType="ShoplinkerOrder">
+		/* TsaShoplinker.getShoplinkerOrderInfo */
+		SELECT
+			ORDER_IF_IDX
+			, SHOPLINKER_ORDER_ID
+			, MALL_ORDER_ID
+			, MALL_NAME
+			, BAESONG_STATUS
+			, ORDER_NAME
+			, ORDER_TEL
+			, ORDER_CEL
+			, ORDER_EMAIL
+			, RECEIVE
+			, RECEIVE_TEL
+			, RECEIVE_CEL
+			, RECEIVE_ZIPCODE
+			, RECEIVE_ADDR
+			, BAESONG_TYPE
+			, BAESONG_BI
+			, DELIVERY_MSG
+			, ORDER_PRODUCT_ID
+			, SHOPLINKER_PRODUCT_ID
+			, PARTNER_PRODUCT_ID
+			, PRODUCT_NAME
+			, QUANTITY
+			, ORDER_PRICE
+			, SALE_PRICE
+			, SUPPLY_PRICE
+			, SKU
+			, STR_TO_DATE(ORDERDATE, '%Y%m%d%H%i%S') as ORDERDATE
+			, STR_TO_DATE(ORDER_REG_DATE, '%Y%m%d%H%i%S') as ORDER_REG_DATE
+			, DELIVERY_INVOICE
+			, ORDER_SEQ
+			, TOTAL_COUNT
+			, TOTAL_PAGE
+			, TOTAL_STANDARD_COUNT
+			, CURRENTLY_PAGE
+			, CURRENTLY_COUNT
+			, SELLER_ID
+			, ONLY_SKU
+			, ADD_SKU
+			, MALL_ID
+			, DIS_PRICE_MALL
+			, DIS_PRICE_SELLER
+			, DIS_PRICE_COUPON
+			, DIS_PRICE_POINT
+			, DISTRIBUTION_DELIVERY
+			, SKU_MATCH_CODE
+			, SKU_BARCODE
+			, ORDER_CUSTOMS_NUMBER
+			, ORDER_INPUT_TYPE
+			, SUPPLY_ID
+			, DELIVERY
+			, ORDER_USER_ID
+			, CRSPIK_USE
+			, SHIP_NO
+			, DEAL_NO
+			, EXCHANGE_ORDER_YN
+			, ORDER_MAIN_KEY
+			, PAN_TYPE
+			, CHANNEL_TYPE
+			, SHIP_RSV_DATE
+			, ORDER_FLAG
+			, EXTMALL_REG_YN
+			, REG_DT
+		FROM SHOPLINKER_ORDER
+		WHERE SHOPLINKER_ORDER_ID = #{shoplinkerOrderId}
+	</select>
+
+	<!-- 제휴몰 주문등록 상세 -->
+	<select id="getExtmallOrderInfo" parameterType="String" resultType="ExtmallOrder">
+		/* TsaShoplinker.getExtmallOrderInfo */
+		SELECT
+			A.*
+			, FN_GET_USER_NM(A.REG_NO) AS REG_NM
+			, FN_GET_CODE_NM('G021', UPLOAD_STAT) AS UPLOAD_STAT_NM
+			, FN_GET_CODE_NM('G022', UPLOAD_FAIL_CD) AS UPLOAD_FAIL_NM
+			, FN_GET_CODE_NM('G003', A.VENDOR_ID) AS VENDOR_NM
+		FROM TB_EXTMALL_ORDER_UPLOAD A
+		WHERE AGENT_ORDER_ID = #{agentOrderId}
+		AND A.UPLOAD_GB = 'S'
+
+	</select>
+
+	<!-- 샵링커주문수집-목록엑셀 -->
+	<select id="getOrderExcelList" parameterType="ShoplinkerOrder" resultType="paramMap">
+		/* TsaShoplinker.getOrderExcelList */
+		SELECT * FROM
+		(
+			SELECT
+				A.*
+				, B.VENDOR_ID
+				, B.EXTMALL_ID
+				, B.EXTMALL_NM
+				, B.AGENT_ORDER_ID
+				, B.EXTMALL_ORDER_ID
+				, FN_GET_CODE_NM('G021', IFNULL(B.UPLOAD_STAT, 'G021_50')) AS UPLOAD_STAT
+				, FN_GET_CODE_NM('G022', B.UPLOAD_FAIL_CD) AS UPLOAD_FAIL_CD
+				, B.UPLOAD_FAIL_REASON
+				, IFNULL(B.ORD_NO, '') AS ORD_NO
+				, B.DELV_ADDR_SQ
+				, B.REG_DT AS EXTMALL_REG_DT
+			FROM SHOPLINKER_ORDER A
+				LEFT OUTER JOIN TB_EXTMALL_ORDER_UPLOAD B
+					ON A.SHOPLINKER_ORDER_ID = B.AGENT_ORDER_ID
+			WHERE 1=1
+
+			<include refid="getSlkOrderListCondition_sql"/>
+		) A
+
+		ORDER BY EXTMALL_REG_DT, REG_DT DESC
+
+	</select>
+
+	<!-- 샵링커주문수집 조건 정보 -->
+	<sql id="getSlkOrderListCondition_sql">
+
+			<if test="stDate != null and stDate != ''">
+	        AND A.ORDER_REG_DATE >= DATE_FORMAT(replace(#{stDate}, '-', ''), '%Y%m%d%H%i%S')
+            </if>
+            <if test="edDate != null and edDate != ''">
+            <![CDATA[
+	        AND A.ORDER_REG_DATE < DATE_FORMAT(DATE_ADD(replace(#{edDate}, '-', ''), INTERVAL 1 DAY), '%Y%m%d%H%i%S')
+            ]]>
+            </if>
+
+			<if test="extmallId != null and extmallId != ''">
+	        AND A.MALL_ID = #{extmallId}
+	        </if>
+
+			<if test="uploadStat != null and uploadStat != ''">
+	        AND B.UPLOAD_STAT = #{uploadStat}
+	        </if>
+	        <if test="uploadFailCd != null and uploadFailCd != ''">
+	        AND B.UPLOAD_FAIL_CD = #{uploadFailCd}
+	        </if>
+
+	        <if test='conditionList != null and conditionList.length>0'>
+	            <choose>
+	              <when test='search != null and search == "shoplinkerOrderId"'>
+	              	AND UPPER(A.SHOPLINKER_ORDER_ID) IN
+			            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+			       		UPPER(#{item})
+			            </foreach>
+	              </when>
+
+	              <when test='search != null and search == "mallOrderId"'>
+	              	AND UPPER(B.EXTMALL_ORDER_ID) IN
+			            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+			       		UPPER(#{item})
+			            </foreach>
+	              </when>
+
+	              <when test='search != null and search == "ordNo"'>
+	              	AND UPPER(B.ORD_NO) IN
+			            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+			       		UPPER(#{item})
+			            </foreach>
+	              </when>
+	            </choose>
+	        </if>
+	</sql>
+
+	<!-- 송장전송-전송 목록 건수 cnt -->
+	<select id="getSendInvoiceListCount" parameterType="ShoplinkerInvoice" resultType="int">
+		/* TsaShoplinker.getSendInvoiceListCount */
+		select count(1) from (
+			SELECT
+				OD.ORD_NO
+				, OD.ORD_DTL_NO
+				, (SELECT SHIP_COMP_NM FROM TB_SHIP_COMPANY S WHERE S.SHIP_COMP_CD = OD.SHIP_COMP_CD ) AS SHIP_COMP_NM
+				, OD.SHIP_COMP_CD AS DELIVERY_CODE-- 배송업체(택배사코드)
+				, OD.INVOICE_NO AS DELIVERY_INVOICE-- 송장번호
+
+				, OD.VENDOR_ID -- 외부몰벤더ID
+				, OD.EXTMALL_ID -- 외부몰ID(외부몰)
+				, OD.AGENT_ORDER_ID -- 에이전트주문번호
+				, OD.EXTMALL_ORDER_ID -- 외부몰주문번호
+				, OD.DELV_ASSIGN_STAT -- 출고지정상태(P:대기,Y:수락,N:거부)
+				, OD.ORD_EXCH_GB -- 주문교환구분(O:주문,E:교환)
+				, OD.ORD_DTL_STAT -- 주문상세상태(공통코드G013)
+				, FN_GET_CODE_NM('G013', OD.ORD_DTL_STAT) AS ORD_DTL_STAT_NM
+				, OD.DELV_STDT
+
+				, SL.API_RESULT
+				, SL.API_MESSAGE
+				, SL.XML_TXT
+				, FN_GET_USER_NM(SL.REG_NO) AS REG_NM
+			FROM
+				TB_ORDER_DETAIL OD
+				LEFT OUTER JOIN SHOPLINKER_SYNC_HST SL ON OD.ORD_DTL_NO = SL.ORD_DTL_NO AND SL.API_TYPE = 'INVOICE'
+			WHERE OD.VENDOR_ID = 'G003_V001'
+			ORDER BY OD.ORD_NO, OD.ORD_DTL_NO
+		) A
+		WHERE 1=1
+		<include refid="getSlkInvoiceCondition_sql"/>
+
+	</select>
+
+	<!-- 송장전송-전송 목록 -->
+	<select id="getSendInvoiceList" parameterType="ShoplinkerInvoice" resultType="ShoplinkerInvoice">
+		/* TsaShoplinker.getSendInvoiceList */
+		SELECT * FROM
+		(
+			SELECT
+				OD.ORD_NO
+				, OD.ORD_DTL_NO
+				, (SELECT SHIP_COMP_NM FROM TB_SHIP_COMPANY S WHERE S.SHIP_COMP_CD = OD.SHIP_COMP_CD ) AS SHIP_COMP_NM
+				, OD.SHIP_COMP_CD AS DELIVERY_CODE-- 배송업체(택배사코드)
+				, OD.INVOICE_NO AS DELIVERY_INVOICE-- 송장번호
+
+				, OD.VENDOR_ID -- 외부몰벤더ID
+				, OD.EXTMALL_ID -- 외부몰ID(외부몰)
+				, OD.AGENT_ORDER_ID -- 에이전트주문번호
+				, OD.EXTMALL_ORDER_ID -- 외부몰주문번호
+				, OD.DELV_ASSIGN_STAT -- 출고지정상태(P:대기,Y:수락,N:거부)
+				, OD.ORD_EXCH_GB -- 주문교환구분(O:주문,E:교환)
+				, OD.ORD_DTL_STAT -- 주문상세상태(공통코드G013)
+				, FN_GET_CODE_NM('G013', OD.ORD_DTL_STAT) AS ORD_DTL_STAT_NM
+				, OD.DELV_STDT
+
+				, SL.API_RESULT
+				, SL.API_MESSAGE
+				, SL.XML_TXT
+				, SL.REG_DT
+			FROM
+				TB_ORDER_DETAIL OD
+				LEFT OUTER JOIN SHOPLINKER_SYNC_HST SL ON OD.ORD_DTL_NO = SL.ORD_DTL_NO AND SL.API_TYPE = 'INVOICE'
+			WHERE OD.VENDOR_ID = 'G003_V001'
+			ORDER BY OD.ORD_NO, OD.ORD_DTL_NO
+		) A
+		WHERE 1=1
+		<include refid="getSlkInvoiceCondition_sql"/>
+
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+	</select>
+
+	<!-- 송장전송-전송 목록 엑셀 -->
+	<select id="getInvoiceExcelList" parameterType="ShoplinkerInvoice" resultType="paramMap">
+		/* TsaShoplinker.getInvoiceExcelList */
+		SELECT * FROM
+		(
+			SELECT
+				OD.ORD_NO
+				, OD.ORD_DTL_NO
+				, (SELECT SHIP_COMP_NM FROM TB_SHIP_COMPANY S WHERE S.SHIP_COMP_CD = OD.SHIP_COMP_CD ) AS SHIP_COMP_NM
+				, OD.SHIP_COMP_CD AS DELIVERY_CODE-- 배송업체(택배사코드)
+				, OD.INVOICE_NO AS DELIVERY_INVOICE-- 송장번호
+
+				, OD.VENDOR_ID -- 외부몰벤더ID
+				, OD.EXTMALL_ID -- 외부몰ID(외부몰)
+				, OD.AGENT_ORDER_ID -- 에이전트주문번호
+				, OD.EXTMALL_ORDER_ID -- 외부몰주문번호
+				, OD.DELV_ASSIGN_STAT -- 출고지정상태(P:대기,Y:수락,N:거부)
+				, OD.ORD_EXCH_GB -- 주문교환구분(O:주문,E:교환)
+				, OD.ORD_DTL_STAT -- 주문상세상태(공통코드G013)
+				, FN_GET_CODE_NM('G013', OD.ORD_DTL_STAT) AS ORD_DTL_STAT_NM
+				, OD.DELV_STDT
+
+				, SL.API_RESULT
+				, SL.API_MESSAGE
+				, SL.XML_TXT
+				, SL.REG_DT
+			FROM
+				TB_ORDER_DETAIL OD
+				LEFT OUTER JOIN SHOPLINKER_SYNC_HST SL ON OD.ORD_DTL_NO = SL.ORD_DTL_NO AND SL.API_TYPE = 'INVOICE'
+			WHERE OD.VENDOR_ID = 'G003_V001'
+			ORDER BY OD.ORD_NO, OD.ORD_DTL_NO
+		) A
+		WHERE 1=1
+		<include refid="getSlkInvoiceCondition_sql"/>
+
+	</select>
+
+	<!-- 상품 목록 조건 정보 -->
+	<sql id="getSlkInvoiceCondition_sql">
+
+			<if test="stDate != null and stDate != ''">
+	        AND DELV_STDT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+            </if>
+            <if test="edDate != null and edDate != ''">
+            <![CDATA[
+	        AND DELV_STDT < DATE_FORMAT(DATE_ADD(#{edDate}, INTERVAL 1 DAY), '%Y-%m-%d %H:%i:%S')
+            ]]>
+            </if>
+
+            <if test="extmallId != null and extmallId != ''">
+	        AND EXTMALL_ID = #{extmallId}
+            </if>
+
+	        <if test='apiResult != null and apiResult != "" and apiResult != "default"'>
+	        AND API_RESULT = #{apiResult}
+	        </if>
+	        <if test='apiResult != null and apiResult == "default"'>
+	        AND API_RESULT != 'true'
+	        </if>
+
+			<if test='conditionList != null and conditionList.length>0'>
+	            <choose>
+	              <when test='search != null and search == "agentOrderId"'>
+	              	AND UPPER(A.AGENT_ORDER_ID) IN
+			            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+			       		UPPER(#{item})
+			            </foreach>
+	              </when>
+
+	              <when test='search != null and search == "extmallOrderId"'>
+	              	AND UPPER(A.EXTMALL_ORDER_ID) IN
+			            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+			       		UPPER(#{item})
+			            </foreach>
+	              </when>
+
+	              <when test='search != null and search == "ordNo"'>
+	              	AND UPPER(A.ORD_NO) IN
+			            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+			       		UPPER(#{item})
+			            </foreach>
+	              </when>
+
+	              <when test='search != null and search == "deliveryInvoice"'>
+	              	AND UPPER(A.DELIVERY_INVOICE) IN
+			            <foreach collection="conditionList" item="item" index="index"  open="(" close=")" separator=",">
+			       		UPPER(#{item})
+			            </foreach>
+	              </when>
+
+	            </choose>
+	        </if>
+	</sql>
+
+</mapper>
+
+

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

@@ -215,8 +215,8 @@
 		<if test="socialSq != null and socialSq != ''">
 		AND A.SOCIAL_SQ != #{socialSq}
 		</if>
-		AND A.SOCIAL_STDT <![CDATA[ <= ]]> DATE_FORMAT(#{socialStdt} , '%Y-%m-%d %H:%i:%S')
-		AND A.SOCIAL_EDDT <![CDATA[ >= ]]> DATE_FORMAT(#{socialStdt} , '%Y-%m-%d %H:%i:%S');
+		AND A.SOCIAL_STDT <![CDATA[ >= ]]> DATE_FORMAT(#{socialStdt} , '%Y-%m-%d %H:%i:%S')
+		AND A.SOCIAL_STDT <![CDATA[ <= ]]> DATE_FORMAT(#{socialStdt} , '%Y-%m-%d %H:%i:%S');
 	</select>
 	
 	

+ 5 - 5
src/main/java/com/style24/persistence/mybatis/shop/TsaWithdraw.xml

@@ -225,11 +225,11 @@
 							, O.CUST_NO 
 							, CASE WHEN A.PAY_GB = 'NAVER' THEN 'Y' ELSE 'N' END AS PAY_GB  
 							, A.ORDER_EXCEPTION_NO 
-							, ''   AS CHG_STAT
-							, NULL AS ORD_CHG_SQ 
-							, ''   AS WD_GB 
-							, NULL AS CHG_REASON
-							, NULL AS CHG_GB 
+							, NULL   AS CHG_STAT
+							, NULL   AS ORD_CHG_SQ 
+							, NULL   AS WD_GB 
+							, NULL   AS CHG_REASON
+							, NULL   AS CHG_GB 
 						  FROM TB_ORDER_RECALL_EXCEPTION A 
 						  JOIN TB_ORDER_RECALL_EXCEPTION_ITEM B ON A.RECALL_EXCEPTION_NO = B.RECALL_EXCEPTION_NO
 						  LEFT JOIN TB_ORDER O ON O.ORD_NO = A.ORDER_NO 

+ 4 - 4
src/main/webapp/WEB-INF/views/board/FaqDetailForm.html

@@ -161,8 +161,8 @@
 	</div>
 </div>
 
-<script type="text/javascript" src="/ux/plugins/summernote/summernote.js?v=2020103001"></script>
-<script type="text/javascript" src="/ux/plugins/gaga/gaga.summernote.js?v=2021053101"></script>
+<!-- <script type="text/javascript" src="/ux/plugins/summernote/summernote.js?v=2020103001"></script>
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.summernote.js?v=2021053101"></script> -->
 <script th:inline="javascript">
 /*<![CDATA[*/
 	// 저장
@@ -190,8 +190,8 @@
 	
 	$(document).ready(function() {
 		// Create a summernote
-		let snOptions = gagaSn.getToolbarOptions();
-		gagaSn.createSummernote(snOptions, '#answer');
+		//let snOptions = gagaSn.getToolbarOptions();
+		//gagaSn.createSummernote(snOptions, '#answer');
 	});
 /*]]>*/
 </script>

+ 3 - 1
src/main/webapp/WEB-INF/views/customer/CustomerDormantListForm.html

@@ -45,6 +45,7 @@
 						<td class="dashR">
 							<select name="searchGb">
 								<option value="">선택</option>
+								<option value="custNo">회원번호</option>
 								<option value="custNm">회원명 </option>
 								<option value="email">이메일</option>
 								<option value="custId">아이디</option>
@@ -122,6 +123,7 @@
 			valueGetter: function (params) { return gagaAgGrid.lookupValue(siteList, params.data.siteCd); }
 		},
 		{headerName: "회원ID", field:'maskingCustId', width:120, cellClass: 'text-left'},
+		{headerName: "회원NO", field: "custNo", width: 120, cellClass: 'text-center'},
 		{headerName: "회원명", field:'maskingCustNm', width:100, cellClass: 'text-left'},
 		{headerName: "핸드폰", field:'maskingCellPhnno', width:140, cellClass: 'text-center'},
 		{headerName: "이메일", field:'maskingEmail', width:220, cellClass: 'text-left'},
@@ -137,6 +139,7 @@
 
 	// Get GridOptions
 	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+		gridOptions.rowSelection = 'multiple';
 
 	// 셀 클릭 이벤트
 	gridOptions.onCellClicked = function(event) {
@@ -178,7 +181,6 @@
 			sureBtnText: "확인",
 			sureBtnClick: function() {
 				var jsonData = JSON.stringify(removedData);
-				console.log(jsonData);
 				gagajf.ajaxJsonSubmit('/customer/dormant/release', jsonData, function() {
 					fnSearch();
 				});

+ 108 - 83
src/main/webapp/WEB-INF/views/customer/CustomerSecedeListForm.html

@@ -24,96 +24,98 @@
 	<div class="infoBox menu-desc">
 	</div>
 	<!-- //메뉴 설명 -->
+	<form id="custSecedeForm" name="custSecedeForm" action="#" th:action="@{'/customer/secede/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+				<table class="frmStyle" aria-describedby="검색조건">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col style="width:15%;"/>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col/>
+					</colgroup>
+					<tbody>
+					<tr>
+						<th class="dashR">검색구분</th>
+						<td class="dashR">
+							<select name="searchGb">
+								<option value="">선택</option>
+								<option value="custNo">회원번호</option>
+								<option value="custNm">회원명 </option>
+								<option value="email">이메일</option>
+								<option value="custId">아이디</option>
+							</select>
+							<input type="text" class="w200" name="searchTxt" id="searchTxt"/>
+						</td>
+						<th class="dashR">사이트</th>
+						<td class="dashR">
+							<select name="siteCd">
+								<option value="">전체</option>
+								<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">탈퇴사유</th>
+						<td class="dashR">
+							<select name="secedeRsn" class="w200">
+								<option value="">전체</option>
+								<option th:if="${secedeRsnList}" th:each="oneData, status : ${secedeRsnList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
+							</select>
+						</td>
+						<th class="dashR">휴대폰번호(숫자만)</th>
+						<td class="dashR">
+							<input type="text" class="w200" name="cellPhnno" id="cellPhnno" maxlength="13"/>
+						</td>
+					</tr>
+					<tr>
+						<th class="dashR">탈퇴일</th>
+						<td class="dashR" colspan="3" id="terms">
+						</td>
+					</tr>
+					</tbody>
+				</table>
 
-	<!-- 검색조건 영역 -->
-	<div class="panelStyle">
-		<form id="custSecedeForm" name="custSecedeForm" action="#" th:action="@{'/customer/secede/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
-			<table class="frmStyle" aria-describedby="검색조건">
-				<colgroup>
-					<col style="width:10%;"/>
-					<col style="width:20%;"/>
-					<col style="width:10%;"/>
-					<col style="width:15%;"/>
-					<col style="width:10%;"/>
-					<col style="width:20%;"/>
-					<col/>
-				</colgroup>
-				<tbody>
-				<tr>
-					<th class="dashR">검색구분</th>
-					<td class="dashR">
-						<select name="searchGb">
-							<option value="">선택</option>
-							<option value="custNm">회원명 </option>
-							<option value="email">이메일</option>
-							<option value="custId">아이디</option>
-						</select>
-						<input type="text" class="w200" name="searchTxt" id="searchTxt"/>
-					</td>
-					<th class="dashR">사이트</th>
-					<td class="dashR">
-						<select name="siteCd">
-							<option value="">전체</option>
-							<option th:if="${siteList}" th:each="oneData, status : ${siteList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
-						</select>
-					</td>
-				</tr>
-				<tr>
-					<th class="dashR">탈퇴사유</th>
-					<td class="dashR">
-						<select name="secedeRsn" class="w200">
-							<option value="">전체</option>
-							<option th:if="${secedeRsnList}" th:each="oneData, status : ${secedeRsnList}" th:value="${oneData.cd}" th:text="|[${oneData.cd}] ${oneData.cdNm}|"></option>
-						</select>
-					</td>
-					<th class="dashR">휴대폰번호(숫자만)</th>
-					<td class="dashR">
-						<input type="text" class="w200" name="cellPhnno" id="cellPhnno" maxlength="13"/>
-					</td>
-				</tr>
-				<tr>
-					<th class="dashR">탈퇴일</th>
-					<td class="dashR" colspan="3" id="terms">
-					</td>
-				</tr>
-				</tbody>
-			</table>
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+						<button type="button" class="btn btn-gray btn-lg" onclick="$('#custSecedeForm')[0].reset();">초기화</button>
+					</li>
+				</ul>
+		</div>
+		<!-- //검색조건 영역 -->
 
+		<!-- 리스트 영역 -->
+		<div class="panelStyle">
+			<ul class="panelBar">
+				<li>
+					<button type="button" class="btn btn-danger btn-lg" id="btnDelete">탈퇴이력삭제</button>
+				</li>
+				<li class="right">
+					검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
+					쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
+					<select id="pageSize" name="pageSize">
+						<option value="50" selected="selected">50개씩 보기</option>
+						<option value="100">100개씩 보기</option>
+						<option value="500">500개씩 보기</option>
+						<option value="1000">1000개씩 보기</option>
+					</select>
+					<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
+				</li>
+			</ul>
+			<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
 			<ul class="panelBar">
 				<li class="center">
-					<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
-					<button type="button" class="btn btn-gray btn-lg" onclick="$('#custSecedeForm')[0].reset();">초기화</button>
+					<div class="tablePaging" id="custListPagination"></div>
 				</li>
 			</ul>
-		</form>
-	</div>
-	<!-- //검색조건 영역 -->
-
-	<!-- 리스트 영역 -->
-	<div class="panelStyle">
-		<ul class="panelBar">
-			<li class="right">
-				검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
-				쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
-				<select id="pageSize" name="pageSize">
-					<option value="50" selected="selected">50개씩 보기</option>
-					<option value="100">100개씩 보기</option>
-					<option value="500">500개씩 보기</option>
-					<option value="1000">1000개씩 보기</option>
-				</select>
-				<input type="hidden" name="pageNo" id="pageNo" value ="1"/>
-			</li>
-		</ul>
-		<div id="gridList" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
-		<ul class="panelBar">
-			<li class="center">
-				<div class="tablePaging" id="custListPagination"></div>
-			</li>
-		</ul>
-	</div>
-	<!-- //리스트 영역 -->
+		</div>
+		<!-- //리스트 영역 -->
+	</form>
 </div>
-
 <script type="text/javascript" th:src="@{'/ux/plugins/gaga/gaga.paging.js?v=' + ${#calendars.format(#calendars.createNow(), 'yyyyMMddHHmmss')}}" src="/ux/plugins/gaga/gaga.paging.js"></script>
 <script th:inline="javascript">
 	/*<![CDATA[*/
@@ -122,11 +124,13 @@
 
 	// specify the columns
 	const columnDefs = [
+		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
 		{
 			headerName: "사이트", field:'siteCd', width:100, cellClass: 'text-center',
 			valueGetter: function (params) { return gagaAgGrid.lookupValue(siteList, params.data.siteCd); }
 		},
 		{headerName: "회원ID", field:'maskingCustId', width:120, cellClass: 'text-left'},
+		{headerName: "회원NO", field: "custNo", width: 120, cellClass: 'text-center'},
 		{headerName: "회원명", field:'maskingCustNm', width:100, cellClass: 'text-left'},
 		{headerName: "핸드폰", field:'maskingCellPhnno', width:140, cellClass: 'text-center'},
 		{headerName: "이메일", field:'maskingEmail', width:220, cellClass: 'text-left'},
@@ -142,6 +146,7 @@
 
 	// Get GridOptions
 	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+		gridOptions.rowSelection = 'multiple';
 
 	// 셀 클릭 이벤트
 	gridOptions.onCellClicked = function(event) {
@@ -206,6 +211,26 @@
 
 	}
 
+	// 탈퇴이력 삭제
+	$('#btnDelete').on('click', function() {
+		var removedData = gagaAgGrid.removeRowData(gridOptions);
+
+		if (removedData.length == 0) {
+			mcxDialog.alert('선택된 행이 없습니다.');
+			return;
+		}
+
+		mcxDialog.alertC('탈퇴이력 삭제 하시겠습니까?', {
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+				var jsonData = JSON.stringify(removedData);
+				gagajf.ajaxJsonSubmit('/customer/secede/delete', jsonData, function() {
+					fnSearch();
+				});
+			}
+		});
+	});
+
 	// 검색
 	var fnSearch = function() {
 		// 유효성 체크

+ 7 - 1
src/main/webapp/WEB-INF/views/display/MainContentsPopupForm.html

@@ -885,6 +885,11 @@
 		$("#mcTable"+tableDataId).find("tr[name=linkPopRow]").find("input[name=link]").val('/planning/detail/form?planSq='+result[0].planSq);
 		$("#mcTable"+tableDataId).find("tr[id=mobImgPop]").find("input[name=imgPath]").val(result[0].mainPimg);
 		if(!gagajf.isNull(result[0].mainPimg)){
+			let pcImgIdx = $("#mcTable"+tableDataId).find('.pcImg').find('input[name=imgIdx]').attr('pcImg-idx');
+			if(contentsLoc=='SOM001'){
+				$("#mcTable"+tableDataId).find('.pcImg').find("#bannerPreViewUrlPop_"+pcImgIdx).attr('src', $("#uploadDefaultUrlPop").val().replace('/contents/', '')+result[0].mainPimg);
+				$("#mcTable"+tableDataId).find('.pcImg').find("#imgViewPop_"+pcImgIdx).removeClass("off").addClass("on");
+			}
 			$("#mcTable"+tableDataId).find('.mobImg').find("#bannerPreViewUrlPop_"+tableDataId).attr('src', $("#uploadDefaultUrlPop").val().replace('/contents/', '')+result[0].mainPimg);
 			$("#mcTable"+tableDataId).find('.mobImg').find("#imgViewPop_"+tableDataId).removeClass("off").addClass("on");
 		}
@@ -1381,7 +1386,8 @@
 			src = $("#uploadDefaultUrlPop").val().replace('/contents/', '')+param;
 			imgPath = param;
 		}
-		var html = '<tr name="imgPopRow">';
+		var html = '<tr class="pcImg" name="imgPopRow">';
+		html += '<input type="hidden" name="imgIdx" pcImg-idx="'+imgIndex+'" />';
 		if(idx>1){
 			html += '<th>모바일용 이미지';
 		}else{

+ 106 - 9
src/main/webapp/WEB-INF/views/goods/GoodsDetailForm.html

@@ -159,7 +159,7 @@
 										</td>
 									</tr>
 									<tr>
-										<td rowspan="13">&nbsp;</td>
+										<td rowspan="14">&nbsp;</td>
 										<th>시즌<em class="required" title="필수"></em></th>
 										<td >
 											<select  name="seasonCd" id="seasonCd">
@@ -290,16 +290,24 @@
 											<input type="hidden" id="returnableYnOrg" name="returnableYnOrg"/>
 										</td>
 										<th>교환여부<em class="required" title="필수"></em></th>
-										<td>
+										<td colspan="3">
 											<label class="rdoBtn"><input type="radio" name="changeableYn" id="changeableYnY" value="Y" />Y</label>
 											<label class="rdoBtn"><input type="radio" name="changeableYn" id="changeableYnN" value="N"/>N</label>
 											<input type="hidden" id="changeableYnOrg" name="changeableYnOrg"/>
 										</td>
+										
+									</tr>
+									<tr>
 										<th>신규가입구매가능여부<em class="required" title="필수"></em></th>
-										<td>
+										<td colspan="5">
 											<label class="rdoBtn"><input type="radio" name="newCustOrdYn" id="newCustOrdYnY" value="Y" />Y</label>
 											<label class="rdoBtn"><input type="radio" name="newCustOrdYn" id="newCustOrdYnN" value="N"/>N</label>
 											<input type="hidden" id="newCustOrdYnOrg" name="newCustOrdYnOrg"/>
+											<input name="newCustOrdStdt" id="newCustOrdStdt" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="판매시작일" />
+											<input type="hidden" id="newCustOrdStdtOrg" name="newCustOrdStdtOrg"/>
+											~
+											<input name="newCustOrdEddt" id="newCustOrdEddt" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="판매 종료일" />
+											<input type="hidden" id="newCustOrdEddtOrg" name="newCustOrdEddtOrg"/>
 										</td>
 									</tr>
 									<tr>
@@ -1043,6 +1051,17 @@
 			$("#goodsDetailForm input[name=changeableYnOrg]").val(result.changeableYn);
 			$("#goodsDetailForm input[name=returnableYnOrg]").val(result.returnableYn);
 			$("#goodsDetailForm input[name=newCustOrdYnOrg]").val(result.newCustOrdYn);
+			
+			if(!gagajf.isNull(result.newCustOrdStdt)){
+				$('#goodsDetailForm input[name=newCustOrdStdt]').val(result.newCustOrdStdt.toDate("YYYYMMDD").format("YYYY-MM-DD") );
+				$('#goodsDetailForm input[name=newCustOrdEddt]').val(result.newCustOrdEddt.toDate("YYYYMMDD").format("YYYY-MM-DD") );	
+				$('#goodsDetailForm input[name=newCustOrdStdtOrg]').val(result.newCustOrdStdt.toDate("YYYYMMDD").format("YYYY-MM-DD") );
+				$('#goodsDetailForm input[name=newCustOrdEddtOrg]').val(result.newCustOrdEddt.toDate("YYYYMMDD").format("YYYY-MM-DD") );
+			}else{
+				$('#goodsDetailForm input[name=newCustOrdStdtOrg]').val('');
+				$('#goodsDetailForm input[name=newCustOrdEddtOrg]').val('');
+			}
+			
 			$("#goodsDetailForm input[name=adultYnOrg]").val(result.adultYn);
 			$("#goodsDetailForm input[name=tobeFormYnOrg]").val(result.tobeFormYn);
 			
@@ -1675,6 +1694,46 @@
 			return false;
 		}
 		
+		//신규가입기간 
+		if ("Y" == $("#goodsDetailForm input[name=newCustOrdYn]:checked").val()){
+			if(isNaN(Date.parse($("#goodsDetailForm input[name=newCustOrdStdt]").val()))){
+				mcxDialog.alertC('날짜형식이 아닙니다.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsDetailForm input[name=newCustOrdStdt]").focus();
+					}
+				});	
+				return false;
+			}
+			
+			if(isNaN(Date.parse($("#goodsDetailForm input[name=newCustOrdEddt]").val()))){
+				mcxDialog.alertC('날짜형식이 아닙니다.', {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$("#goodsDetailForm input[name=newCustOrdEddt]").focus();
+					}
+				});	
+				return false;
+			}
+			
+			var fromDate = $('#goodsDetailForm input[name=newCustOrdStdt]').val();
+			var toDate = $('#goodsDetailForm input[name=newCustOrdEddt]').val();
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("신규가입일의 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#goodsDetailForm input[name=newCustOrdStdt]').focus();
+					}
+				});
+				return false;
+			}
+			
+		}else{
+			$('#goodsDetailForm input[name=newCustOrdStdt]').val('');
+			$('#goodsDetailForm input[name=newCustOrdEddt]').val('');
+		}
+		
 		// 출고처
 		if(gagajf.isNull($("#goodsDetailForm select[name=delvLocCd]").val())){
 			mcxDialog.alertC("출고처를 선택해 주세요.", {
@@ -1811,11 +1870,12 @@
 			return false;
 		}
 		
+		//판매기간
 		if(isNaN(Date.parse($("#goodsDetailForm input[name=sellStYMD]").val()))){
 			mcxDialog.alertC('날짜형식이 아닙니다.', {
 				sureBtnText: "확인",
 				sureBtnClick: function() {
-					$("#goodsDealForm input[name=sellStYMD]").focus();
+					$("#goodsDetailForm input[name=sellStYMD]").focus();
 				}
 			});	
 			return false;
@@ -1825,12 +1885,25 @@
 			mcxDialog.alertC('날짜형식이 아닙니다.', {
 				sureBtnText: "확인",
 				sureBtnClick: function() {
-					$("#goodsDealForm input[name=sellEdYMD]").focus();
+					$("#goodsDetailForm input[name=sellEdYMD]").focus();
 				}
 			});	
 			return false;
 		}
 		
+		var fromDate = $("#goodsDetailForm input[name=sellStYMD]").val().replaceAll('-', '')+ $("#goodsDetailForm select[name=sellStHH]").val();
+		var toDate = $("#goodsDetailForm input[name=sellEdYMD]").val().replaceAll('-', '')+ $("#goodsDetailForm select[name=sellEdHH]").val();
+
+		if (fromDate > toDate) {
+			mcxDialog.alertC("판매기간의 시작일시는 종료일시 보다 클 수 없습니다.", {
+				sureBtnText: "확인",
+				sureBtnClick: function() {
+					$('#goodsDetailForm input[name=sellStYMD]').focus();
+				}
+			});
+			return false;
+		}
+		
 		idx = 0;
 
 		//재고 옵션 관련 확인
@@ -1964,9 +2037,16 @@
 		
 		//인증번호 있는데 인증작업 했는지 여부 확인
 		if (!gagajf.isNull($("#goodsDetailForm input[name=certNum]").val())){
-			if (gagajf.isNull($('#goodsDetailForm').find('#certStateTxt').text())){
-				mcxDialog.alert("안전인증작업을 하거나 인증번호를 확인해주세요.");
-				return false;
+			
+			if ("G084_4" == $("#goodsDetailForm select[name=certFormGb]").val() || 
+				"G084_5" == $("#goodsDetailForm select[name=certFormGb]").val() || 
+				"G081_3" == $("#goodsDetailForm select[name=certType]").val()) {
+				
+			}else{
+				if (gagajf.isNull($('#goodsDetailForm').find('#certStateTxt').text())){
+					mcxDialog.alert("안전인증작업을 하거나 인증번호를 확인해주세요.");
+					return false;
+				}
 			}
 		}
 		
@@ -2325,6 +2405,15 @@
 		if ($("#goodsDetailForm input[name=newCustOrdYnOrg]").val() != $("#goodsDetailForm input[name=newCustOrdYn]:checked").val()){
 			return true;
 		}
+		// 신규가입기간 시작일
+		if ($("#goodsDetailForm input[name=newCustOrdStdt]").val() != $("#goodsDetailForm input[name=newCustOrdStdtOrg]").val()){
+			return true;
+		}
+		// 신규가입기간 종료일
+		if ($("#goodsDetailForm input[name=newCustOrdEddt]").val() != $("#goodsDetailForm input[name=newCustOrdEddtOrg]").val()){
+			return true;
+		}
+		
 		// 성인용품여부
 		if ($("#goodsDetailForm input[name=adultYnOrg]").val() != $("#goodsDetailForm input[name=adultYn]:checked").val()){
 			return true;
@@ -2427,7 +2516,15 @@
 		if (result == null) return;
 		$("#goodsDetailForm input[name=niClsfCd]").val(result[0].niClsfCd)
 	}
-
+	
+	//신규가입구매가능여부 변경시
+	$('#goodsDetailForm input[name=newCustOrdYn]').on('change', function() {
+		var newCustOrdYn = $("#goodsDetailForm input[name=newCustOrdYn]:checked").val();
+		if ("N" == newCustOrdYn){
+			$("#goodsDetailForm input[name=newCustOrdStdt]").val('');
+			$("#goodsDetailForm input[name=newCustOrdEddt]").val('');
+		}
+	});	
 	
 	// 안전인증
 	$("#btnGoodsSafetyCertNum").on("click", function(){

+ 1 - 0
src/main/webapp/WEB-INF/views/goods/GoodsPopupListForm.html

@@ -270,6 +270,7 @@
 				}else{
 					return  params.value.replaceAll("&gt;", ">");
 				}
+			}
 		},
 		{headerName: "전시재고", field: "stockQtySum", width: 100, cellClass: 'text-right',
 			valueFormatter: function(params) {	return params.value.addComma();}

+ 12 - 2
src/main/webapp/WEB-INF/views/ocm/ExtmallForm.html

@@ -112,6 +112,13 @@
 								<option th:if="${supplyCompList}" th:each="oneData, status : ${supplyCompList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
 							</select>
 						</td>
+
+						<th>고객센터연락처</th>
+						<td>
+							<input type="text" class="w150" name="extmallTel" maxlength="20"/>
+						</td>
+						<td colspan="4"></td>
+						<!-- 숨김처리 사용안하기로 함
 						<th>판매매장코드</th>
 						<td>
 							<input type="text" class="w150" name="sellStoreCd" maxlength="20"/>
@@ -124,6 +131,7 @@
 						<td>
 							<input type="text" class="w100 aR" name="priceAcceptRate" maxlength="3" required="required" data-valid-type="real" data-valid-name="가격차이허용율"/>%
 						</td>
+						 -->
 					</tr>
 					<tr>
 						<th>직접회수여부</th>
@@ -181,9 +189,10 @@
 			headerName: "업체", field: "supplyCompCd", width: 150, cellClass: 'text-center',
 			valueGetter: function (params) { return gagaAgGrid.lookupValue(supplyCompList, params.data.supplyCompCd); }
 		},
-		{headerName: "판매매장코드", field: "sellStoreCd", width: 120, cellClass: 'text-center'},
+		{headerName: "고객센터연락처", field: "extmallTel", width: 150, cellClass: 'text-center'},
+		/* {headerName: "판매매장코드", field: "sellStoreCd", width: 120, cellClass: 'text-center'},
 		{headerName: "재고판매비율(%)", field: "stockSellRate", width: 150, cellClass: 'text-center'},
-		{headerName: "가격차이허용율(%)", field: "priceAcceptRate", width: 150, cellClass: 'text-center'},
+		{headerName: "가격차이허용율(%)", field: "priceAcceptRate", width: 150, cellClass: 'text-center'}, */
 		{
 			headerName: "직접회수여부", field: "dwdpYn", width: 150, cellClass: 'text-center',
 			cellRenderer: function (params) {
@@ -215,6 +224,7 @@
 		$('#detailForm input[name=extmallId]').val(event.data.extmallId);
 		$('#detailForm input[name=extmallUserId]').val(event.data.extmallUserId);
 		$('#detailForm input[name=extmallNm]').val(event.data.extmallNm);
+		$('#detailForm input[name=extmallTel]').val(event.data.extmallTel);
 		$('#detailForm select[name=supplyCompCd]').val(event.data.supplyCompCd);
 		$('#detailForm input[name=sellStoreCd]').val(event.data.sellStoreCd);
 		$('#detailForm input[name=stockSellRate]').val(event.data.stockSellRate);

+ 32 - 9
src/main/webapp/WEB-INF/views/ocm/ExtmallOrderRegisterForm.html

@@ -76,11 +76,22 @@
 		{headerName: "상품코드",			field: "goodsCd",				width: 150, cellClass: 'text-center'},
 		{headerName: "상품명",			field: "sku",					width: 150, cellClass: 'text-center'},
 		{headerName: "옵션코드",			field: "optCd",					width: 150, cellClass: 'text-center'},
-		{headerName: "판매금액",			field: "currPrice",				width: 100, cellClass: 'text-center'},
-		{headerName: "할인금액",			field: "cpnDcAmt",				width: 100, cellClass: 'text-center'},
+		{headerName: "판매금액", 			field: "currPrice",				width: 100, cellClass: 'text-center'
+			,valueFormatter: function(params) {return params.value.addComma();},
+			cellEditor: 'textCellEditor',
+			cellEditorParams: { maxlength: 14, validType: 'numeric'}
+		},
 		{headerName: "주문수량",			field: "ordQty",				width: 100, cellClass: 'text-center'},
-		{headerName: "주문금액",			field: "ordAmt",				width: 200, cellClass: 'text-center'},
-		{headerName: "배송비",			field: "delvFee",				width: 100, cellClass: 'text-center'},
+		{headerName: "주문금액", 			field: "ordAmt", 				width: 100, cellClass: 'text-center'
+			,valueFormatter: function(params) {return params.value.addComma();},
+			cellEditor: 'textCellEditor',
+			cellEditorParams: { maxlength: 14, validType: 'numeric'}
+		},
+		{headerName: "배송비", 			field: "delvFee", 				width: 100, cellClass: 'text-center'
+			,valueFormatter: function(params) {return params.value.addComma();},
+			cellEditor: 'textCellEditor',
+			cellEditorParams: { maxlength: 14, validType: 'numeric'}
+		},
 		{headerName: "주문자",			field: "ordNm",					width: 100, cellClass: 'text-center'},
 		{headerName: "주문자전화번호",		field: "ordTelno",				width: 130, cellClass: 'text-center'},
 		{headerName: "주문자핸드폰번호",		field: "ordPhnno",				width: 130, cellClass: 'text-center'},
@@ -114,11 +125,23 @@
 
 	//엑셀업로드 클릭 시
 	$('#btnExcelUpload').on('click', function() {
-		if( click_bool ){
-			cfnExcelUploadPopup('createExtmallOrder', 'createExtmallOrder');
-		}else{
-			mcxDialog.alert("주문등록 처리중입니다. 잠시후 시도해주세요.");
-		}
+
+		var alertMsg = "<span style='color:red'>※ 테스트 주의 ※ <br>품절시 알림톡이 발송되오니, <br>연락처는 자신의 핸드폰번호 또는 010-0000-000으로 넣어주세요.</span>";
+		mcxDialog.confirm(alertMsg, {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+
+				if( click_bool ){
+					cfnExcelUploadPopup('createExtmallOrder', 'createExtmallOrder');
+				}else{
+					mcxDialog.alert("주문등록 처리중입니다. 잠시후 시도해주세요.");
+				}
+
+			}
+		});
+
+
 	});
 
 	//주문등록 클릭 시

+ 411 - 0
src/main/webapp/WEB-INF/views/order/CnclCompleteView.html

@@ -0,0 +1,411 @@
+<!DOCTYPE html>
+<html lang="ko" xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : CnclCompleteView.html
+ * @desc    : 취소완료정보화면
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2019 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.06.30   jsh77b       최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="1400" data-height="600">
+	<div class="panelStyle">
+		<div class="panelTitle">
+			<h2>취소완료</h2>
+			<button type="button" class="close" onclick="uifnPopupClose('popupCancelRequestForm');"><i class="fa fa-times"></i></button>
+		</div>
+			
+		<div class="panelContent" style="height:90%; overflow-y:auto; padding:0px 20px !important; ">
+			<form id="cancelRequestFrm" name="cancelRequestFrm">
+			
+				<h4 id="orderInfoTitle">취소완료정보</h4>
+				<div id="gridCnclRtnCompleteList" style="width:100%; height: 200px;" class="ag-theme-balham"></div>
+
+				<div style="text-align:right; padding-bottom:5px; padding-top:5px;">
+					<button type="button" class="btn btn-success" id="cnclCompleteBtn" onclick="fnCnclReq('cnclComplete');">확인</button>
+				</div>
+				
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:160px;" />
+						<col style="width:320px;" />
+						<col style="width:160px;" />
+						<col />
+					</colgroup>
+					<tbody>
+						<tr>
+							<th>취소사유 <i class="star"></i></th>
+							<td id="chgReasonNm"></td>
+							<th>귀책사유</th>
+							<td><span id="imputeReason"></span></td>
+						</tr>
+						<tr>
+							<th>요청메모</th>
+							<td colspan="3">
+								<textarea id="chgMemo" name="chgMemo" style="height:80px;" placeholder="취소사유를 300자내외로 작성해 주세요"></textarea>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+				
+				<h4>환불예정금액</h4>
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:20%;"/>
+						<col style="width:30%;"/>
+						<col style="width:20%;"/>
+						<col style="width:30%;"/>
+					</colgroup>
+					<tbody>
+						<tr>
+							<th>상품 주문 금액</th>
+							<td><span id="spanOrdAmt"></span>원</td>
+							<th>상품 취소 금액</th>
+							<td><span id="spanCnclRtnAmt"></span>원</td>
+						</tr>
+						<tr>
+							<th>포인트 취소 금액</th>
+							<td colspan="3"><span id="spanTotPntDcAmt"></span>원 (고객 포인트 : <span id="spanPntDcAmt"></span>원 + 상품 선포인트 : <span id="spanPrePntDcAmt"></span>원) </td>
+						</tr>
+						<tr>
+							<th>쿠폰 취소 금액</th>
+							<td colspan="3"><span id="spanCpnDcAmt"></span>원 (즉시할인쿠폰 : <span id="spanCpn1DcAmt"></span>원 + 상품쿠폰 : <span id="spanGoodsCpnDcAmt"></span>원 + 장바구니쿠폰 : <span id="spanCartCpnDcAmt"></span>원 + 배송비쿠폰 : <span id="spanDelvCpnDcAmt"></span>원)</td>
+						</tr>
+						<tr>
+							<th>다다익선 취소 금액</th>
+							<td colspan="3"><span id="spanTmtbDcAmt"></span>원 (수량할인 : <span id="spanTmtb1DcAmt"></span>원 + 금액할인 : <span id="spanTmtb2DcAmt"></span>원)</td>
+						</tr>
+						<tr>
+							<th>상품권 취소 금액</th>
+							<td colspan="3"><span id="spanGfcdUseAmt"></span>원</td>
+						</tr>
+						<tr>
+							<th>상품 실결제 취소 금액</th>
+							<td><span id="spanRealCnclRtnAmt"></span>원</td>
+							<th>추가 배송비 금액</th>
+							<td><span id="spanTotDeliveryFee"></span>원 </td>
+						</tr>
+						
+						<tr>
+							<th>환불 예정 금액</th>
+							<td colspan="3"><span id="spanRefundAmt"></span>원</td>
+						</tr>
+					</tbody>
+				</table>
+				
+				<div id="refundAccount" style="width:100%">
+					<h4>환불계좌정보</h4>
+					<button type="button" id="btnSaveAccount" class="btn btnRight btn-base btn-sm" style="margin-left:10px;" onclick="fnCreateOrderRfAccount();">등록</button>
+					
+					<!-- TABLE -->
+					<table class="tableStyle">
+						<colgroup>
+							<col width="">
+							<col width="">
+							<col width="">
+							<col width="">
+							<col width="">
+						</colgroup>
+						<thead>
+							<tr>
+								<th>은행명</th>
+								<th>은행코드</th>
+								<th>계좌번호</th>
+								<th>예금주</th>
+								<th>기본여부</th>
+							</tr>
+						</thead>
+						<tbody>
+							<tr style="height:30px;">
+								<td class="bankNm"></td>
+								<td class="bankCd"></td>
+								<td class="accountNo"></td>
+								<td class="accountNm"></td>
+								<td class="defaultYn"></td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+				<br>
+			</form>
+		</div>
+	</div>
+</div>
+
+<!-- data -->
+<script th:inline="javascript">
+/*<![CDATA[*/
+var cnclRtnCompleteList 	= [[${cnclRtnCompleteList}]];				// 취소,반품 완료 정보 목록
+var orderInfoList 			= [[${orderInfoList}]];						// 취소,반품 완료 정보 목록
+var pgGb 					= orderInfoList[0].pgGb;					// 결제수단
+var payMeans 				= orderInfoList[0].payMeans;				// 결제방법
+var addPayCost				= cnclRtnCompleteList[0].addPayCost;		// 추가배송비
+var realDelvAmt				= cnclRtnCompleteList[0].realDelvAmt;		// 환불배송비
+var delvCpnDcAmt			= cnclRtnCompleteList[0].delvCpnDcAmt;		// 배송비쿠폰환불
+var chgReason				= cnclRtnCompleteList[0].chgReason;			// 변경사유코드
+var chgReasonNm				= cnclRtnCompleteList[0].chgReasonNm;		// 변경사유코드명
+var chgMemo					= cnclRtnCompleteList[0].chgMemo;			// 변경사유메모
+var raBankNm				= cnclRtnCompleteList[0].raBankNm;			// 환불계좌은행명
+var raBank					= cnclRtnCompleteList[0].raBank;			// 환불계좌은행코드
+var raNo					= cnclRtnCompleteList[0].raNo;				// 환불계좌번호
+var raNm					= cnclRtnCompleteList[0].raNm;				// 환불계좌명
+
+// 1. 취솨,반품완료 정보 목록 조회
+var columnCnclRtnCompleteList = [
+	{headerName: "주문번호"		, field: "ordNo"			, width: 80		, cellClass: 'text-center'},
+	{headerName: "주문상세"		, field: "ordDtlNo"			, width: 80		, cellClass: 'text-center'},
+	{headerName: "상품코드"		, field: "goodsCd"			, width: 100	, cellClass: 'text-left'},
+	{headerName: "상품명"			, field: "goodsNm"			, width: 200	, cellClass: 'text-left'},
+	{headerName: "상품타입"		, field: "goodsTypeNm"		, width: 100	, cellClass: 'text-center'},
+	{
+		headerName		: "주문"
+		, field			: "ordQty"
+		, width			: 80
+		, cellClass		: 'text-center'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "취소"
+		, field			: "cnclRtnQty"
+		, width			: 80
+		, cellClass		: 'text-center'
+		, cellRenderer	: function (params) {
+			var cnclRtnReqQty = parseInt(params.data.cnclRtnQty) + parseInt(params.data.ordReqChgQty);
+			return cnclRtnReqQty;
+		}
+	},
+	{
+		headerName		: "주문"
+		, field			: "ordAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "취소"
+		, field			: "cnclRtnAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "즉시할인"
+		, field			: "cpn1DcAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "다다익선1"
+		, field			: "tmtb1DcAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "다다익선2"
+		, field			: "tmtb2DcAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "상품쿠폰"		
+		, field			: "goodsCpnDcAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "장바구니쿠폰"
+		, field			: "cartCpnDcAmt"
+		, width			: 100		
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "포인트"
+		, field			: "pntDcAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "선포인트"
+		, field			: "prePntDcAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "상품권"
+		, field			: "gfcdUseAmt"
+		, width			: 80
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	},
+	{
+		headerName		: "실결제금액"
+		, field			: "realOrdAmt"
+		, width			: 100		
+		, cellClass		: 'text-right'
+		, cellRenderer	: function (params) {
+			return params.value.addComma();
+		}
+	}
+];
+var gridOptionsCnclRtnCompleteList = gagaAgGrid.getGridOptions(columnCnclRtnCompleteList);
+
+// Add on options
+gridOptionsCnclRtnCompleteList.suppressRowClickSelection = true;
+gridOptionsCnclRtnCompleteList.rowSelection = 'multiple';
+</script>
+
+<script>
+// 현재 사유는 고객 입니다.
+var isCustomer = true;
+
+//  사유
+var fnChangeChgReason = function(reasonCd){
+	var customerReasonArr = ['G686_10', 'G686_20'];
+
+	isCustomer = false;
+	
+	// 귀책사유체크(취소,반품,교환)
+	for (i=0 ; i<customerReasonArr.length ; i++) {
+		if (customerReasonArr[i] == reasonCd) {
+			isCustomer = true;
+		}
+	}
+	
+	// 귀책사유설정
+	if (isCustomer) {
+		$("#imputeReason").text("고객");
+	} else {
+		$("#imputeReason").text("회사");
+	}
+
+	$('#cancelRequestFrm input[name=chgReason]').val(reasonCd);
+}
+
+$(document).ready(function() {
+	
+	// 1. 그리드생성
+	gagaAgGrid.createGrid('gridCnclRtnCompleteList'		, gridOptionsCnclRtnCompleteList);			// 주문정보
+	
+	// 2. 그리드 데이타 싱크작업
+	gridOptionsCnclRtnCompleteList.api.setRowData(cnclRtnCompleteList);								// 주문정보
+	
+	// 2.1 TOTAL ROWS 없애기
+	gagaAgGrid.hideStatusBar('gridCnclRtnCompleteList');
+
+	// 3. 무통장입금아닌경우 환불계좌 그리드 숨김처리
+	if (payMeans !== 'G014_20') {
+		$('#refundAccount').addClass("off");
+	} else {
+		$("#refundAccount .bankNm").text(raBankNm);
+		$("#refundAccount .bankCd").text(raBank);
+		$("#refundAccount .accountNo").text(raNo);
+		$("#refundAccount .accountNm").text(raNm);
+	}
+	
+	// 4. 변경사유설정
+	$("#chgReasonNm").text(chgReasonNm);
+	$("#chgMemo").text(chgMemo);
+	$("#chgMemo").attr("disabled", "true");
+	fnChangeChgReason(chgReason);
+	
+	// 5. 환불에정금액 
+	var spanOrdAmt 			= 0;
+	var spanCnclRtnAmt 		= 0;
+	var spanTotPntDcAmt		= 0;
+	var spanPntDcAmt		= 0;
+	var spanPrePntDcAmt		= 0;
+	var spanCpnDcAmt		= 0;
+	var spanCpn1DcAmt		= 0;
+	var spanGoodsCpnDcAmt	= 0;
+	var spanCartCpnDcAmt	= 0;
+	var spanTmtbDcAmt		= 0;
+	var spanTmtb1DcAmt		= 0;
+	var spanTmtb2DcAmt		= 0;
+	var spanGfcdUseAmt		= 0;
+	var spanRealCnclRtnAmt	= 0;
+	var spanTotDeliveryFee	= addPayCost;
+	var spanRefundAmt		= 0;
+	
+	for (i=0 ; i<cnclRtnCompleteList.length ; i++) {
+		spanOrdAmt 				= spanOrdAmt 			+ cnclRtnCompleteList[i].ordAmt;
+		spanCnclRtnAmt 			= spanCnclRtnAmt 		+ cnclRtnCompleteList[i].cnclRtnAmt;
+		spanPntDcAmt			= spanPntDcAmt			+ cnclRtnCompleteList[i].pntDcAmt;
+		spanPrePntDcAmt			= spanPrePntDcAmt		+ cnclRtnCompleteList[i].prePntDcAmt;
+		spanCpn1DcAmt 			= spanCpn1DcAmt 		+ cnclRtnCompleteList[i].cpn1DcAmt;
+		spanGoodsCpnDcAmt 		= spanGoodsCpnDcAmt 	+ cnclRtnCompleteList[i].goodsCpnDcAmt;
+		spanCartCpnDcAmt 		= spanCartCpnDcAmt 		+ cnclRtnCompleteList[i].cartCpnDcAmt;
+		spanTmtb1DcAmt 			= spanTmtb1DcAmt 		+ cnclRtnCompleteList[i].tmtb1DcAmt;
+		spanTmtb2DcAmt 			= spanTmtb1DcAmt 		+ cnclRtnCompleteList[i].tmtb2DcAmt;
+		spanGfcdUseAmt 			= spanGfcdUseAmt 		+ cnclRtnCompleteList[i].gfcdUseAmt;
+		spanRealCnclRtnAmt 		= spanRealCnclRtnAmt 	+ cnclRtnCompleteList[i].realOrdAmt;
+	}
+	
+	spanTotPntDcAmt	= spanPntDcAmt + spanPrePntDcAmt;
+	spanCpnDcAmt	= spanCpn1DcAmt + spanGoodsCpnDcAmt + spanCartCpnDcAmt + delvCpnDcAmt;
+	spanTmtbDcAmt	= spanTmtb1DcAmt + spanTmtb2DcAmt;
+	spanRefundAmt	= spanRealCnclRtnAmt + realDelvAmt;
+	
+	$("#spanOrdAmt").text(spanOrdAmt.addComma());
+	$("#spanCnclRtnAmt").text(spanCnclRtnAmt.addComma());
+	$("#spanTotPntDcAmt").text(spanTotPntDcAmt.addComma());
+	$("#spanPntDcAmt").text(spanPntDcAmt.addComma());
+	$("#spanPrePntDcAmt").text(spanPrePntDcAmt.addComma());
+	$("#spanPntDcAmt").text(spanPntDcAmt.addComma());
+	$("#spanCpn1DcAmt").text(spanCpn1DcAmt.addComma());
+	$("#spanGoodsCpnDcAmt").text(spanGoodsCpnDcAmt.addComma());
+	$("#spanCartCpnDcAmt").text(spanCartCpnDcAmt.addComma());
+	$("#spanDelvCpnDcAmt").text(delvCpnDcAmt.addComma());
+	$("#spanCpnDcAmt").text(spanCpnDcAmt.addComma());
+	$("#spanTmtb1DcAmt").text(spanTmtb1DcAmt.addComma());
+	$("#spanTmtb2DcAmt").text(spanTmtb2DcAmt.addComma());
+	$("#spanTmtbDcAmt").text(spanTmtbDcAmt.addComma());
+	$("#spanGfcdUseAmt").text(spanGfcdUseAmt.addComma());
+	$("#spanRealCnclRtnAmt").text(spanRealCnclRtnAmt.addComma());
+	$("#spanTotDeliveryFee").text(addPayCost.addComma());
+	$("#spanRefundAmt").text(spanRefundAmt.addComma());
+	
+	// 2021.05.13 높이자동조절
+	var cancelRequestTargetHeight = 50 + (40 * cnclRtnCompleteList.length);
+	$("#gridCnclRtnCompleteList").css("height" , cancelRequestTargetHeight+"px");
+});
+</script>
+</html>
+
+
+
+
+

+ 1 - 1
src/main/webapp/WEB-INF/views/order/CnclReqForm.html

@@ -847,7 +847,7 @@ var gridOptionsDelvCdList = gagaAgGrid.getGridOptions(columnDelvCdList);
 
 <script>
 // 현재 사유는 고객 입니다.
-var isCustomer = true;
+var isCustomer 	= true;
 var pgGb		= orderInfoList[0].pgGb;	// PG구분
 
 // 환불예상금액계산

+ 38 - 14
src/main/webapp/WEB-INF/views/order/OrderDetailForm.html

@@ -319,6 +319,7 @@ var columnDefsGoodsInfo = [
 							paramData 		+= '@' + params.data.ordDtlNo;
 							paramData 		+= '@' + params.data.delvFeeCd;
 							paramData 		+= '@' + params.data.delvFeeCdGrp;
+							paramData 		+= '@' + params.data.ordDtlStat;
 							retStr 			+= '<button type="button" class="btn btn-base btn-sm" onclick="fnCancelRequest(\'' + paramData + '\', null);">취소요청</button>';
 						}
 					}
@@ -330,6 +331,7 @@ var columnDefsGoodsInfo = [
 							paramData 		+= '@' + params.data.ordDtlNo;
 							paramData 		+= '@' + params.data.delvFeeCd;
 							paramData 		+= '@' + params.data.delvFeeCdGrp;
+							paramData 		+= '@' + params.data.ordDtlStat;
 														
 							if (params.data.changeableYn == 'Y') {
 								retStr 			+= '<button type="button" class="btn btn-base btn-sm" onclick="fnReturnRequest(\'' + paramData + '\', null);">반품요청</button>';
@@ -449,7 +451,7 @@ var columnDefsGoodsInfo = [
 				, width			: 80
 				, cellClass		: 'text-right'
 				, cellRenderer	: function (params) {
-					return "<a href=\"javascript:void(0);\" onclick=\"fnOrderPointHst('" + params.data.ordNo + "');\">" + params.value.addComma() + "</a>";
+					return params.value.addComma();
 				}
 			},
 			{
@@ -722,7 +724,9 @@ var columnDefsOrderChangeInfo = [
 			paramData 		+= '@' + params.data.ordDtlNo;
 			paramData 		+= '@' + params.data.delvFeeCd;
 			paramData 		+= '@' + params.data.delvFeeCdGrp;
+			paramData 		+= '@' + params.data.chgStat;
 			
+			/*
 			// 취소접수, 취소대기
 			if (params.data.chgStat == 'G685_10' || params.data.chgStat == 'G685_11') {
 				rtnStr = '<a href="javascript:void(0);" onclick="fnCancelRequest(\'' + paramData + '\',\'' + params.value + '\');">' + params.value + '</a>';
@@ -740,6 +744,25 @@ var columnDefsOrderChangeInfo = [
 			else {
 				rtnStr = params.value;
 			}
+			*/
+			
+			// 2021.06.29 변경구분값으로 변경
+			// 취소요청
+			if (params.data.chgGb == "G680_20") {
+				rtnStr = '<a href="javascript:void(0);" onclick="fnCancelRequest(\'' + paramData + '\',\'' + params.value + '\');">' + params.value + '</a>';
+			}
+			// 반품요청
+			else if (params.data.chgGb == "G680_30") {
+				rtnStr = '<a href="javascript:void(0);" onclick="fnReturnRequest(\'' + paramData + '\',\'' + params.value + '\');">' + params.value + '</a>';
+			}
+			// 교환요청
+			else if (params.data.chgGb == "G680_40") {
+				rtnStr = '<a href="javascript:void(0);" onclick="fnExchangeRequest(\'' + paramData + '\',\'' + params.value + '\');">' + params.value + '</a>';
+			}
+			else {
+				rtnStr = params.value;
+			}
+			
 			return  rtnStr;
 		}
 	},
@@ -775,19 +798,13 @@ var columnDefsOrderChangeInfo = [
 		, cellRenderer	: function (params) {
 			var rtnStr = ""
 			
-			// 회수지수정가능(교환요청, 반품요청)
-			if (params.data.wdGb != 'D' && (params.data.chgStat == 'G685_20' || params.data.chgStat == 'G685_21' || params.data.chgStat == 'G685_50' || params.data.chgStat == 'G685_51')) {
-				rtnStr += params.value;			
-				rtnStr += "<button type=\"button\" style=\"margin-left:10px\" class=\"btn btn-info\" onclick=\"fnOpenDaumAddr('" + params.node.rowIndex + "', 'CLAIM');\">POST</button>";
-				rtnStr += "<button type=\"button\" class=\"btn btn-info\" onclick=\"fnSaveChgerAddr('" + params.node.rowIndex + "');\">저장</button>";
+			// 2021.06.29 회수지, 배송지 정보 수정 교환, 반품 상세화면 수정 변경
+			if (params.data.wdGb == 'W' && (params.data.chgGb == 'G680_30' || params.data.chgGb == 'G680_40')) {
+				rtnStr += params.value;
 			} else {
-				if (params.data.chgGb == 'G680_30' || params.data.chgGb == 'G680_40') {
-					rtnStr += params.value;
-				} else {
-					rtnStr += "";
-				}
+				rtnStr += "";
 			}
-			
+
 			return rtnStr;
 		}
 	},
@@ -1110,10 +1127,16 @@ var fnCancelRequest = function (paramData, ordChgSq) {
 	param += "&ordDtlNo=" 		+ paramArr[1];
 	param += "&delvFeeCd="		+ paramArr[2];
 	param += "&delvFeeCdGrp="	+ paramArr[3];
+	param += "&chgStat="		+ paramArr[4];
 	param += "&ordChgSq=" 		+ ordChgSq;
 	
 	var actionUrl = "/orderChange/cncl/req/form?" + param;
 	
+	// 2021.06.30 취소완료일때 취소완료정보 조회
+	if (paramArr[4] == "G685_17" || paramArr[4] == "G685_18") {
+		actionUrl = "/orderChange/cnclRtn/complete/view?" + param;	
+	}
+
 	cfnOpenModalPopup(actionUrl, 'popupCancelRequestForm');
 	
 	return false;
@@ -1134,9 +1157,9 @@ var fnReturnRequest = function (paramData, ordChgSq) {
 	param += "&ordDtlNo=" 		+ paramArr[1];
 	param += "&delvFeeCd="		+ paramArr[2];
 	param += "&delvFeeCdGrp="	+ paramArr[3];
-	
+	param += "&chgStat="		+ paramArr[4];
 	param += "&ordChgSq=" 		+ ordChgSq;
-	//param += "&ordChgGb=G681_30";
+
 	var actionUrl = "/orderChange/rtn/req/form?" + param;
 	cfnOpenModalPopup(actionUrl, 'popupReturnRequestForm');
 };
@@ -1154,6 +1177,7 @@ var fnExchangeRequest = function (paramData, ordChgSq) {
 	param += "&ordDtlNo=" 		+ paramArr[1];
 	param += "&delvFeeCd="		+ paramArr[2];
 	param += "&delvFeeCdGrp="	+ paramArr[3];
+	param += "&chgStat="		+ paramArr[4];
 	param += "&ordChgSq=" 		+ ordChgSq;
 	//param += "&ordChgGb=G681_20";
 	var actionUrl = "/orderChange/exchange/request/form?" + param;

+ 93 - 65
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerGoodsSendForm.html

@@ -30,73 +30,76 @@
 			<div class="panelStyle">
 				<div class="panelTitle">
 					<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 상품코드나 등록일을 꼭 입력해 주세요.</h3>
+					<span class="panelControl">
+						<i class="fa fa-chevron-up"></i>
+					</span>
 				</div>
-				<table class="frmStyle">
-					<colgroup>
-						<col style="width: 10%;"/>
-						<col style="width: 40%;"/>
-						<col style="width: 10%;"/>
-						<col style="width: 40%;"/>
-						<!-- <col style="width: 10%;"/>
-						<col style="width: 20%;"/> -->
-					</colgroup>
-					<tr>
-						<th>전송일자<em class="required" title="필수"></em></th>
-						<td colspan="5" id="sellTerms"></td>
-					</tr>
-					<tr>
-						<th>상품코드<em class="required" title="필수"></em></th>
-						<td>
-							<textarea class="textareaR3 w20p" name="condition" id="condition"></textarea>
-						</td>
-
-						<th>브랜드</th>
-						<td>
-							<input type="text" class="w100" name="searchTxt" id="searchTxt" maxlength="20" />
-							<button type="button" class="btn icn" id="btnSearchBrand"><i class="fa fa-search"></i></button>
-							<!-- <input type="text" class="w100" name="brandCd" readonly="readonly"/> -->
-							<span id="brandText"></span>
-							<input type="hidden" name="brandList"/>
-						</td>
-					</tr>
-					<tr>
-						<th>API구분</th>
-						<td>
-							<select name="apiType" id="apiType" required="required" data-valid-name="API구분">
-								<option value="">[전체]</option>
-								<option value="OPTION">단품</option>
-								<option value="PRODUCT">상품</option>
-								<option value="NOTI">품목(고시)</option>
-								<option value="CERT">인증</option>
-								<option value="IMAGE">이미지</option>
-							</select>
-						</td>
-
-						<th>IF결과</th>
-						<td>
-							<select name="apiResult" id="apiResult">
-								<option value="">[전체]</option>
-								<option value="true">전송완료</option>
-								<option value="false">전송실패</option>
-								<option value="error">오류</option>
-							</select>
-						</td>
-					</tr>
-				</table>
 
-				<ul class="panelBar">
-					<li class="center">
-						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
-						<button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button>
-						<button type="button" class="btn btn-primary btn-lg" id="btnGoodsUpload">엑셀업로드</button>
-						<!-- <button type="button" class="btn btn-default btn-lg" onclick="fnGoodsExcelDownLoad('');">샵링커상품 엑셀다운로드</button> -->
-						<!-- <button type="button" class="btn btn-default btn-lg" onclick="fnGoodsExcelDownLoad('');">테스트</button> -->
-						<button th:if="${sessionInfo.userId == 'jmh'}" type="button" class="btn btn-default btn-lg" onclick="fnTest();">테스트</button>
-					</li>
-				</ul>
-
-				<p class="cRed">※ 엑셀업로드시 한번에 최대 500개까지 가능합니다.(적정량 250개 이하)</p>
-				<p class="cRed">※ 업로드 후 약 10분 후 결과를 조회해주세요. </p>
+				<div class="panelContent">
+					<table class="frmStyle">
+						<colgroup>
+							<col style="width: 10%;"/>
+							<col style="width: 40%;"/>
+							<col style="width: 10%;"/>
+							<col style="width: 40%;"/>
+							<!-- <col style="width: 10%;"/>
+							<col style="width: 20%;"/> -->
+						</colgroup>
+						<tr>
+							<th>전송일자<em class="required" title="필수"></em></th>
+							<td colspan="5" id="sellTerms"></td>
+						</tr>
+						<tr>
+							<th>상품코드<em class="required" title="필수"></em></th>
+							<td>
+								<textarea class="textareaR3 w30p" name="condition" id="condition"></textarea>
+							</td>
+
+							<th>브랜드</th>
+							<td>
+								<input type="text" class="w100" name="searchTxt" id="searchTxt" maxlength="20" />
+								<button type="button" class="btn icn" id="btnSearchBrand"><i class="fa fa-search"></i></button>
+								<!-- <input type="text" class="w100" name="brandCd" readonly="readonly"/> -->
+								<span id="brandText"></span>
+								<input type="hidden" name="brandList"/>
+							</td>
+						</tr>
+						<tr>
+							<th>API구분</th>
+							<td>
+								<select name="apiType" id="apiType" required="required" data-valid-name="API구분">
+									<option value="">[전체]</option>
+									<option value="OPTION">단품</option>
+									<option value="PRODUCT">상품</option>
+									<option value="NOTI">품목(고시)</option>
+									<option value="CERT">인증</option>
+									<option value="IMAGE">이미지</option>
+								</select>
+							</td>
+
+							<th>IF결과</th>
+							<td>
+								<select name="apiResult" id="apiResult">
+									<option value="">[전체]</option>
+									<option value="true">전송완료</option>
+									<option value="false">전송실패</option>
+									<option value="error">오류</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+
+					<ul class="panelBar">
+						<li class="center">
+							<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+							<button type="button" class="btn btn-gray btn-lg" id="btnInit">초기화</button>
+							<button type="button" class="btn btn-primary btn-lg" id="btnGoodsUpload">엑셀업로드</button>
+							<!-- <button th:if="${sessionInfo.userId == 'jmh'}" type="button" class="btn btn-default btn-lg" onclick="fnTest();">테스트</button> -->
+						</li>
+					</ul>
+					<p class="dot">엑셀업로드시 한번에 최대 500개까지 가능합니다. (적정량 250개 이하)</p>
+					<p class="dot">업로드 후 약 10분 이상 작업소요시간이 걸릴 수 있습니다.</p>
+				</div>
 			</div>
 			<!-- 검색조건 영역 -->
 
@@ -105,6 +108,7 @@
 				<ul class="panelBar">
 					<li>
 						<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF003');">엑셀업로드 양식 다운로드</button>
+						<button type="button" class="btn btn-default btn-lg" onclick="fnExcelDownLoad();">엑셀다운로드</button>
 					</li>
 					<li class="right">
 						검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
@@ -128,6 +132,8 @@
 				</ul>
 			</div>
 			<!-- //리스트 영역 -->
+
+			<a href="javascript:void(0);" id="ExcelList" style="display: none;">엑셀다운로드</a>
 		</form>
 
 	</div>
@@ -154,6 +160,7 @@
 		},
 		{headerName: "IF결과메세지", field: "apiMessage", width: 300, cellClass: 'text-left'},
 		{headerName: "자사 상품코드", field: "goodsCd", width: 150, cellClass: 'text-center'},
+		{headerName: "옵션코드", field: "optCd", width: 150, cellClass: 'text-center'},
 		{headerName: "상품명", field: "goodsNm", width: 300, cellClass: 'text-left'},
 		{headerName: "xml", field: "xmlTxt", width: 100, cellClass: 'text-center', editable: true,
 			cellEditor: 'agLargeTextCellEditor',
@@ -321,6 +328,15 @@
 	}
 	/**************** 검색 // *****************************************************/
 
+	/**************** 초기화 클릭시 *****************************************************/
+	$('#btnInit').on('click', function() {
+
+		$('#searchForm')[0].reset();
+		$("#multiBrand").empty();
+		$('#searchForm input[name=brandList]').val('');
+		$('#searchForm').find('#brandText').html('');
+	});
+	/**************** 초기화 클릭시 // *****************************************************/
 
 	/**************** 엑셀업로드 ********************************************************/
 	$('#btnGoodsUpload').on('click', function() {
@@ -348,6 +364,18 @@
 	}
 	/**************** 엑셀업로드 // *****************************************************/
 
+	/**************** 엑셀다운로드 *****************************************************/
+	var fnExcelDownLoad = function(){
+		var formId = '#searchForm';
+		if (gridOptions.api.getDisplayedRowCount() <= 0){
+			mcxDialog.alert("조회된 데이터가 없습니다.<br/>다시 조회 후 다운로드 받으세요.");
+			return;
+		}
+
+		var params =  $(formId).serialize();
+		$('#ExcelList').attr({ href : '/shoplinker/goods/excel/list?' + params }).get(0).click();
+	}
+	/**************** 엑셀다운로드 // *****************************************************/
 
 	/**************** 테스트용  *******************************************************/
     // 테스트- 실제 샵링커 호출

+ 104 - 61
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerInvoiceSendForm.html

@@ -30,71 +30,84 @@
 			<!-- 검색조건 영역 -->
 			<div class="panelStyle">
 				<div class="panelTitle">
-					<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 주문번호나 등록일을 꼭 입력해 주세요.</h3>
+					<h3>
+						<i class="fa fa-info-circle"></i>아래 검색조건 중 주문번호나 등록일을 꼭 입력해 주세요.
+						<br><i class="fa fa-info-circle"></i>[배치주기] 매일 1시간 마다실행
+					</h3>
+					<span class="panelControl">
+						<i class="fa fa-chevron-up"></i>
+					</span>
 				</div>
-				<table class="frmStyle">
-					<colgroup>
-						<col style="width:10%;"/>
-						<col/>
-						<col style="width:10%;"/>
-						<col style="width:13%;"/>
-						<col style="width:10%;"/>
-						<col style="width:22%;"/>
-					</colgroup>
-
-					<tr>
-						<th>배송시작일자</th>
-						<td colspan="5" id="sellTerms"></td>
-					</tr>
-					<tr>
-						<th>벤더/제휴몰</th>
-						<td>
-							<select name="vendorId" required="required" data-valid-name="벤더">
-								<option th:if="${vendorList}" th:each="oneData, status : ${vendorList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
-							</select>/
-							<select name="extmallId">
-								<option value="">[전체]</option>
-								<option th:if="${extmallList}" th:each="oneData, status : ${extmallList}" th:value="${oneData.extmallId}" th:text="${'[' + oneData.extmallId + '] ' + oneData.extmallNm}"></option>
-							</select>
-						</td>
-
-						<th>IF결과</th>
-						<td>
-							<select name="apiResult" id="apiResult">
-								<option value="">[전체]</option>
-								<option value="true">전송완료</option>
-								<option value="false">전송실패</option>
-								<option value="error">오류</option>
-							</select>
-						</td>
-						<th>키워드</th>
-						<td>
-							<select name="search" id="search">
-								<option value="agentOrderId">샵링커주문번호</option>
-								<option value="extmallOrderId">쇼핑몰주문번호</option>
-								<option value="ordNo">스타일24주문번호</option>
-							</select>
-							<textarea class="textareaR3 w40p" name="condition" id="condition"></textarea>
-						</td>
-					</tr>
-				</table>
-
-				<ul class="panelBar">
-					<li class="center">
-						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
-						<!-- <button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button> -->
-						<button type="button" class="btn btn-primary btn-lg" id="btnSendInvoice">송장전송</button>
-						<!-- <button type="button" class="btn btn-primary btn-lg" id="btnInvoiceUpload">엑셀업로드</button> -->
-					</li>
-				</ul>
-				<p class="cRed">※ 송장전송클릭시 > 약 10분 후 결과를 조회해주세요.(처리할 수량에 따라 소요시간이 늘어날 수 있습니다.)</p>
 
+				<div class="panelContent">
+					<table class="frmStyle">
+						<colgroup>
+							<col style="width:10%;"/>
+							<col/>
+							<col style="width:10%;"/>
+							<col style="width:13%;"/>
+							<col style="width:10%;"/>
+							<col style="width:22%;"/>
+						</colgroup>
+
+						<tr>
+							<th>배송시작일자</th>
+							<td colspan="5" id="sellTerms"></td>
+						</tr>
+						<tr>
+							<th>벤더/제휴몰</th>
+							<td>
+								<select name="vendorId" required="required" data-valid-name="벤더">
+									<option th:if="${vendorList}" th:each="oneData, status : ${vendorList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+								</select>/
+								<select name="extmallId">
+									<option value="">[전체]</option>
+									<option th:if="${extmallList}" th:each="oneData, status : ${extmallList}" th:value="${oneData.extmallId}" th:text="${'[' + oneData.extmallId + '] ' + oneData.extmallNm}"></option>
+								</select>
+							</td>
+
+							<th>IF결과</th>
+							<td>
+								<select name="apiResult" id="apiResult">
+									<option value="default">[전체-전송완료제외]</option>
+									<option value="">[전체]</option>
+									<option value="wait">전송예정</option>
+									<option value="true">전송완료</option>
+									<option value="false">전송실패</option>
+									<option value="error">오류</option>
+								</select>
+							</td>
+							<th>키워드</th>
+							<td>
+								<select name="search" id="search">
+									<option value="agentOrderId">샵링커주문번호</option>
+									<option value="extmallOrderId">쇼핑몰주문번호</option>
+									<option value="ordNo">스타일24주문번호</option>
+									<option value="deliveryInvoice">운송장번호</option>
+								</select>
+								<textarea class="textareaR3 w50p" name="condition" id="condition"></textarea>
+							</td>
+						</tr>
+					</table>
+
+					<ul class="panelBar">
+						<li class="center">
+							<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+							<button type="button" class="btn btn-gray btn-lg" id="btnInit">초기화</button>
+							<button type="button" class="btn btn-primary btn-lg" id="btnSendInvoice">송장전송</button>
+							<!-- <button type="button" class="btn btn-primary btn-lg" id="btnInvoiceUpload">엑셀업로드</button> -->
+						</li>
+					</ul>
+				</div>
 			</div>
 			<!-- 검색조건 영역 -->
 
 			<!-- 리스트 영역 -->
 			<div class="panelStyle">
 				<ul class="panelBar">
+					<li>
+						<button type="button" class="btn btn-default btn-lg" onclick="fnExcelDownLoad();">엑셀다운로드</button>
+					</li>
 					<li class="right">
 						검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
 						쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
@@ -117,6 +130,8 @@
 				</ul>
 			</div>
 			<!-- //리스트 영역 -->
+
+			<a href="javascript:void(0);" id="ExcelList" style="display: none;">엑셀다운로드</a>
 		</form>
 
 	</div>
@@ -135,6 +150,10 @@
 		{headerName: "No", width: 60, cellClass: 'text-center',
 			valueGetter: function(params) { return cfnGridNumner('searchForm',params.node.rowIndex, 'A');}
 		},
+		{headerName: "IF결과", field: "apiResult", width: 100, cellClass: 'text-center',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(procGbValue, params.value); }
+		},
+		{headerName: "전송결과메세지", field: "apiMessage", width: 380, cellClass: 'text-center'},
 		{headerName: "샵링커주문번호", field: "agentOrderId", width: 130, cellClass: 'text-center'},
 		{headerName: "쇼핑몰주문번호", field: "extmallOrderId", width: 130, cellClass: 'text-center'},
 		{
@@ -155,10 +174,6 @@
 		{headerName: "주문상세번호", field: "ordDtlNo", width: 130, cellClass: 'text-center'},
 		{headerName: "배송업체", field: "shipCompNm", width: 150, cellClass: 'text-center'},
 		{headerName: "송장번호", field: "deliveryInvoice", width: 130, cellClass: 'text-center'},
-		{headerName: "IF결과", field: "apiResult", width: 100, cellClass: 'text-center',
-			valueFormatter: function (params) { return gagaAgGrid.lookupValue(procGbValue, params.value); }
-		},
-		{headerName: "전송결과메세지", field: "apiMessage", width: 420, cellClass: 'text-center'},
 		{headerName: "전송일시", field: "regDt", width: 150, cellClass: 'text-center'}
 		/*{headerName: "xml", field: "xmlTxt", width: 100, cellClass: 'text-center', editable: true,
 			cellEditor: 'agLargeTextCellEditor',
@@ -269,6 +284,15 @@
 	}
 	/**************** 검색 // *****************************************************/
 
+	/**************** 초기화 클릭시 *****************************************************/
+	$('#btnInit').on('click', function() {
+
+		$('#searchForm')[0].reset();
+		$("#multiBrand").empty();
+		$('#searchForm input[name=brandList]').val('');
+		$('#searchForm').find('#brandText').html('');
+	});
+	/**************** 초기화 클릭시 // *****************************************************/
 
 	/**************** 송장전송 ********************************************************/
 	$('#btnSendInvoice').on('click', function() {
@@ -296,6 +320,25 @@
 		});
 	});
 
+	/**************** 엑셀다운로드 *****************************************************/
+	var fnExcelDownLoad = function(){
+		var formId = '#searchForm';
+		if (gridOptions.api.getDisplayedRowCount() <= 0){
+			mcxDialog.alert("조회된 데이터가 없습니다.<br/>다시 조회 후 다운로드 받으세요.");
+			return;
+		}
+
+		var fromDate = parseInt($('#searchForm input[name=stDate]').val().replaceAll("-", ""));
+		var toDate =parseInt($('#searchForm input[name=edDate]').val().replaceAll("-", ""));
+		if( 4 < (toDate - fromDate)){
+			mcxDialog.alert("배송시작일자를 3일 이내의 기간으로 설정 후 다운로드해주세요.");
+			return;
+		}
+
+		var params =  $(formId).serialize();
+		$('#ExcelList').attr({ href : '/shoplinker/invoice/excel/list?' + params }).get(0).click();
+	}
+	/**************** 엑셀다운로드 // *****************************************************/
 
 	/**************** 엑셀업로드 방식 ********************************************************/
 	/*

+ 5 - 0
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerOrderDetailForm.html

@@ -179,6 +179,11 @@
 			</table>
 			<!-- //TABLE -->
 			<br>
+
+			<!--
+				아래 4개 상점은 쇼핑몰주문번호를 배송번호로 대처함(같은 주문건은 배송번호로 알 수 있음)
+				APISHOP_0003 옥션 / APISHOP_0010 지마켓 / APISHOP_0286 카카오톡스토어 / APISHOP_0287 위메프
+			-->
 			<div th:if="${extOrderInfo}">
 				<h4>제휴몰 업로드정보</h4>
 				<!-- TABLE -->

+ 80 - 31
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerOrderForm.html

@@ -28,26 +28,34 @@
 		<form id="orderCollectionForm" name="orderCollectionForm" action="#" th:action="@{'/shoplinker/check/api_runable'}" th:method="post">
 
 			<div class="panelStyle">
-				<table class="frmStyle">
-					<colgroup>
-						<col style="width:10%;"/>
-						<col/>
-					</colgroup>
-					<tr>
-						<th>샵링커 주문수집일<em class="required" title="필수"></em></th>
-						<td colspan="7">
-							<input name="apiStDate" id="apiStDate" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="주문수집일" />
-							&nbsp;&nbsp;&nbsp;&nbsp;
-							<button th:if="${sessionInfo.userId == 'jmh'}" type="button" class="btn btn-primary btn-lg" id="btnCollection">주문수집</button>
-							&nbsp;<span class="runable_info"></span>
-						</td>
-					</tr>
-				</table>
-				<!-- <p class="cRed">※ 주문수집 시 샵링커에는 발주획인상태로 변경됩니다.</p> -->
-				<p class="cRed">※ 샵링커 주문수집 => 제휴몰 주문등록 => (제휴몰 주문등록 성공목록만) STYLE24에 주문등록이 됩니다.</p>
-				<p class="cRed">※ 샵링커 주문수집 시 동일한 목록은 '제휴몰 주문등록'이 되지 않습니다. </p>
-				<p class="cRed">※ 주문수집 건수가 많아질 수록 대기시간이 오래걸리므로 하루씩 수집합니다.</p>
-				<p class="cRed">※ [제휴몰 주문등록 상태]가 '미매핑'건은 옵션정보가 없는것으로 딜상품입니다.</p>
+				<div class="panelTitle">
+					<h3><i class="fa fa-info-circle"></i>[배치주기] 평일: 7시~15시 한시간 단위 / 7시: 전날 15 ~ 금일 6시 / 월요일 7시: 전주 금요일 15 ~ 금일 6시</h3>
+					<span class="panelControl">
+						<i class="fa fa-chevron-up"></i>
+					</span>
+				</div>
+
+				<div class="panelContent">
+					<table class="frmStyle">
+						<colgroup>
+							<col style="width:10%;"/>
+							<col/>
+						</colgroup>
+						<tr>
+							<th>샵링커 주문수집일<em class="required" title="필수"></em></th>
+							<td colspan="7">
+								<input name="apiStDate" id="apiStDate" type="text" class="w80 schDate" maxlength="10" required="required" data-valid-name="주문수집일" />
+								&nbsp;&nbsp;&nbsp;&nbsp;
+								<button th:if="${sessionInfo.userId == 'jmh'}" type="button" class="btn btn-primary btn-lg" id="btnCollection">주문수집</button>
+								&nbsp;<span class="runable_info"></span>
+							</td>
+						</tr>
+					</table>
+					<p class="dot">실패사유가 <font color="red">가용재고없음</font>일 경우 고객에게 일림이 발송된 건으로 엑셀업로드를 하지 말아주세요.</p>
+					<p class="dot">샵링커 주문수집 => 제휴몰 주문등록 => (제휴몰 주문등록 성공목록만) STYLE24에 주문등록이 됩니다.</p>
+					<p class="dot">샵링커 주문수집 시 동일한 목록은 '제휴몰 주문등록'이 되지 않습니다. </p>
+					<p class="dot">[제휴몰 주문등록 상태]가 <font color="red">미매핑</font>건은 옵션정보가 없는것으로 <font color="red">제휴몰주문업로드</font> 해주세요.(딜상품)</p>
+				</div>
 			</div>
 		</form>
 
@@ -114,8 +122,8 @@
 				<ul class="panelBar">
 					<li class="center">
 						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+						<button type="button" class="btn btn-gray btn-lg" id="btnInit">초기화</button>
 						<!-- <button type="button" class="btn btn-default btn-lg" onclick="fnTest();">테스트</button> -->
-						<!-- <button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button> -->
 					</li>
 				</ul>
 			</div>
@@ -124,6 +132,9 @@
 			<!-- 리스트 영역 -->
 			<div class="panelStyle">
 				<ul class="panelBar">
+					<li>
+						<button type="button" class="btn btn-default btn-lg" onclick="fnExcelDownLoad();">엑셀다운로드</button>
+					</li>
 					<li class="right">
 						검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
 						쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
@@ -146,6 +157,8 @@
 				</ul>
 			</div>
 			<!-- //리스트 영역 -->
+
+			<a href="javascript:void(0);" id="ExcelList" style="display: none;">엑셀다운로드</a>
 		</form>
 
 	</div>
@@ -207,7 +220,7 @@
 				}
 			}
 		},
-		{headerName: "쇼핑몰 주문번호", field: "mallOrderId", width: 130, cellClass: 'text-center'},
+		{headerName: "쇼핑몰 주문번호", field: "extmallOrderId", width: 130, cellClass: 'text-center'},
 		{headerName: "쇼핑몰 명", field: "mallName", width: 130, cellClass: 'text-center'},
 		{headerName: "배송상태[발주확인]", field: "baesongStatus", width: 130, cellClass: 'text-center'},
 		{headerName: "주문 상품번호", field: "orderProductId", width: 130, cellClass: 'text-center'},
@@ -219,8 +232,12 @@
 		{headerName: "판매단가", field: "salePrice", width: 130, cellClass: 'text-center'},
 		{headerName: "공급가", field: "supplyPrice", width: 130, cellClass: 'text-center'},
 		{headerName: "옵션명", field: "sku", width: 130, cellClass: 'text-center'},
-		{headerName: "주문일자", field: "orderdate", width: 130, cellClass: 'text-center'},
-		{headerName: "주문수집일자", field: "orderRegDate", width: 130, cellClass: 'text-center'},
+		{headerName: "주문수집일자", field: "orderRegDate", width: 150, cellClass: 'text-center',
+			cellRenderer: function(params) {
+				return !gagajf.isNull(params.value) ? params.value.toDate("YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss") : '';
+			}
+		},
+		{headerName: "제휴몰등록일", field: "extmallRegDt", width: 130, cellClass: 'text-center'}
 	];
 
 	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
@@ -337,6 +354,36 @@
 	}
 	/**************** 검색 // *****************************************************/
 
+	/**************** 초기화 클릭시 *****************************************************/
+	$('#btnInit').on('click', function() {
+
+		$('#searchForm')[0].reset();
+		$("#multiBrand").empty();
+		$('#searchForm input[name=brandList]').val('');
+		$('#searchForm').find('#brandText').html('');
+	});
+	/**************** 초기화 클릭시 // *****************************************************/
+
+	/**************** 엑셀다운로드 *****************************************************/
+	var fnExcelDownLoad = function(){
+		var formId = '#searchForm';
+		if (gridOptions.api.getDisplayedRowCount() <= 0){
+			mcxDialog.alert("조회된 데이터가 없습니다.<br/>다시 조회 후 다운로드 받으세요.");
+			return;
+		}
+
+		var fromDate = parseInt($('#searchForm input[name=stDate]').val().replaceAll("-", ""));
+		var toDate =parseInt($('#searchForm input[name=edDate]').val().replaceAll("-", ""));
+		if( 4 < (toDate - fromDate)){
+			mcxDialog.alert("주문수집일자를 3일 이내의 기간으로 설정 후 다운로드해주세요.");
+			return;
+		}
+
+		var params =  $(formId).serialize();
+		$('#ExcelList').attr({ href : '/shoplinker/order/excel/list?' + params }).get(0).click();
+	}
+	/**************** 엑셀다운로드 // *****************************************************/
+
 	$(document).ready(function() {
 
 		cfnCreateCalendar('#terms', 'stDate', 'edDate', true, '수집');
@@ -358,8 +405,8 @@
 		}
 
 		var testDate = Number($("#orderCollectionForm input[name=apiStDate]").val().replaceAll("-", ""));
-		if( testDate < 20210401 || 20210515 < testDate){
-			mcxDialog.alert("※ 테스트 주문수집시 ※<br>실제운영 주문건을 가져오므로 4월부터 ~ 5/15 사이 날짜로 조회해주세요.");
+		if( testDate < 20210401 || 20210601 < testDate){
+			mcxDialog.alert("※ 테스트 주문수집시 ※<br>실제운영 주문건을 가져오므로 4월부터 ~ 6월이전 사이 날짜로 조회해주세요.");
 			return;
 		}
 
@@ -405,15 +452,17 @@
 
 				}else{
 					// 현재 진행중
-					var resultTxt = result.txt;
-					resultTxt = resultTxt.replace("제휴몰", "제휴몰남은수 "+result.remainExtCnt);
-					resultTxt = resultTxt.replace("스타일24", "스타일24남은수 "+result.remainStyleCnt )
-					$(".runable_info").html(resultTxt);
-
 					$("#btnCollection").html("주문수집중");
 					$("#btnCollection").removeClass("btn-primary");
 					$("#btnCollection").addClass("btn-dark");
 
+					var resultTxt = result.txt;
+					if( null != resultTxt ){
+						resultTxt = resultTxt.replace("제휴몰", "제휴몰남은수 "+result.remainExtCnt.addComma());
+						resultTxt = resultTxt.replace("스타일24", "스타일24남은수 "+result.remainStyleCnt.addComma() )
+						$(".runable_info").html(resultTxt);
+					}
+
 					setTimeout(function(){
 						fnGetCallRunableInfo();
 					}, 20000 );

+ 124 - 53
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerStockForm.html

@@ -31,62 +31,74 @@
 			<!-- 검색조건 영역 -->
 			<div class="panelStyle">
 				<div class="panelTitle">
-					<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 상품코드나 등록일을 꼭 입력해 주세요.</h3>
+					<h3>
+						<i class="fa fa-info-circle"></i>아래 검색조건 중 상품코드나 전송일자을 꼭 입력해 주세요.
+						<br><i class="fa fa-info-circle"></i>[배치주기] 매일 --미정
+					</h3>
+					<span class="panelControl">
+						<i class="fa fa-chevron-up"></i>
+					</span>
 				</div>
-				<table class="frmStyle">
-					<colgroup>
-						<col style="width: 10%;"/>
-						<col style="width: 23%;"/>
-						<col style="width: 10%;"/>
-						<col style="width: 23%;"/>
-						<col style="width: 10%;"/>
-						<col style="width: 24%;"/>
-						<col/>
-					</colgroup>
-
-					<tr>
-						<th>전송일자</th>
-						<td colspan="6" id="sellTerms"></td>
-					</tr>
-					<tr>
-						<th>상품코드<em class="required" title="필수"></em></th>
-						<td>
-							<textarea class="textareaR3 w40p" name="condition" id="condition"></textarea>
-						</td>
-
-						<th>브랜드</th>
-						<td>
-							<input type="text" class="w100" name="searchTxt" id="searchTxt" maxlength="20" />
-							<button type="button" class="btn icn" id="btnSearchBrand"><i class="fa fa-search"></i></button>
-							<!-- <input type="text" class="w100" name="brandCd" readonly="readonly"/> -->
-							<span id="brandText"></span>
-							<input type="hidden" name="brandList"/>
-						</td>
-
-						<th>IF결과</th>
-						<td colspan="3">
-							<select name="apiResult" id="apiResult">
-								<option value="">[전체]</option>
-								<option value="true">전송완료</option>
-								<option value="false">전송실패</option>
-								<option value="error">오류</option>
-							</select>
-						</td>
-					</tr>
-				</table>
-
-				<ul class="panelBar">
-					<li class="center">
-						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
-					</li>
-				</ul>
 
+				<div class="panelContent">
+					<table class="frmStyle">
+						<colgroup>
+							<col style="width: 10%;"/>
+							<col style="width: 23%;"/>
+							<col style="width: 10%;"/>
+							<col style="width: 23%;"/>
+							<col style="width: 10%;"/>
+							<col style="width: 24%;"/>
+							<col/>
+						</colgroup>
+
+						<tr>
+							<th>전송일자</th>
+							<td colspan="6" id="sellTerms"></td>
+						</tr>
+						<tr>
+							<th>상품코드<em class="required" title="필수"></em></th>
+							<td>
+								<textarea class="textareaR3 w50p" name="condition" id="condition"></textarea>
+							</td>
+
+							<th>브랜드</th>
+							<td>
+								<input type="text" class="w100" name="searchTxt" id="searchTxt" maxlength="20" />
+								<button type="button" class="btn icn" id="btnSearchBrand"><i class="fa fa-search"></i></button>
+								<!-- <input type="text" class="w100" name="brandCd" readonly="readonly"/> -->
+								<span id="brandText"></span>
+								<input type="hidden" name="brandList"/>
+							</td>
+
+							<th>IF결과</th>
+							<td colspan="3">
+								<select name="apiResult" id="apiResult">
+									<option value="">[전체]</option>
+									<option value="true">전송완료</option>
+									<option value="false">전송실패</option>
+									<option value="error">오류</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+
+					<ul class="panelBar">
+						<li class="center">
+							<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+							<button type="button" class="btn btn-gray btn-lg" id="btnInit">초기화</button>
+						</li>
+					</ul>
+				</div>
 			</div>
 			<!-- 검색조건 영역 -->
 
 			<!-- 리스트 영역 -->
 			<div class="panelStyle">
 				<ul class="panelBar">
+					<li>
+						<button type="button" class="btn btn-default btn-lg" onclick="fnExcelDownLoad();">엑셀다운로드</button>
+					</li>
 					<li class="right">
 						검색결과 : <strong><span id="gridRowTotalCount">0</span> 건</strong>&nbsp;
 						쪽번호 <span id="pgNo">0</span>/ <strong id="endPgNo">0</strong>&nbsp;&nbsp;
@@ -109,6 +121,8 @@
 				</ul>
 			</div>
 			<!-- //리스트 영역 -->
+
+			<a href="javascript:void(0);" id="ExcelList" style="display: none;">엑셀다운로드</a>
 		</form>
 
 	</div>
@@ -124,16 +138,16 @@
 		{headerName: "No", width: 60, cellClass: 'text-center',
 			valueGetter: function(params) { return cfnGridNumner('searchForm',params.node.rowIndex, 'A');}
 		},
+		{headerName: "IF결과", field: "apiResult", width: 100, cellClass: 'text-center',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(procGbValue, params.value); }
+		},
+		{headerName: "전송결과메세지", field: "apiMessage", width: 350, cellClass: 'text-center'},
 		{headerName: "상품코드", field: "goodsCd", width: 130, cellClass: 'text-center'},
 		{headerName: "상품명", field: "goodsNm", width: 250, cellClass: 'text-center'},
 		{headerName: "옵션코드", field: "optCd", width: 130, cellClass: 'text-center'},
-		{headerName: "옵션1", field: "optCd1", width: 150, cellClass: 'text-center'},
+		{headerName: "옵션1", field: "optCd1", width: 130, cellClass: 'text-center'},
 		{headerName: "옵션2", field: "optCd2", width: 130, cellClass: 'text-center'},
 		{headerName: "재고", field: "quantity", width: 80, cellClass: 'text-center'},
-		{headerName: "IF결과", field: "apiResult", width: 100, cellClass: 'text-center',
-			valueFormatter: function (params) { return gagaAgGrid.lookupValue(procGbValue, params.value); }
-		},
-		{headerName: "전송결과메세지", field: "apiMessage", width: 420, cellClass: 'text-center'},
 		{headerName: "전송일시", field: "regDt", width: 150, cellClass: 'text-center'}
 	];
 
@@ -145,6 +159,33 @@
 		fnListSearch();
 	});
 
+	// 브랜드 조회 선택시
+	$('#btnSearchBrand').on('click', function() {
+		cfnOpenBrandListPopup('fnSetBrandInfo', 'M');
+	});
+
+	// 브랜드 조회 팝업에서 호출
+	var fnSetBrandInfo = function(result) {
+		var arrbrandCd = [];
+		var brandText = "";
+		var bIndex = 0;
+		$('#searchForm').find('#brandText').html('');
+		$('#searchForm input[name=searchTxt]').val('');
+		result.forEach(function(brand){
+			bIndex++;
+			arrbrandCd.push(brand.brandCd);
+		});
+
+		// 조회값이 하나일 경우 화면에 코드 노출 그외는 갯수 처리
+		if (bIndex == 1) {
+			$('#searchForm input[name=searchTxt]').val(arrbrandCd[0]);
+		}else{
+			brandText = bIndex + " 개";
+			$('#searchForm').find('#brandText').html(brandText);
+		}
+		var jsonData = JSON.stringify(arrbrandCd);
+		$("#searchForm input[name=brandList]").val(jsonData);
+	}
 
 	/**************** 검색 ********************************************************/
 	$('#btnSearch').on('click', function() {
@@ -236,6 +277,36 @@
 	}
 	/**************** 검색 // *****************************************************/
 
+	/**************** 초기화 클릭시 *****************************************************/
+	$('#btnInit').on('click', function() {
+
+		$('#searchForm')[0].reset();
+		$("#multiBrand").empty();
+		$('#searchForm input[name=brandList]').val('');
+		$('#searchForm').find('#brandText').html('');
+	});
+	/**************** 초기화 클릭시 // *****************************************************/
+
+	/**************** 엑셀다운로드 *****************************************************/
+	var fnExcelDownLoad = function(){
+		var formId = '#searchForm';
+		if (gridOptions.api.getDisplayedRowCount() <= 0){
+			mcxDialog.alert("조회된 데이터가 없습니다.<br/>다시 조회 후 다운로드 받으세요.");
+			return;
+		}
+
+		var fromDate = parseInt($('#searchForm input[name=stDate]').val().replaceAll("-", ""));
+		var toDate =parseInt($('#searchForm input[name=edDate]').val().replaceAll("-", ""));
+		if( 4 < (toDate - fromDate)){
+			mcxDialog.alert("전송일자를 3일 이내의 기간으로 설정 후 다운로드해주세요.");
+			return;
+		}
+
+		var params =  $(formId).serialize();
+		$('#ExcelList').attr({ href : '/shoplinker/stock/excel/list?' + params }).get(0).click();
+	}
+	/**************** 엑셀다운로드 // *****************************************************/
+
 	$(document).ready(function() {
 
 		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', 'X');

+ 10 - 1
src/main/webapp/WEB-INF/views/withdraw/WithdrawExceptionListForm.html

@@ -232,7 +232,16 @@
 				cellRenderer: function(params) {
 					var btnText = '';
 					if(params.data.recallStat === 'P' && params.data.chgStat != null) {
-						btnText= '<a href="javascript:void(0);"  class="btn btn-success btn-ssm">사유변경</a>';
+						if(params.data.reasonCode == '02'){ // 미착 
+							if(params.data.chgGb == 'G680_30'){
+								btnText= '<a href="javascript:void(0);"  class="btn btn-success btn-ssm">반품변경</a>';
+							}else if(params.data.chgGb == 'G680_40'){
+								btnText= '<a href="javascript:void(0);"  class="btn btn-success btn-ssm">교환변경</a>';
+							}
+						} else {
+							btnText= '<a href="javascript:void(0);"  class="btn btn-success btn-ssm">사유변경</a>';	
+						}
+						
 					} else if(params.data.recallStat === 'P' && params.data.chgStat == null){
 						btnText= '<a href="javascript:void(0);"  class="btn btn-success btn-ssm">반품요청</a>';
 					} else { btnText = '' }