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
@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)
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
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
7- Create Service Binding and Publish ODATA Service
8- Preview your App
8 .1- GET Appropriation Request Data through Legacy BAPI : ‘BAPI_APPREQUEST_GETDETAIL’ using custom CDS entity.
8.2 CREATE Appropriation Request through BAPI: ‘BAPI_APPREQUEST_CREATE’ using behavior implementation class.
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