'use client' import { useState } from 'react' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { formatCurrency } from '@/lib/utils' import { Building2, Calendar, FileText, CheckCircle, AlertCircle, XCircle, ArrowRight, BarChart3, Info, } from 'lucide-react' import type { ImportPreview, ParseIssue } from '@/lib/import/types' interface SIEPreviewStepProps { preview: ImportPreview issues: ParseIssue[] missingAccounts: { number: string; name: string }[] onCreateAccounts: () => Promise isCreatingAccounts: boolean onContinue: () => void onBack: () => void } export default function SIEPreviewStep({ preview, issues, missingAccounts, onCreateAccounts, isCreatingAccounts, onContinue, onBack, }: SIEPreviewStepProps) { const errors = issues.filter((i) => i.severity === 'error') const warnings = issues.filter((i) => i.severity === 'warning') // Opening-balance imbalance. The importer plugs any diff > 0.01 to 2099, but a // diff under ~1 SEK is genuine öresavrundning. Anything larger is a real // imbalance (incomplete export: missing liabilities / unappropriated prior-year // result) that would silently book a bogus amount to 2099. Mirrors the importer's // own `fileImbalance > 1.00` "serious" threshold (lib/import/sie-import.ts). const ibDiff = Math.round((preview.trialBalance.totalDebit - preview.trialBalance.totalCredit) * 100) / 100 const significantImbalance = !preview.trialBalance.isBalanced && Math.abs(ibDiff) > 1 const [ackImbalance, setAckImbalance] = useState(false) // Only block on actual parsing errors, not unmapped accounts // (users need to proceed to mapping step to fix unmapped accounts). // A significant IB imbalance is a soft block: the user must acknowledge it. const hasBlockingErrors = errors.length > 0 const blockContinue = hasBlockingErrors || (significantImbalance && !ackImbalance) return (
{/* Company info */} Företagsinformation Information från SIE-filen

Företagsnamn

{preview.companyName || 'Ej angivet'}

Organisationsnummer

{preview.orgNumber || 'Ej angivet'}

{/* Fiscal year */} Räkenskapsår

Start

{preview.fiscalYearStart ?? 'Okänt'}

Slut

{preview.fiscalYearEnd ?? 'Okänt'}

{/* Statistics */}
Konton

{preview.accountCount}

Verifikationer

{preview.voucherCount}

Transaktionsrader

{preview.transactionLineCount}

IB Summa

{formatCurrency(preview.openingBalanceTotal)}

{/* Trial balance check */} {preview.trialBalance.isBalanced ? ( ) : ( )} Balansräkning (IB)

Total debet

{formatCurrency(preview.trialBalance.totalDebit)}

Total kredit

{formatCurrency(preview.trialBalance.totalCredit)}

Status

{preview.trialBalance.isBalanced ? ( Balanserar ) : ( Diff: {formatCurrency(ibDiff)} )}
{/* Significant imbalance: explain + require acknowledgement before continuing */} {significantImbalance && (

Ingående balanser balanserar inte ({formatCurrency(Math.abs(ibDiff))})

Det betyder oftast att exporten från ditt bokföringssystem är ofullständig: t.ex. att skulder saknas eller att föregående års resultat inte är disponerat. Om du fortsätter bokförs differensen på konto 2099 (Årets resultat), vilket nästan alltid blir fel. Vi rekommenderar att du rättar exporten i källsystemet och laddar upp filen på nytt.

)}
{/* Mapping status */} 0 ? 'border-destructive/50' : preview.mappingStatus.lowConfidence > 0 ? 'border-warning/50' : 'border-success/50' } > {preview.mappingStatus.unmapped > 0 ? ( ) : preview.mappingStatus.lowConfidence > 0 ? ( ) : ( )} Kontomappning Hur väl kunde kontona i filen matchas mot din kontoplan

Totalt

{preview.mappingStatus.total}

Mappade

{preview.mappingStatus.mapped}

Ej mappade

0 ? 'text-destructive' : ''}`}> {preview.mappingStatus.unmapped}

Osäkra

0 ? 'text-warning' : ''}`}> {preview.mappingStatus.lowConfidence}

{/* Excluded system accounts info */} {preview.excludedSystemAccounts.length > 0 && (
{preview.excludedSystemAccounts.length} internt systemkonto från källsystemet exkluderades ({preview.excludedSystemAccounts.map((a) => a.number).join(', ')}), inte bokföringskonton
)} {/* Create missing accounts */} {missingAccounts.length > 0 ? ( Skapa saknade konton {missingAccounts.length} konton från SIE-filen finns inte i din kontoplan ännu. Klicka nedan för att skapa dem: de kopplas sedan automatiskt i nästa steg.
{missingAccounts.slice(0, 10).map((acc) => (
{acc.number} {acc.name}
))} {missingAccounts.length > 10 && (
... och {missingAccounts.length - 10} till
)}
) : preview.mappingStatus.mapped === preview.mappingStatus.total && preview.mappingStatus.total > 0 && (
Alla konton skapade och automatiskt kopplade
)} {/* Errors */} {errors.length > 0 && ( Tolkningsfel ({errors.length}) Dessa fel hittades under tolkningen av SIE-filen och kan påverka importresultatet.
{errors.map((issue, i) => (
Rad {issue.line}{' '} {issue.message}
))}
)} {/* Warnings */} {warnings.length > 0 && ( Varningar ({warnings.length}) Dessa varningar blockerar inte importen men bör granskas.
{warnings.map((issue, i) => (
Rad {issue.line}{' '} {issue.message}
))}
)} {/* Actions */}
) }