通过 BADI 实现 SAP 交货单 VL01/02/03N 增强
【摘要】 需求点要求:在创建销售剩余单据时(VL01N、VL10A),在输入屏幕上增加一些限制。一开始直观想到系统的包含文件,类似销售订单一样,因此找到了 MV50AFZ1 中的 userexit_save_document 和 userexit_save_document_prepare 两个用户出口。于是写了这样一段代码:*& MTS销售订单在VL01N创建出库交货时,控制实际发货日期不能晚于...
需求点
要求:在创建销售剩余单据时(VL01N
、VL10A
),在输入屏幕上增加一些限制。一开始直观想到系统的包含文件,类似销售订单一样,因此找到了 MV50AFZ1
中的 userexit_save_document
和 userexit_save_document_prepare
两个用户出口。
于是写了这样一段代码:
*& MTS销售订单在VL01N创建出库交货时,控制实际发货日期不能晚于订单交货日期,否则报错不允许交货过账;
IF ( sy-tcode = 'VL01N' OR sy-tcode = 'VL02N' ).
DATA: lv_auart TYPE vbak-auart. " 订单类型
DATA: lv_edatu TYPE vbep-edatu.
DATA: lv_wadat TYPE likp-wadat_ist.
CLEAR: lv_auart, lv_edatu, lv_wadat.
LOOP AT xlips.
" 取订单行计划行日期 xlips-vgbel
SELECT SINGLE auart FROM vbak INTO lv_auart WHERE vbeln = xlips-vgbel.
IF lv_auart = 'ZOR1' OR lv_auart = 'ZOR2' OR lv_auart = 'ZSP1' OR
lv_auart = 'ZSP2' OR lv_auart = 'ZRE1' OR lv_auart = 'ZRE2' OR
lv_auart = 'ZKE1' OR lv_auart = 'ZKR1'.
SELECT SINGLE edatu FROM vbep INTO lv_edatu WHERE vbeln = xlips-vgbel AND posnr = xlips-vgpos.
lv_wadat = likp-wadat_ist.
IF lv_wadat > lv_edatu.
IF sy-langu = '1'.
MESSAGE '实际发货日期不能晚于订单交货日期:' && lv_wadat TYPE 'E'.
ELSE.
MESSAGE 'The actual ship date cannot be later than the order delivery date' && lv_wadat TYPE 'E'.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.
但是这样一段代码如果出现在交货单,会带出这样的错误信息:
BADI 是用户应用其他异常(如用户扩展)的功能。系统接口:IF_EX_LE_SHP_DELIVERY_PROC
, 它具有与 MV50AFZ1
中的用户出口对应的所有方法。
自定义 BADI 名称:ZCL_IM_E_SHP_DELIVERY_PRO
实现名称:ZE_SHP_DELIVERY_PRO
,当然,你也可以自行起名
实现短文本:交货单增强处理
解决方案
对于消息或用户对话框的输出,您必须确保此退出可以在对话框和后台运行。特别是,在货物发布发布期间,决不能输出消息或用户对话框,因为这可能导致不正确的材料文档。
我们使用保存_DOCUMENT_PREPARE方法。如果您在此方法中发出错误消息,则它不仅回滚对交货文档的更新,而且回滚物料文档的过帐。
IF_EX_LE_SHP_DELIVERY_PROC
的 SAVE_DOCUMENT_PREPARE
方法
最终选择了 DELIVERY_FINAL_CHECK
,在保存前实现检查,这样才不会触发错误后直接退出。
代码示例
METHOD if_ex_le_shp_delivery_proc~delivery_final_check.
**----------------------------------------------------------------------*
DATA: lv_vkaus TYPE vbap-vkaus, " Customer-License
lv_zcont TYPE vbap-zcont. " Customer Royalty No.
*& MTS销售订单在VL01N创建出库交货时,控制实际发货日期不能晚于订单交货日期,否则报错不允许交货过账;
IF ( sy-tcode = 'VL01N' OR sy-tcode = 'VL02N'
OR sy-tcode = 'VL01' OR sy-tcode = 'VL02' OR sy-tcode = 'VL04'
OR sy-tcode = 'VL06G' ).
DATA: lv_auart TYPE vbak-auart. " 订单类型
DATA: lv_edatu TYPE vbep-edatu.
DATA: lv_wadat TYPE likp-wadat_ist.
DATA: ls_likp TYPE LINE OF shp_likp_t.
DATA: ls_lips TYPE LINE OF shp_lips_t.
CLEAR: lv_auart, lv_edatu, lv_wadat.
LOOP AT it_xlips INTO ls_lips.
" 取订单行计划行日期 xlips-vgbel
SELECT SINGLE auart FROM vbak INTO lv_auart WHERE vbeln = ls_lips-vgbel.
IF lv_auart = 'ZOR1' OR lv_auart = 'ZOR2' OR lv_auart = 'ZSP1' OR
lv_auart = 'ZSP2' OR lv_auart = 'ZRE1' OR lv_auart = 'ZRE2' OR
lv_auart = 'ZKE1' OR lv_auart = 'ZKR1'.
" 首个交货日期
SELECT SINGLE edatu FROM vbep INTO lv_edatu WHERE vbeln = ls_lips-vgbel AND posnr = ls_lips-vgpos.
READ TABLE it_xlikp INTO ls_likp WITH KEY vbeln = ls_lips-vbeln.
IF sy-subrc EQ 0.
lv_wadat = ls_likp-wadat_ist. " 实际发货日期
ENDIF.
IF lv_wadat > lv_edatu.
IF sy-langu = '1'.
MESSAGE '实际发货日期不能晚于订单交货日期:' && lv_wadat && '大于' && lv_edatu TYPE 'E'.
ELSE.
MESSAGE 'The actual ship date cannot be later than the order delivery date' && lv_wadat && '大于' && lv_edatu TYPE 'E'.
ENDIF.
ENDIF.
ENDIF.
*& 针对Customer License填写了Y的订单,需要在收货或发货时做一个增强控制:
*& 在VL01N、02N操作时检查销售订单行项目中customer royalty No.
*& 是否有填写信息,有值则允许收货或发货,否则报错不允许收货或发货
SELECT SINGLE vkaus zcont FROM vbap INTO ( lv_vkaus, lv_zcont )
WHERE vbeln = ls_lips-vgbel AND posnr = ls_lips-vgpos.
IF lv_vkaus EQ 'Y'.
IF lv_zcont IS INITIAL.
MESSAGE 'The Customer License is Y, So Customer royalty No. cannot be Empty!' TYPE 'E'.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.
ENDMETHOD.
最终效果
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)