For project reason I need to figure out the logic how fields in index table CRM_ORDER_INDEX are updated.
For example, I have an opportunity with ID 21 and closing date 2017.03.25.
I get its guid 6C0B84B759DF1ED6BDF05763B3DC8841 from CRMD_ORDERADM_H and query CRM_ORDER_INDEX with this guid against field HEADER, 2 records found:
Most of the fields in these two records have the same value except fields like PARTNER_NO, which represent the two involved parties as found in WebUI:
What I am curious about is: the field DATE_2 seems to store the timestamp of Closing Date 2017.03.25 as observed in WebUI. My doubt is, since WebUI only displays the date information, where does this time 22:59:59 come from?
I wrote the following simple report to change Closing Date by code:
PARAMETERS: end TYPE CRMT_OPPORT_H_COM-expect_end DEFAULT '20170319'. CONSTANTS: gv_guid TYPE crmt_object_guid VALUE '6C0B84B759DF1ED6BDF05763B3DC8841'. DATA: lt_opport_h TYPE crmt_opport_h_comt, ls_opport_h LIKE LINE OF lt_opport_h, lt_change TYPE crmt_input_field_tab, ls_change LIKE LINE OF lt_change, lt_saved TYPE crmt_return_objects, lt_exception TYPE crmt_exception_t, lt_to_save TYPE crmt_object_guid_tab, lt_not_to_save TYPE crmt_object_guid_tab. ls_opport_h-ref_guid = gv_guid. ls_opport_h-expect_end = end. ls_change = VALUE #( ref_guid = gv_guid ref_kind = 'A' objectname = 'OPPORT_H' ). APPEND 'EXPECT_END' TO ls_change-field_names. APPEND ls_change TO lt_change. APPEND ls_opport_h TO lt_opport_h. CALL FUNCTION 'CRM_ORDER_MAINTAIN' EXPORTING it_opport_h = lt_opport_h CHANGING ct_input_fields = lt_change EXCEPTIONS error_occurred = 1 document_locked = 2 no_change_allowed = 3 no_authority = 4. APPEND gv_guid TO lt_to_save. CALL FUNCTION 'CRM_ORDER_SAVE' EXPORTING it_objects_to_save = lt_to_save iv_update_task_local = abap_true IMPORTING et_saved_objects = lt_saved et_exception = lt_exception et_objects_not_saved = lt_not_to_save EXCEPTIONS document_not_saved = 1. WRITE: / sy-subrc. COMMIT WORK AND WAIT.
The SAT trace shows clearly that the index table will also be updated during order save:
The main logic of CRM_ORDER_INDEX_SAVE
1. call order header from object buffer and DB buffer separately via CRM_ORDERADM_H_READ_OB and CRM_ORDERADM_H_READ_DB to check whether there is really header change.
2. get old index data from DB via CRM_ORDER_INDEX_SELECT_DB.
3. transfer the latest order data from object buffer to index buffer.
This is done in subroutine fill_data.
Before subroutine is executed, date_1 is initial:
After execution, date_1 is filled with data now. So I can find answer how date_1 is populated later by debugging into fill_data subroutine.
4. The change mode ( insert, update or delete ) is evaluated in subroutine fill_update_tables by comparing the latest change stored in lt_index_ob ( object buffer ) and original data from DB, lt_index_db.
In this example the determined result is that two records ( stored in table lt_index_update ) must be updated. The comparison logic is described in blog Logic of SAVE_EC function module in One Order.
The real database update is done in update function module CRM_ORDER_INDEX_UPDATE_DU.
Closing Date update logic in CRMD_ORDER_INDEX-DATE_2
It is easy to find the logic by debugging into subroutine fill_data.
The Closing Date in WebUI is stored in CRMD_OPPORT_H-EXPECT_END.
The time of Closing Date is hard coded as 235959 and converted to timestamp based on time zone configured in the backend.
I have written a series of blogs to explain how One Order API works. The blogs are written based on a simple scenario: read, change and save field “Closing Date” in Opportunity header level.