@kreiseck/kasseneck-api 0.29.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +174 -0
  2. package/dist/cjs/client/api.d.ts +3 -3
  3. package/dist/cjs/client/index.d.ts +1 -1
  4. package/dist/cjs/client/receipts.d.ts +32 -3
  5. package/dist/cjs/client/receipts.js +121 -6
  6. package/dist/cjs/enums/keck-payment-method.d.ts +10 -0
  7. package/dist/cjs/enums/keck-payment-method.js +6 -0
  8. package/dist/cjs/index.d.ts +2 -2
  9. package/dist/cjs/index.js +6 -2
  10. package/dist/cjs/kasse/index.d.ts +1 -1
  11. package/dist/cjs/kasse/index.js +5 -1
  12. package/dist/cjs/kasse/settings.d.ts +4 -2
  13. package/dist/cjs/kasse/settings.js +5 -2
  14. package/dist/cjs/kasse/texte.d.ts +444 -34
  15. package/dist/cjs/kasse/texte.js +265 -35
  16. package/dist/cjs/models/cancellation.d.ts +25 -2
  17. package/dist/cjs/models/cancellation.js +20 -1
  18. package/dist/cjs/models/index.d.ts +2 -0
  19. package/dist/cjs/models/index.js +7 -1
  20. package/dist/cjs/models/payment-errors.d.ts +22 -0
  21. package/dist/cjs/models/payment-errors.js +46 -0
  22. package/dist/cjs/models/receipt-payment.d.ts +86 -0
  23. package/dist/cjs/models/receipt-payment.js +40 -0
  24. package/dist/cjs/models/receipt-summary.d.ts +9 -0
  25. package/dist/cjs/models/receipt-summary.js +2 -0
  26. package/dist/cjs/models/receipt.d.ts +9 -0
  27. package/dist/cjs/models/receipt.js +19 -0
  28. package/dist/cjs/payments/hobex-hps/transaction-response.js +28 -28
  29. package/dist/cjs/receipt/layout.js +112 -10
  30. package/dist/esm/client/api.d.ts +3 -3
  31. package/dist/esm/client/index.d.ts +1 -1
  32. package/dist/esm/client/receipts.d.ts +32 -3
  33. package/dist/esm/client/receipts.js +121 -6
  34. package/dist/esm/enums/keck-payment-method.d.ts +10 -0
  35. package/dist/esm/enums/keck-payment-method.js +6 -0
  36. package/dist/esm/index.d.ts +2 -2
  37. package/dist/esm/index.js +1 -1
  38. package/dist/esm/kasse/index.d.ts +1 -1
  39. package/dist/esm/kasse/index.js +1 -1
  40. package/dist/esm/kasse/settings.d.ts +4 -2
  41. package/dist/esm/kasse/settings.js +5 -2
  42. package/dist/esm/kasse/texte.d.ts +444 -34
  43. package/dist/esm/kasse/texte.js +262 -34
  44. package/dist/esm/models/cancellation.d.ts +25 -2
  45. package/dist/esm/models/cancellation.js +20 -1
  46. package/dist/esm/models/index.d.ts +2 -0
  47. package/dist/esm/models/index.js +2 -0
  48. package/dist/esm/models/payment-errors.d.ts +22 -0
  49. package/dist/esm/models/payment-errors.js +42 -0
  50. package/dist/esm/models/receipt-payment.d.ts +86 -0
  51. package/dist/esm/models/receipt-payment.js +36 -0
  52. package/dist/esm/models/receipt-summary.d.ts +9 -0
  53. package/dist/esm/models/receipt-summary.js +2 -0
  54. package/dist/esm/models/receipt.d.ts +9 -0
  55. package/dist/esm/models/receipt.js +19 -0
  56. package/dist/esm/payments/hobex-hps/transaction-response.js +28 -28
  57. package/dist/esm/receipt/layout.js +112 -10
  58. package/fixtures/belege/split-bar-rueckgeld.json +58 -0
  59. package/fixtures/belege/split-eine-karte-trinkgeld.json +75 -0
  60. package/fixtures/belege/split-karte-karte-bar.json +102 -0
  61. package/fixtures/belege/split-langer-betrag.json +74 -0
  62. package/fixtures/belege/split-tischrunde-trinkgeld.json +152 -0
  63. package/fixtures/belege/split-trinkgeld-karte.json +82 -0
  64. package/fixtures/belege/split-zwei-karten-gleicher-anbieter.json +89 -0
  65. package/fixtures/belege/storno-split-teil.json +71 -0
  66. package/fixtures/belege/storno-split-voll.json +100 -0
  67. package/fixtures/erwartet/split-bar-rueckgeld.blatt32.json +194 -0
  68. package/fixtures/erwartet/split-bar-rueckgeld.blatt48.json +182 -0
  69. package/fixtures/erwartet/split-bar-rueckgeld.grid32.txt +28 -0
  70. package/fixtures/erwartet/split-bar-rueckgeld.grid48.txt +26 -0
  71. package/fixtures/erwartet/split-bar-rueckgeld.lines.json +286 -0
  72. package/fixtures/erwartet/split-eine-karte-trinkgeld.blatt32.json +242 -0
  73. package/fixtures/erwartet/split-eine-karte-trinkgeld.blatt48.json +224 -0
  74. package/fixtures/erwartet/split-eine-karte-trinkgeld.grid32.txt +36 -0
  75. package/fixtures/erwartet/split-eine-karte-trinkgeld.grid48.txt +33 -0
  76. package/fixtures/erwartet/split-eine-karte-trinkgeld.lines.json +371 -0
  77. package/fixtures/erwartet/split-karte-karte-bar.blatt32.json +356 -0
  78. package/fixtures/erwartet/split-karte-karte-bar.blatt48.json +338 -0
  79. package/fixtures/erwartet/split-karte-karte-bar.grid32.txt +55 -0
  80. package/fixtures/erwartet/split-karte-karte-bar.grid48.txt +52 -0
  81. package/fixtures/erwartet/split-karte-karte-bar.lines.json +519 -0
  82. package/fixtures/erwartet/split-langer-betrag.blatt32.json +266 -0
  83. package/fixtures/erwartet/split-langer-betrag.blatt48.json +260 -0
  84. package/fixtures/erwartet/split-langer-betrag.grid32.txt +40 -0
  85. package/fixtures/erwartet/split-langer-betrag.grid48.txt +39 -0
  86. package/fixtures/erwartet/split-langer-betrag.lines.json +343 -0
  87. package/fixtures/erwartet/split-tischrunde-trinkgeld.blatt32.json +470 -0
  88. package/fixtures/erwartet/split-tischrunde-trinkgeld.blatt48.json +434 -0
  89. package/fixtures/erwartet/split-tischrunde-trinkgeld.grid32.txt +74 -0
  90. package/fixtures/erwartet/split-tischrunde-trinkgeld.grid48.txt +68 -0
  91. package/fixtures/erwartet/split-tischrunde-trinkgeld.lines.json +740 -0
  92. package/fixtures/erwartet/split-trinkgeld-karte.blatt32.json +272 -0
  93. package/fixtures/erwartet/split-trinkgeld-karte.blatt48.json +254 -0
  94. package/fixtures/erwartet/split-trinkgeld-karte.grid32.txt +41 -0
  95. package/fixtures/erwartet/split-trinkgeld-karte.grid48.txt +38 -0
  96. package/fixtures/erwartet/split-trinkgeld-karte.lines.json +428 -0
  97. package/fixtures/erwartet/split-zwei-karten-gleicher-anbieter.blatt32.json +326 -0
  98. package/fixtures/erwartet/split-zwei-karten-gleicher-anbieter.blatt48.json +296 -0
  99. package/fixtures/erwartet/split-zwei-karten-gleicher-anbieter.grid32.txt +50 -0
  100. package/fixtures/erwartet/split-zwei-karten-gleicher-anbieter.grid48.txt +45 -0
  101. package/fixtures/erwartet/split-zwei-karten-gleicher-anbieter.lines.json +504 -0
  102. package/fixtures/erwartet/storno-split-teil.blatt32.json +230 -0
  103. package/fixtures/erwartet/storno-split-teil.blatt48.json +224 -0
  104. package/fixtures/erwartet/storno-split-teil.grid32.txt +34 -0
  105. package/fixtures/erwartet/storno-split-teil.grid48.txt +33 -0
  106. package/fixtures/erwartet/storno-split-teil.lines.json +304 -0
  107. package/fixtures/erwartet/storno-split-voll.blatt32.json +320 -0
  108. package/fixtures/erwartet/storno-split-voll.blatt48.json +314 -0
  109. package/fixtures/erwartet/storno-split-voll.grid32.txt +49 -0
  110. package/fixtures/erwartet/storno-split-voll.grid48.txt +48 -0
  111. package/fixtures/erwartet/storno-split-voll.lines.json +410 -0
  112. package/fixtures/hobex-hps-codes.json +29 -29
  113. package/fixtures/kasse-settings-standard.json +4 -2
  114. package/fixtures/kasse-texte.json +479 -35
  115. package/fixtures/manifest.json +72 -0
  116. package/fixtures/oberflaeche.json +3 -2
  117. package/fixtures/rechnung-api.schema.json +1 -1
  118. package/fixtures/rechnung-texte.json +1 -1
  119. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,180 @@ Was vor 0.7.0 geschah, steht in der Commit-Historie (`git log`); ab hier wird
