package com.by4cloud.platformx.business.service.impl;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.by4cloud.platformx.business.dto.ContractAddDTO;
|
import com.by4cloud.platformx.business.dto.ContractUpdateDTO;
|
import com.by4cloud.platformx.business.entity.*;
|
import com.by4cloud.platformx.business.mapper.*;
|
import com.by4cloud.platformx.business.service.ContractService;
|
import com.by4cloud.platformx.business.utils.ContractNumberGenerator;
|
import com.by4cloud.platformx.business.vo.ContractDetailVo;
|
import com.by4cloud.platformx.common.core.util.R;
|
import com.by4cloud.platformx.common.security.util.SecurityUtils;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Service;
|
|
import java.io.Serializable;
|
import java.math.BigDecimal;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
/**
|
* @author cd
|
* @description
|
* @date 2026/4/29 14:07
|
**/
|
@Service
|
@RequiredArgsConstructor
|
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {
|
|
private final ContractSubjectMatterMapper contractSubjectMatterMapper;
|
private final ContractPaymentScheduleMapper contractPaymentScheduleMapper;
|
private final ContractPaymentScheduleProcessMapper contractPaymentScheduleProcessMapper;
|
private final PaymentConfirmMapper paymentConfirmMapper;
|
private final CurrentOverdueMapper currentOverdueMapper;
|
|
@Override
|
public R add(ContractAddDTO addDTO) {
|
Contract contract = BeanUtil.copyProperties(addDTO,Contract.class);
|
contract.setPartyBId(SecurityUtils.getUser().getCompId());
|
contract.setPartyB(SecurityUtils.getUser().getCompName());
|
contract.setContractNo(ContractNumberGenerator.generateContractNumber());
|
contract.setBillingStatus("0");
|
contract.setErpPushFlag("0");
|
List<Contract> contracts;
|
contracts = baseMapper.selectList(Wrappers.<Contract>lambdaQuery().eq(Contract::getContractNo,contract.getContractNo()));
|
while (ArrayUtil.isNotEmpty(contracts.toArray())){
|
contract.setContractNo(ContractNumberGenerator.generateContractNumber());
|
contracts = baseMapper.selectList(Wrappers.<Contract>lambdaQuery().eq(Contract::getContractNo,contract.getContractNo()));
|
}
|
baseMapper.insert(contract);
|
|
if (ArrayUtil.isNotEmpty(addDTO.getContractSubjectMatter())){
|
addDTO.getContractSubjectMatter().stream().forEach(contractSubjectMatterAddDTO -> {
|
ContractSubjectMatter subjectMatter = BeanUtil.copyProperties(contractSubjectMatterAddDTO, ContractSubjectMatter.class);
|
subjectMatter.setContractId(contract.getId());
|
subjectMatter.setContractName(contract.getContractName());
|
subjectMatter.setDeliveredQuantity(new BigDecimal("0"));
|
subjectMatter.setDeliveryStatus(0);
|
subjectMatter.setTotalAmount(contractSubjectMatterAddDTO.getQuantity().multiply(contractSubjectMatterAddDTO.getUnitPrice()));
|
contractSubjectMatterMapper.insert(subjectMatter);
|
});
|
}
|
|
if (ArrayUtil.isNotEmpty(addDTO.getContractPaymentSchedule())){
|
AtomicInteger index = new AtomicInteger(1);
|
addDTO.getContractPaymentSchedule().stream().forEach(contractPaymentScheduleAddDTO -> {
|
int currentIndex = index.getAndIncrement();
|
ContractPaymentSchedule schedule = BeanUtil.copyProperties(contractPaymentScheduleAddDTO, ContractPaymentSchedule.class);
|
if (contractPaymentScheduleAddDTO.getStageName().equals("合同签订")){
|
schedule.setEffectiveDate(DateUtil.offsetDay(contract.getSignDate(),contractPaymentScheduleAddDTO.getAgreedDays()));
|
}
|
if (ObjUtil.isNotNull(schedule.getEffectiveDate())) {
|
if (schedule.getEffectiveDate().before(DateUtil.date())) {
|
schedule.setFulfillmentStatus(1);
|
} else {
|
schedule.setFulfillmentStatus(0);
|
}
|
}
|
schedule.setPaymentStatus(0);
|
schedule.setContractId(contract.getId());
|
schedule.setContractName(contract.getContractName());
|
schedule.setPlannedAmount(contract.getAmount().multiply(schedule.getPaymentRatio().divide(new BigDecimal("100"))));
|
schedule.setStageOrder(currentIndex);
|
contractPaymentScheduleMapper.insert(schedule);
|
if (contractPaymentScheduleAddDTO.getStageName().equals("货到签收")){
|
contract.setArrivalScheduleId(schedule.getId());
|
baseMapper.updateById(contract);
|
}
|
if (contractPaymentScheduleAddDTO.getStageName().equals("调试完成或验收")){
|
contract.setAcceptScheduleId(schedule.getId());
|
baseMapper.updateById(contract);
|
}
|
});
|
|
}
|
|
|
|
return R.ok();
|
}
|
|
@Override
|
public R edit(ContractUpdateDTO updateDTO) {
|
Contract entity = baseMapper.selectById(updateDTO.getId());
|
if (!StrUtil.equals(entity.getContractStatus()+"","0")){
|
return R.failed("当前状态无法修改合同");
|
}
|
Contract contract = BeanUtil.copyProperties(updateDTO,Contract.class);
|
contract.setContractNo(ContractNumberGenerator.generateContractNumber());
|
baseMapper.updateById(contract);
|
|
if (ArrayUtil.isNotEmpty(updateDTO.getContractSubjectMatter())){
|
contractSubjectMatterMapper.delete(Wrappers.<ContractSubjectMatter>lambdaQuery().eq(ContractSubjectMatter::getContractId,contract.getId()));
|
|
updateDTO.getContractSubjectMatter().stream().forEach(contractSubjectMatterAddDTO -> {
|
ContractSubjectMatter subjectMatter = BeanUtil.copyProperties(contractSubjectMatterAddDTO, ContractSubjectMatter.class);
|
subjectMatter.setContractId(contract.getId());
|
subjectMatter.setContractName(contract.getContractName());
|
subjectMatter.setDeliveredQuantity(new BigDecimal("0"));
|
subjectMatter.setDeliveryStatus(0);
|
contractSubjectMatterMapper.insert(subjectMatter);
|
});
|
}
|
|
if (ArrayUtil.isNotEmpty(updateDTO.getContractPaymentSchedule())){
|
contractPaymentScheduleMapper.delete(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId()));
|
|
AtomicInteger index = new AtomicInteger(1);
|
updateDTO.getContractPaymentSchedule().stream().forEach(contractPaymentScheduleAddDTO -> {
|
int currentIndex = index.getAndIncrement();
|
ContractPaymentSchedule subjectMatter = BeanUtil.copyProperties(contractPaymentScheduleAddDTO, ContractPaymentSchedule.class);
|
subjectMatter.setContractId(contract.getId());
|
subjectMatter.setContractName(contract.getContractName());
|
subjectMatter.setPlannedAmount(contract.getAmount().multiply(subjectMatter.getPaymentRatio().divide(new BigDecimal("100"))));
|
subjectMatter.setStageOrder(currentIndex);
|
contractPaymentScheduleMapper.insert(subjectMatter);
|
});
|
|
}
|
|
return R.ok();
|
}
|
|
@Override
|
public ContractDetailVo detail(Long id) {
|
Contract contract = baseMapper.selectById(id);
|
ContractDetailVo detailVo = BeanUtil.copyProperties(contract,ContractDetailVo.class);
|
List<ContractSubjectMatter> subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.<ContractSubjectMatter>lambdaQuery().eq(ContractSubjectMatter::getContractId,id));
|
detailVo.setContractSubjectMatter(subjectMatterList);
|
List<ContractPaymentSchedule> paymentScheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId()));
|
detailVo.setContractPaymentSchedule(paymentScheduleList);
|
return detailVo;
|
}
|
|
@Override
|
public Boolean takeEffect(Long id) {
|
Contract contract = baseMapper.selectById(id);
|
contract.setContractStatus(1);
|
baseMapper.updateById(contract);
|
ContractPaymentSchedule fitstSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId())
|
.orderByAsc(ContractPaymentSchedule::getCreateTime).last("limit 1"));
|
if (fitstSchedule.getStageName().equals("合同签订")){
|
//新增应收
|
PaymentConfirm paymentConfirm = new PaymentConfirm();
|
paymentConfirm.setBusinessType("合同签订应收");
|
paymentConfirm.setBusGuestId(contract.getPartyAId());
|
paymentConfirm.setBusGuestName(contract.getPartyA());
|
paymentConfirm.setContractId(contract.getId());
|
paymentConfirm.setContractName(contract.getContractName());
|
paymentConfirm.setContractNo(contract.getContractNo());
|
paymentConfirm.setScheduleId(fitstSchedule.getId());
|
paymentConfirm.setScheduleName(fitstSchedule.getStageName());
|
paymentConfirm.setConfirmTime(new Date());
|
paymentConfirm.setTransationAmount(fitstSchedule.getPlannedAmount());
|
paymentConfirm.setReceivableAmount(fitstSchedule.getPlannedAmount());
|
paymentConfirm.setTotalAmount(fitstSchedule.getPlannedAmount().multiply(new BigDecimal("-1")));
|
paymentConfirmMapper.insert(paymentConfirm);
|
//新增合同履约记录
|
ContractPaymentScheduleProcess process = new ContractPaymentScheduleProcess();
|
process.setContractId(contract.getId());
|
process.setContractName(contract.getContractName());
|
process.setScheduleId(fitstSchedule.getId());
|
process.setScheduleName(fitstSchedule.getStageName());
|
process.setProcessDate(contract.getSignDate());
|
contractPaymentScheduleProcessMapper.insert(process);
|
}
|
//查询是否有后续阶段
|
List<ContractPaymentSchedule> afterSchedule = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
|
.eq(ContractPaymentSchedule::getContractId, fitstSchedule.getContractId())
|
.gt(ContractPaymentSchedule::getStageOrder, fitstSchedule.getStageOrder())
|
.orderByAsc(ContractPaymentSchedule::getCreateTime));
|
if (ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()==1){
|
//最后阶段生效时间
|
ContractPaymentSchedule endSchedule = afterSchedule.get(0);
|
if (StrUtil.equals(endSchedule.getStageName(),"质保金")){
|
endSchedule.setEffectiveDate(DateUtil.offsetDay(new Date(),endSchedule.getAgreedDays()));
|
endSchedule.setEffectiveEndDate(contract.getExpirationDate());
|
contractPaymentScheduleMapper.updateById(endSchedule);
|
//第一阶段生效时间
|
fitstSchedule.setEffectiveDate(DateUtil.offsetDay(new Date(),fitstSchedule.getAgreedDays()));
|
fitstSchedule.setEffectiveEndDate(endSchedule.getEffectiveDate());
|
contractPaymentScheduleMapper.updateById(fitstSchedule);
|
|
//最后阶段应收
|
PaymentConfirm newConfim = new PaymentConfirm();
|
newConfim.setBusinessType(endSchedule.getStageName()+"应收");
|
newConfim.setBusGuestId(contract.getPartyAId());
|
newConfim.setBusGuestName(contract.getPartyA());
|
newConfim.setContractId(contract.getId());
|
newConfim.setContractName(contract.getContractName());
|
newConfim.setContractNo(contract.getContractNo());
|
newConfim.setScheduleId(endSchedule.getId());
|
newConfim.setScheduleName(endSchedule.getStageName());
|
newConfim.setConfirmTime(new Date());
|
newConfim.setTransationAmount(endSchedule.getPlannedAmount());
|
newConfim.setReceivableAmount(endSchedule.getPlannedAmount());
|
PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
|
.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
|
BigDecimal lastNewTotal = new BigDecimal("0");
|
if(ObjUtil.isNotNull(lastNewConfirm)){
|
lastNewTotal = lastNewConfirm.getTotalAmount();
|
}
|
newConfim.setTotalAmount(lastNewTotal.subtract(newConfim.getReceivableAmount()));
|
paymentConfirmMapper.insert(newConfim);
|
}
|
//更新合同下个阶段
|
contract.setNextScheduleName(endSchedule.getStageName());
|
baseMapper.updateById(contract);
|
}
|
if(ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()>1){
|
//更新合同下个阶段
|
contract.setNextScheduleName(afterSchedule.get(0).getStageName());
|
baseMapper.updateById(contract);
|
}
|
if(ArrayUtil.isEmpty(afterSchedule.toArray())){
|
fitstSchedule.setEffectiveEndDate(contract.getExpirationDate());
|
contractPaymentScheduleMapper.updateById(fitstSchedule);
|
//更新合同下个阶段
|
contract.setNextScheduleName("无");
|
baseMapper.updateById(contract);
|
}
|
return Boolean.TRUE;
|
}
|
|
@Override
|
public R genCurrentOverdue() {
|
List<ContractPaymentSchedule> scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery()
|
.lt(ContractPaymentSchedule::getEffectiveEndDate, DateUtil.today())
|
.ne(ContractPaymentSchedule::getPaymentStatus,"2"));
|
if (ArrayUtil.isNotEmpty(scheduleList.toArray())){
|
scheduleList.stream().forEach(contractPaymentSchedule -> {
|
Contract contract = baseMapper.selectById(contractPaymentSchedule.getContractId());
|
//应收超期
|
PaymentConfirm overdueConfirm = new PaymentConfirm();
|
overdueConfirm.setBusinessType("应收超期");
|
overdueConfirm.setBusGuestId(contract.getPartyAId());
|
overdueConfirm.setBusGuestName(contract.getPartyA());
|
overdueConfirm.setContractId(contract.getId());
|
overdueConfirm.setContractName(contract.getContractName());
|
overdueConfirm.setContractNo(contract.getContractNo());
|
overdueConfirm.setConfirmTime(new Date());
|
overdueConfirm.setScheduleId(contractPaymentSchedule.getId());
|
overdueConfirm.setScheduleName(contractPaymentSchedule.getStageName());
|
PaymentConfirm newLastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId())
|
.orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
|
overdueConfirm.setTransationAmount(StrUtil.equals(contractPaymentSchedule.getPaymentStatus()+"","0")?
|
contractPaymentSchedule.getPlannedAmount():
|
contractPaymentSchedule.getPlannedAmount().subtract(contractPaymentSchedule.getActualAmount()));
|
overdueConfirm.setReceivableAmount(newLastConfirm.getTotalAmount().multiply(new BigDecimal("-1")));
|
overdueConfirm.setOverdueAmount(overdueConfirm.getTransationAmount());
|
overdueConfirm.setTotalAmount(newLastConfirm.getTotalAmount());
|
overdueConfirm.setCompId(contract.getCompId());
|
//判断当前阶段是否已生成上阶段应收超期
|
PaymentConfirm oiverdueConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getScheduleId, contractPaymentSchedule.getId())
|
.eq(PaymentConfirm::getBusinessType, "应收超期"));
|
if (ObjUtil.isNull(oiverdueConfirm)) {
|
paymentConfirmMapper.insert(overdueConfirm);
|
}
|
//当前逾期
|
CurrentOverdue currentOverdue = new CurrentOverdue();
|
currentOverdue.setBusGuestId(contract.getPartyAId());
|
currentOverdue.setBusGuestName(contract.getPartyA());
|
currentOverdue.setContractId(contractPaymentSchedule.getContractId());
|
currentOverdue.setContractName(contractPaymentSchedule.getContractName());
|
currentOverdue.setScheduleId(contractPaymentSchedule.getId());
|
currentOverdue.setScheduleName(contractPaymentSchedule.getStageName());
|
currentOverdue.setCompId(contract.getCompId());
|
currentOverdue.setContractExpirTime(contractPaymentSchedule.getEffectiveEndDate());
|
currentOverdue.setReceivableAmount(StrUtil.equals(contractPaymentSchedule.getPaymentStatus()+"","0")?
|
contractPaymentSchedule.getPlannedAmount():contractPaymentSchedule.getPlannedAmount().subtract(contractPaymentSchedule.getActualAmount()));
|
currentOverdue.setOverdueDuration(BigDecimal.valueOf(DateUtil.betweenDay(contractPaymentSchedule.getEffectiveEndDate(),new Date(),true)));
|
CurrentOverdue overdue = currentOverdueMapper.selectOne(Wrappers.<CurrentOverdue>lambdaQuery().eq(CurrentOverdue::getContractId,currentOverdue.getContractId())
|
.eq(CurrentOverdue::getScheduleId,currentOverdue.getScheduleId()).last("limit 1"));
|
if (ObjUtil.isNull(overdue)){
|
currentOverdueMapper.insert(currentOverdue);
|
}else {
|
overdue.setOverdueDuration(BigDecimal.valueOf(DateUtil.betweenDay(contractPaymentSchedule.getEffectiveEndDate(),new Date(),true)));
|
currentOverdueMapper.updateById(overdue);
|
}
|
});
|
}
|
return R.ok();
|
}
|
}
|