From cfeda75ee70d47c754bbdec6b8781adc6da87b62 Mon Sep 17 00:00:00 2001 From: aike <17730485278@139.com> Date: Thu, 7 Aug 2025 09:28:01 +0800 Subject: [PATCH] =?UTF-8?q?demand:=20=20=20=20=E6=96=B0=E5=A2=9E=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=89=B9=E6=AC=A1=E8=AF=A6=E6=83=85=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?-=E4=BB=B6=E6=95=B0=E3=80=81=E9=87=8D=E9=87=8F=E3=80=81?= =?UTF-8?q?=E4=BD=93=E7=A7=AF=E6=A0=B9=E6=8D=AE=E5=8E=86=E5=8F=B2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=81=9A=E6=89=A3=E5=87=8F=20=20=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=89=AB=E6=8F=8F=E6=BC=8F=E7=BB=84=E6=89=B9=E6=AC=A1/?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=89=B9=E6=AC=A1=E5=8F=B7=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E6=BC=8F=E7=BB=84=E6=89=B9=E6=AC=A1=E5=A7=8B=E5=8F=91=E7=BD=91?= =?UTF-8?q?=E7=82=B9=E6=97=A0=E9=94=A1=E3=80=81=E5=BC=A0=E5=AE=B6=E6=B8=AF?= =?UTF-8?q?=EF=BC=8C=E5=8D=97=E4=BA=AC=E5=B8=82=E5=9C=BA=E9=83=A8=E3=80=81?= =?UTF-8?q?=E5=8D=97=E4=BA=AC=E5=88=86=E6=8B=A8=E4=B8=AD=E5=BF=83=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BA=92=E6=8D=A2=20committer:=20heyu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../emis/EmisTmsSiteBatchDtlController.java | 9 + .../service/IEmisTmsSiteBatchDtlService.java | 7 + .../impl/EmisTmsSiteBatchDtlServiceImpl.java | 181 +++++++++++++++--- 3 files changed, 173 insertions(+), 24 deletions(-) diff --git a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisTmsSiteBatchDtlController.java b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisTmsSiteBatchDtlController.java index 327bb51e5..54a127970 100644 --- a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisTmsSiteBatchDtlController.java +++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisTmsSiteBatchDtlController.java @@ -68,6 +68,15 @@ public class EmisTmsSiteBatchDtlController extends EmisBaseController return getDataTable(list); } + /** + * 查询批次详情-件数、重量体积根据历史数据做扣减 + */ +// @PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchDtl:getBatchDtl')") + @GetMapping("/getBatchDtl") + public AjaxResult getBatchDtl(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) throws EmisBizError { + return AjaxResult.success(emisTmsSiteBatchDtlService.getBatchDtl(emisTmsSiteBatchDtl)); + } + /** * 导出一级网点TMS组批次明细列表 */ diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisTmsSiteBatchDtlService.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisTmsSiteBatchDtlService.java index 48b43cfa2..a06c38428 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisTmsSiteBatchDtlService.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisTmsSiteBatchDtlService.java @@ -67,4 +67,11 @@ public interface IEmisTmsSiteBatchDtlService * @return 结果 */ public int deleteEmisTmsSiteBatchDtlById(Long id); + + /** + * + * @param emisTmsSiteBatchDtl + * @return + */ + EmisTmsSiteBatchDtl getBatchDtl(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) throws EmisBizError; } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchDtlServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchDtlServiceImpl.java index 0126679f3..5e207b355 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchDtlServiceImpl.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchDtlServiceImpl.java @@ -1,27 +1,31 @@ - /** - * @Project: emis - * @Title: EmisTmsSiteBatchDtlServiceImpl.java - * @author linfso - * @date 2024-03-01 08:54:57 - * @Copyright: ShangHai Duta 2022 All rights reserved. - * @version v1.0 - * @Description:

一级网点TMS组批次明细 实体类

