瞎子摸象---销售开票(二)
接着瞎侃。
上一篇说了资金流,这一篇就扯一下信息流,在软件设计的时候信息流可能有很多想法,每个人对信息流的理解也不一样,所以也没有统一的标准。我这里所分成的信息流,现金流和物流仅仅是为了分析销售开票这个过程,人为地按照我自己的理解把代码分割了一下,便于整理,如此而已。
我这里提到的信息流是指在销售开票的过程中用哪些表和代码记录了与客户相关的信息。企业折腾的过程最终是为了赚钱,所以最后总会落脚到Money,也就是上文提到的那些财务凭证。在从物料转化成Money的过程中,需要记录一系列的信息,要不然将来客户说凭啥给你钱?当然这只是一方面了,还有很多情况,比如一个销售订单可能要多次发货和开票,需要记录每次开票的信息。
AX如何记录这些信息那?
客户开票信息
CustInvoiceJour和CustInvoiceTrans这两张表就是用来记录每次销售开票过账的信息的。AX用来写这两个表的代码也很简单明了,就是在用for循环处理每个销售订单行的时候,顺便通过writeJournalLine方法写CustInvoiceTrans,在处理完一整张销售订单后通过writeJournal方法写CustInvoiceJour,这段代码在SalesFormLetter_Invoice的updateNow方法里,具体每个字段写入的值可以参考相应的方法。
付款计划
在信息流里面还有个问题就是付款计划,关于付款计划的在财务教程I的第9章有详细的介绍,所以关于它的计算逻辑这里也就不再赘述了。AX用了CustPaymSched和CustPaymSchedLine这两张表来存储相关信息,当然还有两张表来存储付款计划的规则,就是PaymSched和PaymSchedLine。由于付款计划对于应收应付来说是通用的,所以对应采购的付款计划也有相应的表VendPaymSched和VendPaymSchedLine,这两套表的处理逻辑大部分都是相同的,所以AX用了Map,CustVendPaymentSched和CustVendPaymentSchedLine来处理,从这里的处理来看也就很能明白Map的实际作用了,就是为了把公用的代码放到一个地方,免得采购和销售各写一套。上面说的是数据层面,在逻辑处理方面,当然要搞几个类来处理一下计算的逻辑,AX弄了PaymSchedCalc及其子类,还有CustVendPaymSched及其子类来处理。
对于付款计划,我不太清楚国内用的是不是有很多应用,对于做项目一般会采用分期付款的方式,比如ERP项目的时候,一般分成几个阶段付款,在合同里都有约定,在word等非结构化文档里显然不适合查询和追踪,把这些条款翻译成AX里对应的付款计划,放到关系数据库表里,显然会方便查询和追款,这或许就是付款计划存在的现实意义吧。
这里只简单介绍一下AX在开销售发票的时候是在哪里处理付款计划的,其他的逻辑方面的东西就不展开讲了,感觉用的不是太多,这年头欠钱的都是老大,计划赶不上变化。
AX是在SalesFormLetter_Invoice的updateNow方法通过调用this.createPaymentSched();来创建付款计划的,当然在这个方法里,AX又会调用前面介绍的关于付款计划的类和表去做相应的处理,具体的处理逻辑先看财务I的第9章然后翻翻代码就OK了。
客户交易记录
万涓成水终究汇流成河,AX处理所有的业务到最终都落脚到一张表上,比如库存到最后是InventTrans,财务是LedgerTrans,客户就是CustTrans了。这种处理方式简介而直观,一如库存模块,不可能在让我库存关帐的时候,再去照顾所有业务对应的表,SalesLine,PurchLine,InventJournalLine之类,如果将来你再来几个新的模块,多开几个新的表,我库存关帐的逻辑都要改,那是要死人的,LedgerTrans和CustTrans也是这个道理。关于客户的交易都放在CustTrans里,在将来处理的时候就简单了,所以最后要介绍的内容就是关于CustTrans的了。上一篇文章中我们介绍了说AX在应收应付模块吧LedgerVoucher封装了一把,变成了CustVendVoucher及其子类,一方面简化了对LedgerVoucher的操作,更重要的是在应收应付模块要处理更多的事情。其中一件很重要的就是要生成客户交易记录。我们通过浏览代码的方式来介绍一下在这部分AX到底做了些什么。
SalesFormLetter_invoice-》updateNow->postJournal
这个方法里的其他方法都很简洁,我们很容易就可以看出它做了什么,我们需要了解的是其中的createCustTrans方法做了什么,顾名思义,这个方法就是创建客户交易记录的。主要的内容在类CustVendVoucher的post方法中:
1.向LedgerVoucher对象中添加交易
客户应收账款额对应的记录,要在这里添加到这个对象中,要不然就瘸了。
2.创建CustTrans记录
创建CustTrans记录,这些信息大部分来自于CustInvoiceJour。
3.创建CustTransOpen记录
之所以需要这个表是因为应收账款和收款以及预付款之间需要核销(Settle),也就是弄明白哪几笔收款付了哪几笔应付款。创建这个表的好处是,可能核销很多次,一笔记录可能要被拆成几笔,如果放在CustTrans里面,CustTrans最后就面目全非了,为了尽可能地保留CustTrans的原貌,未结的交易都放在CustTransOpen这里面,折腾就折腾这个表了。如果用来付款计划,对一笔CustTrans会根据付款计划插入多条记录进CustTransOpen。
4.处理收款和核销
如果采用的付款期限是货到付款(C.O.D)采用现金结算,并指定了现金科目,那么AX在开票的时候就直接生成收款凭证,并且在应收和已收款之间做核销。收款的凭证很简单,就是 贷:应收账款 借:在付款期限处设定的现金科目。至于核销就是另一段故事了,里面牵扯的内容也相对复杂,比如汇兑损益,比如不同过账模板,关闭模板,林林总总,不一而足,在后面专门介绍汇兑损益的时候再把收款和汇兑损益以及核销的逻辑介绍一下。
OK,信息流就说这么多了,物流在介绍库存代码的时候介绍过,实际上销售开票的过程也就是在调用那一段逻辑而已,没什么新鲜的内容,也就不再赘述了。
销售开票就到这里吧。