Skip to Content
Technical Articles
Author's profile photo Nandi Kishore

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
1 Tables Created ZSO_HDR ZSO_ITM ZSO_STAT
2 Interface CDS Views ZSO_HDR_I ZSO_ITM_I ZSO_STAT_I ZSO_ITM_STAT_I
3 Consumption CDS Views ZSO_ITM_C ZSO_STAT_C ZSO_ITM_STAT_C
4 Behavior Definitions ZSO_ITM_I            & ZSO_ITM_C ZSO_STAT_I          & ZSO_STAT_C ZSO_ITM_STAT_I               & ZSO_ITM_STAT_C
5 Service  Definition ZSRV_SO_ITM_STAT
6 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:

 

7. Fiori Application :

Double click on zso_itm_stat_c in service binding or click Preview .

Click Create add details

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

ZSO_ITM_C–> Item level App

Click Create and add details

Similarly add Status for items for ZSO_STAT_C

 

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

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.

 

 

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.

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Samantak Chatterjee
      Samantak Chatterjee

      Hi Nandi,

      Thanks for your blog post. It's really very informative.

      Can you please let me know that if this entire exercise can be done in the SAP Cloud Trial account Environment ? Or do do you need to setup something else ?

      I have a SAP Trial Cloud Account and also have Eclipse Tool installed in my personal laptop. Can I use that setup to complete this exercise ?

      Thanks a lot in advance.

      Best Regards,

      Samantak.

      Author's profile photo Nandi Kishore
      Nandi Kishore
      Blog Post Author

      Hi Samantak,

      yes SAP Trial Cloud Account will work for this .you need to create ABAP Trial instance in Cloud platform by subscribing to it.You can follow this link for ABAP environment setup using Trial account https://developers.sap.com/tutorials/abap-environment-trial-onboarding.html

      https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/720c423ef1a8498ab690cf0e5512ba50.html

      Thanks,

      Nandi