Skip to Content

Create a Custom RAP Business Object to Trigger Purchase Requisitions API

test
0 %
Create a Custom RAP Business Object to Trigger Purchase Requisitions API
Details

Create a Custom RAP Business Object to Trigger Purchase Requisitions API

October 21, 2021
Created by
October 6, 2021
Create a custom RAP business object to trigger purchase requisitions API with SAP S/4HANA Cloud ABAP Environment.

You will learn

  • How to logon to SAP S/4HANA Cloud ABAP Environment
  • How to create an ABAP package
  • How to create a database table
  • How to create a CDS model and projection view
  • How to create behavior definition & implementation
  • How to create service definition & service binding
  • How to run SAP Fiori Elements Preview
QR code

Prerequisites

  • IMPORTANT: It is essential that you are a member of SAP Early Adopter program.
  • You have a license for SAP S/4HANA Cloud and have a developer user in it
  • You have installed the latest Eclipse with ADT.
  • Business Catalog SAP_PRC_BC_PURCHASER_PR needs to be assign to your business user

In the online shop, customers can order various items. Once an item is ordered, a new purchase requisition is created via purchase requisitions API.

EML can be used to trigger purchase requisitions API, which is released for cloud development.

In this tutorial, wherever XXX appears, use a number (e.g. 000).


Step 1: Logon to SAP S/4HANA Cloud ABAP Environment
  1. Open Eclipse, select File > New > Other.

    logon

  2. Search ABAP Cloud Project, select it and click Next >.

    logon

  3. Select SAP S/4HANA Cloud ABAP Environment, enter the ABAP service instance URL and click Next >.

    logon

  4. Click Open Logon Page in Browser to log in.

    logon

  5. Click Next >.

    logon

  6. Check your ABAP service instance connection and click Finish.

    logon

  7. Now your project will be available in the project explorer.

    logon

Log on to answer question
Step 2: Create ABAP package
  1. Select ZLOCAL > New > ABAP Package.

    package

  2. Create new ABAP package:

    • Name: Z_PURCHASE_REQ_XXX
    • Description: Package XXX
    • Check Add to favorite packages

    package

    Click Next >.
  3. Create a new request:

    • Request Description: TR12345

    package

    Click Finish.
Log on to answer question
Step 3: Create database table
  1. Right-click your package Z_PURCHASE_REQ_XXX and select New > Other ABAP Repository Object.

    table

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

    table

  3. Create new database table:

    • Name: ZONLINESHOP_XXX
    • Description: Shop to purchase electronics

    table

    Click Next >.
  4. Click Finish.

    table

  5. Replace your code with following:

    @EndUserText.label : 'Shop to purchase electronics'
    @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
    @AbapCatalog.tableCategory : #TRANSPARENT
    @AbapCatalog.deliveryClass : #A
    @AbapCatalog.dataMaintenance : #RESTRICTED
    define table zonlineshop_xxx {
      key client     : abap.clnt not null;
      key order_uuid : sysuuid_x16 not null;
      order_id       : abap.char(10) not null;
      ordereditem    : abap.char(10) not null;
      deliverydate   : abap.dats;
      creationdate   : abap.dats;
    
    }
    
  6. Save and activate.

  7. Right-click your package Z_PURCHASE_REQ_XXX and select New > Other ABAP Repository Object.

    table

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

    table

  9. Create new database table:

    • Name: ZSHOP_AS_XXX
    • Description: Database table for additional save

    table

    Click Next >.
  10. Click Finish.

    table

  11. Replace your code with following:

    @EndUserText.label : 'Database table for additional save'
    @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
    @AbapCatalog.tableCategory : #TRANSPARENT
    @AbapCatalog.deliveryClass : #A
    @AbapCatalog.dataMaintenance : #RESTRICTED
    define table zshop_as_xxx {
      key client     : abap.clnt not null;
      key order_uuid : sysuuid_x16 not null;
      purchasereqn   : abap.string(256);
      purinforecord  : abap.string(256);
      purorder       : abap.string(256);
    
    }
    
  12. Save and activate.

