| | |
| | | package com.by4cloud.platformx.business.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.date.DatePattern; |
| | | 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.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.by4cloud.platformx.business.dto.OutBoundAddDTO; |
| | |
| | | import com.by4cloud.platformx.business.mapper.*; |
| | | import com.by4cloud.platformx.business.service.OutBoundService; |
| | | import com.by4cloud.platformx.common.core.util.R; |
| | | import com.by4cloud.platformx.common.security.util.SecurityUtils; |
| | | import com.github.yulichang.wrapper.MPJLambdaWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | private final ContractMapper contractMapper; |
| | | private final ContractPaymentScheduleProcessMapper scheduleProcessMapper; |
| | | private final ContractOutBoundMapper contractOutBoundMapper; |
| | | private final DeliveryOverdueMapper deliveryOverdueMapper; |
| | | private final StringRedisTemplate redisTemplate; |
| | | |
| | | @Value("${dept.smj}") |
| | | private String smj; |
| | | |
| | | @Value("${dept.sgb}") |
| | | private String sgb; |
| | | |
| | | @Value("${dept.jxc}") |
| | | private String jxc; |
| | | |
| | | @Value("${dept.tfgs}") |
| | | private String tfgs; |
| | | |
| | | @Value("${dept.ymj}") |
| | | private String ymj; |
| | | |
| | | @Override |
| | | public R add(OutBoundAddDTO addDTO) { |
| | |
| | | MPJLambdaWrapper<ContractSubjectMatter> wrapper = new MPJLambdaWrapper<ContractSubjectMatter>() |
| | | .selectAll(ContractSubjectMatter.class) |
| | | .ne(ContractSubjectMatter::getDeliveryStatus, 2) |
| | | .in(ContractSubjectMatter::getMaterialCode,addDTO.getSubjectMatterList().stream().map(item->item.getSubjectMatterCode()).collect(Collectors.toList())) |
| | | .in(ContractSubjectMatter::getMaterialCode, addDTO.getSubjectMatterList().stream().map(item -> item.getSubjectMatterCode()).collect(Collectors.toList())) |
| | | .exists(Contract.class, contractQuery -> |
| | | contractQuery.select(ContractSubjectMatter::getId) |
| | | .eq(Contract::getContractStatus, 2) |
| | | .eq(Contract::getId, ContractSubjectMatter::getContractId) |
| | | .eq(StrUtil.isNotBlank(addDTO.getBusGuestName()), Contract::getPartyA, addDTO.getBusGuestName()) |
| | | .eq(ObjUtil.isNotNull(addDTO.getBusGuestId()), Contract::getPartyAId, addDTO.getBusGuestId()) |
| | |
| | | if (ArrayUtil.isEmpty(subjectMatterList.toArray())) { |
| | | return R.failed("没有查询到相关合同订单"); |
| | | } |
| | | Double outTotal = subjectMatterList.stream().mapToDouble(item -> { |
| | | // 优先判断 remainNum |
| | | if (item.getRemainingQuantity() != null && item.getRemainingQuantity().compareTo(new BigDecimal("0")) > 0) { |
| | | return item.getRemainingQuantity().doubleValue(); |
| | | } else { |
| | | // remainNum 为 null 或 0 时,使用 quantity |
| | | return item.getQuantity() == null ? 0.0 : item.getQuantity().doubleValue(); |
| | | } |
| | | }).sum(); |
| | | BigDecimal orderNum = addDTO.getSubjectMatterList().stream().map(OutSubjectMatterAddDTO::getOutBoundNum) |
| | | List<String> erpCodeList = subjectMatterList.stream().map(ContractSubjectMatter::getMaterialCode).collect(Collectors.toList()); |
| | | BigDecimal orderNum = subjectMatterList.stream().filter(item -> item.getDeliveryStatus() != 2) |
| | | .map(item -> item.getDeliveryStatus() == 0 ? item.getQuantity() : item.getRemainingQuantity()) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | BigDecimal outTotal = addDTO.getSubjectMatterList().stream() |
| | | .filter(item -> erpCodeList.contains(item.getSubjectMatterCode())) |
| | | .map(OutSubjectMatterAddDTO::getOutBoundNum) |
| | | .filter(num -> num != null) // 过滤掉 null 值,防止 NullPointerException |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | if (new BigDecimal(outTotal).compareTo(orderNum) < 0) { |
| | | if (outTotal.compareTo(orderNum) > 0) { |
| | | return R.failed("出库数量超出合同订单数量"); |
| | | } |
| | | //当前入库标的物 |
| | | List<ContractSubjectMatter> currentOutList = new ArrayList<>(); |
| | | Map<Long, Object> currentOutMap = new HashMap<>(); |
| | | //出库批次 |
| | | // String batchNumber = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN); |
| | | //出库 |
| | | addDTO.getSubjectMatterList().stream().forEach(outSubjectMatterAddDTO -> { |
| | | BigDecimal remainNum = outSubjectMatterAddDTO.getOutBoundNum(); |
| | | for (ContractSubjectMatter subjectMatter : subjectMatterList) { |
| | | Contract contract = contractMapper.selectById(subjectMatter.getContractId()); |
| | | if (subjectMatter.getDeliveredQuantity().compareTo(new BigDecimal("0")) > 0) { |
| | | remainNum = remainNum.subtract(subjectMatter.getRemainingQuantity()); |
| | | //部分交付状态下 全部出库 |
| | | if (remainNum.compareTo(new BigDecimal("0")) >= 0) { |
| | | BigDecimal currentOut = subjectMatter.getRemainingQuantity(); |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity()); |
| | | subjectMatter.setRemainingQuantity(new BigDecimal("0")); |
| | | subjectMatter.setActualDeliveryDate(DateUtil.today()); |
| | | subjectMatter.setDeliveryStatus(2); |
| | | subjectMatter.setLastDeliveredQuantity(currentOut); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutList.add(subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract,addDTO,subjectMatter); |
| | | } else { |
| | | BigDecimal currentOut = remainNum.add(subjectMatter.getRemainingQuantity()); |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity().add(remainNum)); |
| | | subjectMatter.setRemainingQuantity(subjectMatter.getRemainingQuantity().subtract(currentOut)); |
| | | subjectMatter.setActualDeliveryDate(DateUtil.today()); |
| | | subjectMatter.setDeliveryStatus(1); |
| | | subjectMatter.setLastDeliveredQuantity(currentOut); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutList.add(subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract,addDTO,subjectMatter); |
| | | break; |
| | | } |
| | | |
| | | } else { |
| | | //未交付状态下 |
| | | remainNum = remainNum.subtract(subjectMatter.getQuantity()); |
| | | if (remainNum.compareTo(new BigDecimal("0")) >= 0) { |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity()); |
| | | subjectMatter.setRemainingQuantity(new BigDecimal("0")); |
| | | subjectMatter.setActualDeliveryDate(DateUtil.today()); |
| | | subjectMatter.setDeliveryStatus(2); |
| | | subjectMatter.setLastDeliveredQuantity(subjectMatter.getQuantity()); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutList.add(subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract,addDTO,subjectMatter); |
| | | } else { |
| | | BigDecimal currentOut = remainNum.add(subjectMatter.getQuantity()); |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity().add(remainNum)); |
| | | subjectMatter.setRemainingQuantity(remainNum.multiply(new BigDecimal("-1"))); |
| | | subjectMatter.setActualDeliveryDate(DateUtil.today()); |
| | | subjectMatter.setDeliveryStatus(1); |
| | | subjectMatter.setLastDeliveredQuantity(currentOut); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutList.add(subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract,addDTO,subjectMatter); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | OutBound outBound = BeanUtil.copyProperties(outSubjectMatterAddDTO, OutBound.class); |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",smj)){ |
| | | outBound.setBatchNumber(generateSMJContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",sgb)){ |
| | | outBound.setBatchNumber(generateGYBContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",ymj)){ |
| | | outBound.setBatchNumber(generateYMJContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",tfgs)){ |
| | | outBound.setBatchNumber(generateTFContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",jxc)){ |
| | | outBound.setBatchNumber(generateJXCContractCKNo()); |
| | | } |
| | | outBound.setBusGuestName(addDTO.getBusGuestName()); |
| | | outBound.setBusGuestId(addDTO.getBusGuestId()); |
| | | outBound.setOutBoundTime(addDTO.getOutBoundTime()); |
| | | baseMapper.insert(outBound); |
| | | BigDecimal remainNum = outSubjectMatterAddDTO.getOutBoundNum(); |
| | | for (ContractSubjectMatter subjectMatter : subjectMatterList) { |
| | | if (outSubjectMatterAddDTO.getSubjectMatterCode().equals(subjectMatter.getMaterialCode())) { |
| | | Contract contract = contractMapper.selectById(subjectMatter.getContractId()); |
| | | if (subjectMatter.getDeliveredQuantity().compareTo(new BigDecimal("0")) > 0) { |
| | | remainNum = remainNum.subtract(subjectMatter.getRemainingQuantity()); |
| | | //部分交付状态下 全部出库 |
| | | if (remainNum.compareTo(new BigDecimal("0")) > 0) { |
| | | BigDecimal currentOut = subjectMatter.getRemainingQuantity(); |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity()); |
| | | subjectMatter.setRemainingQuantity(new BigDecimal("0")); |
| | | subjectMatter.setActualDeliveryDate(addDTO.getOutBoundTime()); |
| | | subjectMatter.setDeliveryStatus(2); |
| | | subjectMatter.setLastDeliveredQuantity(currentOut); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutMap.put(subjectMatter.getContractId(), subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract, addDTO, subjectMatter, outBound.getId()); |
| | | } else { |
| | | BigDecimal currentOut = remainNum.add(subjectMatter.getRemainingQuantity()); |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity().add(remainNum)); |
| | | subjectMatter.setRemainingQuantity(subjectMatter.getRemainingQuantity().subtract(currentOut)); |
| | | subjectMatter.setActualDeliveryDate(addDTO.getOutBoundTime()); |
| | | subjectMatter.setDeliveryStatus(1); |
| | | subjectMatter.setLastDeliveredQuantity(currentOut); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutMap.put(subjectMatter.getContractId(), subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract, addDTO, subjectMatter, outBound.getId()); |
| | | break; |
| | | } |
| | | |
| | | } else { |
| | | //未交付状态下 |
| | | remainNum = remainNum.subtract(subjectMatter.getQuantity()); |
| | | if (remainNum.compareTo(new BigDecimal("0")) > 0) { |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity()); |
| | | subjectMatter.setRemainingQuantity(new BigDecimal("0")); |
| | | subjectMatter.setActualDeliveryDate(addDTO.getOutBoundTime()); |
| | | subjectMatter.setDeliveryStatus(2); |
| | | subjectMatter.setLastDeliveredQuantity(subjectMatter.getQuantity()); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutMap.put(subjectMatter.getContractId(), subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract, addDTO, subjectMatter, outBound.getId()); |
| | | } else { |
| | | BigDecimal currentOut = remainNum.add(subjectMatter.getQuantity()); |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getQuantity().add(remainNum)); |
| | | subjectMatter.setRemainingQuantity(remainNum.multiply(new BigDecimal("-1"))); |
| | | subjectMatter.setActualDeliveryDate(addDTO.getOutBoundTime()); |
| | | subjectMatter.setDeliveryStatus(1); |
| | | subjectMatter.setLastDeliveredQuantity(currentOut); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | currentOutMap.put(subjectMatter.getContractId(), subjectMatter); |
| | | //新增合同出库历史 |
| | | saveContractOutBound(contract, addDTO, subjectMatter, outBound.getId()); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | }); |
| | | |
| | | //出库应收款明细 |
| | | if (ArrayUtil.isNotEmpty(currentOutList.toArray())) { |
| | | //根据合同id拆分应收明细 |
| | | Map<Long, List<ContractSubjectMatter>> conSubMatMap = currentOutList.stream().collect(Collectors.groupingBy(ContractSubjectMatter::getContractId)); |
| | | |
| | | conSubMatMap.forEach((key, value) -> { |
| | | if (ArrayUtil.isNotEmpty(currentOutMap.keySet())) { |
| | | for (Long contractId : currentOutMap.keySet()) { |
| | | //当前出库合同出库标的物 |
| | | List<ContractSubjectMatter> contractSubjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.<ContractSubjectMatter>lambdaQuery() |
| | | .eq(ContractSubjectMatter::getContractId, contractId).ne(ContractSubjectMatter::getDeliveryStatus, 0)); |
| | | //查询合同是否有出库阶段 |
| | | ContractPaymentSchedule schedule = scheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, key) |
| | | ContractPaymentSchedule schedule = scheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, contractId) |
| | | .eq(ContractPaymentSchedule::getStageName, "发货前")); |
| | | //当前出库金额 |
| | | BigDecimal outPirce = value.stream() |
| | | .filter(item -> item.getLastDeliveredQuantity() != null && item.getUnitPrice() != null) |
| | | .map(item ->(item.getDeliveryStatus()==1?item.getDeliveredQuantity():item.getQuantity()).multiply(item.getUnitPrice())) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | //合同金额 |
| | | Contract contract = contractMapper.selectById(key); |
| | | //出库是否完成 |
| | | if (outPirce.compareTo(contract.getAmount())<0){ |
| | | contract.setBillingStatus("1"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | if (outPirce.compareTo(contract.getAmount())==0){ |
| | | contract.setBillingStatus("2"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | //存在出库阶段 |
| | | if (ObjUtil.isNotNull(schedule)) { |
| | | //按出库资金比例 计算发货前应收更新资金明细 |
| | | //当前出库金额 |
| | | BigDecimal outPirce = contractSubjectMatterList.stream() |
| | | .map(item -> (item.getDeliveryStatus() == 1 ? item.getDeliveredQuantity().multiply(item.getUnitPrice()) : item.getQuantity().multiply(item.getUnitPrice()))) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | //合同金额 |
| | | Contract contract = contractMapper.selectById(contractId); |
| | | //出库是否完成 |
| | | if (outPirce.compareTo(contract.getBillingAmout())>0) { |
| | | contract.setBillingStatus("2"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | if (outPirce.compareTo(contract.getBillingAmout())==0) { |
| | | contract.setBillingStatus("1"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | if (outPirce.compareTo(contract.getAmount()) == 0&& |
| | | outPirce.compareTo(contract.getBillingAmout())==0) { |
| | | contract.setBillingStatus("3"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | //计算发货前应收更新资金明细 |
| | | PaymentConfirm paymentConfirm = new PaymentConfirm(); |
| | | paymentConfirm.setBusinessType("发货前应收"); |
| | | paymentConfirm.setBusGuestId(contract.getPartyAId()); |
| | |
| | | paymentConfirm.setScheduleId(schedule.getId()); |
| | | paymentConfirm.setScheduleName(schedule.getStageName()); |
| | | paymentConfirm.setConfirmTime(addDTO.getOutBoundTime()); |
| | | //按出库资金比例 计算发货前应收 |
| | | paymentConfirm.setTransationAmount(outPirce.divide(contract.getAmount(), 10, RoundingMode.HALF_UP).multiply(schedule.getPlannedAmount())); |
| | | paymentConfirm.setReceivableAmount(paymentConfirm.getTransationAmount()); |
| | | paymentConfirm.setTotalAmount(paymentConfirm.getTransationAmount().multiply(new BigDecimal("-1"))); |
| | | |
| | | //最近应收 |
| | | PaymentConfirm lastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | |
| | | if (ObjUtil.isNotNull(lastConfirm)) { |
| | | paymentConfirm.setTotalAmount(paymentConfirm.getTotalAmount().add(lastConfirm.getTotalAmount())); |
| | | paymentConfirmMapper.insert(paymentConfirm); |
| | | } else { |
| | | paymentConfirmMapper.insert(paymentConfirm); |
| | | } |
| | | //更新发货前收款生效时间 |
| | | if (ObjUtil.isNull(schedule.getEffectiveDate())){ |
| | | schedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getOutBoundTime(),schedule.getAgreedDays())); |
| | | //查询是否有后续阶段 |
| | | List<ContractPaymentSchedule> afterSchedule = scheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, key) |
| | | .gt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder())); |
| | | if (ArrayUtil.isEmpty(afterSchedule.toArray())){ |
| | | schedule.setEffectiveEndDate(contract.getExpirationDate()); |
| | | //已存在发货应收 |
| | | if (StrUtil.equals(lastConfirm.getBusinessType(), paymentConfirm.getBusinessType())) { |
| | | |
| | | //查询之前所有发货前应收 |
| | | List<PaymentConfirm> fhConfirmList = paymentConfirmMapper.selectList(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) |
| | | .eq(PaymentConfirm::getScheduleId, schedule.getId()).orderByDesc(PaymentConfirm::getCreateTime)); |
| | | BigDecimal fhTotalAmount = fhConfirmList.stream().map(item -> item.getTransationAmount()).reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | //本次发货前应收 出库总额 - 所有发货前应收 |
| | | paymentConfirm.setTransationAmount(paymentConfirm.getTransationAmount().subtract(fhTotalAmount)); |
| | | paymentConfirm.setReceivableAmount(paymentConfirm.getTransationAmount()); |
| | | paymentConfirm.setTotalAmount(lastConfirm.getTotalAmount().subtract(paymentConfirm.getTransationAmount())); |
| | | if (schedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { |
| | | paymentConfirmMapper.insert(paymentConfirm); |
| | | } |
| | | } else { |
| | | //不存在发货应收 出库总额 |
| | | paymentConfirm.setTotalAmount(lastConfirm.getTotalAmount().subtract(paymentConfirm.getTransationAmount())); |
| | | if (schedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { |
| | | paymentConfirmMapper.insert(paymentConfirm); |
| | | } |
| | | } |
| | | } else { |
| | | //无之前阶段应收 |
| | | paymentConfirm.setTotalAmount(paymentConfirm.getTransationAmount().multiply(new BigDecimal("-1"))); |
| | | if (schedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { |
| | | paymentConfirmMapper.insert(paymentConfirm); |
| | | //客户付款完成合同 |
| | | List<Contract> customerCompleteContractList = contractMapper.selectList(Wrappers.<Contract>lambdaQuery().eq(Contract::getPartyAId, contract.getPartyAId()) |
| | | .eq(Contract::getPartyBId, SecurityUtils.getUser().getCompId()).apply(" amount = paid_amount")); |
| | | if (ArrayUtil.isNotEmpty(customerCompleteContractList)) { |
| | | List<BigDecimal> outAmountList = new ArrayList<>(); |
| | | for (Contract completeContract : customerCompleteContractList |
| | | ) { |
| | | PaymentConfirm contractLastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, completeContract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | //查询客户付款完成合同中最后明细金额 有预收转入当前合同 |
| | | if (contractLastConfirm.getTotalAmount().compareTo(new BigDecimal("0")) > 0) { |
| | | //新增完成付款合同 资金转出 |
| | | PaymentConfirm outConfirm = BeanUtil.copyProperties(contractLastConfirm, PaymentConfirm.class, "id", "transationAmount", |
| | | "advanceAmount", "receivableAmount", "overdueAmount", "totalAmount"); |
| | | outConfirm.setBusinessType("资金转出"); |
| | | outConfirm.setConfirmTime(new Date()); |
| | | outConfirm.setTransationAmount(contractLastConfirm.getTotalAmount()); |
| | | outConfirm.setTotalAmount(new BigDecimal("0")); |
| | | paymentConfirmMapper.insert(outConfirm); |
| | | outAmountList.add(outConfirm.getTransationAmount()); |
| | | } |
| | | } |
| | | if (ArrayUtil.isNotEmpty(outAmountList.toArray())) { |
| | | BigDecimal currentInSum = outAmountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | //新增当前合同 资金转入 |
| | | PaymentConfirm inConfirm = BeanUtil.copyProperties(paymentConfirm, PaymentConfirm.class, "id", "transationAmount", |
| | | "advanceAmount", "receivableAmount", "overdueAmount", "totalAmount"); |
| | | inConfirm.setBusinessType("资金转入"); |
| | | inConfirm.setConfirmTime(new Date()); |
| | | inConfirm.setTransationAmount(currentInSum); |
| | | inConfirm.setTotalAmount(paymentConfirm.getTotalAmount().add(currentInSum)); |
| | | //更新当前阶段实际收款 和 收款状态 |
| | | schedule.setActualAmount(inConfirm.getTransationAmount()); |
| | | schedule.setPaymentStatus(2); |
| | | if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) > 0) { |
| | | inConfirm.setAdvanceAmount(inConfirm.getTotalAmount()); |
| | | } else if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) < 0) { |
| | | inConfirm.setReceivableAmount(inConfirm.getTotalAmount().multiply(new BigDecimal("-1"))); |
| | | schedule.setActualAmount(paymentConfirm.getTotalAmount().subtract(currentInSum)); |
| | | schedule.setPaymentStatus(1); |
| | | } |
| | | paymentConfirmMapper.insert(inConfirm); |
| | | //更新当前阶段实际收款 和 收款状态 |
| | | scheduleMapper.updateById(schedule); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //更新发货前收款生效时间 |
| | | if (ObjUtil.isNull(schedule.getEffectiveDate())) { |
| | | schedule.setEffectiveEndDate(DateUtil.offsetDay(addDTO.getOutBoundTime(), schedule.getAgreedDays())); |
| | | //查询是否有后续阶段 |
| | | // List<ContractPaymentSchedule> afterSchedule = scheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, contractId) |
| | | // .gt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder())); |
| | | // if (ArrayUtil.isEmpty(afterSchedule.toArray())) { |
| | | // schedule.setEffectiveEndDate(contract.getExpirationDate()); |
| | | // } |
| | | scheduleMapper.updateById(schedule); |
| | | //查询是否有之前阶段 |
| | | ContractPaymentSchedule beforeSchedule = scheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, schedule.getContractId()) |
| | | .lt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()).orderByDesc(ContractPaymentSchedule::getCreateTime).last("limit 1")); |
| | | if (ObjUtil.isNotNull(beforeSchedule)){ |
| | | beforeSchedule.setEffectiveEndDate(DateUtil.offsetDay(addDTO.getOutBoundTime(),beforeSchedule.getAgreedDays())); |
| | | scheduleMapper.updateById(beforeSchedule); |
| | | // ContractPaymentSchedule beforeSchedule = scheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, schedule.getContractId()) |
| | | // .lt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()).orderByDesc(ContractPaymentSchedule::getCreateTime).last("limit 1")); |
| | | // if (ObjUtil.isNotNull(beforeSchedule)) { |
| | | // beforeSchedule.setEffectiveEndDate(schedule.getEffectiveDate()); |
| | | // scheduleMapper.updateById(beforeSchedule); |
| | | // } |
| | | //更新履约 |
| | | ContractPaymentScheduleProcess contractPaymentScheduleProcess = new ContractPaymentScheduleProcess(); |
| | | contractPaymentScheduleProcess.setContractId(schedule.getContractId()); |
| | | contractPaymentScheduleProcess.setContractName(schedule.getContractName()); |
| | | contractPaymentScheduleProcess.setScheduleId(schedule.getId()); |
| | | contractPaymentScheduleProcess.setScheduleName(schedule.getStageName()); |
| | | contractPaymentScheduleProcess.setProcessDate(addDTO.getOutBoundTime()); |
| | | ContractPaymentScheduleProcess lastProcess = scheduleProcessMapper.selectOne(Wrappers.<ContractPaymentScheduleProcess>lambdaQuery().eq(ContractPaymentScheduleProcess::getContractId, schedule.getContractId()) |
| | | .eq(ContractPaymentScheduleProcess::getScheduleId, schedule.getId()).last("limit 1")); |
| | | if (ObjUtil.isNull(lastProcess)) { |
| | | scheduleProcessMapper.insert(contractPaymentScheduleProcess); |
| | | } |
| | | } |
| | | //更新履约 |
| | | ContractPaymentScheduleProcess contractPaymentScheduleProcess = new ContractPaymentScheduleProcess(); |
| | | contractPaymentScheduleProcess.setContractId(schedule.getContractId()); |
| | | contractPaymentScheduleProcess.setContractName(schedule.getContractName()); |
| | | contractPaymentScheduleProcess.setScheduleId(schedule.getId()); |
| | | contractPaymentScheduleProcess.setScheduleName(schedule.getStageName()); |
| | | contractPaymentScheduleProcess.setProcessDate(addDTO.getOutBoundTime()); |
| | | scheduleProcessMapper.insert(contractPaymentScheduleProcess); |
| | | |
| | | //查询是否有后续阶段 |
| | | List<ContractPaymentSchedule> afterSchedule = scheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery() |
| | | .eq(ContractPaymentSchedule::getContractId, schedule.getContractId()) |
| | | .gt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()) |
| | | .orderByAsc(ContractPaymentSchedule::getCreateTime)); |
| | | if (ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()==1){ |
| | | if (ArrayUtil.isNotEmpty(afterSchedule.toArray()) && afterSchedule.size() == 1) { |
| | | //最后阶段生效时间 |
| | | ContractPaymentSchedule endSchedule = afterSchedule.get(0); |
| | | if (StrUtil.equals(endSchedule.getStageName(),"质保金")) { |
| | | endSchedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getOutBoundTime(), endSchedule.getAgreedDays())); |
| | | endSchedule.setEffectiveEndDate(contract.getExpirationDate()); |
| | | scheduleMapper.updateById(endSchedule); |
| | | if (StrUtil.equals(endSchedule.getStageName(), "质保金")) { |
| | | // endSchedule.setEffectiveEndDate(DateUtil.offsetDay(addDTO.getOutBoundTime(), endSchedule.getAgreedDays())); |
| | | // scheduleMapper.updateById(endSchedule); |
| | | //当前阶段生效时间 |
| | | schedule.setEffectiveDate(DateUtil.offsetDay(addDTO.getOutBoundTime(), schedule.getAgreedDays())); |
| | | schedule.setEffectiveEndDate(endSchedule.getEffectiveDate()); |
| | | scheduleMapper.updateById(schedule); |
| | | // schedule.setEffectiveEndDate(DateUtil.offsetDay(addDTO.getOutBoundTime(), schedule.getAgreedDays())); |
| | | // scheduleMapper.updateById(schedule); |
| | | //最后阶段应收 |
| | | PaymentConfirm newConfim = new PaymentConfirm(); |
| | | newConfim.setBusinessType(endSchedule.getStageName() + "应收"); |
| | |
| | | lastNewTotal = lastNewConfirm.getTotalAmount(); |
| | | } |
| | | newConfim.setTotalAmount(lastNewTotal.subtract(newConfim.getReceivableAmount())); |
| | | paymentConfirmMapper.insert(newConfim); |
| | | if (endSchedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { |
| | | paymentConfirmMapper.insert(newConfim); |
| | | } |
| | | } |
| | | //更新合同下个阶段 |
| | | contract.setNextScheduleName(endSchedule.getStageName()); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | if(ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()>1){ |
| | | if (ArrayUtil.isNotEmpty(afterSchedule.toArray()) && afterSchedule.size() > 1) { |
| | | //更新合同下个阶段 |
| | | contract.setNextScheduleName(afterSchedule.get(0).getStageName()); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | if(ArrayUtil.isEmpty(afterSchedule.toArray())){ |
| | | schedule.setEffectiveEndDate(contract.getExpirationDate()); |
| | | scheduleMapper.updateById(schedule); |
| | | if (ArrayUtil.isEmpty(afterSchedule.toArray())) { |
| | | // schedule.setEffectiveEndDate(contract.getExpirationDate()); |
| | | // scheduleMapper.updateById(schedule); |
| | | //更新合同下个阶段 |
| | | contract.setNextScheduleName("无"); |
| | | contractMapper.updateById(contract); |
| | | //当前为合同最后阶段 |
| | | PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | if (lastNewConfirm.getTotalAmount().compareTo(new BigDecimal("0")) >= 0) { |
| | | //有预付且超过应收 关闭合同状态 |
| | | contract.setContractStatus(3); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | return R.ok(); |
| | | } |
| | | |
| | | private void saveContractOutBound(Contract contract, OutBoundAddDTO addDTO, ContractSubjectMatter subjectMatter) { |
| | | private void saveContractOutBound(Contract contract, OutBoundAddDTO addDTO, ContractSubjectMatter subjectMatter, Long outBoundId) { |
| | | ContractOutBound contractOutBound = new ContractOutBound(); |
| | | contractOutBound.setContractId(contract.getId()); |
| | | contractOutBound.setContractName(contract.getContractName()); |
| | |
| | | contractOutBound.setBusGuestName(contract.getPartyA()); |
| | | contractOutBound.setSubjectMatterCode(subjectMatter.getMaterialCode()); |
| | | contractOutBound.setSubjectMatterName(subjectMatter.getMaterialInternalName()); |
| | | contractOutBound.setOutBoundTime(addDTO.getOutBoundTime()); |
| | | contractOutBound.setOutBoundTime(ObjUtil.isNotNull(addDTO.getOutBoundTime())?addDTO.getOutBoundTime():new Date()); |
| | | contractOutBound.setOutBoundNum(subjectMatter.getLastDeliveredQuantity()); |
| | | contractOutBound.setOutBoundAttNames(addDTO.getOutBoundAttNames()); |
| | | contractOutBound.setOutBoundAttPaths(addDTO.getOutBoundAttPaths()); |
| | | contractOutBound.setOutBoundId(outBoundId); |
| | | contractOutBound.setLineNo(subjectMatter.getLineNo()); |
| | | contractOutBound.setInvoiceStatus("0"); |
| | | contractOutBound.setInvoiceNum(new BigDecimal("0")); |
| | | contractOutBoundMapper.insert(contractOutBound); |
| | | if (!StrUtil.equals(contract.getContractCategory(),"water_house")) { |
| | | // 1. 确定用于比较的基准日期(优先级:计划交货日期 > 合同到期日期) |
| | | Date deadline = subjectMatter.getPlannedDeliveryDate(); |
| | | if (ObjUtil.isNull(deadline)) { |
| | | deadline = contract.getExpirationDate(); |
| | | } |
| | | |
| | | // 2. 统一判断是否逾期 |
| | | // 注意:需确保 deadline 不为 null,防止空指针异常 |
| | | if (deadline != null && DateUtil.compare(addDTO.getOutBoundTime(), deadline) > 0) { |
| | | saveOverdueOutBound(contract, addDTO, subjectMatter); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | private void saveOverdueOutBound(Contract contract, OutBoundAddDTO addDTO, ContractSubjectMatter subjectMatter) { |
| | | DeliveryOverdue overdue = new DeliveryOverdue(); |
| | | overdue.setContractId(contract.getId()); |
| | | overdue.setContractName(contract.getContractName()); |
| | | overdue.setBusGuestId(contract.getPartyAId()); |
| | | overdue.setBusGuestName(contract.getPartyA()); |
| | | overdue.setMaterialName(subjectMatter.getMaterialName()); |
| | | overdue.setMaterialInternalName(subjectMatter.getMaterialInternalName()); |
| | | overdue.setMaterialCode(subjectMatter.getMaterialCode()); |
| | | overdue.setOverdueNum(subjectMatter.getLastDeliveredQuantity()); |
| | | overdue.setTotalAmount(subjectMatter.getUnitPrice().multiply(subjectMatter.getLastDeliveredQuantity())); |
| | | overdue.setOverdueDuration(new BigDecimal(DateUtil.betweenDay(addDTO.getOutBoundTime(), contract.getExpirationDate(), true))); |
| | | deliveryOverdueMapper.insert(overdue); |
| | | } |
| | | |
| | | @Override |
| | | public R addContractOut(OutBoundAddDTO addDTO) { |
| | | if (ArrayUtil.isEmpty(addDTO.getSubjectMatterList().toArray())) { |
| | | return R.failed("出库标的物不能为空"); |
| | | } |
| | | // 1. 确定查询用的合同编号字段值 |
| | | String targetContractNo = addDTO.getContractNo(); |
| | | boolean isSgbAndEmptyOutbound = StrUtil.isEmpty(addDTO.getOutBoundType()) |
| | | && StrUtil.equals(String.valueOf(SecurityUtils.getUser().getCompId()), sgb); |
| | | |
| | | // 2. 构建查询条件 |
| | | LambdaQueryWrapper<Contract> queryWrapper = Wrappers.lambdaQuery(Contract.class) |
| | | .eq(Contract::getContractStatus, 2) |
| | | .last("LIMIT 1"); // 注意:last 注入 SQL 片段,需确保防注入或业务可控 |
| | | |
| | | if (isSgbAndEmptyOutbound) { |
| | | // 条件 A: 使用 ERP 合同号查询 |
| | | queryWrapper.eq(Contract::getErpContractNo, targetContractNo); |
| | | } else { |
| | | // 条件 B: 使用普通合同号查询 |
| | | queryWrapper.eq(Contract::getContractNo, targetContractNo); |
| | | } |
| | | |
| | | // 3. 执行查询 |
| | | Contract contract = contractMapper.selectOne(queryWrapper); |
| | | if (ObjUtil.isNull(contract)) { |
| | | return R.failed("合同信息查询失败"); |
| | | } |
| | | //出库数量校验 |
| | | for (OutSubjectMatterAddDTO outSubjectMatterAddDTO: addDTO.getSubjectMatterList()) { |
| | | ContractSubjectMatter subjectMatter = contractSubjectMatterMapper.selectOne(Wrappers.<ContractSubjectMatter>lambdaQuery() |
| | | .eq(ContractSubjectMatter::getContractId,contract.getId()) |
| | | .eq(ContractSubjectMatter::getMaterialCode,outSubjectMatterAddDTO.getSubjectMatterCode()) |
| | | .eq(StrUtil.isNotEmpty(outSubjectMatterAddDTO.getLineNo()),ContractSubjectMatter::getLineNo,outSubjectMatterAddDTO.getLineNo()) |
| | | .last("limit 1")); |
| | | if (ObjUtil.isNull(subjectMatter)){ |
| | | continue; |
| | | } |
| | | if (outSubjectMatterAddDTO.getOutBoundNum().compareTo(new BigDecimal("0"))==0){ |
| | | return R.failed(outSubjectMatterAddDTO.getSubjectMatterCode()+"出库数量不能为0"); |
| | | } |
| | | if (subjectMatter.getDeliveryStatus()==0){ |
| | | if (outSubjectMatterAddDTO.getOutBoundNum().compareTo(subjectMatter.getQuantity())>0){ |
| | | return R.failed(outSubjectMatterAddDTO.getSubjectMatterCode()+"出库数不能超过合同中数量"); |
| | | } |
| | | } |
| | | if (subjectMatter.getDeliveryStatus()==1){ |
| | | if (outSubjectMatterAddDTO.getOutBoundNum().compareTo(subjectMatter.getRemainingQuantity())>0){ |
| | | return R.failed(outSubjectMatterAddDTO.getSubjectMatterCode()+"出库数不能超过未出库数量"); |
| | | } |
| | | } |
| | | if (subjectMatter.getDeliveryStatus()==2){ |
| | | return R.failed(outSubjectMatterAddDTO.getSubjectMatterCode()+"已出库完成,不能超额出库"); |
| | | } |
| | | } |
| | | |
| | | |
| | | addDTO.getSubjectMatterList().stream().forEach(outSubjectMatterAddDTO -> { |
| | | ContractSubjectMatter subjectMatter = contractSubjectMatterMapper.selectOne(Wrappers.<ContractSubjectMatter>lambdaQuery() |
| | | .eq(ContractSubjectMatter::getContractId,contract.getId()) |
| | | .eq(ContractSubjectMatter::getMaterialCode,outSubjectMatterAddDTO.getSubjectMatterCode()) |
| | | .ne(ContractSubjectMatter::getDeliveryStatus,2) |
| | | .eq(StrUtil.isNotEmpty(outSubjectMatterAddDTO.getLineNo()),ContractSubjectMatter::getLineNo,outSubjectMatterAddDTO.getLineNo()) |
| | | .last("limit 1")); |
| | | if (ObjUtil.isNull(subjectMatter)){ |
| | | return; |
| | | } |
| | | subjectMatter.setLastDeliveredQuantity(outSubjectMatterAddDTO.getOutBoundNum()); |
| | | outSubjectMatterAddDTO.setUnitPrice(subjectMatter.getUnitPrice()); |
| | | if (subjectMatter.getDeliveryStatus() == 0) { |
| | | subjectMatter.setDeliveredQuantity(outSubjectMatterAddDTO.getOutBoundNum()); |
| | | subjectMatter.setRemainingQuantity(subjectMatter.getQuantity().subtract(outSubjectMatterAddDTO.getOutBoundNum())); |
| | | } |
| | | if (subjectMatter.getDeliveryStatus() == 1) { |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getDeliveredQuantity().add(outSubjectMatterAddDTO.getOutBoundNum())); |
| | | subjectMatter.setRemainingQuantity(subjectMatter.getRemainingQuantity().subtract(outSubjectMatterAddDTO.getOutBoundNum())); |
| | | } |
| | | subjectMatter.setDeliveryStatus(1); |
| | | if (subjectMatter.getRemainingQuantity().compareTo(new BigDecimal("0")) == 0) { |
| | | subjectMatter.setDeliveryStatus(2); |
| | | } |
| | | subjectMatter.setActualDeliveryDate(addDTO.getOutBoundTime()); |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | // |
| | | OutBound outBound = new OutBound(); |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",smj)){ |
| | | outBound.setBatchNumber(generateSMJContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",sgb)){ |
| | | outBound.setBatchNumber(generateGYBContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",ymj)){ |
| | | outBound.setBatchNumber(generateYMJContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",tfgs)){ |
| | | outBound.setBatchNumber(generateTFContractCKNo()); |
| | | } |
| | | if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",jxc)){ |
| | | outBound.setBatchNumber(generateJXCContractCKNo()); |
| | | } |
| | | outBound.setOutBoundNum(outSubjectMatterAddDTO.getOutBoundNum()); |
| | | outBound.setOutBoundAttNames(addDTO.getOutBoundAttNames()); |
| | | outBound.setOutBoundAttPaths(addDTO.getOutBoundAttPaths()); |
| | | outBound.setBusGuestName(contract.getPartyA()); |
| | | outBound.setBusGuestId(contract.getPartyAId()); |
| | | outBound.setOutBoundTime(ObjUtil.isNotNull(addDTO.getOutBoundTime())?addDTO.getOutBoundTime():new Date()); |
| | | outBound.setSubjectMatterCode(outSubjectMatterAddDTO.getSubjectMatterCode()); |
| | | outBound.setSubjectMatterName(outSubjectMatterAddDTO.getSubjectMatterName()); |
| | | outBound.setOutBoundType("1"); |
| | | if (StrUtil.isEmpty(addDTO.getOutBoundType())){ |
| | | outBound.setOutBoundType("0"); |
| | | } |
| | | baseMapper.insert(outBound); |
| | | // |
| | | saveContractOutBound(contract, addDTO, subjectMatter, outBound.getId()); |
| | | }); |
| | | //当前出库合同出库标的物 |
| | | List<ContractSubjectMatter> contractSubjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.<ContractSubjectMatter>lambdaQuery() |
| | | .eq(ContractSubjectMatter::getContractId, contract.getId()).ne(ContractSubjectMatter::getDeliveryStatus, 0)); |
| | | //查询合同是否有出库阶段 |
| | | ContractPaymentSchedule schedule = scheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery().eq(ContractPaymentSchedule::getContractId, contract.getId()) |
| | | .eq(ContractPaymentSchedule::getStageName, "发货前")); |
| | | //存在出库阶段 |
| | | if (ObjUtil.isNotNull(schedule)) { |
| | | //当前出库金额 |
| | | BigDecimal outPirce = contractSubjectMatterList.stream() |
| | | .map(item -> (item.getDeliveryStatus() == 1 ? item.getDeliveredQuantity().multiply(item.getUnitPrice()) : item.getQuantity().multiply(item.getUnitPrice()))) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | //出库是否完成 |
| | | if (outPirce.compareTo(contract.getBillingAmout())>0) { |
| | | contract.setBillingStatus("2"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | if (outPirce.compareTo(contract.getBillingAmout())==0) { |
| | | contract.setBillingStatus("1"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | if (outPirce.compareTo(contract.getAmount()) == 0&& |
| | | outPirce.compareTo(contract.getBillingAmout())==0) { |
| | | contract.setBillingStatus("3"); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | //计算发货前应收更新资金明细 |
| | | 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(schedule.getId()); |
| | | paymentConfirm.setScheduleName(schedule.getStageName()); |
| | | paymentConfirm.setConfirmTime(addDTO.getOutBoundTime()); |
| | | //计算出库金额 |
| | | BigDecimal outAmount = addDTO.getSubjectMatterList().stream().map(item->item.getUnitPrice().multiply(item.getOutBoundNum())).reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | paymentConfirm.setTransationAmount(outAmount.divide(new BigDecimal("100")).multiply(schedule.getPaymentRatio())); |
| | | if (ObjUtil.isNotNull(contract.getOutBoundAmout())){ |
| | | contract.setOutBoundAmout(outAmount.add(contract.getOutBoundAmout())); |
| | | }else { |
| | | contract.setOutBoundAmout(outAmount); |
| | | } |
| | | contractMapper.updateById(contract); |
| | | //最近明细 |
| | | PaymentConfirm lastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | if (ObjUtil.isNotNull(lastConfirm)) { |
| | | //不存在发货应收 出库总额 |
| | | paymentConfirm.setTotalAmount(lastConfirm.getTotalAmount().subtract(paymentConfirm.getTransationAmount())); |
| | | if (paymentConfirm.getTotalAmount().compareTo(new BigDecimal("0"))>0){ |
| | | paymentConfirm.setAdvanceAmount(paymentConfirm.getTotalAmount()); |
| | | } |
| | | if (paymentConfirm.getTotalAmount().compareTo(new BigDecimal("0"))<0){ |
| | | paymentConfirm.setReceivableAmount(paymentConfirm.getTotalAmount().multiply(new BigDecimal("-1"))); |
| | | } |
| | | if (schedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { |
| | | paymentConfirmMapper.insert(paymentConfirm); |
| | | } |
| | | // } |
| | | } else { |
| | | //无之前阶段应收 |
| | | paymentConfirm.setTotalAmount(paymentConfirm.getTransationAmount().multiply(new BigDecimal("-1"))); |
| | | if (schedule.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { |
| | | paymentConfirmMapper.insert(paymentConfirm); |
| | | //客户付款完成合同 |
| | | List<Contract> customerCompleteContractList = contractMapper.selectList(Wrappers.<Contract>lambdaQuery().eq(Contract::getPartyAId, contract.getPartyAId()) |
| | | .eq(Contract::getPartyBId, SecurityUtils.getUser().getCompId()).apply(" amount = paid_amount")); |
| | | if (ArrayUtil.isNotEmpty(customerCompleteContractList)) { |
| | | List<BigDecimal> outAmountList = new ArrayList<>(); |
| | | for (Contract completeContract : customerCompleteContractList |
| | | ) { |
| | | PaymentConfirm contractLastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, completeContract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | //查询客户付款完成合同中最后明细金额 有预收转入当前合同 |
| | | if (contractLastConfirm.getTotalAmount().compareTo(new BigDecimal("0")) > 0) { |
| | | //新增完成付款合同 资金转出 |
| | | PaymentConfirm outConfirm = BeanUtil.copyProperties(contractLastConfirm, PaymentConfirm.class, "id", "transationAmount", |
| | | "advanceAmount", "receivableAmount", "overdueAmount", "totalAmount"); |
| | | outConfirm.setBusinessType("资金转出"); |
| | | outConfirm.setConfirmTime(new Date()); |
| | | outConfirm.setTransationAmount(contractLastConfirm.getTotalAmount()); |
| | | outConfirm.setTotalAmount(new BigDecimal("0")); |
| | | paymentConfirmMapper.insert(outConfirm); |
| | | outAmountList.add(outConfirm.getTransationAmount()); |
| | | } |
| | | } |
| | | if (ArrayUtil.isNotEmpty(outAmountList.toArray())) { |
| | | BigDecimal currentInSum = outAmountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | //新增当前合同 资金转入 |
| | | PaymentConfirm inConfirm = BeanUtil.copyProperties(paymentConfirm, PaymentConfirm.class, "id", "transationAmount", |
| | | "advanceAmount", "receivableAmount", "overdueAmount", "totalAmount"); |
| | | inConfirm.setBusinessType("资金转入"); |
| | | inConfirm.setConfirmTime(new Date()); |
| | | inConfirm.setTransationAmount(currentInSum); |
| | | inConfirm.setTotalAmount(paymentConfirm.getTotalAmount().add(currentInSum)); |
| | | //更新当前阶段实际收款 和 收款状态 |
| | | schedule.setActualAmount(inConfirm.getTransationAmount()); |
| | | schedule.setPaymentStatus(2); |
| | | if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) > 0) { |
| | | inConfirm.setAdvanceAmount(inConfirm.getTotalAmount()); |
| | | } else if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0")) < 0) { |
| | | inConfirm.setReceivableAmount(inConfirm.getTotalAmount().multiply(new BigDecimal("-1"))); |
| | | schedule.setActualAmount(paymentConfirm.getTotalAmount().subtract(currentInSum)); |
| | | schedule.setPaymentStatus(1); |
| | | } |
| | | paymentConfirmMapper.insert(inConfirm); |
| | | //更新当前阶段实际收款 和 收款状态 |
| | | scheduleMapper.updateById(schedule); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //更新发货前收款生效时间 |
| | | if (ObjUtil.isNull(schedule.getEffectiveDate())) { |
| | | |
| | | //更新履约 |
| | | ContractPaymentScheduleProcess contractPaymentScheduleProcess = new ContractPaymentScheduleProcess(); |
| | | contractPaymentScheduleProcess.setContractId(schedule.getContractId()); |
| | | contractPaymentScheduleProcess.setContractName(schedule.getContractName()); |
| | | contractPaymentScheduleProcess.setScheduleId(schedule.getId()); |
| | | contractPaymentScheduleProcess.setScheduleName(schedule.getStageName()); |
| | | contractPaymentScheduleProcess.setProcessDate(addDTO.getOutBoundTime()); |
| | | ContractPaymentScheduleProcess lastProcess = scheduleProcessMapper.selectOne(Wrappers.<ContractPaymentScheduleProcess>lambdaQuery().eq(ContractPaymentScheduleProcess::getContractId, schedule.getContractId()) |
| | | .eq(ContractPaymentScheduleProcess::getScheduleId, schedule.getId()).last("limit 1")); |
| | | if (ObjUtil.isNull(lastProcess)) { |
| | | scheduleProcessMapper.insert(contractPaymentScheduleProcess); |
| | | } |
| | | } |
| | | |
| | | //查询是否有后续阶段 |
| | | List<ContractPaymentSchedule> afterSchedule = scheduleMapper.selectList(Wrappers.<ContractPaymentSchedule>lambdaQuery() |
| | | .eq(ContractPaymentSchedule::getContractId, schedule.getContractId()) |
| | | .gt(ContractPaymentSchedule::getStageOrder, schedule.getStageOrder()) |
| | | .gt(ContractPaymentSchedule::getPaymentRatio, 0) |
| | | .orderByAsc(ContractPaymentSchedule::getCreateTime)); |
| | | if (ArrayUtil.isNotEmpty(afterSchedule.toArray())&&contract.getOutBoundAmout().compareTo(contract.getAmount())==0) { |
| | | contract.setNextScheduleName(afterSchedule.get(0).getStageName()); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | |
| | | if (ArrayUtil.isEmpty(afterSchedule.toArray())) { |
| | | schedule.setEffectiveEndDate(contract.getExpirationDate()); |
| | | scheduleMapper.updateById(schedule); |
| | | //更新合同下个阶段 |
| | | contract.setNextScheduleName("无"); |
| | | contractMapper.updateById(contract); |
| | | //当前为合同最后阶段 |
| | | PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) |
| | | .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); |
| | | if (lastNewConfirm.getTotalAmount().compareTo(new BigDecimal("0")) >= 0) { |
| | | //有预付且超过应收 关闭合同状态 |
| | | contract.setContractStatus(3); |
| | | contractMapper.updateById(contract); |
| | | } |
| | | } |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 生成格式为: yyyyMMdd + 4位序列号 (例如: 20260629000001) |
| | | */ |
| | | public String generateSMJContractCKNo() { |
| | | // 1. 获取当前日期字符串 |
| | | String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); |
| | | |
| | | // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 |
| | | String key = "ZB-SMJ-CK:" + dateStr; |
| | | |
| | | // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) |
| | | Long sequence = redisTemplate.opsForValue().increment(key, 1); |
| | | redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); |
| | | |
| | | // 4. 格式化序列号,不足6位前补0 |
| | | String seqStr = String.format("%04d", sequence); |
| | | |
| | | // 5. 拼接返回 |
| | | return "ZB-SMJ-CK-"+dateStr + seqStr; |
| | | } |
| | | |
| | | public String generateYMJContractCKNo() { |
| | | // 1. 获取当前日期字符串 |
| | | String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); |
| | | |
| | | // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 |
| | | String key = "ZB-YMJ-CK:" + dateStr; |
| | | |
| | | // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) |
| | | Long sequence = redisTemplate.opsForValue().increment(key, 1); |
| | | redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); |
| | | |
| | | // 4. 格式化序列号,不足6位前补0 |
| | | String seqStr = String.format("%04d", sequence); |
| | | |
| | | // 5. 拼接返回 |
| | | return "ZB-YMJ-CK-"+dateStr + seqStr; |
| | | } |
| | | |
| | | public String generateJXCContractCKNo() { |
| | | // 1. 获取当前日期字符串 |
| | | String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); |
| | | |
| | | // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 |
| | | String key = "ZB-JXC-CK:" + dateStr; |
| | | |
| | | // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) |
| | | Long sequence = redisTemplate.opsForValue().increment(key, 1); |
| | | redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); |
| | | |
| | | // 4. 格式化序列号,不足6位前补0 |
| | | String seqStr = String.format("%04d", sequence); |
| | | |
| | | // 5. 拼接返回 |
| | | return "ZB-JXC-CK-"+dateStr + seqStr; |
| | | } |
| | | |
| | | public String generateTFContractCKNo() { |
| | | // 1. 获取当前日期字符串 |
| | | String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); |
| | | |
| | | // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 |
| | | String key = "ZB-TF-CK:" + dateStr; |
| | | |
| | | // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) |
| | | Long sequence = redisTemplate.opsForValue().increment(key, 1); |
| | | redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); |
| | | |
| | | // 4. 格式化序列号,不足6位前补0 |
| | | String seqStr = String.format("%04d", sequence); |
| | | |
| | | // 5. 拼接返回 |
| | | return "ZB-TF-CK-"+dateStr + seqStr; |
| | | } |
| | | |
| | | public String generateGYBContractCKNo() { |
| | | // 1. 获取当前日期字符串 |
| | | String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); |
| | | |
| | | // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 |
| | | String key = "ZB-GYB-CK:" + dateStr; |
| | | |
| | | // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) |
| | | Long sequence = redisTemplate.opsForValue().increment(key, 1); |
| | | redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); |
| | | |
| | | // 4. 格式化序列号,不足6位前补0 |
| | | String seqStr = String.format("%04d", sequence); |
| | | |
| | | // 5. 拼接返回 |
| | | return "ZB-GYB-CK-"+dateStr + seqStr; |
| | | } |
| | | |
| | | @Override |
| | | public R delOutBound(String batchNumber) { |
| | | List<OutBound> outBoundList = baseMapper.selectList(Wrappers.<OutBound>lambdaQuery().eq(OutBound::getBatchNumber,batchNumber)); |
| | | if (ArrayUtil.isEmpty(outBoundList)){ |
| | | return R.failed("出库信息异常,请联系营销系统管理人员"); |
| | | } |
| | | List<ContractOutBound> contractOutBoundList = contractOutBoundMapper.selectList(Wrappers.<ContractOutBound>lambdaQuery() |
| | | .in(ContractOutBound::getOutBoundId,outBoundList.stream().map(OutBound::getId).collect(Collectors.toList()))); |
| | | if (ArrayUtil.isEmpty(contractOutBoundList)){ |
| | | return R.failed("出库信息异常,请联系营销系统管理人员"); |
| | | } |
| | | boolean allZero = true; |
| | | for (ContractOutBound item : contractOutBoundList) { |
| | | // 假设 invoiceNum 是 Integer 对象 |
| | | if (item.getInvoiceNum() == null || item.getInvoiceNum().compareTo(new BigDecimal("0"))!=0) { |
| | | allZero = false; |
| | | break; // 发现一个不符合即退出 |
| | | } |
| | | } |
| | | if (!allZero){ |
| | | return R.failed("请先冲减所有蓝牌后在操作"); |
| | | } |
| | | for (ContractOutBound item : contractOutBoundList) { |
| | | ContractSubjectMatter subjectMatter = contractSubjectMatterMapper.selectOne(Wrappers.<ContractSubjectMatter>lambdaQuery() |
| | | .eq(ContractSubjectMatter::getContractId,item.getContractId()).eq(ContractSubjectMatter::getMaterialCode,item.getSubjectMatterCode()) |
| | | .eq(ContractSubjectMatter::getLineNo,item.getLineNo())); |
| | | if (ObjUtil.isNotNull(subjectMatter)){ |
| | | subjectMatter.setDeliveredQuantity(subjectMatter.getDeliveredQuantity().subtract(item.getOutBoundNum())); |
| | | subjectMatter.setRemainingQuantity(subjectMatter.getRemainingQuantity().add(item.getOutBoundNum())); |
| | | if (subjectMatter.getDeliveredQuantity().compareTo(new BigDecimal("0"))==0){ |
| | | subjectMatter.setDeliveryStatus(0); |
| | | } |
| | | if (subjectMatter.getDeliveredQuantity().compareTo(new BigDecimal("0"))>0){ |
| | | subjectMatter.setDeliveryStatus(1); |
| | | } |
| | | //标的物更新 |
| | | contractSubjectMatterMapper.updateById(subjectMatter); |
| | | } |
| | | //合同开票状态更新 |
| | | // List<ContractSubjectMatter> subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.<ContractSubjectMatter>lambdaQuery() |
| | | // .eq(ContractSubjectMatter::getContractId,subjectMatter.getContractId())); |
| | | // if (subjectMatterList.stream().allMatch(matter -> matter.getDeliveryStatus() != null && matter.getDeliveryStatus() == 0)){ |
| | | // Contract contract = contractMapper.selectById(subjectMatter.getContractId()); |
| | | // if (ObjUtil.isNotNull(contract)){ |
| | | // contract.setBillingStatus("1"); |
| | | // contractMapper.updateById(contract); |
| | | // } |
| | | // }else { |
| | | // Contract contract = contractMapper.selectById(subjectMatter.getContractId()); |
| | | // if (ObjUtil.isNotNull(contract)){ |
| | | // contract.setBillingStatus("1"); |
| | | // contractMapper.updateById(contract); |
| | | // } |
| | | // } |
| | | //出库记录删除 |
| | | contractOutBoundMapper.deleteById(item); |
| | | } |
| | | baseMapper.delete(Wrappers.<OutBound>lambdaQuery().eq(OutBound::getBatchNumber,batchNumber)); |
| | | return R.ok(); |
| | | } |
| | | } |