Wednesday, April 29, 2020

SAP BAPI (Business Application Programming Interface)






SAP BAPI is a standard interface to the business object models. BAPIs wrap the internal layers of SAP's business object model to ensure that all business logic, validations and authorization checks are executed properly when accessing or changing business objects.


How BAPI works

BAPIs are implemented as function modules that call SAP internal code. Depending on which set of  APIs is being used, they may call business object models defined using the Business Objects Processing Framework (BOPF) or legacy models defined using programs, tables and function modules.
BAPIs expose a formal and stable interface that developers of customer and third-party code can use to access and interface with SAP business objects. BAPI will not have any exception, it will return exception through the return table.

Business Object  - Performs an action (E.g. create MIGO)
Business object repository  (BOR) - Collection of Objects (E.g. Create invoice,Create purchase order)
Interface  - Accessing the business objects through Interface

Business Object -> Interface -> Methods

Tcode for Business Object : SWO1 (Business object builder)

Tcode for BAPI Explorer: BAPI  

Reference : BAPI Documentation

Using BAPI -  GR Posting for each line item of Purchase order:

'BAPI_GOODSMVT_CREATE’ is used here to post Goods Receipt against the PO. Create a program with the following code:

Program Name: ZTEST_PROG_POGRN_BAPI1

INCLUDE ZTEST_PROG_POGRN_BAPI1_TOP.
INCLUDE ZTEST_PROG_POGRN_BAPI1_F01.

INITIALIZATION.

AT SELECTION-SCREEN.

START-OF-SELECTION .
  PERFORM f_get_data .

END-OF-SELECTION.

IF NOT it_ekko IS INITIAL.

    PERFORM f_Call_bapi .

    PERFORM f_fieldcat_alv.

    PERFORM f_display_alv.

ENDIF.

-----------------------------------------------------
**Global Declaration

REPORT ztest_prog_pogrn_bapi1.

TABLESekko.

TYPE-POOLS slis.

DATA gs_ekko TYPE ekko.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.

SELECT-OPTIONSs_ebeln FOR gs_ekko-ebeln." OBLIGATORY.
PARAMETERS:     p_lifnr TYPE lifnr.

SELECTION-SCREEN END OF BLOCK b1.

* Types declaration for EKKO table PURCHASING HEADER
TYPESBEGIN OF ty_ekko,
         ebeln TYPE ebeln,
       END OF ty_ekko.

* Types declaration for EKPO table PURCHASING DOCUMENT ITEM
TYPESBEGIN OF ty_ekpo,
         ebeln TYPE ebeln,
         ebelp TYPE ebelp,
         matnr TYPE matnr,
         werks TYPE ewerk,
         lgort TYPE lgort_d,
         menge TYPE bstmg,
         meins TYPE bstme,
       END OF ty_ekpo.

* Types declaration for MAKTX table MATERIAL DESCRIPTION
TYPESBEGIN OF ty_maktx,
         matnr TYPE matnr,
         maktx TYPE maktx,
       END OF ty_maktx.

*types declaration for combined DATA structure

TYPESBEGIN OF ty_final,
         ebeln TYPE ebeln,
         ebelp TYPE ebelp,
         matnr TYPE matnr,
         werks TYPE ewerk,
         lgort TYPE lgort_d,
         menge TYPE bstmg,
         meins TYPE bstme,
         maktx TYPE maktx,
       END OF ty_final.


*types declaration for Output DATA structure

TYPESBEGIN OF ty_det,
         ebeln TYPE ebeln,
         mblnr TYPE mblnr,
         mjahr TYPE mjahr,
       END OF ty_det.

* Internal Tables & work area Declaration
DATAit_ekko  TYPE TABLE OF ty_ekko,
      wa_ekko  TYPE          ty_ekko,

      it_ekpo  TYPE TABLE OF ty_ekpo,
      wa_ekpo  TYPE          ty_ekpo,

      it_temp  TYPE TABLE OF ty_ekpo,

      it_maktx TYPE TABLE OF ty_maktx,
      wa_maktx TYPE          ty_maktx,

      it_det   TYPE TABLE OF ty_det,
      wa_det   TYPE          ty_det,

      it_final TYPE TABLE OF ty_final,
      wa_final TYPE          ty_final.

* BAPI Structure Declaration
DATA:
  wa_goodsmvt_header  LIKE  bapi2017_gm_head_01,
  wa_goodsmvt_code    LIKE  bapi2017_gm_code,

  wa_goodsmvt_headret LIKE  bapi2017_gm_head_ret,

  it_return           TYPE TABLE OF bapiret2,
  wa_return           TYPE          bapiret2,

  it_goodsmvt_item    TYPE TABLE OF bapi2017_gm_item_create,
  wa_goodsmvt_item    TYPE          bapi2017_gm_item_create.

*  ALV Output Structure Declaration

DATA:
  it_fcat  TYPE slis_t_fieldcat_alv,
  it_fcat1 TYPE slis_t_fieldcat_alv,
  wa_fcat  TYPE slis_fieldcat_alv.

