Skip to Content
Author's profile photo Former Member

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

This blog is on continuation to  Part 1.

In this part we shall create the BOPF action and display the sale order scenario in the Fiori App using Smart Template.

For the BOPF action, go to BOPF Business Object ZDEMO_I_SALESORDER  from Tcode BOBX. Click on change mode. Under the Node Elements, traverse to node ZDEMO_I_SALESORDER and select Action element. Right Click on Action and Click “Create”.

BOPF Action create.jpg

BOPF Action create 2.JPG

Go to Class Builder and create the class ZCL_A-DEMO_SALESORDER.

Action class 1.jpg

Action class 2.JPG

Implement the method Execute.

Action class 3.jpg

Save and Activate. Below is code for Action. Basically the code reads the selected sales order and then change the corresponding BOPF node instance with the new lifecycle status value.


  method /bobf/if_frw_action~execute.

    case is_ctx-act_key.

        "Action - Set overall status
      when zif_demo_i_salesorder_c=>sc_action-zdemo_i_salesorder-set_lifecycle_status_to_paid.
        " Get output structure of Action
        data(lt_sales_order) = value ztdemo_i_salesorder( ).

        "Read UI clicked sale order
            iv_node                 =  is_ctx-node_key   " BO Node Name
            it_key                  =  it_key            " BO Key
            et_data                 =  lt_sales_order ).   " Data Return Structure

        "Assuming single instance for a action
        read table lt_sales_order assigning field-symbol(<fs_sales_order>) index 1.
        if sy-subrc = 0.
          "Set the over all status to Paid ie 'P'
          if <fs_sales_order>-lifecyclestatus is initial.
            <fs_sales_order>-lifecyclestatus  = 'P'.

        "Now update the BO instance
            iv_node           = is_ctx-node_key    " Node
            iv_key            = <fs_sales_order>-key    " Key
            iv_root_key       = <fs_sales_order>-root_key     " NodeID
            is_data           = ref #( <fs_sales_order>-node_data )    " Data
            it_changed_fields = value #(
                                ( zif_demo_i_salesorder_c=>sc_node_attribute-zdemo_i_salesorder-lifecyclestatus ) )

        et_data = lt_sales_order.

      when others.



Okay we are done with all the backend stuff.

Lets display this using as Fiori App using Smart Template.


If all the Web IDE set up explained in Part 1 is fine, we can proceed. Go to Web IDE.  Click on File.

Create app 1.jpg


Click on File –> New –> Project from template

Smart template 2.jpg

On next screen, Select Service Catalog. Click on the dropdown and select your backend system.

Smart template 3.jpg


Once the backend system is selected, OData services in the system are listed. Look for our OData generated service  ZDEMO_C_SALESPRDER_CDS  ie <final consump CDS view>_CDS

Smart template 4.jpg


Select the Odata service. Click on Show details to check if the OData is up and running

Smart template 5.jpg


Here we see the OData service is running fine.

Smart template 6.jpg

Click on Next. In the Next screen the system will read and the OData service metadata file and also the CDS Annotations file(final consumption CDS). These are necessary to display the app.


The annotations in the final consumption CDS view (ZDEMO_C_SALESORDER) contain the UI line position which shall form the basis for field positioning in the app.


Smart template 7.jpg


Click Next. In OData collection, select the consumption view(where OData was published). Our final consumption view has an association to Item. Hence here the OData navigation refers to “_item”.


Smart template 8.jpg


Click Next or Finish and its done !

SMART template 9.jpg


The project name is visible under the workspace. Right click on the project. Click Run as -> Web Application

smart template 10.jpg


If prompted, choose flp sandbox.html. These are used to for test data basically.

Smart template 11.jpg


Click Ok. If prompted, for login credentials, enter the backend system details. Finally the app icon is displayed in the Catalog Tile.

Smart template 12.jpg

 Click on the App. If prompted for the login credentials, enter the back-end system details.


Click on Go in the app to display the sales order records.

App 1.jpg


Select the record by selecting the radio button and clicking. The navigation happens to the detail screen.

App 3.jpg


Click on Edit. For example, lets update the Gross Amount and click on Save.

App 4.jpg


The Gross amount value is edited to 3500 INR.  Click Save. 

“Object saved” message appears.  Go back to previous app page.


The new Gross amount is reflected here.

App 5.jpg

The Edit is excuted in BOPF via CDS and the particular BOPF node instance is edited. This is achieved as we have given the create/update/delete enabled in the final consumption CDS which delegates to the Basic CDS and then to BOPF.



Create a new record.

In the basic CDS ZDEMO_I_SALESORDER, we have maintained the annotation @objectmodel.create enabled: true which means the create logic is taken care by BOPF.


Click on + icon in the app to create a new sales header record.


Enter the values and click on Save.

Create record 3.jpg


An object saved message appears. The record is saved. Go to previous page and see the newly created record.

Create record 4.jpg

 The delete icon works the same way. Just select an record and click on delete.


 Change the sales order Lifecycle status

