Monday 2 November 2020

Transactional Fiori App using ABAP Restful Programming Model

UI Apps development is getting simplified with the evolution of ABAP. In my experience when UI5 was released i had to learn JavaScript ,jQuery concepts and use them to create even a simple UI App ,and then with the advent of  ABAP Programming model for Fiori it changed the approach, since using BOPF with annotations we can easily create  simple Transactional UI app’s with minimal frontend code. Now with ABAP RAP programming which is an evolution of latter, it further simplified and made flexible for UI App development.

In this blog, i had taken a very simple use case without any custom business logic which is  managed by the framework itself and developed a simple Fiori application, of course we can further extend this app with complex use cases.

I had used ABAP Cloud environment which is hosted in SAP Cloud Platform.

Overview

Below are various sequence of objects i had created as in below table.

Steps          
Tables Created ZSO_HDR ZSO_ITM  ZSO_ITM   
Interface CDS Views ZSO_HDR_I   ZSO_ITM_I ZSO_STAT_I  ZSO_ITM_STAT_I
Consumption CDS Views   ZSO_ITM_C ZSO_STAT_C  ZSO_ITM_STAT_C 
Behavior Definitions   ZSO_ITM_I & ZSO_ITM_C ZSO_STAT_I & ZSO_STAT_C  ZSO_ITM_STAT_I & ZSO_ITM_STAT_C 
Service Definition       ZSRV_SO_ITM_STAT
Service Binding       ZBIN_SO_ITM_STAT 

1. Tables Created:


ZSO_HDR

@EndUserText.label : 'Custom Sales Order Header'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table zso_hdr {
  key client : abap.clnt not null;
  key so     : zso not null;
  @Semantics.amount.currencyCode : 'zso_hdr.curr'
  net_val    : abap.curr(10,2);
  curr       : abap.cuky;
  @Semantics.quantity.unitOfMeasure : 'zso_hdr.uom'
  net_qty    : abap.quan(10,2);
  uom        : abap.unit(2);

}

ZSO_ITM

@EndUserText.label : 'Custom Sales Order Item'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table zso_itm {
  key client : abap.clnt not null;
  @AbapCatalog.foreignKey.keyType : #KEY
  @AbapCatalog.foreignKey.screenCheck : true
  key so     : zso not null
    with foreign key [0..*,1] zso_hdr
      where so = zso_itm.so;
  key posnr  : zitem not null;
  matnr      : abap.char(30);
  @Semantics.quantity.unitOfMeasure : 'zso_itm.uom'
  qty        : abap.quan(10,2);
  uom        : abap.unit(2);

}

ZSO_STAT

@EndUserText.label : 'Custom Sales Order Item Status'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table zso_stat {
  key client : abap.clnt not null;
  @AbapCatalog.foreignKey.screenCheck : true
  key so     : zso not null
    with foreign key [0..*,1] zso_itm
      where so = zso_stat.so;
  key posnr  : zitem not null;
  status     : zstat;

}

2. Interface CDS Views:


ZSO_HDR_I

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Interface view for ZSO_HDR'
define root view entity ZSO_HDR_I as select from zso_hdr
{
    //ZSO_HDR
    key so,
    net_val,
    curr,
    net_qty,
    uom
     // Make association public
}

ZSO_ITM_I

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Interface view for ZSO_ITM'
define root view entity zso_itm_i
  as select from zso_itm
  
{
      //ZSO_ITM
  key so,
  key posnr,
      matnr,
      qty,
      uom

}

ZSO_STAT_I

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Interface view for ZSO_STAT'
define root view entity zso_stat_i as select from zso_stat
 {
    //ZSO_STAT
    key so,
    key posnr,
    status  
}

ZSO_ITM_STAT_I

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'INterface view for Zso_hdr_i & Zso_stat_i & Zso_itm_i'
define root view entity zso_itm_stat_i as select from ZSO_HDR_I
association [0..*] to zso_itm_i   as item on  item.so   = $projection.so
association [0..*] to zso_stat_i  as stat on  stat.so   = $projection.so
 {
    //ZSO_HDR
    key so,
    net_val,
    curr,
    net_qty,
    uom,
    item, // Make association public
    stat
}

