外向交货单过账与冲销增强

作者:ABAP三叔 约 6 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, SD, 开发, 销售分销
外向交货单过账与冲销增强 - 封面图
外向交货单过账与冲销增强 - 封面图

前言

外向交货单过账与冲销的增强是一个十分常见的需求,通常用来做与第三方系统的接口、冲销或删除的检查 。

增强方法

1. 方法一:在 程序MV50AFZ1的USEREXIT_SAVE_DOCUMENT做增强

FIELD-SYMBOLS: <wa_xlikp> LIKE xlikp.FIELD-SYMBOLS: <wa_xlips> LIKE xlips.DATA: wa_ylikp LIKE xlikp.DATA: wa_xlips LIKE xlips.DATA: wa_ylips LIKE ylips.DATA: lt_xlips LIKE TABLE OF xlips.DATA: lt_ylips LIKE TABLE OF ylips.DATA: wa_xvbuk LIKE xvbuk.DATA: wa_yvbuk LIKE xvbuk.DATA: lt_ekpo LIKE TABLE OF ekpo WITH HEADER LINE.DATA: wa_ekko LIKE ekko.DATA: wa_vbak LIKE vbak, lt_vbap LIKE TABLE OF vbap WITH HEADER LINE, lt_vbfa LIKE TABLE OF vbfavb WITH HEADER LINE.

DATA:lv_bwkey TYPE bwkey, lv_bukrs1 TYPE bukrs, lv_bukrs2 TYPE bukrs.DATA:ls_xlips LIKE LINE OF xlips.

*循环每个交货单抬头LOOP AT xlikp ASSIGNING <wa_xlikp>.

CLEAR: wa_ylikp,wa_xvbuk,wa_yvbuk,wa_ekko,wa_vbak. REFRESH: lt_xlips,lt_ylips,lt_ekpo,lt_vbap,lt_vbfa.*获取交货单抬头旧值 READ TABLE ylikp INTO wa_ylikp WITH KEY vbeln = <wa_xlikp>-vbeln. READ TABLE xvbuk INTO wa_xvbuk WITH KEY vbeln = <wa_xlikp>-vbeln. READ TABLE yvbuk INTO wa_yvbuk WITH KEY vbeln = <wa_xlikp>-vbeln.*获取交货单行项目 LOOP AT xlips INTO wa_xlips WHERE vbeln = <wa_xlikp>-vbeln. APPEND wa_xlips TO lt_xlips. ENDLOOP.*获取交货单行项目旧值 LOOP AT ylips INTO wa_ylips WHERE vbeln = <wa_xlikp>-vbeln. APPEND wa_ylips TO lt_ylips. ENDLOOP. LOOP AT xvbfa INTO DATA(lw_xvbfa). APPEND xvbfa TO lt_vbfa. ENDLOOP.*读取交货单的第一行.因为是通过第一行确定对应的调拨单. READ TABLE xlips INTO wa_xlips INDEX 1. IF sy-subrc = 0 . CASE wa_xlips-vgtyp . WHEN 'V'. "调拨单创建的交货单 SELECT SINGLE * FROM ekko INTO wa_ekko WHERE ebeln = wa_xlips-vgbel. SELECT * FROM ekpo INTO CORRESPONDING FIELDS OF TABLE lt_ekpo WHERE ebeln = wa_xlips-vgbel. WHEN OTHERS ."销售订单创建的交货单 SELECT SINGLE * FROM vbak INTO wa_vbak WHERE vbeln = wa_xlips-vgbel. SELECT * FROM vbap INTO CORRESPONDING FIELDS OF TABLE lt_vbap WHERE vbeln = wa_xlips-vgbel. ENDCASE. ENDIF. *调用保存增强 CALL FUNCTION 'ZFM_SAVE_EXIT' IN UPDATE TASK EXPORTING is_xlikp = <wa_xlikp> is_ylikp = wa_ylikp iv_trtyp = t180-trtyp is_xvbuk = wa_xvbuk is_yvbuk = wa_yvbuk is_xekko = wa_ekko is_xvbak = wa_vbak is_t180 = t180 TABLES it_xlips = lt_xlips[] it_ylips = lt_ylips[] it_xekpo = lt_ekpo[] it_xvbap = lt_vbap[]      it_xvbfa = lt_vbfa[].

2.方法二:

SE18中创建BADI "LE_SHP_DELIVERY_PROC"的增强实施

2.1 删除检查

修改if_ex_le_shp_delivery_proc~delivery_deletion方法和

