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(); // 生成第一笔账单 // 第一次应缴费日期 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 (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); }else{ rentBill.setEndTime(contract.getEndTime()); } TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); if (tContractRentType!=null && rentBill.getEndTime().isAfter(tContractRentType.getChangeTime()) ){ long moneyDays = 0; switch (contract.getPayType()){ case "1": break; case "2": break; case "3": break; } // 计算租金变动的天数 moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))+1L); contract.setChangeTime(LocalDateTime.now()); // 递增递减的租金 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(contractRentTypeMoney); 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)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); contract.setChangeRent(contractRentTypeMoney); 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(contractRentTypeMoney); 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(contractRentTypeMoney); break; } break; } // 不需要涨租金的时间段 long originalDays = 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{ if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ rentBill.setEndTime(contract.getEndTime()); }else{ LocalDateTime firstPayTime1 = contract.getFirstPayTime(); // 根据支付方式设置账单endTime if (contract.getPayType().equals("1")){ rentBill.setEndTime(firstPayTime1.with(TemporalAdjusters.lastDayOfMonth())); }else if (contract.getPayType().equals("2")){ firstPayTime1 = firstPayTime1.plusMonths(3); rentBill.setEndTime(firstPayTime1.with(TemporalAdjusters.lastDayOfMonth())); }else if (contract.getPayType().equals("3")){ firstPayTime1 = firstPayTime1.plusMonths(12); rentBill.setEndTime(firstPayTime1.with(TemporalAdjusters.lastDayOfMonth())); } } // 不走递增递减 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::getCreateTime) .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())){ TBill tBill = new TBill(); tBill.setContractId(contract.getId()); tBill.setContractNumber(contract.getContractNumber()); // 根据支付方式判断需不需要生成订单 if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) && (contract.getPayType().equals("1")? beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)) .with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime()) && beforeBill.getEndTime().isBefore(contract.getEndTime()) ){ tBill.setContractId(contract.getId()); if (contract.getIsIncreasing()){ if (tContractRentType!=null && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ // 如果没变过 if (contract.getChangeTime()==null){ contract.setChangeTime(LocalDateTime.now()); // 租金递增递减的时长 天 long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.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(contractRentTypeMoney); 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)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); contract.setChangeRent(contractRentTypeMoney); 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(contractRentTypeMoney); 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(contractRentTypeMoney); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); 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()); }else{ // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ contract.setChangeTime(LocalDateTime.now()); // 租金递增递减的时长 天 long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.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(contractRentTypeMoney); 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)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); contract.setChangeRent(contractRentTypeMoney); 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(contractRentTypeMoney); 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(contractRentTypeMoney); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); 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()); }else{ // 不涨租金 用上次的 // 租金递增递减的时长 天 long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.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(contractRentTypeMoney); 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)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); contract.setChangeRent(contractRentTypeMoney); 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(contractRentTypeMoney); 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(contractRentTypeMoney); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); 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()); } } } }else{ tBill.setPayableFeesMoney(contract.getMonthRent().multiply(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } 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.setPayFeesStatus("1"); tBill.setBillType("1"); 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())); 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 && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ // 如果没变过 if (contract.getChangeTime()==null){ contract.setChangeTime(LocalDateTime.now()); // 租金递增递减的时长 天 long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.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(contractRentTypeMoney); 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)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); contract.setChangeRent(contractRentTypeMoney); 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(contractRentTypeMoney); 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(contractRentTypeMoney); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); // 不需要涨租金的时间段 if (contract.getFirstPayTime().isBefore(tContractRentType.getChangeTime())){ 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()); }else{ tBill.setPayableFeesMoney(contractRentTypeMoney); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } }else{ // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ contract.setChangeTime(LocalDateTime.now()); // 租金递增递减的时长 天 long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.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(contractRentTypeMoney); 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)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); contract.setChangeRent(contractRentTypeMoney); 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(contractRentTypeMoney); 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(contractRentTypeMoney); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); 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()); }else{ // 不涨租金 用上次的 // 租金递增递减的时长 天 long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.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(contractRentTypeMoney); 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)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); contract.setChangeRent(contractRentTypeMoney); 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(contractRentTypeMoney); 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(contractRentTypeMoney); break; } break; } // 不需要涨租金的时间段 long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); 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()); } } } }else{ long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); } 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().withHour(0).withMinute(0).withSecond(0).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).withHour(0).withMinute(0).withSecond(0).toLocalDate())); } billService.save(tBill); } break; } case CATEGORY3: { // 合同提前终止审批 int submitStatus = status==0?4:(status==1?6:5); contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus); // 生成验收记录 TContract contract = contractService.getById(processParameter.getString("projectId")); contract.setStatus("7"); TCheckAcceptRecord tCheckAcceptRecord = new TCheckAcceptRecord(); tCheckAcceptRecord.setContractId(contract.getId()); tCheckAcceptRecord.setHouseId(contract.getHouseId()); tCheckAcceptRecord.setLeaseReason("后台终止合同"); tCheckAcceptRecord.setStatus(false); 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); // 将所有未缴费账单设置未已失效 List tBills = billService.list(new LambdaQueryWrapper() .in(TBill::getPayFeesStatus, Arrays.asList("1,2,4")) .eq(TBill::getContractId, contract.getId())); for (TBill tBill : tBills) { tBill.setPayFeesStatus("5"); } billService.updateBatchById(tBills); break; } default: throw new ServiceException("错误类型"); } } }