Browse Source

发票毛重净重列

java8
han\hanst 4 months ago
parent
commit
8160a429d5
  1. 1
      src/main/java/com/xujie/sys/modules/ecss/entity/EcssTemplate.java
  2. 671
      src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java
  3. 6
      src/main/resources/mapper/ecss/CoDelMapper.xml

1
src/main/java/com/xujie/sys/modules/ecss/entity/EcssTemplate.java

@ -50,6 +50,7 @@ public class EcssTemplate extends QueryPage {
private Boolean boxChange;
private String customName;
private Boolean highPalletFlag;
private Boolean showWeight;
/**
*

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

@ -1510,13 +1510,123 @@ public class CoDelServiceImpl implements CoDelService {
}
@Override
@Transactional
public void updateCodelPalletHeaderPalletQty(EcssCoDelPalletHeaderData inData) {
// 获取发货通知单信息
EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(inData.getSite(), inData.getDelNo());
// 检查发货通知单状态是否为已报关
boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus());
// 保存修改前的托数据用于邮件通知
List<EcssCoDelPalletHeaderData> oldPalletHeaderList = null;
List<EcssDeclarationHeaderData> deletedDeclarations = null;
if (isCustomsCleared) {
log.info("托数修改:发货通知单{}状态为已报关,开始删除对应的报关单", inData.getDelNo());
// 保存修改前的托数据
EcssCoDelNotifyHeaderData queryData = new EcssCoDelNotifyHeaderData();
queryData.setSite(inData.getSite());
queryData.setBuNo(inData.getBuNo());
queryData.setDelNo(inData.getDelNo());
List<EcssCoDelPalletHeaderData> allPalletHeaders = coDelMapper.searchEcssCoDelPalletHeaderData(queryData);
// 根据seqNo过滤出当前修改的托盘
oldPalletHeaderList = allPalletHeaders.stream()
.filter(p -> p.getSeqNo() != null && p.getSeqNo().equals(inData.getSeqNo()))
.collect(Collectors.toList());
// 查找对应的报关单
EcssDeclarationHeaderData declarationQuery = new EcssDeclarationHeaderData();
declarationQuery.setSite(inData.getSite());
declarationQuery.setDelNo(inData.getDelNo());
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("已删除发货通知单{}对应的{}个报关单", inData.getDelNo(), deletedDeclarations.size());
// 将通知单状态更新为仓库已确认
notifyHeader.setNotifyStatus("仓库已确认");
coDelMapper.changeEcssDelStatus(notifyHeader);
log.info("发货通知单{}状态已更新为仓库已确认", inData.getDelNo());
}
// 执行修改操作
coDelMapper.updateCodelPalletHeaderPalletQty(inData);
// 如果状态为已报关发送邮件通知创建人
if (isCustomsCleared && deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
sendPalletQtyChangeNotificationEmail(notifyHeader, oldPalletHeaderList, deletedDeclarations, inData);
}
}
@Override
@Transactional
public void deletePalletHeader(EcssCoDelPalletHeaderData inData) {
// 获取发货通知单信息
EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(inData.getSite(), inData.getDelNo());
// 检查发货通知单状态是否为已报关
boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus());
// 保存删除前的托数据用于邮件通知
List<EcssCoDelPalletHeaderData> oldPalletHeaderList = null;
List<EcssDeclarationHeaderData> deletedDeclarations = null;
if (isCustomsCleared) {
log.info("托数删除:发货通知单{}状态为已报关,开始删除对应的报关单", inData.getDelNo());
// 保存删除前的托数据
EcssCoDelNotifyHeaderData queryData = new EcssCoDelNotifyHeaderData();
queryData.setSite(inData.getSite());
queryData.setBuNo(inData.getBuNo());
queryData.setDelNo(inData.getDelNo());
List<EcssCoDelPalletHeaderData> allPalletHeaders = coDelMapper.searchEcssCoDelPalletHeaderData(queryData);
// 根据seqNo过滤出当前删除的托盘
oldPalletHeaderList = allPalletHeaders.stream()
.filter(p -> p.getSeqNo() != null && p.getSeqNo().equals(inData.getSeqNo()))
.collect(Collectors.toList());
// 查找对应的报关单
EcssDeclarationHeaderData declarationQuery = new EcssDeclarationHeaderData();
declarationQuery.setSite(inData.getSite());
declarationQuery.setDelNo(inData.getDelNo());
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("已删除发货通知单{}对应的{}个报关单", inData.getDelNo(), deletedDeclarations.size());
// 将通知单状态更新为仓库已确认
notifyHeader.setNotifyStatus("仓库已确认");
coDelMapper.changeEcssDelStatus(notifyHeader);
log.info("发货通知单{}状态已更新为仓库已确认", inData.getDelNo());
}
// 执行删除操作
coDelMapper.deletePalletHeader(inData);
// 如果状态为已报关发送邮件通知创建人
if (isCustomsCleared && deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
sendPalletDeleteNotificationEmail(notifyHeader, oldPalletHeaderList, deletedDeclarations, inData);
}
}
@ -3195,7 +3305,33 @@ public class CoDelServiceImpl implements CoDelService {
// 如果状态为已报关发送邮件通知创建人
if (isCustomsCleared) {
sendPackingChangeNotificationEmail(notifyHeader, oldBoxList, oldPalletDetailList, inData);
log.info("一键装箱:发货通知单{}状态为已报关,开始删除对应的报关单", inData.getDelNo());
// 查找对应的报关单
EcssDeclarationHeaderData declarationQuery = new EcssDeclarationHeaderData();
declarationQuery.setSite(inData.getSite());
declarationQuery.setDelNo(inData.getDelNo());
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("已删除发货通知单{}对应的{}个报关单", inData.getDelNo(), deletedDeclarations.size());
// 将通知单状态更新为仓库已确认
notifyHeader.setNotifyStatus("仓库已确认");
coDelMapper.changeEcssDelStatus(notifyHeader);
log.info("发货通知单{}状态已更新为仓库已确认", inData.getDelNo());
// 发送邮件通知包含报关单删除信息
sendPackingChangeNotificationEmail(notifyHeader, oldBoxList, oldPalletDetailList, deletedDeclarations, inData);
}
}
@ -3455,18 +3591,46 @@ public class CoDelServiceImpl implements CoDelService {
// 检查发货通知单状态是否为已报关
boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus());
// 如果状态为已报关保存修改前的装箱数据用于对比
// 保存修改前的装箱数据用于邮件通知
List<Map> oldBoxList = new ArrayList<>();
List<EcssDeclarationHeaderData> deletedDeclarations = null;
if (isCustomsCleared) {
log.info("装箱数据修改:发货通知单{}状态为已报关,开始删除对应的报关单", delNo);
// 保存修改前的装箱数据
oldBoxList = coDelMapper.selectBoxList(notifyHeader);
// 查找对应的报关单
EcssDeclarationHeaderData declarationQuery = new EcssDeclarationHeaderData();
declarationQuery.setSite(site);
declarationQuery.setDelNo(delNo);
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);
}
// 执行修改操作
coDelMapper.updateBoxInfo(boxData);
// 如果状态为已报关发送邮件通知创建人
if (isCustomsCleared) {
sendBoxChangeNotificationEmail(notifyHeader, oldBoxList, "修改", boxData);
if (isCustomsCleared && deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
sendBoxChangeNotificationEmailWithDeclaration(notifyHeader, oldBoxList, deletedDeclarations, "修改", boxData);
}
}
@ -3481,10 +3645,38 @@ public class CoDelServiceImpl implements CoDelService {
// 检查发货通知单状态是否为已报关
boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus());
// 如果状态为已报关保存删除前的装箱数据用于对比
// 保存删除前的装箱数据用于邮件通知
List<Map> oldBoxList = new ArrayList<>();
List<EcssDeclarationHeaderData> deletedDeclarations = null;
if (isCustomsCleared) {
log.info("装箱数据删除:发货通知单{}状态为已报关,开始删除对应的报关单", delNo);
// 保存删除前的装箱数据
oldBoxList = coDelMapper.selectBoxList(notifyHeader);
// 查找对应的报关单
EcssDeclarationHeaderData declarationQuery = new EcssDeclarationHeaderData();
declarationQuery.setSite(site);
declarationQuery.setDelNo(delNo);
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);
}
// 获取该箱下的全部箱明细
@ -3523,8 +3715,8 @@ public class CoDelServiceImpl implements CoDelService {
coDelMapper.deleteBoxInfo(boxData);
// 如果状态为已报关发送邮件通知创建人
if (isCustomsCleared) {
sendBoxChangeNotificationEmail(notifyHeader, oldBoxList, "删除", boxData);
if (isCustomsCleared && deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
sendBoxChangeNotificationEmailWithDeclaration(notifyHeader, oldBoxList, deletedDeclarations, "删除", boxData);
}
}
@ -3770,6 +3962,7 @@ public class CoDelServiceImpl implements CoDelService {
* @param notifyHeader 发货通知单头数据
* @param oldBoxList 计算前的箱子列表
* @param oldPalletDetailList 计算前的装箱明细列表
* @param deletedDeclarations 已删除的报关单列表
* @param inData 输入参数
* @author AI Assistant
* @date 2024-10-09
@ -3777,6 +3970,7 @@ public class CoDelServiceImpl implements CoDelService {
private void sendPackingChangeNotificationEmail(EcssCoDelNotifyHeaderData notifyHeader,
List<Map> oldBoxList,
List<EcssCoDelPalletDetailData> oldPalletDetailList,
List<EcssDeclarationHeaderData> deletedDeclarations,
EcssCoDelPalletHeaderData inData) {
try {
log.info("开始发送装箱变更通知邮件,发货通知单号:{}", notifyHeader.getDelNo());
@ -3789,9 +3983,9 @@ public class CoDelServiceImpl implements CoDelService {
queryData.setDelNo(inData.getDelNo());
List<EcssCoDelPalletDetailData> newPalletDetailList = coDelMapper.searchEcssCoDelPalletDetailData(queryData);
// 生成对比邮件内容
// 生成对比邮件内容包含报关单删除信息
String emailContent = generatePackingComparisonEmailContent(notifyHeader, oldBoxList, newBoxList,
oldPalletDetailList, newPalletDetailList);
oldPalletDetailList, newPalletDetailList, deletedDeclarations);
// 获取发货通知单创建人邮箱
SysUserEntity creator = coDelMapper.queryByUserName(notifyHeader.getCreateBy());
@ -3802,7 +3996,7 @@ public class CoDelServiceImpl implements CoDelService {
String creatorEmail = creator.getEmail();
// 发送邮件
String subject = String.format("发货通知单%s【发票:%s】一键装箱数据变更通知",
String subject = String.format("发货通知单%s【发票:%s】一键装箱数据变更及报关单删除通知",
notifyHeader.getDelNo(), notifyHeader.getCmcInvoice());
String[] mailAddress = {creatorEmail};
@ -3825,6 +4019,7 @@ public class CoDelServiceImpl implements CoDelService {
* @param newBoxList 计算后的箱子列表
* @param oldPalletDetailList 计算前的装箱明细列表
* @param newPalletDetailList 计算后的装箱明细列表
* @param deletedDeclarations 已删除的报关单列表
* @return HTML格式的邮件内容
* @author AI Assistant
* @date 2024-10-09
@ -3833,7 +4028,8 @@ public class CoDelServiceImpl implements CoDelService {
List<Map> oldBoxList,
List<Map> newBoxList,
List<EcssCoDelPalletDetailData> oldPalletDetailList,
List<EcssCoDelPalletDetailData> newPalletDetailList) {
List<EcssCoDelPalletDetailData> newPalletDetailList,
List<EcssDeclarationHeaderData> deletedDeclarations) {
StringBuilder emailContent = new StringBuilder();
emailContent.append("<!DOCTYPE html>");
@ -3846,19 +4042,36 @@ public class CoDelServiceImpl implements CoDelService {
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(".warning { color: #ff6600; font-size: 16px; font-weight: bold; margin: 20px 0; padding: 10px; background-color: #fff3cd; border: 1px solid #ff6600; }");
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }");
emailContent.append("</style>");
emailContent.append("</head>");
emailContent.append("<body>");
// 邮件标题
emailContent.append("<h2>发货通知单一键装箱数据变更通知</h2>");
emailContent.append("<h2>发货通知单一键装箱数据变更及报关单删除通知</h2>");
emailContent.append("<p><strong>发货通知单号:</strong>").append(notifyHeader.getDelNo()).append("</p>");
emailContent.append("<p><strong>发票号:</strong>").append(notifyHeader.getCmcInvoice()).append("</p>");
emailContent.append("<p><strong>客户:</strong>").append(notifyHeader.getCustomerName()).append("</p>");
emailContent.append("<p><strong>操作时间:</strong>").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
emailContent.append("<p><strong>操作类型:</strong><span class='changed'>一键装箱重新计算</span></p>");
// 报关单删除警告信息
if (deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
emailContent.append("<div class='warning'>");
emailContent.append("<strong>⚠️ 重要提示:</strong>由于执行了一键装箱重新计算,以下报关单已被删除,发货通知单状态已更新为'仓库已确认':");
emailContent.append("<ul>");
for (EcssDeclarationHeaderData declaration : deletedDeclarations) {
emailContent.append("<li>")
.append(notifyHeader.getCmcInvoice())
.append(" 发票报关单【报关单号:")
.append(declaration.getDeclarationNo())
.append("】已删除</li>");
}
emailContent.append("</ul>");
emailContent.append("</div>");
}
// 箱子信息对比
emailContent.append("<div class='section-title'>箱子信息对比</div>");
emailContent.append(generateBoxListComparisonTable(oldBoxList, newBoxList));
@ -4357,4 +4570,438 @@ public class CoDelServiceImpl implements CoDelService {
return result;
}
/**
* 发送装箱数据变更通知邮件包含报关单删除信息
*
* @param notifyHeader 发货通知单头数据
* @param oldBoxList 操作前的箱子列表
* @param deletedDeclarations 已删除的报关单列表
* @param operation 操作类型修改/删除
* @param boxData 操作的箱子数据
* @author AI Assistant
* @date 2025-01-20
*/
private void sendBoxChangeNotificationEmailWithDeclaration(EcssCoDelNotifyHeaderData notifyHeader,
List<Map> oldBoxList,
List<EcssDeclarationHeaderData> deletedDeclarations,
String operation,
Map<String, Object> boxData) {
try {
log.info("开始发送装箱{}通知邮件(含报关单删除信息),发货通知单号:{}", operation, notifyHeader.getDelNo());
// 获取操作后的装箱数据
List<Map> newBoxList = coDelMapper.selectBoxList(notifyHeader);
// 生成对比邮件内容包含报关单删除信息
String emailContent = generateBoxChangeEmailContentWithDeclaration(notifyHeader, oldBoxList, newBoxList,
deletedDeclarations, operation, boxData);
// 获取发货通知单创建人邮箱
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】装箱数据%s及报关单删除通知",
notifyHeader.getDelNo(), notifyHeader.getCmcInvoice(), operation);
String[] mailAddress = {creatorEmail};
sendMailUtil(subject, emailContent, mailAddress, notifyHeader);
log.info("装箱{}通知邮件发送成功(含报关单删除信息),收件人:{}", operation, creatorEmail);
} catch (Exception e) {
log.error("发送装箱{}通知邮件失败(含报关单删除信息),发货通知单号:{}, 错误信息:{}",
operation, notifyHeader.getDelNo(), e.getMessage(), e);
// 邮件发送失败不影响主流程只记录日志
}
}
/**
* 生成装箱数据变更邮件内容包含报关单删除信息
*
* @param notifyHeader 发货通知单头数据
* @param oldBoxList 操作前的箱子列表
* @param newBoxList 操作后的箱子列表
* @param deletedDeclarations 已删除的报关单列表
* @param operation 操作类型
* @param boxData 操作的箱子数据
* @return HTML格式的邮件内容
*/
private String generateBoxChangeEmailContentWithDeclaration(EcssCoDelNotifyHeaderData notifyHeader,
List<Map> oldBoxList,
List<Map> newBoxList,
List<EcssDeclarationHeaderData> deletedDeclarations,
String operation,
Map<String, Object> boxData) {
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(".deleted { color: red; text-decoration: line-through; }");
emailContent.append(".warning { color: #ff6600; font-size: 16px; font-weight: bold; margin: 20px 0; padding: 10px; background-color: #fff3cd; border: 1px solid #ff6600; }");
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }");
emailContent.append("</style>");
emailContent.append("</head>");
emailContent.append("<body>");
// 邮件标题
emailContent.append("<h2>发货通知单装箱数据").append(operation).append("及报关单删除通知</h2>");
emailContent.append("<p><strong>发货通知单号:</strong>").append(notifyHeader.getDelNo()).append("</p>");
emailContent.append("<p><strong>发票号:</strong>").append(notifyHeader.getCmcInvoice()).append("</p>");
emailContent.append("<p><strong>客户:</strong>").append(notifyHeader.getCustomerName()).append("</p>");
emailContent.append("<p><strong>操作时间:</strong>").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
emailContent.append("<p><strong>操作类型:</strong><span class='changed'>").append(operation).append("装箱数据(序号:").append(boxData.get("item_no")).append(")</span></p>");
// 报关单删除警告信息
if (deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
emailContent.append("<div class='warning'>");
emailContent.append("<strong>⚠️ 重要提示:</strong>由于").append(operation).append("了装箱数据,以下报关单已被删除,发货通知单状态已更新为'仓库已确认':");
emailContent.append("<ul>");
for (EcssDeclarationHeaderData declaration : deletedDeclarations) {
emailContent.append("<li>")
.append(notifyHeader.getCmcInvoice())
.append(" 发票报关单【报关单号:")
.append(declaration.getDeclarationNo())
.append("】已删除</li>");
}
emailContent.append("</ul>");
emailContent.append("</div>");
}
// 装箱数据信息对比
emailContent.append("<div class='section-title'>装箱数据信息对比</div>");
emailContent.append(generateBoxListComparisonTable(oldBoxList, newBoxList));
emailContent.append("<p style='margin-top: 20px;'><strong>备注:</strong>请重新生成报关单。</p>");
emailContent.append("</body>");
emailContent.append("</html>");
return emailContent.toString();
}
/**
* 发送托数修改通知邮件托盘头表
*
* @param notifyHeader 发货通知单头数据
* @param oldPalletHeaderList 修改前的托盘头表数据列表
* @param deletedDeclarations 已删除的报关单列表
* @param inData 托盘头表数据
* @author AI Assistant
* @date 2025-01-20
*/
private void sendPalletQtyChangeNotificationEmail(EcssCoDelNotifyHeaderData notifyHeader,
List<EcssCoDelPalletHeaderData> oldPalletHeaderList,
List<EcssDeclarationHeaderData> deletedDeclarations,
EcssCoDelPalletHeaderData inData) {
try {
log.info("开始发送托数修改通知邮件,发货通知单号:{}", notifyHeader.getDelNo());
// 生成邮件内容
String emailContent = generatePalletQtyChangeEmailContent(notifyHeader, oldPalletHeaderList,
deletedDeclarations, inData);
// 获取发货通知单创建人邮箱
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 oldPalletHeaderList 删除前的托盘头表数据列表
* @param deletedDeclarations 已删除的报关单列表
* @param inData 托盘头表数据
* @author AI Assistant
* @date 2025-01-29
*/
private void sendPalletDeleteNotificationEmail(EcssCoDelNotifyHeaderData notifyHeader,
List<EcssCoDelPalletHeaderData> oldPalletHeaderList,
List<EcssDeclarationHeaderData> deletedDeclarations,
EcssCoDelPalletHeaderData inData) {
try {
log.info("开始发送托数删除通知邮件,发货通知单号:{}", notifyHeader.getDelNo());
// 生成邮件内容
String emailContent = generatePalletDeleteEmailContent(notifyHeader, oldPalletHeaderList,
deletedDeclarations, inData);
// 获取发货通知单创建人邮箱
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 oldPalletHeaderList 删除前的托盘头表数据列表
* @param deletedDeclarations 已删除的报关单列表
* @param inData 托盘头表数据
* @return HTML格式的邮件内容
*/
private String generatePalletDeleteEmailContent(EcssCoDelNotifyHeaderData notifyHeader,
List<EcssCoDelPalletHeaderData> oldPalletHeaderList,
List<EcssDeclarationHeaderData> deletedDeclarations,
EcssCoDelPalletHeaderData inData) {
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(".deleted { color: red; font-weight: bold; }");
emailContent.append(".warning { color: #ff6600; font-size: 16px; font-weight: bold; margin: 20px 0; padding: 10px; background-color: #fff3cd; border: 1px solid #ff6600; }");
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }");
emailContent.append("</style>");
emailContent.append("</head>");
emailContent.append("<body>");
// 邮件标题
emailContent.append("<h2>发货通知单托数删除及报关单删除通知</h2>");
emailContent.append("<p><strong>发货通知单号:</strong>").append(notifyHeader.getDelNo()).append("</p>");
emailContent.append("<p><strong>发票号:</strong>").append(notifyHeader.getCmcInvoice()).append("</p>");
emailContent.append("<p><strong>客户:</strong>").append(notifyHeader.getCustomerName()).append("</p>");
emailContent.append("<p><strong>操作时间:</strong>").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
emailContent.append("<p><strong>操作类型:</strong><span class='deleted'>删除栈板</span></p>");
// 报关单删除警告信息
if (deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
emailContent.append("<div class='warning'>");
emailContent.append("<strong>⚠️ 重要提示:</strong>由于删除了托数,以下报关单已被删除,发货通知单状态已更新为'仓库已确认':");
emailContent.append("<ul>");
for (EcssDeclarationHeaderData declaration : deletedDeclarations) {
emailContent.append("<li>")
.append(notifyHeader.getCmcInvoice())
.append(" 发票报关单【报关单号:")
.append(declaration.getDeclarationNo())
.append("】已删除</li>");
}
emailContent.append("</ul>");
emailContent.append("</div>");
}
// 已删除的托数信息
emailContent.append("<div class='section-title'>已删除的托数信息</div>");
emailContent.append("<p><strong>托盘序号:</strong>").append(inData.getSeqNo()).append("</p>");
if (oldPalletHeaderList != null && !oldPalletHeaderList.isEmpty()) {
EcssCoDelPalletHeaderData oldData = oldPalletHeaderList.get(0);
emailContent.append("<table>");
emailContent.append("<tr><th>字段</th><th>删除前的数据</th></tr>");
// 托数
if (oldData.getPalletQty() != null) {
emailContent.append("<tr><td>托数</td><td class='deleted'>")
.append(oldData.getPalletQty())
.append("</td></tr>");
}
// 高度
if (oldData.getHeight() != null) {
emailContent.append("<tr><td>高度</td><td class='deleted'>")
.append(oldData.getHeight())
.append("</td></tr>");
}
// 托盘编号
// 毛重
if (oldData.getGrossWeight() != null) {
emailContent.append("<tr><td>毛重</td><td>")
.append(oldData.getGrossWeight())
.append("</td></tr>");
}
// 净重
if (oldData.getNetWeight() != null) {
emailContent.append("<tr><td>净重</td><td>")
.append(oldData.getNetWeight())
.append("</td></tr>");
}
// 箱数
if (oldData.getBoxQty() != null) {
emailContent.append("<tr><td>箱数</td><td>")
.append(oldData.getBoxQty())
.append("</td></tr>");
}
emailContent.append("</table>");
}
emailContent.append("<p style='margin-top: 20px;' class='warning'><strong>备注:</strong>请重新生成报关单。</p>");
emailContent.append("</body>");
emailContent.append("</html>");
return emailContent.toString();
}
/**
* 生成托数修改邮件内容
*
* @param notifyHeader 发货通知单头数据
* @param oldPalletHeaderList 修改前的托盘头表数据列表
* @param deletedDeclarations 已删除的报关单列表
* @param inData 托盘头表数据
* @return HTML格式的邮件内容
*/
private String generatePalletQtyChangeEmailContent(EcssCoDelNotifyHeaderData notifyHeader,
List<EcssCoDelPalletHeaderData> oldPalletHeaderList,
List<EcssDeclarationHeaderData> deletedDeclarations,
EcssCoDelPalletHeaderData inData) {
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(".warning { color: #ff6600; font-size: 16px; font-weight: bold; margin: 20px 0; padding: 10px; background-color: #fff3cd; border: 1px solid #ff6600; }");
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }");
emailContent.append("</style>");
emailContent.append("</head>");
emailContent.append("<body>");
// 邮件标题
emailContent.append("<h2>发货通知单托数修改及报关单删除通知</h2>");
emailContent.append("<p><strong>发货通知单号:</strong>").append(notifyHeader.getDelNo()).append("</p>");
emailContent.append("<p><strong>发票号:</strong>").append(notifyHeader.getCmcInvoice()).append("</p>");
emailContent.append("<p><strong>客户:</strong>").append(notifyHeader.getCustomerName()).append("</p>");
emailContent.append("<p><strong>操作时间:</strong>").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
// 报关单删除警告信息
if (deletedDeclarations != null && !deletedDeclarations.isEmpty()) {
emailContent.append("<div class='warning'>");
emailContent.append("<strong>⚠️ 重要提示:</strong>由于修改了托数,以下报关单已被删除,发货通知单状态已更新为'仓库已确认':");
emailContent.append("<ul>");
for (EcssDeclarationHeaderData declaration : deletedDeclarations) {
emailContent.append("<li>")
.append(notifyHeader.getCmcInvoice())
.append(" 发票报关单【报关单号:")
.append(declaration.getDeclarationNo())
.append("】已删除</li>");
}
emailContent.append("</ul>");
emailContent.append("</div>");
}
// 托数修改信息
emailContent.append("<div class='section-title'>托数修改信息</div>");
emailContent.append("<p><strong>托盘序号:</strong>").append(inData.getSeqNo()).append("</p>");
if (oldPalletHeaderList != null && !oldPalletHeaderList.isEmpty()) {
EcssCoDelPalletHeaderData oldData = oldPalletHeaderList.get(0);
emailContent.append("<table>");
emailContent.append("<tr><th>字段</th><th>修改前</th><th>修改后</th></tr>");
// 比较托数字段
if (!Objects.equals(oldData.getPalletQty(), inData.getPalletQty())) {
emailContent.append("<tr><td>托数</td><td>")
.append(oldData.getPalletQty() != null ? oldData.getPalletQty() : "")
.append("</td><td class='changed'>")
.append(inData.getPalletQty() != null ? inData.getPalletQty() : "")
.append("</td></tr>");
}
// 比较高度字段
if (!Objects.equals(oldData.getHeight(), inData.getHeight())) {
emailContent.append("<tr><td>高度</td><td>")
.append(oldData.getHeight() != null ? oldData.getHeight() : "")
.append("</td><td class='changed'>")
.append(inData.getHeight() != null ? inData.getHeight() : "")
.append("</td></tr>");
}
if (oldData.getGrossWeight() != null) {
emailContent.append("<tr><td>毛重</td><td colspan='2'>")
.append(oldData.getGrossWeight())
.append("</td></tr>");
}
if (oldData.getNetWeight() != null) {
emailContent.append("<tr><td>净重</td><td colspan='2'>")
.append(oldData.getNetWeight())
.append("</td></tr>");
}
if (oldData.getBoxQty() != null) {
emailContent.append("<tr><td>箱数</td><td colspan='2'>")
.append(oldData.getBoxQty())
.append("</td></tr>");
}
emailContent.append("</table>");
}
emailContent.append("<p style='margin-top: 20px;' class='warning'><strong>备注:</strong>请重新生成报关单。</p>");
emailContent.append("</body>");
emailContent.append("</html>");
return emailContent.toString();
}
}

6
src/main/resources/mapper/ecss/CoDelMapper.xml

@ -1079,11 +1079,11 @@ left join ecss_CoDelNotifyHeader noHeader on a.site=noHeader.site and a.delNo=no
<insert id="insertEcssTemplateData" >
insert into ecss_template (customName,site,buNo,name,type,upc,so,origin,palletWeight,material,hsCode,packaging,itemNo,
kgs,shippingMark,boxChange,hsCodeDesc,contractFlag,hsCodeDescType,goodsLabel,hsCodeFlag,shippingMode,CreateBy,CreateDate,
salesMethod,currency,madeArea,sendPort,shipper,voyage,deliveryGoodsDate,shippingDate,fscWeight, remark,highPalletFlag)
salesMethod,currency,madeArea,sendPort,shipper,voyage,deliveryGoodsDate,shippingDate,fscWeight, remark,highPalletFlag,showWeight)
values(#{customName,jdbcType=NVARCHAR},#{site},#{buNo},#{name},#{type},#{upc},#{so},#{origin},#{palletWeight},#{material},#{hsCode},#{packaging},
#{itemNo},#{kgs},#{shippingMark},#{boxChange},
#{hsCodeDesc},#{contractFlag},#{hsCodeDescType},#{goodsLabel},#{hsCodeFlag},#{shippingMode},#{createBy},GetDate(),
#{salesMethod},#{currency},#{madeArea},#{sendPort},#{shipper},#{voyage},#{deliveryGoodsDate},#{shippingDate},#{fscWeight},#{remark},#{highPalletFlag})
#{salesMethod},#{currency},#{madeArea},#{sendPort},#{shipper},#{voyage},#{deliveryGoodsDate},#{shippingDate},#{fscWeight},#{remark},#{highPalletFlag},#{showWeight})
</insert>
<update id="updateEcssTemplateData">
@ -1093,7 +1093,7 @@ left join ecss_CoDelNotifyHeader noHeader on a.site=noHeader.site and a.delNo=no
contractFlag=#{contractFlag},hsCodeDescType=#{hsCodeDescType},goodsLabel=#{goodsLabel},hsCodeFlag=#{hsCodeFlag},
shippingMode=#{shippingMode},UpdateDate=GetDate(),UpdateBy=#{updateBy},customName=#{customName,jdbcType=NVARCHAR},salesMethod= #{salesMethod},
currency= #{currency},madeArea= #{madeArea},sendPort= #{sendPort},shipper= #{shipper},remark= #{remark},
voyage= #{voyage},deliveryGoodsDate= #{deliveryGoodsDate},shippingDate= #{shippingDate},fscWeight=#{fscWeight},highPalletFlag=#{highPalletFlag}
voyage= #{voyage},deliveryGoodsDate= #{deliveryGoodsDate},shippingDate= #{shippingDate},fscWeight=#{fscWeight},highPalletFlag=#{highPalletFlag},showWeight=#{showWeight}
where buNo=#{buNo} and name=#{nameNative}
</update>

Loading…
Cancel
Save