ABAP RESTful Application Programming Model

Unmanaged App to post Purchase Requisitions on S/4

RAP is framework that would still allow to use the ABAP to develop Modern applications.

With the below blog I want to show a real life use case which demonstrate the power and easy of use of unmanaged RAP.

With the below demo we develop an unmanaged RAP application that utilizes standard SAP API and EML to allow uses to create and update SAP Requisitions.

Unmanaged RAP model for Purchase Requisition

1. Create new CDS root entity view, use the below code:

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'PR Header root view'
define root view entity YRAP_RV_PRHEADER
  as select from I_PurchaseRequisitionItemAPI01 //as _prhead
{
  key PurchaseRequisition as prnum,
  key PurchaseRequisitionItem,
      PurchaseReqnItemUniqueID,
      PurchasingDocument,
      PurchasingDocumentItem,
      PurReqnReleaseStatus,
      PurchaseRequisitionType,
      PurchasingDocumentSubtype,
      PurchasingDocumentItemCategory,
      PurchaseRequisitionItemText,
      AccountAssignmentCategory,
      Material,
      MaterialGroup,
      PurchasingDocumentCategory,
      RequestedQuantity,
      BaseUnit,
      PurchaseRequisitionPrice,
      PurReqnPriceQuantity,
      MaterialGoodsReceiptDuration,
      ReleaseCode,
      PurchaseRequisitionReleaseDate,
      PurchasingOrganization,
      PurchasingGroup,
      Plant,
      OrderedQuantity,
      DeliveryDate,
      CreationDate,
      CreatedByUser,
      PurReqCreationDate,
      PurReqnItemCurrency,
      /* Associations */
      _PurchaseRequisition,
      _PurReqnAcctAssgmt
}

2. Create Projection view for the root view already created.

@EndUserText.label: 'Projection view for PR Header'
@Metadata.allowExtensions: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Search.searchable: true
define root view entity YRAP_PV_PRHEADER 
provider contract transactional_query
as projection on YRAP_RV_PRHEADER

 {
    key prnum,
    key PurchaseRequisitionItem,
    PurchaseReqnItemUniqueID,
    PurchasingDocument,
    PurchasingDocumentItem,
    PurReqnReleaseStatus,
    PurchaseRequisitionType,
    PurchasingDocumentSubtype,
    PurchasingDocumentItemCategory,
    PurchaseRequisitionItemText,
      @Consumption.valueHelpDefinition: [{

          entity: {
              name: 'I_AccountAssignmentCategory',
              element: 'AccountAssignmentCategory'
          }}]
      @ObjectModel.text.element: ['AccountAssignmentCategory']
      @Search.defaultSearchElement: true    
    AccountAssignmentCategory,
    Material,
      @Consumption.valueHelpDefinition: [{

          entity: {
              name: 'I_ProductGroup_2',
              element: 'ProductGroup'
          }}]
      @ObjectModel.text.element: ['MaterialGroup']
      @Search.defaultSearchElement: true    
    MaterialGroup,
    PurchasingDocumentCategory,
    RequestedQuantity,
    BaseUnit,
    PurchaseRequisitionPrice,
    PurReqnPriceQuantity,
    MaterialGoodsReceiptDuration,
    ReleaseCode,
    PurchaseRequisitionReleaseDate,
    PurchasingOrganization,
      @Consumption.valueHelpDefinition: [{

          entity: {
              name: 'I_PURCHASINGGROUP',
              element: 'PurchasingGroup'
          }}]
      @ObjectModel.text.element: ['PurchasingGroup']
      @Search.defaultSearchElement: true    
    PurchasingGroup,
      @Consumption.valueHelpDefinition: [{

          entity: {
              name: 'I_PLANT',
              element: 'Plant'
          }}]
      @ObjectModel.text.element: ['Plant']
      @Search.defaultSearchElement: true    
    Plant,
    OrderedQuantity,
    DeliveryDate,
    CreationDate,
    CreatedByUser,
    PurReqCreationDate,
    PurReqnItemCurrency,
    /* Associations */
    _PurchaseRequisition,
    _PurReqnAcctAssgmt
}

