Преглед изворни кода

✨ ERP:完成 payment 付款单的逻辑 100%

YunaiV пре 1 година
родитељ
комит
9e3858aea7
15 измењених фајлова са 163 додато и 21 уклоњено
  1. 4 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
  2. 5 0
      yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
  3. 9 1
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java
  4. 2 0
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java
  5. 0 4
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentSaveReqVO.java
  6. 16 2
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentItemMapper.java
  7. 3 1
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseInMapper.java
  8. 4 1
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseReturnMapper.java
  9. 22 0
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpAccountService.java
  10. 6 0
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpAccountServiceImpl.java
  11. 42 10
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
  12. 9 0
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInService.java
  13. 16 1
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInServiceImpl.java
  14. 9 0
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseReturnService.java
  15. 16 1
      yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseReturnServiceImpl.java

+ 4 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java

@@ -311,4 +311,8 @@ public class CollectionUtils {
         return obj == null ? Collections.emptyList() : Collections.singleton(obj);
     }
 
+    public static <T> List<T> newArrayList(List<List<T>> list) {
+        return list.stream().flatMap(Collection::stream).collect(Collectors.toList());
+    }
+
 }

+ 5 - 0
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java

@@ -34,6 +34,8 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00
     ErrorCode PURCHASE_IN_NO_EXISTS = new ErrorCode(1_030_102_004, "生成入库单失败,请重新提交");
     ErrorCode PURCHASE_IN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_102_005, "采购入库单({})已审核,无法修改");
     ErrorCode PURCHASE_IN_NOT_APPROVE = new ErrorCode(1_030_102_006, "采购入库单未审核,无法操作");
+    ErrorCode PURCHASE_IN_FAIL_PAYMENT_PRICE_EXCEED = new ErrorCode(1_030_102_007, "付款金额({})超过采购入库单总金额({})");
+    ErrorCode PURCHASE_IN_PROCESS_FAIL_EXISTS_PAYMENT = new ErrorCode(1_030_102_008, "反审核失败,已存在对应的付款单");
 
     // ========== ERP 采购退货(1-030-103-000) ==========
     ErrorCode PURCHASE_RETURN_NOT_EXISTS = new ErrorCode(1_030_103_000, "采购退货单不存在");
@@ -43,6 +45,8 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00
     ErrorCode PURCHASE_RETURN_NO_EXISTS = new ErrorCode(1_030_103_004, "生成退货单失败,请重新提交");
     ErrorCode PURCHASE_RETURN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_103_005, "采购退货单({})已审核,无法修改");
     ErrorCode PURCHASE_RETURN_NOT_APPROVE = new ErrorCode(1_030_103_006, "采购退货单未审核,无法操作");
+    ErrorCode PURCHASE_RETURN_FAIL_REFUND_PRICE_EXCEED = new ErrorCode(1_030_103_007, "退款金额({})超过采购退货单总金额({})");
+    ErrorCode PURCHASE_RETURN_PROCESS_FAIL_EXISTS_REFUND = new ErrorCode(1_030_103_008, "反审核失败,已存在对应的退款单");
 
     // ========== ERP 客户(1-030-200-000)==========
     ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在");
@@ -145,5 +149,6 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00
     ErrorCode FINANCE_PAYMENT_PROCESS_FAIL = new ErrorCode(1_030_601_002, "反审核失败,只有已审核的付款单才能反审核");
     ErrorCode FINANCE_PAYMENT_APPROVE_FAIL = new ErrorCode(1_030_601_003, "审核失败,只有未审核的付款单才能审核");
     ErrorCode FINANCE_PAYMENT_NO_EXISTS = new ErrorCode(1_030_601_004, "生成付款单号失败,请重新提交");
+    ErrorCode FINANCE_PAYMENT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_601_005, "付款单({})已审核,无法修改");
 
 }

+ 9 - 1
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java