4
4
  es hier geführt. Ein Eintrag nennt die Änderung **und ihren Grund** —
5
5
  nur der Grund überlebt den nächsten Umbau.
6
6
 
7
+ ## 0.31.0
8
+
9
+ Texte und Einstellung für „Getrennt zahlen" an der Kasse (ein Tisch zahlt in Teilen, ein Beleg mit
10
+ mehreren Zahlungen). Nur Texte, eine Einstellung und eine Tasten-Aktion; kein Aufruf und kein
11
+ Rechenweg ändert sich.
12
+
13
+ - **`tenderedCents` an jeder Barzahlung**: die Doku an `ReceiptPaymentInput` und
14
+ `PAYMENT_TENDERED_INVALID` sagte „höchstens an einer Zahlung“. Das Backend erlaubt jetzt jeder
15
+ Barzahlung ihren eigenen gegebenen Betrag. Grund: beim getrennten Zahlen gibt jeder Gast selbst,
16
+ der Bon zeigte Gegeben/Rückgeld aber nur beim letzten. Der Bon druckte schon je Zahlung; ein Test
17
+ hält drei Barzahlungen mit je eigenem Rückgeld fest.
18
+ - **Neue Sätze in `MELDUNGEN`** unter `getrennt.*` (Hinweis zur Einstellung, Prüfungen der
19
+ Teilzahlung, gesperrter Warenkorb, Rückbuchung bar/Terminal/Karte ohne Anbindung, angefangene
20
+ Sitzung nach dem Neuladen) und unter `storno.*` (Rückgabe je Zahlung, Karten nach dem Storno von Hand gutschreiben).
21
+ Grund: Browser-Kasse und Kassen-App sollen am Tresen dieselben Worte sagen; eine schon belastete
22
+ Karte nennt in jedem Satz den Betrag, und keiner rät zum zweiten Kassieren.
23
+ - **`STORNO_ZAHLUNG_FEHLER`**: Zuordnung der Backend-Codes `STORNO_PAYMENTS_REQUIRED`,
24
+ `STORNO_REFUND_EXCEEDS_PAYMENT`, `STORNO_REFUND_REFERENCE_REQUIRED`,
25
+ `STORNO_REFUND_REFERENCE_UNKNOWN` und `PAYMENTS_SUM_MISMATCH` zu ihrem Satz, auch in
26
+ `fixtures/kasse-texte.json` (`stornoZahlungFehler`). Grund: beide Kassen entscheiden am Code,
27
+ nie am Wortlaut des Backends. `stornoZahlungFehler(code)` liefert den Schlüssel dazu, ein
28
+ unbekannter Code fällt auf `storno.fehlgeschlagen` (wie `belegMailFehler`).
29
+ - **Neuer Storno-Code `STORNO_OUTCOME_UNKNOWN`** am Ende von `CANCELLATION_ERROR_CODES` (Zwilling
30
+ von `STORNO_FEHLERCODES` in `functions/gemeinsam/storno-core.js`; unter `/v3`
31
+ `cancellation_outcome_unknown`, `isCancellationErrorCode` prüft weiter exakt) mit dem Satz
32
+ `storno.ergebnis_unklar`. Grund: der Storno-Beleg kann schon signiert sein, obwohl der Ausgang
33
+ offen ist; wer dann noch einmal storniert, storniert womöglich doppelt. Der Satz rät darum,
34
+ nicht zu wiederholen und die Belegliste später neu zu laden.
35
+ - **Aufteilung als eigener Schritt**: neue Beschriftungen `getrennt.weiter` („Weiter · {betrag}
36
+ getrennt“), `getrennt.aufteilung`, `getrennt.zurueck_zahlart`, `getrennt.tab_positionen`,
37
+ `getrennt.tab_betrag`, `getrennt.stueck_mehr`/`_weniger`,
38
+ `getrennt.gegeben`, `getrennt.gegeben_rueckgeld` und die Sätze
39
+ `getrennt.positionen_gesperrt` und `getrennt.positionen_waehlen`. Grund: Nutzertest – erst
40
+ „Weiter“, dann je Zahlung nach Positionen (stückweise) oder als Betrag. Nach einer Zahlung als
41
+ Betrag ist „Nach Positionen“ gesperrt, weil sich Beträge keinen Stücken zuordnen lassen; der
42
+ Satz sagt das.
43
+ - **Zahlart je Zahlung, ein Knopf zum Hinzufügen**: `getrennt.zahlart` („Zahlart“),
44
+ `getrennt.art_bar`/`getrennt.art_karte` („Bar“/„Karte“) als Umschalter oben in der Zahlung,
45
+ `getrennt.zahlung_hinzufuegen` („Zahlung hinzufügen · {betrag}“) für den einen Knopf unten
46
+ rechts und der Satz `getrennt.gegeben_fehlt` (Barzahlung ohne „Gegeben“ bei eingeschaltetem
47
+ Rückgeld-Rechner, Wortlaut wie beim Abschluss). `getrennt.bar_kassieren`/`getrennt.karte_kassieren`
48
+ und `getrennt.kassieren` („Zahlung {n} kassieren“) entfallen (noch nie veröffentlicht). Grund: Nutzertest – zwei Knöpfe, die sofort kassieren,
49
+ lagen zu nah beieinander; jetzt wählt der Kassier die Zahlart wie jede andere Eingabe, und nur
50
+ ein Knopf löst die Zahlung aus. Offen 0 macht aus demselben Knopf „Abschließen“.
51
+ - **Nach Positionen als Kacheln**: `getrennt.offene_positionen`, `getrennt.stueck_offen`
52
+ („{n} offen“), `getrennt.stueck_gewaehlt` („{n} von {offen}“), `getrennt.nichts_gewaehlt` und
53
+ `getrennt.alles_bezahlt`. `getrennt.stueck_bezahlt` entfällt (noch nie veröffentlicht): bezahlte
54
+ Stück verschwinden aus der Auswahl. Grund: Nutzertest – in der großen Fläche stehen nur noch die
55
+ offenen Produkte als Kacheln, der Kassier tippt dort an, was dieser Gast zahlt.
56
+ - **`BESCHRIFTUNGEN` und `beschriftung()`**: ein zweiter Katalog für Knöpfe und Zeilennamen
57
+ („Getrennt", „Zahlung {n}", „Offen", „Rest", „÷ {n}", „davon Trinkgeld {betrag}", „Wie
58
+ zurückgeben?", „Alles bar", „Mehrere" …), in `fixtures/kasse-texte.json` unter `beschriftungen`.
59
+ Grund: `MELDUNGEN` führt nur Sätze (die Wächter beider Kassen erkennen Sätze daran), „Rest" ist
60
+ keiner – muss aber in beiden Kassen gleich heißen. Die Zahlarten folgen dem Bon
61
+ („Kartenzahlung", „Barzahlung").
62
+ - **Vier weitere Sätze unter `getrennt.*`**: `sitzung_unlesbar` (eine auf dem Gerät abgelegte
63
+ Sitzung lässt sich nicht mehr lesen – auf schon belastete Karten hinweisen, im Panel oder am
64
+ Terminal nachsehen lassen), `ablage_fehlgeschlagen` (die Ablage schlägt fehl – vor dem
65
+ Neuladen warnen, sonst verschwinden belastete Karten aus der Liste), `zu_viele_zahlungen`
66
+ (höchstens 20 Zahlungen je Beleg) und `entkoppeln_offene_karten` (ein entkoppeltes Gerät hatte
67
+ noch offene Kartenzahlungen – die Beträge stehen daneben, der Satz selbst bleibt ohne
68
+ Platzhalter). Grund: die Ablage der Teilzahlung läuft rein lokal auf dem Gerät; geht sie
69
+ verloren oder lässt sie sich nicht lesen, ist eine schon belastete Karte das teure Risiko, und
70
+ der Satz muss zum Nachschauen anleiten statt zum Weiterkassieren zu verleiten.
71
+ - **Einstellung `zahlGetrennt`** (Betrieb, Standard `false`) und **Tasten-Aktion `getrennt`**
72
+ (ohne Vorgabe-Taste). Grund: für Betriebe ohne Bedarf bleibt die Kasse, wie sie ist; eine
73
+ unerprobte Vorgabe-Taste finge womöglich der Browser ab. Das Backend (`kasse-settings-core.js`)
74
+ muss beide nachziehen, sonst verwirft sein Validator den Wert beim Speichern.
75
+ - **Vorgabe `kassierenModus` jetzt `'panel'`** (vorher `'seite'`): kassiert wird im Korb-Panel,
76
+ die Kacheln bleiben stehen. Grund: Nutzertest – so bleibt der Kachelbereich beim Kassieren
77
+ sichtbar, auch beim getrennten Zahlen. Ein gespeichertes `'seite'` bleibt; gespeichert werden
78
+ aber nur geänderte Felder, darum wechselt jedes Konto, das den Schalter nie angefasst hat, mit
79
+ dem Backend-Standard auf das Korb-Panel. Das Backend (`BETRIEB_STANDARD` in
80
+ `kasse-settings-core.js`) und der Dart-Zwilling ziehen denselben Wert nach.
81
+ - **Texte, die bisher nur in der Browser-Kasse standen, jetzt im Katalog**: Sätze
82
+ `kassieren.nichts_erfasst`, `kassieren.gegeben_fehlt`, `kassieren.gegeben_zu_wenig`,
83
+ `kassieren.gesperrt` („Kassieren gesperrt: {grund}“), `trinkgeld.ueber_haelfte`,
84
+ `sitzung.meldet_ab` („Kasse meldet in {sekunden} s ab …“), `abmelden.noch_einmal`,
85
+ `kartenzahlung.terminal_bricht_ab` und `connect.entkoppeln_frage` (nur Web); Beschriftungen
86
+ `kassieren.trinkgeld`, `kassieren.kein`, `kassieren.eigener_betrag`, `kassieren.passend`,
87
+ `kassieren.gegeben_loeschen`, `kassieren.es_fehlen_noch`, `kassieren.rueckgeld`,
88
+ `kartenzahlung.betrag_am_terminal`, `kartenzahlung.karte_vorhalten` („… · noch {zeit}“),
89
+ `kopplung.neu_koppeln`, `abmelden.frage`, `abmelden.weiter_arbeiten`, `geraet.entkoppeln`,
90
+ `connect.entkoppeln_bestaetigen` (nur Web), `storno.titel` („Storno zu {beleg}“),
91
+ `meldung.ausblenden` („Meldung ausblenden: {meldung}“) und `meldung.warnung_ausblenden`
92
+ („Verstanden – Warnung ausblenden: {meldung}“). Wortlaut wie bisher in der Browser-Kasse.
93
+ Grund: Oberflächen-Vertrag – beide Kassen zeigen dieselben Wörter; das X an einer Meldung nennt
94
+ jetzt, welche Meldung es ausblendet (in der Ecke stehen oft mehrere).
95
+ - **Halbgeviertstrich statt Geviertstrich** in allen sichtbaren Texten von `MELDUNGEN` (u. a.
96
+ `abschluss.unklar`, `kartenzahlung.unklar`, `kartenzahlung.karte_gebucht_beleg_offen`,
97
+ `connect.*`, `druck.*`) und in den Sätzen der Hobex-Antwortcodes (`transaction-response.ts`,
98
+ auch `fixtures/hobex-hps-codes.json`): „ – “ statt „ — “. Nur das Zeichen ändert sich, kein
99
+ Wortlaut und kein Schlüssel. Wer einen dieser Sätze wörtlich vergleicht, muss nachziehen.
100
+ Grund: einheitliche Typografie am Bildschirm; der Geviertstrich wirkt dort wie ein
101
+ Maschinenzeichen. Die Rechnungstexte (`rechnung/texte.ts`, PDF) bleiben unverändert.
102
+ - **`Cancellation` trägt `refundedByPayment`** (Zahlungs-ID auf positive Cent), Zwilling der
103
+ gleichnamigen Backend-Ablage (`functions/gemeinsam/storno-core.js`). Die Lesung
104
+ (`fromReceiptPayload`) behält nur ganzzahlige, nicht negative Werte, verwirft ungültige
105
+ Einträge einzeln statt den ganzen Eintrag zu verwerfen, und lässt das Feld weg, wenn die
106
+ Nutzlast es nicht trägt – bestehende Belege lesen sich unverändert. Auch am `pending`-Eintrag
107
+ vorhanden. Grund: über alle Storno-Einträge darf je Zahlung nie mehr zurückgehen, als bezahlt
108
+ wurde; ohne das Feld ließe sich das am Client nicht nachvollziehen.
109
+ - **Weitere Sätze in `MELDUNGEN`**: `getrennt.karte_bereits_zurueckgebucht` (das Terminal meldet
110
+ eine Gutschrift, die hier noch als offene Rückbuchung steht), `abschluss.erledigen_frage` (nur erledigen, was wirklich in der Belegliste steht),
111
+ `kartenzahlung.korb_gesperrt_karte_belastet` und `kartenzahlung.entkoppeln_karte_belastet`.
112
+ Grund: jeder dieser Zustände ist eine schon belastete oder gutgeschriebene Karte ohne
113
+ passenden Beleg – der teuerste Fehler am Tresen ist die doppelte Buchung, und kein Satz davon
114
+ darf zum Wiederholen raten, ohne vorher den Terminal-Beleg zu nennen.
115
+ - **Weitere `BESCHRIFTUNGEN`**: `allgemein.abbrechen`, `abschluss.beleg_vorhanden`,
116
+ `abschluss.erledigen`, `getrennt.karte_zurueckbuchen`, `getrennt.trotzdem_neu_koppeln`,
117
+ `getrennt.zahlung_behalten`, `getrennt.klaeren`, `getrennt.wurde_belastet`,
118
+ `getrennt.nicht_belastet`, `getrennt.erneut_zurueckbuchen`, `storno.differenz`. Grund: Knöpfe
119
+ zu den neuen Sätzen oben, in beiden Kassen gleich beschriftet.
120
+ - **Storno eines Belegs mit mehreren Zahlungen: Karten gehen von Hand zurück.**
121
+ `storno.karten_gutschreiben` steht nach dem gebuchten Storno über der Liste der Karten zum
122
+ Abhaken (eine oder mehrere, mit oder ohne Anbindung); `storno.ergebnis_unklar_karten` ersetzt
123
+ `storno.ergebnis_unklar`, wenn der gesendete Vorschlag Karten enthielt – erst die Belegliste
124
+ neu laden, erst dann gutschreiben (`STORNO_ZAHLUNG_FEHLER` zeigt weiter auf
125
+ `storno.ergebnis_unklar`, die Wahl trifft die Kasse am Vorschlag). Die Sätze und Knöpfe einer
126
+ Gutschrift am Terminal VOR dem Senden (`storno.gutschrift_laeuft`,
127
+ `storno.gutschrift_fehlgeschlagen`, `storno.gutschrift_unklar`,
128
+ `storno.gutgeschrieben_nicht_gebucht`, `storno.gutschrift_pruefen`,
129
+ `storno.extern_gutschreiben`, `storno.am_terminal_gutgeschrieben`,
130
+ `storno.nicht_gutgeschrieben`) sind wieder entfernt; sie waren nie veröffentlicht. Grund:
131
+ eine Gutschrift vor dem gebuchten Storno lässt Geld zurückgehen, ohne dass ein Storno-Beleg
132
+ sicher entsteht; die automatische Gutschrift kommt als eigener Schritt mit
133
+ Server-Unterstützung.
134
+ - **`storno.karten_nicht_abgehakt`**: wird die Liste der Karten nach dem gebuchten Storno
135
+ geschlossen, obwohl nicht jede Karte abgehakt ist, fragt die Kasse einmal nach. Grund: eine
136
+ vergessene Gutschrift fällt sonst erst dem Gast auf, und am Storno-Beleg sieht sie niemand mehr.
137
+
138
+ ## 0.30.0
139
+
140
+ Mehrere Zahlungen je Beleg. Setzt ein Backend mit `payments` voraus (keck, live seit
141
+ 2026-09-25); gegen einen älteren Server bleibt alles ohne `payments` wie bisher. Nichts bricht:
142
+ ein Beleg ohne Zahlungsliste liest, sendet und druckt sich byte-gleich wie in 0.29.0.
143
+
144
+ - **`Receipt` und `ReceiptSummary` tragen `payments` (`ReceiptPayment[]`), wenn der Server sie
145
+ liefert**, je Zahlung Zahlart, `amountCents`, bei Bar `tenderedCents`/Rückgeld, bei Karte
146
+ Anbieter und Terminaldaten, bei Stornos `refundOf`, dazu `tipCents` (Trinkgeld je Zahlung).
147
+ Grund: ein Tisch zahlt mit zwei Karten und dem Rest bar, und das Einzelfeld `paymentMethod`
148
+ konnte das nicht abbilden. Altbelege ohne Liste lesen sich unverändert (`payments` fehlt).
149
+ - **`KeckPaymentMethod.mixed` („Mehrere Zahlungsarten")**, nur zum Lesen. Der Server setzt ihn als
150
+ `paymentMethod`, wenn die Zahlungen verschiedene Zahlarten haben; wer ihn selbst sendet, wird
151
+ schon im Client abgewiesen. Grund: sonst wäre ein solcher Beleg für einen älteren Leser eine
152
+ unbekannte Zahlart; zum Kassieren gibt es die Zahlungsliste.
153
+ - **`payments` bei `sellReceipt`, `createReceipt` und `cancelReceipt`**, mit Form- und
154
+ Konfliktprüfung im Client (`payments` zusammen mit `paymentMethod` oder Kartenfeldern ergibt
155
+ `PAYMENTS_CONFLICT`; `payments: null` gilt als nicht angegeben). Für `sellReceipt` gibt es den
156
+ neuen Typ `SellReceiptWithPaymentsOptions`; `SellReceiptOptions` bleibt ein `interface` und
157
+ bekommt nur das optionale `payments?: undefined`, damit bestehender Code unverändert kompiliert
158
+ und die beiden Wege sich nicht mischen lassen. Beim Storno nennt `refundOf` die Zahlung des
159
+ Originals, auf die zurückgezahlt wird.
160
+ - **`PAYMENT_ERROR_CODES` (18 Codes) und `isPaymentErrorCode`**, Zwilling von
161
+ `ZAHLUNGS_FEHLERCODES` im Backend (gleiche Codes, gleiche Reihenfolge). `isPaymentErrorCode`
162
+ erkennt auch die kleingeschriebene `/v3`-Schreibweise, weil `/v3` diese Codes 1:1 klein
163
+ ausliefert. Grund: am Code entscheiden, nie am Text.
164
+ - **`CANCELLATION_ERROR_CODES` um vier `STORNO_…`-Codes ergänzt** (`STORNO_PAYMENTS_REQUIRED`,
165
+ `STORNO_REFUND_EXCEEDS_PAYMENT`, `STORNO_REFUND_REFERENCE_REQUIRED`,
166
+ `STORNO_REFUND_REFERENCE_UNKNOWN`) für die Rückzahlung je Zahlung. `isCancellationErrorCode`
167
+ prüft weiter exakt: unter `/v3` heißen die Storno-Codes nach dem Vokabular anders (nicht bloß
168
+ klein), die Namen kommen mit der Umstellung des Pakets auf `/v3`.
169
+ - **Beleg-Layout: bei mehr als einer Zahlung eine nummerierte Aufschlüsselung** unter „Gesamt:"
170
+ („Zahlungsarten:", dann „1. Kartenzahlung", „2. Barzahlung" … samt Betrag; der Betrag bricht
171
+ auf 58 mm nie). Darunter eingerückt „davon Trinkgeld", „Gegeben" und „Rückgeld" der jeweiligen
172
+ Zahlung; die Kartenblöcke kommen je Zahlung in Zahlungsreihenfolge, jeweils mit derselben
173
+ Nummer darüber. Grund: auf dem Bon muss nachvollziehbar sein, welcher Betrag wie bezahlt wurde
174
+ und zu welcher Zahlung ein Terminal-Block gehört.
175
+ - **Bei genau einer Zahlung bleibt der Beleg wie bisher**, nur „davon Trinkgeld", „Gegeben" und
176
+ „Rückgeld" stehen jetzt eingerückt unter „Zahlungsart:". Ohne Zahlungsliste ändert sich nichts:
177
+ alle bisherigen Vertragsbeispiele (`fixtures/erwartet`) und der Bytestrom-Zwilling sind
178
+ unverändert. Neu sind neun Beispiele `split-*`/`storno-split-*` (Karte+Karte+Bar,
179
+ Tischrunde mit Trinkgeld, Rückgeld, langer Betrag, Voll- und Teilstorno).
180
+
7
181
  ## 0.29.0
8
182
 
9
183
  - **Bricht `./partner` (und nur das): `PARTNER_FEHLER_CODES` ist jetzt durchgehend englisch,
@@ -3,7 +3,7 @@ import { type CreateStripeLinkOptions, type StripeCaptureResult } from '../payme
3
3
  import { type HobexPayOptions, type HobexRefundOptions } from '../payments/hobex.js';
4
4
  import { type TransportOptions } from './transport.js';
5
5
  import { type CashboxStatus, type SignatureStatus } from './status.js';
6
- import { type SendReceiptEmailOptions, type SendReceiptEmailResult, type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
6
+ import { type SendReceiptEmailOptions, type SendReceiptEmailResult, type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type SellReceiptWithPaymentsOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
7
7
  /**
8
8
  * Schlichte Factory ueber den Endpunkt-Funktionen: bindet einen Transport
9
9
  * einmal und liefert die Aufrufe ohne den wiederkehrenden ersten Parameter.
@@ -30,9 +30,9 @@ import { type SendReceiptEmailOptions, type SendReceiptEmailResult, type ListMyR
30
30
  */
31
31
  export interface KasseneckApi {
32
32
  /** Normalbeleg (Verkauf). */
33
- sellReceipt(options: SellReceiptOptions): Promise<Receipt>;
33
+ sellReceipt(options: SellReceiptOptions | SellReceiptWithPaymentsOptions): Promise<Receipt>;
34
34
  /** Normalbeleg samt Firmen-/Druckdaten fuer den Belegdruck. */
35
- sellReceiptWithCompany(options: SellReceiptOptions): Promise<ReceiptWithCompany>;
35
+ sellReceiptWithCompany(options: SellReceiptOptions | SellReceiptWithPaymentsOptions): Promise<ReceiptWithCompany>;
36
36
  /** Storno eines bestehenden Belegs — voll oder in Teilen, ueber den Storno-Endpunkt. */
37
37
  cancelReceipt(options: CancelReceiptOptions): Promise<CancelReceiptResult>;
38
38
  /** Storno aus frei uebergebenen Positionen. */
@@ -2,7 +2,7 @@ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type
2
2
  export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, createTransport, createBinaryTransport, } from './transport.js';
3
3
  export { AUFRUFE, type Aufruf, } from './aufrufe.js';
4
4
  export { KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, } from './errors.js';
5
- export { type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, } from './receipts.js';
5
+ export { type ReceiptCommonOptions, type SellReceiptOptions, type SellReceiptWithPaymentsOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, } from './receipts.js';
6
6
  export { listMyCashregisters } from './cashregisters.js';
7
7
  export { downloadDailyReport, downloadMonthlyReport } from './reports.js';
8
8
  export { type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, } from './status.js';
@@ -1,5 +1,5 @@
1
1
  import { ReceiptType, type ReceiptTypeKey, KeckPaymentMethod, type KeckPaymentMethodKey, CreditCardProvider } from '../enums/index.js';
2
- import { type Receipt, type ReceiptCompany, type ReceiptItem, type Voucher, type ReceiptSummary, type ReportMonth, type CancellationItem, type CancellationOf, type CancellationReason } from '../models/index.js';
2
+ import { type Receipt, type ReceiptCompany, type ReceiptItem, type Voucher, type ReceiptSummary, type ReportMonth, type CancellationItem, type CancellationOf, type CancellationReason, type ReceiptPaymentInput } from '../models/index.js';
3
3
  import type { InternerTransport } from './aufrufe.js';
4
4
  import type { Pruefangaben, ReceiptLayout } from '../receipt/layout.js';
5
5
  import type { LogoStufe } from '../receipt/blatt.js';
@@ -90,11 +90,32 @@ export interface CreateReceiptOptions extends ReceiptCommonOptions {
90
90
  * ausdruecklich uebergebene `paymentMethod` sticht.
91
91
  */
92
92
  paymentMethodFromServer?: string;
93
+ /**
94
+ * Mehrere Zahlungen je Beleg (siehe [ReceiptPaymentInput]). Schliesst
95
+ * `paymentMethod`, `paymentMethodFromServer` und die Kartenfelder aus —
96
+ * die Kartenangaben gehoeren dann in die einzelne Zahlung (Backend:
97
+ * `PAYMENTS_CONFLICT`). Nur bei `standard` und `training`.
98
+ */
99
+ payments?: ReceiptPaymentInput[];
93
100
  items?: ReceiptItem[];
94
101
  vouchers?: Voucher[];
95
102
  }
103
+ /** Verkauf mit einer Zahlungsart (`paymentMethod`, Kartenfelder aus [ReceiptCommonOptions]). */
96
104
  export interface SellReceiptOptions extends ReceiptCommonOptions {
97
105
  paymentMethod: KeckPaymentMethod | KeckPaymentMethodKey;
106
+ payments?: undefined;
107
+ items?: ReceiptItem[];
108
+ vouchers?: Voucher[];
109
+ }
110
+ /**
111
+ * Verkauf mit mehreren Zahlungen (`payments`, siehe [ReceiptPaymentInput]).
112
+ * Ohne `paymentMethod` und ohne die Kartenfelder aus [ReceiptCommonOptions] —
113
+ * die Kartenangaben stehen in der einzelnen Zahlung (Backend:
114
+ * `PAYMENTS_CONFLICT`, zur Laufzeit ebenso geprueft).
115
+ */
116
+ export interface SellReceiptWithPaymentsOptions extends ReceiptCommonOptions {
117
+ payments: ReceiptPaymentInput[];
118
+ paymentMethod?: undefined;
98
119
  items?: ReceiptItem[];
99
120
  vouchers?: Voucher[];
100
121
  }
@@ -126,6 +147,14 @@ export type CancelReceiptOptions = {
126
147
  creditCardProvider?: CreditCardProvider;
127
148
  cardPaymentId?: string;
128
149
  cardPaymentData?: Record<string, unknown>;
150
+ /**
151
+ * Rueckzahlung je Zahlung (Betraege negativ, `refundOf` = `id` der
152
+ * Originalzahlung). Schliesst `paymentMethod` und die Kartenfelder aus
153
+ * (Backend: `PAYMENTS_CONFLICT`). Ohne Angabe spiegelt der Server die
154
+ * Restbetraege jeder Originalzahlung; ein Teilstorno eines Belegs mit
155
+ * mehreren Zahlungen braucht sie (`STORNO_PAYMENTS_REQUIRED`).
156
+ */
157
+ payments?: ReceiptPaymentInput[];
129
158
  } & ({
130
159
  receipt: Receipt;
131
160
  cashregisterId?: string;
@@ -183,12 +212,12 @@ export interface ReceiptWithCompany {
183
212
  */
184
213
  export declare function createReceipt(rufen: InternerTransport, options: CreateReceiptOptions): Promise<Receipt>;
185
214
  /** Normalbeleg (Verkauf) nach RKSV. */
186
- export declare function sellReceipt(rufen: InternerTransport, options: SellReceiptOptions): Promise<Receipt>;
215
+ export declare function sellReceipt(rufen: InternerTransport, options: SellReceiptOptions | SellReceiptWithPaymentsOptions): Promise<Receipt>;
187
216
  /**
188
217
  * Normalbeleg wie [sellReceipt], liefert zusaetzlich die Firmen-/Druckdaten
189
218
  * aus derselben Antwort — alles, was ein Belegdruck braucht, in einem Aufruf.
190
219
  */
191
- export declare function sellReceiptWithCompany(rufen: InternerTransport, options: SellReceiptOptions): Promise<ReceiptWithCompany>;
220
+ export declare function sellReceiptWithCompany(rufen: InternerTransport, options: SellReceiptOptions | SellReceiptWithPaymentsOptions): Promise<ReceiptWithCompany>;
192
221
  /**
193
222
  * Storno-Beleg zu einem bestehenden Beleg — voll oder in Teilen. Prueft die
194
223
  * Eingabe, bevor etwas hinausgeht; der Server haelt die Restmengen und die
@@ -65,6 +65,22 @@ function createReceiptParams(options) {
65
65
  if (items != null && items.length > 0) {
66
66
  params['items'] = alsNutzlast(items, index_js_2.toReceiptItemPayload);
67
67
  }
68
+ // `payments: null` gilt wie im Backend (zahlungs-eingang.js) als nicht angegeben.
69
+ if (options.payments != null) {
70
+ // Der alte Storno-Weg und der Null-/Startbeleg nehmen keine Zahlungsliste
71
+ // (Backend: PAYMENTS_NOT_ALLOWED); ein Storno mit mehreren Zahlungen
72
+ // laeuft ueber cancelReceipt.
73
+ if (typ.value === index_js_1.ReceiptType.cancellation.value) {
74
+ throw eingabefehler('payments am Storno gehen nur ueber cancelReceipt.');
75
+ }
76
+ if (typ.value !== index_js_1.ReceiptType.standard.value && typ.value !== index_js_1.ReceiptType.training.value) {
77
+ throw eingabefehler(`payments sind bei receiptType "${typ.value}" nicht erlaubt.`);
78
+ }
79
+ const konflikt = zahlungsKonflikt(options);
80
+ if (konflikt != null)
81
+ throw eingabefehler(konflikt);
82
+ params['payments'] = gepruefteZahlungen(options.payments, false, 'createReceipt');
83
+ }
68
84
  // Vom Aufrufer kommt sie geprueft, vom Server roh — siehe die beiden Felder
69
85
  // in [CreateReceiptOptions]. Die Typpruefung allein reicht dafuer nicht: ein
70
86
  // Verbraucher ohne Typen faellt durch dieses Netz, und ein Tippfehler in der
@@ -148,11 +164,15 @@ async function cancelReceipt(rufen, options) {
148
164
  if (options.note !== undefined && options.note.length > NOTE_MAX) {
149
165
  throw new errors_js_1.KasseneckValidationError('cancelReceipt', `Anmerkung ist zu lang (hoechstens ${NOTE_MAX} Zeichen)`, 'request');
150
166
  }
167
+ // `payments: null` gilt wie im Backend als nicht angegeben.
168
+ const zahlungen = options.payments != null ? gepruefteStornoZahlungen(options) : undefined;
151
169
  const params = { cashregisterId, originalReceiptId, reason: options.reason };
152
170
  if (options.items !== undefined)
153
171
  params.items = options.items.map((p) => ({ index: p.index, quantity: p.quantity }));
154
172
  if (options.note !== undefined && options.note !== '')
155
173
  params.note = options.note;
174
+ if (zahlungen !== undefined)
175
+ params.payments = zahlungen;
156
176
  if (options.paymentMethod != null)
157
177
  params.paymentMethod = gepruefteZahlungsart(options.paymentMethod);
158
178
  const karte = options.creditCardProvider != null || options.cardPaymentId != null || options.cardPaymentData != null;
@@ -506,15 +526,110 @@ function gepruefterTip(tip) {
506
526
  }
507
527
  return nutzlast;
508
528
  }
509
- /** Zahlungsart des Aufrufers pruefen — unbekannt wirft, bevor etwas rausgeht. */
529
+ /**
530
+ * Zahlungsart des Aufrufers pruefen — unbekannt wirft, bevor etwas rausgeht.
531
+ * `mixed` wirft ebenfalls: den Wert vergibt nur der Server (Beleg mit
532
+ * mehreren Zahlarten); gesendet wird stattdessen die Zahlungsliste.
533
+ */
510
534
  function gepruefteZahlungsart(wert) {
511
- if (typeof wert === 'object') {
512
- return wert.value;
535
+ let zahlungsart;
536
+ if (typeof wert === 'object' && wert !== null) {
537
+ zahlungsart = wert.value;
538
+ }
539
+ else {
540
+ if (typeof wert !== 'string' || !Object.prototype.hasOwnProperty.call(index_js_1.KeckPaymentMethod, wert)) {
541
+ throw eingabefehler(`Zahlungsart: unbekannter Schluessel "${String(wert)}"`);
542
+ }
543
+ zahlungsart = index_js_1.KeckPaymentMethod[wert].value;
513
544
  }
514
- if (!Object.prototype.hasOwnProperty.call(index_js_1.KeckPaymentMethod, wert)) {
515
- throw eingabefehler(`Zahlungsart: unbekannter Schluessel "${wert}"`);
545
+ if (zahlungsart === index_js_1.KeckPaymentMethod.mixed.value) {
546
+ throw eingabefehler('Zahlungsart "mixed" vergibt nur der Server – mehrere Zahlarten gehen als payments hinaus.');
516
547
  }
517
- return index_js_1.KeckPaymentMethod[wert].value;
548
+ return zahlungsart;
549
+ }
550
+ /** Hoechstzahl der Zahlungen je Beleg (Backend: MAX_ZAHLUNGEN). */
551
+ const MAX_ZAHLUNGEN = 20;
552
+ /**
553
+ * `payments` neben einer Einzel-Zahlungsart oder Kartenfeldern? Liefert den
554
+ * Grund (Backend: PAYMENTS_CONFLICT), sonst null. Nie still eines bevorzugen.
555
+ */
556
+ function zahlungsKonflikt(options) {
557
+ for (const feld of ['paymentMethod', 'paymentMethodFromServer', 'creditCardProvider', 'cardPaymentId', 'cardPaymentData']) {
558
+ if (options[feld] != null) {
559
+ return `payments und ${feld} duerfen nicht gemeinsam gesendet werden – Kartenangaben gehoeren in die Zahlung.`;
560
+ }
561
+ }
562
+ return null;
563
+ }
564
+ /**
565
+ * Zahlungsliste pruefen und in Nutzlast-Form bringen — Formpruefung wie
566
+ * `pruefeZahlungen` im Backend, soweit sie ohne Beleg und Zahlbetrag geht
567
+ * (Summe, Anbieter-Pflicht und Trinkgeld prueft der Server). Wirft, bevor
568
+ * etwas hinausgeht.
569
+ */
570
+ function gepruefteZahlungen(roh, storno, functionName) {
571
+ const fehler = (grund) => new errors_js_1.KasseneckValidationError(functionName, grund, 'request');
572
+ if (!Array.isArray(roh))
573
+ throw fehler('payments muss eine Liste sein.');
574
+ if (roh.length > MAX_ZAHLUNGEN)
575
+ throw fehler(`payments: es sind hoechstens ${MAX_ZAHLUNGEN} Eintraege erlaubt.`);
576
+ return roh.map((eintrag, i) => {
577
+ const nr = i + 1;
578
+ if (eintrag == null || typeof eintrag !== 'object' || Array.isArray(eintrag)) {
579
+ throw fehler(`Zahlung ${nr}: kein gueltiges Objekt.`);
580
+ }
581
+ const z = eintrag;
582
+ const method = gepruefteZahlungsart(z['method']);
583
+ const betrag = z['amountCents'];
584
+ if (typeof betrag !== 'number' || !Number.isInteger(betrag) || (storno ? betrag >= 0 : betrag <= 0)) {
585
+ throw fehler(`Zahlung ${nr}: amountCents muss eine ganze Zahl ${storno ? 'kleiner' : 'groesser'} als 0 sein.`);
586
+ }
587
+ const aus = { method, amountCents: betrag };
588
+ if (z['tenderedCents'] !== undefined) {
589
+ const gegeben = z['tenderedCents'];
590
+ if (storno || typeof gegeben !== 'number' || !Number.isInteger(gegeben) || gegeben < betrag) {
591
+ throw fehler(`Zahlung ${nr}: tenderedCents muss eine ganze Zahl von mindestens amountCents sein (nur am Verkauf).`);
592
+ }
593
+ aus['tenderedCents'] = gegeben;
594
+ }
595
+ if (z['tipCents'] !== undefined) {
596
+ const trinkgeld = z['tipCents'];
597
+ if (typeof trinkgeld !== 'number' || !Number.isInteger(trinkgeld) || trinkgeld <= 0) {
598
+ throw fehler(`Zahlung ${nr}: tipCents muss eine ganze Zahl groesser als 0 sein.`);
599
+ }
600
+ aus['tipCents'] = trinkgeld;
601
+ }
602
+ if (z['provider'] !== undefined) {
603
+ aus['provider'] = kartenanbieter(String(z['provider']));
604
+ }
605
+ if (z['providerPaymentId'] !== undefined) {
606
+ if (typeof z['providerPaymentId'] !== 'string' || z['providerPaymentId'] === '') {
607
+ throw fehler(`Zahlung ${nr}: providerPaymentId muss ein nicht-leerer Text sein.`);
608
+ }
609
+ aus['providerPaymentId'] = z['providerPaymentId'];
610
+ }
611
+ if (z['providerData'] !== undefined) {
612
+ const daten = z['providerData'];
613
+ if (daten === null || typeof daten !== 'object' || Array.isArray(daten)) {
614
+ throw fehler(`Zahlung ${nr}: providerData muss ein Objekt sein.`);
615
+ }
616
+ aus['providerData'] = daten;
617
+ }
618
+ if (z['refundOf'] !== undefined) {
619
+ if (!storno || typeof z['refundOf'] !== 'string' || z['refundOf'] === '') {
620
+ throw fehler(`Zahlung ${nr}: refundOf gibt es nur am Storno, als id der Originalzahlung.`);
621
+ }
622
+ aus['refundOf'] = z['refundOf'];
623
+ }
624
+ return aus;
625
+ });
626
+ }
627
+ /** `payments` am Storno: Konflikt mit Zahlungsart/Kartenfeldern, dann Form. */
628
+ function gepruefteStornoZahlungen(options) {
629
+ const konflikt = zahlungsKonflikt(options);
630
+ if (konflikt != null)
631
+ throw new errors_js_1.KasseneckValidationError('cancelReceipt', konflikt, 'request');
632
+ return gepruefteZahlungen(options.payments, true, 'cancelReceipt');
518
633
  }
519
634
  /** Kartenanbieter pruefen — er stammt vom Aufrufer, nicht aus Serverdaten. */
520
635
  function kartenanbieter(wert) {
@@ -5,6 +5,11 @@
5
5
  * `label` ist das deutsche Anzeige-Label fuer die Zahlungsart-Zeile auf dem Beleg.
6
6
  * Muss 1:1 mit dem Backend-Mapping `paymentMethodToString` (functions/helper.js)
7
7
  * uebereinstimmen.
8
+ *
9
+ * `mixed` vergibt nur der Server: ein Beleg mit mehreren Zahlungen
10
+ * verschiedener Zahlart (`payments`) traegt ihn als Einzelfeld
11
+ * `paymentMethod`. Lesen ist erlaubt, Senden nicht — wer mehrere Zahlarten
12
+ * kassiert, schickt die Zahlungsliste, nie `mixed`.
8
13
  */
9
14
  export declare const KeckPaymentMethod: {
10
15
  readonly cash: {
@@ -52,6 +57,11 @@ export declare const KeckPaymentMethod: {
52
57
  readonly needsCreditCard: true;
53
58
  readonly label: "Bolt Card";
54
59
  };
60
+ readonly mixed: {
61
+ readonly value: "mixed";
62
+ readonly needsCreditCard: false;
63
+ readonly label: "Mehrere Zahlungsarten";
64
+ };
55
65
  };
56
66
  export type KeckPaymentMethodKey = keyof typeof KeckPaymentMethod;
57
67
  export type KeckPaymentMethod = (typeof KeckPaymentMethod)[KeckPaymentMethodKey];
@@ -9,6 +9,11 @@ const define_enum_js_1 = require("./define-enum.js");
9
9
  * `label` ist das deutsche Anzeige-Label fuer die Zahlungsart-Zeile auf dem Beleg.
10
10
  * Muss 1:1 mit dem Backend-Mapping `paymentMethodToString` (functions/helper.js)
11
11
  * uebereinstimmen.
12
+ *
13
+ * `mixed` vergibt nur der Server: ein Beleg mit mehreren Zahlungen
14
+ * verschiedener Zahlart (`payments`) traegt ihn als Einzelfeld
15
+ * `paymentMethod`. Lesen ist erlaubt, Senden nicht — wer mehrere Zahlarten
16
+ * kassiert, schickt die Zahlungsliste, nie `mixed`.
12
17
  */
13
18
  exports.KeckPaymentMethod = (0, define_enum_js_1.defineEnum)({
14
19
  cash: { value: 'cash', needsCreditCard: false, label: 'Barzahlung' },
@@ -20,4 +25,5 @@ exports.KeckPaymentMethod = (0, define_enum_js_1.defineEnum)({
20
25
  boltApp: { value: 'boltApp', needsCreditCard: false, label: 'Bolt App' },
21
26
  boltCash: { value: 'boltCash', needsCreditCard: false, label: 'Bolt Cash' },
22
27
  boltCard: { value: 'boltCard', needsCreditCard: true, label: 'Bolt Card' },
28
+ mixed: { value: 'mixed', needsCreditCard: false, label: 'Mehrere Zahlungsarten' },
23
29
  });
@@ -1,5 +1,5 @@
1
1
  export { ReceiptType, type ReceiptTypeKey, VatRate, type VatRateKey, KeckPaymentMethod, type KeckPaymentMethodKey, CreditCardProvider, type CreditCardProviderKey, VoucherType, type VoucherTypeKey, VoucherAction, type VoucherActionKey, StripeLinkMode, type StripeLinkModeKey, } from './enums/index.js';
2
- export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
- export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
2
+ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, type ReceiptPayment, type ReceiptPaymentPayload, type ReceiptPaymentInput, fromReceiptPaymentPayload, toReceiptPaymentPayload, type PaymentErrorCode, PAYMENT_ERROR_CODES, isPaymentErrorCode, type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
+ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type SellReceiptWithPaymentsOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
4
4
  export { parseServerTimeStamp, toViennaWallClock, type ViennaWallClock } from './vienna-time.js';
5
5
  export { type KasseSettingsBetrieb, type KasseSettingsGeraet, type KasseSettings, type ArticleGroup, type KasseArtikel, KASSE_BETRIEB_STANDARD, KASSE_GERAET_STANDARD, mergeKasseSettings, fromArticleGroupPayload, fromKasseArtikelPayload, listMyArticleGroups, listMyArticles, getKasseSettings, setMyKasseSettings, setMyRegisterDeviceSettings, verteileRabatt, cancelScopeOf, receiptsScopeOf, } from './kasse/index.js';
package/dist/cjs/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AUFRUFE = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isReceiptEmailErrorCode = exports.RECEIPT_EMAIL_ERROR_CODES = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
4
- exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.sendReceiptEmail = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.createBinaryTransport = exports.createTransport = void 0;
3
+ exports.apiKeyAuth = exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isReceiptEmailErrorCode = exports.RECEIPT_EMAIL_ERROR_CODES = exports.isPaymentErrorCode = exports.PAYMENT_ERROR_CODES = exports.toReceiptPaymentPayload = exports.fromReceiptPaymentPayload = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
4
+ exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.sendReceiptEmail = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.createBinaryTransport = exports.createTransport = exports.AUFRUFE = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = void 0;
5
5
  var index_js_1 = require("./enums/index.js");
6
6
  Object.defineProperty(exports, "ReceiptType", { enumerable: true, get: function () { return index_js_1.ReceiptType; } });
7
7
  Object.defineProperty(exports, "VatRate", { enumerable: true, get: function () { return index_js_1.VatRate; } });
@@ -29,6 +29,10 @@ Object.defineProperty(exports, "CANCELLATION_ERROR_CODES", { enumerable: true, g
29
29
  Object.defineProperty(exports, "CANCELLATION_RESERVATION_MS", { enumerable: true, get: function () { return index_js_2.CANCELLATION_RESERVATION_MS; } });
30
30
  Object.defineProperty(exports, "isCancellationReason", { enumerable: true, get: function () { return index_js_2.isCancellationReason; } });
31
31
  Object.defineProperty(exports, "isCancellationErrorCode", { enumerable: true, get: function () { return index_js_2.isCancellationErrorCode; } });
32
+ Object.defineProperty(exports, "fromReceiptPaymentPayload", { enumerable: true, get: function () { return index_js_2.fromReceiptPaymentPayload; } });
33
+ Object.defineProperty(exports, "toReceiptPaymentPayload", { enumerable: true, get: function () { return index_js_2.toReceiptPaymentPayload; } });
34
+ Object.defineProperty(exports, "PAYMENT_ERROR_CODES", { enumerable: true, get: function () { return index_js_2.PAYMENT_ERROR_CODES; } });
35
+ Object.defineProperty(exports, "isPaymentErrorCode", { enumerable: true, get: function () { return index_js_2.isPaymentErrorCode; } });
32
36
  Object.defineProperty(exports, "RECEIPT_EMAIL_ERROR_CODES", { enumerable: true, get: function () { return index_js_2.RECEIPT_EMAIL_ERROR_CODES; } });
33
37
  Object.defineProperty(exports, "isReceiptEmailErrorCode", { enumerable: true, get: function () { return index_js_2.isReceiptEmailErrorCode; } });
34
38
  Object.defineProperty(exports, "remainingQuantities", { enumerable: true, get: function () { return index_js_2.remainingQuantities; } });
@@ -10,4 +10,4 @@ export { verteileRabatt } from '../receipt/discount.js';
10
10
  export { cancelScopeOf, receiptsScopeOf, type RegisterScope, type RegisterUserPerms } from '../register/pairing.js';
11
11
  export { type NetzDrucker, type DruckJob, type DruckJobStatus, type CreatePrintJobOptions, listMyPrinters, createPrintJob, getPrintJob } from './drucker.js';
12
12
  export { listMyTipRecipients } from './trinkgeld.js';
13
- export { MELDUNGEN, FEHLERREGELN, meldung, meldungGiltFuer, BELEG_MAIL_FEHLER, belegMailFehler, type Meldung, type MeldungsSchluessel, type Fehlerart, type Seite, type BelegMailFehlercode, } from './texte.js';
13
+ export { MELDUNGEN, FEHLERREGELN, meldung, meldungGiltFuer, BELEG_MAIL_FEHLER, belegMailFehler, STORNO_ZAHLUNG_FEHLER, stornoZahlungFehler, BESCHRIFTUNGEN, beschriftung, type Meldung, type MeldungsSchluessel, type Fehlerart, type Seite, type BelegMailFehlercode, type StornoZahlungFehlercode, type BeschriftungsSchluessel, } from './texte.js';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createPrintJob = exports.listMyPrinters = exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.mengeErlaubt = exports.mengenVorgabe = exports.mengenregelFuerEinheit = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.FERTIG_SEKUNDEN = exports.WZ_SKALA = exports.LOGO_SKALA = exports.WZ_STAERKE = exports.WZ_SEITE = exports.RABATT = exports.AUTO_AB_MIN = exports.KACHELSTIL = exports.SCHRIFT_EINST = exports.LOGO_GROESSE = exports.TASTEN_AKTIONEN = exports.QR_MODUS = exports.LADE_AUTO = exports.SCHNITT = exports.ZEICHENSATZ = exports.PAPIER = exports.TERMINAL_ART = exports.TERMINAL_VIA = exports.DRUCKER_ART = exports.HOEHE = exports.KATPOS = exports.LAYOUT = exports.BELEG_AUSGABE = exports.KASSIEREN_MODUS = exports.TG_MODUS = exports.MENGE = exports.WASSERZEICHEN = exports.SCHRIFT = exports.STIL = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.KASSE_TASTEN_STANDARD = exports.KASSE_TASTEN_AKTIONEN = exports.KARTENANBIETER = void 0;
4
- exports.belegMailFehler = exports.BELEG_MAIL_FEHLER = exports.meldungGiltFuer = exports.meldung = exports.FEHLERREGELN = exports.MELDUNGEN = exports.listMyTipRecipients = exports.getPrintJob = void 0;
4
+ exports.beschriftung = exports.BESCHRIFTUNGEN = exports.stornoZahlungFehler = exports.STORNO_ZAHLUNG_FEHLER = exports.belegMailFehler = exports.BELEG_MAIL_FEHLER = exports.meldungGiltFuer = exports.meldung = exports.FEHLERREGELN = exports.MELDUNGEN = exports.listMyTipRecipients = exports.getPrintJob = void 0;
5
5
  /**
6
6
  * Kachel-Kasse: Einstellungen, Artikelgruppen/Artikel fuer Kacheln,
7
7
  * Rabattverteilung. Die Aufrufe heissen 1:1 wie die Backend-Functions
@@ -77,3 +77,7 @@ Object.defineProperty(exports, "meldung", { enumerable: true, get: function () {
77
77
  Object.defineProperty(exports, "meldungGiltFuer", { enumerable: true, get: function () { return texte_js_1.meldungGiltFuer; } });
78
78
  Object.defineProperty(exports, "BELEG_MAIL_FEHLER", { enumerable: true, get: function () { return texte_js_1.BELEG_MAIL_FEHLER; } });
79
79
  Object.defineProperty(exports, "belegMailFehler", { enumerable: true, get: function () { return texte_js_1.belegMailFehler; } });
80
+ Object.defineProperty(exports, "STORNO_ZAHLUNG_FEHLER", { enumerable: true, get: function () { return texte_js_1.STORNO_ZAHLUNG_FEHLER; } });
81
+ Object.defineProperty(exports, "stornoZahlungFehler", { enumerable: true, get: function () { return texte_js_1.stornoZahlungFehler; } });
82
+ Object.defineProperty(exports, "BESCHRIFTUNGEN", { enumerable: true, get: function () { return texte_js_1.BESCHRIFTUNGEN; } });
83
+ Object.defineProperty(exports, "beschriftung", { enumerable: true, get: function () { return texte_js_1.beschriftung; } });
@@ -156,6 +156,8 @@ export interface KasseSettingsBetrieb {
156
156
  rueckgeld: boolean;
157
157
  schnellbar: boolean;
158
158
  kassierenModus: KasseKassierenModus;
159
+ /** Getrennt zahlen: dritter Knopf neben Bar und Karte, ein Beleg mit mehreren Zahlungen. */
160
+ zahlGetrennt: boolean;
159
161
  /** Trinkgeld-Chips in Prozent (eine Nachkommastelle, max 5, eindeutig, Reihenfolge des Chefs). */
160
162
  tgChips: number[];
161
163
  /** Rabatt-Chips in Prozent — dieselben Regeln wie tgChips, vom Chef einstellbar. */
@@ -168,10 +170,10 @@ export interface KasseSettingsBetrieb {
168
170
  hinweise: boolean;
169
171
  }
170
172
  /** Aktionen der Kasse, die eine Taste bekommen koennen. */
171
- export declare const KASSE_TASTEN_AKTIONEN: readonly ["kassieren", "abschliessen", "abbrechen", "frei", "bar", "karte", "passend", "belege", "letzteZurueck", "einstellungen", "abmelden", "trinkgeld", "vollbild", "gegebenLeeren", "korbLeeren"];
173
+ export declare const KASSE_TASTEN_AKTIONEN: readonly ["kassieren", "abschliessen", "abbrechen", "frei", "bar", "karte", "passend", "belege", "letzteZurueck", "einstellungen", "abmelden", "trinkgeld", "vollbild", "gegebenLeeren", "korbLeeren", "getrennt"];
172
174
  export type KasseTastenAktion = typeof KASSE_TASTEN_AKTIONEN[number];
173
175
  /** Kurzer Name, damit alle Enum-Listen gleich heissen; der alte bleibt gueltig. */
174
- export declare const TASTEN_AKTIONEN: readonly ["kassieren", "abschliessen", "abbrechen", "frei", "bar", "karte", "passend", "belege", "letzteZurueck", "einstellungen", "abmelden", "trinkgeld", "vollbild", "gegebenLeeren", "korbLeeren"];
176
+ export declare const TASTEN_AKTIONEN: readonly ["kassieren", "abschliessen", "abbrechen", "frei", "bar", "karte", "passend", "belege", "letzteZurueck", "einstellungen", "abmelden", "trinkgeld", "vollbild", "gegebenLeeren", "korbLeeren", "getrennt"];
175
177
  /** Tastenkarte: Aktion -> Tasten (`Mod+F`, `Enter`, `Escape`, `F5` ...; `Mod` = ⌘ auf dem Mac, Strg sonst). */
176
178
  export type KasseTastenkarte = Record<KasseTastenAktion, string[]>;
177
179
  export declare const KASSE_TASTEN_STANDARD: Readonly<KasseTastenkarte>;
@@ -92,7 +92,7 @@ exports.WZ_SKALA = ['S', 'M', 'L', 'XL'];
92
92
  /** Wie lange die Fertig-Seite stehen bleibt, in Sekunden; 0 = bis zum Tippen. */
93
93
  exports.FERTIG_SEKUNDEN = [0, 3, 5, 10, 15, 30, 60];
94
94
  /** Aktionen der Kasse, die eine Taste bekommen koennen. */
95
- exports.KASSE_TASTEN_AKTIONEN = ['kassieren', 'abschliessen', 'abbrechen', 'frei', 'bar', 'karte', 'passend', 'belege', 'letzteZurueck', 'einstellungen', 'abmelden', 'trinkgeld', 'vollbild', 'gegebenLeeren', 'korbLeeren'];
95
+ exports.KASSE_TASTEN_AKTIONEN = ['kassieren', 'abschliessen', 'abbrechen', 'frei', 'bar', 'karte', 'passend', 'belege', 'letzteZurueck', 'einstellungen', 'abmelden', 'trinkgeld', 'vollbild', 'gegebenLeeren', 'korbLeeren', 'getrennt'];
96
96
  /** Kurzer Name, damit alle Enum-Listen gleich heissen; der alte bleibt gueltig. */
97
97
  exports.TASTEN_AKTIONEN = exports.KASSE_TASTEN_AKTIONEN;
98
98
  exports.KASSE_TASTEN_STANDARD = Object.freeze({
@@ -114,6 +114,9 @@ exports.KASSE_TASTEN_STANDARD = Object.freeze({
114
114
  // verschiedenen Momenten (Korb vor dem Kassieren, Gegeben-Feld darin) —
115
115
  // der Verteiler laesst die nicht zustaendige Aktion durchfallen.
116
116
  korbLeeren: ['Mod+C'],
117
+ // Bewusst ohne Vorgabe: jede freie Mod-Taste ist in irgendeinem Browser
118
+ // belegt oder am Geraet unerprobt. Der Chef vergibt sie, wenn er sie braucht.
119
+ getrennt: [],
117
120
  });
118
121
  exports.KASSE_BETRIEB_STANDARD = Object.freeze({
119
122
  // Das Petrol der Marke: die Aktionsfarbe des Design-Systems (Rolle `brand`).
@@ -128,7 +131,7 @@ exports.KASSE_BETRIEB_STANDARD = Object.freeze({
128
131
  menge: 'x', notiz: false, suche: false, rabatt: 'aus',
129
132
  zahlBar: true, zahlKarte: false, kartenanbieter: 'keiner', trinkgeld: false, tgModus: 'beides',
130
133
  tgStufen: { 5: true, 10: true, 15: false, 20: false }, tgChips: [5, 10], tgSplit: true, rueckgeld: true,
131
- schnellbar: false, kassierenModus: 'seite',
134
+ schnellbar: false, kassierenModus: 'panel', zahlGetrennt: false,
132
135
  // 'fragen' = Fertig-Seite bietet QR und Bon an — sicherster Standard.
133
136
  logoBild: '', wzSeite: 'mitte', wzPos: 50, wzPosV: 50, wzStaerke: 6, logoSkala: 'M', wzSkala: 'M',
134
137
  glas: true, hinweise: true,