Log on to answer question
Step 4: Create CDS data model
  1. Right-click your package Z_PURCHASE_REQ_XXX and select New > Other ABAP Repository Object.

    cds

  2. Search for data definition, select it and click Next >.

    cds

  3. Create new data definition:

    • Name: ZI_ONLINE_SHOP_XXX
    • Description: Data model for online shop

    cds

    Click Next >.
  4. Click Finish.

    cds

  5. Replace your code with following:

    @EndUserText.label: 'Data model for online shop'
    @AccessControl.authorizationCheck: #CHECK
    define root view entity ZI_ONLINE_SHOP_XXX as select from zonlineshop_xxx {
       key order_uuid as Order_Uuid,
       order_id as Order_Id,
       ordereditem as Ordereditem,
       deliverydate as Deliverydate,
       creationdate as Creationdate  
    }
    
  6. Save and activate.

Log on to answer question
Step 5: Create projection view
  1. Right-click Data Definitions and select New Data Definition.

    projection

  2. Create new projection view:

    • Name: ZC_ONLINE_SHOP_XXX
    • Description: Projection view for online shop
    • Referenced Object: ZI_ONLINE_SHOP_XXX

    projection

    Click Next >.
  3. Click Finish.

    projection

  4. Replace your code with following:

    @EndUserText.label: 'shop projection'
    @AccessControl.authorizationCheck: #CHECK
    @Search.searchable: true
    @UI: { headerInfo: { typeName: 'Online Shop',
                         typeNamePlural: 'Online Shop',
                         title: { type: #STANDARD, label: 'Online Shop', value: 'order_id' } },
    
           presentationVariant: [{ sortOrder: [{ by: 'Creationdate',
                                                 direction: #DESC }] }] }
    define root view entity ZC_ONLINE_SHOP_XXX
      as projection on ZI_ONLINE_SHOP_XXX
    {
          @UI.facet: [          { id:                  'Orders',
                                       purpose:         #STANDARD,
                                       type:            #IDENTIFICATION_REFERENCE,
                                       label:           'Order',
                                       position:        10 }      ]
      key Order_Uuid,
          @UI: { lineItem:       [ { position: 10,label: 'order id', importance: #HIGH } ],
                   identification: [ { position: 10, label: 'order id' } ] }
          @Search.defaultSearchElement: true
          Order_Id,
          @UI: { lineItem:       [ { position: 20,label: 'Ordered item', importance: #HIGH } ],
                  identification: [ { position: 20, label: 'Ordered item' } ] }
          @Search.defaultSearchElement: true
          Ordereditem,
          Deliverydate       as Deliverydate,
          @UI: { lineItem:       [ { position: 50,label: 'Creation date', importance: #HIGH },
                                   { type: #FOR_ACTION, dataAction: 'update_inforecord', label: 'Update IR' } ],
                 identification: [ { position: 50, label: 'Creation date' } ] }
          Creationdate       as Creationdate
    }
    
  5. Save and activate.

Log on to answer question
Step 6: Create behavior definition for CDS data model
  1. Right-click your data definition ZI_ONLINE_SHOP_XXX and select New Behavior Definition.

    behavior

  2. Create new behavior definition:

    behavior

    Click Next >.

  3. Click Finish.

    behavior

  4. Replace your code with following:

    managed implementation in class zbp_i_online_shop_xxx unique;
    
    define behavior for ZI_ONLINE_SHOP_XXX alias Online_Shop
    persistent table zonlineshop_xxx
    lock master
    authorization master ( instance )
    //etag master <field_name>
    {
      field ( numbering : managed, readonly ) order_Uuid;
      field ( mandatory ) Ordereditem;
      field ( readonly ) Creationdate, order_id;
      determination calculate_order_id on modify { create; }
      internal action create_pr;
      internal action set_inforecord;
      internal action update_inforecord;
      create;
      update;
      delete;
    }
    
  5. Save and activate.

Log on to answer question
Step 7: Create behavior definition for projection view
  1. Right-click your projection view ZC_ONLINE_SHOP_XXX and select New Behavior Definition.

    behavior

  2. Create new behavior definition:

    behavior

    Click Next >.

  3. Click Finish.

    behavior

  4. Replace your code with following:

    projection;
    //strict; //Comment this line in to enable strict mode. The strict mode is prerequisite to be future proof regarding syntax and to be able to release your BO.
    
    define behavior for ZC_ONLINE_SHOP_XXX //alias <alias_name>
    {
      use create;
      use update;
      use delete;
    
    }
    
  5. Save and activate.

Log on to answer question
Step 8: Create behavior implementation
  1. In your behavior definition ZI_ONLINE_SHOP_XXX set the cursor before the implementation class zbp_i_online_shop_xxx and click CTRL + 1. Double-click on Create behavior implementation class zbp_i_online_shop_xxx to create your implementation class.

    implementation
  2. Create new implementation class:

    implementation

    Click Next >.

  3. Click Finish.

    implementation

  4. In your Global Class, replace your code with following:

    CLASS zbp_i_online_shop_xxx DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zi_online_shop_xxx.
    PUBLIC SECTION.
    class-DATA cv_pr_mapped TYPE RESPONSE FOR MAPPED i_purchaserequisitiontp.
    class-DATA cv_po_mapped TYPE RESPONSE FOR MAPPED I_PurchaseOrderTP_2.
    ENDCLASS.
    
    CLASS zbp_i_online_shop_xxx IMPLEMENTATION.
    ENDCLASS.
    
  5. In your Local Types, replace your code with following:

    CLASS lhc_zbp_i_online_shop_xxx  DEFINITION INHERITING FROM cl_abap_behavior_handler.
      PRIVATE SECTION.
    
        METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
          IMPORTING keys REQUEST requested_authorizations FOR  online_shop RESULT result.
    
        METHODS create_pr FOR MODIFY
          IMPORTING keys FOR ACTION online_shop~create_pr.
    
        METHODS update_inforecord FOR MODIFY
          IMPORTING keys FOR ACTION online_shop~update_inforecord.
    
        METHODS calculate_order_id FOR DETERMINE ON MODIFY
          IMPORTING keys FOR online_shop~calculate_order_id.
    
    
    ENDCLASS.
    
    CLASS lhc_zbp_i_online_shop_xxx  IMPLEMENTATION.
    
      METHOD get_instance_authorizations.
      ENDMETHOD.
    
      METHOD create_pr.
    **  if a new laptop is ordered, trigger a new purschase requisition
        IF keys IS NOT INITIAL.
          MODIFY ENTITIES OF i_purchaserequisitiontp
     ENTITY purchaserequisition
        CREATE FIELDS ( purchaserequisitiontype )
        WITH VALUE #(  ( %cid                    = 'My%CID_1'
                         purchaserequisitiontype = 'NB' ) )
    
       CREATE BY \_purchaserequisitionitem
       FIELDS ( plant
                purchaserequisitionitemtext
                accountassignmentcategory
                requestedquantity
                baseunit
                purchaserequisitionprice
                purreqnitemcurrency
                materialgroup
                purchasinggroup
                purchasingorganization
    *               MultipleAcctAssgmtDistribution
                    )
       WITH VALUE #(
                     (    %cid_ref = 'My%CID_1'
                          %target = VALUE #(
                                           (  %cid                            = 'My%ItemCID_1'
                                              plant                           = '1010'
                                              purchaserequisitionitemtext     = 'created from PAAS API XXX'
                                                accountassignmentcategory     = 'U'
                                              requestedquantity               = '8.00'
                                              baseunit                        = 'EA'
                                              purchaserequisitionprice        = '10.00'
                                              purreqnitemcurrency             = 'EUR'
                                              materialgroup                   = 'A001'
                                              purchasinggroup                 = '001'
                                              purchasingorganization          = '1010'
    
                                              )
                                           )
                      )
                    )
    ENTITY purchaserequisitionitem
    
    CREATE BY \_purchasereqnacctassgmt
        FIELDS ( CostCenter
                 GLAccount
                 Quantity
                 BaseUnit )
        WITH VALUE #( (   %cid_ref = 'My%ItemCID_1'
                          %target  = VALUE #( ( CostCenter   = 'JMW-COST'
                                                GLAccount    = '0000400000' ) ) ) )
    CREATE BY \_purchasereqnitemtext
       FIELDS ( plainlongtext )
       WITH VALUE #(  (   %cid_ref = 'My%ItemCID_1'
                          %target  = VALUE #( (
                                              textobjecttype = 'B01'
                                              language       = 'E'
                                              plainlongtext  = 'item text created from PAAS API XXX'
                                            ) (
                                              textobjecttype = 'B02'
                                              language       = 'E'
                                              plainlongtext  = 'item2 text created from PAAS API XXX'
                                            ) )
                  )   )
              REPORTED DATA(ls_pr_reported)
              MAPPED DATA(ls_pr_mapped)
              FAILED DATA(ls_pr_failed).
          zbp_i_online_shop_xxx=>cv_pr_mapped = ls_pr_mapped.
    
        ENDIF.
      ENDMETHOD.
    
    
      METHOD update_inforecord.
        SELECT SINGLE * FROM i_purchasinginforecordtp  WHERE PurchasingInfoRecord = '5500000219' INTO @DATA(ls_data).
    *           update an existing info record
    *update remainder for nodays-no delivery remainder after half the timeperiod b/w delivery and creation date/system date
    *fi
        MODIFY ENTITIES OF i_purchasinginforecordtp
               ENTITY purchasinginforecord
               UPDATE SET FIELDS WITH
               VALUE #( ( %key-PurchasingInfoRecord = '5500000219'
                           Supplier                 = ls_data-supplier
                           MaterialGroup            = ls_data-MaterialGroup
                           SupplierMaterialGroup    = ls_data-SupplierMaterialGroup
                           NoDaysReminder1          = '12'
                           PurchasingInfoRecordDesc = 'noDays remainder updated'
                      ) )
                 FAILED   DATA(ls_failed_update)
                 REPORTED DATA(ls_reported_update)
                 MAPPED   DATA(ls_mapped_update).
    
      ENDMETHOD.
    
      METHOD calculate_order_id.
        DATA:
          online_shops TYPE TABLE FOR UPDATE zi_online_shop_xxx,
          online_shop  TYPE STRUCTURE FOR UPDATE zi_online_shop_xxx.
    *      delete from zonlineshop_xxx UP TO 15 ROWS.
        SELECT MAX( order_id ) FROM zonlineshop_xxx INTO @DATA(max_order_id).
        READ ENTITIES OF zi_online_shop_xxx IN LOCAL MODE
           ENTITY zi_online_shop_xxx
            ALL FIELDS
              WITH CORRESPONDING #( keys )
              RESULT DATA(lt_online_shop_result)
          FAILED    DATA(lt_failed)
          REPORTED  DATA(lt_reported).
        DATA(today) = cl_abap_context_info=>get_system_date( ).
    
        LOOP AT lt_online_shop_result INTO DATA(online_shop_read).
          max_order_id += 1.
    
          online_shop               = CORRESPONDING #( online_shop_read ).
          online_shop-order_id      = max_order_id.
          online_shop-Creationdate  = today.
          online_shop-Deliverydate  = today + 10.
          APPEND online_shop TO online_shops.
        ENDLOOP.
        MODIFY ENTITIES OF zi_online_shop_xxx IN LOCAL MODE
       ENTITY zi_online_shop_xxx UPDATE SET FIELDS WITH online_shops
       MAPPED   DATA(ls_mapped_modify)
       FAILED   DATA(lt_failed_modify)
       REPORTED DATA(lt_reported_modify).
    
    **create purchase requisition
    
    * if a new laptop is ordered, trigger a new purschase requisition
        IF lt_failed_modify IS INITIAL.
          MODIFY ENTITIES OF zi_online_shop_xxx IN LOCAL MODE
          ENTITY Online_Shop EXECUTE create_pr FROM CORRESPONDING #( keys )
          FAILED DATA(lt_pr_failed)
          REPORTED DATA(lt_pr_reported).
        ENDIF.
    
    
      ENDMETHOD.
    *
    ENDCLASS.
    
  6. Save and activate.

    HINT: The option internal can be set before the action name to only provide an action for the same BO. An internal action can only be accessed from the business logic inside the business object implementation such as from a determination or from another action.

