Commit 9e3858aea70c16aa596f1b0c055c30e1359038cf

Authored by YunaiV
1 parent 0d551a44

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

Showing 15 changed files with 163 additions and 21 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
... ... @@ -311,4 +311,8 @@ public class CollectionUtils {
311 311 return obj == null ? Collections.emptyList() : Collections.singleton(obj);
312 312 }
313 313  
  314 + public static <T> List<T> newArrayList(List<List<T>> list) {
  315 + return list.stream().flatMap(Collection::stream).collect(Collectors.toList());
  316 + }
  317 +
314 318 }
... ...
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
34 34 ErrorCode PURCHASE_IN_NO_EXISTS = new ErrorCode(1_030_102_004, "生成入库单失败,请重新提交");
35 35 ErrorCode PURCHASE_IN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_102_005, "采购入库单({})已审核,无法修改");
36 36 ErrorCode PURCHASE_IN_NOT_APPROVE = new ErrorCode(1_030_102_006, "采购入库单未审核,无法操作");
  37 + ErrorCode PURCHASE_IN_FAIL_PAYMENT_PRICE_EXCEED = new ErrorCode(1_030_102_007, "付款金额({})超过采购入库单总金额({})");
  38 + ErrorCode PURCHASE_IN_PROCESS_FAIL_EXISTS_PAYMENT = new ErrorCode(1_030_102_008, "反审核失败,已存在对应的付款单");
37 39  
38 40 // ========== ERP 采购退货(1-030-103-000) ==========
39 41 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
43 45 ErrorCode PURCHASE_RETURN_NO_EXISTS = new ErrorCode(1_030_103_004, "生成退货单失败,请重新提交");
44 46 ErrorCode PURCHASE_RETURN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_103_005, "采购退货单({})已审核,无法修改");
45 47 ErrorCode PURCHASE_RETURN_NOT_APPROVE = new ErrorCode(1_030_103_006, "采购退货单未审核,无法操作");
  48 + ErrorCode PURCHASE_RETURN_FAIL_REFUND_PRICE_EXCEED = new ErrorCode(1_030_103_007, "退款金额({})超过采购退货单总金额({})");
  49 + ErrorCode PURCHASE_RETURN_PROCESS_FAIL_EXISTS_REFUND = new ErrorCode(1_030_103_008, "反审核失败,已存在对应的退款单");
46 50  
47 51 // ========== ERP 客户(1-030-200-000)==========
48 52 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
145 149 ErrorCode FINANCE_PAYMENT_PROCESS_FAIL = new ErrorCode(1_030_601_002, "反审核失败,只有已审核的付款单才能反审核");
146 150 ErrorCode FINANCE_PAYMENT_APPROVE_FAIL = new ErrorCode(1_030_601_003, "审核失败,只有未审核的付款单才能审核");
147 151 ErrorCode FINANCE_PAYMENT_NO_EXISTS = new ErrorCode(1_030_601_004, "生成付款单号失败,请重新提交");
  152 + ErrorCode FINANCE_PAYMENT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_601_005, "付款单({})已审核,无法修改");
