Skip to Content
Technical Articles
Author's profile photo Himanshu Verma

Unmanaged App to post Purchase Requisitions on S/4

Hello Everyone,

 

We have read from several previous blog posts  – RAP for Beginners ,   Modernization with RAP, Managed RAP.

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.Projection%20View
    @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.Behavior%20Definition
    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%20Behavior%20Definition
    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. BDEF%20Class
  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.

Hope you all would find the blog helpful and would request you all to provide your thoughts or feedback as comments to this blog.

If you have any questions related to RAP please use the below: –

Q&A

Also join the community for other wonderful information on this topic:- https://blogs.sap.com/tags/7e44126e-7b27-471d-a379-df205a12b1ff/

 

FIORI elements preview: –

 

 

Assigned Tags

      7 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Mustafa Bensan
      Mustafa Bensan

      Hi Himanshu,

      In the interests of providing full context with an end-to-end example, it would be helpful if you could also post screenshots of the Fiori Elements preview so we can see the result from an end user perspective.

      Thanks,

      Mustafa.

      Author's profile photo Himanshu Verma
      Himanshu Verma
      Blog Post Author

      Thanks Mustafa, added.

      Author's profile photo Mustafa Bensan
      Mustafa Bensan

      Great.  Thanks Himanshu.

      Author's profile photo Shai Sinai
      Shai Sinai

      There is a also an SAP tutorial for a similar subject:

      Create a Custom RAP Business Object to Trigger Purchase Requisitions API

      Author's profile photo Diego Valdivia
      Diego Valdivia

      Hi Himanshu,

      When you try to create a PR with incorrect data (Let's say an incorrect plant), are you able to get data populated on FAILED or REPORTED tables? I ask you this because I implemented a similar code, but I don't get any errors on those tables.

      I submitted the following question a couple of weeks ago, but have not received a useful reply yet:

      RAP - Possible bug in standard API i_purchaserequisitiontp? | SAP Community

      Regards.

      Author's profile photo Himanshu Verma
      Himanshu Verma
      Blog Post Author

      Hi Diego,

      Yes I agree with you no errors returned, not even the Requisition that is created currently may be SAP might need to fine tune this API a bit more.

      So for us we validated data entered to make sure we have the right data before we can the API. You can simulate in S/4 to understand what data you need to post a PR.

      Regards,
      Himanshu

       

      Author's profile photo Kah Choon Simon Yong
      Kah Choon Simon Yong

      Hi,

      I tried out the tutorial below to test out how to use BOI to create PR in S4HC but it does not work. I ended up having this error "Unspecified provider error occurred. See Error Context and Call Stack." which does not tell me anything helpful.

      https://developers.sap.com/tutorials/abap-s4hanacloud-procurement-purchasereq-shop.html#974f8bf2-7d32-4b62-9582-2bf54e345315

      May I know whether it is possible to use a CDS view that has I_PurchaseRequisitionItemAPI01 joint with another custom CDS view created for customized table? We'd like to have filter function to only select PRs that are maintained in the customized table.

      Thank you for your support in advance.