package com.zy.asrs.task.handler; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.core.common.Cools; import com.zy.asrs.entity.WrkDetl; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.entity.param.ErpPakoutReportParam; import com.zy.asrs.service.ApiLogService; 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 WorkOutErpReportHandler extends AbstractHandler { public static final long ERP_REPORT_PENDING_WRK_STS = 17L; public static final long ERP_REPORT_FINISHED_WRK_STS = 15L; 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 ApiLogService apiLogService; @Value("${erp.switch.ErpReportOld}") private boolean erpReportOld; @Value("${erp.address.URL}") private String erpUrl; @Value("${erp.address.Outaddress}") private String erpOutAddress; @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"); } ErpPakoutReportParam param = buildParam(wrkMast); String request = JSON.toJSONString(param); String response = ""; boolean success = false; String errorMsg = null; String requestUrl = buildRequestUrl(); try { response = new HttpHandler.Builder() .setUri(erpUrl) .setPath(erpOutAddress) .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( "Outbound ERP Report", requestUrl, null, "127.0.0.1", request, response, success, "workNo=" + wrkMast.getWrkNo() ); } catch (Exception logEx) { log.error("save outbound 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 ErpPakoutReportParam buildParam(WrkMast wrkMast) { ErpPakoutReportParam param = new ErpPakoutReportParam(); param.setPalletId(resolvePalletId(wrkMast)); param.setCreateTime(formatDate(resolveCreateTime(wrkMast))); param.setStartTime(formatDate(resolveStartTime(wrkMast))); return param; } private String resolvePalletId(WrkMast wrkMast) { if (!Cools.isEmpty(wrkMast.getBarcode())) { return wrkMast.getBarcode(); } List wrkDetls = wrkDetlService.selectByWrkNo(wrkMast.getWrkNo()); for (WrkDetl wrkDetl : wrkDetls) { if (!Cools.isEmpty(wrkDetl.getZpallet())) { return wrkDetl.getZpallet(); } } return null; } 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 Date resolveStartTime(WrkMast wrkMast) { if (!Cools.isEmpty(wrkMast.getCrnStrTime())) { return wrkMast.getCrnStrTime(); } if (!Cools.isEmpty(wrkMast.getPlcStrTime())) { return wrkMast.getPlcStrTime(); } 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 outbound 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 erpOutAddress; } if (erpOutAddress == null) { return erpUrl; } if (erpUrl.endsWith("/") && erpOutAddress.startsWith("/")) { return erpUrl + erpOutAddress.substring(1); } if (!erpUrl.endsWith("/") && !erpOutAddress.startsWith("/")) { return erpUrl + "/" + erpOutAddress; } return erpUrl + erpOutAddress; } }