|
@@ -0,0 +1,314 @@
|
|
|
|
|
+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()) {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 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());
|
|
|
|
|
+
|
|
|
|
|
+ // 재고 마스터 테이블 전송여부 Y로 변경
|
|
|
|
|
+ regMap.setSendYn("Y");
|
|
|
|
|
+ regMap.setOptCd(map.getOptCd());
|
|
|
|
|
+ shoplinkerService.updateStockInfo(regMap);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }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.getBrandCd();
|
|
|
|
|
+ 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);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ 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;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|