In SAP’s ABAP RESTful Application Programming (RAP) model, late numbering is a critical technique for managing unique identifiers like document numbers, order IDs, or transaction codes. Unlike traditional numbering that assigns keys before saving data, late numbering generates these identifiers after successful validation and persistence.
Why is Late Numbering Important?
- Prevents number range gaps from failed transactions
- Enables external system integration for key generation
- Supports complex validation workflows
- Improves data integrity in high-volume systems
How Late Numbering Works in RAP
1. Behavior Definition Setup
Enable late numbering in your behavior definition:
define behavior for ZRAP_SalesOrder
late numbering
{
create;
update;
delete;
}
Key Components
DETERMINE ON SAVE
: Triggers numbering after persistence- Number Range Objects: Configured via transaction
SNRO
- Exception Handling: Critical for duplicate key scenarios
Complete ABAP Implementation
Step 1: Behavior Definition
managed implementation in class ZBP_RAP_SALESORDER unique;
strict ( 2 );
with draft;
define behavior for ZRAP_SalesOrder
late numbering
{
create;
update;
delete;
field ( readonly ) SalesOrderNumber;
determination generateSalesOrderNumber on save { create; }
}
Step 2: Behavior Implementation Class
CLASS zbp_rap_salesorder DEFINITION
PUBLIC
ABSTRACT
FINAL
FOR BEHAVIOR OF zrap_salesorder.
PUBLIC SECTION.
PRIVATE SECTION.
METHODS generateSalesOrderNumber FOR DETERMINE ON SAVE
IMPORTING keys FOR SalesOrder~generateSalesOrderNumber.
ENDCLASS.
CLASS zbp_rap_salesorder IMPLEMENTATION.
METHOD generateSalesOrderNumber.
" Read all sales orders without numbers
READ ENTITIES OF zrap_salesorder IN LOCAL MODE
ENTITY SalesOrder
FIELDS ( SalesOrderUuid )
WITH VALUE #( FOR key IN keys ( SalesOrderUuid = key-SalesOrderUuid ) )
RESULT DATA(sales_orders).
" Process numbering
LOOP AT sales_orders ASSIGNING FIELD-SYMBOL(<so>) WHERE SalesOrderNumber IS INITIAL.
TRY.
" Get next number from range
cl_numberrange_runtime=>number_get(
EXPORTING
nr_range_nr = '01'
object = 'ZSO_NUM'
IMPORTING
number = DATA(lv_number) ).
" Format number if needed
<so>-SalesOrderNumber = |SO{ lv_number ALPHA = IN }|.
CATCH cx_number_ranges INTO DATA(lx_error).
" Log error
APPEND VALUE #(
SalesOrderUuid = <so>-SalesOrderUuid
%msg = new_message(
id = 'ZSO_MSG'
number = '001'
severity = if_abap_behv_message=>severity-error )
) TO reported-salesorder.
ENDTRY.
ENDLOOP.
" Update entities with new numbers
MODIFY ENTITIES OF zrap_salesorder IN LOCAL MODE
ENTITY SalesOrder
UPDATE FIELDS ( SalesOrderNumber )
WITH VALUE #( FOR so IN sales_orders (
SalesOrderUuid = so-SalesOrderUuid
SalesOrderNumber = so-SalesOrderNumber
) ).
ENDMETHOD.
ENDCLASS.
ABAP Class Handling Number Assignment
CLASS lhc_order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_features FOR INSTANCE FEATURES
IMPORTING keys REQUEST requested_features FOR order RESULT result.
METHODS generate_order_number FOR DETERMINE ON SAVE
IMPORTING keys FOR order~generate_order_number.
ENDCLASS.
CLASS lhc_order IMPLEMENTATION.
METHOD generate_order_number.
" Read all orders without numbers
READ ENTITIES OF zrap_order IN LOCAL MODE
ENTITY order
FIELDS ( order_uuid )
WITH VALUE #( FOR key IN keys ( order_uuid = key-order_uuid ) )
RESULT DATA(orders).
" Generate numbers for new orders
LOOP AT orders ASSIGNING FIELD-SYMBOL(<order>) WHERE order_number IS INITIAL.
" Call number range API
TRY.
cl_numberrange_runtime=>number_get(
EXPORTING
nr_range_nr = '01'
object = 'ZORDER'
IMPORTING
number = DATA(lv_number) ).
<order>-order_number = lv_number.
CATCH cx_number_ranges INTO DATA(lx_error).
" Handle error
ENDTRY.
ENDLOOP.
" Update entities with new numbers
MODIFY ENTITIES OF zrap_order IN LOCAL MODE
ENTITY order
UPDATE FIELDS ( order_number )
WITH VALUE #( FOR order IN orders (
order_uuid = order-order_uuid
order_number = order-order_number
) ).
ENDMETHOD.
ENDCLASS.
Best Practices for Implementation
- Number Range Configuration
- Set up via
SNRO
with sufficient buffer size - Consider annual numbering if required
- Set up via
- Error Handling
- Implement comprehensive logging
- Use SAP messages for user feedback
- Performance Optimization
- Use buffered number ranges for high-volume scenarios
- Consider bulk number generation for mass operations
- Testing Strategy
- Unit test numbering logic
- Load test with concurrent users
Key Advantages
- Flexibility: Numbers assigned after all validations pass
- No Gaps: Prevents number range gaps from failed transactions
- External Integration: Allows external system to provide numbers
When to Use Late Numbering
- Complex validation requirements
- Integration with external numbering systems
- High-volume transactions where numbering efficiency matters
Conclusion
Late numbering in SAP RAP provides a robust solution for managing unique identifiers in modern Fiori applications. By implementing the pattern shown above, developers can:
✔ Ensure data consistency
✔ Support complex business rules
✔ Enable integration scenarios
✔ Maintain clean number ranges
For production implementations, always include:
- Comprehensive error handling
- Performance testing
- Proper documentation