# Invoice "Set" Pricing — Design & Front-/Back-end Contract Customer requirement: items declared as a **set** in `[dbo].[mfr__items]` (`[Type] = 'set'`) should normally be shown as a single **set price** on the invoice instead of being broken up into their member items and summed. Three display modes (switchable in the invoice editor): | Mode | Set line | Member items | Use as | |---|---|---|---| | **SetPrice** (default) | shown **with price** | shown **without price** | the new default | | **ItemPrices** | shown as a heading **without price** | shown **with price** | the previous behaviour | | **SetOnly** | shown **with price** | **removed** | compact | > **Totals are unaffected.** The invoice total is taken from the registration > balance (`InvoiceBalance` / `InvoiceBalance_net`), not by summing the rendered > lines, so switching modes is purely presentational. The set price always > equals the sum of its members (computed as a fallback when the set header > carries no own price). ## Back-end (implemented + unit-tested) - `Fuchs/code/InvoiceSetPricing.cs` — the authoritative transformation: `SetDisplayMode` + `Build(items, mode)` → ordered `InvoiceSetLine`s, each with `ShowPrice` and `IsSetHeader`. `ModeFromInvoiceOptions(...)` reads the mode from the invoice options. Fully covered by `Fuchs.Tests/InvoiceSetPricingTests.cs`. - `FuchsPdf.ApplyInvoice` renders through `InvoiceSetPricing.Build`: lines with `ShowPrice == false` render **blank** price/total cells (not `0,00 €`), and the set header line is rendered emphasised. Invoices without sets pass through unchanged. ## Front-end contract (to wire in the invoice editor) The editor already knows the set structure (from `fds__prepInvoice`) and assembles the `invc` JSON. To drive the modes it must, when sending the invoice: 1. **Mode** — add a token to `inv.InvoiceOptions` (CSV, alongside `§13b`): - `setmode:setprice` (default — may be omitted), `setmode:itemprices`, or `setmode:setonly`. A 3-way switch in the editor sets this token. 2. **Item flags** — in each service request's `items[]`: - the **set header** item: `type: "set"`, `id: ""`, and `total_net` = the set price (or `0` to let the back-end sum the members); - each **member** item: `setId: ""` (matching the header's id). - standalone items need no extra fields. That is the entire contract — the back-end does the rest. The editor's running **total stays the member sum in every mode**, matching the registration balance. ### Why the switch lives in the editor Set grouping is only known where the request/item tree is rendered (front-end). The back-end intentionally stays the single, tested authority for *how* a chosen mode maps to printed lines, so the editor only needs to pick the mode and tag the items — it does not re-implement the pricing rules. ## Persistence note Draft/preview PDFs render straight from the posted `invc` JSON, so the contract works end-to-end for previews immediately. For a **finalised** invoice to re-render in a chosen mode later, the per-item `type`/`setId` flags (and the `setmode` option) must be persisted with the stored invoice items (`fds__createInvoice_Details` / `fds__invoice_items`). `setmode` already persists via `InvoiceOptions`; persisting the per-item set tags is a small SSDT + create-proc change to make once the editor wiring is confirmed.