@kreiseck/kasseneck-api 0.9.1 → 0.9.2

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 CHANGED
@@ -4,6 +4,62 @@ 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.2
8
+
9
+ ### Sechzehn Saetze: einen Beleg weitergeben, und der Drucker-Wizard
10
+
11
+ **Anlass:** Ein alter Beleg soll sich weitergeben lassen — Link kopieren,
12
+ teilen, per E-Mail senden — und der Drucker richtet sich kuenftig ueber einen
13
+ Wizard ein, der erst testet und bestaetigen laesst und dann speichert. Beides
14
+ entsteht **gleichzeitig** in der Browser-Kasse und in der Kassen-App. Ohne
15
+ diese Schluessel haetten beide Seiten dieselben sieben Lagen unabhaengig
16
+ formuliert, und der Kassier haette zwei verschiedene Woerter fuer dieselbe
17
+ Sache gelesen — genau das, wogegen es diesen Katalog gibt.
18
+
19
+ - **Beleg weitergeben:** `beleg.link_kopiert`, `beleg.teilen_text`
20
+ (`betrieb`, `nummer`, `betrag`, `link`), `beleg.nicht_teilbar`,
21
+ `beleg.test_hinweis_teilen`.
22
+ - **Per E-Mail senden:** `beleg.mail_gesendet` (`an`) und die vier Ausgaenge
23
+ `beleg.mail_adresse_ungueltig`, `beleg.mail_zu_oft`,
24
+ `beleg.mail_fehlgeschlagen`, `beleg.mail_nicht_gefunden`.
25
+ - **Drucker-Wizard** (beide Kassen, deshalb ohne `nur`):
26
+ `druck.wizard_verbinden` (`name`), `druck.wizard_testdruck_frage`,
27
+ `druck.wizard_qr_frage`, `druck.wizard_qr_keiner_hinweis`,
28
+ `druck.wizard_nichts_gekommen`, `druck.wizard_gespeichert` (`name`),
29
+ `druck.wizard_abgebrochen`.
30
+
31
+ **Neu: `BELEG_MAIL_FEHLER` und `belegMailFehler(code)`** — die Zuordnung vom
32
+ `code` des Backends (`adresse_ungueltig`, `zu_oft`, `versand_fehlgeschlagen`,
33
+ `beleg_nicht_gefunden`) auf den Satz. Grund: die vier Ausgaenge verlangen vom
34
+ Kassier vier verschiedene Handlungen, und beide Kassen sollen am **Code**
35
+ entscheiden statt an einer Formulierung, die sich im Backend jederzeit aendern
36
+ darf. Ein unbekannter Code faellt auf `beleg.mail_fehlgeschlagen` zurueck — ein
37
+ leerer Schirm waere schlimmer als ein zu allgemeiner Satz. Die Zuordnung steht
38
+ als `belegMailFehler` mit in `fixtures/kasse-texte.json`, weil die App den
39
+ Katalog aus dem Tarball liest und das Web die Quelle direkt importiert.
40
+
41
+ Bewusst ein Objekt und **keine** Liste in Grossschrift: der
42
+ Oberflaechen-Vertrag liest jede exportierte Liste als Enum der
43
+ Kasseneinstellungen ein, und der Dart-Zwilling schickt deren Werte durch
44
+ `KasseSettings.aus`. Fehlercodes haetten dort nichts verloren.
45
+
46
+ **Abweichung von der Vorlage, bewusst:** `beleg.mail_nicht_gefunden` sagt
47
+ „Dieser Beleg wurde nicht gefunden — er konnte nicht gesendet werden." und
48
+ nicht denselben Satz wie das schon vorhandene `beleg.nicht_gefunden`. Dort
49
+ scheitert das Oeffnen, hier das Senden; der Kassier steht vor einem Adressfeld
50
+ und muss lesen, dass nichts hinausgegangen ist. Ein Satz zweimal im Katalog
51
+ faellt ohnehin schon seit 0.9.1 im Test auf.
52
+
53
+ **Neue abgeleitete Pruefungen:** kein Satz zum Weitergeben eines Belegs ist an
54
+ eine Seite gebunden; der Teilen-Text traegt den Link, und zwar am Schluss;
55
+ jeder platzhalterlose `beleg.mail_`-Satz haengt an genau einem Backend-Code (und
56
+ kein Code an zweien); der einzige `beleg.mail_`-Satz mit Platzhalter ist der
57
+ ueber das Gelingen; jeder Satz des Wizards gilt auf beiden Seiten.
58
+
59
+ `FEHLERREGELN` bleibt unveraendert: die Codes sind die Verfeinerung **eines**
60
+ Aufrufs (`sendReceiptEmail`), keine neue Art, einen Transportfehler
61
+ einzuordnen.
62
+
7
63
  ## 0.9.1
8
64
 
9
65
  ### Elf Saetze fuer die vier Ausgaenge einer Kartenzahlung und das Terminal-Protokoll
@@ -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, type Meldung, type MeldungsSchluessel, type Fehlerart, type Seite, } from './texte.js';
13
+ export { MELDUNGEN, FEHLERREGELN, meldung, meldungGiltFuer, BELEG_MAIL_FEHLER, belegMailFehler, type Meldung, type MeldungsSchluessel, type Fehlerart, type Seite, type BelegMailFehlercode, } from './texte.js';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPrintJob = 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.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.meldungGiltFuer = exports.meldung = exports.FEHLERREGELN = exports.MELDUNGEN = exports.listMyTipRecipients = void 0;
4
+ exports.belegMailFehler = exports.BELEG_MAIL_FEHLER = exports.meldungGiltFuer = exports.meldung = exports.FEHLERREGELN = exports.MELDUNGEN = exports.listMyTipRecipients = 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
@@ -74,3 +74,5 @@ Object.defineProperty(exports, "MELDUNGEN", { enumerable: true, get: function ()
74
74
  Object.defineProperty(exports, "FEHLERREGELN", { enumerable: true, get: function () { return texte_js_1.FEHLERREGELN; } });
75
75
  Object.defineProperty(exports, "meldung", { enumerable: true, get: function () { return texte_js_1.meldung; } });
76
76
  Object.defineProperty(exports, "meldungGiltFuer", { enumerable: true, get: function () { return texte_js_1.meldungGiltFuer; } });
77
+ Object.defineProperty(exports, "BELEG_MAIL_FEHLER", { enumerable: true, get: function () { return texte_js_1.BELEG_MAIL_FEHLER; } });
78
+ Object.defineProperty(exports, "belegMailFehler", { enumerable: true, get: function () { return texte_js_1.belegMailFehler; } });
@@ -221,6 +221,35 @@ declare const MELDUNGEN_ROH: {
221
221
  readonly 'storno.position_fehlt': {
222
222
  readonly text: "Bitte mindestens eine Position wählen.";
223
223
  };
224
+ readonly 'beleg.link_kopiert': {
225
+ readonly text: "Der Link zum Beleg liegt in der Zwischenablage.";
226
+ };
227
+ readonly 'beleg.teilen_text': {
228
+ readonly text: "Beleg {nummer} von {betrieb} über {betrag}: {link}";
229
+ readonly platzhalter: readonly ["betrieb", "nummer", "betrag", "link"];
230
+ };
231
+ readonly 'beleg.nicht_teilbar': {
232
+ readonly text: "Für diesen Beleg gibt es keinen Link — er stammt aus einer älteren Kasse.";
233
+ };
234
+ readonly 'beleg.test_hinweis_teilen': {
235
+ readonly text: "Test-Umgebung — der Beleg ist steuerlich nicht gültig.";
236
+ };
237
+ readonly 'beleg.mail_gesendet': {
238
+ readonly text: "Der Beleg wurde an {an} gesendet.";
239
+ readonly platzhalter: readonly ["an"];
240
+ };
241
+ readonly 'beleg.mail_adresse_ungueltig': {
242
+ readonly text: "Diese E-Mail-Adresse ist nicht gültig.";
243
+ };
244
+ readonly 'beleg.mail_zu_oft': {
245
+ readonly text: "Dieser Beleg wurde schon oft gesendet — bitte später noch einmal.";
246
+ };
247
+ readonly 'beleg.mail_fehlgeschlagen': {
248
+ readonly text: "Der Beleg konnte nicht gesendet werden. Bitte noch einmal versuchen.";
249
+ };
250
+ readonly 'beleg.mail_nicht_gefunden': {
251
+ readonly text: "Dieser Beleg wurde nicht gefunden — er konnte nicht gesendet werden.";
252
+ };
224
253
  readonly 'druck.fehlgeschlagen': {
225
254
  readonly text: "Der Ausdruck ist fehlgeschlagen.";
226
255
  };
@@ -259,6 +288,29 @@ declare const MELDUNGEN_ROH: {
259
288
  readonly platzhalter: readonly ["weg"];
260
289
  readonly nur: readonly ["web"];
261
290
  };
291
+ readonly 'druck.wizard_verbinden': {
292
+ readonly text: "Verbinde mit {name} …";
293
+ readonly platzhalter: readonly ["name"];
294
+ };
295
+ readonly 'druck.wizard_testdruck_frage': {
296
+ readonly text: "Ist der Testdruck gekommen?";
297
+ };
298
+ readonly 'druck.wizard_qr_frage': {
299
+ readonly text: "Welcher QR-Code ist sauber gedruckt?";
300
+ };
301
+ readonly 'druck.wizard_qr_keiner_hinweis': {
302
+ readonly text: "Kein QR-Code kam sauber — der Beleg zeigt den QR-Code dann am Bildschirm.";
303
+ };
304
+ readonly 'druck.wizard_nichts_gekommen': {
305
+ readonly text: "Nichts gekommen? Drucker an, Papier drin, richtiges Gerät gewählt?";
306
+ };
307
+ readonly 'druck.wizard_gespeichert': {
308
+ readonly text: "{name} ist eingerichtet.";
309
+ readonly platzhalter: readonly ["name"];
310
+ };
311
+ readonly 'druck.wizard_abgebrochen': {
312
+ readonly text: "Nichts gespeichert.";
313
+ };
262
314
  readonly 'bluetooth.aus': {
263
315
  readonly text: "Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.";
264
316
  readonly nur: readonly ["app"];
@@ -368,6 +420,37 @@ export declare const FEHLERREGELN: readonly [{
368
420
  readonly verhalten: "ersatz";
369
421
  }];
370
422
  export type Fehlerart = (typeof FEHLERREGELN)[number]['art'];
423
+ /**
424
+ * Beleg per E-Mail senden: welcher `code` des Backends welchen Satz bekommt.
425
+ *
426
+ * `FEHLERREGELN` bleibt davon unberuehrt — das hier ist keine neue Art, einen
427
+ * Transportfehler einzuordnen, sondern die Verfeinerung EINES Aufrufs
428
+ * (`sendReceiptEmail`). Die vier Ausgaenge sind fuer den Kassier vier
429
+ * verschiedene Handlungen: Adresse verbessern, spaeter noch einmal, noch
430
+ * einmal senden, Beleg suchen. Beide Kassen entscheiden am `code`, nicht am
431
+ * Satz des Backends — sonst haengt das Wort am Tresen an einer Formulierung,
432
+ * die sich im Backend jederzeit aendern darf.
433
+ *
434
+ * Bewusst ein Objekt und keine Liste in GROSSSCHRIFT: der
435
+ * Oberflaechen-Vertrag (`fixtures/oberflaeche.json`) liest jede exportierte
436
+ * Liste als Enum der Kasseneinstellungen ein, und der Dart-Zwilling schickt
437
+ * deren Werte durch `KasseSettings.aus`. Fehlercodes haben dort nichts
438
+ * verloren; sie stehen in `fixtures/kasse-texte.json`.
439
+ */
440
+ export declare const BELEG_MAIL_FEHLER: {
441
+ readonly adresse_ungueltig: "beleg.mail_adresse_ungueltig";
442
+ readonly zu_oft: "beleg.mail_zu_oft";
443
+ readonly versand_fehlgeschlagen: "beleg.mail_fehlgeschlagen";
444
+ readonly beleg_nicht_gefunden: "beleg.mail_nicht_gefunden";
445
+ };
446
+ export type BelegMailFehlercode = keyof typeof BELEG_MAIL_FEHLER;
447
+ /**
448
+ * Der Satz zu einem `code` des Backends. Einen Code, den dieses Paket noch
449
+ * nicht kennt, faengt der allgemeine Satz auf: das Senden ist gescheitert und
450
+ * darf wiederholt werden. Ein leerer Schirm waere schlimmer als ein zu
451
+ * allgemeiner Satz.
452
+ */
453
+ export declare function belegMailFehler(code: string | undefined | null): MeldungsSchluessel;
371
454
  /** Der Satz zum Schluessel, Platzhalter ersetzt. Fehlt ein Wert, wirft es — ein `{status}` am Tresen waere schlimmer. */
372
455
  export declare function meldung(schluessel: MeldungsSchluessel, werte?: Record<string, string | number>): string;
373
456
  /** Gilt der Satz auf dieser Seite? */
@@ -16,7 +16,8 @@
16
16
  * auf einer Plattform vorkommen kann.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.FEHLERREGELN = exports.MELDUNGEN = void 0;
19
+ exports.BELEG_MAIL_FEHLER = exports.FEHLERREGELN = exports.MELDUNGEN = void 0;
20
+ exports.belegMailFehler = belegMailFehler;
20
21
  exports.meldung = meldung;
21
22
  exports.meldungGiltFuer = meldungGiltFuer;
22
23
  const MELDUNGEN_ROH = {
@@ -95,6 +96,30 @@ const MELDUNGEN_ROH = {
95
96
  'storno.fehlgeschlagen': { text: 'Das Storno ist fehlgeschlagen.' },
96
97
  'storno.grund_fehlt': { text: 'Bitte einen Grund wählen.' },
97
98
  'storno.position_fehlt': { text: 'Bitte mindestens eine Position wählen.' },
99
+ // --- Beleg weitergeben: Link, Teilen, E-Mail -----------------------------
100
+ // Kopieren, Teilen und Senden fuehren zu demselben Ziel: der oeffentlichen
101
+ // Belegseite (beleg.kasseneck.at/<fullReceiptId>). Kein Satz davon ist
102
+ // plattformgebunden — nur die Huelle unterscheidet sich, nicht das Wort.
103
+ 'beleg.link_kopiert': { text: 'Der Link zum Beleg liegt in der Zwischenablage.' },
104
+ // Der Text, der beim Teilen mitgeht. Der Link steht am Schluss, damit ihn
105
+ // jede Huelle (SMS, Messenger, Mail) bis zum Ende als Link erkennt und nicht
106
+ // mitten im Satz abbricht.
107
+ 'beleg.teilen_text': { text: 'Beleg {nummer} von {betrieb} über {betrag}: {link}', platzhalter: ['betrieb', 'nummer', 'betrag', 'link'] },
108
+ // Belege aus dem Altbestand tragen keine `fullReceiptId`; ohne sie gibt es
109
+ // keine Belegseite. Der Satz nennt den Grund, sonst sucht der Kassier den
110
+ // Fehler bei sich und versucht es ein zweites Mal.
111
+ 'beleg.nicht_teilbar': { text: 'Für diesen Beleg gibt es keinen Link — er stammt aus einer älteren Kasse.' },
112
+ // Ein Testbeleg hat eine Belegseite, ist aber steuerlich nichts wert. Wer
113
+ // den Link weitergibt, muss das vorher lesen, nicht hinterher.
114
+ 'beleg.test_hinweis_teilen': { text: 'Test-Umgebung — der Beleg ist steuerlich nicht gültig.' },
115
+ 'beleg.mail_gesendet': { text: 'Der Beleg wurde an {an} gesendet.', platzhalter: ['an'] },
116
+ 'beleg.mail_adresse_ungueltig': { text: 'Diese E-Mail-Adresse ist nicht gültig.' },
117
+ 'beleg.mail_zu_oft': { text: 'Dieser Beleg wurde schon oft gesendet — bitte später noch einmal.' },
118
+ 'beleg.mail_fehlgeschlagen': { text: 'Der Beleg konnte nicht gesendet werden. Bitte noch einmal versuchen.' },
119
+ // Bewusst nicht derselbe Satz wie `beleg.nicht_gefunden`: dort scheitert das
120
+ // Oeffnen, hier das Senden. Der Kassier steht vor einem Adressfeld und muss
121
+ // lesen, dass nichts hinausgegangen ist.
122
+ 'beleg.mail_nicht_gefunden': { text: 'Dieser Beleg wurde nicht gefunden — er konnte nicht gesendet werden.' },
98
123
  // --- Druck ---------------------------------------------------------------
99
124
  'druck.fehlgeschlagen': { text: 'Der Ausdruck ist fehlgeschlagen.' },
100
125
  'druck.nicht_moeglich': { text: 'Druck nicht möglich: {grund}', platzhalter: ['grund'] },
@@ -106,6 +131,22 @@ const MELDUNGEN_ROH = {
106
131
  'druck.kein_drucker_gefunden': { text: 'Kein Drucker gefunden — ist er eingeschaltet und im selben Netz wie dieser Rechner?', nur: ['web'] },
107
132
  'druck.nur_chrome': { text: '{weg}-Druck geht nur in Chrome oder Edge (Windows, Mac, Android) — nicht in Safari und nicht am iPad.', platzhalter: ['weg'], nur: ['web'] },
108
133
  'druck.kein_weg_drucker': { text: 'Kein {weg}-Drucker verbunden — „{weg}-Drucker verbinden“ und den Drucker im Dialog wählen.', platzhalter: ['weg'], nur: ['web'] },
134
+ // Der Drucker-Wizard: suchen, verbinden, Testdruck, QR-Probe, erst dann
135
+ // speichern. Derselbe Ablauf in beiden Kassen — deshalb hat kein Satz ein
136
+ // `nur`, obwohl der Weg zum Drucker verschieden ist (Bluetooth in der App,
137
+ // Web Bluetooth im Browser). Was der Chef liest, ist beidesmal dasselbe.
138
+ 'druck.wizard_verbinden': { text: 'Verbinde mit {name} …', platzhalter: ['name'] },
139
+ 'druck.wizard_testdruck_frage': { text: 'Ist der Testdruck gekommen?' },
140
+ 'druck.wizard_qr_frage': { text: 'Welcher QR-Code ist sauber gedruckt?' },
141
+ // Kein Modus druckt einen lesbaren QR-Code: gespeichert wird trotzdem (mit
142
+ // Raster als Vorgabe), aber der Chef muss wissen, dass der QR-Code dann vom
143
+ // Bildschirm gelesen werden muss — nach RKSV gehoert er an den Beleg.
144
+ 'druck.wizard_qr_keiner_hinweis': { text: 'Kein QR-Code kam sauber — der Beleg zeigt den QR-Code dann am Bildschirm.' },
145
+ 'druck.wizard_nichts_gekommen': { text: 'Nichts gekommen? Drucker an, Papier drin, richtiges Gerät gewählt?' },
146
+ 'druck.wizard_gespeichert': { text: '{name} ist eingerichtet.', platzhalter: ['name'] },
147
+ // Abbrechen an jeder Stelle: nichts gespeichert. Der Satz sagt genau das,
148
+ // damit niemand einen halb eingerichteten Drucker vermutet.
149
+ 'druck.wizard_abgebrochen': { text: 'Nichts gespeichert.' },
109
150
  'bluetooth.aus': { text: 'Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.', nur: ['app'] },
110
151
  'bluetooth.freigabe_fehlt': { text: 'Bitte die Freigabe in den Geräte-Einstellungen erteilen.', nur: ['app'] },
111
152
  'bluetooth.suche_fehlgeschlagen': { text: 'Die Suche ist fehlgeschlagen: {grund}', platzhalter: ['grund'], nur: ['app'] },
@@ -153,6 +194,39 @@ exports.FEHLERREGELN = [
153
194
  { art: 'unerwartet', schluessel: 'server.unerwartet' },
154
195
  { art: 'sonst', verhalten: 'ersatz' },
155
196
  ];
197
+ /**
198
+ * Beleg per E-Mail senden: welcher `code` des Backends welchen Satz bekommt.
199
+ *
200
+ * `FEHLERREGELN` bleibt davon unberuehrt — das hier ist keine neue Art, einen
201
+ * Transportfehler einzuordnen, sondern die Verfeinerung EINES Aufrufs
202
+ * (`sendReceiptEmail`). Die vier Ausgaenge sind fuer den Kassier vier
203
+ * verschiedene Handlungen: Adresse verbessern, spaeter noch einmal, noch
204
+ * einmal senden, Beleg suchen. Beide Kassen entscheiden am `code`, nicht am
205
+ * Satz des Backends — sonst haengt das Wort am Tresen an einer Formulierung,
206
+ * die sich im Backend jederzeit aendern darf.
207
+ *
208
+ * Bewusst ein Objekt und keine Liste in GROSSSCHRIFT: der
209
+ * Oberflaechen-Vertrag (`fixtures/oberflaeche.json`) liest jede exportierte
210
+ * Liste als Enum der Kasseneinstellungen ein, und der Dart-Zwilling schickt
211
+ * deren Werte durch `KasseSettings.aus`. Fehlercodes haben dort nichts
212
+ * verloren; sie stehen in `fixtures/kasse-texte.json`.
213
+ */
214
+ exports.BELEG_MAIL_FEHLER = {
215
+ adresse_ungueltig: 'beleg.mail_adresse_ungueltig',
216
+ zu_oft: 'beleg.mail_zu_oft',
217
+ versand_fehlgeschlagen: 'beleg.mail_fehlgeschlagen',
218
+ beleg_nicht_gefunden: 'beleg.mail_nicht_gefunden',
219
+ };
220
+ /**
221
+ * Der Satz zu einem `code` des Backends. Einen Code, den dieses Paket noch
222
+ * nicht kennt, faengt der allgemeine Satz auf: das Senden ist gescheitert und
223
+ * darf wiederholt werden. Ein leerer Schirm waere schlimmer als ein zu
224
+ * allgemeiner Satz.
225
+ */
226
+ function belegMailFehler(code) {
227
+ const fehler = exports.BELEG_MAIL_FEHLER;
228
+ return (code !== undefined && code !== null && fehler[code]) || 'beleg.mail_fehlgeschlagen';
229
+ }
156
230
  /** Der Satz zum Schluessel, Platzhalter ersetzt. Fehlt ein Wert, wirft es — ein `{status}` am Tresen waere schlimmer. */
157
231
  function meldung(schluessel, werte = {}) {
158
232
  const eintrag = exports.MELDUNGEN[schluessel];
@@ -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, type Meldung, type MeldungsSchluessel, type Fehlerart, type Seite, } from './texte.js';
13
+ export { MELDUNGEN, FEHLERREGELN, meldung, meldungGiltFuer, BELEG_MAIL_FEHLER, belegMailFehler, type Meldung, type MeldungsSchluessel, type Fehlerart, type Seite, type BelegMailFehlercode, } from './texte.js';
@@ -15,4 +15,4 @@ export { cancelScopeOf, receiptsScopeOf } from '../register/pairing.js';
15
15
  export { listMyPrinters, createPrintJob, getPrintJob } from './drucker.js';
16
16
  export { listMyTipRecipients } from './trinkgeld.js';
17
17
  // Was die Kasse selbst sagt — ein Katalog fuer Browser-Kasse und App.
18
- export { MELDUNGEN, FEHLERREGELN, meldung, meldungGiltFuer, } from './texte.js';
18
+ export { MELDUNGEN, FEHLERREGELN, meldung, meldungGiltFuer, BELEG_MAIL_FEHLER, belegMailFehler, } from './texte.js';
@@ -221,6 +221,35 @@ declare const MELDUNGEN_ROH: {
221
221
  readonly 'storno.position_fehlt': {
222
222
  readonly text: "Bitte mindestens eine Position wählen.";
223
223
  };
224
+ readonly 'beleg.link_kopiert': {
225
+ readonly text: "Der Link zum Beleg liegt in der Zwischenablage.";
226
+ };
227
+ readonly 'beleg.teilen_text': {
228
+ readonly text: "Beleg {nummer} von {betrieb} über {betrag}: {link}";
229
+ readonly platzhalter: readonly ["betrieb", "nummer", "betrag", "link"];
230
+ };
231
+ readonly 'beleg.nicht_teilbar': {
232
+ readonly text: "Für diesen Beleg gibt es keinen Link — er stammt aus einer älteren Kasse.";
233
+ };
234
+ readonly 'beleg.test_hinweis_teilen': {
235
+ readonly text: "Test-Umgebung — der Beleg ist steuerlich nicht gültig.";
236
+ };
237
+ readonly 'beleg.mail_gesendet': {
238
+ readonly text: "Der Beleg wurde an {an} gesendet.";
239
+ readonly platzhalter: readonly ["an"];
240
+ };
241
+ readonly 'beleg.mail_adresse_ungueltig': {
242
+ readonly text: "Diese E-Mail-Adresse ist nicht gültig.";
243
+ };
244
+ readonly 'beleg.mail_zu_oft': {
245
+ readonly text: "Dieser Beleg wurde schon oft gesendet — bitte später noch einmal.";
246
+ };
247
+ readonly 'beleg.mail_fehlgeschlagen': {
248
+ readonly text: "Der Beleg konnte nicht gesendet werden. Bitte noch einmal versuchen.";
249
+ };
250
+ readonly 'beleg.mail_nicht_gefunden': {
251
+ readonly text: "Dieser Beleg wurde nicht gefunden — er konnte nicht gesendet werden.";
252
+ };
224
253
  readonly 'druck.fehlgeschlagen': {
225
254
  readonly text: "Der Ausdruck ist fehlgeschlagen.";
226
255
  };
@@ -259,6 +288,29 @@ declare const MELDUNGEN_ROH: {
259
288
  readonly platzhalter: readonly ["weg"];
260
289
  readonly nur: readonly ["web"];
261
290
  };
291
+ readonly 'druck.wizard_verbinden': {
292
+ readonly text: "Verbinde mit {name} …";
293
+ readonly platzhalter: readonly ["name"];
294
+ };
295
+ readonly 'druck.wizard_testdruck_frage': {
296
+ readonly text: "Ist der Testdruck gekommen?";
297
+ };
298
+ readonly 'druck.wizard_qr_frage': {
299
+ readonly text: "Welcher QR-Code ist sauber gedruckt?";
300
+ };
301
+ readonly 'druck.wizard_qr_keiner_hinweis': {
302
+ readonly text: "Kein QR-Code kam sauber — der Beleg zeigt den QR-Code dann am Bildschirm.";
303
+ };
304
+ readonly 'druck.wizard_nichts_gekommen': {
305
+ readonly text: "Nichts gekommen? Drucker an, Papier drin, richtiges Gerät gewählt?";
306
+ };
307
+ readonly 'druck.wizard_gespeichert': {
308
+ readonly text: "{name} ist eingerichtet.";
309
+ readonly platzhalter: readonly ["name"];
310
+ };
311
+ readonly 'druck.wizard_abgebrochen': {
312
+ readonly text: "Nichts gespeichert.";
313
+ };
262
314
  readonly 'bluetooth.aus': {
263
315
  readonly text: "Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.";
264
316
  readonly nur: readonly ["app"];
@@ -368,6 +420,37 @@ export declare const FEHLERREGELN: readonly [{
368
420
  readonly verhalten: "ersatz";
369
421
  }];
370
422
  export type Fehlerart = (typeof FEHLERREGELN)[number]['art'];
423
+ /**
424
+ * Beleg per E-Mail senden: welcher `code` des Backends welchen Satz bekommt.
425
+ *
426
+ * `FEHLERREGELN` bleibt davon unberuehrt — das hier ist keine neue Art, einen
427
+ * Transportfehler einzuordnen, sondern die Verfeinerung EINES Aufrufs
428
+ * (`sendReceiptEmail`). Die vier Ausgaenge sind fuer den Kassier vier
429
+ * verschiedene Handlungen: Adresse verbessern, spaeter noch einmal, noch
430
+ * einmal senden, Beleg suchen. Beide Kassen entscheiden am `code`, nicht am
431
+ * Satz des Backends — sonst haengt das Wort am Tresen an einer Formulierung,
432
+ * die sich im Backend jederzeit aendern darf.
433
+ *
434
+ * Bewusst ein Objekt und keine Liste in GROSSSCHRIFT: der
435
+ * Oberflaechen-Vertrag (`fixtures/oberflaeche.json`) liest jede exportierte
436
+ * Liste als Enum der Kasseneinstellungen ein, und der Dart-Zwilling schickt
437
+ * deren Werte durch `KasseSettings.aus`. Fehlercodes haben dort nichts
438
+ * verloren; sie stehen in `fixtures/kasse-texte.json`.
439
+ */
440
+ export declare const BELEG_MAIL_FEHLER: {
441
+ readonly adresse_ungueltig: "beleg.mail_adresse_ungueltig";
442
+ readonly zu_oft: "beleg.mail_zu_oft";
443
+ readonly versand_fehlgeschlagen: "beleg.mail_fehlgeschlagen";
444
+ readonly beleg_nicht_gefunden: "beleg.mail_nicht_gefunden";
445
+ };
446
+ export type BelegMailFehlercode = keyof typeof BELEG_MAIL_FEHLER;
447
+ /**
448
+ * Der Satz zu einem `code` des Backends. Einen Code, den dieses Paket noch
449
+ * nicht kennt, faengt der allgemeine Satz auf: das Senden ist gescheitert und
450
+ * darf wiederholt werden. Ein leerer Schirm waere schlimmer als ein zu
451
+ * allgemeiner Satz.
452
+ */
453
+ export declare function belegMailFehler(code: string | undefined | null): MeldungsSchluessel;
371
454
  /** Der Satz zum Schluessel, Platzhalter ersetzt. Fehlt ein Wert, wirft es — ein `{status}` am Tresen waere schlimmer. */
372
455
  export declare function meldung(schluessel: MeldungsSchluessel, werte?: Record<string, string | number>): string;
373
456
  /** Gilt der Satz auf dieser Seite? */
@@ -90,6 +90,30 @@ const MELDUNGEN_ROH = {
90
90
  'storno.fehlgeschlagen': { text: 'Das Storno ist fehlgeschlagen.' },
91
91
  'storno.grund_fehlt': { text: 'Bitte einen Grund wählen.' },
92
92
  'storno.position_fehlt': { text: 'Bitte mindestens eine Position wählen.' },
93
+ // --- Beleg weitergeben: Link, Teilen, E-Mail -----------------------------
94
+ // Kopieren, Teilen und Senden fuehren zu demselben Ziel: der oeffentlichen
95
+ // Belegseite (beleg.kasseneck.at/<fullReceiptId>). Kein Satz davon ist
96
+ // plattformgebunden — nur die Huelle unterscheidet sich, nicht das Wort.
97
+ 'beleg.link_kopiert': { text: 'Der Link zum Beleg liegt in der Zwischenablage.' },
98
+ // Der Text, der beim Teilen mitgeht. Der Link steht am Schluss, damit ihn
99
+ // jede Huelle (SMS, Messenger, Mail) bis zum Ende als Link erkennt und nicht
100
+ // mitten im Satz abbricht.
101
+ 'beleg.teilen_text': { text: 'Beleg {nummer} von {betrieb} über {betrag}: {link}', platzhalter: ['betrieb', 'nummer', 'betrag', 'link'] },
102
+ // Belege aus dem Altbestand tragen keine `fullReceiptId`; ohne sie gibt es
103
+ // keine Belegseite. Der Satz nennt den Grund, sonst sucht der Kassier den
104
+ // Fehler bei sich und versucht es ein zweites Mal.
105
+ 'beleg.nicht_teilbar': { text: 'Für diesen Beleg gibt es keinen Link — er stammt aus einer älteren Kasse.' },
106
+ // Ein Testbeleg hat eine Belegseite, ist aber steuerlich nichts wert. Wer
107
+ // den Link weitergibt, muss das vorher lesen, nicht hinterher.
108
+ 'beleg.test_hinweis_teilen': { text: 'Test-Umgebung — der Beleg ist steuerlich nicht gültig.' },
109
+ 'beleg.mail_gesendet': { text: 'Der Beleg wurde an {an} gesendet.', platzhalter: ['an'] },
110
+ 'beleg.mail_adresse_ungueltig': { text: 'Diese E-Mail-Adresse ist nicht gültig.' },
111
+ 'beleg.mail_zu_oft': { text: 'Dieser Beleg wurde schon oft gesendet — bitte später noch einmal.' },
112
+ 'beleg.mail_fehlgeschlagen': { text: 'Der Beleg konnte nicht gesendet werden. Bitte noch einmal versuchen.' },
113
+ // Bewusst nicht derselbe Satz wie `beleg.nicht_gefunden`: dort scheitert das
114
+ // Oeffnen, hier das Senden. Der Kassier steht vor einem Adressfeld und muss
115
+ // lesen, dass nichts hinausgegangen ist.
116
+ 'beleg.mail_nicht_gefunden': { text: 'Dieser Beleg wurde nicht gefunden — er konnte nicht gesendet werden.' },
93
117
  // --- Druck ---------------------------------------------------------------
94
118
  'druck.fehlgeschlagen': { text: 'Der Ausdruck ist fehlgeschlagen.' },
95
119
  'druck.nicht_moeglich': { text: 'Druck nicht möglich: {grund}', platzhalter: ['grund'] },
@@ -101,6 +125,22 @@ const MELDUNGEN_ROH = {
101
125
  'druck.kein_drucker_gefunden': { text: 'Kein Drucker gefunden — ist er eingeschaltet und im selben Netz wie dieser Rechner?', nur: ['web'] },
102
126
  'druck.nur_chrome': { text: '{weg}-Druck geht nur in Chrome oder Edge (Windows, Mac, Android) — nicht in Safari und nicht am iPad.', platzhalter: ['weg'], nur: ['web'] },
103
127
  'druck.kein_weg_drucker': { text: 'Kein {weg}-Drucker verbunden — „{weg}-Drucker verbinden“ und den Drucker im Dialog wählen.', platzhalter: ['weg'], nur: ['web'] },
128
+ // Der Drucker-Wizard: suchen, verbinden, Testdruck, QR-Probe, erst dann
129
+ // speichern. Derselbe Ablauf in beiden Kassen — deshalb hat kein Satz ein
130
+ // `nur`, obwohl der Weg zum Drucker verschieden ist (Bluetooth in der App,
131
+ // Web Bluetooth im Browser). Was der Chef liest, ist beidesmal dasselbe.
132
+ 'druck.wizard_verbinden': { text: 'Verbinde mit {name} …', platzhalter: ['name'] },
133
+ 'druck.wizard_testdruck_frage': { text: 'Ist der Testdruck gekommen?' },
134
+ 'druck.wizard_qr_frage': { text: 'Welcher QR-Code ist sauber gedruckt?' },
135
+ // Kein Modus druckt einen lesbaren QR-Code: gespeichert wird trotzdem (mit
136
+ // Raster als Vorgabe), aber der Chef muss wissen, dass der QR-Code dann vom
137
+ // Bildschirm gelesen werden muss — nach RKSV gehoert er an den Beleg.
138
+ 'druck.wizard_qr_keiner_hinweis': { text: 'Kein QR-Code kam sauber — der Beleg zeigt den QR-Code dann am Bildschirm.' },
139
+ 'druck.wizard_nichts_gekommen': { text: 'Nichts gekommen? Drucker an, Papier drin, richtiges Gerät gewählt?' },
140
+ 'druck.wizard_gespeichert': { text: '{name} ist eingerichtet.', platzhalter: ['name'] },
141
+ // Abbrechen an jeder Stelle: nichts gespeichert. Der Satz sagt genau das,
142
+ // damit niemand einen halb eingerichteten Drucker vermutet.
143
+ 'druck.wizard_abgebrochen': { text: 'Nichts gespeichert.' },
104
144
  'bluetooth.aus': { text: 'Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.', nur: ['app'] },
105
145
  'bluetooth.freigabe_fehlt': { text: 'Bitte die Freigabe in den Geräte-Einstellungen erteilen.', nur: ['app'] },
106
146
  'bluetooth.suche_fehlgeschlagen': { text: 'Die Suche ist fehlgeschlagen: {grund}', platzhalter: ['grund'], nur: ['app'] },
@@ -148,6 +188,39 @@ export const FEHLERREGELN = [
148
188
  { art: 'unerwartet', schluessel: 'server.unerwartet' },
149
189
  { art: 'sonst', verhalten: 'ersatz' },
150
190
  ];
191
+ /**
192
+ * Beleg per E-Mail senden: welcher `code` des Backends welchen Satz bekommt.
193
+ *
194
+ * `FEHLERREGELN` bleibt davon unberuehrt — das hier ist keine neue Art, einen
195
+ * Transportfehler einzuordnen, sondern die Verfeinerung EINES Aufrufs
196
+ * (`sendReceiptEmail`). Die vier Ausgaenge sind fuer den Kassier vier
197
+ * verschiedene Handlungen: Adresse verbessern, spaeter noch einmal, noch
198
+ * einmal senden, Beleg suchen. Beide Kassen entscheiden am `code`, nicht am
199
+ * Satz des Backends — sonst haengt das Wort am Tresen an einer Formulierung,
200
+ * die sich im Backend jederzeit aendern darf.
201
+ *
202
+ * Bewusst ein Objekt und keine Liste in GROSSSCHRIFT: der
203
+ * Oberflaechen-Vertrag (`fixtures/oberflaeche.json`) liest jede exportierte
204
+ * Liste als Enum der Kasseneinstellungen ein, und der Dart-Zwilling schickt
205
+ * deren Werte durch `KasseSettings.aus`. Fehlercodes haben dort nichts
206
+ * verloren; sie stehen in `fixtures/kasse-texte.json`.
207
+ */
208
+ export const BELEG_MAIL_FEHLER = {
209
+ adresse_ungueltig: 'beleg.mail_adresse_ungueltig',
210
+ zu_oft: 'beleg.mail_zu_oft',
211
+ versand_fehlgeschlagen: 'beleg.mail_fehlgeschlagen',
212
+ beleg_nicht_gefunden: 'beleg.mail_nicht_gefunden',
213
+ };
214
+ /**
215
+ * Der Satz zu einem `code` des Backends. Einen Code, den dieses Paket noch
216
+ * nicht kennt, faengt der allgemeine Satz auf: das Senden ist gescheitert und
217
+ * darf wiederholt werden. Ein leerer Schirm waere schlimmer als ein zu
218
+ * allgemeiner Satz.
219
+ */
220
+ export function belegMailFehler(code) {
221
+ const fehler = BELEG_MAIL_FEHLER;
222
+ return (code !== undefined && code !== null && fehler[code]) || 'beleg.mail_fehlgeschlagen';
223
+ }
151
224
  /** Der Satz zum Schluessel, Platzhalter ersetzt. Fehlt ein Wert, wirft es — ein `{status}` am Tresen waere schlimmer. */
152
225
  export function meldung(schluessel, werte = {}) {
153
226
  const eintrag = MELDUNGEN[schluessel];
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.9.1",
2
+ "version": "0.9.2",
3
3
  "gemessenAn": {
4
4
  "tid": "3600335",
5
5
  "hpsVersion": "1.10.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.9.1",
2
+ "version": "0.9.2",
3
3
  "meldungen": {
4
4
  "netz.keine_verbindung": {
5
5
  "text": "Keine Verbindung zum Server. Bitte die Internetverbindung prüfen und erneut versuchen."
@@ -255,6 +255,42 @@
255
255
  "storno.position_fehlt": {
256
256
  "text": "Bitte mindestens eine Position wählen."
257
257
  },
258
+ "beleg.link_kopiert": {
259
+ "text": "Der Link zum Beleg liegt in der Zwischenablage."
260
+ },
261
+ "beleg.teilen_text": {
262
+ "text": "Beleg {nummer} von {betrieb} über {betrag}: {link}",
263
+ "platzhalter": [
264
+ "betrieb",
265
+ "nummer",
266
+ "betrag",
267
+ "link"
268
+ ]
269
+ },
270
+ "beleg.nicht_teilbar": {
271
+ "text": "Für diesen Beleg gibt es keinen Link — er stammt aus einer älteren Kasse."
272
+ },
273
+ "beleg.test_hinweis_teilen": {
274
+ "text": "Test-Umgebung — der Beleg ist steuerlich nicht gültig."
275
+ },
276
+ "beleg.mail_gesendet": {
277
+ "text": "Der Beleg wurde an {an} gesendet.",
278
+ "platzhalter": [
279
+ "an"
280
+ ]
281
+ },
282
+ "beleg.mail_adresse_ungueltig": {
283
+ "text": "Diese E-Mail-Adresse ist nicht gültig."
284
+ },
285
+ "beleg.mail_zu_oft": {
286
+ "text": "Dieser Beleg wurde schon oft gesendet — bitte später noch einmal."
287
+ },
288
+ "beleg.mail_fehlgeschlagen": {
289
+ "text": "Der Beleg konnte nicht gesendet werden. Bitte noch einmal versuchen."
290
+ },
291
+ "beleg.mail_nicht_gefunden": {
292
+ "text": "Dieser Beleg wurde nicht gefunden — er konnte nicht gesendet werden."
293
+ },
258
294
  "druck.fehlgeschlagen": {
259
295
  "text": "Der Ausdruck ist fehlgeschlagen."
260
296
  },
@@ -309,6 +345,33 @@
309
345
  "web"
310
346
  ]
311
347
  },
348
+ "druck.wizard_verbinden": {
349
+ "text": "Verbinde mit {name} …",
350
+ "platzhalter": [
351
+ "name"
352
+ ]
353
+ },
354
+ "druck.wizard_testdruck_frage": {
355
+ "text": "Ist der Testdruck gekommen?"
356
+ },
357
+ "druck.wizard_qr_frage": {
358
+ "text": "Welcher QR-Code ist sauber gedruckt?"
359
+ },
360
+ "druck.wizard_qr_keiner_hinweis": {
361
+ "text": "Kein QR-Code kam sauber — der Beleg zeigt den QR-Code dann am Bildschirm."
362
+ },
363
+ "druck.wizard_nichts_gekommen": {
364
+ "text": "Nichts gekommen? Drucker an, Papier drin, richtiges Gerät gewählt?"
365
+ },
366
+ "druck.wizard_gespeichert": {
367
+ "text": "{name} ist eingerichtet.",
368
+ "platzhalter": [
369
+ "name"
370
+ ]
371
+ },
372
+ "druck.wizard_abgebrochen": {
373
+ "text": "Nichts gespeichert."
374
+ },
312
375
  "bluetooth.aus": {
313
376
  "text": "Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.",
314
377
  "nur": [
@@ -440,5 +503,11 @@
440
503
  "art": "sonst",
441
504
  "verhalten": "ersatz"
442
505
  }
443
- ]
506
+ ],
507
+ "belegMailFehler": {
508
+ "adresse_ungueltig": "beleg.mail_adresse_ungueltig",
509
+ "zu_oft": "beleg.mail_zu_oft",
510
+ "versand_fehlgeschlagen": "beleg.mail_fehlgeschlagen",
511
+ "beleg_nicht_gefunden": "beleg.mail_nicht_gefunden"
512
+ }
444
513
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.9.1",
2
+ "version": "0.9.2",
3
3
  "aufrufe": [
4
4
  "activateCashregister",
5
5
  "cancelReceipt",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kreiseck/kasseneck-api",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "JavaScript-Zwilling von kasseneck_api (Flutter) fuer das Kasseneck-Backend",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Kreiseck",