Переглянути джерело

门户/项目统计-所有接口,添加报销支出

qianxb 2 роки тому
батько
коміт
f780d9065d
14 змінених файлів з 516 додано та 57 видалено
  1. 18 0
      blade-service-api/blade-control-api/src/main/java/org/springblade/control/vo/ProjectReimburseVO.java
  2. 4 0
      blade-service/blade-control/src/main/java/org/springblade/control/controller/ProjectInfoController.java
  3. 2 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.java
  4. 12 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.xml
  5. 14 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectInfoMapper.java
  6. 32 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectInfoMapper.xml
  7. 4 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectProcessMapper.java
  8. 5 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectProcessMapper.xml
  9. 20 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectInfoService.java
  10. 5 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectProcessService.java
  11. 82 14
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/AnnualBudgetServiceImpl.java
  12. 15 1
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectCostBudgetServiceImpl.java
  13. 201 5
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectInfoServiceImpl.java
  14. 102 37
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectProcessServiceImpl.java

+ 18 - 0
blade-service-api/blade-control-api/src/main/java/org/springblade/control/vo/ProjectReimburseVO.java

@@ -0,0 +1,18 @@
+package org.springblade.control.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.control.entity.EMFinancialReimbursementInfo;
+
+/**
+ * 报销加上项目进程
+ */
+@Data
+public class ProjectReimburseVO extends EMFinancialReimbursementInfo {
+
+    @ApiModelProperty(value = "项目进程id")
+    private Long projectProcess;
+
+    @ApiModelProperty(value = "费用分类")
+    private Integer costType;
+}

+ 4 - 0
blade-service/blade-control/src/main/java/org/springblade/control/controller/ProjectInfoController.java

@@ -19,7 +19,9 @@ import org.springblade.core.tool.api.R;
 import org.springblade.system.user.entity.User;
 import org.springframework.web.bind.annotation.*;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @Param
@@ -156,4 +158,6 @@ public class ProjectInfoController {
         return R.data(projectInfoService.getImplementUser());
     }
 
+
+
 }

+ 2 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.java

@@ -98,4 +98,6 @@ public interface ProjectCostBudgetMapper extends BaseMapper<ProjectCostBudget> {
     List<ProjectCostBudget> getAllMaintainPlan2(@Param("projectId")Long projectId);
 
     List<ProjectCostBudget> getAllMaintainPlan3(@Param("projectId")Long projectId,@Param("costType")Integer costType);
+
+    void updateByBudgetId(@Param("budget") ProjectCostBudget budget);
 }

+ 12 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.xml

@@ -4,6 +4,18 @@
     <update id="updateStatus">
         update c_project_cost_budget set status = #{status} where id = #{id}
     </update>
+    <update id="updateByBudgetId">
+        update
+            c_project_cost_budget
+        set
+            practical_task_days = #{budget.practicalTaskDays},
+            practical_finish_time = #{budget.practicalFinishTime},
+            task_approve = #{budget.taskApprove},
+            actual_total_money = #{budget.actualTotalMoney},
+            status = #{budget.status}
+        where
+            id = #{budget.id}
+    </update>
 
     <delete id="removeOldBudget">
         delete from c_project_cost_budget

+ 14 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectInfoMapper.java

@@ -6,11 +6,14 @@ import org.apache.ibatis.annotations.Param;
 import org.springblade.control.dto.ControlProjectInfoDTO;
 import org.springblade.control.entity.ControlProjectInfo;
 import org.springblade.control.entity.DictInfo;
+import org.springblade.control.entity.EMFinancialReimbursementInfo;
 import org.springblade.control.vo.AllProjectStatsVO;
 import org.springblade.control.vo.ControlProjectInfoVO;
+import org.springblade.control.vo.ProjectReimburseVO;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.user.entity.User;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -40,4 +43,15 @@ public interface ProjectInfoMapper extends BaseMapper<ControlProjectInfo> {
     List<ControlProjectInfo> listByYear(@Param("year") int year);
 
     List<User> getImplementUser();
+
+    BigDecimal getThisYearReimburse(@Param("year") int year);
+
+    List<EMFinancialReimbursementInfo> getYearReimburseByMonth(@Param("year") int year);
+
+    //返回报销对应的进程
+    List<ProjectReimburseVO> getProjectReimburse(@Param("projectId") Long projectId);
+    //返回报销对应的费用分类
+    List<ProjectReimburseVO> getProjectReimburse2(@Param("projectId") Long projectId);
+    //返回指定项目,指定费用分类对应的进程
+    List<ProjectReimburseVO> getProjectReimburse3(@Param("projectId") Long projectId,@Param("costType") Integer costType);
 }

+ 32 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectInfoMapper.xml

@@ -85,6 +85,38 @@
         select bu.id,bu.name from blade_user bu WHERE id in
          (SELECT cpi.implement_principal from c_control_project_info cpi WHERE cpi.is_deleted = 0 GROUP by cpi.implement_principal)
     </select>