3. Right click on the Root View and select to create new behavior definitions for the Root view and activate it. Choose unmanaged implementation type.

unmanaged implementation in class zbp_rap_rv_prheader unique;
strict ( 2 );
define behavior for YRAP_RV_PRHEADER alias prhead
late numbering
lock master
authorization master ( instance )
etag master PurReqCreationDate
{

  field ( readonly )
   prnum;
//  PurchaseRequisitionItem;

  create;
  update;
  delete;

}

4. Right click on the Projection Root View and create and activate the projection behavior definition.

projection;
strict ( 2 );

define behavior for YRAP_PV_PRHEADER alias prhead
{
  use create;
  use update;
  use delete;
}

5. Open the Root behavior definition and create the implementation class.

6. Add the code for the create and update class.

METHOD create.
**** Custom Create
    LOOP AT entities ASSIGNING FIELD-SYMBOL(<fs_prs>).

*** now try to post

      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

                    )
         WITH VALUE #(
                     (    %cid_ref = 'My%CID_1'
                          %target = VALUE #(
                                          (  %cid                             = 'My%ItemCID_1'
                                              plant                           = <fs_prs>-plant
                                              purchaserequisitionitemtext     = <fs_prs>-purchaserequisitionitemtext
                                              accountassignmentcategory       = <fs_prs>-accountassignmentcategory
                                              requestedquantity               = <fs_prs>-requestedquantity
                                              baseunit                        = <fs_prs>-baseunit
                                              purchaserequisitionprice        = <fs_prs>-purchaserequisitionprice
                                              purreqnitemcurrency             = <fs_prs>-purreqnitemcurrency
                                              materialgroup                   = <fs_prs>-materialgroup
                                              purchasinggroup                 = <fs_prs>-purchasinggroup

                                              )
                                          )
                      )
                )
ENTITY purchaserequisitionitem


              CREATE BY \_purchasereqnitemtext
                FIELDS ( plainlongtext )
                WITH VALUE #(  (   %cid_ref = 'My%ItemCID_1'
                                    %target  = VALUE #( (
                                                        %cid = 'MyTargetCID_2'
                                                        textobjecttype = 'B01'
                                                        language       = 'E'
                                                        plainlongtext  = 'item text created from PR Unmanaged APP'
                                                      ) (
                                                        %cid = 'MyTargetCID_3'
                                                        textobjecttype = 'B02'
                                                        language       = 'E'
                                                        plainlongtext  = 'item2 text created from PR Unmanaged APP'
                                                      ) )
                )   )

          REPORTED DATA(ls_reported)
          MAPPED DATA(ls_mapped)
          FAILED DATA(ls_failed).
    ENDLOOP.

  ENDMETHOD.

  METHOD update.

    LOOP AT entities ASSIGNING FIELD-SYMBOL(<fs_prs>).
*** Update values


  MODIFY ENTITIES OF i_purchaserequisitiontp
      ENTITY purchaserequisitionitem UPDATE
      SET FIELDS WITH VALUE #( (
                               purchaserequisition         = <fs_prs>-prnum
                               purchaserequisitionitem     = <fs_prs>-purchaserequisitionitem
                               purchaserequisitionitemtext = <fs_prs>-purchaserequisitionitemtext
                               requestedquantity           = <fs_prs>-requestedquantity
                               baseunit                    = <fs_prs>-baseunit
                                ) ) .

   ENDLOOP.
  ENDMETHOD.

7. In the above we are using the standard SAP provided API “i_purchaserequisitiontp” which is released for development in cloud and can be used for upgrade stable development.

8. Create service definition.

9. Create service binding. We will use V2 as we cannot still have the create with V4 for applications without drafts.

10. This can now be tested using the FIORI Element preview.

With the above example we can use other SAP standard APIs with RAP and build apps that allow us to resolve real work problems.

FIORI elements preview: –