mirror of
https://github.com/vas3k/TaxHacker.git
synced 2026-01-09 15:12:18 -06:00
- Add calcNetTotalPerCurrency function to calculate signed totals (income positive, expenses negative) - Update transaction list footer to display both net total and turnover - Use semantic HTML markup (<dl>, <dt>, <dd>) for better accessibility - Add color coding: green for positive net, red for negative net - Maintain turnover calculation for total transaction volume Fixes issue where transaction totals did not respect transaction type (income/expense)
62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import { Field, Transaction } from "@/prisma/client"
|
|
|
|
export function calcTotalPerCurrency(transactions: Transaction[]): Record<string, number> {
|
|
return transactions.reduce(
|
|
(acc, transaction) => {
|
|
if (transaction.convertedCurrencyCode) {
|
|
acc[transaction.convertedCurrencyCode.toUpperCase()] =
|
|
(acc[transaction.convertedCurrencyCode.toUpperCase()] || 0) + (transaction.convertedTotal || 0)
|
|
} else if (transaction.currencyCode) {
|
|
acc[transaction.currencyCode.toUpperCase()] =
|
|
(acc[transaction.currencyCode.toUpperCase()] || 0) + (transaction.total || 0)
|
|
}
|
|
return acc
|
|
},
|
|
{} as Record<string, number>
|
|
)
|
|
}
|
|
|
|
export function calcNetTotalPerCurrency(transactions: Transaction[]): Record<string, number> {
|
|
return transactions.reduce(
|
|
(acc, transaction) => {
|
|
let amount = 0
|
|
let currency: string | undefined
|
|
if (
|
|
transaction.convertedTotal !== null &&
|
|
transaction.convertedTotal !== undefined &&
|
|
transaction.convertedCurrencyCode
|
|
) {
|
|
amount = transaction.convertedTotal
|
|
currency = transaction.convertedCurrencyCode.toUpperCase()
|
|
} else if (transaction.total !== null && transaction.total !== undefined && transaction.currencyCode) {
|
|
amount = transaction.total
|
|
currency = transaction.currencyCode.toUpperCase()
|
|
}
|
|
if (currency && amount !== 0) {
|
|
const sign = transaction.type === "expense" ? -1 : 1
|
|
acc[currency] = (acc[currency] || 0) + amount * sign
|
|
}
|
|
return acc
|
|
},
|
|
{} as Record<string, number>
|
|
)
|
|
}
|
|
|
|
export const isTransactionIncomplete = (fields: Field[], transaction: Transaction): boolean => {
|
|
const incompleteFields = incompleteTransactionFields(fields, transaction)
|
|
|
|
return incompleteFields.length > 0
|
|
}
|
|
|
|
export const incompleteTransactionFields = (fields: Field[], transaction: Transaction): Field[] => {
|
|
const requiredFields = fields.filter((field) => field.isRequired)
|
|
|
|
return requiredFields.filter((field) => {
|
|
const value = field.isExtra
|
|
? (transaction.extra as Record<string, any>)?.[field.code]
|
|
: transaction[field.code as keyof Transaction]
|
|
|
|
return value === undefined || value === null || value === ""
|
|
})
|
|
}
|