随着系统的正式使用,也发现了一些小问题,做了一些修改,一一记录在此避免再次踩坑。
合同录入和修改的金额匹配问题
原来我的逻辑是,在录入合同的时候检查合同总价=合同不含税价+增值税额,如果不相等,就报错。
但是在实际操作中,发现录入的时候,如果总价为一个整数,含税价和增值税额为两位小数,即使相等也会报错,这是为什么呢,答案就是在比较Decimal
类型数值的时候,没有统一到相同的小数点精度(scale
),导致即使我们认为相等,但其实也不相等,解决办法也很简单,在接受录入数据的时候,强制将其全部转换为两位小数,并且采取四舍五入的办法。由于前端在浏览器那里已经限制了必须录入2位小数的数值,所以这么做其实不会损失精度。
代码修改如下:
// 判断都不为空的情况下,是否相等
if ((contract.getPriceWithoutVAT() != null) && (contract.getVAT() != null)) {
if (!contract.getTotalPrice().setScale(2, RoundingMode.HALF_UP).equals(contract.getPriceWithoutVAT().setScale(2, RoundingMode.HALF_UP).add(contract.getVAT().setScale(2, RoundingMode.HALF_UP)))) {
model.addAttribute("numberError", "不含税价+增值税 不等于 合同总价");
return "pms/contract/contractAdd";
}
}
前边的代码加上这个判断,已经保证了合同总价,含税价和税额三个都不为空。将三个数值全部统一转换成两位小数精度的Decimal
类来进行比较,这样既保留了原来用户录入的金额,可以进行比较。
显示印花税类别
这个是一个非常小的改动,就是在下载数据的合同表中,加上最后一列对应的印花税类别。方便统计印花税。2022
年7
月新的印花税要来了,到时候又要做修改了。
添加按照项目显示所有合同的功能
目前没有这个功能,如果要查看合同,要么通过搜索,要么需要点到具体的合同类别中去,所以要添加这个功能方便一键查看。
Dao
层添加功能
有了之前按照项目id
查找全部Journal的经验,编写这个也方便多了。由于是查找合同,所以将功能添加在ContractDao
中:
public interface ContractDao extends JpaRepository<Contract, Integer> {
Set<Contract> findContractBySubject_ProjectIdOrderByCreateTime(int pid);
}
就是通过Subject
再查到ProjectId
,还是熟悉的套路。
Service
业务层添加功能
在ContractService
业务层添加对应的方法,也很简单:
@Service
public class ContractService {
// 查找某个项目对应的所有合同
@Transactional
public Set<Contract> findContractsByProject(int pid) {
return contractDao.findContractBySubject_ProjectIdOrderByCreateTime(pid);
}
}
控制器与页面
为了实现这个功能,很显然必须要添加一个新的URL
。
Project
类中的URL
方法
由于这个功能是从项目点进去,因此其URL
算在Project
类中。
在Project
类中添加一个拼接URL
的方法:
public String projectContractListURL() {
return "/pms/project/contracts/" + id;
}
之后就可以来编写对应的控制器和页面了。
控制器编写
由于这个功能算在Project
类中,因此我们在ProjectController
中加入ContractService
,然后来编写一个控制器:
public class ProjectController {
private final ProjectService projectService;
private final ContractService contractService;
@Autowired
public ProjectController(ProjectService projectService,ContractService contractService) {
this.projectService = projectService;
this.contractService = contractService;
}
// 显示项目对应的全部合同
@GetMapping("/contracts/{id}")
public String contractsOfProject(@PathVariable("id") int id, Model model) {
Project project = projectService.getProjectById(id);
Set<Contract> contracts = contractService.findContractsByProject(id);
model.addAttribute("project", project);
model.addAttribute("contracts", contracts);
model.addAttribute("count", contracts.size());
return "pms/contract/contractListOfProject";
}
这个控制器很简单,根据id查到项目和对应的所有合同,以及合同的数量。从return
语句可以看到,我们要编写一个pms/contract/contractListOfProject.html
的页面,下边就来编写。
页面编写
这个页面其实很简单,复制一份contractList.html
来进行修改,唯一不同的就是几个小地方比如标题、面包屑导航等要稍微修改一下。
首先是标题的部分,改成如下:
<title>[[${project.projectName}]] - 合同列表</title>
然后是面包屑导航,只保留两个层级即可:
<nav style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb" class="mt-3">
<ol class="breadcrumb">
<li class="breadcrumb-item" aria-current="page"><a href="/pms/project/list" th:href="@{/pms/project/list}" class="link-secondary">项目列表</a></li>
<li class="breadcrumb-item" aria-current="page"><a href="/pms/project/list"
th:href="${project.detailURL()}"
class="link-secondary">[[${project.projectName}]]</a>
</li>
<li class="breadcrumb-item" aria-current="page"><a href="/pms/project/contracts"
th:href="${project.projectContractListURL()}"
class="link-secondary">合同列表</a>
</li>
</ol>
</nav>
由于不会从此页面添加合同,而是到类别中添加,所以这里的一些判断和显示提示,以及添加的链接都可以删除。合同列表最后的操作也暂时删除,让这个页面暂时就纯展示即可。
列表的部分由于合同列表原来是组装的ContractData
,这里只是纯合同,所以就展示一下最简单的数据即可,如下:
<table class="table table-hover" th:if="${count != 0}">
<thead>
<tr>
<th>序号</th>
<th>合同编号</th>
<th>合同类别</th>
<th>供应商</th>
<th>合同名称</th>
<th>合同总价</th>
</tr>
</thead>
<tbody>
<tr th:each="contract, control:${contracts}">
<td th:text="${control.count}"></td>
<td th:text="${contract.number}"></td>
<td th:text="${contract.subject.getSubjectName()}"></td>
<td th:text="${contract.supplier}"></td>
<td><a href="" th:href="${contract.detailURL()}">[[${contract.name}]]</a></td>
<td th:text="${#numbers.formatDecimal(contract.totalPrice,1,'COMMA',2,'POINT')}"></td>
</tr>
</tbody>
</table>
至于分页,如果以后合同特别多了,那么就在这个基础上添加分页功能吧。
最后在projectList.html
中添加上每一行项目的操作中显示项目合同列表的功能就完成了。