Rebate Records

The previous article described how a rebate calculation logic can output forecasts to the end-user, during the creation and negotiation of a Rebate Agreement. At this stage however, the transactions that are encompassed by the agreement haven’t yet been created, and the rebate amount is thus not yet calculable. The logic therefore produced so-called Rebate Records.

This article describes how the Rebate Records are used to calculate the rebate amounts, during (and after) the period wherein the Rebate Agreement is valid.

Rebate Records

During the negotiation of a Rebate Agreement, the rebate calculation logic is executed in the context of the Line Item. This calculation typically results in the creation of one — or more — Rebate Records [1]. Each Rebate Record originates from a single Line Item and contains (among other things):

  • Copies of the Rebate Agreement’s startDate and endDate.

  • Copies of the Line Item inputs.

  • Copies of the Rebate Agreement header inputs.

  • Copies of the Line Item results/outputs.

  • A reference to the Line Item’s Rebate Type.

Figure 1. Schematic representation of the rebate record type.

Creating Rebate Records

To create a Rebate Record, invoke the method IRebateRecordManager.add() [2] on the bind variable [3] rebateRecord:

The most basic way to create a Rebate Record with many field values copied from Line Item.
rebateRecord.add()

Rebate Records can only be created in rebate calculation logics during the Line Item Calculation Context execution phase — nothing will happen if it’s executed in the Rebate Record Calculation Context.

Remember, the groovy code stored in the Elements of the Rebate (line / rebate type) Logic can be executed in 3 different contexts (given by Calculation Context of the Element):

  • "Agreement" - Code executed for the Line Item during negotiation, while the agreement is editable.

  • "Agreement Read-only" - Also for the line item execution, but when the agreement is read-only - either during approval waiting, or later after approval. The results of the calculation are NOT stored, only presented to user.

  • "RebateRecord" - Code executed for the Rebate Record (i.e., in the context of Rebate Record).

If the Calculation Context is not set at all, the Element’s code is used in all three cases.

Much of the data from the Rebate Agreement will be copied into the new Rebate Record. This data can be overridden by custom values; by providing an argument to the add() method:

The default values can be overriden by providing a map as an argument.
rebateRecords.add( [ startDate: startDate, // ❶ endDate: endDate, // ❶ attribute1: "USD" // ❷ ] )

❶ The Rebate Record is created with a different validity date than the Rebate Agreement
❷ An attribute column on the Rebate Record is used to store a currency.

Calculating Rebates

When the Rebate Agreement is approved, the document becomes read-only; which means that if the document is recalculated, the results cannot be saved. [4] However, during the entire validity of the Rebate Agreement, the rebate amount can be periodically re-calculated and stored on the Rebate Records. When the Rebate Record is calculated, the Rebate Logic uses only the Elements with Calculation Context "RebateRecord" (or where the Calculation Context is not set at all).

Figure 2. The sequence of events up until the Rebate Agreement is submitted.

As is the case with calculation logics, the object from the calculation context is accessed with api.currentItem(); in this case, the Rebate Record.

Reading the startDate from the Rebate Record.
api.currentItem()?.startDate

When a logic has finished executing (in the Rebate Record phase) the results of the elements are mapped to the Rebate Record attribute columns by name, and thereafter saved.

❶ The Rebate Record that is being displayed on the screen.
❷ Section for the end-user to provide inputs.
❸ Button for recalculating the Rebate Record.

Although the inputs are copied from the Rebate Agreement line item into the Rebate Record, the UI will only render those inputs that are created during input generation. This means that if an input is generated within an logic element that has the calculation context set to agreement, this input field will not be visible on the Rebate Record detail screen.

Calculating Forecasts

The final rebate is calculated after the end of the Rebate Record’s validity, since that is when the whole transaction data set will be available. However, the logic can also be executed during the validity; that is, when all transactions within the period are not yet available. This is useful when an end user would like to forecast what the final rebate amount will be, and include the incomplete transaction data set in the calculation. This will give a more accurate forecast than the one given during the negotiation of the Rebate Agreement, (i.e., during the Line Item Calculation Context execution).

Multiple Rebates per Line Item

A Rebate Agreement can span over a time during which there are multiple rebates per Line Item.

For example, consider the following Rebate Agreement:

  • If the customer purchases items for more than X EUR within a quarter, the retailer pays back Y% of the total invoice price at the beginning of the following quarter. This agreement is valid for 2 years.

From this, it follows that there will be a total of 8 rebate amounts that need to be calculated; one for each of the 8 quarters during those 2 years.

This can be achieved by creating multiple Rebate Records, during the Line Item Calculation Context execution, where each Rebate Record corresponds to one calculated rebate amount. The Rebate Records are created with different validities than the Rebate Agreement — by overriding the default inherited startDate and endDate ([code_rebateRecordAddMap]), such that each date during the Rebate Agreement validity is covered by a single Rebate Record.

Rebate Record Sets

Different types of rebates can have different outputs, thus requiring different configuration of the Attribute Metadata. This can be achieved by assigning Rebate Records to Rebate Record Sets (RRS). Each Rebate Record set has its own Attribute Metadata. For this reason, only Rebate Records of one set can be displayed on the screen at the time.

Rebate Records are assigned to Rebate Record sets by providing the name of the set as an argument to rebateRecords.add(). [5] If the Rebate Record set does not exist, it will be created. In fact, this is the only way to create Rebate Record sets; it cannot be created in the User Interface. The argument to rebateRecords.add() can also be left out, and the Rebate Record is then assigned to the default set.

Creation of a Rebate Record that belongs to a Rebate Record set "``". If the set doesn’t exist, it will be created.

Scheduled Calculation

Rebate Records usually need to be recalculated periodically, to have the actual accruals available during the period of validity of the Agreement.

The scheduling could be done in several ways:

  • Using a specialized task called "Rebate Calculation".

  • Recalculation triggered by Calculation Flow.

Recalculation by "Rebate Calculation"

Rebate Calculation is a scheduled process, which regularly recalculates a bunch of Rebate Records. This process is located under Rebates  Calculations

Selection of Rebate Records for recalculation:

  • By Rebate Record Set - One part of the filter is also the "Set", so you are selecting which "set" of Rebate Records you want to calculate.

  • By filter on Rebate Records - You can recalculate, for example, only Rebate Records which fall into a specific year.

  • Or by using a Feeder logic - Using a special "Feeder" logic (on the Calculation tab), which can be used for more complex filtering of the Rebate Records to be recalculated.

Recalculation by Calculation Flow

Rebate Records can also be recalculated on a regular basis with calculation flows; by invoking CalculationFlowActionBuilder.addRebateRecordAction(). [6] It takes the label of a Rebate Record set as an argument, and only the Rebate Records that belong to this set will be recalculated.

A calculation flow logic element that triggers calculation of all Rebate Records that belong to a specific Rebate Record set.

❶ Starts the calculation of all Rebate Records in the given Rebate Record set.

Payout Records

Optionally, the rebate calculation logic can produce Payout Records during the Rebate Record calculation context execution. Payout Records are useful when a single rebate amount needs to be divided into a multiple of payouts, which is a common scenario when the buyer is a group of customers. For example:

  • Customers A, B, C form a buying group which makes purchases during the agreement validity period (e.g., during the year). At the end of the year, the rebate amount is calculated and:

    • Customer A is paid 40% of this amount.

    • Customer B is paid 35%.

    • Customer C is paid 25%.

In this example, the Rebate Record would result in three Payout Records.

Found an issue in documentation? Write to us.