ABAP Development

Complete Guide on trigger an outbound IDoc when Good receipt posted in S4

Background:

There are certain ways that we could use in S4 to trigger an outbound IDocs. For example, using change pointers, Output type determination. The ideal fit needs to be chosen based on the requirement. Moreover, when master data creation or delta changes have to be informed to another system change pointers are the best fit where for transactional data, output determination is widely used.

Nevertheless, what if, there is no standard process code found (WE41 / TMSG1 table) for IDoc basic type/message which is required by business requirment.

In this scenario, we need to send the material document information which was posted (VL32N, MIGO or Inbound IDocs ) in S4 while good receving to external system. For that Basic type MBGMCR04 and MBGMCR were used and output determination couldn’t help this.

Solution:

A BADI which is triggered for VL32N, MIGO and IDocs had to be chosen. The reason to find out such a BADI is recommended over using completely a custom ABAP program since otherwise custom abap logics should be written to populate IDoc structures and this would make life harder when it comes to UAT and post go live support.

MB_DOCUMENT_BADI should be implemnted and method MB_DOCUMENT_UPDATE shoud be used. Function module MASTER_IDOC_DISTRIBUTE was leveraged to create the outbound IDoc.

up until this point everything sounds good in terms of sending IDoc to externl party. But for the S4 business user, there is no any link to the IDoc triggered for the interface via material document. So it is crucial to maintain the relationship for a better user experince. This blog post will discuss in detail how to update the IDoc number triggered to see in the relationship browser of material document as well.

Technical configurations steps:

All the details which is required to populate IDoc structures could be found in importing parameters, such as XMKPF and XMSEG tables.

Note: In case a data couldn’t be found in those structures and a custom logic should be written, it is recommend to maintain those under structure mapping in AIF (application interface framework) if available. if AIF is available in your landscape make sure to fill EDIDC data align with AIF partner profile and IDoc will be pushed to AIF port.

once IDoc structures are filled FM : MASTER_IDOC_DISTRIBUTE should be called.

CALL FUNCTION 'MASTER_IDOC_DISTRIBUTE'
          EXPORTING
            master_idoc_control        = ls_edidc
*           OBJ_TYPE                   = ''
*           CHNUM                      = ''
          TABLES
            communication_idoc_control = lt_edidc
            master_idoc_data           = lt_edidd
*     EXCEPTIONS
*           ERROR_IN_IDOC_CONTROL      = 1
*           ERROR_WRITING_IDOC_STATUS  = 2
*           ERROR_IN_IDOC_DATA         = 3
*           SENDING_LOGICAL_SYSTEM_UNKNOWN       = 4
*           OTHERS                     = 5

At the end of this step outbound IDoc is generated and pushed to AIF (it could be directly middleware application too)

Generated IDoc

At this point, let’s see how releationship looks in material document:

ABAP Development
Material Document with no relationship to IDoc

Now let’s try to understand in detail, how IDoc number generated could be added to relationship browser attched to material document.

To achieve this CREATE_LINK method of class CL_BINARY_RELATION could be used. But this method doesn’t support all the object types. For the rest of the object types function module BINARY_RELATION_CREATE could be used.

Hint for determining when to use Function module :

Object types for which above class method is not supported exception “CX_OBL_MODEL_ERROR” is raised. So we suggest you to call above class method inside Try / Catch block.

Building the simple class method to create the relationship to IDoc:

Paramter interface of class method

Sample ABAP code to add the refernce (IDoc) to material document (Referant):

METHOD create_relations_to_idoc.

    TYPES:
      BEGIN OF ty_related.
        INCLUDE TYPE sibflporb.
      TYPES:
        relation TYPE oblreltype,
      END   OF ty_related.

    TYPES:
      ty_relation TYPE ty_related.


    DATA: ls_prop        TYPE sibflporb,
          ls_relation    TYPE ty_relation,  "sibflporbt,
          lwa_relate_key TYPE sibflporb,
          lv_done        TYPE flag,
          ls_parent      TYPE borident,
          lv_relation    TYPE binreltyp,
          ls_related     TYPE borident,
          lv_errstr      TYPE string,
          lx_obl         TYPE REF TO cx_obl.

*** Set material document properties : properties of Referent 
    ls_prop-instid = obj_no_matdoc.
    ls_prop-typeid = obj_type_matdoc.
    ls_prop-catid  = obj_cat_matdoc.

**** set reference : Properties of reference 
    ls_relation-instid = obj_no_idoc.
    ls_relation-typeid = obj_type_idoc.
    ls_relation-catid  = obj_cat_idoc.
    ls_relation-relation = relation.

*** Create relationship to IDoc. 

    MOVE-CORRESPONDING ls_relation TO lwa_relate_key.

    TRY .

*      First calling method to create the Link
        CALL METHOD cl_binary_relation=>create_link
          EXPORTING
            is_object_a = ls_prop                  "material document properties.
            is_object_b = lwa_relate_key           "IDoc properties 
            ip_reltype  = ls_relation-relation.    "IDC0 in this case
*
        lv_done = 'X'.

*       if the class method doesn't help, call the FM to create the link
      CATCH cx_obl_model_error.

        ls_parent-objkey    = ls_prop-instid.    "material document
        ls_parent-objtype   = ls_prop-typeid.    "material document
        ls_related-objkey   = ls_relation-instid.
        ls_related-objtype  = ls_relation-typeid.
        lv_relation         = ls_relation-relation.

        CALL FUNCTION 'BINARY_RELATION_CREATE'
          EXPORTING
            obj_rolea      = ls_parent      "material document 
            obj_roleb      = ls_related     "IDoc 
            relationtype   = lv_relation    "IDC0 in this case
          EXCEPTIONS
            no_model       = 1
            internal_error = 2
            unknown        = 3
            OTHERS         = 4.
        IF sy-subrc <> 0.
          MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
                  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        ELSE.
          lv_done = 'X'.
        ENDIF.
      CATCH cx_obl INTO lx_obl.
        lv_errstr = lx_obl->get_text( ).
        MESSAGE lv_errstr TYPE 'S'.


    ENDTRY.

  ENDMETHOD.

Important:

Normally ABAP “Commit work” needs to be done. But in this scenario, you will get a run time error if you add the commit work at the end. Reason has been BADI method call is an update module. So for this scenario it works perfect with out a commit work.

ABAP code which is calling above class method inside the BADI update method:

CALL METHOD zcl_mb_document_badi=>create_relations_to_idoc
        EXPORTING
          obj_no_matdoc   = lv_mblnr           " material document number + mjahr (document year)
          obj_type_matdoc = lc_obj_typ_matdoc  " BUS2017
          obj_cat_matdoc  = lc_obj_cat         " BO
          obj_no_idoc     = lv_idoc_num        " IDoc number generated by FM Master_IDoc_distribute
          obj_type_idoc   = lc_obj_typ_idoc    " IDOC
          obj_cat_idoc    = lc_obj_cat         " BO
          relation        = lc_relation.       " IDC0

Now, let’s see how relationship browser looks now:

Outbound IDoc number updated in relationship browser

Leave a Reply

Your email address will not be published. Required fields are marked *