Creating a Fiori OVP Application with CDS view annotations – Part 2
In this blog we will add some OVP Cards to the application we created in the previous blog. If you haven’t already done so, please review part 1 of the blog series which can be found at
Creating a Fiori OVP Application with CDS view annotations – Part 1
ADDING CARDS TO THE OVP APPLICATION
TABLE CARD
For the first card we will define the properties necessary to display a Table card. This card presents three fields in a table with the first two columns showing the first two DataFields and the third column shows either the first existing DataPoint or the third DataField. The annotation @UI.lineItem is used to define DataFields. Within this annotation we can specify the position to be shown, a qualifier which allows us to identify an associated set of values, and a label. With this knowledge lets start with a basic example by specifying lineItems for the sales_order_id, customer.company_name and the net_amount. Notice how the position defers from the order of the fields. We will use the qualifier in the OVP application when we define the associated card. Save and activate the changes.
@AbapCatalog.sqlViewName: 'zovpdemo'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'OVP Demo App'
@OData.publish: true
define view Z_Ovp_Demo as select from sepm_cds_sales_order as so {
key so.sales_order_key,
@UI.selectionField: [ { position: 10 } ]
@UI.lineItem: { position: 10, qualifier:'ordOverView', label: 'Sales Order' }
so.sales_order_id,
so.created_by,
so.created_at,
so.changed_by,
so.changed_at,
so.note_guid,
so.currency_code,
so.gross_amount,
@UI.lineItem: { position: 30, qualifier:'ordOverView', label: 'Net Amount'}
so.net_amount,
so.tax_amount,
so.lifecycle_status,
so.billing_status,
so.delivery_status,
so.buyer_guid,
/* Associations */
so.customer,
so.items,
@UI.selectionField: [ { position: 20 } ]
@UI.lineItem: { position: 20, qualifier:'ordOverView', label: 'Customer' }
so.customer.company_name
}
Now in Web IDE right click on the project and select New -> Card. Choose the datasource as shown and press Next.
Choose the Table Card and then press Next.
To define the card view provide the values as shown, making sure to include the qualifier ordOverView that we defined in the CDS view in the annotation path.
com.sap.vocabularies.UI.v1.LineItem#ordOverView
Press Next and Finish to complete the process.
Selecting the Component.js file and choosing Run should result.
Take note that using the smart filter can be used to filter out the displayed results.
TARGET VALUES
Taking this a step further, we can also use the @UI.lineItem to specify a DataPoint. Notice in the example below the @UI.lineItem defined for net_amount specifies a type of #AS_DATAPOINT. In addition to this we have now defined the annotation @UI.dataPoint on the net_amount field. Using the targetValue as well as the criticalityCalculation we can now color code the values shown in the table as they fit in the defined ranges.
@AbapCatalog.sqlViewName: 'zovpdemo'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'OVP Demo App'
@OData.publish: true
define view Z_Ovp_Demo as select from sepm_cds_sales_order as so {
key so.sales_order_key,
@UI.selectionField: [ { position: 10 } ]
@Consumption.semanticObject: 'Action'
@UI.lineItem: { position: 10, qualifier:'ordOverView', label: 'Sales Order'}
so.sales_order_id,
so.created_by,
so.created_at,
so.changed_by,
so.changed_at,
so.note_guid,
so.currency_code,
so.gross_amount,
@UI.dataPoint: {title: 'Net Amt',
criticalityCalculation: {
improvementDirection: #TARGET,
deviationRangeLowValue: 100,
toleranceRangeLowValue: 400,
toleranceRangeHighValue: 800,
deviationRangeHighValue: 1200
}}
@UI.lineItem: { position: 30, qualifier:'ordOverView', label: 'Net Amount', type: #AS_DATAPOINT}
so.net_amount,
so.tax_amount,
so.lifecycle_status,
so.billing_status,
so.delivery_status,
so.buyer_guid,
/* Associations */
so.customer,
so.items,
@UI.selectionField: [ { position: 20 } ]@UI.lineItem: { position: 20, qualifier:'ordOverView', label: 'Customer' }
so.customer.company_name
}
After saving and activating the changes to the CDS view, refreshing the OVP Application should now show the card as
First notice how the net amount label is now being taken from the label defined in the data point. Also, each value shows with a color indicating how it fits in our range. TECUM’s Net Amt shows in orange which is the range between deviationRangeLowValue and toleranceRangeLowValue.
NAVIGATION
Now at this we may want to navigate to another app. In addition to navigating to other sites we can also used intent based navigation which relies on semantic objects and actions. Web IDE provides a launchpad sandbox which has a few apps that we can call using this approach, so lets navigate to one of these from the card. The annotation @UI.lineItem supports an array of objects assignment in which we can define multiple assignment for the same field. For this reason lets just add it to the sales_order_id annotations. For this to work we will need to assign the type of #FOR_INTENT_BASED_NAVIGATION and also a semanticObjectAction which we can assign to toappnavsample to call the sample app. In addition it is also required to define the Semantic Object using the annotation @Consumption.semanticObject which we will assign Action.
With these changes our view will now look like
@AbapCatalog.sqlViewName: 'zovpdemo'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'OVP Demo App'
@OData.publish: true
define view Z_Ovp_Demo as select from sepm_cds_sales_order as so {
key so.sales_order_key,
@UI.selectionField: [ { position: 10 } ]
@Consumption.semanticObject: 'Action'
@UI.lineItem: [{ label: 'salesOrd', qualifier:'ordOverView',type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction: 'toappnavsample'},
{ position: 10, qualifier:'ordOverView', label: 'Sales Order'}]
so.sales_order_id,
so.created_by,
so.created_at,
so.changed_by,
so.changed_at,
so.note_guid,
so.currency_code,
so.gross_amount,
@UI.dataPoint: {title: 'Net Amt',
criticalityCalculation: {
improvementDirection: #TARGET,
deviationRangeLowValue: 100,
toleranceRangeLowValue: 400,
toleranceRangeHighValue: 800,
deviationRangeHighValue: 1200
}}
@UI.lineItem: { position: 30, qualifier:'ordOverView', label: 'Net Amount', type: #AS_DATAPOINT}
so.net_amount,
so.tax_amount,
so.lifecycle_status,
so.billing_status,
so.delivery_status,
so.buyer_guid,
/* Associations */
so.customer,
so.items,
@UI.selectionField: [ { position: 20 } ]
@UI.lineItem: { position: 20, qualifier:'ordOverView', label: 'Customer' }
so.customer.company_name
}
Save and activate the CDS view changes and then refresh the OVP application. Choosing one of the items in the table should now navigate you to the sample app. In my case I selected the entry for Telecomunicaciones Star which you can see in the passed parameters list as well as all of the other values.
ADDING A LIST CARD
Normally for each card you add, you would define additional annotations in your CDS view and assign them a unique qualifier. For the sake of simplicity, lets just reuse what we have already defined and define a List Card as shown
and this will yield
or it we choose the List Flavor Bar, which can be adjusted in the manifest.json which is part of the Web IDE project located under the webapp.
"card01": {
"model": "Z_OVP_DEMO_CDS",
"template": "sap.ovp.cards.list",
"settings": {
"title": "{{card01_title}}",
"category": "{{card01_category}}",
"subTitle": "{{card01_subTitle}}",
"entitySet": "Z_Ovp_Demo",
"listType": "condensed",
"listFlavor": "bar",
"sortBy": "changed_at",
"sortOrder": "descending",
"annotationPath": "com.sap.vocabularies.UI.v1.LineItem#ordOverView"
}
it would result in
In the list flavor bar we are now only seeing two fields. This view is expecting just one data field and two data points, so if we add another data point and set a value format each field as shown
@AbapCatalog.sqlViewName: 'zovpdemo'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'OVP Demo App'
@OData.publish: true
define view Z_Ovp_Demo as select from sepm_cds_sales_order as so {
key so.sales_order_key,
@UI.selectionField: [ { position: 10 } ]
@Consumption.semanticObject: 'Action'
@UI.lineItem: [{ label: 'salesOrd', qualifier:'ordOverView',type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction: 'toappnavsample'},
{ position: 10, qualifier:'ordOverView', label: 'Sales Order'}]
so.sales_order_id,
so.created_by,
so.created_at,
so.changed_by,
so.changed_at,
so.note_guid,
so.currency_code,
so.gross_amount,
@UI.dataPoint: {title: 'Net Amt',
criticalityCalculation: {
improvementDirection: #TARGET,
deviationRangeLowValue: 100,
toleranceRangeLowValue: 400,
toleranceRangeHighValue: 800,
deviationRangeHighValue: 1200
},
valueFormat:{
numberOfFractionalDigits: 1
}}
@UI.lineItem: { position: 30, qualifier:'ordOverView', label: 'Net Amount', type: #AS_DATAPOINT}
so.net_amount,
@UI.dataPoint: {title: 'Tax Amt', valueFormat:{
numberOfFractionalDigits: 1
}}
@UI.lineItem: { position: 40, qualifier:'ordOverView', label: 'Tax Amount', type: #AS_DATAPOINT}
so.tax_amount,
so.lifecycle_status,
so.billing_status,
so.delivery_status,
so.buyer_guid,
/* Associations */
so.customer,
so.items,
@UI.selectionField: [ { position: 20 } ]
@UI.lineItem: { position: 20, qualifier:'ordOverView', label: 'Customer' }
so.customer.company_name
}
After adjusting the card01_title in the i18n properties to Net/Tax Sales Orders, this will yield
Now if we wanted more fields we could change the List View to show in the list type extended which again we can just change in the manifest.json.
"card01": {
"model": "Z_OVP_DEMO_CDS",
"template": "sap.ovp.cards.list",
"settings": {
"title": "{{card01_title}}",
"category": "{{card01_category}}",
"subTitle": "{{card01_subTitle}}",
"entitySet": "Z_Ovp_Demo",
"listType": "extended",
"listFlavor": "bar",
"sortBy": "changed_at",
"sortOrder": "descending",
"annotationPath": "com.sap.vocabularies.UI.v1.LineItem#ordOverView"
}
}
The extended list card presents five fields, on the top left side it shows the first two data fields and on the bottom it present the first data point value in a bar and the second and third data point on the right side of the card if they exist. To max out the fields shown we can add one additional field in our cds view. This time we will add the lifecycle status field. Modify your cds view as shown below and save and activate your changes.
@AbapCatalog.sqlViewName: 'zovpdemo'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'OVP Demo App'
@OData.publish: true
define view Z_Ovp_Demo as select from sepm_cds_sales_order as so {
key so.sales_order_key,
@UI.selectionField: [ { position: 10 } ]
@Consumption.semanticObject: 'Action'
@UI.lineItem: [{ label: 'salesOrd', qualifier:'ordOverView',type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction: 'toappnavsample'},
{ position: 10, qualifier:'ordOverView', label: 'Sales Order'}]
so.sales_order_id,
so.created_by,
so.created_at,
so.changed_by,
so.changed_at,
so.note_guid,
so.currency_code,
so.gross_amount,
@UI.dataPoint: {title: 'Net Amt',
criticalityCalculation: {
improvementDirection: #TARGET,
deviationRangeLowValue: 100,
toleranceRangeLowValue: 400,
toleranceRangeHighValue: 800,
deviationRangeHighValue: 1200
},
valueFormat:{
numberOfFractionalDigits: 1
}}
@UI.lineItem: { position: 30, qualifier:'ordOverView', label: 'Net Amount', type: #AS_DATAPOINT}
so.net_amount,
@UI.dataPoint: {title: 'Tax Amt', valueFormat:{
numberOfFractionalDigits: 1
}}
@UI.lineItem: { position: 40, qualifier:'ordOverView', label: 'Tax Amount', type: #AS_DATAPOINT}
so.tax_amount,
@UI.dataPoint: {title: 'Lifecycle'}
@UI.lineItem: { position: 50, qualifier:'ordOverView', label: 'Lifecycle', type: #AS_DATAPOINT}
so.lifecycle_status,
so.billing_status,
so.delivery_status,
so.buyer_guid,
/* Associations */
so.customer,
so.items,
@UI.selectionField: [ { position: 20 } ]
@UI.lineItem: { position: 20, qualifier:'ordOverView', label: 'Customer' }
so.customer.company_name
}
After refreshing the OVP application your should now see the additional fields showing.
In the next blog we will explore the use of the Stack Card and a Chart Card.
Creating a Fiori OVP Application with CDS view annotations – Part 3
Hello,
it seems that SAP Web IDE changed the 'new card' wizard for a table card.
Instead of an annotation path the wizard demands a data point.
Line items don't seem to work when using the 'position' property in the annotations.
Am I doing something wrong?
Thanks and best regards
David
Hi David,
Looks like the wizard is not working correctly. After adding the card try adjusting it in the manifest to include
"annotationPath": "com.sap.vocabularies.UI.v1.LineItem#ordOverView"
Regards,
Jamie
Hi Jamie,
thanks! I also just figured it out. Already made a bug report đ
Thanks and best regards
David
Hi Jamie,
We are interested in Deploying "Procurement Overview Page". Do you have any idea with which version of S/4 HANA is this available or when is this planned for release?
Regards,
Lokesh.
Hi Lokesh,
OVP is dependent on SAPUI5. You can find details at
https://eaexplorer.hana.ondemand.com/_item.html?id=11065#!/overview
Regards,
Jamie
Hi Jamie,
We have the required UI5 version and able to create custom OVP and run them successfully. I am looking for more info if the below out-of-box OVP has been released by SAP as we have already crossed Q1/2016 release.
"Out-of–the-box SAP Fiori Overview Page for S/4 HANA procurement domain is planned to be released in Q1/2016"
Regards,
Lokesh.
Maybe Raz Korn could help on your question.
Regards,
Jamie
hello Jamie,
Great Blogs...
but I could not see number. I have created a thread explaining in detail. I have created a thread :
SAP FIORI OVP tutorial with cds : numbers not displayed.
If you could help to point out where I am wrong ?
Thanks.
Best regards
Hi Jamie,
Thank you for this great blog!
Question about the app to app navigation. I have a scenario where we want to navigate between two smart template applications. E.g. the first application is the "sales order" application, the second application is the "products" application. The sales order items contain a product ID and should navigate to the ovp of that product. Is this possible via CDS annotations? (type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction, ...)
What I have now is working navigation between the applications, but the "products" application opens from the start, so it shows the list report instead of the ovp of the selected product. From your blog I suppose the product_id is available as application start-up parameter, but is not read by the "products" application. (Can we access that parameter in the fioriSandboxConfig.json file?)
Thanks for your advice!
Kind regards,
Bjorn
Hi Bjorn,
This feature is currently in the testing phase and will be coming in the next few months.
Regards,
Jamie
Thanks! Â Something to look forwad to đ
KR,
Bjorn
Has this feature been implemented yet?
I also have this requirement
Can someone help answer the question at the below link
https://answers.sap.com/questions/216744/index.html
Hi Jamie,
I am using List card with KPI header ( Datapoint annotations)
What annotations would be required get the values display for âTargetâ and âDeviationâ as shown in screenshot below ?
Also, does these labels has to be âTargetâ and âDeviationâ only can we rename it ?
Thanks,
Tanveer
Can you please post your question in the question and answers area?
Thanks,
Jamie
Hi Jamie Cawley ,
Great Blog.
I finally could navigate from Table/List Lines to another app.
But I still could not figure out, how we can navigate from Card Header. I would like to navigate from Card header to another app based on SemanticObject-Action (Intent-based).
It would be great if you can provide some insights here.
Thank you.
Meet
Can you please post your question in the question and answers area?
Thanks,
Jamie
Hi Jamie Cawley ,
I have posted question here.
https://answers.sap.com/questions/13406556/how-to-navigate-from-ovp-card-header.html
Thanks
Meet Vajaria