148 153  
149 154 }
... ...
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;
12 12 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO;
13 13 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentRespVO;
14 14 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
15 16 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO;
16 17 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentItemDO;
17 18 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  19 +import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
18 20 import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService;
19 21 import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
20 22 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
... ... @@ -48,6 +50,8 @@ public class ErpFinancePaymentController {
48 50 private ErpFinancePaymentService financePaymentService;
49 51 @Resource
50 52 private ErpSupplierService supplierService;
  53 + @Resource
  54 + private ErpAccountService accountService;
51 55  
52 56 @Resource
53 57 private AdminUserApi adminUserApi;
... ... @@ -130,13 +134,17 @@ public class ErpFinancePaymentController {
130 134 // 1.2 供应商信息
131 135 Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(
132 136 convertSet(pageResult.getList(), ErpFinancePaymentDO::getSupplierId));
133   - // 1.3 管理员信息
  137 + // 1.3 结算账户信息
  138 + Map<Long, ErpAccountDO> accountMap = accountService.getAccountMap(
  139 + convertSet(pageResult.getList(), ErpFinancePaymentDO::getAccountId));
  140 + // 1.4 管理员信息
134 141 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
135 142 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getFinanceUserId())));
136 143 // 2. 开始拼接
137 144 return BeanUtils.toBean(pageResult, ErpFinancePaymentRespVO.class, payment -> {
138 145 payment.setItems(BeanUtils.toBean(financePaymentItemMap.get(payment.getId()), ErpFinancePaymentRespVO.Item.class));
139 146 MapUtils.findAndThen(supplierMap, payment.getSupplierId(), supplier -> payment.setSupplierName(supplier.getName()));
  147 + MapUtils.findAndThen(accountMap, payment.getAccountId(), account -> payment.setAccountName(account.getName()));
140 148 MapUtils.findAndThen(userMap, Long.parseLong(payment.getCreator()), user -> payment.setCreatorName(user.getNickname()));
141 149 MapUtils.findAndThen(userMap, payment.getFinanceUserId(), user -> payment.setFinanceUserName(user.getNickname()));
142 150 });
... ...
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 {
37 37  
38 38 @Schema(description = "付款账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28989")
39 39 private Long accountId;
  40 + @Schema(description = "付款账户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  41 + private String accountName;
40 42  
41 43 @Schema(description = "合计价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "13832")
42 44 private BigDecimal totalPrice;
... ...
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 {
17 17 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23752")
18 18 private Long id;
19 19  
20   - @Schema(description = "付款单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "FKD888")
21   - @NotEmpty(message = "付款单号不能为空")
22   - private String no;
23   -
24 20 @Schema(description = "付款时间", requiredMode = Schema.RequiredMode.REQUIRED)
25 21 @NotNull(message = "付款时间不能为空")
26 22 private LocalDateTime paymentTime;
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentItemMapper.java
1 1 package cn.iocoder.yudao.module.erp.dal.mysql.finance;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.map.MapUtil;
3 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 6 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentItemDO;
  7 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 8 import org.apache.ibatis.annotations.Mapper;
6 9  
  10 +import java.math.BigDecimal;
7 11 import java.util.Collection;
8 12 import java.util.List;
  13 +import java.util.Map;
9 14  
10 15 /**
11 16 * ERP 付款单项 Mapper
... ... @@ -23,8 +28,17 @@ public interface ErpFinancePaymentItemMapper extends BaseMapperX&lt;ErpFinancePayme
23 28 return selectList(ErpFinancePaymentItemDO::getPaymentId, paymentIds);
24 29 }
25 30  
26   - default int deleteByPaymentId(Long paymentId) {
27   - return delete(ErpFinancePaymentItemDO::getPaymentId, paymentId);
  31 + default BigDecimal selectPaymentPriceSumByBizIdAndBizType(Long bizId, Integer bizType) {
  32 + // SQL sum 查询
  33 + List<Map<String, Object>> result = selectMaps(new QueryWrapper<ErpFinancePaymentItemDO>()
  34 + .select("SUM(payment_price) AS paymentPriceSum")
  35 + .eq("biz_id", bizId)
  36 + .eq("biz_type", bizType));
  37 + // 获得数量
  38 + if (CollUtil.isEmpty(result)) {
  39 + return BigDecimal.ZERO;
  40 + }
  41 + return BigDecimal.valueOf(MapUtil.getDouble(result.get(0), "paymentPriceSum", 0D));
28 42 }
29 43  
30 44 }
31 45 \ No newline at end of file
... ...
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;
7 7 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO;
8 8 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
9 9 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
  10 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
10 11 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
11 12 import org.apache.ibatis.annotations.Mapper;
12 13  
... ... @@ -41,7 +42,8 @@ public interface ErpPurchaseInMapper extends BaseMapperX&lt;ErpPurchaseInDO&gt; {
41 42 query.apply("t.payment_price = t.total_price");
42 43 }
43 44 if (Boolean.TRUE.equals(reqVO.getPaymentEnable())) {
44   - query.apply("t.payment_price < t.total_price");
  45 + query.eq(ErpPurchaseInDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
  46 + .apply("t.payment_price < t.total_price");
45 47 }
46 48 if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
47 49 query.leftJoin(ErpPurchaseInItemDO.class, ErpPurchaseInItemDO::getInId, ErpPurchaseInDO::getId)
... ...
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;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 6 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
7 8 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO;
8 9 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO;
  10 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
9 11 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
10 12 import org.apache.ibatis.annotations.Mapper;
11 13  
... ... @@ -40,7 +42,8 @@ public interface ErpPurchaseReturnMapper extends BaseMapperX&lt;ErpPurchaseReturnDO
40 42 query.apply("t.refund_price = t.total_price");
41 43 }
42 44 if (Boolean.TRUE.equals(reqVO.getRefundEnable())) {
43   - query.apply("t.refund_price < t.total_price");
  45 + query.eq(ErpPurchaseInDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
  46 + .apply("t.refund_price < t.total_price");
44 47 }
45 48 if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
46 49 query.leftJoin(ErpPurchaseReturnItemDO.class, ErpPurchaseReturnItemDO::getReturnId, ErpPurchaseReturnDO::getId)
... ...
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
6 6 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
7 7 import jakarta.validation.Valid;
8 8  
  9 +import java.util.Collection;
9 10 import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
10 14  
11 15 /**
12 16 * ERP 结算账户 Service 接口
... ... @@ -70,6 +74,24 @@ public interface ErpAccountService {
70 74 List<ErpAccountDO> getAccountListByStatus(Integer status);
71 75  
72 76 /**
  77 + * 获得结算账户列表
  78 + *
  79 + * @param ids 编号数组
  80 + * @return 结算账户列表
  81 + */
  82 + List<ErpAccountDO> getAccountList(Collection<Long> ids);
  83 +
  84 + /**
  85 + * 获得结算账户 Map
  86 + *
  87 + * @param ids 编号数组
  88 + * @return 结算账户 Map
  89 + */
  90 + default Map<Long, ErpAccountDO> getAccountMap(Collection<Long> ids) {
  91 + return convertMap(getAccountList(ids), ErpAccountDO::getId);
  92 + }
  93 +
  94 + /**
73 95 * 获得结算账户分页
74 96 *
75 97 * @param pageReqVO 分页查询
... ...
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;
11 11 import org.springframework.stereotype.Service;
12 12 import org.springframework.validation.annotation.Validated;
13 13  
  14 +import java.util.Collection;
14 15 import java.util.List;
15 16  
16 17 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -99,6 +100,11 @@ public class ErpAccountServiceImpl implements ErpAccountService {
99 100 }
100 101  
101 102 @Override
  103 + public List<ErpAccountDO> getAccountList(Collection<Long> ids) {
  104 + return accountMapper.selectBatchIds(ids);
  105 + }
  106 +
  107 + @Override
102 108 public PageResult<ErpAccountDO> getAccountPage(ErpAccountPageReqVO pageReqVO) {
103 109 return accountMapper.selectPage(pageReqVO);
104 110 }
... ...
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
1 1 package cn.iocoder.yudao.module.erp.service.finance;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
4 5 import cn.hutool.core.util.ObjectUtil;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 9 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO;
8 10 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO;
... ... @@ -68,7 +70,8 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
68 70 @Transactional(rollbackFor = Exception.class)
69 71 public Long createFinancePayment(ErpFinancePaymentSaveReqVO createReqVO) {
70 72 // 1.1 校验订单项的有效性
71   - List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(createReqVO.getItems());
  73 + List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(
  74 + createReqVO.getSupplierId(), createReqVO.getItems());
72 75 // 1.2 校验供应商
73 76 supplierService.validateSupplier(createReqVO.getSupplierId());
74 77 // 1.3 校验结算账户
... ... @@ -102,7 +105,7 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
102 105 // 1.1 校验存在
103 106 ErpFinancePaymentDO payment = validateFinancePaymentExists(updateReqVO.getId());
104 107 if (ErpAuditStatus.APPROVE.getStatus().equals(payment.getStatus())) {
105   - throw exception(SALE_ORDER_UPDATE_FAIL_APPROVE, payment.getNo());
  108 + throw exception(FINANCE_PAYMENT_UPDATE_FAIL_APPROVE, payment.getNo());
106 109 }
107 110 // 1.2 校验供应商
108 111 supplierService.validateSupplier(updateReqVO.getSupplierId());
... ... @@ -115,7 +118,8 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
115 118 adminUserApi.validateUser(updateReqVO.getFinanceUserId());
116 119 }
117 120 // 1.5 校验付款单项的有效性
118   - List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(updateReqVO.getItems());
  121 + List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(
  122 + updateReqVO.getSupplierId(), updateReqVO.getItems());
119 123  
120 124 // 2.1 更新付款单
121 125 ErpFinancePaymentDO updateObj = BeanUtils.toBean(updateReqVO, ErpFinancePaymentDO.class);
... ... @@ -123,6 +127,9 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
123 127 financePaymentMapper.updateById(updateObj);
124 128 // 2.2 更新付款单项
125 129 updateFinancePaymentItemList(updateReqVO.getId(), paymentItems);
  130 +
  131 + // 3. 更新采购入库、退货的付款金额情况
  132 + updatePurchasePrice(paymentItems);
126 133 }
127 134  
128 135 private void calculateTotalPrice(ErpFinancePaymentDO payment, List<ErpFinancePaymentItemDO> paymentItems) {
... ... @@ -138,25 +145,29 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
138 145 ErpFinancePaymentDO payment = validateFinancePaymentExists(id);
139 146 // 1.2 校验状态
140 147 if (payment.getStatus().equals(status)) {
141   - throw exception(approve ? SALE_ORDER_APPROVE_FAIL : SALE_ORDER_PROCESS_FAIL);
  148 + throw exception(approve ? FINANCE_PAYMENT_APPROVE_FAIL : FINANCE_PAYMENT_PROCESS_FAIL);
142 149 }
143 150  
144 151 // 2. 更新状态
145 152 int updateCount = financePaymentMapper.updateByIdAndStatus(id, payment.getStatus(),
146 153 new ErpFinancePaymentDO().setStatus(status));
147 154 if (updateCount == 0) {
148   - throw exception(approve ? SALE_ORDER_APPROVE_FAIL : SALE_ORDER_PROCESS_FAIL);
  155 + throw exception(approve ? FINANCE_PAYMENT_APPROVE_FAIL : FINANCE_PAYMENT_PROCESS_FAIL);
149 156 }
150 157 }
151 158  
152   - private List<ErpFinancePaymentItemDO> validateFinancePaymentItems(List<ErpFinancePaymentSaveReqVO.Item> list) {
  159 + private List<ErpFinancePaymentItemDO> validateFinancePaymentItems(
  160 + Long supplierId,
  161 + List<ErpFinancePaymentSaveReqVO.Item> list) {
153 162 return convertList(list, o -> BeanUtils.toBean(o, ErpFinancePaymentItemDO.class, item -> {
154 163 if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.PURCHASE_IN.getType())) {
155 164 ErpPurchaseInDO purchaseIn = purchaseInService.validatePurchaseIn(item.getBizId());
  165 + Assert.equals(purchaseIn.getSupplierId(), supplierId, "供应商必须相同");
156 166 item.setTotalPrice(purchaseIn.getTotalPrice()).setBizNo(purchaseIn.getNo());
157 167 } else if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.PURCHASE_RETURN.getType())) {
158 168 ErpPurchaseReturnDO purchaseReturn = purchaseReturnService.validatePurchaseReturn(item.getBizId());
159   - item.setTotalPrice(purchaseReturn.getTotalPrice()).setBizNo(purchaseReturn.getNo());
  169 + Assert.equals(purchaseReturn.getSupplierId(), supplierId, "供应商必须相同");
  170 + item.setTotalPrice(purchaseReturn.getTotalPrice().negate()).setBizNo(purchaseReturn.getNo());
160 171 } else {
161 172 throw new IllegalArgumentException("业务类型不正确:" + item.getBizType());
162 173 }
... ... @@ -180,6 +191,23 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
180 191 if (CollUtil.isNotEmpty(diffList.get(2))) {
181 192 financePaymentItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpFinancePaymentItemDO::getId));
182 193 }
  194 +
  195 + // 第三步,更新采购入库、退货的付款金额情况
  196 + updatePurchasePrice(CollectionUtils.newArrayList(diffList));
  197 + }
  198 +
  199 + private void updatePurchasePrice(List<ErpFinancePaymentItemDO> paymentItems) {
  200 + paymentItems.forEach(paymentItem -> {
  201 + BigDecimal totalPaymentPrice = financePaymentItemMapper.selectPaymentPriceSumByBizIdAndBizType(
  202 + paymentItem.getBizId(), paymentItem.getBizType());
  203 + if (ErpBizTypeEnum.PURCHASE_IN.getType().equals(paymentItem.getBizType())) {
  204 + purchaseInService.updatePurchaseInPaymentPrice(paymentItem.getBizId(), totalPaymentPrice);
  205 + } else if (ErpBizTypeEnum.PURCHASE_RETURN.getType().equals(paymentItem.getBizType())) {
  206 + purchaseReturnService.updatePurchaseReturnRefundPrice(paymentItem.getBizId(), totalPaymentPrice.negate());
  207 + } else {
  208 + throw new IllegalArgumentException("业务类型不正确:" + paymentItem.getBizType());
  209 + }
  210 + });
183 211 }
184 212  
185 213 @Override
... ... @@ -192,7 +220,7 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
192 220 }
193 221 payments.forEach(payment -> {
194 222 if (ErpAuditStatus.APPROVE.getStatus().equals(payment.getStatus())) {
195   - throw exception(SALE_ORDER_DELETE_FAIL_APPROVE, payment.getNo());
  223 + throw exception(FINANCE_PAYMENT_DELETE_FAIL_APPROVE, payment.getNo());
196 224 }
197 225 });
198 226  
... ... @@ -201,14 +229,18 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
201 229 // 2.1 删除付款单
202 230 financePaymentMapper.deleteById(payment.getId());
203 231 // 2.2 删除付款单项
204   - financePaymentItemMapper.deleteByPaymentId(payment.getId());
  232 + List<ErpFinancePaymentItemDO> paymentItems = financePaymentItemMapper.selectListByPaymentId(payment.getId());
  233 + financePaymentItemMapper.deleteBatchIds(convertSet(paymentItems, ErpFinancePaymentItemDO::getId));
  234 +
  235 + // 2.3 更新采购入库、退货的付款金额情况
  236 + updatePurchasePrice(paymentItems);
205 237 });
206 238 }
207 239  
208 240 private ErpFinancePaymentDO validateFinancePaymentExists(Long id) {
209 241 ErpFinancePaymentDO payment = financePaymentMapper.selectById(id);
210 242 if (payment == null) {
211   - throw exception(SALE_ORDER_NOT_EXISTS);
  243 + throw exception(FINANCE_PAYMENT_NOT_EXISTS);
212 244 }
213 245 return payment;
214 246 }
... ...
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;
7 7 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
8 8 import jakarta.validation.Valid;
9 9  
  10 +import java.math.BigDecimal;
10 11 import java.util.Collection;
11 12 import java.util.List;
12 13  
... ... @@ -41,6 +42,14 @@ public interface ErpPurchaseInService {
41 42 void updatePurchaseInStatus(Long id, Integer status);
42 43  
43 44 /**
  45 + * 更新采购入库的付款金额
  46 + *
  47 + * @param id 编号
  48 + * @param paymentPrice 付款金额
  49 + */
  50 + void updatePurchaseInPaymentPrice(Long id, BigDecimal paymentPrice);
  51 +
  52 + /**
44 53 * 删除采购入库
45 54 *
46 55 * @param ids 编号数组
... ...
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 {
163 163 if (purchaseIn.getStatus().equals(status)) {
164 164 throw exception(approve ? PURCHASE_IN_APPROVE_FAIL : PURCHASE_IN_PROCESS_FAIL);
165 165 }
166   - // TODO 芋艿:稍后加下校验
  166 + // 1.3 校验已付款
  167 + if (approve && purchaseIn.getPaymentPrice().compareTo(BigDecimal.ZERO) > 0) {
  168 + throw exception(PURCHASE_IN_PROCESS_FAIL_EXISTS_PAYMENT);
  169 + }
167 170  
168 171 // 2. 更新状态
169 172 int updateCount = purchaseInMapper.updateByIdAndStatus(id, purchaseIn.getStatus(),
... ... @@ -184,6 +187,18 @@ public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
184 187 });
185 188 }
186 189  
  190 + @Override
  191 + public void updatePurchaseInPaymentPrice(Long id, BigDecimal paymentPrice) {
  192 + ErpPurchaseInDO purchaseIn = purchaseInMapper.selectById(id);
  193 + if (purchaseIn.getPaymentPrice().equals(paymentPrice)) {
  194 + return;
  195 + }
  196 + if (paymentPrice.compareTo(purchaseIn.getTotalPrice()) > 0) {
  197 + throw exception(PURCHASE_IN_FAIL_PAYMENT_PRICE_EXCEED, purchaseIn.getTotalPrice(), paymentPrice);
  198 + }
  199 + purchaseInMapper.updateById(new ErpPurchaseInDO().setId(id).setPaymentPrice(paymentPrice));
  200 + }
  201 +
187 202 private List<ErpPurchaseInItemDO> validatePurchaseInItems(List<ErpPurchaseInSaveReqVO.Item> list) {
188 203 // 1. 校验产品存在
189 204 List<ErpProductDO> productList = productService.validProductList(
... ...
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;
7 7 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO;
8 8 import jakarta.validation.Valid;
9 9  
  10 +import java.math.BigDecimal;
10 11 import java.util.Collection;
11 12 import java.util.List;
12 13  
... ... @@ -41,6 +42,14 @@ public interface ErpPurchaseReturnService {
41 42 void updatePurchaseReturnStatus(Long id, Integer status);
42 43  
43 44 /**
  45 + * 更新采购退货的退款金额
  46 + *
  47 + * @param id 编号
  48 + * @param refundPrice 退款金额
  49 + */
  50 + void updatePurchaseReturnRefundPrice(Long id, BigDecimal refundPrice);
  51 +
  52 + /**
44 53 * 删除采购退货
45 54 *
46 55 * @param ids 编号数组
... ...
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 {
159 159 if (purchaseReturn.getStatus().equals(status)) {
160 160 throw exception(approve ? PURCHASE_RETURN_APPROVE_FAIL : PURCHASE_RETURN_PROCESS_FAIL);
161 161 }
162   - // TODO 芋艿:稍后加下校验
  162 + // 1.3 校验已退款
  163 + if (approve && purchaseReturn.getRefundPrice().compareTo(BigDecimal.ZERO) > 0) {
  164 + throw exception(PURCHASE_RETURN_PROCESS_FAIL_EXISTS_REFUND);
  165 + }
163 166  
164 167 // 2. 更新状态
165 168 int updateCount = purchaseReturnMapper.updateByIdAndStatus(id, purchaseReturn.getStatus(),
... ... @@ -180,6 +183,18 @@ public class ErpPurchaseReturnServiceImpl implements ErpPurchaseReturnService {
180 183 });
181 184 }
182 185  
  186 + @Override
  187 + public void updatePurchaseReturnRefundPrice(Long id, BigDecimal refundPrice) {
  188 + ErpPurchaseReturnDO purchaseReturn = purchaseReturnMapper.selectById(id);
  189 + if (purchaseReturn.getRefundPrice().equals(refundPrice)) {
  190 + return;
  191 + }
  192 + if (refundPrice.compareTo(purchaseReturn.getTotalPrice()) > 0) {
  193 + throw exception(PURCHASE_RETURN_FAIL_REFUND_PRICE_EXCEED, purchaseReturn.getTotalPrice(), refundPrice);
  194 + }
  195 + purchaseReturnMapper.updateById(new ErpPurchaseReturnDO().setId(id).setRefundPrice(refundPrice));
  196 + }
  197 +
183 198 private List<ErpPurchaseReturnItemDO> validatePurchaseReturnItems(List<ErpPurchaseReturnSaveReqVO.Item> list) {
184 199 // 1. 校验产品存在
185 200 List<ErpProductDO> productList = productService.validProductList(
... ...