Browse Source

总毛重调整

java8
han\hanst 1 month ago
parent
commit
e110e6a75d
  1. 18
      src/main/java/com/xujie/sys/modules/ecss/controller/CoDelController.java
  2. 6
      src/main/java/com/xujie/sys/modules/ecss/service/CoDelService.java
  3. 149
      src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java

18
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<String, Object> 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,

6
src/main/java/com/xujie/sys/modules/ecss/service/CoDelService.java

@ -76,6 +76,12 @@ public interface CoDelService {
*/
void batchUpdatePackingInfo(Map<String, Object> batchData);
/**
* 调整总毛重 - 按原毛重比例重新分配所有箱的毛重和净重
* @param adjustData 包含site, buNo, delNo, actualGrossWeight, updateBy
*/
void adjustTotalGrossWeight(Map<String, Object> adjustData);
//void deleteEmptyBoxAfterDetailDelete(EcssCoDelPalletData detailData);
void saveCoDelPalletDataByExcel(MultipartFile file, EcssCoDelNotifyHeaderData data, String palletRecords);

149
src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java

@ -4696,6 +4696,155 @@ public class CoDelServiceImpl implements CoDelService {
}
}
/**
* 调整总毛重 - 按原毛重比例重新分配所有箱的毛重和净重
*
* <p><b>功能说明</b></p>
* <ul>
* <li>查询指定发货通知单下的所有箱数据</li>
* <li>计算当前总毛重所有箱毛重之和</li>
* <li>按照原箱毛重占总毛重的比例计算新毛重</li>
* <li>根据新毛重重新计算净重净重 = 毛重 - box_qty/2</li>
* <li>确保所有箱的新毛重总和完全等于用户输入的实际总毛重</li>
* </ul>
*
* <p><b>精度保证</b></p>
* <ul>
* <li>使用BigDecimal进行精确计算避免浮点数误差</li>
* <li>采用"最大余额法"分配误差确保总和精确相等</li>
* </ul>
*
* @param adjustData 包含site, buNo, delNo, actualGrossWeight, updateBy
*/
@Override
@Transactional
public void adjustTotalGrossWeight(Map<String, Object> 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<Map> 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<Map<String, Object>> 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<String, Object> 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<String, Object> newBoxData : newBoxDataList) {
coDelMapper.updateBoxInfo(newBoxData);
}
// 5. 验证最终总毛重
BigDecimal finalTotalGrossWeight = BigDecimal.ZERO;
for (Map<String, Object> 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);
}
}
/**
* 发送批量修改通知邮件
*

Loading…
Cancel
Save