Skip to Content
Author's profile photo Former Member

Create Fiori app using CDS with BOPF- For beginners Part 1

This blog is for developers who wants to get started with the UI5/Fiori + OData + CDS + BOPF.



1) Concepts of Core Data Services(CDS)

2) Basic Understanding of OData service

3) Concepts of BOPF

4) Conceptual knowledge of Fiori(Smart Template)


The Fiori/Ui5 is for the UI part, the CDS is for the data retrieval(code push down) while the BOPF is for handling DB activities.


Technically in the S4 Hana world, with the Code-Push down paradigm the intense business logic should happen in DB layer rather than in ABAP Application server.  This blog is for pure test demo using CDS + BOPF to display the Fiori App. The performance optimization is not the intention here, but rather on how to use CDS + BOPF to get started with in S4 Hana Cloud.


Am using Web IDE environment with cloud connector to display the Fiori app. Let me quickly show how does the app look like.

App Look and feel.jpg

The + and Delete buttons are handled by BOPF framework while the other action is manually created in BOPF. The Business logic of this other action shall be done in an BOPF action class. We shall get into the details later on.


Lets get started with the development.


Initial set up required

1) You need HANA studio or Eclipse tool as we need to use ADT(ABAP Development Tool)

2) For hosting the app, Web IDE has been used. I recommend checking the link on how to install and set up the Web IDE trial and how to set up the Cloud connector.

3) System is S4 HANA ON PREMISE 1.0 with ABAP 7.50


For those who are using Hana account trial, the link in step 2 will take care of the web IDE including the cloud connector. Make sure the cloud connector is connected to the backend system as per the set up in step 2.


If the Cloud Connector set up is done, it should look something like this:

Cloud connector

Clound connector 1.jpg

Clound connector 2.jpg



After logging into HANA account trial and go to services and click on Web IDE.

Open Web IDE now.

Web IDE 1.jpg


We shall be creating an sales order app as an demo example.

Basic steps involved in creating this app are :

  • Create 2 Consumption CDS views (Sales Order header & Sales Order Items)
  • Use annotation (Consumption view) for generating OData service 
  • Use annotations (Basic views) for generating BOPF objects
  • Use Fiori Smart Template to display Sales order application

 Technically at a higher level :

– The Fiori app shall consume the OData

– The OData has data source as CDS views (ie consumption CDS)

– The BOPF takes care of table CRUD operations. Here the BOPF objects are generated from the CDS views via annotations.


 Lets start with the CDS views.

Basically in the CDS, there are consumption CDS, Basic CDS and Composite CDS. Consumption CDS are exposed to the UI. The intention is not to get into CDS details here, but to give a quick information on CDS.


We have 2 consumption CDS view’s. And the Header Consumption view shall be used by Fiori. For simplicity sake, the naming convention shall be as :
Consumption CDS with *_C_*
Basic CDS with *_I_*


1) Header Consumption ZDEMO_C_SALESORDER

    1.1)  The SO header consumption view utilize the Basic CDS view ZDEMO_I_SALESORDER

      1.2)  The Basic view use a Header Table “ZPROTO_SO_A”. This shall form the BOPF root table for SO Header


2) Item consumption view is  ZDEMO_C_SALESORDER_ITEM

    2.1) The Item consumption view use Basic CDS view ZDEMO_I_SALESORDER_ITEM

    2.2) The Basic view use the Item table ZPROTO_SOI_A which shall form the BOPF item node table


First prepare the table structure for SO header and SO item respectively.

SO header table ZPROTO_SO_A

SO header table.JPG


SO Item table ZPROTO_SOI_A

SO Item table.JPG

Now, we can use these tables in Basic CDS views.

Lets start creating with Basic Item CDS view

Basic SO Item  CDS

For creating CDS view, in the HANA studio, go to ABAP perspective. Choose your system and create a Package underneath. Right click on the package and choose New -> Other repository object.

Create CDS view 3 .jpg


SO Item CDS creation.jpg

Give the name of the view and click on Finish.

The CDS + annotations used are:

SO Item I CDS annotations.jpg

Basic CDS SO I item coding.jpg


Here the association between item and header imply an LEFT OUTER JOIN. If you want to force an inner join with association, example you can do something like this for example

inner join association.JPG

For more clarity on path expression joins, pls refer to here


Save and activate the ZDEMO_I_SALESORDER CDS view. 

Post activation, following objects are created in Dictionary :


2) DD SQL view (Columnar) : ZDDL_I_SOI16


Since this Basic view cannot be used directly for UI display, an Consumption view shall be created. 


Consumption SO Item CDS

The CDS code + Annotations are as below:

Consump CDS SO Item annotation.jpg

Consump CDS SO Item coding.jpg

Save and Activate.

Post activation the objects created are in Dictionary :


2) DD SQL View – ZDDL_C_SOI16

We are done with sales order Item.


Lets move to Sales Order Header starting with Basic view.



The CDS code + Annotations are:

Basic CDS annotations.jpg

Optional: there is an Object model annotation for modelCategory: # BusinessObject. If we use this the create sales order logic has to be written as an BOPF action. And this action shall be triggered when the + icon is clicked.


Basic CDS SO Header view.jpg


Save and Activate.

Post activation, following objects are generated  :

1) DD Sql view ZDDL_I_SO16


3) And an BOPF Business Object by the CDS name ie Business Object ZDEMO_I_SALESORDER


The BOPF Business Object can be viewed in Hana Studio/Eclipse via ABAP perspective. Go to the package, under Business Objects and here you shall see the generated BOPF object. Other option is via SAP Gui. You can open GUI in studio as well. Use Tcode BOBX or /BOBF/CONF_UI.

BO Generated.jpg

BOPF Business Object

Header BOPF Node.jpg

SO Item BOPF node.jpg


Now lets use this Basic Header view in a Consumption Header View



The CDS code + Annotations are:

SO Header Consumption Annotations.jpg

SO Header Consumption codoing .jpg

Save and Activate.

Post activation, the following objects are created:

1) DD Sql View DDL_C_SO16

2) DB view ie CDS entity  ZDEMO_C_SALESORDER (DDIC)

3)OData service (<CDS view>_CDS)


OData created.jpg

The OData service generated is not active. To activate go to Tcode Gui Tcode /IWFND/MAINT_SERVICE.

Click on Add service. Choose Local and enter the Name of CDS in the Technical Service and click Get services.

OData maint service.jpg

Click on “Get Services. Click on Service or click on “Add Selected Service”. In the next screen enter the package or local object and click ok. The OData service is now Active.

In the background when the CDS view with OData annotations get activated, the SADL generates Gateway artifacts such as Model Provider Class (MPC) and Data Provider Class (DPC) which form the backbone of OData.

Normally to create an OData service we go to Tcode SEGW and create a project and a Data Model(Data Reference as Final Consumption CDS view) and the MPC and DPC are generated.

In our case we can view these artifacts as shown below.

Test the Odata service.

Go back to the service maintenance screen. Click on Filter and enter the service name as Technical service in our case ZDEMO_C_SALESORDER_CDS

Click on Gateway Client. In the new window click on execute. If the status is 200, all is well.

Odata service 3.jpg


The OData metadata is fine. Test if the OData returns records by choosing the entity sets.

Odata service 4.jpg


So we are done with Final Consumption CDS view. And we can use this view in Fiori Smart Template.


Recap of what we have done so far.

1) Created Basic Item CDS

2) Created Consumption Item CDS

3) Created Basic Header CDS

4) Created Consumption Header CDS


Before we start with Fiori App, we shall create BOPF action. The action shall change the Lifecycle Status of an Sales order

BOPF action.jpg


The BOPF action and the App display will be covered in the Part 2.

