package com.ruoyi.cwgl.service.impl; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Objects; import com.ruoyi.common.enums.SystemDataNoEnum; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import javax.annotation.Resource; import com.ruoyi.cwgl.domain.ReceivableFeeDetail; import com.ruoyi.cwgl.domain.vo.ReceivableFeeStatisticsVo; 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.ReceivableFeeManagementMapper; import com.ruoyi.cwgl.domain.ReceivableFeeManagement; import com.ruoyi.cwgl.domain.ReceivableBillManagement; import com.ruoyi.cwgl.domain.ReceivableBillSettlementDetail; import com.ruoyi.cwgl.service.IReceivableFeeDetailService; import com.ruoyi.cwgl.service.IReceivableFeeManagementService; import com.ruoyi.cwgl.service.IReceivableBillManagementService; import com.ruoyi.cwgl.service.IReceivableBillSettlementDetailService; import com.ruoyi.cwgl.domain.vo.ReceivableBillCreateVo; import com.ruoyi.common.core.text.Convert; /** * 应收费用管理Service业务层处理 * * @author ruoyi * @date 2025-12-17 */ @Service @Transactional(rollbackFor = Exception.class) public class ReceivableFeeManagementServiceImpl extends BaseService implements IReceivableFeeManagementService { protected final Logger logger = LoggerFactory.getLogger(getClass()); @Resource private ReceivableFeeManagementMapper receivableFeeManagementMapper; @Autowired private IReceivableFeeDetailService receivableFeeDetailService; @Resource private SysConfigMapper sysConfigMapper; @Autowired private IReceivableBillManagementService receivableBillManagementService; @Autowired private IReceivableBillSettlementDetailService receivableBillSettlementDetailService; @Autowired ISystemDataNoService systemDataNoService; /** * 查询应收费用管理 * * @param id 应收费用管理ID * @return 应收费用管理 */ @DataSource(DataSourceType.SLAVE) @Override public ReceivableFeeManagement selectReceivableFeeManagementById(Integer id) { ReceivableFeeManagement receivableFeeManagement = receivableFeeManagementMapper.selectReceivableFeeManagementById(id); if (receivableFeeManagement != null) { // 查询对应的费用明细 ReceivableFeeDetail detail = new ReceivableFeeDetail(); detail.setReceivableFeeId(id); List detailList = receivableFeeDetailService.selectReceivableFeeDetailList(detail); receivableFeeManagement.setReceivableFeeDetailList(detailList); } return receivableFeeManagement; } /** * 查询应收费用管理 记录数 * * @param receivableFeeManagement 应收费用管理 * @return 应收费用管理集合 */ @DataSource(DataSourceType.SLAVE) @Override public int selectReceivableFeeManagementCount(ReceivableFeeManagement receivableFeeManagement) { return receivableFeeManagementMapper.selectReceivableFeeManagementCount(receivableFeeManagement); } /** * 查询应收费用管理列表 * * @param receivableFeeManagement 应收费用管理 * @return 应收费用管理 */ @DataSource(DataSourceType.SLAVE) @Override public List selectReceivableFeeManagementList(ReceivableFeeManagement receivableFeeManagement) { return receivableFeeManagementMapper.selectReceivableFeeManagementList(receivableFeeManagement); } /** * 查询应收费用管理列表 异步 导出 * * @param receivableFeeManagement 应收费用管理 * @param exportKey 导出功能的唯一标识 * @return 应收费用管理集合 */ @DataSource(DataSourceType.SLAVE) @Async @Override public void export(ReceivableFeeManagement receivableFeeManagement,String exportKey) { super.export(ReceivableFeeManagement.class,exportKey,"receivableFeeManagementData",(pageNum)->{ PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE); return selectReceivableFeeManagementList(receivableFeeManagement); }); } /** * 新增应收费用管理 * * @param receivableFeeManagement 应收费用管理 * @return 结果 */ @Override public int insertReceivableFeeManagement(ReceivableFeeManagement receivableFeeManagement) { receivableFeeManagement.setCreateTime(DateUtils.getNowDate()); String noByKey = systemDataNoService.getNoByKey(SystemDataNoEnum.YS); receivableFeeManagement.setSystemNo(noByKey); // 保存主表信息 int result = receivableFeeManagementMapper.insertReceivableFeeManagement(receivableFeeManagement); // 获取主表ID Integer receivableFeeId = receivableFeeManagement.getId(); // 批量保存明细列表 if (receivableFeeManagement.getReceivableFeeDetailList() != null && !receivableFeeManagement.getReceivableFeeDetailList().isEmpty()) { // 设置每个明细的应收费用管理ID receivableFeeManagement.getReceivableFeeDetailList().forEach(detail -> { detail.setReceivableFeeId(receivableFeeId); detail.setCreateTime(DateUtils.getNowDate()); // 设置创建时间 }); // 调用批量插入方法 receivableFeeDetailService.insertReceivableFeeDetailBatch(receivableFeeManagement.getReceivableFeeDetailList()); } return result; } /** * 新增应收费用管理[批量] * * @param receivableFeeManagements 应收费用管理 * @return 结果 */ @Override public int insertReceivableFeeManagementBatch(List receivableFeeManagements) { int rows = receivableFeeManagementMapper.insertReceivableFeeManagementBatch(receivableFeeManagements); return rows; } /** * 修改应收费用管理 * * @param receivableFeeManagement 应收费用管理 * @return 结果 */ @Override public int updateReceivableFeeManagement(ReceivableFeeManagement receivableFeeManagement) { receivableFeeManagement.setUpdateTime(DateUtils.getNowDate()); // 1. 更新主表信息 int result = receivableFeeManagementMapper.updateReceivableFeeManagement(receivableFeeManagement); // 2. 获取主表ID Integer receivableFeeId = receivableFeeManagement.getId(); // 3. 删除该应收费用下的所有现有明细 receivableFeeDetailService.deleteReceivableFeeDetailByReceivableFeeId(receivableFeeId); // 4. 批量保存新的明细列表 if (receivableFeeManagement.getReceivableFeeDetailList() != null && !receivableFeeManagement.getReceivableFeeDetailList().isEmpty()) { // 设置每个明细的应收费用管理ID receivableFeeManagement.getReceivableFeeDetailList().forEach(detail -> { detail.setReceivableFeeId(receivableFeeId); detail.setUpdateTime(DateUtils.getNowDate()); // 设置更新时间 }); // 调用批量插入方法 receivableFeeDetailService.insertReceivableFeeDetailBatch(receivableFeeManagement.getReceivableFeeDetailList()); } return result; } /** * 修改应收费用管理[批量] * * @param receivableFeeManagements 应收费用管理 * @return 结果 */ @Override public int updateReceivableFeeManagementBatch(List receivableFeeManagements){ return receivableFeeManagementMapper.updateReceivableFeeManagementBatch(receivableFeeManagements); } /** * 删除应收费用管理对象 * * @param ids 需要删除的数据ID * @return 结果 */ @Override public int deleteReceivableFeeManagementByIds(String ids) { return deleteReceivableFeeManagementByIds(Convert.toIntArray(ids)); } /** * 删除应收费用管理对象 * * * @param ids 需要删除的数据ID * @return 结果 */ @Override public int deleteReceivableFeeManagementByIds(Integer[] ids) { return receivableFeeManagementMapper.deleteReceivableFeeManagementByIds(ids); } /** * 删除应收费用管理信息 * * @param id 应收费用管理ID * @return 结果 */ @Override public int deleteReceivableFeeManagementById(Integer id) { return receivableFeeManagementMapper.deleteReceivableFeeManagementById(id); } /** * 根据应收费用ID数组查询统计信息和明细 * * @param ids 应收费用ID数组 * @return 包含统计信息和明细的结果 */ @DataSource(DataSourceType.SLAVE) @Override public ReceivableFeeStatisticsVo getReceivableFeeStatistics(Integer[] ids) { // 查询应收费用主表记录 List receivableFeeList = receivableFeeManagementMapper.selectReceivableFeeManagementByIds(ids); // 检查所有记录是否属于同一个客户 if (!receivableFeeList.isEmpty()) { Integer firstCustomerId = receivableFeeList.get(0).getCustomerId(); boolean allSameCustomer = receivableFeeList.stream() .allMatch(item -> Objects.equals(item.getCustomerId(), firstCustomerId)); if (!allSameCustomer) { throw new ServiceException("所选记录包含不同客户的数据,无法进行统计"); } } // 计算单据数量 int documentCount = receivableFeeList.size(); SysConfig sysConfig = sysConfigMapper.selectConfig(new SysConfig() {{ setConfigKey("sys.hk.rmb.rate"); }}); // 计算总应收金额 BigDecimal totalReceivableAmount = receivableFeeList.stream() .map(ReceivableFeeManagement::getReceivableAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal exchangeRate = new BigDecimal(sysConfig.getConfigValue()); BigDecimal totalAmountHkd = totalReceivableAmount.divide(exchangeRate, 2, RoundingMode.HALF_UP); // 组装返回结果 ReceivableFeeStatisticsVo result = new ReceivableFeeStatisticsVo(); result.setDocumentCount(documentCount); result.setRate(exchangeRate); result.setTotalReceivableAmount(totalReceivableAmount); result.setTotalAmountRmb(totalReceivableAmount); result.setTotalAmountHkd(totalAmountHkd); result.setIds(ids); return result; } /** * 根据统计数据创建应收账单 * * @param billCreateVo 包含统计数据和账单类型的请求对象 * @return 创建的应收账单ID */ @Override public Integer createReceivableBill(ReceivableBillCreateVo billCreateVo) { // 1. 准备数据 ReceivableFeeStatisticsVo statisticsVo = billCreateVo.getStatisticsData(); Integer billType = billCreateVo.getBillType(); // 2. 创建应收账单主记录 ReceivableBillManagement billManagement = new ReceivableBillManagement(); billManagement.setDocumentCount(statisticsVo.getDocumentCount()); billManagement.setExchangeRate(statisticsVo.getRate()); billManagement.setStatus("0"); // 默认草稿状态 billManagement.setCreateTime(DateUtils.getNowDate()); billManagement.setBillName(billCreateVo.getBillName()); billManagement.setCustomerName(billCreateVo.getCustomerName()); billManagement.setIsInternalSettlement(billCreateVo.getIsInternalSettlement()); billManagement.setInternalSettlementUnit(billCreateVo.getInternalSettlementUnit()); // 3. 根据账单类型设置币种和总金额 if (billType == 0) { // 人民币账单 billManagement.setCurrency("CNY"); billManagement.setTotalAmount(statisticsVo.getTotalAmountRmb()); } else if (billType == 1) { // 港币账单 billManagement.setCurrency("HKD"); billManagement.setTotalAmount(statisticsVo.getTotalAmountHkd()); } else { throw new IllegalArgumentException("无效的账单类型:" + billType); } String noByKey = systemDataNoService.getNoByKey(SystemDataNoEnum.YSZD); billManagement.setSystemNo(noByKey); // 4. 保存主账单记录 int i = receivableBillManagementService.insertReceivableBillManagement(billManagement); // 5. 更新应收费用主表的关联账单编号 if (statisticsVo.getIds() != null && statisticsVo.getIds().length > 0) { // 获取生成的账单系统编号 String billSystemNo = billManagement.getSystemNo(); // 批量更新应收费用主表的关联账单编号 for (Integer feeId : statisticsVo.getIds()) { ReceivableFeeManagement feeManagement = new ReceivableFeeManagement(); feeManagement.setId(feeId); feeManagement.setRelatedBillNo(billSystemNo); feeManagement.setStatus("1"); receivableFeeManagementMapper.updateReceivableFeeManagement(feeManagement); } // 调用批量更新方法 } return i; } }