【项目实施随笔】生产领料

好久没涂鸦了,最近一段时间一个人做项目,有些忙乱。
写一篇关于生产领料的帖子,这篇帖子只是描述了我实施这个项目的做法,只适合这个项目的实际情况,没有普遍意义,每个项目都有自己的需求,抛砖引玉,希望得到大家的指点,得到最佳实践。
公司的规模比较小,按单生产,每个产品的生产周期都比较长,一般在三四个月左右,只使用了最基本的生产功能,做领料的管理,没有使用主计划模块,工序相对简单,都是手工作业,工时定额也不好算出,成本方面人工费占得比重很小,所以暂时也没有使用工艺路线做管理,生产模块使用的也就是领料了。
公司的物料领用一共有如下三种情况:
1.正冲(Forward Flushing)倒冲(Backward Flushing)
有一些物料的单件价值不大,不需要每次领料都让库房管理员去登记,财务要求在生产工单开工或者完工的时候就把这部分物料的领用在财务上体现。
2.正常领用
这部分物料是需要正常领用的,生产工人根据生产情况需要去库房领用,库房管理员发货并登记在系统。
3.采购入库的时候领用
有一部分物料是根据生产订单采购的,这部分物料在采购入库后就直接到了放到生产车间,由于这部分物料是针对特z项目的,在库房里特定的区域,工人根据需要去拿就行了,库房管理员不希望每次工人去领用都到他那边登记,太过麻烦,希望系统在采购入库的时候自动产生领料单并过账,他就不必为这部分物料忙活了。
第1和第2种情况,AX的现有功能都可以应对,第三种情况可以用供应商类型的BOM行来实现,但是需做一些修改。下面以一个虚拟的实例描述一下这个项目的做法:
设置产成品,物料号为000001,该物料有几个子物料组成,这里只举四个物料为例,分别代表上面的几种情况:
000001_001            正冲
000001_002            倒冲
000001_003            正常领用
000001_004            采购入库时领用
1.基础设置
关于正冲和倒冲,AX在物料,物料清单行以及生产BOM行处各有一个选项设置,实际上这三个选项都是都是依次覆盖的,也就是生产BOM行的设置会覆盖物料清单行的设置,物料清单行的设置会覆盖物料的设置。另外在生产订单做开始和完工入库动作的时候还有个选项做控制。下面一一介绍这些参数:
物料上的选项:
库存管理->物料->参考(选项卡)->刷新原则

刷新原则有三个选项:
开始:在生产订单做开始动作的时候对该物料生成领料单;
完成:在生产订单做完成动作的时候对该物料生成领料单;
手动:系统不会生成领料单,需要手动生成创建领料单并添加行。
这三个选项的选择取决于这个物料在大多数情况下通过何种方式领料,比如在大多数情况下这个物料在用于生产的时候都是在生产订单做开工动作的时候领料的,那么这个选项就选 开始,依次类推。我们的物料分别按照如下设置:
000001_001:开始
000001_002:完成
000001_003:手动
000001_004:手动
物料清单行的选项:
库存管理->物料->物料清单(按钮)->物料清单行->行->设置(选项卡)

这里面比物料的定义多了一个空选项,空选项的意思是继承物料的定义,如果想覆盖物料的定义就选择开始,完成和手动的一个,如果某个物料在大多数情况下是 正冲的,但是用于某个产成品的时候 是 倒冲的,那就在这里选择 完成。我这个项目都是跟物料的定义一样的,所以保留它的空白选项就可以了。
当然在生产BOM上也有个类似的选项定义,跟BOM行的效果类似,这里就不赘述了.
物料清单行类型的定义:
库存管理->物料->物料清单(按钮)->物料清单行->行->常规(选项卡)

行类型一共有四种:
1.物料,这个就是普通的类型,地球人都知道;
2.虚拟,就是虚项,英文叫做Phantom,这个项目也用了这个功能,为了不至于这篇文章太过臭婆娘的裹脚,这里就不做赘述了,后面会写一篇文章专门介绍一下这个选项,AX的Phantom跟APICS的定义有些区别。
3.生产,就是会对这个物料清单行的物料产生一个生产订单;
4.供应商,外协,根据物料清单行物料的物料类型,产生外协采购单或者外协生产订单。
这个项目只用到了第1和第4个选项,设定如下:
000001_001:物料
000001_002:物料
000001_003:物料
000001_004:供应商
2.创建生产订单
这样基础设定就搞定了,接下来就是创建生产订单了,创建生产订单的过程很简单,由于在财务核算的时候,财务要求生产订单和销售订单做关联,所以我在生产订单上加了个销售订单号字段,用户在创建生产订单时需要填写,另外对于物料清单行类型是供应商的物料,由于是专门给这个生产订单采购的,所以财务要求把这些物料的成本归集到这个项目上,而不是按照所有物料先进先出,因为对于同一个物料在不同时期采购时价格有差异,所以我对000001_004这个物料使用了批处理号管理,并选中批处理号的物理库存和财务库存维度,这样就可以按照生产订单归集了。这样剩下的问题是,如何让系统在产生生产订单和采购订单的时候自动把批处理号给创建了,因为让用户手动创建这些东西确实是太残忍了,我能这么熟练地操作AX都不想用,更何况一个第一眼面对AX的人那?己所不欲勿施于人,所以还是让程序自动化一些,自己创建吧。ERP这玩意在更大的程度上是增加了一线员工的工作量,本来别人就有抵触情绪,所以能让别人方便点就方便点。
在创建生产订单的时候,AX会根据基础BOM生成生产BOM,也就是根据表BOM生成ProdBOM表的记录,原来就不在这里介绍了,只说一下如何修改吧:
找到类ProdBOMType的insert方法,添加几行代码,让其自动生成包含InventBatchId和InventLocationId的InventDim:

Code

其中ProdTable的SalesContractNo是我添加的销售合同单号,作为批号。仓库和库位这样写不符合最佳实践,最好找个地方来设定这些东西,然后读取,以后重构的时候再说了。
这样修改之后,并非万事大吉了,还需要修改一个地方,因为AX系统不会帮你在InventBatch表里添加相应的批号,它如果找不到它就报错了,所以需要修改一下它的代码,如果在InventBatch找不到相应的记录就让它自动生成而不是报错:
找到表InventDim的checkDimSearchFieldId方法,修改其中关于InventBatch的一段代码:

Code

在InventBatch里添加一个静态的create方法:

Code

修改后的效果如下,创建生产订单:


创建完成后,查看生产BOM的000001_004的维度,如下图所示:

3.做生产订单的估计

对生产订单做  估计 动作。生产订单的估计动作会做很多事情,一方面是估算物料的用量,估算工时,从而根据根据设定的计算组计算生产订单的成本,还有个比较重要的任务是,如果物料清单行的类型是 供应商和生产类型,在估计的时候,系统会生成相应的采购和生产订单。于是这一步对000001_004这个物料就至关重要了,它要生成与生产订单关联的采购订单。
在生成采购订单的时候,AX4.0有个bug(我个人认为是个bug,如果有人非要说是系统就是这么设计的,我也没办法了),根据生产订单BOM行生成采购订单的时候,在库存维度上指定的值不会带到采购订单行,甚至原来在生产订单BOM行上指定的库存维度也会被清除,我觉得这不可接受,自己动手丰衣足食,改之。找到表PurchLine的initFromProdBOM方法,修改如下:

Code

修改后就可以把库存维度带到采购订单行了,如下图所示:
与物料清单行关联的采购订单:

采购订单行的库存维度

4.对生产订单做开始动作
在做开始动作的时候,正冲的物料000001_001就可以自动生成领料单并过账了,当然前提是要在生产BOM上指定正确的库存维度,并且有足够的物料可以出库。

