VF02销售开票IDOC触发采购发票校验
SMOD MRMH0002 EXIT_SAPLMRMH_011
如果是基于收货的发票校验,报错M8321 as was not possible determine the correct order item,
是因为SAPLMRMH mrm_gr_distribute [form] 分配采购订单收货的物料凭证作为发票校验参考时出错了。标准程序有个Bug,一个采购订单行有多笔收货时,每次分配参考行都按采购订单号+项目分配,不会排除之前已经分配过的行。这样发票校验时就用了重复参考行就会报错。
参考note 2177340,此Note有解释但是没有修复,需要增强处理。在EXIT_SAPLMRMH_011中把参考相同采购订单行的多个IDOC段数量合并。
demo
*&---------------------------------------------------------------------*
*& 包含 ZXM08U22
*&---------------------------------------------------------------------*
*合并IDOC段
data:
ls_e1edp01_s like e1edp01, "source data
ls_e1edp01 like e1edp01,
ls_e1edp02 like e1edp02,
ls_e1edp26 like e1edp26,
begin of lt_ekpo occurs 0,
belnr type e1edp02-belnr,
zeile type e1edp02-zeile,
menge type ekpo-menge,
betrg type ekpo-netwr,
end of lt_ekpo.
*合计数量
read table t_idoc_data with key segnam = 'E1EDP01'.
if sy-subrc = 0.
loop at t_idoc_data from sy-tabix.
data(lv_tabix) = sy-tabix.
case t_idoc_data-segnam.
when 'E1EDP01'. "读数量
clear lt_ekpo.
ls_e1edp01 = t_idoc_data-sdata.
lt_ekpo-menge = ls_e1edp01-menge.
when 'E1EDP02'.
ls_e1edp02 = t_idoc_data-sdata.
if ls_e1edp02-qualf = '001'. "采购订单
lt_ekpo-belnr = ls_e1edp02-belnr.
lt_ekpo-zeile = ls_e1edp02-zeile.
endif.
when 'E1EDP26'. "读金额
ls_e1edp26 = t_idoc_data-sdata.
if ls_e1edp26-qualf = '003'. "003和010都有金额,防止重复只取一行
lt_ekpo-betrg = ls_e1edp26-betrg.
endif.
endcase.
data(lv_tabix_next) = lv_tabix + 1.
read table t_idoc_data into data(ls_idoc_data_next) index lv_tabix_next.
if sy-subrc = 0 .
if ls_idoc_data_next-hlevel <= 2. "回到第2层或更上层了
collect lt_ekpo.
if ls_idoc_data_next-segnam ne 'E1EDP01'.
exit.
endif.
endif.
else. "最后一行了
collect lt_ekpo.
exit.
endif.
endloop.
endif.
*替换数量
data lv_del.
read table t_idoc_data with key segnam = 'E1EDP01'.
if sy-subrc = 0.
loop at t_idoc_data from sy-tabix.
lv_tabix = sy-tabix.
if t_idoc_data-hlevel = 2.
clear lv_del.
endif.
if lv_del = 'X'.
delete t_idoc_data.
continue.
endif.
case t_idoc_data-segnam.
when 'E1EDP01'. "更新数量
lv_tabix_next = lv_tabix + 1.
read table t_idoc_data into ls_idoc_data_next index lv_tabix_next.
if sy-subrc = 0 and ls_idoc_data_next-segnam = 'E1EDP02'.
ls_e1edp02 = ls_idoc_data_next-sdata.
read table lt_ekpo with key belnr = ls_e1edp02-belnr zeile = ls_e1edp02-zeile.
if sy-subrc = 0.
data(lv_betrg) = lt_ekpo-betrg.
ls_e1edp01 = t_idoc_data-sdata.
ls_e1edp01-menge = lt_ekpo-menge.
t_idoc_data-sdata = ls_e1edp01.
delete lt_ekpo index sy-tabix.
modify t_idoc_data.
else. "读不到说明是重复行,和底层一起删掉
delete t_idoc_data.
lv_del = 'X'.
endif.
endif.
when 'E1EDP26'. "更新金额
ls_e1edp26 = t_idoc_data-sdata.
ls_e1edp26-betrg = lv_betrg.
t_idoc_data-sdata = ls_e1edp26.
modify t_idoc_data.
endcase.
endloop.
endif.