Parcourir la source

샵링커 개발

jmh il y a 5 ans
Parent
commit
db71fa5c80
24 fichiers modifiés avec 8478 ajouts et 75 suppressions
  1. 239 0
      src/main/java/com/style24/admin/biz/dao/TsaOcmDao.java
  2. 262 0
      src/main/java/com/style24/admin/biz/dao/TsaShoplinkerDao.java
  3. 776 56
      src/main/java/com/style24/admin/biz/service/TsaOcmService.java
  4. 1730 0
      src/main/java/com/style24/admin/biz/service/TsaShoplinkerService.java
  5. 898 0
      src/main/java/com/style24/admin/biz/web/TsaShoplinkerController.java
  6. 39 2
      src/main/java/com/style24/admin/support/env/TsaConstants.java
  7. 107 0
      src/main/java/com/style24/persistence/domain/ExtmallOrder.java
  8. 3 0
      src/main/java/com/style24/persistence/domain/Goods.java
  9. 48 0
      src/main/java/com/style24/persistence/domain/GoodsStock.java
  10. 137 0
      src/main/java/com/style24/persistence/domain/ShoplinkerGoods.java
  11. 67 0
      src/main/java/com/style24/persistence/domain/ShoplinkerInvoice.java
  12. 192 0
      src/main/java/com/style24/persistence/domain/ShoplinkerOrder.java
  13. 101 0
      src/main/java/com/style24/persistence/domain/ShoplinkerSearch.java
  14. 1242 6
      src/main/java/com/style24/persistence/mybatis/shop/TsaOcm.xml
  15. 849 0
      src/main/java/com/style24/persistence/mybatis/shop/TsaShoplinker.xml
  16. 17 0
      src/main/resources/config/application-locd.yml
  17. 17 0
      src/main/resources/config/application-style.yml
  18. 18 1
      src/main/resources/config/application-tsit.yml
  19. 357 0
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerGoodsSendForm.html
  20. 346 0
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerInvoiceSendForm.html
  21. 305 0
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerOrderDetailForm.html
  22. 433 0
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerOrderForm.html
  23. 251 0
      src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerStockForm.html
  24. 44 10
      src/main/webapp/ux/js/admin.popup.js

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

@@ -5,8 +5,13 @@ 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.Goods;
+import com.style24.persistence.domain.GoodsStock;
+import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.Payment;
 
 /**
  * 영업망관리 Dao
@@ -69,4 +74,238 @@ 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);
+
+	/**
+	 * 제휴몰주문등록 - 주문등록 cnt
+	 * @param order
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 31
+	 */
+	int getExtmallOrderCnt(Order order);
+
+
+	// ------------------------- 주문등록 소스 -------------------------------------------//
+	// ------------------------- 주문등록 소스 -------------------------------------------//
+	/**
+	 * 1. 주문기본정보 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createOrder(Order order);
+
+	/**
+	 * 2. 주문배송지정보 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createDeliveryAddr(Order order);
+
+	/**
+	 * 3. 주문배송비정보등록 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createDeliveryFee(Order order);
+
+	/**
+	 * 4. 주문상세정보등록 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createOrderDetail(Order order);
+
+	/**
+	 * 4-2 주문상세 이력 등록
+	 *
+	 * @param Order
+	 * @return
+	 * @author jmh
+	 * @since 2020. 11. 30
+	 */
+	int createOrderDetailHst(Order order);
+
+	/**
+	 * 5. 주문상세단품정보등록 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	Collection<Order> getOrderDetailItem(Order order);
+
+	/**
+	 * 6. 주문상세단품정보등록 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createOrderDetailItem(Order order);
+
+	/**
+	 * 7. 주문상세단품이력정보등록 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createOrderDetailItemHst(Order order);
+
+	/**
+	 * 8. 주문사은품 마스터 정보 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createOrdFreegift(Order order);
+
+	/**
+	 * 9. 주문사은품 상품 정보 등록
+	 *
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createOrdFreegiftVal(Order order);
+
+	/**
+	 * 10. 주문사은품 주문상세 정보 등록
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createOrdFreegiftDtl(Order order);
+
+	/**
+	 * 11. PAYMENT INSERT
+	 * @param param
+	 * @return
+	 */
+	int insertPayment(Payment param);
+
+	/**
+	 * 12. 재고정보등록
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 03. 09
+	 */
+	int createSellQty(Order order);
+
+	/**
+	 * 13. 사은품 남은수량 업데이트
+	 * @param Order - 주문 정보
+	 * @return
+	 * @author jmh
+	 * @since 2021. 04. 13
+	 */
+	int updateFreegiftValLeftQty(Order order);
+
+	/**
+	 * 상품 정보 조회
+	 * @param goods
+	 * @return
+	 * @author xodud1202
+	 * @since 2021. 01. 28
+	 */
+	Goods getGoodsInfo(Goods goods);
+
+	/**
+	 * 상품 재고 조회
+	 * @param goodsStock
+	 * @return
+	 * @author xodud1202
+	 * @since 2021. 01. 28
+	 */
+	GoodsStock getGoodsStockInfo(GoodsStock goodsStock);
+
+	/**
+	 * 사은품 : 1차조건 적용된 사음품 정보, 상품 금액 조회
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2021. 02. 02
+	 */
+	Collection<Order> getFreeGiftGoodsApplyAmt(Order order);
+
+	/**
+	 * 사은품 : 2차조건 적용된 사은품상품금액 구간정보조회
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2021. 02. 02
+	 */
+	Collection<Order> getFreeGiftGoodsApplySection(Order order);
+
+	/**
+	 * 사은품 : 3차조건 적용된 구간정보의 사은품정보조회
+	 *
+	 * @param Order
+	 * @author jsh77b
+	 * @since 2021. 02. 02
+	 */
+	Collection<Order> getFreeGiftGoodsApplyVal(Order order);
+	// ------------------------- 주문등록 소스 끝 -------------------------------------------//
+	// ------------------------- 주문등록 소스 끝 -------------------------------------------//
 }

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

@@ -0,0 +1,262 @@
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+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
+	 */
+	void insertShoplinerApiHst(ShoplinkerGoods shoplinkerGoods);
+
+	/**
+	 *  샵링커 api 호출 가능여부
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	ShoplinkerSearch getCallRunableInfo(ShoplinkerSearch slkSearch);
+
+	/**
+	 * 샵링커 api 호출 가능여부 상태 저장
+	 *
+	 * @param dataMap
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	void saveCallApiRunable(ShoplinkerSearch slkSearch);
+
+	/**
+	 * 샵링커 api 호출 가능여부 상태 수정
+	 *
+	 * @param dataMap
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	void updateCallApiRunable(ShoplinkerSearch slkSearch);
+
+	/**
+	 * 상품등록-단품 목록 조회
+	 *
+	 * @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 shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int insertShoplinkerOrder(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 샵링커주문수집-목록 건수
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int getShoplinkerOrderListCount(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 샵링커주문수집-목록
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerOrder> getShoplinkerOrderList(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 샵링커주문수집-상세
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	ShoplinkerOrder getShoplinkerOrderInfo(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 샵링커주문수집- 제휴몰 주문업로드여부 업데이트
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 31
+	 */
+	void updateShoplinkerOrder(ShoplinkerOrder shoplinkerOrder);
+
+	/**
+	 * 제휴몰 주문등록 상세
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 31
+	 */
+	ExtmallOrder getExtmallOrderInfo(String extmallOrder);
+
+	/**
+	 * 제휴몰 주문등록 대상목록
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 31
+	 */
+	Collection<ShoplinkerOrder> getShoplinkerRegExtmallList();
+
+	/**
+	 * 송장전송-전송 목록 건수
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int getSendInvoiceListCount(ShoplinkerInvoice shoplinkerInvoice);
+
+	/**
+	 * 송장전송-전송 목록
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerInvoice> getSendInvoiceList(ShoplinkerInvoice shoplinkerInvoice);
+
+	/**
+	 * 송장전송-상세목록
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerInvoice> getShoplinkerInvoiceOrdDtlList(ShoplinkerInvoice shoplinkerInvoice);
+
+	/**
+	 * 재고전송-목록 건수
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	int getStockListCount(ShoplinkerSearch shoplinkerSearch);
+
+	/**
+	 * 재고전송-목록
+	 *
+	 * @param shoplinkerSearch
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	Collection<ShoplinkerGoods> getStockListList(ShoplinkerSearch shoplinkerSearch);
+
+}

+ 776 - 56
src/main/java/com/style24/admin/biz/service/TsaOcmService.java

@@ -1,18 +1,29 @@
 package com.style24.admin.biz.service;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import com.gagaframework.web.parameter.GagaMap;
 import com.style24.admin.biz.dao.TsaOcmDao;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.admin.support.env.TsaConstants.ExtmallUploadFailStat;
 import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.biz.service.TscOrderChangeService;
+import com.style24.core.support.env.TscConstants;
 import com.style24.core.support.message.TscMessageByLocale;
 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.Goods;
+import com.style24.persistence.domain.GoodsStock;
+import com.style24.persistence.domain.Order;
+import com.style24.persistence.domain.Payment;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -26,81 +37,790 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class TsaOcmService {
 
-	@Autowired
-	private TscMessageByLocale message;
+    @Autowired
+    private TscMessageByLocale message;
 
-	@Autowired
-	private TsaOcmDao ocmDao;
+    @Autowired
+    private TsaOcmDao ocmDao;
 
-	/**
-	 * 제휴몰 목록
-	 * @param extmall - 제휴몰 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 5
+    /**
+     * 제휴몰 목록
+     * @param extmall - 제휴몰 정보
+     * @return
+     * @author gagamel
+     * @since 2020. 11. 5
+     */
+    public Collection<Extmall> getExtmallList(Extmall extmall) {
+        return ocmDao.getExtmallList(extmall);
+    }
+
+    /**
+     * 제휴몰 등록/수정 처리
+     * @param extmall - 제휴몰 정보
+     * @author gagamel
+     * @since 2020. 11. 5
+     */
+    @Transactional("shopTxnManager")
+    public void saveExtmall(Extmall extmall) {
+        extmall.setRegNo(TsaSession.getInfo().getUserNo());
+        extmall.setUpdNo(TsaSession.getInfo().getUserNo());
+        ocmDao.saveExtmall(extmall);
+    }
+
+    /**
+     * 제휴몰 고시정보 목록
+     * @param extmallNoti - 제휴몰고시정보
+     * @return
+     * @author gagamel
+     * @since 2020. 11. 6
+     */
+    public Collection<ExtmallNoti> getExtmallNotiinfoList(ExtmallNoti extmallNoti) {
+        return ocmDao.getExtmallNotiinfoList(extmallNoti);
+    }
+
+    /**
+     * 제휴몰 원산지 목록
+     * @param extmallOrigin - 제휴몰원산지 정보
+     * @return
+     * @author gagamel
+     * @since 2020. 11. 12
+     */
+    public Collection<ExtmallOrigin> getExtmallOriginList(ExtmallOrigin extmallOrigin) {
+        return ocmDao.getExtmallOriginList(extmallOrigin);
+    }
+
+    /**
+     * 제휴몰가격연계 목록
+     * @param extmallPriceSync - 제휴몰가격연계 정보
+     * @return
+     * @author gagamel
+     * @since 2020. 11. 7
+     */
+    public Collection<ExtmallPriceSync> getExtmallPriceSyncList(ExtmallPriceSync extmallPriceSync) {
+        return ocmDao.getExtmallPriceSyncList(extmallPriceSync);
+    }
+
+    /**
+     * 제휴몰가격연계 등록/수정
+     * @param extmallPriceSyncList - 제휴몰가격연계 목록
+     * @author gagamel
+     * @since 2020. 11. 7
+     */
+    public void saveExtmallPriceSync(Collection<ExtmallPriceSync> extmallPriceSyncList) {
+        for (ExtmallPriceSync extmallPriceSync : extmallPriceSyncList) {
+            extmallPriceSync.setRegNo(TsaSession.getInfo().getUserNo());
+            extmallPriceSync.setUpdNo(TsaSession.getInfo().getUserNo());
+            ocmDao.saveExtmallPriceSync(extmallPriceSync);
+        }
+    }
+
+
+
+
+
+
+
+
+
+    /**
+     * 스타일 24 주문정보등록
+     * @param Order
+     * @return Order
+     * @author jsh77b
+     * @since 2021. 03. 09
+     *
+     * TscOrderService.createPreOrder 참조
+     * 샵링커 주문수집으로 외부몰주문등록된 건 중 '대기'상태인 것들에 대해 주문등록처리를 한다.
+     */
+    @Transactional("shopTxnManager")
+    public void createShoplinkerOrder() {
+
+    	Collection<Order> orderList = this.sortOrderList();
+
+    	if (orderList != null && !orderList.isEmpty()) {
+	    	for( Order order : orderList ) {
+
+	    		String ordCheckMsg = this.orderValidationCheck(order);
+
+	    		// ALL_SUCCESS 전체성공,  ALL_FAIL 전체실패, PART_SUCCESS 일부성공, NOT 이미 등록된 주문건
+	    		if("ALL_SUCCESS".equals(ordCheckMsg) || "PART_SUCCESS".equals(ordCheckMsg)) {
+	    			// 일부 또는 전체 성공
+
+	    			// 1. 주문기본정보등록
+	                ocmDao.createOrder(order);
+
+	                // 2. 주문배송정보등록
+	                ocmDao.createDeliveryAddr(order);
+
+	                // 3. 주문배송비정보등록
+	                ocmDao.createDeliveryFee(order);
+
+					// 4. 주문상세정보등록
+	                String dtlNos = "";			// 주문상세번호
+	                String cancelGoodsNms = ""; // 콤마로 구분
+	                int cancelAmt = 0;
+	                int payAmt = 0;
+	                GagaMap vdMap;
+	                ExtmallOrder exOrdDtl;
+	    			for( Order orderDetail : order.getOrderDetailList()) {
+
+	    				vdMap = this.saveGoodsInfo(orderDetail);
+
+	    				exOrdDtl = new ExtmallOrder();
+	    				exOrdDtl.setOrdNo(order.getOrdNo());
+						exOrdDtl.setDelvAddrSq(order.getDelvAddrSq());
+	    				exOrdDtl.setVendorId(orderDetail.getVendorId());
+						exOrdDtl.setExtmallId(orderDetail.getExtmallId());
+						exOrdDtl.setAgentOrderId(orderDetail.getAgentOrderId());
+						exOrdDtl.setExtmallOrderId(orderDetail.getExtmallOrderId());
+
+	    				if (!"SUCCESS".equals(vdMap.get("message").toString())) {
+	    					cancelGoodsNms += orderDetail.getGoodsNm()+",";
+	    					cancelAmt += orderDetail.getOrdAmt();
+
+	    					exOrdDtl.setUploadStat("G021_40");	// 실패
+	    					exOrdDtl.setOrdNo(null);
+	    					exOrdDtl.setUploadFailCd(vdMap.getString("uploadFailCd"));
+	    					exOrdDtl.setUploadFailReason(vdMap.getString("message"));
+	    					ocmDao.updateExtmallOrder(exOrdDtl);
+
+	    				}else {
+
+	    					orderDetail.setOrdNo(order.getOrdNo());
+	    					orderDetail.setDelvAddrSq(order.getDelvAddrSq());
+
+	    					// TODO 총알배송, 구매대행상품여부 체크
+	                        ocmDao.createOrderDetail(orderDetail); // 주문상세정보등록
+
+	                        ocmDao.createOrderDetailHst(orderDetail); // 주문상세이력정보등록
+
+	                        Collection<Order> orderDetailItemList = ocmDao.getOrderDetailItem(orderDetail); // 주문상세단품정보조회
+
+	                        // 주문상세단품단위 금액 등록
+	                        int length				= orderDetailItemList.size();
+	                        int index				= 1;
+	                        int leftOrdAmt 			= orderDetail.getOrdAmt();
+	                        int leftCpn1DcAmt 		= orderDetail.getCpn1DcAmt();
+	                        int leftTmtb1DcAmt 		= orderDetail.getTmtb1DcAmt();
+	                        int leftTmtb2DcAmt 		= orderDetail.getTmtb2DcAmt();
+	                        int leftGoodsCpnDcAmt 	= orderDetail.getGoodsCpnDcAmt();
+	                        int leftCartCpnDcAmt 	= orderDetail.getCartCpnDcAmt();
+	                        int leftPntDcAmt 		= orderDetail.getPntDcAmt();
+	                        int leftPrePntDcAmt 	= orderDetail.getPrePntDcAmt();
+	                        int leftSavePntAmt 		= orderDetail.getSavePntAmt();
+	                        int leftRealOrdAmt 		= orderDetail.getRealOrdAmt();
+	                        int leftGfcdUseAmt 		= orderDetail.getGfcdUseAmt();
+
+	                        for (Order orderDetailItem : orderDetailItemList) {
+	                            int itemPrice 		= orderDetailItem.getItemPrice();
+	                            int optAddPrice 	= orderDetailItem.getOptAddPrice();
+	                            int itemQty 		= orderDetailItem.getItemQty();
+	                            double currPrice	= orderDetailItem.getCurrPrice();
+	                            double itemOrdAmt	= (itemPrice + optAddPrice) * itemQty;
+	                            double tempDivD		= (itemOrdAmt / currPrice) * 100;
+	                            int tempDiv 		= Integer.parseInt(String.valueOf(Math.round(tempDivD)));
+
+	                            if (index == length) {
+	                                orderDetailItem.setOrdAmt(leftOrdAmt);
+	                                orderDetailItem.setCpn1DcAmt(leftCpn1DcAmt);
+	                                orderDetailItem.setTmtb1DcAmt(leftTmtb1DcAmt);
+	                                orderDetailItem.setTmtb2DcAmt(leftTmtb2DcAmt);
+	                                orderDetailItem.setGoodsCpnDcAmt(leftGoodsCpnDcAmt);
+	                                orderDetailItem.setCartCpnDcAmt(leftCartCpnDcAmt);
+	                                orderDetailItem.setPntDcAmt(leftPntDcAmt);
+	                                orderDetailItem.setPrePntDcAmt(leftPrePntDcAmt);
+	                                orderDetailItem.setSavePntAmt(leftSavePntAmt);
+	                                orderDetailItem.setRealOrdAmt(leftRealOrdAmt);
+	                                orderDetailItem.setGfcdUseAmt(leftGfcdUseAmt);
+	                            } else {
+	                                orderDetailItem.setOrdAmt((orderDetail.getOrdAmt() * tempDiv) / 100);
+	                                orderDetailItem.setCpn1DcAmt((orderDetail.getCpn1DcAmt() * tempDiv) / 100);
+	                                orderDetailItem.setTmtb1DcAmt((orderDetail.getTmtb1DcAmt() * tempDiv) / 100);
+	                                orderDetailItem.setTmtb2DcAmt((orderDetail.getTmtb2DcAmt() * tempDiv) / 100);
+	                                orderDetailItem.setGoodsCpnDcAmt((orderDetail.getGoodsCpnDcAmt() * tempDiv) / 100);
+	                                orderDetailItem.setCartCpnDcAmt((orderDetail.getCartCpnDcAmt() * tempDiv) / 100);
+	                                orderDetailItem.setPntDcAmt((orderDetail.getPntDcAmt() * tempDiv) / 100);
+	                                orderDetailItem.setPrePntDcAmt((orderDetail.getPrePntDcAmt() * tempDiv) / 100);
+	                                orderDetailItem.setSavePntAmt((orderDetail.getSavePntAmt() * tempDiv) / 100);
+	                                orderDetailItem.setRealOrdAmt((orderDetail.getRealOrdAmt() * tempDiv) / 100);
+	                                orderDetailItem.setGfcdUseAmt((orderDetail.getGfcdUseAmt() * tempDiv) / 100);
+
+	                                leftOrdAmt 			= leftOrdAmt 			- ((orderDetail.getOrdAmt() * tempDiv) / 100);
+	                                leftCpn1DcAmt 		= leftCpn1DcAmt 		- ((orderDetail.getCpn1DcAmt() * tempDiv) / 100);
+	                                leftTmtb1DcAmt 		= leftTmtb1DcAmt 		- ((orderDetail.getTmtb1DcAmt() * tempDiv) / 100);
+	                                leftTmtb2DcAmt 		= leftTmtb2DcAmt 		- ((orderDetail.getTmtb2DcAmt() * tempDiv) / 100);
+	                                leftGoodsCpnDcAmt 	= leftGoodsCpnDcAmt 	- ((orderDetail.getGoodsCpnDcAmt() * tempDiv) / 100);
+	                                leftCartCpnDcAmt 	= leftCartCpnDcAmt 		- ((orderDetail.getCartCpnDcAmt() * tempDiv) / 100);
+	                                leftPntDcAmt 		= leftPntDcAmt 			- ((orderDetail.getPntDcAmt() * tempDiv) / 100);
+	                                leftPrePntDcAmt 	= leftPrePntDcAmt 		- ((orderDetail.getPrePntDcAmt() * tempDiv) / 100);
+	                                leftSavePntAmt 		= leftSavePntAmt 		- ((orderDetail.getSavePntAmt() * tempDiv) / 100);
+	                                leftRealOrdAmt 		= leftRealOrdAmt 		- ((orderDetail.getRealOrdAmt() * tempDiv) / 100);
+	                                leftGfcdUseAmt 		= leftGfcdUseAmt 		- ((orderDetail.getGfcdUseAmt() * tempDiv) / 100);
+	                            }
+
+	                            // 2021.05.06 옵션금액 단품 추가
+	                            orderDetailItem.setOptAddPrice(optAddPrice);
+	                            orderDetailItem.setCustNo(order.getCustNo());
+
+	                            ocmDao.createOrderDetailItem(orderDetailItem); // 주문상세단품정보등록
+
+	                            ocmDao.createOrderDetailItemHst(orderDetailItem); // 주문상세단품이력정보등록
+
+	                            index++;
+
+
+	                            // 5. 재고등록(샵링커 주문목록을 보면 동일한 몰 주문번호에 동일한 상품(sku)이 수량이 아닌 개별로 있는 데이터가 존재하므로 > 주문번호로 한번에 처리가 아닌 개별로 처리 함)
+	            				orderDetail.setSellGb(TscConstants.SellGb.ORDER.value());			// 판매구분(10:주문(-),
+	            				ocmDao.createSellQty(orderDetail);
+
+	                            // 외부몰 정보 업데이트
+	                            exOrdDtl.setUploadStat("G021_30");	// 성공
+	        					ocmDao.updateExtmallOrder(exOrdDtl);
+
+	        					dtlNos += orderDetail.getOrdDtlNo()+",";
+	        				}
+	    				}
+	            	}
+
+
+	    			// 6. 주문사은품정보등록
+	        		dtlNos = dtlNos.substring(0, dtlNos.length()-1);
+	    	        String [] dtlNdsArr = dtlNos.split(",");	// 주문상세번호
+	    	        order.setItemCdArr(dtlNdsArr);
+	    			order.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());		//주문상세상태 - 결제완료처리
+					GagaMap giftMap = this.getOrderFreegift(order);
+
+	    	        if( null != giftMap) {
+	    		        if( null != giftMap.get("freegiftList")) {
+	    		        	if( !"".equals(giftMap.get("freegiftList"))) {
+
+	    		    			// 상품코드
+	    		        		String dtlGoodsCds = "";	// 사은품관련 상품코드. 콤마로구분
+	    		        		String[] dtlGoodsCdsArr;
+	    		        		Collection<Order> freegiftApplyAmtList = (Collection<Order>) giftMap.get("freegiftApplyAmtList");
+
+	    		        		for(Order ftMap : freegiftApplyAmtList ) {
+	    		        			dtlGoodsCds += ftMap.getGoodsCd() +",";
+	    		        		}
+	    		        		System.out.println("hmj 2dtlGoodsCds ; "+dtlGoodsCds );
+	    		        		dtlGoodsCds = dtlGoodsCds.substring(0, dtlGoodsCds.length()-1);
+	    		        		dtlGoodsCdsArr = dtlGoodsCds.split(",");
+	    		        		order.setFreegiftGoodsArr(dtlGoodsCdsArr);
+
+	    		        		Collection<Order> freegiftList = (Collection<Order>) giftMap.get("freegiftList");
+	    		                ArrayList<Integer> fitValSqArr = new ArrayList<Integer>();
+	    		                for(Order ftMap : freegiftList ) {
+	    		                	fitValSqArr.add(ftMap.getFreegiftValSq());
+	    		                }
+	    		                int[] freegiftValArr = new int[fitValSqArr.size()];
+	    		                for( int i=0; i<fitValSqArr.size(); i++) {
+	    		                	freegiftValArr[i] = fitValSqArr.get(i);
+	    		                }
+
+	    		                order.setFreegiftValArr(freegiftValArr);
+	    		                order.setCustNo(0);
+	    		                if(order.getFreegiftValArr() != null && order.getFreegiftValArr().length > 0) {
+	    		                    ocmDao.createOrdFreegift(order);
+
+	    		                    // 6. 주문사은품 상품 정보 등록
+	    		                    ocmDao.createOrdFreegiftVal(order);
+
+	    		                    // 7. 주문사은품 주문상세정보 등록
+	    		                    for(Order ftMap : freegiftApplyAmtList ) {
+	    			    		    	order.setFreegiftSq(ftMap.getFreegiftSq());
+	    				    			order.setGoodsCd(ftMap.getGoodsCd());
+	    				    			ocmDao.createOrdFreegiftDtl(order);
+	    			    		    }
+	    		                }
+
+	    		                // 14. 사은품 수량 차감 로직 TB_FREEGIFT_VAL LEFT_QTY
+	    		                ocmDao.updateFreegiftValLeftQty(order);
+
+	    		        	}
+	    		        }
+	    	        }
+
+	    			// 7. 결제 TB_PAYMENT
+	                Payment payment = new Payment();
+	                payment.setOrdNo(order.getOrdNo());
+	                payment.setPayMeans(TscConstants.PayMeans.EXTMALL.value());		// 결제수단
+	                payAmt = order.getRealOrdSumAmt() + order.getDelvFee() - cancelAmt;			// 결제금액 = 실결제금액 + 배송비 - 취소금액
+	                payment.setPayAmt(payAmt);
+	                payment.setPgCpnAmt(0);											// PG쿠폰금액
+	                payment.setNpayPntAmt(0);   									// 네이버페이포인트금액
+	                payment.setPayGb("O");											// 결제구분(O:주문시결제, D:배송시결제, E:에러(강제 결제 태울 때 또는 에러일 때)
+	                payment.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());		// 결제상태 - 결제완료
+	                payment.setRegNo(0);
+	                payment.setUpdNo(0);
+
+	                ocmDao.insertPayment(payment);
+
+
+	                // 8. 알림톡 발송
+	                if( 0 == cancelAmt ) {
+	                	// 전체성공
+	                	System.out.println(" hmj :: 전체성공 !! ");
+
+	                }else {
+	                	// 부분품절 - 제휴몰에서 자동 취소 문자 발송을 하지 않는 경우에만 발송
+	                	// coupang, WEMAPE, ST11TH, GMARKET, AUCTION, Fashion Plus, 판다코리아, 예스24, 홈플러스, LOTTE ON
+	                	cancelGoodsNms = cancelGoodsNms.substring(0, cancelGoodsNms.length()-1);
+	                	System.out.println(" hmj :: 부분성공  (실패 상품명 : "+cancelGoodsNms);
+	                }
+
+
+	    		}else {
+
+	    			if( "ALL_FAIL".equals(ordCheckMsg) ) {	// NOT = 이미 등록된 주문건
+	    				// 전체실패 일때만 알림톡 발송
+	    				// 제휴몰에서 자동 취소 문자 발송을 하지 않는 경우에만 발송
+	        			// coupang, WEMAPE, ST11TH, GMARKET, AUCTION, Fashion Plus, 판다코리아, 예스24, 홈플러스, LOTTE ON
+
+
+	    				// 외부몰 주문등록 상태 업데이트
+	    				ExtmallOrder exOrdDtl;
+	    				GagaMap vdMap;
+	    				for( Order orderDetail : order.getOrderDetailList()) {
+
+	    					vdMap = this.saveGoodsInfo(orderDetail);
+
+	    					exOrdDtl = new ExtmallOrder();
+	    					exOrdDtl.setVendorId(orderDetail.getVendorId());
+	    					exOrdDtl.setExtmallId(orderDetail.getExtmallId());
+	    					exOrdDtl.setAgentOrderId(orderDetail.getAgentOrderId());
+	    					exOrdDtl.setExtmallOrderId(orderDetail.getExtmallOrderId());
+	    					exOrdDtl.setUploadStat("G021_40");	// 실패
+
+	    					exOrdDtl.setUploadFailCd(vdMap.getString("uploadFailCd"));
+	    					exOrdDtl.setUploadFailReason(vdMap.getString("message"));
+	    					ocmDao.updateExtmallOrder(exOrdDtl);
+	    				}
+
+
+	    			}
+	    		}
+	        }
+
+    	}
+
+    }
+
+    /**
+     * 스타일 24 주문정보등록 - 제휴몰주문등록 데이터 정렬
+     * @param Order
+     * @return Order
+     * @author jsh77b
+     * @since 2021. 03. 09
+    */
+    private Collection<Order> sortOrderList() {
+    	Collection<Order> orderList = new ArrayList<Order>();
+        Collection<Order> tmpOrdDtlList = new ArrayList<Order>();
+
+        // 1. 외부몰주문등록 대기목록 조회
+        ExtmallOrder params = new ExtmallOrder();
+        params.setUploadStat("G021_00");	// 대기
+        Collection<ExtmallOrder> exMastList = ocmDao.getExtmallMasterOrderList(params);
+
+        Collection<ExtmallOrder> exList = ocmDao.getExtmallOrderList(params);
+        Collection<ExtmallOrder> tmpList = new ArrayList<ExtmallOrder>();
+
+
+        // 2. 그룹별 주문상세목록 세팅
+        for( ExtmallOrder ordGroup : exMastList) {
+
+            tmpList = new ArrayList<ExtmallOrder>();
+            for(ExtmallOrder ordMap : exList ) {
+            	if(ordGroup.getVendorId().equals(ordMap.getVendorId())
+            		 && ordGroup.getExtmallId().equals(ordMap.getExtmallId())
+            		 && ordGroup.getExtmallOrderId().equals(ordMap.getExtmallOrderId())
+            		 && ordGroup.getOrdNm().equals(ordMap.getOrdNm())
+            		 && ordGroup.getOrdPhnno().equals(ordMap.getOrdPhnno())
+            		 && ordGroup.getRecipNm().equals(ordMap.getRecipNm())
+            		 && ordGroup.getRecipPhnno().equals(ordMap.getRecipPhnno())
+            		 && ordGroup.getRecipBaseAddr().equals(ordMap.getRecipBaseAddr())
+            		 && ordGroup.getRecipDtlAddr().equals(ordMap.getRecipDtlAddr())
+            	 ) {
+
+            		tmpList = ordGroup.getOrderDetailList();
+            		if( null == tmpList ) tmpList = new ArrayList<ExtmallOrder>();
+
+            		tmpList.add(ordMap);
+            		ordGroup.setOrderDetailList(tmpList);
+            	}
+            }
+        }
+
+        // 3. vo 값설정 ExtmallOrder -> Order
+        Order order;
+        for( ExtmallOrder ordGroup : exMastList) {
+        	order = new Order();
+
+        	// 기타 정보
+        	order.setOrdNm(ordGroup.getOrdNm());							// 주문자명
+            order.setOrdPhnno(ordGroup.getOrdPhnno());						// 주문자폰번호
+            order.setOrdDt(ordGroup.getOrdDt());							// 주문일
+            order.setPayDt(ordGroup.getOrdDt());
+            order.setSiteCd(TscConstants.Site.STYLE24.value());
+            order.setVendorId(TsaConstants.VendorId.SHOPLINKER.value());	// 외부몰벤더ID(공통코드G003) - 샵링커
+            order.setExtmallId(ordGroup.getExtmallId());					// 외부몰
+            order.setExtmallOrderId(ordGroup.getExtmallOrderId());		// 외부몰주문번호(=쇼핑몰주문번호)
+
+        	// 주문기본정보 (그룹으로 가져오는 정보)
+        	order.setCustNo(0);												// 고객번호 - 외부몰 0
+            order.setCustNm(ordGroup.getOrdNm());							// 주문자명
+            order.setRecipPhnno(ordGroup.getOrdPhnno());					// 주문자폰번호
+            order.setRecipTelno(ordGroup.getOrdTelno());					// 주문자전화번호
+            order.setFrontGb("P");											// PC
+            order.setRecipNm(ordGroup.getRecipNm());						//수령자명
+            order.setRecipPhnno(ordGroup.getRecipPhnno());					//수령자 폰번호
+            order.setRecipBaseAddr(ordGroup.getRecipBaseAddr());			//수령자기본주소
+            order.setRecipDtlAddr(ordGroup.getRecipDtlAddr());				//수령자상세주소
+
+            order.setDelvFeeGb("G018_10");									// 원주문배송비 코드
+            order.setDelvFeeCd("WMS"); 										// SHOT 자사총알배송 | WMS 자사일반배송 | RES  자사예약배송
+            order.setDelvFee(ordGroup.getDelvFee());						// 배송비
+            order.setDelvCpnDcAmt(0);										// 배송비쿠폰할인금액
+            order.setRealDelvAmt(ordGroup.getDelvFee());					// 배송비실결제금액
+            order.setDelvUsacYn("N");										// 배송비 정산여부
+
+
+            // 주문상세정보
+            order.setOrderDetailList(new ArrayList<Order>());
+            tmpOrdDtlList = new ArrayList<Order>();
+            Collection<ExtmallOrder> orderDetailList = ordGroup.getOrderDetailList();
+            String dtlGoodsCds = "";
+            Order orderDetail;
+            for (ExtmallOrder exOrdDtl : orderDetailList) {
+
+            	orderDetail = new Order();
+                orderDetail.setOrdNo(order.getOrdNo());								// 주문번호
+                orderDetail.setDelvAddrSq(order.getDelvAddrSq());					// 배송지일련번호
+                orderDetail.setOrdExchGb("O");										// 주문교환구분(O:주문,E:교환)
+                orderDetail.setCustNo(order.getCustNo());							// 고객번호
+                orderDetail.setRegNo(order.getCustNo());							// 등록자
+                orderDetail.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());	// 주문상세상태=>결제완료 처리
+
+                dtlGoodsCds += exOrdDtl.getGoodsCd()+",";
+                orderDetail.setGoodsCd(exOrdDtl.getGoodsCd());
+                orderDetail.setCurrPrice(exOrdDtl.getCurrPrice());					// 현재판매가
+                orderDetail.setOrdQty(exOrdDtl.getOrdQty());						// 주문수량
+                orderDetail.setOrdAmt(exOrdDtl.getOrdAmt());						// 주문금액(=(현재판매가 + 옵션추가가격) * 주문수량) // 샵링커에서는 현재판매가 x 주문수량 계산된 금액이 ord_amt에 계산되어 옴
+                orderDetail.setDelvCpnDcAmt(0);										// 1차쿠폰(즉시할인쿠폰)할인금액
+                // orderDetail.setGoodsCpnDcAmt();									// 상품쿠폰할인금액
+                orderDetail.setRealOrdAmt(exOrdDtl.getOrdAmt());					// 실주문금액(주문금액 - 취소반품금액 - 1차쿠폰 - 다다익선1 - 다다익선2 - 상품쿠폰 - 장바구니쿠폰 - 포인트할인금액 - 선포인트할인금액)
+                orderDetail.setVendorId(TsaConstants.VendorId.SHOPLINKER.value());	// 외부몰벤더ID(공통코드G003) - 샵링커
+                orderDetail.setExtmallId(exOrdDtl.getExtmallId());					// 외부몰ID(외부몰)
+                orderDetail.setAgentOrderId(exOrdDtl.getAgentOrderId());			// 에이전트주문번호
+                orderDetail.setExtmallOrderId(exOrdDtl.getExtmallOrderId());		// 외부몰주문번호(=쇼핑몰주문번호)
+                orderDetail.setDelvFeeCd("WMS"); 									// SHOT 자사총알배송 | WMS 자사일반배송 | RES  자사예약배송
+                orderDetail.setShotDelvYn("N");										// 총알배송여부
+                orderDetail.setGiftPackYn("N"); 									// 선물포장여부
+                orderDetail.setGiftAddrInpYn("N");									// 선물주소입력여부
+                orderDetail.setSavePntAmt(0);										// 외부몰주문 포인트 적립금 없음
+
+                orderDetail.setOptCd(exOrdDtl.getOptCd());							// 옵션코드
+                orderDetail.setOrdNm(exOrdDtl.getOrdNm());							// 주문자명
+                orderDetail.setOrdPhnno(exOrdDtl.getOrdPhnno());					// 주문자핸폰
+                orderDetail.setGoodsNm(exOrdDtl.getGoodsNm());
+
+                tmpOrdDtlList.add(orderDetail);										// 상세정보 저장
+                order.setDelvMemo(exOrdDtl.getDelvMemo());							// 배송메모
+                order.setRecipTelno(exOrdDtl.getRecipTelno());						// 수령자 전화번호
+                order.setRecipZipcode(exOrdDtl.getRecipZipcode());					// 수령자우편번호
+                order.setEmail(exOrdDtl.getOrdEmail());								// 주문자이메일
+                if (exOrdDtl.getSupplyCompCd() != null && !exOrdDtl.getSupplyCompCd().isEmpty()) {
+                	order.setSupplyCompCd(exOrdDtl.getSupplyCompCd());					// 공급업체코드
+                }
+            }
+
+            order.setRealOrdSumAmt(ordGroup.getTotalOrdAmt());
+            order.setOrderDetailList(tmpOrdDtlList);
+            orderList.add(order);
+        }
+
+    	return orderList;
+    }
+
+    /**
+	 * 주문정보유효성체크 >> 개별체크
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2021. 03. 09
 	 */