3. Consumption CDS Views:


ZSO_ITM_C

@EndUserText.label: 'Consumption view for Zso_itm_i'
@AccessControl.authorizationCheck: #CHECK

@UI: { headerInfo: { title.label: 'SO Item Info',title.type: #STANDARD,
                     typeName: 'SO Item',typeNamePlural: 'SO Items'}}
define root view entity zso_itm_c
  as projection on zso_itm_i
{
      @UI.facet: [{ id: 'POSNR',position: 10,label: 'SO Item Details',type: #IDENTIFICATION_REFERENCE }]
      @UI.lineItem: [{position: 10,type: #STANDARD }]
      @UI.identification: [{position: 10,type: #STANDARD }]
  key so,
      @UI.lineItem: [{position: 20,type: #STANDARD }]
      @UI.identification: [{position: 20,type: #STANDARD }]
  key posnr,
      @UI.lineItem: [{position: 30,type: #STANDARD,label: 'Material' }]
      @UI.identification: [{position: 30,type: #STANDARD,label: 'Material' }]
      matnr,
      @UI.lineItem: [{position: 40,type: #STANDARD,label: 'Qty' }]
      @UI.identification: [{position: 50,type: #STANDARD,label: 'Qty' }]
      qty,
      @UI.lineItem: [{position: 50,type: #STANDARD,label: 'UOM' }]
      @UI.identification: [{position: 50,type: #STANDARD,label: 'UOM' }]
      @Consumption.valueHelpDefinition: [{entity:{ element: 'UnitOfMeasure',name: 'I_UnitOfMeasureStdVH'} }] 
      uom
}

ZSO_STAT_C

@EndUserText.label: 'Consumption view for Zso_stat_i'
@AccessControl.authorizationCheck: #CHECK

@UI: { headerInfo: { title.label: 'SO Item Status',title.type: #STANDARD,
                     typeName: 'SO Item Status',typeNamePlural: 'SO Items Status'}}
                     
define root view entity zso_stat_c as projection on zso_stat_i {
    //ZSO_STAT_I
      @UI.facet: [{ id: 'STAT',position: 10,label: 'SO Item STatus',type: #IDENTIFICATION_REFERENCE }]
      @UI.lineItem: [{position: 10,type: #STANDARD }]
      @UI.identification: [{position: 10,type: #STANDARD }]    
    key so,
      @UI.lineItem: [{position: 20,type: #STANDARD }]
      @UI.identification: [{position: 20,type: #STANDARD }]    
    key posnr,
      @UI.lineItem: [{position: 30,type: #STANDARD }]
      @UI.identification: [{position: 30,type: #STANDARD }]    
    status
}

ZSO_ITM_STAT_C

@EndUserText.label: 'Consumption view for Zso_hdr_i & Zso_stat_i & Zso_itm_i'
@AccessControl.authorizationCheck: #CHECK


@UI: { headerInfo: { title.label: 'SO Info',title.type: #STANDARD,
                     typeName: 'SO Info',typeNamePlural: 'SO'}}
                     
define root view entity zso_itm_stat_c as projection on zso_itm_stat_i {

@UI.facet: [{ id: 'SO',position: 10,label: 'SO Details',type: #COLLECTION },
            { position: 20,label: 'SO Item Details',type:#LINEITEM_REFERENCE,targetElement: 'item'}, 
            { position: 30,label: 'SO Item Status',type:#LINEITEM_REFERENCE,targetElement: 'stat'},            
            { id: 'FLD',parentId: 'SO',position: 10,type: #FIELDGROUP_REFERENCE,targetQualifier: 'GP'}]   
            
@UI.lineItem: [{position: 10}]
@UI.fieldGroup: [{qualifier: 'GP',position: 10 }] 
@UI.selectionField: [{position: 10}]
    key so,
@UI.lineItem: [{position: 20,label:'Net Value'}]
@UI.fieldGroup: [{qualifier: 'GP',position: 30,label:'Net Value' }]    
    net_val,
@UI.lineItem: [{position: 30,label:'Currency'}]
@UI.fieldGroup: [{qualifier: 'GP',position: 50,label:'Currency' }]  
@Consumption.valueHelpDefinition: [{entity:{ element: 'Currency',name: 'I_CurrencyStdVH'} }]  
    curr,
@UI.lineItem: [{position: 40,label:'Net Qty'}]
@UI.fieldGroup: [{qualifier: 'GP',position: 20,label:'Net Qty' }]    
    net_qty,
@UI.lineItem: [{position: 50,label:'UOM'}]
@UI.fieldGroup: [{qualifier: 'GP',position: 40 ,label:'UOM'}]    
@Consumption.valueHelpDefinition: [{entity:{ element: 'UnitOfMeasure',name: 'I_UnitOfMeasureStdVH'} }] 
    uom,
    /* Associations */
    //zso_itm_stat_i
    item : redirected to zso_itm_c,
    stat : redirected to zso_stat_c    
}
 

4. Behavior Definitions:


ZSO_STAT_I & ZSO_STAT_C

ZSO_STAT_I

managed; // implementation in class zbp_so_stat_i unique;

define behavior for zso_stat_i alias STATI
persistent table zso_stat
lock master
//authorization master ( instance )
//etag master <field_name>
{
  create;
  update;
  delete;
}

ZSO_STAT_C

projection;

define behavior for zso_stat_c alias STATC
{
  use create;
  use update;
  use delete;
}

ZSO_ITM_I & ZSO_ITM_C

ZSO_ITM_I

managed; // implementation in class zbp_so_itm_i unique;

define behavior for zso_itm_i alias ITEMI
persistent table zso_itm
lock master
//authorization master ( instance )
//etag master <field_name>
{
  create;
  update;
  delete;
}

ZSO_ITM_C
projection;

define behavior for zso_itm_c alias ITEMC
{
  use create;
  use update;
  use delete;
}

ZSO_ITM_STAT_I & ZSO_ITM_STAT_C

ZSO_ITM_STAT_I

managed; // implementation in class zbp_so_itm_stat_i unique;

define behavior for zso_itm_stat_i alias SOINFOI
persistent table zso_hdr
lock master
//authorization master ( instance )
//etag master <field_name>
{
  create;
  update;
  delete;

}

ZSO_ITM_STAT_C

projection;

define behavior for zso_itm_stat_c alias SOINFOC
{
  use create;
  use update;
  use delete;
}

5. Service  Definition:


ZSRV_SO_ITM_STAT

@EndUserText.label: 'Service for Transaction App of SO'
define service ZSRV_SO_ITM_STAT {
  expose zso_itm_stat_c;
  expose zso_itm_c;
  expose zso_stat_c;
}

6. Service Binding:


SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

7. Fiori Application :


Double click on zso_itm_stat_c in service binding or click Preview .

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

Click Create add details

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

Create Line Item Entries & Status Entries for Sales Order using ZSO_ITM_C & ZSO_STAT_C

ZSO_ITM_C–> Item level App

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

Click Create and add details

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

Similarly add Status for items for ZSO_STAT_C

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

And after adding data in the final app on ZSO_ITM_STAT_C we can see the data flow.

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

Using this App on Click on Header EDIT button we edit all details ,just to note in this App Create button functionality of SO Item Details & Status Details may not work since we need to do Behavior Implementations for those, but individual Apps of SO Item Details & Status will work without any issues for Create as in above screenshots of ZSO_ITM_C & ZSO_STAT_C.

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

SAP ABAP Exam Prep, SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Guides

Restful ABAP Programming has simplified the Fiori App development as we can use CDS  views with annotations and behavior implementations to create complex or simple UI Apps.

No comments:

Post a Comment