gaoluyang
2026-11-03 006020bc9a87dc40c2e73bc50f244b348b831de1
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java
@@ -357,9 +357,12 @@
    private void calculateTotalPrice(ErpPurchaseOrderDO purchaseOrder, List<ErpPurchaseOrderItemDO> purchaseOrderItems) {
        purchaseOrder.setTotalCount(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getCount, BigDecimal::add));
        purchaseOrder.setTotalProductPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO));
        purchaseOrder.setTotalTaxPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
        purchaseOrder.setTotalPrice(purchaseOrder.getTotalProductPrice().add(purchaseOrder.getTotalTaxPrice()));
        // 明细的 totalPrice 是「数量 × 含税单价」,即含税总价;不含税金额 = 含税总价 − 税额
        BigDecimal totalPriceWithTax = getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO);
        BigDecimal totalTaxPrice = getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO);
        purchaseOrder.setTotalTaxPrice(totalTaxPrice);
        purchaseOrder.setTotalPrice(totalPriceWithTax);
        purchaseOrder.setTotalProductPrice(totalPriceWithTax.subtract(totalTaxPrice));
        // 计算优惠价格
        if (purchaseOrder.getDiscountPercent() == null) {
            purchaseOrder.setDiscountPercent(BigDecimal.ZERO);
@@ -513,13 +516,12 @@
    private List<ErpPurchaseOrderItemDO> validatePurchaseOrderItems(List<ErpPurchaseOrderSaveReqVO.Item> list) {
        // 转化为 ErpPurchaseOrderItemDO 列表(产品验证已移除)
        return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseOrderItemDO.class, item -> {
            // 产品单价为含税单价:行总价 = 数量 × 含税单价,税额再从含税总价里倒算
            item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()));
            if (item.getTotalPrice() == null) {
                return;
            }
            if (item.getTaxPercent() != null) {
                item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent()));
            }
            item.setTaxPrice(MoneyUtils.priceCalculateTaxIncluded(item.getTotalPrice(), item.getTaxPercent()));
        }));
    }
@@ -548,7 +550,8 @@
        // 1. 更新每个采购订单项
        orderItems.forEach(item -> {
            BigDecimal inCount = inCountMap.getOrDefault(item.getId(), BigDecimal.ZERO);
            if (item.getInCount().equals(inCount)) {
            // 历史/导入数据的入库数量可能为空,按 0 处理,避免 NPE
            if (ObjectUtil.defaultIfNull(item.getInCount(), BigDecimal.ZERO).compareTo(inCount) == 0) {
                return;
            }
            if (inCount.compareTo(item.getCount()) > 0) {
@@ -568,12 +571,14 @@
        // 1. 更新每个采购订单项
        orderItems.forEach(item -> {
            BigDecimal returnCount = returnCountMap.getOrDefault(item.getId(), BigDecimal.ZERO);
            if (item.getReturnCount().equals(returnCount)) {
            // 历史/导入数据的退货数量、入库数量可能为空,按 0 处理,避免 NPE
            if (ObjectUtil.defaultIfNull(item.getReturnCount(), BigDecimal.ZERO).compareTo(returnCount) == 0) {
                return;
            }
            if (returnCount.compareTo(item.getInCount()) > 0) {
            BigDecimal inCount = ObjectUtil.defaultIfNull(item.getInCount(), BigDecimal.ZERO);
            if (returnCount.compareTo(inCount) > 0) {
                throw exception(PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED,
                        "产品ID:" + item.getProductId(), item.getInCount());
                        "产品ID:" + item.getProductId(), inCount);
            }
            purchaseOrderItemMapper.updateById(new ErpPurchaseOrderItemDO().setId(item.getId()).setReturnCount(returnCount));
        });