---------------------------------------------------------------------------------------------
FORM f_get_data .

  REFRESH it_ekko.
  CLEAR wa_ekko.

  IF NOT s_ebeln IS INITIAL.

    SELECT ebeln
           FROM ekko
           INTO TABLE it_ekko
           WHERE ebeln IN s_ebeln
           AND lifnr p_lifnr .

  ENDIF.

  IF NOT it_ekko[] IS INITIAL.
    SORT it_ekko BY ebeln.

*Retrieve PO document details from Item (EKPO) table
    SELECT ebeln ebelp matnr werks lgort menge meins
    FROM ekpo
    INTO TABLE it_ekpo
   FOR ALL ENTRIES IN it_ekko
   WHERE ebeln it_ekko-ebeln.

    IF sy-subrc IS INITIAL
      AND NOT it_ekpo[] IS INITIAL.
      it_temp[] it_ekpo[].
      SORT it_temp BY matnr.
      DELETE ADJACENT DUPLICATES FROM it_temp COMPARING matnr.

      IF NOT it_temp[] IS INITIAL.
* Retrieve the Material Description from MAKT table
        SELECT matnr maktx
        FROM makt
        INTO TABLE it_maktx
        FOR ALL ENTRIES IN it_temp
        WHERE matnr it_temp-matnr
          AND spras 'E'.
        SORT it_ekpo BY ebeln ebelp.
        IF sy-subrc IS INITIAL
          AND NOT it_maktx IS INITIAL.
          LOOP AT it_ekpo INTO wa_ekpo.
            wa_final-ebeln wa_ekpo-ebeln.
            wa_final-ebelp wa_ekpo-ebelp .
            wa_final-matnr wa_ekpo-matnr .
            wa_final-werks wa_ekpo-werks .
            wa_final-lgort wa_ekpo-lgort .
            wa_final-menge wa_ekpo-menge .
            wa_final-meins wa_ekpo-meins .

            READ TABLE it_maktx INTO wa_maktx
             WITH KEY matnr wa_ekpo-matnr
             BINARY SEARCH.
            IF sy-subrc IS INITIAL.
              wa_final-maktx wa_maktx-maktx.
            ENDIF.
            APPEND wa_final TO it_final.
            CLEAR wa_final.
          ENDLOOP.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDIF.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_CALL_BAPI
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM f_call_bapi .

  REFRESH it_return.
  CLEAR it_return.


* Fill the bapi Header structure details
  wa_goodsmvt_header-pstng_date sy-datum.
  wa_goodsmvt_header-doc_date sy-datum.
  wa_goodsmvt_header-pr_uname sy-uname.
*  wa_goodsmvt_header-REF_DOC_NO = WA_EKPO-EBELN.

* Looping the PO details.
  LOOP AT it_final INTO wa_final "WHERE ebeln = wa_final-ebeln .

* FILL THE BAPI ITEM STRUCTURE DETAILS
    wa_goodsmvt_item-material wa_final-matnr.
    wa_goodsmvt_item-item_text wa_final-maktx.
    wa_goodsmvt_item-plant wa_final-werks.
    wa_goodsmvt_item-stge_loc wa_final-lgort.
    wa_goodsmvt_item-move_type '101'.
    wa_goodsmvt_item-po_number wa_final-ebeln.
    wa_goodsmvt_item-po_item wa_final-ebelp.
    wa_goodsmvt_item-entry_qnt wa_final-menge.
    wa_goodsmvt_item-entry_uom wa_final-meins.
    wa_goodsmvt_item-no_more_gr 'X'.
    wa_goodsmvt_item-ref_doc wa_final-ebeln.
    wa_goodsmvt_item-prod_date sy-datum.
    wa_goodsmvt_item-mvt_ind 'B'.

    APPEND wa_goodsmvt_item TO it_goodsmvt_item.
    CLEAR wa_goodsmvt_item.

  ENDLOOP.

*  * Call the BAPI FM for GR posting
  CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
    EXPORTING
      goodsmvt_header  wa_goodsmvt_header
      goodsmvt_code    '01'
      testrun          space
    IMPORTING
      goodsmvt_headret wa_goodsmvt_headret
    TABLES
      goodsmvt_item    it_goodsmvt_item
      return           it_return.

*    IF sy-subrc = 0.
** For commit the changes use BAPI_TRANSACTION_COMMIT FM.
*      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
*        EXPORTING
*          wait = 'X'.
*      MOVE: wa_goodsmvt_headret-mat_doc TO wa_det-mblnr,
*            wa_goodsmvt_headret-doc_year TO wa_det-mjahr ,
*            wa_ekpo-ebeln TO wa_det-ebeln.
*      APPEND wa_det TO it_det.
*      CLEAR wa_det.
*    ENDIF.
*
*
*
*  WRITE:1(15)'PO document', 18(20)'Material Document', 40(5)'Year'.
*  LOOP AT it_det INTO wa_det.
*    WRITE:/1(15) wa_det-ebeln,
*           18(20) wa_det-mblnr,
*           40(5) wa_det-mjahr.
*  ENDLOOP.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_FIELDCAT_ALV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM f_fieldcat_alv .

  REFRESHit_fcat.
  CLEAR wa_fcat.

  IF sy-subrc 0.
