SDRV_accounting_document_create函数的代码解读

 FUNCTION rv_accounting_document_create.
  DATA : da_anzah_netwr  LIKE vbrp-netwr.
  DATA : da_anzah_mwsbp  LIKE vbrp-mwsbp.
  DATA : da_anzah_netwrg LIKE vbrk-netwr.
  DATA : da_anzah_fplnr  LIKE vbrp-fplnr.
  DATA : da_anzah_sign.
  DATA : da_pos_netwr    LIKE vbrp-netwr.
  DATA : da_tax_subtracted.
  DATA : ld_aenderung_konv.
  DATA : lt_vbpa LIKE vbpavb OCCURS 5 WITH HEADER LINE.

  DATA : abfor LIKE vbrp-abfor.

  DATA : loc_accrev LIKE accrev.
  DATA : nonewcancel.
  DATA: ld_collect_processed LIKE boole-boole.

  MOVE invoice_header TO vbrk.
  MOVE vbrk-rfbsk TO o_vbrk_rfbsk.
*
  IF mode NE 'B'.
    REFRESH: xacchd, xaccit, xacccr, xaccit_wt, accdpc, xaccit_deb.
*xacchd:会计界面:标题信息
*xaccit:会计核算界面:项目信息
*xacccr:会计核算界面:货币信息
*xaccit_wt:FI 界面的预扣税信息
*accdpc:预付定金清算的代码字段
*xaccit_deb:关于创建客户行的项目字段
    CLEAR: xkomk1, xkomk2, xkomk3.
    CLEAR: xacchd, xaccit, xacccr, accdpc.
    CLEAR: loc_bsid, loc_bkpf.
    CLEAR: jcdactive, external, txjlv, txjdp.
    CLEAR: o_new_cancel_fail.
  ENDIF.
  CLEAR: rule_new_cancel.

* start Revenue Recognition Project

*清除内表数据
  REFRESH: rr_accit, rr_acccr.
  CLEAR: rr_accit, rr_acccr.
* end Revenue Recognition Project
*系统默认的财务项目编号从1001编号,对应的客户项目1编号

  IF mode = 'B'.
    posnr = 500000.
  ELSE.
    posnr = 1000.
  ENDIF.
  tax = 0.
  cashdiscount = 0.
  securevalue  = 0.
  totalvalue   = 0.
  creditvalue  = 0.
  CLEAR xgsber.
  postgsb = ' '.
  IF t001-bukrs NE vbrk-bukrs.
    SELECT SINGLE * FROM t001 WHERE bukrs EQ vbrk-bukrs.
  ENDIF.
  IF tvfk-fkart NE vbrk-fkart OR vbrk-sfakn NE space.
    SELECT SINGLE * FROM tvfk WHERE fkart EQ vbrk-fkart.
  ENDIF.

* check if external tax determination is active
  IF vbrk-vbtyp NA vbtyp_reli.
    CALL FUNCTION 'CHECK_JURISDICTION_ACTIVE'
      EXPORTING
        i_land     = t001-land1
        i_bukrs    = vbrk-bukrs
      IMPORTING
        e_external = external
        e_isactive = jcdactive.
  ENDIF.

* fill header
  IF mode CA ' A'.
    CLEAR xacchd.
    xacchd-mandt = sy-mandt.
    xacchd-awtyp = con_awtyp_vbrk.
    xacchd-awref = vbrk-vbeln.
    xacchd-awsys = vbrk-logsys.
    xacchd-usnam = sy-uname.
    xacchd-tcode = sy-tcode.
    xacchd-cpudt = sy-datum.
    xacchd-cputm = sy-uzeit.
    IF mode = 'A'.
      xacchd-aworg = 'CORR'.
    ENDIF.

    IF vbrk-fktyp = con_fktyp_p.
*     business transaction for downpayment request
      xacchd-glvor = con_glvor_rfst.
    ELSE.
*     business transaction for normal invoice
      xacchd-glvor = con_glvor_sd00.
    ENDIF.
  ENDIF.
*系统默认SD 的发票生成RV类型的财务凭证
* use document type from TVFK if entered
  IF tvfk-blart IS INITIAL.
    xaccit-blart = 'RV'.
  ELSE.
    xaccit-blart = tvfk-blart.
  ENDIF.

* rebate and vprs update with ext. number range: use new document type
  IF mode CA 'AB' AND NOT blart IS INITIAL.
    xaccit-blart = blart.
  ENDIF.

  xvbrp_key       = vbrk.
  IF document_old(1) = con_$.
    xvbrp_key-vbeln = document_old.
  ENDIF.

