最近在项目上遇到一个案例。是关于换班转课后再次修改的操作,导致财务账对不上,仔细分析了该案例,觉得是一个比较典型的需要 业务人员+需求分析师+架构设计师+测试人员 四方一起协作才能解决的例子。
目录
1. bug基本背景
1.1 bug描述
客户反馈,系统的转入转出表,数据对不上,经检查,发现是因为老师在操作了换班转课之后,再修改了转课后的合同,而导致的问题。
1.2 测试初步排查发现
在检查过程中,发现一个学生,在某个时间(举例2020-05-30日),只有转入记录,却没有转出记录,经扩大时间查找后,发现历史的转出记录在半年前,这样就造成了,财务在看当月转入转出的时候,数据是对不平的,既然数据对不平,那财务就认为报表有问题。
那为什么转出记录在半年前,而转入记录在半年后呢?原因是这个学生转入的课程合同,总金额大于转出,所以一直没关闭,直到半年后学管师才修改这个合同,调整了产品,并关闭。
1.3 初步分析结论
经过与技术讨论,发现当转出合同数据被变更的时候,程序会主动根据原合同去变更转入转出表中的信息,这样可以保证对于单个学生的数据闭环,从转入转出表中,体现出合同产品的变化。而正是因为这个变更,导致了日期的错开,从单个日期上看不能形成闭环。(细节看问题详细分析)
2. 问题详细分析
2.1 模型建立
为了在分析中数据明确,将各个数据点简化成字母+数字标记。
学生:S1
首次报读时间:T1,首次报读合同:C1,首次报读2个产品:P1,P2
首次换班转课时间:T2,将P1转到产品:P3,P4 (P2不转,简化模型)
后续修改合同时间:T3,将产品P3,改成产品P3,P5
前提假设:合同报读时已完款,换班转课时无欠款(实际案例是换班转课时有欠款,导致合同可以修改,另外又更改了优惠金额,导致前面已经分配了的产品实收金额又重新计算,比较复杂,但这里不影响后续问题分析,简化模型中忽略)
2.2 步骤设计
如果要分析问题到底出在哪里,需要还原步骤,以便找出那些地方需要细看
- S1在T1报读合同C1,包含两个产品P1,P2。这个时候正常生成合同记录及产品记录,没有问题
- S1在T1对合同完款,没有问题
- S1在T2时换班转课,操作:将C1.P1, P2 转到C2.P3, P4,转入转出没有问题
- S1在T3时修改合同,操作:将P3调整,改成P3,P5.(P4没动) 这里出了问题
2.3 详细步骤+数据拆解
第一步:S1在T1报读合同C1,包含两个产品P1,P2。
第二步:在T1完款
此时数据表如下
产品表
产品 | 所属合同 | 报读时间 | 总收费 | 剩余资金 |
---|---|---|---|---|
P1 | C1 | T1 | 10000 | 10000 |
P2 | C1 | T1 | 5000 | 5000 |
第三步:在T2时间,假设P1使用了5000元,剩余5000元的时候,使用换班转课,将P1的5000元转到P3(3000),P4(2000)中,数据表如下:
产品表 – 变更前
产品 | 所属合同 | 报读时间 | 总收费 | 剩余资金 |
---|---|---|---|---|
P1 | C1 | T1 | 10000 | 5000 |
P2 | C1 | T1 | 5000 | 不影响 |
产品表 – 变更后
产品 | 所属合同 | 报读时间 | 总收费 | 剩余资金 |
---|---|---|---|---|
P1 | C1 | T1 | 10000 | 0 |
P2 | C1 | T1 | 5000 | 不影响 |
P3 | C2 | T2 | 3000 | 3000 |
P4 | C2 | T2 | 2000 | 2000 |
转入转出表 - 变更后
转费编号 | 转费类型 | 学生 | 转费日期 | 所属合同 | 产品 | 金额 |
---|---|---|---|---|---|---|
3302 | 转出 | S1 | T2 | C1 | P1 | -5000 |
3302 | 转入 | S1 | T2 | C2 | P3 | 3000 |
3302 | 转入 | S1 | T2 | C2 | P4 | 2000 |
第三步做完,在T2时间的总转出 = 总转入,无论是从学生S1看,还是从时间T2看,都是闭环的。5000 = 3000+2000
第四步:在T3时间,老师调整P3(3000元),改成P3(1900元),P5(1100元)
产品表 – 变更后
产品 | 所属合同 | 报读时间 | 总收费 | 剩余资金 |
---|---|---|---|---|
P1 | C1 | T1 | 10000 | 0 |
P2 | C1 | T1 | 5000 | 不影响 |
P3 | C2 | T2 | 1900 | 1900 |
P4 | C2 | T2 | 2000 | 2000 |
P5 | C2 | T3 | 1100 | 1100 |
转入转出表 - 变更后
转费编号 | 转费日期 | 转费类型 | 所属合同 | 产品 | 金额 |
---|---|---|---|---|---|
3302 | 转出 | T2 | C1 | P1 | -5000 |
3302 | 转入 | T2 | C2 | P3 | 1900 |
3302 | 转入 | T2 | C2 | P4 | 2000 |
3302 | 转入 | T3 | C2 | P5 | 1100 |
根据变更后的数据表发现,对于单个学生来说,转入=转出,单个学生闭环是没问题的。
但从日期上来看,因为T3和T2相差半年(如果是在一个月内,问题也不大),T3时间的账务是对不平的,这个是最主要的问题。其实改动之后,连T2的账务都对不平了
2.4 业务结果分析
在财务上,原本要求是每天的转入转出成为闭环(转出-转入=0),但因上述改动,T2的转出-转入=1100。而T3的转出-转入=0-1100。当机构的数据量大的时候,很多的此类例子叠加,就造成了每个月都不等,从而使转入转出核对报表失去应有的作用,如果财务需要核对每一区别,那这个系统就变得没有意义了。但要解决这个问题,并不是技术部门可以解决的,需要业务部门对现状有所了解,并一同探讨解决方案。
3. 思考及解决方案
3.1 业务诉求场景分析-财务
首先考虑财务的业务诉求的逻辑合理性。财务希望转入=转出,达到资金闭环,这个很合理,是财务的正常诉求。转入=转出可以从2个方面来进行验证:
- 单个学生的转出=转入
- 某个时间段的转出=转入
首先单个学生的转出=转入,这个是最基本的数据逻辑,如果单个学生都不相等,那整体就一定不相等了。在本案例中,是能做到单个学生转出=转入的。但因为后续转入合同有变更,虽然做到了单个学生闭环,但在时间上就跨了很长时间了。
其次是某个时间段的转出=转入,这个在财务上一般都是用财月或财年,对应的有月度封账及年度封账的做法,而本案例中,T2到T3跨了半年,自然在报表上无法对准。而财务一般是对总账,再到明细账,让财务对单个学生做报表核对,不大合理。
所以对于财务来说,首先是按月的总账核对,再到明细,在报表呈现上,需要以月度为单位形成闭环。本案例在月度闭环上未能满足要求
3.2 业务诉求场景分析-学管师
换班转课为必要业务,这里不再讨论。需要关注的,是换班转课之后,是否有必要再次进行修改。经与客户沟通有以下情况,是确实需要更改的:
- 转班之后,新的产品价格高于原产品,需要补交费用
- 转班之后,家长又不想转了,想留在原来产品
- 老师操作错误,转错了,需要修改
本案例在操作上能满足业务需求
3.3 系统实现方案分析
系统实现的逻辑,也可以分为2个部分。
第一部分:首次换班转课形成的转出转入记录,这一部分的逻辑没有问题,不再做探讨。
第二部分:对于转入的合同,进行3.2所描述的业务操作的应对。
目前逻辑是:
- 如果有产品被删除了,那就从转入转出表中删除这个产品
- 如果有产品的金额被改变了,那就从转入转出表中找到这个产品,改变金额,不改变日期
- 如果有产品新增了,那就在转入转出表中增加这个产品,日期=今天。
- 如果合同优惠被更改了,在转入转出表中,所有产品的实收金额都要被改变,但不改变日期
客户也确认逻辑正确,因为确实转入合同需要能更改。
那么在目前的方案下,需要考虑几点:
- 金额确实有必要被更改,因为允许修改优惠和产品价格
- 原有产品日期是否有必要更改?如果不更改日期,就有本文中的T3对不上的情况
- 如果更改日期,那就丢失了原来操作的真实时间。
3.4 新方案思考
既然原方案中针对被更改的产品进行更改,从而导致日期无论改不改都很矛盾的情况,是否可以探讨以下方案?
3.4.1 财务接受按月不闭环,但单个学生闭环的方案
该方案不需要任何系统改动,仅需要财务接受实际情况即可。
3.4.2 将改动日期统一,或者调到之前的日期,或者调到之后的日期
该方案改动比较简单,只要拿到转费编号,将日期统一即可,但这样不能反应真实的改变时间
3.4.3 禁止对转入合同进行改变(仍能收款),并增加“撤回”功能
该方案改动较大,撤回需要对整个路径进行反推,并重新计算回抽的资金,且在首次转课到撤回之间时间间隔会很长,学生账务可能出现比较大的变更,撤回可能会引起更大的资金问题。特别是,如果改动是删除产品,因为系统做的是物理删除,目前是无法支撑回撤的,如果要改成逻辑删除,那对整体系统的变更要求就非常大了。
3.4.4 禁止对转入合同进行改变(仍能收款),如需变更,再走一次新的换班转课
该方案对财务及技术最有利,能保证不影响到之前已经确定的换班转课数据,但学管老师需要多操作一次换班转课。经与财务,业务老师,甲方产品沟通之后,采取了此方案。这个方案能保证已经确定的操作不会再被更改,并且会提醒业务老师在进行换班转课时慎重考虑,不要把这个当做是一件随意的事情。
4. 案例总结
本案例中,可以看到,从单个操作来说,似乎都对,但从整体来看,似乎哪里不对。咋一看上去,好像怎么改都不太对。这对大型复杂逻辑系统来说,其实是比较常见的事情。
在本案例中,如果缺少了财务老师,业务老师,需求分析师,架构设计师及测试的参与,是很难达到一个相对平衡的解决方案的,为什么说相对平衡而不是完美的解决方案,是因为当系统功能只需要满足一个部门时,可能可以达到完美,但牵扯多个部门,很少有完美的解决方案。就好比用拼音输入法你得记住读音,用手写输入法你得记住字是怎么写的。新的方案中,各种方案,要么系统改变很大,要么某一方业务妥协。
当前方案,之前也是经过讨论得出,已经考虑了各种改动下对数据的影响,但仍然有考虑不周的地方,这更突显了在大型ERP系统中对业务及财务逻辑分析的重要性,及一线人员对逻辑的详尽描述及理解。本案例中,如果以下事情能提前沟通,可能不至于在比较晚期才发现问题:
- 学管老师描述各种操作的可能性,比如本案例中过了半年才操作,并且会改动优惠来关闭合同
- 财务老师需要描述对日期闭环的要求,会如何使用报表数据。
- 需求分析对各种情况的详细列举
- 架构设计在设计数据结构,及代码路径时主动考虑合理性。本案例的原方案,当用户删除产品时会重新计算整个转入转出闭环,当用户改动优惠时会重新计算资金分配,这些都是主动工作量的,在设计时,可对要求的合理性提出疑问,令到需求分析重新梳理详细案例。
- 测试人员除了对正常流程进行测试之外,需要主动考虑例外情况,以提前知晓哪些路径当前方案没有覆盖到。