- */ +/** +* @Project: emis +* @Title: EmisTmsSiteBatchDtlServiceImpl.java +* @author linfso +* @date 2024-03-01 08:54:57 +* @Copyright: ShangHai Duta 2022 All rights reserved. +* @version v1.0 +* @Description:

一级网点TMS组批次明细 实体类

+*/ package com.xdadan.erp.emis.service.impl; -import java.util.List; -import java.util.Objects; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; import cn.hutool.core.collection.CollectionUtil; import com.xdadan.erp.emis.domain.EmisTmsSiteBatch; +import com.xdadan.erp.emis.domain.EmisTransPlanRule; import com.xdadan.erp.emis.domain.EmisWaybill; import com.xdadan.erp.emis.domain.enumtype.EmisBizErrorType; import com.xdadan.erp.emis.domain.exception.EmisBizError; import com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMapper; +import com.xdadan.erp.emis.mapper.EmisTransPlanRuleMapper; import com.xdadan.erp.emis.mapper.EmisWaybillMapper; import com.xdadan.erp.emis.service.IEmisTmsSiteBatchService; import jodd.util.StringUtil; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.xdadan.erp.emis.domain.EmisTmsSiteBatchDtl; @@ -35,8 +39,7 @@ import com.xdadan.erp.emis.service.IEmisTmsSiteBatchDtlService; * @date 2024-03-01 08:54:57 */ @Service -public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlService -{ +public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlService { @Autowired private EmisTmsSiteBatchDtlMapper emisTmsSiteBatchDtlMapper; @@ -49,6 +52,9 @@ public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlServi @Autowired private IEmisTmsSiteBatchService emisTmsSiteBatchService; + @Autowired + private EmisTransPlanRuleMapper emisTransPlanRuleMapper; + /** * 查询一级网点TMS组批次明细 * @@ -56,8 +62,7 @@ public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlServi * @return 一级网点TMS组批次明细 */ @Override - public EmisTmsSiteBatchDtl selectEmisTmsSiteBatchDtlById(Long id) - { + public EmisTmsSiteBatchDtl selectEmisTmsSiteBatchDtlById(Long id) { return emisTmsSiteBatchDtlMapper.selectEmisTmsSiteBatchDtlById(id); } @@ -68,8 +73,7 @@ public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlServi * @return 一级网点TMS组批次明细 */ @Override - public List selectEmisTmsSiteBatchDtlList(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) - { + public List selectEmisTmsSiteBatchDtlList(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) { return emisTmsSiteBatchDtlMapper.selectEmisTmsSiteBatchDtlList(emisTmsSiteBatchDtl); } @@ -81,7 +85,8 @@ public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlServi */ @Override public int insertEmisTmsSiteBatchDtl(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) throws EmisBizError { - EmisTmsSiteBatch oldSiteBatch = emisTmsSiteBatchMapper.selectTmsSiteBatchByBatchNo(emisTmsSiteBatchDtl.getBatchNo()); + EmisTmsSiteBatch oldSiteBatch = emisTmsSiteBatchMapper + .selectTmsSiteBatchByBatchNo(emisTmsSiteBatchDtl.getBatchNo()); emisTmsSiteBatchService.checkSiteBatch(oldSiteBatch, emisTmsSiteBatchDtl); return emisTmsSiteBatchDtlMapper.insertEmisTmsSiteBatchDtl(emisTmsSiteBatchDtl); } @@ -93,8 +98,7 @@ public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlServi * @return 结果 */ @Override - public int updateEmisTmsSiteBatchDtl(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) - { + public int updateEmisTmsSiteBatchDtl(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) { return emisTmsSiteBatchDtlMapper.updateEmisTmsSiteBatchDtl(emisTmsSiteBatchDtl); } @@ -105,8 +109,7 @@ public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlServi * @return 结果 */ @Override - public int deleteEmisTmsSiteBatchDtlByIds(Long[] ids) - { + public int deleteEmisTmsSiteBatchDtlByIds(Long[] ids) { return emisTmsSiteBatchDtlMapper.deleteEmisTmsSiteBatchDtlByIds(ids); } @@ -117,9 +120,139 @@ public class EmisTmsSiteBatchDtlServiceImpl implements IEmisTmsSiteBatchDtlServi * @return 结果 */ @Override - public int deleteEmisTmsSiteBatchDtlById(Long id) - { + public int deleteEmisTmsSiteBatchDtlById(Long id) { return emisTmsSiteBatchDtlMapper.deleteEmisTmsSiteBatchDtlById(id); } + @Override + public EmisTmsSiteBatchDtl getBatchDtl(EmisTmsSiteBatchDtl emisTmsSiteBatchDtl) throws EmisBizError { + // 参数校验 + if (emisTmsSiteBatchDtl == null || emisTmsSiteBatchDtl.getParams() == null) { + throw new EmisBizError(EmisBizErrorType.FAIL, "参数不能为空"); + } + + String billCode = emisTmsSiteBatchDtl.getBillCode(); + String startSiteCode = (String) emisTmsSiteBatchDtl.getParams().get("startSiteCode"); + String nextSiteCode = (String) emisTmsSiteBatchDtl.getParams().get("nextSiteCode"); + String supplierCode = (String) emisTmsSiteBatchDtl.getParams().get("supplierCode"); + + // 参数校验 + if (StringUtils.isBlank(billCode)) { + throw new EmisBizError(EmisBizErrorType.FAIL, "运单号不能为空"); + } + if (StringUtils.isBlank(startSiteCode)) { + throw new EmisBizError(EmisBizErrorType.FAIL, "起始网点编码不能为空"); + } + if (StringUtils.isBlank(nextSiteCode)) { + throw new EmisBizError(EmisBizErrorType.FAIL, "下一网点编码不能为空"); + } + + // 查询运单信息 + EmisWaybill emisWaybill = emisWaybillMapper.selectEmisWaybillByBillCode(billCode); + if (emisWaybill == null) { + return null; + } + + // 创建返回结果对象 + EmisTmsSiteBatchDtl result = new EmisTmsSiteBatchDtl(); + result.setWaybillDetail(emisWaybill); + + // 查询运输计划规则 + EmisTransPlanRule emisTransPlanRule = new EmisTransPlanRule(); + emisTransPlanRule.setStartSiteCode(startSiteCode); + emisTransPlanRule.setNextSiteCode(nextSiteCode); + emisTransPlanRule.setSupplierCode(supplierCode); + emisTransPlanRule.setLineCode(emisWaybill.getTransLineType()); + emisTransPlanRule.setProductType(emisWaybill.getProductType()); + + List rules = emisTransPlanRuleMapper.checkTransPlanRule(emisTransPlanRule); + + // 根据起始网点、下一网点和运单号查询TMS组批次 + List existingBatches = emisTmsSiteBatchMapper.selectTmsSiteBatchBySiteAndBillCode( + startSiteCode, + nextSiteCode, + billCode, + null); + + // 计算运单的件数、重量、体积 + Integer waybillParcelQty = emisWaybill.getParcelQty() != null ? emisWaybill.getParcelQty() : 0; + BigDecimal waybillWeight = emisWaybill.getBillWeight() != null ? emisWaybill.getBillWeight() + : BigDecimal.ZERO; + BigDecimal waybillVolume = emisWaybill.getTotalVolume() != null ? emisWaybill.getTotalVolume() + : BigDecimal.ZERO; + + // 如果没有现有批次,直接使用运单的原始值 + if (CollectionUtil.isEmpty(existingBatches)) { + result.setBatchParcelQty(waybillParcelQty); + result.setBatchWeight(waybillWeight); + result.setBatchVolume(waybillVolume); + return result; + } + + // 检查rule.supplierCode是否包含多个供应商编码(用逗号隔开) + if (CollectionUtil.isNotEmpty(rules) && StringUtils.isNotBlank(rules.get(0).getSupplierCode()) + && rules.get(0).getSupplierCode().contains(",")) { + // 将supplierCode按逗号分割成数组 + String[] supplierCodes = rules.get(0).getSupplierCode().split(","); + List supplierCodeList = Arrays.asList(supplierCodes); + + // 检查现有批次中是否有supplierCode在rule.supplierCode内 + boolean hasMatchingSupplier = existingBatches.stream() + .anyMatch(batch -> supplierCodeList.contains(batch.getSupplierCode())); + + if (hasMatchingSupplier) { + // 找到匹配的批次,检查重量、体积、件数是否一致 + EmisTmsSiteBatch matchingBatch = existingBatches.stream() + .filter(batch -> supplierCodeList.contains(batch.getSupplierCode())) + .findFirst() + .orElse(null); + if (Objects.nonNull(matchingBatch)) { + result.setBatchParcelQty( + matchingBatch.getTotalParcelQty() != null ? matchingBatch.getTotalParcelQty() : 0); + result.setBatchWeight( + matchingBatch.getTotalWeight() != null ? matchingBatch.getTotalWeight() : BigDecimal.ZERO); + result.setBatchVolume( + matchingBatch.getTotalVolume() != null ? matchingBatch.getTotalVolume() : BigDecimal.ZERO); + return result; + } + } + } + + // 将existingBatches根据起始网点、下一网点、批次重量、件数、体积分组去重 + Map> groupedBatches = existingBatches.stream() + .filter(Objects::nonNull) // 过滤空值 + .collect(Collectors.groupingBy(batch -> { + // 构建分组键,包含所有相关字段 + BigDecimal totalWeight = batch.getTotalWeight() != null ? batch.getTotalWeight() : BigDecimal.ZERO; + Integer totalParcelQty = batch.getTotalParcelQty() != null ? batch.getTotalParcelQty() : 0; + BigDecimal totalVolume = batch.getTotalVolume() != null ? batch.getTotalVolume() : BigDecimal.ZERO; + + return batch.getStartSiteCode() + "_" + batch.getNextSiteCode() + "_" + + totalWeight + "_" + totalParcelQty + "_" + totalVolume; + })); + + // 计算去重后的批次总重量、总件数、总体积 + BigDecimal totalWeight = groupedBatches.values().stream() + .map(batchList -> batchList.get(0).getTotalWeight()) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + Integer totalParcelQty = groupedBatches.values().stream() + .map(batchList -> batchList.get(0).getTotalParcelQty()) + .filter(Objects::nonNull) + .reduce(0, Integer::sum); + + BigDecimal totalVolume = groupedBatches.values().stream() + .map(batchList -> batchList.get(0).getTotalVolume()) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 设置批次明细的件数、重量、体积(运单值减去已存在批次的总和) + result.setBatchParcelQty(Math.max(0, waybillParcelQty - totalParcelQty)); + result.setBatchWeight(waybillWeight.subtract(totalWeight).max(BigDecimal.ZERO)); + result.setBatchVolume(waybillVolume.subtract(totalVolume).max(BigDecimal.ZERO)); + + return result; + } + }