* negative posting
  IF mode = ' '.
    PERFORM xaccit_xnegp_set.
* credit memo with value date
    PERFORM xaccit_xvalgs_zfbdt_set.
  ENDIF.

  xaccit-budat = vbrk-fkdat.
  xaccit-bldat = vbrk-fkdat.
  xaccit-xblnr = vbrk-xblnr.                                "H27515
  xaccit-wwert = vbrk-kurrf_dat.

  IF mode = ' '.
*   Userexit Header
    CALL CUSTOMER-FUNCTION '001'
       EXPORTING
          xacchd     = xacchd
          xaccit     = xaccit
          vbrk       = vbrk
          doc_number = xvbrp_key-vbeln
       IMPORTING
          xacchd     = xacchd
          xaccit     = xaccit
       TABLES
          cvbrp      = xvbrp
          ckomv      = xkomv.
  ENDIF.                               "Modus

  IF mode CA ' A'.
    APPEND xacchd.
  ENDIF.

  MOVE-CORRESPONDING xaccit TO xkomk1.
  PERFORM userexit_fill_xkomk1.

* new cancellation
* sfakn is only set, when the whole invoice is cancelled

*取消发票处理
  IF NOT vbrk-sfakn IS INITIAL AND NOT vbrk-fktyp EQ con_fktyp_p AND rule_new_cancel NE con_a AND new_acct_det IS INITIAL.
    IF NOT rrrel IS INITIAL.
      nonewcancel = 'X'.
    ENDIF.

    IF nonewcancel IS INITIAL.
      loc_accrev-awtyp = con_awtyp_vbrk.
      loc_accrev-awref = vbrk-vbeln.
      loc_accrev-aworg = space.
      loc_accrev-awsys = vbrk-logsys.
      loc_accrev-belnr = vbrk-vbeln.
      loc_accrev-fkart = vbrk-fkart.
      loc_accrev-awref_rev = vbrk-sfakn.
      loc_accrev-aworg_rev = space.
      loc_accrev-bukrs = vbrk-bukrs.
      loc_accrev-budat = vbrk-fkdat.
      loc_accrev-budat_rev = vbrk-fkdat.
      loc_accrev-xnegp = xaccit-xnegp.
      loc_accrev-glvor = xacchd-glvor.
      loc_accrev-cpudt = xacchd-cpudt.
      loc_accrev-cputm = xacchd-cputm.
      loc_accrev-glvor = xacchd-glvor.
* badi grants management method: gm_billing_status_set
* loc_accrev added for FI-CA
      DATA: l_sd_gm_exit   TYPE REF TO if_ex_badi_sd_gm,
            active TYPE xfeld.

      IF vbrk-vbtyp NA vbtyp_reli.
        CALL FUNCTION 'GET_HANDLE_SD_GM'
          IMPORTING
            handle = l_sd_gm_exit
            active = active.

        IF active = 'X'.
          CALL METHOD l_sd_gm_exit->gm_billing_status_set
            EXPORTING
              fvbrk    = vbrk
              fxvbrpvb = xvbrp[]
              f_tvfk   = tvfk
            CHANGING
              faccrev  = loc_accrev.
        ENDIF.
      ENDIF.

*反向生成取消发票的财务操作

      CALL FUNCTION 'AC_DOCUMENT_REVERSE'
        EXPORTING
          i_accrev           = loc_accrev
          i_comp             = i_comp
        EXCEPTIONS
          reverse_impossible = 1
          error_message      = 2
          OTHERS             = 3.
      IF sy-subrc = 0.
        EXIT.
      ENDIF.
      IF sy-subrc = 2.
        IF sy-msgty = 'A'.
*       display error directly when abend message
          MESSAGE ID sy-msgid TYPE 'A' NUMBER sy-msgno
                WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        ENDIF.
        IF rule_new_cancel NE con_b.
          IF check NE con_x.
*       write error to protocol
            RAISE error_01.
          ELSE.
*       display error directly
            MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
                  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
          ENDIF.
        ENDIF.
      ENDIF.
      IF sy-subrc EQ 1 OR sy-subrc = 3.
        IF check EQ con_x.
          MESSAGE ID 'VF' TYPE 'I' NUMBER '208'
          WITH vbrk-sfakn vbrk-vbeln.
        ELSE.
          o_new_cancel_fail = 'X'.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDIF.