+    <select id="getThisYearReimburse" resultType="java.math.BigDecimal">
+        SELECT SUM(fri.fr_money)
+        FROM c_control_project_info cpi left join c_expense_financial_reimbursement_info fri on cpi.id  = fri.project_id
+        WHERE cpi.is_deleted = 0 and fri.is_deleted = 0 and fri.status = 2
+        <if test="year != 0">
+            and #{year} = DATE_FORMAT(fri.fr_date ,'%Y')
+        </if>
+    </select>
+    <select id="getYearReimburseByMonth"
+            resultType="org.springblade.control.entity.EMFinancialReimbursementInfo">
+        SELECT fri.*
+        FROM c_control_project_info cpi left join c_expense_financial_reimbursement_info fri on cpi.id  = fri.project_id
+        WHERE cpi.is_deleted = 0 and fri.is_deleted = 0 and fri.status = 2
+        <if test="year != 0">
+            and #{year} = DATE_FORMAT(fri.fr_date ,'%Y')
+        </if>
+    </select>
+    <select id="getProjectReimburse" resultType="org.springblade.control.vo.ProjectReimburseVO">
+        SELECT fri.*,pcb.project_process
+        FROM  c_expense_financial_reimbursement_info fri inner join c_project_cost_budget pcb on fri.budget_plan_ids = pcb.id
+        WHERE fri.is_deleted = 0 and fri.status = 2 and fri.project_id = #{projectId} and fri.budget_plan_ids > 0
+    </select>
+    <select id="getProjectReimburse2" resultType="org.springblade.control.vo.ProjectReimburseVO">
+        SELECT fri.*,pcb.cost_type
+        FROM  c_expense_financial_reimbursement_info fri inner join c_project_cost_budget pcb on fri.budget_plan_ids = pcb.id
+        WHERE fri.is_deleted = 0 and fri.status = 2 and fri.project_id = #{projectId} and fri.budget_plan_ids > 0
+    </select>
+    <select id="getProjectReimburse3" resultType="org.springblade.control.vo.ProjectReimburseVO">
+        SELECT fri.*,pcb.project_process
+        FROM  c_expense_financial_reimbursement_info fri inner join c_project_cost_budget pcb on fri.budget_plan_ids = pcb.id
+        WHERE fri.is_deleted = 0 and fri.status = 2 and fri.project_id = #{projectId} and and pcb.costType = #{costType} and fri.budget_plan_ids > 0
+    </select>
 
 
 </mapper>

+ 4 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectProcessMapper.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.control.entity.ProjectProcess;
 import org.springblade.control.vo.ProjectProcessVO;
+import org.springblade.control.vo.ProjectReimburseVO;
 
 import java.util.List;
 
@@ -16,4 +17,7 @@ public interface ProjectProcessMapper extends BaseMapper<ProjectProcess> {
     List<ProjectProcessVO> getBaseProcess();
 
     List<ProjectProcessVO> getProjectProcess(@Param("id") Long id);
+
+    //返回指定项目,指定费用分类对应的进程
+    List<ProjectReimburseVO> getProjectReimburse3(@Param("projectId") Long projectId, @Param("costType") Integer costType);
 }

+ 5 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectProcessMapper.xml

@@ -14,4 +14,9 @@
         WHERE project_id = #{id}
         order by sort
     </select>
+    <select id="getProjectReimburse3" resultType="org.springblade.control.vo.ProjectReimburseVO">
+        SELECT fri.*,pcb.project_process
+        FROM  c_expense_financial_reimbursement_info fri inner join c_project_cost_budget pcb on fri.budget_plan_ids = pcb.id
+        WHERE fri.is_deleted = 0 and fri.status = 2 and fri.project_id = #{projectId} and pcb.cost_type = #{costType} and fri.budget_plan_ids > 0
+    </select>
 </mapper>

+ 20 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectInfoService.java

@@ -11,7 +11,9 @@ import org.springblade.core.mp.support.Query;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.user.entity.User;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @Param
@@ -43,4 +45,22 @@ public interface IProjectInfoService extends BaseService<ControlProjectInfo> {
 
     List<User> getImplementUser();
 
+    //获取当年所有的报销
+    BigDecimal getThisYearReimburse(int year);
+
+    //获取所有项目截至当年的报销支出,分月返回
+    Map<Long,List<BigDecimal>> getYearReimburseByMonth(int year);
+
+    //获取所有项目截至当年的报销支出,按年返回
+    Map<Long,BigDecimal> getYearReimburseByYear(int year);
+
+    //获取指定项目截至报销支出,按项目进程返回
+    Map<Long,BigDecimal> getProjectReimburseByProcess(Long projectId);
+
+    //获取指定项目截至报销支出,按项目进程返回
+    Map<Integer,BigDecimal> getProjectReimburseByCostType(Long projectId);
+
+    //根据项目id获取项目截至目前-某个费用分类的的报销支出,按项目环节返回
+    Map<Long,BigDecimal> getProjectReimburseByCostType(Long projectId,Integer costType);
+
 }

