Monday 18 February 2019

MyInbox UI generation using CDS views and UI.facet annotation

Intro


Many of you probably may have observed that the MyInbox has an option to generate the UI based on the annotations but the information you may get from the help or online(questions&blogs) is very limited.

Target


This blog will give you a basic idea of how to generate the UI for MyInbox based on the annotations and is targeted for those how have good understanding of ABAP Programming model for Fiori

We will discuss two things in this blog.

1. How to use the UI.Facet annotations in the CDS view
2. How to generate the UI using the annotations in the MyInbox

System I used is S4HANA 1809. Not sure if the annotations that I used will work in the older systems.

I’ve taken the Flight data model as I was lazy to create a proper example and so I am using the same code base which I used for testing.

End Result:



SAP ABAP Tutorial and Materials, SAP ABAP Guides, SAP ABAP Certifications

At the end of following all the steps, we will be able to generate the annotation based UI in the MyInbox app as shown above

BTW SAP team designed the annotation based UI very nicely which is based on XML templating. Kudos to the team behind it!! You can check the code in the “annotationsBasedTaskUI” folder of the MyInbox app.

Break down of the annotations used to generate the above UI


I will breakdown the UI into 4 parts

1. Header information
2. Body -> where we will show the actual data of the root CDS view
3. Footer(Associated child entities)-> we will show the associated child data
4. Child navigation to Detail page(from the footer/associated child entities)

Header Information:

SAP ABAP Tutorial and Materials, SAP ABAP Guides, SAP ABAP Certifications

In the header, to show the title & description, we will use the regular headerInfo annotation,

@UI.headerInfo:{
    title.value: 'carrid',
    title.url: 'url',
    description.value: 'carrname'
}

Body:

For showing the data in the body, I used field groups. Even after using them, the UI will not generate as it requires Facet annotation. 


SAP ABAP Tutorial and Materials, SAP ABAP Guides, SAP ABAP Certifications

  @UI.fieldGroup: [{
        // Qualifier is mandatory as this is
        // the way to distinguish between
        // Multiple groups
        qualifier: 'one',
        position: 10
       }]
      @UI.identification: [{position: 10 }]
  key scarr.carrid,
      @UI.fieldGroup: [{
        qualifier: 'two',
        position: 10
      }]
      @UI.identification: [{position: 20 }]
      scarr.carrname,
      @UI.fieldGroup: [{
        qualifier: 'two',
        position: 20
      }]

So after adding the fieldGroup, we need to add the Facet information to the CDS view.

UI.facet

The example that I referred was purchase order release approval workflow where they generate the Facet releated annotations in the MPC Extension class.

I was lazy and didn’t want to code in the MPC_EXT class so started searching for the facet annotations in the CDS view level and again very limited information on this topic. (Not sure if it is released for the customer). But anyway ended up spending a lot of time should have gone with the MPC_EXT based annotations

So after multiple trail & errors I’ve found that it should be added like show below:

@UI.facet: [
      // This is for the body
     { // This tells it is a collection of facet
       // under that we will have reference facets
        id: 'GeneralInformation',
       // Summary is mandatory,
       // MyInbox generetes the Body based on this
        isSummary: true, 
        type: #COLLECTION
     },
     // The below two are reference facets
     {
     // Need to mention the parent Id so the field group
     // that is linked to below qualifier will be added to the facet
       parentId: 'GeneralInformation',
       id:'group1Information',
       type: #FIELDGROUP_REFERENCE,
       targetQualifier: 'two',
       label: 'Group 1'
     },
     {
       parentId: 'GeneralInformation',
       id:'group2Information',
       type: #FIELDGROUP_REFERENCE,
       targetQualifier: 'one',
       label: 'Group 2'
     }
      // Items will be added below, will show later
]

The above code is self explanatory and this information will be general and not specific to myinbox. We can use the Facet annotation to create the facets in the listreport object page as well.

Footer(Associated child entities)


SAP ABAP Tutorial and Materials, SAP ABAP Guides, SAP ABAP Certifications

In the above code, I’ve mentioned in the comment at the end that “Items will be added below”, we have to add the items facet annotations there.

{
   id:'lineItems',
   type: #LINEITEM_REFERENCE,
   targetElement: '_Flight',
   label: 'Flights'
}

Now one thing I’ve noticed is that the Items should have the Importance as High or else it is not displaying the fields as the table columns. Also, it seems you can display the Form as well in the footer(child)(If you have 1:1 cardinality child)

Child Navigation to Detail Page


SAP ABAP Tutorial and Materials, SAP ABAP Guides, SAP ABAP Certifications

If you navigate to detail page from the line Items, you will see a blank page. So to show the information, we need to maintain the similar facet information in the flights CDS view.

@UI.facet: [
      // This is for the body
      {
        id: 'GeneralInformationFlights',
        isSummary: true,
        type: #COLLECTION
       },
        {
       parentId: 'GeneralInformationFlights',
       id:'group1Information',
       type: #FIELDGROUP_REFERENCE,
       targetQualifier: 'one',
       label: 'Item Group 1'
       }]

      @UI.fieldGroup: [{
        // Qualifier is mandatory as this is
        // the way to distinguish between
        // Multiple groups
        qualifier: 'one',
        position: 10
       }]
  key spfli.carrid,
      @UI.fieldGroup: [{
        qualifier: 'one',
        position: 20
       }]
  @UI.lineItem:{position: 10, importance: #HIGH}
  key spfli.connid,
      @UI.fieldGroup: [{
        qualifier: 'one',
        position: 30
       }]
  @UI.lineItem:{position: 20, importance: #HIGH}
      spfli.countryfr,

CDS Views Code


I am pasting all the CDS views code for the reference.

@AbapCatalog.sqlViewName: 'ZVCCARRIER'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Carrier'
@VDM.viewType: #CONSUMPTION
@OData:{
    publish: true
}
@UI.headerInfo:{
    title.value: 'carrid',
    title.url: 'url',
    description.value: 'carrname'
}
define view ZC_Carrier
  as select from scarr
  association [0..*] to ZC_Flight as _Flight on _Flight.carrid = $projection.carrid
{
      @UI.facet: [
      // This is for the body
      {
        id: 'GeneralInformation',
        isSummary: true,
        type: #COLLECTION
       },
        {
       parentId: 'GeneralInformation',
       id:'group1Information',
       type: #FIELDGROUP_REFERENCE,
       targetQualifier: 'two',
       label: 'Group 1'
       },
       {
       parentId: 'GeneralInformation',
       id:'group2Information',
       type: #FIELDGROUP_REFERENCE,
       targetQualifier: 'one',
       label: 'Group 2'
       },
       // This is for the Items
       {
       id:'lineItems',
       type: #LINEITEM_REFERENCE,
       targetElement: '_Flight',
       label: 'Flights'
       }]

      @UI.fieldGroup: [{
        // Qualifier is mandatory as this is
        // the way to distinguish between
        // Multiple groups
        qualifier: 'one',
        position: 10
       }]
      @UI.identification: [{position: 10 }]
  key scarr.carrid,
      @UI.fieldGroup: [{
        qualifier: 'two',
        position: 10
      }]
      @UI.identification: [{position: 20 }]
      scarr.carrname,
      @UI.fieldGroup: [{
        qualifier: 'two',
        position: 20
      }]
      @UI.identification: [{position: 30 }]
      @Semantics.currencyCode: true
      scarr.currcode,
      @UI.identification: [{position: 40 }]
      scarr.url,
      @ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
      _Flight
}

@AbapCatalog.sqlViewName: 'ZVC_FLIGHT'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Flights'
@UI.headerInfo:{
  typeNamePlural: 'Flights',
  typeName: 'Flight'
}
define view ZC_Flight
  as select from spfli
  association [1..1] to ZC_Carrier as _carrier on _carrier.carrid = $projection.carrid
{

  key spfli.carrid,
  @UI.lineItem:{position: 10, importance: #HIGH}
  key spfli.connid,
  @UI.lineItem:{position: 20, importance: #HIGH}
      spfli.countryfr,
  @UI.lineItem:{position: 30, importance: #HIGH}
      spfli.countryto,
  @UI.lineItem:{position: 40, importance: #HIGH}
      spfli.cityfrom,
  @UI.lineItem:{position: 50, importance: #HIGH}
      spfli.cityto,
  @UI.lineItem:{position: 60, importance: #HIGH}
      spfli.distance,
      @ObjectModel.association:{ type: [ #TO_COMPOSITION_PARENT, #TO_COMPOSITION_ROOT ] }
      _carrier
}

Task Configuration


Now once our CDS view is created it will generate the OData service, which will need to provide in the SWFVISU task.

SAP ABAP Tutorial and Materials, SAP ABAP Guides, SAP ABAP Certifications

APPLICATION_PATH
COMPONENT_NAME  cross.fnd.fiori.inbox.annotationBasedTaskUI
QUERY_PARAM00  service=/sap/opu/odata/sap/ZC_CARRIER_CDS 
QUERY_PARAM01  entity=/ZC_Carrier(‘{&CARRIER_ID&}’) 
QUERY_PARAM02  annotations=/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName=’ZC_CARRIER_CDS_VAN’,Version=’0001′)/$value/ 
SCHEME  Sapui5

BTW I created this dummy test workflow and a copied the decision task

SAP ABAP Tutorial and Materials, SAP ABAP Guides, SAP ABAP Certifications

No comments:

Post a Comment