Fiori Elements List Report – Visualising Data – Rating Indicator

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

ValuesRounded to
0.00 to 0.240.00
0.25 to 0.740.50
0.75 to 0.991.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.

Leave a Reply