+ 5 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectProcessService.java

@@ -5,7 +5,9 @@ import org.springblade.control.entity.ProjectProcess;
 import org.springblade.control.vo.ProjectProcessVO;
 import org.springblade.core.mp.base.BaseService;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @Param
@@ -25,4 +27,7 @@ public interface IProjectProcessService extends BaseService<ProjectProcess> {
 
     List<ProjectProcessVO> processService(Long projectId, Integer costType);
 
+    //根据项目id获取项目截至目前-某个费用分类的的报销支出,按项目环节返回
+    Map<Long, BigDecimal> getProjectReimburseByCostType(Long projectId, Integer costType);
+
 }

+ 82 - 14
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/AnnualBudgetServiceImpl.java

@@ -328,10 +328,13 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         vo3.setYearReturned(yearReturned);
 
         //统计今年的已盈利:已收入-支出 ,目前已支出只统计闭环的计划
-        //获取年人工支出
+        //获取年人工支出
         BigDecimal yearStaffDisburse = budgetService.getYearStaffDisburse(year);
+        //获取今年维护支出
         BigDecimal cost = budgetService.getAllMaintainCost(LocalDate.now().getYear());
-        vo3.setYearProfit(yearReturned.subtract(yearStaffDisburse).subtract(cost));
+        //获取今年报销支出
+        BigDecimal decimal = projectInfoService.getThisYearReimburse(LocalDate.now().getYear());
+        vo3.setYearProfit(yearReturned.subtract(yearStaffDisburse).subtract(cost).subtract(decimal));
 
         //获取今年的年度预算
         AnnualBudget annualBudget = baseMapper.getThisYearBudget(year);
@@ -408,7 +411,9 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         }else {
             cost = budgetService.getAllMaintainCost(y);
         }
-        map.put("yearStaffDisburse",yearStaffDisburse.add(cost));
+        //报销支出
+        BigDecimal yearReimburse = projectInfoService.getThisYearReimburse(y);
+        map.put("yearStaffDisburse",yearStaffDisburse.add(cost).add(yearReimburse));
         //总计划支出:年度预算总计划支出
         if (y == 0){
             List<AnnualBudget> list = baseMapper.getAllYearBudget(y);
@@ -467,9 +472,15 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         //维护支出
         Map<Long, List<BigDecimal>> listMap = budgetService.getAllMaintainCost3(y);
         Boolean isMaintain = true;
-        if (listMap == null && listMap.size() <= 0){
+        if (listMap == null || listMap.size() <= 0){
             isMaintain = false;
         }
+        //报销支出
+        Map<Long, List<BigDecimal>> reimburseMap = projectInfoService.getYearReimburseByMonth(y);
+        Boolean isReimburse = true;
+        if (reimburseMap == null || reimburseMap.size() <= 0){
+            isReimburse = false;
+        }
         for (ControlProjectInfo project : list) {
             AnnualProjectCostVO vo = new AnnualProjectCostVO();
             List<Integer> integerList = new ArrayList<>();
@@ -490,6 +501,14 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
                         big = big.add(decimals.get(i -1));
                     }
                 }
+                //计算报销
+                if (isReimburse){
+                    List<BigDecimal> decimals = reimburseMap.get(project.getId());
+                    if (decimals != null && decimals.size() > 0){
+                        big = big.add(decimals.get(i -1));
+                    }
+                }
+
                 integerList.add(big.intValue());
             }
             vo.setName(project.getName());
@@ -645,6 +664,12 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         if (listMap == null || listMap.size() <= 0){
             isMaintain = false;
         }
+        //报销支出
+        Map<Long, BigDecimal> reimburseMap = projectInfoService.getYearReimburseByYear(Integer.parseInt(date.substring(0,4)));
+        Boolean isReimburse = true;
+        if (reimburseMap == null || reimburseMap.size() <= 0){
+            isReimburse = false;
+        }
         List<ProjectIncomeCostRatioVO> vos = new ArrayList<>();
         //按年获取闭环任务,根据项目分组
         List<ProjectCostBudget> costByMonth = budgetService.getPlanPracticalCostByMonth(date.substring(0,4));
@@ -666,17 +691,31 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         }
         Map<Long, List<ProjectCostBudget>> map = costByMonth.parallelStream()
                 .collect(Collectors.groupingBy(ProjectCostBudget::getProjectId));
-        //为每个合同设置支出
+        //为每个项目设置支出
         for (ControlProjectInfo info : list) {
             ProjectIncomeCostRatioVO vo = new ProjectIncomeCostRatioVO();
             vo.setProjectName(info.getName());
             BigDecimal big = new BigDecimal(0);
+            //获取人工支出
             List<ProjectCostBudget> budgets = map.get(info.getId());
             if (budgets != null && budgets.size() > 0){
                 for (ProjectCostBudget budget : budgets) {
                     big = big.add(budget.getActualTotalMoney());
                 }
             }
+            //维护支出
+            if (isMaintain){
+                if (listMap.get(info.getId()) != null){
+                    big = big.add(listMap.get(info.getId()));
+                }
+            }
+            //计算报销
+            if (isReimburse){
+                BigDecimal decimals = reimburseMap.get(info.getId());
+                if (decimals != null){
+                    big = big.add(decimals);
+                }
+            }
             vo.setProjectCost(big.intValue());
             vos.add(vo);
         }
@@ -746,12 +785,18 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         //获取项目所有已经闭环的计划
         List<ProjectCostBudget> finishedTask = budgetService.getProjectAllFinishedTask(projectId, null);
         Map<Long, List<ProjectCostBudget>> collect = new HashMap<>();
-        boolean isPlan = false ;
+        boolean isPlan = true ;
         if (finishedTask != null && finishedTask.size() > 0){
             collect = finishedTask.parallelStream()
                     .collect(Collectors.groupingBy(ProjectCostBudget::getProjectProcess));
         }else {
-            isPlan = true;
+            isPlan = false;
+        }
+        //项目每个进程的报销支出
+        Map<Long, BigDecimal> reimburseMap = projectInfoService.getProjectReimburseByProcess(projectId);
+        Boolean isReimburse = true;
+        if (reimburseMap == null || reimburseMap.size() <= 0){
+            isReimburse = false;
         }
         //把计划根据进程分组
         //为每个进程设置值
@@ -794,7 +839,13 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
             }
             //设置进程支出金额,目前只统计人工支出
             if (isPlan){
-                vo.setProcessCostCount(new BigDecimal(0));
+                if (isReimburse){
+                    if (reimburseMap.get(process.getId()) != null){
+                        vo.setProcessCostCount(reimburseMap.get(process.getId()));
+                    }
+                }else {
+                    vo.setProcessCostCount(new BigDecimal(0));
+                }
             }else {
                 List<ProjectCostBudget> budgets = collect.get(process.getId());
                 if (budgets != null && budgets.size() > 0){
@@ -803,9 +854,20 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
                     for (ProjectCostBudget budget : budgets) {
                         big = big.add(budget.getActualTotalMoney());
                     }
+                    if (isReimburse){
+                        if (reimburseMap.get(process.getId()) != null){
+                            big = big.add(reimburseMap.get(process.getId()));
+                        }
+                    }
                     vo.setProcessCostCount(big);
                 }else {
-                    vo.setProcessCostCount(new BigDecimal(0));
+                    if (isReimburse){
+                        if (reimburseMap.get(process.getId()) != null){
+                            vo.setProcessCostCount(reimburseMap.get(process.getId()));
+                        }
+                    }else {
+                        vo.setProcessCostCount(new BigDecimal(0));
+                    }
                 }
             }
             //设置进程支出金额百分比,统计实际支出和预算的百分比
@@ -813,17 +875,23 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
                 List<ProjectCostBudget> budgets = collect2.get(process.getId());
                 if (budgets != null && budgets.size() > 0) {
                     BigDecimal allMoney = new BigDecimal(0);
-                    BigDecimal costMoney = new BigDecimal(0);
+//                    BigDecimal costMoney = new BigDecimal(0);
                     for (ProjectCostBudget budget : budgets) {
                         if (budget.getBudgetCountMoney() == null){
                             budget.setBudgetCountMoney(new BigDecimal(0));
                         }
                         allMoney = allMoney.add(budget.getBudgetCountMoney());
-                        if (budget.getTaskApprove() == 1) {
-                            costMoney = costMoney.add(budget.getActualTotalMoney());
-                        }
+//                        //统计人工支出
+//                        if (budget.getTaskApprove() == 1) {
+//                            costMoney = costMoney.add(budget.getActualTotalMoney());
+//                        }
+                    }
+                    //统计报销支出
+                    if (vo.getProcessCostCount() != null &&vo.getProcessCostCount().intValue() != 0){
+                        vo.setProcessCostProgressBar(vo.getProcessCostCount().divide(allMoney, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue());
+                    }else {
+                        vo.setProcessProgressBar(0);
                     }
-                    vo.setProcessCostProgressBar(costMoney.divide(allMoney, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue());
                 } else {
                     vo.setProcessCostProgressBar(0);
                 }

+ 15 - 1
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectCostBudgetServiceImpl.java

@@ -1027,6 +1027,17 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
         //如果子计划为空,则清空父计划,然后修改可以编辑父计划
         List<ProjectCostBudgetVO2> list = vo2.getChildrenList();
         if (list != null && list.size() > 0){
+            //查看进行中的子计划的任务类型是否被更改
+            for (ProjectCostBudgetVO2 vo : list) {
+                if (vo.getIsShowDelete() != null) {
+                    if (vo.getIsShowDelete() == 0) {
+                        ProjectCostBudget budget = this.getById(vo.getId());
+                        if (!budget.getPlanTaskType().equals(vo.getPlanTaskType())) {
+                            throw new ServiceException("不能更改正在进行中或已完成的子计划类型");
+                        }
+                    }
+                }
+            }
             //获取子计划任务类型,用于判断子计划类型是否一致
             ProjectCostBudgetVO2 budgetVO2 = list.get(0);
             Long taskType;
@@ -1155,6 +1166,9 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
      */
     @Override
     public void taskFinishedStats(Long PlanId, LocalDate practicalFinishTime) {
+        if (practicalFinishTime == null){
+            throw new ServiceException("请传入任务完成时间");
+        }
         //先获取当前计划
         ProjectCostBudget budget = this.getById(PlanId);
         budget.setStatus(4);
@@ -1205,7 +1219,7 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
             budget.setPracticalTaskDays(new BigDecimal(realWorkDays));
             //实际人工支出
             budget.setActualTotalMoney(new BigDecimal(realWorkDays).multiply(new BigDecimal(money)));
-            this.updateById(budget);
+            baseMapper.updateByBudgetId(budget);
         }
     }
 

+ 201 - 5
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectInfoServiceImpl.java

@@ -11,6 +11,7 @@ import org.springblade.control.mapper.ProjectInfoMapper;
 import org.springblade.control.service.*;
 import org.springblade.control.vo.AllProjectStatsVO;
 import org.springblade.control.vo.ControlProjectInfoVO;
+import org.springblade.control.vo.ProjectReimburseVO;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Query;
@@ -26,10 +27,10 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -165,7 +166,9 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, C
         AllProjectStatsVO vo = baseMapper.allProjectStats();
         //获取截至目前所有维护支出
         BigDecimal cost2 = budgetService.getAllMaintainCost2();
-        vo.setAllPracticalDisburse(vo.getAllPracticalDisburse().add(cost2));
+        //所有的报销支出
+        BigDecimal decimal = this.getThisYearReimburse(0);
+        vo.setAllPracticalDisburse(vo.getAllPracticalDisburse().add(cost2).add(decimal));
         return vo;
     }
 
@@ -175,20 +178,35 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, C
     @Override
     public List<AllProjectStatsVO> ProjectListStats() {
         List<AllProjectStatsVO> vos = baseMapper.ProjectListStats();
+        //获取维护支出
         Map<Long, BigDecimal> map = budgetService.getAllMaintainCost5();
         Boolean isMaintain = true;
         if (map == null || map.size() <= 0){
             isMaintain = false;
         }
+        //报销支出
+        Map<Long, BigDecimal> reimburseMap = this.getYearReimburseByYear(0);
+        Boolean isReimburse = true;
+        if (reimburseMap == null || reimburseMap.size() <= 0){
+            isReimburse = false;
+        }
         for (AllProjectStatsVO vo : vos) {
             if (isMaintain) {
                 BigDecimal decimal = map.get(vo.getProjectId());
+                //维护支出
                 if (decimal != null) {
                     if (vo.getPracticalPayCost() == null){
                         vo.setPracticalPayCost(new BigDecimal(0));
                     }
                     vo.setPracticalPayCost(vo.getPracticalPayCost().add(decimal));
                 }
+                //计算报销
+                if (isReimburse){
+                    BigDecimal decimals = reimburseMap.get(vo.getProjectId());
+                    if (decimals != null){
+                        vo.setPracticalPayCost(vo.getPracticalPayCost().add(decimals));
+                    }
+                }
             }
         }
         return vos;
@@ -214,6 +232,13 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, C
         if (map == null || map.size() <= 0){
             isMaintain = false;
         }
+
+        //报销支出
+        Map<Integer, BigDecimal> reimburseMap = this.getProjectReimburseByCostType(id);
+        Boolean isReimburse = true;
+        if (reimburseMap == null || reimburseMap.size() <= 0){
+            isReimburse = false;
+        }
         //获取项目所有实际费用
         List<ProjectCostBudget> practicalList = budgetService.getAllPracticalBudgetByProjectId(id);
         if (budgets != null && budgets.size() > 0){
@@ -255,6 +280,13 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, C
                         practicalCost = practicalCost.add(decimal);
                     }
                 }
+                //加上每个部门的报销支出
+                if (isReimburse){
+                    BigDecimal decimals = reimburseMap.get(i);
+                    if (decimals != null){
+                        practicalCost = practicalCost.add(decimals);
+                    }
+                }
                 vo.setPracticalCost(practicalCost);
                 list.add(vo);
             }
@@ -307,5 +339,169 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, C
         return baseMapper.getImplementUser();
     }
 