*下面代码为正常发票生成财务凭证
*判断是否有发票凭证:xvbrp_key =800+发票号
  READ TABLE xvbrp WITH KEY xvbrp_key BINARY SEARCH.
  IF sy-subrc = 0.
    xvbrp_tabix = sy-tabix.
*对发票项目进行循环,将各个项目对应的定价过程生成数据提取汇总到内表(生成财务财务凭证需要的数据)
*   invoice items ( l o o p )
    DO.
*     reset item information for debitor line items
      CLEAR xaccit_deb.
*     initialize amount for POS interface
      CLEAR da_pos_netwr.
      CLEAR ld_collect_processed.
      CLEAR item_with_rrdp.
* BADI call for FI-CA
      IF NOT vbrk-vkont IS INITIAL.
      DATA: l_sd_accounting_exit   TYPE REF TO if_ex_badi_sd_accounting.
        IF vbrk-vbtyp NA vbtyp_reli.
          CALL FUNCTION 'GET_HANDLE_SD_ACCOUNTING'
            IMPORTING
              handle = l_sd_accounting_exit
              active = active.
          IF active = 'X'.
            CALL METHOD l_sd_accounting_exit->fica_kunnr_get
              EXPORTING
                f_old_document = document_old
                fvbrk          = vbrk
                fvbrp          = xvbrp
                fxvbpa         = xvbpa[]
              CHANGING
                fxkomv         = xkomv[]
                f_konv_changed = ld_aenderung_konv.
          ENDIF.
        ENDIF.
      ENDIF.
*     choose document/ item number for downpayment request
      IF xvbrp-fareg CA con_fareg_anzahlungen.
        IF NOT xvbrp-vbelv IS INITIAL.
          anz_vgbel = xvbrp-vbelv.
          anz_vgpos = xvbrp-posnv.
        ELSE.
          anz_vgbel = xvbrp-vgbel.
          anz_vgpos = xvbrp-vgpos.
        ENDIF.
      ENDIF.
* down payments/ billing plan with resource-related billing
* check if the item is relevant
      IF xvbrp-fareg EQ '5'.
        CALL FUNCTION 'DPBP_RELEVANCE_CHECK'
          EXPORTING
            i_vgbel          = xvbrp-vgbel
            i_vgpos          = xvbrp-vgpos
            i_fplnr          = xvbrp-fplnr
            i_fpltr          = xvbrp-fpltr
            i_aubel          = xvbrp-aubel
            i_vgtyp          = xvbrp-vgtyp
          IMPORTING
            e_item_with_rrdp = item_with_rrdp.
        IF NOT item_with_rrdp IS INITIAL.
          anz_vgbel = xvbrp-aubel.
          anz_vgpos = xvbrp-aupos.
        ENDIF.
      ENDIF.
*     no tax and G/L account items for down payment requests
      IF vbrk-fktyp  EQ con_fktyp_p OR
         vbrk-fktyp  NE con_fktyp_p AND
         xvbrp-fareg NA con_fareg_anzahlungen.
        IF xvbrp-kowrr IS INITIAL.                          " h115788
*         Save net value of the invoice item for value check of
*         the downpayments that will be cleared
          CLEAR: da_anzah_netwr,
                 da_anzah_mwsbp,
                 da_anzah_fplnr,
                 da_anzah_sign.
          da_anzah_netwr = xvbrp-netwr.
          da_anzah_mwsbp = xvbrp-mwsbp.
          da_anzah_fplnr = xvbrp-fplnr.
          IF xvbrp-netwr GE 0.
            da_anzah_sign = con_plus.
          ELSE.
            da_anzah_sign = con_minus.
          ENDIF.
* down payments/ billing plan with resource-related billing
          IF vbrk-fktyp NE con_fktyp_p AND
* not for downpayment requests
            NOT item_with_rrdp IS INITIAL.
            DATA: sum_da_anzah_netwr LIKE da_anzah_netwr.
            DATA: sum_da_anzah_mwsbp LIKE da_anzah_mwsbp.
            DATA: save_aubel LIKE xvbrp-aubel.
            DATA: save_aupos LIKE xvbrp-aupos.
            IF xvbrp-aubel NE save_aubel OR
                        xvbrp-aupos NE save_aupos.
              CLEAR sum_da_anzah_netwr.
              CLEAR sum_da_anzah_mwsbp.
              save_aubel = xvbrp-aubel.
              save_aupos = xvbrp-aupos.
            ENDIF.
            sum_da_anzah_netwr = sum_da_anzah_netwr + xvbrp-netwr.
            sum_da_anzah_mwsbp = sum_da_anzah_mwsbp + xvbrp-mwsbp.
            da_anzah_netwr = sum_da_anzah_netwr.
            da_anzah_mwsbp = sum_da_anzah_mwsbp.
            IF da_anzah_netwr GE 0.
              da_anzah_sign = con_plus.
            ELSE.
              da_anzah_sign = con_minus.
            ENDIF.
          ENDIF.

          IF mode = ' '.
