目录
业务场景:
业务场景为SAP ERP系统与仓储业务系统集成,核心集成分两步:
解决思路:
==分割线===
今天在补充一下思路,目前认为如果要和外围系统集成,最佳的触发时点就是实时同步,包括创建/修改/删除。所以就和我们在处理单据校验逻辑一样,在订单保存的增强出口实现集成数据推送为最佳思路。当然重新推送数据也可以在这里去获取然后同时推送,但是单独推送的功能也必须要有设计。
==分割线===
代码实现:
创建、修改、删除采购订单时,可在BADI的增强出口ME_PURCHDOC_POSTED触发订单同步:
在POST方法中调用接口,根据OLD和NEW值判断更改标识:
CALL FUNCTION 'XXXXX' STARTING NEW TASK 'XXXXX'
EXPORTING
im_ekko = im_ekko
TABLES
im_eket = im_eket
im_ekpo = im_ekpo
im_ekpo_old = im_ekpo_old
im_ekkn = im_ekkn.
2. 仓储业务系统负责业务端来料登记、质检、入库业务数据,通过接口将数据同步至SAP。SAP不记录质检数据,只记录来料登记数量(103)、质检不合格退货数量(124)、合格入库数量(105)、合格入库后其他质量问题退库,未做发票校验(122)操作。针对采购退货订单(161移动类型)、103、124、105、122、161冲销凭证实现过于简单不做赘述。具体参考:
这里涉及一个重要问题就是供应商主数据是否勾选了基于收货的发票校验,这个数据选项影响到105(质检合格)、124(质检不合格)、122(质检合格后,未做发票校验退货)的凭证是否要参考物料凭证过账,前台MIGO过账,系统会自动匹配,调用BAPI过账需求自开发程序进行匹配。如下图:
ECC版本:
S4版本:
在代码逻辑实现要进行考虑:
1、105和124的凭证过账时,都是参考103的凭证。需要计算排除104冲销产生的103凭证外,剩余103凭证可被参考(103-104-105+106-124+125)的凭证数据。
2、122的凭证参考的也是103的凭证。需要排除104冲销掉产生的103凭证和已经做了发票校验的凭证外可被参考的凭证,即:(105+123-122-106)-已作发票校验的数量。
具体代码:
"判断基于发票的勾是否勾上
SELECT SINGLE webre
FROM ekpo
INTO @DATA(lv_webre)
WHERE ebeln = @lw_po-ebeln
AND ebelp = @lw_po-ebelp.
"105,124凭证需要参考凭证
IF ( lt_item-move_type = '105' OR lt_item-move_type = '124' )
AND lv_webre IS NOT INITIAL.
"订单行的所有103凭证
SELECT gjahr,belnr,buzei,bamng,lfgja ,lfbnr,lfpos
FROM ekbe
INTO TABLE @DATA(lt_103)
WHERE ebeln = @lw_po-ebeln
AND ebelp = @lw_po-ebelp
AND bwart = '103'.
LOOP AT lt_103 INTO DATA(lw_103).
IF lw_103-belnr NE lw_103-lfbnr."104冲销产生的103凭证排除
lw_103-bamng = 0."SAP中,103凭证未被完全参考时,参考凭证 = 原凭证
ELSE.
SELECT SUM(
CASE bwart
WHEN '104' THEN bamng * -1
WHEN '105' THEN bamng * -1
WHEN '124' THEN bamng * -1
ELSE bamng
END )
FROM ekbe
INTO @DATA(lv_bamng)
WHERE ebeln = @lw_po-ebeln
AND ebelp = @lw_po-ebelp
AND bwart IN ( '105' , '106' , '104', '124' , '125' ,'103' )
AND lfgja = @lw_103-gjahr
AND lfbnr = @lw_103-belnr
AND lfpos = @lw_103-buzei.
lw_103-bamng = lv_bamng.
"计算103凭证可剩余冲105的数量(103-104-105-124=lv_bamng),数量为0删除
ENDIF.
MODIFY lt_103 FROM lw_103.
CLEAR:lw_103,lv_bamng.
ENDLOOP.
DELETE lt_103 WHERE bamng = 0.
SORT lt_103 BY belnr.
LOOP AT lt_103 INTO lw_103.
IF lw_po-erfmg >= lw_103-bamng.
lt_item-entry_qnt = lw_103-bamng.
lt_item-ref_doc_yr = lw_103-gjahr.
lt_item-ref_doc = lw_103-belnr.
lt_item-ref_doc_it = lw_103-buzei.
lw_po-erfmg = lw_po-erfmg - lw_103-bamng.
APPEND lt_item.
CLEAR:lt_item-entry_qnt,lt_item-ref_doc_yr,
lt_item-ref_doc,lt_item-ref_doc_it.
ELSEIF lw_po-erfmg < lw_103-bamng AND lw_po-erfmg > 0.
lt_item-entry_qnt = lw_po-erfmg.
lt_item-ref_doc_yr = lw_103-gjahr.
lt_item-ref_doc = lw_103-belnr.
lt_item-ref_doc_it = lw_103-buzei.
lw_po-erfmg = 0.
APPEND lt_item.
CLEAR:lt_item-entry_qnt,lt_item-ref_doc_yr,
lt_item-ref_doc,lt_item-ref_doc_it.
ELSE.
EXIT.
ENDIF.
ENDLOOP.
"
IF lw_po-erfmg > 0.
lt_item-entry_qnt = lw_103-bamng.
CLEAR:lt_item-entry_qnt.
lw_po-erfmg = lw_po-erfmg - lw_103-bamng.
APPEND lt_item.
CLEAR:lt_item-entry_qnt.
ENDIF.
CLEAR:lt_item.
"122 也需要参考103的凭证
ELSEIF lt_item-move_type = '122'
AND lv_webre IS NOT INITIAL.
"订单行的所有103凭证
SELECT gjahr,belnr,buzei,bamng,lfgja ,lfbnr,lfpos
FROM ekbe
INTO TABLE @DATA(lt_105)
WHERE ebeln = @lw_po-ebeln
AND ebelp = @lw_po-ebelp
AND bwart = '103'.
LOOP AT lt_105 INTO DATA(lw_105).
"104冲销产生的103凭证排除
IF lw_105-belnr NE lw_105-lfbnr.
lw_105-bamng = 0.
ELSE.
SELECT SUM(
CASE bwart
WHEN '106' THEN bamng * -1
WHEN '122' THEN bamng * -1
ELSE bamng
END )
FROM ekbe
INTO @DATA(lv_bamng1)
WHERE ebeln = @lw_po-ebeln
AND ebelp = @lw_po-ebelp
AND bwart IN ( '105' , '106' , '123' , '122' )
AND lfgja = @lw_105-gjahr
AND lfbnr = @lw_105-belnr
AND lfpos = @lw_105-buzei.
"排除已经发票校验的数据
SELECT SUM(
CASE shkzg
WHEN 'S' THEN menge * 1
WHEN 'H' THEN menge * -1
ELSE menge
END
)
FROM ekbe
INTO @DATA(lv_menge)
WHERE ebeln = @lw_po-ebeln
AND ebelp = @lw_po-ebelp
AND bwart = @space
AND lfgja = @lw_105-gjahr
AND lfbnr = @lw_105-belnr
AND lfpos = @lw_105-buzei.
"计算103凭证可剩余冲105的数量(103-104-105-124=lv_bamng),数量为0删除
lw_105-bamng = lv_bamng1 - lv_menge.
ENDIF.
MODIFY lt_105 FROM lw_105.
CLEAR:lw_105,lv_bamng1,lv_menge.
ENDLOOP.
DELETE lt_105 WHERE bamng = 0.
SORT lt_105 BY belnr.
LOOP AT lt_105 INTO lw_105.
IF lw_po-erfmg >= lw_105-bamng.
lt_item-entry_qnt = lw_105-bamng.
lt_item-ref_doc_yr = lw_105-gjahr.
lt_item-ref_doc = lw_105-belnr.
lt_item-ref_doc_it = lw_105-buzei.
lw_po-erfmg = lw_po-erfmg - lw_105-bamng.
APPEND lt_item.
CLEAR:lt_item-entry_qnt,lt_item-ref_doc_yr,
lt_item-ref_doc,lt_item-ref_doc_it.
ELSEIF lw_po-erfmg < lw_105-bamng AND lw_po-erfmg > 0.
lt_item-entry_qnt = lw_po-erfmg.
lt_item-ref_doc_yr = lw_105-gjahr.
lt_item-ref_doc = lw_105-belnr.
lt_item-ref_doc_it = lw_105-buzei.
lw_po-erfmg = 0.
APPEND lt_item.
CLEAR:lt_item-entry_qnt,lt_item-ref_doc_yr,
lt_item-ref_doc,lt_item-ref_doc_it.
ELSE.
EXIT.
ENDIF.
ENDLOOP.
IF lw_po-erfmg > 0.
lt_item-entry_qnt = lw_105-bamng.
CLEAR:lt_item-entry_qnt.
lw_po-erfmg = lw_po-erfmg - lw_105-bamng.
APPEND lt_item.
CLEAR:lt_item-entry_qnt.
ENDIF.
CLEAR:lt_item.
ELSE. "未启用基于发票的校验
lt_item-entry_qnt = lw_po-erfmg.
APPEND lt_item.
CLEAR:lt_item.
ENDIF.