-	public Collection<Extmall> getExtmallList(Extmall extmall) {
-		return ocmDao.getExtmallList(extmall);
+	public String orderValidationCheck(Order order) {
+		String resultStr	= "SUCCESS";
+
+		// 1. 주문상세체크
+		Collection<Order> orderDetailList = order.getOrderDetailList();
+
+		int dtlCnt = orderDetailList.size();
+		int succCnt = 0;
+		for (Order orderDetail : orderDetailList) {
+
+			GagaMap resultMap = this.saveGoodsInfo(orderDetail);
+
+			if ("SUCCESS".equals(resultMap.get("message").toString())) {
+				succCnt ++;
+			}
+
+			// 동일한 주문건이 있을경우, 전체 중지
+			if (ExtmallUploadFailStat.ORDER.value().equals(resultMap.get("uploadFailCd").toString())) {
+				succCnt = -1;	// 알림톡 발송도 안함.
+				break;
+			}
+		}
+
+		if( succCnt < 0 ) {
+			// 전체실패 - 알림톡발송 안함
+			resultStr = "NOT";
+
+		}else if( 0 == succCnt ) {
+			// 전체실패
+			resultStr = "ALL_FAIL";
+		}else if( dtlCnt == succCnt ) {
+			// 전체성공
+			resultStr = "ALL_SUCCESS";
+		}else {
+			// 일부성공
+			resultStr = "PART_SUCCESS";
+		}
+		return resultStr;
 	}
 
 	/**
-	 * 제휴몰 등록/수정 처리
-	 * @param extmall - 제휴몰 정보
-	 * @author gagamel
-	 * @since 2020. 11. 5
+	 * 상품마스터 정보 및 재고확인    (( 장바구니 저장
+	 * 단품 : goodsCd, optCd, optCd1, optCd2
+	 * 세트 : goodsCd,
+	 * @param params
 	 */
 	@Transactional("shopTxnManager")
-	public void saveExtmall(Extmall extmall) {
-		extmall.setRegNo(TsaSession.getInfo().getUserNo());
-		extmall.setUpdNo(TsaSession.getInfo().getUserNo());
-		ocmDao.saveExtmall(extmall);
-	}
+	public GagaMap saveGoodsInfo(Order param) {
+		GagaMap result = new GagaMap();
+		result.put("message", "SUCCESS");
 
-	/**
-	 * 제휴몰 고시정보 목록
-	 * @param extmallNoti - 제휴몰고시정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 6
-	 */
-	public Collection<ExtmallNoti> getExtmallNotiinfoList(ExtmallNoti extmallNoti) {
-		return ocmDao.getExtmallNotiinfoList(extmallNoti);
-	}
+		// 중복저장확인
+		param.setVendorId(TsaConstants.VendorId.SHOPLINKER.value());
+		int extRegCnt = ocmDao.getExtmallOrderCnt(param);
+		if( 0 < extRegCnt) {
+			result.put("uploadFailCd", ExtmallUploadFailStat.ORDER.value());
+			result.put("message", "동일한 주문건이 존재합니다.");
+			return result;
+		}
 
-	/**
-	 * 제휴몰 원산지 목록
-	 * @param extmallOrigin - 제휴몰원산지 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 12
-	 */
-	public Collection<ExtmallOrigin> getExtmallOriginList(ExtmallOrigin extmallOrigin) {
-		return ocmDao.getExtmallOriginList(extmallOrigin);
+		// 상품 마스터 정보 확인
+		Goods goods = new Goods();
+		goods.setGoodsCd(param.getGoodsCd());
+		// goods.setCustNo(0);
+		goods.setFrontGb("P");
+		goods.setSiteCd(TscConstants.Site.STYLE24.value());
+		goods = ocmDao.getGoodsInfo(goods);
+
+		if (goods == null) {
+			result.put("uploadFailCd", ExtmallUploadFailStat.GOODS.value());
+			result.put("message", "상품 정보가 존재하지 않습니다.");
+			return result;
+		} else if (TscConstants.GoodsStat.SOLDOUT.value().equals(goods.getGoodsStat())) {
+			result.put("uploadFailCd", ExtmallUploadFailStat.STOCK.value());
+			result.put("message", "품절입니다.");
+			return result;
+		} else if (!TscConstants.GoodsStat.SOLDOUT.value().equals(goods.getGoodsStat()) && !TscConstants.GoodsStat.APPR.value().equals(goods.getGoodsStat())) {
+			result.put("uploadFailCd", ExtmallUploadFailStat.STOCK.value());
+			result.put("message", "판매중인 상품이 아닙니다.");
+			return result;
+		}
+
+		//상품 재고 확인
+		GoodsStock checkParam = new GoodsStock();
+		checkParam.setGoodsCd(param.getGoodsCd());
+		checkParam.setOptCd(param.getOptCd());
+		checkParam.setItemCd(param.getItemCd());
+		checkParam.setGoodsQty(param.getGoodsQty());
+		checkParam.setGoodsType(param.getGoodsType());
+		String stockResult = this.getCheckStock(checkParam);
+
+		if (!"SUCCESS".equals(stockResult)) {
+			result.put("uploadFailCd", ExtmallUploadFailStat.STOCK.value());
+			result.put("message", stockResult);
+			return result;
+		}
+
+		return result;
 	}
 
 	/**
-	 * 제휴몰가격연계 목록
-	 * @param extmallPriceSync - 제휴몰가격연계 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 7
+	 * 상품 재고 체크
+	 * @param param
+	 * goodsCd   (원상품코드) 필수
+	 * goodsType (상품타입) 필수
+	 * optCd     (옵션코드) 필수
+	 * goodsQty  (확인 재고 수량) 필수
+	 * itemCd    (세트 구성 상품코드) 세트
+	 * @return String
+	 * @author xodud1202
+	 * @since 2021. 01. 28
 	 */
-	public Collection<ExtmallPriceSync> getExtmallPriceSyncList(ExtmallPriceSync extmallPriceSync) {
-		return ocmDao.getExtmallPriceSyncList(extmallPriceSync);
+	public String getCheckStock(GoodsStock param) {
+		// 상품 마스터 정보 확인
+		Goods goodsInfo = new Goods();
+		goodsInfo.setGoodsCd(param.getGoodsCd());
+		goodsInfo.setSiteCd(TscConstants.Site.STYLE24.value());
+		goodsInfo = ocmDao.getGoodsInfo(goodsInfo);
+
+		if (TscConstants.GoodsStat.SOLDOUT.value().equals(goodsInfo.getGoodsStat())) {
+			return param.getGoodsCd() + "는 품절 상품입니다.";
+		}
+
+		GoodsStock stockCheck = new GoodsStock();								// 재고 조회 결과
+		stockCheck.setGoodsCd(param.getGoodsCd());
+		stockCheck.setOptCd(param.getOptCd());
+
+		stockCheck = ocmDao.getGoodsStockInfo(stockCheck);					// 구성 상품 재고 조회
+
+		if (stockCheck == null) {
+			return "재고체크 실패했습니다. 새로고침 후 다시 시도해주세요.";
+		}
+
+		if ("Y".equals(stockCheck.getSoldoutYn())) {
+			return stockCheck.getOptCd2() + " 옵션은 품절입니다.";
+		}
+
+		if (param.getGoodsQty() > stockCheck.getCurrStockQty()) {
+			return "옵션의 재고가 충분하지 않습니다.";
+		}
+
+		return "SUCCESS";
 	}
 
 	/**
-	 * 제휴몰가격연계 등록/수정
-	 * @param extmallPriceSyncList - 제휴몰가격연계 목록
-	 * @author gagamel
-	 * @since 2020. 11. 7
+	 * 사은품정보 조회
+	 * @param Order
+	 * @return Order
+	 * @author jsh77b
+	 * @since 2020. 12. 16
 	 */
-	public void saveExtmallPriceSync(Collection<ExtmallPriceSync> extmallPriceSyncList) {
-		for (ExtmallPriceSync extmallPriceSync : extmallPriceSyncList) {
-			extmallPriceSync.setRegNo(TsaSession.getInfo().getUserNo());
-			extmallPriceSync.setUpdNo(TsaSession.getInfo().getUserNo());
-			ocmDao.saveExtmallPriceSync(extmallPriceSync);
+	public GagaMap getOrderFreegift(Order order) {
+
+		GagaMap resultMap = new GagaMap();
+		Collection<Order> freegiftGoodsList 	= null;
+		Collection<Order> freegiftList 			= null;
+
+		// 1. 장바구니 담긴 상품으로 적용된 사은품 프로모션 정보 조회 (with 상품금액)
+		Collection<Order> freegiftApplyAmtList = ocmDao.getFreeGiftGoodsApplyAmt(order);
+
+		// 1.1 장바구니 상품으로 적용된 사은품 여부 판단
+		if (freegiftApplyAmtList.size() > 0) {
+
+			Collection<Order> freegiftGoodsApplyAmtList = new ArrayList<Order>();
+			int tempFreegiftSq 		= 0;
+			int index				= 0;
+			boolean	temp			 = false;
+
+			// 사은품시퀀스 담기
+			for (Order freegiftApplyAmt : freegiftApplyAmtList) {
+				temp = true;
+				if (freegiftGoodsApplyAmtList.size() > 0) {
+					for (Order freegiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
+						if (freegiftApplyAmt.getFreegiftSq() == freegiftGoodsApplyAmt.getFreegiftSq()) {
+							temp = false;
+						}
+					}
+
+					if (temp) {
+						freegiftGoodsApplyAmtList.add(freegiftApplyAmt);
+					}
+				} else {
+					freegiftGoodsApplyAmtList.add(freegiftApplyAmt);
+				}
+			}
+
+
+			// 사은품시퀀스(FREEGIFT_SQ), 사은품시퀀스합계금액(FREEGIFT_AMT)
+			for (Order freegiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
+				// 금액초기화
+				freegiftGoodsApplyAmt.setFreegiftAmt(0);
+
+				for (Order freegiftApplyAmt : freegiftApplyAmtList) {
+					int ordAmt = (freegiftApplyAmt.getCurrPrice() + freegiftApplyAmt.getOptAddPrice()) * freegiftApplyAmt.getGoodsQty();
+					if (freegiftGoodsApplyAmt.getFreegiftSq() == freegiftApplyAmt.getFreegiftSq()) {
+						freegiftGoodsApplyAmt.setFreegiftAmt(freegiftGoodsApplyAmt.getFreegiftAmt() + ordAmt);
+					}
+				}
+			}
+
+
+			// 사은품시퀀스배열생성
+			int[] freegiftSqArr = new int[freegiftGoodsApplyAmtList.size()];
+			index = 0;
+
+			// 사은품시퀀스(FREEGIFT_SQ), 사은품시퀀스합계금액(FREEGIFT_AMT)
+			for (Order fregiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
+				freegiftSqArr[index] = fregiftGoodsApplyAmt.getFreegiftSq();
+				index++;
+			}
+
+			order.setFreegiftSqArr(freegiftSqArr);
+
+			// 2. 사은품 적용구간 정보 조회
+			Collection<Order> freegiftGoodsApplySectionList = ocmDao.getFreeGiftGoodsApplySection(order);
+
+			// 2.1 사은품 적용구간이 있는지 판단
+			if (freegiftGoodsApplySectionList.size() > 0) {
+				int[] freegiftSectionSqArr = new int[freegiftGoodsApplySectionList.size()];
+
+				int tempFreegiftSectionSq = 0;
+				int k = 0;
+
+				// 사은품시퀀스(FREEGIFT_SQ), 사은품시퀀스합계금액(FREEGIFT_AMT)
+				for (Order freegiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
+					int freegiftAmt 	= freegiftGoodsApplyAmt.getFreegiftAmt();
+
+					// 사은풐구간시퀀스(FREEGIFT_SECTION_SQ, 사은품시퀀스(FREEGIFT_SQ), 사은풐구간금액(SECTION_VAL)
+					for (Order freegiftGoodsApplySection : freegiftGoodsApplySectionList) {
+						int freegiftSectionSq 	= freegiftGoodsApplySection.getFreegiftSectionSq();
+						int sectionVal 			= freegiftGoodsApplySection.getSectionVal();
+
+						// 같은 사은품 프로모션끼리 등록
+						if (freegiftGoodsApplyAmt.getFreegiftSq() == freegiftGoodsApplySection.getFreegiftSq()) {
+							// 2021.05.07 금액체크는 이상일때 수정
+							if (freegiftAmt >= sectionVal) {
+								tempFreegiftSectionSq = freegiftSectionSq;
+							}
+						}
+					}
+
+					freegiftSectionSqArr[k] = tempFreegiftSectionSq;
+					k++;
+				}
+
+				// 3. 사은품 적용구간 의 적용 사은품정보조회
+				order.setFreegiftSectionSqArr(freegiftSectionSqArr);
+				Collection<Order> freegiftGoodsApplyValList = ocmDao.getFreeGiftGoodsApplyVal(order);
+
+				if (freegiftGoodsApplyValList.size() > 0) {
+					freegiftList 		= new ArrayList<Order>();
+					freegiftGoodsList 	= new ArrayList<Order>();
+
+					for (Order freegiftGoodsApplyVal : freegiftGoodsApplyValList) {
+
+						// 제휴몰 사은품 전체 제공
+						//if (freegiftGoodsApplyVal.getFreegiftSq() != tempFreegiftSq) {
+							freegiftList.add(freegiftGoodsApplyVal);
+							tempFreegiftSq = freegiftGoodsApplyVal.getFreegiftSq();
+						//}
+
+						freegiftGoodsList.add(freegiftGoodsApplyVal);
+					}
+				}
+			}
 		}
+
+		resultMap.set("freegiftApplyAmtList"		, freegiftApplyAmtList);
+		resultMap.set("freegiftGoodsList"			, freegiftGoodsList);
+		resultMap.set("freegiftList"				, freegiftList);
+
+		return resultMap;
 	}
 
+
 }

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

@@ -0,0 +1,1730 @@
+package com.style24.admin.biz.service;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.gagaframework.excel.env.GagaExcelConstants;
+import com.gagaframework.shoplinker.GagaShoplinkertUtil;
+import com.gagaframework.shoplinker.domain.orderlist.Order;
+import com.gagaframework.shoplinker.env.GagaShoplinkerConstants;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.style24.admin.biz.dao.TsaOcmDao;
+import com.style24.admin.biz.dao.TsaShoplinkerDao;
+import com.style24.admin.support.env.TsaConstants;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.admin.support.util.TsitUtil;
+import com.style24.core.support.env.TscConstants;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.ExtmallOrder;
+import com.style24.persistence.domain.Goods;
+import com.style24.persistence.domain.GoodsStock;
+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 shoplinkerDao;
+
+	@Autowired
+	private TsaCommonService commonService;
+
+	@Autowired
+	private TsaOcmDao ocmDao;
+
+	private String dateStr; // yymmddhh24mi
+
+
+	/**
+	 * 샵링커 api 호출 가능여부
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 28
+	 */
+	public ShoplinkerSearch getCallRunableInfo(ShoplinkerSearch slkSearch ) {
+		return shoplinkerDao.getCallRunableInfo(slkSearch);
+	}
+
+	/**
+	 * 샵링커 api 호출 가능여부 상태 저장
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 28
+	 */
+	public void saveCallApiRunable(ShoplinkerSearch slkSearch) {
+		shoplinkerDao.saveCallApiRunable(slkSearch);
+	}
+
+	/**
+	 * 샵링커 api 호출 가능여부 상태 수정
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 28
+	 */
+	public void updateCallApiRunable(ShoplinkerSearch slkSearch) {
+		shoplinkerDao.updateCallApiRunable(slkSearch);
+	}
+
+
+	/**
+	 * 샵링커 상품등록
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public GagaMap createShoplinkerXml(Collection<GagaMap> ecxelGoodsList, ShoplinkerGoods shoplinkerGoods)throws IOException {
+		// 파일명 뒤에 붙일 시간
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
+		dateStr = sdf.format(cal.getTime());
+
+		GagaMap rtnMap = new GagaMap();
+		int optionAll=0, optionSucc=0;
+		int excelCnt= ecxelGoodsList.size();
+		int tProdSucc = 0, productSucc=0, goodsNotiSucc=0, certSucc=0, imageSucc=0;
+
+		shoplinkerGoods.setRegNo(TsaSession.getInfo().getUserNo());
+
+		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;
+
+				// 상품생성 성공 시 고시,인증,이미지 보냄
+				if( 0 < tProdSucc ) {
+				//if( true ) {
+					// 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 = shoplinkerDao.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");
+
+					// api 호출 및 결과 history 저장
+					succCnt += callGoodsRegApi(regMap , sbRequest, "option_"+opCnt);
+				}
+			}
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			regMap.setApiResult("error");
+			regMap.setApiMessage("xml 생성오류");
+			shoplinkerDao.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 = shoplinkerDao.getGoods(shoplinkerGoods);
+
+			// 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");
+
+			// 상세폼신규사용여부 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");
+
+				sbRequest.append("			<detail_desc>").append(descStr).append("</detail_desc>\n");
+			}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 = shoplinkerDao.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") || -1 <map.getSysImgNm().indexOf("_"+map.getColorCd()+"_M")) { //대표상품 모델컷
+						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") || -1 < map.getSysImgNm().indexOf("_"+map.getColorCd()+"_S")) { //대표상품 패브릭(소재컷?)
+						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");
+
+					sbRequest.append("			<detail_desc>").append(descStr).append("</detail_desc>\n");
+
+				}else {
+
+					String htmlDesc = "";
+					// 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 = shoplinkerDao.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 = shoplinkerDao.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=''>";
+
+	                	String typeCd = "";
+	                	int cnt = 0;
+	                	for(ShoplinkerGoods size : sizeList) {
+	                		typeCd = size.getSizeTypecd();
+	                		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 = shoplinkerDao.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 - 인증대상아님
+	                	}
+	                }
+
+					sbRequest.append("			<detail_desc>").append(htmlDesc).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()+")");
+				shoplinkerDao.insertShoplinerApiHst(regMap);
+			}
+
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			regMap.setApiResult("error");
+			regMap.setApiMessage("xml 생성오류");
+			shoplinkerDao.insertShoplinerApiHst(regMap);
+		}
+
+		return succCnt;
+	}
+
+	/**
+	 * 샵링커 상품등록 - 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 = shoplinkerDao.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 생성오류");
+			shoplinkerDao.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 = shoplinkerDao.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 생성오류");
+			shoplinkerDao.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 = shoplinkerDao.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 생성오류");
+			shoplinkerDao.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;
+
+		try {
+			GagaShoplinkertUtil shoplinkerUtil = new GagaShoplinkertUtil("MS949");
+
+			// XML 파일 생성
+			StringBuilder xmlFileName = new StringBuilder();
+			xmlFileName.append(fileNm+"_"+dateStr).append(".xml");
+			String xmlPath = GagaFileUtil.getConcatenationPath(map.getXmlPath(), xmlFileName.toString());
+			shoplinkerUtil.makeRequestXmlFile(sbRequest.toString(), xmlPath);
+			String xmlUrl = GagaFileUtil.getConcatenationPath(map.getDomainUrl(), xmlFileName.toString());
+
+			// API 호출
+			String apiUrl = GagaShoplinkerConstants.API_DOMAIN + map.getApiSubUrl() + URLEncoder.encode(xmlUrl);
+						// 테스트 URL
+						//apiUrl = GagaShoplinkerConstants.API_DOMAIN+"/Product/attribute_prod_insert.php?iteminfo_url="+"http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/option_1.xml";
+			String responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(apiUrl, "");
+
+			log.info(map.getApiType()+" ####xmlUrl "+xmlUrl);
+			log.info(map.getApiType()+" ####apiUrl "+apiUrl);
+			//log.error(map.getApiType()+" ####responseXmlData n"+responseXmlData);
+
+			// response 결과
+			shoplinkerResult = (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			map.setXmlTxt(sbRequest.toString());
+			map.setApiProductId(resultMsg.getProductId());
+			map.setApiResult(resultMsg.getResult());
+			map.setApiMessage(resultMsg.getMessage());
+
+			if( "true".equals(resultMsg.getResult())){
+				succCnt = 1;
+			}
+
+			// 생성 파일삭제
+			//GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(map.getXmlPath(), xmlFileName.toString()));
+
+		} catch (Exception e) {
+			log.error("error", e);
+			map.setXmlTxt(sbRequest.toString());
+			map.setApiResult("error");
+			map.setApiMessage("API 통신오류");
+		}
+
+		// 전송이력 저장
+		shoplinkerDao.insertShoplinerApiHst(map);
+
+		return succCnt;
+	}
+
+	/**
+	 * 상품등록-상품 목록 건수
+	 *
+	 * @param getGoodsSendListCount
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getGoodsSendListCount(ShoplinkerSearch shoplinkerSearch) {
+		return shoplinkerDao.getGoodsSendListCount(shoplinkerSearch);
+	}
+
+	/**
+	 * 상품등록-상품 목록
+	 *
+	 * @param getGoodsSendList
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerGoods> getGoodsSendList(ShoplinkerSearch shoplinkerSearch) {
+		return shoplinkerDao.getGoodsSendList(shoplinkerSearch);
+	}
+
+	/**
+	 * 샵링커주문수집-목록 건수
+	 *
+	 * @param getGoodsSendListCount
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getShoplinkerOrderListCount(ShoplinkerOrder shoplinkerOrder) {
+		return shoplinkerDao.getShoplinkerOrderListCount(shoplinkerOrder);
+	}
+
+	/**
+	 * 샵링커주문수집-목록
+	 *
+	 * @param getGoodsSendList
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerOrder> getShoplinkerOrderList(ShoplinkerOrder shoplinkerOrder) {
+		return shoplinkerDao.getShoplinkerOrderList(shoplinkerOrder);
+	}
+
+	/**
+	 * 샵링커주문수집-상세
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 28
+	 */
+	public ShoplinkerOrder getShoplinkerOrderInfo(ShoplinkerOrder shoplinkerOrder) {
+		return shoplinkerDao.getShoplinkerOrderInfo(shoplinkerOrder);
+	}
+
+	/**
+	 * 샵링커주문수집-주문수집등록 페이지별 호출
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public GagaMap insertShoplinkerOrderStep1(ShoplinkerOrder shoplinkerOrder) throws IOException {
+		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
+		slkSearch.setSid(shoplinkerOrder.getSid());
+		slkSearch.setRunStat("RUN");
+
+		// 파일명 뒤에 붙일 시간
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
+		dateStr = sdf.format(cal.getTime());
+
+		int totalPage = 0;
+		int totalCount = 0;
+		int currentlyPage = 1;
+		int currListCount = 0;
+
+		// 1. 첫번째 호출
+		shoplinkerOrder.setOrderPageNo(currentlyPage);
+		GagaMap map = this.insertShoplinkerOrderStep1Xml(shoplinkerOrder);
+		totalPage = map.getInt("totalPage");
+		totalCount = map.getInt("totalCount");
+		currentlyPage = map.getInt("currentlyPage");
+		currListCount = map.getInt("currListCount");
+
+		slkSearch.setTxt(shoplinkerOrder.getApiStDate()+ " 총페이지: "+totalPage+ "("+totalCount+"건) || "+currentlyPage);
+		updateCallApiRunable(slkSearch);
+
+		if( currentlyPage < 1 ) currentlyPage = 1;
+		currentlyPage ++;	// 두번째 호출 페이지 수
+
+		// 2. 페이지번호가 존재할 경우, n번째까지 호출(주문수집)
+		//totalPage = 2;
+		for( int i=currentlyPage; i<= totalPage; i++) {
+
+			slkSearch.setTxt("=>"+i);
+			updateCallApiRunable(slkSearch);
+
+			shoplinkerOrder.setOrderPageNo(i);
+			map = this.insertShoplinkerOrderStep1Xml(shoplinkerOrder);
+			currListCount += map.getInt("currListCount");
+		}
+
+		map.setInt("currListCount", currListCount);
+
+		return map;
+	}
+
+	/**
+	 * 샵링커주문수집-주문수집등록
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public GagaMap insertShoplinkerOrderStep1Xml(ShoplinkerOrder shoplinkerOrder) throws IOException {
+
+		GagaMap returnMap = new GagaMap();
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+		regMap.setApiSubUrl(env.getProperty("shoplinker.url.order"));
+		regMap.setDomainUrl(shoplinkerOrder.getDomainUrl());
+
+		int totalPage = 0;
+		int currentlyPage = 0;	// 샵링커 header 현재 호출된 페이지번호
+		int totalCount = 0;		// 샵링커 header 총 주문건수
+		int currListCount = 0;  // for문안 목록 건수 건건이
+		try {
+
+			// xml 데이터 세팅
+			String responseXmlData;
+			com.gagaframework.shoplinker.domain.orderlist.Shoplinker shoplinkerResult;
+
+			List<Order> rOrdList;
+			com.gagaframework.shoplinker.domain.orderlist.Header rHeader;
+			StringBuilder sbRequest;
+
+			sbRequest = new StringBuilder();
+			sbRequest.append("<?xml version=\"1.0\" encoding=\"euc-kr\"?>\n");
+			sbRequest.append("<Shoplinker>\n");
+			sbRequest.append("	<OrderInfo>\n");
+			sbRequest.append("		<Order>\n");
+
+			sbRequest.append("			<customer_id>").append(shoplinkerOrder.getCustomerId()).append("</customer_id>\n");
+			sbRequest.append("			<shoplinker_id><![CDATA[").append(shoplinkerOrder.getShoplinkerId()).append("]]></shoplinker_id>\n");
+			sbRequest.append("			<st_date>").append(shoplinkerOrder.getApiStDate().replace("-", "")).append("</st_date>\n");
+			sbRequest.append("			<ed_date>").append(shoplinkerOrder.getApiStDate().replace("-", "")).append("</ed_date>\n");
+			sbRequest.append("			<page_no>").append(shoplinkerOrder.getOrderPageNo()).append("</page_no>\n");
+
+			sbRequest.append("		</Order>\n");
+			sbRequest.append("	</OrderInfo>\n");
+			sbRequest.append("</Shoplinker>\n");
+			log.info("\n\n###################"+ sbRequest.toString());
+
+
+			GagaShoplinkertUtil shoplinkerUtil = new GagaShoplinkertUtil("MS949");
+
+			// XML 파일 생성
+			StringBuilder xmlFileName = new StringBuilder();
+			xmlFileName.append("order"+"_"+dateStr).append(".xml");
+			String xmlPath = GagaFileUtil.getConcatenationPath(shoplinkerOrder.getXmlPath(), xmlFileName.toString());
+			shoplinkerUtil.makeRequestXmlFile(sbRequest.toString(), xmlPath);
+			String xmlUrl = GagaFileUtil.getConcatenationPath(shoplinkerOrder.getDomainUrl(), xmlFileName.toString());
+
+			if ("run".equals(shoplinkerOrder.getProfiles())) { // 운영서버이면
+				try {
+					// API 호출
+					responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+regMap.getApiSubUrl()+URLEncoder.encode(xmlUrl), "");
+
+					// response 결과
+					shoplinkerResult = (com.gagaframework.shoplinker.domain.orderlist.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.orderlist.Shoplinker.class, responseXmlData);
+					rHeader = shoplinkerResult.getHeader();
+					rOrdList = shoplinkerResult.getOrder();
+
+					// 수집정보 없음
+					if( null != rHeader ) {
+						totalCount = rHeader.getTotalCount();
+						totalPage = rHeader.getTotalPage();
+						currentlyPage = rHeader.getCurrentlyPage();
+						ShoplinkerOrder slOrder = null;
+
+						for(Order ord : rOrdList) {
+							slOrder = new ShoplinkerOrder();
+							slOrder.setAllParams(ord);
+							slOrder.setOrderIfIdx(commonService.getNextSequence("SEQ_SHHOPLINKER_ORD"));
+							currListCount ++;
+
+							//1. 샵링커 주문등록
+							try {
+
+								shoplinkerDao.insertShoplinkerOrder(slOrder);
+							}catch(Exception e) {
+								ShoplinkerGoods map = new ShoplinkerGoods();
+								String chkParams = "";
+								chkParams += "SHOPLINKER_ORDER_ID="+ord.getShoplinkerOrderId() +",MALL_ORDER_ID="+ord.getMallOrderId()
+										  + ",ORDER_NAME="+ord.getOrderName() + ",ORDER_TEL="+ord.getOrderTel() + ",ORDER_CEL="+ord.getOrderCel()
+										  + ",RECEIVE="+ord.getReceive() + ",RECEIVE_TEL="+ord.getReceiveTel() + ",RECEIVE_CEL="+ord.getReceiveCel()
+										  + ",RECEIVE_ADDR="+ord.getReceiveAddr() + ",DELIVERY_MSG="+ord.getDeliveryMsg() + ",PRODUCT_NAME="+ord.getProductName()
+										  + ",SKU="+ord.getSku() + ",SUPPLY_ID="+ord.getSupplyId() + ",DELIVERY="+ord.getDelivery() + ",ORDER_USER_ID="+ord.getOrderUserId()
+										  + ",SCRSPIK_USE="+ord.getCrspikUse() + ",DEAL_NO="+ord.getDealNo() + ",ORDER_MAIN_KEY="+ord.getOrderMainKey()
+										  + ",PAN_TYPE="+ord.getPanType() + ",SCHANNEL_TYPE="+ord.getChannelType() + ",SHIP_NO="+ord.getShipNo();
+								map.setApiType("ORDER");
+								map.setXmlTxt(chkParams);
+								map.setApiResult("error");
+								map.setApiMessage("샵링커 주문생성 오류");
+
+								// 오류이력 저장
+								shoplinkerDao.insertShoplinerApiHst(map);
+							}
+						}
+
+						log.debug("Shoplinker API Call: success");
+						log.debug("responseXmlData {}", responseXmlData);
+					}else {
+
+						ShoplinkerGoods map = new ShoplinkerGoods();
+						map.setApiType("ORDER");
+						map.setXmlTxt(responseXmlData);
+						map.setApiResult("false");
+						map.setApiMessage(shoplinkerOrder.getApiStDate() + " => 처리건 없음");
+						shoplinkerDao.insertShoplinerApiHst(map);
+					}
+
+				} catch (Exception e) {
+					log.error("error", e);
+					ShoplinkerGoods map = new ShoplinkerGoods();
+					map.setApiType("ORDER");
+					map.setXmlTxt(sbRequest.toString());
+					map.setApiResult("error");
+					map.setApiMessage("API 통신오류 =>"+StringUtils.abbreviate(e.getMessage(), 0 , 120));
+					shoplinkerDao.insertShoplinerApiHst(map);
+				}
+
+			}else {
+				// 테스트용
+				xmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order/order_real_0430_"+shoplinkerOrder.getOrderPageNo()+".xml";
+
+				// API 호출
+				//responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+regMap.getApiSubUrl()+URLEncoder.encode(xmlUrl), "");
+								//testOrderStr();
+				try {
+					// API 호출
+					responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+regMap.getApiSubUrl()+URLEncoder.encode(xmlUrl), "");
+
+					// response 결과
+					shoplinkerResult = (com.gagaframework.shoplinker.domain.orderlist.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.orderlist.Shoplinker.class, responseXmlData);
+					rHeader = shoplinkerResult.getHeader();
+					rOrdList = shoplinkerResult.getOrder();
+
+					// 수집정보 없음
+					if( null != rHeader ) {
+						totalCount = rHeader.getTotalCount();
+						totalPage = rHeader.getTotalPage();
+						currentlyPage = rHeader.getCurrentlyPage();
+						ShoplinkerOrder slOrder = null;
+
+						for(Order ord : rOrdList) {
+							slOrder = new ShoplinkerOrder();
+							slOrder.setAllParams(ord);
+							slOrder.setOrderIfIdx(commonService.getNextSequence("SEQ_SHHOPLINKER_ORD"));
+							currListCount ++;
+
+							//1. 샵링커 주문등록
+							try {
+
+								shoplinkerDao.insertShoplinkerOrder(slOrder);
+							}catch(Exception e) {
+								ShoplinkerGoods map = new ShoplinkerGoods();
+								String chkParams = "";
+								chkParams += "SHOPLINKER_ORDER_ID="+ord.getShoplinkerOrderId() +",MALL_ORDER_ID="+ord.getMallOrderId()
+										  + ",ORDER_NAME="+ord.getOrderName() + ",ORDER_TEL="+ord.getOrderTel() + ",ORDER_CEL="+ord.getOrderCel()
+										  + ",RECEIVE="+ord.getReceive() + ",RECEIVE_TEL="+ord.getReceiveTel() + ",RECEIVE_CEL="+ord.getReceiveCel()
+										  + ",RECEIVE_ADDR="+ord.getReceiveAddr() + ",DELIVERY_MSG="+ord.getDeliveryMsg() + ",PRODUCT_NAME="+ord.getProductName()
+										  + ",SKU="+ord.getSku() + ",SUPPLY_ID="+ord.getSupplyId() + ",DELIVERY="+ord.getDelivery() + ",ORDER_USER_ID="+ord.getOrderUserId()
+										  + ",SCRSPIK_USE="+ord.getCrspikUse() + ",DEAL_NO="+ord.getDealNo() + ",ORDER_MAIN_KEY="+ord.getOrderMainKey()
+										  + ",PAN_TYPE="+ord.getPanType() + ",SCHANNEL_TYPE="+ord.getChannelType() + ",SHIP_NO="+ord.getShipNo();
+								map.setApiType("ORDER");
+								map.setXmlTxt(chkParams);
+								map.setApiResult("error");
+								map.setApiMessage("샵링커 주문생성 오류");
+
+								// 오류이력 저장
+								shoplinkerDao.insertShoplinerApiHst(map);
+							}
+						}
+
+						log.debug("Shoplinker API Call: success");
+						log.debug("responseXmlData {}", responseXmlData);
+					}else {
+
+						ShoplinkerGoods map = new ShoplinkerGoods();
+						map.setApiType("ORDER");
+						map.setXmlTxt(responseXmlData);
+						map.setApiResult("false");
+						map.setApiMessage(shoplinkerOrder.getApiStDate() + " => 처리건 없음");
+						shoplinkerDao.insertShoplinerApiHst(map);
+					}
+
+				} catch (Exception e) {
+					log.error("error", e);
+					ShoplinkerGoods map = new ShoplinkerGoods();
+					map.setApiType("ORDER");
+					map.setXmlTxt(sbRequest.toString());
+					map.setApiResult("error");
+					map.setApiMessage("API 통신오류 =>"+StringUtils.abbreviate(e.getMessage(), 0 , 120));
+					shoplinkerDao.insertShoplinerApiHst(map);
+				}
+			}
+
+			returnMap.setString("RESULT_TYPE", "TRUE");
+
+			// 생성 파일삭제
+			GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(shoplinkerOrder.getXmlPath(), xmlFileName.toString()));
+
+		}catch(Exception e) {
+			log.error("xml 생성오류 ", e);
+			returnMap.setString("RESULT_TYPE", "error");
+			returnMap.setString("RESULT_MSG", "xml 생성오류");
+		}
+
+		returnMap.setInt("currListCount", currListCount);
+		returnMap.setInt("totalCount", totalCount);	// 총 주문건수
+		returnMap.setInt("totalPage", totalPage);
+		returnMap.setInt("currentlyPage", currentlyPage);
+
+		return returnMap;
+	}
+
+	/**
+	 * 샵링커주문수집-제휴몰 주문등록
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public void insertShoplinkerOrderStep2(ShoplinkerOrder shoplinkerOrder) throws IOException {
+
+		// 1. 외부몰 미등록 목록 가져옴
+		Collection<ShoplinkerOrder> slkOrdList = shoplinkerDao.getShoplinkerRegExtmallList();
+
+		ExtmallOrder extmallOrder;
+		GagaMap addrMap; 	//주소 분리
+		GagaMap checkMap;
+		for(ShoplinkerOrder slOrder : slkOrdList) {
+
+			extmallOrder = new ExtmallOrder();
+			extmallOrder.setAllParams(slOrder);
+			extmallOrder.setVendorId(TsaConstants.VendorId.SHOPLINKER.value());	// 샵링커
+			extmallOrder.setUploadStat("G021_00"); // 대기
+			extmallOrder.setRegNo(TsaSession.getInfo().getUserNo());
+
+			try {
+
+				if( null != slOrder.getDisPriceCoupon() && !slOrder.getDisPriceCoupon().isEmpty()) {
+					extmallOrder.setCpnDcAmt(Integer.parseInt(slOrder.getDisPriceCoupon()));
+				}else {
+					extmallOrder.setCpnDcAmt(0);
+				}
+
+				if( null != slOrder.getDisPricePoint() && !slOrder.getDisPricePoint().isEmpty()) {
+					extmallOrder.setPntDcAmt(Integer.parseInt(slOrder.getDisPricePoint()));
+				}else {
+					extmallOrder.setPntDcAmt(0);
+				}
+
+				// validation 체크
+				checkMap = getRegOrderValidation(slOrder);
+				if( "FAIL".equals(checkMap.getString("RESULT_MSG"))) {
+					extmallOrder.setUploadStat(checkMap.getString("UploadStat"));	//실패
+					extmallOrder.setUploadFailCd(checkMap.getString("UploadFailCd"));
+					extmallOrder.setUploadFailReason(checkMap.getString("UploadFailReason")); // 실패사유
+
+				}else {
+					// 주소분리
+					addrMap = this.returnChangeAddr(slOrder.getReceiveAddr());
+					extmallOrder.setRecipBaseAddr(addrMap.getString("addrBase"));
+					extmallOrder.setRecipDtlAddr(addrMap.getString("addrDtl"));
+				}
+
+				ocmDao.insertExtmallOrder(extmallOrder);
+
+			}catch(Exception e) {
+				log.error("TsaShoplinkerService.insertShoplinkerOrderStep2 Error : "+e);
+				extmallOrder.setUploadStat("G021_40");	//실패
+				extmallOrder.setUploadFailCd("G022_90");
+				//extmallOrder.setUploadFailCd(xmlUrl);
+				extmallOrder.setUploadFailReason("제휴몰 등록오류 :: "+StringUtils.abbreviate(e.getMessage(), 0 , 120)); // 실패사유
+				ocmDao.insertExtmallOrder(extmallOrder);
+			}
+
+			// 제휴몰등록여부 업데이트
+			shoplinkerDao.updateShoplinkerOrder(slOrder);
+		}
+	}
+
+	/**
+	 * 샵링커주문수집-validation 체크
+	 *
+	 * @param shoplinkerOrder
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public GagaMap getRegOrderValidation(ShoplinkerOrder slOrder) {
+
+		GagaMap rMap = new GagaMap();
+		rMap.setString("RESULT_MSG", "FAIL");
+		rMap.setString("UploadStat", "G021_40");
+
+		/*if( null != slOrder.getDeliveryInvoice() && !slOrder.getDeliveryInvoice().isEmpty()) {
+		    rMap.setString("UploadFailCd", "G022_70");
+			rMap.setString("UploadFailReason", "송장번호가 존재하는 주문건입니다. 제휴몰 주문업로드 불가");
+			return rMap;
+		}*/
+
+		if( null == slOrder.getReceiveAddr() || slOrder.getReceiveAddr().isEmpty()) {
+			rMap.setString("UploadFailCd", "G022_90");
+			rMap.setString("UploadFailReason", "주소정보 없음.");
+			return rMap;
+		}
+
+		rMap.setString("RESULT_MSG", "SUCCESS");
+
+		return rMap;
+	}
+
+	/**
+	 * 제휴몰 주문수집 상세
+	 *
+	 * @param
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 28
+	 */
+	public ExtmallOrder getExtmallOrderInfo(String extmallOrder) {
+		return shoplinkerDao.getExtmallOrderInfo(extmallOrder);
+	}
+
+	/**
+	 * 송장전송-전송
+	 *
+	 * @param shoplinkerGoods
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	public void createShoplinkerInvoiceXml(ShoplinkerInvoice shoplinkerInvoice) throws IOException {
+		// 파일명 뒤에 붙일 시간
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
+		dateStr = 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(0);
+		regMap.setXmlPath(shoplinkerInvoice.getXmlPath());
+		regMap.setDomainUrl(shoplinkerInvoice.getDomainUrl());
+
+		StringBuilder sbRequest;
+		com.gagaframework.shoplinker.domain.invoice.ResultMessage resultMsg_tmp;
+
+		Collection<ShoplinkerInvoice> sendList = shoplinkerDao.getShoplinkerInvoiceOrdDtlList(shoplinkerInvoice);
+
+		if( null != sendList && !sendList.isEmpty()) {
+			for(ShoplinkerInvoice info : sendList) {
+				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()+"_"+dateStr).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"; // test
+					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.gagaframework.shoplinker.domain.goods.result.ResultMessage resultMsg;	//임시
+					resultMsg = (com.gagaframework.shoplinker.domain.goods.result.ResultMessage)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.ResultMessage.class, responseXmlData);
+					//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 shoplinkerGoods
+	 * @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");
+		dateStr = 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.getShoplinkerInvoiceOrdDtlList(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()+"_"+dateStr).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 getGoodsSendListCount
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getSendInvoiceListCount(ShoplinkerInvoice shoplinkerInvoice) {
+		return shoplinkerDao.getSendInvoiceListCount(shoplinkerInvoice);
+	}
+
+	/**
+	 * 송장전송-목록
+	 *
+	 * @param getGoodsSendList
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerInvoice> getSendInvoiceList(ShoplinkerInvoice shoplinkerInvoice) {
+		return shoplinkerDao.getSendInvoiceList(shoplinkerInvoice);
+	}
+
+	/**
+	 * 재고전송-목록 건수
+	 *
+	 * @param getStockListCount
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public int getStockListCount(ShoplinkerSearch shoplinkerSearch) {
+		return shoplinkerDao.getStockListCount(shoplinkerSearch);
+	}
+
+	/**
+	 * 재고전송-목록
+	 *
+	 * @param getStockListList
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public Collection<ShoplinkerGoods> getStockListList(ShoplinkerSearch shoplinkerSearch) {
+		return shoplinkerDao.getStockListList(shoplinkerSearch);
+	}
+
+	/**
+	 * 제휴몰 주문등록 주소분리
+	 *
+	 * @param addrStr
+	 * @return
+	 * @author jmh
+	 * @since 2020. 5. 21
+	 */
+	public GagaMap returnChangeAddr(String addrStr) {
+		GagaMap rtnMap = new GagaMap();
+
+		String tmpStr = "";
+		String addrBase = "";
+		String addrDtl = "";
+
+		if( -1 < addrStr.indexOf(" ")) {
+			// 공백  있음!
+			String[] addr = addrStr.split(" ");
+			if( addrStr.getBytes().length <= 100) {
+				addrBase = addr[0];
+				addrDtl = addrStr.replace(addr[0], "").trim();
+			}else {
+
+				for( int i=0; i< addr.length; i++) {
+					tmpStr = addrBase + addr[i];
+					if( 100 <  tmpStr.getBytes().length) {
+						break;
+					}else {
+						addrBase += addr[i]+" ";
+					}
+				}
+
+				addrBase = addrBase.trim();
+				addrDtl = addrStr.replace(addrBase, "").trim();
+			}
+
+		}else {
+			// 공백 없음! 무작위로 자르기!!
+			if( addrStr.getBytes().length <= 100) {
+				addrBase = addrStr;
+				addrDtl = null;
+			}else {
+
+				tmpStr = addrStr.substring(0, addrStr.length()/2);
+				if( 100 < tmpStr.getBytes().length ) {
+					tmpStr = tmpStr.substring(0, tmpStr.length()/2);
+				}
+				// 숫자를 기준으로 자름
+				for (char c : tmpStr.toCharArray()) {
+					if (Character.isDigit(c)) {
+			           break;
+			        }else {
+			        	addrBase += c;
+			        }
+			    }
+				addrBase = addrBase.trim();
+				addrDtl = addrStr.replace(addrBase, "").trim();
+			}
+		}
+
+		rtnMap.put("addrBase", addrBase);
+		rtnMap.put("addrDtl", addrDtl);
+
+		return rtnMap;
+	}
+
+	// 테스트데이터
+	private String testOrderStr() {
+
+		String bbb = "<?xml version=\"1.0\" encoding=\"euc-kr\"?>"
+				+ "<Shoplinker>\r\n"
+				+ "<header>\r\n"
+				+ "<total_count>27</total_count>\r\n"
+				+ "<total_page>1</total_page>\r\n"
+				+ "<currently_page>1</currently_page>\r\n"
+				+ "<currently_count>27</currently_count>\r\n"
+				+ "</header>\r\n"
+
+				+ "<order>\r\n"
+				+ "<shoplinker_order_id>0611683168</shoplinker_order_id>\r\n"
+				+ "<mall_order_id><![CDATA[20210129292734]]></mall_order_id>\r\n"
+				+ "<mall_name><![CDATA[(주)현대홈쇼핑]]></mall_name>\r\n"
+				+ "<baesong_status><![CDATA[송장전송완료]]></baesong_status>\r\n"
+				+ "<order_name><![CDATA[]]></order_name>\r\n"
+				+ "<order_tel><![CDATA[]]></order_tel>\r\n"
+				+ "<order_cel><![CDATA[]]></order_cel>\r\n"
+				+ "<order_email><![CDATA[]]></order_email>\r\n"
+				+ "<receive><![CDATA[]]></receive>\r\n"
+				+ "<receive_tel><![CDATA[]]></receive_tel>\r\n"
+				+ "<receive_cel><![CDATA[]]></receive_cel>\r\n"
+				+ "<receive_zipcode><![CDATA[]]></receive_zipcode>\r\n"
+				+ "<receive_addr><![CDATA[주소소주소주주소소주소주주소소주소주주소13소주소주주소소주주소소주소주주소소주소주]]></receive_addr>\r\n"
+				+ "<baesong_type><![CDATA[쇼핑몰확인요망]]></baesong_type>\r\n"
+				+ "<baesong_bi>0</baesong_bi>\r\n"
+				+ "<delivery_msg><![CDATA[]]></delivery_msg>\r\n"
+				+ "<order_product_id>2118602667</order_product_id>\r\n"
+				+ "<shoplinker_product_id>prd143809490</shoplinker_product_id>\r\n"
+				+ "<partner_product_id>NNW13QPM69</partner_product_id>\r\n"
+				+ "<product_name><![CDATA[[나이키 조던 키즈] 윙스MA-1 재킷B NNW13QPM69 (주니어)]]></product_name>\r\n"
+				+ "<quantity>1</quantity>\r\n"
+				+ "<order_price>47600</order_price>\r\n"
+				+ "<sale_price>47600</sale_price>\r\n"
+				+ "<supply_price>36176</supply_price>\r\n"
+				+ "<sku><![CDATA[NA/160]]></sku>\r\n"
+				+ "<orderdate>20210129132721</orderdate>\r\n"
+				+ "<order_reg_date>20210201004337</order_reg_date>\r\n"
+				+ "<delivery_invoice>339382561300</delivery_invoice>\r\n"
+				+ "<order_flag>004</order_flag>\r\n"
+				+ "<seller_id>hs009583</seller_id>\r\n"
+				+ "<only_sku><![CDATA[]]></only_sku>\r\n"
+				+ "<add_sku><![CDATA[]]></add_sku>\r\n"
+				+ "<mall_id><![CDATA[APISHOP_0015]]></mall_id>\r\n"
+				+ "<dis_price_mall><![CDATA[]]></dis_price_mall>\r\n"
+				+ "<dis_price_seller><![CDATA[]]></dis_price_seller>\r\n"
+				+ "<dis_price_coupon><![CDATA[]]></dis_price_coupon>\r\n"
+				+ "<dis_price_point><![CDATA[]]></dis_price_point>\r\n"
+				+ "<distribution_delivery><![CDATA[001]]></distribution_delivery>\r\n"
+				+ "<sku_match_code><![CDATA[12112927-3]]></sku_match_code>\r\n"
+				+ "<sku_barcode><![CDATA[]]></sku_barcode>\r\n"
+				+ "<order_main_key><![CDATA[]]></order_main_key>\r\n"
+				+ "<order_customs_number><![CDATA[]]></order_customs_number>\r\n"
+				+ "<order_input_type><![CDATA[001]]></order_input_type>\r\n"
+				+ "<supply_id><![CDATA[]]></supply_id>\r\n"
+				+ "<delivery><![CDATA[delv0094]]></delivery>\r\n"
+				+ "<order_user_id><![CDATA[]]></order_user_id>\r\n"
+				+ "<crspik_use><![CDATA[]]></crspik_use>\r\n"
+				+ "<ship_no>20210129292734</ship_no>\r\n"
+				+ "<pan_type><![CDATA[]]></pan_type>\r\n"
+				+ "<exchange_order_yn></exchange_order_yn>\r\n"
+				+ "<channel_type>현대Hmall</channel_type>\r\n"
+				+ "<ship_rsv_date></ship_rsv_date>\r\n"
+				+ "</order>\r\n"
+
+				+ "</Shoplinker>\r\n";
+		return bbb;
+	}
+}

+ 898 - 0
src/main/java/com/style24/admin/biz/web/TsaShoplinkerController.java

@@ -0,0 +1,898 @@
+package com.style24.admin.biz.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashMap;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gagaframework.excel.GagaExcelUtil;
+import com.gagaframework.shoplinker.GagaShoplinkertUtil;
+import com.gagaframework.shoplinker.env.GagaShoplinkerConstants;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.rest.server.GagaResponse;
+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.env.TsaConstants;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.TscPageRequest;
+import com.style24.persistence.domain.Extmall;
+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;
+
+/**
+ * 샵링커 Controller
+ *
+ * @author jmh
+ * @since 2021. 5. 20
+ */
+@Controller
+@RequestMapping("/shoplinker")
+@Slf4j
+public class TsaShoplinkerController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaShoplinkerService shoplinkerService;
+
+	@Autowired
+	private TsaOcmService ocmService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private ObjectMapper mapper;
+
+	private static final int EXCEL_ROW_COUNT = 1000;
+
+
+
+	/**
+	 * 샵링커상품등록-화면
+	 *
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@GetMapping("/goods/send/form")
+	public ModelAndView goodsSendForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("shoplinker/ShoplinkerGoodsSendForm");
+
+		return mav;
+	}
+
+	/**
+	 * 샵링커상품등록-전송목록조회
+	 *
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@PostMapping("/goods/send/list")
+	@ResponseBody
+	public GagaMap getSendGoodsList(@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("브랜드코드 검색중 오류로 인해 조회되지 않았습니다.");
+			}
+		}
+
+		shoplinkerSearch.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerSearch.setPageable(new TscPageRequest(shoplinkerSearch.getPageNo() - 1, shoplinkerSearch.getPageSize()));
+		shoplinkerSearch.getPageable().setTotalCount(shoplinkerService.getGoodsSendListCount(shoplinkerSearch));
+
+		result.set("pageing", shoplinkerSearch);
+		result.set("goodsList", shoplinkerService.getGoodsSendList(shoplinkerSearch));
+
+		return result;
+	}
+
+	/**
+	 * 샵링커상품등록-상품등록엑셀업로드
+	 *
+	 * @param shoplinkerGoods
+	 * @return GagaMap
+	 * @throws Exception
+	 * @author jmh
+	 * @since 2021.5.20
+	 */
+	@PostMapping("/goods/send/excelupload/register")
+	@ResponseBody
+	public void shoplinkerGoodsRegister(@RequestParam HashMap<String, String> paramMap) throws IOException {
+
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+		String datestr = sdf.format(cal.getTime());
+
+		ShoplinkerGoods shoplinkerGoods = new ShoplinkerGoods();
+		shoplinkerGoods.setExcelFileNm(paramMap.get("excelFileNm"));
+
+		GagaMap rtnMap = new GagaMap();
+		boolean a_bool = true;
+		String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		Collection<GagaMap> ecxelGoodsList = new ArrayList<>();
+
+		// API 호출 중인건수 있는지 확인
+		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
+		slkSearch.setApiType("GOODS");
+		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		if( null != runMap ) {
+			a_bool = false;
+			// 현재 실행중인값 존재
+			rtnMap.setString("RESULT_TYPE", "RUN");
+			rtnMap.setString("RESULT_MSG", runMap.getRunStdt()+"에 호출한 건이 현재 실행중입니다.");
+		}
+
+		if( a_bool ) {
+			try {
+				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
+				slkSearch.setSid(datestr);
+				slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
+				shoplinkerService.saveCallApiRunable(slkSearch);
+
+				// 2. 엑셀데이터 확인 및 xml 관련 위치 확인
+				String[] goodsNames = {"goodsCd", "supplyCompCd"};
+				ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, shoplinkerGoods.getExcelFileNm()), 0, goodsNames, 0);
+
+				if (ecxelGoodsList != null && ecxelGoodsList.size() > EXCEL_ROW_COUNT) {
+					throw new IllegalStateException("엑셀 파일의 건수를 " +EXCEL_ROW_COUNT + "건 이하로 사용하세요.");
+				}
+
+				// xml 생성경로
+				shoplinkerGoods.setXmlPath(env.getProperty("shoplinker.xml.path")+"/goods_reg");
+				// xml 확인domain url
+				shoplinkerGoods.setDomainUrl(env.getProperty("shoplinker.xml.view")+"/goods_reg");
+
+				// 샵링커 기본폴더 존재여부 확인
+				String slFolder = GagaFileUtil.getConcatenationPath(env.getProperty("shoplinker.xml.path"));
+				File slPath = new File(slFolder);
+				if (!slPath.exists()) {
+					slPath.mkdir();
+				}
+				//하위폴더존재확인(상품등록)
+				slFolder = GagaFileUtil.getConcatenationPath(shoplinkerGoods.getXmlPath());
+				slPath = new File(slFolder);
+				if (!slPath.exists()) {
+					slPath.mkdir();
+				}
+
+				// 3. xml 데이터 생성
+				shoplinkerGoods.setCustomerId(env.getProperty("shoplinker.customer_id"));
+				rtnMap = shoplinkerService.createShoplinkerXml(ecxelGoodsList, shoplinkerGoods);
+
+				// 4. 파일 삭제
+				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, shoplinkerGoods.getExcelFileNm()));
+
+				rtnMap.setString("RESULT_TYPE", "TRUE");
+
+			}catch (Exception e) {
+
+				log.error("TsaShoplinkerController.orderReceiveList => error \n"+e);
+				rtnMap.setString("RESULT_TYPE", "ERROR");
+				rtnMap.setString("RUN_STAT", "ERROR");
+				rtnMap.setString("TXT", e.getMessage());
+
+			}finally {
+				// 4. API 호출 이력 저장 종료
+				slkSearch.setRunStat("END");
+				shoplinkerService.saveCallApiRunable(slkSearch);
+			}
+		}
+	}
+
+
+	/**
+	 * 주문수집관리-화면
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@GetMapping("/order/collection/form")
+	public ModelAndView orderCollectionForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 제휴몰벤더
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		// 제휴몰
+		Extmall extmall = new Extmall();
+		extmall.setVendorId(TsaConstants.VendorId.SHOPLINKER.value()); // 샵링커
+		mav.addObject("extmallList", ocmService.getExtmallList(extmall));
+
+		// 업로드상태 콤보박스 목록
+		mav.addObject("uploadStatList", rendererService.getCommonCodeList("G021"));
+
+		// 업로드실패사유 콤보박스 목록
+		mav.addObject("uploadFailList", rendererService.getCommonCodeList("G022"));
+
+		mav.setViewName("shoplinker/ShoplinkerOrderForm");
+
+		return mav;
+	}
+
+	/**
+	 * 주문수집관리-목록조회
+	 *
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@PostMapping("/order/collection/list")
+	@ResponseBody
+	public GagaMap getCollectionList(@RequestBody ShoplinkerOrder shoplinkerOrder) {
+
+		GagaMap result = new GagaMap();
+
+		shoplinkerOrder.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerOrder.setPageable(new TscPageRequest(shoplinkerOrder.getPageNo() - 1, shoplinkerOrder.getPageSize()));
+		shoplinkerOrder.getPageable().setTotalCount(shoplinkerService.getShoplinkerOrderListCount(shoplinkerOrder));
+
+		result.set("pageing", shoplinkerOrder);
+		result.set("shoplinkerOrderList", shoplinkerService.getShoplinkerOrderList(shoplinkerOrder));
+
+		return result;
+	}
+
+	/**
+	 * 주문수집관리-주문상세 화면
+	 *
+	 * @param ordNo - 주문번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 11. 26
+	 */
+	@GetMapping("/order/collection/info")
+	@ResponseBody
+	public ModelAndView collectionOrderForm(@RequestParam(value = "shoplinkerOrderId") String shoplinkerOrderId) {
+		ModelAndView mav = new ModelAndView();
+
+		ShoplinkerOrder order = new ShoplinkerOrder();
+		order.setShoplinkerOrderId(shoplinkerOrderId);
+
+		mav.addObject("slkOrderInfo", shoplinkerService.getShoplinkerOrderInfo(order));
+		mav.addObject("extOrderInfo", shoplinkerService.getExtmallOrderInfo(shoplinkerOrderId));
+
+		mav.setViewName("shoplinker/ShoplinkerOrderDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 주문수집관리-주문수집 api 호출
+	 * @return
+	 * @author jmh
+	 * @throws IOException
+	 * @since 2021. 5. 20
+	 */
+	@PostMapping("/order/collection/receiveList/{apiStDate}")
+	@ResponseBody
+	public void orderReceiveList(@PathVariable("apiStDate") String apiStDate) throws IOException {
+
+		GagaMap rtnMap = new GagaMap();
+
+		boolean a_bool = true;
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+		String datestr = sdf.format(cal.getTime());
+
+		ShoplinkerOrder shoplinkerOrder = new ShoplinkerOrder();
+		shoplinkerOrder.setApiStDate(apiStDate);
+
+		// 서버타입
+		String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		// xml path
+		shoplinkerOrder.setXmlPath(env.getProperty("shoplinker.xml.path")+"/order");
+		// xml 확인domain url
+		shoplinkerOrder.setDomainUrl(env.getProperty("shoplinker.xml.view")+"/order");
+
+		// 하위폴더존재확인(주문)
+		String slFolder = GagaFileUtil.getConcatenationPath(shoplinkerOrder.getXmlPath());
+		File slPath = new File(slFolder);
+		if (!slPath.exists()) {
+			slPath.mkdir();
+		}
+
+		// API 호출 중인건수 있는지 확인
+		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
+		slkSearch.setApiType("ORDER");
+		slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
+		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		if( null != runMap ) {
+			a_bool = false;
+			rtnMap.setString("RESULT_TYPE", "RUN");
+			rtnMap.setString("RESULT_MSG", runMap.getRunStdt()+"에 호출한 건이 현재 실행중입니다.<br>[처리중] "+runMap.getTxt());
+		}
+
+		if( a_bool ) {
+			try {
+				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
+				slkSearch.setSid(datestr);
+				shoplinkerService.saveCallApiRunable(slkSearch);
+
+				// 2. 샵링커 api 호출 샵링커주문수집 등록
+				shoplinkerOrder.setSid(datestr);
+				shoplinkerOrder.setProfiles(profiles);
+				shoplinkerOrder.setCustomerId(env.getProperty("shoplinker.customer_id"));
+				shoplinkerOrder.setShoplinkerId(env.getProperty("shoplinker.shoplinker_id"));
+				rtnMap = shoplinkerService.insertShoplinkerOrderStep1(shoplinkerOrder);
+
+				// 3. 제휴몰 주문등록
+				slkSearch.setTxt("=>제휴몰 주문등록 처리중");
+				shoplinkerService.saveCallApiRunable(slkSearch);
+				shoplinkerService.insertShoplinkerOrderStep2(shoplinkerOrder);
+
+				// 4. 스타일24 주문등록 (제휴몰 - 대기상태인 것들)
+				slkSearch.setTxt("=>스타일24 주문등록 처리중");
+				shoplinkerService.saveCallApiRunable(slkSearch);
+				ocmService.createShoplinkerOrder();
+
+			}catch (Exception e) {
+
+				log.error("TsaShoplinkerController.orderReceiveList => error \n"+e);
+				rtnMap.setString("RESULT_TYPE", "ERROR");
+				rtnMap.setString("RUN_STAT", "ERROR");
+				rtnMap.setString("TXT", e.getMessage());
+				rtnMap.setString("RESULT_MSG", "오류입니다. 관리자에게 문의하세요. \n"+StringUtils.abbreviate(e.getMessage(), 0 , 120));
+				slkSearch.setRunStat("ERROR");
+				slkSearch.setTxt("=>ERROR : "+StringUtils.abbreviate(e.getMessage(), 0 , 120));
+
+			}finally {
+				// 4. API 호출 이력 저장 종료
+				if(!"ERROR".equals(slkSearch.getRunStat())){
+					slkSearch.setRunStat("END");
+					slkSearch.setTxt("=>FINISH");
+				}
+				shoplinkerService.saveCallApiRunable(slkSearch);
+			}
+		}
+
+	}
+
+	/**
+	 * 송장전송관리-화면
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@GetMapping("/invoice/send/form")
+	public ModelAndView invoiceSendForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 제휴몰벤더
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		// 제휴몰
+		Extmall extmall = new Extmall();
+		extmall.setVendorId(TsaConstants.VendorId.SHOPLINKER.value()); // 샵링커
+		mav.addObject("extmallList", ocmService.getExtmallList(extmall));
+
+		mav.setViewName("shoplinker/ShoplinkerInvoiceSendForm");
+
+		return mav;
+	}
+
+	/**
+	 * 송장전송관리-전송목록조회
+	 *
+	 * @return
+	 * @author jmh
+	 * @since 2021. 5. 20
+	 */
+	@PostMapping("/invoice/send/list")
+	@ResponseBody
+	public GagaMap getInvoiceSendList(@RequestBody ShoplinkerInvoice shoplinkerInvoice) {
+
+		GagaMap result = new GagaMap();
+
+		shoplinkerInvoice.setRegNo(TsaSession.getInfo().getUserNo()); // 엑셀조회시 로그인 사용자의 엑셀 상품조회시 사용
+		shoplinkerInvoice.setPageable(new TscPageRequest(shoplinkerInvoice.getPageNo() - 1, shoplinkerInvoice.getPageSize()));
+		shoplinkerInvoice.getPageable().setTotalCount(shoplinkerService.getSendInvoiceListCount(shoplinkerInvoice));
+
+		result.set("pageing", shoplinkerInvoice);
+		result.set("invoiceList", shoplinkerService.getSendInvoiceList(shoplinkerInvoice));
+
+		return result;
+	}
+
+	/**
+	 * 송장전송관리-송장전송
+	 *
+	 * @param shoplinkerGoods
+	 * @return GagaMap
+	 * @throws Exception
+	 * @author jmh
+	 * @since 2021.5.20
+	 */
+	@PostMapping("/invoice/send/register")
+	@ResponseBody
+	public void shoplinkerSendInvoice(@RequestParam(value = "stDate") String stDate, @RequestParam(value = "edDate") String edDate) throws Exception {
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+		String datestr = sdf.format(cal.getTime());
+
+		GagaMap rtnMap = new GagaMap();
+		boolean a_bool = true;
+
+		// API 호출 중인건수 있는지 확인
+		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
+		slkSearch.setApiType("INVOICE");
+		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		if( null != runMap ) {
+			a_bool = false;
+			// 현재 실행중인값 존재
+			rtnMap.setString("RESULT_TYPE", "RUN");
+			rtnMap.setString("RESULT_MSG", runMap.getRunStdt()+"에 호출한 건이 현재 실행중입니다.");
+		}
+
+		if( a_bool ) {
+			try {
+				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
+				slkSearch.setSid(datestr);
+				slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
+				shoplinkerService.saveCallApiRunable(slkSearch);
+
+				ShoplinkerInvoice shoplinkerInvoice = new ShoplinkerInvoice();
+				shoplinkerInvoice.setStDate(stDate);
+				shoplinkerInvoice.setEdDate(edDate);
+
+				// xml 생성경로
+				shoplinkerInvoice.setXmlPath(env.getProperty("shoplinker.xml.path")+"/invoice");
+				// xml 확인domain url
+				shoplinkerInvoice.setDomainUrl(env.getProperty("shoplinker.xml.view")+"/invoice");
+
+				// 샵링커 기본폴더 존재여부 확인
+				String slFolder = GagaFileUtil.getConcatenationPath(env.getProperty("shoplinker.xml.path"));
+				File slPath = new File(slFolder);
+				if (!slPath.exists()) {
+					slPath.mkdir();
+				}
+				//하위폴더존재확인(상품등록)
+				slFolder = GagaFileUtil.getConcatenationPath(shoplinkerInvoice.getXmlPath());
+				slPath = new File(slFolder);
+				if (!slPath.exists()) {
+					slPath.mkdir();
+				}
+
+				// 2. xml 데이터 생성
+				shoplinkerInvoice.setCustomerId(env.getProperty("shoplinker.customer_id"));
+				shoplinkerService.createShoplinkerInvoiceXml(shoplinkerInvoice);
+
+				rtnMap.setString("RESULT_TYPE", "TRUE");
+
+			}catch (Exception e) {
+
+				log.error("TsaShoplinkerController.shoplinkerInvoiceRegister => error \n"+e);
+				rtnMap.setString("RESULT_TYPE", "ERROR");
+				rtnMap.setString("RUN_STAT", "ERROR");
+				rtnMap.setString("TXT", e.getMessage());
+				rtnMap.setString("RESULT_MSG", "오류입니다. 관리자에게 문의해주세요.");
+				slkSearch.setRunStat("ERROR");
+				slkSearch.setTxt("=>ERROR : "+StringUtils.abbreviate(e.getMessage(), 0 , 120));
+
+			}finally {
+				// 3. API 호출 이력 저장 종료
+				if(!"ERROR".equals(slkSearch.getRunStat())){
+					slkSearch.setRunStat("END");
+					slkSearch.setTxt("=>FINISH");
+				}
+				shoplinkerService.saveCallApiRunable(slkSearch);
+			}
+		}
+
+	}
+
+	/**
+	 * 송장전송관리-송장전송(엑셀용)
+	 *
+	 * @param shoplinkerGoods
+	 * @return GagaMap
+	 * @throws Exception
+	 * @author jmh
+	 * @since 2021.5.20
+	 */
+	/******************************************************************************************
+	@PostMapping("/invoice/send/excelupload/register")
+	@ResponseBody
+	public GagaMap shoplinkerInvoiceRegister(@RequestBody ShoplinkerInvoice shoplinkerInvoice) throws Exception {
+
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+		String datestr = sdf.format(cal.getTime());
+
+		GagaMap rtnMap = new GagaMap();
+		boolean a_bool = true;
+		String profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
+		Collection<GagaMap> ecxelGoodsList = new ArrayList<>();
+
+		// API 호출 중인건수 있는지 확인
+		ShoplinkerSearch slkSearch = new ShoplinkerSearch();
+		slkSearch.setApiType("INVOICE");
+		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+		if( null != runMap ) {
+			a_bool = false;
+			// 현재 실행중인값 존재
+			rtnMap.setString("RESULT_TYPE", "RUN");
+			rtnMap.setString("RESULT_MSG", runMap.getRunStdt()+"에 호출한 건이 현재 실행중입니다.");
+		}
+
+		if( a_bool ) {
+			try {
+				// 1. API 호출 이력 저장 시작(실행중 재호출 금지하기 위함)
+				slkSearch.setSid(datestr);
+				slkSearch.setRegNo(TsaSession.getInfo().getUserNo());
+				shoplinkerService.saveCallApiRunable(slkSearch);
+
+				// 2. 엑셀데이터 확인 및 xml 관련 위치 확인
+				String[] goodsNames = {"ordNo", "supplyCompCd"};
+				ecxelGoodsList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, shoplinkerInvoice.getExcelFileNm()), 0, goodsNames, 0);
+
+				if (ecxelGoodsList != null && ecxelGoodsList.size() > EXCEL_ROW_COUNT) {
+					throw new IllegalStateException("엑셀 파일의 건수를 " +EXCEL_ROW_COUNT + "건 이하로 사용하세요.");
+				}
+
+				// xml 생성경로
+				shoplinkerInvoice.setXmlPath(env.getProperty("shoplinker.xml.path")+"/invoice");
+				// xml 확인domain url
+				shoplinkerInvoice.setDomainUrl(env.getProperty("shoplinker.xml.view")+"/invoice");
+
+				// 샵링커 기본폴더 존재여부 확인
+				String slFolder = GagaFileUtil.getConcatenationPath(env.getProperty("shoplinker.xml.path"));
+				File slPath = new File(slFolder);
+				if (!slPath.exists()) {
+					slPath.mkdir();
+				}
+				//하위폴더존재확인(상품등록)
+				slFolder = GagaFileUtil.getConcatenationPath(shoplinkerInvoice.getXmlPath());
+				slPath = new File(slFolder);
+				if (!slPath.exists()) {
+					slPath.mkdir();
+				}
+
+				// 2. xml 데이터 생성
+				shoplinkerInvoice.setCustomerId(env.getProperty("shoplinker.customer_id"));
+				shoplinkerService.createShoplinkerInvoiceXml(ecxelGoodsList, shoplinkerInvoice);
+
+				// 3. 파일 삭제
+				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, shoplinkerInvoice.getExcelFileNm()));
+
+				rtnMap.setString("RESULT_TYPE", "TRUE");
+
+			}catch (Exception e) {
+
+				log.error("TsaShoplinkerController.shoplinkerInvoiceRegister => error \n"+e);
+				rtnMap.setString("RESULT_TYPE", "ERROR");
+				rtnMap.setString("RUN_STAT", "ERROR");
+				rtnMap.setString("TXT", e.getMessage());
+				rtnMap.setString("RESULT_MSG", "오류입니다. 관리자에게 문의해주세요.");
+				slkSearch.setRunStat("ERROR");
+				slkSearch.setTxt("=>ERROR : "+StringUtils.abbreviate(e.getMessage(), 0 , 120));
+
+			}finally {
+				// 4. API 호출 이력 저장 종료
+				if(!"ERROR".equals(slkSearch.getRunStat())){
+					slkSearch.setRunStat("END");
+					slkSearch.setTxt("=>FINISH");
+				}
+				shoplinkerService.saveCallApiRunable(slkSearch);
+			}
+		}
+
+		return rtnMap;
+	}
+	 ******************************************************************************************/
+
+	/**
+	 * 재고이력-화면
+	 * @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("브랜드코드 검색중 오류로 인해 조회되지 않았습니다.");
+			}
+		}
+
+		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.getStockListList(shoplinkerSearch));
+
+		return result;
+	}
+
+	/**
+	 * 공통-api 실행여부확인
+	 *
+	 * @param ordNo - 주문번호
+	 * @return ModelAndView
+	 * @author jsh77b
+	 * @since 2020. 11. 26
+	 */
+	@PostMapping("/check/api_runable")
+	@ResponseBody
+	public GagaMap apiRunable(@RequestBody ShoplinkerSearch slkSearch) throws IOException {
+		GagaMap rtnMap = new GagaMap();
+
+		ShoplinkerSearch runMap = shoplinkerService.getCallRunableInfo(slkSearch);
+
+		if( null != runMap ) {
+			rtnMap.setString("RESULT_TYPE", "RUN");	// 처리중인 목록있음
+			rtnMap.setString("RESULT_MSG", runMap.getRunStdt()+"에 호출한 건이 현재 실행중입니다.");
+			rtnMap.setString("RESULT_TXT", runMap.getTxt());
+
+		}else {
+			rtnMap.setString("RESULT_TYPE", "SUCCESS");	// 가능
+		}
+
+		return rtnMap;
+	}
+
+
+
+
+
+	/*
+	 *
+	 * api test
+	 */
+	@PostMapping("/apiTest2")
+	@ResponseBody
+	public GagaResponse apiTest3(@RequestBody ShoplinkerGoods shoplinkerGoods) throws Exception {
+
+		Calendar cal = Calendar.getInstance();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
+		String datestr = sdf.format(cal.getTime());
+		System.err.println("### 조회시작:: "+datestr);
+
+		int i=0;
+		System.out.println("############### test api ###############");
+		try {
+			GagaShoplinkertUtil shoplinkerUtil = new GagaShoplinkertUtil("MS949");
+
+			String responseXmlData = "";
+
+			com.gagaframework.shoplinker.domain.goods.result.Shoplinker shoplinkerResult;
+			com.gagaframework.shoplinker.domain.goods.result.ResultMessage resultMsg;
+			com.gagaframework.shoplinker.domain.invoice.ObjectFactory obf;
+
+			/**** 송장전송테스트 ************/
+			com.gagaframework.shoplinker.domain.invoice.ResultMessage invoceMsg;
+			responseXmlData = "<?xml version='1.0' encoding='euc-kr'?>\r\n"
+					+ "<ResultMessage>\r\n"
+					+ "<result>false</result>\r\n"
+					+ "<id>123</id>\r\n"
+					+ "<message><![CDATA[택배사 명칭이 일치하지 않거나 코드가 일치하지 않습니다. 재전송 바랍니다.]]></message>\r\n"
+					+ "</ResultMessage>";
+
+			String responseXmlData2 = "<?xml version=\"1.0\" encoding=\"euc-kr\"?>\r\n"
+					+ "			<Shoplinker>\r\n"
+					+ "				<ResultMessage>\r\n"
+					+ "					<result>true</result>\r\n"
+					+ "					<product_id>P1524578</product_id>\r\n"
+					+ "					<message>등록성공</message>\r\n"
+					+ "				</ResultMessage>\r\n"
+					+ "			</Shoplinker>";
+
+
+
+			//xx invoceMsg = (com.gagaframework.shoplinker.domain.invoice.ResultMessage) shoplinkerUtil.unmarshal(null, responseXmlData);
+			//xx obf = (com.gagaframework.shoplinker.domain.invoice.ObjectFactory) shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.invoice.ObjectFactory.class, responseXmlData);
+
+			//invoceMsg = (com.gagaframework.shoplinker.domain.invoice.ResultMessage) shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.invoice.ResultMessage, responseXmlData);
+
+			/*
+			com.style24.admin.support.util.ResultMessage22 re;
+
+			 JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] {com.style24.admin.support.util.ResultMessage22.class});
+			 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+			 System.out.println("####### :: "+unmarshaller.unmarshal((Reader)new StringReader(responseXmlData)));
+			 re = (ResultMessage22) unmarshaller.unmarshal((Reader)new StringReader(responseXmlData));
+System.out.println("####### : "+re.getMessage());
+System.out.println("####### : "+re.getId());
+System.out.println("####### : "+re.getResult());
+*/
+			// System.out.println(" hmj obf :: "+ obf);
+			// invoceMsg = (com.gagaframework.shoplinker.domain.invoice.ResultMessage) unmarshaller.unmarshal((Reader)new StringReader(responseXmlData));
+			// invoceMsg.getId();
+
+		    // invoceMsg =  (ResultMessage) unmarshaller.unmarshal((Reader)new StringReader(responseXmlData));
+
+			//shoplinkerResult = (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			//invoceMsg = shoplinkerResult.getResultMessage();
+			//System.out.println("HMj 2 : ");
+			//invoceMsg = responseXmlData;
+
+		//	System.out.println(" HMJ invoice2 : "+invoceMsg);
+		//	System.out.println(" HMJ invoice3 : "+invoceMsg.getResult());
+		//	System.out.println(" HMJ invoice4 : "+invoceMsg.getMessage());
+		//	System.out.println(" HMJ invoice5 : "+invoceMsg.getId());
+
+			/**** 송장전송테스트 끝 ************/
+
+
+			//1 상품등록 테스트
+			String testXmlUrl;
+
+	for( i=1; i< 1; i++) {
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/option_1.xml";
+			responseXmlData =    shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/attribute_insert.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "" );
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 1.단품 result1 :: "+resultMsg.getResult());
+		  	System.out.println("### 1.단품 result2 :: "+resultMsg.getMessage());
+
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/option_2.xml";
+			responseXmlData =    shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/attribute_insert.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "" );
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 1.단품 result1 :: "+resultMsg.getResult());
+			System.out.println("### 1.단품 result2 :: "+resultMsg.getMessage());
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/option_3.xml";
+			responseXmlData =    shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/attribute_insert.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "" );
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 1.단품 result1 :: "+resultMsg.getResult());
+			System.out.println("### 1.단품 result2 :: "+resultMsg.getMessage());
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/option_4.xml";
+			responseXmlData =    shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/attribute_insert.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "" );
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 1.단품 result1 :: "+resultMsg.getResult());
+			System.out.println("### 1.단품 result2 :: "+resultMsg.getMessage());
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/product.xml";
+			responseXmlData =   shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/attribute_prod_insert.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "");
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n\n\n### 2.상품 result1 :: "+resultMsg.getResult());
+			System.out.println("### 2.상품 result2 :: "+resultMsg.getMessage());
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/goods.xml";
+			responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/goods_info_reg.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "");
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 3.품목(고시) result1 :: "+resultMsg.getResult());
+			System.out.println("### 3.품목(고시) result2 :: "+resultMsg.getMessage());
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/cert.xml"; //ok
+			responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/cert_info_reg.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "");
+			shoplinkerResult = (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 4.인증 result1 :: "+resultMsg.getResult());
+			System.out.println("### 4.인증 result2 :: "+resultMsg.getMessage());
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/image_MOM0HZNN04.xml";
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/image.xml";
+
+			responseXmlData =     shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/product_image_register.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "");
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 5.이미지 result1 :: "+resultMsg.getResult());
+			System.out.println("### 5.이미지 result2 :: "+resultMsg.getMessage());
+	}
+
+			//2 재고
+/*
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/goods_reg/option_stock_upd.xml";
+			responseXmlData =     shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Product/attribute_modify.php?iteminfo_url="+URLEncoder.encode(testXmlUrl), "");
+			shoplinkerResult =  (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			System.out.println("\n### 6.재고upd result1 :: "+resultMsg.getResult());
+			System.out.println("### 6.재고upd result2 :: "+resultMsg.getMessage());
+*/
+
+			//99 주문수집 목록확인
+/*
+			List<com.gagaframework.shoplinker.domain.orderlist.Order> rOrdList;
+			com.gagaframework.shoplinker.domain.orderlist.Header rHeader;
+			com.gagaframework.shoplinker.domain.orderlist.Shoplinker shoplinkerOrdResult;
+
+			testXmlUrl = "http://ts5000.ipdisk.co.kr:8999/shoplinker/order_real.xml";
+			responseXmlData =   shoplinkerUtil.callShoplinkerApiByGet(GagaShoplinkerConstants.API_DOMAIN+"/Order/orderlist.php?iteminfo_url="+testXmlUrl, "");
+			shoplinkerOrdResult = (com.gagaframework.shoplinker.domain.orderlist.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.orderlist.Shoplinker.class, responseXmlData);
+			rHeader = shoplinkerOrdResult.getHeader();
+			rOrdList = shoplinkerOrdResult.getOrder();
+
+			System.out.println(" url chk:: "+GagaShoplinkerConstants.API_DOMAIN+"/Order/orderlist.php?iteminfo_url="+ testXmlUrl);
+
+			//System.out.println("\n\n\n### 7.주문 result1 :: "+responseXmlData);
+			System.out.println("### 7.주문 result2 :: "+rHeader.toString());
+			System.out.println("### 7.주문 result22 :: "+rHeader.getTotalCount()); // 1233
+			System.out.println("### 7.주문 result23 :: "+rHeader.getTotalPage()); //3
+			System.out.println("### 7.주문 result24 :: "+rHeader.getCurrentlyPage()); //1
+			System.out.println("### 7.주문 result24 :: "+rHeader.getCurrentlyCount()); //500
+			System.out.println("### 7.주문 result order size :: "+rOrdList.size()); //500
+*/
+			//99 주문수집 목록확인 끝
+
+			cal = Calendar.getInstance();
+			datestr = sdf.format(cal.getTime());
+			System.err.println(i+"개 ### 조회종료:: "+datestr);
+
+		}catch(Exception e) {
+			cal = Calendar.getInstance();
+			datestr = sdf.format(cal.getTime());
+			System.err.println(i+"개 ### 조회종료:: "+datestr);
+			System.out.println("error :: "+e);
+		}
+		return super.ok("");
+	}
+
+
+}
+

