在编写好收款和付款结算之后,由于需要在合同页面内展示一个合同对应的所有结算的累计合计数字,所以很显然需要一个BO
来进行加载,我们就把这个设置在业务层内,目前需要的BO
主要是两个,是某个合同所属的所有收款结算和付款结算的合计数字。
实际上这也意味着我们完成数据结构搭建之后,要开始写重型计算业务来一层一层汇总金额了。
BO
类设计
目前的一个合同下边有收款和付款结算记录,将来还要挂载具体的Journal
,对于虚拟的非合同项目也是如此,所以要设计一个单个合同的完整数据,包含其中的所有需要的数据,目前这里要包含合同本身,收款和付款结算记录,以及收款和付款结算记录的合计,所以设计如下:
public class ContractData {
private Contract contract;
private Set<ReceiptSettlement> receiptSettlements;
private Set<PaymentSettlement> paymentSettlements;
private BigDecimal totalReceivable = new BigDecimal("0.00");
private BigDecimal totalReceiptDeduction= new BigDecimal("0.00");
private BigDecimal totalReceived= new BigDecimal("0.00");
private BigDecimal totalPayable= new BigDecimal("0.00");
private BigDecimal totalPaymentDeduction= new BigDecimal("0.00");
private BigDecimal totalPaid= new BigDecimal("0.00");
}
相关的getter
和setter
方法都省略,为了防止出错,默认值都设置为0
。
业务类的编写
由于是合同的数据,在合同业务类中添加一个新方法,用于根据合同的id
来组装对应的ContractData
类:
@Transactional
public ContractData getContractData(int id) {
Contract contract = getContractById(id);
ContractData contractData = new ContractData();
contractData.setContract(contract);
contractData.setReceiptSettlements(contract.getReceiptSettlements());
contractData.setPaymentSettlements(contract.getPaymentSettlements());
contract.getReceiptSettlements().forEach(receiptSettlement -> {
contractData.setTotalReceivable(contractData.getTotalReceivable().add(receiptSettlement.totalReceivable()));
});
contract.getReceiptSettlements().forEach(receiptSettlement -> {
contractData.setTotalReceiptDeduction(contractData.getTotalReceiptDeduction().add(receiptSettlement.totalDeduction()));
});
contract.getReceiptSettlements().forEach(receiptSettlement -> {
contractData.setTotalReceived(contractData.getTotalReceived().add(receiptSettlement.totalReceived()));
});
contract.getPaymentSettlements().forEach(paymentSettlement -> {
contractData.setTotalPayable(contractData.getTotalPayable().add(paymentSettlement.totalPayable()));
});
contract.getPaymentSettlements().forEach(paymentSettlement -> {
contractData.setTotalPaymentDeduction(contractData.getTotalPaymentDeduction().add(paymentSettlement.totalDeduction()));
});
contract.getPaymentSettlements().forEach(paymentSettlement -> {
contractData.setTotalPaid(contractData.getTotalPaid().add(paymentSettlement.totalPaid()));
});
return contractData;
}
这个方法首先获取合同对象,然后将合同对应的收款结算和付款结算都设置上,最后将所有的累计数都累计到6个属性上,计算出对应的结果。
修改控制器
这里其实对于页面渲染来说,与合同有关的内容,可以只传入一个ContractData
就足够了,然而我不想大改控制器,所以就追加传入这个对象:
// 合同详情页
@GetMapping("/detail/{id}")
public String contractDetailPage(@PathVariable("id") int cid, Model model) {
Contract contract = contractService.getContractById(cid);
Set<Budget> budgets = contract.getBudgets();
Project project = ((Budget) budgets.toArray()[0]).getProject();
model.addAttribute("contract", contract);
model.addAttribute("budgets", budgets);
model.addAttribute("project", project);
model.addAttribute("contractData", contractService.getContractData(cid));
return "pms/contract/contractDetail";
}
控制器实际上就添加了contractData
这个数据,剩下就是如何渲染出来。
页面渲染
这里添加判断,如果一个合同没有收款或者付款结算记录,就无需渲染。
<h2 th:if="${contractData.getReceiptSettlements().size()!=0}" class="mt-2">合同收款结算情况</h2>
<table th:if="${contractData.getReceiptSettlements().size()!=0}" class="table table-sm table-striped" th:object="${contractData}">
<thead>
<tr>
<th>属性</th>
<th>金额</th>
</tr>
</thead>
<tbody>
<tr>
<td>应收结算款合计</td>
<td th:text="${#numbers.formatDecimal(contractData.totalReceivable,1,'COMMA',2,'POINT')}"></td>
</tr>
<tr>
<td>扣款合计</td>
<td th:text="${#numbers.formatDecimal(contractData.totalReceiptDeduction,1,'COMMA',2,'POINT')}"></td>
</tr>
<tr>
<td>实际收款合计</td>
<td th:text="${#numbers.formatDecimal(contractData.totalReceived,1,'COMMA',2,'POINT')}"></td>
</tr>
</tbody>
</table>
<h2 th:if="${contractData.getPaymentSettlements().size()!=0}" class="mt-2">合同付款结算情况</h2>
<table th:if="${contractData.getPaymentSettlements().size()!=0}" class="table table-sm table-striped" th:object="${contractData}">
<thead>
<tr>
<th>属性</th>
<th>金额</th>
</tr>
</thead>
<tbody>
<tr>
<td>应付结算款合计</td>
<td th:text="${#numbers.formatDecimal(contractData.totalPayable,1,'COMMA',2,'POINT')}"></td>
</tr>
<tr>
<td>扣款合计</td>
<td th:text="${#numbers.formatDecimal(contractData.totalPaymentDeduction,1,'COMMA',2,'POINT')}"></td>
</tr>
<tr>
<td>实际付款合计</td>
<td th:text="${#numbers.formatDecimal(contractData.totalPaid,1,'COMMA',2,'POINT')}"></td>
</tr>
</tbody>
</table>
上边这块代码加入到合同详情页的基础数据下边就可以了,这样就可以展示出来合同所属的收款和付款结算记录了。
现在马上就要开始编写最后一层,也就是明细记录,即Journal
类了。在编写完成之后,我们还需要再来修改ContractData
,以提供一个合同的完整数据,展示在合同列表和合同详情页面。
修改收款和付款结算记录的列表页
很显然我们现在有了对应的合计数,这里就可以在收款和付款结算记录的列表页添加上对应的合计数。这个比较简单,控制器里添加一条:
model.addAttribute("contractData", contractService.getContractData(cid));
然后在表格里添加一行,以收款结算记录为例:
<tr>
<td class="text-center" th:text="合计" colspan="2"></td>
<td class="text-primary" th:text="${#numbers.formatDecimal(contractData.totalReceivable,1,'COMMA',2,'POINT')}"></td>
<td class="text-primary" th:text="${#numbers.formatDecimal(contractData.totalReceiptDeduction,1,'COMMA',2,'POINT')}"></td>
<td class="text-primary" th:text="${#numbers.formatDecimal(contractData.totalReceived,1,'COMMA',2,'POINT')}"></td>
</tr>
现在修改好了合同数据,之后要做一层一层的汇总了。