'use client' import Link from 'next/link' import { useTranslations } from 'next-intl' import { Badge } from '@/components/ui/badge' import { Info } from 'lucide-react' import JournalEntryStatusBadge from '@/components/bookkeeping/JournalEntryStatusBadge' import { formatDate } from '@/lib/utils' import { formatVoucher } from '@/lib/bookkeeping/voucher-series-resolver' import type { JournalEntry, JournalEntryLine } from '@/types' interface Props { currentEntryId: string chain: JournalEntry[] } function useGetRole() { const t = useTranslations('journal_correction') return (entry: JournalEntry): { label: string; color: string } => { if (entry.source_type === 'storno') { return { label: t('role_storno'), color: 'bg-destructive' } } if (entry.source_type === 'correction') { return { label: t('role_correction'), color: 'bg-primary' } } return { label: t('role_original'), color: 'bg-muted-foreground' } } } function getTotal(entry: JournalEntry): number { const lines = (entry.lines || []) as JournalEntryLine[] return lines.reduce((sum, l) => sum + (Number(l.debit_amount) || 0), 0) } export default function CorrectionChain({ currentEntryId, chain }: Props) { const t = useTranslations('journal_correction') const getRole = useGetRole() if (chain.length === 0) return null // Combine current entry isn't in chain — chain is "other" entries // Sort chronologically const sorted = [...chain].sort( (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime() ) return (

{t('title')}

{t('info')}

{/* Vertical line connecting nodes */}
{sorted.map((entry) => { const role = getRole(entry) const total = getTotal(entry) const isCurrent = entry.id === currentEntryId // A cancelled entry is residue from an aborted correction attempt: // it was voided before taking effect and its lines were removed, so // it always sums to 0,00. Without the status badge it renders // exactly like a live storno — dim it and say what it is. const isCancelled = entry.status === 'cancelled' return (
{/* Timeline dot */}
{role.label} {formatVoucher(entry)} {formatDate(entry.entry_date)} {isCurrent && ( {t('current')} )} {total.toLocaleString('sv-SE', { minimumFractionDigits: 2 })} kr
{entry.description && (

{entry.description}

)}
) })}
) }