feat: add 4 new Swedish bank CSV parsers and improve transaction categorization
Add auto-detecting CSV parsers for Länsförsäkringar, ICA Banken, Skandia, and Lunar. Refine SEB detection to avoid false matches. Update bank file upload UI with new bank options and export instructions. Include booking templates, improved AI categorization, and transaction review enhancements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
431f385b4b
commit
bbb82866ee
@@ -3,6 +3,7 @@ import { NextResponse } from 'next/server'
|
||||
import { eventBus } from '@/lib/events'
|
||||
import { ensureInitialized } from '@/lib/init'
|
||||
import { buildMappingResultFromCategory } from '@/lib/bookkeeping/category-mapping'
|
||||
import { getTemplateById, buildMappingResultFromTemplate } from '@/lib/bookkeeping/booking-templates'
|
||||
import { createTransactionJournalEntry } from '@/lib/bookkeeping/transaction-entries'
|
||||
import { saveUserMappingRule } from '@/lib/bookkeeping/mapping-engine'
|
||||
import { validateBody } from '@/lib/api/validate'
|
||||
@@ -153,18 +154,36 @@ export async function POST(
|
||||
const fiscalYearStartMonth: number = settings?.fiscal_year_start_month ?? 1
|
||||
|
||||
// Determine the category to use
|
||||
const finalCategory: TransactionCategory = is_business
|
||||
? (category || 'uncategorized')
|
||||
: 'private'
|
||||
let finalCategory: TransactionCategory
|
||||
if (body.template_id) {
|
||||
const template = getTemplateById(body.template_id)
|
||||
if (template) {
|
||||
finalCategory = is_business ? template.fallback_category : 'private'
|
||||
} else {
|
||||
return NextResponse.json({ error: 'Invalid template_id' }, { status: 400 })
|
||||
}
|
||||
} else {
|
||||
finalCategory = is_business ? (category || 'uncategorized') : 'private'
|
||||
}
|
||||
|
||||
// Build mapping result from category
|
||||
const mappingResult = buildMappingResultFromCategory(
|
||||
finalCategory,
|
||||
transaction as Transaction,
|
||||
is_business,
|
||||
entityType,
|
||||
body.vat_treatment
|
||||
)
|
||||
// Build mapping result from template or category
|
||||
let mappingResult
|
||||
if (body.template_id) {
|
||||
const template = getTemplateById(body.template_id)!
|
||||
mappingResult = buildMappingResultFromTemplate(
|
||||
template,
|
||||
transaction as Transaction,
|
||||
entityType
|
||||
)
|
||||
} else {
|
||||
mappingResult = buildMappingResultFromCategory(
|
||||
finalCategory,
|
||||
transaction as Transaction,
|
||||
is_business,
|
||||
entityType,
|
||||
body.vat_treatment
|
||||
)
|
||||
}
|
||||
|
||||
// Apply account override if provided (only for business transactions)
|
||||
if (is_business && body.account_override) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createClient } from '@/lib/supabase/server'
|
||||
import { NextResponse } from 'next/server'
|
||||
import { getSuggestedCategories, mergeAiSuggestions, type SuggestedCategory } from '@/lib/transactions/category-suggestions'
|
||||
import type { Transaction, TransactionCategory } from '@/types'
|
||||
import { getSuggestedCategories, mergeAiSuggestions, getSuggestedTemplates, type SuggestedCategory, type SuggestedTemplate } from '@/lib/transactions/category-suggestions'
|
||||
import type { Transaction, TransactionCategory, EntityType } from '@/types'
|
||||
|
||||
/**
|
||||
* POST /api/transactions/suggest-categories
|
||||
@@ -78,8 +78,17 @@ export async function POST(request: Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch entity type for template matching
|
||||
const { data: settings } = await supabase
|
||||
.from('company_settings')
|
||||
.select('entity_type')
|
||||
.eq('user_id', user.id)
|
||||
.single()
|
||||
const entityType = (settings?.entity_type as EntityType) || undefined
|
||||
|
||||
// Generate suggestions for each transaction
|
||||
const suggestions: Record<string, SuggestedCategory[]> = {}
|
||||
const template_suggestions: Record<string, SuggestedTemplate[]> = {}
|
||||
|
||||
for (const tx of transactions) {
|
||||
let result = getSuggestedCategories(
|
||||
@@ -95,7 +104,8 @@ export async function POST(request: Request) {
|
||||
}
|
||||
|
||||
suggestions[tx.id] = result
|
||||
template_suggestions[tx.id] = getSuggestedTemplates(tx as Transaction, entityType)
|
||||
}
|
||||
|
||||
return NextResponse.json({ suggestions })
|
||||
return NextResponse.json({ suggestions, template_suggestions })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user