The post How to replicate IDocs from one SAP system to another appeared first on INT4.
]]>Reading time: 4 minutes
The most common reason for the IDoc replication is when the business users identify an issue on Production and the interface is based on Inbound IDocs. In that case the same IDoc must be replicated on Quality or other testing environment.
In this blog I will present you the most common ways on how to copy an IDoc from one system to another. Moreover, I will focus on how to copy an IDoc from Production environment to a test environment. I will not get into the details of the common ways to achieve the IDoc replication, but I want to present you the best way to do that. It does not matter if you are a business user, a functional consultant, an integration consultant, or an ABAP developer. I will show you the easiest way that each user who needs to replicate an IDoc, will be able to do that.
Usually, the following ways are used to replicate an IDoc from production to test environment:
So, what is the easiest way to replicate an IDoc from Production environment to any other SAP system?
The only thing that you need is Int4 IFTT. Int4 IFTT is a regression testing tool, for SAP API testing. But, why not to benefit from it and use it whenever possible. So, I always use it when I need to copy an IDoc from one system to another. That way I am not only able to replicate the IDoc processing, but also Int4 IFTT does a backend validation at the same time, so I can make sure that the documents get posted in the exact same way on both systems and the issue was replicated properly.
Based on the initial configuration of the Int4 IFTT you have the option to read the IDocs from the integration platform or directly from the SAP S/4 backend. In both cases you need only the IDoc numbers. Either you already have those number or you can use the Message Selector of the Int4 IFTT Cockpit to find the needed IDocs.
Let’s have look at a step by step Example.
Choose an Automation Object created based on the IDoc details
Int4 IFTT Cockpit – New test case creation
IDoc Message Selector
IDoc Message Selector – Transfer Selected
Int4 IFTT cockpit – Save test cases
Test case execution on other environment
The IDOCs are replicated on the TEST Environment! And the whole replication process took me only 30 seconds!
Test Execution Report
The green status shows that the IDoc are replicated in the exact same way and they created the exact business documents in Test as they are in Production.
Moreover the most important is that we have our needed IDocs replicated in Test environment and we can debug and dive into the processing details!
If you have access to Int4 IFTT, why not to benefit from it in every possible way. One great way to get advantage of it is to use it always when you need to replicate business documents from one SAP system to another. That way you ensure that there is no trespassing to the production system. By creating a single test case, you have an exact copy of the wanted IDoc and you can reprocess it any number of times on any connected SAP system. And the most important, it will take just seconds to replicate the wanted IDoc from one system to another.
If you want to find out more about the Int4 IFTT features, take a look at rest blogs about it, also you can book a consultation with the product demo or contact us.
1. Speed up Int4 IFTT test case creation using Message Selector
2. Int4 IFTT: how to set up a test for a message split?
The post How to replicate IDocs from one SAP system to another appeared first on INT4.
]]>The post IDoc modification made easy with ABAP Object Oriented Programming appeared first on INT4.
]]>In this blog, you will learn how to easily perform the create, read, update and delete (CRUD) operations on IDoc segments, thanks to the use of ABAP Object Oriented Programming.
Reading time: 4 minutes
The Intermediate Document (IDoc) format is widely used throughout the SAP system, with thousands of message types and countless segment types. Still, the standard way of handling the CRUD operations relies on performing modifications directly on the internal table that contains all of the message’s segments. This means that you, the developer, are responsible for not only modifying the values in the segments, but also for maintaining the correct structure of the IDoc (segments sequence). This can be cumbersome when dealing with different IDoc types/extensions and adds unnecessary work.
The example below shows the standard logic responsible for creating an invoice IDoc, as seen in the function ISU_IDOC_INVOICE_CREATE:
*$*$ macro to append a segment to an IDOC * &1 segment name * &2 segment data define append_segment. clear t_idoc_data. t_idoc_data-segnam = &1. t_idoc_data-sdata = &2. append t_idoc_data. clear &2. end-of-definition. case e1isu_begin_inv_big4010-big08. when co_cancel. * Invoice cancelled ref-ref01 = co_original_doc_no. * BUILD UNIQUE TRANSACTION NUMBER concatenate x_invoice_data-header-intopbel x_invoice_data-erch-belnr into ref-ref02 . append_segment co_seg_ref ref . when others. * Do nothing endcase.
To simplify the code responsible for IDoc CRUD operations, you can implement a Facade pattern. The proposed facade consists of a set of three custom classes, and the relationship between them is shown on the UML diagram below:
UML diagram of Facade objects’ relationships
In short, each of the classes is responsible for:
Before any modification is done to the IDoc segments, you need to create an object, which will represent the message. You can do this using the CREATE_WITH_DATA method of the ZCL_IDOC_EDIDD class.
CONSTANTS: lc_type_orders05 TYPE edi_idoctp VALUE 'ORDERS05', lc_extension_none TYPE edi_cimtyp VALUE ". DATA: lt_edidd TYPE edidd_tt. TRY. DATA(lo_idoc) = zcl_idoc_edidd=>create_with_data( iv_idoc_type = lc_type_orders05 iv_idoc_extension = lc_extension_none it_edidd = lt_edidd ). CATCH zcx_idoc_exceptions INTO DATA(lo_exception). MESSAGE lo_exception TYPE 'I'. RETURN. ENDTRY.
As you can see in the example above, the first two parameters define the message type and extension. This way, the LO_IDOC object is able to retrieve all information about the structure of the message that is required for maintaining the correct sequence of the segments.
The IT_EDIDD parameter is optional. You should populate it with the EDIDD internal table of the IDoc you wish to modify.
When the IDoc object is created, you are ready to modify its contents. You can use the ADD_SEGMENT method to add a new segment to the IDoc. Remember about catching exceptions that may be raised during the operation, for example if the segment is not part of the message type.
DATA: ls_edidd TYPE edidd, ls_e1edka1 TYPE e1edka1. ls_e1edka1-parvw = 'WE'. ls_e1edka1-partn = '1234567890'. ls_edidd-segnam = 'E1EDKA1'. ls_edidd-sdata = ls_e1edka1. TRY. lo_idoc->add_segment( ls_edidd ). CATCH zcx_idoc_exceptions INTO DATA(lo_exception). MESSAGE lo_exception TYPE 'I'. RETURN. ENDTRY.
As you can see, there is no need to worry about the position of the added segment. The LO_IDOC object will handle it on its own, adding the segment in the correct position under the root segment of the IDoc or under the last parent segment (if a non-root parent is required).
If the parent segment is not found, an exception will be raised.
You can also add a child segment directly under a specific parent segment.
DATA: ls_edidd TYPE edidd, ls_e1edp01 TYPE e1edp01, ls_e1edp19 TYPE e1edp19. ls_e1edp01-posex = '10'. ls_e1edp19-qualf = '003'. TRY. ls_edidd-segnam = 'E1EDP01'. ls_edidd-sdata = ls_e1edp01 DATA(lo_item) = lo_idoc->add_segment( ls_edidd ). CLEAR ls_edidd. ls_edidd-segnam = 'E1EDP19'. ls_edidd-sdata = ls_e1edp19. lo_item->add_segment( ls_edidd ). CATCH zcx_idoc_exceptions INTO DATA(lo_exception). MESSAGE lo_exception TYPE 'I'. RETURN. ENDTRY.
This way, you are in total control under which parent the new segment will appear in the IDoc. But how to find the segment you are interested in? For this, you need to use the GET_SEGMENTS method, which returns a collection of segments. Have a look at the example below:
DATA: ls_edidd TYPE edidd, ls_e1edp01 TYPE e1edp01, ls_e1edp19 TYPE e1edp19, lo_segment TYPE REF TO zcl_idoc_edidd_segment. ls_e1edp19-qualf = '003'. ls_edidd-segnam = 'E1EDP19'. ls_edidd-sdata = ls_e1edp19. TRY. DATA(lo_collection) = lo_idoc->get_segments( 'E1EDP01' ). DATA(lo_iterator) = lo_collection->get_iterator( ). WHILE lo_iterator->has_next( ). lo_segment ?= lo_iterator->get_next( ). ls_e1edp01 = lo_segment->get_sdata( ). " add child under position 50 CHECK ls_e1edp01-posex = '50'. lo_segment->add_segment( ls_edidd ). EXIT. ENDWHILE. CATCH zcx_idoc_exceptions INTO DATA(lo_exception). MESSAGE lo_exception TYPE 'I'. RETURN. ENDTRY.
Modification of any of the segments is as simple as finding it, retrieving its SDATA structure, modifying it and putting it back into the segment.
DATA: ls_e1edka1 TYPE e1edka1, lo_segment TYPE REF TO zcl_idoc_edidd_segment. " get the first E1EDKA1 segment lo_segment ?= lo_idoc->get_segments( 'E1EDKA1' )->get( 1 ). IF lo_segment IS BOUND. ls_e1edka1 = lo_segment->get_sdata( ). ls_e1edka1-partn = '0987654321'. lo_segment->set_sdata( ls_e1edka1 ). ENDIF.
Last but not least, the delete operation.
If you want to remove any of the segments from the IDoc, simply use the REMOVE_SEGMENT method. The segment will be removed even if it is not placed directly under the specified parent. This means that if you use the LO_IDOC object for the method call, the segment will be removed regardless of its position in the IDoc.
DATA: lo_segment TYPE REF TO zcl_idoc_edidd_segment. " get the first E1EDKA1 segment lo_segment ?= lo_idoc->get_segments( 'E1EDKA1' )->get( 1 ). IF lo_segment IS BOUND. lo_idoc->remove_segment( lo_segment ). ENDIF.
It is worth mentioning that when you remove a segment from the IDoc, all of its children are removed as well. So, again, there is no need to bother with maintaining the correct structure of the message.
After you are finished with the modifications, all is left to do is to retrieve the resulting internal table containing the IDoc segments. You can do this by calling the GET_EDIDD method.
DATA(lt_edidd) = lo_idoc->get_edidd( ).
With the use of just three simple ABAP classes, you are able to simplify the implementation of IDoc CRUD operations, leaving handling of the correctness of the segments’ sequence to the system.
You can download the solution from GitHub.
The post IDoc modification made easy with ABAP Object Oriented Programming appeared first on INT4.
]]>The post AIF – Interface Determination for IDOC Interfaces – setup appeared first on INT4.
]]>allows to define multiple interfaces with common IDOC basic type. From this blog you will learn:
In this short blog I would like to show you how to quickly configure Interface Determination for IDOC interfaces. As AIF allows to define multiple interfaces with common IDOC basic type it also provides a way to determine which message should go through which interfaces depending on particular fields value.
As an example, let’s take two different inbound interfaces using common basic type DELVRY02
To differentiate lets assume they are named DELVRY02_I and DEL02_XX_I. We need two separate interfaces in order to maintain separate business logic depending on the sender partner.
To determine which interface should the message go through we need to access /AIF/CUST t-code and move on to Interfaces Determination -> Define Interface Determination for IDOC Interfaces.
In the next step we need to add a new entry to Define Determination Key.
After providing Basic Type and Message Type of the IDOC we need to define fields within IDOC structure that will serve as a key for interface determination. In this case we will need IDOC’s direction (inbound – ‘2’ or outbound – ‘1’) and sender partner value. Both of these fields reside in the IDOC’s control segment thus we need to set field category for both as “IDOC Control Record” together with the actual field name.
Now we must proceed to “assign interfaces”.
For each of the fields defined in the previous step, we now have a relevant operator (Equal, Not Equal, etc. ) and value for interface determination to be set. Let’s assume that we want all messages from sender partner LS_1 to go only through DEL02_XX_I Interface. In order to achieve this for DEL02_XX_I Interface we must set operator for SNDPRT field as EQUAL LS_1…
… while setting the opposite for the DELVRY02_I interface.
If you want to learn more about AIF’s advanced features, please check these books by our SAP Press authors:
The post AIF – Interface Determination for IDOC Interfaces – setup appeared first on INT4.
]]>The post AIF Index Tables: IDOC qualifiers appeared first on INT4.
]]>AIF allows for indexing field values in order to facilitate filtering out messages in its message monitoring – /AIF/ERR. For this purpose, Index Tables are used. They keep all the data that comes through the particular interface in selected fields.
From this step-by-step manual you will learn:
Things get a bit more complicated when it comes to an IDOC scenario. Some IDOC segments contain qualifiers, which hold value that determines other fields within the segment. I.e. in the IDOC basic type INVOICE02 segment E1EDK02 has a BELNR field, that for qualifier = ‘001’ is the Customer Purchase Order number and for qualifier = ?009? is the invoice number. This way the same field of a structure can be used to maintain different types of data.
Now let?s say the requirement is to index only BELNR values with these two qualifiers, and to keep them under two separate fields.
While we define our fields of EDI_BELNR data type in Error Handling -> Define Interface- Specific Features-> Define Key Fields for Multi Search we must remember to mark checkbox Key Field Rule. Then, in the Function Module field we pass reference to a FM that contains our logic for processing the BELNR values depending on the qualifier value.
In this sample function module we store BELNR values only if the 3 initial characters of sdata structure (it?s where the qualifier value resides) are equal to ‘009’.
FUNCTION AIF_KEYFIELD_BELNR_001 . *"---------------------------------------------------------------------- *"*"Local Interface: *" IMPORTING *" REFERENCE(IS_RAW_STRUCTURE) TYPE ANY OPTIONAL *" REFERENCE(IS_SAP_STRUCTURE) TYPE ANY OPTIONAL *" REFERENCE(IS_KFLDS) TYPE /AIF/T_INF_KFLDS *" CHANGING *" REFERENCE(CS_SIDX_ENTRY) TYPE ANY *"---------------------------------------------------------------------- FIELD-SYMBOLS: <lt_idoc_data> TYPE edidd_tt. ASSIGN COMPONENT 'ZZBNRINV' OF STRUCTURE cs_sidx_entry TO FIELD-SYMBOL(<fs_ZZBNRINV>). CHECK <fs_ZZBNRINV> IS ASSIGNED. ASSIGN COMPONENT 'IDOC_DATA' OF STRUCTURE is_sap_structure TO <lt_idoc_data>. CHECK <lt_idoc_data> IS ASSIGNED. IF LINE_EXISTS( <lt_idoc_data>[ segnam = 'E1EDK02' sdata(3) = '009'] ) . <fs_ZZBNRINV> = <lt_idoc_data>[ segnam = 'E1EDK02' sdata(3) = '009' ]-sdata+3(38). ELSE. CLEAR <fs_ZZBNRINV>. ENDIF . ENDFUNCTION.
However we must keep in mind that this will work only for Single selection type index tables.
If you would like to learn more about AIF Index tables please read these blogs by Mateusz Nowak:
The post AIF Index Tables: IDOC qualifiers appeared first on INT4.
]]>