浏览代码

샵링커재고전송-전체전송 배치 추가개발

jmh 4 年之前
父节点
当前提交
3c7e3e9126

+ 9 - 0
src/main/java/com/style24/batch/biz/dao/TsbShoplinkerDao.java

@@ -46,6 +46,15 @@ public interface TsbShoplinkerDao {
 	 */
 	void updateSyncStock();
 
+	/**
+	 * 재고 전체전송 (특별한날 사용)
+	 *
+	 * @return
+	 * @author jmh
+	 * @since  2021. 10. 19
+	 */
+	Collection<ShoplinkerGoods> getSyncStockAllList();
+	
 	/**
 	 * 재고 변경 목록
 	 *

+ 296 - 0
src/main/java/com/style24/batch/biz/job/shoplinker/TsbShoplinkerStockAllJob.java

@@ -0,0 +1,296 @@
+package com.style24.batch.biz.job.shoplinker;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import com.gagaframework.shoplinker.GagaShoplinkertUtil;
+import com.gagaframework.shoplinker.env.GagaShoplinkerConstants;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.style24.batch.biz.job.TsbAbstractJob;
+import com.style24.batch.biz.service.TsbShoplinkerService;
+import com.style24.core.support.env.TscConstants;
+import com.style24.persistence.domain.ShoplinkerGoods;
+
+import lombok.extern.slf4j.Slf4j;
+
+
+/**
+ * 샵링커 재고전송
+ *
+ * @author jmh
+ * @since 2021.06.22
+*/
+@Component
+@Slf4j
+public class TsbShoplinkerStockAllJob extends TsbAbstractJob<Collection<ShoplinkerGoods>, Collection<ShoplinkerGoods>, String>{
+
+	@Autowired
+	private TsbShoplinkerService shoplinkerService;
+
+	@Autowired
+	private Environment env;
+
+	@Override
+	public Collection<ShoplinkerGoods> read() throws Exception {
+
+		// 재고 전체전송목록 - 1000 건씩 가져옴
+		return shoplinkerService.getSyncStockAllList();
+	}
+
+	@Override
+	public Collection<ShoplinkerGoods> process(Collection<ShoplinkerGoods> stockList) throws Exception {
+		return stockList;
+	}
+
+	@Override
+	public String write(Collection<ShoplinkerGoods> stockList) throws Exception {
+		ShoplinkerGoods regMap = new ShoplinkerGoods();
+
+		// xml 생성경로
+		String xmlPath = env.getProperty("shoplinker.xml.path");
+
+		// 샵링커 기본폴더 존재여부 확인
+		String slFolder = GagaFileUtil.getConcatenationPath(xmlPath);
+		File slPath = new File(slFolder);
+		if (!slPath.exists()) {
+			slPath.mkdir();
+		}
+		//하위폴더존재확인(재고)
+		slFolder = GagaFileUtil.getConcatenationPath(xmlPath+"/stock");
+		slPath = new File(slFolder);
+		if (!slPath.exists()) {
+			slPath.mkdir();
+		}
+
+		if (stockList != null && !stockList.isEmpty()) {
+
+			// 1. 재고 마스터 테이블 전송여부 Y로 일괄 변경(실패건이 거의 없으므로 실패건만 개별로 업데이트 시킨다.)
+			regMap.setSendYn("Y");
+			regMap.setAllUpdYn("Y");
+			shoplinkerService.updateStockInfo(regMap);
+
+			// 2. xml 파일 정보세팅
+			String toDtTime = GagaDateUtil.getTodayDateTime();
+			String customerId = env.getProperty("shoplinker.customer_id");
+			regMap.setSendYn("N");													// 성공이 아닐경우만 개별업데이트
+			regMap.setAllUpdYn("N");												// 성공이 아닐경우만 개별업데이트
+			regMap.setApiType("STOCK");
+			regMap.setApiSubUrl(env.getProperty("shoplinker.url.stock"));
+			regMap.setXmlPath(env.getProperty("shoplinker.xml.path")+"/stock");		// xml 생성경로
+			regMap.setDomainUrl(env.getProperty("shoplinker.xml.view")+"/stock");	// xml 확인domain url
+
+			try {
+				StringBuilder sbRequest;
+				int qty = 0;
+				for (ShoplinkerGoods map : stockList) {
+					
+					// 21.10.18 재고비율 추가 - 샵링커에 전송 및 전송이력에는 재고비율 수량으로 저장함
+					// 참고)재고 마스터 테이블에는 원 수량임(동기화 처리시에도 원 수량으로 됨)
+					qty = GetStockQtyForBrand(map, false);
+
+					// xml 데이터 세팅
+					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(customerId).append("</customer_id>\n");
+					sbRequest.append("		<mall_update_yn>N</mall_update_yn>\n");
+					sbRequest.append("		<partner_product_id><![CDATA[").append(map.getOptCd()).append("]]></partner_product_id>\n");
+					sbRequest.append("		<quantity>").append(qty).append("</quantity>\n");
+
+					sbRequest.append("	</product>\n");
+					sbRequest.append("</shoplinker>\n");
+
+					regMap.setGoodsCd(map.getGoodsCd());
+					regMap.setOptCd(map.getOptCd());
+					regMap.setQuantity(qty);
+
+					// 3. api 호출 및 결과 history 저장
+					callGoodsRegApi(regMap , sbRequest, map.getOptCd());
+				}
+
+			}catch(Exception e) {
+				log.error("xml 생성오류 ", e);
+				regMap.setApiResult(TscConstants.ShoplinkerApiStat.S_ERROR.value());
+				regMap.setApiMessage("xml 생성오류");
+				shoplinkerService.insertShoplinerApiHst(regMap);
+			}
+		}
+
+		return "OK";
+	}
+
+	@Override
+	public void notify(String result) throws Exception {
+		// Do nothing
+	}
+
+	private int callGoodsRegApi(ShoplinkerGoods map, StringBuilder sbRequest, String fileNm) throws IOException {
+
+		int succCnt = 0;
+		String xmlPath = "";
+		String xmlUrl = "";
+		String responseXmlData = "";
+		StringBuilder xmlFileName = new StringBuilder();
+		com.gagaframework.shoplinker.domain.goods.result.Shoplinker shoplinkerResult;
+		com.gagaframework.shoplinker.domain.goods.result.ResultMessage resultMsg;
+
+		try {
+			GagaShoplinkertUtil shoplinkerUtil = new GagaShoplinkertUtil("MS949");
+
+			// XML 파일 생성
+			xmlFileName = new StringBuilder();
+			xmlFileName.append("stock_"+fileNm).append(".xml");
+			xmlPath = GagaFileUtil.getConcatenationPath(map.getXmlPath(), xmlFileName.toString());
+			shoplinkerUtil.makeRequestXmlFile(sbRequest.toString(), xmlPath);
+			xmlUrl = GagaFileUtil.getConcatenationPath(map.getDomainUrl(), xmlFileName.toString());
+
+			// API 호출URL
+			String apiUrl = GagaShoplinkerConstants.API_DOMAIN + map.getApiSubUrl() + URLEncoder.encode(xmlUrl);
+
+			// API 호출결과
+			responseXmlData = shoplinkerUtil.callShoplinkerApiByGet(apiUrl, "");
+
+			// response 결과
+			shoplinkerResult = (com.gagaframework.shoplinker.domain.goods.result.Shoplinker)shoplinkerUtil.unmarshal(com.gagaframework.shoplinker.domain.goods.result.Shoplinker.class, responseXmlData);
+			resultMsg = shoplinkerResult.getResultMessage();
+			map.setXmlTxt(sbRequest.toString());
+			map.setApiProductId(resultMsg.getProductId());
+			map.setApiResult(resultMsg.getResult());
+			map.setApiMessage(resultMsg.getMessage());
+
+			if( "true".equals(resultMsg.getResult())){
+				succCnt = 1;
+			}else {
+				// 실패 전송이력 N으로 수정
+				shoplinkerService.updateStockInfo(map);
+			}
+
+		} catch (Exception e) {
+			log.error("callGoodsRegApi error", e);
+
+			java.io.File file = new java.io.File(xmlUrl);
+			String errStr = "[파일존재여부] : "+file.exists();
+			errStr += "\n[xmlPath] : "+xmlPath;
+			errStr += "\n[xmlUrl] : "+xmlUrl;
+			errStr += "\n\n[responseXmlData] : "+responseXmlData;
+			errStr += "\n\n[xml] : "+sbRequest.toString();
+
+			map.setXmlTxt(errStr);
+			map.setApiResult(TscConstants.ShoplinkerApiStat.S_ERROR.value());
+			map.setApiMessage("API 오류 " +StringUtils.abbreviate(responseXmlData, 0 , 120));
+
+			shoplinkerService.updateStockInfo(map);
+		}
+
+		// 전송이력 저장
+		shoplinkerService.insertShoplinerApiHst(map);
+
+		// 생성 파일삭제
+		//GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(map.getXmlPath(), xmlFileName.toString()));
+
+		return succCnt;
+	}
+	
+	/**
+	 * 샵링커 브랜드별 재고비율
+	 *
+	 * @return
+	 * @author jmh
+	 * @since  2021. 10. 18
+	 */
+	private int GetStockQtyForBrand(ShoplinkerGoods map, boolean isFirst)
+    {
+        int resultQty = 0;
+        String brandCd = map.getBrand();
+        int qty = map.getQuantity();
+
+        if (brandCd.equals("S0016") || brandCd.equals("S0018") || brandCd.equals("S0012"))
+        {
+            if (qty >= 0 && qty <= 5)
+            {
+                resultQty = isFirst ? 1 : 0;
+            }
+            else if (qty >= 6 && qty <= 29)
+            {
+                resultQty = (int)Math.floor(qty * 0.25);
+            }
+            else if (qty >= 30)
+            {
+                resultQty = (int)Math.floor(qty * 0.4);
+            }
+        }
+        else if (brandCd.equals("S0005"))
+        {
+            if (qty >= 0 && qty <= 3)
+            {
+                resultQty = isFirst ? 1 : 0;
+            }
+            else if (qty >= 4 && qty <= 29)
+            {
+                resultQty = (int)Math.floor(qty * 0.25);
+            }
+            else if (qty >= 30)
+            {
+                resultQty = (int)Math.floor(qty * 0.4);
+            }
+        }
+        else if (brandCd.equals("S0003") || brandCd.equals("S0004") || brandCd.equals("S0007") || brandCd.equals("S0001") || brandCd.equals("S0006"))
+        {
+            if (qty >= 0 && qty <= 3)
+            {
+                resultQty = isFirst ? 1 : 0;
+            }
+            else if (qty >= 4 && qty <= 29)
+            {
+                resultQty = (int)Math.ceil(qty * 0.25);
+            }
+            else if (qty >= 30)
+            {
+                resultQty = (int)Math.floor(qty * 0.4);
+            }
+        }
+        else if (brandCd.equals("S0013"))
+        {
+            if (qty >= 0 && qty <= 2)
+            {
+                resultQty = isFirst ? 1 : 0;
+            }
+            else if (qty >= 3 && qty <= 29)
+            {
+                resultQty = (int)Math.ceil(qty * 0.25);
+            }
+            else if (qty >= 30)
+            {
+                resultQty = (int)Math.floor(qty * 0.4);
+            }
+        }
+
+        else if (brandCd.equals("S0015"))
+        {
+            if (qty >= 0 && qty <= 2)
+            {
+                resultQty = isFirst ? 1 : 0;
+            }
+            else if (qty >= 3 && qty <= 29)
+            {
+                resultQty = (int)Math.ceil(qty * 0.25);
+            }
+            else if (qty >= 30)
+            {
+                resultQty = (int)Math.floor(qty * 0.4);
+            }
+        }
+
+        return resultQty;
+    }
+}

+ 11 - 0
src/main/java/com/style24/batch/biz/service/TsbShoplinkerService.java

@@ -59,6 +59,17 @@ public class TsbShoplinkerService {
 		shoplinkerDao.updateSyncStock();
 	}
 
+	/**
+	 * 재고 전체전송 (특별한날 사용)
+	 *
+	 * @return
+	 * @author jmh
+	 * @since  2021. 10. 19
+	 */
+	public Collection<ShoplinkerGoods> getSyncStockAllList() {
+		return shoplinkerDao.getSyncStockAllList();
+	}
+	
 	/**
 	 * 재고 변경 목록
 	 *

+ 17 - 0
src/main/java/com/style24/batch/biz/task/TsbShoplinkerTask.java

@@ -7,6 +7,7 @@ import org.springframework.stereotype.Component;
 
 import com.style24.batch.biz.job.shoplinker.TsbShoplinkerInvoiceJob;
 import com.style24.batch.biz.job.shoplinker.TsbShoplinkerOrderJob;
+import com.style24.batch.biz.job.shoplinker.TsbShoplinkerStockAllJob;
 import com.style24.batch.biz.job.shoplinker.TsbShoplinkerStockJob;
 
 import lombok.extern.slf4j.Slf4j;
@@ -20,6 +21,9 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class TsbShoplinkerTask {
 
+	@Autowired
+	private TsbShoplinkerStockAllJob shoplinkerStockAllJob;
+	
 	@Autowired
 	private TsbShoplinkerStockJob shoplinkerStockJob;
 
@@ -30,6 +34,19 @@ public class TsbShoplinkerTask {
 	private TsbShoplinkerInvoiceJob shoplinkerInvoiceJob;
 
 
+	/**
+	 * 재고 전체전송 (특별한날 사용)
+	 *
+	 * @return
+	 * @author jmh
+	 * @since  2021. 10. 19
+	 */
+	@Scheduled(cron = "${cron.shoplinker.stock.sendAll}")
+	@Async
+	public void stockSendJobAll() throws Exception {
+		shoplinkerStockAllJob.runById("cron.shoplinker.stock.sendAll");
+	}
+	
 	/**
 	 * 재고전송 10시
 	 * @throws Exception

+ 17 - 0
src/main/java/com/style24/batch/biz/web/TsbShoplinkerController.java

@@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 import com.style24.batch.biz.job.shoplinker.TsbShoplinkerInvoiceJob;
 import com.style24.batch.biz.job.shoplinker.TsbShoplinkerOrderJob;
+import com.style24.batch.biz.job.shoplinker.TsbShoplinkerStockAllJob;
 import com.style24.batch.biz.job.shoplinker.TsbShoplinkerStockJob;
 import com.style24.core.support.controller.TscBaseController;
 
@@ -26,6 +27,9 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class TsbShoplinkerController extends TscBaseController {
 
+	@Autowired
+	private TsbShoplinkerStockAllJob shoplinkerStockAllJob;
+	
 	@Autowired
 	private TsbShoplinkerStockJob shoplinkerStockJob;
 
@@ -37,6 +41,19 @@ public class TsbShoplinkerController extends TscBaseController {
 
 
 
+	/**
+	 * 재고전송 10시
+	 * @throws Exception - 예외처리
+	 * @author jmh
+	 * @since 2021. 06. 22
+	 */
+	@GetMapping("/stock/sendAll")
+	@ResponseBody
+	public String sendStockAll() throws Exception {
+		shoplinkerStockAllJob.runById("cron.shoplinker.stock.sendAll");
+		return "OK";
+	}
+	
 	/**
 	 * 재고전송 10시
 	 * @throws Exception - 예외처리

+ 33 - 0
src/main/java/com/style24/persistence/mybatis/shop/TsbShoplinker.xml

@@ -35,6 +35,39 @@
 		)
 	</insert>
 
+	<!-- 재고 전체 전송 - 전송예정 목록-->
+	<select id="getSyncStockAllList" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
+		/*TsbCustomerDao.getSyncStockAllList*/
+		SELECT
+			TG.ITEMKIND_CD
+			, A.GOODS_CD
+			, A.OPT_CD
+			, A.STOCK_QTY AS QUANTITY
+			, TG.BRAND_CD
+			, CASE 
+				  WHEN TG.BRAND_CD = 'S0016' THEN 1
+				  WHEN TG.BRAND_CD = 'S0018' THEN 2
+				  WHEN TG.BRAND_CD = 'S0012' THEN 3
+				  WHEN TG.BRAND_CD = 'S0005' THEN 4
+				  WHEN TG.BRAND_CD = 'S0003' THEN 5
+				  WHEN TG.BRAND_CD = 'S0004' THEN 6
+				  WHEN TG.BRAND_CD = 'S0007' THEN 7
+				  WHEN TG.BRAND_CD = 'S0001' THEN 8
+				  WHEN TG.BRAND_CD = 'S0006' THEN 9
+				  WHEN TG.BRAND_CD = 'S0013' THEN 10
+				  WHEN TG.BRAND_CD = 'S0015' THEN 11
+				  ELSE 99
+			  END RANK_NO		       
+		FROM   SHOPLINKER_STOCK A
+		INNER JOIN TB_GOODS TG ON A.GOODS_CD = TG.GOODS_CD
+		WHERE 1=1  
+		AND   A.SEND_YN = 'N'
+		AND   A.SEND_DT IS NULL
+		ORDER BY 6
+		LIMIT 1000
+
+	</select>
+	
 	<!-- 재고 전송예정 목록-->
 	<select id="getSyncStockList" parameterType="ShoplinkerGoods" resultType="ShoplinkerGoods">
 		/*TsbCustomerDao.getSyncStockList*/

+ 3 - 2
src/main/resources/config/application-brdg.yml

@@ -180,9 +180,10 @@ cron:
 
     # 샵링커
     shoplinker:
+        stock.sendAll: 0 0/10 * * * *       #재고 전체전송(특별한날만 사용)
         stock.send10: 0 0 10 * * *          #재고 10시 (1일 1회)
-        stock.send15: 0 0 15 * * *           #재고 15시 (1일 1회)
-        order.receive: 2 22 2 29 2 ?       #주문 (평일 5시 ~ 15시 5분에 실행)
+        stock.send15: 0 0 15 * * *          #재고 15시 (1일 1회)
+        order.receive: 2 22 2 29 2 ?        #주문 (평일 5시 ~ 15시 5분에 실행)
         invoice.send: 0 16 * * * *          #송장 (1시간 1회)
 
 # USAFE 보증보험 정보 (TODO: 오픈 시 운영용으로 변경)

+ 5 - 4
src/main/resources/config/application-locd.yml

@@ -178,10 +178,11 @@ cron:
 
     # 샵링커
     shoplinker:
-        stock.send10: 2 22 2 29 2 ?           #재고 10시 (1일 1회)
-        stock.send15: 2 22 2 29 2 ?           #재고 15시 (1일 1회)
-        order.receive: 2 22 2 29 2 ?  #주문 (1시간 1회)
-        invoice.send: 2 22 2 29 2 ?            #송장 (1시간 1회)
+        stock.sendAll: 2 22 2 29 2 ?       #재고 전체전송(특별한날만 사용)
+        stock.send10: 2 22 2 29 2 ?        #재고 10시 (1일 1회)
+        stock.send15: 2 22 2 29 2 ?        #재고 15시 (1일 1회)
+        order.receive: 2 22 2 29 2 ?       #주문 (1시간 1회)
+        invoice.send: 2 22 2 29 2 ?        #송장 (1시간 1회)
 
 # USAFE 보증보험 정보
 usafe.guarantee:

+ 5 - 4
src/main/resources/config/application-locp.yml

@@ -178,10 +178,11 @@ cron:
 
     # 샵링커
     shoplinker:
-        stock.send10: 2 22 2 29 2 ?           #재고 10시 (1일 1회)
-        stock.send15: 2 22 2 29 2 ?           #재고 15시 (1일 1회)
-        order.receive: 2 22 2 29 2 ?  #주문 (1시간 1회)
-        invoice.send: 2 22 2 29 2 ?            #송장 (1시간 1회)
+        stock.sendAll: 2 22 2 29 2 ?       #재고 전체전송(특별한날만 사용)
+        stock.send10: 2 22 2 29 2 ?        #재고 10시 (1일 1회)
+        stock.send15: 2 22 2 29 2 ?        #재고 15시 (1일 1회)
+        order.receive: 2 22 2 29 2 ?       #주문 (1시간 1회)
+        invoice.send: 2 22 2 29 2 ?        #송장 (1시간 1회)
 
 # USAFE 보증보험 정보
 usafe.guarantee:

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

@@ -171,6 +171,7 @@ cron:
 
     # 샵링커 (public 배치)
     shoplinker:
+        stock.sendAll: 2 22 2 29 2 ?       #재고 전체전송(특별한날만 사용)
         stock.send10: 2 22 2 29 2 ?        #재고 10시
         stock.send15: 2 22 2 29 2 ?        #재고 15시
         order.receive: 0 4 5-15 * * MON-FRI #주문 (평일 5시 ~ 15시 5분에 실행)