feat(webshop): generate orderunderlag and attach it to the verifikat at booking (#1899)
* feat(webshop): generate orderunderlag PDF and attach it to the verifikat at booking Booked webshop orders only carried the VAT split; the verifikat showed no product lines, customer or payment method although the sync already stores all of it in webshop_orders.line_items (#1881). - lib/webshop-orders/order-underlag.tsx: pure model builder + react-pdf template (order lines, customer, payment method, per-rate VAT summary, SEK conversion facts) + archiveWebshopOrderUnderlag, which renders and archives the PDF on the committed verifikat through uploadDocument (upload_source system, extraction none), mirroring archiveIssuedInvoicePdf. Never throws: the booking is immutable by then. - book route: archive after commitEntry; response gains underlag_archived. FX-retry now also syncs the in-memory row so the underlag shows the resolved SEK facts. - webshop_order added to NEEDS_DOC_SOURCE_TYPES and (new migration 20260825140000) to the verifikat_without_documents needs-doc list, so a failed attach or a historical booking surfaces on the saknar-underlag worklist. transactions_without_documents is deliberately unchanged. - tests: underlag model/render/archive unit tests, book-route archive and failure-isolation cases, pg test extended (per-source-type probe now covers webshop_order; explicit flagged/silenced pair). Fixes #1881 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(migrations): move webshop needs-doc migration after main's 20260825150000 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(webshop): add manually_booked fields to the underlag order fixture Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(webshop): skeptic findings on the orderunderlag (#1881) Two refutations from the skeptic pass on PR #1899, both fixed: 1. Correctness: sv-SE Intl emits U+2212 MINUS SIGN for negatives, which Helvetica/WinAnsi PDF fonts drop silently, so refund and discount amounts on the archived underlag rendered as POSITIVE. formatAmount now replaces U+2212 with an ASCII hyphen (same guard as formatPdfCurrency), is exported, and is pinned by a regression test. 2. Regression: NEEDS_DOC_SOURCE_TYPES had two hardcoded copies that missed webshop_order, so flagged rows rendered without the "Underlag saknas" chip, waiver toggle, or batch-exempt selection, and the weekly missing-underlag push cron disagreed with the badge. The constant now lives in dependency-free lib/worklist/types.ts (client-safe), is re-exported from categories.ts, and both JournalEntryList.tsx and push-notifications/notification-scheduler.ts consume it instead of their own copies. Also: "Bokfört i SEK" reworded to "Motsvarande i SEK" (compliance skeptic observation: the dialog's lines are user-editable, so the underlag must state the order's conversion, not claim a booking fact). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c6f2bebab9
commit
5fc0be9ed7
@@ -16,21 +16,11 @@ import {
|
||||
} from '@/lib/invoices/matchable-statuses'
|
||||
import type { SuggestedMatch } from './types'
|
||||
|
||||
const log = createLogger('worklist')
|
||||
// Canonical home is lib/worklist/types.ts (dependency-free, client-safe);
|
||||
// re-exported here so existing server-side imports keep working.
|
||||
export { NEEDS_DOC_SOURCE_TYPES } from './types'
|
||||
|
||||
/**
|
||||
* Journal-entry source types that require underlag (BFL 5 kap 7§). Source
|
||||
* types representing system-generated entries (VAT settlement, year-end,
|
||||
* currency revaluation, …) are exempt by omission.
|
||||
*/
|
||||
export const NEEDS_DOC_SOURCE_TYPES = [
|
||||
'manual',
|
||||
'bank_transaction',
|
||||
'supplier_invoice_registered',
|
||||
'supplier_invoice_paid',
|
||||
'supplier_invoice_cash_payment',
|
||||
'import',
|
||||
] as const
|
||||
const log = createLogger('worklist')
|
||||
|
||||
/**
|
||||
* Upper bound on the unconsumed-inbox scan in countInboxDocuments. An inbox
|
||||
|
||||
@@ -117,3 +117,27 @@ export interface SuggestedMatch {
|
||||
counterparty_name: string | null
|
||||
candidate_total: number | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Journal-entry source types that require underlag (BFL 5 kap 7 §). Source
|
||||
* types representing system-generated entries (VAT settlement, year-end,
|
||||
* currency revaluation, ...) are exempt by omission.
|
||||
*
|
||||
* Single source of truth for EVERY TS surface (worklist counts, journal-list
|
||||
* chip/waiver UI, no-doc-required batch route, push notifications); the SQL
|
||||
* mirror lives in the verifikat_without_documents RPC, pinned by
|
||||
* tests/pg/document-surfaces-unification.pg.test.ts. Lives here (not in
|
||||
* categories.ts) because this module is dependency-free and safe to import
|
||||
* from client components.
|
||||
*/
|
||||
export const NEEDS_DOC_SOURCE_TYPES = [
|
||||
'manual',
|
||||
'bank_transaction',
|
||||
'supplier_invoice_registered',
|
||||
'supplier_invoice_paid',
|
||||
'supplier_invoice_cash_payment',
|
||||
'import',
|
||||
// Webshop order bookings rest on the generated orderunderlag (#1881); an
|
||||
// entry whose underlag failed to attach must surface here.
|
||||
'webshop_order',
|
||||
] as const
|
||||
|
||||
Reference in New Issue
Block a user