'use client' import { Badge } from '@/components/ui/badge' import { Separator } from '@/components/ui/separator' import { AccountNumber } from '@/components/ui/account-number' import { formatCurrency } from '@/lib/utils' import type { Supplier } from '@/types' interface ReviewLineItem { description: string amount: number account_number: string vat_rate: number } interface SupplierInvoiceReviewContentProps { supplier: Supplier invoiceNumber: string invoiceDate: string dueDate: string deliveryDate?: string currency: string exchangeRate?: string reverseCharge: boolean paymentReference?: string items: ReviewLineItem[] subtotal: number totalVat: number total: number } function formatAmount(amount: number): string { return amount.toLocaleString('sv-SE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) } interface JournalPreviewLine { account_number: string description: string debit: number credit: number } function buildJournalPreview( items: ReviewLineItem[], subtotal: number, totalVat: number, total: number, reverseCharge: boolean, ): JournalPreviewLine[] { const lines: JournalPreviewLine[] = [] // Aggregate expense amounts by account number const expenseByAccount = new Map() for (const item of items) { const current = expenseByAccount.get(item.account_number) || 0 expenseByAccount.set(item.account_number, current + Math.round(item.amount * 100) / 100) } // Debit: Expense accounts for (const [accountNumber, amount] of expenseByAccount) { lines.push({ account_number: accountNumber, description: accountNumber, debit: Math.round(amount * 100) / 100, credit: 0, }) } if (reverseCharge) { // EU reverse charge: fiktiv moms const vatRate = 0.25 const fiktivVat = Math.round(subtotal * vatRate * 100) / 100 lines.push({ account_number: '2645', description: 'Beräknad ingående moms', debit: fiktivVat, credit: 0, }) lines.push({ account_number: '2614', description: 'Utgående moms omvänd', debit: 0, credit: fiktivVat, }) // Credit: 2440 at subtotal (no real VAT for reverse charge) lines.push({ account_number: '2440', description: 'Leverantörsskulder', debit: 0, credit: Math.round(subtotal * 100) / 100, }) } else { if (totalVat > 0) { lines.push({ account_number: '2641', description: 'Ingående moms', debit: Math.round(totalVat * 100) / 100, credit: 0, }) } // Credit: 2440 at total incl. VAT lines.push({ account_number: '2440', description: 'Leverantörsskulder', debit: 0, credit: Math.round(total * 100) / 100, }) } return lines } const ACCOUNT_LABELS: Record = { '2440': 'Leverantörsskulder', '2641': 'Ingående moms', '2645': 'Beräknad ingående moms', '2614': 'Utg. moms omvänd skattskyldighet', } export function SupplierInvoiceReviewContent({ supplier, invoiceNumber, invoiceDate, dueDate, deliveryDate, currency, exchangeRate, reverseCharge, paymentReference, items, subtotal, totalVat, total, }: SupplierInvoiceReviewContentProps) { const journalLines = buildJournalPreview(items, subtotal, totalVat, total, reverseCharge) const totalDebit = journalLines.reduce((sum, l) => sum + l.debit, 0) const totalCredit = journalLines.reduce((sum, l) => sum + l.credit, 0) return (
{/* Supplier info */}

{supplier.name}

Fakturanr: {invoiceNumber}

{reverseCharge && ( Omvänd skattskyldighet )} {currency !== 'SEK' && ( {currency} {exchangeRate && ` (kurs ${exchangeRate})`} )}
{/* Dates */}
Fakturadatum

{invoiceDate}

Förfallodatum

{dueDate}

{deliveryDate && (
Leveransdatum

{deliveryDate}

)}
{/* Line items table */} {items.map((item, index) => { const vatAmount = Math.round(item.amount * item.vat_rate * 100) / 100 return ( ) })}
Konto Beskrivning Belopp Moms% Moms
{item.description} {formatAmount(item.amount)} {Math.round(item.vat_rate * 100)}% {formatAmount(vatAmount)}
{/* Totals */}
Netto (exkl. moms) {formatCurrency(subtotal, currency)}
Moms {formatCurrency(totalVat, currency)}
Totalt {formatCurrency(total, currency)}
{currency !== 'SEK' && exchangeRate && (
SEK-belopp (vid kurs {exchangeRate}) {formatCurrency(total * parseFloat(exchangeRate))}
)}
{/* Verifikation preview */}

Verifikation som bokförs

{journalLines.map((line, index) => ( ))}
Konto Beskrivning Debet Kredit
{ACCOUNT_LABELS[line.account_number] || line.description} {line.debit > 0 ? formatAmount(line.debit) : ''} {line.credit > 0 ? formatAmount(line.credit) : ''}
SUMMA {formatAmount(totalDebit)} {formatAmount(totalCredit)}
{/* Payment reference */} {paymentReference && (

Betalningsreferens: {paymentReference}

)}
) }