feat(project): 新增付款计划功能并优化资金计划计算逻辑
- 新增 ProjectBudgetPayPlan 相关实体类和 Repository - 在 ProjectBudgetService 中添加付款计划相关方法 - 修改资金计划计算逻辑,支持按月汇总付款计划- 在 ProjectController 中添加付款计划保存和查询接口 - 优化 ProjectGrossProfit 计算方法dev_1.0.0
parent
4e495c3eff
commit
acf0b64c96
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue