diff --git a/app/(dashboard)/invoices/page.tsx b/app/(dashboard)/invoices/page.tsx index f21360c3..4357fbbf 100644 --- a/app/(dashboard)/invoices/page.tsx +++ b/app/(dashboard)/invoices/page.tsx @@ -47,6 +47,7 @@ import { FileInput, FileDown, FileText, + FileClock, } from 'lucide-react' import { StartCard } from '@/components/dashboard/StartCard' import { useCompany } from '@/contexts/CompanyContext' @@ -246,8 +247,12 @@ export default function InvoicesPage() { const copyFromId = searchParams.get('copy') const showNewInvoice = searchParams.has('new') || copyFromId !== null const openSelfBilled = searchParams.has('self') - // ?quote=1 preselects the offert document type ("Ny offert" split entry). + // ?quote=1 preselects the offert document type ("Ny offert" split entry); + // ?proforma=1 the proforma type ("Ny proformafaktura" split entry, #2217: + // proforma existed but only behind the collapsed Förval panel inside the + // editor, so a user coming from Fortnox concluded it did not exist). const openQuote = searchParams.has('quote') + const openProforma = searchParams.has('proforma') const showRotRutPayout = searchParams.has('rot-rut') // Open/close handlers rewrite only their own keys: a hardcoded '/invoices' // would destroy the ?status= view write-back (and any other params) every @@ -264,6 +269,7 @@ export default function InvoicesPage() { p.delete('new') p.delete('self') p.delete('quote') + p.delete('proforma') p.delete('copy') }), { scroll: false }, @@ -286,6 +292,14 @@ export default function InvoicesPage() { }), { scroll: false }, ) + const openNewProforma = () => + router.push( + invoicesUrl((p) => { + p.set('new', '1') + p.set('proforma', '1') + }), + { scroll: false }, + ) const closeRotRutPayout = () => router.replace(invoicesUrl((p) => p.delete('rot-rut')), { scroll: false }) const openRotRutPayout = () => @@ -527,6 +541,15 @@ export default function InvoicesPage() { disabledTitle: t('viewer_disabled_tooltip'), onSelect: () => openNewQuote(), }, + { + key: 'proforma', + label: t('create_proforma'), + icon: FileClock, + description: t('create_proforma_desc'), + disabled: !canWrite, + disabledTitle: t('viewer_disabled_tooltip'), + onSelect: () => openNewProforma(), + }, { key: 'aterkommande', label: t('create_recurring'), @@ -929,7 +952,7 @@ export default function InvoicesPage() { open copyFromId={copyFromId} selfBilled={openSelfBilled} - documentType={openQuote ? 'quote' : undefined} + documentType={openQuote ? 'quote' : openProforma ? 'proforma' : undefined} onOpenChange={(open) => { if (!open) closeNewInvoice() }} diff --git a/components/invoices/NewInvoiceDialog.tsx b/components/invoices/NewInvoiceDialog.tsx index 8b26e977..b4b86b13 100644 --- a/components/invoices/NewInvoiceDialog.tsx +++ b/components/invoices/NewInvoiceDialog.tsx @@ -30,7 +30,7 @@ interface Props { copyFromId?: string | null /** Preselect the självfaktura tab (split-button entry on /invoices). */ selfBilled?: boolean - /** Preselect a document type, e.g. 'quote' ("Ny offert" split-button entry). */ + /** Preselect a document type: 'quote' ("Ny offert") or 'proforma' ("Ny proformafaktura") split-button entries. */ documentType?: InvoiceDocumentType } @@ -146,7 +146,9 @@ export default function NewInvoiceDialog({ ? t('title_copy') : documentType === 'quote' && !selfBilled ? t('title_quote') - : t('title_invoice')} + : documentType === 'proforma' && !selfBilled + ? t('title_proforma') + : t('title_invoice')} {copyFromId ? ( copyLoadFailed ? ( diff --git a/messages/en.json b/messages/en.json index 6fdbf82f..dfb9ef9e 100644 --- a/messages/en.json +++ b/messages/en.json @@ -6465,6 +6465,8 @@ "create_self_desc": "Register a self-billing invoice from your customer", "create_quote": "New quote", "create_quote_desc": "Create a quote that can become an invoice", + "create_proforma": "New proforma invoice", + "create_proforma_desc": "Advance invoice that is not booked and can become a real invoice", "bulkbar_selected": "{count, plural, one {invoice selected} other {invoices selected}}", "bulk_select_all": "Select all ({count})", "bulk_clear": "Clear", diff --git a/messages/sv.json b/messages/sv.json index f65a7f92..b92121c0 100644 --- a/messages/sv.json +++ b/messages/sv.json @@ -6465,6 +6465,8 @@ "create_self_desc": "Registrera en självfaktura från din kund", "create_quote": "Ny offert", "create_quote_desc": "Skapa en offert som kan bli en faktura", + "create_proforma": "Ny proformafaktura", + "create_proforma_desc": "Förhandsfaktura som inte bokförs och kan bli en riktig faktura", "bulkbar_selected": "{count, plural, one {faktura vald} other {fakturor valda}}", "bulk_select_all": "Markera alla ({count})", "bulk_clear": "Rensa",