The business scenario used in this tutorial is that of an online shop or ordering application. Users can create orders, providing as input a production start date, the number of days required for the order to be produced, as well as one of the available factory calendars. This information is used by the application to dynamically calculate the production end date, taking into account the working days defined by the specified factory calendar. The user can further input a delivery date, which will be validated using the same factory calendar to make sure that this date is not earlier than the calculated production end date.
Please keep in mind that this tutorial uses standard, SAP-delivered factory calendars. The creation and configuration of custom factory calendars is not part of this tutorial.
In this tutorial, wherever ### appears, use a number (e.g., 000).
Create your exercise package. This ABAP package will contain all the artefacts that will be created in this tutorial.
In ADT, go to the Project Explorer, right-click on the package ZLOCAL, and select New > ABAP Package from the context menu.
Maintain the required information:
Name: `ZFACTORYORDER_###`
Description: `Factory Calendar Tutorial`
Select the box **Add to favourite packages**
Click Next.
The ABAP Package properties remain as is. Click Next.
No transport request is necessary, as change recording is not enabled. Click Finish.
Step 2Create a Database Table
+
Create a database table to store the underlying data of the order application.
Right-click on your ABAP package and select New > Other ABAP Repository Object from the context menu.
Search for Database Table, select it, and click Next.
Maintain the required information:
Name: `ZFACTORYORD_###`
Description: `Factory Calendar Tutorial - Order data`
Click Next.
No transport request is necessary, as change recording is not enabled. Click Finish.
Replace the default code with the code snippet provided below (make sure to replace the placeholder ###):
ABAP
@EndUserText.label:'Factory Calendar Tutorial - Order data'@AbapCatalog.enhancement.category:#NOT_EXTENSIBLE@AbapCatalog.tableCategory:#TRANSPARENT@AbapCatalog.deliveryClass:#A@AbapCatalog.dataMaintenance:#RESTRICTEDdefinetablezfactoryord_###{keyclient:abap.clntnotnull;keyorder_id:sysuuid_x16notnull;description:abap.char(100);days_to_produce:abap.int4;factory_calendar:abap.char(32);production_start_date:abap.dats;delivery_date:abap.dats;created_by:abp_creation_user;created_at:abp_creation_tstmpl;last_changed_by:abp_lastchange_user;last_changed_at:abp_lastchange_tstmpl;local_last_changed_at:abp_locinst_lastchange_tstmpl;}
Save and activate the changes
Step 3Create a Business Object
+
Use the Generate ABAP Repository Objects Wizard built into ADT to create a business object on top of your database table. This will generate a full stack of objects, following the ABAP RESTful Application Programming Model (RAP), which results in a transactional UI service.
Right-click on your database table and select Generate ABAP Repository Objects.
Select option OData UI Service and click Next.
Choose the previously created package and click Next.
Maintain the following names for the objects that will be generated:
Section
Subsection
Field
Name
General
Project Name
FACTORYORDER_###
General
Artifacts Prefix
General
Artifacts Suffix
Business Object
Data Model
CDS Entity Name
ZR_FACTORYORDER_###
Business Object
Data Model
CDS Entity Alias
FactoryOrder
Business Object
Behavior
Behavior Implementation Class
ZBP_R_FACTORYORDER_###
Business Object
Behavior
Draft Table Name
ZFACTORYORDD_###
Service projection
Service projection Entity
CDS Entity Name
ZC_FACTORYORDER_###
Service Projection
Service Projection Behavior
Behavior Implementation Class
ZBP_C_FACTORYORDER_###
Business Service
Service Definition
Service Definition Name
ZUI_FACTORYORDER_###_O4
Business Service
Service Binding Name
Service Binding Name
ZUI_FACTORYORDER_###_O4
Click Next, review the objects that will be created, and click Next again.
No transport request is necessary, as change recording is not enabled. Click Finish.
Publish the generated Service Binding.
Select the entity set FactoryOrder and launch the Preview. Create a new factory order to get familiar with the initial state of your application.
Step 4Define a Custom Value Help for choosing a Factory Calendar
+
Currently, a user needs to know the desired factory calendar ID to be able to input it on the UI. In this step you will define a value help to improve the usability. To this end, you can use the released CDS view I_FactoryCalendarValueHelp.
Open the projection layer CDS view, ZC_FACTORYORDER_###.
Add the below annotation to the FactoryCalendar field:
Reload the service binding Preview and check that the value help is displayed correctly.Preview
Step 5Define a Validation for the Factory Calendar Selection
+
The value help allows selecting a factory calendar from the list. However, the user can still input an arbitrary string in the corresponding field. For this reason, you will now introduce a validation that checks the existence of the specified factory calendar ID.
Open the interface layer behavior definition ZR_FACTORYORDER_###.
Define a new validation on the factory calendar field, which shall be triggered during the save process. Add the new validation to the standard Prepare action:
Use the quick fix that is offered to generate the required method shell in your behavior implementation class. The IDE will automatically navigate to the class.
Implement the method as shown below:
ABAP
METHODcheckFactoryCalendarId.SELECTFactoryCalendarIDFROMI_FactoryCalendarBasicINTOTABLE@DATA(lt_fcal).READENTITIESOFzr_factoryorder_###INLOCALMODEENTITYFactoryOrderFIELDS(FactoryCalendar)WITHCORRESPONDING#(keys)RESULT DATA(lt_orders).LOOP AT lt_ordersINTODATA(ls_order).READTABLElt_fcalWITHKEYFactoryCalendarID=ls_order-FactoryCalendarINTODATA(ls_fcal).IFls_fcalIS INITIAL.APPENDVALUE#(%tky=ls_order-%tky)TOfailed-factoryorder.APPENDVALUE#(%tky=ls_order-%tky%msg=new_message_with_text(severity=if_abap_behv_message=>severity-errortext='Factory calendar does not exist.'))TOreported-factoryorder.ENDIF.ENDLOOP.ENDMETHOD.
Save and activate your changes.
Reload the service binding Preview. Create a new factory order and input a non-existent factory calendar ID. Check that the new validation is triggered when clicking Save.Factory calenddar does not existThe validation starts by reading all available factory calendar IDs from the released CDS view I_FactoryCalendarBasic. Additionally, the factory calendar ID of the entries for which the validation is run are also read. For each entry, the existence of the calendar is checked by filtering the first table for the chosen calendar ID. If the result is empty, an error is raised.
Step 6Create a Scalar Function Definition
+
Each factory order receives a production start date and the required production days as input. The chosen factory calendar, which defines the relevant working days, can then be used to determine the correct production end date. This can be implemented by using a CDS scalar function, which dynamically performs the calculation for each order, to add the result to your CDS model. The first step is to create a scalar function definition.
Right-click on your ABAP package and select New > Other ABAP Repository Object from the context menu.
Search for Scalar Function Definition and click Next.
Maintain the required information:
Name: `ZFACTORYORDER_SCALAR_###`
Description: `Factory Calendar Tutorial – Scalar Function Definition`
Click **Next**.
No transport request is necessary, as change recording is not enabled. Click Next.
Choose template defineScalarFunction and click Finish.
Replace the generated code with the following code:
Step 7Create a Scalar Function Implementation Reference
+
To link the scalar function definition to the actual logic a scalar function implementation reference object must be created. The implementation reference will point to the class and method containing the function logic, which will be created in the next step.
Right-click on your ABAP package and select New > Other ABAP Repository Object from the context menu.
Search for Scalar Function Implementation Reference and click Next.
Maintain the required information:
Name: `ZFACTORYORDER_SCALAR_###_SQL`
Description: `Factory Calendar Tutorial – Scalar Function Impl. Ref.`
Scalar Function Name: `ZFACTORYORDER_SCALAR_###`
Engine: `SQL Engine`
Click **Next**.
No transport request is necessary, as change recording is not enabled. Click Finish.
Maintain ZCL_FACTORYORDER_###=>CALCULATE_PRODUCTION_END_DATE for the AMDP Reference field.
Save the object. Activation is not yet possible, as the implementation class does not exist yet.
The suffix _SQL indicates that the scalar function is implemented using SQL. The rest of the name must be identical to an existing scalar function definition.
Step 8Implement the Logic for the Scalar Function
+
You will now implement the actual logic for the scalar function, which will be contained in an ABAP class. A special syntax is used for methods which implement scalar functions, as can be seen below.
Right-click on your ABAP package and select New > ABAP Class from the context menu.
Maintain the required information:
Name: `ZCL_FACTORYORDER_###`
Description: `Factory Calendar Tutorial – Production Date calculation`
Add interface `if_amdp_marker_hdb`
Click **Next**.
No transport request is necessary, as change recording is not enabled. Click Finish.
Declare and implement a new class method as shown in the code snippet below:
Use the Activate inactive ABAP development objects functionality (Crtl + Shift + F3) to activate all class artifacts and the scalar function implementation reference. Since the objects are dependent on each other, they must be activated simultaneously.
Two built-in HANA SQL functions are used. First, ADD_WORKDAYS Function | SAP Help Portal is used to add the specified days to the production start date. This function makes use of the factory calendars maintained in your system. Since the output is in DATE format, function TO_DATS | SAP Help Portal is used to convert it to the same ABAP date format as the other dates.
Step 9Consume the Scalar Function in your Business Object
+
You can now use the defined scalar function to add a production date field to your CDS model.
Open the interface layer CDS view ZR_FACTORYORDER_###.
Add a new field which is calculated using the scalar function and the other required fields as input:
Open the interface layer behavior definition ZR_FACTORYORDER_###.
You should see a syntax error appear in your behavior definition. Since you added a field to the CDS view, your draft table does no longer match the data model. Use the offered quick fix to adjust the draft table.
Save and activate the draft table.
Back in the behavior definition, add the new field productionenddate to the group of read-only fields.
Save and activate the behavior definition.
Open the projection layer CDS view ZC_FACTORYORDER_###.
Expose the new field ProductionEndDate by adding it to the CDS view.
Save and activate the changes.
Open the metadata extension ZC_FACTORYORDER_###.
Add UI annotations for the newly defined field, so that it will be visible on the UI:
Reload the service binding Preview. Check that the new field is visible in the UI, and that it is automatically calculated once a factory order is saved.
Preview
Step 10Define a Validation using the chosen Factory Calendar
+
The user inputs a delivery date when creating an order. This date should be validated to ensure it is not earlier than the production end date that is calculated by the system. You can achieve this by introducing a validation in your business object.
Open the interface layer behavior definition ZR_FACTORYORDER_###.
Define a new validation on the delivery date field, which shall be triggered during the save process. Add the new validation to the standard Prepare action:
ABAP
validationcheckFactoryCalendarIdonsave{fieldFactoryCalendar;}validation checkDeliveryDate on save {fieldDeliveryDate;}draft determine action Prepare {validationcheckFactoryCalendarId;validationcheckDeliveryDate;}
Save and activate your changes.
Use the quick fix that is offered to generate the required method shell in your behavior implementation class. The IDE will automatically navigate to the class.
Implement the method as shown below:
ABAP
METHODcheckDeliveryDate.READENTITIESOFzr_factoryorder_###INLOCALMODEENTITYFactoryOrderALLFIELDSWITHCORRESPONDING#(keys)RESULT DATA(lt_orders).LOOP AT lt_ordersINTODATA(ls_order).TRY.DATA(lo_fcal_run)=cl_fhc_calendar_runtime=>create_factorycalendar_runtime(iv_factorycalendar_id=ls_order-FactoryCalendar).DATA(production_end_date)=lo_fcal_run->add_workingdays_to_date(iv_start=ls_order-ProductionStartDateiv_number_of_workingdays=ls_order-DaysToProduce).CATCHcx_fhc_runtimeINTODATA(lx_err)."Exception handling – here you can catch any errors related to the factory calendar runtime
"This is out of scope for this tutorial
ENDTRY.IFls_order-DeliveryDate<production_end_date.APPENDVALUE#(%tky=ls_order-%tky)TOfailed-factoryorder.APPENDVALUE#(%tky=ls_order-%tky%msg=new_message_with_text(severity=if_abap_behv_message=>severity-errortext='Delivery date is too early.'))TOreported-factoryorder.ENDIF.ENDLOOP.ENDMETHOD.
Save and activate your changes.
Reload the service binding Preview. Create a new factory order and input a delivery date that is too early (for example, before the production start date). Check that the new validation is triggered when clicking Save.
Preview
The validation starts by reading all fields of the entries for which the validation is run. For each entry, the chosen factory calendar ID is used to create a factory calendar runtime object. This object is then used to compute the production end date, using the start date and required production days. This date is compared to the delivery date and an error is raised if the latter is too early.
You could also compare the delivery date to the already computed production end date field. However, since the goal is to showcase the factory calendar reuse functionality, the validation is implemented using the cl_fhc_calendar_runtime class and related released objects.
Step 11Summary
+
With that, you have successfully implemented all the planned features of your application. You have used factory calendar functionality in your business scenario and you have also learned how to define and consume CDS scalar functions to enrich your CDS models.
When creating a factory order, the application…
Offers a value help showing all available factory calendars,
Validates the existence of the specified factory calendar,
Calculates the production end date automatically using the provided input,
Validates the delivery date, making sure that it is not before the calculated production end date.
Share feedback on this tutorial or join the conversation in SAP Community.
Submit detailed feedbackDiscuss in Community
Steps
Step 1 of 12
1. Create your own ABAP Package2. Create a Database Table3. Create a Business Object4. Define a Custom Value Help for choosing a Factory Calendar5. Define a Validation for the Factory Calendar Selection6. Create a Scalar Function Definition7. Create a Scalar Function Implementation Reference8. Implement the Logic for the Scalar Function9. Consume the Scalar Function in your Business Object10. Define a Validation using the chosen Factory Calendar11. Summary12. Test yourself
Joule
AI Notice
Joule is an AI assistant. Generative AI may produce inaccurate, incomplete, or biased information. Always verify important details before acting on them.
Conversations are sent to SAP-hosted large language models for processing. Do not include personal data, credentials, or confidential information in your messages.
Joule's responses are based on the SAP tutorial catalog and may not reflect the latest product changes. For authoritative guidance, consult the linked tutorials and official SAP documentation.