| | |
| | | import com.zy.asrs.task.core.ReturnT; |
| | | import com.zy.common.entity.Parameter; |
| | | import com.zy.common.utils.HttpHandler; |
| | | import com.zy.integration.iot.biz.IotInstructionService; |
| | | 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.math.BigDecimal; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | |
| | | 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"; |
| | | public static final String ERP_REPORT_SKIPPED_FLAG = "S"; |
| | | |
| | | private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; |
| | | |
| | |
| | | private WaitPakinService waitPakinService; |
| | | @Autowired |
| | | private ApiLogService apiLogService; |
| | | @Autowired |
| | | private IotInstructionService iotInstructionService; |
| | | |
| | | @Value("${erp.switch.ErpReportOld}") |
| | | private boolean erpReportOld; |
| | |
| | | return SUCCESS; |
| | | } |
| | | |
| | | // 历史/运行中数据可能已经在完工时被置为 ERP 待上报。 |
| | | // 调度器执行前再做一次来源判断,确保 MQTT 来源任务即使已进入待上报状态,也会被改回完成态并跳过 ERP HTTP 调用。 |
| | | if (iotInstructionService.isMqttOriginWork(wrkMast)) { |
| | | skipReport(wrkMast); |
| | | return SUCCESS; |
| | | } |
| | | |
| | | if (!isErpReportEnabled()) { |
| | | finishReport(wrkMast, false, getRetryTimes(wrkMast), "ERP reporting is disabled", false); |
| | | return FAIL.setMsg("ERP reporting is disabled"); |
| | |
| | | |
| | | WaitPakin waitPakin = findWaitPakin(wrkMast.getBarcode()); |
| | | ErpPakinReportParam param = buildParam(wrkMast, wrkDetls, waitPakin); |
| | | |
| | | // 庫位轉換 |
| | | String locId = param.getLocId(); |
| | | String row = locId.substring(0, 2); |
| | | String col = locId.substring(2, 5); |
| | | String lev = locId.substring(5, 7); |
| | | if(Integer.parseInt(row) >= 37) { |
| | | row = "C" + row; |
| | | } else if(Integer.parseInt(row) >= 13) { |
| | | row = "B" + row; |
| | | } else { |
| | | row = "A" + row; |
| | | } |
| | | String newLocId = row + "-" + col + "-" + lev; |
| | | param.setLocId(newLocId); |
| | | |
| | | String request = JSON.toJSONString(param); |
| | | String response = ""; |
| | | boolean success = false; |
| | |
| | | param.setPalletId(resolvePalletId(wrkMast, wrkDetls)); |
| | | param.setAnfme(sumAnfme(wrkDetls)); |
| | | param.setLocId(wrkMast.getLocNo()); |
| | | param.setWeight(sumWeight(wrkDetls)); |
| | | // param.setWeight(sumWeight(wrkDetls)); |
| | | param.setWeight(adjustErpReportWeight(wrkMast.getScWeight())); |
| | | param.setCreateTime(formatDate(resolveCreateTime(wrkMast))); |
| | | param.setBizNo(resolveBizNo(wrkDetls, waitPakin)); |
| | | param.setStartTime(formatDate(resolveStartTime(wrkMast, waitPakin))); |
| | | param.setPhotos(wrkDetls.get(0).getPic()); |
| | | return param; |
| | | } |
| | | |
| | | /** 上报 ERP 重量:≤20 传 0,>20 减 10 */ |
| | | private static BigDecimal adjustErpReportWeight(BigDecimal scWeight) { |
| | | BigDecimal base = scWeight == null ? BigDecimal.ZERO : scWeight; |
| | | if (base.compareTo(new BigDecimal("20")) <= 0) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | return base.subtract(new BigDecimal("20.8")); |
| | | // BigDecimal v = base.subtract(new BigDecimal("10")); |
| | | // return v.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : v; |
| | | } |
| | | private String resolvePalletId(WrkMast wrkMast, List<WrkDetl> wrkDetls) { |
| | | if (!Cools.isEmpty(wrkMast.getBarcode())) { |
| | | return wrkMast.getBarcode(); |
| | |
| | | return total; |
| | | } |
| | | |
| | | private Double sumWeight(List<WrkDetl> 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 Double sumWeight(List<WrkDetl> 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(); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | private void skipReport(WrkMast wrkMast) { |
| | | Date now = new Date(); |
| | | wrkMast.setWrkSts(ERP_REPORT_FINISHED_WRK_STS); |
| | | wrkMast.setLogMk(ERP_REPORT_SKIPPED_FLAG); |
| | | wrkMast.setExpTime(0D); |
| | | wrkMast.setLogErrMemo(null); |
| | | wrkMast.setLogErrTime(null); |
| | | wrkMast.setModiTime(now); |
| | | if (!wrkMastService.updateById(wrkMast)) { |
| | | throw new IllegalStateException("skip inbound erp report failed, workNo=" + wrkMast.getWrkNo()); |
| | | } |
| | | // 兼容已进入 ERP 待上报的旧任务:跳过 ERP 后补一次 MQTT 完工入队,已有记录时 queueWorkCompletion 会直接返回。 |
| | | iotInstructionService.queueWorkCompletion(wrkMast); |
| | | } |
| | | |
| | | private String truncate(String message, int maxLength) { |
| | | if (message == null || message.length() <= maxLength) { |
| | | return message; |