Saturday, 3 July 2021

ABAP Restful Application Programming Model with Legacy BAPI

Unmanaged Or Managed?

While Sap was constructing the new RAP model, it made a distinction between managed and unmanaged scenarios. Managed means completely new and Greenfield implementation(no legacy logic).

If you have to use existing BAPI or function, SAP is recommended to turn to the unmanaged scenario in RAP model.

What will you learn?

In this example I will create “Unmanaged Restful Application Programming Model Scenario” with Legacy Appropriation Requests BAPIs and structures.

You’ll learn

1- How to create custom cds entity and implement a query provider class include BAPI_APPREQUEST_GETDETAIL’

2- How to create behavior definition and implementation include BAPI_APPREQUEST_CREATE function.

3- How to create service definition and service binding.

Legacy Codes Summary

◉ GET Appropriation Request Data through Legacy BAPI : ‘BAPI_APPREQUEST_GETDETAIL’

◉ CREATE Appropriation Request through BAPI: ‘BAPI_APPREQUEST_CREATE’

RAP Codes Summary

Get Appropriation Requests

◉ Create a Custom CDS Entity: ZHVL_IC_APPROPREQ

◉ Implement a query provider class: ZCL_APPROP_VIA_RFC->interface>if_rap_query_provider

Create Appropriation Request

◉ Create Behavior Definition for ZHVL_IC_APPROPREQ Custom CDS Entity

◉ Create Control Structure Name: ZHVL_CS_APPROP

◉ In Behavior Definition->create mapping for ZHVL_IC_APPROPREQ using control structure ZHVL_CS_APPROP

◉ Create Behavior Implementation->unmanaged implementation in class ZBP_HVL_IC_APPROPREQ

Create ODATA Service

◉ Create Service Definition

◉ Create Service Binding

1- Create Custom CDS Entity

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

@EndUserText.label: 'Approp Request Custom Cds Entity'
@ObjectModel.query.implementedBy: 'ABAP:ZCL_APPROP_VIA_RFC'

@UI: {
headerInfo: {
typeName: 'Approp Request',
typeNamePlural: 'Approp Requests'
}
}

define root custom entity ZHVL_IC_APPROPREQ

