|
@@ -16,6 +16,8 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.rmi.ServerException;
|
|
|
+import java.time.LocalDate;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -32,6 +34,16 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
|
|
|
|
|
|
private final IAnnualBudgetDisburseService disburseService;
|
|
|
|
|
|
+ private final IContractReturnedInfoService returnedInfoService;
|
|
|
+
|
|
|
+ private final IProjectCostBudgetService budgetService;
|
|
|
+
|
|
|
+ private final IDepartmentMonthPlanService monthPlanService;
|
|
|
+
|
|
|
+ private final IContractInfoService contractInfoService;
|
|
|
+
|
|
|
+ private final IProjectInfoService projectInfoService;
|
|
|
+
|
|
|
/**
|
|
|
* 新增年度经营预算
|
|
|
* @param dto
|
|
@@ -50,11 +62,11 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
|
|
|
BigDecimal contractTotal = map2.get("1");
|
|
|
BigDecimal planReturnedTotal = map2.get("2");
|
|
|
|
|
|
- //总经营预算
|
|
|
+ //总经营预算,所有支出总额
|
|
|
dto.setTotalBudget(disburseTotal);
|
|
|
- //年度合同指标
|
|
|
- dto.setAnnualContractTarget(contractTotal);
|
|
|
- //年度利润指标
|
|
|
+ //年度合同指标,预计本年度回款总额
|
|
|
+ dto.setAnnualContractTarget(planReturnedTotal);
|
|
|
+ //年度利润指标, 合同指标减经营预算
|
|
|
dto.setAnnualProfitTarget(planReturnedTotal.subtract(disburseTotal));
|
|
|
//人工成本
|
|
|
dto.setStaffCost(staffTotal);
|
|
@@ -290,6 +302,264 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
|
|
|
return allBudgetSubject;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 门户-年度指标统计 ,统计今年的
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public AnnualBudgetVO3 portalAnnualTarget() {
|
|
|
+ AnnualBudgetVO3 vo3 = new AnnualBudgetVO3();
|
|
|
+ //获取今年
|
|
|
+ int year = LocalDate.now().getYear();
|
|
|
+ //获取今年的年度预算
|
|
|
+ AnnualBudget annualBudget = baseMapper.getThisYearBudget(year);
|
|
|
+ if (annualBudget == null){
|
|
|
+ throw new ServiceException("请先做年度预算");
|
|
|
+ }
|
|
|
+ //年度利润指标
|
|
|
+ if (annualBudget.getAnnualContractTarget() == null){
|
|
|
+ annualBudget.setAnnualContractTarget(new BigDecimal(0));
|
|
|
+ }
|
|
|
+ if (annualBudget.getAnnualProfitTarget() == null){
|
|
|
+ annualBudget.setAnnualProfitTarget(new BigDecimal(0));
|
|
|
+ }
|
|
|
+ vo3.setAnnualProfitTarget(annualBudget.getAnnualProfitTarget());
|
|
|
+ //年度合同指标
|
|
|
+ vo3.setAnnualContractTarget(annualBudget.getAnnualContractTarget());
|
|
|
+ //获取今年的已收入:合同回款
|
|
|
+ BigDecimal yearReturned = returnedInfoService.getYearReturned(year);
|
|
|
+ vo3.setYearReturned(yearReturned);
|
|
|
+ //统计今年的已盈利:已收入-支出 ,目前已支出只统计闭环的计划
|
|
|
+ //获取一年人工支出
|
|
|
+ BigDecimal yearStaffDisburse = budgetService.getYearStaffDisburse(year);
|
|
|
+ vo3.setYearProfit(yearReturned.subtract(yearStaffDisburse));
|
|
|
+ //合同进度统计
|
|
|
+ if (vo3.getAnnualContractTarget() == null || vo3.getAnnualContractTarget().compareTo(BigDecimal.ZERO) == 0 || vo3.getYearReturned().compareTo(BigDecimal.ZERO) == 0){
|
|
|
+ vo3.setContractSchedule(0);
|
|
|
+ }else {
|
|
|
+ vo3.setContractSchedule(vo3.getYearReturned().divide(vo3.getAnnualContractTarget(),2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue());
|
|
|
+ }
|
|
|
+ //利润进度统计
|
|
|
+ if (vo3.getAnnualProfitTarget() == null || vo3.getAnnualProfitTarget().compareTo(BigDecimal.ZERO) == 0 || vo3.getYearProfit().compareTo(BigDecimal.ZERO) == 0){
|
|
|
+ vo3.setProfitSchedule(0);
|
|
|
+ }else {
|
|
|
+ vo3.setProfitSchedule(vo3.getYearProfit().divide(vo3.getAnnualProfitTarget(),2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue());
|
|
|
+ }
|
|
|
+ return vo3;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 门户-年度各项费用统计 ,如果全部就传0
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Map<String, BigDecimal> portalAnnualCost(String year) {
|
|
|
+ int y;
|
|
|
+ if ("汇总所有".equals(year)){
|
|
|
+ y = 0;
|
|
|
+ }else {
|
|
|
+ y = Integer.parseInt(year.substring(0,4));
|
|
|
+ }
|
|
|
+ Map<String,BigDecimal> map = new HashMap<>();
|
|
|
+ //总合同:当年所有合同金额
|
|
|
+ BigDecimal yearContractMoney = contractInfoService.getYearContractMoney(y);
|
|
|
+ map.put("yearContractMoney",yearContractMoney);
|
|
|
+ //总实际收入:当年所有回款
|
|
|
+ BigDecimal yearReturned = returnedInfoService.getYearReturned(y);
|
|
|
+ map.put("yearReturned",yearReturned);
|
|
|
+ //总实际支出:当年所有报销支出,和人工支出
|
|
|
+ BigDecimal yearStaffDisburse = budgetService.getYearStaffDisburse(y);
|
|
|
+ map.put("yearStaffDisburse",yearStaffDisburse);
|
|
|
+ //总计划支出:年度预算总计划支出
|
|
|
+ if (y == 0){
|
|
|
+ List<AnnualBudget> list = baseMapper.getAllYearBudget(y);
|
|
|
+ BigDecimal decimal = new BigDecimal(0);
|
|
|
+ for (AnnualBudget budget : list) {
|
|
|
+ if (budget.getTotalBudget() != null){
|
|
|
+ decimal = decimal.add(budget.getTotalBudget());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ map.put("totalBudget", decimal);
|
|
|
+ }else {
|
|
|
+ AnnualBudget annualBudget = baseMapper.getThisYearBudget(y);
|
|
|
+ if (annualBudget != null && annualBudget.getTotalBudget() != null) {
|
|
|
+ BigDecimal totalBudget = annualBudget.getTotalBudget();
|
|
|
+ map.put("totalBudget", totalBudget);
|
|
|
+ }else {
|
|
|
+ map.put("totalBudget", new BigDecimal(0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> yearList(Integer type) {
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
+ Integer year = baseMapper.yearList();
|
|
|
+ if (year != null) {
|
|
|
+ int thisYear = LocalDate.now().getYear();
|
|
|
+ for (int i = year; i <= thisYear; i++) {
|
|
|
+ list.add(i + "年");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (type != 1) {
|
|
|
+ list.add("汇总所有");
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 门户-年度各项目支出对比
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<AnnualProjectCostVO> portalAnnualProjectCost(String year) {
|
|
|
+ int y = Integer.parseInt(year.substring(0,4));
|
|
|
+ //查出指定年的项目
|
|
|
+ List<ControlProjectInfo> list = projectInfoService.listByYear(y);
|
|
|
+ if (list == null || list.size() <= 0){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<AnnualProjectCostVO> mapList = new ArrayList<>();
|
|
|
+ //按年查询所有支出,按照项目分组,然后再按照月份分组统计
|
|
|
+ //目前查询人工支出
|
|
|
+ List<ProjectCostBudget> budgetByYear = budgetService.getBudgetByYear(y);
|
|
|
+ Map<Long, List<ProjectCostBudget>> map = budgetByYear.parallelStream()
|
|
|
+ .collect(Collectors.groupingBy(ProjectCostBudget::getProjectId));
|
|
|
+ for (ControlProjectInfo project : list) {
|
|
|
+ AnnualProjectCostVO vo = new AnnualProjectCostVO();
|
|
|
+ List<Integer> integerList = new ArrayList<>();
|
|
|
+ List<ProjectCostBudget> budgets = map.get(project.getId());
|
|
|
+ for (int i = 1; i <= 12; i++) {
|
|
|
+ BigDecimal big = new BigDecimal(0);
|
|
|
+ if (budgets != null && budgets.size() > 0) {
|
|
|
+ for (ProjectCostBudget budget : budgets) {
|
|
|
+ if (budget.getPracticalFinishTime().getMonthValue() == i) {
|
|
|
+ big = big.add(budget.getActualTotalMoney());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ integerList.add(big.intValue());
|
|
|
+ }
|
|
|
+ vo.setName(project.getName());
|
|
|
+ vo.setValue(integerList);
|
|
|
+ mapList.add(vo);
|
|
|
+ }
|
|
|
+ return mapList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 门户-当月各部门计划安排比重
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<DeptMonthPlanRatioVO> portalProjectMonthRatio(String date) {
|
|
|
+ //获取当月所有计划,和计划工资
|
|
|
+ List<ProjectCostBudgetVO2> planByMonth = budgetService.getPlanByMonth(date);
|
|
|
+ if (planByMonth != null || planByMonth.size() >= 0) {
|
|
|
+ List<DeptMonthPlanRatioVO> vos = new ArrayList<>();
|
|
|
+ //月计划包含的项目
|
|
|
+ Set<Long> projectIds = new HashSet<>();
|
|
|
+ //每个部门投入总和
|
|
|
+ BigDecimal businessCount = new BigDecimal(0);
|
|
|
+ BigDecimal devCount = new BigDecimal(0);
|
|
|
+ BigDecimal maintainCount = new BigDecimal(0);
|
|
|
+ //循环获取项目,获取每个部门总和
|
|
|
+ for (ProjectCostBudgetVO2 plan : planByMonth) {
|
|
|
+ projectIds.add(plan.getProjectId());
|
|
|
+ if (plan.getCostType() == 3) {
|
|
|
+ businessCount = businessCount.add(plan.getPlanCountMoney());
|
|
|
+ } else if (plan.getCostType() == 2) {
|
|
|
+ devCount = devCount.add(plan.getPlanCountMoney());
|
|
|
+ } else if (plan.getCostType() == 4) {
|
|
|
+ maintainCount = maintainCount.add(plan.getPlanCountMoney());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //根据项目再一个一个存入
|
|
|
+ Map<Long, List<ProjectCostBudgetVO2>> projectMap = planByMonth.parallelStream()
|
|
|
+ .collect(Collectors.groupingBy(ProjectCostBudgetVO2::getProjectId));
|
|
|
+ List<ControlProjectInfo> projectInfos = projectInfoService.listByIds(projectIds);
|
|
|
+ for (ControlProjectInfo projectInfo : projectInfos) {
|
|
|
+ DeptMonthPlanRatioVO vo = new DeptMonthPlanRatioVO();
|
|
|
+ BigDecimal business = new BigDecimal(0);
|
|
|
+ BigDecimal dev = new BigDecimal(0);
|
|
|
+ BigDecimal maintain = new BigDecimal(0);
|
|
|
+ vo.setProjectName(projectInfo.getName());
|
|
|
+ List<ProjectCostBudgetVO2> list = projectMap.get(projectInfo.getId());
|
|
|
+ for (ProjectCostBudgetVO2 vo2 : list) {
|
|
|
+ if (vo2.getCostType() == 3) {
|
|
|
+ business = business.add(vo2.getPlanCountMoney());
|
|
|
+ } else if (vo2.getCostType() == 2) {
|
|
|
+ dev = dev.add(vo2.getPlanCountMoney());
|
|
|
+ } else if (vo2.getCostType() == 4) {
|
|
|
+ maintain = maintain.add(vo2.getPlanCountMoney());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //设置投入比
|
|
|
+ if (new BigDecimal(0).compareTo(businessCount) != 0){
|
|
|
+ vo.setBusinessRatio(business.divide(businessCount, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue() + "%");
|
|
|
+ }
|
|
|
+ if (new BigDecimal(0).compareTo(devCount) != 0) {
|
|
|
+ vo.setDevRatio(dev.divide(devCount, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue() + "%");
|
|
|
+ }
|
|
|
+ if (new BigDecimal(0).compareTo(maintainCount) != 0) {
|
|
|
+ vo.setMaintainRatio(maintain.divide(maintainCount, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue() + "%");
|
|
|
+ }
|
|
|
+ //插入结果集
|
|
|
+ vos.add(vo);
|
|
|
+ }
|
|
|
+ return vos;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 门户-风险计划
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<AllProjectStatsVO> portalRiskPlan() {
|
|
|
+ //获取所有风险计划
|
|
|
+ List<ProjectCostBudget> riskPlan = budgetService.getRiskPlan(null,null);
|
|
|
+ if (riskPlan == null || riskPlan.size() <= 0) {
|
|
|
+ throw new ServiceException("暂无风险计划");
|
|
|
+ }
|
|
|
+ List<AllProjectStatsVO> vos = new ArrayList<>();
|
|
|
+ //获取部门映射值
|
|
|
+ List<DictInfo> costTypeDict = monthPlanService.getDepartmentDict();
|
|
|
+ Map<Integer, List<DictInfo>> collect = costTypeDict.parallelStream()
|
|
|
+ .collect(Collectors.groupingBy(DictInfo::getDictValue));
|
|
|
+ //风险计划按项目分组,再按照部门分组,再统计计划总数
|
|
|
+ Map<Long, List<ProjectCostBudget>> map = riskPlan.parallelStream()
|
|
|
+ .collect(Collectors.groupingBy(ProjectCostBudget::getProjectId));
|
|
|
+ List<ControlProjectInfo> projectInfos = projectInfoService.listByIds(map.keySet());
|
|
|
+ for (ControlProjectInfo info : projectInfos) {
|
|
|
+ //获取项目延期计划
|
|
|
+ List<ProjectCostBudget> budgets = map.get(info.getId());
|
|
|
+ //通过部门分组
|
|
|
+ Map<Integer, List<ProjectCostBudget>> listMap = budgets.parallelStream()
|
|
|
+ .collect(Collectors.groupingBy(ProjectCostBudget::getCostType));
|
|
|
+ //添加进结果集
|
|
|
+ for (Integer integer : listMap.keySet()) {
|
|
|
+ AllProjectStatsVO vo = new AllProjectStatsVO();
|
|
|
+ vo.setProjectName(info.getName());
|
|
|
+ vo.setProjectId(info.getId());
|
|
|
+ vo.setCostType(integer);
|
|
|
+ //如果不为管理支出和外包劳务,则直接设置
|
|
|
+ if (integer != 5 && integer != 6){
|
|
|
+ vo.setCostTypeValue(collect.get(integer).get(0).getDictName());
|
|
|
+ vo.setTimeOutPlanTotal(listMap.get(integer).size());
|
|
|
+ }else {
|
|
|
+ vo.setCostTypeValue(collect.get(5).get(0).getDictName());
|
|
|
+ if (listMap.get(5) != null && listMap.get(6) != null){
|
|
|
+ vo.setTimeOutPlanTotal(listMap.get(5).size() + listMap.get(6).size());
|
|
|
+ }else if (listMap.get(5) != null){
|
|
|
+ vo.setTimeOutPlanTotal(listMap.get(5).size());
|
|
|
+ }else if (listMap.get(6) != null){
|
|
|
+ vo.setTimeOutPlanTotal(listMap.get(6).size());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vos.add(vo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return vos;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 统计支出 1支出总和2工资总和
|
|
|
*/
|