In my previous blog S/4HANA for Customer Management 1.0 introduction from technical point of view I give you an overall introduction about this new offering. As in this blog, I will share some more detail regarding One Order Model redesign in S/4HANA for Customer Management 1.0.
The redesign project is led by SAP CRM Chief Architect Scheuch Carsten, who has almost 20 years experience on SAP CRM and is well respected by all CRM developers distributed in different sites within SAP. I really learned a lot by working with him side by side for three months last year.
This blog consists of three parts:
- Why the One Order Model needs redesign in S/4HANA?
- Short review on One Order model in SAP CRM
- New Model in S/4HANA – persistence design
Why the One Order Model needs redesign in S/4HANA?
The One Order model in SAP CRM has proven a very successful, convincing and stable basis for SAP CRM transactions for many years. It is easily extensible, and developing new data sets or features can be accomplished in an add-on style, keeping the influence on existing logic at a minimum.
When the CRM transactions on top of such models moves to S/4HANA world, new requirement arises especially on analytical, reporting or search capabilities. All of these requirement must ultimately fulfill one goal: scan high volume of transactions and extract either aggregated figures or transactions with given attributes. Thanks to HANA, now it is possible to run transactional and analytical applications on the same data basis, even in the same application.
In current One Order Model transaction data is distributed over many tables, which makes multiple joins necessary and sometimes even unavoidable of the name/value style tables inclusion. This will deteriorate the performance of analytics application.
As a remedy, the index table CRMD_ORDER_INDEX was introduced from the very beginning of CRM, into which the most important attributes from transaction data storage tables are replicated as a FLAT table. The analytics processing gets accelerated at the cost of some additionally duplicated storage.
Now with the move to S/4HANA world, it is the best timing to redefine One Order persistence model in such a way that the primary database tables behave well for analytical applications, and that the use of CRMD_ORDER_INDEX is no longer necessary.
Short review on One Order model in SAP CRM
One Order model consists of “segments” with different types highlighted with different colors below.
1. ORDERADM_H and ORDERADM_I: as the name ADM indicates, these two nodes contain ADMinistrative data for Header and Item level.
2. SERVICE_H, PRODUCT_I( orange color below ): Extensions are data segments which EXCLUSIVELY belong to a header or to an item, distinguished by post-fix H or I. Cardinality to header or item is 1:n.
3. SHIPPING, PARTNER( blue color below ): A set is a collection of data which can be linked EITHER to a header OR to an item at the same time. Taking SHIPPING for example, it makes sense for an order to maintain different shipping data on both header and item level.
How CRMD_LINK works in SAP CRM
Each segment introduced above is usually represented by one database table (naming convention: CRMD_<segment>). Some segments might have more than one.
For extensions, the table design is pretty easy: just use the guid of ORDERADM_H( ORDERADM_I ) as primary key of header( item ) extension persistence table.
For set, since it might be used for either header or item, so the persistence table design for set is a little bit tricky compared with extension.
Taking SHIPPING set for example, the connection between ORDERADM_H and SHIPPING is established by CRMD_LINK, the primary key of CRMD_ORDERADM_H and CRMD_SHIPPING are stored in field of GUID_HI and GUID_SET separately.
New Model in S/4HANA – persistence design
Instead of having business data spread in different dedicated table, we now have two flattened tables, one for header and one for item.
Both contains include structures which consists of fields from original set like ORGMAN, PARTNER etc, and header flat table CRMS4D_SERV_H contains fields from original header extension, and item flat table CRMS4D_SERV_I contains fields from original item extension accordingly.
The original table for each segment for example CRMD_ORDERADM_H, CRMD_OPPORT_H etc will remain there but will NOT be used by any application AT ALL. Neither are any data stored there.
Have a look at new package which contains some important table for new model control.
In version 1.0 only a subset of Sales & Service transactions are supported, for example service order, service request and service confirmation. The header level business data of these three transactions are stored in above mentioned table CRMS4D_SERV_H. In later release more transactions will be introduced.
How about the table name for these new transactions? It’s determined by API CL_CRMS4_ACRONYM_CB=>GET_TABLE_NAME.
In new model design the database table has naming convention CRMS4D_<acronym>_H[I] where acronym has 1:1 relationship with object type, maintained in table CRMS4C_ACRONYM.
Shadow table CRMS4D_BTX_H
In SAP CRM if we have a order ID and would like to know its guid, we simply select guid from CRMD_ORDERADM_H using order id and order process type, as orders with different order type might have the same ID.
In S/4HANA for Customer Management this is NOT possible, since CRMD_ORDERADM_H becomes obsolete. And only order ID is available, it is not known whether it is a service document or an activity or whatever else, so we don’t know which table should be used for query, CRMS4D_SERV_H, CRMS4D_ACTV_H or CRMDS4D_<acronym>_H.
The shadow table CRMS4D_BTX_H comes on the stage: it stores order guid, object ID and object type. With object type, the corresponding database table is then available by calling API CL_CRMS4_ACRONYM_CB=>GET_TABLE_NAME mentioned before.
You may consider it as “reduced version” of CRMD_ORDERADM_H, representing a bridge between the old GUID based world and the new database design.
How Order read works under new model
The processing logic of One Order framework is divided into three layers. Each component is equipped with corresponding function groups CRM_<component>_xx, where xx is the layer acronym: OB, OW or DB.
- OW = Object Workarea: treats the current record that is processed by the API.
- OB = Object Buffer: holds the most recent state of the document in the current transaction.
- DB = Database Buffer: holds the current database image of the transaction.
Take OPPORT_H for example:
It’s better that you have some understanding about how these three layers orchestrate for Order read & write scenario as prerequisite knowledge before you deep into One order in S/4HANA world. You might refer to my blog Buffer logic in One Order header extension Read for some illustration. In the end of that blog I provide some links which also contains my blogs regarding One order change, create and save scenario.
The basic idea is: with the goal that all three layers( including event handler and callback functions invoked) shall work as before, it is only necessary to INJECT some new code which acts as a bridge to connect the new model in S/4 world with the old function modules in three layers.
Let’s use a real case for illustration. Suppose I would like to read the item and partner data of this service order.
The implementation is almost exactly the same as you would code in CRM, except the necessity to use shadow table CRMS4D_BTX_H instead of CRMD_ORDERADM_H.
REPORT zcrms4_order_read. DATA: lt_guid TYPE crmt_object_guid_tab, lt_product_i TYPE crmt_product_i_wrkt, lt_partner TYPE crmt_partner_external_wrkt. SELECT SINGLE guid INTO @DATA(lv_guid) FROM crms4d_btx_h WHERE object_id = '8000494705'. CHECK sy-subrc = 0. APPEND lv_guid TO lt_guid. CALL FUNCTION 'CRM_ORDER_READ' EXPORTING it_header_guid = lt_guid IMPORTING et_product_i = lt_product_i et_partner = lt_partner.
Let’s first have a look at what exactly the “injected” code is. We create a new function group for segment BTX_H in DB layer, that is CRMS4_BTX_H_DB. Have a look at CRMS4_BTX_H_READ_DB.
This function module will read header data from corresponding header flat table CRMS4D_<acronym>_H and then call function module CRMS4_BTX_H_PUT_TO_DB_BUFFER, which does the trick.
The importing parameter is_header_db has a generic type ANY because it is filled with data read from corresponding table CRMS4D_<acronym>_H in the runtime.
Within this function module, the following logic has been implemented:
1. get all allowed segments belonging to current process type via function module CRMS4_ORDER_OBJECTS_ALLOWED_CB
2. loop all these allowed segments, call the corresponding PUT_DB function module of each to insert the dedicated data into database layer.
In order to avoid the lengthy code as below:
We introduce the concept of converter class – each segment has its own converter class by implementing the defined interface IF_CRMS4_BTX_DATA_MODEL where the dedicated PUT_DB function module is called.
The method name CONVERT_S4_TO_1O gives you a hint that it is responsible to put the data fetched from S/4HANA new persistence table CRMS4D_<acronym>_H to the classical One order DB buffer.
Relationship between segment name and its mapping class name is maintained in table CRMS4C_BTX_CONV.
When and where these new logic will be injected?
Debug the simple report zcrms4_order_read to unveil the mystery. Just set a breakpoint on CRMS4_BTX_H_PUT_TO_DB_BUFFER and observe when and where it is called.
I highlight some important callstacks as below.
CRM_ORDER_READ calls CRM_ORDERADM_H_READ_DB, this is exactly the same as in SAP CRM. The injection of new logic is done in callstack 11: now we read data from CRMS4D_<acronym>_H, and then call CRMS4_BTX_H_PUT_TO_DB_BUFFER to split the data with flat structure into each segment’s database buffer by calling CONVERT_S4_TO_1O method of their converter class.
Since now database buffer for each segment is filled, the subsequent call for database buffer READ will hit the buffer.
See the comparison between S/4HANA for Customer Management and SAP CRM. The injection is clearly displayed in the highlighted area in the left area.
All the left handling for read scenario remains unchanged compared with the logic in SAP CRM.
How about it you would like to direct access the object buffer of a segment by calling its read function module instead of CRM_ORDER_READ?
Here below is the diagram for CRM_OPPORT_H_READ_OB in SAP CRM:
Here below is counterpart in S/4HANA for Customer Management:
Hope this blog can help you understand the adaptation of One Order Model in S/4HANA. In my next blog we will explore how One Order write scenario works under this new model. Stay Tuned!
Jerry’s other blogs on S/4HANA for Customer Management
- S/4HANA for Customer Management 1.0 introduction from technical point of view
- CRM One Order Model Redesign in S/4HANA for Customer Management 1.0 – Part 1
- CRM One Order Model Redesign in S/4HANA for Customer Management 1.0 – Part 2
- Create Mass Products by code in S/4HANA for Customer Management
- Create Mass Service document in S/4HANA for Customer Management
- One order extensibility in S4HANA for Customer Management