diff options
| author | Sebastien Castiel <sebastien@castiel.me> | 2023-12-06 17:02:37 -0500 |
|---|---|---|
| committer | Sebastien Castiel <sebastien@castiel.me> | 2023-12-06 17:02:59 -0500 |
| commit | 12b1cdb52a9d2723c319083b45a4e9a21896b3b4 (patch) | |
| tree | 0521ab02b3a3fbab7c8955acf20da20f919b48e6 /src/lib/balances.ts | |
| parent | 72fe19987957e78cbd1d97ccfd8b87d85fea5c88 (diff) | |
Balances
Diffstat (limited to 'src/lib/balances.ts')
| -rw-r--r-- | src/lib/balances.ts | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/lib/balances.ts b/src/lib/balances.ts new file mode 100644 index 0000000..fa00640 --- /dev/null +++ b/src/lib/balances.ts @@ -0,0 +1,42 @@ +import { getGroupExpenses } from '@/lib/api' +import { Participant } from '@prisma/client' + +export type Balances = Record< + Participant['id'], + { paid: number; paidFor: number; total: number } +> + +export function getBalances( + expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>, +): Balances { + const balances: Balances = {} + + for (const expense of expenses) { + const paidBy = expense.paidById + const paidFors = expense.paidFor.map((p) => p.participantId) + + if (!balances[paidBy]) balances[paidBy] = { paid: 0, paidFor: 0, total: 0 } + balances[paidBy].paid += expense.amount + balances[paidBy].total += expense.amount + paidFors.forEach((paidFor, index) => { + if (!balances[paidFor]) + balances[paidFor] = { paid: 0, paidFor: 0, total: 0 } + + const dividedAmount = divide( + expense.amount, + paidFors.length, + index === paidFors.length - 1, + ) + balances[paidFor].paidFor += dividedAmount + balances[paidFor].total -= dividedAmount + }) + } + + return balances +} + +function divide(total: number, count: number, isLast: boolean): number { + if (!isLast) return Math.floor((total * 100) / count) / 100 + + return total - divide(total, count, false) * (count - 1) +} |
