Creating Simple Report in SAP Cloud Platform ABAP environment. Step-by-step guide

SAP Cloud Platform, ABAP Environment is the SAP Platform-as-a-Service (PaaS) offering for ABAP development that enables developers to leverage their traditional on-premise ABAP know-how to develop and run ABAP applications in the SAP Cloud Platform, either as extension to SAP software or as standalone applications.

Also Read: What is SAP ABAP 7.4 Certification?

This blog post will introduce you to ABAP RESTful Programming Model which consists of three main layers:

  • Data Modeling & Behavior
  • Business Services Provisioning
  • Service Consumption

The data modeling and behavior layer contains domain-specific business objects, that are defined with Core Data Services (CDS) and transactional behavior.

The business service provisioning layer consists of projection views with their projection behavior to focus on a particular aspect of the data model which is exposed as business services through the OData protocol.

The service consumption layer allows you to consume all types of OData services as well as OData Web APIs.

The development flow will look as follows :

This tutorial is based on Data Dictionary , CDS , ABAP OO , Fiori Elements ( Semantic Annotations ) , Services.

I will use this to create a Report that will display Purchasing Documents Header and Items .

Step 1: Create ABAP package

Open ABAP Development Tools (ADT) and select your ABAP Cloud Project you created in Create an SAP Cloud Platform ABAP Environment Trial User.

Right-click on ZLOCAL and select ABAP Package.

Create a new ABAP package:

  • Name: ZREPORT_PO
  • Description: PO Report Package

Click Next > twice then Select Create new request and enter a request description : “PO Report” and optionally you can add this package to favorite packages to access it easily by (Right-click on Favorite Packages and select Add Package and choose the created one .

Step 2: Create database tables which will contains PO header and items tables.

Right-click on your package ZREPORT_PO, select New > Other ABAP Repository Object.

Search for database table, select it and click Next >.

Create a new database table:

  • Name: ZPOHEAD
  • Description: PO HEAD

Click Next >. and choose the request we created earlier .

Replace your code with following:

@EndUserText.label : 'POHEAD'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table zpohead {
  key client   : abap.clnt not null;
  key po_order : abap.char(10) not null;
  comp_code    : abap.char(4);
  doc_type     : abap.char(4);
  vendor       : abap.numc(10);
  status       : abap.char(4);
  created_by   : syuname;
  created_at   : timestampl;

}

We will repeat this for the Items Table :

The new database table will be :

  • Name: ZPOITEMS
  • Description: PO ITEMS
@EndUserText.label : 'POITEMS'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table zpoitems {
  key client     : abap.clnt not null;
  key po_order   : abap.char(10) not null;
  key order_item : abap.numc(4) not null;
  unit           : abap.unit(3);
  @Semantics.quantity.unitOfMeasure : 'zpoitems.unit'
  quantity       : abap.quan(10,3);

}

Step 3: Create ABAP class which we will use it to generate data into the tables created.

Right-click on your package ZREPORT_PO, select New > ABAP Class.

Create a new ABAP class:

  • Name: zcl_po_generate_data
  • Description: Class for generating PO data

Click Next > then Click Finish on our transport request.

Replace your code with following:

CLASS zcl_po_generate_data DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
     INTERFACES if_oo_adt_classrun.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_po_generate_data IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA:itab TYPE TABLE OF zpohead,
         itab2 TYPE TABLE OF ZPOITEMS.

*   read current timestamp
    GET TIME STAMP FIELD DATA(ztime).

*   fill internal PO Header  internal table (itab)
    itab = VALUE #(
    ( po_order = '0000000001' comp_code = 'test' doc_type ='ZMM1'  vendor = '0010000000' status = 'P' created_by = 'user1' created_at = ztime )
    ( po_order = '0000000002' comp_code = 'test' doc_type ='ZMM2'  vendor = '0010000001' status = 'C' created_by = 'user2' created_at = ztime )
    ( po_order = '0000000003' comp_code = 'test' doc_type ='ZMM3'  vendor = '0010000002' status = 'D' created_by = 'user2' created_at = ztime )
    ) .
*   fill internal PO Items internal table (itab2)
    itab2 = VALUE #(
    ( po_order = '0000000001' order_item = '10' unit = 'PC' quantity = '5' )
    ( po_order = '0000000002' order_item = '10' unit = 'KG' quantity = '30.1' )
    ( po_order = '0000000002' order_item = '20' unit = 'KG' quantity = '20.2' )

    ) .

*   insert the table entries
    INSERT zpohead FROM TABLE @itab.
    INSERT zpoitems FROM TABLE @itab2.

    out->write( 'PO data inserted successfully!').

  ENDMETHOD.
ENDCLASS.

In this Class we created two internal tables the 1st one for the header and 2nd one for the items then we fill this tables with dummy data for testing and then inserting them into the database tables created.

Save, activate and click F9 to run your ABAP class.

The ABAP Console will produce sucess message ‘PO data inserted successfully!’

-To check the database tables data , Switch to your database table and press F8 to see your data.

Now the dictionary tables are filled with data.

Step 4 : Define CDS-based PO data model

We will create first the Items data model which will contains Items properties then the Main model .

Right-click on your package ZREPORT_PO, select New > Other ABAP Repository Object.

Search for data definition under Core Data Services Node, select it and click Next >.

Create a data definition:

  • Name: Z_R_ITEMS
  • Description: PO Items Data Model

