mirror of
https://github.com/spliit-app/spliit.git
synced 2026-02-25 00:46:13 +01:00
* Added computed expenses per balance to fix #127 * add missing import that got lost during merge * if we are in percentage mode or amount mode, the shares have to be multiplied by 100
This commit is contained in:
@@ -23,48 +23,56 @@ export function getTotalActiveUserPaidFor(
|
||||
)
|
||||
}
|
||||
|
||||
type Expense = NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>[number]
|
||||
|
||||
export function calculateShare(
|
||||
participantId: string | null,
|
||||
expense: Pick<
|
||||
Expense,
|
||||
'amount' | 'paidFor' | 'splitMode' | 'isReimbursement'
|
||||
>,
|
||||
): number {
|
||||
if (expense.isReimbursement) return 0
|
||||
|
||||
const paidFors = expense.paidFor
|
||||
const userPaidFor = paidFors.find(
|
||||
(paidFor) => paidFor.participant.id === participantId,
|
||||
)
|
||||
|
||||
if (!userPaidFor) return 0
|
||||
|
||||
const shares = Number(userPaidFor.shares)
|
||||
|
||||
switch (expense.splitMode) {
|
||||
case 'EVENLY':
|
||||
// Divide the total expense evenly among all participants
|
||||
return expense.amount / paidFors.length
|
||||
case 'BY_AMOUNT':
|
||||
// Directly add the user's share if the split mode is BY_AMOUNT
|
||||
return shares
|
||||
case 'BY_PERCENTAGE':
|
||||
// Calculate the user's share based on their percentage of the total expense
|
||||
return (expense.amount * shares) / 10000 // Assuming shares are out of 10000 for percentage
|
||||
case 'BY_SHARES':
|
||||
// Calculate the user's share based on their shares relative to the total shares
|
||||
const totalShares = paidFors.reduce(
|
||||
(sum, paidFor) => sum + Number(paidFor.shares),
|
||||
0,
|
||||
)
|
||||
return (expense.amount * shares) / totalShares
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
export function getTotalActiveUserShare(
|
||||
activeUserId: string | null,
|
||||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>,
|
||||
): number {
|
||||
let total = 0
|
||||
|
||||
expenses.forEach((expense) => {
|
||||
if (expense.isReimbursement) return
|
||||
|
||||
const paidFors = expense.paidFor
|
||||
const userPaidFor = paidFors.find(
|
||||
(paidFor) => paidFor.participant.id === activeUserId,
|
||||
)
|
||||
|
||||
if (!userPaidFor) {
|
||||
// If the active user is not involved in the expense, skip it
|
||||
return
|
||||
}
|
||||
|
||||
switch (expense.splitMode) {
|
||||
case 'EVENLY':
|
||||
// Divide the total expense evenly among all participants
|
||||
total += expense.amount / paidFors.length
|
||||
break
|
||||
case 'BY_AMOUNT':
|
||||
// Directly add the user's share if the split mode is BY_AMOUNT
|
||||
total += userPaidFor.shares
|
||||
break
|
||||
case 'BY_PERCENTAGE':
|
||||
// Calculate the user's share based on their percentage of the total expense
|
||||
total += (expense.amount * userPaidFor.shares) / 10000 // Assuming shares are out of 10000 for percentage
|
||||
break
|
||||
case 'BY_SHARES':
|
||||
// Calculate the user's share based on their shares relative to the total shares
|
||||
const totalShares = paidFors.reduce(
|
||||
(sum, paidFor) => sum + paidFor.shares,
|
||||
0,
|
||||
)
|
||||
total += (expense.amount * userPaidFor.shares) / totalShares
|
||||
break
|
||||
}
|
||||
})
|
||||
const total = expenses.reduce(
|
||||
(sum, expense) => sum + calculateShare(activeUserId, expense),
|
||||
0,
|
||||
)
|
||||
|
||||
return parseFloat(total.toFixed(2))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user