Files
accounted/lib/extensions/use-account-totals.ts
T
EmilandClaude Opus 4.6 6a5b2b7792 feat: overhaul all 12 sector extensions with full CRUD, validation, and tests
Add shared components (ConfirmDeleteDialog, EditEntryDialog, validation utils),
enhance all 12 extension workspaces with edit/delete dialogs, input validation,
period comparisons, and new analytics features. Fix critical bugs in
ProjectBilling margin calculation and EarningsPerLiter revenue allocation.
Add pure calculation modules with 183 new tests across all extensions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 15:21:49 +01:00

81 lines
2.0 KiB
TypeScript

'use client'
import { useState, useEffect, useCallback, useRef } from 'react'
interface AccountTotal {
account_number: string
debit: number
credit: number
net: number
}
interface MonthlyTotal {
month: string
account_number: string
debit: number
credit: number
net: number
}
interface UseAccountTotalsOptions {
from: string
to: string
dateFrom?: string
dateTo?: string
groupBy?: 'month'
}
export function useAccountTotals(options: UseAccountTotalsOptions) {
const [totals, setTotals] = useState<AccountTotal[]>([])
const [monthly, setMonthly] = useState<MonthlyTotal[]>([])
const [isLoading, setIsLoading] = useState(true)
const mountedRef = useRef(true)
useEffect(() => {
mountedRef.current = true
return () => { mountedRef.current = false }
}, [])
const refresh = useCallback(async () => {
setIsLoading(true)
try {
const params = new URLSearchParams({
from: options.from,
to: options.to,
})
if (options.dateFrom) params.set('date_from', options.dateFrom)
if (options.dateTo) params.set('date_to', options.dateTo)
if (options.groupBy) params.set('group_by', options.groupBy)
const res = await fetch(`/api/bookkeeping/account-totals?${params}`)
if (res.ok) {
const json = await res.json()
if (mountedRef.current) {
setTotals(json.totals ?? [])
setMonthly(json.monthly ?? [])
}
}
} finally {
if (mountedRef.current) setIsLoading(false)
}
}, [options.from, options.to, options.dateFrom, options.dateTo, options.groupBy])
useEffect(() => {
refresh()
}, [refresh])
const totalDebit = totals.reduce((sum, t) => sum + t.debit, 0)
const totalCredit = totals.reduce((sum, t) => sum + t.credit, 0)
const totalNet = totals.reduce((sum, t) => sum + t.net, 0)
return {
totals,
monthly,
isLoading,
totalDebit: Math.round(totalDebit * 100) / 100,
totalCredit: Math.round(totalCredit * 100) / 100,
totalNet: Math.round(totalNet * 100) / 100,
refresh,
}
}