+ 39 - 2
src/main/java/com/style24/admin/support/env/TsaConstants.java

@@ -41,7 +41,7 @@ public class TsaConstants {
 			return value;
 		}
 	}
-	
+
 	// 출고처분류
 	public enum DeliveryClassification {
 		WARE_HOUSE("G024_10"),				// 물류창고
@@ -59,7 +59,7 @@ public class TsaConstants {
 			return value;
 		}
 	}
-	
+
 	// 주문상세상태
 		public enum OrderDetailStat {
 			ORDER_RECEIPT("G013_00"),			// 주문접수
@@ -90,4 +90,41 @@ public class TsaConstants {
 				return value;
 			}
 		}
+
+	// 제휴몰벤더ID
+	public enum VendorId {
+		SHOPLINKER("G003_V001");			// 샵링커
+
+		private String value;
+
+		private VendorId(String value) {
+			this.value = value;
+		}
+
+		public String value() {
+			return value;
+		}
+	}
+
+	// 제휴몰 파일업로드 실패유형
+	public enum ExtmallUploadFailStat {
+		GOODS("G022_10"),				// 상품코드미매핑
+		SIZE("G022_20"),				// 사이즈미매핑
+		ORD_QTY("G022_30"),				// 주문수량오류
+		PRICE("G022_40"),				// 상품가격이상
+		STORE("G022_50"),				// 판매매장미등록
+		STOCK("G022_60"),				// 가용재고없음
+		ORDER("G022_70"),				// 동일주문수집
+		ETC("G022_90");					// 기타
+
+		private String value;
+
+		private ExtmallUploadFailStat(String value) {
+			this.value = value;
+		}
+
+		public String value() {
+			return value;
+		}
+	}
 }

