invoice_validation_update.md
8.05 KB
发票验证功能更新
修改概述
在 InvoiceMainServiceImpl 中的 addInvoice 和 updateInvoice 方法中添加了全面的验证逻辑,确保发票中的经销商与关联订单和出库单中的经销商保持一致。
修改内容
1. 新增自定义异常类
创建了 InvoiceValidationException 异常类,用于处理发票验证失败的情况:
public class InvoiceValidationException extends RuntimeException {
public InvoiceValidationException(String message) {
super(message);
}
public InvoiceValidationException(String message, Throwable cause) {
super(message, cause);
}
}
2. 扩展DeliveryMainMapper接口
在 DeliveryMainMapper 接口中添加了 selectByDeliveryNo 方法:
@Select("SELECT * FROM t_delivery_main WHERE delivery_no = #{deliveryNo} AND del_flag = '0'")
DeliveryMain selectByDeliveryNo(@Param("deliveryNo") String deliveryNo);
3. 新增验证方法
在 InvoiceMainServiceImpl 中添加了两个验证方法:
validateOrderConsistency方法
private void validateOrderConsistency(String orderNo, String invoiceDealerCode) {
// 根据订单编号查询订单信息
OrderMain order = orderMainMapper.selectByOrderNo(orderNo);
if (order == null) {
throw new IllegalArgumentException("关联的订单不存在");
}
// 比较经销商编码
if (!invoiceDealerCode.equals(order.getDealerCode())) {
String errorMessage = String.format(
"发票中的经销商编码[%s]与关联订单[%s]中的经销商编码[%s]不一致",
invoiceDealerCode, orderNo, order.getDealerCode()
);
throw new InvoiceValidationException(errorMessage);
}
}
validateDeliveryConsistency方法
private void validateDeliveryConsistency(String deliveryNo, String invoiceDealerCode) {
// 根据出库单编号查询出库单信息
DeliveryMain delivery = deliveryMainMapper.selectByDeliveryNo(deliveryNo);
if (delivery == null) {
throw new IllegalArgumentException("关联的出库单不存在");
}
// 比较经销商编码
if (!invoiceDealerCode.equals(delivery.getDealerCode())) {
String errorMessage = String.format(
"发票中的经销商编码[%s]与关联出库单[%s]中的经销商编码[%s]不一致",
invoiceDealerCode, deliveryNo, delivery.getDealerCode()
);
throw new InvoiceValidationException(errorMessage);
}
}
4. 修改addInvoice方法
在 addInvoice 方法中添加了验证逻辑:
// 验证关联的订单是否存在且经销商一致
validateOrderConsistency(addReq.getOrderNo(), addReq.getDealerCode());
// 验证关联的出库单是否存在且经销商一致(如果提供了出库单号)
if (StringUtils.hasText(addReq.getDeliveryNo())) {
validateDeliveryConsistency(addReq.getDeliveryNo(), addReq.getDealerCode());
}
5. 修改updateInvoice方法
在 updateInvoice 方法中添加了验证逻辑:
// 验证关联的订单是否存在且经销商一致
validateOrderConsistency(updateReq.getOrderNo(), updateReq.getDealerCode());
// 验证关联的出库单是否存在且经销商一致(如果提供了出库单号)
if (StringUtils.hasText(updateReq.getDeliveryNo())) {
validateDeliveryConsistency(updateReq.getDeliveryNo(), updateReq.getDealerCode());
}
验证逻辑说明
验证流程
- 订单存在性验证:验证关联的订单编号是否在订单管理中存在
- 订单经销商一致性验证:验证发票中的经销商编码与关联订单中的经销商编码是否一致
- 出库单存在性验证:如果提供了出库单号,验证关联的出库单编号是否在出库管理中存在
- 出库单经销商一致性验证:如果提供了出库单号,验证发票中的经销商编码与关联出库单中的经销商编码是否一致
- 异常处理:如果任何验证失败,抛出相应的异常
验证时机
-
新增发票时:在
addInvoice方法中,在发票编号存在性验证之后立即进行验证 -
修改发票时:在
updateInvoice方法中,在发票编号存在性验证之后立即进行验证
异常信息
订单经销商不一致
发票中的经销商编码[DEALER002]与关联订单[ORDER001]中的经销商编码[DEALER001]不一致
出库单经销商不一致
发票中的经销商编码[DEALER002]与关联出库单[DELIVERY001]中的经销商编码[DEALER001]不一致
订单不存在
关联的订单不存在
出库单不存在
关联的出库单不存在
测试
单元测试
创建了 InvoiceMainServiceImplValidationTest 测试类,包含以下测试用例:
-
成功场景测试:
- 经销商一致时的正常流程
- 不提供出库单号时的验证逻辑
- 验证方法调用正确性
-
异常场景测试:
- 订单经销商不一致时抛出
InvoiceValidationException - 出库单经销商不一致时抛出
InvoiceValidationException - 订单不存在时抛出
IllegalArgumentException - 出库单不存在时抛出
IllegalArgumentException
- 订单经销商不一致时抛出
-
异常消息测试:
- 验证异常消息格式的正确性
测试覆盖
- ✅ 新增发票时的订单验证
- ✅ 新增发票时的出库单验证
- ✅ 修改发票时的订单验证
- ✅ 修改发票时的出库单验证
- ✅ 经销商不一致的异常处理
- ✅ 关联记录不存在的异常处理
- ✅ 异常消息格式验证
影响范围
修改的文件
-
backend/src/main/java/com/apple/erp/exception/InvoiceValidationException.java- 新增异常类 -
backend/src/main/java/com/apple/erp/mapper/DeliveryMainMapper.java- 扩展Mapper接口 -
backend/src/main/java/com/apple/erp/service/impl/InvoiceMainServiceImpl.java- 修改服务实现 -
backend/src/test/java/com/apple/erp/service/impl/InvoiceMainServiceImplValidationTest.java- 新增测试类
影响的方法
-
InvoiceMainServiceImpl.addInvoice()- 新增验证逻辑 -
InvoiceMainServiceImpl.updateInvoice()- 新增验证逻辑 - 新增
validateOrderConsistency()私有方法 - 新增
validateDeliveryConsistency()私有方法 -
DeliveryMainMapper.selectByDeliveryNo()- 新增查询方法
业务价值
数据一致性保障
- 确保发票与关联订单的经销商信息保持一致
- 确保发票与关联出库单的经销商信息保持一致
- 防止因经销商信息不匹配导致的数据错误
- 提高系统的数据完整性和可靠性
错误预防
- 在数据录入阶段就发现并阻止经销商不匹配的问题
- 提供清晰的错误信息,便于用户快速定位和修正问题
- 减少后续业务流程中的数据异常
系统健壮性
- 增强系统的数据验证能力
- 提供更好的错误处理和用户反馈
- 提高系统的整体稳定性和可维护性
向后兼容性
- 新增的验证逻辑不会影响现有的正常业务流程
- 只有在经销商不匹配或关联记录不存在时才会抛出异常
- 保持了原有的方法签名和返回值类型
- 不影响现有的API接口
- 出库单号验证是可选的,只有在提供出库单号时才会进行验证
使用示例
成功场景
// 发票中的经销商与订单和出库单中的经销商一致
InvoiceAddReq addReq = new InvoiceAddReq();
addReq.setOrderNo("ORDER001");
addReq.setDeliveryNo("DELIVERY001");
addReq.setDealerCode("DEALER001"); // 与订单和出库单中的经销商一致
invoiceMainService.addInvoice(addReq); // 验证通过
失败场景
// 发票中的经销商与订单中的经销商不一致
InvoiceAddReq addReq = new InvoiceAddReq();
addReq.setOrderNo("ORDER001");
addReq.setDealerCode("DEALER002"); // 与订单中的经销商不一致
try {
invoiceMainService.addInvoice(addReq);
} catch (InvoiceValidationException e) {
System.out.println("验证失败:" + e.getMessage());
// 输出:验证失败:发票中的经销商编码[DEALER002]与关联订单[ORDER001]中的经销商编码[DEALER001]不一致
}