Fix/m sprint fixes (#613)

* fix(dashboard): exclude ignored and already-triaged transactions from stale count

The "Gamla transaktioner" widget counted transactions that had been ignored
or already marked as is_business=true but not yet booked, so users saw a
nag for a row they had already dealt with — and the /transactions inbox
correctly hid it. Align the count with the inbox criterion (is_business
IS NULL, is_ignored = false) so the widget clears when the row leaves
the inbox.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(transactions): read entity_type from settings response wrapper

The transactions page read entityRes.entity_type directly, but
/api/settings returns { data: { entity_type, ... } }. The expression
was always undefined, so setEntityType never fired and entityType
stayed at its initial 'enskild_firma'. The template picker's
entity_type filter then dropped every aktiebolag-tagged user template
for AB customers — only entity_type='all' templates made it through.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* stale templates
bank sync
journal entry from transaction

* fixed pr comments

* fixed pr comment

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-05-30 01:28:41 +02:00
committed by GitHub
co-authored by Claude Opus 4.7
parent fc7a46c3f2
commit ea1bf01f1e
76 changed files with 5474 additions and 532 deletions
+17 -8
View File
@@ -133,6 +133,15 @@ export const POST = withRouteContext(
const accountingMethod = settings?.accounting_method || 'accrual'
const entityType = (settings?.entity_type as EntityType) || 'enskild_firma'
// Drive the JE shape from the invoice's actual booking state, not from
// the current accounting_method setting. If the invoice was booked at
// send (Dr 1510 / Cr 30xx + VAT), the payment MUST clear 1510 —
// otherwise the receivable orphans and 30xx + VAT double-count. Only
// when there is no prior JE (pure kontantmetoden) do we recognise
// revenue + VAT here.
const invoiceAlreadyBooked = !!(invoice as { journal_entry_id?: string | null }).journal_entry_id
const useCashEntry = !invoiceAlreadyBooked && accountingMethod === 'cash'
const isRealInvoice = !invoice.document_type || invoice.document_type === 'invoice'
let journalEntryId: string | null = null
@@ -155,7 +164,7 @@ export const POST = withRouteContext(
details: { paymentDate },
})
}
const sourceType = accountingMethod === 'accrual' ? 'invoice_paid' : 'invoice_cash_payment'
const sourceType = useCashEntry ? 'invoice_cash_payment' : 'invoice_paid'
const input: CreateJournalEntryInput = {
fiscal_period_id: fiscalPeriodId,
entry_date: paymentDate,
@@ -168,18 +177,18 @@ export const POST = withRouteContext(
}
const journalEntry = await createJournalEntry(supabase, companyId!, user.id, input)
journalEntryId = journalEntry?.id ?? null
} else if (accountingMethod === 'accrual') {
const journalEntry = await createInvoicePaymentJournalEntry(
supabase, companyId!, user.id, invoice as Invoice, paymentDate,
exchangeRateDifference, invoice.customer?.name,
)
journalEntryId = journalEntry?.id ?? null
} else {
} else if (useCashEntry) {
const journalEntry = await createInvoiceCashEntry(
supabase, companyId!, user.id, invoice as Invoice, paymentDate,
entityType, invoice.customer?.name,
)
journalEntryId = journalEntry?.id ?? null
} else {
const journalEntry = await createInvoicePaymentJournalEntry(
supabase, companyId!, user.id, invoice as Invoice, paymentDate,
exchangeRateDifference, invoice.customer?.name,
)
journalEntryId = journalEntry?.id ?? null
}
} catch (err) {
if (isBookkeepingError(err)) {