if_ex_le_shp_delivery_proc~item_deletion方法.

METHOD if_ex_le_shp_delivery_proc~delivery_deletion.* 生成过结算链的禁止删除 CHECK is_likp-lfart = 'ZNL1'. SELECT SINGLE vbeln_vl INTO @DATA(lv_vbeln_vl) FROM ztsd013_h WHERE vbeln_vl = @is_likp-vbeln AND current_doc_type <> '1' AND current_doc_type <> '2' AND bapi_mtype = 'S'. IF sy-subrc = 0.      "请先删除结算链单据后再删除交货单 MESSAGE e007(zsd). ENDIF. ENDMETHOD.
METHOD if_ex_le_shp_delivery_proc~item_deletion.* 生成过结算链的禁止删除 CHECK is_likp-lfart = 'ZNL1'. SELECT SINGLE vbeln_vl INTO @DATA(lv_vbeln_vl) FROM ztsd013_h WHERE vbeln_vl = @is_likp-vbeln AND current_doc_type <> '1' AND current_doc_type <> '2' AND bapi_mtype = 'S'. IF sy-subrc = 0. "请先删除结算链单据后再删除交货单 MESSAGE e007(zsd). ENDIF. ENDMETHOD.

2.2过账前最后检查

修改if_ex_le_shp_delivery_proc~delivery_final_check方法

METHOD if_ex_le_shp_delivery_proc~delivery_final_check.* 交货单数量禁止为0 DATA: lv_zero TYPE c, ls_finchdel TYPE finchdel. DATA:ls_xlikp TYPE likpvb, ls_xlips TYPE lipsvb. LOOP AT it_xlikp INTO ls_xlikp WHERE updkz NE 'D'. CLEAR lv_zero. LOOP AT it_xlips INTO ls_xlips WHERE vbeln EQ ls_xlikp-vbeln AND updkz NE 'D'. CHECK ls_xlikp-lfart = 'ZNL1'. IF ls_xlips-lfimg = 0. lv_zero = 'X'. EXIT. ENDIF. ENDLOOP. IF lv_zero = 'X'. CLEAR ls_finchdel. ls_finchdel-vbeln = ls_xlikp-vbeln. ls_finchdel-pruefung = '99'. ls_finchdel-msgty = 'E'. ls_finchdel-msgid = 'ZSD'. ls_finchdel-msgno = '004'.        "交货单明细行数量不可为0* Note: CT_FINCHDEL is a hashed table INSERT ls_finchdel INTO TABLE ct_finchdel. ENDIF. ENDLOOP. ENDMETHOD.

2.3过账和冲销检查

修改if_ex_le_shp_delivery_proc~save_and_publish_before_output方法

METHOD if_ex_le_shp_delivery_proc~save_and_publish_before_output. LOOP AT it_xlikp INTO DATA(wa_xlikp). CHECK wa_xlikp-lfart = 'ZNL1'. READ TABLE it_ylikp INTO DATA(wa_ylikp) WITH KEY vbeln = wa_xlikp-vbeln. CHECK sy-subrc = 0. "冲销检查 IF wa_xlikp-wbstk = 'A' AND wa_ylikp-wbstk = 'C'. SELECT SINGLE vbeln_vl INTO @DATA(lv_vbeln_vl) FROM ztsd013_h WHERE vbeln_vl = @wa_xlikp-vbeln AND current_doc_type <> '1' AND current_doc_type <> '2' AND bapi_mtype = 'S'. IF sy-subrc = 0. ROLLBACK WORK.          "请先删除结算链单据后再冲销交货单 MESSAGE e005(zsd). ENDIF. ENDIF. "过账检查 IF wa_xlikp-wbstk = 'C' AND wa_ylikp-wbstk = 'A'. SELECT SINGLE vbeln_vl INTO @lv_vbeln_vl FROM ztsd013_h WHERE vbeln_vl = @wa_xlikp-vbeln AND current_doc_type <> '1' AND current_doc_type <> '2' AND bapi_mtype = 'S'. IF sy-subrc = 0. ROLLBACK WORK.          "请先删除结算链单据后再过账交货单 MESSAGE e006(zsd). ENDIF. ENDIF.    ENDLOOP. ENDMETHOD.

2.4过账前,将物料平均价写入LIPS行项目的增强字段

修改if_ex_le_shp_delivery_proc~save_document_prepare方法

