A few weeks back I was debugging some issue with the status management of an order in SAP CRM. That was the first time that I noticed, that the general status management functionality is part of the core functionality of SAP Netweaver. As I like to use SAP standard whenever possible I was wondering whether it is possible to use the standard status management in custom development.
Status management in custom developments is a requirement I encountered regularly in the past. Most of the time I implemented a basic status management myself on the basis of some custom domain with numerical status values. This basic status management notable lagged most of the features the standard status management provides, like e.g.
Searching SDN I could only find little information regarding the standard status management. While there is a wiki page in the CRM area of the SDN wiki (Status Management - CRM - SCN Wiki) and a few threads on the topic (e.g. Integrating a Z Business Object with SAP Standard general status mangement?
with some very helpful comment by rdiger.plantiko) I couldn't find any complete example or tutorial on the topic. Therefore, I decided to create one myself. I this blog I'll provide a complete example consisting of creating a custom status object, customizing the status schema and finally using it in a simple example program.
For the purpose of this blog I create a simple database table ZCD_D_STATUS_OBJ as an example business object. This table only contains the three field MANDT, OBJECT_ID and OBJECT_TEXT.
The first thing that is needed to create a new status object for this table is a new object type including the necessary control parameters in table TBO00. The control parameters basically specify in which database table the custom object is stored and which are the key fields identifying an entry. For this example I create an new object type "Z1" with the value "ZCD_D_STATUS_OBJ" for the fields "Table" and "Ref.Struc." and "OBJECT_ID" for the field "Key Field":
Next a new object type needs to be created using transaction BS12. For this example I created the object type ZT1. No further customizing is needed here for this example.
With this basic setup in place, it is now possible to customize the status schema for our new status object. Customizing the status schema is done via transaction BS12. I created a test status schema ZCDT0001 for this example. The status schema consists only of the following three status:
CREA is set as the initial status value. The lowest and highest status numbers are set up in such a way that it is always only possible to go to a higher status, e.g. from PROC to FINI.
Now all the customizing is in place to use the custom status object.
The function modules necessary to use the standard status management are locate in the function group BSVA in the package BSV. The following simple test program shows how to use these function modules to create and update the custom status object. The test program consists of the following parts:
REPORT zcd_test_status_object.
TYPES: BEGIN OF object_key,
object_id TYPE char10,
END OF object_key.
DATA: status_test_obj TYPE zcd_d_status_obj,
object_key TYPE object_key,
status_obj_nr TYPE j_objnr,
object_type TYPE j_obtyp,
status_schema TYPE j_stsma,
status_number TYPE j_stonr,
status_table TYPE ttjstat,
s TYPE string.
FIELD-SYMBOLS: <status> TYPE jstat.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Initialize the object key with an unique value
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = '01'
object = 'BU_PARTNER'
IMPORTING
number = status_test_obj-object_id.
status_test_obj-object_text = 'Test Status Obj ' && status_test_obj-object_id.
INSERT zcd_d_status_obj FROM status_test_obj.
object_key-object_id = status_test_obj-object_id.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Creation of the status object
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
CALL FUNCTION 'OBJECT_NUMBER_GET_GENERIC'
EXPORTING
i_obart = 'Z1'
i_objectkey = object_key
IMPORTING
e_objnr = status_obj_nr
EXCEPTIONS
number_already_exists = 1
obart_invalid = 2
objectkey_missing = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CALL FUNCTION 'STATUS_OBJECT_CREATE'
EXPORTING
objnr = status_obj_nr
obtyp = 'ZT1'
stsma = 'ZCDT0001'
EXCEPTIONS
obtyp_invalid = 1
status_object_already_exists = 2
stsma_invalid = 3
stsma_obtyp_invalid = 4
OTHERS = 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
COMMIT WORK AND WAIT.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Read the initial status values and print it
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
CALL FUNCTION 'STATUS_READ'
EXPORTING
objnr = status_obj_nr
IMPORTING
obtyp = object_type
stsma = status_schema
stonr = status_number
TABLES
status = status_table
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
WRITE / 'Initial status values'.
s = |Object Type: | && object_type && | - Status Schema: | && status_schema && | - Status Number: | && status_number.
WRITE / s.
WRITE / 'Status Table:'.
LOOP AT status_table ASSIGNING <status>.
s = |Status: | && <status>-stat && | - Inactive: | && <status>-inact.
WRITE / s.
ENDLOOP.
ULINE.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Set some external and internal status values and print it
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
CALL FUNCTION 'STATUS_CHANGE_EXTERN'
EXPORTING
objnr = status_obj_nr
user_status = 'E0003'
EXCEPTIONS
object_not_found = 1
status_inconsistent = 2
status_not_allowed = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CLEAR status_table.
APPEND INITIAL LINE TO status_table ASSIGNING <status>.
<status>-stat = 'I0098'.
CALL FUNCTION 'STATUS_CHANGE_INTERN'
EXPORTING
objnr = status_obj_nr
TABLES
status = status_table
EXCEPTIONS
object_not_found = 1
status_inconsistent = 2
status_not_allowed = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CLEAR status_table.
CALL FUNCTION 'STATUS_READ'
EXPORTING
objnr = status_obj_nr " Objektnummer
IMPORTING
obtyp = object_type " Objekttyp
stsma = status_schema " Statusschema
stonr = status_number " Statusordnungsnummer
TABLES
status = status_table " Tabelle der Einzelstatus zum Objekt
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
WRITE / 'New Status values'.
s = |Object Type: | && object_type && | - Status Schema: | && status_schema && | - Status Number: | && status_number.
WRITE / s.
WRITE / 'Status Table:'.
LOOP AT status_table ASSIGNING <status>.
s = |Status: | && <status>-stat && | - Inactive: | && <status>-inact.
WRITE / s.
ENDLOOP.
ULINE.
Running this program produces the following result:
After the status object has initially been created the user status E0001 is automatically set for the status object. This is the status that was defined in the status schema ZCDT0001. After setting the internal status I0098 and the user status E0003, the status E0001 is set to inactive.
I hope this blog provides an useful introduction for anyone trying to use the standard status management in a custom development.
Christian
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
2 | |
2 | |
2 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |