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. *