METHOD if_ex_le_shp_delivery_proc~save_document_prepare. IF ct_xlips[] IS NOT INITIAL. SELECT matnr, a~bwkey, verpr, peinh INTO TABLE @DATA(lt_mbew) FROM mbew AS a JOIN t001w AS b ON b~bwkey = a~bwkey FOR ALL ENTRIES IN @ct_xlips WHERE matnr = @ct_xlips-matnr AND b~werks = @ct_xlips-werks. ENDIF. LOOP AT ct_xlikp INTO DATA(ls_xlikp). CHECK ls_xlikp-lfart = 'ZNL1'. LOOP AT ct_xlips INTO DATA(ls_xlips) WHERE vbeln = ls_xlikp-vbeln. READ TABLE lt_mbew INTO DATA(ls_mbew) WITH KEY matnr = ls_xlips-matnr bwkey = ls_xlips-werks. CHECK sy-subrc = 0. ls_xlips-zverpr = ls_mbew-verpr / ls_mbew-peinh. MODIFY ct_xlips FROM ls_xlips. ENDLOOP. ENDLOOP. ENDMETHOD.

2.5过账后,执行公司间结算单据流

修改IF_EX_LE_SHP_DELIVERY_PROC~SAVE_AND_PUBLISH_DOCUMENT方法

METHOD IF_EX_LE_SHP_DELIVERY_PROC~SAVE_AND_PUBLISH_DOCUMENT. DATA:LT_LIKP TYPE TABLE OF LIKP, LS_LIPS TYPE LIPS, LT_LIPS_O TYPE TABLE OF LIPS, "门店领用/总部领用 交货单明细行 LT_LIPS_S TYPE TABLE OF LIPS, "销售 交货单明细行 LT_EKKO_O TYPE TABLE OF EKKO, "门店领用/总部领用 采购单 LT_EKKO_S TYPE TABLE OF EKKO, "销售 采购单 LT_EKPO_O TYPE TABLE OF EKPO, "门店领用/总部领用 采购单明细行         LT_EKPO_S TYPE TABLE OF EKPO. "销售 采购单明细行 IF IT_XLIPS[] IS NOT INITIAL. SELECT * INTO TABLE @DATA(LT_EKKO) FROM EKKO FOR ALL ENTRIES IN @IT_XLIPS WHERE EBELN = @IT_XLIPS-VGBEL. SELECT * INTO TABLE @DATA(LT_EKPO) FROM EKPO FOR ALL ENTRIES IN @IT_XLIPS WHERE EBELN = @IT_XLIPS-VGBEL. ENDIF. LOOP AT IT_XLIKP INTO DATA(LS_XLIKP). CHECK LS_XLIKP-LFART = 'ZNL1'. "获取交货单抬头旧值 READ TABLE IT_YLIKP INTO DATA(LS_YLIKP) WITH KEY VBELN = LS_XLIKP-VBELN. CHECK SY-SUBRC = 0. "过账 IF LS_XLIKP-WBSTK = 'C' AND LS_YLIKP-WBSTK = 'A'. "结算链 REFRESH:LT_LIKP,LT_LIPS_O,LT_EKKO_O,LT_EKPO_O. LOOP AT IT_XLIPS INTO DATA(LS_XLIPS) WHERE VBELN = LS_XLIKP-VBELN AND UPDKZ NE 'D'.* 取采购订单类型 READ TABLE LT_EKKO INTO DATA(LS_EKKO) WITH KEY EBELN = LS_XLIPS-VGBEL. CHECK SY-SUBRC = 0."采购订单类型 CHECK LS_EKKO-BSART = 'Z061' "形象品领用 OR LS_EKKO-BSART = 'Z062'."形象品领用退 READ TABLE LT_EKPO INTO DATA(LS_EKPO) WITH KEY EBELN = LS_XLIPS-VGBEL EBELP = LS_XLIPS-VGPOS. CHECK SY-SUBRC = 0 AND LS_EKPO-ZYYDM IS NOT INITIAL. SELECT SINGLE ZZJSLX INTO @DATA(LS_JSLX) FROM ZTSD012 WHERE ZYYDM = @LS_EKPO-ZYYDM. CHECK SY-SUBRC = 0. CLEAR LS_LIPS. MOVE-CORRESPONDING LS_XLIPS TO LS_LIPS. CASE LS_JSLX. "原因码 WHEN '1'."门店领用/总部领用 APPEND LS_LIPS TO LT_LIPS_O. READ TABLE LT_EKKO_O TRANSPORTING NO FIELDS WITH KEY

...

ABAP三叔

关于作者:ABAP三叔

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「外向交货单过账与冲销增强.md」整理生成,仅用于内部技术分享与学习交流。