While working on a “Travel Management Roll out using Fiori Apps” project for one of our client recently, I came across a requirement of calculating amount of a receipt based on some business rules. We were implementing “My Travel Expense” app Version 2.
A little dig into the implementation guide of the fiori app suggested implementing Badi PAOC_MTE_BADI. Unfortunately, i couldn’t find any help on implementing this Badi. The situation worsened when I tried implementing the badi and failed to save my changes to the trip data. Neither I was able to show custom messages.
After effort of hours and days, finally i was able to succeed. So i thought i must share it with community to help save others some precious time.
Note that this blog post was written for Fiori app “My Travel Expense” V2. It may or may not work for other versions.
Functional Requirement
The requirement is to auto calculate amount of a receipt in “My Travel Expense” (MTE) Fiori app.
Additionally, the code must be capable of throwing custom error/warning messages.
Solution Overview
1. We will implement Badi PAOC_MTE_BADI using T-code SE19.
2. Two methods are of our interest:
◉ IF_PAOC_MTE~RECEIPT_CREATE_ENTITY: This method is called every time a new receipt is entered/created. This essentially means selecting an “Expense Type” from the popup in MTE.
◉ IF_PAOC_MTE~RECEIPT_UPDATE_ENTITY: This method is called every time a receipt is changed/edited. This essentially means selecting a receipt and clicking “Edit” link in MTE.
3. Retrieve memory data using method cl_trv_access=>retrieve_expense_from_cluster (refer note 2775801 )
4. Make changes to the receipt table retrieved from et_receipts parameter of cl_trv_access=>retrieve_expense_from_cluster.
5. Return messages through table retrieved from ct_return parameter of cl_trv_access=>retrieve_expense_from_cluster.
6. Write changed data to memory using method cl_trv_access=>save_expense_to_cluster (refer note 2775801)
Lets dive into the details.
Solution Details
Step1: Implement PAOC_MTE_BADI
I will not go into details of implementing a Badi as it is readily available and out of scope of this blog. However, important is Badi name and the relevant method that will contain our code.
Step 2: Implementing method IF_PAOC_MTE~RECEIPT_CREATE_ENTITY
This method is called every time a new expense type is added to MTE. Its signature is like:
◉ I_PERNR: To get employee information e.g. IT0017
◉ I_TRIPNO: To get trip info, if trip number has been assigned.
◉ CS_RECEIPT : A changing structure to process receipt related information. We will save our changes in this structure first and then eventually pass these changes to et_receipt of cl_trv_access=>save_expense_to_cluster
◉ CT_RETURN : A changing table to keep all your custom messages. These messages are then appended to et_return of cl_trv_access=>save_expense_to_cluster
SAP maintains complete trip data in memory clusters. Changes to trip data must be written to these clusters. To ensure that trip data is not lost, we will first retrieve current data from clusters and then modify/amend it with our changes.
Retrieve memory Data
Use this code to retrieve memory data.
*TRY.
DATA:
ev_mode TYPE ptrv_trip_action_s,
iv_crud TYPE com_crud VALUE 'R',
ev_editable TYPE xfeld,
ev_deletable TYPE xfeld,
ev_tripnumber TYPE bapitrip-tripno,
ev_periodnumber TYPE bapitrvxxx-period,
ev_periodversion TYPE ptrv_perio-pdvrs,
ev_persistencystatus TYPE com_persistancy_status,
ev_locked_by TYPE sy-uname,
es_header TYPE ptrv_web_general_data_ext,
et_receipts TYPE ptrv_web_receipts_ext_t_2,
et_deductions TYPE ptrv_web_deductions_ext_t,
et_itinerary TYPE ptrv_web_itinerary_ext_t,
et_costdist_trip TYPE ptrv_web_costdist_ext_t,
et_costdist_itin TYPE ptrv_web_costdist_ext_t,
et_costdist_rece TYPE ptrv_web_costdist_ext_t,
et_costdist_mile TYPE ptrv_web_costdist_ext_t,
ev_fm_posting_date TYPE fm_posting_date,
et_mastercost_default TYPE ptrv_web_costdist_trip_ext_t,
et_advances TYPE ptrv_web_advances_ext_t,
et_mileage TYPE ptrv_web_mileage_ext_t,
et_amounts TYPE ptra_web_bapitrvsum_t,
et_paufa TYPE ptrv_util_paufa_t,
et_ccc_trans_rec TYPE ptrv_util_ccc_trans_rec_t,
et_ccc_buffer TYPE ptrv_util_ccc_buf_t,
et_history TYPE ptrv_web_history_t,
et_return TYPE bapirettab,
ev_subrc TYPE sy-subrc
.
data: ls_return type bapiret2.
CALL METHOD cl_trv_access=>retrieve_expense_from_cluster
EXPORTING
iv_employeenumber = i_pernr
iv_tripnumber = i_tripno
* iv_crud = 'R'
IMPORTING
ev_mode = ev_mode
ev_editable = ev_editable
ev_deletable = ev_deletable
ev_tripnumber = ev_tripnumber
ev_periodnumber = ev_periodnumber
ev_periodversion = ev_periodversion
ev_persistencystatus = ev_persistencystatus
ev_locked_by = ev_locked_by
es_header = es_header
et_receipts = et_receipts
et_deductions = et_deductions
et_itinerary = et_itinerary
et_costdist_trip = et_costdist_trip
et_costdist_itin = et_costdist_itin
et_costdist_rece = et_costdist_rece
et_costdist_mile = et_costdist_mile
ev_fm_posting_date = ev_fm_posting_date
et_mastercost_default = et_mastercost_default
et_advances = et_advances
et_mileage = et_mileage
et_amounts = et_amounts
et_paufa = et_paufa
et_ccc_trans_rec = et_ccc_trans_rec
et_ccc_buffer = et_ccc_buffer
et_history = et_history
et_return = et_return
ev_subrc = ev_subrc.
* CATCH /iwbep/cx_mgw_busi_exception.
*ENDTRY.
After this code, complete current data related to trip being created/modified is in data objects provided in importing clause.
Perform Calculations
Use cs_receipt structure to prepare your changes to the receipt data. Following are important fields of this structure:
◉ rec_amount
◉ rec_curr
◉ pay_amount
◉ pay_curr
◉ shorttxt
◉ descript
Using your business logic, perform needful calculations and set fields of cs_receipt appropriately.
Example code is listed below:
cs_receipt-shorttxt = 'This is a short description.'.
*calculate receipt amount
cs_receipt-rec_amount = rate * number * multiplier.
IF cs_receipt-rec_amount > 0.
cs_receipt-rec_curr = curr.
cs_receipt-descript = |Days = { number }; Rate/Day = { rate } { curr }; Factor = { multiplier }; |.
ENDIF.
*set amount reimbursed
CALL FUNCTION 'CONVERT_AMOUNT_TO_CURRENCY'
EXPORTING
DATE = cs_receipt-rec_date
foreign_currency = cs_receipt-rec_curr
foreign_amount = cs_receipt-rec_amount
local_currency = cs_receipt-pay_curr
IMPORTING
LOCAL_AMOUNT = cs_receipt-pay_amount
* TABLES
* T_C_ERRORS =
EXCEPTIONS
ERROR = 1
OTHERS = 2
.
Add custom Error/warning messages
In case you want to add your custom error/warning messages, make changes to ct_return data object. Note that row and parameter fields are very important while making changes to ct_return.
Example code is:
data: ls_return type bapiret2.
IF sy-subrc <> 0.
* Currency conversion error
ls_return-type = 'E'.
ls_return-id = 'ZFFF_TRIP'.
ls_return-number = '007'.
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
msgid = ls_return-id
msgnr = ls_return-number
* MSGV1 = ' '
* MSGV2 = ' '
* MSGV3 = ' '
* MSGV4 = ' '
IMPORTING
MESSAGE_TEXT_OUTPUT = ls_return-message
.
ls_return-row = cs_receipt-receiptno. "this is must to add to FIORI messages
ls_return-parameter = 'PTRV_WEB_RECEIPTS_INT_2'. "this is must to add to FIORI messages
append ls_return to ct_return.
ENDIF.
Save changes (i.e. Write changes back to cluster)
Finally, the changes made to cs_receipt and ct_return must be saved / written to the cluster to make them persistent.
Sample code is as follows:
DATA: wa_receipt TYPE ptrv_web_receipts_ext_2.
MOVE-CORRESPONDING: cs_receipt TO wa_receipt.
MODIFY et_receipts FROM wa_receipt TRANSPORTING rec_amount rec_curr pay_amount pay_curr shorttxt descript WHERE receiptno = wa_receipt-receiptno.
*TRY.
CALL METHOD cl_trv_access=>save_expense_to_cluster
EXPORTING
iv_employeenumber = i_pernr
iv_tripnumber = i_tripno
iv_mode = ev_mode
iv_editable = ev_editable
iv_deletable = ev_deletable
iv_periodnumber = ev_periodnumber
iv_periodversion = ev_periodversion
iv_persistencystatus = ev_persistencystatus
iv_locked_by = ev_locked_by
is_header = es_header
it_receipts = et_receipts
it_deductions = et_deductions
it_itinerary = et_itinerary
it_costdist_trip = et_costdist_trip
it_costdist_itin = et_costdist_itin
it_costdist_rece = et_costdist_rece
it_costdist_mile = et_costdist_mile
iv_fm_posting_date = ev_fm_posting_date
iv_mastercost_default = et_mastercost_default
it_advances = et_advances
it_mileage = et_mileage
it_amounts = et_amounts
it_paufa = et_paufa
it_ccc_buffer = et_ccc_buffer
it_ccc_trans_rec = et_ccc_trans_rec
it_history = et_history
it_return = ct_return
IMPORTING
ev_subrc = ev_subrc.
* CATCH /iwbep/cx_mgw_busi_exception.
*ENDTRY.
And this will add receipt to a trip with prefilled auto calculated amounts!
Step 3: Implementing method IF_PAOC_MTE~RECEIPT_UPDATE_ENTITY
Consider a scenario where user selects a receipt and edit “from date” or “to date” of a receipt. consequently, the amount for the receipt must be recalculated to cater changed no. of days. Such calculations which are required on changes in receipt data must be performed in IF_PAOC_MTE~RECEIPT_UPDATE_ENTITY method of Badi PAOC_MTE_BADI.
The principal is same as in IF_PAOC_MTE~RECEIPT_CREATE_ENTITY method. i.e. retrieve cluster data, make necessary changes, save changes to cluster data.
However, while adding custom messages, a small change in above code is required as follow:
ls_return–row = I_RECEIPT_NUMBER.
No comments:
Post a Comment