Skip to Content
Technical Articles
Author's profile photo Dhananjay Hegde

How to use Early Numbering with Semantic Keys – RAP Managed BO

In my previous blog post, I discussed how to use Late Numbering in RAP Unmanaged Business Object.

If you are new to RESTful Application Programming (RAP) model, then this blog post by Carine Tchoutouo Djomo is a great starting place.

For this post, I assume you have some knowledge of RAP, Core Data Services (CDS) views and so on.

Source code for all artifacts including tables and CDS views are available in this GitHub repository.

Early Numbering – Managed & Unmanaged

Early numbering is a scenario in which instance keys are generated in the interaction phase of RAP as opposed to Late Numbering where keys are generated during save phase.

If your Business Object has GUID based keys, then you can use managed early numbering. It is managed because RAP runtime engine generates and assigns values to primary key fields.

In this post, I am going to discuss unmanaged early numbering.  It is unmanaged because:

  • RAP runtime engine assigns values to primary key fields
  • How this assignment takes place is defined by the application developer in the behavior implementation pool inside specially defined methods for this purpose.  Such methods are defined using keywords FOR NUMBERING


Demo Business Object – the “Document”

This demo business object, called the “Document”, named so for the lack of any kind of creativity on my part, has 3 tables:


Tables and Foreign Key Relationships


Here are the CDS view entities where ZDH_MngdDocumentHeader is the root entity:


CDS Model


Initial Behavior Definition (BDEF) (Managed)

When you generate the BDEF, it would look like this initially:


Initial Behavior Definition as generate


Let’s add some more details to this BDEF such as “alias” for each entity, authorization, etag and lock.

Define Unmanaged Early Numbering

This is done by adding the keywords early numbering for each entity that needs to implement this.  Notice the highlighted lines in the BDEF below:



Behavior Definition Updated


Since, field names in tables and respective CDS views are different, you also need to add mapping for each entity.  It looks like something like below.  Refer to GitHub folder for complete listing.  This is not required for early numbering, per se.


Field Mapping


Activate BDEF and then use quick help to generate the BIL class.  It should look something like this:


Initial Behavior Implementation Class


Notice the highlighted methods – for each entity that has early numbering defined, there is a method generated. Notice the FOR NUMBERING in the method definition.


These methods are called when instances of those entities are “created”.  In other words when you execute MODIFY ENTITIES OF... CREATE...  or MODIFY ENTITIES OF.... CREATE BY... for an entity, respective FOR NUMBERING method is called.

Our goal is to add some lines of code here to generate the keys for each entity instances.


Pause and Note

This post is for educational purpose only.  It is to demonstrate “how” to implement early numbering. Therefore, numbers are generated in a very simplistic manner.  In a productive implementation, you will want to draw these numbers from Number Range object.  How to do that is not in the scope of this post.

Also, note that, when keys are generated early in the interaction phase, validation failures in the later phase may cause gaps in the numbering.  Therefore, if gap-less numbering is important or numbers need to be sequential, take extra caution while using this method!

Generate keys

I created this class ZCL_DH_MNGD_DOCUMENT_HANDLER which has 3 methods:


  • GET_NEXT_DOC_NUMBER -> returns next available document number. How it is done is not so important
  • GET_NEXT_ITEM_NUMBER -> returns next item number for a given document
  • GET_NEXT_ACCOUNT_NUMBER -> returns next account number for a given document item


Implement Numbering methods in BIL

In EARLYNUMBERING_ methods of BIL class, for each created instance (%CID), generate a new number and then fill “mapped” parameter.

These methods are called before any determination ... on modify { create; } are called


In EARLYNUMBERING_CREATE method, notice that we are filling MAPPED-HEADER by calling GET_NEXT_DOC_NUMBER() method:


  METHOD earlynumbering_create.
    DATA(lo_doc_handler) = zcl_dh_mngd_document_handler=>get_instance( ).

    LOOP AT entities ASSIGNING FIELD-SYMBOL(<ls_entity>).
      INSERT VALUE #( %cid            = <ls_entity>-%cid
                      DocumentNumber  = lo_doc_handler->get_next_doc_number( ) ) INTO TABLE mapped-header.


In EARLYNUMBERING_CBA_ITEM method, we are filling MAPPED-ITEM by calling GET_NEXT_ITEM_NUMBER() method.  Notice that we are passing the DocumentNumber to this method which is available in the importing parameter entities:

METHOD earlynumbering_cba_Item.
    DATA(lo_doc_handler) = zcl_dh_mngd_document_handler=>get_instance( ).

    LOOP AT entities ASSIGNING FIELD-SYMBOL(<ls_entity>).
      LOOP AT <ls_entity>-%target ASSIGNING FIELD-SYMBOL(<ls_item_create>).
        INSERT VALUE #( %cid            = <ls_item_create>-%cid
                        DocumentNumber  = <ls_entity>-DocumentNumber
                        ItemNumber      = lo_doc_handler->get_next_item_number( iv_doc_number = <ls_entity>-DocumentNumber ) ) INTO TABLE mapped-item.


Similar logic is implemented in method EARLYNUMBERING_CBA_ACCOUNT as well.

  METHOD earlynumbering_cba_Account.
    DATA(lo_doc_handler) = zcl_dh_mngd_document_handler=>get_instance( ).

    LOOP AT entities ASSIGNING FIELD-SYMBOL(<ls_entity>).
      LOOP AT <ls_entity>-%target ASSIGNING FIELD-SYMBOL(<ls_account_create>).
        INSERT VALUE #( %cid            = <ls_account_create>-%cid
                        DocumentNumber  = <ls_entity>-DocumentNumber
                        ItemNumber      = <ls_entity>-ItemNumber
                        AccountNumber   = lo_doc_handler->get_next_account_number( iv_doc_number  = <ls_entity>-DocumentNumber
                                                                                   iv_item_number = <ls_entity>-ItemNumber ) ) INTO TABLE mapped-account.


Apart from this, we have also added a determination for each entity in our BDEF named Defaults to fill administrative fields such as CreatedBy, CreatedOn.  Complete listing of BIL class as well as ZCL_DH_MNGD_DOCUMENT_HANDLER is available on the GitHub repo.


EML Test – Deep Create:

Let’s test it by writing an EML test.

Below EML will create 1 document with 1 item and 1 account line. Use valid company code, purchase organization and cost center depending on in which system you are writing this:


      ENTITY Header
        CREATE SET FIELDS WITH VALUE #( ( %cid                   = 'doc1'
                                          CompanyCode            = '0001'
                                          PurchasingOrganization = '0001' ) )
        CREATE BY \_Item SET FIELDS WITH VALUE #( (  %cid_ref = 'doc1'
                                                     %target  = VALUE #( ( %cid             = 'item1'
                                                                           itemdescription  = 'EML Test Item 1' ) ) ) )
      ENTITY Item
        CREATE BY \_Account SET FIELDS WITH VALUE #( (  %cid_ref  = 'item1'
                                                        %target   = VALUE #( (  %cid        = 'acc1'
                                                                                costcenter  = 'SVC_001' ) ) ) )
      MAPPED DATA(mapped)
      FAILED DATA(failed)
      REPORTED DATA(reported).



You can find complete test implemented as A Unit on GitHub repo.  This listing should go into “local test classes” of our BIL class.


  • Define early numbering in BDEF for each entity where you need to generate and assign primary keys
  • Implement a method FOR NUMBERING for each such entity
  • Methods should map “%CID”s to generated number and fill respective  mappedparameter

That’s it for this post.  I hope this was helpful.  Let me know in the comments how I could improve this post.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Robson Soares
      Robson Soares

      Thanks, it helped me a lot!

      Best Regards.

      Author's profile photo amr alaa
      amr alaa

      I cannot use early numbering in my managed behavior , i do not know why .

      Author's profile photo Former Member
      Former Member

      me too

      Author's profile photo Michal Tvrdy
      Michal Tvrdy

      using early numbering and strict is possibel only on BTP (cloud) ... for on-premise systems it is not allowed ...

      Author's profile photo ismail erdogan
      ismail erdogan

      so, is there any alternative solution for thıs situation?

      Author's profile photo Michal Tvrdy
      Michal Tvrdy

      May be on higher versions of S4 (2021 and later) it works on on-premise too.

      Author's profile photo Paul Jabez John David
      Paul Jabez John David


      I'm new to RAP,

      I've tried this Early Numbering in Managed Scenario for Purchase Order Creation but I had to write the EML in determination<det_name> on Modify {create;} ---------> This Method

      This method is triggering after entering the values and giving create (Basically while saving)

      also, this method which is created when early numbering(in Bdef) is given.

      METHODS earlynumbering_create FOR NUMBERING

      IMPORTING entities FOR CREATE ZPJ_I_ekko

      This method is triggering only after the Create button is clicked (while saving)

      When I give the create PO action button and try to enter the values at that time the PO number is blank. but only after creating the Po, the Po Number is visible.

      So isn't this called Late Numbering and not Early numbering?

      Someone help me and thanks in advance.