+ 107 - 0
src/main/java/com/style24/persistence/domain/ExtmallOrder.java

@@ -0,0 +1,107 @@
+package com.style24.persistence.domain;
+
+import java.util.Collection;
+
+import com.gagaframework.shoplinker.domain.orderlist.Order;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 외부몰 Domain
+ *
+ * @author gagamel
+ * @since 2020. 11. 5
+ */
+@SuppressWarnings("serial")
+@Data
+public class ExtmallOrder extends TscBaseDomain {
+
+	private String vendorId; 			// 벤더ID(공통코드G003)
+	private String vendorNm; 			// 벤더명
+	private String extmallId; 			// 외부몰ID(외부몰). TB_EXMALL.EXTMALL_ID
+	private String extmallNm; 			// 외부몰명.SHOPLINKER_ORDER.MALL_NAME
+	private String agentOrderId; 		// 에이전트주문번호.SHOPLINKER_ORDER.SHOPLINKER_ORDER_ID
+	private String extmallOrderId; 		// 외부몰주문번호(쇼핑몰주문번호).SHOPLINKER_ORDER.MALL_ORDER_ID
+	private String extmallProdId; 		// 외부몰상품ID. SHOPLINKER_ORDER.ORDER_PRODUCT_ID
+	private String extmallProdNm; 		// 외부몰상품명. SHOPLINKER_ORDER.PRODUCT_NAME
+	private String goodsCd; 			// 상품코드(상품)
+	private String goodsNm;
+	private String sku; 				// 옵션명(필수옵션+추가옵션)
+	private Integer currPrice; 			// 현재판매가. SHOPLINKER_ORDER.SALE_PRICE
+	private Integer ordQty; 			// 주문수량. SHOPLINKER_ORDER.QUANTITY
+	private Integer ordAmt; 			// 주문금액. SHOPLINKER_ORDER.ORDER_PRICE
+	private Integer cpnDcAmt; 			// 쿠폰할인금액(오픈마켓(인터파크,지마켓,옥션,스토어팜,스마트스토어) + 고도몰 적용). SHOPLINKER_ORDER.DIS_PRICE_COUPON
+	private Integer pntDcAmt; 			// 포인트할인금액(오픈마켓(인터파크,지마켓,옥션,스토어팜,스마트스토어) + 고도몰 적용). SHOPLINKER_ORDER.DIS_PRICE_POINT
+	private int delvFee; 				// 배송비.  SHOPLINKER_ORDER.BAESONG_BI
+	private String ordRecvDt; 			// 주문수집일.SHOPLINKER_ORDER.ORDER_REG_DATE
+	private String ordDt; 				// 주문일.SHOPLINKER_ORDER.ORDERDATE
+	private String ordNm; 				// 주문자명.SHOPLINKER_ORDER.ORDER_NAME
+	private String ordPhnno; 			// 주문자휴대전화번호.SHOPLINKER_ORDER.ORDER_CEL
+	private String ordTelno; 			// 주문자전화번호.SHOPLINKER_ORDER.ORDER_TEL
+	private String ordEmail; 			// 주문자이메일.SHOPLINKER_ORDER.ORDER_EMAIL
+	private String recipNm; 			// 수령자명.SHOPLINKER_ORDER.RECEIVE
+	private String recipPhnno; 			// 수령자휴대전화번호.SHOPLINKER_ORDER.RECEIVE_CEL
+	private String recipTelno; 			// 수령자전화번호.SHOPLINKER_ORDER.RECEIVE_TEL
+	private String recipZipcode; 		// 수령자우편번호.SHOPLINKER_ORDER.RECEIVE_ZIPCODE
+	private String recipBaseAddr;		// 수령자기본주소
+	private String recipDtlAddr;		// 수령자상세주소
+	private String delvMemo; 			// 배송메모.SHOPLINKER_ORDER.DELIVERY_MSG
+	private String uploadStat; 			// 업로드상태(공통코드G021)
+	private String uploadStatNm;
+	private String uploadFailCd; 		// 업로드실패코드(공통코드G022)
+	private String uploadFailNm;
+	private String uploadFailReason; 	// 업로드실패사유
+	private Integer ordNo; 				// 주문번호(주문)
+	private Integer delvAddrSq; 		// 배송지일련번호(배송지)
+	private String optCd;				// 옵션코드
+
+	private String stDate;
+	private String edDate;
+
+	private String supplyCompCd;		// 공급업체코드
+	private Integer totalOrdAmt;		// 총 주문금액
+
+	private String regNm;				// 자사-등록자명
+	private Integer regNo;				// 자사-등록자번호
+	private String regDt;				// 자사-등록일시
+
+
+
+	Collection<ExtmallOrder> orderDetailList;		// 주문상세목록
+	Collection<ExtmallOrder> delvFeeCdList;		// 배송정보목록
+	// ValidationCheck
+
+	public void setAllParams(ShoplinkerOrder ord) {
+
+		this.extmallId = ord.getMallId();
+		this.extmallNm = ord.getMallName();
+		this.agentOrderId = ord.getShoplinkerOrderId();
+		this.extmallOrderId = ord.getMallOrderId();
+		this.extmallProdId = ord.getOrderProductId();
+		this.extmallProdNm = ord.getProductName();
+		this.goodsCd = ord.getPartnerProductId();
+		this.sku = ord.getSku();
+		this.currPrice = Integer.parseInt(ord.getSalePrice());
+		this.ordQty = Integer.parseInt(ord.getQuantity());
+		this.ordAmt = Integer.parseInt(ord.getOrderPrice());
+		this.optCd = ord.getSkuMatchCode();
+		this.delvFee = Integer.parseInt(ord.getBaesongBi());
+		this.ordRecvDt = ord.getOrderRegDate();
+		this.ordDt = ord.getOrderdate();
+		this.ordNm = ord.getOrderName();
+		this.ordPhnno = ord.getOrderCel();
+		this.ordTelno = ord.getOrderTel();
+		this.ordEmail = ord.getOrderEmail();
+		this.recipNm = ord.getReceive();
+		this.recipPhnno = ord.getReceiveCel();
+		this.recipTelno = ord.getReceiveTel();
+		this.recipZipcode = ord.getReceiveZipcode();
+		this.delvMemo = ord.getDeliveryMsg();
+	}
+}
+
+
+
+
+

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

@@ -146,6 +146,9 @@ public class Goods extends TscBaseDomain {
 
 	private int goodsSq;
 	private String sizeGb;
+	private String colorCd;
+	private String frontGb;
+	private Integer custNo;
 
 	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 	private String[] arrGoodsCd;

+ 48 - 0
src/main/java/com/style24/persistence/domain/GoodsStock.java

@@ -0,0 +1,48 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 상품옵션
+ *
+ * @author xodud1202
+ * @since 2021.01.22
+ */
+@SuppressWarnings("serial")
+@Data
+public class GoodsStock extends TscBaseDomain {
+	// 재고 정보
+	private Integer productNo;		// ProductNo(WMS)
+	private String goodsCd;			// 상품번호
+	private String optCd;			// 옵션코드
+	private String optCd1;			// 옵션코드1(자사 : 컬러, 입점 : 옵션명1)
+	private String optCd2;			// 옵션코드1(자사 : 사이즈, 입점 : 옵션명2)
+	private String skuModelNo;		// SKUModelNo(WMS)
+	private String productCode;		// ProductCode(WMS)
+	private String soldoutYn;		// 품절여부
+	private int currStockQty;		// 가용재고
+	private int addPrice;			// 추가금액
+	private int dispOrd;			// 표시순서
+	private String colorNm;			// 컬러명
+	private String itemCd;			// 구성상품코드
+	private String goodsType;		// 상품구분
+	private String sysImgNm;		// 상품이미지 명
+	private int goodsQty;			// 안전재고
+	private int stockQty;			// 상품 재고
+	private String selfGoodsYn;		// 자사상품구분
+	private String optNm;			// 옵션명
+	private String goodsStat;		// 상품상태
+	private int minOrdQty;
+	private int maxOrdQty;
+	private int currPrice;
+	private String optCd1Nm;		// 옵션1칼라명(입점은 옵션명)
+	private String dispYn;			// 노출 여부
+	private int qty;				// 구성상품의 기본 수량
+	
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] arrGoodsOption;				
+	
+}

+ 137 - 0
src/main/java/com/style24/persistence/domain/ShoplinkerGoods.java

@@ -0,0 +1,137 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 샵링커 상품정보 Domain
+ *
+ * @author jmh
+ * @since 2021. 05. 11
+ */
+@SuppressWarnings("serial")
+@Data
+public class ShoplinkerGoods extends TscBaseDomain {
+
+	// 공통
+	private String customerId; 					// 고객사 코드(샵링커 가입코드)
+	private String partnerProductId;			// 자사 상품코드 (상품관리코드)
+	private String attributeTitleCode;			// 그룹 속성 코드
+	private String attributePartnerProductId;	// 자사 단품코드 (복수시 콤마로 구분)
+	private String productName;					// 상품명  (단품인경우 "옵션1_옵션2" 값임)
+
+	private String domainUrl;					// 이미지 domain url
+	private String excelFileNm;					//엑셀업로드 파일명
+	private String profiles;
+
+	private String xmlPath;
+	private String apiType;						// API구분(10:상품등록API, 11:상품수정API, 12:옵션재고수정API)
+	//private String vendorId;					// 벤더ID
+	private int idx;
+	private String xmlTxt;						// xml내용
+	private String apiSubUrl;					// api url 하위 경로
+
+
+	// 1. 단품(옵션)
+	private String attributeCode;				// (안씀) 단품 속성 코드
+	private int quantity;						// 공급가능수량
+	private String optCd; 						// 옵션1
+	private String optCd1; 						// 옵션1
+	private String optCd2;						// 옵션2
+
+	// 2. 상품
+	private String detailDesc;					// 상세설명
+	private String detailDescNew10;				// 신규상세설명
+	private String detailDescNew20;				// 신규상세설명
+	private String detailDescNew30;				// 신규상세설명
+	private String modelInfo;					// 모델정보
+
+	private String marketPrice;					// (안씀) 쇼핑몰시중가(도서정가)
+	private String salePrice;					// 쇼핑몰판매가
+	private String supplyPrice;					// 쇼핑몰공급가
+	private String marketPriceP;				// (안씀) 매입처 시중가(도서정가)
+	private String salePriceP;					// (안씀) 매입처 판매가
+	private String supplyPriceP;				// (안씀) 매입처 공급가
+	private String saleStatus;					// 상품판매상태
+	private String makerDt;						// 발행일(제조일)
+	private String taxYn;						// 과세
+	private String newDescTop;					// (안씀) 신상세설명
+	private String salearea;					// 판매지역
+	private String sex;							// 남여상품
+	private String model;						// 모델명
+	private String modelNo;						// 모델 NO
+	private String brand;						// 브랜드명
+	private String authNo;						// 인증번호
+	private String expirydate;					// 유효일
+	private String maker;						// 제조업체
+	private String origin;						// 원산지명/코드
+	private String adultInfo;					// 성인상품
+	private String ccategoryL;					// 고객사 카테고리 대분류코드
+	private String ccategoryM;					// 고객사 카테고리 중분류코드
+	private String ccategoryS;					// 고객사 카테고리 소분류코드
+	private String ccategoryD;					// 고객사 카테고리 세분류코드
+	private String selfGoodsYn;					// 자사-자사상품여부
+	private String tobeFormYn;					// 자사-상세폼신규사용여부
+	private String regNm;						// 자사-등록자명
+	private Integer regNo;						// 자사-등록자번호
+	private String regDt;						// 자사-등록일시
+	private String goodsCd;						// 자사-상품코드
+	private String goodsNm;						// 자사-상품명
+	private String brandCd;						// 자사-브랜드코드
+	private String itemkindCd;					// 자사-품목코드
+	private String mainColorCd;					// 자사-대표색상코드
+	private String mainColorEnm;				// 자사-대표색상코드 영문명
+	private String colorKnm;					// 자사-컬러 한글명
+	private String goodsStat;					// 자사-상품상태(공통코드G008)
+	private String allOptCd1;					// 자사-옵션1정보 여러개
+	private String shoplinkerItemkindNm;		// 샵링커 품목매핑명
+	private String syncYn;						// 가격연계여부
+	private String colorListYn;
+	private String kidsYn;						// 아동유무
+	private String brandEnm; 					// 브랜드 영문명
+	private String sizeTypecd;					// 사이즈타입
+	private String sizeValue1;					// 사이즈 값1
+	private String sizeValue2;					// 사이즈 값2
+	private String sizeValue3;					// 사이즈 값3
+	private String sizeValue4;					// 사이즈 값4
+	private String sizeValue5;					// 사이즈 값5
+
+
+
+	// 3. 자사몰 - 품목정보
+	private String lclassId;					// 샵링커 품목 대분류 코드
+	private String itemSeq;						// 항목 상세코드
+	private String itemInfo;					// 항목 상세설명
+
+	// 4. 자사몰 - 인증정보
+	private String certItem;					// 인증 코드
+	private String certOrgan;					// 인증기관명
+	private String certNo;						// 인증 번호
+	private String certTargetGb;				// 인증대상구분
+	private String CertTargetNm;				// 인증대상구분명
+	private String CertFormGb;					// 인증형태구분
+	private String CertFormNm;					// 인증형태구분명
+	private String CertType;					// 인증타입
+	private String CertTypeNm;					// 인증타입명
+	private String CertNum;						// 안전인증번호
+	private String CertState;					// 인증상태(적합,반납,청문실시,기간만료,안저인증취소 등)
+	private String CertDiv;						// 인증구분
+	private String CertOrganName;				// 인증기관
+	private String CertDt;						// 안전인증일
+
+	// 5. 자사몰 - 이미지
+	private String sysImgNm;
+	private String colorCd;
+	private String defaultImgYn;
+	private String extmallImgYn;				// 외부몰이미지 여부
+
+	// 결과
+	private String apiProductId;				// 샵링커 상품코드
+	private String apiResult;					// 결과플래그 (true or false)
+	private String apiMessage;					// 결과
+
+	private Integer ordDtlNo;					// 주문상세번호
+
+}
+

+ 67 - 0
src/main/java/com/style24/persistence/domain/ShoplinkerInvoice.java

@@ -0,0 +1,67 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+import com.style24.persistence.TscPageRequest;
+
+import lombok.Data;
+
+/**
+ * 샵링커 상품정보 Domain
+ *
+ * @author jmh
+ * @since 2021. 05. 11
+ */
+@SuppressWarnings("serial")
+@Data
+public class ShoplinkerInvoice extends TscBaseDomain {
+
+	// 공통
+	private String customerId; 					// 고객사 코드(샵링커 가입코드)
+	private String productName;					// 상품명  (단품인경우 "옵션1_옵션2" 값임)
+
+	private String domainUrl;					// 이미지 domain url
+	private String excelFileNm;					//엑셀업로드 파일명
+	private String profiles;
+
+	private String xmlPath;
+	private String apiType;						// API구분(10:상품등록API, 11:상품수정API, 12:옵션재고수정API)
+	//private String vendorId;					// 벤더ID
+	private int idx;
+	private String xmlTxt;						// xml내용
+	private String apiSubUrl;					// api url 하위 경로
+
+	private Integer ordNo;						// 주문번호(주문)
+	private Integer ordDtlNo;					// 주문번호(주문)
+	private String deliveryName;				// 택배사명
+	private String deliveryCode;				// 배송업체(택배사코드)
+	private String deliveryInvoice;				// 송장번호
+	private String vendorId;					// 외부몰벤더ID
+	private String extmallId;					// 외부몰ID(외부몰)
+	private String extmallNm;					// 외부몰 명
+	private String agentOrderId;				// 에이전트주문번호
+	private String extmallOrderId;				// 외부몰주문번호
+	private String delvAssignStat;				// 출고지정상태(P:대기,Y:수락,N:거부)
+	private String ordExchGb;					// 주문교환구분
+	private String ordDtlStat;					// 주문상세상태
+	private String ordDtlStatNm;				// 주문상세상태명
+
+	private String stDate;
+	private String edDate;
+	private String uploadFailCd;
+	private String regNm;
+	private String shipCompNm;	// 배송업체
+
+	// Pagination
+	private TscPageRequest pageable;
+	private int pageNo = 1;
+	private int pageSize = 50;
+	private int pageUnit = 10;
+
+	// 결과
+	private String apiProductId;				// 주문상세번호
+	private String apiResult;					// 결과플래그 (true or false)
+	private String apiMessage;					// 결과
+
+
+}
+

+ 192 - 0
src/main/java/com/style24/persistence/domain/ShoplinkerOrder.java

