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
+23 -4
View File
@@ -63,6 +63,12 @@ export function InvoicePreviewCard({ settings }: InvoicePreviewCardProps) {
if (customerError) throw customerError
if (cancelled) return
// Non-momsregistrerade säljare ska inte få en exempel-rad med 25 %
// VAT — förhandsvisningen är hårdkodad sample-data, inte ett val
// användaren gjort, så vi följer settings.vat_registered direkt här
// (till skillnad från /invoices/new som låter användaren välja och
// bara varnar vid submit).
const previewVatRate = settings.vat_registered === false ? 0 : 25
const response = await fetch('/api/invoices/preview-pdf', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -77,7 +83,7 @@ export function InvoicePreviewCard({ settings }: InvoicePreviewCardProps) {
quantity: 1,
unit: 'st',
unit_price: 1000,
vat_rate: 25,
vat_rate: previewVatRate,
},
],
}),
@@ -147,11 +153,24 @@ export function InvoicePreviewCard({ settings }: InvoicePreviewCardProps) {
)}
{!isLoading && !error && blobUrl && (
<iframe
src={blobUrl}
// <object> + type="application/pdf" invokes Chrome's PDF plugin
// directly. <iframe> went through Chrome's frame pipeline first
// and intermittently surfaced "Det här innehållet har blockerats"
// even with a permissive CSP. See AttachmentPreviewSheet.tsx for
// the same workaround on journal entry attachments.
<object
data={blobUrl}
type="application/pdf"
title={t('iframe_title')}
className="w-full h-[70vh] rounded-lg border border-border"
/>
>
<p className="p-4 text-sm text-muted-foreground">
{t('error')}:{' '}
<a href={blobUrl} target="_blank" rel="noreferrer" className="underline">
{t('iframe_title')}
</a>
</p>
</object>
)}
</DialogContent>
</Dialog>
@@ -15,7 +15,7 @@ import { Loader2 } from 'lucide-react'
import { getErrorMessage } from '@/lib/errors/get-error-message'
import type { CompanySettings, JournalEntrySourceType } from '@/types'
const SERIES_OPTIONS = 'ABCDEFG'.split('')
const SERIES_OPTIONS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
// Subset of source_types presented to the user. The DB column accepts every
// JournalEntrySourceType, but several values (storno, correction, etc.) are