Invoice set pricing: wire editor + align editor/backend contract

Front-end (fis.inv_shared.js / fis.inv_txt_de.js, rebuilt bundles):
- 3-way set display switch (setprice/itemprices/setonly) via admin.setmode,
  emitted into InvoiceOptions by FdsInvoiceData.BuildInvoiceOptions.
- Each request block now posts items[] in the backend contract shape
  (title/desc/qty/price_net/total_net + set type/setId tags) via itemToContract.
- invcPayload normalises the editor model to the field names BuildInvoiceParams
  reads (sms totals -> new.total_net/total_gross, invoicetitle->title,
  loc->provisionlocation, admin.paymentterms->new.paymentterm, CustomerId->customerid).

Back-end:
- BuildInvoiceOptions adds the setmode token alongside §13b.
- VAT rate+amount now taken from sms.vat (HighestVat) instead of the broken
  items 'is List<object>' detection that pinned the rate to 19.
- InvoiceSetPricing blanks price/total cells for text/title heading lines.

Tests: set-pricing text-line blanking, HighestVat selection/parsing, updated
the VAT param test to the sms.vat contract. 180 passing.

Note: the second VAT slot (InvoiceVAT_2) stays unused by design; mixed-rate
invoices store only the highest rate (pre-existing, accepted).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 10:48:14 +02:00
parent ebdb92713a
commit bfc695ed6a
12 changed files with 552 additions and 67 deletions
@@ -40,6 +40,12 @@
eis: 'Der Rechnungsentwurf konnte nicht gespeichert werden.',
iss: 'Zwischenstand speichern.',
p13b: 'USt -> §13b',
setm: 'Set-Preisanzeige',
setmo: {
setprice: 'Set mit Preis Positionen ohne Preis',
itemprices: 'Positionen mit Preis Set als Überschrift',
setonly: 'Nur Set mit Preis Positionen ausgeblendet'
},
ctp: 'Ansprechpartner festlegen',
mfr: 'Von MFR neu abrufen',
rq1: 'Auftragsdaten werden von MFR abgerufen.\nDer Vorgang kann bis zu 90Sek dauern.',