@@ -12,9 +12,11 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentRespVO;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO;
+import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentItemDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
+import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
 import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@@ -48,6 +50,8 @@ public class ErpFinancePaymentController {
     private ErpFinancePaymentService financePaymentService;
     @Resource
     private ErpSupplierService supplierService;
+    @Resource
+    private ErpAccountService accountService;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -130,13 +134,17 @@ public class ErpFinancePaymentController {
         // 1.2 供应商信息
         Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(
                 convertSet(pageResult.getList(), ErpFinancePaymentDO::getSupplierId));
-        // 1.3 管理员信息
+        // 1.3 结算账户信息
+        Map<Long, ErpAccountDO> accountMap = accountService.getAccountMap(
+                convertSet(pageResult.getList(), ErpFinancePaymentDO::getAccountId));
+        // 1.4 管理员信息
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
                 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getFinanceUserId())));
         // 2. 开始拼接
         return BeanUtils.toBean(pageResult, ErpFinancePaymentRespVO.class, payment -> {
             payment.setItems(BeanUtils.toBean(financePaymentItemMap.get(payment.getId()), ErpFinancePaymentRespVO.Item.class));
             MapUtils.findAndThen(supplierMap, payment.getSupplierId(), supplier -> payment.setSupplierName(supplier.getName()));
+            MapUtils.findAndThen(accountMap, payment.getAccountId(), account -> payment.setAccountName(account.getName()));
             MapUtils.findAndThen(userMap, Long.parseLong(payment.getCreator()), user -> payment.setCreatorName(user.getNickname()));
             MapUtils.findAndThen(userMap, payment.getFinanceUserId(), user -> payment.setFinanceUserName(user.getNickname()));
         });

+ 2 - 0
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java

@@ -37,6 +37,8 @@ public class ErpFinancePaymentRespVO {
 
     @Schema(description = "付款账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28989")
     private Long accountId;
+    @Schema(description = "付款账户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
+    private String accountName;
 
     @Schema(description = "合计价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "13832")
     private BigDecimal totalPrice;

+ 0 - 4
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentSaveReqVO.java

@@ -17,10 +17,6 @@ public class ErpFinancePaymentSaveReqVO {
     @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23752")
     private Long id;
 
-    @Schema(description = "付款单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "FKD888")
-    @NotEmpty(message = "付款单号不能为空")
-    private String no;
-
     @Schema(description = "付款时间", requiredMode = Schema.RequiredMode.REQUIRED)
     @NotNull(message = "付款时间不能为空")
     private LocalDateTime paymentTime;

+ 16 - 2
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentItemMapper.java

@@ -1,11 +1,16 @@
 package cn.iocoder.yudao.module.erp.dal.mysql.finance;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentItemDO;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * ERP 付款单项 Mapper
@@ -23,8 +28,17 @@ public interface ErpFinancePaymentItemMapper extends BaseMapperX<ErpFinancePayme
         return selectList(ErpFinancePaymentItemDO::getPaymentId, paymentIds);
     }
 
-    default int deleteByPaymentId(Long paymentId) {
-        return delete(ErpFinancePaymentItemDO::getPaymentId, paymentId);
+    default BigDecimal selectPaymentPriceSumByBizIdAndBizType(Long bizId, Integer bizType) {
+        // SQL sum 查询
+        List<Map<String, Object>> result = selectMaps(new QueryWrapper<ErpFinancePaymentItemDO>()
+                .select("SUM(payment_price) AS paymentPriceSum")
+                .eq("biz_id", bizId)
+                .eq("biz_type", bizType));
+        // 获得数量
+        if (CollUtil.isEmpty(result)) {
+            return BigDecimal.ZERO;
+        }
+        return BigDecimal.valueOf(MapUtil.getDouble(result.get(0), "paymentPriceSum", 0D));
     }
 
 }

+ 3 - 1
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseInMapper.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
+import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -41,7 +42,8 @@ public interface ErpPurchaseInMapper extends BaseMapperX<ErpPurchaseInDO> {
             query.apply("t.payment_price = t.total_price");
         }
         if (Boolean.TRUE.equals(reqVO.getPaymentEnable())) {
-            query.apply("t.payment_price < t.total_price");
+            query.eq(ErpPurchaseInDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
+                    .apply("t.payment_price < t.total_price");
         }
         if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
             query.leftJoin(ErpPurchaseInItemDO.class, ErpPurchaseInItemDO::getInId, ErpPurchaseInDO::getId)

+ 4 - 1
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseReturnMapper.java

@@ -4,8 +4,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnPageReqVO;
+import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO;
+import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -40,7 +42,8 @@ public interface ErpPurchaseReturnMapper extends BaseMapperX<ErpPurchaseReturnDO
             query.apply("t.refund_price = t.total_price");
         }
         if (Boolean.TRUE.equals(reqVO.getRefundEnable())) {
-            query.apply("t.refund_price < t.total_price");
+            query.eq(ErpPurchaseInDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
+                    .apply("t.refund_price < t.total_price");
         }
         if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
             query.leftJoin(ErpPurchaseReturnItemDO.class, ErpPurchaseReturnItemDO::getReturnId, ErpPurchaseReturnDO::getId)

+ 22 - 0
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpAccountService.java

@@ -6,7 +6,11 @@ import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.account.ErpAccoun
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
 import jakarta.validation.Valid;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
 /**
  * ERP 结算账户 Service 接口
@@ -69,6 +73,24 @@ public interface ErpAccountService {
      */
     List<ErpAccountDO> getAccountListByStatus(Integer status);
 
+    /**
+     * 获得结算账户列表
+     *
+     * @param ids 编号数组
+     * @return 结算账户列表
+     */
+    List<ErpAccountDO> getAccountList(Collection<Long> ids);
+
+    /**
+     * 获得结算账户 Map
+     *
+     * @param ids 编号数组
+     * @return 结算账户 Map
+     */
+    default Map<Long, ErpAccountDO> getAccountMap(Collection<Long> ids) {
+        return convertMap(getAccountList(ids), ErpAccountDO::getId);
+    }
+
     /**
      * 获得结算账户分页
      *

+ 6 - 0
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpAccountServiceImpl.java

@@ -11,6 +11,7 @@ import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
+import java.util.Collection;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -98,6 +99,11 @@ public class ErpAccountServiceImpl implements ErpAccountService {
         return accountMapper.selectListByStatus(status);
     }
 
+    @Override
+    public List<ErpAccountDO> getAccountList(Collection<Long> ids) {
+        return accountMapper.selectBatchIds(ids);
+    }
+
     @Override
     public PageResult<ErpAccountDO> getAccountPage(ErpAccountPageReqVO pageReqVO) {
         return accountMapper.selectPage(pageReqVO);

+ 42 - 10
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java

@@ -1,8 +1,10 @@
 package cn.iocoder.yudao.module.erp.service.finance;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO;
@@ -68,7 +70,8 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
     @Transactional(rollbackFor = Exception.class)
     public Long createFinancePayment(ErpFinancePaymentSaveReqVO createReqVO) {
         // 1.1 校验订单项的有效性
-        List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(createReqVO.getItems());
+        List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(
+                createReqVO.getSupplierId(), createReqVO.getItems());
         // 1.2 校验供应商
         supplierService.validateSupplier(createReqVO.getSupplierId());
         // 1.3 校验结算账户
@@ -102,7 +105,7 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
         // 1.1 校验存在
         ErpFinancePaymentDO payment = validateFinancePaymentExists(updateReqVO.getId());
         if (ErpAuditStatus.APPROVE.getStatus().equals(payment.getStatus())) {
-            throw exception(SALE_ORDER_UPDATE_FAIL_APPROVE, payment.getNo());
+            throw exception(FINANCE_PAYMENT_UPDATE_FAIL_APPROVE, payment.getNo());
         }
         // 1.2 校验供应商
         supplierService.validateSupplier(updateReqVO.getSupplierId());
@@ -115,7 +118,8 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
             adminUserApi.validateUser(updateReqVO.getFinanceUserId());
         }
         // 1.5 校验付款单项的有效性
-        List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(updateReqVO.getItems());
+        List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(
+                updateReqVO.getSupplierId(), updateReqVO.getItems());
 
         // 2.1 更新付款单
         ErpFinancePaymentDO updateObj = BeanUtils.toBean(updateReqVO, ErpFinancePaymentDO.class);
@@ -123,6 +127,9 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
         financePaymentMapper.updateById(updateObj);
         // 2.2 更新付款单项
         updateFinancePaymentItemList(updateReqVO.getId(), paymentItems);
+
+        // 3. 更新采购入库、退货的付款金额情况
+        updatePurchasePrice(paymentItems);
     }
 
     private void calculateTotalPrice(ErpFinancePaymentDO payment, List<ErpFinancePaymentItemDO> paymentItems) {
@@ -138,25 +145,29 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
         ErpFinancePaymentDO payment = validateFinancePaymentExists(id);
         // 1.2 校验状态
         if (payment.getStatus().equals(status)) {
-            throw exception(approve ? SALE_ORDER_APPROVE_FAIL : SALE_ORDER_PROCESS_FAIL);
+            throw exception(approve ? FINANCE_PAYMENT_APPROVE_FAIL : FINANCE_PAYMENT_PROCESS_FAIL);
         }
 
         // 2. 更新状态
         int updateCount = financePaymentMapper.updateByIdAndStatus(id, payment.getStatus(),
                 new ErpFinancePaymentDO().setStatus(status));
         if (updateCount == 0) {
-            throw exception(approve ? SALE_ORDER_APPROVE_FAIL : SALE_ORDER_PROCESS_FAIL);
+            throw exception(approve ? FINANCE_PAYMENT_APPROVE_FAIL : FINANCE_PAYMENT_PROCESS_FAIL);
         }
     }
 
-    private List<ErpFinancePaymentItemDO> validateFinancePaymentItems(List<ErpFinancePaymentSaveReqVO.Item> list) {
+    private List<ErpFinancePaymentItemDO> validateFinancePaymentItems(
+            Long supplierId,
+            List<ErpFinancePaymentSaveReqVO.Item> list) {
         return convertList(list, o -> BeanUtils.toBean(o, ErpFinancePaymentItemDO.class, item -> {
             if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.PURCHASE_IN.getType())) {
                 ErpPurchaseInDO purchaseIn = purchaseInService.validatePurchaseIn(item.getBizId());
+                Assert.equals(purchaseIn.getSupplierId(), supplierId, "供应商必须相同");
                 item.setTotalPrice(purchaseIn.getTotalPrice()).setBizNo(purchaseIn.getNo());
             } else if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.PURCHASE_RETURN.getType())) {
                 ErpPurchaseReturnDO purchaseReturn = purchaseReturnService.validatePurchaseReturn(item.getBizId());
-                item.setTotalPrice(purchaseReturn.getTotalPrice()).setBizNo(purchaseReturn.getNo());
+                Assert.equals(purchaseReturn.getSupplierId(), supplierId, "供应商必须相同");
+                item.setTotalPrice(purchaseReturn.getTotalPrice().negate()).setBizNo(purchaseReturn.getNo());
             } else {
                 throw new IllegalArgumentException("业务类型不正确:" + item.getBizType());
             }
@@ -180,6 +191,23 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
         if (CollUtil.isNotEmpty(diffList.get(2))) {
             financePaymentItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpFinancePaymentItemDO::getId));
         }
+
+        // 第三步,更新采购入库、退货的付款金额情况
+        updatePurchasePrice(CollectionUtils.newArrayList(diffList));
+    }
+
+    private void updatePurchasePrice(List<ErpFinancePaymentItemDO> paymentItems) {
+        paymentItems.forEach(paymentItem -> {
+            BigDecimal totalPaymentPrice = financePaymentItemMapper.selectPaymentPriceSumByBizIdAndBizType(
+                    paymentItem.getBizId(), paymentItem.getBizType());
+            if (ErpBizTypeEnum.PURCHASE_IN.getType().equals(paymentItem.getBizType())) {
+                purchaseInService.updatePurchaseInPaymentPrice(paymentItem.getBizId(), totalPaymentPrice);
+            } else if (ErpBizTypeEnum.PURCHASE_RETURN.getType().equals(paymentItem.getBizType())) {
+                purchaseReturnService.updatePurchaseReturnRefundPrice(paymentItem.getBizId(), totalPaymentPrice.negate());
+            } else {
+                throw new IllegalArgumentException("业务类型不正确:" + paymentItem.getBizType());
+            }
+        });
     }
 
     @Override
@@ -192,7 +220,7 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
         }
         payments.forEach(payment -> {
             if (ErpAuditStatus.APPROVE.getStatus().equals(payment.getStatus())) {
-                throw exception(SALE_ORDER_DELETE_FAIL_APPROVE, payment.getNo());
+                throw exception(FINANCE_PAYMENT_DELETE_FAIL_APPROVE, payment.getNo());
             }
         });
 
@@ -201,14 +229,18 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
             // 2.1 删除付款单
             financePaymentMapper.deleteById(payment.getId());
             // 2.2 删除付款单项
-            financePaymentItemMapper.deleteByPaymentId(payment.getId());
+            List<ErpFinancePaymentItemDO> paymentItems = financePaymentItemMapper.selectListByPaymentId(payment.getId());
+            financePaymentItemMapper.deleteBatchIds(convertSet(paymentItems, ErpFinancePaymentItemDO::getId));
+
+            // 2.3 更新采购入库、退货的付款金额情况
+            updatePurchasePrice(paymentItems);
         });
     }
 
     private ErpFinancePaymentDO validateFinancePaymentExists(Long id) {
         ErpFinancePaymentDO payment = financePaymentMapper.selectById(id);
         if (payment == null) {
-            throw exception(SALE_ORDER_NOT_EXISTS);
+            throw exception(FINANCE_PAYMENT_NOT_EXISTS);
         }
         return payment;
     }

+ 9 - 0
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInService.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
 import jakarta.validation.Valid;
 
+import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
 
@@ -40,6 +41,14 @@ public interface ErpPurchaseInService {
      */
     void updatePurchaseInStatus(Long id, Integer status);
 
+    /**
+     * 更新采购入库的付款金额
+     *
+     * @param id 编号
+     * @param paymentPrice 付款金额
+     */
+    void updatePurchaseInPaymentPrice(Long id, BigDecimal paymentPrice);
+
     /**
      * 删除采购入库
      *

+ 16 - 1
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInServiceImpl.java

@@ -163,7 +163,10 @@ public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
         if (purchaseIn.getStatus().equals(status)) {
             throw exception(approve ? PURCHASE_IN_APPROVE_FAIL : PURCHASE_IN_PROCESS_FAIL);
         }
-        // TODO 芋艿:稍后加下校验
+        // 1.3 校验已付款
+        if (approve && purchaseIn.getPaymentPrice().compareTo(BigDecimal.ZERO) > 0) {
+            throw exception(PURCHASE_IN_PROCESS_FAIL_EXISTS_PAYMENT);
+        }
 
         // 2. 更新状态
         int updateCount = purchaseInMapper.updateByIdAndStatus(id, purchaseIn.getStatus(),
@@ -184,6 +187,18 @@ public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
         });
     }
 
+    @Override
+    public void updatePurchaseInPaymentPrice(Long id, BigDecimal paymentPrice) {
+        ErpPurchaseInDO purchaseIn = purchaseInMapper.selectById(id);
+        if (purchaseIn.getPaymentPrice().equals(paymentPrice)) {
+            return;
+        }
+        if (paymentPrice.compareTo(purchaseIn.getTotalPrice()) > 0) {
+            throw exception(PURCHASE_IN_FAIL_PAYMENT_PRICE_EXCEED, purchaseIn.getTotalPrice(), paymentPrice);
+        }
+        purchaseInMapper.updateById(new ErpPurchaseInDO().setId(id).setPaymentPrice(paymentPrice));
+    }
+
     private List<ErpPurchaseInItemDO> validatePurchaseInItems(List<ErpPurchaseInSaveReqVO.Item> list) {
         // 1. 校验产品存在
         List<ErpProductDO> productList = productService.validProductList(

+ 9 - 0
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseReturnService.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO;
 import jakarta.validation.Valid;
 
+import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
 
@@ -40,6 +41,14 @@ public interface ErpPurchaseReturnService {
      */
     void updatePurchaseReturnStatus(Long id, Integer status);
 
+    /**
+     * 更新采购退货的退款金额
+     *
+     * @param id 编号
+     * @param refundPrice 退款金额
+     */
+    void updatePurchaseReturnRefundPrice(Long id, BigDecimal refundPrice);
+
     /**
      * 删除采购退货
      *

+ 16 - 1
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseReturnServiceImpl.java

@@ -159,7 +159,10 @@ public class ErpPurchaseReturnServiceImpl implements ErpPurchaseReturnService {
         if (purchaseReturn.getStatus().equals(status)) {
             throw exception(approve ? PURCHASE_RETURN_APPROVE_FAIL : PURCHASE_RETURN_PROCESS_FAIL);
         }
-        // TODO 芋艿:稍后加下校验
+        // 1.3 校验已退款
+        if (approve && purchaseReturn.getRefundPrice().compareTo(BigDecimal.ZERO) > 0) {
+            throw exception(PURCHASE_RETURN_PROCESS_FAIL_EXISTS_REFUND);
+        }
 
         // 2. 更新状态
         int updateCount = purchaseReturnMapper.updateByIdAndStatus(id, purchaseReturn.getStatus(),
@@ -180,6 +183,18 @@ public class ErpPurchaseReturnServiceImpl implements ErpPurchaseReturnService {
         });
     }
 
+    @Override
+    public void updatePurchaseReturnRefundPrice(Long id, BigDecimal refundPrice) {
+        ErpPurchaseReturnDO purchaseReturn = purchaseReturnMapper.selectById(id);
+        if (purchaseReturn.getRefundPrice().equals(refundPrice)) {
+            return;
+        }
+        if (refundPrice.compareTo(purchaseReturn.getTotalPrice()) > 0) {
+            throw exception(PURCHASE_RETURN_FAIL_REFUND_PRICE_EXCEED, purchaseReturn.getTotalPrice(), refundPrice);
+        }
+        purchaseReturnMapper.updateById(new ErpPurchaseReturnDO().setId(id).setRefundPrice(refundPrice));
+    }
+
     private List<ErpPurchaseReturnItemDO> validatePurchaseReturnItems(List<ErpPurchaseReturnSaveReqVO.Item> list) {
         // 1. 校验产品存在
         List<ErpProductDO> productList = productService.validProductList(