*           initialize cash management data
            CLEAR : fmii1.
*           cash management: determine order account assignment
            IF    NOT xvbrp-aubel IS INITIAL
              AND NOT xvbrp-aupos IS INITIAL
              AND     xvbrp-autyp CA vbtyp_verk
              AND      vbrk-vbtyp NA vbtyp_fkiv.

              CALL FUNCTION 'FM_CO_ASS_INPUT_GET_SD'
                EXPORTING
                  i_vbeln                  = xvbrp-aubel
                  i_posnr                  = xvbrp-aupos
                  i_bukrs                  = vbrk-bukrs
                  i_flg_check_completeness = 'X'
                IMPORTING
                  e_fipos                  = fmii1-fipos
                  e_fistl                  = fmii1-fistl
                  e_fonds                  = fmii1-fonds
                  e_fkber                  = fmii1-farea
                  e_grant_nbr              = fmii1-grant_nbr
                EXCEPTIONS
                  no_customizing_found     = 1
                  assignment_incomplete    = 2
                  not_active               = 3.

              IF sy-subrc = 2.
                IF check NE con_x.
*             display error into log
                  RAISE error_01.
                ELSE.
*             display error directly
                  MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
                        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
                ENDIF.
              ENDIF.
            ENDIF.

            PERFORM txjcd_aufbereiten.
*         cash discount value of the item is summed up for the customer
*         line item
            ADD xvbrp-skfbp TO xaccit_deb-skfbp.
*         determine secure value
            IF abfor NE xvbrp-abfor.
              SELECT SINGLE * FROM t691k WHERE absfo = xvbrp-abfor.
              abfor = xvbrp-abfor.
            ENDIF.
            IF t691k-abstp NE '3'.     " not for credit cards
              PERFORM cmpre_calculate(saplvkmp)
                            USING    xvbrp-cmpre
                                     xvbrp-cmpre_flt
                                     xvbrp-fkimg
                                     xvbrp-abges
                            CHANGING creditvalue_det
                                     totalvalue_det
                                     securevalue_det.
              ADD totalvalue_det  TO xaccit_deb-totalval.
              ADD creditvalue_det TO xaccit_deb-creditval.
              ADD securevalue_det TO xaccit_deb-secureval.
            ENDIF.

            IF vbrk-fktyp EQ con_fktyp_p."Note: 113374 (98)
              free-of-charge = 'N'.
            ELSE.
              free-of-charge = 'X'.    " P30K123459
            ENDIF.

            IF postgsb = ' '.
              xgsber = xvbrp-gsber.
            ELSE.
              IF xgsber NE xvbrp-gsber.
                CLEAR xgsber.
              ENDIF.
            ENDIF.
            postgsb = 'X'.
          ENDIF.                       "Modus
          xkomv_key       = xvbrp_key.
          IF document_old(1) NE con_$.
            xkomv_key-knumv = vbrk-knumv.
          ENDIF.
          xkomv_key-kposn = xvbrp-posnr.
          IF mode NE 'A'.
* START OF : account determination
* 根据当前的发票项目号,对xkomv表(定价过程生成的定价内表)中对应的该项目号的记录进行确定科目,
* 并将科目填写到xkomv表中,就是修改SAKN1和SAKN2
            IF   xvbrp-kowrr = space                       AND
                 vbrk-sfakn  = space                       AND "已取消的出具发票凭证号
                 i_comp IS INITIAL                         AND
                 xvbrp-fareg NA con_fareg_anzahlungen      AND
               ( ( vbrk-rfbsk CA ' ABHIK'  OR mode = 'B' )  OR
                 ( sy-cprog = 'SAPFACC0'               )   OR
                 ( sy-cprog = 'SAPFACC1' ) ) OR
                 ( new_acct_det EQ con_x ).
              CALL FUNCTION 'RV_INVOICE_ACCOUNT_DETERM'  "确定科目
                EXPORTING
                  document_internal = document_old
                  invoice_header    = vbrk
                  invoice_item      = xvbrp
                  procedure         = tvfk-kalsmc
                  protocol          = ' '
                  mode              = mode
                  new_acct_det      = new_acct_det
                IMPORTING
                  konv_changed      = ld_aenderung_konv
                TABLES
                  tkomv             = xkomv
                  xvbpa             = xvbpa
                EXCEPTIONS
                  account_missing   = 4.
              IF sy-subrc NE 0.
                CASE vbrk-rfbsk.
                  WHEN ' '.
                    o_vbrk_rfbsk = 'B'.
                    sy-msgid = 'VF'.
                    sy-msgno = '051'.   "凭证 & 保存(帐户确定出错)
                    sy-msgv1 = vbrk-vbeln.
                    RAISE error_01.
                  WHEN 'H'.
                    o_vbrk_rfbsk = 'I'.
                ENDCASE.
              ENDIF.
              IF ld_aenderung_konv = 'X'.
                o_konv_changed = 'X'.
              ENDIF.
            ENDIF.
          ENDIF.                       "Modus
