【MM】基於收貨的發票校驗Bapi Demo

SAP劍客發表於2020-12-06

正常我們都會在供應商主檔和資訊記錄主檔中勾選“基於收貨的發票校驗”選項,意味著做採購發票校驗的時候需要基於收貨憑證。

      LS_ITEM-REF_DOC = LT_ZMSEG-MBLNR. 
      LS_ITEM-REF_DOC_YEAR = LT_ZMSEG-MJAHR.
      LS_ITEM-REF_DOC_IT = LT_ZMSEG-ZEILE.

下面分享一個簡單的Demo:

1、資料準備

  DATA: LS_HEADER TYPE BAPI_INCINV_CREATE_HEADER.
  DATA: LT_ITEMS TYPE TABLE OF BAPI_INCINV_CREATE_ITEM.

  PERFORM FILL_VALUES TABLES LT_ITEMS
                       USING LS_HEADER.

  PERFORM RUN_TO_CREATE_IV TABLES LT_ITEMS
                            USING LS_HEADER.

2、資料填充

*&---------------------------------------------------------------------*
*&      Form  fill_values
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_ITEMS   text
*      -->PS_HEADER  text
*----------------------------------------------------------------------*
FORM FILL_VALUES TABLES PT_ITEMS STRUCTURE BAPI_INCINV_CREATE_ITEM
                  USING PS_HEADER TYPE BAPI_INCINV_CREATE_HEADER.

  DATA: LS_ITEM LIKE LINE OF PT_ITEMS[].
  FIELD-SYMBOLS: <LS_ITEM> LIKE LINE OF PT_ITEMS[].
  DATA: LS_DATA2 LIKE LINE OF GT_DATA2.
  DATA: LV_AMOUNT(40).
  DATA: LS_EKPO TYPE EKPO.
  DATA: LT_ZMSEG LIKE TABLE OF ZMSEG WITH HEADER LINE.
  DATA: LT_ZMSEG1 LIKE TABLE OF ZMSEG WITH HEADER LINE.
  DATA: LV_ITEM TYPE N LENGTH 6.
  DATA: LV_NETWR TYPE ZMJMIMS0023-NETWR.

  "Fill Header data
  READ TABLE GT_DATA2 INTO LS_DATA2 INDEX 1.
  SELECT SINGLE RETPO
                  FROM EKPO
                  INTO LS_EKPO-RETPO
                 WHERE EBELN = LS_DATA2-EBELN
                   AND EBELP = LS_DATA2-EBELP.
  IF LS_EKPO-RETPO = 'X'.
    PS_HEADER-INVOICE_IND = SPACE.
  ELSE.
    PS_HEADER-INVOICE_IND = 'X'.
  ENDIF.
  PS_HEADER-DOC_TYPE = 'RE'.
  PS_HEADER-DOC_DATE = ZMCAIMS0021-COMDT.
  PS_HEADER-PSTNG_DATE = ZMCAIMS0021-BUDAT.
  PS_HEADER-COMP_CODE = ZMCAIMS0021-BUKRS.
  PS_HEADER-CURRENCY = ZMCAIMS0021-WAERS.
  CLEAR: LV_AMOUNT.
  WRITE ZMCAIMS0021-RMWWR TO LV_AMOUNT CURRENCY ZMCAIMS0021-WAERS.
  REPLACE ALL OCCURRENCES OF ',' IN LV_AMOUNT WITH ''.
  PS_HEADER-GROSS_AMOUNT = LV_AMOUNT.
  PS_HEADER-PMNTTRMS = ZMCAIMS0021-ZTERM.
  PS_HEADER-BLINE_DATE = ZMCAIMS0021-BUDAT.
  PS_HEADER-PERSON_EXT = SY-UNAME.
  PS_HEADER-HEADER_TXT = ZMCAIMS0021-BLENO.


  PS_HEADER-REF_DOC_NO = ZMCAIMS0021-COMIV.

  CLEAR :GV_IV,LV_ITEM.
  SORT GT_DATA2.
  LOOP AT GT_DATA2 INTO LS_DATA2.
    REFRESH LT_ZMSEG[].
    CLEAR : LV_MENGE_TOL,LV_AMOUNT_TOL."合計校驗
    SELECT * FROM ZMSEG
      INTO TABLE LT_ZMSEG
      WHERE EBELN = LS_DATA2-EBELN
        AND EBELP = LS_DATA2-EBELP
        AND BWART IN ('101','102','161','162').

    "剔除沖銷專案
    LT_ZMSEG1[] = LT_ZMSEG[].
    LOOP AT LT_ZMSEG1 WHERE SMBLN IS NOT INITIAL.
      DELETE LT_ZMSEG WHERE MBLNR = LT_ZMSEG1-SMBLN
                        AND ZEILE = LT_ZMSEG1-SMBLP.
    ENDLOOP.
    DELETE LT_ZMSEG WHERE SMBLN IS NOT INITIAL.

    LOOP AT LT_ZMSEG.
      CLEAR: LS_ITEM.
      CHECK LT_ZMSEG-MENGE > 0.
      LV_ITEM = LV_ITEM + 1.
      LS_ITEM-INVOICE_DOC_ITEM = LV_ITEM.
      LS_ITEM-PO_NUMBER = LS_DATA2-EBELN.
      LS_ITEM-PO_ITEM = LS_DATA2-EBELP.
      LS_ITEM-REF_DOC = LT_ZMSEG-MBLNR."參照收貨憑證
      LS_ITEM-REF_DOC_YEAR = LT_ZMSEG-MJAHR.
      LS_ITEM-REF_DOC_IT = LT_ZMSEG-ZEILE.
      LS_ITEM-TAX_CODE = 'J0'.
      LS_ITEM-ITEM_TEXT = PS_HEADER-ITEM_TEXT.
      LS_ITEM-QUANTITY = LT_ZMSEG-MENGE.
      LS_ITEM-PO_UNIT = LT_ZMSEG-MEINS.
      CLEAR: LV_NETWR,LV_AMOUNT.
      LV_NETWR = LT_ZMSEG-MENGE * LS_DATA2-NETPR.
      WRITE LV_NETWR TO LV_AMOUNT CURRENCY ZMCAIMS0021-WAERS.
      REPLACE ALL OCCURRENCES OF ',' IN LV_AMOUNT WITH ''.
      LS_ITEM-ITEM_AMOUNT = LV_AMOUNT.
      APPEND LS_ITEM TO PT_ITEMS.
    ENDLOOP.

  ENDLOOP.

