From c5c45b8be69753a1897dfdec423f359fe053fcdb Mon Sep 17 00:00:00 2001 From: PoffyZhang <99775271@qq.com> Date: Fri, 10 Nov 2023 10:57:17 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A9=BE=E9=A9=B6=E8=88=B1=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=20=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pmapi/dashboard/model/entity/CockpitStats.java | 6 +- .../scheduler/task/CockpitStatsStatisticsTask.java | 243 +++++++++++++++++---- 2 files changed, 208 insertions(+), 41 deletions(-) diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/entity/CockpitStats.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/entity/CockpitStats.java index b744f46..8cad88a 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/entity/CockpitStats.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/entity/CockpitStats.java @@ -199,11 +199,11 @@ public class CockpitStats implements Serializable { @ApiModelProperty("差额-批复状态") private BigDecimal differenceApproval; - @ApiModelProperty("申报金额-建设状态") + @ApiModelProperty("申报金额-合同状态") private BigDecimal declaredAmountContract; - @ApiModelProperty("批复金额-建设状态") + @ApiModelProperty("批复金额-合同状态") private BigDecimal approvalAmountContract; - @ApiModelProperty("差额-建设状态") + @ApiModelProperty("差额-合同状态") private BigDecimal differenceContract; @ApiModelProperty("产出-应用数量") diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java index 1dc3ce2..df6d558 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java @@ -19,14 +19,8 @@ import com.ningdatech.pmapi.dashboard.service.ICockpitStatsService; import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; import com.ningdatech.pmapi.gov.enumeration.GovProjectStatusEnum; -import com.ningdatech.pmapi.gov.model.entity.GovBizProjectApply; -import com.ningdatech.pmapi.gov.model.entity.GovBizProjectApprove; -import com.ningdatech.pmapi.gov.model.entity.GovBizProjectBaseinfo; -import com.ningdatech.pmapi.gov.model.entity.GovOperationProjectBaseinfo; -import com.ningdatech.pmapi.gov.service.IGovBizProjectApplyService; -import com.ningdatech.pmapi.gov.service.IGovBizProjectApproveService; -import com.ningdatech.pmapi.gov.service.IGovBizProjectBaseinfoService; -import com.ningdatech.pmapi.gov.service.IGovOperationProjectBaseinfoService; +import com.ningdatech.pmapi.gov.model.entity.*; +import com.ningdatech.pmapi.gov.service.*; import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalProject; import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalProjectService; import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; @@ -102,6 +96,9 @@ public class CockpitStatsStatisticsTask { private IGovBizProjectApproveService approveService; @Autowired + private IGovBizProjectProcureService procureService; + + @Autowired private IGovOperationProjectBaseinfoService operationBaseInfoService; @Autowired @@ -216,6 +213,7 @@ public class CockpitStatsStatisticsTask { List approves = Lists.newArrayList(); List applies = Lists.newArrayList(); + List procures = Lists.newArrayList(); if(CollUtil.isNotEmpty(baseInfos)){ List baseProjIds = baseInfos.stream().map(GovBizProjectBaseinfo::getBaseProjId).collect(Collectors.toList()); approves = approveService.list(Wrappers.lambdaQuery(GovBizProjectApprove.class) @@ -223,6 +221,9 @@ public class CockpitStatsStatisticsTask { applies = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class) .in(GovBizProjectApply::getBaseProjId, baseProjIds)); + + procures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class) + .in(GovBizProjectProcure::getBaseProjId, baseProjIds)); } @@ -336,7 +337,8 @@ public class CockpitStatsStatisticsTask { cockpitStats.setExpertTechnicalFeasibilityAssessmentNum(0); //3.顶部数据 - //3.1 计划项目数(建设方案待申报和申报了未开始审核的项目) + //3.1 计划项目数(申报项目:完成年度计划的项目总数 + // 项目归集:评审中、待立项、已立项、已采购、已初验、已终验项目总和) Integer planProjectNum = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && p.getStatus().compareTo(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()) >= 0){ @@ -344,8 +346,18 @@ public class CockpitStatsStatisticsTask { } return Boolean.FALSE; }).collect(Collectors.toList()).size(); - cockpitStats.setTopPlanProjectsNum(planProjectNum); - //3.2 批复项目数(可以用批复金额来判断) + Integer planProjectNumGov = baseInfos.stream().filter(p -> { + if(Objects.nonNull(p.getBaseProjSetProg()) && + //排除 已驳回 已终止 + (!Lists.newArrayList(GovProjectStatusEnum.REJECTED.getCode(), + GovProjectStatusEnum.TERMINATED.getCode()).contains(p.getBaseProjSetProg()))){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + cockpitStats.setTopPlanProjectsNum(planProjectNum + planProjectNumGov); + + //3.2 批复项目数(申报项目:完成立项批复流程项目总数 项目归集:已立项、已采购、已初验、已终验项目总和) Integer approvalNumDeclared = projects.stream().filter(p -> { if(Objects.nonNull(p.getApprovalAmount())){ return Boolean.TRUE; @@ -392,7 +404,7 @@ public class CockpitStatsStatisticsTask { //3.4 在建项目数 采购备案后的项目 Integer contructionNum = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && - p.getStatus().compareTo(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) >= 0 + p.getStatus().compareTo(ProjectStatusEnum.TO_BE_PURCHASED.getCode()) >= 0 && p.getStatus().compareTo(ProjectStatusEnum.ACCEPTED.getCode()) < 0){ return Boolean.TRUE; } @@ -411,18 +423,25 @@ public class CockpitStatsStatisticsTask { cockpitStats.setProjectsTotal(projects.size() + baseProjCount); //5.下面项目状态数 - //5.1 计划 + //5.1 计划(申报项目:项目预审完成到年度计划未完成 项目归集:评审中) Integer inPlanNum = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && - p.getStatus().compareTo(ProjectStatusEnum.PRE_APPLYING.getCode()) > 0 && + p.getStatus().compareTo(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode()) > 0 && p.getStatus().compareTo(ProjectStatusEnum.IN_THE_ANNUAL_PLAN.getCode()) <= 0){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()).size(); - cockpitStats.setProjectsTotalPlan(inPlanNum); + Integer inPlanNumGov = baseInfos.stream().filter(p -> { + if(Objects.nonNull(p.getBaseProjSetProg()) && + p.getBaseProjSetProg().equals(GovProjectStatusEnum.APPROVAL.getCode())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + cockpitStats.setProjectsTotalPlan(inPlanNum + inPlanNumGov); - //5.2 处于申报 + //5.2 处于申报(申报项目:年度计划完成到建设方案审批第一个节点审批未通过前 项目归集:待立项) Integer inApplyNum = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && (ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode().equals(p.getStatus()) || @@ -432,44 +451,102 @@ public class CockpitStatsStatisticsTask { } return Boolean.FALSE; }).collect(Collectors.toList()).size(); - cockpitStats.setProjectsTotalApply(inApplyNum); + Integer inApplyNumGov = baseInfos.stream().filter(p -> { + if(Objects.nonNull(p.getBaseProjSetProg()) && + p.getBaseProjSetProg().equals(GovProjectStatusEnum.PENDING.getCode())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + cockpitStats.setProjectsTotalApply(inApplyNum + inApplyNumGov); - //5.3 处于审批 (建设方案) + //5.3 处于审批 (申报项目:建设方案审批第一个节点审批通过到立项批复未完成 项目归集:已立项) Integer inApproveNum = projects.stream().filter(p -> { - if(Objects.nonNull(p.getStatus()) && p.getStatus().equals(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode())){ + if(Objects.nonNull(p.getStatus()) && + (ProjectStatusEnum.TO_BE_APPROVED.getCode().equals(p.getStatus()) || + p.getStatus().compareTo(ProjectStatusEnum.APPROVED_AFTER_CHOICE.getCode()) > 0 || + (ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode().equals(p.getStatus()) && + searchSechmeReviewedFlow(p.getProjectCode())))){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + Integer inApproveNumGov = baseInfos.stream().filter(p -> { + if(Objects.nonNull(p.getBaseProjSetProg()) && + p.getBaseProjSetProg().equals(GovProjectStatusEnum.APPROVED.getCode())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + cockpitStats.setProjectsTotalApprove(inApproveNum + inApproveNumGov); + + //5.4 建设 (申报项目:立项批复完成到项目初验未完成 项目归集:已采购) + Integer inConstructionNum = projects.stream().filter(p -> { + if(Objects.nonNull(p.getStatus()) && + (p.getStatus().compareTo(ProjectStatusEnum.APPROVED_AFTER_CHOICE.getCode()) > 0 && + p.getStatus().compareTo(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) < 0) || + //如果在建设中 那么初验材料为空代表 初验未完成 + (p.getStatus().equals(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) && + StringUtils.isBlank(p.getPreliminaryInspectionMaterials()))){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + Integer inConstructionNumGov = baseInfos.stream().filter(p -> { + if(Objects.nonNull(p.getBaseProjSetProg()) && + p.getBaseProjSetProg().equals(GovProjectStatusEnum.PURCHASED.getCode())){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()).size(); - cockpitStats.setProjectsTotalApprove(inApproveNum); - //5.4 建设 (建设中) - cockpitStats.setProjectsTotalConstruction(contructionNum + contructionNumGov); + cockpitStats.setProjectsTotalConstruction(inConstructionNum + inConstructionNumGov); - //5.5 验收 和 绩效 可以一起查 + //5.5 验收 (申报项目:项目初验完成到项目终验未完成 项目归集:已初验) List inAccpetProjects = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && - p.getStatus().equals(ProjectStatusEnum.ACCEPTED.getCode())){ + p.getStatus().compareTo(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) > 0 && + p.getStatus().compareTo(ProjectStatusEnum.ACCEPTED.getCode()) < 0 || + //如果在建设中 那么初验材料不为空代表 初验完成 + (p.getStatus().equals(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) && + StringUtils.isNotBlank(p.getPreliminaryInspectionMaterials()))){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()); List inAccpetProjectsGov = baseInfos.stream().filter(b -> { if(Objects.nonNull(b.getBaseProjSetProg()) && - b.getBaseProjSetProg().equals(GovProjectStatusEnum.HAS_FINAL_INS.getCode())){ + b.getBaseProjSetProg().equals(GovProjectStatusEnum.HAS_PRE_INS.getCode())){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()); + cockpitStats.setProjectsTotalAccept(inAccpetProjects.size() + inAccpetProjectsGov.size()); - List inAccpetCodes = inAccpetProjects.stream().map(Project::getProjectCode).collect(Collectors.toList()); + //5.6 运维(申报项目:项目验收完成后且项目未注销 项目归集:已终验) + List inOperationProjects = projects.stream().filter(p -> { + if(Objects.nonNull(p.getStatus()) && + p.getStatus().equals(ProjectStatusEnum.ACCEPTED.getCode())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()); + Integer inOperationProjectsGov = baseInfos.stream().filter(b -> { + if(Objects.nonNull(b.getBaseProjSetProg()) && + b.getBaseProjSetProg().equals(GovProjectStatusEnum.HAS_FINAL_INS.getCode())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + cockpitStats.setProjectsTotalOperation(inOperationProjects.size() + inOperationProjectsGov); + + //5.7 绩效(申报项目:项目验收完成后且未完成绩效自评 项目归集:无) + List inAccpetCodes = inOperationProjects.stream().map(Project::getProjectCode).collect(Collectors.toList()); List performances = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class) .in(CollUtil.isNotEmpty(inAccpetCodes),PerformanceAppraisalProject::getProjectCode, inAccpetCodes) .in(CollUtil.isEmpty(inAccpetCodes),PerformanceAppraisalProject::getProjectCode, Lists.newArrayList("NONE")) .isNotNull(PerformanceAppraisalProject::getVerifyTotalScore)); - cockpitStats.setProjectsTotalAccept(inAccpetProjects.size() + inAccpetProjectsGov.size()); cockpitStats.setProjectsTotalPerformance(performances.size()); cockpitStats.setProjectsTotalLogOff(0); - cockpitStats.setProjectsTotalOperation(inAccpetProjects.size() + inAccpetProjectsGov.size() + operationBaseInfos.size()); //6.项目效益 cockpitStats.setExcellentBestAppNum(0); @@ -491,7 +568,8 @@ public class CockpitStatsStatisticsTask { cockpitStats.setReduceFundsTotal(BigDecimal.valueOf(reduceFundsTotal)); //7.2驳回节约资金 List rejectPreProjects = projects.stream().filter(p -> { - if (Objects.nonNull(p.getStatus()) && p.getStatus().equals(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode())) { + if (Objects.nonNull(p.getStatus()) && + p.getStatus().equals(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode())) { return Boolean.TRUE; } return Boolean.FALSE; @@ -503,18 +581,80 @@ public class CockpitStatsStatisticsTask { return 0.0; }).sum(); cockpitStats.setRejectSavingsFunds(BigDecimal.valueOf(rejectPreSum)); + //7.3 柱状图 //7.3.1 申报状态的3个资金 // projects.stream() - cockpitStats.setApprovalAmountApproval(BigDecimal.ZERO); - cockpitStats.setApprovalAmountApprove(BigDecimal.ZERO); - cockpitStats.setApprovalAmountContract(BigDecimal.ZERO); - cockpitStats.setDeclaredAmountApproval(BigDecimal.ZERO); - cockpitStats.setDeclaredAmountApprove(BigDecimal.ZERO); - cockpitStats.setDeclaredAmountContract(BigDecimal.ZERO); - cockpitStats.setDifferenceApproval(BigDecimal.ZERO); - cockpitStats.setDifferenceApprove(BigDecimal.ZERO); - cockpitStats.setDifferenceContract(BigDecimal.ZERO); + //首先完成年度计划 并且未注销的项目 + List normalProjects = projects.stream().filter(p -> { + if (Objects.nonNull(p.getStatus()) && + p.getStatus().compareTo(ProjectStatusEnum.BE_SUSPENDED.getCode()) > 0) { + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()); + + //申报的申报金额(申报项目:初步方案申报金额 项目归集:项目总投资) + Double declaredAmountApprove = normalProjects.stream().mapToDouble(p -> { + BigDecimal declareAmount = Objects.nonNull(p.getDeclareAmount()) ? p.getDeclareAmount() : BigDecimal.ZERO; + return declareAmount.doubleValue(); + }).sum(); + Double declaredAmountApproveGov = applies.stream().mapToDouble(g -> { + BigDecimal totalAmount = Objects.nonNull(g.getBaseProjTotalAmount()) ? g.getBaseProjTotalAmount() : BigDecimal.ZERO; + return totalAmount.doubleValue(); + }).sum(); + BigDecimal declaredAmountApproveTotal = BigDecimal.valueOf(declaredAmountApprove).add(BigDecimal.valueOf(declaredAmountApproveGov)); + cockpitStats.setDeclaredAmountApprove(declaredAmountApproveTotal); + + //申报的批复金额(申报项目:建设方案申报金额 项目归集:建议总投资) + Double approvalAmountApprove = normalProjects.stream().mapToDouble(p -> { + BigDecimal declareAmount = Objects.nonNull(p.getApprovalAmount()) ? p.getApprovalAmount() : BigDecimal.ZERO; + return declareAmount.doubleValue(); + }).sum(); + Double approvalAmountApproveGov = approves.stream().mapToDouble(p -> { + BigDecimal expertTotalMoney = Objects.nonNull(p.getBaseExpertTotalMoney()) ? p.getBaseExpertTotalMoney() : BigDecimal.ZERO; + return expertTotalMoney.doubleValue(); + }).sum(); + BigDecimal approvalAmountApproveTotal = BigDecimal.valueOf(approvalAmountApprove).add(BigDecimal.valueOf(approvalAmountApproveGov)); + cockpitStats.setApprovalAmountApprove(approvalAmountApproveTotal); + //申报的差额 + cockpitStats.setDifferenceApprove(declaredAmountApproveTotal.subtract(approvalAmountApproveTotal)); + + //批复的申报金额(申报项目:建设方案申报金额 项目归集:建议总投资) + cockpitStats.setDeclaredAmountApproval(approvalAmountApproveTotal); + + //批复的批复金额(申报项目:归集信息建议批复总投资 项目归集:建议批复总投资) + Double approvalAmountApproval = normalProjects.stream().mapToDouble(p -> { + BigDecimal proposeTotalInvest = Objects.nonNull(p.getProposeTotalInvest()) ? p.getProposeTotalInvest() : BigDecimal.ZERO; + return proposeTotalInvest.doubleValue(); + }).sum(); + Double approvalAmountApprovalGov = approves.stream().mapToDouble(p -> { + BigDecimal reviewTotalMoney = Objects.nonNull(p.getBaseInitialReviewTotalMoney()) ? p.getBaseInitialReviewTotalMoney() : BigDecimal.ZERO; + return reviewTotalMoney.doubleValue(); + }).sum(); + BigDecimal approvalAmountApprovalTotal = BigDecimal.valueOf(approvalAmountApproval).add(BigDecimal.valueOf(approvalAmountApprovalGov)); + cockpitStats.setApprovalAmountApproval(approvalAmountApprovalTotal); + + //批复的差额 + cockpitStats.setDifferenceApproval(approvalAmountApproveTotal.subtract(approvalAmountApprovalTotal)); + + //合同的申报金额(申报项目:归集信息建议批复总投资 项目归集:建议批复总投资) + cockpitStats.setDeclaredAmountContract(approvalAmountApprovalTotal); + + //合同的批复金额(申报项目:成交金额 项目归集:成交金额) + Double approvalAmountContract = normalProjects.stream().mapToDouble(p -> { + BigDecimal transactionAmount = Objects.nonNull(p.getTransactionAmount()) ? p.getTransactionAmount() : BigDecimal.ZERO; + return transactionAmount.doubleValue(); + }).sum(); + Double approvalAmountContractGov = procures.stream().mapToDouble(p -> { + BigDecimal purchaseAmount = Objects.nonNull(p.getBaseProjPurchaseAmount()) ? p.getBaseProjPurchaseAmount() : BigDecimal.ZERO; + return purchaseAmount.doubleValue(); + }).sum(); + BigDecimal approvalAmountContractTotal = BigDecimal.valueOf(approvalAmountContract).add(BigDecimal.valueOf(approvalAmountContractGov)); + cockpitStats.setApprovalAmountContract(approvalAmountContractTotal); + + //合同的差额 + cockpitStats.setDifferenceContract(approvalAmountApprovalTotal.subtract(approvalAmountContractTotal)); //8 产出数据 cockpitStats.setProduceAppNum(0); @@ -631,6 +771,33 @@ public class CockpitStatsStatisticsTask { } return Boolean.FALSE; } + //已经开始审批 + private boolean searchSechmeReviewedFlow(String projectCode) { + Project project = projectService.getProjectByCode(projectCode); + if(Objects.isNull(project)){ + return Boolean.FALSE; + } + List allVersionProjectId = projectService.getAllVersionProjectId(project); + ProjectInst pi = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class) + .in(ProjectInst::getProjectId, allVersionProjectId) + .eq(ProjectInst::getInstType, InstTypeEnum.CONSTRUCTION_PLAN_REVIEW.getCode()) + .last(BizConst.LIMIT_1)); + if(Objects.isNull(pi)){ + return Boolean.FALSE; + } + String instCode = pi.getInstCode(); + List finished = historyService.createHistoricActivityInstanceQuery() + .finished() + .processInstanceId(instCode) + .orderByHistoricActivityInstanceEndTime() + .asc() + .list(); + //已经完成的 则可计算 + if(CollUtil.isNotEmpty(finished)){ + return Boolean.TRUE; + } + return Boolean.FALSE; + } /** * 计算环节滞后项目