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)
At this point, let’s see how releationship looks in material document:
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:
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: