From e110e6a75df0a7f30d1bd2e461574d76bffefc68 Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Fri, 5 Dec 2025 16:16:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=80=BB=E6=AF=9B=E9=87=8D=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ecss/controller/CoDelController.java | 18 +++ .../modules/ecss/service/CoDelService.java | 6 + .../ecss/service/impl/CoDelServiceImpl.java | 149 ++++++++++++++++++ 3 files changed, 173 insertions(+) diff --git a/src/main/java/com/xujie/sys/modules/ecss/controller/CoDelController.java b/src/main/java/com/xujie/sys/modules/ecss/controller/CoDelController.java index 623a6e40..ff6e7941 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/controller/CoDelController.java +++ b/src/main/java/com/xujie/sys/modules/ecss/controller/CoDelController.java @@ -279,6 +279,24 @@ public class CoDelController { } } + /** + * @Author System + * @Description 调整总毛重 - 按原毛重比例重新分配所有箱的毛重和净重 + * @Date 2025/12/05 + * @Param [adjustData] 包含site, buNo, delNo, actualGrossWeight, updateBy + * @return com.xujie.sys.common.utils.R + **/ + @PostMapping("/adjustTotalGrossWeight") + @ResponseBody + public R adjustTotalGrossWeight(@RequestBody Map adjustData){ + try { + coDelService.adjustTotalGrossWeight(adjustData); + return R.ok("总毛重调整成功"); + } catch (Exception e) { + return R.error("调整失败: " + e.getMessage()); + } + } + @PostMapping("/saveCoDelPalletDataByExcel") public R saveCoDelPalletDataByExcel(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "palletRecords", required = false) String palletRecords, diff --git a/src/main/java/com/xujie/sys/modules/ecss/service/CoDelService.java b/src/main/java/com/xujie/sys/modules/ecss/service/CoDelService.java index f5d5e990..a2cf3113 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/service/CoDelService.java +++ b/src/main/java/com/xujie/sys/modules/ecss/service/CoDelService.java @@ -76,6 +76,12 @@ public interface CoDelService { */ void batchUpdatePackingInfo(Map batchData); + /** + * 调整总毛重 - 按原毛重比例重新分配所有箱的毛重和净重 + * @param adjustData 包含site, buNo, delNo, actualGrossWeight, updateBy + */ + void adjustTotalGrossWeight(Map adjustData); + //void deleteEmptyBoxAfterDetailDelete(EcssCoDelPalletData detailData); void saveCoDelPalletDataByExcel(MultipartFile file, EcssCoDelNotifyHeaderData data, String palletRecords); diff --git a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java index 52a2ebae..6f046f71 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java @@ -4696,6 +4696,155 @@ public class CoDelServiceImpl implements CoDelService { } } + /** + * 调整总毛重 - 按原毛重比例重新分配所有箱的毛重和净重 + * + *

功能说明:

+ *
    + *
  • 查询指定发货通知单下的所有箱数据
  • + *
  • 计算当前总毛重(所有箱毛重之和)
  • + *
  • 按照原箱毛重占总毛重的比例计算新毛重
  • + *
  • 根据新毛重重新计算净重:净重 = 毛重 - box_qty/2
  • + *
  • 确保所有箱的新毛重总和完全等于用户输入的实际总毛重
  • + *
+ * + *

精度保证:

+ *
    + *
  • 使用BigDecimal进行精确计算,避免浮点数误差
  • + *
  • 采用"最大余额法"分配误差,确保总和精确相等
  • + *
+ * + * @param adjustData 包含site, buNo, delNo, actualGrossWeight, updateBy + */ + @Override + @Transactional + public void adjustTotalGrossWeight(Map adjustData) { + String site = (String) adjustData.get("site"); + String buNo = (String) adjustData.get("buNo"); + String delNo = (String) adjustData.get("delNo"); + Object actualGrossWeightObj = adjustData.get("actualGrossWeight"); + String updateBy = (String) adjustData.get("updateBy"); + + log.info("=== 开始调整总毛重 ==="); + log.info("发货单号: {}, 实际总毛重: {}", delNo, actualGrossWeightObj); + + // 转换实际总毛重为BigDecimal + BigDecimal actualTotalGrossWeight; + if (actualGrossWeightObj instanceof Number) { + actualTotalGrossWeight = new BigDecimal(actualGrossWeightObj.toString()); + } else { + throw new RuntimeException("实际总毛重格式错误"); + } + + if (actualTotalGrossWeight.compareTo(BigDecimal.ZERO) <= 0) { + throw new RuntimeException("实际总毛重必须大于0"); + } + + // 1. 查询所有箱数据 + EcssCoDelNotifyHeaderData queryData = new EcssCoDelNotifyHeaderData(); + queryData.setSite(site); + queryData.setBuNo(buNo); + queryData.setDelNo(delNo); + List boxList = coDelMapper.selectBoxList(queryData); + + if (boxList == null || boxList.isEmpty()) { + throw new RuntimeException("未找到箱数据"); + } + + log.info("查询到 {} 个箱", boxList.size()); + + // 2. 计算当前总毛重 + BigDecimal currentTotalGrossWeight = BigDecimal.ZERO; + for (Map box : boxList) { + Object grossWeightObj = box.get("grossWeight"); + if (grossWeightObj != null) { + BigDecimal grossWeight = new BigDecimal(grossWeightObj.toString()); + currentTotalGrossWeight = currentTotalGrossWeight.add(grossWeight); + } + } + + if (currentTotalGrossWeight.compareTo(BigDecimal.ZERO) <= 0) { + throw new RuntimeException("当前总毛重为0,无法进行调整"); + } + + log.info("当前总毛重: {}, 实际总毛重: {}", currentTotalGrossWeight, actualTotalGrossWeight); + + // 3. 按比例计算每个箱的新毛重和净重 + List> newBoxDataList = new ArrayList<>(); + BigDecimal calculatedTotalGrossWeight = BigDecimal.ZERO; // 实际计算的总和 + + for (int i = 0; i < boxList.size(); i++) { + Map box = boxList.get(i); + + Object grossWeightObj = box.get("grossWeight"); + Object boxQtyObj = box.get("box_qty"); + + BigDecimal oldGrossWeight = grossWeightObj != null ? new BigDecimal(grossWeightObj.toString()) : BigDecimal.ZERO; + BigDecimal boxQty = boxQtyObj != null ? new BigDecimal(boxQtyObj.toString()) : BigDecimal.ZERO; + + // 计算新毛重:按比例分配 + BigDecimal newGrossWeight; + if (i == boxList.size() - 1) { + // 最后一个箱:用实际总毛重减去前面所有箱的毛重,确保总和精确相等 + newGrossWeight = actualTotalGrossWeight.subtract(calculatedTotalGrossWeight); + } else { + // 按比例计算:新毛重 = 原毛重 / 当前总毛重 * 实际总毛重 + newGrossWeight = oldGrossWeight + .multiply(actualTotalGrossWeight) + .divide(currentTotalGrossWeight, 3, RoundingMode.HALF_UP); + calculatedTotalGrossWeight = calculatedTotalGrossWeight.add(newGrossWeight); + } + + // 计算新净重:净重 = 毛重 - box_qty/2 + BigDecimal newNetWeight = newGrossWeight.subtract( + boxQty.divide(new BigDecimal("2"), 3, RoundingMode.HALF_UP) + ); + + // 构造更新数据 + Map newBoxData = new HashMap<>(); + newBoxData.put("site", site); + newBoxData.put("buNo", buNo); + newBoxData.put("delNo", delNo); + newBoxData.put("item_no", box.get("item_no")); + newBoxData.put("palletRemark", box.get("palletRemark")); + newBoxData.put("box_qty", box.get("box_qty")); + newBoxData.put("grossWeight", newGrossWeight.setScale(3, RoundingMode.HALF_UP)); + newBoxData.put("netWeight", newNetWeight.setScale(3, RoundingMode.HALF_UP)); + newBoxData.put("rolls", box.get("rolls")); + newBoxData.put("updateBy", updateBy); + + newBoxDataList.add(newBoxData); + + log.info("Box #{}: 原毛重={}, 新毛重={}, 新净重={}", + box.get("item_no"), + oldGrossWeight, + newGrossWeight.setScale(3, RoundingMode.HALF_UP), + newNetWeight.setScale(3, RoundingMode.HALF_UP)); + } + + // 4. 批量更新数据库 + for (Map newBoxData : newBoxDataList) { + coDelMapper.updateBoxInfo(newBoxData); + } + + // 5. 验证最终总毛重 + BigDecimal finalTotalGrossWeight = BigDecimal.ZERO; + for (Map newBoxData : newBoxDataList) { + finalTotalGrossWeight = finalTotalGrossWeight.add((BigDecimal) newBoxData.get("grossWeight")); + } + + log.info("=== 调整总毛重完成 ==="); + log.info("目标总毛重: {}", actualTotalGrossWeight); + log.info("实际总毛重: {}", finalTotalGrossWeight); + log.info("误差: {}", actualTotalGrossWeight.subtract(finalTotalGrossWeight).abs()); + + // 验证误差(应该为0或非常接近0) + BigDecimal difference = actualTotalGrossWeight.subtract(finalTotalGrossWeight).abs(); + if (difference.compareTo(new BigDecimal("0.001")) > 0) { + log.warn("警告:调整后总毛重与目标值存在误差: {}", difference); + } + } + /** * 发送批量修改通知邮件 *