ENDFORM.                    "fill_values

3、Bapi呼叫

*&---------------------------------------------------------------------*
*&      Form  run_to_create_iv
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_ITEMS   text
*      -->PS_HEADER  text
*----------------------------------------------------------------------*
FORM RUN_TO_CREATE_IV TABLES PT_ITEMS STRUCTURE BAPI_INCINV_CREATE_ITEM
                       USING PS_HEADER TYPE BAPI_INCINV_CREATE_HEADER.

  DATA: LT_RET TYPE TABLE OF BAPIRET2.
  DATA: LV_INVNO TYPE BAPI_INCINV_FLD-INV_DOC_NO,
        LV_FYEAR TYPE BAPI_INCINV_FLD-FISC_YEAR.
  DATA: LS_BKPF TYPE BKPF.

  CLEAR: LT_RET.
  CALL FUNCTION 'BAPI_INCOMINGINVOICE_CREATE'
    EXPORTING
      HEADERDATA          = PS_HEADER
*     ADDRESSDATA         =
    IMPORTING
      INVOICEDOCNUMBER    = LV_INVNO
      FISCALYEAR          = LV_FYEAR
    TABLES
      ITEMDATA            = PT_ITEMS[]
*     ACCOUNTINGDATA      =
*     GLACCOUNTDATA       =
*     MATERIALDATA        =
*     TAXDATA             = lt_taxes
*     WITHTAXDATA         =
*     VENDORITEMSPLITDATA =
      RETURN              = LT_RET.

  PERFORM CHECK_BAPI_ERROR USING LT_RET.
  IF GV_BAPI_ERROR <> 'X'.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
    EXPORTING
      WAIT          = 'X'
*     IMPORTING
*       RETURN        =
              .
    MESSAGE S398(00) WITH 'Invoice document(' ZMCAIMS0021-INVNO ') created'.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'
*     IMPORTING
*       RETURN        =
              .
    PERFORM SHOW_MESSAGE USING LT_RET.
  ENDIF.
ENDFORM.                    " run_to_create_iv

*&---------------------------------------------------------------------*
*&      Form  show_message
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_MSG     text
*----------------------------------------------------------------------*
FORM SHOW_MESSAGE USING PT_MSG TYPE BAPIRET2_T.

  PERFORM CHECK_BAPI_ERROR USING PT_MSG[].

  IF GV_BAPI_ERROR = 'X'."오류 메시지가 발생했을 경우
    CALL FUNCTION 'FB_MESSAGES_DISPLAY_POPUP'
      EXPORTING
*       IT_SMESG        =
*       ID_SMESG_ZEILE  =
        IT_RETURN       = PT_MSG[]
*       ID_SEND_IF_ONE  =
      EXCEPTIONS
        NO_MESSAGES     = 1
        POPUP_CANCELLED = 2
        OTHERS          = 3.
  ENDIF.
ENDFORM.                    " show_message

*&---------------------------------------------------------------------*
*&      Form  check_bapi_error
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_BAPI_MSG  text
*----------------------------------------------------------------------*
FORM CHECK_BAPI_ERROR USING PT_BAPI_MSG TYPE BAPIRET2_T.
  CLEAR: GV_BAPI_ERROR.
  READ TABLE PT_BAPI_MSG TRANSPORTING NO FIELDS WITH KEY TYPE = 'E'.
  IF SY-SUBRC = 0.
    GV_BAPI_ERROR = 'X'.
  ENDIF.
  READ TABLE PT_BAPI_MSG TRANSPORTING NO FIELDS WITH KEY TYPE = 'A'.
  IF SY-SUBRC = 0.
    GV_BAPI_ERROR = 'X'.
  ENDIF.
ENDFORM.                    " check_bapi_error

 

相關文章