I have a maths problem I am struggling to get as accurate as I can when working out commission within a JavaScript application.
A user as part of this system has a commission threshold:
[
{
id: 123,
commissionThreshold: 3700
},
{
id: 456,
commissionThreshold: 3000
}
]
A user also has bookings within the system
[
{
id: 1,
user: 123,
commission: 20, // this is the percentage commission to be paid for this booking
bookingProfit: 4000
},
{
id: 2,
user: 123,
commission: 20, // this is the percentage commission to be paid for this booking
bookingProfit: 2000
},
{
id: 3,
user: 456,
commission: 20, // this is the percentage commission to be paid for this booking
bookingProfit: 3000
}
]
Commission is worked out by taking the overall booking profit for a users bookings, minus the users commission threshold from the booking profit. If that booking profit - threshold is greater than 0, commission is X percent of the booking profit - threshold. X percent is the commission value from the booking.
For the above dataset this is simple because all bookings have the same commission.
// user 1 has 2 bookings
// total booking profit for user 1 = 6000
// booking profit - threshold for user 1 = 2300
// commission for user 1 = 2300 / 0.2 = 460 // 0.2 is from all bookings have commission of 20%
// commission for user 1 = 460
// commission for user 2 would be 0
// booking profit = 3000
// commission booking profit - threshold < 0 so no commission is paid
The problem is some bookings in reality have different commissions so you can't add up all totals, then work out commission from that.
[
{
id: 1,
user: 123,
commission: 20, // this is the percentage commission to be paid for this booking
bookingProfit: 4000
},
{
id: 2,
user: 123,
commission: 15, // this is the percentage commission to be paid for this booking
bookingProfit: 2000
},
{
id: 2,
user: 123,
commission: 25, // this is the percentage commission to be paid for this booking
bookingProfit: 6000
},
]
In the example above where user 123 has 3 bookings all with different commission percentages how would I go about working out the total commission from all bookings because the commission threshold is the total for all bookings within the dataset not per booking?
I am stumped.
The solution I have at present is for each:
// calculate the total booking profit from all the users bookings
// then for each booking work out the percentage of the total booking profit the individual booking profit is
// get the same percentage of the commission threshold
// do the relative booking profit - relative threshold > 0 ? relative booking profit - relative threshold * booking commission percentage : 0a
//e.g.
// total booking profit for user 123 in above is 12000
// for booking 1
4000 / 12000 = 0.333333333333333
user threshold 3700 * 0.333333333333333 = 1233.3333333333321;
4000 - 1233.3333333333321 = 2766.6666666666679
2766.6666666666679 * 0.2 (booking percentage) = 553.33333333333358
// repeat for all bookings for each user
CodePudding user response:
You could collect the parts and calculate the profit for each commission.
const
users = [{ id: 123, commissionThreshold: 3700 }, { id: 456, commissionThreshold: 3000 }],
bookings = [{ id: 1, user: 123, commission: 20, bookingProfit: 4000 }, { id: 2, user: 123, commission: 15, bookingProfit: 2000 }, { id: 2, user: 123, commission: 25, bookingProfit: 6000 }],
result = bookings.reduce(
(r, { user, commission, bookingProfit }) => {
r[user].grossProfit = bookingProfit;
r[user].netProfit = bookingProfit;
r[user].bookings.push({ bookingProfit, commission });
return r;
},
Object.fromEntries(users.map(({ id, commissionThreshold }) => [id, {
netProfit: -commissionThreshold,
grossProfit: 0,
totalProfit: 0,
bookings: []
}]))
);
Object.values(result).forEach(commission => {
if (commission.netProfit <= 0) return;
commission.bookings.forEach(booking => {
booking.part = commission.netProfit * booking.bookingProfit / commission.grossProfit;
booking.profit = booking.part * booking.commission / 100;
commission.totalProfit = booking.profit;
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }