aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/balances.ts
diff options
context:
space:
mode:
authorSebastien Castiel <sebastien@castiel.me>2023-12-06 17:02:37 -0500
committerSebastien Castiel <sebastien@castiel.me>2023-12-06 17:02:59 -0500
commit12b1cdb52a9d2723c319083b45a4e9a21896b3b4 (patch)
tree0521ab02b3a3fbab7c8955acf20da20f919b48e6 /src/lib/balances.ts
parent72fe19987957e78cbd1d97ccfd8b87d85fea5c88 (diff)
Balances
Diffstat (limited to 'src/lib/balances.ts')
-rw-r--r--src/lib/balances.ts42
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)
+}