Creating an SAP Fiori Smart Template Application
Recently I attended the openSAP course Build You Own Fiori App in the Cloud (2016) where Smart Templates was part of it. With this blog post I want to share my experiences and show you a demo how to build a Smart Template app with SAP Web IDE.
Smart Templates strictly follow SAPs Fiori design guidelines. Without any coding you describe the application screens and behavior using Floorpans and annotations. Annotations provided by the OData service in the SAP backend help the app to understand the data model and its semantics.
More more details on Smart Templates I highly recommend the mentioned openSAP course.
Create the App Project
For this sample app, I used the demo OData service GWSAMPLE_BASIC in Gateway system ES4 provided by SAP. This article describes how to subscribe to the system. The service contains an entity collection BusinessPartnerSet which will be my starting point for the demo. From a single entity the navigation properties ToContacts and ToSalesOrders connect a business partner to its contact persons and sales orders. The sales order itself contains several line items by navigation property ToLineItems.
The app will consist of three pages, one list report and two object pages.
The list report page is the entry point and allows a search for business partners. The results are displayed as list with selectable rows.
Selecting one line in the list will show this particular customer in a detailed object page. The page contains three so-called facets: general information about the customer, the contacts and the sales orders created for that customer. Contacts and sales orders are displayed as lists.
A click on a sales order will open the according sales order object page. Two facets (sales order header information and line items) are part of this page.
Let’s start by creating a new project from template in SAP Web IDE. At the time of writing, only one Smart Template application template is available.
Basic information and data connection must be entered as usually for template based apps. As Gateway service I took GWSAMPLE_BASIC from SAP demo system ES4 as described above.
The part that is different for Smart Template applications comes now: You must add the annotation file describing the service. Normally, the OData service contains the annotation file itself so it can be retrieved from there. However, the demo system doesn’t provide such file, therefore I uploaded the exemplar from openSAP course „Build Your Own SAP Fiori App in the Cloud (2016)“ (exercises of week 5). This file fits to the selected OData service.
Last step is the template customization. I select BusinessPartnerSet as collection and ToContacts as navigation. This will create a list report for business partners with a second facet and object page for contacts.
After completing the wizard, the project is created.
Customer List Report Page
Now comes the fine-tuning and enhancing of the wizard-generated app. First the list report page will be customized such that the required columns are displayed in the report table. As mentioned above the main-target of Smart Templates are easier and ideally coding-free development of Fiori apps. The main task in this exercise is to enhance the annotation files in the project. The wizard has generated two XML files in folder webapp/annotations:
- annotations.xml contains annotations with settings selected in the wizard, i. e. the facets of the customer detail page (we will come back to that later)
- localAnnotations_1.xml is empty by default but needs to be enhanced now. It contains the base annotations.xml which is indicated by the read-only node „Annotations From Other Sources“.
Web IDE contains an Annotation Modeler (right-click on localAnnotations_1.xml, Open With -> Annotations Modeler) to simplify the development. Annotations are based on the entity sets in the selected OData service. We will start by annotating the BusinessPartnerSet.
Annotations from annotations.xml are displayed as read-only. All updates made now are done under the Local Annotations node. First the line items in the report list must be customized, i. e. define the columns to be displayed. Click the Action button at node Local Annotations, select UI.LineItem in the popup, click the add action at the UI.LineItem node and select UI.DataField. Now a new column on the report list was defined. Pick the entity property in the right pane that should be bound to the column.
In the screenshot below I have added five columns as data fields to the line item definition (BusinessPartnerID, CompanyName, LegalForm, PhoneNumber, EmailAddress).
Run the application. The customers are now displayed with the selected properties (if data is not displayed immediately, click the Go button).
Remark: The BusinessPartner entity contains a property Address which is a complex type containing the single address fields (street, city, postal code, etc.). It wasn’t possible to bind a single address field (e. g. Address/Street) to a data field. The reason is, internally the app will request the field from the backend via $select what is not possible for complex types (see here).
Customer Object Page
The customer object page will consist of three facets (general information, contacts, sales orders). By selecting the OData entity set and navigation property, the Web IDE generated two facets already for general information and contacts. These must be filled with controls now. The third facet for sales orders will be added afterwards.
The general information facet generated by the wizard references to an identification control. By adding the UI.Identification annotation with some data fields, the general information is displayed in the object page.
Afterwards, I added a UI.HeaderInfo annotation containing the customer’s name and ID. The header info is the fix area at the top of an object page. By entering the type name Customer, the Web IDE automatically adds a placeholder in the i18n properties in order to enable translation into other languages later.
When executing the app now, the object page shows the general information. The contacts facet with the generated name Second Facet is still empty.
The second facet containing the contacts was generated as a list item control for the navigation property ToContacts. So to add columns to the list of contacts, we must annotate ContactSet, add the UI.LineItem control and add the desired data fields.
Now the contacts of that customer are displayed in the second facet of the object page. We will change the facet’s name later.
You notice in above screenshot the little arrow at the right of the list. This indicates that the line is selectable and the app would navigate to a new object page, i. e. the contact detail object page. This was generated by the wizard automatically. Because I don’t want to show the contacts details here, the object page as sub page of the customer object page must be removed. This is done in the manifest.json file.
To add the third facet containing a customer’s sales orders requires a little more work. We need to add the facet, the page and the controls to the annotations file.
The sales orders should be displayed as a list as well in the facet, therefore I start annotating SalesOrderSet and add the UI.LineItem control with some data fields. By the way, you can concatenate several properties by clicking the button Add Concatenation in the properties pane. In the screenshot I concatenated gross amount and currency separated by a blank.
Next, the facet must be added. Because the facet structure for the business partner was initially defined in the project creation wizard, the Web IDE has generated it in the annotations.xml file. Unfortunately, for me it didn’t work to add the facet in localAnnotations_1.xml where I did all other modifications, therefore I needed to go with the generated annotations file.
Under the UI.Facets node, an UI.ReferenceFacet annotation was added. Important here is to select the ToSalesOrders as target entity set and the UI.LineItem as target annotation that was created in previous step.
Executing the app brings now the sales orders facet to the customer object page. However, you notice the little arrow at the right of the list is missing per row, i. e. you cannot select the sales order to see its details. This is because we didn’t create an object page so far. This is done in the next step.
Now to change the name of the contacts facet, the i18n.properties file must be adapted accordingly.
Sales Order Object Page
To bring a sales order object page in, the manifest.json must be adapted such that a new page is added to the customer object page.
This enables navigation from the sales order list to the detailed object page. However, the page is still blank. To start we need to add some fields. This works the same way as for the customer object page using the UI.HeaderInfo and UI.Identification annotations.
The sales order object page should contain two facets with header information and the line items. The header information comes in as UI.CollectionFacet that contains another UI.ReferenceFacet. This time the target entity set isn’t needed (because we display data of the same entity set SalesOrderSet). The target annotation is the created UI.Identification control.
The sales order line items are displayed in a list, so a UI.LineItem with a bunch of data fields are added to entity set SalesOrderLineItemSet. By the way, it’s also possible to display properties of related entities (like in the name of the product in the line item, ToProduct/Name).
Lastly, a new UI.ReferenceFacet is added to the SalesOrderSet relating to the line items by navigation property ToLineItems.
The items are displayed now in the sales order object page.
This completes my demo.
Smart Templates are an easy and quick way to visualize and mobilize data from an SAP backend system. To setup the demo app, it took me about four hours, and I only did the exercises from the openSAP course before and had no other training on Smart Templates. If you understand the principles of Smart Templates, you can build the app really fast. And if SAP provides other Floorplans as Smart Templates (what I am sure they’ll do) in the future, Smart Templates will become an even more productive way of implementing Fiori apps.
Some findings and personal opinions about restrictions I see compared to programmed Fiori-based apps. I know this is by design because Smart Templates are supposed to be coding-free and therefore it’s obvious that apps developed in SAPUI5 are more powerful. Nevertheless I want to point out my findings to help you decide whether Smart Templates are the better choice for your app. Btw, the list contains my findings and is neither complete nor 100 % validated. Maybe there is a solution that I didn’t find.
- The OData service needs to be very powerful and, eventually, tailored to your Smart Template app or at least to your business case. For example, what I already mentioned, you cannot bind controls to complex types’ properties. In SAPUI5 you could implement that via the controller if necessary.
- Obviously, the OData service must support annotations to be used in Smart Template apps (in contrast to general SAPUI5 apps where this is not mandatory).
- There is no way to format a date, like in the sales order items list where the delivery date is displayed as timestamp and not as date.
- There is no way to format anything, for example remove the leading zeros at IDs (business partner ID, sales order ID, item position). Solution would be that the OData service delivers the IDs without leading zeros already but this puts another restriction on the OData service.
I would appreciate very much any feedback in the comments section.