Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

Issue -

If a case is opened in frontend and then we try to open the same case again from Case BADIs using the Case APIs then it fails. This would occur from 702 SAP Basis release onwards.

Solution -

We do not support usage of Case APIs in Case BADIs. Opening the case using IF_SCMG_CASE_API~OPEN_CASE creates a new instance of the case, so there is risk of data inconsistency if case is being modified at the same time via frontend and from API.

Case Management framework at runtime works on a single root instance which holds all objects accessed in RM in buffer. First time the case is opened in frontend then the root instance is created and objects are locked and buffered in the root. Now when the same case is opened from backend then in the BADI implementation the original root instance is not accessed and instead a new root instance is created. New root means new case instance is being created. So frontend has one instance of the case in one root instance and backend has another instance for case & the root which is not correct. Hence we do not support this.

Work around for this problem is to use the Record backend methods (Class - CL_SRM_SP_RECORD) within Case BADIs to perform activities on case record.
Please bear in mind, that you should be very careful in using Record backend methods in this scenario as data issues can be very hard to track.

Sample Algorithm -
1> From frontend case handler retrieve the corresponding case record handle (which would be record backend handle).
2> Cast the retrieved Case Record handle to interface handle of IF_SRM_SP_RECORD_EXPERT.

3> Using this handle (of interface IF_SRM_SP_RECORD_EXPERT) set the lock mode to 'M' using record backend method - SET_LOCK_MODE(). Mode ' M ' means more than one lock can be set for the same user.

4> Then using previously retrieved case record handler call the Record backend methods to fetch/add/delete elements from the case record.
5> Save and close the case record and free the handlers.

//This is a code sample block

DATA:
lif_case_read                                     TYPE REF TO if_scmg_case_read,
l_tab_subcomponents_backend      TYPE scmg_tt_subcomponent_backend,
wa_subcomponent                            LIKE LINE OF l_tab_subcomponents_backend,
lcl_rec_class                                      TYPE REFTO IF_SCMG_SUBCOMPONENT_BACKEND,
record_api                                          TYPE REF TO object,
lcl_rec_api                                          TYPE REF TO if_srm_sp_record,
my_record_expert                              TYPE REF TO if_srm_sp_record_expert.

  lif_case_read ?= im_case.

* From case handler retrieve the backend record handle. *
  l_tab_subcomponents_backend = lif_case_read->get_subcomponents( ).
  READ TABLE l_tab_subcomponents_backend INTO wa_subcomponent
  WITH KEY fcode = 'SUBCOMPONENT_RECORD'.
  IF sy-subrc = 0.
    lcl_rec_class = wa_subcomponent-class.
    record_api = lcl_rec_class->GET_API( ).
  ENDIF.

* Cast the backend record handler to IF_SRM_SP_RECORD_EXPERT. *
  IF record_api IS NOT INITIAL.
    lcl_rec_api ?= record_api.
    my_record_expert ?= lcl_rec_api.
    my_record_expert->SET_LOCK_MODE( mode = 'M' ).
    TRY.
        lcl_rec_api->open( for_update = 'X' ).
        ...
    CATCH.
    ENDTRY.
   ENDIF.

* You could use methods of IF_SRM_SP_RECORD to process the case record
and finally free all the handlers. *