MIRO 发票校验BAPI使用案例
FUNCTION zmm_srm2sap_006. *"---------------------------------------------------------------------- *"*"本地接口: *" TABLES *" IT_TAB STRUCTURE ZMMS004 *" ET_TAB STRUCTURE ZMMS004_RSP OPTIONAL *"---------------------------------------------------------------------- DATA: ls_zmms004 TYPE zmms004, headerdata TYPE bapi_incinv_create_header, invoicedocnumber TYPE bapi_incinv_fld-inv_doc_no, itemdata TYPE TABLE OF bapi_incinv_create_item WITH HEADER LINE, withtaxdata TYPE TABLE OF bapi_incinv_create_withtax WITH HEADER LINE, taxdata TYPE TABLE OF bapi_incinv_create_tax WITH HEADER LINE, return TYPE TABLE OF bapiret2 WITH HEADER LINE. DATA: lt_input TYPE TABLE OF zmms004. DATA: lv_item TYPE rblgp. DATA: lv_gross_amount TYPE bapi_incinv_create_header-gross_amount. DATA: lv_kbetr TYPE konp-kbetr. DATA: lv_msg TYPE string. DATA: lv_iferror_flg TYPE c. DATA: lv_iferror_lifnr_flg TYPE c. DATA:lv_wrbtr_sum TYPE zmms004-zwrbtr. DATA: lv_bu_sort1 TYPE string. DATA: lv_lifnr TYPE bseg-lifnr. DATA: lt_out TYPE TABLE OF zmms004_rsp WITH HEADER LINE. DATA: lt_out_temp TYPE TABLE OF zmms004_rsp WITH HEADER LINE. DATA: lv_numc TYPE numc2. DATA: lv_zjss_initial TYPE zmmt004-zjss. DATA: lv_zjsje_initial TYPE zmmt004-zjsje. TYPES: BEGIN OF ts_stru, zfbdt TYPE zmms004-zfbdt, bldat TYPE zmms004-bldat, zwrbtr TYPE zmms004-zwrbtr, zwrbtr1 TYPE zmms004-zwrbtr1, zwrbtr2 TYPE zmms004-zwrbtr2, sgtxt TYPE zmms004-sgtxt, lastchangedatetime TYPE ekko-lastchangedatetime, ebeln TYPE ekpo-ebeln, ebelp TYPE ekpo-ebelp, matnr TYPE ekpo-matnr, werks TYPE ekpo-werks, ekorg TYPE ekKO-ekorg, bukrs TYPE ekpo-bukrs, waers TYPE ekko-waers, pstyp TYPE ekpo-pstyp, esokz TYPE a017-esokz, mwskz TYPE ekpo-mwskz, zjss TYPE zmmt004-zjss, zjsje TYPE zmmt004-zjsje, meins TYPE ekpo-meins, zwrbtr1_line TYPE zmms004-zwrbtr1, zwrbtr2_line TYPE zmms004-zwrbtr2, gjahr TYPE ekbe-gjahr, belnr TYPE ekbe-belnr, buzei TYPE ekbe-buzei, END OF ts_stru. TYPES:BEGIN OF ts_data, lifnr TYPE zmmt004-lifnr, zflg TYPE c, zdzd TYPE zmmt004-zdzd, zdzdh TYPE zmmt004-zdzdh. INCLUDE TYPE ts_stru. TYPES END OF ts_data. TYPES:BEGIN OF ts_typ, bukrs TYPE ekpo-bukrs, lifnr TYPE zmmt004-lifnr, matnr TYPE ekpo-matnr, zflg TYPE c, zdzd TYPE zmmt004-zdzd, zdzdh TYPE zmmt004-zdzdh, zfbdt TYPE zmms004-zfbdt, bldat TYPE zmms004-bldat, zwrbtr TYPE zmms004-zwrbtr, zwrbtr1 TYPE zmms004-zwrbtr1, zwrbtr2 TYPE zmms004-zwrbtr2, sgtxt TYPE zmms004-sgtxt, lastchangedatetime TYPE ekko-lastchangedatetime, ebeln TYPE ekpo-ebeln, ebelp TYPE ekpo-ebelp, werks TYPE ekpo-werks, ekorg TYPE ekKO-ekorg, waers TYPE ekko-waers, pstyp TYPE ekpo-pstyp, esokz TYPE a017-esokz, mwskz TYPE ekpo-mwskz, zjss TYPE zmmt004-zjss, zjsje TYPE zmmt004-zjsje, meins TYPE ekpo-meins, zwrbtr1_line TYPE zmms004-zwrbtr1, zwrbtr2_line TYPE zmms004-zwrbtr2, gjahr TYPE ekbe-gjahr, belnr TYPE ekbe-belnr, buzei TYPE ekbe-buzei, END OF ts_typ. DATA: lt_zmmt004_temp TYPE TABLE OF ts_typ WITH HEADER LINE. DATA: lv_zwrbtr1_LINE TYPE zmms004-zwrbtr. DATA: lv_zwrbtr2_LINE TYPE zmms004-zwrbtr. DATA: lt_zmmt004 TYPE TABLE OF ts_data. DATA: lv_count TYPE int4. DATA: BEGIN OF lt_tax_rate OCCURS 0, mwskz TYPE ekpo-mwskz, kbetr TYPE konp-kbetr, END OF lt_tax_rate. DATA: lv_memory_id TYPE char50. DATA: lv_if_interface TYPE c. CONSTANTS: lc_failed TYPE string VALUE '接口调用失败', lc_successed TYPE string VALUE '接口调用成功', lc_part TYPE string VALUE '接口调用部分成功,部分失败,'. DATA: lt_zmmt006_update TYPE TABLE OF zmmt006 WITH HEADER LINE. DATA: BEGIN OF ls_update, zname TYPE zmmt006-zname, zdate TYPE zmmt006-zdate, ztime TYPE zmmt006-ztime, END OF ls_update. DATA: lv_if_failed TYPE c, lv_if_successful TYPE c. INCLUDE zfunc_top."定义抬头文件 INCLUDE zfunc_begin."记录接收数据 e_code = 'E'. e_msg = lc_failed. "check SORT it_tab[] BY zdzd zdzdh. CLEAR lv_count. CLEAR lt_out_temp[]. CLEAR lt_out[]. LOOP AT it_tab ASSIGNING FIELD-SYMBOL(<ls_tab>). <ls_tab>-zdzdh = |{ <ls_tab>-zdzdh ALPHA = IN }|. AT NEW zdzdh. CLEAR lv_count. CLEAR lt_out_temp[]. ENDAT. lv_count = lv_count + 1. CLEAR lt_out_temp. lt_out_temp-zdzd = <ls_tab>-zdzd. lt_out_temp-zdzdh = <ls_tab>-zdzdh. APPEND lt_out_temp. AT END OF zdzdh. IF lv_count NE 1. lt_out_temp-type = 'E'. lt_out_temp-message = '对账单重复,请检查。'. MODIFY lt_out_temp TRANSPORTING type message WHERE zdzd IS NOT INITIAL . APPEND LINES OF lt_out_temp[] TO lt_out[]. ELSE. IF <ls_tab>-zwrbtr2 NE ( <ls_tab>-zwrbtr + <ls_tab>-zwrbtr1 ). lt_out_temp-type = 'E'. lt_out_temp-message = '该行对账单借贷不平,请检查。'. MODIFY lt_out_temp TRANSPORTING type message WHERE zdzd IS NOT INITIAL . APPEND LINES OF lt_out_temp[] TO lt_out[]. ELSE. IF NOT ( ( <ls_tab>-zwrbtr GT 0 AND <ls_tab>-zwrbtr1 GT 0 AND <ls_tab>-zwrbtr2 GT 0 ) OR ( <ls_tab>-zwrbtr LT 0 AND <ls_tab>-zwrbtr1 LT 0 AND <ls_tab>-zwrbtr2 LT 0 ) ). lt_out_temp-type = 'E'. lt_out_temp-message = '该行对账单的金额正负号必须一致,请检查。'. MODIFY lt_out_temp TRANSPORTING type message WHERE zdzd IS NOT INITIAL . APPEND LINES OF lt_out_temp[] TO lt_out[]. ENDIF. ENDIF. ENDIF. ENDAT. ENDLOOP. IF lt_out[] IS NOT INITIAL. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. "SET TAXCODE RATE CLEAR lt_tax_rate[]. lt_tax_rate-mwskz = 'J0'. lt_tax_rate-kbetr = '0'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J1'. lt_tax_rate-kbetr = '170'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J2'. lt_tax_rate-kbetr = '160'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J3'. lt_tax_rate-kbetr = '130'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J4'. lt_tax_rate-kbetr = '110'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J5'. lt_tax_rate-kbetr = '100'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J6'. lt_tax_rate-kbetr = '90'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J7'. lt_tax_rate-kbetr = '70'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J8'. lt_tax_rate-kbetr = '60'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'J9'. lt_tax_rate-kbetr = '50'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'JA'. lt_tax_rate-kbetr = '40'. APPEND lt_tax_rate. lt_tax_rate-mwskz = 'JB'. lt_tax_rate-kbetr = '30'. APPEND lt_tax_rate. SORT lt_tax_rate[] BY mwskz. CLEAR lt_input. lt_input = it_tab[]. SELECT c~bukrs, b~lifnr, b~matnr, a~zdzd, a~zdzdh, b~zjss, a~zfbdt, a~bldat, a~zwrbtr, a~zwrbtr1, a~zwrbtr2, a~sgtxt FROM @lt_input AS a JOIN zmmt002 AS b ON a~zdzd EQ b~zdzd AND a~zdzdh EQ b~zdzdh JOIN t001k AS c ON b~werks EQ c~bwkey WHERE b~zjss NE @lv_zjss_initial INTO TABLE @DATA(lt_zmmt002). IF sy-subrc NE 0. CLEAR lt_out[]. LOOP AT it_tab. CLEAR lt_out. lt_out-zdzd = it_tab-zdzd. lt_out-zdzdh = it_tab-zdzdh. lt_out-type = 'E'. lv_msg = |未发现对账单数据,请检查底表ZMMT002。|. lt_out-message = lv_msg. APPEND lt_out. ENDLOOP. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. CLEAR lt_out[]. SELECT a~zdzd, a~zdzdH FROM zmmt006 AS a JOIN @lt_input AS b ON a~zdzd EQ b~zdzd AND a~zdzdH EQ b~zdzdh WHERE a~zif_miro EQ 'X' INTO TABLE @DATA(lt_zmmt006_exist). IF sy-subrc EQ 0. LOOP AT lt_zmmt006_exist INTO DATA(ls_zmmt006_exist). CLEAR lt_out. lt_out-zdzd = ls_zmmt006_exist-zdzd. lt_out-zdzdh = ls_zmmt006_exist-zdzdh. lt_out-type = 'E'. lv_msg = |该对账单已经完成发票校验,请勿重复推送。|. lt_out-message = lv_msg. APPEND lt_out. ENDLOOP. ENDIF. IF lt_out[] IS NOT INITIAL. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. DATA: lt_relation LIKE lt_zmmt002 WITH HEADER LINE. lt_relation[] = lt_zmmt002. DATA: BEGIN OF lt_zmmt002_sum OCCURS 0, bukrs TYPE zmmt002-werks, lifnr TYPE zmmt002-lifnr, matnr TYPE zmmt002-matnr, zjss TYPE zmmt002-zjss, zwrbtr TYPE zmms004-zwrbtr, zwrbtr1 TYPE zmms004-zwrbtr1, zwrbtr2 TYPE zmms004-zwrbtr2, END OF lt_zmmt002_sum. DATA: lt_zmmt002_sum_a LIKE TABLE OF lt_zmmt002_sum WITH HEADER LINE, lt_zmmt002_sum_b LIKE TABLE OF lt_zmmt002_sum WITH HEADER LINE. DATA: lv_tabix TYPE int4. "合计同一公司代码,供应商,物料下的结算数量,金额 CLEAR lt_zmmt002_sum[]. LOOP AT lt_zmmt002 ASSIGNING FIELD-SYMBOL(<ls_zmmt002>). <ls_zmmt002>-lifnr = |{ <ls_zmmt002>-lifnr ALPHA = IN WIDTH = 10 }|. <ls_zmmt002>-matnr = |{ <ls_zmmt002>-matnr ALPHA = IN WIDTH = 18 }|. CLEAR lt_zmmt002_sum. MOVE-CORRESPONDING <ls_zmmt002> TO lt_zmmt002_sum. COLLECT lt_zmmt002_sum. IF <ls_zmmt002>-zwrbtr LT 0. CLEAR lt_zmmt002_sum_a. MOVE-CORRESPONDING <ls_zmmt002> TO lt_zmmt002_sum_a. COLLECT lt_zmmt002_sum_a. ELSE. CLEAR lt_zmmt002_sum_b. MOVE-CORRESPONDING <ls_zmmt002> TO lt_zmmt002_sum_b. COLLECT lt_zmmt002_sum_b. ENDIF. ENDLOOP. SORT lt_zmmt002_sum[] BY bukrs lifnr matnr. SORT lt_zmmt002_sum_a[] BY bukrs lifnr matnr. SORT lt_zmmt002_sum_b[] BY bukrs lifnr matnr. DATA: lv_zwrbtr_sum TYPE zmms004-zwrbtr, lv_zwrbtr1_sum TYPE zmms004-zwrbtr1, lv_zwrbtr2_sum TYPE zmms004-zwrbtr2. "汇总结算数量小于0,且金额合计大于0时,校正汇总(按照公司代码,供应商,物料维度)金额, "用对应维度汇总金额为正的减去汇总金额为负的得到对应金额作为更新值 CLEAR lt_out[]. LOOP AT lt_zmmt002_sum ASSIGNING FIELD-SYMBOL(<ls_zmmt002_sum>) WHERE zjss LT 0 AND zwrbtr GT 0. DELETE lt_zmmt002 WHERE bukrs EQ <ls_zmmt002_sum>-bukrs AND lifnr EQ <ls_zmmt002_sum>-lifnr AND matnr EQ <ls_zmmt002_sum>-matnr AND zwrbtr LT 0 . IF sy-subrc NE 0. LOOP AT lt_zmmt002 INTO DATA(ls_zmmt002) WHERE bukrs EQ <ls_zmmt002_sum>-bukrs AND lifnr EQ <ls_zmmt002_sum>-lifnr AND matnr EQ <ls_zmmt002_sum>-matnr. CLEAR lt_out. lt_out-zdzd = ls_zmmt002-zdzd. lt_out-zdzdh = ls_zmmt002-zdzdh. lt_out-type = 'E'. lv_msg = |该对账单必须传入含有金额为负的数据行,请检查。|. lt_out-message = lv_msg. APPEND lt_out. ENDLOOP. ELSE. CLEAR lt_zmmt002_sum_a. READ TABLE lt_zmmt002_sum_a WITH KEY bukrs = <ls_zmmt002_sum>-bukrs lifnr = <ls_zmmt002_sum>-lifnr matnr = <ls_zmmt002_sum>-matnr BINARY SEARCH. CLEAR lt_zmmt002_sum_b. READ TABLE lt_zmmt002_sum_b WITH KEY bukrs = <ls_zmmt002_sum>-bukrs lifnr = <ls_zmmt002_sum>-lifnr matnr = <ls_zmmt002_sum>-matnr BINARY SEARCH. <ls_zmmt002_sum>-zwrbtr = lt_zmmt002_sum_b-zwrbtr + lt_zmmt002_sum_a-zwrbtr. <ls_zmmt002_sum>-zwrbtr1 = lt_zmmt002_sum_b-zwrbtr1 + lt_zmmt002_sum_a-zwrbtr1. <ls_zmmt002_sum>-zwrbtr2 = lt_zmmt002_sum_b-zwrbtr2 + lt_zmmt002_sum_a-zwrbtr2. ENDIF. ENDLOOP. IF lt_out[] IS NOT INITIAL. SORT lt_out[] BY zdzd zdzdh. DELETE ADJACENT DUPLICATES FROM lt_out[] COMPARING zdzd zdzdh. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. DATA: lv_zjss_type TYPE zmmt002-zjss. DATA: lt_zmmt002_distinct LIKE lt_zmmt002. "去重(公司代码,供应商,物料),因为不同对账单行可能对应相同的公司代码,供应商,物料的组合, "但是后续 1)抓取未清数量是以公司代码,供应商,物料为维度获取, " 2)发票校验又是以供应商,采购订单类别的维度去执行的, "遂防止数量double叠加,去重公司代码,供应商,物料 lt_zmmt002_distinct = lt_zmmt002. SORT lt_zmmt002_distinct BY bukrs lifnr matnr. DELETE ADJACENT DUPLICATES FROM lt_zmmt002_distinct COMPARING bukrs lifnr matnr. "获取未清的采购订单 SELECT a~ebeln, b~ebelp, a~bukrs, a~lifnr, b~matnr, c~vgabe, a~bedat, a~lastchangedatetime, c~shkzg, c~menge, c~gjahr, c~belnr, c~buzei, c~lfgja, c~lfbnr, c~lfpos, c~bwart, d~zdzd, d~zdzdh, d~zfbdt, d~bldat, d~zwrbtr, d~zwrbtr1, d~zwrbtr2, d~sgtxt, b~werks, a~ekorg, a~waers, b~pstyp AS esokz, b~mwskz, b~meins, CASE a~ebeln WHEN ' ' THEN @( lv_zjss_type ) ELSE @( lv_zjss_type ) END AS zjss FROM ekko AS a JOIN ekpo AS b ON a~ebeln EQ b~ebeln JOIN ekbe AS c ON b~ebeln EQ c~ebeln AND b~ebelp EQ c~ebelp JOIN @lt_zmmt002_distinct AS d ON a~bukrs EQ d~bukrs AND a~lifnr EQ d~lifnr AND b~matnr EQ d~matnr WHERE a~loekz EQ ' ' AND b~loekz EQ ' ' AND c~vgabe IN ( '1', '2' ) INTO TABLE @DATA(lt_tab). IF sy-subrc NE 0. CLEAR lt_out[]. LOOP AT it_tab. CLEAR lt_out. lt_out-zdzd = it_tab-zdzd. lt_out-zdzdh = it_tab-zdzdh. lt_out-type = 'E'. lv_msg = |未发现符合条件的采购订单数据,请检查。|. lt_out-message = lv_msg. APPEND lt_out. ENDLOOP. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. DATA: lt_tab_temp LIKE lt_tab WITH HEADER LINE. DATA: lt_tab_temp_local LIKE lt_tab WITH HEADER LINE. DATA: lv_menge TYPE ekbe-menge. DATA: lv_mengex TYPE ekbe-menge. "计算未清发票数量 SORT lt_tab BY ebeln ebelp bukrs lifnr matnr vgabe. "先根据 S- H, 事务类型1(收货) - 事务类型2 (发票)获取总的未清的采购订单数量 CLEAR: lt_tab_temp[],lt_tab_temp. CLEAR: lt_tab_temp_local[],lt_tab_temp_local. LOOP AT lt_tab ASSIGNING FIELD-SYMBOL(<ls_tabx>). IF <ls_tabx>-shkzg EQ 'S'. lv_menge = lv_menge + <ls_tabx>-menge. ELSE. lv_menge = lv_menge + <ls_tabx>-menge * ( -1 ). ENDIF. AT END OF vgabe. IF <ls_tabx>-vgabe EQ 1. lv_mengex = lv_mengex + lv_menge. ELSE. lv_mengex = lv_mengex - lv_menge. ENDIF. CLEAR lv_menge. AT END OF matnr. "合计后未清数量为0的采购订单去除,不考虑 IF lv_mengex IS NOT INITIAL. lt_tab_temp_local = <ls_tabx>. lt_tab_temp_local-menge = lv_mengex. APPEND lt_tab_temp_local. ENDIF. CLEAR: lt_tab_temp_local. CLEAR lv_mengex. ENDAT. ENDAT. ENDLOOP. DATA: ls_tabx LIKE LINE OF lt_tab. DATA: lt_tab_2 LIKE lt_tab WITH HEADER LINE. SORT lt_tab_temp_local[] BY ebeln ebelp bukrs lifnr matnr. "合计后未清数量为0的采购订单去除, "此处是删除明细的采购订单数据 LOOP AT lt_tab INTO ls_tabx. lv_tabix = sy-tabix. READ TABLE lt_tab_temp_local TRANSPORTING NO FIELDS WITH KEY ebeln = ls_tabx-ebeln ebelp = ls_tabx-ebelp bukrs = ls_tabx-bukrs lifnr = ls_tabx-lifnr matnr = ls_tabx-matnr BINARY SEARCH. CHECK sy-subrc NE 0. DELETE lt_tab INDEX lv_tabix. ENDLOOP. "获取事务类型2 的采购数据(发票校验数据),以便后续用于扣除计算收货数量得到明细行的未清数量 lt_tab_2[] = VALUE #( FOR wa IN lt_tab WHERE ( vgabe = '2' ) ( wa ) ). DELETE lt_tab WHERE vgabe EQ '2'. SORT lt_tab BY ebeln ebelp bukrs lifnr matnr gjahr belnr buzei. SORT lt_tab_2[] BY ebeln ebelp bukrs lifnr matnr lfgja lfbnr lfpos. LOOP AT lt_tab_temp_local. IF lt_tab_temp_local-menge GT 0. "非60的采购订单,逐行计算每一行剩余的未清的采购订单 LOOP AT lt_tab ASSIGNING <ls_tabx> WHERE ebeln EQ lt_tab_temp_local-ebeln AND ebelp EQ lt_tab_temp_local-ebelp AND bukrs EQ lt_tab_temp_local-bukrs AND lifnr EQ lt_tab_temp_local-lifnr AND matnr EQ lt_tab_temp_local-matnr AND vgabe EQ '1'. IF <ls_tabx>-shkzg EQ 'H'. READ TABLE lt_tab TRANSPORTING NO FIELDS WITH KEY ebeln = <ls_tabx>-ebeln ebelp = <ls_tabx>-ebelp bukrs = <ls_tabx>-bukrs lifnr = <ls_tabx>-lifnr matnr = <ls_tabx>-matnr gjahr = <ls_tabx>-lfgja belnr = <ls_tabx>-lfbnr buzei = <ls_tabx>-lfpos BINARY SEARCH. IF sy-subrc EQ 0. DELETE lt_tab INDEX sy-tabix. ENDIF. ELSE. lv_tabix = sy-tabix. LOOP AT lt_tab_2 INTO ls_tabx WHERE ebeln = <ls_tabx>-ebeln AND ebelp = <ls_tabx>-ebelp AND bukrs = <ls_tabx>-bukrs AND lifnr = <ls_tabx>-lifnr AND matnr = <ls_tabx>-matnr AND lfgja = <ls_tabx>-gjahr AND lfbnr = <ls_tabx>-belnr AND lfpos = <ls_tabx>-buzei . IF ls_tabx-shkzg EQ 'S'. <ls_tabx>-menge = <ls_tabx>-menge - ls_tabx-menge. ELSE. <ls_tabx>-menge = <ls_tabx>-menge + ls_tabx-menge. ENDIF. ENDLOOP. IF <ls_tabx>-menge IS INITIAL. DELETE lt_tab INDEX lv_tabix. ENDIF. ENDIF. ENDLOOP. DELETE lt_tab WHERE ebeln EQ lt_tab_temp_local-ebeln AND ebelp EQ lt_tab_temp_local-ebelp AND bukrs EQ lt_tab_temp_local-bukrs AND lifnr EQ lt_tab_temp_local-lifnr AND matnr EQ lt_tab_temp_local-matnr AND vgabe EQ '1' AND shkzg EQ 'H' . ELSE. "60的采购订单,逐行计算每一行剩余的未清的采购订单 LOOP AT lt_tab ASSIGNING <ls_tabx> WHERE ebeln EQ lt_tab_temp_local-ebeln AND ebelp EQ lt_tab_temp_local-ebelp AND bukrs EQ lt_tab_temp_local-bukrs AND lifnr EQ lt_tab_temp_local-lifnr AND matnr EQ lt_tab_temp_local-matnr AND vgabe EQ '1'. IF <ls_tabx>-shkzg EQ 'S'. READ TABLE lt_tab TRANSPORTING NO FIELDS WITH KEY ebeln = <ls_tabx>-ebeln ebelp = <ls_tabx>-ebelp bukrs = <ls_tabx>-bukrs lifnr = <ls_tabx>-lifnr matnr = <ls_tabx>-matnr gjahr = <ls_tabx>-lfgja belnr = <ls_tabx>-lfbnr buzei = <ls_tabx>-lfpos BINARY SEARCH. IF sy-subrc EQ 0. DELETE lt_tab INDEX sy-tabix. ENDIF. ELSE. lv_tabix = sy-tabix. LOOP AT lt_tab_2 INTO ls_tabx WHERE ebeln = <ls_tabx>-ebeln AND ebelp = <ls_tabx>-ebelp AND bukrs = <ls_tabx>-bukrs AND lifnr = <ls_tabx>-lifnr AND matnr = <ls_tabx>-matnr AND lfgja = <ls_tabx>-gjahr AND lfbnr = <ls_tabx>-belnr AND lfpos = <ls_tabx>-buzei . IF ls_tabx-shkzg EQ 'H'. <ls_tabx>-menge = <ls_tabx>-menge - ls_tabx-menge. ELSE. <ls_tabx>-menge = <ls_tabx>-menge + ls_tabx-menge. ENDIF. ENDLOOP. IF <ls_tabx>-menge IS INITIAL. DELETE lt_tab INDEX lv_tabix. ENDIF. ENDIF. ENDLOOP. DELETE lt_tab WHERE ebeln EQ lt_tab_temp_local-ebeln AND ebelp EQ lt_tab_temp_local-ebelp AND bukrs EQ lt_tab_temp_local-bukrs AND lifnr EQ lt_tab_temp_local-lifnr AND matnr EQ lt_tab_temp_local-matnr AND vgabe EQ '1' AND shkzg EQ 'S'. ENDIF. ENDLOOP. "对于非60采购订单,剩余的一定是S行, "对于60采购订单,剩余的一定是H行,数量乘以 -1 LOOP AT lt_tab ASSIGNING <ls_tabx> WHERE shkzg EQ 'H'. <ls_tabx>-menge = <ls_tabx>-menge * ( -1 ). ENDLOOP. CLEAR lt_tab_temp[]. MOVE-CORRESPONDING lt_tab TO lt_tab_temp[]. "由于该发票校验是基于收货的采购订单, "故得到所有移动类型的未清数量后,再次过滤得到101 161的采购订单数据 DELETE lt_tab_temp[] WHERE bwart NE '101' AND bwart NE '161'. ********************************************************************** " 需求变更 合计结算数量小于0,金额也小于0时该种情况下金额摊走 "以下为原逻辑注释 20220825 * "合计结算数量小于0,金额也小于0时,取到的必有60贷项采购订单,否则报错 * CLEAR lt_out[]. * LOOP AT lt_zmmt002_sum WHERE zjss LT 0 AND zwrbtr LT 0. * LOOP AT lt_tab_temp WHERE bukrs EQ lt_zmmt002_sum-bukrs * AND lifnr EQ lt_zmmt002_sum-lifnr * AND matnr EQ lt_zmmt002_sum-matnr * AND ebeln(2) EQ '60' . * EXIT. * ENDLOOP. * IF sy-subrc NE 0. * LOOP AT lt_tab_temp WHERE bukrs EQ lt_zmmt002_sum-bukrs * AND lifnr EQ lt_zmmt002_sum-lifnr * AND matnr EQ lt_zmmt002_sum-matnr. * * CLEAR lt_out. * lt_out-zdzd = lt_tab_temp-zdzd. * lt_out-zdzdh = lt_tab_temp-zdzdh. * lt_out-type = 'E'. * lv_msg = |未发现贷项60开头的采购订单数据,请检查。|. * lt_out-message = lv_msg. * APPEND lt_out. * * ENDLOOP. * ENDIF. * * ENDLOOP. * IF lt_out[] IS NOT INITIAL. * SORT lt_out[] BY zdzd zdzdh. * DELETE ADJACENT DUPLICATES FROM lt_out[] COMPARING zdzd zdzdh. * et_tab[] = lt_out[]. * PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. * INCLUDE zfunc_end."记录返回数据 * RETURN. * ENDIF. DATA: BEGIN OF lt_bukrs_lifnr_tab OCCURS 0, bukrs TYPE zmmt002-werks, lifnr TYPE zmmt002-lifnr, flag TYPE c, END OF lt_bukrs_lifnr_tab. DATA: lt_zmmt002_sum_temp LIKE TABLE OF lt_zmmt002_sum WITH HEADER LINE . DATA: lt_zmmt002_sum_temp_a LIKE TABLE OF lt_zmmt002_sum WITH HEADER LINE . DATA: lt_zmmt002_sum_temp_b LIKE TABLE OF lt_zmmt002_sum WITH HEADER LINE . DATA: lt_zmmt002_sum_temp_b_details LIKE TABLE OF lt_zmmt002_sum WITH HEADER LINE . DATA: BEGIN OF lt_tab_key OCCURS 0, bukrs TYPE zmmt002-werks, lifnr TYPE zmmt002-lifnr, END OF lt_tab_key. LOOP AT lt_zmmt002_sum WHERE zjss LT 0 AND zwrbtr LT 0. lt_tab_key-bukrs = lt_zmmt002_sum-bukrs. lt_tab_key-lifnr = lt_zmmt002_sum-lifnr. APPEND lt_tab_key. CLEAR lt_tab_key. ENDLOOP. CLEAR lt_bukrs_lifnr_tab[]. CLEAR lv_tabix. SORT lt_tab_key[] BY bukrs lifnr. DELETE ADJACENT DUPLICATES FROM lt_tab_key[] COMPARING bukrs lifnr. LOOP AT lt_tab_key. LOOP AT lt_zmmt002_sum WHERE bukrs EQ lt_tab_key-bukrs AND lifnr EQ lt_tab_key-lifnr. lv_tabix = sy-tabix. CLEAR lt_zmmt002_sum_temp. lt_zmmt002_sum_temp-bukrs = lt_zmmt002_sum-bukrs. lt_zmmt002_sum_temp-lifnr = lt_zmmt002_sum-lifnr. lt_zmmt002_sum_temp-zwrbtr = lt_zmmt002_sum-zwrbtr . lt_zmmt002_sum_temp-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_zmmt002_sum_temp-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. COLLECT lt_zmmt002_sum_temp. IF lt_zmmt002_sum-zwrbtr LT 0. CLEAR lt_zmmt002_sum_temp_a. lt_zmmt002_sum_temp_a-bukrs = lt_zmmt002_sum-bukrs. lt_zmmt002_sum_temp_a-lifnr = lt_zmmt002_sum-lifnr. lt_zmmt002_sum_temp_a-zwrbtr = lt_zmmt002_sum-zwrbtr . lt_zmmt002_sum_temp_a-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_zmmt002_sum_temp_a-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. COLLECT lt_zmmt002_sum_temp_a. lt_bukrs_lifnr_tab-bukrs = lt_zmmt002_sum-bukrs. lt_bukrs_lifnr_tab-lifnr = lt_zmmt002_sum-lifnr. APPEND lt_bukrs_lifnr_tab. DELETE lt_zmmt002_sum[] INDEX lv_tabix. ELSEIF lt_zmmt002_sum-zwrbtr GT 0. CLEAR lt_zmmt002_sum_temp_b. lt_zmmt002_sum_temp_b-bukrs = lt_zmmt002_sum-bukrs. lt_zmmt002_sum_temp_b-lifnr = lt_zmmt002_sum-lifnr. lt_zmmt002_sum_temp_b-zwrbtr = lt_zmmt002_sum-zwrbtr . lt_zmmt002_sum_temp_b-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_zmmt002_sum_temp_b-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. COLLECT lt_zmmt002_sum_temp_b. CLEAR lt_zmmt002_sum_temp_b_details. lt_zmmt002_sum_temp_b_details = lt_zmmt002_sum. APPEND lt_zmmt002_sum_temp_b_details. ENDIF. ENDLOOP. ENDLOOP. CLEAR lt_out[]. LOOP AT lt_zmmt002_sum_temp WHERE zwrbtr LE 0. LOOP AT lt_zmmt002_sum WHERE bukrs EQ lt_zmmt002_sum_temp-bukrs AND lifnr EQ lt_zmmt002_sum_temp-lifnr. LOOP AT lt_zmmt002 INTO ls_zmmt002 WHERE bukrs EQ lt_zmmt002_sum-bukrs AND lifnr EQ lt_zmmt002_sum-lifnr AND matnr EQ lt_zmmt002_sum-matnr. lt_out-zdzd = ls_zmmt002-zdzd. lt_out-zdzdh = ls_zmmt002-zdzdh. lt_out-type = 'E'. lv_msg = |结算数量为负数,结算金额小于0,按照公司代码+供应商汇总金额必须大于0|. lt_out-message = lv_msg. APPEND lt_out. ENDLOOP. ENDLOOP. ENDLOOP. IF lt_out[] IS NOT INITIAL. SORT lt_out[] BY zdzd zdzdh. DELETE ADJACENT DUPLICATES FROM lt_out[] COMPARING zdzd zdzdh. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. SORT lt_bukrs_lifnr_tab[] BY bukrs lifnr. DELETE ADJACENT DUPLICATES FROM lt_bukrs_lifnr_tab[] COMPARING ALL FIELDS. SORT lt_zmmt002_sum_temp_b[] BY bukrs lifnr. SORT lt_zmmt002_sum_temp_a[] BY bukrs lifnr. "根据公司代码,供应商汇总后,金额大于0时,将原来的金额小于0的按照大于0的金额的加权比列分摊扣减至大于0的金额 SORT lt_zmmt002_sum_temp_b_details[] BY bukrs lifnr zwrbtr. LOOP AT lt_zmmt002_sum_temp_b_details ASSIGNING FIELD-SYMBOL(<ls_zmmt002_sum_details>). AT NEW lifnr. CLEAR: lv_zwrbtr_sum,lv_zwrbtr1_sum,lv_zwrbtr2_sum. CLEAR lt_zmmt002_sum_temp_b. READ TABLE lt_zmmt002_sum_temp_b WITH KEY bukrs = <ls_zmmt002_sum_details>-bukrs lifnr = <ls_zmmt002_sum_details>-lifnr BINARY SEARCH. CLEAR lt_zmmt002_sum_temp_a. READ TABLE lt_zmmt002_sum_temp_a WITH KEY bukrs = <ls_zmmt002_sum_details>-bukrs lifnr = <ls_zmmt002_sum_details>-lifnr BINARY SEARCH. ENDAT. AT END OF lifnr. <ls_zmmt002_sum_details>-zwrbtr = <ls_zmmt002_sum_details>-zwrbtr - ( lv_zwrbtr_sum - lt_zmmt002_sum_temp_a-zwrbtr ). <ls_zmmt002_sum_details>-zwrbtr1 = <ls_zmmt002_sum_details>-zwrbtr1 - ( lv_zwrbtr1_sum - lt_zmmt002_sum_temp_a-zwrbtr1 ). <ls_zmmt002_sum_details>-zwrbtr2 = <ls_zmmt002_sum_details>-zwrbtr2 - ( lv_zwrbtr2_sum - lt_zmmt002_sum_temp_a-zwrbtr2 ). CONTINUE. ENDAT. lv_zwrbtr_sum = lv_zwrbtr_sum + ( <ls_zmmt002_sum_details>-zwrbtr / lt_zmmt002_sum_temp_b-zwrbtr ) * lt_zmmt002_sum_temp_a-zwrbtr. lv_zwrbtr1_sum = lv_zwrbtr1_sum + ( <ls_zmmt002_sum_details>-zwrbtr1 / lt_zmmt002_sum_temp_b-zwrbtr1 ) * lt_zmmt002_sum_temp_a-zwrbtr1. lv_zwrbtr2_sum = lv_zwrbtr2_sum + ( <ls_zmmt002_sum_details>-zwrbtr2 / lt_zmmt002_sum_temp_b-zwrbtr2 ) * lt_zmmt002_sum_temp_a-zwrbtr2. <ls_zmmt002_sum_details>-zwrbtr = <ls_zmmt002_sum_details>-zwrbtr + ( <ls_zmmt002_sum_details>-zwrbtr / lt_zmmt002_sum_temp_b-zwrbtr ) * lt_zmmt002_sum_temp_a-zwrbtr. <ls_zmmt002_sum_details>-zwrbtr1 = <ls_zmmt002_sum_details>-zwrbtr1 + ( <ls_zmmt002_sum_details>-zwrbtr1 / lt_zmmt002_sum_temp_b-zwrbtr1 ) * lt_zmmt002_sum_temp_a-zwrbtr1. <ls_zmmt002_sum_details>-zwrbtr2 = <ls_zmmt002_sum_details>-zwrbtr2 + ( <ls_zmmt002_sum_details>-zwrbtr2 / lt_zmmt002_sum_temp_b-zwrbtr2 ) * lt_zmmt002_sum_temp_a-zwrbtr2. ENDLOOP. IF lt_zmmt002_sum_temp_b_details[] IS NOT INITIAL. SORT lt_zmmt002_sum[] BY bukrs lifnr matnr. LOOP AT lt_zmmt002_sum_temp_b_details. READ TABLE lt_zmmt002_sum ASSIGNING <ls_zmmt002_sum> WITH KEY bukrs = lt_zmmt002_sum_temp_b_details-bukrs lifnr = lt_zmmt002_sum_temp_b_details-lifnr matnr = lt_zmmt002_sum_temp_b_details-matnr BINARY SEARCH. CHECK sy-subrc EQ 0. <ls_zmmt002_sum>-zwrbtr = lt_zmmt002_sum_temp_b_details-zwrbtr. <ls_zmmt002_sum>-zwrbtr1 = lt_zmmt002_sum_temp_b_details-zwrbtr1. <ls_zmmt002_sum>-zwrbtr2 = lt_zmmt002_sum_temp_b_details-zwrbtr2. ENDLOOP. ENDIF. ********************************************************************** DATA: lt_tab_temp_x LIKE lt_tab WITH HEADER LINE. CLEAR lt_out[]. SORT lt_tab_temp[] BY bukrs lifnr matnr bedat lastchangedatetime ebeln ebelp. "获取参与抵减的结算数量,以及对应的汇总(基于公司代码,供应商)后的结算金额,税额,含税金额,以及采购订单相关信息 "备注:按照采购订单的创建时间的先后顺序 CLEAR:lv_iferror_flg. CLEAR lv_msg. CLEAR lv_menge. CLEAR lv_mengex. CLEAR lv_tabix. LOOP AT lt_zmmt002_sum. lv_tabix = sy-tabix. IF lt_zmmt002_sum-zjss IS INITIAL. DELETE lt_zmmt002_sum[] INDEX lv_tabix. ELSEIF lt_zmmt002_sum-zjss LT 0. IF lt_zmmt002_sum-zwrbtr GT 0. CLEAR lt_zmmt002_sum_b. READ TABLE lt_zmmt002_sum_b WITH KEY bukrs = lt_zmmt002_sum-bukrs lifnr = lt_zmmt002_sum-lifnr matnr = lt_zmmt002_sum-matnr BINARY SEARCH. LOOP AT lt_tab_temp WHERE bukrs = lt_zmmt002_sum-bukrs AND lifnr = lt_zmmt002_sum-lifnr AND matnr = lt_zmmt002_sum-matnr. lt_zmmt002_sum_b-zjss = lt_zmmt002_sum_b-zjss - lt_tab_temp-menge. IF lt_zmmt002_sum_b-zjss GE 0. CLEAR lt_tab_temp_x. lt_tab_temp_x = lt_tab_temp. lt_tab_temp_x-zjss = lt_tab_temp-menge. lt_tab_temp_x-zwrbtr = lt_zmmt002_sum-zwrbtr. lt_tab_temp_x-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_tab_temp_x-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. APPEND lt_tab_temp_x. IF lt_zmmt002_sum_b-zjss IS INITIAL. EXIT. ENDIF. ELSE. CLEAR lt_tab_temp_x. lt_tab_temp_x = lt_tab_temp. lt_tab_temp_x-menge = lt_tab_temp-menge + lt_zmmt002_sum_b-zjss. lt_tab_temp_x-zjss = lt_tab_temp_x-menge. lt_tab_temp_x-zwrbtr = lt_zmmt002_sum-zwrbtr. lt_tab_temp_x-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_tab_temp_x-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. APPEND lt_tab_temp_x. EXIT. ENDIF. ENDLOOP. IF lt_zmmt002_sum_b-zjss GT 0. lv_iferror_flg = 'B'. EXIT. ENDIF. ELSEIF lt_zmmt002_sum-zwrbtr LT 0. "该种条件下(汇总结算数量小于0,金额小于0,)由于前面的分摊扣减逻辑,理论上这段逻辑不会执行 LOOP AT lt_tab_temp WHERE bukrs = lt_zmmt002_sum-bukrs AND lifnr = lt_zmmt002_sum-lifnr AND matnr = lt_zmmt002_sum-matnr AND ebeln(2) EQ '60'. lt_zmmt002_sum-zjss = lt_zmmt002_sum-zjss - lt_tab_temp-menge. IF lt_zmmt002_sum-zjss LE 0. CLEAR lt_tab_temp_x. lt_tab_temp_x = lt_tab_temp. lt_tab_temp_x-zjss = lt_tab_temp-menge. lt_tab_temp_x-zwrbtr = lt_zmmt002_sum-zwrbtr. lt_tab_temp_x-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_tab_temp_x-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. APPEND lt_tab_temp_x. IF lt_zmmt002_sum-zjss IS INITIAL. EXIT. ENDIF. ELSE. CLEAR lt_tab_temp_x. lt_tab_temp_x = lt_tab_temp. lt_tab_temp_x-menge = lt_zmmt002_sum-zjss + lt_tab_temp-menge. lt_tab_temp_x-zjss = lt_tab_temp_x-menge. lt_tab_temp_x-zwrbtr = lt_zmmt002_sum-zwrbtr. lt_tab_temp_x-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_tab_temp_x-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. APPEND lt_tab_temp_x. EXIT. ENDIF. ENDLOOP. IF lt_zmmt002_sum-zjss LT 0. lv_iferror_flg = 'C'. EXIT. ENDIF. ENDIF. ELSE. LOOP AT lt_tab_temp WHERE bukrs = lt_zmmt002_sum-bukrs AND lifnr = lt_zmmt002_sum-lifnr AND matnr = lt_zmmt002_sum-matnr. lt_zmmt002_sum-zjss = lt_zmmt002_sum-zjss - lt_tab_temp-menge. IF lt_zmmt002_sum-zjss GE 0. CLEAR lt_tab_temp_x. lt_tab_temp_x = lt_tab_temp. lt_tab_temp_x-zjss = lt_tab_temp-menge. lt_tab_temp_x-zwrbtr = lt_zmmt002_sum-zwrbtr. lt_tab_temp_x-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_tab_temp_x-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. APPEND lt_tab_temp_x. IF lt_zmmt002_sum-zjss IS INITIAL. EXIT. ENDIF. ELSE. CLEAR lt_tab_temp_x. lt_tab_temp_x = lt_tab_temp. lt_tab_temp_x-menge = lt_tab_temp-menge + lt_zmmt002_sum-zjss. lt_tab_temp_x-zjss = lt_tab_temp_x-menge. lt_tab_temp_x-zwrbtr = lt_zmmt002_sum-zwrbtr. lt_tab_temp_x-zwrbtr1 = lt_zmmt002_sum-zwrbtr1. lt_tab_temp_x-zwrbtr2 = lt_zmmt002_sum-zwrbtr2. APPEND lt_tab_temp_x. EXIT. ENDIF. ENDLOOP. IF lt_zmmt002_sum-zjss GT 0. lv_iferror_flg = 'B'. EXIT. ENDIF. ENDIF. ENDLOOP. IF lv_iferror_flg IS NOT INITIAL. CLEAR:lt_out[],lt_out. LOOP AT lt_zmmt002 INTO ls_zmmt002. CLEAR lt_out. lt_out-zdzd = ls_zmmt002-zdzd. lt_out-zdzdh = ls_zmmt002-zdzdh. lt_out-lifnr = ls_zmmt002-lifnr. lt_out-type = 'E'. IF lv_iferror_flg EQ 'C'. * lv_msg = |结算数量为负,请检查。|. lv_msg = |创建60贷项凭证的结算数量不能大于未清发票数量,请检查。|. ELSE. lv_msg = |结算数量不能大于未清发票数量,请检查。|. ENDIF. lt_out-message = lv_msg. APPEND lt_out. ENDLOOP. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. MOVE-CORRESPONDING lt_tab_temp_x[] TO lt_zmmt004. DATA: lv_initlal TYPE zmmt004-zjsje . SELECT a~lifnr, a~matnr, a~ekorg, a~werks, a~esokz, b~knumh, c~kbetr, c~kpein FROM @lt_zmmt004 AS a JOIN a017 AS b ON a~lifnr EQ b~lifnr AND a~matnr EQ b~matnr AND a~ekorg EQ b~ekorg AND a~werks EQ b~werks AND a~esokz EQ b~esokz JOIN konp AS c ON b~knumh EQ c~knumh AND c~kschl EQ 'PB01' AND c~loevm_ko NE 'X' WHERE a~zjsje EQ @lv_initlal INTO TABLE @DATA(lt_konp). SORT lt_konp BY lifnr matnr ekorg werks esokz. ****************************************************************************************** "根据结算数量(未清发票数量)计算明细行(每一个采购订单)结算金额 LOOP AT lt_zmmt004 ASSIGNING FIELD-SYMBOL(<ls_zmmt004>). IF <ls_zmmt004>-ebeln(2) NE '60'. <ls_zmmt004>-zflg = 'A'. ELSE. <ls_zmmt004>-zflg = 'B'. ENDIF. CHECK <ls_zmmt004>-zjsje IS INITIAL. READ TABLE lt_konp INTO DATA(ls_konp) WITH KEY lifnr = <ls_zmmt004>-lifnr matnr = <ls_zmmt004>-matnr ekorg = <ls_zmmt004>-ekorg werks = <ls_zmmt004>-werks esokz = <ls_zmmt004>-esokz BINARY SEARCH. CHECK sy-subrc EQ 0. CHECK ls_konp-kpein NE 0. <ls_zmmt004>-zjsje = ls_konp-kbetr * <ls_zmmt004>-zjss / ls_konp-kpein. ENDLOOP. ****************************************************************************************** MOVE-CORRESPONDING lt_zmmt004 TO lt_zmmt004_temp[]. ****************************************************************************************** "根据公司代码,供应商,物料 修正每一行的结算金额,优先修正60的采购订单 SORT lt_zmmt002_sum[] BY bukrs lifnr matnr. SORT lt_zmmt004_temp[] BY bukrs lifnr matnr zflg DESCENDING lastchangedatetime ebeln ebelp zjsje. LOOP AT lt_zmmt004_temp ASSIGNING FIELD-SYMBOL(<ls_zmmt004_temp>). AT NEW matnr. CLEAR lt_zmmt002_sum. READ TABLE lt_zmmt002_sum WITH KEY bukrs = <ls_zmmt004_temp>-bukrs lifnr = <ls_zmmt004_temp>-lifnr matnr = <ls_zmmt004_temp>-matnr BINARY SEARCH. CLEAR lv_wrbtr_sum. ENDAT. AT END OF matnr. <ls_zmmt004_temp>-zjsje = <ls_zmmt004_temp>-zwrbtr - lv_wrbtr_sum. CONTINUE. ENDAT. <ls_zmmt004_temp>-zjsje = ( <ls_zmmt004_temp>-zjss / lt_zmmt002_sum-zjss ) * <ls_zmmt004_temp>-zwrbtr. lv_wrbtr_sum = lv_wrbtr_sum + ( <ls_zmmt004_temp>-zjss / lt_zmmt002_sum-zjss ) * <ls_zmmt004_temp>-zwrbtr. ENDLOOP. ****************************************************************************************** ****************************************************************************************** "根据公司代码,供应商,物料汇总后的金额 去分摊计算每一行采购订单的金额 "同时按照1, 优先60采购订单分摊, "2,其次按照采购订单创建的时间先后顺序去分摊 "3,再按照采购订单,金额大小排序 SORT lt_zmmt004_temp[] BY bukrs lifnr matnr zflg DESCENDING lastchangedatetime ebeln ebelp zjsje. LOOP AT lt_zmmt004_temp ASSIGNING <ls_zmmt004_temp>. AT NEW matnr. CLEAR lv_wrbtr_sum. CLEAR: lv_zwrbtr1_LINE,lv_zwrbtr2_LINE. ENDAT. lv_wrbtr_sum = lv_wrbtr_sum + <ls_zmmt004_temp>-zjsje. CLEAR lv_kbetr. CLEAR lt_tax_rate. READ TABLE lt_tax_rate WITH KEY mwskz = <ls_zmmt004_temp>-mwskz BINARY SEARCH. IF sy-subrc EQ 0. lv_kbetr = lt_tax_rate-kbetr. ELSE. SELECT SINGLE kbetr INTO lv_kbetr FROM konp WHERE kappl EQ 'TX' AND mwsk1 EQ <ls_zmmt004_temp>-mwskz AND kbetr NE space. ENDIF. lv_kbetr = lv_kbetr / 1000. <ls_zmmt004_temp>-zwrbtr1_line = <ls_zmmt004_temp>-zjsje * lv_kbetr. lv_zwrbtr1_LINE = lv_zwrbtr1_LINE + <ls_zmmt004_temp>-zwrbtr1_line . <ls_zmmt004_temp>-zwrbtr2_line = <ls_zmmt004_temp>-zjsje * lv_kbetr + <ls_zmmt004_temp>-zjsje. lv_zwrbtr2_LINE = lv_zwrbtr2_LINE + <ls_zmmt004_temp>-zwrbtr2_line. AT END OF matnr. IF lv_wrbtr_sum NE <ls_zmmt004_temp>-zwrbtr. <ls_zmmt004_temp>-zjsje = <ls_zmmt004_temp>-zjsje + ( <ls_zmmt004_temp>-zwrbtr - lv_wrbtr_sum ). ENDIF. IF lv_zwrbtr1_LINE NE <ls_zmmt004_temp>-zwrbtr1 . <ls_zmmt004_temp>-zwrbtr1_line = <ls_zmmt004_temp>-zwrbtr1_line + ( <ls_zmmt004_temp>-zwrbtr1 - lv_zwrbtr1_LINE ). ENDIF. IF lv_zwrbtr2_LINE NE <ls_zmmt004_temp>-zwrbtr2 . <ls_zmmt004_temp>-zwrbtr2_line = <ls_zmmt004_temp>-zwrbtr2_line + ( <ls_zmmt004_temp>-zwrbtr2 - lv_zwrbtr2_LINE ). ENDIF. ENDAT. ENDLOOP. ****************************************************************************************** CLEAR lt_zmmt004. MOVE-CORRESPONDING lt_zmmt004_temp[] TO lt_zmmt004. SELECT a~lifnr, b~lifn2, c~bu_sort1 FROM @lt_zmmt004 AS a JOIN wyt3 AS b ON a~lifnr EQ b~lifnr AND b~ekorg EQ '1000' AND b~parvw EQ 'RS' LEFT JOIN but000 AS c ON b~lifn2 EQ c~partner INTO TABLE @DATA(lt_wyt3). SORT lt_wyt3 BY lifnr. SELECT a~lifnr, b~bu_sort1 FROM @lt_zmmt004 AS a JOIN but000 AS b ON a~lifnr EQ b~partner INTO TABLE @DATA(lt_but000). SORT lt_but000 BY lifnr. SORT lt_zmmt004 BY lifnr zflg DESCENDING zdzd zdzdh zjsje. ************************************************************************************** DATA: lt_zmmt004_error_record TYPE TABLE OF ts_data WITH HEADER LINE. IF 1 EQ 2. "正式过账前先逐行模拟过账已检查错误 "该逐行校验比较耗时,遂不在SRM调用接口时执行,而是在ZFLG接口日志调试时分析使用 CLEAR lt_out[]. LOOP AT lt_zmmt004 ASSIGNING <ls_zmmt004>. CLEAR lv_iferror_lifnr_flg. CLEAR lv_numc. CLEAR lt_out_temp[]. CLEAR: lv_gross_amount. CLEAR: lv_item. lv_numc = lv_numc + 1. CLEAR: headerdata,itemdata[],taxdata[],itemdata,taxdata. ******************************************** "set item data lv_item = lv_item + 1. CLEAR itemdata. itemdata-invoice_doc_item = lv_item. itemdata-po_number = <ls_zmmt004>-ebeln. itemdata-po_item = <ls_zmmt004>-ebelp. itemdata-tax_code = <ls_zmmt004>-mwskz. itemdata-item_amount = abs( <ls_zmmt004>-zjsje ). itemdata-quantity = abs( <ls_zmmt004>-zjss ). itemdata-po_unit = <ls_zmmt004>-meins. itemdata-item_text = <ls_zmmt004>-sgtxt. itemdata-ref_doc = <ls_zmmt004>-belnr. itemdata-ref_doc_year = <ls_zmmt004>-gjahr. itemdata-ref_doc_it = <ls_zmmt004>-buzei. APPEND itemdata. taxdata-tax_amount = abs( <ls_zmmt004>-zwrbtr1_LINE ). APPEND taxdata. ******************************************** lv_gross_amount = lv_gross_amount + <ls_zmmt004>-zwrbtr2_line. "set rsp data LOOP AT lt_zmmt002 INTO ls_zmmt002 WHERE bukrs EQ <ls_zmmt004>-bukrs AND lifnr EQ <ls_zmmt004>-lifnr AND matnr EQ <ls_zmmt004>-matnr . CLEAR lt_out_temp. lt_out_temp-zdzd = ls_zmmt002-zdzd. lt_out_temp-zdzdh = ls_zmmt002-zdzdh. lt_out_temp-lifnr = ls_zmmt002-lifnr. lt_out_temp-numc = lv_numc. APPEND lt_out_temp. ENDLOOP. ******************************************** "set header data headerdata-simulation = 'X'. headerdata-doc_date = <ls_zmmt004>-bldat. headerdata-pstng_date = <ls_zmmt004>-bldat. ************************************************** * "过账日期特殊处理 * headerdata-doc_date = '20220831'. * headerdata-pstng_date = '20220831'. ************************************************** headerdata-comp_code = <ls_zmmt004>-bukrs. headerdata-currency = <ls_zmmt004>-waers. headerdata-gross_amount = lv_gross_amount. headerdata-gross_amount = abs( headerdata-gross_amount ) . IF <ls_zmmt004>-zflg EQ 'A'. headerdata-invoice_ind = 'X'. ELSE. CLEAR headerdata-invoice_ind. ENDIF. READ TABLE lt_wyt3 INTO DATA(ls_wyt3) WITH KEY lifnr = <ls_zmmt004>-lifnr BINARY SEARCH. IF ls_wyt3-lifnr NE ls_wyt3-lifn2 AND ls_wyt3-lifn2 IS NOT INITIAL. lv_bu_sort1 = ls_wyt3-bu_sort1. lv_lifnr = |{ ls_wyt3-lifn2 ALPHA = OUT }|. ELSE. READ TABLE lt_but000 INTO DATA(ls_but000) WITH KEY lifnr = <ls_zmmt004>-lifnr BINARY SEARCH. lv_bu_sort1 = ls_but000-bu_sort1. lv_lifnr = |{ ls_but000-lifnr ALPHA = OUT }|. ENDIF. headerdata-item_text = |欠{ lv_bu_sort1 }{ headerdata-pstng_date+4(2) ALPHA = OUT }月集中挂账货款|. CONDENSE headerdata-item_text NO-GAPS. headerdata-ref_doc_no = |{ headerdata-pstng_date+4(2) ALPHA = OUT }月{ lv_lifnr }挂账|. CONDENSE headerdata-ref_doc_no NO-GAPS. ******************************************** "用于后续 BTE增强(替换9) 时的动作捕获识别, "发票校验会同时产生会计凭证,对应凭证的行文本按需替换 lv_memory_id = sy-uname && 'ZMM_SRM2SAP_006'. lv_if_interface = 'X'. CALL FUNCTION 'ZFM_TRANSFER_DATA_COMMON' EXPORTING i_memory_id = lv_memory_id i_opearation = 'E' * I_OPTION_DATABASE = CHANGING c_data1 = lv_if_interface c_data2 = lv_lifnr. CLEAR return[]. CALL FUNCTION 'BAPI_INCOMINGINVOICE_CREATE' EXPORTING headerdata = headerdata IMPORTING invoicedocnumber = invoicedocnumber TABLES itemdata = itemdata taxdata = taxdata return = return. CLEAR lv_msg. CLEAR lv_iferror_flg. LOOP AT return WHERE type EQ 'E' OR type EQ 'A' OR type EQ 'I' OR type EQ 'X'. IF lv_msg IS INITIAL. lv_msg = return-message. ELSE. lv_msg = lv_msg && ',' && return-message. ENDIF. lv_iferror_flg = 'X'. ENDLOOP. IF lv_iferror_flg IS NOT INITIAL. lt_out_temp-type = 'E'. lt_out_temp-message = lv_msg. MODIFY lt_out_temp TRANSPORTING type message WHERE type IS INITIAL. lv_iferror_lifnr_flg = 'X'. APPEND LINES OF lt_out_temp[] TO lt_out[]. APPEND <ls_zmmt004> TO lt_zmmt004_error_record. ENDIF. CALL FUNCTION 'ZFM_TRANSFER_DATA_COMMON' EXPORTING i_memory_id = lv_memory_id i_opearation = 'F'. ENDLOOP. ************************************************************** "前面逐行模拟过账发生错误的采购订单明细行记录在内表 lt_zmmt004_error_record, "即如果有错误发生,可以在表lt_zmmt004_error_record中看到发生错误的对应的明细采购订单数据 "该内表lt_zmmt004_error_record由于是程序临时内表,若发生相关错误需要debug调试去看。 CHECK 1 EQ 1. ************************************************************** IF lt_out[] IS NOT INITIAL. SORT lt_out[] BY zdzd zdzdh. DELETE ADJACENT DUPLICATES FROM lt_out[] COMPARING zdzd zdzdh. et_tab[] = lt_out[]. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 RETURN. ENDIF. ENDIF. ************************************************************************************** "按照供应商,采购订单类别去调用BAPI做发票校验 CLEAR: lv_item. LOOP AT lt_zmmt004 ASSIGNING <ls_zmmt004>. AT NEW lifnr. CLEAR lv_iferror_lifnr_flg. CLEAR lv_numc. CLEAR lt_out_temp[]. ENDAT. AT NEW zflg. CLEAR: lv_gross_amount. CLEAR: lv_item. lv_numc = lv_numc + 1. CLEAR: headerdata,itemdata[],taxdata[],itemdata,taxdata. ENDAT. ******************************************** "set item data lv_item = lv_item + 1. CLEAR itemdata. itemdata-invoice_doc_item = lv_item. itemdata-po_number = <ls_zmmt004>-ebeln. itemdata-po_item = <ls_zmmt004>-ebelp. itemdata-tax_code = <ls_zmmt004>-mwskz. itemdata-item_amount = abs( <ls_zmmt004>-zjsje ). itemdata-quantity = abs( <ls_zmmt004>-zjss ). itemdata-po_unit = <ls_zmmt004>-meins. itemdata-item_text = <ls_zmmt004>-sgtxt. itemdata-ref_doc = <ls_zmmt004>-belnr. itemdata-ref_doc_year = <ls_zmmt004>-gjahr. itemdata-ref_doc_it = <ls_zmmt004>-buzei. APPEND itemdata. taxdata-tax_amount = abs( <ls_zmmt004>-zwrbtr1_LINE ). APPEND taxdata. ******************************************** lv_gross_amount = lv_gross_amount + <ls_zmmt004>-zwrbtr2_line. "set rsp data AT NEW zdzdh. LOOP AT lt_zmmt002 INTO ls_zmmt002 WHERE bukrs EQ <ls_zmmt004>-bukrs AND lifnr EQ <ls_zmmt004>-lifnr AND matnr EQ <ls_zmmt004>-matnr . CLEAR lt_out_temp. lt_out_temp-zdzd = ls_zmmt002-zdzd. lt_out_temp-zdzdh = ls_zmmt002-zdzdh. lt_out_temp-lifnr = ls_zmmt002-lifnr. lt_out_temp-numc = lv_numc. APPEND lt_out_temp. ENDLOOP. ********************************************************************************** "ADD LOGIC WITH 结算数量小于0,金额小于0的对账单特殊处理 STEP 1 IF lt_bukrs_lifnr_tab[] IS NOT INITIAL. READ TABLE lt_bukrs_lifnr_tab ASSIGNING FIELD-SYMBOL(<ls_bukrs_lifnr_tab>) WITH KEY bukrs = <ls_zmmt004>-bukrs lifnr = <ls_zmmt004>-lifnr BINARY SEARCH. IF sy-subrc EQ 0. <ls_bukrs_lifnr_tab>-flag = 'X'. ENDIF. ENDIF. ********************************************************************************** ENDAT. AT END OF zflg. ********************************************************************************** "ADD LOGIC WITH 结算数量小于0,金额小于0的对账单特殊处理 STEP 2 LOOP AT lt_bukrs_lifnr_tab WHERE flag = 'X'. LOOP AT lt_zmmt002 INTO ls_zmmt002 WHERE bukrs = lt_bukrs_lifnr_tab-bukrs AND lifnr = lt_bukrs_lifnr_tab-lifnr. SORT lt_out_temp[] BY zdzd zdzdh. READ TABLE lt_out_temp TRANSPORTING NO FIELDS WITH KEY zdzd = ls_zmmt002-zdzd zdzdh = ls_zmmt002-zdzdh BINARY SEARCH. IF sy-subrc NE 0. CLEAR lt_out_temp. lt_out_temp-zdzd = ls_zmmt002-zdzd. lt_out_temp-zdzdh = ls_zmmt002-zdzdh. lt_out_temp-lifnr = ls_zmmt002-lifnr. IF lv_numc EQ '01'. lt_out_temp-numc = lv_numc. APPEND lt_out_temp. ELSE. lt_out_temp-numc = '01'. APPEND lt_out_temp. lt_out_temp-numc = lv_numc. APPEND lt_out_temp. ENDIF. ENDIF. ENDLOOP. ENDLOOP. CLEAR lt_bukrs_lifnr_tab-flag. MODIFY lt_bukrs_lifnr_tab TRANSPORTING flag WHERE flag IS NOT INITIAL . ********************************************************************************** ******************************************** "set header data headerdata-doc_date = <ls_zmmt004>-bldat. headerdata-pstng_date = <ls_zmmt004>-bldat. ************************************************** * "过账日期特殊处理 * headerdata-doc_date = '20220831'. * headerdata-pstng_date = '20220831'. ************************************************** headerdata-comp_code = <ls_zmmt004>-bukrs. headerdata-currency = <ls_zmmt004>-waers. headerdata-gross_amount = lv_gross_amount. headerdata-gross_amount = abs( headerdata-gross_amount ) . IF <ls_zmmt004>-zflg EQ 'A'. headerdata-invoice_ind = 'X'. ELSE. CLEAR headerdata-invoice_ind. ENDIF. READ TABLE lt_wyt3 INTO ls_wyt3 WITH KEY lifnr = <ls_zmmt004>-lifnr BINARY SEARCH. IF ls_wyt3-lifnr NE ls_wyt3-lifn2 AND ls_wyt3-lifn2 IS NOT INITIAL. lv_bu_sort1 = ls_wyt3-bu_sort1. lv_lifnr = |{ ls_wyt3-lifn2 ALPHA = OUT }|. ELSE. READ TABLE lt_but000 INTO ls_but000 WITH KEY lifnr = <ls_zmmt004>-lifnr BINARY SEARCH. lv_bu_sort1 = ls_but000-bu_sort1. lv_lifnr = |{ ls_but000-lifnr ALPHA = OUT }|. ENDIF. headerdata-item_text = |欠{ lv_bu_sort1 }{ headerdata-pstng_date+4(2) ALPHA = OUT }月集中挂账货款|. CONDENSE headerdata-item_text NO-GAPS. headerdata-ref_doc_no = |{ headerdata-pstng_date+4(2) ALPHA = OUT }月{ lv_lifnr }挂账|. CONDENSE headerdata-ref_doc_no NO-GAPS. ******************************************** "用于后续 BTE增强(替换9) 时的动作捕获识别, "发票校验会同时产生会计凭证,对应凭证的行文本按需替换 lv_memory_id = sy-uname && 'ZMM_SRM2SAP_006'. lv_if_interface = 'X'. CALL FUNCTION 'ZFM_TRANSFER_DATA_COMMON' EXPORTING i_memory_id = lv_memory_id i_opearation = 'E' * I_OPTION_DATABASE = CHANGING c_data1 = lv_if_interface c_data2 = lv_lifnr. CLEAR return[]. CALL FUNCTION 'BAPI_INCOMINGINVOICE_CREATE' EXPORTING headerdata = headerdata IMPORTING invoicedocnumber = invoicedocnumber TABLES itemdata = itemdata taxdata = taxdata return = return. CLEAR lv_msg. CLEAR lv_iferror_flg. LOOP AT return WHERE type EQ 'E' OR type EQ 'A' OR type EQ 'I' OR type EQ 'X'. IF lv_msg IS INITIAL. lv_msg = return-message. ELSE. lv_msg = lv_msg && ',' && return-message. ENDIF. lv_iferror_flg = 'X'. ENDLOOP. IF lv_iferror_flg IS NOT INITIAL. lt_out_temp-type = 'E'. lt_out_temp-message = lv_msg. MODIFY lt_out_temp TRANSPORTING type message WHERE type IS INITIAL. lv_iferror_lifnr_flg = 'X'. ELSE. lt_out_temp-type = 'S'. CLEAR lt_out_temp-message . lt_out_temp-belnr = invoicedocnumber. MODIFY lt_out_temp TRANSPORTING belnr type message WHERE type IS INITIAL. ENDIF. CALL FUNCTION 'ZFM_TRANSFER_DATA_COMMON' EXPORTING i_memory_id = lv_memory_id i_opearation = 'F'. ENDAT. AT END OF lifnr. IF lv_iferror_lifnr_flg IS INITIAL. COMMIT WORK. lt_out_temp-message = TEXT-001. MODIFY lt_out_temp TRANSPORTING message WHERE zdzdh IS NOT INITIAL. ELSE. ROLLBACK WORK. lt_out_temp-message = '数据检查通过'. MODIFY lt_out_temp TRANSPORTING message WHERE type EQ 'S'. CLEAR lt_out_temp-belnr. lt_out_temp-type = 'E'. MODIFY lt_out_temp TRANSPORTING belnr type WHERE zdzdh IS NOT INITIAL. ENDIF. APPEND LINES OF lt_out_temp[] TO lt_out[]. ENDAT. ENDLOOP. CLEAR ls_update. ls_update-zdate = sy-datum. ls_update-zname = sy-uname. ls_update-ztime = sy-uzeit. CLEAR lt_zmmt006_update[]. LOOP AT lt_out . CLEAR lt_zmmt006_update. lt_zmmt006_update-zdzd = lt_out-zdzd. lt_zmmt006_update-zdzdh = lt_out-zdzdh. lt_zmmt006_update-belnr = lt_out-belnr. IF lt_out-type EQ 'S'. lt_zmmt006_update-zif_miro = 'X'. ELSE. CLEAR lt_zmmt006_update-zif_miro . ENDIF. MOVE-CORRESPONDING ls_update TO lt_zmmt006_update. APPEND lt_zmmt006_update. ENDLOOP. CLEAR lv_if_failed. IF lt_zmmt006_update[] IS NOT INITIAL. TRY . MODIFY zmmt006 FROM TABLE lt_zmmt006_update[]. CATCH cx_sy_open_sql_db. lv_if_failed = 'X'. ENDTRY. IF lv_if_failed IS INITIAL. COMMIT WORK. ENDIF. ENDIF. et_tab[] = lt_out[]. CLEAR: lv_if_failed,lv_if_successful. LOOP AT lt_out WHERE type EQ 'E'. lv_if_failed = 'X'. EXIT. ENDLOOP. LOOP AT lt_out WHERE type EQ 'S'. lv_if_successful = 'X'. EXIT. ENDLOOP. IF lv_if_failed IS NOT INITIAL AND lv_if_successful IS NOT INITIAL. e_code = 'E'. e_msg = lc_part. ELSEIF lv_if_failed IS NOT INITIAL AND lv_if_successful IS INITIAL. e_code = 'E'. e_msg = lc_failed. ELSEIF lv_if_failed IS INITIAL AND lv_if_successful IS NOT INITIAL. e_code = 'S'. e_msg = lc_successed. ENDIF. PERFORM update_status IN PROGRAM zfunc USING lv_zz_log_id e_code e_msg. INCLUDE zfunc_end."记录返回数据 ENDFUNCTION.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)