* END OF : account determination
          REFRESH taccit_wt.
*xkomv_key :单据条件数+条件项目号
*对已经确认科目的Xkomv表中对应的记录进行财务凭证项目生成
          READ TABLE xkomv WITH KEY xkomv_key BINARY SEARCH.
          IF sy-subrc = 0.
            xkomv_tabix = sy-tabix.
            CLEAR remmwskz.            " note 141899
*         conditions ( l o o p )
            DO.
              IF xkomv-koaid = con_d AND "con_d 表示税
                 xkomv-kinak = space AND "表示条件不活跃
                 mode = space AND
                 xkomv-kstat = space.     "条件用作统计
*             tax line item
                ADD xkomv-kwert TO xaccit_deb-mwsbp.
*             set tax indicator for downpayment requests
                IF vbrk-fktyp EQ con_fktyp_p.
                  xaccit_deb-mwsk1 = xkomv-mwsk1.
                ENDIF.
* FI-CA: set tax indicator for debit lines
                IF NOT vbrk-vkont IS INITIAL AND xkomv-kstat IS INITIAL
                   OR NOT deb_lines_for_cond IS INITIAL.
                  xaccit_deb-mwsk1 = xkomv-mwsk1.
                ENDIF.
* end: set tax indicator
                IF xkomv-kwert NE 0 OR xkomv-mwsk1 NE space.
                  PERFORM accounting_tax_line.
                ENDIF.
              ENDIF.
              IF xkomv-koaid NE con_d AND
                 xkomv-koaid NE con_w AND
                 xkomv-kinak EQ space AND
                 xkomv-kwert NE 0     AND
                 vbrk-fktyp  NE con_fktyp_p.
                free-of-charge = 'N'.  " P30K123459
*             G/L account item
*             FI-CA: set tax indicator for debit lines
                IF NOT vbrk-vkont IS INITIAL AND xkomv-kstat IS INITIAL
                   OR NOT deb_lines_for_cond IS INITIAL.
                  xaccit_deb-mwsk1 = xkomv-mwsk1.
                ENDIF.
                IF mode CA 'AB'.
                  IF xkomv-koaid EQ con_c AND               "nur Bonus
                     mode_types = '1'.
                    PERFORM accounting_item_line.
                  ENDIF.
                  IF xkomv-kntyp CA 'Ghb' AND        "nur VPRS und TP
                     mode_types = '2'.
                    PERFORM accounting_item_line.
                  ENDIF.
                ELSE.
                  PERFORM accounting_item_line.
                ENDIF.
              ENDIF.
*             FI-CA: set tax indicator for debit lines
              IF NOT vbrk-vkont IS INITIAL AND xkomv-kstat IS INITIAL
                 OR NOT deb_lines_for_cond IS INITIAL.
                xaccit_deb-mwsk1 = xkomv-mwsk1.
              ENDIF.

              IF xkomv-koaid = con_w AND xkomv-kinak = space.
*             withholding tax data for( customer line item(s))
                CLEAR taccit_wt.
                PERFORM wt_type_for_kschl_get USING xvbrp-aland
                                                    xkomv-kschl
                                             CHANGING taccit_wt-witht.
                IF taccit_wt-witht <> space.
                  taccit_wt-wt_withcd = xkomv-mwsk2.
                ENDIF.
                APPEND taccit_wt.
              ENDIF.