@@ -0,0 +1,192 @@
+package com.style24.persistence.domain;
+
+import com.gagaframework.shoplinker.domain.orderlist.Order;
+import com.style24.persistence.TscBaseDomain;
+import com.style24.persistence.TscPageRequest;
+
+import lombok.Data;
+
+/**
+ * 샵링커 상품정보 Domain
+ *
+ * @author jmh
+ * @since 2021. 05. 11
+ */
+@SuppressWarnings("serial")
+@Data
+public class ShoplinkerOrder extends TscBaseDomain {
+
+	// Request
+	private String customerId; 					// 고객사 코드(샵링커 가입코드)
+	private String shoplinkerId;
+	private String orderFlag;  //※ 테스트시에는 발주확인주문(007로 하고, 실제 적용시에는 000으로 교체)
+	private String stDate;
+	private String edDate;
+	private Integer orderPageNo;
+	private String apiStDate;
+
+	// Response
+	private Integer orderIfIdx; 				// 주문수집차수
+	private String shoplinkerOrderId; 			// 샵링커 주문번호
+	private String mallOrderId; 				// 쇼핑몰 주문번호
+	private String mallName; 					// 쇼핑몰 명
+	private String baesongStatus; 				// 배송상태[발주확인]
+	private String orderName; 					// 주문자명
+	private String orderTel; 					// 주문자 전화번호
+	private String orderCel; 					// 주문자 핸드폰번호
+	private String orderEmail; 					// 주문자 이메일주소
+	private String receive; 					// 수취인명
+	private String receiveTel; 					// 수취인 전화번호
+	private String receiveCel; 					// 수취인 핸드폰번호
+	private String receiveZipcode; 				// 수취인 우편번호
+	private String receiveAddr; 				// 수취인 주소
+	private String baesongType; 				// 배송비결제방식[무료,착불,착불 선결제]
+	private String baesongBi; 					// 배송비
+	private String deliveryMsg; 				// 배송메세지
+	private String orderProductId; 				// 주문 상품번호
+	private String shoplinkerProductId; 		// 샵링커 상품번호
+	private String partnerProductId; 			// 자사 상품코드
+	private String productName; 				// 상품명
+	private String quantity; 					// 주문수량
+	private String orderPrice; 					// 주문금액
+	private String salePrice; 					// 판매단가
+	private String supplyPrice; 				// 공급가
+	private String sku; 						// 옵션명
+	private String orderdate; 					// 주문일자
+	private String orderRegDate; 				// 주문수집일자
+	private String deliveryInvoice; 			// 송장번호
+	private String orderSeq; 					// 묶음주문번호
+	private String totalCount; 					// 총 주문건수
+	private String totalPage; 					// 총 페이지수
+	private String totalStandardCount; 			// 페이지당 노출할 총 갯수
+	private String currentlyPage; 				// 현재 호출된 페이지번호
+	private String currentlyCount; 				// 현재 호출된 주문건수
+	private String sellerId; 					// 쇼핑몰 계정
+	private String onlySku; 					// 필수옵션
+	private String addSku; 						// 추가옵션
+	private String mallId; 						// 샵링커 쇼핑몰 코드
+	private String disPriceMall; 				// 쇼핑몰부담할인액
+	private String disPriceSeller; 				// 판매자부담할인액
+	private String disPriceCoupon; 				// 쿠폰할인액
+	private String disPricePoint; 				// 포인트할인액
+	private String distributionDelivery; 		// 물류배송여부
+	private String skuMatchCode; 				// 옵션매칭코드
+	private String skuBarcode; 					// 옵션바코드
+	private String orderCustomsNumber; 			// 개인고유통관번호
+	private String orderInputType; 				// 주문서 타입
+	private String supplyId; 					// 매입처 아이디
+	private String delivery; 					// 택배사 코드
+	private String orderUserId; 				// 구매자 계정
+	private String crspikUse; 					// 크로스픽 주문
+	private String shipNo; 						// 배송번호
+	private String dealNo; 						// 딜 번호
+	private String exchangeOrderYn; 			// 교환접수 여부
+	private String orderMainKey; 				// 추가상품(인터파크,11번가)
+	private String panType; 					// 네이버페이결제수단
+	private String channelType; 				// 채널구분
+	private String shipRsvDate; 				// 배송예정일
+
+
+	private String profiles;
+	private String xmlPath;
+	private String domainUrl;					// 이미지 domain url
+	private String apiSubUrl;					// api url 하위 경로
+
+
+	private String vendorId;
+	private String extmallId;
+	private String extmallNm;
+
+	private String dtGb;			// 일자검색타입
+	private String uploadStat; 		// 외부몰 주문등록 업로드 상태
+	private String uploadFailCd;	// 외부몰 주문등록 업로드 실패코드
+	private String uploadFailReason;	// 외부몰 주문등록 업로드 실패사유 msg
+	private Integer ordNo;				// 주문번호(주문)
+	private Integer delvAddrSq;			// 배송지일련번호(배송지)
+	private String goodsCd;
+	private String optCd;
+
+	// 검색
+	private int startRow;
+	private int endRow;
+
+	// Pagination
+	private TscPageRequest pageable;
+	private int pageNo = 1;
+	private int pageSize = 50;
+	private int pageUnit = 10;
+
+	private String sid;
+
+	public ShoplinkerOrder() {
+
+	}
+
+	public void setAllParams(Order ord) {
+		//this.orderIfIdx = ord.getOrderIfIdx();
+		this.shoplinkerOrderId = ord.getShoplinkerOrderId();
+		this.mallOrderId = ord.getMallOrderId();
+		this.mallName = ord.getMallName();
+		this.baesongStatus = ord.getBaesongStatus();
+		this.orderName = ord.getOrderName();
+		this.orderTel = ord.getOrderTel();
+		this.orderCel = ord.getOrderCel();
+		this.orderEmail = ord.getOrderEmail();
+		this.receive = ord.getReceive();
+		this.receiveTel = ord.getReceiveTel();
+		this.receiveCel = ord.getReceiveCel();
+		this.receiveZipcode = ord.getReceiveZipcode();
+		this.receiveAddr = ord.getReceiveAddr();
+		this.baesongType = ord.getBaesongType();
+		this.baesongBi = ord.getBaesongBi();
+		this.deliveryMsg = ord.getDeliveryMsg();
+		this.orderProductId = ord.getOrderProductId();
+		this.shoplinkerProductId = ord.getShoplinkerProductId();
+		this.partnerProductId = ord.getPartnerProductId();
+		this.productName = ord.getProductName();
+		this.quantity = ord.getQuantity();
+		this.orderPrice = ord.getOrderPrice();
+		this.salePrice = ord.getSalePrice();
+		this.supplyPrice = ord.getSupplyPrice();
+		this.sku = ord.getSku();
+		this.orderdate = ord.getOrderdate();
+		this.orderRegDate = ord.getOrderRegDate();
+		this.deliveryInvoice = ord.getDeliveryInvoice();
+		this.orderSeq = ord.getOrderSeq();
+		this.totalCount = ord.getTotalCount();
+		this.totalPage = ord.getTotalPage();
+		this.totalStandardCount = ord.getTotalStandardCount();
+		this.currentlyPage = ord.getCurrentlyPage();
+		this.currentlyCount = ord.getCurrentlyCount();
+		this.sellerId = ord.getSellerId();
+		this.onlySku = ord.getOnlySku();
+		this.addSku = ord.getAddSku();
+		this.mallId = ord.getMallId();
+		this.disPriceMall = ord.getDisPriceMall();
+		this.disPriceSeller = ord.getDisPriceSeller();
+		this.disPriceCoupon = ord.getDisPriceCoupon();
+		this.disPricePoint = ord.getDisPricePoint();
+		this.distributionDelivery = ord.getDistributionDelivery();
+		this.skuMatchCode = ord.getSkuMatchCode();
+		this.skuBarcode = ord.getSkuBarcode();
+		this.orderCustomsNumber = ord.getOrderCustomsNumber();
+		this.orderInputType = ord.getOrderInputType();
+		this.supplyId = ord.getSupplyId();
+		this.delivery = ord.getDelivery();
+		this.orderUserId = ord.getOrderUserId();
+		this.crspikUse = ord.getCrspikUse();
+		this.shipNo = ord.getShipNo();
+		this.dealNo = ord.getDealNo();
+		this.exchangeOrderYn = ord.getExchangeOrderYn();
+		this.orderMainKey = ord.getOrderMainKey();
+		this.panType = ord.getPanType();
+		this.channelType = ord.getChannelType();
+		this.shipRsvDate = ord.getShipRsvDate();
+	}
+
+
+	/*
+	 * @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY) private
+	 * String[] conditionList;
+	 */
+}

+ 101 - 0
src/main/java/com/style24/persistence/domain/ShoplinkerSearch.java

@@ -0,0 +1,101 @@
+package com.style24.persistence.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.style24.persistence.TscBaseDomain;
+import com.style24.persistence.TscPageRequest;
+
+import lombok.Data;
+
+/**
+ * 상품 검색 Domain
+ *
+ * @author eskim
+ * @since 2019. 12. 10
+ */
+@SuppressWarnings("serial")
+@Data
+public class ShoplinkerSearch extends TscBaseDomain {
+
+	private int startRow;
+	private int endRow;
+	private String search; // 키워드 종류
+	private String condition; // 키워드 종류별 값
+	private String supplyCompCd;
+	private String brandGrpNm;
+	private String brandCd;
+
+	private String stDate;
+	private String edDate;
+
+	private String regSuccYn;
+	private String searchGb;
+	private String callBackFun;
+	private String applyStdt;
+	private String applyEddt;
+	private String goodsCd;
+	private String goodsNum;
+	private String goodsNm;
+	private String inoutGb;
+	private String applyFlag;
+	private String barcode;
+	private String dateGbn;
+	private String goodsTnmRes;
+	private String searchBrandCd;
+	private String brandList;
+	private String supplyCompList;
+	private String searchTxt;
+
+	private String regNm;
+	private String apiType;
+	private String apiResult;
+	private String apiStDate;
+
+
+	//@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	//private String[] siteCd;
+
+	/* 상품목록 Multi CheckBox 항목*/
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] multiBrand;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] multiItemkindCd;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] multiGoodsStat;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] multiStyleYear;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] multiSeasonCd;
+	/* 상품목록 Multi CheckBox 항목*/
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] conditionList;
+
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] arrGoodsCd;
+
+	/* 다다익선 Multi 추가 */
+	@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+	private String[] multiSupplyCompCd;
+
+	private String pageingYn;
+
+	/* 다다익선 Multi 추가 */
+
+	// Pagination
+	private TscPageRequest pageable;
+	private int pageNo = 1;
+	private int pageSize = 50;
+	private int pageUnit = 10;
+
+	// api 호출 가능여부 확인
+	private String sid;
+	private String runStdt;
+	private String runEddt;
+	private String runStat;
+	private Integer runCnt;	// 현재 실행중인건수
+	private String txt;
+}

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

@@ -26,7 +26,7 @@
 		</if>
 		ORDER  BY VENDOR_ID, EXTMALL_ID, EXTMALL_USER_ID
 	</select>
-	
+
 	<!-- 외부몰 등록/수정 -->
 	<insert id="saveExtmall" parameterType="Extmall">
 		/* TsaOcm.saveExtmall */
@@ -77,7 +77,7 @@
 		     , UPD_NO = #{updNo}
 		     , UPD_DT = NOW()
 	</insert>
-	
+
 	<!-- 외부몰고시정보 목록 -->
 	<select id="getExtmallNotiinfoList" parameterType="ExtmallNoti" resultType="ExtmallNoti">
 		/* TsaOcm.getExtmallNotiinfoList */
@@ -104,7 +104,7 @@
 		WHERE  A.VENDOR_ID = #{vendorId}
 		ORDER  BY A.EXTMALL_NI_CLSF_CD, A.EXTMALL_NI_ITEM_CD
 	</select>
-	
+
 	<!-- 외부몰원산지 목록 -->
 	<select id="getExtmallOriginList" parameterType="ExtmallOrigin" resultType="ExtmallOrigin">
 		/* TsaOcm.getExtmallOriginList */
@@ -122,7 +122,7 @@
 		WHERE  A.VENDOR_ID = #{vendorId}
 		ORDER  BY A.EXTMALL_ORIGIN_NM
 	</select>
-	
+
 	<!-- 외부몰가격연계 목록 -->
 	<select id="getExtmallPriceSyncList" parameterType="ExtmallPriceSync" resultType="ExtmallPriceSync">
 		/* TsaOcm.getExtmallPriceSyncList */
@@ -137,7 +137,7 @@
 		WHERE  A.SELF_YN = 'Y' /*자사브랜드만*/
 		ORDER  BY 1, 2
 	</select>
-	
+
 	<!-- 외부몰가격연계 등록/수정 -->
 	<insert id="saveExtmallPriceSync" parameterType="ExtmallPriceSync">
 		/* TsaOcm.saveExtmallPriceSync */
@@ -164,5 +164,1241 @@
 		     , UPD_NO = #{updNo}
 		     , UPD_DT = NOW()
 	</insert>