* For commit the changes use BAPI_TRANSACTION_COMMIT FM.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait 'X'.
    MOVEwa_goodsmvt_headret-mat_doc TO wa_det-mblnr,
          wa_goodsmvt_headret-doc_year TO wa_det-mjahr ,
          wa_ekpo-ebeln TO wa_det-ebeln.
    APPEND wa_det TO it_det.
    CLEAR wa_det.
  ENDIF.


  wa_fcat-row_pos '1'.
  wa_fcat-col_pos '1'.
  wa_fcat-fieldname 'EBELN'.
  wa_fcat-tabname 'IT_DET'.
  wa_fcat-seltext_l TEXT-003.
  APPEND wa_fcat TO it_fcat.
  CLEAR wa_fcat.

  wa_fcat-row_pos '1'.
  wa_fcat-col_pos '2'.
  wa_fcat-fieldname 'MBLNR'.
  wa_fcat-tabname 'IT_DET'.
  wa_fcat-seltext_l TEXT-004.
  APPEND wa_fcat TO it_fcat.
  CLEAR wa_fcat.

  wa_fcat-row_pos '1'.
  wa_fcat-col_pos '3'.
  wa_fcat-fieldname 'MJAHR'.
  wa_fcat-tabname 'IT_DET'.
  wa_fcat-seltext_l TEXT-005.
  APPEND wa_fcat TO it_fcat.
  CLEAR wa_fcat.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_DISPLAY_ALV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM f_display_alv .

  DATAlv_repid TYPE sy-repid.

  lv_repid sy-repid.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program      lv_repid
      i_callback_user_command 'DISPLAY_ITEMS'
      it_fieldcat             it_fcat
      i_save                  'A'
* IMPORTING
*     E_EXIT_CAUSED_BY_CALLER =
*     ES_EXIT_CAUSED_BY_USER  =
    TABLES
      t_outtab                it_det
    EXCEPTIONS
      program_error           1
      OTHERS                  2.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form DISPLAY_ITEMS
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM display_items USING ucomm TYPE sy-ucomm
                         selfield TYPE slis_selfield.

  CASE ucomm.
    WHEN '&IC1'.

*      BREAK-POINT.

****      drill down to the transaction
      READ TABLE it_det INTO wa_det INDEX selfield-tabindex.

      IF selfield-fieldname 'EBELN'.
        SET PARAMETER ID 'BES' FIELD wa_det-ebeln.
        CALL TRANSACTION 'ME23N'  AND  SKIP FIRST SCREEN.
      ELSEIF selfield-fieldname 'MBLNR'.
        SET PARAMETER ID 'AUN' FIELD wa_det-mblnr.
        CALL FUNCTION 'MIGO_DIALOG'
          EXPORTING
            i_action            'A04'
            i_refdoc            'R02'
            i_notree            'X'
            i_no_auth_check     ' '
            i_deadend           'X'
            i_skip_first_screen 'X'
            i_okcode            'OK_GO'
            i_mblnr             wa_det-mblnr
            i_mjahr             wa_det-mjahr.
      ENDIF.


  ENDCASE.

ENDFORM.

---------------------------------------------------------------------------

Execute the program.

Create a PO using the Tcode : ME21N












The selection screen will be displayed.
Enter the Purchase order number “4500000051”  and Vendor as '12' , Execute the Program.










It will create a material document number for posting of movement type 101.

The output will be displayed as below








To check the details of the material document created , Please double click on the material document. It will display the material document. Similarly to check the PO details, double click on the Purchase order, it will display the PO document.


















Tuesday, April 28, 2020

User Exit in Sales Document

Business Requirement:  When user enters the Incoterm as FOB, Automatically shipping condition has to determine as 'Picking'. By default it will be as 'standard'.

VA01 is the t-code for creating a sales order, this uses standard SAP program SAPMV45A, the standard program will not have the functionality of determine the shipping conditions based on Incoterm.

As per the requirement, we need to find a suitable user exit for this and we need add additional code to determine the shipping condition based on incoterm.

 Technical information : Incoterm field is INCO1 (Table - VBKD) and shipping condition field name is VSBED (Table - VBAK).

Reference Document : SAP User Exit SD Processing

To implement the user exit for this we need to follow the below steps.

Step 1: Find the user exit.

Step 2: Verify the user exit.
Step 3: Implement the user exit.

Go to SE80 Tcode, Program name : SAPMV45A



















Click on Enhance button














Go to Edit -> Enhancement operations -> Show Implicit Enhancement Options


























Right click on the 'USEREXIT_SAVE_DOCUMENT_PREPARE' . Enhancement Operations -> Create Implementation. 



















Click on the Code option.

























Create a customized code and assign the transportable package.


























Write the code inside the enhancement block.
















Create a Sales order VA01, Enter the incoterm as FOB and save the document.
































Go to VA02 document, Check the Shipping condition in the shipping tab - Header.