List Report – using ABAP RESTful Application Programming Model

Quick introduction of ABAP RESTful Programming Model then we jump straight into the system and develop Fiori Elements List Report using ABAP ABAP RESTful Programming Model.

SAP is calling ABAP RESTful Programming Model as an evolution from ABAP Programming Model for SAP Fiori. Its available SAP Cloud Platform and also on-premise from S4HANA 1909.

Below is the architecture of ABAP RESTful Application Programming Model to develop Odata services. With List Report, we will cover QUERIES, Sevice Definition, Service Binding and SAP Fiori UI.

A query provides read-only access to the database and it is used for list reports or analytical reports.

Irrespective of whether it’s read-only (QUERIES) or transactional app (Business Objects) what we will have to do create, and which is a new concept introduced by ABAP RESTful Programming Model, are Service Definition and Service Binding.

To start with we have this ZMaterialPlant CDS View along with Metadata extension where UI annotations are defined.

CDS View: ZMaterialPlant

@AbapCatalog.sqlViewName: 'ZMATPLANT'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Material Plant'

@VDM.viewType: #BASIC
@Search.searchable: true

@ObjectModel.usageType.serviceQuality: #A
@ObjectModel.usageType.sizeCategory : #L
@ObjectModel.usageType.dataClass: #MASTER
@ClientHandling.algorithm: #SESSION_VARIABLE

@Metadata.allowExtensions: true

define view ZMaterialPlant
  as select from marc
    inner join   mara on marc.matnr = mara.matnr
  association [1..1] to I_Plant         as _Plant         
       on  $projection.Plant = _Plant.Plant
  association [0..*] to I_MaterialText  as _MaterialText  
       on  $projection.Material = _MaterialText.Material
  association [1..1] to I_MaterialGroup as _MaterialGroup 
       on  $projection.MaterialGroup = _MaterialGroup.MaterialGroup
{
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 0.8
      @ObjectModel.text.association: '_MaterialText'
  key marc.matnr as Material,

      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 0.8
      @ObjectModel.text.element: 'PlantName'
  key marc.werks as Plant,
      _Plant.PlantName,

      @Semantics.quantity.unitOfMeasure: 'MaterialBaseUnit'
      marc.eisbe as MaterialSafetyStockQty,

      @Semantics.unitOfMeasure: true
      mara.meins as MaterialBaseUnit,

      @ObjectModel.foreignKey.association: '_MaterialGroup'
      mara.matkl as MaterialGroup ,

      _MaterialText,
      _MaterialGroup
}

Metadata Extension: ZMaterialPlant

@Metadata.layer: #CORE

@UI.headerInfo: { typeName: 'Material' ,
                  typeNamePlural: 'Materials',
                  title: { value: 'Material'  } }

annotate view ZMaterialPlant 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 }]
  Plant;

  @UI.selectionField: [{ position: 20 }]
  @UI.lineItem: [{ position: 20 }]
  @UI.identification: [{ position: 20 }]
  Material;


  @UI.selectionField: [{ position: 40 }]
  @UI.lineItem: [{ position: 40 }]
  @UI.identification: [{ position: 40 }]
  MaterialGroup;

  @UI.lineItem: [{ position: 50 }]
  @UI.identification: [{ position: 50 }]
  MaterialSafetyStockQty;
}

This is where the difference starts with ABAP RESTful Programming Model. Instead of using Odata.publish: true or SEGW with reference to CDS View we will be creating Service Definition.

Service Definition

To create service definition right click on the CDS View and Select “New Service Definition”.

Specify name and description press Next.

This will create service definition exposing CDS View ZMaterialPlant, I have given an alias name MaterialPlant.

@EndUserText.label: 'Material Plant Service Definition'
define service ZMaterialPlant_SD {
  expose ZMaterialPlant as MaterialPlant;
}

So the key point here is use Service Definition instead of Odata.publish: true or SEGW to expose CDS View.

