| | |
| | | |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import javax.annotation.Resource; |
| | | |
| | | import lombok.NonNull; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.scheduling.annotation.Async; |
| | |
| | | import com.ruoyi.common.core.service.BaseService; |
| | | |
| | | import com.ruoyi.cwgl.mapper.FundFlowClaimDetailMapper; |
| | | import com.ruoyi.cwgl.mapper.FundFlowMapper; |
| | | import com.ruoyi.cwgl.domain.FundFlowClaimDetail; |
| | | import com.ruoyi.cwgl.domain.FundFlow; |
| | | import com.ruoyi.cwgl.domain.ReceivableBillSettlementDetail; |
| | | import com.ruoyi.cwgl.domain.PayableBillSettlementDetail; |
| | | import com.ruoyi.cwgl.domain.ReceivableBillManagement; |
| | | import com.ruoyi.cwgl.domain.PayableBillManagement; |
| | | import com.ruoyi.cwgl.service.IFundFlowClaimDetailService; |
| | | import com.ruoyi.cwgl.service.IReceivableBillSettlementDetailService; |
| | | import com.ruoyi.cwgl.service.IPayableBillSettlementDetailService; |
| | | import com.ruoyi.cwgl.service.IReceivableBillManagementService; |
| | | import com.ruoyi.cwgl.service.IPayableBillManagementService; |
| | | import com.ruoyi.common.core.text.Convert; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * 账单认领明细Service业务层处理 |
| | |
| | | protected final Logger logger = LoggerFactory.getLogger(getClass()); |
| | | @Resource |
| | | private FundFlowClaimDetailMapper fundFlowClaimDetailMapper; |
| | | |
| | | @Resource |
| | | private FundFlowMapper fundFlowMapper; |
| | | |
| | | @Resource |
| | | private IReceivableBillSettlementDetailService receivableBillSettlementDetailService; |
| | | |
| | | @Resource |
| | | private IPayableBillSettlementDetailService payableBillSettlementDetailService; |
| | | |
| | | @Resource |
| | | private IReceivableBillManagementService receivableBillManagementService; |
| | | |
| | | @Resource |
| | | private IPayableBillManagementService payableBillManagementService; |
| | | |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public int deleteFundFlowClaimDetailByIds(String ids) |
| | | { |
| | | |
| | | return deleteFundFlowClaimDetailByIds(Convert.toIntArray(ids)); |
| | | } |
| | | |
| | |
| | | @Override |
| | | public int deleteFundFlowClaimDetailByIds(Integer[] ids) |
| | | { |
| | | if (ids == null || ids.length == 0) { |
| | | throw new RuntimeException("删除的认领明细ID不能为空"); |
| | | } |
| | | |
| | | // 由于删除只会有一条记录,取第一条进行处理 |
| | | Integer id = ids[0]; |
| | | FundFlowClaimDetail claimDetail = fundFlowClaimDetailMapper.selectFundFlowClaimDetailById(id); |
| | | if (claimDetail == null) { |
| | | throw new RuntimeException("未找到要删除的认领明细记录,ID: " + id); |
| | | } |
| | | |
| | | Integer fundFlowId = claimDetail.getFundFlowId(); |
| | | BigDecimal deleteAmount = claimDetail.getClaimAmount(); |
| | | |
| | | // 查询资金流水信息 |
| | | FundFlow fundFlow = fundFlowMapper.selectFundFlowById(fundFlowId); |
| | | if (fundFlow == null) { |
| | | throw new RuntimeException("资金流水不存在,ID: " + fundFlowId); |
| | | } |
| | | |
| | | // 更新资金流水的已认领金额 |
| | | BigDecimal newClaimedAmount = fundFlow.getClaimedAmount().subtract(deleteAmount); |
| | | if (newClaimedAmount.compareTo(BigDecimal.ZERO) < 0) { |
| | | newClaimedAmount = BigDecimal.ZERO; |
| | | } |
| | | |
| | | // 根据新的认领金额设置状态 |
| | | String newStatus =fundFlow.getStatus(); |
| | | if (newClaimedAmount.compareTo(BigDecimal.ZERO) == 0) { |
| | | // 已认领金额为0,状态改为1(未认领) |
| | | newStatus = "1"; |
| | | } else if (newClaimedAmount.compareTo(fundFlow.getTransactionAmount()) < 0) { |
| | | // 已认领金额小于交易金额,状态改为2(部分认领) |
| | | newStatus = "2"; |
| | | } |
| | | |
| | | // 更新资金流水状态和已认领金额 |
| | | fundFlow.setStatus(newStatus); |
| | | fundFlow.setClaimedAmount(newClaimedAmount); |
| | | fundFlow.setUpdateTime(DateUtils.getNowDate()); |
| | | int updateResult = fundFlowMapper.updateFundFlow(fundFlow); |
| | | if (updateResult <= 0) { |
| | | throw new RuntimeException("更新资金流水状态失败,ID: " + fundFlowId); |
| | | } |
| | | |
| | | // 删除结算明细并更新账单状态 |
| | | deleteSettlementDetailsAndUpdateBillStatus(claimDetail,fundFlow); |
| | | |
| | | return fundFlowClaimDetailMapper.deleteFundFlowClaimDetailByIds(ids); |
| | | } |
| | | |
| | |
| | | @Override |
| | | public int deleteFundFlowClaimDetailById(Integer id) |
| | | { |
| | | |
| | | return fundFlowClaimDetailMapper.deleteFundFlowClaimDetailById(id); |
| | | } |
| | | |
| | | /** |
| | | * 账单认领 |
| | | * |
| | | * @param fundFlowId 资金流水ID |
| | | * @param claimDetails 账单认领明细列表 |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int claimBill(Integer fundFlowId, FundFlowClaimDetail claimDetail) |
| | | { |
| | | if (fundFlowId == null) { |
| | | throw new RuntimeException("资金流水ID不能为空"); |
| | | } |
| | | |
| | | if (claimDetail == null ) { |
| | | throw new RuntimeException("认领明细列表不能为空"); |
| | | } |
| | | |
| | | //金额 |
| | | BigDecimal claimAmount = claimDetail.getClaimAmount(); |
| | | if (claimAmount == null || claimAmount.compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw new RuntimeException("认领金额必须大于0"); |
| | | |
| | | } |
| | | |
| | | // 查询资金流水信息 |
| | | FundFlow fundFlow = fundFlowMapper.selectFundFlowById(fundFlowId); |
| | | |
| | | // 根据总认领金额与交易金额的比较设置状态 |
| | | String newStatus = getString(fundFlowId, claimDetail, fundFlow); |
| | | |
| | | // 更新资金流水状态和已认领金额 |
| | | fundFlow.setStatus(newStatus); |
| | | fundFlow.setClaimedAmount(fundFlow.getClaimedAmount().add(claimAmount)); // 设置已认领金额 |
| | | fundFlow.setUpdateTime(DateUtils.getNowDate()); |
| | | int updateResult = fundFlowMapper.updateFundFlow(fundFlow); |
| | | if (updateResult <= 0) { |
| | | throw new RuntimeException("更新资金流水状态失败,ID: " + fundFlowId); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | // 设置资金流水ID |
| | | claimDetail.setFundFlowId(fundFlowId); |
| | | // 设置认领日期 |
| | | claimDetail.setClaimDate(DateUtils.getNowDate()); |
| | | // 设置创建时间 |
| | | claimDetail.setCreateTime(DateUtils.getNowDate()); |
| | | |
| | | |
| | | int insertResult = fundFlowClaimDetailMapper.insertFundFlowClaimDetail(claimDetail); |
| | | |
| | | // 新增:创建结算明细并更新账单状态 |
| | | if (insertResult > 0) { |
| | | |
| | | |
| | | createSettlementDetailsAndUpdateBillStatus(claimDetail, fundFlow); |
| | | } |
| | | |
| | | return insertResult; |
| | | } |
| | | |
| | | /** |
| | | * 根据资金流水ID、认领详情列表和资金流水对象获取状态字符串 |
| | | * @param fundFlowId 资金流水ID,用于标识特定的资金流水记录 |
| | | * @param claimDetail 认领详情列表,包含所有认领金额信息 |
| | | * @param fundFlow 资金流水对象,包含交易金额等关键信息 |
| | | * @return 返回处理后的状态字符串 |
| | | * @throws RuntimeException 当资金流水对象为null时抛出异常 |
| | | */ |
| | | private static @NonNull String getString(Integer fundFlowId, FundFlowClaimDetail claimDetail, FundFlow fundFlow) { |
| | | // 检查资金流水对象是否为空,如果为空则抛出异常 |
| | | if (fundFlow == null) { |
| | | throw new RuntimeException("资金流水不存在,ID: " + fundFlowId); |
| | | } |
| | | |
| | | // 计算总认领金额 |
| | | BigDecimal totalClaimAmount = claimDetail.getClaimAmount(); |
| | | |
| | | |
| | | // 验证总认领金额不能超过交易金额 |
| | | return getString(fundFlow, totalClaimAmount); |
| | | |
| | | } |
| | | |
| | | private static @NonNull String getString(FundFlow fundFlow, BigDecimal totalClaimAmount) { |
| | | BigDecimal transactionAmount = fundFlow.getTransactionAmount(); |
| | | if (totalClaimAmount.compareTo(transactionAmount) > 0) { |
| | | throw new RuntimeException("总认领金额不能超过交易金额。交易金额: " + transactionAmount + ", 总认领金额: " + totalClaimAmount); |
| | | } |
| | | |
| | | // 根据总认领金额与交易金额的比较设置状态 |
| | | String newStatus; |
| | | if (totalClaimAmount.compareTo(transactionAmount) < 0) { |
| | | // 总认领金额小于交易金额,状态改为2(部分认领) |
| | | newStatus = "2"; |
| | | } else { |
| | | // 总认领金额等于交易金额,状态改为3(完全认领) |
| | | newStatus = "3"; |
| | | } |
| | | return newStatus; |
| | | } |
| | | |
| | | /** |
| | | * 创建结算明细并更新账单状态 |
| | | */ |
| | | private void createSettlementDetailsAndUpdateBillStatus(FundFlowClaimDetail claimDetail, FundFlow fundFlow) { |
| | | |
| | | String billNo = claimDetail.getBillNo(); |
| | | BigDecimal claimAmount = claimDetail.getClaimAmount(); |
| | | Integer claimDetailId = claimDetail.getId(); |
| | | |
| | | // 根据收支标识借贷标志判断是应收账单还是应付账单 |
| | | if (fundFlow.getIncomeExpenseFlag().equals(0)) { |
| | | // 应收账单 |
| | | createReceivableSettlementDetail(billNo, claimAmount, fundFlow, claimDetailId); |
| | | } else { |
| | | // 应付账单 |
| | | createPayableSettlementDetail(billNo, claimAmount, fundFlow, claimDetailId); |
| | | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 创建应收账单结算明细 |
| | | */ |
| | | private void createReceivableSettlementDetail(String billNo, BigDecimal claimAmount, FundFlow fundFlow, Integer claimDetailId) { |
| | | try { |
| | | // 根据账单编号查询应收账单 |
| | | ReceivableBillManagement bill = receivableBillManagementService.selectReceivableBillManagementBySystemNo(billNo); |
| | | if (bill != null) { |
| | | // 创建结算明细 |
| | | ReceivableBillSettlementDetail settlementDetail = new ReceivableBillSettlementDetail(); |
| | | settlementDetail.setBillId(bill.getId()); |
| | | settlementDetail.setClaimDetailId(claimDetailId); // 设置认领明细ID |
| | | settlementDetail.setReceiptAmount(claimAmount); |
| | | settlementDetail.setReceiptDate(fundFlow.getTransactionDate()); |
| | | settlementDetail.setSettlementMethod("银行转账"); // 根据实际情况设置 |
| | | settlementDetail.setCreateBy(SecurityUtils.getUsername()); |
| | | settlementDetail.setCreateTime(DateUtils.getNowDate()); |
| | | |
| | | // 插入结算明细(会自动更新账单状态) |
| | | receivableBillSettlementDetailService.insertReceivableBillSettlementDetail(settlementDetail); |
| | | |
| | | logger.info("成功创建应收账单结算明细,账单编号:{},金额:{},认领明细ID:{}", billNo, claimAmount, claimDetailId); |
| | | } else { |
| | | logger.warn("未找到对应的应收账单,账单编号:{}", billNo); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.error("创建应收账单结算明细失败,账单编号:{}", billNo, e); |
| | | // 这里可以选择抛出异常或记录日志,但不中断整个认领流程 |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 创建应付账单结算明细 |
| | | */ |
| | | private void createPayableSettlementDetail(String billNo, BigDecimal claimAmount, FundFlow fundFlow, Integer claimDetailId) { |
| | | try { |
| | | // 根据账单编号查询应付账单 |
| | | PayableBillManagement bill = payableBillManagementService.selectPayableBillManagementBySystemNo(billNo); |
| | | if (bill != null) { |
| | | // 创建结算明细 |
| | | PayableBillSettlementDetail settlementDetail = new PayableBillSettlementDetail(); |
| | | settlementDetail.setBillId(bill.getId()); |
| | | settlementDetail.setClaimDetailId(claimDetailId); // 设置认领明细ID |
| | | settlementDetail.setPaymentAmount(claimAmount); |
| | | settlementDetail.setPaymentDate(fundFlow.getTransactionDate()); |
| | | settlementDetail.setSettlementMethod("银行转账"); // 根据实际情况设置 |
| | | settlementDetail.setCreateBy(SecurityUtils.getUsername()); |
| | | settlementDetail.setCreateTime(DateUtils.getNowDate()); |
| | | |
| | | // 插入结算明细(会自动更新账单状态) |
| | | payableBillSettlementDetailService.insertPayableBillSettlementDetail(settlementDetail); |
| | | |
| | | logger.info("成功创建应付账单结算明细,账单编号:{},金额:{},认领明细ID:{}", billNo, claimAmount, claimDetailId); |
| | | } else { |
| | | logger.warn("未找到对应的应付账单,账单编号:{}", billNo); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.error("创建应付账单结算明细失败,账单编号:{}", billNo, e); |
| | | // 这里可以选择抛出异常或记录日志,但不中断整个认领流程 |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除结算明细并更新账单状态 |
| | | */ |
| | | private void deleteSettlementDetailsAndUpdateBillStatus(FundFlowClaimDetail claimDetail, FundFlow fundFlow) { |
| | | String billNo = claimDetail.getBillNo(); |
| | | Integer claimDetailId = claimDetail.getId(); |
| | | |
| | | try { |
| | | |
| | | |
| | | // 根据收支标识借贷标志判断是应收账单还是应付账单 |
| | | if (fundFlow.getIncomeExpenseFlag().equals(0)) { |
| | | // 应收账单 |
| | | deleteReceivableSettlementDetail(claimDetailId); |
| | | } else { |
| | | // 应付账单 |
| | | deletePayableSettlementDetail(claimDetailId); |
| | | } |
| | | |
| | | logger.info("成功删除结算明细,认领明细ID:{}", claimDetailId); |
| | | } catch (Exception e) { |
| | | logger.error("删除结算明细失败,认领明细ID:{}", claimDetailId, e); |
| | | // 这里可以选择抛出异常或记录日志,但不中断整个删除流程 |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除应收账单结算明细 |
| | | */ |
| | | private void deleteReceivableSettlementDetail(Integer claimDetailId) { |
| | | try { |
| | | // 根据认领明细ID查询应收账单结算明细 |
| | | ReceivableBillSettlementDetail receivableQuery = new ReceivableBillSettlementDetail(); |
| | | receivableQuery.setClaimDetailId(claimDetailId); |
| | | List<ReceivableBillSettlementDetail> receivableDetails = receivableBillSettlementDetailService.selectReceivableBillSettlementDetailList(receivableQuery); |
| | | |
| | | if (!receivableDetails.isEmpty()) { |
| | | Integer[] receivableIds = receivableDetails.stream() |
| | | .map(ReceivableBillSettlementDetail::getId) |
| | | .toArray(Integer[]::new); |
| | | receivableBillSettlementDetailService.deleteReceivableBillSettlementDetailByIds(receivableIds); |
| | | logger.info("成功删除应收账单结算明细,认领明细ID:{}", claimDetailId); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.error("删除应收账单结算明细失败,认领明细ID:{}", claimDetailId, e); |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除应付账单结算明细 |
| | | */ |
| | | private void deletePayableSettlementDetail(Integer claimDetailId) { |
| | | try { |
| | | // 根据认领明细ID查询应付账单结算明细 |
| | | PayableBillSettlementDetail payableQuery = new PayableBillSettlementDetail(); |
| | | payableQuery.setClaimDetailId(claimDetailId); |
| | | List<PayableBillSettlementDetail> payableDetails = payableBillSettlementDetailService.selectPayableBillSettlementDetailList(payableQuery); |
| | | |
| | | if (!payableDetails.isEmpty()) { |
| | | Integer[] payableIds = payableDetails.stream() |
| | | .map(PayableBillSettlementDetail::getId) |
| | | .toArray(Integer[]::new); |
| | | payableBillSettlementDetailService.deletePayableBillSettlementDetailByIds(payableIds); |
| | | logger.info("成功删除应付账单结算明细,认领明细ID:{}", claimDetailId); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.error("删除应付账单结算明细失败,认领明细ID:{}", claimDetailId, e); |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | } |