|
|
@ -2235,6 +2235,11 @@ public class CoDelServiceImpl implements CoDelService { |
|
|
.filter(Objects::nonNull) // 防止空指针 |
|
|
.filter(Objects::nonNull) // 防止空指针 |
|
|
.reduce(0, Integer::sum); |
|
|
.reduce(0, Integer::sum); |
|
|
defaultData.setPackageQty(totalPlt); |
|
|
defaultData.setPackageQty(totalPlt); |
|
|
|
|
|
defaultData.setPalletWeight(palletHeaderDataList.stream() |
|
|
|
|
|
.map(EcssCoDelPalletHeaderData::getWeight) |
|
|
|
|
|
.filter(Objects::nonNull) // 防止空指针 |
|
|
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add)); |
|
|
|
|
|
defaultData.setAllWeight(defaultData.getGrossWeight().add(defaultData.getPalletWeight())); |
|
|
List<Map> boxList = coDelMapper.exportCoDelBoxList(notifyHeaderData); |
|
|
List<Map> boxList = coDelMapper.exportCoDelBoxList(notifyHeaderData); |
|
|
// 检查box_qty是否存在null或0 |
|
|
// 检查box_qty是否存在null或0 |
|
|
for (Map box : boxList) { |
|
|
for (Map box : boxList) { |
|
|
@ -4732,6 +4737,12 @@ public class CoDelServiceImpl implements CoDelService { |
|
|
log.info("=== 开始调整总毛重 ==="); |
|
|
log.info("=== 开始调整总毛重 ==="); |
|
|
log.info("发货单号: {}, 实际总毛重: {}", delNo, actualGrossWeightObj); |
|
|
log.info("发货单号: {}, 实际总毛重: {}", delNo, actualGrossWeightObj); |
|
|
|
|
|
|
|
|
|
|
|
// 获取发货通知单信息 |
|
|
|
|
|
EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(site, delNo); |
|
|
|
|
|
|
|
|
|
|
|
// 检查发货通知单状态是否为已报关 |
|
|
|
|
|
boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus()); |
|
|
|
|
|
|
|
|
// 转换实际总毛重为BigDecimal |
|
|
// 转换实际总毛重为BigDecimal |
|
|
BigDecimal actualTotalGrossWeight; |
|
|
BigDecimal actualTotalGrossWeight; |
|
|
if (actualGrossWeightObj instanceof Number) { |
|
|
if (actualGrossWeightObj instanceof Number) { |
|
|
@ -4751,6 +4762,15 @@ public class CoDelServiceImpl implements CoDelService { |
|
|
queryData.setDelNo(delNo); |
|
|
queryData.setDelNo(delNo); |
|
|
List<Map> boxList = coDelMapper.selectBoxList(queryData); |
|
|
List<Map> boxList = coDelMapper.selectBoxList(queryData); |
|
|
|
|
|
|
|
|
|
|
|
// 如果状态为已报关,保存调整前的箱数据用于邮件对比 |
|
|
|
|
|
List<Map> oldBoxList = null; |
|
|
|
|
|
if (isCustomsCleared) { |
|
|
|
|
|
oldBoxList = new ArrayList<>(); |
|
|
|
|
|
for (Map box : boxList) { |
|
|
|
|
|
oldBoxList.add(new HashMap<>(box)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (boxList == null || boxList.isEmpty()) { |
|
|
if (boxList == null || boxList.isEmpty()) { |
|
|
throw new RuntimeException("未找到箱数据"); |
|
|
throw new RuntimeException("未找到箱数据"); |
|
|
} |
|
|
} |
|
|
@ -4847,6 +4867,36 @@ public class CoDelServiceImpl implements CoDelService { |
|
|
if (difference.compareTo(new BigDecimal("0.001")) > 0) { |
|
|
if (difference.compareTo(new BigDecimal("0.001")) > 0) { |
|
|
log.warn("警告:调整后总毛重与目标值存在误差: {}", difference); |
|
|
log.warn("警告:调整后总毛重与目标值存在误差: {}", difference); |
|
|
} |
|
|
} |
|
|
|
|
|
if (isCustomsCleared) { |
|
|
|
|
|
log.info("装箱数据删除:发货通知单{}状态为已报关,开始删除对应的报关单", delNo); |
|
|
|
|
|
|
|
|
|
|
|
// 查找对应的报关单 |
|
|
|
|
|
EcssDeclarationHeaderData declarationQuery = new EcssDeclarationHeaderData(); |
|
|
|
|
|
declarationQuery.setSite(site); |
|
|
|
|
|
declarationQuery.setDelNo(delNo); |
|
|
|
|
|
|
|
|
|
|
|
List<EcssDeclarationHeaderData> deletedDeclarations = coDelMapper.searchDeclarationHeader( |
|
|
|
|
|
new Page<EcssDeclarationHeaderData>(1, 1000), declarationQuery).getRecords(); |
|
|
|
|
|
|
|
|
|
|
|
// 删除找到的报关单 |
|
|
|
|
|
for (EcssDeclarationHeaderData declaration : deletedDeclarations) { |
|
|
|
|
|
log.info("删除报关单,报关单号:{}", declaration.getDeclarationNo()); |
|
|
|
|
|
coDelMapper.deleteDeclarationHeader(declaration); |
|
|
|
|
|
coDelMapper.deleteDeclarationDetail(declaration); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
log.info("已删除发货通知单{}对应的{}个报关单", delNo, deletedDeclarations.size()); |
|
|
|
|
|
|
|
|
|
|
|
// 将通知单状态更新为仓库已确认 |
|
|
|
|
|
notifyHeader.setNotifyStatus("仓库已确认"); |
|
|
|
|
|
coDelMapper.changeEcssDelStatus(notifyHeader); |
|
|
|
|
|
|
|
|
|
|
|
log.info("发货通知单{}状态已更新为仓库已确认", delNo); |
|
|
|
|
|
} |
|
|
|
|
|
// 如果状态为已报关,发送邮件通知创建人 |
|
|
|
|
|
if (isCustomsCleared) { |
|
|
|
|
|
sendGrossWeightAdjustmentNotificationEmail(notifyHeader, oldBoxList, newBoxDataList, actualTotalGrossWeight, updateBy); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -6317,7 +6367,6 @@ public class CoDelServiceImpl implements CoDelService { |
|
|
emailContent.append("<tr><td style='width: 150px;'>发货通知单号</td><td>").append(notifyHeader.getDelNo()).append("</td></tr>"); |
|
|
emailContent.append("<tr><td style='width: 150px;'>发货通知单号</td><td>").append(notifyHeader.getDelNo()).append("</td></tr>"); |
|
|
emailContent.append("<tr><td>发票号</td><td>").append(notifyHeader.getCmcInvoice() != null ? notifyHeader.getCmcInvoice() : "").append("</td></tr>"); |
|
|
emailContent.append("<tr><td>发票号</td><td>").append(notifyHeader.getCmcInvoice() != null ? notifyHeader.getCmcInvoice() : "").append("</td></tr>"); |
|
|
emailContent.append("<tr><td>客户</td><td>").append(notifyHeader.getCustomerName() != null ? notifyHeader.getCustomerName() : "").append("</td></tr>"); |
|
|
emailContent.append("<tr><td>客户</td><td>").append(notifyHeader.getCustomerName() != null ? notifyHeader.getCustomerName() : "").append("</td></tr>"); |
|
|
emailContent.append("<tr><td>原状态</td><td style='color: red;'>"+(notifyHeader.getNotifyStatus())+"</td></tr>"); |
|
|
|
|
|
emailContent.append("<tr><td>当前状态</td><td style='color: green;'>仓库已确认</td></tr>"); |
|
|
emailContent.append("<tr><td>当前状态</td><td style='color: green;'>仓库已确认</td></tr>"); |
|
|
emailContent.append("</table>"); |
|
|
emailContent.append("</table>"); |
|
|
|
|
|
|
|
|
@ -6807,6 +6856,205 @@ public class CoDelServiceImpl implements CoDelService { |
|
|
coDelMapper.updatePartPackageNo(updateParams); |
|
|
coDelMapper.updatePartPackageNo(updateParams); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 发送总毛重调整通知邮件 |
|
|
|
|
|
* |
|
|
|
|
|
* @param notifyHeader 发货通知单头数据 |
|
|
|
|
|
* @param oldBoxList 调整前的箱子列表 |
|
|
|
|
|
* @param newBoxList 调整后的箱子列表 |
|
|
|
|
|
* @param targetGrossWeight 目标总毛重 |
|
|
|
|
|
* @param updateBy 操作人 |
|
|
|
|
|
* @author AI Assistant |
|
|
|
|
|
* @date 2024-12-09 |
|
|
|
|
|
*/ |
|
|
|
|
|
private void sendGrossWeightAdjustmentNotificationEmail(EcssCoDelNotifyHeaderData notifyHeader, |
|
|
|
|
|
List<Map> oldBoxList, |
|
|
|
|
|
List<Map<String, Object>> newBoxList, |
|
|
|
|
|
BigDecimal targetGrossWeight, |
|
|
|
|
|
String updateBy) { |
|
|
|
|
|
try { |
|
|
|
|
|
log.info("开始发送总毛重调整通知邮件,发货通知单号:{}", notifyHeader.getDelNo()); |
|
|
|
|
|
|
|
|
|
|
|
// 生成邮件内容 |
|
|
|
|
|
String emailContent = generateGrossWeightAdjustmentEmailContent( |
|
|
|
|
|
notifyHeader, oldBoxList, newBoxList, targetGrossWeight, updateBy); |
|
|
|
|
|
|
|
|
|
|
|
// 获取发货通知单创建人邮箱 |
|
|
|
|
|
SysUserEntity creator = coDelMapper.queryByUserName(notifyHeader.getCreateBy()); |
|
|
|
|
|
if (creator == null || StringUtils.isBlank(creator.getEmail())) { |
|
|
|
|
|
log.warn("发货通知单创建人{}不存在或没有配置邮箱地址", notifyHeader.getCreateBy()); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
String creatorEmail = creator.getEmail(); |
|
|
|
|
|
|
|
|
|
|
|
// 发送邮件 |
|
|
|
|
|
String subject = String.format("发货通知单%s【发票:%s】总毛重调整通知", |
|
|
|
|
|
notifyHeader.getDelNo(), notifyHeader.getCmcInvoice()); |
|
|
|
|
|
String[] mailAddress = {creatorEmail}; |
|
|
|
|
|
|
|
|
|
|
|
sendMailUtil(subject, emailContent, mailAddress, notifyHeader); |
|
|
|
|
|
|
|
|
|
|
|
log.info("总毛重调整通知邮件发送成功,收件人:{}", creatorEmail); |
|
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("发送总毛重调整通知邮件失败,发货通知单号:{}, 错误信息:{}", |
|
|
|
|
|
notifyHeader.getDelNo(), e.getMessage(), e); |
|
|
|
|
|
// 邮件发送失败不影响主流程,只记录日志 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 生成总毛重调整邮件内容 |
|
|
|
|
|
* |
|
|
|
|
|
* @param notifyHeader 发货通知单头数据 |
|
|
|
|
|
* @param oldBoxList 调整前的箱子列表 |
|
|
|
|
|
* @param newBoxList 调整后的箱子列表 |
|
|
|
|
|
* @param targetGrossWeight 目标总毛重 |
|
|
|
|
|
* @param updateBy 操作人 |
|
|
|
|
|
* @return HTML格式的邮件内容 |
|
|
|
|
|
*/ |
|
|
|
|
|
private String generateGrossWeightAdjustmentEmailContent(EcssCoDelNotifyHeaderData notifyHeader, |
|
|
|
|
|
List<Map> oldBoxList, |
|
|
|
|
|
List<Map<String, Object>> newBoxList, |
|
|
|
|
|
BigDecimal targetGrossWeight, |
|
|
|
|
|
String updateBy) { |
|
|
|
|
|
StringBuilder emailContent = new StringBuilder(); |
|
|
|
|
|
|
|
|
|
|
|
emailContent.append("<!DOCTYPE html>"); |
|
|
|
|
|
emailContent.append("<html>"); |
|
|
|
|
|
emailContent.append("<head>"); |
|
|
|
|
|
emailContent.append("<meta charset='UTF-8'>"); |
|
|
|
|
|
emailContent.append("<style>"); |
|
|
|
|
|
emailContent.append("body { font-family: Arial, sans-serif; margin: 20px; }"); |
|
|
|
|
|
emailContent.append("table { border-collapse: collapse; width: 100%; margin: 10px 0; }"); |
|
|
|
|
|
emailContent.append("th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }"); |
|
|
|
|
|
emailContent.append("th { background-color: #f2f2f2; font-weight: bold; }"); |
|
|
|
|
|
emailContent.append(".changed { color: red; font-weight: bold; }"); |
|
|
|
|
|
emailContent.append(".info { color: #0066cc; font-size: 14px; margin: 15px 0; padding: 10px; background-color: #e6f2ff; border-left: 4px solid #0066cc; }"); |
|
|
|
|
|
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }"); |
|
|
|
|
|
emailContent.append(".summary { color: #333; font-size: 14px; margin: 10px 0; padding: 10px; background-color: #f9f9f9; }"); |
|
|
|
|
|
emailContent.append("</style>"); |
|
|
|
|
|
emailContent.append("</head>"); |
|
|
|
|
|
emailContent.append("<body>"); |
|
|
|
|
|
|
|
|
|
|
|
// 邮件标题 |
|
|
|
|
|
emailContent.append("<h2>发货通知单总毛重调整通知</h2>"); |
|
|
|
|
|
|
|
|
|
|
|
// 发货通知单基本信息 |
|
|
|
|
|
emailContent.append("<div class='section-title'>一、发货通知单信息</div>"); |
|
|
|
|
|
emailContent.append("<table>"); |
|
|
|
|
|
emailContent.append("<tr><td style='width: 150px;'>发货通知单号</td><td>").append(notifyHeader.getDelNo()).append("</td></tr>"); |
|
|
|
|
|
emailContent.append("<tr><td>发票号</td><td>").append(notifyHeader.getCmcInvoice() != null ? notifyHeader.getCmcInvoice() : "").append("</td></tr>"); |
|
|
|
|
|
emailContent.append("<tr><td>客户</td><td>").append(notifyHeader.getCustomerName() != null ? notifyHeader.getCustomerName() : "").append("</td></tr>"); |
|
|
|
|
|
emailContent.append("<tr><td>当前状态</td><td>").append(notifyHeader.getNotifyStatus()).append("</td></tr>"); |
|
|
|
|
|
emailContent.append("<tr><td>操作人</td><td>").append(updateBy).append("</td></tr>"); |
|
|
|
|
|
emailContent.append("</table>"); |
|
|
|
|
|
|
|
|
|
|
|
// 计算总毛重变化 |
|
|
|
|
|
BigDecimal oldTotalGrossWeight = BigDecimal.ZERO; |
|
|
|
|
|
BigDecimal newTotalGrossWeight = BigDecimal.ZERO; |
|
|
|
|
|
|
|
|
|
|
|
for (Map box : oldBoxList) { |
|
|
|
|
|
Object grossWeightObj = box.get("grossWeight"); |
|
|
|
|
|
if (grossWeightObj != null) { |
|
|
|
|
|
BigDecimal grossWeight = new BigDecimal(grossWeightObj.toString()); |
|
|
|
|
|
oldTotalGrossWeight = oldTotalGrossWeight.add(grossWeight); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (Map box : newBoxList) { |
|
|
|
|
|
Object grossWeightObj = box.get("grossWeight"); |
|
|
|
|
|
if (grossWeightObj != null) { |
|
|
|
|
|
BigDecimal grossWeight = new BigDecimal(grossWeightObj.toString()); |
|
|
|
|
|
newTotalGrossWeight = newTotalGrossWeight.add(grossWeight); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 总毛重调整汇总 |
|
|
|
|
|
emailContent.append("<div class='section-title'>二、总毛重调整汇总</div>"); |
|
|
|
|
|
emailContent.append("<div class='summary'>"); |
|
|
|
|
|
emailContent.append("<p><strong>调整前总毛重:</strong>").append(oldTotalGrossWeight.setScale(3, RoundingMode.HALF_UP)).append(" KG</p>"); |
|
|
|
|
|
emailContent.append("<p><strong>调整后总毛重:</strong><span class='changed'>").append(newTotalGrossWeight.setScale(3, RoundingMode.HALF_UP)).append(" KG</span></p>"); |
|
|
|
|
|
emailContent.append("</p>"); |
|
|
|
|
|
emailContent.append("</div>"); |
|
|
|
|
|
|
|
|
|
|
|
// 箱子详细变化信息 |
|
|
|
|
|
emailContent.append("<div class='section-title'>三、箱子重量调整明细</div>"); |
|
|
|
|
|
emailContent.append("<table>"); |
|
|
|
|
|
emailContent.append("<tr>"); |
|
|
|
|
|
emailContent.append("<th>箱号</th>"); |
|
|
|
|
|
emailContent.append("<th>箱数</th>"); |
|
|
|
|
|
emailContent.append("<th>调整前毛重(KG)</th>"); |
|
|
|
|
|
emailContent.append("<th>调整后毛重(KG)</th>"); |
|
|
|
|
|
emailContent.append("<th>调整后净重(KG)</th>"); |
|
|
|
|
|
emailContent.append("<th>毛重变化</th>"); |
|
|
|
|
|
emailContent.append("</tr>"); |
|
|
|
|
|
|
|
|
|
|
|
// 创建箱号到旧数据的映射 |
|
|
|
|
|
Map<String, Map> oldBoxMap = new HashMap<>(); |
|
|
|
|
|
for (Map oldBox : oldBoxList) { |
|
|
|
|
|
String itemNo = oldBox.get("item_no") != null ? oldBox.get("item_no").toString() : ""; |
|
|
|
|
|
oldBoxMap.put(itemNo, oldBox); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (Map newBox : newBoxList) { |
|
|
|
|
|
String itemNo = newBox.get("item_no") != null ? newBox.get("item_no").toString() : ""; |
|
|
|
|
|
Map oldBox = oldBoxMap.get(itemNo); |
|
|
|
|
|
|
|
|
|
|
|
emailContent.append("<tr>"); |
|
|
|
|
|
emailContent.append("<td>").append(itemNo).append("</td>"); |
|
|
|
|
|
emailContent.append("<td>").append(newBox.get("box_qty") != null ? newBox.get("box_qty").toString() : "0").append("</td>"); |
|
|
|
|
|
|
|
|
|
|
|
// 旧毛重 |
|
|
|
|
|
BigDecimal oldGrossWeight = BigDecimal.ZERO; |
|
|
|
|
|
if (oldBox != null && oldBox.get("grossWeight") != null) { |
|
|
|
|
|
oldGrossWeight = new BigDecimal(oldBox.get("grossWeight").toString()); |
|
|
|
|
|
} |
|
|
|
|
|
emailContent.append("<td>").append(oldGrossWeight.setScale(3, RoundingMode.HALF_UP)).append("</td>"); |
|
|
|
|
|
|
|
|
|
|
|
// 新毛重 |
|
|
|
|
|
BigDecimal newGrossWeight = BigDecimal.ZERO; |
|
|
|
|
|
if (newBox.get("grossWeight") != null) { |
|
|
|
|
|
newGrossWeight = new BigDecimal(newBox.get("grossWeight").toString()); |
|
|
|
|
|
} |
|
|
|
|
|
emailContent.append("<td class='changed'>").append(newGrossWeight.setScale(3, RoundingMode.HALF_UP)).append("</td>"); |
|
|
|
|
|
|
|
|
|
|
|
// 新净重 |
|
|
|
|
|
BigDecimal newNetWeight = BigDecimal.ZERO; |
|
|
|
|
|
if (newBox.get("netWeight") != null) { |
|
|
|
|
|
newNetWeight = new BigDecimal(newBox.get("netWeight").toString()); |
|
|
|
|
|
} |
|
|
|
|
|
emailContent.append("<td class='changed'>").append(newNetWeight.setScale(3, RoundingMode.HALF_UP)).append("</td>"); |
|
|
|
|
|
|
|
|
|
|
|
// 毛重变化 |
|
|
|
|
|
BigDecimal weightChange = newGrossWeight.subtract(oldGrossWeight); |
|
|
|
|
|
emailContent.append("<td class='changed'>"); |
|
|
|
|
|
if (weightChange.compareTo(BigDecimal.ZERO) > 0) { |
|
|
|
|
|
emailContent.append("+"); |
|
|
|
|
|
} |
|
|
|
|
|
emailContent.append(weightChange.setScale(3, RoundingMode.HALF_UP)).append("</td>"); |
|
|
|
|
|
|
|
|
|
|
|
emailContent.append("</tr>"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
emailContent.append("</table>"); |
|
|
|
|
|
|
|
|
|
|
|
// 注意事项 |
|
|
|
|
|
emailContent.append("<div class='info'>"); |
|
|
|
|
|
emailContent.append("⚠️ <strong>注意事项:</strong>"); |
|
|
|
|
|
emailContent.append("<ul style='margin: 5px 0;'>"); |
|
|
|
|
|
emailContent.append("<li>此操作已自动按比例调整所有箱的毛重和净重</li>"); |
|
|
|
|
|
emailContent.append("<li>净重计算公式:净重 = 毛重 - (箱数 / 2)</li>"); |
|
|
|
|
|
emailContent.append("<li>如有疑问,请及时联系仓库或相关负责人确认</li>"); |
|
|
|
|
|
emailContent.append("</ul>"); |
|
|
|
|
|
emailContent.append("</div>"); |
|
|
|
|
|
|
|
|
|
|
|
emailContent.append("</body>"); |
|
|
|
|
|
emailContent.append("</html>"); |
|
|
|
|
|
|
|
|
|
|
|
return emailContent.toString(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 获取单元格值为字符串 |
|
|
* 获取单元格值为字符串 |
|
|
*/ |
|
|
*/ |
|
|
|