2026-06-05 d1fac30e634e33edd29e3440de1f91da84c150c1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package com.ruoyi.account.service.impl.purchase;
 
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.ruoyi.account.bean.dto.purchase.AccountPurchasePaymentDto;
import com.ruoyi.account.bean.vo.purchase.AccountPurchasePaymentVo;
import com.ruoyi.account.mapper.AccountStatementDetailsMapper;
import com.ruoyi.account.mapper.purchase.AccountPaymentApplicationMapper;
import com.ruoyi.account.mapper.purchase.AccountPurchasePaymentMapper;
import com.ruoyi.account.pojo.AccountStatementDetails;
import com.ruoyi.account.pojo.purchase.AccountPaymentApplication;
import com.ruoyi.account.pojo.purchase.AccountPurchasePayment;
import com.ruoyi.account.service.purchase.AccountPurchasePaymentService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Random;
 
/**
 * <p>
 * 财务管理--付款单 服务实现类
 * </p>
 *
 * @author 芯导软件(江苏)有限公司
 * @since 2026-05-19 04:14:51
 */
@Service
@RequiredArgsConstructor
public class AccountPurchasePaymentServiceImpl extends ServiceImpl<AccountPurchasePaymentMapper, AccountPurchasePayment> implements AccountPurchasePaymentService {
 
    private static final DateTimeFormatter CODE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyMMddHHmmss");
    private final AccountPurchasePaymentMapper accountPurchasePaymentMapper;
    private final AccountStatementDetailsMapper accountStatementDetailsMapper;
    private final AccountPaymentApplicationMapper accountPaymentApplicationMapper;
 
    @Override
    public IPage<AccountPurchasePaymentVo> listPageAccountPurchasePayment(Page page, AccountPurchasePaymentDto accountPurchasePaymentDto) {
        return accountPurchasePaymentMapper.listPageAccountPurchasePayment(page, accountPurchasePaymentDto);
    }
 
    @Override
    public boolean addAccountPurchasePayment(AccountPurchasePayment accountPurchasePayment) {
        if (StringUtils.isEmpty(accountPurchasePayment.getPaymentNumber())) {
            accountPurchasePayment.setPaymentNumber(genAccountPurchasePaymentNo());
        }
        //校验付款申请是否存在且审核通过
        AccountPaymentApplication accountPaymentApplication = accountPaymentApplicationMapper.selectById(accountPurchasePayment.getAccountPaymentApplicationId());
        if (accountPaymentApplication == null) {
            throw new ServiceException("付款申请不存在");
        }
        if (accountPaymentApplication.getStatus() == null || accountPaymentApplication.getStatus() != 1) {
            throw new ServiceException("付款申请未审核通过,不能付款");
        }
        //校验累计付款金额不能超过申请金额
        List<AccountPurchasePayment> accountPurchasePayments = accountPurchasePaymentMapper.selectList(
                Wrappers.<AccountPurchasePayment>lambdaQuery()
                        .eq(AccountPurchasePayment::getAccountPaymentApplicationId, accountPurchasePayment.getAccountPaymentApplicationId()));
        BigDecimal totalPaymentAmount = accountPurchasePayments.stream()
                .map(AccountPurchasePayment::getPaymentAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal newTotal = totalPaymentAmount.add(accountPurchasePayment.getPaymentAmount());
        if (newTotal.compareTo(accountPaymentApplication.getPaymentAmount()) > 0) {
            throw new ServiceException("累计付款金额不能超过申请金额");
        }
        boolean result = save(accountPurchasePayment);
        // 更新付款申请的付款状态
        if (result) {
            updatePaymentStatus(accountPaymentApplication, newTotal);
        }
        return result;
    }
 
    @Override
    public void exportAccountPurchasePayment(HttpServletResponse response, AccountPurchasePaymentDto accountPurchasePaymentDto) {
        List<AccountPurchasePaymentVo> list = accountPurchasePaymentMapper.listPageAccountPurchasePayment(new Page(1,-1),accountPurchasePaymentDto).getRecords();
        ExcelUtil<AccountPurchasePaymentVo> util = new ExcelUtil<>(AccountPurchasePaymentVo.class);
        util.exportExcel(response, list , "付款单");
    }
 
    @Override
    public boolean deleteAccountPurchasePayment(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        //如果该付款单已经生成对账单则无法删除
        List<AccountPurchasePayment> accountPurchasePayments = accountPurchasePaymentMapper.selectByIds(ids);
        List<String> strings = accountPurchasePayments.stream().map(AccountPurchasePayment::getPaymentNumber).toList();
        List<AccountStatementDetails> accountStatementDetails = accountStatementDetailsMapper.selectList(Wrappers.<AccountStatementDetails>lambdaQuery()
                .in(AccountStatementDetails::getReceiptNumber, strings));
        if (CollectionUtils.isNotEmpty(accountStatementDetails)){
            throw new ServiceException("该付款单已经生成对账单,无法删除");
        }
        boolean result = removeByIds(ids);
        // 删除成功后,更新付款申请的付款状态
        if (result) {
            for (AccountPurchasePayment payment : accountPurchasePayments) {
                if (payment.getAccountPaymentApplicationId() != null) {
                    AccountPaymentApplication application = accountPaymentApplicationMapper.selectById(payment.getAccountPaymentApplicationId());
                    if (application != null) {
                        // 计算剩余付款金额
                        List<AccountPurchasePayment> remainingPayments = accountPurchasePaymentMapper.selectList(
                                Wrappers.<AccountPurchasePayment>lambdaQuery()
                                        .eq(AccountPurchasePayment::getAccountPaymentApplicationId, application.getId()));
                        BigDecimal remainingAmount = remainingPayments.stream()
                                .map(AccountPurchasePayment::getPaymentAmount)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        updatePaymentStatus(application, remainingAmount);
                    }
                }
            }
        }
        return result;
    }
 
    /**
     * 更新付款申请的付款状态
     * @param application 付款申请
     * @param paidAmount 已付款金额
     */
    private void updatePaymentStatus(AccountPaymentApplication application, BigDecimal paidAmount) {
        BigDecimal applyAmount = application.getPaymentAmount();
        int newPaymentStatus;
        if (paidAmount.compareTo(BigDecimal.ZERO) == 0) {
            newPaymentStatus = 0; // 未付款
        } else if (paidAmount.compareTo(applyAmount) < 0) {
            newPaymentStatus = 1; // 部分付款
        } else {
            newPaymentStatus = 2; // 已付款
        }
        if (application.getPaymentStatus() == null || application.getPaymentStatus() != newPaymentStatus) {
            application.setPaymentStatus(newPaymentStatus);
            accountPaymentApplicationMapper.updateById(application);
        }
    }
 
    private String genAccountPurchasePaymentNo() {
        return "SK" + LocalDateTime.now().format(CODE_TIME_FORMATTER) + new Random().nextInt(10);
    }
}