package com.ruoyi.system.service.impl; import cn.hutool.core.util.ObjectUtil; import com.aizuda.bpm.engine.FlowLongEngine; import com.aizuda.bpm.engine.assist.ObjectUtils; import com.aizuda.bpm.engine.core.FlowCreator; import com.aizuda.bpm.engine.core.FlowLongContext; import com.aizuda.bpm.engine.core.enums.EventType; import com.aizuda.bpm.engine.core.enums.NodeApproveSelf; import com.aizuda.bpm.engine.core.enums.NodeSetType; import com.aizuda.bpm.engine.core.enums.TaskType; import com.aizuda.bpm.engine.entity.FlwExtInstance; import com.aizuda.bpm.engine.entity.FlwHisTask; import com.aizuda.bpm.engine.entity.FlwTask; import com.aizuda.bpm.engine.entity.FlwTaskActor; import com.aizuda.bpm.engine.listener.TaskListener; import com.aizuda.bpm.engine.model.NodeAssignee; import com.aizuda.bpm.engine.model.NodeModel; import com.aizuda.bpm.engine.model.ProcessModel; import com.aizuda.bpm.mybatisplus.mapper.FlwExtInstanceMapper; import com.aizuda.bpm.mybatisplus.mapper.FlwHisTaskMapper; import com.aizuda.bpm.mybatisplus.mapper.FlwTaskActorMapper; import com.aizuda.bpm.mybatisplus.mapper.FlwTaskMapper; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.google.common.collect.ImmutableMap; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.enums.ProcessCategoryEnum; import com.ruoyi.common.enums.SubmitStatusEnum; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.system.mapper.TCheckAcceptRecordMapper; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TCheckAcceptRecord; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.TContractRentType; import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TContractRentTypeService; import com.ruoyi.system.service.TContractService; import com.ruoyi.system.task.base.QuartzManager; import com.ruoyi.system.task.base.TimeJobType; import com.ruoyi.system.task.jobs.StateProcessJob; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.function.Supplier; import java.util.stream.Collectors; /** * 工作流程全局任务监听 同步方式 只监听流程完成、流程中断类型,修改拒绝状态 *

* 1. 入户调查 * 2. 价格评估 * 3. 协议签订 * 4. 资金管理-预算资金 * 5. 住宅临时安置补助费 * 6. 停产停业经济损失补助费 * 7. 安置情况(流程图中叫做录入货币补偿金额信息) * 固定对应表 state_process_module */ @Slf4j @Component @RequiredArgsConstructor public class FlowListenerService implements TaskListener { private final FlwExtInstanceMapper flwExtInstanceMapper; private final FlowLongEngine flowLongEngine; private final FlwTaskActorMapper flwTaskActorMapper; private final FlwHisTaskMapper flwHisTaskMapper; private final ISysRoleService sysRoleService; private final FlwTaskMapper flwTaskMapper; private final TContractService contractService; private final TContractRentTypeService contractRentTypeService; private final TBillService billService; private final TCheckAcceptRecordMapper checkAcceptRecordMapper; @Override public boolean notify(EventType eventType, Supplier supplier, NodeModel nodeModel, FlowCreator flowCreator) { FlwTask flwTask = supplier.get(); if (ObjectUtil.isNull(flwTask)) { return true; } // 创建任务时候,判断是否自动审批通过 if (EventType.create.eq(eventType)) { Integer approveSelf = nodeModel.getApproveSelf(); if (NodeApproveSelf.AutoSkip.eq(approveSelf)) { // 普通成员情况 List nodeAssigneeList = null; if (NodeSetType.specifyMembers.eq(nodeModel.getSetType())) { nodeAssigneeList = nodeModel.getNodeAssigneeList(); if (ObjectUtil.isEmpty(nodeAssigneeList)) { return true; } //查询发起人 LambdaQueryWrapper flwHisTaskLambdaQueryWrapper = new LambdaQueryWrapper<>(); flwHisTaskLambdaQueryWrapper.eq(FlwTask::getTaskType, TaskType.major.getValue()); flwHisTaskLambdaQueryWrapper.eq(FlwTask::getInstanceId, flwTask.getInstanceId()); FlwHisTask flwHisTask = flwHisTaskMapper.selectOne(flwHisTaskLambdaQueryWrapper); if (ObjectUtil.isEmpty(flwHisTask)) { return true; } // 添加定时任务 Map maps = new ImmutableMap.Builder(). put("id", flwTask.getId()) .build(); QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name + flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT, new Date(new Date().getTime() + 48 * 60 * 60 * 1000L), maps); //对比发起人和节点审批人 if (nodeAssigneeList.stream().noneMatch(t -> Objects.equals(t.getId(), flwHisTask.getCreateId()))) { return true; } //查询当前节点审核人是否与创建人一致 List flwTaskActor = flwTaskActorMapper.selectListByTaskId(flwTask.getId()); if (ObjectUtil.isNotEmpty(flwTaskActor)) { for (FlwTaskActor flwTaskActor1 : flwTaskActor) { if (flwTaskActor1.getActorId().equals(flwHisTask.getCreateId())) { return flowLongEngine.autoJumpTask(flwTask.getId(), flowCreator); } } } } else if (NodeSetType.role.eq(nodeModel.getSetType())) { //角色任务跳过 nodeAssigneeList = nodeModel.getNodeAssigneeList(); //获取角色下的用户 List roleIds = nodeAssigneeList.stream().map(NodeAssignee::getId).collect(Collectors.toList()); List actorList = sysRoleService.selectRoleByUserIds(roleIds); List flwTaskActors = new ArrayList<>(); if (ObjectUtils.isNotEmpty(actorList)) { for (SysRole sysRole : actorList) { if (ObjectUtil.isEmpty(sysRole.getRoleName())) { continue; } NodeAssignee nodeAssignee = new NodeAssignee(); nodeAssignee.setId(String.valueOf(sysRole.getRoleId())); nodeAssignee.setName(sysRole.getRoleName()); flwTaskActors.add(FlwTaskActor.of(nodeAssignee, 0)); } } if (ObjectUtil.isEmpty(flwTaskActors)) { return true; } //查询发起人 LambdaQueryWrapper flwHisTaskLambdaQueryWrapper = new LambdaQueryWrapper<>(); flwHisTaskLambdaQueryWrapper.eq(FlwTask::getTaskType, TaskType.major.getValue()); flwHisTaskLambdaQueryWrapper.eq(FlwTask::getInstanceId, flwTask.getInstanceId()); FlwHisTask flwHisTask = flwHisTaskMapper.selectOne(flwHisTaskLambdaQueryWrapper); if (ObjectUtil.isEmpty(flwHisTask)) { return true; } // 添加定时任务 Map maps = new ImmutableMap.Builder(). put("id", flwTask.getId()) .build(); QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name + flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT, new Date(new Date().getTime() + 48 * 60 * 60 * 1000L), maps); //对比发起人和节点审批人 if (flwTaskActors.stream().noneMatch(t -> Objects.equals(t.getActorId(), flwHisTask.getCreateId()))) { return true; } //查询当前节点审核人是否与创建人一致 List flwTaskActor = flwTaskActorMapper.selectListByTaskId(flwTask.getId()); if (ObjectUtil.isNotEmpty(flwTaskActor)) { for (FlwTaskActor flwTaskActor1 : flwTaskActor) { if (flwTaskActor1.getActorId().equals(flwHisTask.getCreateId())) { return flowLongEngine.autoJumpTask(flwTask.getId(), flowCreator); } } } } } } if (eventType.equals(EventType.reject) || eventType.equals(EventType.autoReject)) { System.out.println("流程失败:" + flwTask.getVariable()); handlerBusiness(flwTask.getVariable(), 2); } else if (eventType.equals(EventType.complete)) { // 查询流程模型 FlwExtInstance flwExtInstance = flwExtInstanceMapper.selectById(flwTask.getInstanceId()); String modelContent = flwExtInstance.getModelContent(); ProcessModel processModel = FlowLongContext.parseProcessModel(modelContent, null, false); NodeModel node = processModel.getNode(flwTask.getTaskKey()); if (ObjectUtil.isEmpty(node)) { log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId()); return true; } long count = flwTaskMapper.selectCount(new LambdaQueryWrapper().eq(FlwTask::getInstanceId, flwTask.getInstanceId())); if (count > 0) { return true; } //最后一个节点 if (ObjectUtil.isEmpty(node.getChildNode()) || ObjectUtil.isEmpty(node.getChildNode().getNodeName())) { System.out.println("流程完成:" + flwTask.getVariable()); handlerBusiness(flwTask.getVariable(), 1); } } else if (eventType.eq(EventType.cc)) { // 查询流程模型//抄送 FlwExtInstance flwExtInstance = flwExtInstanceMapper.selectById(flwTask.getInstanceId()); String modelContent = flwExtInstance.getModelContent(); ProcessModel processModel = FlowLongContext.parseProcessModel(modelContent, null, false); NodeModel node = processModel.getNode(flwTask.getTaskKey()); if (ObjectUtil.isEmpty(node)) { log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId()); return true; } //抄送是最后一个节点 if (ObjectUtil.isEmpty(node.getChildNode()) || ObjectUtil.isEmpty(node.getChildNode().getNodeName())) { System.out.println("流程完成:" + flwTask.getVariable()); handlerBusiness(flwTask.getVariable(), 1); } } else if (eventType.eq(EventType.autoJump)) { // 查询流程模型 自动跳转 FlwExtInstance flwExtInstance = flwExtInstanceMapper.selectById(flwTask.getInstanceId()); String modelContent = flwExtInstance.getModelContent(); ProcessModel processModel = FlowLongContext.parseProcessModel(modelContent, null, false); NodeModel node = processModel.getNode(flwTask.getTaskKey()); if (ObjectUtil.isEmpty(node)) { log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId()); return true; } long count = flwTaskMapper.selectCount(new LambdaQueryWrapper().eq(FlwTask::getInstanceId, flwTask.getInstanceId())); if (count > 0) { return true; } //最后一个节点 if (ObjectUtil.isEmpty(node.getChildNode()) || ObjectUtil.isEmpty(node.getChildNode().getNodeName())) { System.out.println("流程完成:" + flwTask.getVariable()); handlerBusiness(flwTask.getVariable(), 1); } } return true; } /** * 业务状态变更 */ private void handlerBusiness(String variable, Integer status) { JSONObject processParameter = JSON.parseObject(variable); //必须参数,肯定有不判断null Integer category = processParameter.getInteger("category"); //状态 暂定:0待审核 1审核通过 2审核拒绝 ProcessCategoryEnum categoryEnum = ProcessCategoryEnum.getEnumByKey(category); switch (categoryEnum) { case CATEGORY1: { // 合同新增审批 int submitStatus = status == 0 ? 2 : (status == 1 ? 3 : 5); contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus); // TODO 发短信 break; } case CATEGORY2: { // 合同签订审批 int submitStatus = status == 0 ? 3 : (status == 1 ? 4 : 5); contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus); TContract contract = contractService.getById(processParameter.getString("projectId")); List contractRentTypes = contractRentTypeService.list(); TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); // 生成第一笔账单 // 第一次应缴费日期 LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0); TBill rentBill = new TBill(); rentBill.setContractId(contract.getId()); rentBill.setContractNumber(contract.getContractNumber()); rentBill.setPayableFeesTime(firstPayTime.toLocalDate()); rentBill.setPayFeesStatus("1"); rentBill.setBillType("1"); rentBill.setStartTime(contract.getStartPayTime()); if (rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime())) { if (rentBill.getStartTime().getDayOfMonth() != 1) { rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())); } else { rentBill.setEndTime(rentBill.getStartTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth())); } } else { rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())); } if (tContractRentType != null && rentBill.getEndTime().isAfter(tContractRentType.getChangeTime())) { long moneyDays = 0; moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), rentBill.getEndTime()); // 计算租金变动的天数 contract.setChangeTime(tContractRentType.getChangeTime()); // 递增递减的租金 BigDecimal contractRentTypeMoney = new BigDecimal("0"); // 不递增递减的租金 BigDecimal originalMoney = new BigDecimal("0"); // 原租金 switch (tContractRentType.getIncreasingDecreasingType()) { case 1: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); // 变动后的每月租金 contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; } break; case 2: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); break; } break; } // 不需要涨租金的时间段 long originalDays = Math.abs(ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime())); originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) .multiply(new BigDecimal(originalDays)); rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); } else { // 不走递增递减 long allDays = ChronoUnit.DAYS.between(contract.getStartPayTime(), rentBill.getEndTime()); int dayOfMonth = rentBill.getStartTime().getDayOfMonth(); if (dayOfMonth == 1) { rentBill.setPayableFeesMoney(contract.getMonthRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); } else { rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); } rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); } // 押金账单 TBill depositBill = new TBill(); depositBill.setContractId(contract.getId()); depositBill.setContractNumber(contract.getContractNumber()); depositBill.setPayableFeesMoney(contract.getDeposit()); depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney()); depositBill.setStartTime(contract.getStartPayTime()); depositBill.setEndTime(contract.getEndTime()); depositBill.setPayableFeesTime(firstPayTime.toLocalDate()); depositBill.setPayFeesStatus("1"); depositBill.setBillType("2"); contractService.updateById(contract); billService.save(rentBill); billService.save(depositBill); // 生成后续账单 try { TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime) .last("limit 1").one(); if (!beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) { while (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).isBefore(contract.getEndTime())) { System.err.println("生成后续账单"); TBill tBill = new TBill(); tBill.setContractId(contract.getId()); tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth())); tBill.setContractNumber(contract.getContractNumber()); if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).getDayOfMonth() <= 15) { tBill.setPayableFeesTime(contract.getEndTime().toLocalDate()); } else { tBill.setPayableFeesTime((contract.getPayType().equals("1") ? beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15).toLocalDate() : contract.getPayType().equals("2") ? beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15).toLocalDate() : beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).toLocalDate())); } tBill.setContractId(contract.getId()); if (contract.getIsIncreasing()) { System.err.println("执行递增递减"); if (tContractRentType != null) { // 如果变过 并且时间在递增递减时间段内 if (contract.getChangeTime() != null) { // 下次递增递减时间 LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime()); // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) { contract.setChangeTime(changeTime); // 租金递增递减的时长 天 long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), beforeBill.getEndTime())); // 递增递减的租金 BigDecimal contractRentTypeMoney = new BigDecimal("0"); // 不递增递减的租金 BigDecimal originalMoney = new BigDecimal("0"); // 原租金 switch (tContractRentType.getIncreasingDecreasingType()) { case 1: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); // 变动后的每月租金 contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; } break; case 2: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); if (originalDays > 0) { originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) .multiply(new BigDecimal(originalDays)); } tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); contractService.updateById(contract); } else { // 不涨租金 用上次的 tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1")?1:contract.getPayType().equals("2")?3:12))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } }else{ if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) { contract.setChangeTime(tContractRentType.getChangeTime()); // 租金递增递减的时长 天 long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), beforeBill.getEndTime())); // 递增递减的租金 BigDecimal contractRentTypeMoney = new BigDecimal("0"); // 不递增递减的租金 BigDecimal originalMoney = new BigDecimal("0"); // 原租金 switch (tContractRentType.getIncreasingDecreasingType()) { case 1: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); // 变动后的每月租金 contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; } break; case 2: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); if (originalDays > 0) { originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) .multiply(new BigDecimal(originalDays)); } tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); contractService.updateById(contract); } } } else { tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } }else { System.err.println("不执行递增递减"); tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } tBill.setContractNumber(contract.getContractNumber()); tBill.setPayFeesStatus("1"); tBill.setBillType("1"); billService.save(tBill); beforeBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth())); } } } catch (Exception e) { e.printStackTrace(); } TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime) .last("limit 1").one(); // 生成最后一笔账单 if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) && beforeBill.getEndTime().isBefore(contract.getEndTime()) ) { TBill tBill = new TBill(); tBill.setContractId(contract.getId()); tBill.setPayFeesStatus("1"); tBill.setBillType("1"); tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); tBill.setEndTime(contract.getEndTime()); if (contract.getIsIncreasing()) { if (tContractRentType != null) { // 如果变过 并且时间在递增递减时间段内 if (contract.getChangeTime() != null) { // 下次递增递减时间 LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime()); // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) { contract.setChangeTime(changeTime); // 租金递增递减的时长 天 long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), beforeBill.getEndTime())); // 递增递减的租金 BigDecimal contractRentTypeMoney = new BigDecimal("0"); // 不递增递减的租金 BigDecimal originalMoney = new BigDecimal("0"); // 原租金 switch (tContractRentType.getIncreasingDecreasingType()) { case 1: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); // 变动后的每月租金 contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; } break; case 2: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); if (originalDays > 0) { originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) .multiply(new BigDecimal(originalDays)); } tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); contractService.updateById(contract); } else { // 不涨租金 用上次的 tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1")?1:contract.getPayType().equals("2")?3:12))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } }else{ if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) { contract.setChangeTime(tContractRentType.getChangeTime()); // 租金递增递减的时长 天 long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), beforeBill.getEndTime())); // 递增递减的租金 BigDecimal contractRentTypeMoney = new BigDecimal("0"); // 不递增递减的租金 BigDecimal originalMoney = new BigDecimal("0"); // 原租金 switch (tContractRentType.getIncreasingDecreasingType()) { case 1: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); // 变动后的每月租金 contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); break; } break; case 2: switch (tContractRentType.getIncreasingDecreasing()) { case 1: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); break; case 2: contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); if (originalDays > 0) { originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) .multiply(new BigDecimal(originalDays)); } tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); contractService.updateById(contract); } } } else { if (tBill.getStartTime().getDayOfMonth()==1 && tBill.getEndTime().toLocalDate().equals(tBill.getEndTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate())){ tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); }else{ // 最后一笔账单时间 long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } } }else{ long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); tBill.setContractNumber(contract.getContractNumber()); } if (tBill.getEndTime().getDayOfMonth()>=15){ tBill.setPayableFeesTime(tBill.getStartTime().withDayOfMonth(15).toLocalDate()); }else if (tBill.getStartTime().getYear()==tBill.getEndTime().getYear()&& tBill.getStartTime().getMonthValue()==tBill.getEndTime().getMonthValue()){ // 如果同年同月 且日小于15 缴费时间取合同 tBill.setPayableFeesTime(tBill.getStartTime().toLocalDate()); }else{ tBill.setPayableFeesTime(tBill.getStartTime().withDayOfMonth(15).toLocalDate()); } billService.save(tBill); } break; } case CATEGORY3: { // 合同提前终止审批 int submitStatus = status == 0 ? 4 : (status == 1 ? 7 : 5); contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus); // 生成验收记录 TContract contract = contractService.getById(processParameter.getString("projectId")); TCheckAcceptRecord tCheckAcceptRecord = new TCheckAcceptRecord(); tCheckAcceptRecord.setContractId(contract.getId()); tCheckAcceptRecord.setHouseId(contract.getHouseId()); tCheckAcceptRecord.setLeaseReason("后台终止合同"); tCheckAcceptRecord.setAcceptanceTime(LocalDateTime.now()); LocalDate now = LocalDate.now(); String replace = (now + "").replace("-", ""); int size = checkAcceptRecordMapper.selectList(new LambdaQueryWrapper() .likeRight(TCheckAcceptRecord::getAcceptanceTime, LocalDate.now())).size(); tCheckAcceptRecord.setCode(replace.substring(2) + String.format("%03d", size + 1)); checkAcceptRecordMapper.insert(tCheckAcceptRecord); break; } default: throw new ServiceException("错误类型"); } } }