+    /**
+     * 获取当年所有的报销
+     * @param year
+     * @return
+     */
+    @Override
+    public BigDecimal getThisYearReimburse(int year) {
+        BigDecimal decimal = baseMapper.getThisYearReimburse(year);
+        if (decimal == null){
+            decimal = new BigDecimal(0);
+        }
+        return decimal;
+    }
+
+    /**
+     * 获取所有项目截至当年的报销支出,分月返回
+     * @param year
+     * @return
+     */
+    @Override
+    public Map<Long, List<BigDecimal>> getYearReimburseByMonth(int year) {
+        List<EMFinancialReimbursementInfo> list = baseMapper.getYearReimburseByMonth(year);
+        if (list != null && list.size() > 0){
+            Map<Long, List<BigDecimal>> result = new HashMap<>();
+            //按项目分组
+            Map<Long, List<EMFinancialReimbursementInfo>> map = list.parallelStream()
+                    .collect(Collectors.groupingBy(EMFinancialReimbursementInfo::getProjectId));
+            //再计算每个月的总报销额
+            //循环项目
+            for (Long aLong : map.keySet()) {
+                List<BigDecimal> decimals = new ArrayList<>();
+                for (int i = 0; i < 12; i++) {
+                    decimals.add(new BigDecimal(0));
+                }
+                List<EMFinancialReimbursementInfo> infoList = map.get(aLong);
+                //循环项目下的所有报销
+                for (EMFinancialReimbursementInfo info : infoList) {
+                    Date frDate = info.getFrDate();
+                    Instant instant = frDate.toInstant();
+                    ZoneId zoneId = ZoneId.systemDefault();
+                    LocalDate localDate = instant.atZone(zoneId).toLocalDate();
+                    decimals.set(localDate.getMonthValue() - 1,decimals.get(localDate.getMonthValue() - 1).add(info.getFrMoney()));
+                }
+                result.put(aLong,decimals);
+            }
+            return result;
+        }
+        return null;
+    }
+
+    /**
+     * 获取所有项目截至当年的报销支出,按年返回
+     * @param year
+     * @return
+     */
+    @Override
+    public Map<Long, BigDecimal> getYearReimburseByYear(int year) {
+        List<EMFinancialReimbursementInfo> list = baseMapper.getYearReimburseByMonth(year);
+        if (list != null && list.size() > 0){
+            Map<Long, BigDecimal> result = new HashMap<>();
+            //按项目分组
+            Map<Long, List<EMFinancialReimbursementInfo>> map = list.parallelStream()
+                    .collect(Collectors.groupingBy(EMFinancialReimbursementInfo::getProjectId));
+            //再计算每个月的总报销额
+            //循环项目
+            for (Long aLong : map.keySet()) {
+              BigDecimal big = new BigDecimal(0);
+                List<EMFinancialReimbursementInfo> infoList = map.get(aLong);
+                //循环项目下的所有报销
+                for (EMFinancialReimbursementInfo info : infoList) {
+                    big = big.add(info.getFrMoney());
+                }
+                result.put(aLong,big);
+            }
+            return result;
+        }
+        return null;
+    }
+
+    /**
+     * 获取指定项目截至报销支出,按项目进程返回
+     * @param projectId
+     * @return
+     */
+    @Override
+    public Map<Long, BigDecimal> getProjectReimburseByProcess(Long projectId) {
+        //获取项目的所有关联进程的报销
+        List<ProjectReimburseVO> infos = baseMapper.getProjectReimburse(projectId);
+        if (infos == null || infos.size() <= 0){
+            return null;
+        }
+        //按照项目进程分组
+        Map<Long, List<ProjectReimburseVO>> map = infos.parallelStream()
+                .collect(Collectors.groupingBy(ProjectReimburseVO::getProjectProcess));
+        Map<Long, BigDecimal> decimalMap = new HashMap<>();
+        //统计每个进程的报销总和
+        for (Long aLong : map.keySet()) {
+            BigDecimal big = new BigDecimal(0);
+            List<ProjectReimburseVO> list = map.get(aLong);
+            for (ProjectReimburseVO vo : list) {
+                big = big.add(vo.getFrMoney());
+            }
+            decimalMap.put(aLong,big);
+        }
+        return decimalMap;
+    }
+
+    /**
+     * 获取指定项目截至报销支出,按费用分类返回
+     * @param projectId
+     * @return
+     */
+    @Override
+    public Map<Integer, BigDecimal> getProjectReimburseByCostType(Long projectId) {
+        //获取项目的所有关联进程的报销
+        List<ProjectReimburseVO> infos = baseMapper.getProjectReimburse2(projectId);
+        if (infos == null || infos.size() <= 0){
+            return null;
+        }
+        //按照项目费用分类分组
+        Map<Integer, List<ProjectReimburseVO>> map = infos.parallelStream()
+                .collect(Collectors.groupingBy(ProjectReimburseVO::getCostType));
+        Map<Integer, BigDecimal> decimalMap = new HashMap<>();
+        //统计每个分类的报销总和
+        for (Integer aLong : map.keySet()) {
+            BigDecimal big = new BigDecimal(0);
+            List<ProjectReimburseVO> list = map.get(aLong);
+            for (ProjectReimburseVO vo : list) {
+                big = big.add(vo.getFrMoney());
+            }
+            decimalMap.put(aLong,big);
+        }
+        return decimalMap;
+    }
+
+    /**
+     * 根据项目id获取项目截至目前-某个费用分类的的报销支出,按项目环节返回
+     * @param projectId
+     * @param costType
+     * @return
+     */
+    @Override
+    public Map<Long, BigDecimal> getProjectReimburseByCostType(Long projectId, Integer costType) {
+        //获取项目的所有关联进程的报销
+        List<ProjectReimburseVO> infos = baseMapper.getProjectReimburse3(projectId, costType);
+        if (infos == null || infos.size() <= 0) {
+            return null;
+        }
+        //按照项目进程分组
+        Map<Long, List<ProjectReimburseVO>> map = infos.parallelStream()
+                .collect(Collectors.groupingBy(ProjectReimburseVO::getProjectProcess));
+        Map<Long, BigDecimal> decimalMap = new HashMap<>();
+        //统计每个进程的报销总和
+        for (Long aLong : map.keySet()) {
+            BigDecimal big = new BigDecimal(0);
+            List<ProjectReimburseVO> list = map.get(aLong);
+            for (ProjectReimburseVO vo : list) {
+                big = big.add(vo.getFrMoney());
+            }
+            decimalMap.put(aLong, big);
+        }
+        return decimalMap;
+    }
+
 
 }