Click Next > then Click Finish on our transport request.

Your code will look like the following:

@AbapCatalog.sqlViewName: 'ZVRI_MODEL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'PO Items Data Model'
define view Z_R_ITEMS as select from zpoitems {
    @UI: {lineItem: [{ position: 10  }]}
    @EndUserText.label: 'Purchasing Document'
    key po_order,
    @UI: {lineItem: [{ position: 20  }]}
    @EndUserText.label: 'Item'
    key order_item,
    @UI: {lineItem: [{ position: 30  }]}
    @EndUserText.label: 'Unit'
    unit,
    @UI: {lineItem: [{ position: 40  }]}
    @EndUserText.label: 'Quantity'
    quantity
}

Now we will repeat this to create Main PO Model :

  • Name: Z_R_MODEL
  • Description: PO Items Data Model

The Main PO root model will look like the following:

@AbapCatalog.sqlViewName: 'ZVR_MODEL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'PO Data Model'
define root view Z_R_MODEL as select from zpohead
association [1..*] to Z_R_ITEMS as items on $projection.po_order = items.po_order {
    //zpohead
    key po_order,
    comp_code,
    doc_type,
    vendor,
    status,
    created_by,
    created_at,
    items
}

In this step we First defined the data model of items which specify fields selected , labels & position , Second we defined the main data model which contains the header data fields and its relation to the items .

Step 5 : Create projection view for PO

We will create which will contains all the View properties to be displayed .

Right-click on your package ZREPORT_PO, select New > Other ABAP Repository Object.

Search for data definition under Core Data Services Node, select it and click Next >.

Create a data definition:

  • Name: ZPR_VIEW
  • Description: PO Projection View

Click Next >.

Click Next > then Click Finish on our transport request.

Your code will look like the following:

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'PO Projection View'
@UI: {
 headerInfo: { typeName: 'Purchasing Order Details', typeNamePlural: 'Purchasing Orders' } 
 }

define root view entity ZPR_VIEW  as projection on Z_R_MODEL {
   @UI.facet: [      { id:             'POHeader',
                      type:            #IDENTIFICATION_REFERENCE,
                      label:           'PO Header',
                      position:        10,
                      purpose:         #STANDARD
                      },
                      
                      
                      { id:            'Item',
                      purpose:         #STANDARD,
                      type:            #LINEITEM_REFERENCE,
                      label:           'Items',
                      targetElement:   'items',
                      position:        20
                      }
                    
                  ]
    @UI: {
          lineItem:       [ { position: 10, importance: #HIGH } ] , selectionField: [ { position: 10 }] , identification: [ { position: 10} ]}
    @Search.defaultSearchElement: true
    @EndUserText.label: 'Purchasing Document'
    key po_order,
    @UI: {
          lineItem:       [ { position: 20, importance: #HIGH } ] , selectionField: [ { position: 20 }],  identification: [ { position: 20} ] }
    @EndUserText.label: 'Company Code'
    @Search.defaultSearchElement: true
    comp_code,
    @UI: {
          lineItem:       [ { position: 30, importance: #HIGH } ] , selectionField: [ { position: 30 }], identification: [ { position: 30} ]}
    @EndUserText.label: 'Document Type'
    @Search.defaultSearchElement: true
    doc_type,
    @UI: {
          lineItem:       [ { position: 40, importance: #HIGH } ]}
    @EndUserText.label: 'Vendor'
    vendor,
     @UI: {
          lineItem:       [ { position: 50, importance: #HIGH } ]}
    @EndUserText.label: 'Status'
    status,
    @UI: {
          lineItem:       [ { position: 60, importance: #HIGH } ]}
    @EndUserText.label: 'Created By'
    created_by,
    @UI: {
          lineItem:       [ { position: 70, importance: #HIGH } ]}
    @EndUserText.label: 'Created At'
    created_at ,
    
    items
}

In this step we created the View properties which defines Header information , Selections fields on the first page (Order , Company Code & Document Type) and Also the Navigation on the selected line item page ( facet ) properties ( Header and Body ).

Step 6: Create service definition

Right-click on your data definition ZPR_VIEW and select New Service Definition.

Create a new service definition:

  • Name: ZR_SERV
  • Description: PO Report Service Definiton

Click Next >.

Click Finish on our transport request.

Your code will look like the following:

@EndUserText.label: 'PO Report Service Definiton'
define service ZR_SERV {
  expose ZPR_VIEW;
  expose Z_R_ITEMS;
}

In this step we created service definition on our view for our report which we exposed our View and its Items .

Step 7: Create service binding

Right-click on your service definition ZR_SERV and select New Service Binding.

Create a new service binding:

  • Name: ZR_SERV_B
  • Description: PO Report Service Binding
  • Binding Type: ODATA V2 – UI

Click Next >.

Click Finish on our transport request.

Activate your service binding.

In this step we created our service binding which generates our service with its entities and associations and allows you to bind the service definition to an ODATA protocol.

Double-click on ZPR_VIEW to see our SAP Fiori Elements Application on the UI.

This Screen will open on the browser , Logon to your ABAP system with your trial email and password .

After logging in , you can see our selection parameters .

Click GO to see the result (We can use the filters later).

It’s working , Now we can the the PO documents which we created earlier and if we clicked on any items like the second line , We can see the 2nd page which contains order header selected fields and the order items displayed on the body.

Leave a Reply

Your email address will not be published. Required fields are marked *