Skip to Content
Technical Articles
Author's profile photo Syed Salman Asghar

Auto Calculations for a Receipt in My Travel Expense Fiori App

Why I am writing this?

Hi!

This is Syed Salman Asghar, HCM Lead consultant with techno-functional role.

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_returnrow I_RECEIPT_NUMBER.

Conclusion

In short, we can perform auto calculations in receipts of Travel Expense using the methods IF_PAOC_MTE~RECEIPT_CREATE_ENTITY and IF_PAOC_MTE~RECEIPT_UPDATE_ENTITY of badi PAOC_MTE_BADI.

 

Feel free to comment below with your questions / suggestions.

If you like this blog post, please like it and share it.

Cheers!

Assigned tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.