zoukankan      html  css  js  c++  java
  • 瞎子摸象汇兑损益

    所谓的汇兑损益,就是由汇率变化引起的损失或者收益。如果公司没有外币业务,就不必关心这个功能了。关于国内会计对汇兑损益的处理规定在CPA2008教程的第12章外币业务有详细的论述,看等有时间把相关内容抄到这篇文章中来。
    我们先来看一下AX中是怎么来处理汇兑损益的,由于本人财务知识有限,错误在所难免,还望高人指点。
    概述
    在AX财务教程II的第三章MutilCurrency有关于汇兑损益操作的介绍,这里就不详细介绍了,只是简单过一下,还是将重点放到代码的分析上。
    在AX中汇兑损益的调整分成两种:
    1.总账模块的调整
    2.应收应付模块的调整
    总账模块的汇兑损益调整逻辑极其简单,只用了一个继承自RunbaseBatch的类LedgerExchAdj,几个方法搞定。它的思路也很简单,找到用户指定时间范围(从组里的时间和到组里的时间)的LedgerTrans记录,用一个类KeySum把这些记录按照科目和维度分组汇总外币金额和主货币金额(也就是MST),用到组里的时间的汇率*外币金额得到新的主货币金额,如果有差异就生成一笔调整分录,简单吧?嗯。
    这样不就OK了吗?干吗费劲折腾要在应收应付模块里弄一把,用刑捕头的话说,这真让人费解啊,confused......我能想到的理由:
    1.应收应付模块可能是最多涉及到外币业务的模块;
    2.应收应付模块还牵扯到应收应付款和已收已付款的冲销;
    3.应收应付模块需要在客户交易记录表中记录每次汇率调整的记录。
    应收模块的汇兑损益逻辑
    应收和应付模块汇兑损益的逻辑类似,这里只介绍应收模块,应付double一下就可以了。
    我想AX对汇兑损益的处理与国内有所不同的地方就是在应收应付处理的时候分为了已实现损益和未实现损益两个来处理。其实AX的观点处理方式很明确也很直接,应收和已收冲销的时候产生的汇兑损益是已实现损益,未冲销前的汇率调整产生的损益是未实现损益。
    客户交易可以分为两类应收和已收,对于应收和已收又分为已结和未结,所谓的已结和未结也就是应收和收款之间有没有做过冲销(Settle),我们知道应收的会计分录是:
    借:应收账款
    贷:主营业务收入
    收款的是
    借:现金(银行存款)之类
    贷:应收账款
    实际上收款是将应收账款从贷方转走,在完全冲销后借贷相等,应收账款为零(当然这是理想状况)。这里就有个问题,收款对应哪些笔应收款的问题,反之亦然,所以要有个settle的功能。AX在settle的时候会进行汇兑损益的处理,它的逻辑是借贷反向冲回前面已经做的未实现损益,然后用收款交易的汇率和应收款交易汇率之间的差额产生已实现损益。
    简单介绍一下AX应收和收款之间Settle的表和类结构.在表方面,有三张表CustTrans,CustSettlement和CustTransOpen.从表的名字上可以看出,AX在设计的时候是把记录分成已结和未结的,已结的放在CustSettlement,未结的放在CustTransOpen,已结和未结的都在CustTrans,记录起初在CustTransOpen,随着核销的进行慢慢转移到了CustSettlement里.这种设计很直观。
    至于类结构,也很直观,CustVendSettle,CustVendSettle_Cust,最主要的逻辑在CustVendSettle的SettleNow方法中进行,这个方法有将近1000行之多。。。顺着看一遍这个方法,它所处理的逻辑也相对简单,主要的逻辑是将客户的借方交易记录(应收)和贷方交易记录(收款)进行冲销,还有就是处理现金折扣,特殊增值税,收款和应收过账模板不同时的处理以及如果记录完全Settle,并且对应的过账模板指定了关闭模板的科目转移,当然还有本文所关注的重点---汇兑损益的处理逻辑,把代码摘录如下:

    Code

    可以很简单地看到AX在Settle的时候对汇兑损益的处理逻辑。前两个if,分别反向冲回未实现汇兑损益,后面一个if过账已实现汇兑损益。
    OK,已实现汇兑损益就这么多了,那么未实现汇兑损益是怎么弄的那?
    实在 应收模块的汇率调整在 应收账款->期间->汇兑损益调整 窗体中进行,我们首先介绍一下处理未实现汇兑损益涉及到的类。
    首先是继承自RunbaseBatch的类,CustVendExchAdj及其子类CustExchAdj,我们知道继承自RunbaseBatch的类一般就是提供给用户一个输入信息的界面,如果处理逻辑比较复杂,一般会再写一些类用来处理具体的业务逻辑,放在上述类的run方法里调用,汇率调整这里也不能免俗,它用了CustVendExchAdjTrans及其子类CustExchAdjTrans来处理汇率的调整。主要的逻辑代码在CustVendExchAdjTrans的update方法里,这个方法的逻辑分成两部分处理已结交易和未结交易,分别通过exchAdjustSettlement和exchAdjustTrans进行。exchAdjustTrans的处理很直观,把之前的未实现的汇兑损益冲回,在生成新的未实现汇兑损益。对于调整已结交易,AX的方法exchAdjustSettlement处理方式有些让人费解,可能我还没有理解汇兑损益的真谛的缘故,也许有一天对这块业务大彻大悟了就能明白它的处理方式了,我发现看AX代码确实有这么一个过程,代码的理解是随着对业务的理解而逐渐加深的,如果不了解业务,能看到的只是读写表的过程,随着对业务的理解,代码也就有了生命.当对业务大彻大悟的时候,代码也就被复原成生龙活虎的人了。现在我只能把AX的处理逻辑复述一遍,至于为什么这么做还需要继续修炼...
    1.调整数据的范围

    Code

    我们从类CustVendExchAdj的update方法的上述代码中可以看到,AX要处理的交易记录是在 考虑日期 之后(包含考虑日期)有过核销记录,并且交易日期在考虑日期之前的。这可真有点绕的。。。
    2.调整的逻辑
    在CustVendExchAdj的exchAdjustSettlement方法。我感觉它的逻辑应该是分成两类 之前有过未实现汇兑损益调整记录的和没有调整过的。
    我的想法是:既然是已经核销过的记录,已经产生了已实现汇兑损益,理论上不应该再进行未实现的汇兑损益调整了,因为已经结转到现金和银行类科目了,再调整就没完没了了.那AX干吗还要这么折腾?I have no idea...
    我猜想应该是AX想补回一些未结的汇兑损益记录,举个例子:

    发票 2008年8月1日
    应收账款:100 USD                      汇率:720            

           2008年9月1日                      汇率:700

    收款 2008年10月4日                    汇率:690
    应收账款:                  100USD
    第一种情况:在核销时没有进行未结的汇兑损益调整,那么在核销时产生的已结汇兑损益调整凭证应该是:
    借:已实现汇兑损失   30
    贷:应收账款           30
    损失了30大洋。如果这个时候再运行期间里的汇兑损益调整,考虑日期选择2008年9月8日,AX会怎么处理那?
    很明显根据 调整数据的范围 里的介绍,2008年8月1日的发票对应的记录在调整之列,AX会生成啥凭证那?
    2008-10-4
    借:未实现汇兑收益  20
    贷:应收账款                  20
    2008-09-08
    借:应收账款          20
    贷:未实现汇兑损失          20
    从表面的意思看,它是补了一对借贷相反的未实现汇兑损益凭证,当然各个科目的金额都没什么变化,因为本来也不应该调整,只是给相应的科目增加了两笔记录。
    第二种情况是在核销时已经进行了未结的汇兑损益调整,然后在核销后用核销日期前的某个日期做为考虑日期再进行一次期间的汇兑损益,这个过程会产生N多凭证,不过正过来反过去,到最后只是多了一些交易,但都借贷相反冲掉了,科目的余额还是按照核销时产生的已实现汇兑损益计算。

  • 相关阅读:
    ASP.NET结合COM组件发送Email
    木马生成技术
    AJAX中使用Session
    对象模型文档对象模型DOM简介
    何遍历数据源中的表名称
    AJAX.NET用户开发指南
    用ASP.NET上传大文件
    .net反编译利器
    Equals和GetHashcode
    Factory Method模式
  • 原文地址:https://www.cnblogs.com/Farseer1215/p/1364613.html
Copyright © 2011-2022 走看看