需求背景:
-
- MIRO过账时生成的会计凭证,科目类型KOART= “K” 的凭证行项目(科目为应付)金额进行拆分,若有多行KOART为K的行,则每行都进行拆分。并且将拆分后的配送单写入每一行的分配字段ZUONR。
-
- 批量发票校验生成的凭证中会存在多行暂估类科目,将需拆分的行项目(应付已收票)金额按照暂估科目金额的比例R(每一行暂估科目金额/所有暂估科目金额总和)拆分为多行已收票,每行已收票的金额为对应暂估行比例R*已收票行的金额,同时取暂估科目行项目的EBELN(采购订单)和PRCTR(利润中心)字段值,填入拆分出来的对应的应付分配(ZUONR)和PRCTR(利润中心)字段中。
-
- 如果拆分多行应付已收票金额的合计不等于原已收票的金额,存在尾差,将尾差加到拆分出的应付已收票最后一行金额中。
增强实现:
SMOD: FMRESERV
LOOP AT T_ACCIT INTO LS_ACCIT WHERE KOART = 'K'.
CLEAR LS_ACCIT_YFYSP.
LS_ACCIT_YFYSP = LS_ACCIT.
APPEND LS_ACCIT_YFYSP TO LT_ACCIT_YFYSP.
ENDLOOP.
IF LT_ACCIT_YFYSP[] IS NOT INITIAL.
* 暂估类科目
SELECT *
INTO TABLE LT_ZTFI070
FROM ZTFI070 FOR ALL ENTRIES IN T_ACCIT
WHERE HKONT = T_ACCIT-HKONT.
SORT LT_ZTFI070 BY HKONT.
LOOP AT LT_ACCIT_YFYSP INTO LS_ACCIT_YFYSP.
CLEAR LV_PSWBT_SUM.
FREE LT_FENTAN[].
LOOP AT T_ACCIT INTO LS_ACCIT .
READ TABLE LT_ZTFI070 INTO LS_ZTFI070
WITH KEY HKONT = LS_ACCIT-HKONT
BINARY SEARCH.
IF SY-SUBRC = 0.
CLEAR LS_FENTAN.
MOVE-CORRESPONDING LS_ACCIT TO LS_FENTAN.
APPEND LS_FENTAN TO LT_FENTAN.
LV_PSWBT_SUM = LV_PSWBT_SUM + LS_ACCIT-PSWBT.
ENDIF.
IF LV_POSNR_MAX < LS_ACCIT-POSNR.
LV_POSNR_MAX = LS_ACCIT-POSNR.
ENDIF.
ENDLOOP.
CLEAR LV_LINES.
DESCRIBE TABLE LT_FENTAN LINES LV_LINES.
IF LV_LINES >= 2. " 多行暂估科目,需要做金额拆分
DELETE T_ACCIT WHERE POSNR = LS_ACCIT_YFYSP-POSNR.
FREE LT_ACCCR_YFYSP[].
LOOP AT T_ACCCR INTO LS_ACCCR WHERE POSNR = LS_ACCIT_YFYSP-POSNR..
CLEAR LS_ACCCR_YFYSP.
MOVE-CORRESPONDING LS_ACCCR TO LS_ACCCR_YFYSP.
APPEND LS_ACCCR_YFYSP TO LT_ACCCR_YFYSP.
DELETE T_ACCCR.
CONTINUE.
ENDLOOP.
CLEAR: LV_PSWBT_FTH_SUM,
LV_PSWBT_WEICHA.
LOOP AT LT_FENTAN INTO LS_FENTAN.
LS_FENTAN-PSWBT_FTH = LS_ACCIT_YFYSP-PSWBT * ( LS_FENTAN-PSWBT / LV_PSWBT_SUM ).
LV_PSWBT_FTH_SUM = LV_PSWBT_FTH_SUM + LS_FENTAN-PSWBT_FTH.
MODIFY LT_FENTAN FROM LS_FENTAN.
ENDLOOP.
LV_PSWBT_WEICHA = LS_ACCIT_YFYSP-PSWBT - LV_PSWBT_FTH_SUM.
IF LV_PSWBT_WEICHA IS NOT INITIAL.
* 把尾差加到金额最大的行上, 这个金额本身是负数,所以升序排序,就是最大的负数
SORT LT_FENTAN BY PSWBT_FTH.
LOOP AT LT_FENTAN INTO LS_FENTAN.
LS_FENTAN-PSWBT_FTH = LS_FENTAN-PSWBT_FTH + LV_PSWBT_WEICHA.
MODIFY LT_FENTAN FROM LS_FENTAN.
EXIT.
ENDLOOP.
ENDIF.
SORT LT_FENTAN BY HKONT.
LOOP AT LT_FENTAN INTO LS_FENTAN.
LV_INDEX = SY-TABIX.
IF LV_INDEX = '1'.
CLEAR LS_ACCIT.
MOVE-CORRESPONDING LS_ACCIT_YFYSP TO LS_ACCIT.
LS_ACCIT-PSWBT = LS_FENTAN-PSWBT_FTH.
LS_ACCIT-POSNR = LS_ACCIT_YFYSP-POSNR.
LS_ACCIT-EBELN = LS_FENTAN-EBELN.
LS_ACCIT-EBELP = LS_FENTAN-EBELP.
LS_ACCIT-PRCTR = LS_FENTAN-PRCTR.
LS_ACCIT-ZUONR = LS_FENTAN-EBELN.
APPEND LS_ACCIT TO T_ACCIT.
LOOP AT LT_ACCCR_YFYSP INTO LS_ACCCR_YFYSP.
CLEAR LS_ACCCR.
MOVE-CORRESPONDING LS_ACCCR_YFYSP TO LS_ACCCR.
LS_ACCCR-WRBTR = LS_FENTAN-PSWBT_FTH.
LS_ACCCR-SKFBT = LS_FENTAN-PSWBT_FTH.
LS_ACCCR-POSNR = LS_ACCIT_YFYSP-POSNR.
APPEND LS_ACCCR TO T_ACCCR.
ENDLOOP.
ELSE.
LV_POSNR_MAX = LV_POSNR_MAX + 1.
CLEAR LS_ACCIT.
MOVE-CORRESPONDING LS_ACCIT_YFYSP TO LS_ACCIT.
LS_ACCIT-PSWBT = LS_FENTAN-PSWBT_FTH.
LS_ACCIT-POSNR = LV_POSNR_MAX.
LS_ACCIT-EBELN = LS_FENTAN-EBELN.
LS_ACCIT-EBELP = LS_FENTAN-EBELP.
LS_ACCIT-PRCTR = LS_FENTAN-PRCTR.
LS_ACCIT-ZUONR = LS_FENTAN-EBELN.
APPEND LS_ACCIT TO T_ACCIT.
LOOP AT LT_ACCCR_YFYSP INTO LS_ACCCR_YFYSP.
CLEAR LS_ACCCR.
MOVE-CORRESPONDING LS_ACCCR_YFYSP TO LS_ACCCR.
LS_ACCCR-WRBTR = LS_FENTAN-PSWBT_FTH.
LS_ACCCR-SKFBT = LS_FENTAN-PSWBT_FTH.
LS_ACCCR-POSNR = LV_POSNR_MAX.
APPEND LS_ACCCR TO T_ACCCR.
ENDLOOP.
ENDIF.
ENDLOOP.
SORT T_ACCIT BY POSNR.
SORT T_ACCCR BY POSNR.
ENDIF.
ENDLOOP.
ENDIF.
注意事项
经过SMOD: FMRESERV代码实现,可完成凭证行项目的拆分。
但是,凭证会无法提交。导致更新中止。如下图:
此时需要BTE增强更新两个参数来解决此问题。
SAMPLE_PROCESS_00001120。配置过程不做详解:
IF SY-TCODE = 'MIRO'.
LOOP AT IT_BSEG WHERE KOART = 'K'.
LV_INDEX = SY-TABIX.
READ TABLE T_BSEGSUB INTO LS_BSEGSUB
WITH KEY TABIX = LV_INDEX.
IF SY-SUBRC = 0.
LV_INDEX_BSEGSUB = SY-TABIX.
LS_BSEGSUB-XKRES = 'X'.
LS_BSEGSUB-XOPVW = 'X'.
MODIFY T_BSEGSUB FROM LS_BSEGSUB INDEX LV_INDEX_BSEGSUB.
ENDIF.
ENDLOOP.
ENDIF.