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
@@ -60,16 +60,14 @@ import { useCanWrite } from '@/lib/hooks/use-can-write'
|
||||
import { getErrorMessage } from '@/lib/errors/get-error-message'
|
||||
import { useCompanyOptional } from '@/contexts/CompanyContext'
|
||||
import { listContextKey, writeListContext } from '@/lib/navigation/list-context'
|
||||
import { NEEDS_DOC_SOURCE_TYPES } from '@/lib/worklist/types'
|
||||
import type { FiscalPeriod, JournalEntry, JournalEntryLine } from '@/types'
|
||||
|
||||
const NEEDS_ATTACHMENT = new Set([
|
||||
'manual',
|
||||
'bank_transaction',
|
||||
'supplier_invoice_registered',
|
||||
'supplier_invoice_paid',
|
||||
'supplier_invoice_cash_payment',
|
||||
'import',
|
||||
])
|
||||
// Shared source of truth (lib/worklist/types.ts) so the per-row chip and
|
||||
// waiver UI can never drift from the worklist count and the SQL predicate
|
||||
// (skeptic finding on #1881: a hardcoded copy here missed webshop_order,
|
||||
// leaving flagged rows without chip or waiver toggle).
|
||||
const NEEDS_ATTACHMENT = new Set<string>(NEEDS_DOC_SOURCE_TYPES)
|
||||
|
||||
// Column-header sorting (support feedback: "filtrera/sortera alla rubriker").
|
||||
// The sort order is a priority-ordered STACK of keys (max 3): the second key
|
||||
|
||||
Reference in New Issue
Block a user