Assigned Tags

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

      hi sujin,

      thanks for this tutorial. i tried to do all the steps but if i activate the basic cds view of sales order in eclipse there is no business object generated by the BOPF runtime.

      Do you know why this could happen?


      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Hergen,

      I can think of 2 reasons why the BO must not be generated:

      1) the use of @ObjectModel annotations as shown below.

      2) Make sure that the DB table  (in this example ZPROTO_SO_A) is available in the dictionary.

      If the BO is not generated, the error messages shown during CDS activation. You can see these when you mouse over the Icon next to @objectmodel. Good luck !


      Author's profile photo Jason Muzzy
      Jason Muzzy

      I realize this question is old, but I found it while looking for a solution to the same problem.  I noticed that if I activated the CDS view as a local object then it would generate the BOPF object.  Based on that I found and implemented note 2948149 which allowed the BOPF object to generate even though the package was assigned to transport layer SAP.

      Author's profile photo Jason Scott
      Jason Scott

      This is a great simple example... but what has me scratching my head is that this whole CDS/BOPF thing is designed around completely separate custom data tables.

      The reality of real-life is that you nearly always need to integrate with standard sap business processes.. For example you will need to call BAPI's to post purchase orders or goods movements or whatever... Not just on the write-side either - often its far easy to get the correct data out of the system by calling a bapi like BAPI_PR_GETDETAIL for example.

      It seems that this technique of using CDS annotations to auto-generate a BOPF object will not work for these more real-life scenarios... Or am I missing something and it is just that all tutorials on this subject are extremely basic using a Z table?!?

      Is there an "Extension" concept for these generated BOPF objects so that you can code your own ABAP update routines?

      Because... if there isn't then this whole CDS/BOPF is purely academic. Great for creating mars explorer demos at a TechEd keynote... but thats about it...

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Jason,

      Thank you for your comment. You are right with the real time reality scenarios. Here’s my take on that.

      With the new code to data Paradigm in place and with the S/4 Architecture along side, seems the CDS-BOPF combination will persists for long now.

      Lets say for an write scenario, the CDS-BOPF will work just perfectly as BOPF framework takes care of the DB write/lock/buffer/validation/consistency. In a typical real time scenario, say we have some ERP tables in S4. For query purpose the CDS should work faster than a BAPI call, because the CDS is interacting with the DB layer.

      Regarding extension and ABAP routines am not sure. But you can do something like this as mentioned in the Blog which is Generate the BOPF via annotations and then go to the BOPF framework and edit to add actions/determinations/validations etc.

      On another note, for query/read, there are basically 2 approaches keeping in mind the code-to-data concept.
      Top down approach – using CDS to interact with DB and
      Bottom up approach – using HANA modelling and using the HANA artifacts for reports/query.


      Author's profile photo Florian Royer
      Florian Royer

      First of all, thank you Sujin for your detailed guide !

      This is exactly what I am thinking about when I hear buzzwords like BOPF & CDS in one sentence. Still cannot figure out, when to use what.

      My one and only productive use of a BOPF Object was:

      • Z-Table HEAD
      • Z-Table ITEM

      Business logic in BOPF object, vizualisation in FPM, generated by Wizards. Very simple, but yet very powerful compared to other development approaches ( to be honest – I think I wrote about 200 lines of code in total, only because I wanted to implement a Drag and Drop feature, otherwise it would be less code).

      I agree per 100% to Jason’s post. When can I use BOPF / CDS in a real-life scenario, where I can’t base on Z-Tables, like create a purchase order using custom BOPF?

      The answer to this question is still open, looking forward to your replies.

      Author's profile photo Former Member
      Former Member

      Hi Sujin,

      Thanks for the so cleared blog about cds-bopf.

      Author's profile photo Former Member
      Former Member

      Hi Suijin,

      thanks for the tutorial. What I need to do that I can see "Smart Template" as Project Type in SAP WebIDE? I don't get this option.

      Is this already available for Partners/Csustomers?



      Author's profile photo Cain Sun
      Cain Sun

      Thanks for the tutorial, I noticed that the DB table for SO header does not have GUID and NODE GUID fields, how can BOPF store the data? In fact, I encounter some errors during testing the result.

      Author's profile photo Sebastian Freilinger-Huber
      Sebastian Freilinger-Huber

      Hi Cain,

      as far as I know in classical BOPF you need GUIDs on the database. With BOPF in S/4 context now this has been reworked and improved by SAP.

      In case for example your database table contains a common ID field or some other sort of key (instead of a GUID), you can generate the BOPF object on it as well using the corresponding CDS annotations (ObjectModel). From my understanding to make this work the ID has to be defined as key field in the CDS view, which  is used for the BOPF generation.

      Best regards,


      Author's profile photo Joseph BERTHE
      Joseph BERTHE


      Thanks for your blog, I try to follow it and I encounter some difficulties 🙂 During the activation of the zdemo_i_SalesOrder CDS it through me this error :

      [BO check] Element SALESORDERITEMID is not a DB field (view ZDEMO_I_SALESORDER_ITEM, table ZPROTO_SOI_A)

      As you can imagine, the field SALESORDERITEMID is in the table.

      What could be the problem ?



      Author's profile photo Former Member
      Former Member


      Thanks for the blog.

      I would like to try the tutorial, but i don't know where i get the tables mentioned in the tutorial. So far i only know sflight.




      Author's profile photo Sourabh Gandhi
      Sourabh Gandhi

      Thanks Sujin. This was very helpful. Please provide more complex scenarios. Regards Prateek Sonthalia

      Author's profile photo Sebastian Freilinger-Huber
      Sebastian Freilinger-Huber

      Hi Sujin,

      thanks for this blog. Just one question considering the maintenance of the BO Objects.

      Is there a reason why you don't use Eclipse as you are already working on a 7.50 system?

      Best regards,


      Author's profile photo Terry Huang
      Terry Huang


      why we need to create seprate cusumption and basic views, I just tried only create two basic views. it wroks properly.


      Best regards,


      Author's profile photo Former Member
      Former Member

      I tried creating 2 basic views but if I want to expose to UI then what should be done in this situation. How is consumption view different from basic view.

      Need suggestions

      Author's profile photo IDMIR LEVI DE LA CRUZ CLEMENTE
      Hi sujin Thanks for this blog.
      I'm trying to consume the service to insert the detail and I'm getting the following error.
      when I register the cabezera I have no problem.
      The CDS is the following
      @AbapCatalog.sqlViewName: 'ZDDL_I_SO16'
      @AbapCatalog.compiler.compareFilter: true
      @AbapCatalog.preserveKey: true
      @AccessControl.authorizationCheck: #NOT_REQUIRED
      @EndUserText.label: 'ZDEMO_I_SALESORDER'
      @Search.searchable: true
          compositionRoot: true,
          transactionalProcessingEnabled: true,
          writeActivePersistence: 'ZPROTO_SO_A',
          semanticKey: ['SalesOrderID'],
          representativeKey: 'SalesOrderID',
          createEnabled: true,
          updateEnabled: true,
          deleteEnabled: true
      define view ZDEMO_I_SALESORDER
        as select from zproto_so_a as SalesOrder
        association [0..*] to ZDEMO_I_SALESORDER_ITEM as _Item on $projection.SalesOrderID = _Item.SalesOrderID
            @Search.defaultSearchElement: true
        key SalesOrder.salesorderid       as SalesOrderID,
            @Search.defaultSearchElement: true
            SalesOrder.businesspartnerid  as BusinessPartnerID,
            SalesOrder.currencycode       as CurrencyCode,
            SalesOrder.grossamount        as GrossAmount,
            SalesOrder.netamount          as NetAmount,
            SalesOrder.taxamount          as TaxaMount,
            SalesOrder.lifecyclestatus    as LifecycleStutus,
            @ObjectModel.association.type: #TO_COMPOSITION_CHILD
      Author's profile photo Kai Sicker
      Kai Sicker

      Thanks a lot!