Farseer

导航

生产过程代码分析(一)--概述

在AX中生产订单要经过几个步骤才能结束,其过程如下图所示:


本系列文章分析AX是如何实现这六个步骤的,介绍它的数据存储结构,还原其静态结构图和序列图。由于笔者水平有限,错误在所难免,还望多多指教。
准备知识
我们知道在生产模块物料清单和工艺路线是必须的基础数据,所以在介绍正式的生产前,需要了解这两个基础数据是如何存储的。
BOM的存储结构如下图所示:


BOMTable存储的是BOM的定义,BOM存储的是BOM清单行,这两者的关系类似于SalesTable和SalesLine,BOMVersion存储的是BOMTable和物料的映射关系。
工艺路线的存储结构与BOM是一样的,RouteTable存储的是工艺路线的定义,Route存储的是工艺路线的明细,RouteVersion存储的是RouteTable和物料的映射关系。
上面提到的BOM和工艺路线都是基础数据,实际上每一张生产订单都会有自己的生产BOM和生产工艺路线,在系统中创建生产订单的时候,会把在基础数据中定义的BOM和工艺路线数据拷贝到生产工单对应的表中,其中BOM数据会拷贝到ProdBOM表,工艺路线会拷贝到ProdRoute表。这个动作发生在创建生产订单记录的时候。
大体过程如下面的序列图所示:


第一次用UML画这东西,有很多符号拿不准,还望多多指教。
OK, 到这里生产工单六步曲的准备工作已经做好了。
概览
这一部分先把这六个步骤所用到的表结构以及类的静态结构图给一个大体的描述。
AX的生产沿袭了AX的整体风格,我喜欢称之为Parm方式,无论是销售还是采购,都采用了Parm的处理方式,每次在做一个动作的时候都用Parm表存储每次更新的信息,并用Parm窗体展现数据,用Parm类处理逻辑,这样的风格一脉相承,从整体上看比较统一,理解了一个也就理解了其余的几个。当然销售和采购更加类似,与生产有一点差异,销售采购所有的动作都用一张表记录更新信息,用一个字段标志当前更新具体是哪个动作,而生产模块每个动作都用单独的一张表去存储。
先来看看数据存储层面的东西。
生产订单是生产模块的主数据,每个功能都要用到这个表,这个毋庸多言。由于在逻辑处理层面用到了继承,那么在数据层面应该也抽象出一些基类,我们知道AX的表是不支持继承的,这样处理多个类继承的时候,一定会用到Map,在本文中要用到的Map是ParmBuffer,其"派生类"包括ProdParmBOMCalc,ProdParmCostEstimation,ProdParmHistoricalCost,ProdParmRelease,ProdParmReportFinished,ProdParmScheduling,ProdParmSplit,
ProdParmStartUp,ProdParmStatusDecrease,如下图所示:

由于反向过程出来的Map和表之间没有创建继承关系,这里也就不再添加了,不过在行为上确实类似于继承关系。这里只列出了生产的六个步骤中用到的六个表,还有几个表与这次讨论的内容没有关系,没有列出。
在看了表结构以后,我们需要了解一下这六个步骤都涉及到了哪些类。
下表列出的是六个生产步骤完成更新动作用到的核心类的静态结构图

第一次玩这东西,对UML不了解,不知道实现接口在UML中应该怎么表示,这里拖了个泛化来表示,如果有错的话,还望多多指教。这个反向工程的图把操作略去了,只保留了属性。如果想了解方法列表可以反向工程出来看一下。
通过上面图可以看出,这些类的关系很简单,每个生产步骤对应一个具体的子类实现,这些子类都继承自ProdUdp这个抽象类,而ProdUpd这个抽象类又继承自实现了RunbaseRecsMapable接口的UpdateBase类。
这些类是通过ProdTableType来调用的,下面只列出ProdTableType的静态结构图,具体的调用序列图在后面介绍具体功能时再说明。

上面的这个类关系也比较简单,只是不太明白为什么这里要扩展出Standard和Vendor两个子类,从业务上很容易理解,对于供应商类型的生产订单要用Vendor这个子类,但看代码就会知道,这两个子类没有任何属性和方法,只有一个类定义而已,为啥不用包含去实现而要用继承那?或许以后会找到答案。
生产通过ProTableType去调用ProdUpd相应子类取实现更新。
我们还需要继续往前走,因为到这里还没到达最初的调用的地方。
接下来就是ProdStatusType及其子类了。

OK,走到这里总算快看到头了,是的,我们一直提到的跟表对应的包含Parm的类终于要出现了。


上面类的静态结构图看上去蛮复杂的,其实一直到ProdMulti都是抽象类,真正实现功能时是通过调用其子类来实现的。
上面的这些子类继承自Runbase,很容易想到,这些类一定会启动一个窗体,而启动窗体的名称通过fromName方法返回,这样我们很容易就可以得到完成上面六个动作跟用户发生交互的窗体名称
ProdParmCostEstimation

ProdParmOperationScheduling
ProdParmJobScheduling

ProdParmRelease
ProdParmStartUp
ProdParmReportFinished
ProdParmHistoricalCost
至此我们可以得到实现生产过程的六个步骤的方法调用的时序图:


当然上面的序列图只是个示意图,其中prodMulti和ProdStatusType是抽象类不能实例化,具体到某个生产过程,这些任务由各自的子类去完成,方法名也不是run,而是run+任务名称,比如runCostEstimation等。
这篇文章主要从面上介绍了生产过程涉及到的类和表结构,从下一篇文章开始,笔者根据生产过程的顺序,介绍各个步骤的代码实现情况。

posted on 2007-06-05 17:37  佛西亚  阅读(1116)  评论(3编辑  收藏  举报