feat: add foreign currency support, refactor bookkeeping engine, and improve invoice inbox document classification
- Add currency-utils module for SEK conversion with exchange rates - Refactor createJournalEntry to use draft+commit flow preventing voucher number gaps (BFL 5 kap. 7§) - Add foreign currency support to invoice entries with per-line SEK conversion - Centralize category-to-account mapping into single source of truth - Refactor invoice inbox to use shared document analyzer with document type classification (receipt, supplier invoice, government letter) - Update mapping engine, supplier invoice entries, and transaction entries - Fix report component rendering issues - Add new validation schemas and tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
547fd053ec
commit
6f4573f380
@@ -126,7 +126,8 @@ describe('POST /api/invoices/[id]/mark-paid', () => {
|
||||
expect.anything(),
|
||||
'user-1',
|
||||
expect.objectContaining({ id: 'inv-1' }),
|
||||
expect.any(String)
|
||||
expect.any(String),
|
||||
undefined
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
createInvoicePaymentJournalEntry,
|
||||
createInvoiceCashEntry,
|
||||
} from '@/lib/bookkeeping/invoice-entries'
|
||||
import { MarkInvoicePaidSchema } from '@/lib/api/schemas'
|
||||
import type { EntityType, Invoice } from '@/types'
|
||||
|
||||
/**
|
||||
@@ -49,8 +50,24 @@ export async function POST(
|
||||
)
|
||||
}
|
||||
|
||||
// Parse optional body (backward compatible — body may be empty)
|
||||
let exchangeRateDifference: number | undefined
|
||||
let bodyPaymentDate: string | undefined
|
||||
try {
|
||||
const text = await request.text()
|
||||
if (text) {
|
||||
const parsed = MarkInvoicePaidSchema.safeParse(JSON.parse(text))
|
||||
if (parsed.success) {
|
||||
exchangeRateDifference = parsed.data.exchange_rate_difference
|
||||
bodyPaymentDate = parsed.data.payment_date
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// No body or invalid JSON — use defaults
|
||||
}
|
||||
|
||||
const now = new Date().toISOString()
|
||||
const paymentDate = now.split('T')[0]
|
||||
const paymentDate = bodyPaymentDate || now.split('T')[0]
|
||||
|
||||
// Update status to paid
|
||||
const { error: updateError } = await supabase
|
||||
@@ -89,7 +106,8 @@ export async function POST(
|
||||
supabase,
|
||||
user.id,
|
||||
invoice as Invoice,
|
||||
paymentDate
|
||||
paymentDate,
|
||||
exchangeRateDifference
|
||||
)
|
||||
journalEntryId = journalEntry?.id ?? null
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user