mirror of
https://github.com/spliit-app/spliit.git
synced 2026-03-07 20:59:05 +01:00
Round totals rather than expense by expense (#88)
* do balance rounding only on full balances rather than on every expense * use "public balances" calculated from reimbursements to show on balance page * fixes for totals that did not work as expected * prettier
This commit is contained in:
@@ -9,7 +9,11 @@ import {
|
|||||||
CardTitle,
|
CardTitle,
|
||||||
} from '@/components/ui/card'
|
} from '@/components/ui/card'
|
||||||
import { getGroupExpenses } from '@/lib/api'
|
import { getGroupExpenses } from '@/lib/api'
|
||||||
import { getBalances, getSuggestedReimbursements } from '@/lib/balances'
|
import {
|
||||||
|
getBalances,
|
||||||
|
getPublicBalances,
|
||||||
|
getSuggestedReimbursements,
|
||||||
|
} from '@/lib/balances'
|
||||||
import { Metadata } from 'next'
|
import { Metadata } from 'next'
|
||||||
import { notFound } from 'next/navigation'
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
@@ -28,6 +32,7 @@ export default async function GroupPage({
|
|||||||
const expenses = await getGroupExpenses(groupId)
|
const expenses = await getGroupExpenses(groupId)
|
||||||
const balances = getBalances(expenses)
|
const balances = getBalances(expenses)
|
||||||
const reimbursements = getSuggestedReimbursements(balances)
|
const reimbursements = getSuggestedReimbursements(balances)
|
||||||
|
const publicBalances = getPublicBalances(reimbursements)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -40,7 +45,7 @@ export default async function GroupPage({
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<BalancesList
|
<BalancesList
|
||||||
balances={balances}
|
balances={publicBalances}
|
||||||
participants={group.participants}
|
participants={group.participants}
|
||||||
currency={group.currency}
|
currency={group.currency}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export function getBalances(
|
|||||||
|
|
||||||
if (!balances[paidBy]) balances[paidBy] = { paid: 0, paidFor: 0, total: 0 }
|
if (!balances[paidBy]) balances[paidBy] = { paid: 0, paidFor: 0, total: 0 }
|
||||||
balances[paidBy].paid += expense.amount
|
balances[paidBy].paid += expense.amount
|
||||||
balances[paidBy].total += expense.amount
|
|
||||||
|
|
||||||
const totalPaidForShares = paidFors.reduce(
|
const totalPaidForShares = paidFors.reduce(
|
||||||
(sum, paidFor) => sum + paidFor.shares,
|
(sum, paidFor) => sum + paidFor.shares,
|
||||||
@@ -46,13 +45,40 @@ export function getBalances(
|
|||||||
|
|
||||||
const dividedAmount = isLast
|
const dividedAmount = isLast
|
||||||
? remaining
|
? remaining
|
||||||
: Math.floor((expense.amount * shares) / totalShares)
|
: (expense.amount * shares) / totalShares
|
||||||
remaining -= dividedAmount
|
remaining -= dividedAmount
|
||||||
balances[paidFor.participantId].paidFor += dividedAmount
|
balances[paidFor.participantId].paidFor += dividedAmount
|
||||||
balances[paidFor.participantId].total -= dividedAmount
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rounding and add total
|
||||||
|
for (const participantId in balances) {
|
||||||
|
// add +0 to avoid negative zeros
|
||||||
|
balances[participantId].paidFor =
|
||||||
|
Math.round(balances[participantId].paidFor) + 0
|
||||||
|
balances[participantId].paid = Math.round(balances[participantId].paid) + 0
|
||||||
|
|
||||||
|
balances[participantId].total =
|
||||||
|
balances[participantId].paid - balances[participantId].paidFor
|
||||||
|
}
|
||||||
|
return balances
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicBalances(reimbursements: Reimbursement[]): Balances {
|
||||||
|
const balances: Balances = {}
|
||||||
|
reimbursements.forEach((reimbursement) => {
|
||||||
|
if (!balances[reimbursement.from])
|
||||||
|
balances[reimbursement.from] = { paid: 0, paidFor: 0, total: 0 }
|
||||||
|
|
||||||
|
if (!balances[reimbursement.to])
|
||||||
|
balances[reimbursement.to] = { paid: 0, paidFor: 0, total: 0 }
|
||||||
|
|
||||||
|
balances[reimbursement.from].paidFor += reimbursement.amount
|
||||||
|
balances[reimbursement.from].total -= reimbursement.amount
|
||||||
|
|
||||||
|
balances[reimbursement.to].paid += reimbursement.amount
|
||||||
|
balances[reimbursement.to].total += reimbursement.amount
|
||||||
|
})
|
||||||
return balances
|
return balances
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,5 +112,5 @@ export function getSuggestedReimbursements(
|
|||||||
balancesArray.shift()
|
balancesArray.shift()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reimbursements.filter(({ amount }) => amount !== 0)
|
return reimbursements.filter(({ amount }) => Math.round(amount) + 0 !== 0)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user