*           save value of cash conditions from POS interface
              IF xkomv-kntyp EQ con_kntyp_pos.
                da_pos_netwr = da_pos_netwr + xkomv-kwert.
              ENDIF.
              IF NOT vbrk-vkont IS INITIAL OR
                 NOT deb_lines_for_cond IS INITIAL.
                PERFORM fill_accit_deb USING 'C'
                                       CHANGING da_pos_netwr
                                                ld_collect_processed.
              ENDIF.
              ADD 1 TO xkomv_tabix.
              READ TABLE xkomv INDEX xkomv_tabix.
              IF sy-subrc NE 0 OR xkomv-knumv NE xkomv_key-knumv
                               OR xkomv-kposn NE xkomv_key-kposn.
                EXIT.
              ENDIF.
            ENDDO.  "SD单据的单个项目对应定价循环结束
          ENDIF.
* fill data for the customer lines
*使用collect方法添加到Xaccit_deb内表,供后续计算客户项目使用
          PERFORM fill_accit_deb USING 'I'
                                 CHANGING da_pos_netwr
                                          ld_collect_processed.
        ENDIF.                                              " h115788

* BADI call for FI-CA
        IF NOT vbrk-vkont IS INITIAL AND NOT xvbrp-aubel IS INITIAL AND
             NOT xvbrp-fplnr IS INITIAL.
          DATA: l_sd_billing_item_exit TYPE REF TO
                                             if_ex_badi_sd_billing_item.

          IF vbrk-vbtyp NA vbtyp_reli.
            CALL FUNCTION 'GET_HANDLE_SD_BILLING_ITEM'
              IMPORTING
                handle = l_sd_billing_item_exit
                active = active.

            IF active = 'X'.
           CALL METHOD l_sd_billing_item_exit->fi_ca_down_payments_read
                EXPORTING
                  f_waerk = vbrk-waerk
                  f_vgbel = xvbrp-aubel
                  f_tvfk  = tvfk
                  fvbrk   = vbrk
                CHANGING
                  faccdpc = t_sdaccdpc[].
            ENDIF.
          ENDIF.
        ENDIF.
      ELSE.
        IF i_comp IS INITIAL.          "  Not for subsequent posting
*         Item net value
          IF xvbrp-mwsbp IS INITIAL.
            da_anzah_netwr = da_anzah_netwr + da_anzah_mwsbp
                                            - xvbrp-netwr.
          ELSE.
            da_anzah_netwr = da_anzah_netwr - xvbrp-netwr.
          ENDIF.
*         Header net value
          IF xvbrp-mwsbp IS INITIAL AND da_tax_subtracted IS INITIAL.
            da_anzah_netwrg = da_anzah_netwrg + xvbrp-netwr
                                              - vbrk-mwsbk.
            da_tax_subtracted = 'X'.
          ELSE.
            da_anzah_netwrg = da_anzah_netwrg + xvbrp-netwr.
          ENDIF.
          IF da_anzah_fplnr NE xvbrp-fplnr OR
            ( NOT item_with_rrdp IS INITIAL ) OR
            ( da_anzah_sign  EQ con_plus  AND da_anzah_netwr GE 0 ) OR
            ( da_anzah_sign  EQ con_minus AND da_anzah_netwr LE 0 ).
*           Fill FI table with downpayment clearings
            PERFORM accdpc_fuellen_aus_sdaccdpc.
          ELSE.
            sy-msgid = 'VF'.
            sy-msgno = '525'.
            sy-msgv1 = xvbrp-posnr.
            IF check NE con_x.
*             Write message to protocol
              RAISE error_01.
            ELSE.
*             Send message
              MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
                  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
            ENDIF.
          ENDIF.

        ENDIF.                         "  Not for subsequent posting
      ENDIF.
      ADD 1 TO xvbrp_tabix.
      READ TABLE xvbrp INDEX xvbrp_tabix.
      IF sy-subrc NE 0 OR xvbrp-vbeln NE xvbrp_key-vbeln.
        EXIT.
      ENDIF.
    ENDDO."SD单据项目循环

*   Down payments are higher than invoice net value
    IF vbrk-netwr GT 0 AND vbrk-netwr LT da_anzah_netwrg OR
       vbrk-netwr LT 0 AND vbrk-netwr GT da_anzah_netwrg.
      sy-msgid = 'VF'.
      sy-msgno = '527'.
      sy-msgv1 = vbrk-vbeln.
      IF check NE con_x.
*       Write message to protocol
        RAISE error_01.
      ELSE.
*       Send message
        MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.
    ENDIF.

  ENDIF.

* start Revenue Recognition Project
* Save the position number before it is cleared for rev. rec.
  DATA : lif_posnr LIKE accit-posnr.
  lif_posnr = posnr.
* end Revenue Recognition Project

