feat(project): 增加项目报表导出功能

- 新增项目预算相关数据查询方法
- 实现项目报表导出的后端接口
- 优化项目列表查询,支持导出功能
dev_2.0.2
chenhao 2025-02-06 15:20:43 +08:00
parent 2dbcc43a43
commit c117b9a331
9 changed files with 138 additions and 3 deletions

View File

@ -154,12 +154,14 @@ public class ProjectController extends BaseController {
downloadHeader(httpServletResponse, Utils.generateExcelName("项目报表"), "application/octet-stream");
String[] headers = {"项目编号", "项目名称", "项目类型", "垫资模式", "垫资利息", "垫资峰值", "项目合同金额", "项目毛利A", "项目毛利A利率", "项目毛利", "项目毛利率", "项目把握度", "汇智产品金额", "华智产品金额",
"华三产品金额", "其他产品金额", "项目当前状态", "行业场景应用", "解决方案", "客户名称", "最终用户名称", "预计合同签订时间", "项目计划招标时间", "是否二次合作", "直签", "战略合作对象",
"项目负责人", "价值及风险", "主合同收款条款", "主合同具体解决方案", "计收计划", "审核状态", "当前审核人", "项目创建者", "部门名称","项目阶段", "公司销售阶段", "当前进度描述", "下一步计划", "项目开始时间", "项目结束时间", "最后更新时间"};
"项目负责人", "价值及风险", "主合同收款条款", "主合同具体解决方案", "计收计划", "审核状态", "当前审核人", "项目创建者", "部门名称","项目阶段", "公司销售阶段", "当前进度描述", "下一步计划", "项目开始时间", "项目结束时间", "最后更新时间",
"收入合计(不含税金额)","收入合计(税金)","采购成本合计(不含税金额)","采购成本合计(税金)","项目管理费用","资金占用成本"};
String[] exportColumns = {"projectNo", "name", "typeDesc", "underwrittenModeStr", "advanceInterestAmountRound", "advancePeakAmountRound", "contractRound", "grossProfitARound", "grossProfitAMarginRound", "grossProfitRound", "grossProfitMarginRound", "certaintyStr", "huizhiRound", "huazhiRound",
"huasanRound", "ziguangRound", "statusDesc", "industryScenario", "resolvePlanStr", "customer", "terminalCustomer", "contractTimeStr", "bidsTimeStr", "isSecondStr", "signTypeStr", "collaborator",
"principal", "valueRisk", "mainContractCollectionTerms", "mainContractResolvePlan", "calculationCollection", "approveStatusDesc", "approveName", "creatorName", "deptName","stageName", "saleStageName", "stageRemark", "nextPlan", "startDateStr", "endDateStr", "lastUpdateTimeStr"};
"principal", "valueRisk", "mainContractCollectionTerms", "mainContractResolvePlan", "calculationCollection", "approveStatusDesc", "approveName", "creatorName", "deptName","stageName", "saleStageName", "stageRemark", "nextPlan", "startDateStr", "endDateStr", "lastUpdateTimeStr",
"incomeTotalTaxExclude","incomeTotalTax","costTotalTaxExclude","costTotalTax","costProjectManageTaxExclude","costExpropriationTaxExclude"};
ExportUtils.exportToExcel(headers, exportColumns, 1, 10000,
httpServletResponse.getOutputStream(), (pN, pS) -> projectService.list(searchInfo, pN, pS).getList());
httpServletResponse.getOutputStream(), (pN, pS) -> projectService.listExport(searchInfo, pN, pS).getList());
}
/**

View File

@ -8,6 +8,7 @@ import java.util.List;
public interface ProjectBudgetCostDetailRepository extends JpaRepository<ProjectBudgetCostDetail,Integer> {
List<ProjectBudgetCostDetail> findAllByProjectIdEquals(int id);
List<ProjectBudgetCostDetail> findAllByProjectIdIn(List<Integer> id);
@Query(value = "select sum(amount) from project_budget_cost_detail where project_id = ?1", nativeQuery = true)
BigDecimal findAmountByProject(int projectId);

View File

@ -8,6 +8,7 @@ import java.util.List;
public interface ProjectBudgetCostManageRepository extends JpaRepository<ProjectBudgetCostManage,Integer> {
List<ProjectBudgetCostManage> findAllByProjectIdEquals(int id);
List<ProjectBudgetCostManage> findAllByProjectIdIn(List<Integer> id);
@Query(value = "select sum(cost_tax_exclude) from project_budget_cost_manage where type = ?", nativeQuery = true)
BigDecimal costTaxExcludeSum(int type);

View File

@ -8,6 +8,7 @@ import java.util.List;
public interface ProjectBudgetCostProjectManageDetailRepository extends JpaRepository<ProjectBudgetCostProjectManageDetail,Integer> {
List<ProjectBudgetCostProjectManageDetail> findAllByProjectIdEquals(int id);
List<ProjectBudgetCostProjectManageDetail> findAllByProjectIdIn(List<Integer> id);
@Query(value = "select sum(amount) from project_budget_cost_project_manage_detail where project_id = ?1", nativeQuery = true)
BigDecimal findAmountByProject(int id);

View File

@ -8,6 +8,7 @@ import java.util.List;
public interface ProjectBudgetCostRepository extends JpaRepository<ProjectBudgetCost,Integer> {
List<ProjectBudgetCost> findAllByProjectIdEquals(int id);
List<ProjectBudgetCost> findAllByProjectIdIn(List<Integer> id);
@Query(value = "select sum(cost_tax_include) from project_budget_cost where type = ?", nativeQuery = true)
BigDecimal costTaxIncludeSum(int type);

View File

@ -8,6 +8,7 @@ import java.util.List;
public interface ProjectBudgetIncomeDetailRepository extends JpaRepository<ProjectBudgetIncomeDetail,Integer> {
List<ProjectBudgetIncomeDetail> findAllByProjectIdEquals(int id);
List<ProjectBudgetIncomeDetail> findAllByProjectIdIn(List<Integer> id);
@Query(value = "select sum(amount) from project_budget_income_detail where project_id = ?1", nativeQuery = true)
BigDecimal findAmountByProject(int projectId);

View File

@ -7,6 +7,7 @@ import java.util.List;
public interface ProjectBudgetPlanDetailRepository extends JpaRepository<ProjectBudgetPlanDetail,Integer> {
List<ProjectBudgetPlanDetail> findAllByProjectIdEquals(int id);
List<ProjectBudgetPlanDetail> findAllByProjectIdIn(List<Integer> id);
@Query(value = "select * from project_budget_plan_detail where project_id in ?1", nativeQuery = true)
List<ProjectBudgetPlanDetail> findAllByProjectIds(List<Integer> projectInt);

View File

@ -281,6 +281,106 @@ public class ProjectBudgetService {
return budgetBean;
}
public Map<Integer,BudgetBean> getBudgetMap(List<Integer> projectIdList) {
Map<Integer,BudgetBean> resultMap=new HashMap<>();
//收入
List<ProjectBudgetIncomeDetail> incomeDetailList = projectBudgetIncomeDetailRepository.findAllByProjectIdIn(projectIdList);
Map<Integer, List<ProjectBudgetIncomeDetail>> incomeDetailMap = incomeDetailList.stream().collect(Collectors.groupingBy(ProjectBudgetIncomeDetail::getProjectId));
//采购成本
List<ProjectBudgetCostDetail> projectBudgetCostDetailList = projectBudgetCostDetailRepository.findAllByProjectIdIn(projectIdList);
Map<Integer, List<ProjectBudgetCostDetail>> projectBudgetCostDetailMap = projectBudgetCostDetailList.stream().collect(Collectors.groupingBy(ProjectBudgetCostDetail::getProjectId));
//项目管理成本
List<ProjectBudgetCostProjectManageDetail> projectManageDetailList = projectBudgetCostProjectManageDetailRepository.findAllByProjectIdIn(projectIdList);
Map<Integer, List<ProjectBudgetCostProjectManageDetail>> projectManageDetailMap = projectManageDetailList.stream().collect(Collectors.groupingBy(ProjectBudgetCostProjectManageDetail::getProjectId));
//其他其他成本
List<ProjectBudgetCost> costList = projectBudgetCostRepository.findAllByProjectIdIn(projectIdList);
Map<Integer, List<ProjectBudgetCost>> costMap = costList.stream().collect(Collectors.groupingBy(ProjectBudgetCost::getProjectId));
//资金占用成本
List<ProjectBudgetPlanDetail> budgetPlanDetailList = projectBudgetPlanDetailRepository.findAllByProjectIdIn(projectIdList);
Map<Integer, List<ProjectBudgetPlanDetail>> budgetPlanDetailMap = budgetPlanDetailList.stream().collect(Collectors.groupingBy(ProjectBudgetPlanDetail::getProjectId));
//公司管理成本
List<ProjectBudgetCostManage> manageList = projectBudgetCostManageRepository.findAllByProjectIdIn(projectIdList);
Map<Integer, List<ProjectBudgetCostManage>> manageMap = manageList.stream().collect(Collectors.groupingBy(ProjectBudgetCostManage::getProjectId));
for (Integer projectId : projectIdList) {
BudgetBean budgetBean = new BudgetBean();
if(CollectionUtil.isNotEmpty(incomeDetailMap.get(projectId))){
List<ProjectBudgetIncomeDetail> incomeDetails = incomeDetailMap.get(projectId);
//设备类收入,含税和不含税
List<ProjectBudgetIncomeDetail> collectDevice = incomeDetails.stream().filter(d -> d.getType() == ProjectBudgetIncomeDetail.TYPE_DEVICE).collect(Collectors.toList());
budgetBean.setIncomeDeviceTaxInclude(getIncomeTotalTaxInclude(collectDevice));
budgetBean.setIncomeDeviceTaxExclude(getIncomeTotalTaxExclude(collectDevice));
budgetBean.setIncomeDeviceTax(budgetBean.getIncomeDeviceTaxInclude().subtract(budgetBean.getIncomeDeviceTaxExclude()));
//工程类收入,含税和不含税
List<ProjectBudgetIncomeDetail> collectEngineer = incomeDetails.stream().filter(d -> d.getType() == ProjectBudgetIncomeDetail.TYPE_ENGINEER).collect(Collectors.toList());
budgetBean.setIncomeEngineerTaxInclude(getIncomeTotalTaxInclude(collectEngineer));
budgetBean.setIncomeEngineerTaxExclude(getIncomeTotalTaxExclude(collectEngineer));
budgetBean.setIncomeEngineerTax(budgetBean.getIncomeEngineerTaxInclude().subtract(budgetBean.getIncomeEngineerTaxExclude()));
//服务类收入,含税和不含税
List<ProjectBudgetIncomeDetail> collectService = incomeDetails.stream().filter(d -> d.getType() == ProjectBudgetIncomeDetail.TYPE_SERVICE).collect(Collectors.toList());
budgetBean.setIncomeServiceTaxInclude(getIncomeTotalTaxInclude(collectService));
budgetBean.setIncomeServiceTaxExclude(getIncomeTotalTaxExclude(collectService));
budgetBean.setIncomeServiceTax(budgetBean.getIncomeServiceTaxInclude().subtract(budgetBean.getIncomeServiceTaxExclude()));
}
if(CollectionUtil.isNotEmpty(projectBudgetCostDetailMap.get(projectId))){
List<ProjectBudgetCostDetail> projectBudgetCostDetails = projectBudgetCostDetailMap.get(projectId);
//采购成本-设备,含税和不含税
List<ProjectBudgetCostDetail> collectDevice = projectBudgetCostDetails.stream().filter(d -> d.getType() == ProjectBudgetCostDetail.TYPE_DEVICE).collect(Collectors.toList());
budgetBean.setCostPurchaseDeviceTaxInclude(getCostTotalTaxInclude(collectDevice));
budgetBean.setCostPurchaseDeviceTaxExclude(getCostTotalTaxExclude(collectDevice));
budgetBean.setCostPurchaseDeviceTax(budgetBean.getCostPurchaseDeviceTaxInclude().subtract(budgetBean.getCostPurchaseDeviceTaxExclude()));
//采购成本-施工,含税和不含税
List<ProjectBudgetCostDetail> collectBuild = projectBudgetCostDetails.stream().filter(d -> d.getType() == ProjectBudgetCostDetail.TYPE_BUILD).collect(Collectors.toList());
budgetBean.setCostPurchaseBuildTaxInclude(getCostTotalTaxInclude(collectBuild));
budgetBean.setCostPurchaseBuildTaxExclude(getCostTotalTaxExclude(collectBuild));
budgetBean.setCostPurchaseBuildTax(budgetBean.getCostPurchaseBuildTaxInclude().subtract(budgetBean.getCostPurchaseBuildTaxExclude()));
//采购成本-服务,含税和不含税
List<ProjectBudgetCostDetail> collectService = projectBudgetCostDetails.stream().filter(d -> d.getType() == ProjectBudgetCostDetail.TYPE_SERVICE).collect(Collectors.toList());
budgetBean.setCostPurchaseServiceTaxInclude(getCostTotalTaxInclude(collectService));
budgetBean.setCostPurchaseServiceTaxExclude(getCostTotalTaxExclude(collectService));
budgetBean.setCostPurchaseServiceTax(budgetBean.getCostPurchaseServiceTaxInclude().subtract(budgetBean.getCostPurchaseServiceTaxExclude()));
//采购成本-其他,含税和不含税
List<ProjectBudgetCostDetail> collectOther = projectBudgetCostDetails.stream().filter(d -> d.getType() == ProjectBudgetCostDetail.TYPE_OHTER).collect(Collectors.toList());
budgetBean.setCostPurchaseOtherTaxInclude(getCostTotalTaxInclude(collectOther));
budgetBean.setCostPurchaseOtherTaxExclude(getCostTotalTaxExclude(collectOther));
budgetBean.setCostPurchaseOtherTax(budgetBean.getCostPurchaseOtherTaxInclude().subtract(budgetBean.getCostPurchaseOtherTaxExclude()));
budgetBean.setCostPurchaseTotalTaxInclude(getCostTotalTaxInclude(collectDevice).add(getCostTotalTaxInclude(collectBuild)).add(getCostTotalTaxInclude(collectService)).add(getCostTotalTaxInclude(collectOther)));
budgetBean.setCostPurchaseTotalTaxExclude(getCostTotalTaxExclude(collectDevice).add(getCostTotalTaxExclude(collectBuild)).add(getCostTotalTaxExclude(collectService)).add(getCostTotalTaxExclude(collectOther)));
}
if(CollectionUtil.isNotEmpty(projectManageDetailMap.get(projectId))){
List<ProjectBudgetCostProjectManageDetail> projectManageDetails = projectManageDetailMap.get(projectId);
budgetBean.setCostProjectManageTaxExclude(getCostProjectManageTotalTaxExclude(projectManageDetails));
}
if(CollectionUtil.isNotEmpty(costMap.get(projectId))){
List<ProjectBudgetCost> costs = costMap.get(projectId);
ProjectBudgetCost projectBudgetCostOtherOther = costs.stream().filter(d -> d.getType() == ProjectBudgetCost.TYPE_OTHER_OTHER).collect(Collectors.toList()).get(0);
budgetBean.setCostOtherOtherTaxInclude(projectBudgetCostOtherOther.getCostTaxInclude());
budgetBean.setCostOtherOtherTaxExclude(projectBudgetCostOtherOther.getCostTaxExclude());
budgetBean.setCostOtherOtherTax(budgetBean.getCostOtherOtherTaxInclude().subtract(budgetBean.getCostOtherOtherTaxExclude()));
}
if(CollectionUtil.isNotEmpty(budgetPlanDetailMap.get(projectId))){
budgetBean.setCostExpropriationTaxExclude(getTotalCapitalInterest(budgetPlanDetailMap.get(projectId)));
}
if(CollectionUtil.isNotEmpty(manageMap.get(projectId))){
ProjectBudgetCostManage costManageCompany = manageMap.get(projectId).stream().filter(d -> d.getType() == ProjectBudgetCostManage.TYPE_COMPANY_MANAGE).collect(Collectors.toList()).get(0);
budgetBean.setCostCompanyManageTaxExclude(costManageCompany.getCostTaxExclude());
}
resultMap.put(projectId,budgetBean);
}
return resultMap;
}
private BigDecimal getIncomeTotalTaxInclude(List<ProjectBudgetIncomeDetail> list){
BigDecimal total = new BigDecimal(0);
if(CollectionUtil.isEmpty(list)){

View File

@ -4,11 +4,13 @@ import cn.palmte.work.bean.*;
import cn.palmte.work.config.activiti.ActApproveTypeEnum;
import cn.palmte.work.config.activiti.ActProcessKeyEnum;
import cn.palmte.work.model.*;
import cn.palmte.work.pojo.ProjectExportDto;
import cn.palmte.work.utils.InterfaceUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -306,6 +308,31 @@ public class ProjectService {
return page;
}
public Page<ProjectExportDto> listExport(Map<String, String> searchInfo, int pageNumber, int pageSize) {
Page<Project> list = this.list(searchInfo, pageNumber, pageSize);
List<ProjectExportDto> dtoList = new ArrayList<>();
Map<Integer, BudgetBean> budgetMap = projectBudgetService.getBudgetMap(list.getList().stream().map(Project::getId).collect(Collectors.toList()));
list.getList().forEach(project -> {
BudgetBean budgetBean = budgetMap.get(project.getId());
ProjectExportDto projectExportDto = new ProjectExportDto();
BeanUtils.copyProperties(project, projectExportDto);
if (null != budgetBean) {
//收入
projectExportDto.setIncomeTotalTaxExclude(budgetBean.getIncomeTotalTaxExclude());
projectExportDto.setIncomeTotalTax(budgetBean.getIncomeTotalTax());
//采购成本
projectExportDto.setCostTotalTaxExclude(budgetBean.getCostTotalTaxExclude());
projectExportDto.setCostTotalTax(budgetBean.getCostTotalTax());
//项目管理费用
projectExportDto.setCostProjectManageTaxExclude(budgetBean.getCostProjectManageTaxExclude());
//资金占用成本
projectExportDto.setCostExpropriationTaxExclude(budgetBean.getCostExpropriationTaxExclude());
}
dtoList.add(projectExportDto);
});
return new Page<ProjectExportDto>(dtoList, list.getPageNumber(), list.getPageSize(), list.getTotalPage(), list.getTotalRow());
}
public String getStageName(int stage){
if(stage == 0){
return "C0、项目可研";