-	
+
+
+
+
+
+
+
+
+
+	<!-- 제휴몰주문등록 - 주문업로드 그룹별 목록 -->
+	<select id="getExtmallMasterOrderList" parameterType="ExtmallOrder" resultType="ExtmallOrder">
+	/* TsaOcm.getExtmallMasterOrderList */
+		SELECT
+			A.VENDOR_ID, A.EXTMALL_ID, A.EXTMALL_ORDER_ID, A.ORD_NM, A.ORD_PHNNO, A.RECIP_NM, A.RECIP_PHNNO, A.RECIP_BASE_ADDR, A.RECIP_DTL_ADDR
+			, SUM(A.DELV_FEE) AS DELV_FEE
+			, SUM(A.ORD_AMT) AS TOTAL_ORD_AMT
+		FROM TB_EXTMALL_ORDER_UPLOAD A
+		WHERE A.UPLOAD_STAT = 'G021_00'
+		GROUP BY A.VENDOR_ID, A.EXTMALL_ID, A.EXTMALL_ORDER_ID, A.ORD_NM, A.ORD_PHNNO, A.RECIP_NM, A.RECIP_PHNNO, A.RECIP_BASE_ADDR, A.RECIP_DTL_ADDR
+		ORDER BY A.VENDOR_ID, A.EXTMALL_ID, A.EXTMALL_ORDER_ID
+	</select>
+
+	<!-- 제휴몰주문등록 - 주문업로드 전체 목록 -->
+	<select id="getExtmallOrderList" parameterType="ExtmallOrder" resultType="ExtmallOrder">
+	/* TsaOcm.getExtmallOrderList */
+		SELECT
+			 B.GOODS_NM
+			, B.SUPPLY_COMP_CD -- 공급업체코드
+			, B.DELV_FEE_CD -- 배송비정책코드
+			, A.*
+		FROM TB_EXTMALL_ORDER_UPLOAD A
+			LEFT OUTER JOIN TB_GOODS B ON A.GOODS_CD = B.GOODS_CD
+		WHERE 1=1
+		<if test="uploadStat != null and uploadStat != ''">
+	      AND A.UPLOAD_STAT = #{uploadStat}
+	    </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>
+		order by A.VENDOR_ID, A.EXTMALL_ID, A.EXTMALL_ORDER_ID, A.AGENT_ORDER_ID
+	</select>
+
+	<!-- 제휴몰주문등록 - 주문등록  -->
+	<insert id="insertExtmallOrder" parameterType="ExtmallOrder">
+	/* TsaOcm.insertExtmallOrder */
+		INSERT INTO TB_EXTMALL_ORDER_UPLOAD
+		(
+			VENDOR_ID
+			, EXTMALL_ID
+			, EXTMALL_NM
+			, AGENT_ORDER_ID
+			, EXTMALL_ORDER_ID
+			, EXTMALL_PROD_ID
+			, EXTMALL_PROD_NM
+			, GOODS_CD
+			, SKU
+			, CURR_PRICE
+			, ORD_QTY
+			, ORD_AMT
+			, CPN_DC_AMT
+			, PNT_DC_AMT
+			, DELV_FEE
+			, ORD_RECV_DT
+			, ORD_DT
+			, ORD_NM
+			, ORD_PHNNO
+			, ORD_TELNO
+			, ORD_EMAIL
+			, RECIP_NM
+			, RECIP_PHNNO
+			, RECIP_TELNO
+			, RECIP_ZIPCODE
+			, RECIP_BASE_ADDR
+			, RECIP_DTL_ADDR
+			, DELV_MEMO
+			, UPLOAD_STAT
+			, UPLOAD_FAIL_CD
+			, UPLOAD_FAIL_REASON
+			, ORD_NO
+			, DELV_ADDR_SQ
+			, REG_NO
+			, REG_DT
+			, OPT_CD
+		)
+		SELECT
+			#{vendorId}
+			, #{extmallId}
+			, #{extmallNm}
+			, #{agentOrderId}
+			, #{extmallOrderId}
+			, #{extmallProdId}
+			, #{extmallProdNm}
+			, #{goodsCd}
+			, #{sku}
+			, IFNULL(#{currPrice}, 0)
+			, IFNULL(#{ordQty}, 0)
+			, IFNULL(#{ordAmt}, 0)
+			, IFNULL(#{cpnDcAmt}, 0)
+			, IFNULL(#{pntDcAmt}, 0)
+			, IFNULL(#{delvFee}, 0)
+			, STR_TO_DATE(#{ordRecvDt}, '%Y%m%d%H%i%s')
+			, STR_TO_DATE(#{ordDt}, '%Y%m%d%H%i%s')
+			, IFNULL(#{ordNm}, #{recipNm})
+			, IFNULL(#{ordPhnno}, #{recipPhnno})
+			, IFNULL(#{ordTelno}, #{recipTelno})
+			, #{ordEmail}
+			, #{recipNm}
+			, #{recipPhnno}
+			, #{recipTelno}
+			, replace(#{recipZipcode}, '-', '')
+			, #{recipBaseAddr}
+			, #{recipDtlAddr}
+			, #{delvMemo}
+			, #{uploadStat}
+			, #{uploadFailCd}
+			, #{uploadFailReason}
+			, #{ordNo}
+			, #{delvAddrSq}
+			, #{regNo}
+			, now()
+			, #{optCd}
+		FROM DUAL
+		WHERE NOT EXISTS(
+				SELECT 1 FROM TB_EXTMALL_ORDER_UPLOAD
+				WHERE VENDOR_ID = #{vendorId}
+				AND EXTMALL_ID = #{extmallId}
+				AND AGENT_ORDER_ID = #{agentOrderId}
+				AND EXTMALL_ORDER_ID = #{extmallOrderId}
+			  )
+	</insert>
+
+	<!-- 제휴몰주문등록 - 주문등록 상태값 업데이트 -->
+	<update id="updateExtmallOrder" parameterType="ExtmallOrder">
+	/* TsaOcm.updateExtmallOrder */
+		UPDATE TB_EXTMALL_ORDER_UPLOAD
+		SET
+			ORD_NO = #{ordNo}
+			, DELV_ADDR_SQ = #{delvAddrSq}
+			, UPLOAD_STAT = #{uploadStat}
+			, UPLOAD_FAIL_CD = #{uploadFailCd}
+			, UPLOAD_FAIL_REASON = #{uploadFailReason}
+
+		WHERE VENDOR_ID = #{vendorId}
+		AND EXTMALL_ID = #{extmallId}
+		AND AGENT_ORDER_ID = #{agentOrderId}
+		AND EXTMALL_ORDER_ID = #{extmallOrderId}
+
+	</update>
+
+	<!-- 제휴몰주문등록 - 주문등록 cnt -->
+	<select id="getExtmallOrderCnt" parameterType="Order" resultType="int">
+	/* TsaOcm.getExtmallOrderCnt */
+		SELECT
+			COUNT(1)
+		FROM TB_ORDER_DETAIL A
+				LEFT OUTER JOIN TB_EXTMALL_ORDER_UPLOAD B
+					ON A.VENDOR_ID = B.VENDOR_ID
+					AND A.EXTMALL_ID = B.EXTMALL_ID
+					AND A.AGENT_ORDER_ID = B.AGENT_ORDER_ID
+					AND A.EXTMALL_ORDER_ID = B.EXTMALL_ORDER_ID
+		WHERE A.VENDOR_ID = #{vendorId}
+		AND A.EXTMALL_ID = #{extmallId}
+		AND A.AGENT_ORDER_ID = #{agentOrderId}
+		AND A.EXTMALL_ORDER_ID = #{extmallOrderId}
+	</select>
+
+
+
+<!--***** 주문정보등록 **************************************************************** -->
+<!--***** 주문정보등록 **************************************************************** -->
+	<!-- 1. 주문기본정보등록 -->
+	<insert id="createOrder" parameterType="Order" keyProperty="ordNo">
+		/* TsaOrder.createOrder : 주문기본정보등록 */
+		INSERT INTO TB_ORDER (
+		    MALL_GB
+		    , ORD_DT
+		    , PAY_DT
+		    , CUST_NO
+		    , ORD_NM
+		    , ORD_PHNNO
+		    , ORD_TELNO
+		    , ORD_EMAIL
+		    , SITE_CD
+		    , NPAY_ORD_NO
+		    , FRONT_GB
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		) VALUES (
+		     'G011_20'
+		     , NOW()
+		     , NOW()
+		     , #{custNo}
+		     , #{custNm}
+		     , #{recipPhnno}
+		     , #{recipTelno}
+		     , #{email}
+		     , 'G000_10'
+		     , #{npayOrdNo}
+		     , #{frontGb}
+		     , #{custNo}
+		     , NOW()
+		     , #{custNo}
+		     , NOW()
+		)
+	</insert>
+
+	<!-- 2. 주문배송주소정보등록-->
+	<insert id="createDeliveryAddr" parameterType="Order" keyProperty="delvAddrSq">
+		/* TsaOrder.createDeliveryAddr : 주문배송주소정보등록 */
+		INSERT INTO TB_DELIVERY_ADDR (
+		    RECIP_NM
+		    , RECIP_PHNNO
+		    , RECIP_TELNO
+		    , RECIP_ZIPCODE
+		    , RECIP_BASE_ADDR
+		    , RECIP_DTL_ADDR
+		    , DELV_MEMO
+		    , GIFT_MSG
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		) VALUES (
+		    #{recipNm}
+		    , #{recipPhnno}
+		    , #{recipTelno}
+		    , #{recipZipcode}
+		    , #{recipBaseAddr}
+		    , #{recipDtlAddr}
+		    , #{delvMemo}
+		    , #{giftMsg}
+		    , #{custNo}
+		    , NOW()
+		    , #{custNo}
+		    , NOW()
+		)
+	</insert>
+
+	<!-- 3. 주문배송비정보등록-->
+	<insert id="createDeliveryFee" parameterType="Order">
+		/* TsaOrder.createDeliveryFee : 주문배송비정보등록 */
+		INSERT INTO TB_DELIVERY_FEE (
+		    PAY_SQ
+		    , ORD_NO
+		    , DELV_FEE_GB
+		    , DELV_FEE_CD
+		    , DELV_FEE
+		    , DELV_CPN_SQ
+		    , DELV_CPN_DC_AMT
+		    , REAL_DELV_AMT
+		    , ORD_CHG_SQ
+		    , SUPPLY_COMP_CD
+		    , DELV_USAC_YN
+		    , DELV_USAC_DT
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		) VALUES (
+		    NULL
+		    , #{ordNo}
+		    , #{delvFeeGb}
+		    , #{delvFeeCd}
+		    , #{delvFee}
+		    , #{delvCpnSq}
+		    , #{delvCpnDcAmt}
+		    , #{realDelvAmt}
+		    , NULL
+		    , #{supplyCompCd}
+		    , 'N'
+		    , NULL
+		    , #{custNo}
+		    , NOW()
+		    , #{custNo}
+		    , NOW()
+		)
+	</insert>
+
+	<!-- 4. 주문상세정보등록-->
+	<insert id="createOrderDetail" parameterType="Order" keyProperty="ordDtlNo">
+		/* TsaOcm.createOrderDetail : 주문상세정보등록 */
+		INSERT INTO TB_ORDER_DETAIL (
+		    ORD_NO
+		    , ORD_EXCH_GB
+		    , ORD_DTL_STAT
+		    , ORG_ORD_DTL_NO
+		    , SUPPLY_COMP_CD
+		    , GOODS_CD
+		    , DEAL_GOODS_CD
+		    , FORMAL_GB
+		    , GOODS_TYPE
+		    , LIST_PRICE
+		    , CURR_PRICE
+		    , DC_RATE
+		    , OPT_ADD_PRICE
+		    , ORD_QTY
+		    , ORD_AMT
+		    , CNCL_RTN_QTY
+		    , CNCL_RTN_AMT
+		    , CPN1_CPN_SQ
+		    , CPN1_DC_AMT
+		    , TMTB1_SQ
+		    , TMTB1_DC_AMT
+		    , TMTB2_SQ
+		    , TMTB2_DC_AMT
+		    , GOODS_CPN_SQ
+		    , GOODS_CPN_DC_AMT
+		    , CART_CPN_SQ
+		    , CART_CPN_DC_AMT
+		    , BURDEN_RATE
+		    , PNT_DC_AMT
+		    , PRE_PNT_DC_AMT
+		    , SAVE_PNT_AMT
+		    , REAL_ORD_AMT
+		    , GFCD_USE_AMT
+		    , VENDOR_ID
+		    , EXTMALL_ID
+		    , AGENT_ORDER_ID
+		    , EXTMALL_ORDER_ID
+		    , CHANGEABLE_YN
+		    , CHANGE_FEE_FREE_YN
+		    , RETURNABLE_YN
+		    , RETURN_FEE_FREE_YN
+		    , SOLDOUT_YN
+		    , SOLDOUT_MEMO
+		    , SOLDOUT_REG_NO
+		    , SOLDOUT_REG_DT
+		    , DELV_ADDR_SQ
+		    , DELV_FEE_CD
+		    , SHOT_DELV_YN
+		    , GIFT_PACK_YN
+		    , GIFT_ADDR_INP_YN
+		    , MAKE_GOODS_YN
+		    , ENTRY_NO
+		    , DELV_LOC_CD
+		    , DELV_ASSIGN_DT
+		    , DELV_ASSIGN_STAT
+		    , DSTRBT_NOTE
+		    , DELV_STDT
+		    , DELV_EDDT
+		    , SHIP_COMP_CD
+		    , INVOICE_NO
+		    , INVOICE_SEND_YN
+		    , SELL_STORE_CD
+		    , SELL_FEE_RATE
+		    , AF_LINK_CD
+		    , ITHR_CD
+		    , CONTENTS_LOC
+		    , PLAN_DTL_SQ
+		    , SOCIAL_SQ
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		)
+		SELECT #{ordNo}                     AS ORD_NO
+		     , #{ordExchGb}                 AS ORD_EXCH_GB
+		     , #{ordDtlStat}                AS ORD_DTL_STAT
+		     , NULL                         AS ORG_ORD_DTL_NO
+		     , G.SUPPLY_COMP_CD             AS SUPPLY_COMP_CD
+		     , G.GOODS_CD                  AS GOODS_CD
+		     , null             AS DEAL_GOODS_CD
+		     , G.FORMAL_GB                  AS FORMAL_GB
+		     , G.GOODS_TYPE                 AS GOODS_TYPE
+		     , G.LIST_PRICE                 AS LIST_PRICE
+		     , #{currPrice}                AS CURR_PRICE
+		     , G.DC_RATE                    AS DC_RATE
+		     , #{optAddPrice}               AS OPT_ADD_PRICE
+		     , #{ordQty}                AS GOODS_QTY
+		     , #{ordAmt}                    AS ORD_AMT
+		     , 0                            AS CNCL_RTN_QTY
+		     , 0                            AS CNCLRTN_AMT
+		     , #{cpn1CpnSq}                 AS CPN1_CPN_SQ
+		     , #{cpn1DcAmt}                 AS CPN1_DC_AMT
+		     , #{tmtb1Sq}                   AS TMTB1_SQ
+		     , #{tmtb1DcAmt}                AS TMTB1_DC_AMT
+		     , #{tmtb2Sq}                   AS TMTB2_SQ
+		     , #{tmtb2DcAmt}                AS TMTB2_DC_AMT
+		     , #{goodsCpnSq}                AS GOODS_CPN_SQ
+		     , #{goodsCpnDcAmt}             AS GOODS_CPN_DC_AMT
+		     , #{cartCpnSq}                 AS CART_CPN_SQ
+		     , #{cartCpnDcAmt}              AS CART_CPN_DC_AMT
+		     , 0                            AS BURDEN_RATE
+		     , #{pntDcAmt}                  AS PNT_DC_AMT
+		     , #{prePntDcAmt}               AS PRE_PNT_DC_AMT
+		     , #{savePntAmt}                AS SAVE_PNT_AMT
+		     , #{realOrdAmt}                AS REAL_ORD_AMT
+		     , #{gfcdUseAmt}                AS GFCD_USE_AMT
+		     , #{vendorId}                  AS VENDOR_ID
+		     , #{extmallId}                 AS EXTMALL_ID
+		     , #{agentOrderId}              AS AGENT_ORDER_ID
+		     , #{extmallOrderId}            AS EXTMALL_ORDER_ID
+		     , G.CHANGEABLE_YN              AS CHANGEABLE_YN
+		     , G.CHANGE_FEE_FREE_YN         AS CHANGE_FEE_FREE_YN
+		     , G.RETURNABLE_YN              AS RETURNABLE_YN
+		     , G.RETURN_FEE_FREE_YN         AS RETURN_FEE_FREE_YN
+		     , 'N'                          AS SOLDOUT_YN
+		     , NULL                         AS SOLDOUT_MEMO
+		     , NULL                         AS SOLDOUT_REG_NO
+		     , NULL                         AS SOLDOUT_REG_DT
+		     , #{delvAddrSq}                AS DELV_ADDR_SQ
+		     , #{delvFeeCd}	                AS DELV_FEE_CD
+		     , #{shotDelvYn}                AS SHOT_DELV_YN
+		     , #{giftPackYn}                AS GIFT_PACK_YN
+		     , 'N'                          AS GIFT_ADDR_INP_YN
+		     , G.ORDER_MADE_YN              AS MAKE_GOODS_YN
+		     , #{entryNo}                   AS ENTRY_NO
+		     , NULL                         AS DELV_LOC_CD
+		     , NULL                         AS DELV_ASSIGN_DT
+		     , 'P'                          AS DELV_ASSIGN_STAT
+		     , NULL                         AS DSTRBT_NOTE
+		     , NULL                         AS DELV_STDT
+		     , NULL                         AS DELV_EDDT
+		     , NULL                         AS SHIP_COMP_CD
+		     , NULL                         AS INVOICE_NO
+		     , 'N'                          AS INVOICE_SEND_YN
+		     , NULL                         AS SELL_STORE_CD
+		     , G.SELL_FEE_RATE              AS SELL_FEE_RATE
+		     , null              AS AF_LINK_CD
+		     , null              AS ITHR_CD
+		     , null              AS CONTENTS_LOC
+		     , null              AS PLAN_DTL_SQ
+		     , NULL                         AS SOCIAL_SQ
+		     , #{custNo}                    AS REG_NO
+		     , NOW()                        AS REG_DT
+		     , #{custNo}                    AS UPD_NO
+		     , NOW()                        AS UPD_DT
+		FROM TB_GOODS G
+		WHERE  GOODS_CD = #{goodsCd}
+	</insert>
+
+	<!-- 4-2. 주문상세 이력 등록-->
+	<insert id="createOrderDetailHst" parameterType="Order">
+		/* TsaOcm.createOrderDetailHst */
+		INSERT INTO TB_ORDER_DETAIL_HST (
+		    ORD_DTL_NO
+		    , ORD_NO
+		    , ORD_EXCH_GB
+		    , ORD_DTL_STAT
+		    , ORG_ORD_DTL_NO
+		    , SUPPLY_COMP_CD
+		    , GOODS_CD
+		    , DEAL_GOODS_CD
+		    , FORMAL_GB
+		    , GOODS_TYPE
+		    , LIST_PRICE
+		    , CURR_PRICE
+		    , DC_RATE
+		    , OPT_ADD_PRICE
+		    , ORD_QTY
+		    , ORD_AMT
+		    , CNCL_RTN_QTY
+		    , CNCL_RTN_AMT
+		    , CPN1_CPN_SQ
+		    , CPN1_DC_AMT
+		    , TMTB1_SQ
+		    , TMTB1_DC_AMT
+		    , TMTB2_SQ
+		    , TMTB2_DC_AMT
+		    , GOODS_CPN_SQ
+		    , GOODS_CPN_DC_AMT
+		    , CART_CPN_SQ
+		    , CART_CPN_DC_AMT
+		    , BURDEN_RATE
+		    , PNT_DC_AMT
+		    , PRE_PNT_DC_AMT
+		    , SAVE_PNT_AMT
+		    , REAL_ORD_AMT
+		    , GFCD_USE_AMT
+		    , VENDOR_ID
+		    , EXTMALL_ID
+		    , AGENT_ORDER_ID
+		    , EXTMALL_ORDER_ID
+		    , CHANGEABLE_YN
+		    , CHANGE_FEE_FREE_YN
+		    , RETURNABLE_YN
+		    , RETURN_FEE_FREE_YN
+		    , SOLDOUT_YN
+		    , SOLDOUT_MEMO
+		    , SOLDOUT_REG_NO
+		    , SOLDOUT_REG_DT
+		    , DELV_ADDR_SQ
+		    , DELV_FEE_CD
+		    , SHOT_DELV_YN
+		    , GIFT_PACK_YN
+		    , GIFT_ADDR_INP_YN
+		    , MAKE_GOODS_YN
+		    , ENTRY_NO
+		    , DELV_LOC_CD
+		    , DELV_ASSIGN_DT
+		    , DELV_ASSIGN_STAT
+		    , DSTRBT_NOTE
+		    , DELV_STDT
+		    , DELV_EDDT
+		    , SHIP_COMP_CD
+		    , INVOICE_NO
+		    , INVOICE_SEND_YN
+		    , SELL_STORE_CD
+		    , SELL_FEE_RATE
+		    , AF_LINK_CD
+		    , ITHR_CD
+		    , CONTENTS_LOC
+		    , PLAN_DTL_SQ
+		    , SOCIAL_SQ
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		)
+		SELECT ORD_DTL_NO
+		     , ORD_NO
+		     , ORD_EXCH_GB
+		     , ORD_DTL_STAT
+		     , ORG_ORD_DTL_NO
+		     , SUPPLY_COMP_CD
+		     , GOODS_CD
+		     , DEAL_GOODS_CD
+		     , FORMAL_GB
+		     , GOODS_TYPE
+		     , LIST_PRICE
+		     , CURR_PRICE
+		     , DC_RATE
+		     , OPT_ADD_PRICE
+		     , ORD_QTY
+		     , ORD_AMT
+		     , CNCL_RTN_QTY
+		     , CNCL_RTN_AMT
+		     , CPN1_CPN_SQ
+		     , CPN1_DC_AMT
+		     , TMTB1_SQ
+		     , TMTB1_DC_AMT
+		     , TMTB2_SQ
+		     , TMTB2_DC_AMT
+		     , GOODS_CPN_SQ
+		     , GOODS_CPN_DC_AMT
+		     , CART_CPN_SQ
+		     , CART_CPN_DC_AMT
+		     , BURDEN_RATE
+		     , PNT_DC_AMT
+		     , PRE_PNT_DC_AMT
+		     , SAVE_PNT_AMT
+		     , REAL_ORD_AMT
+		     , GFCD_USE_AMT
+		     , VENDOR_ID
+		     , EXTMALL_ID
+		     , AGENT_ORDER_ID
+		     , EXTMALL_ORDER_ID
+		     , CHANGEABLE_YN
+		     , CHANGE_FEE_FREE_YN
+		     , RETURNABLE_YN
+		     , RETURN_FEE_FREE_YN
+		     , SOLDOUT_YN
+		     , SOLDOUT_MEMO
+		     , SOLDOUT_REG_NO
+		     , SOLDOUT_REG_DT
+		     , DELV_ADDR_SQ
+		     , DELV_FEE_CD
+		     , SHOT_DELV_YN
+		     , GIFT_PACK_YN
+		     , GIFT_ADDR_INP_YN
+		     , MAKE_GOODS_YN
+		     , ENTRY_NO
+		     , DELV_LOC_CD
+		     , DELV_ASSIGN_DT
+		     , DELV_ASSIGN_STAT
+		     , DSTRBT_NOTE
+		     , DELV_STDT
+		     , DELV_EDDT
+		     , SHIP_COMP_CD
+		     , INVOICE_NO
+		     , INVOICE_SEND_YN
+		     , SELL_STORE_CD
+		     , SELL_FEE_RATE
+		     , AF_LINK_CD
+		     , ITHR_CD
+		     , CONTENTS_LOC
+		     , PLAN_DTL_SQ
+		     , SOCIAL_SQ
+		     , #{regNo}
+		     , NOW()
+		     , #{regNo}
+		     , NOW()
+		  FROM TB_ORDER_DETAIL
+		 WHERE ORD_DTL_NO = #{ordDtlNo}
+	</insert>
+
+	<!-- 5. 주문상세단품정보등록을 위한 조회 -->
+	<select id="getOrderDetailItem" parameterType="Order" resultType="Order">
+		/* TsaOcm.getOrderDetailItem : 주문상세단품정보등록을 위한 조회 */
+		SELECT
+			#{ordDtlNo}                                  AS ORD_DTL_NO
+		     , #{ordNo}                                     AS ORD_NO
+		     , #{ordDtlStat}                                AS ORD_DTL_STAT
+			 , OP.GOODS_CD
+		     , OP.GOODS_CD as ITEM_CD
+		     , OP.OPT_CD
+		     , OP.OPT_CD1
+		     , OP.OPT_CD2
+		     , OP.SKU_MODEL_NO
+		     , OP.PRODUCT_NO
+		     , OP.PRODUCT_CODE
+		     , G.CURR_PRICE
+		     , IFNULL(GC.QTY, 1)                            AS ITEM_QTY
+		     , IFNULL(GC.COMPS_CURR_PRICE, G.CURR_PRICE)    AS ITEM_PRICE
+		     , OP.ADD_PRICE                                 AS OPT_ADD_PRICE
+		    /* , CD.DISP_ORD*/
+		     , 0                                            AS ORD_AMT
+		     , 0                                            AS CNCL_RTN_AMT
+		     , 0                                            AS CPN1_DC_AMT
+		     , 0                                            AS TMTB1_DC_AMT
+		     , 0                                            AS TMTB2_DC_AMT
+		     , 0                                            AS GOODS_CPN_DC_AMT
+		     , 0                                            AS CART_CPN_DC_AMT
+		     , 0                                            AS PNT_DC_AMT
+		     , 0                                            AS PRE_PNT_DC_AMT
+		     , 0                                            AS SAVE_PNT_AMT
+		     , 0                                            AS REAL_ORD_AMT
+		     , 0                                            AS GFCD_USE_AMT
+		FROM   TB_OPTION OP
+		INNER  JOIN TB_GOODS G
+		ON     op.GOODS_CD = G.GOODS_CD
+		LEFT   OUTER JOIN TB_GOODS_COMPOSE GC
+		ON    G.GOODS_CD = GC.GOODS_CD
+		WHERE 1=1
+		and OP.OPT_CD= #{optCd}
+
+	</select>
+
+	<!-- 6. 주문상세단품정보등록 -->
+	<insert id="createOrderDetailItem" parameterType="Order" keyProperty="ordDtlItemSq">
+		/* TsaOrder.createOrderDetailItem : 주문상세단품정보등록 */
+		INSERT INTO TB_ORDER_DETAIL_ITEM (
+		    ORD_DTL_NO
+		    , ORD_NO
+		    , ORD_DTL_STAT
+		    , ITEM_CD
+		    , OPT_CD
+		    , OPT_CD1
+		    , OPT_CD2
+		    , SKU_MODEL_NO
+		    , PRODUCT_NO
+		    , PRODUCT_CODE
+		    , ITEM_QTY
+		    , ITEM_PRICE
+		    , OPT_ADD_PRICE
+		    , DISP_ORD
+		    , ORD_AMT
+		    , CNCL_RTN_AMT
+		    , CPN1_DC_AMT
+		    , TMTB1_DC_AMT
+		    , TMTB2_DC_AMT
+		    , GOODS_CPN_DC_AMT
+		    , CART_CPN_DC_AMT
+		    , PNT_DC_AMT
+		    , PRE_PNT_DC_AMT
+		    , SAVE_PNT_AMT
+		    , REAL_ORD_AMT
+		    , GFCD_USE_AMT
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		) VALUES (
+		    #{ordDtlNo}
+		    , #{ordNo}
+		    , #{ordDtlStat}
+		    , #{itemCd}
+		    , #{optCd}
+		    , #{optCd1}
+		    , #{optCd2}
+		    , #{skuModelNo}
+		    , #{productNo}
+		    , #{productCode}
+		    , #{itemQty}
+		    , #{itemPrice}
+		    , #{optAddPrice}
+		    , #{dispOrd}
+		    , #{ordAmt}
+		    , #{cnclRtnAmt}
+		    , #{cpn1DcAmt}
+		    , #{tmtb1DcAmt}
+		    , #{tmtb2DcAmt}
+		    , #{goodsCpnDcAmt}
+		    , #{cartCpnDcAmt}
+		    , #{pntDcAmt}
+		    , #{prePntDcAmt}
+		    , #{savePntAmt}
+		    , #{realOrdAmt}
+		    , #{gfcdUseAmt}
+		    , #{custNo}
+		    , NOW()
+		    , #{custNo}
+		    , NOW()
+		)
+	</insert>
+
+	<!-- 7. 주문상세단품이력정보 등록 -->
+	<insert id="createOrderDetailItemHst" parameterType="Order">
+		/* TsaOrder.createOrderDetailItemHst */
+		INSERT INTO TB_ORDER_DETAIL_ITEM_HST (
+		    ORD_DTL_ITEM_SQ
+		    , ORD_DTL_NO
+		    , ORD_NO
+		    , ORD_DTL_STAT
+		    , ITEM_CD
+		    , OPT_CD
+		    , OPT_CD1
+		    , OPT_CD2
+		    , SKU_MODEL_NO
+		    , PRODUCT_NO
+		    , PRODUCT_CODE
+		    , ITEM_QTY
+		    , ITEM_PRICE
+		    , OPT_ADD_PRICE
+		    , DISP_ORD
+		    , ORD_AMT
+		    , CNCL_RTN_AMT
+		    , CPN1_DC_AMT
+		    , TMTB1_DC_AMT
+		    , TMTB2_DC_AMT
+		    , GOODS_CPN_DC_AMT
+		    , CART_CPN_DC_AMT
+		    , PNT_DC_AMT
+		    , PRE_PNT_DC_AMT
+		    , SAVE_PNT_AMT
+		    , REAL_ORD_AMT
+		    , GFCD_USE_AMT
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		)
+		SELECT ORD_DTL_ITEM_SQ
+		     , ORD_DTL_NO
+		     , ORD_NO
+		     , ORD_DTL_STAT
+		     , ITEM_CD
+		     , OPT_CD
+		     , OPT_CD1
+		     , OPT_CD2
+		     , SKU_MODEL_NO
+		     , PRODUCT_NO
+		     , PRODUCT_CODE
+		     , ITEM_QTY
+		     , ITEM_PRICE
+		     , OPT_ADD_PRICE
+		     , DISP_ORD
+		     , ORD_AMT
+		     , CNCL_RTN_AMT
+		     , CPN1_DC_AMT
+		     , TMTB1_DC_AMT
+		     , TMTB2_DC_AMT
+		     , GOODS_CPN_DC_AMT
+		     , CART_CPN_DC_AMT
+		     , PNT_DC_AMT
+		     , PRE_PNT_DC_AMT
+		     , SAVE_PNT_AMT
+		     , REAL_ORD_AMT
+		     , GFCD_USE_AMT
+		     , REG_NO
+		     , NOW()
+		     , UPD_NO
+		     , NOW()
+		  FROM TB_ORDER_DETAIL_ITEM
+		 WHERE 1=1
+		   AND ORD_DTL_ITEM_SQ = #{ordDtlItemSq}
+	</insert>
+
+	<!-- 8. 주문사은품 마스터 정보 등록 -->
+	<insert id="createOrdFreegift" parameterType="Order">
+		/* TsaOrder.createOrdFreegift */
+		INSERT INTO TB_ORD_FREEGIFT (
+		    ORD_NO
+		    , FREEGIFT_SQ
+		    , DEL_YN
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		)
+		SELECT #{ordNo}
+		     , FG.FREEGIFT_SQ
+		     , 'N'
+		     , #{custNo}
+		     , NOW()
+		     , #{custNo}
+		     , NOW()
+		FROM   TB_FREEGIFT_VAL FGV
+		INNER  JOIN TB_FREEGIFT FG
+		ON     FGV.FREEGIFT_SQ = FG.FREEGIFT_SQ
+		WHERE  1=1
+		AND    FREEGIFT_VAL_SQ IN
+		<foreach collection="freegiftValArr" item="item" index="index"  open="(" close=")" separator=",">
+			#{item}
+		</foreach>
+		GROUP  BY FREEGIFT_SQ
+	</insert>
+
+	<!-- 9. 주문사은품 상품 정보 등록 -->
+	<insert id="createOrdFreegiftVal" parameterType="Order">
+		/* TsaOrder.createOrdFreegiftVal */
+		INSERT INTO TB_ORD_FREEGIFT_VAL (
+		    ORD_FREEGIFT_SQ
+		    , ORD_NO
+		    , FREEGIFT_SQ
+		    , FREEGIFT_VAL_SQ
+		    , ORD_DTL_STAT
+		    , USE_POINT
+		    , ITEM_QTY
+		    , PRODUCT_NO
+		    , PRODUCT_CODE
+		    , BRAND_CD
+		    , DEL_YN
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		)
+		SELECT OFG.ORD_FREEGIFT_SQ
+		    , #{ordNo}
+		    , FGV.FREEGIFT_SQ
+		    , FGV.FREEGIFT_VAL_SQ
+		    , #{ordDtlStat}
+		    , CASE WHEN FG.ALL_YN IN ('Y')
+		           THEN 0
+		           ELSE FGV.USE_POINT
+		           END USE_POINT
+		    , FGV.ITEM_QTY
+		    , FGV.PRODUCT_NO
+		    , FRG.PRODUCT_CODE
+		    , FRG.BRAND_CD
+		    , 'N'
+		    , #{custNo}
+		    , NOW()
+		    , #{custNo}
+		    , NOW()
+		FROM   TB_FREEGIFT_VAL FGV
+		INNER  JOIN TB_FREEGIFT FG
+		ON     FGV.FREEGIFT_SQ = FG.FREEGIFT_SQ
+		INNER  JOIN TB_FREE_GOODS FRG
+		ON     FGV.PRODUCT_NO = FRG.PRODUCT_NO
+		INNER  JOIN TB_ORD_FREEGIFT OFG
+		ON     FGV.FREEGIFT_SQ = OFG.FREEGIFT_SQ
+		WHERE  1=1
+		AND    OFG.ORD_NO = #{ordNo}
+		AND    FGV.FREEGIFT_VAL_SQ IN
+		<foreach collection="freegiftValArr" item="item" index="index"  open="(" close=")" separator=",">
+			#{item}
+		</foreach>
+	</insert>
+
+	<!-- 10. 주문사은품 주문상세 정보 등록 -->
+	<insert id="createOrdFreegiftDtl" parameterType="Order">
+		/* TsaOrder.createOrdFreegiftDtl */
+		INSERT INTO TB_ORD_FREEGIFT_DTL (
+		    ORD_FREEGIFT_SQ
+		    , FREEGIFT_SQ
+		    , ORD_NO
+		    , ORD_DTL_NO
+		    , DEL_YN
+		    , REG_NO
+		    , REG_DT
+		    , UPD_NO
+		    , UPD_DT
+		)
+		SELECT OFR.ORD_FREEGIFT_SQ
+		     , OFR.FREEGIFT_SQ
+		     , OD.ORD_NO
+		     , OD.ORD_DTL_NO
+		     , 'N'
+		     , #{custNo}
+		     , NOW()
+		     , #{custNo}
+		     , NOW()
+		FROM   TB_ORDER_DETAIL OD
+		INNER  JOIN TB_ORD_FREEGIFT OFR
+		ON     OD.ORD_NO = OFR.ORD_NO
+		INNER  JOIN TB_ORD_FREEGIFT_VAL OFV
+		ON     OFR.ORD_FREEGIFT_SQ = OFV.ORD_FREEGIFT_SQ
+		WHERE  1=1
+		AND    OD.GOODS_CD = #{goodsCd}
+		AND    OFR.FREEGIFT_SQ = #{freegiftSq}
+		AND    OD.ORD_NO = #{ordNo}
+		GROUP  BY OD.ORD_DTL_NO
+		     , OFR.FREEGIFT_SQ
+		     , OFR.ORD_FREEGIFT_SQ
+	</insert>
+
+	<!-- 11. 결제 PAYMENT INSERT-->
+	<insert id="insertPayment" parameterType="Payment" keyProperty="paySq">
+		/* TsaOcm.insertPayment : PAYMENT INSERT */
+		INSERT INTO TB_PAYMENT (
+			  ORD_NO
+			, PAY_DT
+			, PAY_MEANS
+			, PAY_AMT
+			, PG_CPN_AMT
+			, NPAY_PNT_AMT
+			, PAY_GB
+			, PAY_STAT
+			, CARD_PCABLE_YN
+			, REG_NO
+			, REG_DT
+			, UPD_NO
+			, UPD_DT
+		) VALUES (
+			  #{ordNo}
+			, NOW()
+			, #{payMeans}
+			, #{payAmt}
+			, #{pgCpnAmt}
+			, #{npayPntAmt}
+			, #{payGb}
+			, #{payStat}
+			, IFNULL(#{cardPcableYn}, 'Y')
+			, #{regNo}
+			, NOW()
+			, #{updNo}
+			, NOW()
+		)
+	</insert>
+
+	<!-- 12. 재고정보등록 -->
+	<insert id="createSellQty" parameterType="Order">
+		/* TsaOcm.createSellQty */
+		INSERT INTO TB_SELL_QTY (
+		    GOODS_CD
+		    , OPT_CD
+		    , SELL_GB
+		    , ORD_DTL_NO
+		    , ORD_CHG_SQ
+		    , AGENT_ORDER_ID
+		    , EXTMALL_ORDER_ID
+		    , SELL_QTY
+		    , REG_NO
+		    , REG_DT
+		)
+		SELECT ODI.ITEM_CD
+		     , ODI.OPT_CD
+		     , #{sellGb}
+		     , ODI.ORD_DTL_NO
+		     , NULL
+		     , OD.AGENT_ORDER_ID
+		     , OD.EXTMALL_ORDER_ID
+		     , ODI.ITEM_QTY * OD.ORD_QTY
+		     , #{custNo}
+		     , NOW()
+		FROM   TB_ORDER_DETAIL_ITEM ODI
+		INNER  JOIN TB_ORDER_DETAIL OD
+		ON     ODI.ORD_DTL_NO = OD.ORD_DTL_NO
+		WHERE  1=1
+		AND    ODI.ORD_NO = #{ordNo}
+		AND    ODI.ORD_DTL_NO = #{ordDtlNo}
+	</insert>
+
+	<!-- 13. 사은품 남은수량 업데이트 -->
+	<update id="updateFreegiftValLeftQty" parameterType="Order">
+		/* TsaOrder.updateFreegiftValLeftQty */
+		UPDATE TB_FREEGIFT_VAL FV
+		INNER  JOIN TB_ORD_FREEGIFT_VAL OFV
+		ON     FV.FREEGIFT_VAL_SQ = OFV.FREEGIFT_VAL_SQ
+		SET    FV.LEFT_QTY = FV.LEFT_QTY - FV.ITEM_QTY
+		WHERE  1=1
+		AND    OFV.ORD_NO = #{ordNo}
+		AND    FV.DEL_YN = 'N'
+	</update>
+
+	<!-- 상품 정보 -->
+	<select id="getGoodsInfo" parameterType="Goods" resultType="Goods">
+		/* TsaOcm.getGoodsInfo */
+		SELECT Z.*
+		     , 100 - ROUND((CURR_PRICE / LIST_PRICE) * 100 ,0) AS DC_RATE
+		     , ((PNT_RATE * CURR_PRICE) / 100) AS PNT_AMT
+		     , FN_GET_GOODS_NM(GOODS_NM,GOODS_GB,FOREIGN_BUY_YN,PARALLEL_IMPORT_YN,ORDER_MADE_YN) AS GOODS_FULL_NM /*상품FULL명*/
+		FROM (
+		SELECT G.GOODS_CD
+		     , G.GOODS_NM
+		     , G.GOODS_TNM
+		     , G.GOODS_GB
+		     , G.FOREIGN_BUY_YN
+		     , G.PARALLEL_IMPORT_YN
+		     , G.ORDER_MADE_YN
+		     , G.BRAND_CD
+		     , (CASE WHEN D.DISP_NM_LANG = 'EN' THEN D.BRAND_GROUP_ENM ELSE D.BRAND_GROUP_KNM END) AS BRAND_GROUP_NM
+		     , D.BRAND_GROUP_NO
+		     , B.LOGO_FILE_NM
+		     , G.ITEMKIND_CD
+		     , G.FORMAL_GB
+		     , G.LIST_PRICE
+		     , FN_GET_APPLY_CPN1_PRICE(G.GOODS_CD, #{frontGb})  AS CURR_PRICE
+		     , G.SELF_GOODS_YN
+		     , G.GOODS_STAT
+		     , (CASE WHEN #{frontGb} = 'P' THEN G.PNT_PRATE ELSE G.PNT_MRATE END) AS PNT_RATE
+		     , (CASE WHEN #{frontGb} = 'P' THEN G.PRE_PPNT_USABLE_YN ELSE G.PRE_MPNT_USABLE_YN END) AS PRE_PNT_USABLE_YN
+		     , G.MIN_ORD_QTY
+		     , G.MAX_ORD_QTY
+		     , G.DAY_MAX_ORD_QTY
+		     , G.SEX_GB
+		     , FN_GET_CODE_NM('G007',G.SEX_GB) AS SEX_NM
+		     , E.DELV_FEE
+		     , E.RTN_DELV_FEE
+		     , E.MIN_ORD_AMT
+		     , E.DELV_FEE_CRITE
+		     , FN_GET_CODE_NM('G073',G.GOODS_GB) AS GOODS_GB_NM
+		     , (SELECT NI_CLSF_CD
+		        FROM TB_ITEMKIND
+		        WHERE ITEMKIND_CD = G.ITEMKIND_CD) AS NI_CLSF_CD
+		     , G.MAIN_COLOR_CD
+		     , (IFNULL(NULLIF(#{colorCd},'') , G.MAIN_COLOR_CD )) AS COLOR_CD
+		     , G.SUPPLY_COMP_CD
+		     , G.SELF_MALL_YN
+		     , G.AGE_GRP_CD
+		     , G.GIFT_PACK_YN
+		     , G.NEW_CUST_ORD_YN
+		     , G.ADULT_YN
+		     , G.GOODS_TYPE
+		     , G.CHANGEABLE_YN
+		     , G.RETURNABLE_YN
+		     , G.ORIGIN_CD
+		     , G.TOBE_FORM_YN
+		     , FN_GET_CODE_NM('G076',G.ORIGIN_CD) AS ORIGIN_NM
+		     , FN_GET_CODE_NM('G008',G.GOODS_STAT) AS GOODS_STAT_NM
+		     , DATE_FORMAT(G.REG_DT ,'%Y%m%d%H%i%S') AS REG_DT
+		     , DATE_FORMAT(G.UPD_DT ,'%Y%m%d%H%i%S') AS UPD_DT
+		     , (SELECT MAX(SYS_IMG_NM) FROM TB_GOODS_IMG WHERE GOODS_CD = G.GOODS_CD AND COLOR_CD = IFNULL(#{colorCd}, IFNULL(G.MAIN_COLOR_CD,'XX')) AND DEFAULT_IMG_YN = 'Y') AS SYS_IMG_NM
+		     , (SELECT COLOR_KNM FROM TB_COLOR C WHERE COLOR_CD = IFNULL(NULLIF(#{colorCd},'') , G.MAIN_COLOR_CD ) AND USE_YN  = 'Y') AS COLOR_NM
+		     -- , BP.CURR_PRICE AS BENEFIT_PRICE
+		     , (CASE WHEN W.GOODS_CD IS NULL THEN 'N' ELSE 'Y' END) AS WISH_YN
+		     , (CASE WHEN G.GOODS_TYPE = 'G056_N' THEN (SELECT IFNULL(MAX(CASE WHEN SOLDOUT_YN = 'Y' THEN 0
+		                                                               ELSE CURR_STOCK_QTY
+		                                                               END) ,0)
+		                                                FROM  VW_STOCK
+		                                                WHERE GOODS_CD = G.GOODS_CD
+		                                                AND OPT_CD1 =  (CASE WHEN G.SELF_GOODS_YN = 'N' THEN OPT_CD1
+		                                                                    ELSE  IFNULL(#{colorCd}, IFNULL(G.MAIN_COLOR_CD,'XX')) END)
+		                                                GROUP BY GOODS_CD )
+		            ELSE (SELECT IFNULL(MAX(CASE WHEN SOLDOUT_YN = 'Y' THEN 0
+		                                      ELSE CURR_STOCK_QTY
+		                                      END) ,0)
+		                  FROM  VW_STOCK_COMPOSE
+		                  WHERE GOODS_CD= G.GOODS_CD
+		                  GROUP BY GOODS_CD )
+		            END) AS STOCK_QTY
+		     , (CASE WHEN G.SELF_GOODS_YN ='Y' AND IFNULL(DS.GOODS_CD, 'Y') = 'Y' THEN 'Y' ELSE 'N' END ) AS QUIK_DELV_YN
+		     , GS.REVIEW_REG_CNT
+		     , GS.SCORE
+		     , GS.SCORE_SIZE1
+		     , GS.SCORE_SIZE2
+		     , GS.SCORE_SIZE3
+		     , GS.SCORE_COLOR1
+		     , GS.SCORE_COLOR2
+		     , GS.SCORE_COLOR3
+		     , GS.SCORE_FIT1
+		     , GS.SCORE_FIT2
+		     , GS.SCORE_FIT3
+		     , GS.SCORE_THICK1
+		     , GS.SCORE_THICK2
+		     , GS.SCORE_THICK3
+		     , GS.SCORE_WEIGHT1
+		     , GS.SCORE_WEIGHT2
+		     , GS.SCORE_WEIGHT3
+		     , GS.SCORE_BALL1
+		     , GS.SCORE_BALL2
+		     , GS.SCORE_BALL3
+		     , GS.GOODS_QNA_CNT
+		     , (SELECT TI.SIZE_GB FROM TB_ITEMKIND TI WHERE TI.ITEMKIND_CD = G.ITEMKIND_CD) AS SIZE_GB
+		FROM TB_GOODS G
+		INNER JOIN TB_GOODS_SUMMARY GS ON G.GOODS_CD = GS.GOODS_CD
+		INNER JOIN TB_BRAND B ON G.BRAND_CD = B.BRAND_CD
+		                      AND B.USE_YN = 'Y'
+		INNER JOIN TB_SITE_BRAND SB ON B.BRAND_CD  = SB.BRAND_CD
+		                            AND SB.USE_YN = 'Y'
+		                            AND SB.SITE_CD = #{siteCd}
+		INNER JOIN TB_BRAND_GROUP D ON B.BRAND_GROUP_NO = D.BRAND_GROUP_NO
+		                            AND D.USE_YN = 'Y'
+		INNER JOIN TB_DELV_FEE_POLICY E ON G.SUPPLY_COMP_CD = E.SUPPLY_COMP_CD
+		                                     AND G.DELV_FEE_CD =  E.DELV_FEE_CD
+		LEFT OUTER JOIN TB_WISHLIST W ON G.GOODS_CD = W.GOODS_CD
+		                              AND IFNULL(#{custNo}, 0) = W.CUST_NO
+		LEFT OUTER JOIN TB_GOODS_SHOT_DELV_SKIP DS ON G.GOODS_CD =DS.GOODS_CD
+		WHERE G.GOODS_CD = #{goodsCd}
+		AND NOW() BETWEEN SELL_STDT AND SELL_EDDT	/*판매기간 확인*/
+
+		) Z
+	</select>
+
+	<!-- 상품 재고 조회 -->
+	<select id="getGoodsStockInfo" parameterType="GoodsStock" resultType="GoodsStock">
+		/* TsaOcm.getGoodsStockInfo */
+		SELECT VS.GOODS_CD
+			 , VS.OPT_CD
+			 , VS.OPT_CD1
+			 , VS.OPT_CD2
+			 , VS.SOLDOUT_YN
+			 , VS.CURR_STOCK_QTY
+		     , VS.ADD_PRICE
+			 , O.SKU_MODEL_NO
+		  FROM VW_STOCK VS
+		 INNER JOIN TB_OPTION O
+		    ON VS.GOODS_CD = O.GOODS_CD
+		   AND VS.OPT_CD = O.OPT_CD
+		 WHERE VS.GOODS_CD = #{goodsCd}
+		   AND VS.OPT_CD = #{optCd}
+	</select>
+
+	<!-- 사은품 : 1차조건 적용된 사음품 정보, 상품 금액 조회 -->
+	<select id="getFreeGiftGoodsApplyAmt" parameterType="Order" resultType="Order">
+		/* TsaOcm.getFreeGiftGoodsApplyAmt */
+		WITH GOODS_DATA AS (
+			SELECT G.GOODS_CD
+			     , G.SUPPLY_COMP_CD
+			     , G.BRAND_CD
+			     , OD.ORD_QTY as GOODS_QTY
+			     , OD.ORD_AMT as CURR_PRICE
+			     , G.GOODS_TYPE
+			FROM   TB_GOODS G
+			INNER JOIN TB_ORDER_DETAIL OD ON OD.GOODS_CD = G.GOODS_CD
+			WHERE OD.ORD_NO = #{ordNo}
+			AND OD.ORD_DTL_NO IN
+			<foreach collection="itemCdArr" item="item" index="index"  open="(" close=")" separator=",">
+				#{item}
+			</foreach>
+
+		)
+		SELECT FGG.FREEGIFT_SQ
+		     , FGG.GOODS_CD
+		     , FGG.CURR_PRICE
+		     , FGG.GOODS_QTY
+		     , FG.FREEGIFT_STDT
+		     , FG.FREEGIFT_EDDT
+		     , FE.*
+		FROM   TB_FREEGIFT FG
+		INNER JOIN TB_FREEGIFT_EXTMALL FE ON FG.FREEGIFT_SQ = FE.FREEGIFT_SQ
+		INNER  JOIN (
+			SELECT FGG.FREEGIFT_SQ
+			    , GD.GOODS_CD
+			    , GD.CURR_PRICE
+			    , GD.GOODS_QTY
+			FROM   TB_FREEGIFT_GOODS FGG
+			INNER  JOIN GOODS_DATA GD
+			ON     FGG.TARGET_VAL = GD.GOODS_CD
+			WHERE  1=1
+			AND    FGG.GOODS_GB = 'G800_20' -- 적용상품
+			AND    FGG.TARGET_GB= 'G260_10' -- 상품
+			AND    FGG.DEL_YN = 'N'
+			UNION
+			SELECT FGG1.FREEGIFT_SQ
+			     , GD.GOODS_CD
+			     , GD.CURR_PRICE
+			     , GD.GOODS_QTY
+			FROM   GOODS_DATA GD
+			INNER  JOIN TB_FREEGIFT_GOODS_APPLY FGG1
+			ON     GD.SUPPLY_COMP_CD = FGG1.TARGET_VAL
+			AND    FGG1.TARGET_GB= 'G260_13' -- 공급처
+			INNER  JOIN TB_FREEGIFT_GOODS_APPLY FGG2
+			ON     GD.BRAND_CD = FGG2.TARGET_VAL
+			AND    FGG2.TARGET_GB= 'G260_12' -- 브랜드
+			AND    FGG1.FREEGIFT_SQ = FGG2.FREEGIFT_SQ
+		) FGG
+		ON     FG.FREEGIFT_SQ = FGG.FREEGIFT_SQ
+		LEFT   OUTER JOIN TB_FREEGIFT_GOODS NOT_APPLY_GOODS
+		ON     FGG.FREEGIFT_SQ = NOT_APPLY_GOODS.FREEGIFT_SQ
+		AND    FGG.GOODS_CD = NOT_APPLY_GOODS.TARGET_VAL
+		AND    NOT_APPLY_GOODS.TARGET_GB = 'G800_30'
+		WHERE  1=1
+		AND    NOT_APPLY_GOODS.FREEGIFT_SQ IS NULL
+		AND    FG.DEL_YN = 'N'
+		AND    FG.SELF_YN = 'N' -- 외부몰
+		AND    FG.FREEGIFT_STAT = 'G232_11' -- 진행
+		AND	   FE.EXTMALL_ID = #{extmallId}
+		AND	   FE.DEL_YN = 'N'
+		AND    FG.FREEGIFT_STDT <![CDATA[<]]> CURRENT_TIMESTAMP
+		AND    FG.FREEGIFT_EDDT > CURRENT_TIMESTAMP
+		ORDER  BY FGG.FREEGIFT_SQ
+
+	</select>
+
+	<!-- 사은품 : 2차조건 적용된 사은품상품금액 구간정보조회 -->
+	<select id="getFreeGiftGoodsApplySection" parameterType="Order" resultType="Order">
+		/* TsaOcm.getFreeGiftGoodsApplySection */
+		SELECT FGS.FREEGIFT_SECTION_SQ
+		     , FGS.FREEGIFT_SQ
+		     , FGS.SECTION_VAL
+		FROM   TB_FREEGIFT_SECTION FGS
+		WHERE  1=1
+		AND    FGS.DEL_YN = 'N'
+		AND    FGS.SECTION_GB = 'G810_11' -- 금액만 처리
+		AND    FGS.FREEGIFT_SQ IN
+		<foreach collection="freegiftSqArr" item="item" index="index"  open="(" close=")" separator=",">
+			#{item}
+		</foreach>
+		ORDER  BY FGS.FREEGIFT_SQ
+		     , FGS.SECTION_VAL
+	</select>
+
+	<!-- 사은품 : 3차조건 적용된 구간정보의 사은품정보조회 -->
+	<select id="getFreeGiftGoodsApplyVal" parameterType="Order" resultType="Order">
+		/* TsaOcm.getFreeGiftGoodsApplyVal */
+		SELECT FGV.FREEGIFT_VAL_SQ
+		     , FG.FREEGIFT_NM
+		     , FGV.FREEGIFT_SECTION_SQ
+		     , FGV.FREEGIFT_SQ
+		     , FGV.USE_POINT
+		     , FGV.ITEM_QTY
+		     , FG.ALL_YN
+		     , G.PRODUCT_NO
+		     , G.PRODUCT_CODE
+		     , G.GOODS_NM
+		     , G.SYS_IMG_NM
+		FROM   TB_FREEGIFT_VAL FGV
+		INNER  JOIN TB_FREEGIFT FG
+		ON     FGV.FREEGIFT_SQ = FG.FREEGIFT_SQ
+		INNER  JOIN TB_FREE_GOODS G
+		ON     FGV.PRODUCT_NO = G.PRODUCT_NO
+		WHERE  1=1
+		AND    FGV.DEL_YN = 'N'
+		AND    FGV.LEFT_QTY <![CDATA[>=]]> FGV.ITEM_QTY
+		AND    FGV.FREEGIFT_SECTION_SQ IN
+		<foreach collection="freegiftSectionSqArr" item="item" index="index"  open="(" close=")" separator=",">
+			#{item}
+		</foreach>
+		ORDER  BY FG.FREEGIFT_SQ
+		        , FGV.FREEGIFT_SECTION_SQ
+		        , FGV.USE_POINT
+	</select>
+<!--***** 주문정보등록 **************************************************************** -->
+<!--***** 주문정보등록 **************************************************************** -->
+
+
 </mapper>

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

@@ -0,0 +1,849 @@
+<?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">
+
+	<!-- 샵링커 전송 이력 -->
+	<insert id="insertShoplinerApiHst" parameterType="ShoplinkerGoods">
+		/* TsaShoplinkerDao.insertShoplinerApiHst */
+		INSERT INTO SHOPLINKER_SYNC_HST (
+		      LOG_SQ
+			, API_TYPE
+			, API_RESULT
+			, API_MESSAGE
+			, API_PRODUCT_ID
+			, GOODS_CD
+			, OPT_CD
+			, QTY
+			, ORD_DTL_NO
+			, XML_TXT
+			, REG_NO
+			, REG_DT
+		)
+		VALUES (
+		      null
+		    , #{apiType}
+			, #{apiResult}
+			, #{apiMessage}
+			, #{apiProductId}
+			, #{goodsCd}
+			, #{optCd}
+			, #{quantity}
+			, #{ordDtlNo}
+			, #{xmlTxt}
+			, #{regNo}
+		    , NOW()
+		)
+	</insert>
+
+	<!-- 샵링커 api 호출 가능여부   -->
+	<select id="getCallRunableInfo" parameterType="ShoplinkerSearch" resultType="ShoplinkerSearch">
+		/* TsaShoplinkerDao.getCallRunableInfo */
+		SELECT
+			RUN_STDT
+			, SID
+			, TXT
+		FROM SHOPLINKER_RUNABLE A
+		WHERE A.API_TYPE = #{apiType}
+		AND RUN_EDDT IS NULL
+		ORDER BY RUN_STDT DESC
+		limit 1
+	</select>
+
+	<!-- 샵링커 api 호출 가능여부 상태 저장  -->
+	<insert id="saveCallApiRunable" parameterType="ShoplinkerSearch">
+		/* TsaShoplinkerDao.saveCallApiRunable */
+		INSERT INTO SHOPLINKER_RUNABLE (
+		    SID
+		    , API_TYPE
+			, RUN_STDT
+			, RUN_EDDT
+			, RUN_STAT
+			, REG_NO
+			, TXT
+		)
+		VALUES (
+			#{sid}
+		    , #{apiType}
+			, NOW()
+			, null
+			, 'START'
+			, #{regNo}
+			, null
+		) ON DUPLICATE KEY UPDATE
+		  	RUN_EDDT = NOW()
+			, RUN_STAT = #{runStat}
+			, TXT = CONCAT(ifnull(TXT, ''), #{txt})
+	</insert>
+
+	<!-- 샵링커 api 호출 가능여부 상태 수정  -->
+	<update id="updateCallApiRunable" parameterType="ShoplinkerSearch">
+	/* ShoplinkerGoods.updateCallApiRunable */
+		UPDATE SHOPLINKER_RUNABLE
+		SET
+			RUN_STAT = #{runStat}
+			, TXT = CONCAT(ifnull(TXT, ''), #{txt})
+			<if test='runStat != null and runStat == "END"'>
+			, RUN_EDDT = NOW()
+			</if>
+		WHERE SID = #{sid}
+	</update>
+
+
+	<!-- 상품등록-단품 목록 조회 -->
+	<select id="getOptionList" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/* ShoplinkerGoods.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">
+		/* TsaShoplinkerDao.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 TEMP_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">
+		/* ShoplinkerGoods.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">
+		/* ShoplinkerGoods.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">
+		/* TsaShoplinkerDao.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">
+		/* TsaShoplinkerDao.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">
+		/* ShoplinkerGoods.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
+		) A
+		WHERE 1=1
+		<include refid="getListCondition_sql"/>
+	</select>
+
+	<!-- 상품등록-상품 목록 -->
+	<select id="getGoodsSendList" parameterType="ShoplinkerSearch" resultType="ShoplinkerGoods">
+		/* ShoplinkerGoods.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
+		) A
+		WHERE 1=1
+		<include refid="getListCondition_sql"/>
+
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+
+	</select>
+
+	<!-- 상품 목록 조건 정보 -->
+	<sql id="getListCondition_sql">
+
+		        <if test="goodsCd != null and goodsCd != ''">
+		        AND UPPER(A.GOODS_CD) LIKE CONCAT('%',UPPER(#{goodsCd}),'%')
+		        </if>
+		        <if test="arrGoodsCd != null and arrGoodsCd.length>0">
+		        AND UPPER(A.GOODS_CD) IN
+		            <foreach collection="arrGoodsCd" item="item" index="index"  open="(" close=")" separator=",">
+		        UPPER(#{item})
+		            </foreach>
+		        </if>
+		         <if test="goodsNm != null and goodsNm != ''">
+		        AND UPPER(A.GOODS_NM) LIKE CONCAT('%',UPPER(#{goodsNm}),'%')
+		        </if>
+		        <if test="brandCd != null and brandCd != ''">
+		        AND A.BRAND_CD = #{brandCd}
+		        </if>
+		        <if test="multiBrand != null and multiBrand != ''">
+		        AND A.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>
+
+
+	<!-- 샵링커주문수집 - 주문수집등록 -->
+	<insert id="insertShoplinkerOrder" parameterType="ShoplinkerOrder">
+		/* TsaShoplinkerDao.insertShoplinkerOrder */
+		INSERT INTO SHOPLINKER_ORDER (
+			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
+			, ORDERDATE
+			, 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
+			, EXTMALL_REG_YN
+			, REG_DT
+		)
+		SELECT
+			#{orderIfIdx}
+		    , #{shoplinkerOrderId}
+			, #{mallOrderId}
+			, #{mallName}
+			, #{baesongStatus}
+			, #{orderName}
+			, #{orderTel}
+			, #{orderCel}
+			, #{orderEmail}
+			, #{receive}
+			, #{receiveTel}
+			, #{receiveCel}
+			, #{receiveZipcode}
+			, #{receiveAddr}
+			, #{baesongType}
+			, #{baesongBi}
+			, #{deliveryMsg}
+			, #{orderProductId}
+			, #{shoplinkerProductId}
+			, #{partnerProductId}
+			, #{productName}
+			, #{quantity}
+			, #{orderPrice}
+			, #{salePrice}
+			, #{supplyPrice}
+			, #{sku}
+			, #{orderdate}
+			, #{orderRegDate}
+			, #{deliveryInvoice}
+			, #{orderSeq}
+			, #{totalCount}
+			, #{totalPage}
+			, #{totalStandardCount}
+			, #{currentlyPage}
+			, #{currentlyCount}
+			, #{sellerId}
+			, #{onlySku}
+			, #{addSku}
+			, #{mallId}
+			, #{disPriceMall}
+			, #{disPriceSeller}
+			, #{disPriceCoupon}
+			, #{disPricePoint}
+			, #{distributionDelivery}
+			, #{skuMatchCode}
+			, #{skuBarcode}
+			, #{orderCustomsNumber}
+			, #{orderInputType}
+			, #{supplyId}
+			, #{delivery}
+			, #{orderUserId}
+			, #{crspikUse}
+			, #{shipNo}
+			, #{dealNo}
+			, #{exchangeOrderYn}
+			, #{orderMainKey}
+			, #{panType}
+			, #{channelType}
+			, #{shipRsvDate}
+			, 'N'
+			, NOW()
+		FROM DUAL
+		WHERE NOT EXISTS(SELECT 1 FROM SHOPLINKER_ORDER WHERE SHOPLINKER_ORDER_ID = #{shoplinkerOrderId} )
+
+	</insert>
+
+	<!-- 샵링커주문수집-목록 건수 cnt -->
+	<select id="getShoplinkerOrderListCount" parameterType="ShoplinkerOrder" resultType="int">
+		/* ShoplinkerGoods.getShoplinkerOrderListCount */
+		select count(1) from (
+			SELECT
+				A.*
+				, B.VENDOR_ID
+				, B.EXTMALL_ID
+				, B.EXTMALL_NM
+				, B.AGENT_ORDER_ID
+				, B.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
+					AND A.MALL_ORDER_ID = B.EXTMALL_ORDER_ID
+			WHERE A.SKU_MATCH_CODE IS NOT NULL
+			AND A.SKU_MATCH_CODE != ''
+		) A
+		WHERE 1=1
+		<include refid="getSlkOrderListCondition_sql"/>
+
+	</select>
+
+	<!-- 샵링커주문수집-목록 -->
+	<select id="getShoplinkerOrderList" parameterType="ShoplinkerOrder" resultType="ShoplinkerOrder">
+		/* ShoplinkerGoods.getShoplinkerOrderList */
+		SELECT * FROM
+		(
+			SELECT
+				A.*
+				, B.VENDOR_ID
+				, B.EXTMALL_ID
+				, B.EXTMALL_NM
+				, B.AGENT_ORDER_ID
+				, B.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
+					AND A.MALL_ORDER_ID = B.EXTMALL_ORDER_ID
+			WHERE A.SKU_MATCH_CODE IS NOT NULL
+			AND A.SKU_MATCH_CODE != ''
+		) A
+		WHERE 1=1
+		<include refid="getSlkOrderListCondition_sql"/>
+
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+
+	</select>
+
+	<!-- 샵링커주문수집-상세 -->
+	<select id="getShoplinkerOrderInfo" parameterType="ShoplinkerOrder" resultType="ShoplinkerOrder">
+		/* ShoplinkerGoods.getShoplinkerOrderInfo */
+		SELECT
+			*
+		FROM SHOPLINKER_ORDER
+		WHERE SHOPLINKER_ORDER_ID = #{shoplinkerOrderId}
+	</select>
+
+	<!-- 샵링커주문수집- 제휴몰 주문업로드여부 업데이트  -->
+	<update id="updateShoplinkerOrder" parameterType="ShoplinkerOrder">
+	/* ShoplinkerGoods.updateShoplinkerOrder */
+		UPDATE SHOPLINKER_ORDER
+		SET
+			EXTMALL_REG_YN = 'Y'
+		WHERE MALL_ID = #{mallId}
+		AND MALL_ORDER_ID = #{mallOrderId}
+		AND SHOPLINKER_ORDER_ID = #{shoplinkerOrderId}
+	</update>
+
+	<!-- 샵링커주문수집 조건 정보 -->
+	<sql id="getSlkOrderListCondition_sql">
+
+			<if test="dtGb != null and dtGb == 'orderRegDate'">
+				<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>
+			<if test="dtGb != null and dtGb == 'orderdate'">
+				<if test="stDate != null and stDate != ''">
+		        AND A.ORDERDATE >= DATE_FORMAT(replace(#{stDate}, '-', ''), '%Y%m%d%H%i%S')
+	            </if>
+	            <if test="edDate != null and edDate != ''">
+	            <![CDATA[
+		        AND A.ORDERDATE < DATE_FORMAT(DATE_ADD(replace(#{edDate}, '-', ''), INTERVAL 1 DAY), '%Y%m%d%H%i%S')
+	            ]]>
+	            </if>
+			</if>
+
+			<if test="extmallId != null and extmallId != ''">
+	        AND MALL_ID = #{extmallId}
+	        </if>
+
+			<if test="uploadStat != null and uploadStat != ''">
+	        AND UPLOAD_STAT = #{uploadStat}
+	        </if>
+	        <if test="uploadFailCd != null and uploadFailCd != ''">
+	        AND UPLOAD_FAIL_CD = #{uploadFailCd}
+	        </if>
+
+	        <if test="shoplinkerOrderId != null and shoplinkerOrderId != ''">
+	        AND SHOPLINKER_ORDER_ID = #{shoplinkerOrderId}
+	        </if>
+	        <if test="mallOrderId != null and mallOrderId != ''">
+	        AND MALL_ORDER_ID = #{mallOrderId}
+	        </if>
+	        <if test="ordNo != null and ordNo != ''">
+	        AND ORDER_NO = #{ordNo}
+	        </if>
+	</sql>
+
+
+	<!-- 제휴몰 주문등록 상세 -->
+	<select id="getExtmallOrderInfo" parameterType="String" resultType="ExtmallOrder">
+		/* ShoplinkerGoods.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}
+
+	</select>
+
+	<!-- 제휴몰 주문등록 대상목록 SKU_MATCH_CODE가 없는 것은 딜상품(딜상품은 엑셀 수동등록)-->
+	<select id="getShoplinkerRegExtmallList" parameterType="ShoplinkerOrder" resultType="ShoplinkerOrder">
+		SELECT
+			  A.*
+		FROM SHOPLINKER_ORDER A
+		WHERE A.EXTMALL_REG_YN = 'N'
+		AND A.SKU_MATCH_CODE IS NOT NULL
+		AND A.SKU_MATCH_CODE != ''
+		ORDER BY A.MALL_ID, A.MALL_ORDER_ID, A.SHOPLINKER_ORDER_ID
+	</select>
+
+
+	<!-- 송장전송-전송 목록 건수 cnt -->
+	<select id="getSendInvoiceListCount" parameterType="ShoplinkerInvoice" resultType="int">
+		/* ShoplinkerGoods.getSendInvoiceListCount */
+		select count(1) from (
+			SELECT
+				B.ORD_NO
+				, B.ORD_DTL_NO
+				, (SELECT SHIP_COMP_NM FROM TB_SHIP_COMPANY S WHERE S.SHIP_COMP_CD = B.SHIP_COMP_CD ) AS SHIP_COMP_NM
+				, B.SHIP_COMP_CD AS DELIVERY_CODE-- 배송업체(택배사코드)
+				, B.INVOICE_NO AS DELIVERY_INVOICE-- 송장번호
+
+				, B.VENDOR_ID -- 외부몰벤더ID
+				, B.EXTMALL_ID -- 외부몰ID(외부몰)
+				, B.AGENT_ORDER_ID -- 에이전트주문번호
+				, B.EXTMALL_ORDER_ID -- 외부몰주문번호
+				, B.DELV_ASSIGN_STAT -- 출고지정상태(P:대기,Y:수락,N:거부)
+				, B.ORD_EXCH_GB -- 주문교환구분(O:주문,E:교환)
+				, B.ORD_DTL_STAT -- 주문상세상태(공통코드G013)
+				, FN_GET_CODE_NM('G013', B.ORD_DTL_STAT) AS ORD_DTL_STAT_NM
+
+				, A.API_RESULT
+				, A.API_MESSAGE
+				, A.XML_TXT
+				, A.REG_DT
+				, FN_GET_USER_NM(A.REG_NO) AS REG_NM
+			FROM
+				SHOPLINKER_SYNC_HST A
+				, TB_ORDER_DETAIL B
+			WHERE A.API_PRODUCT_ID = B.ORD_DTL_NO
+			AND A.API_TYPE = 'INVOICE'
+			ORDER BY B.ORD_NO, B.ORD_DTL_NO
+		) A
+		WHERE 1=1
+		<include refid="getSlkInvoiceCondition_sql"/>
+
+	</select>
+
+	<!-- 송장전송-전송 목록 -->
+	<select id="getSendInvoiceList" parameterType="ShoplinkerInvoice" resultType="ShoplinkerInvoice">
+		/* TsaShoplinkerDao.getSendInvoiceList */
+		SELECT * FROM
+		(
+			SELECT
+				B.ORD_NO
+				, B.ORD_DTL_NO
+				, (SELECT SHIP_COMP_NM FROM TB_SHIP_COMPANY S WHERE S.SHIP_COMP_CD = B.SHIP_COMP_CD ) AS SHIP_COMP_NM
+				, B.SHIP_COMP_CD AS DELIVERY_CODE-- 배송업체(택배사코드)
+				, B.INVOICE_NO AS DELIVERY_INVOICE-- 송장번호
+
+				, B.VENDOR_ID -- 외부몰벤더ID
+				, B.EXTMALL_ID -- 외부몰ID(외부몰)
+				, B.AGENT_ORDER_ID -- 에이전트주문번호
+				, B.EXTMALL_ORDER_ID -- 외부몰주문번호
+				, B.DELV_ASSIGN_STAT -- 출고지정상태(P:대기,Y:수락,N:거부)
+				, B.ORD_EXCH_GB -- 주문교환구분(O:주문,E:교환)
+				, B.ORD_DTL_STAT -- 주문상세상태(공통코드G013)
+				, FN_GET_CODE_NM('G013', B.ORD_DTL_STAT) AS ORD_DTL_STAT_NM
+
+				, A.API_RESULT
+				, A.API_MESSAGE
+				, A.XML_TXT
+				, A.REG_DT
+				, FN_GET_USER_NM(A.REG_NO) AS REG_NM
+			FROM
+				SHOPLINKER_SYNC_HST A
+				, TB_ORDER_DETAIL B
+			WHERE A.API_PRODUCT_ID = B.ORD_DTL_NO
+			AND A.API_TYPE = 'INVOICE'
+			ORDER BY B.ORD_NO, B.ORD_DTL_NO
+		) A
+		WHERE 1=1
+		<include refid="getSlkInvoiceCondition_sql"/>
+
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+	</select>
+
+	<!-- 송장전송-상세목록 -->
+	<select id="getShoplinkerInvoiceOrdDtlList" parameterType="ShoplinkerInvoice" resultType="ShoplinkerInvoice">
+		/* TsaShoplinkerDao.getShoplinkerInvoiceOrdDtlList */
+		SELECT
+			B.ORD_NO
+			, B.ORD_DTL_NO
+
+		  	, C.SHIP_COMP_NM AS DELIVERY_NAME -- 택배사명
+			, B.SHIP_COMP_CD AS DELIVERY_CODE-- 배송업체(택배사코드)
+			, B.INVOICE_NO AS DELIVERY_INVOICE-- 송장번호
+
+			, B.VENDOR_ID -- 외부몰벤더ID
+			, B.EXTMALL_ID -- 외부몰ID(외부몰)
+			, (select EXTMALL_NM from tb_extmall te where TE.USE_YN = 'N' and TE.EXTMALL_ID = B.EXTMALL_ID) as EXTMALL_NM
+			, B.AGENT_ORDER_ID -- 에이전트주문번호
+			, B.EXTMALL_ORDER_ID -- 외부몰주문번호
+			, DELV_ASSIGN_STAT -- 출고지정상태(P:대기,Y:수락,N:거부)
+			, ORD_EXCH_GB -- 주문교환구분(O:주문,E:교환)
+			, ORD_DTL_STAT -- 주문상세상태(공통코드G013)
+			, FN_GET_CODE_NM('G013', ORD_DTL_STAT) AS ORD_DTL_STAT_NM
+		from
+			TB_ORDER A
+			inner join TB_ORDER_DETAIL B on A.ORD_NO = B.ORD_NO
+		  	inner join TB_SHIP_COMPANY C on B.SHIP_COMP_CD = C.SHIP_COMP_CD
+
+		WHERE A.MALL_GB = 'G011_20'
+		and VENDOR_ID = 'G003_V001'
+	 	and B.INVOICE_NO is not null
+	 	and B.ORD_DTL_STAT = 'G013_50' -- 배송중
+		and DATE_FORMAT(B.DELV_STDT, '%Y-%m-%d' ) between DATE_FORMAT(#{stDate}, '%Y-%m-%d') and DATE_FORMAT(#{edDate}, '%Y-%m-%d')
+		and NOT EXISTS(SELECT 1 FROM SHOPLINKER_SYNC_HST s
+			where s.API_TYPE = 'INVOICE' and s.ord_dtl_no = B.ord_dtl_no
+			and api_result = 'true'
+			)
+
+		ORDER BY ORD_NO, ORD_DTL_NO
+
+	</select>
+
+	<!-- 상품 목록 조건 정보 -->
+	<sql id="getSlkInvoiceCondition_sql">
+
+			<if test="stDate != null and stDate != ''">
+	        AND REG_DT >= DATE_FORMAT(#{stDate}, '%Y-%m-%d %H:%i:%S')
+            </if>
+            <if test="edDate != null and edDate != ''">
+            <![CDATA[
+	        AND REG_DT < 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 API_RESULT = #{apiResult}
+	        </if>
+
+	        <if test="agentOrderId != null and agentOrderId != ''">
+	        AND AGENT_ORDER_ID = #{agentOrderId}
+	        </if>
+	        <if test="extmallOrderId != null and extmallOrderId != ''">
+	        AND EXTMALL_ORDER_ID = #{extmallOrderId}
+	        </if>
+	        <if test="ordNo != null and ordNo != ''">
+	        AND ORD_NO = #{ordNo}
+	        </if>
+	</sql>
+
+
+	<!-- 재고전송-목록 건수 -->
+	<select id="getStockListCount" parameterType="ShoplinkerSearch" resultType="int">
+		/* ShoplinkerGoods.getShoplinkerOrderListCount */
+		select count(1) from (
+			SELECT
+				A.GOODS_CD
+				, A.GOODS_NM
+				, A.REG_DT
+				, B.OPT_CD
+				, B.OPT_CD1
+				, B.OPT_CD2
+				, VS.CURR_STOCK_QTY AS QUANTITY
+			FROM TB_GOODS A
+				INNER JOIN TB_OPTION B ON A.GOODS_CD = B.GOODS_CD
+				INNER JOIN VW_STOCK VS ON A.GOODS_CD = VS.GOODS_CD AND B.OPT_CD = VS.OPT_CD
+			WHERE A.SELF_GOODS_YN = 'Y'
+			LIMIT 100
+		) A
+		WHERE 1=1
+		<!-- <include refid="getSlkOrderListCondition_sql"/> -->
+
+	</select>
+
+	<!-- 재고전송-목록 -->
+	<select id="getStockListList" parameterType="ShoplinkerSearch" resultType="ShoplinkerGoods">
+		/* ShoplinkerGoods.getShoplinkerOrderList */
+		SELECT * FROM
+		(
+			SELECT
+				A.GOODS_CD
+				, A.GOODS_NM
+				, A.REG_DT
+				, B.OPT_CD
+				, B.OPT_CD1
+				, B.OPT_CD2
+				, VS.CURR_STOCK_QTY AS QUANTITY
+			FROM TB_GOODS A
+				INNER JOIN TB_OPTION B ON A.GOODS_CD = B.GOODS_CD
+				INNER JOIN VW_STOCK VS ON A.GOODS_CD = VS.GOODS_CD AND B.OPT_CD = VS.OPT_CD
+			WHERE A.SELF_GOODS_YN = 'Y'
+			LIMIT 100
+		) A
+		WHERE 1=1
+		<!-- <include refid="getSlkOrderListCondition_sql"/> -->
+
+		LIMIT #{pageable.limitStartRow} ,  #{pageable.pageSize}
+	</select>
+
+</mapper>
+
+

+ 17 - 0
src/main/resources/config/application-locd.yml

@@ -100,3 +100,20 @@ naverPay:
     order.api.url: https://test-api.pay.naver.com/o/customer/api/order/v20/register
     order.pc.url: https://test-order.pay.naver.com/customer/buy/
     order.mobile.url: https://test-m.pay.naver.com/o/customer/buy/
+
+# 샵링커 API(개발계정)
+shoplinker:
+    customer_id : a0024007
+    shoplinker_id : istyle1
+    xml:
+        path: /WIDE/workspace/files/data/style24/shoplinker
+        view: //ldimage.style24.com/shoplinker
+    url:
+        option : /Product/attribute_insert.php?iteminfo_url=
+        product : /Product/attribute_prod_insert.php?iteminfo_url=
+        good_noti : /Product/goods_info_reg.php?iteminfo_url=
+        cert : /Product/cert_info_reg.php?iteminfo_url=
+        image : /Product/product_image_register.php?iteminfo_url=
+        stock : /Product/attribute_modify.php?iteminfo_url=       
+        order : /Order/orderlist.php?iteminfo_url=
+        invoice : /Order/delivery.php?iteminfo_url=

+ 17 - 0
src/main/resources/config/application-style.yml

@@ -90,3 +90,20 @@ naverPay:
     payUrl:
         web : test-pay.naver.com
         mob : test-m.pay.naver.com
+
+# 샵링커 API(개발계정)
+shoplinker:
+    customer_id : a0024007
+    shoplinker_id : istyle1
+    xml:
+        path: http://stage.istyle24.com/Partner/ShopLinker/dev
+        view: http://stage.istyle24.com/Partner/ShopLinker/dev
+    url:
+        option : /Product/attribute_insert.php?iteminfo_url=
+        product : /Product/attribute_prod_insert.php?iteminfo_url=
+        good_noti : /Product/goods_info_reg.php?iteminfo_url=
+        cert : /Product/cert_info_reg.php?iteminfo_url=
+        image : /Product/product_image_register.php?iteminfo_url=
+        stock : /Product/attribute_modify.php?iteminfo_url=       
+        order : /Order/orderlist.php?iteminfo_url=
+        invoice : /Order/delivery.php?iteminfo_url=

+ 18 - 1
src/main/resources/config/application-tsit.yml

@@ -82,4 +82,21 @@ naverPay:
     apiUrl: https://dev.apis.naver.com/
     payUrl:
         web : test-pay.naver.com
-        mob : test-m.pay.naver.com
+        mob : test-m.pay.naver.com
+
+# 샵링커 API(개발계정)
+shoplinker:
+    customer_id : a0024007
+    shoplinker_id : istyle1
+    xml:
+        path: //ts5000.ipdisk.co.kr:8999/shoplinker
+        view: //ts5000.ipdisk.co.kr:8999/shoplinker
+    url:
+        option : /Product/attribute_insert.php?iteminfo_url=
+        product : /Product/attribute_prod_insert.php?iteminfo_url=
+        good_noti : /Product/goods_info_reg.php?iteminfo_url=
+        cert : /Product/cert_info_reg.php?iteminfo_url=
+        image : /Product/product_image_register.php?iteminfo_url=
+        stock : /Product/attribute_modify.php?iteminfo_url=       
+        order : /Order/orderlist.php?iteminfo_url=
+        invoice : /Order/delivery.php?iteminfo_url=

+ 357 - 0
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerGoodsSendForm.html

@@ -0,0 +1,357 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ShoplinkerGoodsSendForm.html
+ * @desc    : 샵링커 상품전송관리 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.05.20   jmh     최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+
+		<form id="searchForm" name="searchForm" action="#" th:action="@{'/shoplinker/goods/send/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+			<!-- 검색조건 영역 -->
+			<div class="panelStyle">
+				<div class="panelTitle">
+					<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 상품코드나 등록일을 꼭 입력해 주세요.</h3>
+				</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>
+							<input type="text" class="w130" name="goodsCd" id="goodsCd" maxlength="20" />
+						</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 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>
+			<!-- 검색조건 영역 -->
+
+			<!-- 리스트 영역 -->
+			<div class="panelStyle">
+				<ul class="panelBar">
+					<li>
+						<button type="button" class="btn btn-default btn-lg" onclick="cfnDownloadSampleFile('SF003');">엑셀업로드 양식 다운로드</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: 470px" class="ag-theme-balham"></div>
+
+				<ul class="panelBar">
+					<li class="center">
+						<div class="tablePaging" id="goodsListPagination"></div>
+					</li>
+				</ul>
+			</div>
+			<!-- //리스트 영역 -->
+		</form>
+
+	</div>
+
+
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=20210114"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var apiTypeValue = {"OPTION":"단품", "PRODUCT":"상품", "NOTI":"품목(고시)", "CERT":"인증", "IMAGE":"이미지" };
+	var procGbValue = {"true":"전송완료", "false":"전송실패", "error":"오류"};
+
+	//let vendorList = gagajf.convertToArray([[${vendorList}]]);
+	//let supplyCompList = gagajf.convertToArray([[${supplyCompList}]]);
+
+	let columnDefs = [
+		{headerName: "No", width: 60, cellClass: 'text-center',
+			valueGetter: function(params) { return cfnGridNumner('searchForm',params.node.rowIndex, 'A');}
+		},
+		{headerName: "샵링커 상품코드", field: "apiProductId", width: 150, cellClass: 'text-center'},
+		{
+			headerName: "API구분", field: "apiType", width: 100, cellClass: 'text-center',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(apiTypeValue, params.value); }
+		},
+		{headerName: "IF결과", field: "apiResult", width: 100, cellClass: 'text-center',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(procGbValue, params.value); }
+		},
+		{headerName: "IF결과메세지", field: "apiMessage", width: 300, cellClass: 'text-left'},
+		{headerName: "자사 상품코드", field: "goodsCd", 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',
+			cellRenderer: function(params) {
+				/* params.value = '<a href="javascript:void(0);">보기</a>'; */
+				params.value = '<button type="button"class="btn btn-success">보기</button>';
+				return params.value;
+			}
+		},
+		{headerName: "등록자", field: "regNm", width: 100, cellClass: 'text-center'},
+		{
+			headerName: "전송일자", field: "regDt", width: 150, cellClass: 'text-center',
+			cellRenderer: function (params) { return gagaAgGrid.toDateTimeFormat(params.value); }
+		}
+	];
+
+	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+
+	//페이징
+	$('#searchForm select[name=pageSize]').on('change', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnGoodsListSearch();
+	});
+
+	// 브랜드 조회 선택시
+	$('#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() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnGoodsListSearch();
+	});
+
+	// 조회
+	var fnGoodsListSearch = function() {
+
+		if(!fnConditionCheck()) return;
+		gagaPaging.init('searchForm', fnSearchCallBack, 'goodsListPagination', $('#searchForm').find('#pageSize').val());
+		gagaPaging.load($("#searchForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#searchForm';
+		var form = document.searchForm;
+
+		if (event.keyCode === 13) return false;
+
+		var searchFlag = false;
+		var cnt = 0;
+
+		if( !gagajf.isNull($("#searchForm input[name=goodsCd]").val())
+				|| (!gagajf.isNull($("#searchForm input[name=stDate]").val()) && !gagajf.isNull($("#searchForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{
+
+			/* for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+
+				if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+
+			if(cnt > 0) searchFlag = true; */
+		}
+
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+
+		var fromDate = $('#searchForm input[name=stDate]').val();
+		var toDate = $('#searchForm input[name=edDate]').val();
+
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("등록 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+		}
+		return true;
+	}
+
+	var fnSearchCallBack = function(result){
+
+		$('#searchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#searchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.goodsList);
+		gagaPaging.createPagination(result.pageing.pageable);
+
+	}
+	/**************** 검색 // *****************************************************/
+
+
+	/**************** 엑셀업로드 ********************************************************/
+	$('#btnGoodsUpload').on('click', function() {
+		cfnExcelUploadPopup('shoplinkerUploadGoods', 'shoplinkerUploadGoods');
+	});
+
+	var shoplinkerUploadGoods = function(result){
+
+		var actionUrl = "/shoplinker/goods/send/excelupload/register";
+		let params = {};
+		params.procJob = result.procJob;
+		params.excelFileNm = result.excelFileNm;
+		$.post(actionUrl, $.param(params), null, 'json');
+	}
+	/**************** 엑셀업로드 // *****************************************************/
+
+
+	/**************** 테스트용  *******************************************************/
+    // 테스트- 실제 샵링커 호출
+	var fnTest = function(){
+		var data = {procJob : "1"
+				,excelFileNm : "2"
+				};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/shoplinker/apiTest2', jsonData, null);
+	}
+
+	// 테스트- 엑셀업로드2
+	var fnGoodsExcelDownLoad = function(flag){
+		cfnExcelUploadPopup('shoplinkerSearchGoods', 'shoplinkerSearchGoods');
+	};
+
+	var shoplinkerSearchGoods = function(result){
+
+		var data = {procJob : result.procJob
+					,excelFileNm : result.excelFileNm
+					};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/shoplinker/goods/excel/list', jsonData, null);
+	}
+	/**************** 테스트용 // *****************************************************/
+
+
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', 'X');
+		$('.btnToday').trigger('click');
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+	});
+
+/*]]>*/
+</script>
+
+</html>

+ 346 - 0
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerInvoiceSendForm.html

@@ -0,0 +1,346 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ShoplinkerInvoiceSendForm.html
+ * @desc    : 샵링커 송장전송 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.05.20   jmh     최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+
+		<form id="searchForm" name="searchForm" action="#" th:action="@{'/shoplinker/invoice/send/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+			<input type="hidden" name="apiType" value="INVOICE" />
+
+			<!-- 검색조건 영역 -->
+			<div class="panelStyle">
+				<div class="panelTitle">
+					<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 주문번호나 등록일을 꼭 입력해 주세요.</h3>
+				</div>
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col style="width:30%;"/>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col style="width:10%;"/>
+						<col style="width:20%;"/>
+						<col/>
+					</colgroup>
+
+					<tr>
+						<th>배송시작일자</th>
+						<td colspan="5" id="sellTerms"></td>
+					</tr>
+					<tr>
+						<th>벤더/제휴몰</th>
+						<td colspan="3">
+							<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 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>
+					<tr>
+						<th>샵링커주문번호</th>
+						<td>
+							<input type="text" class="w150" name="agentOrderId" maxlength="20"/>
+						</td>
+						<th>쇼핑몰주문번호</th>
+						<td>
+							<input type="text" class="w150" name="extmallOrderId" maxlength="50" onkeyup="$(this).val($(this).val().toUpperCase());"/>
+						</td>
+						<th>주문번호</th>
+						<td>
+							<input type="text" class="w150" name="ordNo" maxlength="50"/>
+						</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>
+
+			</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: 470px" class="ag-theme-balham"></div>
+
+				<ul class="panelBar">
+					<li class="center">
+						<div class="tablePaging" id="invoiceListPagination"></div>
+					</li>
+				</ul>
+			</div>
+			<!-- //리스트 영역 -->
+		</form>
+
+	</div>
+
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=20210114"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var sessRoleCd 		= [[${sessionInfo.roleCd}]];
+	var procGbValue = {"true":"전송완료", "false":"전송실패", "error":"오류"};
+
+	let vendorList = gagajf.convertToArray([[${vendorList}]]);
+	let extmallList = gagajf.convertToArray([[${extmallList}]]);
+
+	let columnDefs = [
+		{headerName: "No", width: 60, cellClass: 'text-center',
+			valueGetter: function(params) { return cfnGridNumner('searchForm',params.node.rowIndex, 'A');}
+		},
+		{headerName: "샵링커주문번호", field: "agentOrderId", width: 130, cellClass: 'text-center'},
+		{headerName: "쇼핑몰주문번호", field: "extmallOrderId", width: 130, cellClass: 'text-center'},
+		{
+			headerName		: "스타일24 주문번호"
+			, field			: 'ordNo'
+			, width			: 130
+			, cellClass		: 'text-center'
+			, sortable		: true
+			, cellRenderer	: function (params) {
+				var roleCd = [[${sessionInfo.roleCd}]];
+				if (!roleCd.startsWith("C") && "" != params.value) {
+					return "<a href=\"javascript:void(0);\" onclick=\"fnOpenOrderDetailPopup('" + params.value + "');\">" + params.value + "</a>";
+				} else {
+					return params.value;
+				}
+			}
+		},
+		{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',
+			cellRenderer: function(params) {
+				params.value = '보기';
+				return params.value;
+			}
+		},*/
+	];
+
+	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	//페이징
+	$('#searchForm select[name=pageSize]').on('change', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnGoodsListSearch();
+	});
+
+
+	/**************** 검색 ********************************************************/
+	$('#btnSearch').on('click', function() {
+		//gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions, '#searchForm');
+		$("#searchForm input[name=pageNo]").val('1');
+		fnGoodsListSearch();
+	});
+
+	// 조회
+	var fnGoodsListSearch = function() {
+
+		if(!fnConditionCheck()) return;
+		gagaPaging.init('searchForm', fnSearchCallBack, 'invoiceListPagination', $('#searchForm').find('#pageSize').val());
+		gagaPaging.load($("#searchForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#searchForm';
+		var form = document.searchForm;
+
+		if (event.keyCode === 13) return false;
+
+		var searchFlag = false;
+		var cnt = 0;
+
+		if( !gagajf.isNull($("#searchForm input[name=agentOrderId]").val())
+				|| !gagajf.isNull($("#searchForm input[name=extmallOrderId]").val())
+				|| !gagajf.isNull($("#searchForm input[name=ordNo]").val())
+				|| (!gagajf.isNull($("#searchForm input[name=stDate]").val()) && !gagajf.isNull($("#searchForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{
+
+			/* for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+
+				if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+
+			if(cnt > 0) searchFlag = true; */
+		}
+
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+
+		var fromDate = $('#searchForm input[name=stDate]').val();
+		var toDate = $('#searchForm input[name=edDate]').val();
+
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("등록 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+		}
+		return true;
+	}
+
+	var fnSearchCallBack = function(result){
+
+		$('#searchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#searchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.invoiceList);
+		gagaPaging.createPagination(result.pageing.pageable);
+
+	}
+	/**************** 검색 // *****************************************************/
+
+
+	/**************** 송장전송 ********************************************************/
+	$('#btnSendInvoice').on('click', function() {
+
+		if( gagajf.isNull($("#searchForm input[name=stDate]").val()) || gagajf.isNull($("#searchForm input[name=edDate]").val())){
+			mcxDialog.alert("배송시작일을 입력해주세요.");
+			return;
+		}
+
+		mcxDialog.confirm("배송시작일자 기준으로 송장전송이 진행됩니다. 진행하시겠습니까?", {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+
+				gagajf.ajaxFormSubmit('/shoplinker/check/api_runable', '#searchForm', function(result) {
+					if( "RUN" == result.RESULT_TYPE){
+						// 현재 진행중
+						mcxDialog.alert(result.RESULT_MSG+"<br>"+result.RESULT_TXT);
+					}else{
+
+						var actionUrl = '/shoplinker/invoice/send/register?stDate='+ $("#searchForm input[name=stDate]").val()+"&edDate="+ $("#searchForm input[name=edDate]").val();
+						$.post(actionUrl, null, null, 'json');
+
+					}
+				});
+			}
+		});
+	});
+
+
+	/**************** 엑셀업로드 방식 ********************************************************/
+	/*
+	$('#btnInvoiceUpload').on('click', function() {
+		cfnExcelUploadPopup('shoplinkerUploadInvoice', 'shoplinkerUploadInvoice');
+	});
+	var shoplinkerUploadInvoice = function(result){
+		var data = {procJob : result.procJob
+				,excelFileNm : result.excelFileNm
+				};
+		var jsonData = JSON.stringify(data);
+		gagajf.ajaxJsonSubmit('/shoplinker/invoice/send/excelupload/register', jsonData, fnGoodsUpdateCallBack);
+
+	}
+
+	var fnGoodsUpdateCallBack = function(result){
+		var str = "";
+		if( "TRUE" == result.RESULT_TYPE){
+			str = "처리되었습니다. 결과조회로 성공여부를 확인해주세요.";
+		}else{
+			str = result.RESULT_MSG;
+		}
+		mcxDialog.alert(str);
+	}*/
+	/**************** 엑셀업로드 방식 // *****************************************************/
+
+
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', 'X');
+		$('.btnToday').trigger('click');
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+	});
+
+/*]]>*/
+</script>
+
+</html>

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

@@ -0,0 +1,305 @@
+<!DOCTYPE html>
+<html lang="ko" xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ShoplinkerOrderDetailForm.html
+ * @desc    : 샵링커 주문수집, 제휴몰주문등록 상세 팝업
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.05.31   jmh       최초 작성
+ *******************************************************************************
+ -->
+<div class="modalPopup" data-width="1200" data-height="750">
+	<div class="panelStyle">
+		<div class="panelTitle">
+			<h2>샵링커 주문수집 상세 팝업</h2>
+			<button type="button" class="close" onclick="fnSlkOrderDetailClose()"><i class="fa fa-times"></i></button>
+		</div>
+
+		<div class="panelContent" style="height:90%; overflow-y:auto; padding:0px 20px !important; ">
+			<h4>샵링커 기본정보</h4>
+			<!-- TABLE -->
+			<table class="tableStyle">
+				<colgroup>
+					<col width="10%">
+					<col width="23%">
+					<col width="10%">
+					<col width="23%">
+					<col width="10%">
+					<col width="23%">
+				</colgroup>
+				<tbody>
+					<tr>
+						<th>주문수집차수</th>
+						<td class="aL padL10" th:text=" ${slkOrderInfo.orderIfIdx}"></td>
+						<th>샵링커주문번호</th>
+						<td class="aL padL10" th:text=" ${slkOrderInfo.shoplinkerOrderId}"></td>
+						<th>쇼핑몰주문번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.mallOrderId}"></td>
+					</tr>
+					<tr>
+						<th>쇼핑몰명</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.mallName}"></td>
+						<th>배송상태[발주확인]</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.baesongStatus}"></td>
+						<th>주문자명</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderName}"></td>
+					</tr>
+					<tr>
+						<th>주문자전화번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderTel}"></td>
+						<th>주문자핸드폰번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderCel}"></td>
+						<th>주문자이메일주소</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderEmail}"></td>
+					</tr>
+					<tr>
+						<th>수취인명</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.receive}"></td>
+						<th>수취인전화번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.receiveTel}"></td>
+						<th>수취인핸드폰번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.receiveCel}"></td>
+					</tr>
+					<tr>
+						<th>수취인우편번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.receiveZipcode}"></td>
+						<th>수취인주소</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.receiveAddr}"></td>
+						<th>배송비결제방식</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.baesongType}"></td>
+					</tr>
+					<tr>
+						<th>배송비</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.baesongBi}"></td>
+						<th>배송메세지</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.deliveryMsg}"></td>
+						<th>주문상품번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderProductId}"></td>
+					</tr>
+					<tr>
+						<th>샵링커상품번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.shoplinkerProductId}"></td>
+						<th>자사상품코드</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.partnerProductId}"></td>
+						<th>상품명</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.productName}"></td>
+					</tr>
+					<tr>
+						<th>주문수량</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.quantity}"></td>
+						<th>주문금액</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderPrice}"></td>
+						<th>판매단가</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.salePrice}"></td>
+					</tr>
+					<tr>
+						<th>공급가</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.supplyPrice}"></td>
+						<th>옵션명</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.sku}"></td>
+						<th>주문일자</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderdate}"></td>
+					</tr>
+					<tr>
+						<th>주문수집일자</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderRegDate}"></td>
+						<th>송장번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.deliveryInvoice}"></td>
+						<th>쇼핑몰계정</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.sellerId}"></td>
+					</tr>
+					<tr>
+						<th>필수옵션</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.onlySku}"></td>
+						<th>추가옵션</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.addSku}"></td>
+						<th>샵링커쇼핑몰코드</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.mallId}"></td>
+					</tr>
+					<tr>
+						<th>쇼핑몰부담할인액</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.disPriceMall}"></td>
+						<th>판매자부담할인액</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.disPriceSeller}"></td>
+						<th>쿠폰할인액</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.disPriceCoupon}"></td>
+					</tr>
+					<tr>
+						<th>포인트할인액</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.disPricePoint}"></td>
+						<th>물류배송여부</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.distributionDelivery}"></td>
+						<th>옵션매칭코드</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.skuMatchCode}"></td>
+					</tr>
+					<tr>
+						<th>옵션바코드</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.skuBarcode}"></td>
+						<th>개인고유통관번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderCustomsNumber}"></td>
+						<th>주문서타입</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderInputType}"></td>
+					</tr>
+					<tr>
+						<th>매입처아이디</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.supplyId}"></td>
+						<th>택배사코드</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.delivery}"></td>
+						<th>구매자계정</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderUserId}"></td>
+					</tr>
+					<tr>
+						<th>크로스픽주문</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.crspikUse}"></td>
+						<th>배송번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.shipNo}"></td>
+						<th>딜번호</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.dealNo}"></td>
+					</tr>
+					<tr>
+						<th>교환접수여부</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.exchangeOrderYn}"></td>
+						<th>추가상품</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.orderMainKey}"></td>
+						<th>네이버페이결제수단</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.panType}"></td>
+					</tr>
+					<tr>
+						<th>채널구분</th>
+						<td class="aL padL10" th:text="${slkOrderInfo.channelType}"></td>
+						<th>배송예정일</th>
+						<td class="aL padL10" colspan="3" th:text="${slkOrderInfo.shipRsvDate}"></td>
+					</tr>
+				</tbody>
+			</table>
+			<!-- //TABLE -->
+			<br>
+			<h4>제휴몰 업로드정보</h4>
+			<!-- TABLE -->
+			<table class="tableStyle">
+				<colgroup>
+					<col width="10%">
+					<col width="23%">
+					<col width="10%">
+					<col width="23%">
+					<col width="10%">
+					<col width="23%">
+				</colgroup>
+				<tbody>
+					<tr>
+						<th>업로드상태</th>
+						<td class="aL padL10" th:text="${extOrderInfo.uploadStatNm}"></td>
+
+						<th>업로드실패코드</th>
+						<td class="aL padL10" colspan="3" th:text="${extOrderInfo.uploadFailNm}"></td>
+					</tr>
+					<tr>
+						<th>업로드실패사유</th>
+						<td class="aL padL10" colspan="5" th:text="${extOrderInfo.uploadFailReason}"></td>
+					</tr>
+					<tr>
+						<th>벤더명</th>
+						<td class="aL padL10" th:text="${extOrderInfo.vendorNm}"></td>
+						<th>제휴몰ID</th>
+						<td class="aL padL10" th:text="${extOrderInfo.extmallId}"></td>
+						<th>제휴몰명</th>
+						<td class="aL padL10" th:text="${extOrderInfo.extmallNm}"></td>
+					</tr>
+					<tr>
+						<th>에이전트주문번호</th>
+						<td class="aL padL10" th:text="${extOrderInfo.agentOrderId}"></td>
+						<th>제휴몰주문번호<br>(쇼핑몰주문번호)</th>
+						<td class="aL padL10" th:text="${extOrderInfo.extmallOrderId}"></td>
+						<th>제휴몰상품ID</th>
+						<td class="aL padL10" th:text="${extOrderInfo.extmallProdId}"></td>
+					</tr>
+					<tr>
+						<th>제휴몰상품명</th>
+						<td class="aL padL10" th:text="${extOrderInfo.extmallProdNm}"></td>
+						<th>상품코드(상품)</th>
+						<td class="aL padL10" th:text="${extOrderInfo.goodsCd}"></td>
+						<th>옵션명</th>
+						<td class="aL padL10" th:text="${extOrderInfo.sku}"></td>
+					</tr>
+					<tr>
+						<th>현재판매가</th>
+						<td class="aL padL10" th:text="${extOrderInfo.currPrice}"></td>
+						<th>주문수량</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordQty}"></td>
+						<th>주문금액</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordAmt}"></td>
+					</tr>
+					<tr>
+						<th>쿠폰할인금액</th>
+						<td class="aL padL10" th:text="${extOrderInfo.cpnDcAmt}"></td>
+						<th>포인트할인금액</th>
+						<td class="aL padL10" th:text="${extOrderInfo.pntDcAmt}"></td>
+						<th>배송비</th>
+						<td class="aL padL10" th:text="${extOrderInfo.delvFee}"></td>
+					</tr>
+					<tr>
+						<th>주문수집일</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordRecvDt}"></td>
+						<th>주문일</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordDt}"></td>
+						<th>주문자명</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordNm}"></td>
+					</tr>
+					<tr>
+						<th>주문자휴대전화번호</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordPhnno}"></td>
+						<th>주문자전화번호</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordTelno}"></td>
+						<th>주문자이메일</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordEmail}"></td>
+					</tr>
+					<tr>
+						<th>수령자명</th>
+						<td class="aL padL10" th:text="${extOrderInfo.recipNm}"></td>
+						<th>수령자휴대전화번호</th>
+						<td class="aL padL10" th:text="${extOrderInfo.recipPhnno}"></td>
+						<th>수령자전화번호</th>
+						<td class="aL padL10" th:text="${extOrderInfo.recipTelno}"></td>
+					</tr>
+					<tr>
+						<th>수령자우편번호</th>
+						<td class="aL padL10" th:text="${extOrderInfo.recipZipcode}"></td>
+						<th>수령자기본주소</th>
+						<td class="aL padL10" th:text="${extOrderInfo.recipBaseAddr}"></td>
+						<th>수령자상세주소</th>
+						<td class="aL padL10" th:text="${extOrderInfo.recipDtlAddr}"></td>
+					</tr>
+					<tr>
+						<th>배송메모</th>
+						<td class="aL padL10" colspan="5" th:text="${extOrderInfo.delvMemo}"></td>
+					</tr>
+					<tr>
+						<th>주문번호</th>
+						<td class="aL padL10" th:text="${extOrderInfo.ordNo}"></td>
+						<th>등록자</th>
+						<td class="aL padL10" th:text="${extOrderInfo.regNm}"></td>
+						<th>등록일시</th>
+						<td class="aL padL10" th:text="${extOrderInfo.regDt}"></td>
+					</tr>
+				</tbody>
+			</table>
+
+
+		</div>
+	</div>
+</div>
+
+
+<script th:inline="javascript">
+// 팝업닫기
+var fnSlkOrderDetailClose = function(){
+	uifnPopupClose('popupSlkOrderDetail');
+}
+</script>
+</html>
+