{

      @UI.facet        : [
             {
               id      :       'AppropRequest',
               purpose :  #STANDARD,
               type    :     #IDENTIFICATION_REFERENCE,
               label   :    'Approp Request',
               position: 10 }
           ]


      @UI              : {
      lineItem         : [{position: 10, importance: #HIGH}],
      identification   : [{position: 10}],
      selectionField   : [{position: 10}]
      }
  key externalnumber   : abap.char( 24 );
      //MASTER DATA
      @UI              : {
      lineItem         : [{position: 20, importance: #HIGH}],
      identification   : [{position: 20}],
      selectionField   : [{position: 20}]
      }
      REQ_TXT          : ima_txt50;
      @UI              : {
      lineItem         : [{position: 30, importance: #HIGH}],
      identification   : [{position: 30}],
      selectionField   : [{position: 30}]
      }
      RSP_COST_CENTER  : ima_vkostl;
      @UI              : {
      lineItem         : [{position: 40, importance: #HIGH}],
      identification   : [{position: 40}],
      selectionField   : [{position: 40}]
      }
      APPR_DATE        : ima_gdatu;
      @UI              : {
      lineItem         : [{position: 50, importance: #HIGH}],
      identification   : [{position: 50}],
      selectionField   : [{position: 50}]
      }
      ORIG_APPR_YEAR   : ima_gjahr;
      @UI              : {
      lineItem         : [{position: 60, importance: #HIGH}],
      identification   : [{position: 60}],
      selectionField   : [{position: 60}]
      }

      //Variant Data
      DESCRIPTION      : ima_txv50;
      @UI              : {
      lineItem         : [{position: 70, importance: #HIGH}],
      identification   : [{position: 70}],
      selectionField   : [{position: 70}]
      }
      COMPLETION_DATE  : ima_fdatu;
      START_UP_DATE    : ima_idatu;

      //PLAN TOTAL
      OVERHEAD_COSTS   : bapicurr_d;

      // ORG_UNITS
      REQ_COST_CENTER  : ima_akostl;
      PERCENTAGE       : ima_aproz;

      //PARTNER DATA
      PARTNER_FUNCTION : abap.char( 2 );
      PARTNER          : i_parnr;

      //PLAN_YEAR
      FISCAL_YEAR      : gjahr;


      INV_PROG         : im_prnam;
      APPR_YEAR        : im_gnjhr;
      PROGRAM_POS      : abap.char( 24 );
      PERCENT_PROG_POS : im_prozu;

}

2- Implement a query provider class to get the data, using a BAPI (Business Application Programming Interface)

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

CLASS zcl_approp_via_rfc DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_rap_query_provider .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_approp_via_rfc IMPLEMENTATION.
  METHOD if_rap_query_provider~select.
    TYPES: BEGIN OF ty_approp,
             externalnumber   TYPE ima_posid,
             req_txt          TYPE ima_txt50,
             rsp_cost_center  TYPE ima_vkostl,
             appr_date        TYPE ima_gdatu,
             orig_appr_year   TYPE ima_gjahr,
             description      TYPE ima_txv50,
             completion_date  TYPE ima_fdatu,
             start_up_date    TYPE ima_idatu,
             overhead_costs   TYPE bapicurr_d,
             req_cost_center  TYPE ima_akostl,
             percentage       TYPE ima_aproz,
             partner_function TYPE parvw,
             partner          TYPE i_parnr,
             fiscal_year      TYPE gjahr,
             inv_prog         TYPE im_prnam,
             appr_year        TYPE im_gnjhr,
             program_pos      TYPE im_posid,
             percent_prog_pos TYPE im_prozu,
           END OF ty_approp.
    DATA: ls_approp_req TYPE ty_approp.
    DATA: lt_approp_req TYPE STANDARD TABLE OF ty_approp.
    DATA: ls_master_data TYPE bapiappreqmaster,
          ls_controlling TYPE bapi_appreq_id-cntrl_area,
          lt_org         TYPE TABLE OF bapiappreqorgunit,
          lt_partner     TYPE TABLE OF bapiappreqpartnerout,
          lt_pos         TYPE TABLE OF bapiappreqexpprogassgn,
          lt_variant     TYPE TABLE OF bapiappreqvarntmulti,
          lt_plantot     TYPE TABLE OF bapiappreqplantotalmulti,
          lt_planyear    TYPE TABLE OF bapiappreqplanyearmulti,
          lt_return      TYPE TABLE OF bapiret2.
    "Set RFC destination
    TRY.
        "data(lo_rfc_dest) = cl_rfc_destination_provider=>proxy_type_onpremise(
        "i_name = ''
        ").
        "DATA(lv_rfc_dest_name) = lo_rfc_dest->get_destination_name(  ).
        "Check if data is requested
        IF io_request->is_data_requested(  ).
*          DATA lv_maxrows TYPE int4.
*          DATA(lv_skip) = io_request->get_paging( )->get_offset(  ).
*          DATA(lv_top) = io_request->get_paging( )->get_page_size(  ).
*          lv_maxrows = lv_skip + lv_top.
          io_request->get_paging( )->get_offset(  ).
          io_request->get_paging( )->get_page_size(  ).
          "Call BAPI
          CALL FUNCTION 'BAPI_APPREQUEST_GETDETAIL'
            EXPORTING
              externalnumber    = '2.018E11-016288'
*             language          =
*             language_iso      =
            IMPORTING
              master_data       = ls_master_data
*             user_fields       =
              "controlling_area  = ls_controlling
            TABLES
              org_units         = lt_org
*             division          =
*             material_group    =
*             invest_reason     =
*             environmnt_invest =
*             assets_equis      =
*             order             =
*             wbs_element       =
              partner           = lt_partner
              assignment_to_pos = lt_pos
*             assignment_to_budg_categ =
              variant           = lt_variant
*             variant_to_version       =
*             assigned_apprequests     =
              plan_total        = lt_plantot
              plan_year         = lt_planyear
*             plan_total_obj    =
*             plan_year_obj     =
              return            = lt_return.
        ENDIF.
        ls_approp_req-externalnumber = '2.018E11-016288'.
        ls_approp_req-req_txt = ls_master_data-req_txt.
        ls_approp_req-rsp_cost_center = ls_master_data-rsp_cost_center.
        ls_approp_req-appr_date = ls_master_data-appr_date.
        ls_approp_req-orig_appr_year = ls_master_data-orig_appr_year.

        READ TABLE lt_org INTO DATA(ls_org) INDEX 1.
        ls_approp_req-req_cost_center = ls_org-req_cost_center.
        ls_approp_req-percentage = ls_org-percentage.

        READ TABLE lt_partner INTO DATA(ls_partner) INDEX 1.
        ls_approp_req-partner_function = ls_partner-partner_function.
        ls_approp_req-partner = ls_partner-partner.

        READ TABLE lt_pos INTO DATA(ls_pos) INDEX 1.
        ls_approp_req-inv_prog = ls_pos-inv_prog.
        ls_approp_req-appr_year = ls_pos-appr_year.
        ls_approp_req-percent_prog_pos = ls_pos-percent_prog_pos.
        ls_approp_req-program_pos = ls_pos-program_pos.

        READ TABLE lt_variant INTO DATA(ls_variant) INDEX 1.
        ls_approp_req-req_cost_center = ls_variant-description.
        ls_approp_req-start_up_date = ls_variant-start_up_date.

        READ TABLE lt_plantot INTO DATA(ls_plantot) INDEX 1.
        ls_approp_req-overhead_costs = ls_plantot-overhead_costs.

        READ TABLE lt_planyear INTO DATA(ls_planyear) INDEX 1.
        ls_approp_req-fiscal_year = ls_planyear-fiscal_year.

        APPEND ls_approp_req TO lt_approp_req.
        CLEAR ls_approp_req.
        "Set total no. of records
        io_response->set_total_number_of_records( lines( lt_approp_req ) ).
        "Output data
        io_response->set_data( lt_approp_req ).
      CATCH  cx_rfc_dest_provider_error INTO DATA(lx_dest).
    ENDTRY.

  ENDMETHOD.

ENDCLASS.

3- Create Behavior Definition for ZHVL_IC_APPROPREQ

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

unmanaged implementation in class zbp_hvl_ic_appropreq unique;

define behavior for ZHVL_IC_APPROPREQ alias approp
//late numbering
//lock master
//etag master <field_name>


{
  create;
  update;
  delete;

  mapping for ZHVL_IC_APPROPREQ control zhvl_cs_approp

  {
    externalnumber = externalnumber;
    req_txt = req_txt;
    rsp_cost_center = rsp_cost_center;
    appr_date = appr_date;
    orig_appr_year = orig_appr_year;
    description = description;
    completion_date = completion_date;
    start_up_date = start_up_date;
    overhead_costs = overhead_costs;
    req_cost_center = req_cost_center;
    percentage = percentage;
    partner_function = partner_function;
    partner = partner;
    fiscal_year = fiscal_year;
    inv_prog = inv_prog;
    appr_year = appr_year;
    program_pos = program_pos;
    percent_prog_pos = percent_prog_pos;
  }

}

3.1- Create control structure: zhvl_cs_approp

@EndUserText.label : 'Control Structure For Approp Req'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
define structure zhvl_cs_approp {
  externalnumber   : xsdboolean;
  req_txt          : xsdboolean;
  rsp_cost_center  : xsdboolean;
  appr_date        : xsdboolean;
  orig_appr_year   : xsdboolean;
  description      : xsdboolean;
  completion_date  : xsdboolean;
  start_up_date    : xsdboolean;
  overhead_costs   : xsdboolean;
  req_cost_center  : xsdboolean;
  percentage       : xsdboolean;
  partner_function : xsdboolean;
  partner          : xsdboolean;
  fiscal_year      : xsdboolean;
  inv_prog         : xsdboolean;
  appr_year        : xsdboolean;
  program_pos      : xsdboolean;
  percent_prog_pos : xsdboolean;

}
 

4- Create a custom RFC function module and call legacy BAPI in this function module.**IMPORTANT


Important Note: 

RAP framework does not allow Commit/Rollback statements, as the framework itself internally takes care for committing/roll backing entities. If you try calling BAPI directly in behavior implementation class methods. You’ll get a dump.Because of this reason,We will call this RFC enabled function with destination none in behavior implementation class.(this may not be the best method. But I couldn’t find a better way,If anyone can find a better way, I would appreciate it if they write in the comments section.)

FUNCTION zhvl_approp_req
  IMPORTING
    VALUE(legacy_entity_in) TYPE zhvl_ic_appropreq
  EXPORTING
    VALUE(gv_ext) TYPE bapi_appreq_id-appreq
    VALUE(gv_appr) TYPE bapi_appreq_id-appreqvrnt.

 DATA messages   TYPE bapiret2.


    DATA : ls_masterdata TYPE bapiappreqmaster.
    DATA: lt_org      TYPE TABLE OF bapiappreqorgunit,
          lt_partner  TYPE TABLE OF bapiappreqpartner,
          lt_pos      TYPE TABLE OF bapiappreqexpprogassgn,
          lt_variant  TYPE TABLE OF bapiappreqvarntmulti,
          lt_plantot  TYPE TABLE OF bapiappreqplantotalmulti,
          lt_planyear TYPE TABLE OF bapiappreqplanyear,
          lt_return   TYPE TABLE OF bapiret2.

    DATA: ls_org      TYPE  bapiappreqorgunit,
          ls_partner  TYPE  bapiappreqpartner,
          ls_pos      TYPE  bapiappreqexpprogassgn,
          ls_variant  TYPE  bapiappreqvarnt,
          ls_plantot  TYPE  bapiappreqplantotal,
          ls_planyear TYPE  bapiappreqplanyear,
          ls_return   TYPE  bapiret2.


      ls_masterdata-req_txt = legacy_entity_in-req_txt.
      ls_masterdata-rsp_cost_center = legacy_entity_in-rsp_cost_center.
      ls_masterdata-appr_date  = legacy_entity_in-appr_date.
      ls_masterdata-orig_appr_year = legacy_entity_in-orig_appr_year.


      ls_variant-description = legacy_entity_in-description.
      ls_variant-completion_date = legacy_entity_in-completion_date.
      ls_variant-start_up_date = legacy_entity_in-start_up_date.

      ls_plantot-overhead_costs = legacy_entity_in-overhead_costs.

      ls_org-req_cost_center = legacy_entity_in-req_cost_center.
      ls_org-percentage = legacy_entity_in-percentage.
      APPEND ls_org TO lt_org.


*      ls_partner-partner_function = legacy_entity_in-partner_function.
*      ls_partner-partner = legacy_entity_in-partner.
*      APPEND ls_partner TO lt_partner.

      ls_partner-partner_function = 'I1'.
      ls_partner-partner = 'user1'.
      APPEND ls_partner TO lt_partner.
      ls_partner-partner_function = 'I2'.
      ls_partner-partner = 'user1'.
      APPEND ls_partner TO lt_partner.
      ls_partner-partner_function = 'I3'.
      ls_partner-partner = 'user2'.
      APPEND ls_partner TO lt_partner.
      ls_partner-partner_function = 'I4'.
      ls_partner-partner = 'user2'.
      APPEND ls_partner TO lt_partner.
      ls_partner-partner_function = 'I5'.
      ls_partner-partner = 'user2'.
      APPEND ls_partner TO lt_partner.
      ls_partner-partner_function = 'I6'.
      ls_partner-partner = 'user3'.
      APPEND ls_partner TO lt_partner.

      ls_planyear-fiscal_year = legacy_entity_in-fiscal_year.
      ls_planyear-overhead_costs = legacy_entity_in-overhead_costs.
      APPEND ls_planyear TO lt_planyear.


      ls_pos-inv_prog = legacy_entity_in-inv_prog.
      ls_pos-appr_year = legacy_entity_in-appr_year.
      ls_pos-program_pos = legacy_entity_in-program_pos.
      ls_pos-percent_prog_pos = legacy_entity_in-percent_prog_pos.
      APPEND ls_pos TO lt_pos.


    CALL FUNCTION 'BAPI_APPREQUEST_CREATE'
      EXPORTING
        apprequest_type                = '10'
        appropriationrequest_in        = legacy_entity_in-externalnumber
        appropriationrequestvariant_in = ''
        controlling_area               = 'A000'
        master_data                    = ls_masterdata
        "user_fields                    = ls_user
        variant                        = ls_variant
        plan_total                     = ls_plantot
        test_run                       = ''
      IMPORTING
        externalnumber                 = gv_ext
        appropriationrequestvariantout = gv_appr
      TABLES
        org_units                      = lt_org
        "division                       = lt_division
        "material_grp                   = lt_matgroup
        "investment_reason              = lt_investrea
        "environmnt_invest              = lt_environve
        "orders                         = lt_order
        "wbs_element                    = lt_wbselement
        "variant_to_version             = lt_variant
        partner                        = lt_partner
        assignment_to_pos              = lt_pos
        plan_year                      = lt_planyear
        return                         = lt_return.


    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.

ENDFUNCTION.
 

5- Create Behavior Implementation: class ZBP_HVL_IC_APPROPREQ.


CLASS lhc_ZHVL_IC_APPROPREQ DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.

    METHODS create FOR MODIFY
      IMPORTING entities FOR CREATE approp.

    METHODS delete FOR MODIFY
      IMPORTING keys FOR DELETE approp.

    METHODS update FOR MODIFY
      IMPORTING entities FOR UPDATE approp.

    METHODS read FOR READ
      IMPORTING keys FOR READ approp RESULT result.

ENDCLASS.

CLASS lhc_ZHVL_IC_APPROPREQ IMPLEMENTATION.

  METHOD create.

    DATA legacy_entity_in  TYPE zhvl_ic_appropreq.
    DATA: gv_ext  TYPE bapi_appreq_id-appreq,
          gv_appr TYPE bapi_appreq_id-appreqvrnt.

    LOOP AT entities ASSIGNING FIELD-SYMBOL(<entity>).

      legacy_entity_in = CORRESPONDING #( <entity> MAPPING FROM ENTITY USING CONTROL ).

    CALL FUNCTION 'ZHVL_APPROP_REQ' DESTINATION 'NONE'
      EXPORTING
        legacy_entity_in = legacy_entity_in
      IMPORTING
        gv_ext           = gv_ext
        gv_appr          = gv_appr.
      
    ENDLOOP.

  ENDMETHOD.

  METHOD delete.
  ENDMETHOD.

  METHOD update.
  ENDMETHOD.

  METHOD read.
  ENDMETHOD.

ENDCLASS.

CLASS lsc_ZHVL_IC_APPROPREQ DEFINITION INHERITING FROM cl_abap_behavior_saver.
  PROTECTED SECTION.

    METHODS check_before_save REDEFINITION.

    METHODS finalize          REDEFINITION.

    METHODS save REDEFINITION.


ENDCLASS.

CLASS lsc_ZHVL_IC_APPROPREQ IMPLEMENTATION.

  METHOD check_before_save.
  ENDMETHOD.

  METHOD finalize.
  ENDMETHOD.

  METHOD save.

ENDMETHOD.
ENDCLASS.

6- Create Service Definition

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

7- Create Service Binding and Publish ODATA Service

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

8- Preview your App


8 .1- GET Appropriation Request Data through Legacy BAPI : ‘BAPI_APPREQUEST_GETDETAIL’ using custom CDS entity.

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

8.2 CREATE Appropriation Request through BAPI: ‘BAPI_APPREQUEST_CREATE’ using behavior implementation class.

ABAP Restful Application Programming Model, SAP ABAP Tutorial and Material, SAP ABAP Career, SAP ABAP Material, SAP ABAP Certification, SAP ABAP Preparation

Important Note:

The codes in this example are purely for illustrative purposes. No performance testing has been done. No development has been made regarding the return parameters. May not be suitable for production system.

No comments:

Post a Comment