package com.ruoyi.cwgl.service.impl; import java.math.RoundingMode; import java.util.List; import java.util.HashMap; import java.util.Map; import java.math.BigDecimal; import com.ruoyi.common.enums.SystemDataNoEnum; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import javax.annotation.Resource; import com.ruoyi.cwgl.domain.*; import com.ruoyi.cwgl.service.IPayableFeeManagementLogService; import com.ruoyi.cwgl.service.IPayableBillManagementService; import com.ruoyi.cwgl.domain.vo.PayableFeeStatisticsVo; import com.ruoyi.cwgl.domain.vo.PayableBillCreateVo; import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.mapper.SysConfigMapper; import com.ruoyi.system.service.ISystemDataNoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.stereotype.Service; import org.springframework.scheduling.annotation.Async; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.annotation.DataSource; import com.ruoyi.common.enums.DataSourceType; import com.ruoyi.common.core.service.BaseService; import com.ruoyi.cwgl.mapper.PayableFeeManagementMapper; import com.ruoyi.cwgl.service.IPayableFeeManagementService; import com.ruoyi.cwgl.service.IPayableFeeDetailService; import com.ruoyi.common.core.text.Convert; /** * 应付费用管理Service业务层处理 * * @author ruoyi * @date 2025-12-17 */ @Service @Transactional(rollbackFor = Exception.class) public class PayableFeeManagementServiceImpl extends BaseService implements IPayableFeeManagementService { protected final Logger logger = LoggerFactory.getLogger(getClass()); @Resource private PayableFeeManagementMapper payableFeeManagementMapper; @Resource private IPayableFeeDetailService payableFeeDetailService; @Autowired private IPayableFeeManagementLogService logService; @Autowired private IPayableBillManagementService payableBillManagementService; @Resource private SysConfigMapper sysConfigMapper; @Autowired ISystemDataNoService systemDataNoService; /** * 查询应付费用管理 * * @param id 应付费用管理ID * @return 应付费用管理 */ @DataSource(DataSourceType.SLAVE) @Override public PayableFeeManagement selectPayableFeeManagementById(Integer id) { PayableFeeManagement payableFeeManagement = payableFeeManagementMapper.selectPayableFeeManagementById(id); if (payableFeeManagement != null) { // 查询对应的费用明细 PayableFeeDetail detail = new PayableFeeDetail(); detail.setPayableFeeId(id); List detailList = payableFeeDetailService.selectPayableFeeDetailList(detail); payableFeeManagement.setPayableFeeDetailList(detailList); } return payableFeeManagement; } /** * 查询应付费用管理 记录数 * * @param payableFeeManagement 应付费用管理 * @return 应付费用管理集合 */ @DataSource(DataSourceType.SLAVE) @Override public int selectPayableFeeManagementCount(PayableFeeManagement payableFeeManagement) { return payableFeeManagementMapper.selectPayableFeeManagementCount(payableFeeManagement); } /** * 查询应付费用管理列表 * * @param payableFeeManagement 应付费用管理 * @return 应付费用管理 */ @DataSource(DataSourceType.SLAVE) @Override public List selectPayableFeeManagementList(PayableFeeManagement payableFeeManagement) { return payableFeeManagementMapper.selectPayableFeeManagementList(payableFeeManagement); } /** * 查询应付费用管理列表 异步 导出 * * @param payableFeeManagement 应付费用管理 * @param exportKey 导出功能的唯一标识 * @return 应付费用管理集合 */ @DataSource(DataSourceType.SLAVE) @Async @Override public void export(PayableFeeManagement payableFeeManagement,String exportKey) { super.export(PayableFeeManagement.class,exportKey,"payableFeeManagementData",(pageNum)->{ PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE); return selectPayableFeeManagementList(payableFeeManagement); }); } /** * 新增应付费用管理 * * @param payableFeeManagement 应付费用管理 * @return 结果 */ @Override public int insertPayableFeeManagement(PayableFeeManagement payableFeeManagement) { payableFeeManagement.setCreateTime(DateUtils.getNowDate()); // 计算应付金额字符串描述 if (payableFeeManagement.getPayableFeeDetailList() != null && !payableFeeManagement.getPayableFeeDetailList().isEmpty()) { String payableAmountStr = calculatePayableAmountStr(payableFeeManagement.getPayableFeeDetailList()); payableFeeManagement.setPayableAmountStr(payableAmountStr); } String noByKey = systemDataNoService.getNoByKey(SystemDataNoEnum.YF); payableFeeManagement.setSystemNo(noByKey); // 保存主实体 int result = payableFeeManagementMapper.insertPayableFeeManagement(payableFeeManagement); Integer payableFeeId = payableFeeManagement.getId(); // 批量保存明细 if (payableFeeManagement.getPayableFeeDetailList() != null && !payableFeeManagement.getPayableFeeDetailList().isEmpty()) { payableFeeManagement.getPayableFeeDetailList().forEach(detail -> { detail.setPayableFeeId(payableFeeId); detail.setCreateTime(DateUtils.getNowDate()); }); payableFeeDetailService.insertPayableFeeDetailBatch(payableFeeManagement.getPayableFeeDetailList()); } if (result > 0) { PayableFeeManagementLog log = new PayableFeeManagementLog(); log.setPayableFeeId(payableFeeId); log.setOperator(SecurityUtils.getUsername()); log.setOperationTime(DateUtils.getNowDate()); log.setOperationDesc("新增应付费用管理记录,系统编号:" + payableFeeManagement.getSystemNo()); log.setCreateTime(DateUtils.getNowDate()); logService.insertPayableFeeManagementLog(log); } return result; } /** * 新增应付费用管理[批量] * * @param payableFeeManagements 应付费用管理 * @return 结果 */ @Override public int insertPayableFeeManagementBatch(List payableFeeManagements) { int rows = payableFeeManagementMapper.insertPayableFeeManagementBatch(payableFeeManagements); return rows; } /** * 修改应付费用管理 * * @param payableFeeManagement 应付费用管理 * @return 结果 */ @Override public int updatePayableFeeManagement(PayableFeeManagement payableFeeManagement) { payableFeeManagement.setUpdateTime(DateUtils.getNowDate()); // 计算应付金额字符串描述 if (payableFeeManagement.getPayableFeeDetailList() != null && !payableFeeManagement.getPayableFeeDetailList().isEmpty()) { String payableAmountStr = calculatePayableAmountStr(payableFeeManagement.getPayableFeeDetailList()); payableFeeManagement.setPayableAmountStr(payableAmountStr); } // 1. 更新主表信息 int result = payableFeeManagementMapper.updatePayableFeeManagement(payableFeeManagement); // 2. 获取主表ID Integer payableFeeId = payableFeeManagement.getId(); // 3. 删除该应付费用下的所有现有明细 payableFeeDetailService.deletePayableFeeDetailByPayableFeeId(payableFeeId); // 4. 批量保存新的明细列表 if (payableFeeManagement.getPayableFeeDetailList() != null && !payableFeeManagement.getPayableFeeDetailList().isEmpty()) { // 设置每个明细的应付费用管理ID payableFeeManagement.getPayableFeeDetailList().forEach(detail -> { detail.setPayableFeeId(payableFeeId); detail.setUpdateTime(DateUtils.getNowDate()); // 设置更新时间 }); // 调用批量插入方法 payableFeeDetailService.insertPayableFeeDetailBatch(payableFeeManagement.getPayableFeeDetailList()); } // 记录操作日志 if (result > 0) { PayableFeeManagementLog log = new PayableFeeManagementLog(); log.setPayableFeeId(payableFeeId); log.setOperator(SecurityUtils.getUsername()); log.setOperationTime(DateUtils.getNowDate()); log.setOperationDesc("修改应付费用管理记录,系统编号:" + payableFeeManagement.getSystemNo()); log.setCreateTime(DateUtils.getNowDate()); logService.insertPayableFeeManagementLog(log); } return result; } /** * 修改应付费用管理[批量] * * @param payableFeeManagements 应付费用管理 * @return 结果 */ @Override public int updatePayableFeeManagementBatch(List payableFeeManagements){ return payableFeeManagementMapper.updatePayableFeeManagementBatch(payableFeeManagements); } /** * 删除应付费用管理对象 * * @param ids 需要删除的数据ID * @return 结果 */ @Override public int deletePayableFeeManagementByIds(String ids) { return deletePayableFeeManagementByIds(Convert.toIntArray(ids)); } /** * 删除应付费用管理对象 * * * @param ids 需要删除的数据ID * @return 结果 */ @Override public int deletePayableFeeManagementByIds(Integer[] ids) { return payableFeeManagementMapper.deletePayableFeeManagementByIds(ids); } /** * 删除应付费用管理信息 * * @param id 应付费用管理ID * @return 结果 */ @Override public int deletePayableFeeManagementById(Integer id) { return payableFeeManagementMapper.deletePayableFeeManagementById(id); } /** * 查询应付费用统计信息 * * @param ids 应付费用管理ID数组 * @return 应付费用统计结果 */ @Override public PayableFeeStatisticsVo getPayableFeeStatistics(Integer[] ids) { PayableFeeStatisticsVo statisticsVo = new PayableFeeStatisticsVo(); // 查询选中的应付费用记录 List feeList = payableFeeManagementMapper.selectPayableFeeManagementByIds(ids); if (feeList.isEmpty()) { return statisticsVo; } // 检查供应商名称是否一致 String supplierName = feeList.get(0).getSupplierName(); for (PayableFeeManagement fee : feeList) { if (!supplierName.equals(fee.getSupplierName())) { throw new RuntimeException("所选记录的供应商名称不一致,无法进行统计"); } } // 获取汇率配置 SysConfig sysConfig = sysConfigMapper.selectConfig(new SysConfig() {{ setConfigKey("sys.hk.rmb.rate"); }}); BigDecimal exchangeRate = new BigDecimal(sysConfig.getConfigValue()); statisticsVo.setRate(exchangeRate); // 设置单据数量 statisticsVo.setDocumentCount(feeList.size()); statisticsVo.setIds(ids); // 获取所有应付费用明细,按币种分别计算金额 List detailList = payableFeeDetailService.selectPayableFeeDetailByPayableFeeIds(ids); // 按币种汇总金额 BigDecimal totalAmountRmb = BigDecimal.ZERO; BigDecimal totalAmountHkd = BigDecimal.ZERO; for (PayableFeeDetail detail : detailList) { if ("CNY".equals(detail.getCurrency())) { totalAmountRmb = totalAmountRmb.add(detail.getBillingAmount()); } else if ("HKD".equals(detail.getCurrency())) { totalAmountHkd = totalAmountHkd.add(detail.getBillingAmount()); } } // 计算转换后的总金额 BigDecimal totalAmountRmbWithConversion = totalAmountRmb.add( totalAmountHkd.multiply(exchangeRate).setScale(2, RoundingMode.HALF_UP) ); BigDecimal totalAmountHkdWithConversion = totalAmountHkd.add( totalAmountRmb.divide(exchangeRate, 2, RoundingMode.HALF_UP) ); // 设置统计结果 statisticsVo.setTotalPayableAmount(totalAmountRmbWithConversion); statisticsVo.setTotalAmountRmb(totalAmountRmbWithConversion); statisticsVo.setTotalAmountHkd(totalAmountHkdWithConversion); return statisticsVo; } /** * 创建应付账单 * * @param billCreateVo 应付账单创建请求VO * @return 结果 */ @Override @Transactional(rollbackFor = Exception.class) public int createPayableBill(PayableBillCreateVo billCreateVo) { // 获取应付费用统计数据 PayableFeeStatisticsVo statisticsVo = billCreateVo.getStatisticsData(); Integer[] ids = statisticsVo.getIds(); // 查询选中的应付费用记录 List feeList = payableFeeManagementMapper.selectPayableFeeManagementByIds(ids); if (feeList.isEmpty()) { throw new RuntimeException("未找到有效的应付费用记录"); } // 检查状态,只有状态为0的记录可以创建账单 for (PayableFeeManagement fee : feeList) { if (!"0".equals(fee.getStatus())) { throw new RuntimeException("只能选择状态为0的应付费用记录创建账单"); } } // 创建应付账单管理对象 PayableBillManagement bill = new PayableBillManagement(); bill.setBillName(billCreateVo.getBillName()); bill.setSupplierName(billCreateVo.getSupplierName()); bill.setIsInternalSettlement(billCreateVo.getIsInternalSettlement()); bill.setInternalSettlementUnit(billCreateVo.getInternalSettlementUnit()); bill.setDocumentCount(statisticsVo.getDocumentCount()); bill.setCreateBy(SecurityUtils.getUsername()); bill.setExchangeRate(statisticsVo.getRate()); bill.setStatus("0"); // 草稿状态 bill.setCreateTime(DateUtils.getNowDate()); // 根据账单类型设置币种和总金额 if (billCreateVo.getBillType() == 0) { // 人民币账单 bill.setCurrency("RMB"); bill.setTotalAmount(statisticsVo.getTotalAmountRmb()); bill.setCnyAmount(statisticsVo.getTotalAmountRmb()); } else { // 港币账单 bill.setCurrency("HKD"); bill.setTotalAmount(statisticsVo.getTotalAmountHkd()); bill.setCnyAmount(statisticsVo.getTotalAmountRmb()); } bill.setPendingAmount(bill.getTotalAmount()); String noByKey = systemDataNoService.getNoByKey(SystemDataNoEnum.YFZD); bill.setSystemNo(noByKey); // 保存应付账单记录 int result = payableBillManagementService.insertPayableBillManagement(bill); if (result > 0) { // 批量更新应付费用主表,设置关联账单编号和状态 for (PayableFeeManagement fee : feeList) { fee.setRelatedBillNo(bill.getSystemNo()); fee.setStatus("1"); // 已生成账单状态 payableFeeManagementMapper.updatePayableFeeManagement(fee); // 记录操作日志 PayableFeeManagementLog log = new PayableFeeManagementLog(); log.setPayableFeeId(fee.getId()); log.setOperator(SecurityUtils.getUsername()); log.setOperationTime(DateUtils.getNowDate()); log.setOperationDesc("生成应付账单,账单编号:" + bill.getSystemNo()); log.setCreateTime(DateUtils.getNowDate()); logService.insertPayableFeeManagementLog(log); } } return result; } /** * 根据关联账单编号批量更新应付费用管理记录 * 清除关联账单编号并将状态改为0(待生成账单) * 使用场景:当应付账单被删除或作废时,需要将关联的应付费用记录恢复为待生成账单状态 * * @param relatedBillNo 关联账单编号 * @return 影响的行数 */ @Override public int updatePayableFeeManagementByRelatedBillNo(String relatedBillNo) { // 调用Mapper层方法执行批量更新 int result = payableFeeManagementMapper.updatePayableFeeManagementByRelatedBillNo(relatedBillNo); return result; } /** * 作废应付费用管理记录 * * @param id 应付费用管理ID * @return 结果 */ @Override public int voidPayableFeeManagement(Integer id) { // 查询应付费用记录 PayableFeeManagement payableFeeManagement = payableFeeManagementMapper.selectPayableFeeManagementById(id); if (payableFeeManagement == null) { throw new RuntimeException("应付费用记录不存在"); } // 检查状态,只有状态为0的记录可以作废 if (!"0".equals(payableFeeManagement.getStatus())) { throw new RuntimeException("只能作废状态为0的应付费用记录"); } // 设置状态为2(作废) payableFeeManagement.setStatus("2"); payableFeeManagement.setUpdateTime(DateUtils.getNowDate()); int result = payableFeeManagementMapper.updatePayableFeeManagement(payableFeeManagement); if (result > 0) { // 记录操作日志 PayableFeeManagementLog log = new PayableFeeManagementLog(); log.setPayableFeeId(id); log.setOperator(SecurityUtils.getUsername()); log.setOperationTime(DateUtils.getNowDate()); log.setOperationDesc("作废应付费用记录,系统编号:" + payableFeeManagement.getSystemNo()); log.setCreateTime(DateUtils.getNowDate()); logService.insertPayableFeeManagementLog(log); } return result; } /** * 计算应付金额字符串描述 * 根据明细列表按币种汇总金额,格式如:"200港币100人民币" * * @param detailList 应付费用明细列表 * @return 应付金额字符串描述 */ private String calculatePayableAmountStr(List detailList) { if (detailList == null || detailList.isEmpty()) { return ""; } // 按币种汇总金额 Map currencyAmountMap = new HashMap<>(); for (PayableFeeDetail detail : detailList) { String currency = detail.getCurrency(); BigDecimal billingAmount = detail.getBillingAmount(); if (currency != null && billingAmount != null) { currencyAmountMap.merge(currency, billingAmount, BigDecimal::add); } } // 构建字符串描述 StringBuilder sb = new StringBuilder(); for (Map.Entry entry : currencyAmountMap.entrySet()) { if (sb.length() > 0) { sb.append(" "); } sb.append(entry.getValue().stripTrailingZeros().toPlainString()); // 根据币种显示对应的货币名称 String currency = entry.getKey(); if ("RMB".equals(currency)) { sb.append("人民币"); } else if ("HKD".equals(currency)) { sb.append("港币"); } else if ("USD".equals(currency)) { sb.append("美元"); } else { sb.append(currency); } } return sb.toString(); } }