1.问题描述
单据导入发票,保存或提交后,或是打开有导入发票的费用报销类单据,发现分录上显示的发票数量和发票分录的发票数量不一致,发票分录数量更少,存在丢失的情况。如下图:分录发票数量显示发票一张,发票分录为空
2.问题分析
因为费用报销类单据分录实体(invoiceEntryId字段)和发票分录实体(bizEntryBill字段)建立了一对多的聚合关联关系(即相当于单头和分录的关系)。所以在单据入库时必须做以下两点,以正确维护它们的关系:
(1)在单据首次入库时,发票分录bizEntryBill字段必须存有对应的分录id或分录对象。
(2)在单据非首次入库时,单据分录invoiceEntryId字段必须存有正确的值,即分录已对应的发票分录,该字段的值是编辑打开单据或保存单据刷新页面时,框架根据bizEntryBill的值,自动查询并加载的。如果值不存在或不正确,那该单据入库,就会将已对应的发票分录给删除。因为invoiceEntryId为空,框架会认为分录没有相对应的发票分录了,入库时就会生成删除语句删除这些发票分录。
其中(2)就会导致发票分录删除,看起来像丢失了一样。其本质原因还是数据库中分录实际有对应发票,即bizEntryBill存了对应分录id了,但单据再次入库时,分录invoiceEntryId字段没有获取或更新到数据库中正确的值(值为分录所有对应的发票分录),单据和数据库中实际关系存在不一致,导致发票分录被删除了。可能有以下原因导致这种情况发生:
1. 发票分录的bizEntryBill没有正确设置对应分录id值,导致没有建立起发票分录和分录的关系。会导致单据打开,查看不到发票分录,这时实际数据库还存在发票分录。但单据再次入库时,会因为invoiceEntryId没有获取到正确的值(此时为空),导致发票分录被删除。这种可能的原因有:
(1)费用单据页面方案分录bizEntryBill字段丢失了,如扩展误删除了该字段;
(2)第三方系统集成发票分录过来,bizEntryBill没有设置正确值;
(3)二开了bizEntryBil相关的代码,没有设置正确的值,如二开了saveinvoiceXXXHandler里的bizEntryBil相关代码。
下图为页面方案发票分录bizEntryBil字段
正常单据,有一条发票分录
将bizEntryBill字段清空,页面就会查看不到发票分录。该单据如果再次入库,该发票分录就会被删除
2. 单据编辑入库时,model里invoiceEntryId字段没有值或值不正确导致。这种可能原因为:
(1)页面没有该字段,所以没有查出来。可能为扩展丢失了等。
(2)在编辑页或审批节点配编辑页面,上传了发票后,连续多次点击提交,导致发票分录丢失。因为连续提交,可能触发多次submit请求,后续的请求model中的invoiceEntryId没有更新,入库就会导致对应发票分录被删除。这种场景标准产品已出补丁优化,需要确认是否已更新补丁。
单据编辑页面连续点击优化补丁
8.6.1补丁PT165098(2022-05-05),web框架补丁861发版就有 R20201223-1383
8.5补丁PT160711(2021-09-26),R20201223-1383
8.2费用补丁PT168551(2022-11-25),web框架补丁PT168778(2022-11-18) R20221017-1300
8.0费用补丁PT161140(2021-10-19),web框架补丁PT161999(2021-11-12)
单据审批节点配编辑页面连续点击优化补丁
8.6.1补丁PT164234(2022-03-04) ,提单R20220118-1990
8.5补丁PT165269(2022-04-29)
8.2 补丁 PT168551(2022-11-25
3.二开代码问题导致。这种有一些场景导致,以下列举出现过的:
以下的核心原因都是invoiceEntryId没有正确处理,所以如果二开和问题排查需要特别注意这点
(1)在单据一次入库过程中,有两次调用保存或提交入库,且后一次调用单据中的invoiceEntryId是没有更新的,就导致发票分录被删除。比如在单据提交中,二开先调用了一次单据保存/提交入库处理业务,这时model中的invoiceEntryId没有更新,导致单据继续正常提交入库时,发票分录被删除
(2)在web端单据保存或提交成功后,正常是要刷新页面model的,这时invoiceEntryId是会刷新为最新值的。但因为一些二开业务,比如在保存或提交的success到单据页面刷新的过程中,处理了一些二开业务报错了,导致标准后续的刷新页面控件或model处理失效, invoiceEntryId没有刷新,用户再保存或提交就可能导致发票分录被删除。
如下图就是二开了fieldOnLoadEvent事件,且二开代码写的有问题,rowid大小写不对,导致保存单据后,执行到fieldOnLoadEvent刷新控件值时,这里报错了,导致model上invoiceEntryId刷不到页面上,单据再保存或提交时invoiceEntryId值不对,发票分录就会丢失
3.发票分录丢失修复
费用模块标准产品做了发票修复工具,可以修复丢失的发票分录,或单据和发票关系不一致的关系,需要更新补丁,各版本补丁如下:
8.8 PTM172091(2023-09-11)
8.6.1 PT169230(2022-12-09)
8.5 PT169870(2023-02-10)
修复工具使用如下:
在web端发票类型设置页面,按ctrl+Alt+Shift+I快捷键,打开发票修复工具页面,如下图
需要有【修正发票关系】权限才能使用
输入单据编码,点击查询,结果如下图,如果单据发票分录没有问题,【数据类型】字段会显示未发现问题。也支持批量查询和修复,批量查询时,将单据编码用逗号连接,如number1,number2
如以下这张单据,分录显示有发票1张,但看不到发票分录,这就是发票分录丢失了。查询该单据,则【数据类型】会显示发票分录丢失。选中该单据,点击【修复数据】,则会修复发票分录和发票云存储的单据与发票的关联关系。如果点击【修复发票关系】,则只会修复发票云存储的单据与发票的关联关系,如果发票关系不一致(查看发票时看到的发票,和单据上的发票不一致),可以用【修复发票关系】功能修复。
修复成功后
查看页面发票分录也正常了
4.解决发票分录丢失问题补丁
目前8.6.1及以上版本,将报销类单据分录实体(invoiceEntryId字段)和发票分录实体(bizEntryBill字段)建立的聚合关联关系(即单头和分录的关系)去掉了,这样发票分录不需要再依赖正确的invoiceEntryId,可以彻底解决发票分录丢失问题。优化补丁如下:
8.6.1费用补丁PT172335(2023-07-24),依赖补丁:PT172347(2023-07-07)(web框架)
8.8发版包就已优化,不需要额外更新补丁
需要注意的点:优化补丁对发票功能有一些特殊扩展的会有影响,需要调整扩展。目前发现的有:
(1)费用报销类单据分录和发票分录实体有元数据私包,实体还是旧的存在关联关系,会导致和补丁冲突,需要调整私包实体元数据。
(2)利用了报销单分录(invoiceEntryId字段)与发票分录(bizEntryBill字段)关联关系的。比如单据列表页的query里面,通过该关系字段,加入了发票分录字段的,或者二开代码中通过该关系字段,去查发票分录的,更新补丁后会报错,因为这个关系实际已经没有了,需要现场二开去调整。实际这个关系也没有作用了,因为目前分录和发票分录是多对多的关系,可以通过分录【分录相关联的发票流水号】字段(entrySerialNo),建立与发票分录关系。