feat(project): 新增付款计划功能并优化资金计划计算逻辑

- 新增 ProjectBudgetPayPlan 相关实体类和 Repository
- 在 ProjectBudgetService 中添加付款计划相关方法
- 修改资金计划计算逻辑,支持按月汇总付款计划- 在 ProjectController 中添加付款计划保存和查询接口
- 优化 ProjectGrossProfit 计算方法
dev_1.0.0
chenhao 2024-10-28 10:59:08 +08:00
parent 4e495c3eff
commit acf0b64c96
7 changed files with 228 additions and 24 deletions

View File

@ -45,7 +45,7 @@ public abstract class IncomeCostBean {
*
*/
private BigDecimal costPurchaseServiceTaxInclude;
/*private BigDecimal costProjectManageTaxInclude;*/
/* private BigDecimal costProjectManageTaxInclude; */
/**
*
*/
@ -264,7 +264,6 @@ public abstract class IncomeCostBean {
this.costPurchaseServiceTaxInclude = costPurchaseServiceTaxInclude;
}
/**
* =
*/
@ -272,9 +271,12 @@ public abstract class IncomeCostBean {
return getCostProjectManageTaxExclude();
}
/*public void setCostProjectManageTaxInclude(BigDecimal costProjectManageTaxInclude) {
this.costProjectManageTaxInclude = costProjectManageTaxInclude;
}*/
/*
* public void setCostProjectManageTaxInclude(BigDecimal
* costProjectManageTaxInclude) {
* this.costProjectManageTaxInclude = costProjectManageTaxInclude;
* }
*/
public BigDecimal getCostPurchaseOtherTaxInclude() {
return handleSpecial(costPurchaseOtherTaxInclude);
@ -346,7 +348,6 @@ public abstract class IncomeCostBean {
this.costOtherOtherTaxExclude = costOtherOtherTaxExclude;
}
public BigDecimal getCostExpropriationTaxExclude() {
return handleSpecial(costExpropriationTaxExclude);
}
@ -377,7 +378,6 @@ public abstract class IncomeCostBean {
return costExpropriationTaxExclude.add(costCompanyManageTaxExclude);
}
/**
*
*/
@ -485,7 +485,8 @@ public abstract class IncomeCostBean {
*/
public BigDecimal getProjectGrossProfitA() {
BigDecimal incomeTotalTaxExclude = getIncomeTotalTaxExclude();
BigDecimal costTotalTaxExclude = getCostPurchaseDeviceTaxExclude().add(getCostPurchaseBuildTaxExclude()).add(getCostPurchaseServiceTaxExclude()).add(getCostPurchaseOtherTaxExclude());
BigDecimal costTotalTaxExclude = getCostPurchaseDeviceTaxExclude().add(getCostPurchaseBuildTaxExclude())
.add(getCostPurchaseServiceTaxExclude()).add(getCostPurchaseOtherTaxExclude());
if (null == incomeTotalTaxExclude) {
return handleSpecial(null);
}
@ -514,18 +515,31 @@ public abstract class IncomeCostBean {
/**
*
* --
* B=A--
*/
public BigDecimal getProjectGrossProfit() {
BigDecimal incomeTotalTaxExclude = getIncomeTotalTaxExclude();
BigDecimal costTotalTaxExclude = getCostTotalTaxExclude();
BigDecimal costExpropriationTaxExclude = getCostExpropriationTaxExclude();
if (null == incomeTotalTaxExclude || null == costTotalTaxExclude || null == costExpropriationTaxExclude) {
// BigDecimal incomeTotalTaxExclude = getIncomeTotalTaxExclude();
// BigDecimal costTotalTaxExclude = getCostTotalTaxExclude();
// BigDecimal costExpropriationTaxExclude = getCostExpropriationTaxExclude();
// if (null == incomeTotalTaxExclude || null == costTotalTaxExclude || null ==
// costExpropriationTaxExclude) {
// return handleSpecial(null);
// }
// return incomeTotalTaxExclude
// .subtract(costTotalTaxExclude)
// .subtract(costExpropriationTaxExclude);
BigDecimal projectGrossProfitA = getProjectGrossProfitA(); // 项目毛利A
BigDecimal costExpropriationTaxExclude = getCostExpropriationTaxExclude(); // 财务费用
BigDecimal costProjectManageTaxExclude = getCostProjectManageTaxExclude(); // 项目管理费用
if (null == projectGrossProfitA || null == costExpropriationTaxExclude || null == costProjectManageTaxExclude) {
return handleSpecial(null);
}
return incomeTotalTaxExclude
.subtract(costTotalTaxExclude)
.subtract(costExpropriationTaxExclude);
return projectGrossProfitA
.subtract(costExpropriationTaxExclude)
.subtract(costProjectManageTaxExclude);
}
/**

View File

@ -402,6 +402,9 @@ public class ProjectController extends BaseController {
//收入计划
List<ProjectBudgetIncomePlanDetail> budgetIncomePlanDetail = projectBudgetService.getBudgetIncomePlanDetail(project);
model.put("incomePlanDetails", budgetIncomePlanDetail);
//付款计划表
List<ProjectBudgetPayPlan> budgetPayPlan = projectBudgetService.getBudgetPayPlan(project);
model.put("budgetPayPlan", budgetPayPlan);
BigDecimal incomePlanTotalReceiveAmount = projectBudgetService.getBudgetIncomePlanReceiveAmount(project);
model.put("incomePlanTotal", incomePlanTotalReceiveAmount);
//成本明细
@ -594,6 +597,26 @@ public class ProjectController extends BaseController {
return ResponseMsg.buildSuccessMsg("成功");
}
/**
*
*/
@RequestMapping("/budgetEditSaveBudgetPayPlan")
@ResponseBody
public ResponseMsg budgetEditSaveBudgetPayPlan(@RequestBody String body) {
JSONObject jsonObject = JSON.parseObject(body);
JSONArray details = jsonObject.getJSONArray(DETAILS);
List<ProjectBudgetPayPlan> detailList = new ArrayList<>(details.size());
for (int i = 0; i < details.size(); i++) {
ProjectBudgetPayPlan detail = details.getObject(i, ProjectBudgetPayPlan.class);
detailList.add(detail);
}
Project project = projectService.getProject(jsonObject.getInteger(PROJECT_ID));
projectBudgetService.saveBudgetPayPlan(project, detailList);
return ResponseMsg.buildSuccessMsg("成功");
}
/**
@ -696,6 +719,9 @@ public class ProjectController extends BaseController {
model.put("incomePlanDetails", budgetIncomePlanDetail);
BigDecimal incomePlanTotalReceiveAmount = projectBudgetService.getBudgetIncomePlanReceiveAmount(project);
model.put("incomePlanTotal", incomePlanTotalReceiveAmount);
//付款计划表
List<ProjectBudgetPayPlan> budgetPayPlan = projectBudgetService.getBudgetPayPlan(project);
model.put("budgetPayPlan", budgetPayPlan);
//成本明细
List<ProjectBudgetCostDetail> budgetCostDetail = projectBudgetService.getBudgetCostDetail(project);
model.put("costDetails", budgetCostDetail);

View File

@ -0,0 +1,12 @@
package cn.palmte.work.model;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
*
*/
@Entity
@Table(name = "project_budget_pay_plan")
public class ProjectBudgetPayPlan extends ProjectBudgetPayPlanBase {
}

View File

@ -0,0 +1,92 @@
package cn.palmte.work.model;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
@MappedSuperclass
public class ProjectBudgetPayPlanBase {
/**
* id
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@GenericGenerator(name = "persistenceGenerator", strategy = "increment")
private Integer id;
@Column(name = "project_id")
private int projectId;
@Column(name = "pay_point")
private String payPoint;
@Column(name = "pay_time")
@Temporal(TemporalType.TIMESTAMP)
private Date payTime;
@Column(name = "pay_amount")
private BigDecimal payAmount;
@Column(name = "pay_project")
private String payProject;
@Column(name = "supplier")
private String supplier;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public int getProjectId() {
return projectId;
}
public void setProjectId(int projectId) {
this.projectId = projectId;
}
public String getPayPoint() {
return payPoint;
}
public void setPayPoint(String payPoint) {
this.payPoint = payPoint;
}
public Date getPayTime() {
return payTime;
}
public void setPayTime(Date payTime) {
this.payTime = payTime;
}
public BigDecimal getPayAmount() {
return payAmount;
}
public void setPayAmount(BigDecimal payAmount) {
this.payAmount = payAmount;
}
public String getPayProject() {
return payProject;
}
public void setPayProject(String payProject) {
this.payProject = payProject;
}
public String getSupplier() {
return supplier;
}
public void setSupplier(String supplier) {
this.supplier = supplier;
}
}

View File

@ -0,0 +1,12 @@
package cn.palmte.work.model;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.math.BigDecimal;
import java.util.List;
public interface ProjectBudgetPayPlanRepository extends JpaRepository<ProjectBudgetPayPlan,Integer> {
List<ProjectBudgetPayPlan> findAllByProjectIdEquals(int id);
}

View File

@ -1,11 +1,23 @@
package cn.palmte.work.model;
import lombok.Data;
import javax.persistence.*;
import java.math.BigDecimal;
/**
*
*/
@Entity
@Table(name = "project_budget_plan_detail")
@Data
public class ProjectBudgetPlanDetail extends ProjectBudgetPlanDetailBase{
//服务支出
private BigDecimal serviceCost;
// private BigDecimal deviceCost;
// private BigDecimal projectCost;
//其它支出
private BigDecimal otherCost;
}

View File

@ -15,6 +15,7 @@ import top.jfunc.common.utils.CollectionUtil;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@ -38,6 +39,8 @@ public class ProjectBudgetService {
@Autowired
private ProjectBudgetIncomePlanDetailRepository projectBudgetIncomePlanDetailRepository;
@Autowired
private ProjectBudgetPayPlanRepository projectBudgetPayPlanRepository;
@Autowired
private ProjectBudgetIncomePlanDetailTempRepository projectBudgetIncomePlanDetailTempRepository;
@Autowired
private ProjectBudgetCostDetailRepository projectBudgetCostDetailRepository;
@ -656,10 +659,25 @@ public class ProjectBudgetService {
*
*/
public ProjectBudgetPlanDetail getProjectBudgetPlanDetailTotal(Project project, List<ProjectBudgetPlanDetail> projectBudgetPlanDetails) {
List<ProjectBudgetPayPlan> budgetPayPlan = projectBudgetService.getBudgetPayPlan(project);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
Map<String, Map<String, BigDecimal>> monthlyProjectPaymentSum = budgetPayPlan.stream()
.collect(Collectors.groupingBy(
plan -> formatter.format(plan.getPayTime()), // 将 Date 转换为 yyyy-MM 格式的字符串
Collectors.groupingBy(
ProjectBudgetPayPlan::getPayProject,
Collectors.mapping(
ProjectBudgetPayPlan::getPayAmount,
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
)
)
));
BigDecimal deviceCost = new BigDecimal(0);
BigDecimal engineerCost = new BigDecimal(0);
BigDecimal projectManageCost = new BigDecimal(0);
BigDecimal earnestMoneyCost = new BigDecimal(0);
BigDecimal serviceCost = new BigDecimal(0);
BigDecimal otherCost = new BigDecimal(0);
BigDecimal totalCost = new BigDecimal(0);
BigDecimal saleIncome = new BigDecimal(0);
BigDecimal earnestMoneyIncome = new BigDecimal(0);
@ -672,10 +690,14 @@ public class ProjectBudgetService {
if(CollectionUtil.isNotEmpty(projectBudgetPlanDetails)){
for (ProjectBudgetPlanDetail budgetPlan : projectBudgetPlanDetails) {
deviceCost = deviceCost.add(budgetPlan.getDeviceCost());
engineerCost = engineerCost.add(budgetPlan.getEngineerCost());
projectManageCost = projectManageCost.add(budgetPlan.getProjectManageCost());
earnestMoneyCost = earnestMoneyCost.add(budgetPlan.getEarnestMoneyCost());
String month = budgetPlan.getMonth();
Map<String, BigDecimal> projectPayments = monthlyProjectPaymentSum.getOrDefault(month, Collections.emptyMap());
deviceCost = deviceCost.add(projectPayments.getOrDefault("设备成本", BigDecimal.ZERO));
engineerCost = engineerCost.add(projectPayments.getOrDefault("工程成本", BigDecimal.ZERO));
serviceCost = serviceCost.add(projectPayments.getOrDefault("服务成本", BigDecimal.ZERO));
otherCost = otherCost.add(projectPayments.getOrDefault("其他成本", BigDecimal.ZERO));
totalCost = totalCost.add(budgetPlan.getTotalCost());
saleIncome = saleIncome.add(budgetPlan.getSaleIncome());
earnestMoneyIncome = earnestMoneyIncome.add(budgetPlan.getEarnestMoneyIncome());
@ -695,8 +717,8 @@ public class ProjectBudgetService {
projectBudgetPlanDetail.setMonth("合计");
projectBudgetPlanDetail.setDeviceCost(deviceCost);
projectBudgetPlanDetail.setEngineerCost(engineerCost);
projectBudgetPlanDetail.setProjectManageCost(projectManageCost);
projectBudgetPlanDetail.setEarnestMoneyCost(earnestMoneyCost);
projectBudgetPlanDetail.setServiceCost(serviceCost); // 设置服务成本
projectBudgetPlanDetail.setOtherCost(otherCost); // 设置其他成本
projectBudgetPlanDetail.setTotalCost(totalCost);
projectBudgetPlanDetail.setSaleIncome(saleIncome);
projectBudgetPlanDetail.setEarnestMoneyIncome(earnestMoneyIncome);
@ -1300,4 +1322,18 @@ public class ProjectBudgetService {
temp.setRemark((String) o1);
costDetailTempList.add(temp);
}
public List<ProjectBudgetPayPlan> getBudgetPayPlan(Project project) {
return projectBudgetPayPlanRepository.findAllByProjectIdEquals(project.getId());
}
public void saveBudgetPayPlan(Project project, List<ProjectBudgetPayPlan> detailList) {
if(CollectionUtil.isNotEmpty(detailList)){
for (ProjectBudgetPayPlan temp : detailList) {
temp.setProjectId(project.getId());
// temp.setUnderwrittenTaxRate(project.getUnderwrittenTaxRate());
}
projectBudgetPayPlanRepository.save(detailList);
}
}
}