* customer line item(s)
  IF mode = ' '.
*清空,从1开始编写客户项目编号,
*前面的其他项目从1000开始编号
    CLEAR: posnr.
*   CCARD ...
    PERFORM credit_card.
*   Reduce the end value of the customer lines using the value
*   previously posted. Tax and cashdiscount are not reduced
*   The risk management fields are already processed with a factor
*   The end value is corrected for rounding differences
*   The cash discount is not corrected
    DATA: da_factor TYPE f,
          da_brtwr_total_v LIKE xaccit_deb-brtwr,
          da_brtwr_total_n LIKE xaccit_deb-brtwr,
          da_brtwr_diff    LIKE xaccit_deb-brtwr,
          da_brtwr_total   LIKE xaccit_deb-brtwr,
          da_tabix         LIKE sy-tabix.
    IF ctotal NE 0.                    " Hinweis: 111916/116922
      da_brtwr_total = invoice_header-netwr + invoice_header-mwsbk.
      IF da_brtwr_total NE 0.          " If da_brtwr_total...
        da_factor = ( 1 - ctotal / da_brtwr_total ).
        LOOP AT xaccit_deb.
          ADD xaccit_deb-brtwr TO da_brtwr_total_v.
          xaccit_deb-brtwr = xaccit_deb-brtwr * da_factor.
          xaccit_deb-skfbp = xaccit_deb-skfbp * da_factor.
          ADD xaccit_deb-brtwr TO da_brtwr_total_n.
          MODIFY xaccit_deb.
        ENDLOOP.
      ENDIF.                           " If da_brtwr_total...
      da_brtwr_diff = ( da_brtwr_total_v - ctotal ) -
                      ( da_brtwr_total_n ).
      DESCRIBE TABLE xaccit_deb LINES da_tabix.
      IF da_tabix NE 0.
        READ TABLE xaccit_deb INDEX da_tabix.
        ADD da_brtwr_diff TO xaccit_deb-brtwr.
        ADD da_brtwr_diff TO xaccit_deb-skfbp.
        MODIFY xaccit_deb INDEX da_tabix.
      ENDIF.
    ENDIF.
*   Create debitor lines
    LOOP AT xaccit_deb.
*     set global data, no change of the customer line item with respect to XACCCR
      pos_brutto   = xaccit_deb-brtwr.
      pos_netto    = xaccit_deb-netwr.
      tax          = xaccit_deb-mwsbp.
      cashdiscount = xaccit_deb-skfbp.
      securevalue  = xaccit_deb-secureval.
      creditvalue  = xaccit_deb-creditval.
      totalvalue   = xaccit_deb-totalval.
      IF NOT xgsber IS INITIAL.
        xaccit_deb-gsber = xgsber.
      ENDIF.
*填写客户项目到XACCIT表
      PERFORM accounting_head_line.
    ENDLOOP.
* call badi_sd_accounting
    IF vbrk-vbtyp NA vbtyp_reli.
      CALL FUNCTION 'GET_HANDLE_SD_ACCOUNTING'
        IMPORTING
          handle = l_sd_accounting_exit
          active = active.

      IF active = 'X'.
        CALL METHOD l_sd_accounting_exit->accounting_interface
          EXPORTING
            fcvbrk      = vbrk
            fdoc_number = xvbrp_key-vbeln
          CHANGING
            fxvbrp      = xvbrp[]
            fxkomv      = xkomv[]
            fxaccit     = xaccit[]
            fxacccr     = xacccr[].
      ENDIF.
    ENDIF.

*   possibility to change interface tables
    CALL CUSTOMER-FUNCTION '008'
       EXPORTING
          cvbrk      = vbrk
          doc_number = xvbrp_key-vbeln
       TABLES
          xaccit     = xaccit
          xacccr     = xacccr
          cvbrp      = xvbrp
          ckomv      = xkomv
          caccdpc    = accdpc.

*   call from simulation report
    IF sy-cprog = 'SAPFACC0'
    OR sy-cprog = 'SAPFACC1'.
      EXPORT xacchd xaccit xacccr TO MEMORY ID 'SAPLV60B'.
      EXIT.
    ENDIF.
  ENDIF.

* create FI document
  DESCRIBE TABLE xaccit LINES sy-tabix.
  IF sy-tabix = 0.
*   start Revenue Recognition Project
    IF NOT rrrel      IS INITIAL AND
           vbrk-fktyp NE con_fktyp_p.    " No downpayment requests
      DESCRIBE TABLE rr_accit LINES sy-tabix.
    ENDIF.
    IF sy-tabix = 0.
