The blog explains how to use Rating indicator in Fiori Element List Report’s list page and in object page using CDS Annotation. There are also some handy tips.
Rating indicator is used to display the rating of an item on 0 to 5 scale where 5 is the best rating and 0 the worst. Rating Indicator can also render the half ratings for example 1.5, 2.5, 3.5 etc.
To work with CDS View, I’ve created this table ZMATDEMO where I’ll specify the rating against material and use that in List App. This way we can easily adjust rating values and see how its reflected in frontend.
Getting Ready
Table ZMATDEMO
Creating table ZMATDEMO in the system and generate the table maintenance.
CDS ZMaterialDemo
CDS View ZMaterialDemo where we are exposing ZMATDEMO table values.
@AbapCatalog.sqlViewName: 'ZVMATDEMO1'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Material Visual Fields'
@VDM.viewType: #BASIC
@ObjectModel.usageType.serviceQuality: #A
@ObjectModel.usageType.sizeCategory : #L
@ObjectModel.usageType.dataClass: #MASTER
@ClientHandling.algorithm: #SESSION_VARIABLE
define view ZMaterialDemo
as select from zmatdemo
{
key matnr as Product,
key werks as Plant,
customer_rating as CustomerRating,
current_stock as CurrentStock,
insme as StockinQualityInsp
//calculated fields
}
CDS ZMaterialVisual
Then we have CDS view ZMaterialVisual which is exposed using Service Definition and Service Binding however you can use Odata.publish or expose via SEGW. I am going to put Rating related annotation in the metadata extension file.
@AbapCatalog.sqlViewName: 'ZMATVIS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Material Visualisation'
@VDM.viewType: #TRANSACTIONAL
@Search.searchable: true
@ObjectModel.usageType.serviceQuality: #A
@ObjectModel.usageType.sizeCategory : #L
@ObjectModel.usageType.dataClass: #MASTER
@ClientHandling.algorithm: #SESSION_VARIABLE
@Metadata.allowExtensions: true
define view ZMaterialVisual
as select from ZMaterialDemo as matvis
inner join marc on matvis.Product = marc.matnr
and matvis.Plant = marc.werks
inner join mara on matvis.Product = mara.matnr
association [1..1] to I_Plant as _Plant
on $projection.Plant = _Plant.Plant
association [0..*] to I_MaterialText as _MaterialText
on $projection.Product = _MaterialText.Material
{
@Search: { defaultSearchElement: true , fuzzinessThreshold: 0.8 }
@ObjectModel.text.association: '_MaterialText'
key matvis.Product,
@Search: { defaultSearchElement: true , fuzzinessThreshold: 0.8 }
@ObjectModel.text.element: 'PlantName'
key matvis.Plant,
_Plant.PlantName,
@Semantics.unitOfMeasure: true
mara.meins as MaterialBaseUnit,
CustomerRating,
CustomerRating as CustomerRating_Value,
@Semantics.quantity.unitOfMeasure: 'MaterialBaseUnit'
CurrentStock,
@Semantics.quantity.unitOfMeasure: 'MaterialBaseUnit'
StockinQualityInsp,
@Semantics.quantity.unitOfMeasure: 'MaterialBaseUnit'
marc.minbe as ReOrderPoint,
_Plant,
_MaterialText
}
Before looking at the annotation in Metadata extension file having quick look at our data. I have some materials added to table ZMATDEMO with rating column filled from 0 to 5
Rating Annotation
In metadata extension file below you can see highlighted annotation required to render Rating in the list.
Metadata extension ZMATERIALVISUAL
@Metadata.layer: #CORE
@UI.headerInfo: { typeName: 'Material' ,
typeNamePlural: 'Materials',
title: { value: 'Product' } }
annotate view ZMaterialVisual with
{
@UI.facet: [
{ id:'idGeneralInformation' ,
type: #COLLECTION ,
label: 'General Information' ,
position: 10 } ,
{ type: #IDENTIFICATION_REFERENCE ,
label : 'General Information',
parentId: 'idGeneralInformation',
id: 'idIdentification' ,
position: 10 } ]
@UI.selectionField: [{ position: 10 }]
@UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
@Consumption.valueHelpDefinition: [{
entity: { name: 'C_Plantvaluehelp',
element: 'Plant' } }]
Plant;
@UI.selectionField: [{ position: 20 }]
@UI.lineItem: [{ position: 20 }]
@UI.identification: [{ position: 20 }]
Product;
@UI.lineItem: [{ type:#AS_DATAPOINT ,
position: 30,
label: 'Customer Rating' }]
@UI.dataPoint:{visualization:#RATING,
title:'Customer Rating' }
CustomerRating;
@UI.lineItem: [{ position: 35 }]
@EndUserText:{ label: 'Customer Rating Value' }
CustomerRating_Value;
}
With type:#AS_DATAPOINT in @UI.lineItem and @UI.dataPoint.visualization: #RATING you should start to see the Rating in the list.
Annotation label (line 35) and the title (line 37) are optional, system by default take column heading in list and title in object page from data element text. Since I haven’t used data element in the table I have specified label and title.
A couple of points I would like to make
- You should have rating values stored in the table in scale 0-5. If, for example, your rating values are stored with scale 0-100 then you will run into datatype and rounding issue when you try to convert your 0-100 scale values (in CDS) into 0-5 for Rating.
- I would recommend defining rating values in the database as DEC type with at least one decimal place. Rating indicator can render 0.5 values which we will see next.
I have now changed the rating values
Pay attention to how the values are rounded
Values | Rounded to |
0.00 to 0.24 | 0.00 |
0.25 to 0.74 | 0.50 |
0.75 to 0.99 | 1.00 |
Object Page
Let’s look at what is going on in Object page. @UI.dataPoint annotation automatically put the value in Header of Object Page if you have not defined any HEADER facet explicitly.
Currently, Customer Rating is coming up on the header of the object page. However, it’s not displayed using Rating indicator.
To display Customer Rating on the header of object page we will add a HEADER facet of type DATAPOINT_REFERENCE in annotation file with target CustomerRating.
@Metadata.layer: #CORE
@UI.headerInfo: { typeName: 'Material' ,
typeNamePlural: 'Materials',
title: { value: 'Product' } }
annotate view ZMaterialVisual with
{
@UI.facet: [
{ id : 'idHeader' ,
type: #DATAPOINT_REFERENCE ,
label: 'Header' ,
purpose: #HEADER ,
targetQualifier: 'CustomerRating'} ,
{ id:'idGeneralInformation' ,
type: #COLLECTION ,
label: 'General Information' ,
position: 10 } ,
{ type: #IDENTIFICATION_REFERENCE ,
label : 'General Information',
parentId: 'idGeneralInformation',
id: 'idIdentification' ,
position: 10 }
]
@UI.selectionField: [{ position: 10 }]
@UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
@Consumption.valueHelpDefinition: [{
entity: { name: 'C_Plantvaluehelp',
element: 'Plant' } }]
Plant;
@UI.selectionField: [{ position: 20 }]
@UI.lineItem: [{ position: 20 }]
@UI.identification: [{ position: 20 }]
Product;
@UI.lineItem: [{ type:#AS_DATAPOINT ,
position: 30 ,
label: 'Customer Rating'}]
@UI.dataPoint:{ visualization:#RATING ,
title:'Customer Rating'}
CustomerRating;
@UI.lineItem: [{ position: 35 }]
@EndUserText:{ label: 'Customer Rating Value' }
CustomerRating_Value;
}
Customer Rating now displayed on Object Page header with Rating indicator.