自动物料清单消耗量 字段有三个选项:
刷新原则:根据在物料,物料清单行和生产订单BOM行的刷新原则指定的规则生成领料单日志。对于物料000001_001,我们刷新原则指定的是开始,所以在做开始动作的时候就会为该物料产生领料记录,而被指定为手动或者结束的,则不会在做开始动作的时候产生领料记录。
始终:不管物料,物料清单行和生产订单BOM行的上指定的刷新原则,始终自动为该物料产生领料记录。
从不:不管物料,物料清单行和生产订单BOM行的上指定的刷新原则,始终不自动为该物料产生领料记录。
很明显,我们要选择刷新原则,这样就只会为物料000001_001产生领料记录。
选中  立即将领料单过账,这样就自动为000001_001产生的领料单日志过账了。

查看领料单日志记录就可以确认,只为物料000001_001产生了领料日志并过账,其他三个物料并没有产生领料记录。
倒冲的物料000001_002跟正冲大体类似,只是在完工入库的时候产生领料单并过账,这里就不在赘述了。
至于正常领料的就相对简单了,创建一个领料单日志,手动创建行,从批次ID中选择相应的物料行,如果在下拉窗体想过滤掉正冲,倒冲以及采购入库时自动领料的物料,可以修改窗体ProdJournalBOMLookUp的数据源ProdBOM的executeQuery方法添加过滤条件。
5.采购开票的时候自动产生领料单并过账
这一部分,AX的处理方式很不符合我这个项目的要求,所以就需要动动小手术了。
AX支持物料的外协,前面也看到了,它帮我生成了才订单,并做了Mark,问题出在采购开票时帮我自动产生领料单并做帐的问题上。首先,AX设定了一个参数,来控制是否自动产生领料单并过账,路径为:生产订单->设置->参数设置->自动更新(选项卡)

这个参数选择 始终就可以了。
有这个参数控制不错,但是AX还有几个关口:
a.物料清单行的物料必须是服务类型的;
这个在我这个项目是不可接受的,虽然AX建议外协采购的物料是服务类型的,但是我们公司的这些物料还是有库存的,所以不太适合。怎么办?改之。
b.物料清单行的工序必须不为空
由于暂时没有采用工艺路线管理,所以这个也不是适合,改之。
c.生成领料的领料单包含物料的逻辑
我需要的是当前收货哪个物料就过账哪个物料,但是AX的逻辑是根据工序来选择,只要与当前过账的采购单物料的开始工序和结束工序相同的就全部过账。所以在AX的现行逻辑下,如果要正常运行,必须做到 每个外协的物料都必须单独用一个工序,哪怕是从同一个供应商采购的不同物料,也要分别用不同的工序来表示,否则就会出现重复产生领料单的情况。
综上所述,要想AX能满足我现在的想法,必须要做一些改动,改动步骤如下:
在类PurchFormLetter_PackingSlip和类PurchFormLetter_Invoice中都有方法updateProduction,这两个地方的代码是完全一样的,之所以这两个地方都写,是因为收货动作和开票同时进行,如果没有做装箱单动作,在开票动作的时候要完成装箱单同样的动作才行。这个方法的代码如下:

Code

这个方法的内容很可爱,就不用修改了。
我们直接走向表prodBOM的postVendorProdBOM这个方法:

Code

我取消了物料类型和工序号的限制,并给ProdJournalCreateBOM增加了一个runSpecial,createLineSpecial的方法,因为AX原有的做法都是工序去筛选prodBOM的记录从而创建ProdJournalTrans的记录的,这不合我意,我想通过InventTransId去过滤ProdBOM的记录从而生成prodJournalTrans的记录,于是,改之。

while select forupdate prodBOM
        index hint NumIdx
        
where prodBOM.ProdId == prodId      &&
              prodBOM.InventTransId 
== this.parmInventTransId()

CreateLine方法的其他地方不变,只是把过滤条件从工序号变成了InventTransId.这样应该差不多了。

OK,就这些了。

原文地址:https://www.cnblogs.com/Farseer1215/p/1514426.html