*   end Revenue Recognition Project
*   clear SYS-MSG-fields, as previously the fields were filled without
*   outputting them ( example: text processing )
      CLEAR: sy-msgno, sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4.
      RAISE no_document_required.
      EXIT.
    ENDIF.
  ENDIF.

  IF mode = ' '.
*   check if there are down payment clearings
    DESCRIBE TABLE accdpc LINES sy-tabix.

    IF sy-tabix > 0 OR NOT vbrk-vkont IS INITIAL.
*     fill tables ACCIT and ACCCR with downpayment clearings
      PERFORM anzahlungen_fuer_accit_acccr.
    ENDIF.
  ENDIF.


  CHECK mode NE 'A'.

* start Revenue Recognition Project
  IF NOT rrrel      IS INITIAL AND
         vbrk-fktyp NE con_fktyp_p AND    " No downpayment requests
         mode = ' '.

*   Call Rev. Rec. Billing Function Module
    CALL FUNCTION 'SD_REV_REC_BILLING'
      EXPORTING
        fis_vbrk     = vbrk
        fif_dummy_nr = document_old
        fis_t001     = t001
        fif_posnr    = lif_posnr
      TABLES
        fit_xaccit   = xaccit
        fit_xacccr   = xacccr
        fit_xvbrp    = xvbrp
        fit_xkomv    = xkomv
        fit_xacchd   = xacchd
        fit_rr_accit = rr_accit
        fit_rr_acccr = rr_acccr
        fit_xfplt    = xfplt
        fit_xvbpa    = xvbpa
      EXCEPTIONS
        error_01     = 01.

    IF sy-subrc EQ 0.
*     Check RW-interface table again whether there are entries
      DESCRIBE TABLE xaccit LINES sy-tabix.
      IF sy-tabix = 0.
        CLEAR: sy-msgno, sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4.
        RAISE no_document_required.
        EXIT.
      ENDIF.
    ENDIF.
  ELSE.
*   Initialize error mark
    CLEAR: sy-subrc.
  ENDIF.

  IF sy-subrc EQ 0.
* end Revenue Recognition Project

    IF mode = ' ' OR ( mode = 'B' AND mode_types = '2' ).
*   Gegenbuchung zu Transferpreisen erzeugen.
      CALL FUNCTION 'TP_PREPARE_ACCCR_SD'
        TABLES
          t_acchd = xacchd
          t_accit = xaccit
          t_acccr = xacccr
        EXCEPTIONS
          OTHERS  = 0.
    ENDIF.

    IF sy-subrc NE 01.
*     Call badi_sd_gm grants management
      IF mode = ' ' AND vbrk-vbtyp NA vbtyp_reli.
        CALL FUNCTION 'GET_HANDLE_SD_GM'
          IMPORTING
            handle = l_sd_gm_exit
            active = active.

        IF active = 'X'.
          CALL METHOD l_sd_gm_exit->gm_billing_status_set
            EXPORTING
              fvbrk    = vbrk
              fxvbrpvb = xvbrp[].
        ENDIF.
      ENDIF.
*生成SAP的财务凭证
*该函数里会根据SAP配置调用对应过程生成对应的各类凭证
*对应过程存储在TRWPR表里
      CALL FUNCTION 'AC_DOCUMENT_CREATE'
        EXPORTING
          i_comp        = i_comp
          i_comp_check  = i_comp_check
        TABLES
          t_acccr       = xacccr
          t_acchd       = xacchd
          t_accit       = xaccit
          t_accfi       = lt_accfi    "会计界面:财务会计一次性科目->只包含需要记账的记录
          t_accwt       = xaccit_wt
        EXCEPTIONS
          error_message = 01.

    ENDIF.

* start Revenue Recognition Project
  ENDIF.
* end Revenue Recognition Project

  IF sy-subrc = 01.

    IF mode = ' '.
* start Revenue Recognition Project
*     if posting to accounting failed,then this function restores xvbrev
      IF NOT rrrel      IS INITIAL AND
             vbrk-fktyp NE con_fktyp_p.    " No downpayment requests
        CALL FUNCTION 'SD_REV_REC_RESTORE'.
      ENDIF.
* end Revenue Recognition Project
    ENDIF.

    IF check NE con_x.
*      write error to protocol
      RAISE error_01.
    ELSE.
*      display error directly
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDIF.

ENDFUNCTION.

原文地址:https://www.cnblogs.com/xiaomaohai/p/6157039.html