Select an sales order which has initial status and click on icon “Set Lifecycle Status to Paid”. The code which we have written for the BOPF Action is triggered and the status is changed to P.

Change status 1.jpg


Lifecycle status has changed to P(Paid)

change status 2.jpg

That’s it. Hope this is helpful.

The same technique can be used for SAP Standard tables.  Below is an quick example of using Standard tables VBAK and VBAP.

Basic Sales Order header CDS

Basic Sales Order Item CDS

And here are corresponding BOPF objects generated using the CDS annotations.

These are just the Basic CDS views. Use these in the consumption CDS similar to the example demonstrated in Part 1.

Assigned Tags

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

      So we are not supposed to write any UI5 code for the events?

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

      I have used Smart templates here. Coding can be done once the controllers and xml files are generated. Else you can try using Smart control's.

      Author's profile photo Former Member
      Former Member

      Hi, I couldn't find the code example for BOPF action.

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

      Hi Pedro,

      During the transition to new SCN UI, I guess the code was missed somewhere. I have re-provided  the Action class code now.


      Author's profile photo Christian Drumm
      Christian Drumm

      Hi Sujin,

      first of all great blog!

      I tried to follow your examples but ran into a problem when executing the generated Web application. When I start the app I only see the header of the page. However, the content is not loaded. I looked at the error console and network traffic in Chrome and saw the following error messages:

      • Annotation Helper: Spaces are not allowed in ID parts. Please check the annotations, probably something is wrong there
      • Uncaught (in promise) Error: "TEST_PROG_MODEL::sap.suite.ui.generic.template.ListReport.view.ListReport::Zcd_C_Salesorder--action::ERROR: Mandatory Value for Action not found" is not a valid ID.

      Do you have any idea what the cause of these errors could be and how to solve them?


      Author's profile photo Former Member
      Former Member

      My question is that for using CDS view, we need to know the SAP tables inside and out for all the fields and rules and then it wouldn’t count the customer enhancements.  Can we build CDS views with BAPI calls to validate?

      I’ve always used BAPI or known FM to report; This way all the custom enhancement at least at the Business Object layer include automatically in the reporting.  Is this something in plan with SAP?

      Author's profile photo Saranya sakthivel
      Saranya sakthivel

      Hi Sujin,

      Good Day .

      we are trying to create a UI application with the CDS , Gateway and BOPF framework. The issue is,  BOPF actions are not retrieved as Function imports in the gateway service. 

      1. We have created a CDS view, with the annotations for generating Business Object.
      2. Business object is created in the back end . We have created one custom Action for our BO object  .
      3. We are not directly exposing CDS as service. we are using Gateway client for this.
      4. We have imported the CDS as below.  But it is not bringing the Function imports here ( which is implemented as Action in BO object )

      Please help us here with your suggestions.


      Thanks & Regards,

      Saranya Sakthi.



      Author's profile photo Samson Moses
      Samson Moses

      Hi Saranya,

      I have the exact situation where the CDS + BOPF is exposed as OData service. In SEGW we used reference data source to build our service model.

      But I not seeing the function import ( BOPF Action nodes ). Can you provide some insights of how you had resolved the same?



      Author's profile photo Sebastian Gesiarz
      Sebastian Gesiarz

      Hello Sujin,


      Thank you for a great tutorial.

      My OData service does not seem to be running in web IDE. In results in the "Service is not available" error. Could you please tell what could be the possible cause? It is running fine in SEGW. The service & metadata has been published successfully.


      Like in the snapshots below. Please take a look.

      Service status – Green


      Odata request checks – all OK

      Error while selecting from Web IDE:


      I’m looking forward to your reply.

      Thank you & Best regards,


      Author's profile photo Former Member
      Former Member


      I am myself a big fan of the BOPF framework for quite sometime now but isn't it an overkill to go for such ways when a simple oDATA as function import. That would have been a rather simple way to go.

      Author's profile photo Xie Zhanli
      Xie Zhanli

      Hi Former Member,


      I also encountered the same error reported by Christian Drumm.

      【Annotation Helper: Spaces are not allowed in ID parts. Please check the annotations, probably something is wrong there】.

      Could anyone can help on solving this issue?


      Best Regards,






      Author's profile photo Vikki Asati
      Vikki Asati


      Thanks for awesome blog.

      I have  applied same concept in one example. Need to populate some common data from Header to line  item while creating line item.

      I have no idea about how to achieve auto fill line item record from header one. Please give suggest to complete my requirement.

      Author's profile photo Nilesh Puranik
      Nilesh Puranik


      Thank you very much for a very informative blog.

      1 question.

      If i wish to update multiple records for the BOPF action, what changes should i need to do ?

      (1) The table displayed should have Multiselect instead of Single select ? —> How ?

      (2)  The action defined should be ‘MultiInstance’ instead of ‘Single instance’ ??? –> Is that correct?

      Please advice,