Skip to Content
Author's profile photo Christian Drumm

Using the Standard Status Management in Custom Developments

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.

  • the possibility to have different system and user status
  • the ability to have multiple system status active
  • or customizable and extendible status values.

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 Rüdiger 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.

Creating a custom status object

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.

/wp-content/uploads/2014/04/status1_426448.png

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”:

/wp-content/uploads/2014/04/status2_426473.png

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.

/wp-content/uploads/2014/04/status3_426474.png

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 – Created
  • PROC – Processes
  • FINI – Finished.

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.

/wp-content/uploads/2014/04/status4_426479.png

Now all the customizing is in place to use the custom status object.

Test program for 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:

  • First in lines 18-31 I simply use the BP number range to create an unique key for the entry in the custom table.
  • After that in lines 33-68 the custom status object for the object type ZT1 and the status schema ZCDT0001 is created.
  • In lines 70-98 the initial status values are read and printed to the output.
  • Finally in lines 100-163 some external and internal status values are set and then read and printed to the output again.

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:

/wp-content/uploads/2014/04/status45_426480.png

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

Assigned Tags

      7 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Vimal Vidyadharan
      Vimal Vidyadharan

      Good to know this. Thank you for sharing this idea  Christian.

      However, the problems I have faced while trying to adapt this feature for custom built processes/screens is that there is customizing involved with tables having Delivery Class 'S'.

      Author's profile photo Christian Drumm
      Christian Drumm
      Blog Post Author

      Hi Vimal,

      yes I guess some of these tables have deliver class 'S'. Frankly,I didn't check this. For me it comes down to balance the advantages and disadvantages of creating entries in these tables to the ones of developing a custom status management. In this case, at least IMHO, the advantages of using the standard outweigh the disadvantages of adding entries to S-tables.

      Christian

      Author's profile photo Jeroen MARIJNISSEN
      Jeroen MARIJNISSEN

      Thanks for this very useful blog.

      Using transaction BSVW I have linked every status in my status profile with a business object type event. In this case, the name that you give to the key (ZR ) has to be the prefix for the object type (ZR1, ZR2).

      Author's profile photo Jonathan Bourne
      Jonathan Bourne

      Great blog, thanks Christian. One small correction, customising the status schema is done in transaction BS02 rather than BS12.

      I'm hoping to use the standard status management in a bespoke development in the near future so this has been very helpful.

      All the best, Jon

       

      Author's profile photo Prasanna Gunji
      Prasanna Gunji

      Christian - This documents has been so helpful. Thanks so much!

      Author's profile photo Ashutosh Mishra
      Ashutosh Mishra

      Thank you Christian, It is very useful blog.

      Author's profile photo Wolfgang Lindner
      Wolfgang Lindner

      Hi,

      thank you for this summary. Is my understanding right that I need for each new business object an entry in TBO00?

      Regards Wolfgang