Service Binding

The Service Binding binds a Service Definition to a client-server communication protocol such as OData.

To create Service Binding right-click on Service Definition and choose option New Service Binding

Specify a name and description, press Next. This will create Service Binding.

On Service Binding page now click on Activate. Activation will create SICF node and also show you Entity Set and Association exposed. For now, we only have MaterialPlant (notice Alias is shown here).

If you go to /IWFND/MAINT_SERVICE you will notice that the service is now registered (I am on system with embedded gateway).

On Service Binding page, there is a Preview button which will launch Fiori Element List Report for exposed service. This is really handy if you are developing a List Report. Select EntitySet MaterialPlant and press Preview Button. This should launch the List Report.

SAP Fiori UI – Consuming Odata Service

I am now consuming the Odata service which I created and exposed using service definition and service binding in Fiori Element List Report.

In WebIDE creating Project using Fiori Elements List Report and Object page template.

On Data Binding page select the Entity. Keep pressing Next until you have App.

There we have it Fiori Element List Report using ABAP RESTful Programming Model. Consuming service in Fiori Element app is no different than ABAP Programming Model for SAP Fiori.

Adding Entities To Service Definition

You might have noticed Material Group column is not displaying text although have all relevant annotation i.e. @ObjectModel.foreignKey.association: ‘_MaterialGroup’ and @ObjectModel.text.association: ‘_Text’ in I_MaterialGroup CDS View and we have also exposed association _MaterialGroup in CDS View ZMaterialPlant.

Reason for this is CDS I_MaterialGroup is not exposed in Service Definition. So let’s go ahead and add this in Service Definition and activate it.

@EndUserText.label: 'Material Plant Service Definition'
define service ZMaterialPlant_SD {
  expose ZMaterialPlant as MaterialPlant;
  expose I_MaterialGroup as MaterialGroup;
}

Check Service Binding and you will now see (press F5 to refresh) association to_MaterialGroup and Entity Set MaterilGroup being exposed.

Material Group is now displaying text.

Observations here: Service Definition allows you to put alias against EntitySet. This feature was not there previously. We end up create entities with name ZC_.. or ZI..

Value Help

WIth ABAP Programming Model for SAP Fiori, annotation @ObjectModel.foreignKey.association: ‘_MaterialGroup’ creates metadata required for value help. With ABAP RESTful Application Programming Model that is no longer the case. We have to explicitly use @Consumption.valueHelpDefinition annotation to get value help metadata.

Adding @Consumption.valueHelpDefinition to metadata extension code

@Metadata.layer: #CORE

@UI.headerInfo: { typeName: 'Material' ,
                  typeNamePlural: 'Materials',
                  title: { value: 'Material'  } }

annotate view ZMaterialPlant 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 }]
  Material;


  @UI.selectionField: [{ position: 40 }]
  @UI.lineItem: [{ position: 40 }]
  @UI.identification: [{ position: 40 }]
  @Consumption.valueHelpDefinition: [{
          entity: { name:    'I_MaterialGroup',
                    element: 'MaterialGroup' } }]
  MaterialGroup;

  @UI.lineItem: [{ position: 50 }]
  @UI.identification: [{ position: 50 }]
  MaterialSafetyStockQty;
}

Service Binding automatically included the value help Entity, no need to change Service Definition.

And there we have it, value helps on Material Group and Plant.

3 Replies to “List Report – using ABAP RESTful Application Programming Model

  1. Great Post, thanks a lot for your explanations.
    Did you try to use a parameter in your CDS View in addition to Odata.pulish : true annotation ?
    I did not succeed even in ABAP Programming for SAP Fiori.

    Thanks a lot
    Anthony

      1. Hello Pawan,
        Thanks a lot for your answer.
        I’ve seen these posts but i didn’t succeed to apply the method.
        nevertheless, thanks a lot for your time 😉
        Regards

Leave a Reply