Introduction
This article describes a Payout Record entity, which was introduced to help performance situations when too many Rebate Records were used.
The information is intended for Configuration Engineers who are going to implement rebate management for customer solution.
Business Use Case
The customer needs to calculate the rebates/accruals/payouts on a much lower level, e.g.:
not on customer lever, but maybe down to store/shop level.
not on product group level, but maybe per SKU, customer and payout period
Terminology
accruals | Accrual/s - refers to a time-procedural process usually carried out by accounting departments to "accrue" money in the bank for payouts that are expected to be made in the future. In other words, it’s calculation of additional money the company must put aside, to have enough money available to pay the rebate to the customer at the time of payout date. Accruals usually needs to be exported to the external system every month. |
payout | how much money to pay to the customer. Frequency of export of Payout information to the external system depends on the payout period |
payout period | how often is the rebate money paid to the customer. Usually it’s annually, semi-annually, quarterly or monthly. |
payout date | at what date should the money be given to the customer. |
Concept
What is a Payout Record
Payout Record:
is a data-entity
on which you can store the same data as Rebate Record - rebates, accruals, payouts, etc.
which is always associated with a Rebate Record, so
the Rebate Record can have higher level/summary information,
and its Payout Records will contain the calculations on more fine-grained level
which is "lightweight" - does not have "rich" features like calculation contexts, workflow, overrides
is managed by the Rebate Logic (in rebate record context)
logic you can quickly create/update/delete even hundreds of thousands of those records
System Usecase
Number of records
Generally, you can use Payout Records whenever your solution would lead to the need for generation/calculation of a lot of Rebate Records.
Because Rebate Records have many "rich" features like calculation contexts, workflow, overrides, etc., their handling is more complex and they are not intended to be used, when your solution needs more than roughly 100 Rebate Records per Rebate Agreement.
So in solutions, where customer requirement would lead to more than 100 Rebate Records (many times they need far more, even hundreds of thousands), do use Payout Records.
2nd level of calculations
You can also consider Payout Records, when it would be handy to have more levels of calculations. (But bear in mind also, that only Rebate Record is approvable, if that’s what you need)
When your solution needs 2 levels of calculation:
1st level - summary calculations (possibly for group of customers, or groups of products )
2nd level - more fine-grained calculation (on customer ID level, on SKU level, etc)
Comparison of Rebate Record and Payout Record
Rebate Record | Payout Record | |
---|---|---|
Amount per Rebate Agreement | up to 100 | up to hundreds of thousands |
Features | Calculation Contexts, Workflow, Overrides | none (it a "Lightweight" data entity) |
Handling | Creation by Logic, but update/delete/status by system | All management up to Logic - create/update/delete |
"Parent" entity | Rebate Line Item | Rebate Record |
Flow of work with PayoutRecords
The flow of the Rebates is usually following:
Design / Create Rebate Strategy (RBA)
Accrue expected payouts as time passes (RR)
Finalize accrual into customer payment (Approve RR & Create PYR)
From the diagram you can see, that the Payout Records are created only at the time of calculation (not creation) of Rebate Records.
The colors are in sync with the Data Model diagram, so you can distinguish the stages, when the Payout Record is created/updated and when it’s exported out to external system.
Figure 1. Work with Price records during 3 different stages - during creation of the Agreement, during periodic recalculations of Rebate Records and when the Rebate Record get’s approved.
Data Model
Payout Records are associated with the Rebate Records. So the Payout Record is not a "replacement" of the Rebate Record, but rather a solution, how to store fine-grained information calculated in the context of the Rebate Record.
Figure 2. Relation 1:n between Rebate Agreement, Rebate Line, Rebate Record and PayoutRecord
You can also review the more detailed ERD diagram below, in which you could notice:
some fields are found in more entities - for example startDate, endDate and payoutDate - but they can have different values among the entities (i.e. RALI, RR and PYR), if you need to store more fine-grained accruals/rebates for different time periods (e.g. RALI can have validity per year, RR per quarter and PYR per month)
the PYR fields gives you a lot of flexibility in how you will use them. Only couple fields are built-in and for the rest you need to use the attributeX columns.
Figure 3. Detail of Entities used in Rebates, their fields and relations. This reflects the data in database, not the object model and it’s methods.
Types of Payout Record
Each Payout Record has a type, which gives it certain meaning - what kind of information it actually stores.
You can think about it in similar way, as RebateRecordSet can be used (for Rebate Records).
Couple examples of values used across projects in the Payout Record Type field:
"Summary"
"Detail"
"Accrual Summary"
"Accrual Detail"
"Payout"
etc.
Implementation / Configuration
Logics
You’re working with Payout Records:
only in Rebate Logic, in "Rebate Record" context
this context contains the current Rebate Record via
api.currentItem()
and this is the Rebate Record, to which the newly added PayoutRecords will be linked to
via object PayoutRecordManager which is available via binding variable
payoutRecords
.
Example 1. Code sample - Create Payout Records in the Rebate Logic (Rebate Record context)
Code Block |
---|
def rebateRecord = api.currentItem() payoutRecords.bulkLoadMode() //(1) //payoutRecords.delete() //(2) payoutRecords.add( "Payout", "${rebateRecord.id}-${productId}-${customerId}", [ startDate : rebateRecord.startDate, //(3) endDate : rebateRecord.endDate, //(3) payoutDate : rebateRecord.payoutDate, //(3) attribute1: customerId, attribute2: productId, attribute3: rebateValue, attribute4: currency, attribute5: rebatePct, attribute6: paymentPeriod, attribute7: rebateRecord.attribute2 ] ) payoutRecords.flush() //(4) |
1 | use if you’re generating huge amount of Payout Records |
2 | delete all PayoutRecords linked to the current Rebate Record. This is important, if you know, that it’s possible, that you’re going to create different set of the Payout Records during recalculation of the Rebate Record. |
3 | in this sample we are using the same dates as on the Rebate Record, but in some other use-cases you might use more granular date ranges. |
4 | when you use bulk mode, the flush() must be called once all records have been added or updated, otherwise the more recent additions and updates will not be persisted in the database. If you do not use the bulk mode, the logic will flush the data at the end anyway, so it’s not necessary to call it explicitly. |
Note |
---|
during Testing of the logic, the functions on |
Configuration
Payout Record attribute columns metadata
You can also rename and customize the PayoutRecord’s attributeX fields. Even though it’s technically not required, it’s likely a good idea, because testing in Pricefx UI will be then much easier and more obvious.
Those given field name can be also utilized by Integration Manager, when it exports the PayoutRecords, so the integration setup will be somewhat easier to read.
Since you’re doing the field’s metadata setup via Pricefx UI, remember to fetch the "Payout record attr (PYR)" metadata configuration from the partition to your project so that you can store it to Version Control.
Advanced Configuration
There’s optionally Advanced Configuration available for the Payout Records, so if you need some special settings, please refer to "Configure Payout Records" section of documentation page Payout+Records
If you’re using the Advanced Setting, remember to fetch the Advanced Option "payoutRecordsConfiguration" to your project and store in version system.
Considerations
possible important considerations which must be bear in mind
Performance
Usage of Payout Records
Depending on the project, try to estimate, how many Rebate Records you would be using. If the estimated number of Rebate Records per Agreement will go over 100, then consider using Payout Records as a data storage, otherwise you might have performance issues.
If you only need one or a few 'records' per line item, you likely do not have to consider Payout Records.
Usage of Bulk Mode in the Logic
When you’re creating thousands of PayoutRecords, it will be faster, when you use the Bulk Mode - it’s designed to speed-up storing of high amounts of Payout Records.
However, there’s some overhead needed by the Bulk Mode, so for lower amounts of Payout records, you will likely not use it. The best answer is always a test of performance with expected size of PayoutRecords.
References
Groovy API
Documentation
Knowledge Base