package com.zy.asrs.task.handler; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.zy.asrs.entity.WaitPakin; import com.zy.asrs.entity.WrkDetl; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.entity.param.ErpPakinReportParam; import com.zy.asrs.service.ApiLogService; import com.zy.asrs.service.WaitPakinService; import com.zy.asrs.service.WrkDetlService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.task.AbstractHandler; import com.zy.asrs.task.core.ReturnT; import com.zy.common.entity.Parameter; import com.zy.common.utils.HttpHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @Slf4j @Service public class WorkErpReportHandler extends AbstractHandler { public static final long ERP_REPORT_PENDING_WRK_STS = 16L; public static final long ERP_REPORT_FINISHED_WRK_STS = 5L; public static final int ERP_REPORT_MAX_RETRY_TIMES = 3; public static final String ERP_REPORT_PENDING_FLAG = "P"; public static final String ERP_REPORT_SUCCESS_FLAG = "Y"; public static final String ERP_REPORT_FAIL_FLAG = "F"; private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; @Autowired private WrkMastService wrkMastService; @Autowired private WrkDetlService wrkDetlService; @Autowired private WaitPakinService waitPakinService; @Autowired private ApiLogService apiLogService; @Value("${erp.switch.ErpReportOld}") private boolean erpReportOld; @Value("${erp.address.URL}") private String erpUrl; @Value("${erp.address.Inaddress}") private String erpInAddress; @Transactional(rollbackFor = Exception.class) public ReturnT start(WrkMast source) { WrkMast wrkMast = wrkMastService.selectById(source.getWrkNo()); if (wrkMast == null || !Long.valueOf(ERP_REPORT_PENDING_WRK_STS).equals(wrkMast.getWrkSts())) { return SUCCESS; } if (!isErpReportEnabled()) { finishReport(wrkMast, false, getRetryTimes(wrkMast), "ERP reporting is disabled", false); return FAIL.setMsg("ERP reporting is disabled"); } List wrkDetls = wrkDetlService.selectByWrkNo(wrkMast.getWrkNo()); if (Cools.isEmpty(wrkDetls)) { finishReport(wrkMast, false, getRetryTimes(wrkMast), "work details are empty", false); return FAIL.setMsg("work details are empty"); } WaitPakin waitPakin = findWaitPakin(wrkMast.getBarcode()); ErpPakinReportParam param = buildParam(wrkMast, wrkDetls, waitPakin); String request = JSON.toJSONString(param); String response = ""; boolean success = false; String errorMsg = null; String requestUrl = buildRequestUrl(); try { response = new HttpHandler.Builder() .setUri(erpUrl) .setPath(erpInAddress) .setJson(request) .build() .doPost(); success = isErpReportSuccess(response); if (!success) { errorMsg = extractErrorMsg(response); } finishReport(wrkMast, success, getRetryTimes(wrkMast), errorMsg, true); } catch (Exception e) { errorMsg = e.getMessage(); finishReport(wrkMast, false, getRetryTimes(wrkMast), errorMsg, true); } finally { try { apiLogService.save( "Inbound ERP Report", requestUrl, null, "127.0.0.1", request, response, success, "workNo=" + wrkMast.getWrkNo() ); } catch (Exception logEx) { log.error("save erp api log failed", logEx); } } if (success) { return SUCCESS; } return FAIL.setMsg(errorMsg); } private boolean isErpReportEnabled() { if (!erpReportOld) { return false; } String erpReport = Parameter.get().getErpReport(); return Cools.isEmpty(erpReport) || "true".equalsIgnoreCase(erpReport); } private WaitPakin findWaitPakin(String barcode) { if (Cools.isEmpty(barcode)) { return null; } return waitPakinService.selectOne(new EntityWrapper().eq("zpallet", barcode)); } private ErpPakinReportParam buildParam(WrkMast wrkMast, List wrkDetls, WaitPakin waitPakin) { ErpPakinReportParam param = new ErpPakinReportParam(); param.setPalletId(resolvePalletId(wrkMast, wrkDetls)); param.setAnfme(sumAnfme(wrkDetls)); param.setLocId(wrkMast.getLocNo()); param.setWeight(sumWeight(wrkDetls)); param.setCreateTime(formatDate(resolveCreateTime(wrkMast))); param.setBizNo(resolveBizNo(wrkDetls, waitPakin)); param.setStartTime(formatDate(resolveStartTime(wrkMast, waitPakin))); return param; } private String resolvePalletId(WrkMast wrkMast, List wrkDetls) { if (!Cools.isEmpty(wrkMast.getBarcode())) { return wrkMast.getBarcode(); } for (WrkDetl wrkDetl : wrkDetls) { if (!Cools.isEmpty(wrkDetl.getZpallet())) { return wrkDetl.getZpallet(); } } return null; } private Double sumAnfme(List wrkDetls) { double total = 0D; for (WrkDetl wrkDetl : wrkDetls) { if (!Cools.isEmpty(wrkDetl.getAnfme())) { total += wrkDetl.getAnfme(); } } return total; } private Double sumWeight(List wrkDetls) { double total = 0D; for (WrkDetl wrkDetl : wrkDetls) { if (Cools.isEmpty(wrkDetl.getWeight())) { continue; } double qty = Cools.isEmpty(wrkDetl.getAnfme()) ? 1D : wrkDetl.getAnfme(); total += wrkDetl.getWeight() * qty; } return total; } private Date resolveCreateTime(WrkMast wrkMast) { if (!Cools.isEmpty(wrkMast.getCrnEndTime())) { return wrkMast.getCrnEndTime(); } if (!Cools.isEmpty(wrkMast.getModiTime())) { return wrkMast.getModiTime(); } if (!Cools.isEmpty(wrkMast.getIoTime())) { return wrkMast.getIoTime(); } return new Date(); } private String resolveBizNo(List wrkDetls, WaitPakin waitPakin) { for (WrkDetl wrkDetl : wrkDetls) { if (!Cools.isEmpty(wrkDetl.getThreeCode())) { return wrkDetl.getThreeCode(); } } return waitPakin == null ? null : waitPakin.getThreeCode(); } private Date resolveStartTime(WrkMast wrkMast, WaitPakin waitPakin) { if (waitPakin != null && !Cools.isEmpty(waitPakin.getAppeTime())) { return waitPakin.getAppeTime(); } if (!Cools.isEmpty(wrkMast.getAppeTime())) { return wrkMast.getAppeTime(); } if (!Cools.isEmpty(wrkMast.getIoTime())) { return wrkMast.getIoTime(); } return new Date(); } private String formatDate(Date date) { if (date == null) { return null; } return new SimpleDateFormat(DATE_TIME_PATTERN).format(date); } private boolean isErpReportSuccess(String response) { if (Cools.isEmpty(response)) { return false; } try { JSONObject jsonObject = JSON.parseObject(response); if (jsonObject == null) { return false; } Boolean success = jsonObject.getBoolean("success"); if (success != null) { return success; } Integer code = jsonObject.getInteger("code"); if (code != null) { return code == 200 || code == 0; } Integer status = jsonObject.getInteger("status"); if (status != null) { return status == 200 || status == 0; } String result = jsonObject.getString("result"); if (!Cools.isEmpty(result)) { return "success".equalsIgnoreCase(result) || "ok".equalsIgnoreCase(result) || "true".equalsIgnoreCase(result); } } catch (Exception ignore) { return response.toLowerCase().contains("success") && response.toLowerCase().contains("true"); } return false; } private String extractErrorMsg(String response) { if (Cools.isEmpty(response)) { return "empty erp response"; } try { JSONObject jsonObject = JSON.parseObject(response); if (jsonObject == null) { return response; } String[] keys = new String[]{"msg", "message", "error", "errMsg"}; for (String key : keys) { String value = jsonObject.getString(key); if (!Cools.isEmpty(value)) { return value; } } } catch (Exception ignore) { } return response; } private int getRetryTimes(WrkMast wrkMast) { if (wrkMast.getExpTime() == null) { return 0; } return wrkMast.getExpTime().intValue(); } private void finishReport(WrkMast wrkMast, boolean success, int currentRetryTimes, String errorMsg, boolean countCurrentAttempt) { int retryTimes = currentRetryTimes + (countCurrentAttempt ? 1 : 0); Date now = new Date(); wrkMast.setExpTime((double) retryTimes); wrkMast.setModiTime(now); if (success) { wrkMast.setWrkSts(ERP_REPORT_FINISHED_WRK_STS); wrkMast.setLogMk(ERP_REPORT_SUCCESS_FLAG); wrkMast.setLogErrMemo(null); wrkMast.setLogErrTime(null); } else { wrkMast.setLogErrMemo(truncate(errorMsg, 500)); wrkMast.setLogErrTime(now); if (retryTimes >= ERP_REPORT_MAX_RETRY_TIMES || !countCurrentAttempt) { wrkMast.setWrkSts(ERP_REPORT_FINISHED_WRK_STS); wrkMast.setLogMk(ERP_REPORT_FAIL_FLAG); } else { wrkMast.setWrkSts(ERP_REPORT_PENDING_WRK_STS); wrkMast.setLogMk(ERP_REPORT_PENDING_FLAG); } } if (!wrkMastService.updateById(wrkMast)) { throw new IllegalStateException("update erp report status failed, workNo=" + wrkMast.getWrkNo()); } } private String truncate(String message, int maxLength) { if (message == null || message.length() <= maxLength) { return message; } return message.substring(0, maxLength); } private String buildRequestUrl() { if (Cools.isEmpty(erpUrl)) { return erpInAddress; } if (erpInAddress == null) { return erpUrl; } if (erpUrl.endsWith("/") && erpInAddress.startsWith("/")) { return erpUrl + erpInAddress.substring(1); } if (!erpUrl.endsWith("/") && !erpInAddress.startsWith("/")) { return erpUrl + "/" + erpInAddress; } return erpUrl + erpInAddress; } }