Technical Articles
在 SAP S/4HANA Cloud 中通过自定义逻辑限制未发料、未确认工单 101 入库
问题背景:
客户发现在业务中存在不规范的情况,有些用户对于工单并没做发料或者工序确认,就做产成品101入库。但是在实际业务中这种情况是不存在的,因为没有发料和报工,产成品不可能生产出来。因此客户想在系统中做些限制,如果没有报工或者发料,不允许做产成品的入库。
解决方案:
尝试通过自定义逻辑,写一个 BAdI 来满足需求。
分析步骤:
1. 首先,我们需要在 SAP S/4HANA Cloud 系统的应用 – 自定义逻辑里,新建增强实施。根据业务场景,选择下图中的业务上下文以及业务加载项描述,填写好实施描述以及实施标识。
新增增强措施
2. 在自定义逻辑里根据本问题涉及业务上下文以及业务加载项描述完成新建增强实施后,我们需要找到字段获取工单的状态。根据客户的需求,我们可以去前台应用 – 监控生产/计划订单里查找到未发料、未确认涉及以下几种状态:
GMPS – Goods Movement Posted
PCNF – Part Confirmed
CNF – Confirmed
在应用“监控生产/计划订单”里查看订单状态
3. 首先,这个 BAdI 不仅适用于应用 – 过账生产订单的收货,还适用于应用 – 过账采购凭证的收货。所以为了防止该 BAdI 影响到采购订单的收货,我们需要加一个判断条件。
if GR4XY_HEADER-SOURCEOFGR = 'PRODORD'.
...
endif.
我们尝试在 CDS View 里进行查找和检索字段来表示工单的状态。I_MfgOrderWithStatus 里存在多个字段可以表示工单的状态,其中 OrderIsPartiallyConfirmed 和 OrderIsConfirmed 可以分别表示 PCNF 和 CNF 两种涉及确认的状态。那么,我们可以写出关于确认状态的判断语句。
SELECT SINGLE
FROM i_mfgorderwithstatus
FIELDS OrderIsConfirmed
WHERE ManufacturingOrder = @im_gr4xy_item->inbounddelivery
INTO @ls_orderisconfirmed.
SELECT SINGLE
FROM i_mfgorderwithstatus
FIELDS OrderIsPartiallyConfirmed
WHERE ManufacturingOrder = @im_gr4xy_item->inbounddelivery
INTO @ls_orderispartiallyconfirmed.
...
if ls_orderisconfirmed <> 'X' AND ls_orderispartiallyconfirmed <> 'X'.
append value #( messagetype = 'E' messagetext = '当前工单没有工序确认,禁止101入库。' ) to messages.
endif.
但涉及发料的 GMPS 状态通过这个 CDS View 无法表示。我们需要找到另一个 CDS View 来帮助我们获取发料状态。I_MfgOrderDocdGoodsMovement 这个 CDS View 记录了工单的货物移动情况。如果工单存在货物移动,则在这个 CDS View 里会有对应的一条记录。那么只要我们使用工单号在该 CDS View 里进行检索,如果返回的记录数不为 0 ,则代表工单已经有发料。那么,我们可以写出关于发料状态的判断语句。
SELECT count(*) from I_MfgOrderDocdGoodsMovement with privileged access
WHERE ManufacturingOrder = @im_gr4xy_item->inbounddelivery AND GoodsMovementType = '261'
INTO @ls_orderisgoodsmoventposted.
...
if ls_orderisgoodsmoventposted = '0'.
append value #( messagetype = 'E' messagetext = '当前工单没有发料,禁止101入库。' ) to messages.
endif.
接下来要注意的就是数据匹配。在这个 BAdI 里我们需要从 gr4xy_item 这张表中读取当前工单的数据,所以需要使用 loop 循环。同时值得注意的是,在 gr4xy_item 这张表里表示工单号的字段是 inbounddelivery 。
4. 根据以上分析过程,实现 BAdI ,具体代码如下。
DATA: ls_orderisconfirmed TYPE string.
DATA: ls_orderispartiallyconfirmed TYPE string.
DATA: ls_orderisgoodsmoventposted TYPE I.
if GR4XY_HEADER-SOURCEOFGR = 'PRODORD'.
loop at gr4xy_item REFERENCE INTO DATA(im_gr4xy_item).
if im_gr4xy_item->inbounddelivery IS NOT INITIAL AND im_gr4xy_item->plant = '1310'.
SELECT count(*) from I_MfgOrderDocdGoodsMovement with privileged access
WHERE ManufacturingOrder = @im_gr4xy_item->inbounddelivery AND GoodsMovementType = '261'
INTO @ls_orderisgoodsmoventposted.
SELECT SINGLE
FROM i_mfgorderwithstatus
FIELDS OrderIsConfirmed
WHERE ManufacturingOrder = @im_gr4xy_item->inbounddelivery
INTO @ls_orderisconfirmed.
SELECT SINGLE
FROM i_mfgorderwithstatus
FIELDS OrderIsPartiallyConfirmed
WHERE ManufacturingOrder = @im_gr4xy_item->inbounddelivery
INTO @ls_orderispartiallyconfirmed.
if ls_orderisconfirmed <> 'X' AND ls_orderispartiallyconfirmed <> 'X'.
append value #( messagetype = 'E' messagetext = '当前工单没有工序确认,禁止101入库。' ) to messages.
endif.
if ls_orderisgoodsmoventposted = '0'.
append value #( messagetype = 'E' messagetext = '当前工单没有发料,禁止101入库。' ) to messages.
endif.
endif.
endloop.
endif.
5. 如图所示,我们取 1000061 、1000162 、1000163 、1000165 这四个工单来验证我们的 BAdI 是否有效。其中工单 1000061 包含 GMPS 和 CNF 这两种状态,工单 1000162 不包含 GMPS, CNF, PCNF 这三种状态,工单 1000163 包含 CNF 状态,工单 1000165 包含 GMPS 状态。
工单 1000061 ,包含 GMPS 和 CNF 这两种状态
工单 1000162 ,不包含 GMPS , CNF, PCNF 这三种状态
工单 1000163 ,包含 CNF 状态
工单 1000165 ,包含 GMPS 状态
6. 进入应用 – 过账生产订单的收货,分别对上面所述的四个工单进行收货,效果如图所示,由此证明该 BAdI 的效果满足我们的需求。
工单 1000061 既发料也已确认,可以收货
工单 1000162 既未发料也未已确认,不可以收货
工单 1000163 未发料,不可以收货
工单 1000165 未确认,不可以收货
结语:
通过阅读本文,希望您已知晓如何通过自定义逻辑来限制未发料、未确认工单 101 入库。
关注以下链接可以看到更多有关 SAP S/4HANA Cloud 制造相关的问题:All Questions in SAP S/4HANA Cloud for Manufacturing | SAP Community
您也可以通过后面的链接阅读更多有关 SAP S/4HANA Cloud 制造的博文:SAP S/4HANA Cloud for Manufacturing | SAP | SAP Blogs
如果您对本文有任何的建议和想法,欢迎在评论区提出,期待与您一起交流。如果本文对您有任何帮助,欢迎您关注我的个人账号,期待我们在下一篇博文再见!
清晰简明好文
请问这个增强是否也适用于应用 - 过账货物移动 呢?
Hi Cindy,
可以参考如下链接:2956742 - How to enter a Purchase Order in BADI MMIM_GR4X - SAP ONE Support Launchpad
根据链接中提到的,
The Badi MMIM_GR4XY_CHECK_DATA only supports the mentioned Fiori apps Goods Receipt for ProdnOrd, PurOrd, NoRef, InbDeliv
The field “inbounddelivery TYPE aufnr (for order we need 12 characters)” is used for all possible objects but it can have only one name. Using the GR4PO-App use the field 'inbounddelivery' to fill the Purchase Order number.
**The BADI MMIM_GR4XY_CHECK_DATA does not support 'Post Goods Movement' / 'MIGO'
因此这个增强只支持几个 Fiori 的应用,不支持 Web GUI 的应用。
Best Regards,
Zhehui
好的,非常感谢!~
您好!MIGO过账给行项目自定义字段赋值的BADI有吗?
您好,
可以参考这个链接的回答是否可以满足您的需求:
MIGO行项目自定义字段赋值