+ 433 - 0
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerOrderForm.html

@@ -0,0 +1,433 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ShoplinkerOrderForm.html
+ * @desc    : 샵링커 주문수집 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.05.20   jmh     	 최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+
+		<form id="orderCollectionForm" name="orderCollectionForm" action="#" th:action="@{'/shoplinker/check/api_runable'}" th:method="post">
+			<input type="hidden" name="apiType" value="ORDER" />
+
+			<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 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>
+			</div>
+		</form>
+
+		<form id="searchForm" name="searchForm" action="#" th:action="@{'/shoplinker/order/collection/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+			<!-- 검색조건 영역 -->
+			<div class="panelStyle">
+
+				<table class="frmStyle">
+					<colgroup>
+						<col style="width:10%;"/>
+						<col/>
+						<col style="width:10%;"/>
+						<col style="width:17%;"/>
+						<col style="width:10%;"/>
+						<col style="width:17%;"/>
+					</colgroup>
+
+					<tr>
+						<th>일자<em class="required" title="필수"></em></th>
+						<td colspan="7">
+							<select name="dtGb">
+								<option value="orderRegDate">주문수집일자</option>
+								<option value="orderdate">주문일자</option>
+							</select>
+							<span id="terms">
+							</span>
+						</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>제휴몰 주문등록 상태</th>
+						<td>
+							<select name="uploadStat">
+								<option value="">[전체]</option>
+								<option th:if="${uploadStatList}" th:each="oneData, status : ${uploadStatList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+						<th>실패사유</th>
+						<td colspan="3">
+							<select name="uploadFailCd">
+								<option value="">[전체]</option>
+								<option th:if="${uploadFailList}" th:each="oneData, status : ${uploadFailList}" th:value="${oneData.cd}" th:text="${'[' + oneData.cd + '] ' + oneData.cdNm}"></option>
+							</select>
+						</td>
+					</tr>
+					<tr>
+						<th>샵링커주문번호</th>
+						<td>
+							<input type="text" class="w150" name="shoplinkerOrderId" maxlength="20"/>
+						</td>
+						<th>쇼핑몰주문번호</th>
+						<td>
+							<input type="text" class="w150" name="mallOrderId" maxlength="50" onkeyup="$(this).val($(this).val().toUpperCase());"/>
+						</td>
+						<th>스타일24주문번호</th>
+						<td>
+							<input type="text" class="w150" name="ordNo" maxlength="50"/>
+						</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-default btn-lg" onclick="fnTest();">테스트</button> -->
+						<!-- <button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button> -->
+					</li>
+				</ul>
+			</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: 470px" class="ag-theme-balham"></div>
+
+				<ul class="panelBar">
+					<li class="center">
+						<div class="tablePaging" id="shoplinkerOrderListPagination"></div>
+					</li>
+				</ul>
+			</div>
+			<!-- //리스트 영역 -->
+		</form>
+
+	</div>
+
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=20210114"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+	var sessRoleCd 		= [[${sessionInfo.roleCd}]];
+
+	var statusValue = {"Y":"판매중", "N":"판매중지"};
+	var apiGbValue = {"10":"상품등록", "11":"상품수정"};
+	var procGbValue = {"1":"전송완료", "0":"전송실패"};
+
+	let vendorList = gagajf.convertToArray([[${vendorList}]]);
+	let extmallList = gagajf.convertToArray([[${extmallList}]]);
+	let uploadStatList = gagajf.convertToArray([[${uploadStatList}]]);
+	let uploadFailList = gagajf.convertToArray([[${uploadFailList}]]);
+
+	let columnDefs = [
+		{headerName: "주문수집차수", field: "orderIfIdx", width: 100, cellClass: 'text-center'},
+		{headerName: "제휴몰주문등록 상태", field: "uploadStat" , width: 130, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(uploadStatList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(uploadStatList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(uploadStatList, params.newValue); }
+		},
+		{headerName: "실패사유", field: "uploadFailCd" , width: 150, cellClass: 'text-center',
+			cellEditorParams: { values: gagaAgGrid.extractValues(uploadFailList) },
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(uploadFailList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(uploadFailList, params.newValue); }
+		},
+		{headerName: "업로드실패사유", field: "uploadFailReason", width: 200, cellClass: 'text-center'},
+		{
+			headerName		: "스타일24 주문번호"
+			, field			: 'ordNo'
+			, width			: 130
+			, cellClass		: 'text-center'
+			, sortable		: true
+			, cellRenderer	: function (params) {
+				var roleCd = [[${sessionInfo.roleCd}]];
+				if (!roleCd.startsWith("C") && "" != params.value) {
+					return "<a href=\"javascript:void(0);\" onclick=\"fnOpenOrderDetailPopup('" + params.value + "');\">" + params.value + "</a>";
+				} else {
+					return params.value;
+				}
+			}
+		},
+		{
+			headerName		: "샵링커 주문번호"
+			, field			: 'shoplinkerOrderId'
+			, width			: 130
+			, cellClass		: 'text-center'
+			, sortable		: true
+			, cellRenderer	: function (params) {
+				var roleCd = [[${sessionInfo.roleCd}]];
+				if (!roleCd.startsWith("C")) {
+					return "<a href=\"javascript:void(0);\" onclick=\"fnReOpenSlkOrderDetailPopup('" + params.value + "');\">" + params.value + "</a>";
+				} else {
+					return params.value;
+				}
+			}
+		},
+		{headerName: "쇼핑몰 주문번호", field: "mallOrderId", 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'},
+		{headerName: "샵링커 상품번호", field: "shoplinkerProductId", width: 130, cellClass: 'text-center'},
+		{headerName: "자사 상품코드", field: "partnerProductId", width: 130, cellClass: 'text-center'},
+		{headerName: "상품명", field: "productName", width: 130, cellClass: 'text-center'},
+		{headerName: "주문수량", field: "quantity", width: 130, cellClass: 'text-center'},
+		{headerName: "주문금액", field: "orderPrice", width: 130, cellClass: 'text-center'},
+		{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'},
+	];
+
+	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	// Cell click
+	gridOptions.onCellClicked = function(event) {
+		if (event.colDef.field != 'extmallId')
+			return;
+
+		$('#detailForm select[name=vendorId]').val(event.data.vendorId);
+		$('#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 select[name=supplyCompCd]').val(event.data.supplyCompCd);
+		$('#detailForm input[name=sellStoreCd]').val(event.data.sellStoreCd);
+		$('#detailForm input[name=stockSellRate]').val(event.data.stockSellRate);
+		$('#detailForm input[name=priceAcceptRate]').val(event.data.priceAcceptRate);
+
+		if (event.data.dwdpYn == 'Y') {
+			$('#detailForm input:radio[name=dwdpYn]').eq(0).trigger('click');
+		} else {
+			$('#detailForm input:radio[name=dwdpYn]').eq(1).trigger('click');
+		}
+
+		if (event.data.cnclsmsSendYn == 'Y') {
+			$('#detailForm input:radio[name=cnclsmsSendYn]').eq(0).trigger('click');
+		} else {
+			$('#detailForm input:radio[name=cnclsmsSendYn]').eq(1).trigger('click');
+		}
+
+		if (event.data.useYn == 'Y') {
+			$('#detailForm input:radio[name=useYn]').eq(0).trigger('click');
+		} else {
+			$('#detailForm input:radio[name=useYn]').eq(1).trigger('click');
+		}
+	}
+
+
+	//페이징
+	$('#searchForm select[name=pageSize]').on('change', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnGoodsListSearch();
+	});
+
+	/**************** 검색 ********************************************************/
+	$('#btnSearch').on('click', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnGoodsListSearch();
+	});
+
+	// 조회
+	var fnGoodsListSearch = function() {
+
+		if(!fnConditionCheck()) return;
+		gagaPaging.init('searchForm', fnSearchCallBack, 'shoplinkerOrderListPagination', $('#searchForm').find('#pageSize').val());
+		gagaPaging.load($("#searchForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#searchForm';
+		var form = document.searchForm;
+
+		if (event.keyCode === 13) return false;
+
+		var searchFlag = false;
+		var cnt = 0;
+		if((!gagajf.isNull($("#searchForm input[name=stDate]").val()) && !gagajf.isNull($("#searchForm input[name=edDate]").val()))){
+			searchFlag = true;
+		}
+
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+
+		var fromDate = $('#searchForm input[name=stDate]').val();
+		var toDate = $('#searchForm input[name=edDate]').val();
+
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+		}
+		return true;
+	}
+
+	var fnSearchCallBack = function(result){
+
+		$('#searchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#searchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.shoplinkerOrderList);
+		gagaPaging.createPagination(result.pageing.pageable);
+
+	}
+	/**************** 검색 // *****************************************************/
+
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#terms', 'stDate', 'edDate', true, '수집');
+		$('.btnToday').trigger('click');
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+
+	});
+
+
+	$('#btnCollection').on('click', function() {
+
+		if( gagajf.isNull($("#orderCollectionForm input[name=apiStDate]").val())){
+			mcxDialog.alert("샵링커 주문일 입력하세요.");
+			return;
+		}
+
+		var testDate = Number($("#orderCollectionForm input[name=apiStDate]").val().replaceAll("-", ""));
+		if( 20210510 < testDate ){
+			mcxDialog.alert("※ 테스트 주문수집시 ※<br>실제운영 주문건을 가져오므로 5/10 이전 날짜로 조회해주세요.");
+			return;
+		}
+
+		mcxDialog.confirm("주문수집을 진행하시겠습니까?", {
+			cancelBtnText: "취소",
+			sureBtnText: "확인",
+			sureBtnClick: function() {
+
+				gagajf.ajaxFormSubmit($('#orderCollectionForm').prop('action'), '#orderCollectionForm', function(result) {
+					if( "RUN" == result.RESULT_TYPE){
+						// 현재 진행중
+						mcxDialog.alert(result.RESULT_MSG+"<br>"+result.RESULT_TXT);
+					}else{
+						var actionUrl = '/shoplinker/order/collection/receiveList/' + $('#apiStDate').val();
+						$.post(actionUrl, null, null, 'json');
+
+						setTimeout(function(){
+							fnGetCallRunableInfo();
+						}, 25000 );
+					}
+				});
+			}
+		});
+	});
+
+	// 진행상태 확인
+	var fnGetCallRunableInfo = function(){
+
+		gagajf.ajaxFormSubmit($('#orderCollectionForm').prop('action'), '#orderCollectionForm', function(result) {
+			if( "RUN" == result.RESULT_TYPE){
+
+				$(".runable_info").html(result.RESULT_TXT);
+				// 현재 진행중
+				setTimeout(function(){
+					fnGetCallRunableInfo();
+				}, 20000 );
+
+			}else{
+				// 종료처리
+				var str = $(".runable_info").html();
+				$(".runable_info").html(str + "=>FINISH");
+			}
+		});
+	}
+
+	var fnOpenOrderDetailPopup = function (ordNo) {
+		currOrdNo = ordNo;
+		cfnOpenOrderDetailPopup(ordNo);
+	};
+
+	var fnReOpenOrderDetailPopup = function () {
+		cfnOpenOrderDetailPopup(currOrdNo);
+	};
+
+	var fnReOpenSlkOrderDetailPopup = function (shoplinkerOrderId) {
+		cfnOpenSlkOrderPopup(shoplinkerOrderId);
+	};
+
+	var fnReOpenExtmallOrderDetailPopup = function (ordNo) {
+		cfnOpenExtmallOrderPopup(ordNo);
+	};
+
+/*]]>*/
+</script>
+
+</html>

+ 251 - 0
src/main/webapp/WEB-INF/views/shoplinker/ShoplinkerStockForm.html

@@ -0,0 +1,251 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org">
+<!--
+ *******************************************************************************
+ * @source  : ShoplinkerStockForm.html
+ * @desc    : 샵링커 재고전송이력 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.05.20   jmh     최초 작성
+ *******************************************************************************
+ -->
+	<div id="main">
+		<!-- 메인타이틀 영역 -->
+		<div class="main-title">
+		</div>
+		<!-- //메인타이틀 영역 -->
+
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+
+		<form id="searchForm" name="searchForm" action="#" th:action="@{'/shoplinker/stock/result/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
+			<input type="hidden" name="apiType" value="STOCK" />
+
+			<!-- 검색조건 영역 -->
+			<div class="panelStyle">
+				<div class="panelTitle">
+					<h3><i class="fa fa-info-circle"></i>아래 검색조건 중 상품코드나 등록일을 꼭 입력해 주세요.</h3>
+				</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>
+							<input type="text" class="w130" name="goodsCd" id="goodsCd" maxlength="20" />
+						</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>
+			<!-- 검색조건 영역 -->
+
+			<!-- 리스트 영역 -->
+			<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: 470px" class="ag-theme-balham"></div>
+
+				<ul class="panelBar">
+					<li class="center">
+						<div class="tablePaging" id="listPagination"></div>
+					</li>
+				</ul>
+			</div>
+			<!-- //리스트 영역 -->
+		</form>
+
+	</div>
+
+<script type="text/javascript" src="/ux/plugins/gaga/gaga.paging.js?v=20210114"></script>
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+	var sessRoleCd 		= [[${sessionInfo.roleCd}]];
+	var procGbValue = {"true":"전송완료", "false":"전송실패", "error":"오류"};
+
+	let columnDefs = [
+		{headerName: "No", width: 60, cellClass: 'text-center',
+			valueGetter: function(params) { return cfnGridNumner('searchForm',params.node.rowIndex, 'A');}
+		},
+		{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: "옵션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'}
+	];
+
+	let gridOptions = gagaAgGrid.getGridOptions(columnDefs);
+
+	//페이징
+	$('#searchForm select[name=pageSize]').on('change', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnListSearch();
+	});
+
+
+	/**************** 검색 ********************************************************/
+	$('#btnSearch').on('click', function() {
+		$("#searchForm input[name=pageNo]").val('1');
+		fnListSearch();
+	});
+
+	// 조회
+	var fnListSearch = function() {
+
+		if(!fnConditionCheck()) return;
+		gagaPaging.init('searchForm', fnSearchCallBack, 'listPagination', $('#searchForm').find('#pageSize').val());
+		gagaPaging.load($("#searchForm input[name=pageNo]").val());
+	}
+
+	//검색 조건 확인
+	var fnConditionCheck = function(){
+		var formId = '#searchForm';
+		var form = document.searchForm;
+
+		if (event.keyCode === 13) return false;
+
+		var searchFlag = false;
+		var cnt = 0;
+
+		if( !gagajf.isNull($("#searchForm input[name=agentOrderId]").val())
+				|| !gagajf.isNull($("#searchForm input[name=extmallOrderId]").val())
+				|| !gagajf.isNull($("#searchForm input[name=ordNo]").val())
+				|| (!gagajf.isNull($("#searchForm input[name=stDate]").val()) && !gagajf.isNull($("#searchForm input[name=edDate]").val()))
+			){
+			searchFlag = true;
+		}else{
+
+			/* for (i = 0; i < form.elements.length; i++ ) {
+				var el = form.elements[i];
+
+				if ($(el).prop("type") == "text" || ($(el).prop("type") == "select-one" && el.name != "search" && el.name != "pageSize")) {
+					if (!(el.value == null || el.value == "")) {
+						cnt++;
+					}
+				}
+			}
+
+			if(cnt > 0) searchFlag = true; */
+		}
+
+		if(searchFlag == false){
+			mcxDialog.alert("검색조건을 입력하세요.");
+			return false;
+		}
+
+		var fromDate = $('#searchForm input[name=stDate]').val();
+		var toDate = $('#searchForm input[name=edDate]').val();
+
+		if (!gagajf.isNull(fromDate) || !gagajf.isNull(toDate)) {
+
+			if (gagajf.isNull(fromDate) || gagajf.isNull(toDate)) {
+				mcxDialog.alertC("등록일 조회시 시작일자와 종료일자를 입력하세요.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+
+			if (fromDate > toDate) {
+				mcxDialog.alertC("등록 시작일자는 종료일자 보다 클 수 없습니다.", {
+					sureBtnText: "확인",
+					sureBtnClick: function() {
+						$('#searchForm input[name=stDate]').focus();
+					}
+				});
+				return false;
+			}
+		}
+		return true;
+	}
+
+	var fnSearchCallBack = function(result){
+
+		$('#searchForm').find('#gridRowTotalCount').html(result.pageing.pageable.totalCount.addComma());
+		$('#searchForm').find('#pageNo').val(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#pgNo').html(result.pageing.pageable.pageNo.addComma());
+		$('#searchForm').find('#endPgNo').html(result.pageing.pageable.totalPage.addComma());
+		gridOptions.api.setRowData(result.stockList);
+		gagaPaging.createPagination(result.pageing.pageable);
+
+	}
+	/**************** 검색 // *****************************************************/
+
+	$(document).ready(function() {
+
+		cfnCreateCalendar('#sellTerms', 'stDate', 'edDate', true, '등록일', 'X');
+		$('.btnToday').trigger('click');
+
+		// Create a agGrid
+		gagaAgGrid.createGrid('gridList', gridOptions);
+	});
+
+/*]]>*/
+</script>
+
+</html>

+ 44 - 10
src/main/webapp/ux/js/admin.popup.js

@@ -1,8 +1,8 @@
 /*
  * Popup Java Script
- * 
+ *
  * 모든 팝업은 공통으로 사용할 수 있기 때문에 여기에 함수를 등록해 처리한다.
- * 
+ *
  * Copyright (c) 2014 gagamel (exrkorea.com)
  *
  * $Date: 2014-06-13$
@@ -14,9 +14,9 @@
  * @desc   : 팝업창 window.open 에서 사용되는 방식으로 features 설정
  * <pre>
  *     cfOpenWindowPopup('/popup.do?cmd=getIDPassword', 'popup', 710, 610);
- *     
+ *
  *     or
- *     
+ *
  *     cfOpenWindowPopup('/popup.do?cmd=getIDPassword', 'popup', 710, 610, 1, 400, 200, 'no', '');
  * </pre>
  * @param  : theURL - 새창의 Url
@@ -42,7 +42,7 @@ function cfOpenWindowPopup(theURL, winName, width, height, center, left, top, sc
 	if (left == undefined) left = 100;
 	if (top == undefined) top = 100;
 	if (resizable == undefined) resizable = 'no';
-		
+
 	if (center == 1) {
 		if (fstate == "") {
 			state = features + ", left=" + (screen.width-width)/2 + ",top=" + (screen.height-height)/2+",scrollbars=" + scrollbars + ",resizable=" + resizable + ",toolbar=0,menubar=0";
@@ -82,7 +82,7 @@ var cfnOpenModalPopup = function(actionUrl, oTarget) {
 
 	$("#" + oTarget).load(actionUrl, function() {
 		uifnPopupOpen(oTarget);
-		
+
 		$('.schDate').datepicker({
 			changeMonth: true,
 			changeYear: true,
@@ -217,7 +217,7 @@ var cfnOpenImagePreViewPopup = function(id,imgUrl) {
  */
 //비디오 팝업 열기
 var cfnOpenGoodsVideoPopup = function(id, objId, formid, type, fullUrl) {
-	
+
 	var src = $(formid).find("#"+objId).val();
 	var str = '';
 	str += '<div class="videoPopup"  style="width:700px; height:350px"  id="'+id+'">';
@@ -786,7 +786,7 @@ var cfnOpenFreeGoodsPromotionSetPopup = function(gbn, freegiftSq) {
  *     cfnOpenCompanyListPopup('fnResult', 'S', 'TBJ', 'inputId');				// 문자열은 멀티구분 S이고, 결과가 하나일때 supplyCompCd값을 넣어줄 html tag id, S가 아니고, inputId가 존재하지 않으면 무조건 팝업이 열림.
  *     or
  *     cfnOpenCompanyListPopup('fnResult', 'S', 'TBJ', 'inputId', 'Y');			// '': 전체 공급업체(기본값), Y: 자사공급업체, N:입점공급업체
- *     
+ *
  * </pre>
  * @since  : 2020/12/23
  * @author : xodud1202
@@ -954,8 +954,8 @@ var cfnOpenAfChannelPopup = function(callbackfun) {
 	}
 	if (typeof(callbackfun) != 'undefined'){
 		actionUrl += "?callBackFun=" + callbackfun;
-	} 
-		
+	}
+
 	cfnOpenModalPopup(actionUrl,'popupAfChannel');
 }
 
@@ -990,3 +990,37 @@ var cfnOpenMainGnbContentsPopup = function(cateNo, contentsLoc, brandGroupNo) {
 	if (typeof(brandGroupNo) != 'undefined') actionUrl += "&brandGroupNo=" + brandGroupNo;
 	cfnOpenModalPopup(actionUrl, 'popupMainGnbContents');
 }
+
+/**
+ * @type   : function
+ * @access : public
+ * @desc   : 샵링커 주문수집 팝업
+ * <pre>
+ *     cfnOpenSlkOrderPopup('샵링커주문번호');
+ * </pre>
+ * @param  : orderNo - 샵링커주문번호:필수
+ * @since  : 2021/05/31
+ * @author : jmh
+ */
+var cfnOpenSlkOrderPopup = function(shoplinkerOrderId) {
+	var actionUrl = "/shoplinker/order/collection/info";
+	if (typeof(shoplinkerOrderId) != 'undefined') actionUrl += "?shoplinkerOrderId=" + shoplinkerOrderId;
+	cfnOpenModalPopup(actionUrl, "popupSlkOrderDetail");
+}
+
+/**
+ * @type   : function
+ * @access : public
+ * @desc   : 샵링커 주문수집 팝업
+ * <pre>
+ *     cfnOpenSlkOrderPopup('샵링커주문번호');
+ * </pre>
+ * @param  : orderNo - 샵링커주문번호:필수
+ * @since  : 2021/05/31
+ * @author : jmh
+ */
+var cfnOpenExtmallOrderPopup = function(ordNo) {
+	var actionUrl = "/shoplinker/order/extmall/info";
+	if (typeof(ordNo) != 'undefined') actionUrl += "?ordNo=" + ordNo;
+	cfnOpenModalPopup(actionUrl, "popupExtmallOrderDetail");
+}