An Example of Linear Accrual Method: How to Create Your Own Method
Do you have experience using the solution of SAP accruals management? If yes, you must be quite familiar with the term of accrual methods. When you create an accrual object in the system, it’s required to assign a method to an accrual item type, and normally, you choose an accrual method that the system proposes as the default. By the way, if you want to define a default accrual method, go to Customizing under Accrual Calculation > Define Accrual Methods and you assign them under Basic Settings > Accrual Item Types > Define Accrual Item Types by entering your method in the Default Accrual Method field.
However, it seems not enough. What do you think? It could happen when you can hardly find the pre-delivered accrual methods that fit your business requirements. Or you may want the system to calculate and post accrual amounts with a new method created yourself? As a developer, you can have the access and define the way for accruals calculation as you like, while it could be a bit complicated and difficult to do the coding work. In this blog, let’s have a close look at the linear accrual method which is a pre-delivered one and you can get the basic idea how the method is composed of and how to create a method of such.
Value Collector CL_ACE_VALUES and Attribute MT_FIN_PERIOD_VALUES
The most important class in defining an accrual method is CL_ACE_Values (Value Collector) that serves as a container as well as a central tool to calculate for an accrual subobject item. To be more specific, the Accrual Engine calculates accrual amount of each accrual subobject item and stores all the amounts as the calculation result in the MT_FIN_PERIOD_VALUES attribute of this class. Not only the calculated amount, but also the utilization methods are provided by this class, such as ADD_VALUE, ADD_TOTAL, ADD_PERIODS, and so on. See the graphic below for how the class is connected to an accrual subobject item:
Let’s step closer to see the core hierarchy structure in the MT_FIN_PERIOD_VALUES attribute. Before that, here is a graphic to display how the accrual information is stored in the tables.
In the overview table, a financial period for accruals is represented with the Date To and Date From fields for each entry in the Vsource column. The closing frequency of item types determines the number of financial periods within a calendar year. Every entry in the overview table can be transmitted to a detail table that stores periodic accrual amounts for periods. The posting frequency in accrual item type settings determines how many posting periods needed. Normally you configure the frequencies in the Define Item Types activity:
Here is an example to show how the posting frequency and closing frequency impact the data stored with MT_FIN_PERIOD_VALUES attribute. Suppose an accrual object has a lifetime that spans year 2021. You choose Quarterly for the closing frequency and Per Posting Period for the posting frequency. As a result, such a configuration creates four CALCULATED entries in the Vsource column of the overview table, with a quarter for each line. As each closing period generates lines in accordance with the posting periods, the attribute structure looks like the following:
The most frequently used values for the Vsource column:
- CALCULATED: Calculated with defined accrual methods. Used for accrual periodic posting run.
- TOTAL: To be posted by the opening posting if needed.
- POST_IP (or PP…): Posted by the Accrual Engine with certain posting types.
The S_AMOUNT field is crucial to amount calculation because it controls what amount and currency to post, and which ledgers to post accruals to in a single period. In fact, S_AMOUNT represents a structure of defining amount attributes and it is the only structure allowed for accrual amounts processed by the Accrual Engine. Furthermore, it overrides other posting configuration. For example, if you enter currency types and amount values in S_AMOUNT, the final posting amounts will strictly follow your input despite exchanging rates between currencies and customizing you have made elsewhere.
To calculate amounts and store amounts in a structure for S_AMOUNT, the class CL_ACE_GENERIC_SERVICES is used to perform operations. Some frequently used operations in this class are as follows:
- VALUES_COLUMN_TO_ROW: Convert S_AMOUNT to one row.
- VALUES_ROW_TO_COLUMN: Convert one row to S_AMOUNT.
- VALUES_ROW_TO_ROW: Copy one row to another, with different prefixes.
Example: How to create an accrual method?
The general steps to create a new accrual method:
- Create an ABAP class interface IF_ACE_CFG_METHOD.
- Implement method IF_ACE_CFG_METHOD~CALCULATE.
- Create an accrual method using the new class in step 1 for calculation.
- Create an accrual object to test the new accrual method in transaction ACACTREE02.
Let’s assume that the total accrual amount is 600 EUR with the lifetime from 01.01.2021 to 30.06.2021. It is requested to distribute the planned cost in a linear way through the posting periods. The key implementation steps are:
- If an open posting is required, set the total amount to value source ‘TOTAL’ that is used later.
- Calculate total posting periods using CL_ACE_CFG_FREQUENCY=>COUNT_PERIODS.
- Calculate balance amount for each period Using CL_ACE_GENERIC_SERVICES=>VALUES_PROPORTION.
- Set amount to value source ‘CALCULATED’ for each period using CL_ACE_VALUES->SET_TOTAL_VALUE. Alternatively, you can use CL_ACE_VALUES->ADD_VALUE to only set the delta amount for a period.
See the following coding for this example. If you are interested in creating other accrual methods, welcome to have a try and let us know if you need any support.
METHOD if_ace_cfg_method~calculate. "set total value ir_mdo_subobj_item->mo_values->set_total_value( is_amount = is_item_td_parameters-s_amount id_date = is_item_td_parameters-life_start_date id_vsource = if_ace_mdo_types=>cv_vsource_total id_rldnr = is_item_td_parameters-rldnr ). "read setting DATA(ls_ledger_parameters) = cl_ace_cfg_db_buffer=>get_item_ledger_parameters( id_comp = ir_mdo_subobj_item->mo_subobj->ms_subobj_key-comp id_bukrs = ir_mdo_subobj_item->mo_subobj->ms_subobj_key-bukrs id_itemtype = ir_mdo_subobj_item->mv_itemtype id_rldnr = is_item_td_parameters-rldnr ). "count total periods DATA(lv_periods_all) = cl_ace_cfg_frequency=>count_periods( iv_periv = ls_ledger_parameters-periv iv_date_from = is_item_td_parameters-life_start_date iv_date_to = is_item_td_parameters-life_end_date iv_rhythm = ls_ledger_parameters-rhythm ). "read vsource CALCULATED result DATA(lt_calculated_values) = ir_mdo_subobj_item->mo_values->get_values_delta( ir_vsource = VALUE #( ( sign = 'I' option = 'EQ' low = if_ace_mdo_types=>cv_vsource_calculated ) ) ir_rldnr = VALUE #( ( sign = 'I' option = 'EQ' low = is_item_td_parameters-rldnr ) ) ). LOOP AT lt_calculated_values ASSIGNING FIELD-SYMBOL(<ls_calculated_values>) .DATA(ls_balance_amount) = cl_ace_generic_services=>values_proportion( is_amount = is_item_td_parameters-s_amount id_mult = CONV #( sy-tabix ) id_div = CONV #( lv_periods_all ) ). ir_mdo_subobj_item->mo_values->set_total_value( is_amount = ls_balance_amount id_date = <ls_calculated_values>-date_to id_vsource = <ls_calculated_values>-vsource id_rldnr = <ls_calculated_values>-rldnr ). ENDLOOP. ENDMETHOD.
For more information about accruals management and accrual methods, please visit the following topics: