@kreiseck/kasseneck-api 0.8.0 → 0.9.1
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.
- package/CHANGELOG.md +83 -0
- package/dist/cjs/kasse/texte.d.ts +39 -0
- package/dist/cjs/kasse/texte.js +20 -0
- package/dist/cjs/receipt/layout.d.ts +11 -5
- package/dist/cjs/receipt/layout.js +248 -26
- package/dist/esm/kasse/texte.d.ts +39 -0
- package/dist/esm/kasse/texte.js +20 -0
- package/dist/esm/receipt/layout.d.ts +11 -5
- package/dist/esm/receipt/layout.js +247 -26
- package/fixtures/belege/karte-eigener.json +44 -0
- package/fixtures/belege/karte-gptom-ios.json +59 -0
- package/fixtures/belege/karte-gptom.json +59 -0
- package/fixtures/belege/karte-hobex-cloud.json +54 -0
- package/fixtures/belege/karte-hobex-hps.json +54 -0
- package/fixtures/belege/karte-mypos.json +55 -0
- package/fixtures/belege/karte-stripe-eps.json +52 -0
- package/fixtures/belege/karte-stripe.json +57 -0
- package/fixtures/belege/karte-sumup.json +53 -0
- package/fixtures/erwartet/karte-eigener.grid32.txt +22 -0
- package/fixtures/erwartet/karte-eigener.grid48.txt +22 -0
- package/fixtures/erwartet/karte-eigener.lines.json +216 -0
- package/fixtures/erwartet/karte-gptom-ios.grid32.txt +34 -0
- package/fixtures/erwartet/karte-gptom-ios.grid48.txt +34 -0
- package/fixtures/erwartet/karte-gptom-ios.lines.json +286 -0
- package/fixtures/erwartet/karte-gptom.grid32.txt +34 -0
- package/fixtures/erwartet/karte-gptom.grid48.txt +34 -0
- package/fixtures/erwartet/karte-gptom.lines.json +286 -0
- package/fixtures/erwartet/karte-hobex-cloud.grid32.txt +29 -0
- package/fixtures/erwartet/karte-hobex-cloud.grid48.txt +29 -0
- package/fixtures/erwartet/karte-hobex-cloud.lines.json +256 -0
- package/fixtures/erwartet/karte-hobex-hps.grid32.txt +33 -0
- package/fixtures/erwartet/karte-hobex-hps.grid48.txt +33 -0
- package/fixtures/erwartet/karte-hobex-hps.lines.json +272 -0
- package/fixtures/erwartet/karte-mypos.grid32.txt +38 -0
- package/fixtures/erwartet/karte-mypos.grid48.txt +36 -0
- package/fixtures/erwartet/karte-mypos.lines.json +353 -0
- package/fixtures/erwartet/karte-stripe-eps.grid32.txt +28 -0
- package/fixtures/erwartet/karte-stripe-eps.grid48.txt +28 -0
- package/fixtures/erwartet/karte-stripe-eps.lines.json +250 -0
- package/fixtures/erwartet/karte-stripe.grid32.txt +31 -0
- package/fixtures/erwartet/karte-stripe.grid48.txt +31 -0
- package/fixtures/erwartet/karte-stripe.lines.json +268 -0
- package/fixtures/erwartet/karte-sumup.grid32.txt +32 -0
- package/fixtures/erwartet/karte-sumup.grid48.txt +30 -0
- package/fixtures/erwartet/karte-sumup.lines.json +316 -0
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/kasse-texte.json +60 -1
- package/fixtures/manifest.json +54 -0
- package/fixtures/oberflaeche.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,89 @@ 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.9.1
|
|
8
|
+
|
|
9
|
+
### Elf Saetze fuer die vier Ausgaenge einer Kartenzahlung und das Terminal-Protokoll
|
|
10
|
+
|
|
11
|
+
**Anlass:** Die Kassen-App bekommt GP Tom mit denselben vier Ausgaengen, die
|
|
12
|
+
die Browser-Kasse schon kennt — geglueckt, abgebrochen, gescheitert, unklar —
|
|
13
|
+
und dazu ein Terminal-Protokoll. Beide Kassen duerfen nur Katalogsaetze zeigen;
|
|
14
|
+
ohne diese Schluessel haette die App eigene Formulierungen erfunden, und der
|
|
15
|
+
Kassier haette am Tresen zwei verschiedene Woerter fuer dieselbe Lage gelesen.
|
|
16
|
+
|
|
17
|
+
**Grund fuer die Auswahl:** Der teuerste Fehler an der Kasse ist die zweite
|
|
18
|
+
Belastung derselben Karte. Deshalb tragen die neuen Saetze zu den unsicheren
|
|
19
|
+
Ausgaengen alles, was der Kassier braucht, um NICHT zu wiederholen: Betrag,
|
|
20
|
+
Kennung und den Hinweis auf den Terminal-Beleg.
|
|
21
|
+
|
|
22
|
+
- **GP Tom** (nur App, wie die uebrigen `gptom.`-Saetze): `gptom.abgelehnt` und
|
|
23
|
+
`gptom.abgelehnt_mit_code` (das Terminal hat entschieden — sicher nichts
|
|
24
|
+
gebucht), `gptom.nicht_geoeffnet` (die App liess sich nicht starten),
|
|
25
|
+
`gptom.zeit_abgelaufen` / `gptom.zeit_abgelaufen_mit_kennung` (Frist abgelaufen
|
|
26
|
+
ist **kein** Abbruch: die Karte kann belastet sein).
|
|
27
|
+
- **Karte gebucht, Beleg fehlt:** `kartenzahlung.karte_gebucht_beleg_offen` und
|
|
28
|
+
`kartenzahlung.karte_gebucht_korb_geaendert`, beide mit `betrag` und `kennung`.
|
|
29
|
+
Der zweite nennt die Entscheidung, die er verlangt: Beleg erstellen oder am
|
|
30
|
+
Terminal stornieren und hier verwerfen.
|
|
31
|
+
- **Warteschirm:** `kartenzahlung.wartet_auf_terminal`.
|
|
32
|
+
- **Terminal-Protokoll:** `protokoll.leer`, `protokoll.kopiert` — ohne `nur`,
|
|
33
|
+
weil an dem Satz nichts plattformgebunden ist.
|
|
34
|
+
|
|
35
|
+
**Neue abgeleitete Pruefungen** statt einer gepflegten Liste: kein Satz steht
|
|
36
|
+
zweimal im Katalog; jeder `gptom.`-Satz gilt nur in der App; jede Fassung
|
|
37
|
+
`…_mit_kennung` ist ihre Grundfassung plus dem Anker und teilt deren `nur`;
|
|
38
|
+
jeder unklare Ausgang warnt vor dem zweiten Kassieren.
|
|
39
|
+
|
|
40
|
+
`FEHLERREGELN` bleibt unveraendert — die neuen Saetze sind Ausgaenge einer
|
|
41
|
+
Kartenzahlung, keine neue Art, einen Transportfehler einzuordnen.
|
|
42
|
+
|
|
43
|
+
## 0.9.0
|
|
44
|
+
|
|
45
|
+
### Alle Kartenzahlungsbloecke im Belegmodell — nicht nur Hobex
|
|
46
|
+
|
|
47
|
+
**Anlass:** Am Bon aus der Flutter-App standen bei einer Stripe-Zahlung Marke,
|
|
48
|
+
letzte vier Ziffern, 3-D Secure, Betrag, Zahlzeitpunkt und Referenz. Dasselbe
|
|
49
|
+
Blatt als PDF geoeffnet sagte nur „Zahlungsart: Kartenzahlung". Betroffen waren
|
|
50
|
+
vier der sieben Anbieter: GP Tom, SumUp, myPOS und Stripe.
|
|
51
|
+
|
|
52
|
+
**Ursache:** Bis 0.8.0 trug dieses Modell nur den Hobex-Block, begruendet damit,
|
|
53
|
+
die uebrigen Anbieter druckten „in ihren eigenen Apps". Das Argument gilt fuer
|
|
54
|
+
die Frage, wer das TERMINAL bedient — nicht dafuer, was auf dem BELEGDOKUMENT
|
|
55
|
+
steht. Aus der einen Regel wurde beim Bau des Zeilenmodells die andere. Im
|
|
56
|
+
Backend hatte die vorherige PDF-Erzeugung (`generateReceiptPdf`) alle sieben
|
|
57
|
+
Anbieter; mit der Umstellung auf dieses Modell fielen vier still weg.
|
|
58
|
+
|
|
59
|
+
- Neu: `gpTomBlock`, `sumupBlock`, `myposBlock`, `stripeBlock` — Zeile fuer
|
|
60
|
+
Zeile portiert aus `print_paper.dart` des Dart-Zwillings, inklusive der
|
|
61
|
+
Eigenheiten: GP Tom schreibt `transactionType` im Plugin-`toMap` mit
|
|
62
|
+
Tippfehler (`transacitonType`), myPOS liefert den Zeitpunkt als
|
|
63
|
+
`YYMMDDhhmmss` ohne Trenner, Stripe kennt neben Karte auch EPS.
|
|
64
|
+
- `stripeReceiptLines` wird exportiert, wie im Dart-Paket: Druck und Anzeige
|
|
65
|
+
sollen dieselbe Quelle haben, nicht zwei.
|
|
66
|
+
- Ein myPOS-Zeitpunkt, der nicht wie `YYMMDDhhmmss` aussieht, wird
|
|
67
|
+
**unveraendert** durchgereicht statt zerschnitten — eine halb geratene
|
|
68
|
+
Uhrzeit auf einem Beleg ist schlimmer als ein roher Wert.
|
|
69
|
+
- Ein unbekannter Anbieter ergibt weiterhin keinen Block, still und ohne
|
|
70
|
+
Fehler: ein Beleg muss sich immer zeigen lassen.
|
|
71
|
+
|
|
72
|
+
### Neun Golden-Belege fuer Kartenzahlungen
|
|
73
|
+
|
|
74
|
+
**Anlass:** Von den 22 Golden-Belegen trug **keiner** eine Kartenzahlung.
|
|
75
|
+
Deshalb konnte der Verlust der vier Bloecke passieren, ohne dass irgendetwas
|
|
76
|
+
rot wurde.
|
|
77
|
+
|
|
78
|
+
- Neu: `karte-hobex-hps`, `karte-hobex-cloud`, `karte-gptom`, `karte-gptom-ios`,
|
|
79
|
+
`karte-sumup`, `karte-mypos`, `karte-stripe`, `karte-stripe-eps`,
|
|
80
|
+
`karte-eigener`. Die Paare decken beide Zweige ab, wo es welche gibt
|
|
81
|
+
(Unterschriftsfeld ja/nein, Karte gegen EPS, Tippfehler-Schluessel).
|
|
82
|
+
- Neu: eine Pruefung, die die Anbieterliste **aus dem Enum** nimmt statt aus
|
|
83
|
+
einer Handliste — wer einen Anbieter aufnimmt, wird rot, bis ein Golden-Beleg
|
|
84
|
+
dazuliegt. Sie fand beim ersten Lauf sofort zwei weitere Luecken
|
|
85
|
+
(`gpTomIos`, `hobexCloudApi`).
|
|
86
|
+
- Neu: eine zweite Pruefung, dass ein Beleg MIT Terminaldaten auch wirklich
|
|
87
|
+
einen Block traegt. Ein Golden-Beleg allein beweist nur, dass die Datei da
|
|
88
|
+
ist.
|
|
89
|
+
|
|
7
90
|
## 0.7.2
|
|
8
91
|
|
|
9
92
|
### `55` („PIN falsch") ist eine gemessene Host-Ablehnung → `declined`
|
|
@@ -124,6 +124,17 @@ declare const MELDUNGEN_ROH: {
|
|
|
124
124
|
readonly text: "Unklar, ob die Kartenzahlung durchgegangen ist — die Verbindung zum Terminal riss ab. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird: die Karte kann belastet sein. Kennung der Zahlung: {kennung}.";
|
|
125
125
|
readonly platzhalter: readonly ["kennung"];
|
|
126
126
|
};
|
|
127
|
+
readonly 'kartenzahlung.wartet_auf_terminal': {
|
|
128
|
+
readonly text: "Bitte am Terminal fortfahren …";
|
|
129
|
+
};
|
|
130
|
+
readonly 'kartenzahlung.karte_gebucht_beleg_offen': {
|
|
131
|
+
readonly text: "Die Karte ist bereits mit {betrag} belastet (Kennung {kennung}) — der Beleg dazu fehlt noch. Bitte jetzt den Beleg erstellen und nicht erneut kassieren.";
|
|
132
|
+
readonly platzhalter: readonly ["betrag", "kennung"];
|
|
133
|
+
};
|
|
134
|
+
readonly 'kartenzahlung.karte_gebucht_korb_geaendert': {
|
|
135
|
+
readonly text: "Es gibt eine gebuchte Kartenzahlung über {betrag} (Kennung {kennung}), aber der Korb hat sich seither geändert. Bitte zuerst entscheiden: den Beleg zur gebuchten Zahlung erstellen oder die Zahlung am Terminal stornieren und hier verwerfen.";
|
|
136
|
+
readonly platzhalter: readonly ["betrag", "kennung"];
|
|
137
|
+
};
|
|
127
138
|
readonly 'kartenzahlung.connect_nicht_verbunden': {
|
|
128
139
|
readonly text: "Kartenzahlung nicht möglich: Kasseneck Connect ist nicht verbunden — Einstellungen → Kasseneck Connect.";
|
|
129
140
|
readonly nur: readonly ["web"];
|
|
@@ -161,6 +172,34 @@ declare const MELDUNGEN_ROH: {
|
|
|
161
172
|
readonly platzhalter: readonly ["code"];
|
|
162
173
|
readonly nur: readonly ["app"];
|
|
163
174
|
};
|
|
175
|
+
readonly 'gptom.abgelehnt': {
|
|
176
|
+
readonly text: "Das Terminal hat die Zahlung abgelehnt.";
|
|
177
|
+
readonly nur: readonly ["app"];
|
|
178
|
+
};
|
|
179
|
+
readonly 'gptom.abgelehnt_mit_code': {
|
|
180
|
+
readonly text: "Das Terminal hat die Zahlung abgelehnt ({code}).";
|
|
181
|
+
readonly platzhalter: readonly ["code"];
|
|
182
|
+
readonly nur: readonly ["app"];
|
|
183
|
+
};
|
|
184
|
+
readonly 'gptom.nicht_geoeffnet': {
|
|
185
|
+
readonly text: "GP Tom ließ sich nicht öffnen — bitte die GP-Tom-App prüfen und erneut versuchen.";
|
|
186
|
+
readonly nur: readonly ["app"];
|
|
187
|
+
};
|
|
188
|
+
readonly 'gptom.zeit_abgelaufen': {
|
|
189
|
+
readonly text: "Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird.";
|
|
190
|
+
readonly nur: readonly ["app"];
|
|
191
|
+
};
|
|
192
|
+
readonly 'gptom.zeit_abgelaufen_mit_kennung': {
|
|
193
|
+
readonly text: "Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird. Kennung der Zahlung: {kennung}.";
|
|
194
|
+
readonly platzhalter: readonly ["kennung"];
|
|
195
|
+
readonly nur: readonly ["app"];
|
|
196
|
+
};
|
|
197
|
+
readonly 'protokoll.leer': {
|
|
198
|
+
readonly text: "Noch keine Einträge — das Protokoll füllt sich mit der ersten Kartenzahlung.";
|
|
199
|
+
};
|
|
200
|
+
readonly 'protokoll.kopiert': {
|
|
201
|
+
readonly text: "Das Protokoll liegt in der Zwischenablage.";
|
|
202
|
+
};
|
|
164
203
|
readonly 'belege.laden_fehlgeschlagen': {
|
|
165
204
|
readonly text: "Die Belege konnten nicht geladen werden.";
|
|
166
205
|
};
|
package/dist/cjs/kasse/texte.js
CHANGED
|
@@ -59,6 +59,13 @@ const MELDUNGEN_ROH = {
|
|
|
59
59
|
'kartenzahlung.unklar': { text: 'Unklar, ob die Kartenzahlung durchgegangen ist — die Verbindung zum Terminal riss ab. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird: die Karte kann belastet sein.' },
|
|
60
60
|
// Die Kennung ist der einzige Anker, um die Zahlung am Terminal-Beleg wiederzufinden — liegt sie vor, gilt dieser Satz statt kartenzahlung.unklar.
|
|
61
61
|
'kartenzahlung.unklar_mit_kennung': { text: 'Unklar, ob die Kartenzahlung durchgegangen ist — die Verbindung zum Terminal riss ab. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird: die Karte kann belastet sein. Kennung der Zahlung: {kennung}.', platzhalter: ['kennung'] },
|
|
62
|
+
'kartenzahlung.wartet_auf_terminal': { text: 'Bitte am Terminal fortfahren …' },
|
|
63
|
+
// Ein geglücktes Kartenergebnis ohne Beleg ist der teuerste Zustand am Tresen:
|
|
64
|
+
// wer hier erneut kassiert, belastet die Karte ein zweites Mal. Beide Sätze
|
|
65
|
+
// nennen deshalb Betrag UND Kennung — nur damit findet der Kassier die Zahlung
|
|
66
|
+
// am Terminal-Beleg wieder — und keiner rät zum Wiederholen.
|
|
67
|
+
'kartenzahlung.karte_gebucht_beleg_offen': { text: 'Die Karte ist bereits mit {betrag} belastet (Kennung {kennung}) — der Beleg dazu fehlt noch. Bitte jetzt den Beleg erstellen und nicht erneut kassieren.', platzhalter: ['betrag', 'kennung'] },
|
|
68
|
+
'kartenzahlung.karte_gebucht_korb_geaendert': { text: 'Es gibt eine gebuchte Kartenzahlung über {betrag} (Kennung {kennung}), aber der Korb hat sich seither geändert. Bitte zuerst entscheiden: den Beleg zur gebuchten Zahlung erstellen oder die Zahlung am Terminal stornieren und hier verwerfen.', platzhalter: ['betrag', 'kennung'] },
|
|
62
69
|
'kartenzahlung.connect_nicht_verbunden': { text: 'Kartenzahlung nicht möglich: Kasseneck Connect ist nicht verbunden — Einstellungen → Kasseneck Connect.', nur: ['web'] },
|
|
63
70
|
'terminal.keines_gefunden': { text: 'Kein Hobex-Terminal gefunden — ist es eingeschaltet und im selben Netz wie dieser Rechner?', nur: ['web'] },
|
|
64
71
|
'terminal.nicht_bereit': { text: 'Terminal antwortet, ist aber nicht betriebsbereit: {antwort} — TID prüfen.', platzhalter: ['antwort'], nur: ['web'] },
|
|
@@ -67,6 +74,19 @@ const MELDUNGEN_ROH = {
|
|
|
67
74
|
'gptom.zahlung_fehlgeschlagen': { text: 'GP Tom: Zahlung fehlgeschlagen: {grund}', platzhalter: ['grund'], nur: ['app'] },
|
|
68
75
|
'gptom.terminal_antwortet_nicht': { text: 'Das Terminal hat nicht geantwortet: {grund}', platzhalter: ['grund'], nur: ['app'] },
|
|
69
76
|
'gptom.zahlung_nicht_abgeschlossen': { text: 'Die Zahlung wurde nicht abgeschlossen ({code}).', platzhalter: ['code'], nur: ['app'] },
|
|
77
|
+
// Abgelehnt heißt: das Terminal hat entschieden, es ist sicher nichts gebucht.
|
|
78
|
+
// Der Code ist die einzige Handhabe, mit der der Inhaber bei GP nachfragen kann —
|
|
79
|
+
// liegt einer vor, gilt die Fassung mit Code.
|
|
80
|
+
'gptom.abgelehnt': { text: 'Das Terminal hat die Zahlung abgelehnt.', nur: ['app'] },
|
|
81
|
+
'gptom.abgelehnt_mit_code': { text: 'Das Terminal hat die Zahlung abgelehnt ({code}).', platzhalter: ['code'], nur: ['app'] },
|
|
82
|
+
'gptom.nicht_geoeffnet': { text: 'GP Tom ließ sich nicht öffnen — bitte die GP-Tom-App prüfen und erneut versuchen.', nur: ['app'] },
|
|
83
|
+
// Frist abgelaufen ist kein Abbruch: die Karte kann belastet sein, nur die
|
|
84
|
+
// Antwort blieb aus. Deshalb derselbe Ton wie kartenzahlung.unklar.
|
|
85
|
+
'gptom.zeit_abgelaufen': { text: 'Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird.', nur: ['app'] },
|
|
86
|
+
'gptom.zeit_abgelaufen_mit_kennung': { text: 'Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird. Kennung der Zahlung: {kennung}.', platzhalter: ['kennung'], nur: ['app'] },
|
|
87
|
+
// --- Terminal-Protokoll --------------------------------------------------
|
|
88
|
+
'protokoll.leer': { text: 'Noch keine Einträge — das Protokoll füllt sich mit der ersten Kartenzahlung.' },
|
|
89
|
+
'protokoll.kopiert': { text: 'Das Protokoll liegt in der Zwischenablage.' },
|
|
70
90
|
// --- Belege und Storno ---------------------------------------------------
|
|
71
91
|
'belege.laden_fehlgeschlagen': { text: 'Die Belege konnten nicht geladen werden.' },
|
|
72
92
|
'belege.keine_im_zeitraum': { text: 'Keine Belege in diesem Zeitraum.' },
|
|
@@ -22,11 +22,15 @@ import type { PosPaperSize } from '../printing/escpos.js';
|
|
|
22
22
|
*
|
|
23
23
|
* Bewusst **nicht** enthalten: Firmenlogo und Rasterbilder (brauchen
|
|
24
24
|
* Bildverarbeitung, die im Browser anders aussieht als in Node), PDF-Erzeugung
|
|
25
|
-
* und Druckeransteuerung.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
25
|
+
* und Druckeransteuerung.
|
|
26
|
+
*
|
|
27
|
+
* Die anbieterspezifischen Kartenzahlungsbloecke sind dagegen **alle**
|
|
28
|
+
* enthalten (Hobex, GP Tom, SumUp, myPOS, Stripe). Bis 0.8.0 trug das Modell
|
|
29
|
+
* nur den Hobex-Block, weil die Browser-Kasse nur das HPS-Terminal selbst
|
|
30
|
+
* bedient und die uebrigen Anbieter „in ihren eigenen Apps drucken". Das
|
|
31
|
+
* Argument gilt fuer die Frage, wer das TERMINAL bedient — nicht dafuer, was
|
|
32
|
+
* auf dem BELEGDOKUMENT steht. Aus der einen Regel wurde die andere, und
|
|
33
|
+
* derselbe Beleg trug im PDF weniger als auf dem Bon.
|
|
30
34
|
*/
|
|
31
35
|
/** Ausrichtung einer Zeile bzw. einer Spalte. */
|
|
32
36
|
export type LayoutAlign = 'left' | 'center' | 'right';
|
|
@@ -129,6 +133,8 @@ export interface BuildReceiptLayoutOptions {
|
|
|
129
133
|
* diesem Paket ausnahmslos ganzzahlig gerechnet).
|
|
130
134
|
*/
|
|
131
135
|
export declare function formatCents(cents: number): string;
|
|
136
|
+
/** Zwilling von `stripeReceiptLines` (print_paper.dart). */
|
|
137
|
+
export declare function stripeReceiptLines(daten: Record<string, unknown>, cardPaymentId: string | null): string[];
|
|
132
138
|
/**
|
|
133
139
|
* Hinweis auf die Steuerbefreiung, den ein Kleinunternehmerbeleg tragen muss —
|
|
134
140
|
* ohne ihn stuende in der USt-Tabelle „D 0 %" ohne jede Begruendung, und ab
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SMALL_BUSINESS_NOTICE = exports.AKTUELLES_REGELWERK = void 0;
|
|
4
4
|
exports.formatCents = formatCents;
|
|
5
|
+
exports.stripeReceiptLines = stripeReceiptLines;
|
|
5
6
|
exports.receiptSignatureFailed = receiptSignatureFailed;
|
|
6
7
|
exports.receiptSignatureIsTest = receiptSignatureIsTest;
|
|
7
8
|
exports.receiptIsZero = receiptIsZero;
|
|
@@ -71,6 +72,36 @@ function originalDatum(timeStamp) {
|
|
|
71
72
|
* `typeof null === 'object'` ist, ergab das beim Lesen von `.label` einen
|
|
72
73
|
* nackten TypeError.
|
|
73
74
|
*/
|
|
75
|
+
/**
|
|
76
|
+
* Die anbieterspezifischen Kartenzahlungsbloecke.
|
|
77
|
+
*
|
|
78
|
+
* WARUM DIESE BLOECKE HIER STEHEN
|
|
79
|
+
*
|
|
80
|
+
* Bis 0.8.0 trug dieses Modell nur den Hobex-Block, mit der Begruendung, die
|
|
81
|
+
* uebrigen Anbieter druckten "in ihren eigenen Apps". Das Argument gilt fuer
|
|
82
|
+
* die Frage, wer das TERMINAL bedient -- nicht dafuer, was auf dem
|
|
83
|
+
* BELEGDOKUMENT steht. Aus der einen Regel wurde die andere, und damit
|
|
84
|
+
* verschwanden vier Bloecke: Wer denselben Beleg als PDF oeffnete, sah "nur
|
|
85
|
+
* Kartenzahlung", waehrend der Bon daneben Marke, letzte Ziffern, Betrag und
|
|
86
|
+
* Referenz auswies. Vorher (backend `generateReceiptPdf`) hatte das PDF alle
|
|
87
|
+
* sieben Anbieter.
|
|
88
|
+
*
|
|
89
|
+
* Gebaut werden die Zeilen deshalb hier, an genau EINER Stelle. Wer sie
|
|
90
|
+
* anderswo noch einmal baut, oeffnet die Drift wieder.
|
|
91
|
+
*
|
|
92
|
+
* Vorbild ist `print_paper.dart` im Dart-Paket (`_gpTom`, `_hobexHps`,
|
|
93
|
+
* `_sumup`, `_mypos`, `_stripe`); die Fixtures unter `fixtures/belege/karte-*`
|
|
94
|
+
* halten je Anbieter eine Zeile-fuer-Zeile-Probe fest.
|
|
95
|
+
*/
|
|
96
|
+
/** Ein Feld aus `cardPaymentData` als Text; fehlend/null wird leer. */
|
|
97
|
+
function kartenFeld(daten, schluessel) {
|
|
98
|
+
const v = daten[schluessel];
|
|
99
|
+
return v == null ? '' : String(v);
|
|
100
|
+
}
|
|
101
|
+
/** Nicht-leere Teile mit Mittelpunkt verbinden. */
|
|
102
|
+
function verbunden(teile) {
|
|
103
|
+
return teile.filter(Boolean).join(' · ');
|
|
104
|
+
}
|
|
74
105
|
/**
|
|
75
106
|
* Kartenzahlungsblock fuer Hobex (HPS am Geraet wie Cloud-API): die Felder
|
|
76
107
|
* kommen aus `cardPaymentData` in der Form von [hobexReceiptToCardPaymentData]
|
|
@@ -78,43 +109,234 @@ function originalDatum(timeStamp) {
|
|
|
78
109
|
* Antwortcode. Bei CVM "1" verlangt die Karte eine Unterschrift; dafuer
|
|
79
110
|
* bekommt der Bon eine Linie. Der PAN haengt beim HPS das Ablaufdatum mit
|
|
80
111
|
* Unterstrich an ("…4720_2810") — gedruckt wird nur die maskierte Nummer.
|
|
81
|
-
*
|
|
82
|
-
* Andere Anbieter (GP Tom, SumUp, myPOS, Stripe) drucken in ihren eigenen
|
|
83
|
-
* Apps; ihre Bloecke bleiben bewusst draussen (siehe Kopfkommentar).
|
|
84
112
|
*/
|
|
85
|
-
function
|
|
86
|
-
const
|
|
87
|
-
const daten = receipt.cardPaymentData;
|
|
88
|
-
if ((provider !== 'hobexHps' && provider !== 'hobexCloudApi') || daten == null) {
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
91
|
-
const feld = (k) => {
|
|
92
|
-
const v = daten[k];
|
|
93
|
-
return v == null ? '' : String(v);
|
|
94
|
-
};
|
|
95
|
-
const paar = (teile) => teile.filter(Boolean).join(' · ');
|
|
96
|
-
const pan = feld('cardNumber').split('_')[0] ?? '';
|
|
97
|
-
const rc = feld('responseCode');
|
|
113
|
+
function hobexBlock(daten) {
|
|
114
|
+
const feld = (k) => kartenFeld(daten, k);
|
|
98
115
|
const zeilen = [textZeile('Hobex Beleg', 'center', true)];
|
|
99
116
|
const inhalt = [
|
|
100
117
|
feld('date'),
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
verbunden([feld('tid') && `TID ${feld('tid')}`, feld('no') && `Nr. ${feld('no')}`]),
|
|
119
|
+
verbunden([feld('type'), feld('cardBrand')]),
|
|
120
|
+
feld('cardNumber').split('_')[0] ?? '',
|
|
121
|
+
feld('responseCode') && `RC ${feld('responseCode')}`,
|
|
122
|
+
];
|
|
123
|
+
for (const zeile of inhalt) {
|
|
124
|
+
if (zeile)
|
|
125
|
+
zeilen.push(textZeile(zeile, 'center'));
|
|
126
|
+
}
|
|
127
|
+
if (feld('cvm') === '1')
|
|
128
|
+
zeilen.push(...unterschriftsfeld());
|
|
129
|
+
return zeilen;
|
|
130
|
+
}
|
|
131
|
+
/** Zwei Leerzeilen, Linie, Wort -- das Unterschriftsfeld auf dem Bon. */
|
|
132
|
+
function unterschriftsfeld() {
|
|
133
|
+
return [
|
|
134
|
+
{ kind: 'space', lines: 2 },
|
|
135
|
+
textZeile('------------------', 'center'),
|
|
136
|
+
textZeile('Unterschrift', 'center'),
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* GP-Tom-`transactionType`: das Plugin-`toMap` schreibt den Schluessel mit
|
|
141
|
+
* Tippfehler (`transacitonType`), aeltere Daten tragen ihn gar nicht. Beide
|
|
142
|
+
* Schreibweisen werden gelesen -- ein Beleg von damals soll nicht anders
|
|
143
|
+
* aussehen als einer von heute.
|
|
144
|
+
*/
|
|
145
|
+
function gpTomVorgangsart(daten) {
|
|
146
|
+
switch (daten.transactionType ?? daten.transacitonType) {
|
|
147
|
+
case 1: return 'Sale';
|
|
148
|
+
case 2: return 'Void';
|
|
149
|
+
case 3: return 'Refund';
|
|
150
|
+
case 4: return 'Close Batch';
|
|
151
|
+
default: return '';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** GP-Tom-Betrag: ganze Zahl = Cent, sonst schon ein Eurobetrag. */
|
|
155
|
+
function gpTomBetrag(wert) {
|
|
156
|
+
if (typeof wert !== 'number')
|
|
157
|
+
return '-';
|
|
158
|
+
return Number.isInteger(wert) ? formatCents(wert) : wert.toFixed(2).replace('.', ',');
|
|
159
|
+
}
|
|
160
|
+
function gpTomBlock(daten) {
|
|
161
|
+
const feld = (k) => kartenFeld(daten, k);
|
|
162
|
+
const art = gpTomVorgangsart(daten);
|
|
163
|
+
const zeilen = [textZeile('GP Tom Beleg', 'center', true)];
|
|
164
|
+
const inhalt = [
|
|
165
|
+
`Batch: ${feld('batchNumber')}`,
|
|
166
|
+
`Receipt: ${feld('externalTransactionID')}`,
|
|
167
|
+
`TID: ${feld('terminalID')}`,
|
|
168
|
+
feld('emvAid'),
|
|
169
|
+
(daten.emvAppLable != null || daten.cardDataEntry != null)
|
|
170
|
+
? `${feld('emvAppLable')} ${feld('cardDataEntry')}`.trim() : '',
|
|
171
|
+
feld('cardNumber'),
|
|
172
|
+
`${art ? `${art} ` : ''}Amount ${feld('currencyCode')} ${gpTomBetrag(daten.amount)}`,
|
|
173
|
+
daten.pinOk === true ? 'PIN OK' : 'PIN NOT OK',
|
|
174
|
+
`Authorization Code ${feld('approvedCode')}`,
|
|
175
|
+
`Sequence Number: ${feld('sequenceNumber')}`,
|
|
105
176
|
];
|
|
106
177
|
for (const zeile of inhalt) {
|
|
107
178
|
if (zeile)
|
|
108
179
|
zeilen.push(textZeile(zeile, 'center'));
|
|
109
180
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
181
|
+
return zeilen;
|
|
182
|
+
}
|
|
183
|
+
function sumupBlock(daten) {
|
|
184
|
+
const feld = (k) => kartenFeld(daten, k);
|
|
185
|
+
const betrag = typeof daten.amount === 'number'
|
|
186
|
+
? (Number.isInteger(daten.amount) ? formatCents(daten.amount) : daten.amount.toFixed(2).replace('.', ','))
|
|
187
|
+
: '-';
|
|
188
|
+
return [
|
|
189
|
+
textZeile('Sumup Beleg', 'center', true),
|
|
190
|
+
paarZeile('Kartentyp:', feld('cardType') || 'n/a'),
|
|
191
|
+
paarZeile('Kartennummer:', `**** **** **** ${feld('cardLastDigits')}`),
|
|
192
|
+
paarZeile('Zahlungstyp:', feld('paymentType') || 'n/a'),
|
|
193
|
+
paarZeile('Gesamtbetrag:', `${betrag} ${feld('currency')}`.trim()),
|
|
194
|
+
paarZeile('Transaktionscode:', feld('transactionCode') || '-'),
|
|
195
|
+
paarZeile('Modus:', feld('entryMode').toUpperCase()),
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* myPOS liefert den Zeitpunkt als `YYMMDDhhmmss` ohne Trenner. Ein Wert, der
|
|
200
|
+
* nicht so aussieht, wird UNVERAENDERT durchgereicht statt zerschnitten: eine
|
|
201
|
+
* halb geratene Uhrzeit auf einem Beleg ist schlimmer als ein roher Wert.
|
|
202
|
+
*/
|
|
203
|
+
function myposZeitpunkt(wert) {
|
|
204
|
+
const t = /^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/.exec(wert);
|
|
205
|
+
if (!t)
|
|
206
|
+
return wert;
|
|
207
|
+
return `${t[3]}.${t[2]}.20${t[1]} ${t[4]}:${t[5]}:${t[6]}`;
|
|
208
|
+
}
|
|
209
|
+
function myposBlock(daten) {
|
|
210
|
+
const feld = (k) => kartenFeld(daten, k);
|
|
211
|
+
const zeilen = [
|
|
212
|
+
textZeile('MyPos Beleg', 'center', true),
|
|
213
|
+
paarZeile('TERMINAL ID:', feld('TID') || '-'),
|
|
214
|
+
paarZeile('DATUM:', myposZeitpunkt(feld('date_time'))),
|
|
215
|
+
];
|
|
216
|
+
if (feld('application_name'))
|
|
217
|
+
zeilen.push(textZeile(feld('application_name'), 'center', true));
|
|
218
|
+
zeilen.push(paarZeile('KARTE:', feld('pan') || '-'));
|
|
219
|
+
if (daten.signature_required === true)
|
|
220
|
+
zeilen.push(...unterschriftsfeld());
|
|
221
|
+
zeilen.push(paarZeile('STAN:', feld('STAN') ? feld('STAN').padStart(6, '0') : '-'));
|
|
222
|
+
zeilen.push(paarZeile('AUTH. CODE:', feld('authorization_code') || '-'));
|
|
223
|
+
zeilen.push(paarZeile('RRN:', feld('reference_number') || '-'));
|
|
224
|
+
zeilen.push(paarZeile('AID:', feld('AID') || '-'));
|
|
225
|
+
return zeilen;
|
|
226
|
+
}
|
|
227
|
+
const STRIPE_KARTENART = {
|
|
228
|
+
debit: 'Debitkarte',
|
|
229
|
+
credit: 'Kreditkarte',
|
|
230
|
+
prepaid: 'Prepaid-Karte',
|
|
231
|
+
};
|
|
232
|
+
const STRIPE_WALLET = {
|
|
233
|
+
apple_pay: 'Apple Pay',
|
|
234
|
+
google_pay: 'Google Pay',
|
|
235
|
+
};
|
|
236
|
+
/** EPS-Bank-Slug (`bank_austria`) -> Anzeigename (`Bank Austria`). */
|
|
237
|
+
function stripeEpsBank(slug) {
|
|
238
|
+
return slug.split('_').filter(Boolean)
|
|
239
|
+
.map((w) => w[0].toUpperCase() + w.slice(1)).join(' ');
|
|
240
|
+
}
|
|
241
|
+
function stripeMarkenZeile(daten) {
|
|
242
|
+
const teile = [];
|
|
243
|
+
if (daten.cardBrand != null)
|
|
244
|
+
teile.push(String(daten.cardBrand));
|
|
245
|
+
const art = STRIPE_KARTENART[String(daten.cardFunding)];
|
|
246
|
+
if (art)
|
|
247
|
+
teile.push(art);
|
|
248
|
+
let zeile = teile.join(' ');
|
|
249
|
+
if (daten.wallet != null) {
|
|
250
|
+
const wallet = STRIPE_WALLET[String(daten.wallet)] ?? String(daten.wallet);
|
|
251
|
+
zeile = zeile ? `${zeile} (${wallet})` : `(${wallet})`;
|
|
252
|
+
}
|
|
253
|
+
return zeile;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Stripe-Zahlzeitpunkt: Sekunden seit Epoche, gedruckt in **Wiener** Zeit.
|
|
257
|
+
* Ueber `toViennaWallClock`, nicht ueber die lokale Zeitzone -- ein Beleg
|
|
258
|
+
* traegt Ortszeit des Betriebs, nicht die des Geraets, das ihn oeffnet.
|
|
259
|
+
*/
|
|
260
|
+
function stripeZeitpunkt(sekunden) {
|
|
261
|
+
const t = (0, vienna_time_js_1.toViennaWallClock)(new Date(sekunden * 1000));
|
|
262
|
+
const zwei = (n) => String(n).padStart(2, '0');
|
|
263
|
+
return `${zwei(t.day)}.${zwei(t.month)}.${t.year} ${zwei(t.hour)}:${zwei(t.minute)}`;
|
|
264
|
+
}
|
|
265
|
+
/** Zwilling von `stripeReceiptLines` (print_paper.dart). */
|
|
266
|
+
function stripeReceiptLines(daten, cardPaymentId) {
|
|
267
|
+
const zeilen = [];
|
|
268
|
+
const art = daten.paymentMethodType == null ? null : String(daten.paymentMethodType);
|
|
269
|
+
if (art === 'card') {
|
|
270
|
+
const marke = stripeMarkenZeile(daten);
|
|
271
|
+
if (marke)
|
|
272
|
+
zeilen.push(marke);
|
|
273
|
+
if (daten.cardLastDigits != null)
|
|
274
|
+
zeilen.push(`**** **** **** ${daten.cardLastDigits}`);
|
|
275
|
+
if (daten.threeDSecure === 'authenticated')
|
|
276
|
+
zeilen.push('3-D Secure: ja');
|
|
277
|
+
}
|
|
278
|
+
else if (art === 'eps') {
|
|
279
|
+
if (daten.epsBank != null)
|
|
280
|
+
zeilen.push(`EPS - ${stripeEpsBank(String(daten.epsBank))}`);
|
|
281
|
+
}
|
|
282
|
+
else if (art != null) {
|
|
283
|
+
zeilen.push(art.toUpperCase());
|
|
284
|
+
}
|
|
285
|
+
if (typeof daten.amount === 'number' && Number.isInteger(daten.amount)) {
|
|
286
|
+
const waehrung = daten.currency == null ? 'EUR' : String(daten.currency).toUpperCase();
|
|
287
|
+
zeilen.push(`Gesamtbetrag ${formatCents(daten.amount)} ${waehrung}`);
|
|
288
|
+
}
|
|
289
|
+
if (typeof daten.paidAt === 'number' && Number.isInteger(daten.paidAt)) {
|
|
290
|
+
zeilen.push(`Bezahlt: ${stripeZeitpunkt(daten.paidAt)}`);
|
|
291
|
+
}
|
|
292
|
+
if (daten.statementDescriptor != null)
|
|
293
|
+
zeilen.push(`Abrechnung: ${daten.statementDescriptor}`);
|
|
294
|
+
if (cardPaymentId != null)
|
|
295
|
+
zeilen.push(`Referenz: ${cardPaymentId}`);
|
|
296
|
+
return zeilen;
|
|
297
|
+
}
|
|
298
|
+
function stripeBlock(daten, cardPaymentId) {
|
|
299
|
+
const zeilen = [textZeile('Online-Zahlung (Stripe)', 'center', true)];
|
|
300
|
+
for (const zeile of stripeReceiptLines(daten, cardPaymentId)) {
|
|
301
|
+
zeilen.push(textZeile(zeile, 'center'));
|
|
114
302
|
}
|
|
115
|
-
zeilen.push({ kind: 'space', lines: 1 });
|
|
116
303
|
return zeilen;
|
|
117
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Der Kartenzahlungsblock des Belegs -- fuer JEDEN Anbieter, den das Backend
|
|
307
|
+
* kennt. Ohne `cardPaymentData` bleibt der Block weg; ein unbekannter Anbieter
|
|
308
|
+
* ebenfalls, still und ohne Fehler: ein Beleg muss sich immer zeigen lassen.
|
|
309
|
+
*/
|
|
310
|
+
function kartenblock(receipt) {
|
|
311
|
+
const daten = receipt.cardPaymentData;
|
|
312
|
+
if (daten == null)
|
|
313
|
+
return [];
|
|
314
|
+
const zeilen = (() => {
|
|
315
|
+
switch (receipt.creditCardProvider) {
|
|
316
|
+
case 'hobexHps':
|
|
317
|
+
case 'hobexCloudApi':
|
|
318
|
+
return hobexBlock(daten);
|
|
319
|
+
case 'gpTomAndroid':
|
|
320
|
+
case 'gpTomIos':
|
|
321
|
+
return gpTomBlock(daten);
|
|
322
|
+
case 'sumup':
|
|
323
|
+
return sumupBlock(daten);
|
|
324
|
+
case 'myposPro':
|
|
325
|
+
return myposBlock(daten);
|
|
326
|
+
case 'stripe':
|
|
327
|
+
return stripeBlock(daten, receipt.cardPaymentId ?? null);
|
|
328
|
+
default:
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
})();
|
|
332
|
+
if (zeilen.length === 0)
|
|
333
|
+
return [];
|
|
334
|
+
// Eine Leerzeile hinter JEDEM Block, nicht nur hinter manchen. Das Vorbild
|
|
335
|
+
// ist hier uneinheitlich (nur `_sumup` setzt am Ende ein `addFeed()`), was
|
|
336
|
+
// den Abstand zur Fusszeile vom Anbieter abhaengig machte. Die Leerzeile
|
|
337
|
+
// gehoert aber zum Blatt, nicht zum Terminal.
|
|
338
|
+
return [...zeilen, { kind: 'space', lines: 1 }];
|
|
339
|
+
}
|
|
118
340
|
function zahlungsartText(wert) {
|
|
119
341
|
if (wert != null && typeof wert === 'object') {
|
|
120
342
|
return wert.label;
|
|
@@ -708,7 +930,7 @@ function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
708
930
|
lines.push({ kind: 'qr', data: receipt.qr });
|
|
709
931
|
lines.push({ kind: 'space', lines: 1 });
|
|
710
932
|
// --- Kartenzahlungsblock (Hobex) — wie im Vorbild UNTER dem QR-Code.
|
|
711
|
-
lines.push(...
|
|
933
|
+
lines.push(...kartenblock(receipt));
|
|
712
934
|
// --- Dankestext und Fusszeilen
|
|
713
935
|
if (company.thanksMessage.length > 0) {
|
|
714
936
|
lines.push({ kind: 'space', lines: 1 });
|
|
@@ -124,6 +124,17 @@ declare const MELDUNGEN_ROH: {
|
|
|
124
124
|
readonly text: "Unklar, ob die Kartenzahlung durchgegangen ist — die Verbindung zum Terminal riss ab. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird: die Karte kann belastet sein. Kennung der Zahlung: {kennung}.";
|
|
125
125
|
readonly platzhalter: readonly ["kennung"];
|
|
126
126
|
};
|
|
127
|
+
readonly 'kartenzahlung.wartet_auf_terminal': {
|
|
128
|
+
readonly text: "Bitte am Terminal fortfahren …";
|
|
129
|
+
};
|
|
130
|
+
readonly 'kartenzahlung.karte_gebucht_beleg_offen': {
|
|
131
|
+
readonly text: "Die Karte ist bereits mit {betrag} belastet (Kennung {kennung}) — der Beleg dazu fehlt noch. Bitte jetzt den Beleg erstellen und nicht erneut kassieren.";
|
|
132
|
+
readonly platzhalter: readonly ["betrag", "kennung"];
|
|
133
|
+
};
|
|
134
|
+
readonly 'kartenzahlung.karte_gebucht_korb_geaendert': {
|
|
135
|
+
readonly text: "Es gibt eine gebuchte Kartenzahlung über {betrag} (Kennung {kennung}), aber der Korb hat sich seither geändert. Bitte zuerst entscheiden: den Beleg zur gebuchten Zahlung erstellen oder die Zahlung am Terminal stornieren und hier verwerfen.";
|
|
136
|
+
readonly platzhalter: readonly ["betrag", "kennung"];
|
|
137
|
+
};
|
|
127
138
|
readonly 'kartenzahlung.connect_nicht_verbunden': {
|
|
128
139
|
readonly text: "Kartenzahlung nicht möglich: Kasseneck Connect ist nicht verbunden — Einstellungen → Kasseneck Connect.";
|
|
129
140
|
readonly nur: readonly ["web"];
|
|
@@ -161,6 +172,34 @@ declare const MELDUNGEN_ROH: {
|
|
|
161
172
|
readonly platzhalter: readonly ["code"];
|
|
162
173
|
readonly nur: readonly ["app"];
|
|
163
174
|
};
|
|
175
|
+
readonly 'gptom.abgelehnt': {
|
|
176
|
+
readonly text: "Das Terminal hat die Zahlung abgelehnt.";
|
|
177
|
+
readonly nur: readonly ["app"];
|
|
178
|
+
};
|
|
179
|
+
readonly 'gptom.abgelehnt_mit_code': {
|
|
180
|
+
readonly text: "Das Terminal hat die Zahlung abgelehnt ({code}).";
|
|
181
|
+
readonly platzhalter: readonly ["code"];
|
|
182
|
+
readonly nur: readonly ["app"];
|
|
183
|
+
};
|
|
184
|
+
readonly 'gptom.nicht_geoeffnet': {
|
|
185
|
+
readonly text: "GP Tom ließ sich nicht öffnen — bitte die GP-Tom-App prüfen und erneut versuchen.";
|
|
186
|
+
readonly nur: readonly ["app"];
|
|
187
|
+
};
|
|
188
|
+
readonly 'gptom.zeit_abgelaufen': {
|
|
189
|
+
readonly text: "Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird.";
|
|
190
|
+
readonly nur: readonly ["app"];
|
|
191
|
+
};
|
|
192
|
+
readonly 'gptom.zeit_abgelaufen_mit_kennung': {
|
|
193
|
+
readonly text: "Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird. Kennung der Zahlung: {kennung}.";
|
|
194
|
+
readonly platzhalter: readonly ["kennung"];
|
|
195
|
+
readonly nur: readonly ["app"];
|
|
196
|
+
};
|
|
197
|
+
readonly 'protokoll.leer': {
|
|
198
|
+
readonly text: "Noch keine Einträge — das Protokoll füllt sich mit der ersten Kartenzahlung.";
|
|
199
|
+
};
|
|
200
|
+
readonly 'protokoll.kopiert': {
|
|
201
|
+
readonly text: "Das Protokoll liegt in der Zwischenablage.";
|
|
202
|
+
};
|
|
164
203
|
readonly 'belege.laden_fehlgeschlagen': {
|
|
165
204
|
readonly text: "Die Belege konnten nicht geladen werden.";
|
|
166
205
|
};
|
package/dist/esm/kasse/texte.js
CHANGED
|
@@ -54,6 +54,13 @@ const MELDUNGEN_ROH = {
|
|
|
54
54
|
'kartenzahlung.unklar': { text: 'Unklar, ob die Kartenzahlung durchgegangen ist — die Verbindung zum Terminal riss ab. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird: die Karte kann belastet sein.' },
|
|
55
55
|
// Die Kennung ist der einzige Anker, um die Zahlung am Terminal-Beleg wiederzufinden — liegt sie vor, gilt dieser Satz statt kartenzahlung.unklar.
|
|
56
56
|
'kartenzahlung.unklar_mit_kennung': { text: 'Unklar, ob die Kartenzahlung durchgegangen ist — die Verbindung zum Terminal riss ab. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird: die Karte kann belastet sein. Kennung der Zahlung: {kennung}.', platzhalter: ['kennung'] },
|
|
57
|
+
'kartenzahlung.wartet_auf_terminal': { text: 'Bitte am Terminal fortfahren …' },
|
|
58
|
+
// Ein geglücktes Kartenergebnis ohne Beleg ist der teuerste Zustand am Tresen:
|
|
59
|
+
// wer hier erneut kassiert, belastet die Karte ein zweites Mal. Beide Sätze
|
|
60
|
+
// nennen deshalb Betrag UND Kennung — nur damit findet der Kassier die Zahlung
|
|
61
|
+
// am Terminal-Beleg wieder — und keiner rät zum Wiederholen.
|
|
62
|
+
'kartenzahlung.karte_gebucht_beleg_offen': { text: 'Die Karte ist bereits mit {betrag} belastet (Kennung {kennung}) — der Beleg dazu fehlt noch. Bitte jetzt den Beleg erstellen und nicht erneut kassieren.', platzhalter: ['betrag', 'kennung'] },
|
|
63
|
+
'kartenzahlung.karte_gebucht_korb_geaendert': { text: 'Es gibt eine gebuchte Kartenzahlung über {betrag} (Kennung {kennung}), aber der Korb hat sich seither geändert. Bitte zuerst entscheiden: den Beleg zur gebuchten Zahlung erstellen oder die Zahlung am Terminal stornieren und hier verwerfen.', platzhalter: ['betrag', 'kennung'] },
|
|
57
64
|
'kartenzahlung.connect_nicht_verbunden': { text: 'Kartenzahlung nicht möglich: Kasseneck Connect ist nicht verbunden — Einstellungen → Kasseneck Connect.', nur: ['web'] },
|
|
58
65
|
'terminal.keines_gefunden': { text: 'Kein Hobex-Terminal gefunden — ist es eingeschaltet und im selben Netz wie dieser Rechner?', nur: ['web'] },
|
|
59
66
|
'terminal.nicht_bereit': { text: 'Terminal antwortet, ist aber nicht betriebsbereit: {antwort} — TID prüfen.', platzhalter: ['antwort'], nur: ['web'] },
|
|
@@ -62,6 +69,19 @@ const MELDUNGEN_ROH = {
|
|
|
62
69
|
'gptom.zahlung_fehlgeschlagen': { text: 'GP Tom: Zahlung fehlgeschlagen: {grund}', platzhalter: ['grund'], nur: ['app'] },
|
|
63
70
|
'gptom.terminal_antwortet_nicht': { text: 'Das Terminal hat nicht geantwortet: {grund}', platzhalter: ['grund'], nur: ['app'] },
|
|
64
71
|
'gptom.zahlung_nicht_abgeschlossen': { text: 'Die Zahlung wurde nicht abgeschlossen ({code}).', platzhalter: ['code'], nur: ['app'] },
|
|
72
|
+
// Abgelehnt heißt: das Terminal hat entschieden, es ist sicher nichts gebucht.
|
|
73
|
+
// Der Code ist die einzige Handhabe, mit der der Inhaber bei GP nachfragen kann —
|
|
74
|
+
// liegt einer vor, gilt die Fassung mit Code.
|
|
75
|
+
'gptom.abgelehnt': { text: 'Das Terminal hat die Zahlung abgelehnt.', nur: ['app'] },
|
|
76
|
+
'gptom.abgelehnt_mit_code': { text: 'Das Terminal hat die Zahlung abgelehnt ({code}).', platzhalter: ['code'], nur: ['app'] },
|
|
77
|
+
'gptom.nicht_geoeffnet': { text: 'GP Tom ließ sich nicht öffnen — bitte die GP-Tom-App prüfen und erneut versuchen.', nur: ['app'] },
|
|
78
|
+
// Frist abgelaufen ist kein Abbruch: die Karte kann belastet sein, nur die
|
|
79
|
+
// Antwort blieb aus. Deshalb derselbe Ton wie kartenzahlung.unklar.
|
|
80
|
+
'gptom.zeit_abgelaufen': { text: 'Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird.', nur: ['app'] },
|
|
81
|
+
'gptom.zeit_abgelaufen_mit_kennung': { text: 'Das Terminal hat in der Frist nicht geantwortet — die Karte kann belastet sein. Bitte am Terminal-Beleg nachsehen, BEVOR neu kassiert wird. Kennung der Zahlung: {kennung}.', platzhalter: ['kennung'], nur: ['app'] },
|
|
82
|
+
// --- Terminal-Protokoll --------------------------------------------------
|
|
83
|
+
'protokoll.leer': { text: 'Noch keine Einträge — das Protokoll füllt sich mit der ersten Kartenzahlung.' },
|
|
84
|
+
'protokoll.kopiert': { text: 'Das Protokoll liegt in der Zwischenablage.' },
|
|
65
85
|
// --- Belege und Storno ---------------------------------------------------
|
|
66
86
|
'belege.laden_fehlgeschlagen': { text: 'Die Belege konnten nicht geladen werden.' },
|
|
67
87
|
'belege.keine_im_zeitraum': { text: 'Keine Belege in diesem Zeitraum.' },
|
|
@@ -22,11 +22,15 @@ import type { PosPaperSize } from '../printing/escpos.js';
|
|
|
22
22
|
*
|
|
23
23
|
* Bewusst **nicht** enthalten: Firmenlogo und Rasterbilder (brauchen
|
|
24
24
|
* Bildverarbeitung, die im Browser anders aussieht als in Node), PDF-Erzeugung
|
|
25
|
-
* und Druckeransteuerung.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
25
|
+
* und Druckeransteuerung.
|
|
26
|
+
*
|
|
27
|
+
* Die anbieterspezifischen Kartenzahlungsbloecke sind dagegen **alle**
|
|
28
|
+
* enthalten (Hobex, GP Tom, SumUp, myPOS, Stripe). Bis 0.8.0 trug das Modell
|
|
29
|
+
* nur den Hobex-Block, weil die Browser-Kasse nur das HPS-Terminal selbst
|
|
30
|
+
* bedient und die uebrigen Anbieter „in ihren eigenen Apps drucken". Das
|
|
31
|
+
* Argument gilt fuer die Frage, wer das TERMINAL bedient — nicht dafuer, was
|
|
32
|
+
* auf dem BELEGDOKUMENT steht. Aus der einen Regel wurde die andere, und
|
|
33
|
+
* derselbe Beleg trug im PDF weniger als auf dem Bon.
|
|
30
34
|
*/
|
|
31
35
|
/** Ausrichtung einer Zeile bzw. einer Spalte. */
|
|
32
36
|
export type LayoutAlign = 'left' | 'center' | 'right';
|
|
@@ -129,6 +133,8 @@ export interface BuildReceiptLayoutOptions {
|
|
|
129
133
|
* diesem Paket ausnahmslos ganzzahlig gerechnet).
|
|
130
134
|
*/
|
|
131
135
|
export declare function formatCents(cents: number): string;
|
|
136
|
+
/** Zwilling von `stripeReceiptLines` (print_paper.dart). */
|
|
137
|
+
export declare function stripeReceiptLines(daten: Record<string, unknown>, cardPaymentId: string | null): string[];
|
|
132
138
|
/**
|
|
133
139
|
* Hinweis auf die Steuerbefreiung, den ein Kleinunternehmerbeleg tragen muss —
|
|
134
140
|
* ohne ihn stuende in der USt-Tabelle „D 0 %" ohne jede Begruendung, und ab
|