Log on to answer question
Step 9: Open documentation

You have 2 options to open the documentation inside ADT.

Option 1:

  1. Open your ABAP class zbp_i_online_shop_xxx, search for i_purchaserequisitiontp, press CTRL and click on it.
    service
  2. Now you are in the released object i_purchaserequisitiontp.
    Click Open Documentation to open it.
    service
  3. Now you are able to read the documentation.
    service

    HINT: You can also open the Element Info by clicking i_purchaserequisitiontp and pressing F2.
    service

    You can also switch to different layers inside the Element Info.
    service

Option 2:

  1. Go back to tab i_purchaserequisitiontp. You are now able to see the behavior definition folder of the released object i_purchaserequisitiontp in the project explorer. Now navigate to the documentation i_purchaserequisitiontp and open it.
    service

    HINT: You can also check the API State of released object and see its visibility by selecting the properties.

  2. Now you can see the documentation.
    service
Log on to answer question
Step 10: Create service definition
  1. Right-click your projection view ZC_ONLINE_SHOP_XXX and select New Service Definition.

    service

  2. Create new service definition:

    • Name: ZSD_SHOP_XXX
    • Description: Service definition for online shop

    service

    Click Next >.
  3. Click Finish.

    service

  4. Replace your code with following:

    @EndUserText.label: 'Service definition for online shop'
    define service ZSD_SHOP_XXX {
      expose ZC_ONLINE_SHOP_XXX as online_shop;
    }
    
  5. Save and activate.

Log on to answer question
Step 11: Create service binding
  1. Right-click your service binding ZSD_SHOP_XXX and select New Service Binding.

    binding

  2. Create new service binding:

    • Name: ZSB_SHOP_XXX
    • Description: Service binding for online shop
    • Binding Type: OData V2 - UI
    • Service Definition: ZSD_SHOP_XXX

    binding

    Click Next >.
  3. Click Finish.

    binding

  4. Right-click your service binding ZSB_SHOP_XXX and select Activate.

    binding

  5. Click Publish to publish your service binding.

    binding

Log on to answer question
Step 12: Run SAP Fiori Elements preview
  1. Select online_shop in your service binding and click Preview to open SAP Fiori Elements preview.

    preview
  2. Click Create to create a new entry.

    preview

  3. Enter an id and date, click Create.

    preview

  4. Check your result

    preview

Log on to answer question
Step 13: Check purchase requisition
  1. In the Project Explorer, select your system and right click on Properties.

    preview

  2. Select ABAP Development and copy the system URL without -api, paste it in a browser and log in.

    preview

  3. Select the Manage Purchase Requisitions tile.

    preview

  4. Click Go.

    preview

  5. Select your purchase requisition.

    preview

  6. Check your purchase requisition item and select it. Your ID should appear here instead of XXX.

    preview

  7. Select Notes and check your item text. Your ID should appear here instead of XXX.
    preview

  8. Check your item note. Your ID should appear here instead of XXX.

    preview

Log on to answer question
Step 14: Test yourself
How can you open the documentation inside ADT?
×

Give us 55 seconds of your time to help us improve

Next Steps

Back to top