+ 102 - 37
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectProcessServiceImpl.java

@@ -3,13 +3,16 @@ package org.springblade.control.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.AllArgsConstructor;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.control.controller.ProjectInfoController;
 import org.springblade.control.dto.ControlProjectInfoDTO;
 import org.springblade.control.entity.ProjectCostBudget;
 import org.springblade.control.entity.ProjectProcess;
 import org.springblade.control.mapper.ProjectProcessMapper;
 import org.springblade.control.service.IProjectCostBudgetService;
+import org.springblade.control.service.IProjectInfoService;
 import org.springblade.control.service.IProjectProcessService;
 import org.springblade.control.vo.ProjectProcessVO;
+import org.springblade.control.vo.ProjectReimburseVO;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.system.entity.TopMenu;
 import org.springframework.stereotype.Service;
@@ -17,10 +20,7 @@ import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -34,6 +34,7 @@ public class ProjectProcessServiceImpl extends BaseServiceImpl<ProjectProcessMap
     private final ProjectProcessMapper processMapper;
     private final IProjectCostBudgetService budgetService;
 
+
     /**
      * 新增项目时保存进程
      *
@@ -121,57 +122,121 @@ public class ProjectProcessServiceImpl extends BaseServiceImpl<ProjectProcessMap
     public List<ProjectProcessVO> processService(Long projectId, Integer costType) {
         //获取当前项目所有项目环节
         List<ProjectProcessVO> list = processMapper.getProjectProcess(projectId);
+        //获取项目所有维护预算
         Map<Long, BigDecimal> maintainMap = budgetService.getAllMaintainCost7(projectId, costType);
         Boolean isMaintain = true;
         if (maintainMap == null || maintainMap.size() <= 0){
             isMaintain = false;
         }
+        //报销支出
+        Map<Long, BigDecimal> reimburseMap = this.getProjectReimburseByCostType(projectId,costType);
+        Boolean isReimburse = true;
+        if (reimburseMap == null || reimburseMap.size() <= 0){
+            isReimburse = false;
+        }
+
         //获取项目具体部门所有已闭环的任务
         List<ProjectCostBudget> budgets = budgetService.getProjectAllFinishedTask(projectId,costType);
-        if (budgets != null || budgets.size() > 0){
+        Boolean isBudgets = true;
+        Set<Long> set = new HashSet<>();
+        Map<Long, List<ProjectCostBudget>> map = new HashMap<>();
+        if (budgets != null && budgets.size() > 0){
             //获取项目环节的set集合
-            Set<Long> set = budgets.stream().map(l -> l.getProjectProcess()).collect(Collectors.toSet());
+            set = budgets.stream().map(l -> l.getProjectProcess()).collect(Collectors.toSet());
             //根据项目环节分组
-            Map<Long, List<ProjectCostBudget>> map = budgets.parallelStream()
+            map = budgets.parallelStream()
                     .collect(Collectors.groupingBy(ProjectCostBudget::getProjectProcess));
-            //包含此环节就统计,不包含就跳出
-            for (ProjectProcessVO vo : list) {
-                if (set.contains(vo.getId()) || (isMaintain && maintainMap.get(vo.getId()) != null)){
-                    //设置参与
-                    vo.setIsParticipate(1);
-                    //时间成本统计总天数,人员投入统计总人数,成本支出统计当前环节总支出
-                    BigDecimal costDisburse = new BigDecimal(0);
-                    BigDecimal timeCost = new BigDecimal(0);
-                    int staffTotal = 0;
-                    if (set.contains(vo.getId())) {
-                        List<ProjectCostBudget> budgetList = map.get(vo.getId());
-                        staffTotal = budgetList.size();
-                        for (ProjectCostBudget budget : budgetList) {
-                            costDisburse = costDisburse.add(budget.getActualTotalMoney());
-                            timeCost = timeCost.add(budget.getPracticalTaskDays());
-                        }
-                    }
-                    if (isMaintain && maintainMap.get(vo.getId()) != null){
-                        costDisburse = costDisburse.add(maintainMap.get(vo.getId()));
+        }else {
+            isBudgets = false;
+        }
+        //包含此环节就统计,不包含就跳出
+        for (ProjectProcessVO vo : list) {
+            if ((isBudgets && map.get(vo.getId()) != null) || (isMaintain && maintainMap.get(vo.getId()) != null) || (isReimburse && reimburseMap.get(vo.getId()) != null)){
+                //设置参与
+                vo.setIsParticipate(1);
+                //时间成本统计总天数,人员投入统计总人数,成本支出统计当前环节总支出
+                BigDecimal costDisburse = new BigDecimal(0);
+                BigDecimal timeCost = new BigDecimal(0);
+                int staffTotal = 0;
+                //设置费用明细
+                List<ProjectProcessVO.costDetail> details = new ArrayList<>();
+                if (isBudgets && map.get(vo.getId()) != null) {
+                    List<ProjectCostBudget> budgetList = map.get(vo.getId());
+                    staffTotal = budgetList.size();
+                    for (ProjectCostBudget budget : budgetList) {
+                        costDisburse = costDisburse.add(budget.getActualTotalMoney());
+                        timeCost = timeCost.add(budget.getPracticalTaskDays());
                     }
-                    //设置费用明细
-                    List<ProjectProcessVO.costDetail> details = new ArrayList<>();
                     ProjectProcessVO.costDetail costDetail = new ProjectProcessVO.costDetail();
                     costDetail.setCostTypeValue("人工成本");
                     costDetail.setPrice(costDisburse);
                     costDetail.setTotal(costDisburse);
                     details.add(costDetail);
-                    //目前环节费用的成本支出只统计了人工成本
-                    vo.setCostDisburse(costDisburse);
-                    vo.setTimeCost(timeCost);
-                    vo.setStaffTotal(staffTotal);
-                    vo.setCostDetails(details);
-                }else {
-                    vo.setIsParticipate(0);
                 }
+                //维护支出
+                if (isMaintain && maintainMap.get(vo.getId()) != null){
+                    costDisburse = costDisburse.add(maintainMap.get(vo.getId()));
+                    ProjectProcessVO.costDetail costDetail = new ProjectProcessVO.costDetail();
+                    costDetail.setCostTypeValue("维护支出");
+                    costDetail.setPrice(maintainMap.get(vo.getId()));
+                    costDetail.setTotal(maintainMap.get(vo.getId()));
+                    details.add(costDetail);
+                }
+                //报销支出
+                if (isReimburse && reimburseMap.get(vo.getId()) != null){
+                    costDisburse = costDisburse.add(reimburseMap.get(vo.getId()));
+                    ProjectProcessVO.costDetail costDetail = new ProjectProcessVO.costDetail();
+                    costDetail.setCostTypeValue("报销支出");
+                    costDetail.setPrice(reimburseMap.get(vo.getId()));
+                    costDetail.setTotal(reimburseMap.get(vo.getId()));
+                    details.add(costDetail);
+                }
+                //统计最后的总计
+                if (details.size() > 0) {
+                    BigDecimal big = new BigDecimal(0);
+                    for (ProjectProcessVO.costDetail detail : details) {
+                        big = big.add(detail.getPrice());
+                    }
+                    details.get(0).setTotal(big);
+                }
+                //目前环节费用的成本支出统计了:人工成本,维护支出,项目报销
+                vo.setCostDisburse(costDisburse);
+                vo.setTimeCost(timeCost);
+                vo.setStaffTotal(staffTotal);
+                vo.setCostDetails(details);
+            }else {
+                vo.setIsParticipate(0);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * 根据项目id获取项目截至目前-某个费用分类的的报销支出,按项目环节返回
+     * @param projectId
+     * @param costType
+     * @return
+     */
+    @Override
+    public Map<Long, BigDecimal> getProjectReimburseByCostType(Long projectId, Integer costType) {
+        //获取项目的所有关联进程的报销
+        List<ProjectReimburseVO> infos = baseMapper.getProjectReimburse3(projectId, costType);
+        if (infos == null || infos.size() <= 0) {
+            return null;
+        }
+        //按照项目进程分组
+        Map<Long, List<ProjectReimburseVO>> map = infos.parallelStream()
+                .collect(Collectors.groupingBy(ProjectReimburseVO::getProjectProcess));
+        Map<Long, BigDecimal> decimalMap = new HashMap<>();
+        //统计每个进程的报销总和
+        for (Long aLong : map.keySet()) {
+            BigDecimal big = new BigDecimal(0);
+            List<ProjectReimburseVO> list = map.get(aLong);
+            for (ProjectReimburseVO vo : list) {
+                big = big.add(vo.getFrMoney());
             }
-            return list;
+            decimalMap.put(aLong, big);
         }
-        return null;
+        return decimalMap;
     }
 }