package com.ruoyi.cwgl.service.impl;
|
|
import java.util.List;
|
|
import com.ruoyi.common.utils.DateUtils;
|
import javax.annotation.Resource;
|
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.ReceivableBillSettlementDetailMapper;
|
import com.ruoyi.cwgl.domain.ReceivableBillSettlementDetail;
|
import com.ruoyi.cwgl.service.IReceivableBillSettlementDetailService;
|
import com.ruoyi.cwgl.service.IReceivableBillManagementService;
|
import com.ruoyi.cwgl.service.IReceivableBillManagementLogService;
|
import com.ruoyi.cwgl.domain.ReceivableBillManagement;
|
import com.ruoyi.cwgl.domain.ReceivableBillManagementLog;
|
import com.ruoyi.common.core.text.Convert;
|
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import java.math.BigDecimal;
|
import java.util.Set;
|
import java.util.Objects;
|
import java.util.stream.Collectors;
|
import java.util.HashSet;
|
|
/**
|
* 应收账单结算明细Service业务层处理
|
*
|
* @author ruoyi
|
* @date 2025-12-17
|
*/
|
@Service
|
@Transactional(rollbackFor = Exception.class)
|
public class ReceivableBillSettlementDetailServiceImpl extends BaseService<ReceivableBillSettlementDetailMapper, ReceivableBillSettlementDetail> implements IReceivableBillSettlementDetailService
|
{
|
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
@Resource
|
private ReceivableBillSettlementDetailMapper receivableBillSettlementDetailMapper;
|
|
@Resource
|
private IReceivableBillManagementService receivableBillManagementService;
|
|
@Resource
|
private IReceivableBillManagementLogService receivableBillManagementLogService;
|
|
|
/**
|
* 查询应收账单结算明细
|
*
|
* @param id 应收账单结算明细ID
|
* @return 应收账单结算明细
|
*/
|
@DataSource(DataSourceType.SLAVE)
|
@Override
|
public ReceivableBillSettlementDetail selectReceivableBillSettlementDetailById(Integer id)
|
{
|
return receivableBillSettlementDetailMapper.selectReceivableBillSettlementDetailById(id);
|
}
|
|
/**
|
* 查询应收账单结算明细 记录数
|
*
|
* @param receivableBillSettlementDetail 应收账单结算明细
|
* @return 应收账单结算明细集合
|
*/
|
@DataSource(DataSourceType.SLAVE)
|
@Override
|
public int selectReceivableBillSettlementDetailCount(ReceivableBillSettlementDetail receivableBillSettlementDetail)
|
{
|
return receivableBillSettlementDetailMapper.selectReceivableBillSettlementDetailCount(receivableBillSettlementDetail);
|
}
|
|
/**
|
* 查询应收账单结算明细列表
|
*
|
* @param receivableBillSettlementDetail 应收账单结算明细
|
* @return 应收账单结算明细
|
*/
|
@DataSource(DataSourceType.SLAVE)
|
@Override
|
public List<ReceivableBillSettlementDetail> selectReceivableBillSettlementDetailList(ReceivableBillSettlementDetail receivableBillSettlementDetail)
|
{
|
return receivableBillSettlementDetailMapper.selectReceivableBillSettlementDetailList(receivableBillSettlementDetail);
|
}
|
|
/**
|
* 查询应收账单结算明细列表 异步 导出
|
*
|
* @param receivableBillSettlementDetail 应收账单结算明细
|
* @param exportKey 导出功能的唯一标识
|
* @return 应收账单结算明细集合
|
*/
|
@DataSource(DataSourceType.SLAVE)
|
@Async
|
@Override
|
public void export(ReceivableBillSettlementDetail receivableBillSettlementDetail,String exportKey) {
|
|
super.export(ReceivableBillSettlementDetail.class,exportKey,"receivableBillSettlementDetailData",(pageNum)->{
|
PageUtils.startPage(pageNum, Constants.EXPORT_PATE_SIZE);
|
return selectReceivableBillSettlementDetailList(receivableBillSettlementDetail);
|
});
|
}
|
|
|
/**
|
* 新增应收账单结算明细
|
*
|
* @param receivableBillSettlementDetail 应收账单结算明细
|
* @return 结果
|
*/
|
@Override
|
public int insertReceivableBillSettlementDetail(ReceivableBillSettlementDetail receivableBillSettlementDetail)
|
{
|
// 1. 设置创建时间
|
receivableBillSettlementDetail.setCreateTime(DateUtils.getNowDate());
|
|
// 2. 插入结算明细记录
|
int result = receivableBillSettlementDetailMapper.insertReceivableBillSettlementDetail(receivableBillSettlementDetail);
|
|
// 3. 如果插入成功且billId不为空,则更新主表金额和状态
|
if (result > 0 && receivableBillSettlementDetail.getBillId() != null) {
|
updateReceivableBillAmountAndStatus(receivableBillSettlementDetail.getBillId());
|
|
// 记录添加结算明细操作日志
|
ReceivableBillManagement billManagement = receivableBillManagementService.selectReceivableBillManagementById(receivableBillSettlementDetail.getBillId());
|
if (billManagement != null) {
|
ReceivableBillManagementLog log = new ReceivableBillManagementLog();
|
log.setBillId(receivableBillSettlementDetail.getBillId());
|
log.setCreateBy(SecurityUtils.getUsername());
|
log.setCreateTime(DateUtils.getNowDate());
|
log.setOperation("添加结算明细,账单编号:" + billManagement.getSystemNo());
|
receivableBillManagementLogService.insertReceivableBillManagementLog(log);
|
}
|
}
|
|
return result;
|
}
|
|
/**
|
* 更新应收账单主表的金额和状态
|
*
|
* @param billId 应收账单ID
|
*/
|
private void updateReceivableBillAmountAndStatus(Integer billId) {
|
// 1. 查询应收账单主表记录
|
ReceivableBillManagement billManagement = receivableBillManagementService.selectReceivableBillManagementById(billId);
|
if (billManagement == null) {
|
throw new ServiceException("应收账单主表记录不存在,ID:" + billId);
|
}
|
|
// 2. 查询该账单的所有结算明细记录
|
ReceivableBillSettlementDetail queryDetail = new ReceivableBillSettlementDetail();
|
queryDetail.setBillId(billId);
|
List<ReceivableBillSettlementDetail> settlementDetails = receivableBillSettlementDetailMapper.selectReceivableBillSettlementDetailList(queryDetail);
|
|
// 3. 计算总收款金额
|
BigDecimal totalReceiptAmount = settlementDetails.stream()
|
.map(ReceivableBillSettlementDetail::getReceiptAmount)
|
.filter(amount -> amount != null)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
// 4. 验证金额不能为负数
|
if (totalReceiptAmount.compareTo(BigDecimal.ZERO) < 0) {
|
throw new ServiceException("收款金额不能为负数");
|
}
|
|
// 5. 计算待收金额(应结算金额 - 已收金额 - 减免金额)
|
BigDecimal totalAmount = billManagement.getTotalAmount() != null ? billManagement.getTotalAmount() : BigDecimal.ZERO;
|
BigDecimal discountAmount = billManagement.getDiscountAmount() != null ? billManagement.getDiscountAmount() : BigDecimal.ZERO;
|
BigDecimal pendingAmount = totalAmount.subtract(totalReceiptAmount).subtract(discountAmount);
|
|
// 6. 验证待收金额不能为负数
|
if (pendingAmount.compareTo(BigDecimal.ZERO) < 0) {
|
throw new ServiceException("待收金额不能为负数,当前计算值:" + pendingAmount);
|
}
|
|
// 7. 更新主表金额
|
billManagement.setReceivedAmount(totalReceiptAmount);
|
billManagement.setPendingAmount(pendingAmount);
|
|
// 8. 根据待收金额更新状态
|
if (pendingAmount.compareTo(BigDecimal.ZERO) == 0) {
|
// 待收金额为0,状态改为3(已结算)
|
billManagement.setStatus("3");
|
} else {
|
// 待收金额大于0,状态改为1(结算中)
|
billManagement.setStatus("1");
|
}
|
|
// 9. 更新主表记录
|
billManagement.setUpdateTime(DateUtils.getNowDate());
|
receivableBillManagementService.updateReceivableBillManagement(billManagement);
|
}
|
|
/**
|
* 新增应收账单结算明细[批量]
|
*
|
* @param receivableBillSettlementDetails 应收账单结算明细
|
* @return 结果
|
*/
|
@Override
|
public int insertReceivableBillSettlementDetailBatch(List<ReceivableBillSettlementDetail> receivableBillSettlementDetails)
|
{
|
// 1. 设置创建时间
|
for (ReceivableBillSettlementDetail detail : receivableBillSettlementDetails) {
|
detail.setCreateTime(DateUtils.getNowDate());
|
}
|
|
// 2. 批量插入结算明细记录
|
int rows = receivableBillSettlementDetailMapper.insertReceivableBillSettlementDetailBatch(receivableBillSettlementDetails);
|
|
// 3. 如果插入成功,则更新相关主表金额和状态
|
if (rows > 0) {
|
// 获取所有不重复的billId
|
Set<Integer> billIds = receivableBillSettlementDetails.stream()
|
.map(ReceivableBillSettlementDetail::getBillId)
|
.filter(Objects::nonNull)
|
.collect(Collectors.toSet());
|
|
// 更新每个账单主表的金额和状态
|
for (Integer billId : billIds) {
|
updateReceivableBillAmountAndStatus(billId);
|
}
|
|
// 记录添加结算明细操作日志
|
if (!billIds.isEmpty()) {
|
for (Integer billId : billIds) {
|
ReceivableBillManagement billManagement = receivableBillManagementService.selectReceivableBillManagementById(billId);
|
if (billManagement != null) {
|
ReceivableBillManagementLog log = new ReceivableBillManagementLog();
|
log.setBillId(billId);
|
log.setCreateBy(SecurityUtils.getUsername());
|
log.setCreateTime(DateUtils.getNowDate());
|
|
// 计算本次添加的明细数量
|
long detailCount = receivableBillSettlementDetails.stream()
|
.filter(detail -> billId.equals(detail.getBillId()))
|
.count();
|
|
log.setOperation("添加" + detailCount + "条结算明细,账单编号:" + billManagement.getSystemNo());
|
receivableBillManagementLogService.insertReceivableBillManagementLog(log);
|
}
|
}
|
}
|
}
|
|
return rows;
|
}
|
|
/**
|
* 修改应收账单结算明细
|
*
|
* @param receivableBillSettlementDetail 应收账单结算明细
|
* @return 结果
|
*/
|
@Override
|
public int updateReceivableBillSettlementDetail(ReceivableBillSettlementDetail receivableBillSettlementDetail)
|
{
|
// 1. 获取修改前的记录,用于后续更新主表
|
ReceivableBillSettlementDetail oldDetail = null;
|
if (receivableBillSettlementDetail.getId() != null) {
|
oldDetail = receivableBillSettlementDetailMapper.selectReceivableBillSettlementDetailById(receivableBillSettlementDetail.getId());
|
}
|
|
// 2. 设置更新时间
|
receivableBillSettlementDetail.setUpdateTime(DateUtils.getNowDate());
|
|
// 3. 更新结算明细记录
|
int result = receivableBillSettlementDetailMapper.updateReceivableBillSettlementDetail(receivableBillSettlementDetail);
|
|
// 4. 如果更新成功,则更新相关主表金额和状态
|
if (result > 0) {
|
// 获取需要更新的billId(优先使用新记录的billId,如果没有则使用旧记录的billId)
|
Integer billId = receivableBillSettlementDetail.getBillId();
|
if (billId == null && oldDetail != null) {
|
billId = oldDetail.getBillId();
|
}
|
|
if (billId != null) {
|
updateReceivableBillAmountAndStatus(billId);
|
}
|
}
|
|
return result;
|
}
|
|
/**
|
* 修改应收账单结算明细[批量]
|
*
|
* @param receivableBillSettlementDetails 应收账单结算明细
|
* @return 结果
|
*/
|
@Override
|
public int updateReceivableBillSettlementDetailBatch(List<ReceivableBillSettlementDetail> receivableBillSettlementDetails){
|
// 1. 设置更新时间
|
for (ReceivableBillSettlementDetail detail : receivableBillSettlementDetails) {
|
detail.setUpdateTime(DateUtils.getNowDate());
|
}
|
|
// 2. 批量更新结算明细记录
|
int result = receivableBillSettlementDetailMapper.updateReceivableBillSettlementDetailBatch(receivableBillSettlementDetails);
|
|
// 3. 如果更新成功,则更新相关主表金额和状态
|
if (result > 0) {
|
// 获取所有不重复的billId
|
Set<Integer> billIds = receivableBillSettlementDetails.stream()
|
.map(ReceivableBillSettlementDetail::getBillId)
|
.filter(Objects::nonNull)
|
.collect(Collectors.toSet());
|
|
// 更新每个账单主表的金额和状态
|
for (Integer billId : billIds) {
|
updateReceivableBillAmountAndStatus(billId);
|
}
|
}
|
|
return result;
|
}
|
|
/**
|
* 删除应收账单结算明细对象
|
*
|
* @param ids 需要删除的数据ID
|
* @return 结果
|
*/
|
@Override
|
public int deleteReceivableBillSettlementDetailByIds(String ids)
|
{
|
return deleteReceivableBillSettlementDetailByIds(Convert.toIntArray(ids));
|
}
|
|
/**
|
* 删除应收账单结算明细对象
|
*
|
*
|
* @param ids 需要删除的数据ID
|
* @return 结果
|
*/
|
@Override
|
public int deleteReceivableBillSettlementDetailByIds(Integer[] ids)
|
{
|
// 1. 获取删除前的记录,用于后续更新主表
|
Set<Integer> billIds = new HashSet<>();
|
for (Integer id : ids) {
|
ReceivableBillSettlementDetail detail = receivableBillSettlementDetailMapper.selectReceivableBillSettlementDetailById(id);
|
if (detail != null && detail.getBillId() != null) {
|
billIds.add(detail.getBillId());
|
}
|
}
|
|
// 2. 删除结算明细记录
|
int result = receivableBillSettlementDetailMapper.deleteReceivableBillSettlementDetailByIds(ids);
|
|
// 3. 如果删除成功,则更新相关主表金额和状态
|
if (result > 0) {
|
for (Integer billId : billIds) {
|
updateReceivableBillAmountAndStatus(billId);
|
}
|
}
|
|
return result;
|
}
|
|
/**
|
* 删除应收账单结算明细信息
|
*
|
* @param id 应收账单结算明细ID
|
* @return 结果
|
*/
|
@Override
|
public int deleteReceivableBillSettlementDetailById(Integer id)
|
{
|
// 1. 获取删除前的记录,用于后续更新主表
|
Integer billId = null;
|
ReceivableBillSettlementDetail detail = receivableBillSettlementDetailMapper.selectReceivableBillSettlementDetailById(id);
|
if (detail != null && detail.getBillId() != null) {
|
billId = detail.getBillId();
|
}
|
|
// 2. 删除结算明细记录
|
int result = receivableBillSettlementDetailMapper.deleteReceivableBillSettlementDetailById(id);
|
|
// 3. 如果删除成功,则更新相关主表金额和状态
|
if (result > 0 && billId != null) {
|
updateReceivableBillAmountAndStatus(billId);
|
}
|
|
return result;
|
}
|
}
|