@kreiseck/kasseneck-api 0.6.9 → 0.6.45
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/README.md +21 -0
- package/dist/cjs/client/aufrufe.d.ts +21 -0
- package/dist/cjs/client/aufrufe.js +34 -0
- package/dist/cjs/client/cashregisters.d.ts +2 -2
- package/dist/cjs/client/index.d.ts +2 -1
- package/dist/cjs/client/index.js +3 -1
- package/dist/cjs/client/receipts.d.ts +31 -12
- package/dist/cjs/client/receipts.js +51 -0
- package/dist/cjs/client/reports.d.ts +3 -3
- package/dist/cjs/client/status.d.ts +3 -3
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/kasse/artikel.d.ts +3 -3
- package/dist/cjs/kasse/client.d.ts +4 -4
- package/dist/cjs/kasse/drucker.d.ts +4 -4
- package/dist/cjs/kasse/index.d.ts +1 -1
- package/dist/cjs/kasse/index.js +30 -1
- package/dist/cjs/kasse/settings.d.ts +113 -26
- package/dist/cjs/kasse/settings.js +91 -9
- package/dist/cjs/models/index.d.ts +1 -1
- package/dist/cjs/models/index.js +3 -1
- package/dist/cjs/models/receipt-item.d.ts +41 -0
- package/dist/cjs/models/receipt-item.js +41 -1
- package/dist/cjs/models/receipt.d.ts +7 -0
- package/dist/cjs/models/receipt.js +2 -0
- package/dist/cjs/payments/hobex.d.ts +3 -3
- package/dist/cjs/payments/stripe.d.ts +3 -3
- package/dist/cjs/printing/escpos.js +7 -0
- package/dist/cjs/react/index.js +11 -1
- package/dist/cjs/receipt/discount.js +1 -1
- package/dist/cjs/receipt/layout-escpos.js +9 -4
- package/dist/cjs/receipt/layout.d.ts +6 -3
- package/dist/cjs/receipt/layout.js +166 -14
- package/dist/cjs/register/index.d.ts +1 -1
- package/dist/cjs/register/index.js +2 -1
- package/dist/cjs/register/pairing.d.ts +17 -0
- package/dist/cjs/register/pairing.js +28 -3
- package/dist/cjs/register/session.d.ts +3 -3
- package/dist/esm/client/aufrufe.d.ts +21 -0
- package/dist/esm/client/aufrufe.js +31 -0
- package/dist/esm/client/cashregisters.d.ts +2 -2
- package/dist/esm/client/index.d.ts +2 -1
- package/dist/esm/client/index.js +1 -0
- package/dist/esm/client/receipts.d.ts +31 -12
- package/dist/esm/client/receipts.js +51 -0
- package/dist/esm/client/reports.d.ts +3 -3
- package/dist/esm/client/status.d.ts +3 -3
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/kasse/artikel.d.ts +3 -3
- package/dist/esm/kasse/client.d.ts +4 -4
- package/dist/esm/kasse/drucker.d.ts +4 -4
- package/dist/esm/kasse/index.d.ts +1 -1
- package/dist/esm/kasse/index.js +3 -1
- package/dist/esm/kasse/settings.d.ts +113 -26
- package/dist/esm/kasse/settings.js +90 -8
- package/dist/esm/models/index.d.ts +1 -1
- package/dist/esm/models/index.js +1 -1
- package/dist/esm/models/receipt-item.d.ts +41 -0
- package/dist/esm/models/receipt-item.js +39 -1
- package/dist/esm/models/receipt.d.ts +7 -0
- package/dist/esm/models/receipt.js +2 -0
- package/dist/esm/payments/hobex.d.ts +3 -3
- package/dist/esm/payments/stripe.d.ts +3 -3
- package/dist/esm/printing/escpos.js +7 -0
- package/dist/esm/react/index.js +11 -1
- package/dist/esm/receipt/discount.js +1 -1
- package/dist/esm/receipt/layout-escpos.js +9 -4
- package/dist/esm/receipt/layout.d.ts +6 -3
- package/dist/esm/receipt/layout.js +167 -15
- package/dist/esm/register/index.d.ts +1 -1
- package/dist/esm/register/index.js +1 -1
- package/dist/esm/register/pairing.d.ts +17 -0
- package/dist/esm/register/pairing.js +27 -3
- package/dist/esm/register/session.d.ts +3 -3
- package/fixtures/belege/rabatt-chef-trinkgeld.json +89 -0
- package/fixtures/belege/rabatt-einfach.json +50 -0
- package/fixtures/belege/rabatt-trinkgeld.json +75 -0
- package/fixtures/belege/rabatt-wertgutschein.json +70 -0
- package/fixtures/belege/rabattzeilen.json +5 -3
- package/fixtures/belege/storno-rabatt.json +68 -0
- package/fixtures/erwartet/rabatt-chef-trinkgeld.grid32.txt +31 -0
- package/fixtures/erwartet/rabatt-chef-trinkgeld.grid48.txt +30 -0
- package/fixtures/erwartet/rabatt-chef-trinkgeld.lines.json +317 -0
- package/fixtures/erwartet/rabatt-einfach.grid32.txt +26 -0
- package/fixtures/erwartet/rabatt-einfach.grid48.txt +25 -0
- package/fixtures/erwartet/rabatt-einfach.lines.json +250 -0
- package/fixtures/erwartet/rabatt-trinkgeld.grid32.txt +31 -0
- package/fixtures/erwartet/rabatt-trinkgeld.grid48.txt +30 -0
- package/fixtures/erwartet/rabatt-trinkgeld.lines.json +336 -0
- package/fixtures/erwartet/rabatt-wertgutschein.grid32.txt +32 -0
- package/fixtures/erwartet/rabatt-wertgutschein.grid48.txt +31 -0
- package/fixtures/erwartet/rabatt-wertgutschein.lines.json +330 -0
- package/fixtures/erwartet/rabattzeilen.grid32.txt +4 -2
- package/fixtures/erwartet/rabattzeilen.grid48.txt +4 -2
- package/fixtures/erwartet/rabattzeilen.lines.json +18 -8
- package/fixtures/erwartet/storno-rabatt.grid32.txt +34 -0
- package/fixtures/erwartet/storno-rabatt.grid48.txt +32 -0
- package/fixtures/erwartet/storno-rabatt.lines.json +317 -0
- package/fixtures/kasse-settings-standard.json +44 -5
- package/fixtures/manifest.json +34 -4
- package/fixtures/oberflaeche.json +216 -0
- package/package.json +3 -2
|
@@ -49,6 +49,6 @@ function verteileRabatt(positionen, rabattCents, name = 'Rabatt') {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
return liste
|
|
52
|
-
.map((g, i) => ({ name, quantity: 1, vat: g.vat, priceCents: -anteile[i] }))
|
|
52
|
+
.map((g, i) => ({ name, quantity: 1, vat: g.vat, priceCents: -anteile[i], kind: 'discount' }))
|
|
53
53
|
.filter((z) => z.priceCents < 0);
|
|
54
54
|
}
|
|
@@ -50,11 +50,16 @@ function escPosLayoutBytes(layout, options = {}) {
|
|
|
50
50
|
case 'qr':
|
|
51
51
|
(0, index_js_1.escPosQrCode)(doc, zeile.qr ?? '', qrOptionen);
|
|
52
52
|
break;
|
|
53
|
-
case 'banner':
|
|
54
|
-
// Belegart/Warnung: fett
|
|
55
|
-
//
|
|
56
|
-
|
|
53
|
+
case 'banner': {
|
|
54
|
+
// Belegart/Warnung: fett zwischen zwei Volllinien — derselbe Rahmen-
|
|
55
|
+
// Stil wie im Beleg-Viewer und im PDF (frueher druckte der Bon invers
|
|
56
|
+
// weiss-auf-schwarz und sah damit anders aus als jede Anzeige).
|
|
57
|
+
const rahmen = '='.repeat(grid_js_1.ZEICHEN_JE_PAPIER[paperSize]);
|
|
58
|
+
(0, index_js_1.escPosText)(doc, rahmen, { styles: { align: 'left', bold: true } });
|
|
59
|
+
(0, index_js_1.escPosText)(doc, zeile.text.trimEnd(), { styles: { align: 'left', bold: true, height: 2 } });
|
|
60
|
+
(0, index_js_1.escPosText)(doc, rahmen, { styles: { align: 'left', bold: true } });
|
|
57
61
|
break;
|
|
62
|
+
}
|
|
58
63
|
default:
|
|
59
64
|
(0, index_js_1.escPosText)(doc, zeile.text.trimEnd(), { styles: { align: 'left', bold: zeile.bold } });
|
|
60
65
|
break;
|
|
@@ -21,9 +21,12 @@ import type { PosPaperSize } from '../printing/escpos.js';
|
|
|
21
21
|
* stuende auch auf dem Bildschirm „EUR".
|
|
22
22
|
*
|
|
23
23
|
* Bewusst **nicht** enthalten: Firmenlogo und Rasterbilder (brauchen
|
|
24
|
-
* Bildverarbeitung, die im Browser anders aussieht als in Node), PDF-Erzeugung
|
|
25
|
-
* Druckeransteuerung
|
|
26
|
-
* Vorbilds (GP Tom,
|
|
24
|
+
* Bildverarbeitung, die im Browser anders aussieht als in Node), PDF-Erzeugung
|
|
25
|
+
* und Druckeransteuerung. Von den anbieterspezifischen Kartenzahlungsbloecken
|
|
26
|
+
* des Vorbilds (GP Tom, SumUp, myPOS, Stripe) ist nur der **Hobex-Block**
|
|
27
|
+
* enthalten: die Browser-Kasse bedient das HPS-Terminal selbst (via Kasseneck
|
|
28
|
+
* Connect) und druckt den Bon aus genau diesem Modell — die uebrigen Anbieter
|
|
29
|
+
* drucken in ihren eigenen Apps.
|
|
27
30
|
*/
|
|
28
31
|
/** Ausrichtung einer Zeile bzw. einer Spalte. */
|
|
29
32
|
export type LayoutAlign = 'left' | 'center' | 'right';
|
|
@@ -56,6 +56,50 @@ function belegZeit(timeStamp) {
|
|
|
56
56
|
* `typeof null === 'object'` ist, ergab das beim Lesen von `.label` einen
|
|
57
57
|
* nackten TypeError.
|
|
58
58
|
*/
|
|
59
|
+
/**
|
|
60
|
+
* Kartenzahlungsblock fuer Hobex (HPS am Geraet wie Cloud-API): die Felder
|
|
61
|
+
* kommen aus `cardPaymentData` in der Form von [hobexReceiptToCardPaymentData]
|
|
62
|
+
* (models/hobex-receipt.ts) — Datum, TID, Genehmigungsnummer, Karte, PAN,
|
|
63
|
+
* Antwortcode. Bei CVM "1" verlangt die Karte eine Unterschrift; dafuer
|
|
64
|
+
* bekommt der Bon eine Linie. Der PAN haengt beim HPS das Ablaufdatum mit
|
|
65
|
+
* Unterstrich an ("…4720_2810") — gedruckt wird nur die maskierte Nummer.
|
|
66
|
+
*
|
|
67
|
+
* Andere Anbieter (GP Tom, SumUp, myPOS, Stripe) drucken in ihren eigenen
|
|
68
|
+
* Apps; ihre Bloecke bleiben bewusst draussen (siehe Kopfkommentar).
|
|
69
|
+
*/
|
|
70
|
+
function hobexKartenblock(receipt) {
|
|
71
|
+
const provider = receipt.creditCardProvider;
|
|
72
|
+
const daten = receipt.cardPaymentData;
|
|
73
|
+
if ((provider !== 'hobexHps' && provider !== 'hobexCloudApi') || daten == null) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const feld = (k) => {
|
|
77
|
+
const v = daten[k];
|
|
78
|
+
return v == null ? '' : String(v);
|
|
79
|
+
};
|
|
80
|
+
const paar = (teile) => teile.filter(Boolean).join(' · ');
|
|
81
|
+
const pan = feld('cardNumber').split('_')[0] ?? '';
|
|
82
|
+
const rc = feld('responseCode');
|
|
83
|
+
const zeilen = [textZeile('Hobex Beleg', 'center', true)];
|
|
84
|
+
const inhalt = [
|
|
85
|
+
feld('date'),
|
|
86
|
+
paar([feld('tid') && `TID ${feld('tid')}`, feld('no') && `Nr. ${feld('no')}`]),
|
|
87
|
+
paar([feld('type'), feld('cardBrand')]),
|
|
88
|
+
pan,
|
|
89
|
+
rc && `RC ${rc}`,
|
|
90
|
+
];
|
|
91
|
+
for (const zeile of inhalt) {
|
|
92
|
+
if (zeile)
|
|
93
|
+
zeilen.push(textZeile(zeile, 'center'));
|
|
94
|
+
}
|
|
95
|
+
if (feld('cvm') === '1') {
|
|
96
|
+
zeilen.push({ kind: 'space', lines: 2 });
|
|
97
|
+
zeilen.push(textZeile('------------------', 'center'));
|
|
98
|
+
zeilen.push(textZeile('Unterschrift', 'center'));
|
|
99
|
+
}
|
|
100
|
+
zeilen.push({ kind: 'space', lines: 1 });
|
|
101
|
+
return zeilen;
|
|
102
|
+
}
|
|
59
103
|
function zahlungsartText(wert) {
|
|
60
104
|
if (wert != null && typeof wert === 'object') {
|
|
61
105
|
return wert.label;
|
|
@@ -154,21 +198,19 @@ function gutscheinText(voucher) {
|
|
|
154
198
|
if (name != null && name.toLowerCase().includes(text.toLowerCase())) {
|
|
155
199
|
return name;
|
|
156
200
|
}
|
|
157
|
-
|
|
158
|
-
|
|
201
|
+
// Der Betrag steht in derselben Zeile rechts in der Betragsspalte — ihn
|
|
202
|
+
// auch ins Label zu schreiben war doppelt und brach auf 58 mm haesslich
|
|
203
|
+
// um ("Wertgutschein 3 €" + Folgezeile "€"). Statt dessen der Code: er
|
|
204
|
+
// identifiziert den Gutschein (Mehrzweck: der Kunde will wissen, WELCHER
|
|
205
|
+
// eingeloest wurde).
|
|
206
|
+
if (voucher.code != null && voucher.code !== '') {
|
|
207
|
+
text += ` ${voucher.code}`;
|
|
159
208
|
}
|
|
160
209
|
if (name != null && name.length > 0) {
|
|
161
210
|
text += ` - ${name}`;
|
|
162
211
|
}
|
|
163
212
|
return text;
|
|
164
213
|
}
|
|
165
|
-
/**
|
|
166
|
-
* Ganze Betraege kurz (`"10"`), krumme mit zwei Nachkommastellen (`"1,50"`) —
|
|
167
|
-
* Zwilling von `KeckVoucher.formatVoucherAmount`.
|
|
168
|
-
*/
|
|
169
|
-
function gutscheinBetrag(cents) {
|
|
170
|
-
return cents % 100 === 0 ? String(cents / 100) : formatCents(cents);
|
|
171
|
-
}
|
|
172
214
|
// ----------------------------------------------------------------- Bauteile
|
|
173
215
|
function textZeile(text, align = 'left', bold = false) {
|
|
174
216
|
return { kind: 'text', text, align, bold };
|
|
@@ -196,6 +238,46 @@ function tabellenZeile(werte, paperSize) {
|
|
|
196
238
|
})),
|
|
197
239
|
};
|
|
198
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Trinkgeld auf dem Bon: keine Menge, kein Einzelpreis — Bezeichnung und
|
|
243
|
+
* Summe. Eine Steuer-Kategorie steht hinter dem Betrag (D = Durchlaeufer,
|
|
244
|
+
* sonst Inhaber-Trinkgeld als Umsatz); bei mehreren steht die Aufteilung in
|
|
245
|
+
* einer zweiten, eingerueckten Zeile. Breite 8:4: „Trinkgeld Personal“ (18
|
|
246
|
+
* Zeichen) muss auf 58 mm in die Zeile passen, rechts reichen zehn Zeichen
|
|
247
|
+
* auch fuer „-123,45 D“.
|
|
248
|
+
*/
|
|
249
|
+
function trinkgeldZeilen(name, teile) {
|
|
250
|
+
const summe = teile.reduce((s, t) => s + t.cents, 0);
|
|
251
|
+
if (teile.length === 1) {
|
|
252
|
+
return [{
|
|
253
|
+
kind: 'columns',
|
|
254
|
+
columns: [
|
|
255
|
+
{ text: name, width: 8, align: 'left' },
|
|
256
|
+
{ text: `${formatCents(summe)} ${teile[0].satz.category}`, width: 4, align: 'right' },
|
|
257
|
+
],
|
|
258
|
+
}];
|
|
259
|
+
}
|
|
260
|
+
const sortiert = [...teile].sort((a, b) => a.satz.category.localeCompare(b.satz.category));
|
|
261
|
+
return [
|
|
262
|
+
{
|
|
263
|
+
kind: 'columns',
|
|
264
|
+
columns: [
|
|
265
|
+
{ text: name, width: 8, align: 'left' },
|
|
266
|
+
// Stern statt Kategorie-Buchstabe: fluchtet mit den Warenbetraegen
|
|
267
|
+
// (" B" ist zwei Zeichen, " *" auch) und verweist auf die
|
|
268
|
+
// Aufteilungszeile darunter — klassische Fussnote.
|
|
269
|
+
{ text: `${formatCents(summe)} *`, width: 4, align: 'right' },
|
|
270
|
+
],
|
|
271
|
+
},
|
|
272
|
+
{ kind: 'text', text: `* davon ${sortiert.map((t) => `${formatCents(t.cents)} ${t.satz.category}`).join(', ')}`, align: 'left', bold: false },
|
|
273
|
+
];
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Rabatt auf dem Bon: dieselbe Form wie Trinkgeld — Summenzeile, bei einem
|
|
277
|
+
* Steuersatz mit Kategorie-Buchstaben, im Mischfall mit Stern und der
|
|
278
|
+
* Aufteilung als Fussnote darunter (siehe trinkgeldZeilen).
|
|
279
|
+
*/
|
|
280
|
+
const rabattZeilen = trinkgeldZeilen;
|
|
199
281
|
/** Positionszeile: Menge, Bezeichnung, ab Menge 2 der Einzelpreis. */
|
|
200
282
|
function positionsZeile(item, satz) {
|
|
201
283
|
const menge = String(item.quantity);
|
|
@@ -454,10 +536,58 @@ function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
454
536
|
gruppen.set(satz.rate, neu);
|
|
455
537
|
return neu;
|
|
456
538
|
};
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
539
|
+
// Trinkgeld-Positionen gleichen Namens werden auf dem Bon zu EINER Zeile
|
|
540
|
+
// mit der Summe zusammengefasst (die Aufteilung des Inhaber-Trinkgelds auf
|
|
541
|
+
// mehrere Steuersaetze bzw. mehrere Empfaenger ist fiskalisch notwendig,
|
|
542
|
+
// fuer den Gast aber nur Rauschen); bei mehr als einer Steuer-Kategorie
|
|
543
|
+
// steht die Aufteilung darunter. USt-Tabelle und DEP bleiben positionsgenau.
|
|
544
|
+
// Rabatt-Positionen gleichen Namens werden wie Trinkgeld zu EINER Zeile mit
|
|
545
|
+
// der Summe zusammengefasst (die Aufteilung je Steuersatz ist fiskalisch
|
|
546
|
+
// notwendig, fuer den Gast aber Rauschen); vor dem ERSTEN Rabatt-Block steht
|
|
547
|
+
// einmalig die Zwischensumme der Waren — der Gast sieht vorher/nachher.
|
|
548
|
+
// USt-Tabelle und DEP bleiben positionsgenau.
|
|
549
|
+
const warenSummeCents = receipt.items
|
|
550
|
+
.filter((it) => !(0, index_js_2.isTipItem)(it) && !(0, index_js_2.isDiscountItem)(it))
|
|
551
|
+
.reduce((summe, it) => summe + (0, index_js_2.receiptItemTotalCents)(it), 0);
|
|
552
|
+
let zwischensummeGezeigt = false;
|
|
553
|
+
let i = 0;
|
|
554
|
+
while (i < receipt.items.length) {
|
|
555
|
+
const item = receipt.items[i];
|
|
556
|
+
if (!(0, index_js_2.isTipItem)(item) && !(0, index_js_2.isDiscountItem)(item)) {
|
|
557
|
+
const satz = steuersatz(item.vat);
|
|
558
|
+
gruppeVon(satz).bruttoCents += (0, index_js_2.receiptItemTotalCents)(item);
|
|
559
|
+
lines.push(positionsZeile(item, satz));
|
|
560
|
+
i += 1;
|
|
561
|
+
continue;
|
|
562
|
+
}
|
|
563
|
+
const artVon = (it) => ((0, index_js_2.isTipItem)(it) ? 'tip' : 'discount');
|
|
564
|
+
const art = artVon(item);
|
|
565
|
+
const gruppe = [];
|
|
566
|
+
while (i < receipt.items.length && artVon(receipt.items[i]) === art && !(!(0, index_js_2.isTipItem)(receipt.items[i]) && !(0, index_js_2.isDiscountItem)(receipt.items[i])) && receipt.items[i].name === item.name) {
|
|
567
|
+
gruppe.push(receipt.items[i]);
|
|
568
|
+
i += 1;
|
|
569
|
+
}
|
|
570
|
+
const teile = [];
|
|
571
|
+
for (const teil of gruppe) {
|
|
572
|
+
const satz = steuersatz(teil.vat);
|
|
573
|
+
gruppeVon(satz).bruttoCents += (0, index_js_2.receiptItemTotalCents)(teil);
|
|
574
|
+
const vorhanden = teile.find((t) => t.satz.category === satz.category);
|
|
575
|
+
if (vorhanden)
|
|
576
|
+
vorhanden.cents += (0, index_js_2.receiptItemTotalCents)(teil);
|
|
577
|
+
else
|
|
578
|
+
teile.push({ satz, cents: (0, index_js_2.receiptItemTotalCents)(teil) });
|
|
579
|
+
}
|
|
580
|
+
if (art === 'discount' && !zwischensummeGezeigt) {
|
|
581
|
+
// Trennlinie vor dem Rabatt-Block: die Warenzeilen enden sichtbar,
|
|
582
|
+
// darunter beginnt die Verrechnung (Zwischensumme, Rabatt).
|
|
583
|
+
lines.push({ kind: 'rule', char: '-' });
|
|
584
|
+
// Zwei Fuellzeichen, wo bei den Warenzeilen " B" steht — so fluchten
|
|
585
|
+
// ALLE Betraege (Waren, Zwischensumme, Rabatt, Trinkgeld) in einer
|
|
586
|
+
// Spalte; die letzten zwei Zeichen sind die Kategorie-/Stern-Spalte.
|
|
587
|
+
lines.push(paarZeile('Zwischensumme', `${formatCents(warenSummeCents)} `, 8, 4));
|
|
588
|
+
zwischensummeGezeigt = true;
|
|
589
|
+
}
|
|
590
|
+
lines.push(...(art === 'discount' ? rabattZeilen(item.name, teile) : trinkgeldZeilen(item.name, teile)));
|
|
461
591
|
}
|
|
462
592
|
// --- Gutscheine: verkaufte Wertgutscheine sind Umsatz zu 0 %, eingeloeste
|
|
463
593
|
// Promotionsgutscheine mindern die Steuergruppen anteilig.
|
|
@@ -505,6 +635,24 @@ function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
505
635
|
formatCents(bruttoCents),
|
|
506
636
|
], paperSize));
|
|
507
637
|
}
|
|
638
|
+
// Mitarbeiter-Trinkgeld ist als Null-%-Umsatz erfasst (Erlass 2.4.2.1), aber
|
|
639
|
+
// kein Umsatz des Betriebs — die Klarstellung steht direkt unter der
|
|
640
|
+
// 0-%-Zeile, damit der Beleg (auch als Rechnung) nicht nach steuerfreiem
|
|
641
|
+
// Umsatz aussieht. Inhaber-Trinkgeld ist Umsatz und bekommt keine Zeile.
|
|
642
|
+
const durchlaufendesTrinkgeldCents = receipt.items
|
|
643
|
+
.filter((it) => (0, index_js_2.isTipItem)(it) && it.recipient?.owner !== true)
|
|
644
|
+
.reduce((summe, it) => summe + (0, index_js_2.receiptItemTotalCents)(it), 0);
|
|
645
|
+
// Nur wenn die 0-%-Gruppe MEHR enthaelt als das Trinkgeld (Wertgutschein-
|
|
646
|
+
// Verkauf ist ebenfalls Kategorie D, beim Kleinunternehmer ist alles 0 %):
|
|
647
|
+
// dann trennt diese Zeile den Durchlaeufer vom uebrigen Null-Prozent-Betrag.
|
|
648
|
+
// Besteht die 0-%-Gruppe ohnehin nur aus dem Trinkgeld, sagt die Position
|
|
649
|
+
// "Trinkgeld Personal" schon alles — die Wiederholung waere Rauschen.
|
|
650
|
+
const nullGruppeCents = gruppen.get(index_js_1.VatRate.vat0.rate)?.bruttoCents ?? 0;
|
|
651
|
+
if (durchlaufendesTrinkgeldCents !== 0 && nullGruppeCents !== durchlaufendesTrinkgeldCents) {
|
|
652
|
+
// Breite 9:3 — auf 58 mm (32 Zeichen) passt die Beschriftung so in eine
|
|
653
|
+
// Zeile; der Betrag braucht rechts hoechstens acht Zeichen.
|
|
654
|
+
lines.push(paarZeile('Trinkgeld, kein Umsatz:', formatCents(durchlaufendesTrinkgeldCents), 9, 3));
|
|
655
|
+
}
|
|
508
656
|
lines.push({ kind: 'rule', char: '-' });
|
|
509
657
|
// --- Summen
|
|
510
658
|
const summeCents = (0, index_js_2.receiptSumCents)(receipt);
|
|
@@ -513,7 +661,9 @@ function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
513
661
|
lines.push(paarZeile('Zwischensumme', `${formatCents(zwischensummeCents)} €`));
|
|
514
662
|
for (const voucher of receipt.vouchers) {
|
|
515
663
|
if (voucher.action === index_js_1.VoucherAction.redeem && voucher.type === index_js_1.VoucherType.value) {
|
|
516
|
-
|
|
664
|
+
// Breite 8:4 — "Wertgutschein GS-1" (Label + Code) passt so auf 58 mm
|
|
665
|
+
// in die Zeile, statt den Code in eine Folgezeile fliessen zu lassen.
|
|
666
|
+
lines.push(paarZeile(gutscheinText(voucher), `-${formatCents(voucher.valueCents ?? 0)} €`, 8, 4));
|
|
517
667
|
}
|
|
518
668
|
}
|
|
519
669
|
lines.push({ kind: 'rule', char: '-' });
|
|
@@ -538,6 +688,8 @@ function buildReceiptLayout(receipt, company, options = {}) {
|
|
|
538
688
|
// --- RKSV-QR-Code
|
|
539
689
|
lines.push({ kind: 'qr', data: receipt.qr });
|
|
540
690
|
lines.push({ kind: 'space', lines: 1 });
|
|
691
|
+
// --- Kartenzahlungsblock (Hobex) — wie im Vorbild UNTER dem QR-Code.
|
|
692
|
+
lines.push(...hobexKartenblock(receipt));
|
|
541
693
|
// --- Dankestext und Fusszeilen
|
|
542
694
|
if (company.thanksMessage.length > 0) {
|
|
543
695
|
lines.push({ kind: 'space', lines: 1 });
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
* daraus entstehende ID-Token und `sitzung.sessionId` ergeben zusammen
|
|
48
48
|
* `registerUserAuth` — ab da laeuft alles Weitere ueber den ueblichen Weg.
|
|
49
49
|
*/
|
|
50
|
-
export { type RegisterDeviceConnection, type RegisterDeviceCredentials, type PairRegisterDeviceOptions, type PairedRegisterDevice, type RegisterUserKind, type RegisterUserSummary, type RegisterUserPerms, type RegisterScope, type RegisterUser, type RegisterUserSession, type ListRegisterUsersForDeviceOptions, type RegisterUserLoginOptions, type RegisterPinLoginOptions, type RegisterPinPolicy, type RegisterLoginMode, type RegisterDeviceUsers, type RegisterClientInfo, type RegisterGeo, type RegisterGeraeteAngaben, pairRegisterDevice, listRegisterUsersForDevice, unpairRegisterDevice, registerUserLogin, registerPinLogin, } from './pairing.js';
|
|
50
|
+
export { type RegisterDeviceConnection, type RegisterDeviceCredentials, type PairRegisterDeviceOptions, type PairedRegisterDevice, type RegisterUserKind, type RegisterUserSummary, type RegisterUserPerms, REGISTER_PERMS, type RegisterScope, type RegisterUser, type RegisterUserSession, type ListRegisterUsersForDeviceOptions, type RegisterUserLoginOptions, type RegisterPinLoginOptions, type RegisterPinPolicy, type RegisterLoginMode, type RegisterDeviceUsers, type RegisterClientInfo, type RegisterGeo, type RegisterGeraeteAngaben, pairRegisterDevice, listRegisterUsersForDevice, unpairRegisterDevice, registerUserLogin, registerPinLogin, } from './pairing.js';
|
|
51
51
|
export { renewRegisterSession, endRegisterSession } from './session.js';
|
|
@@ -49,8 +49,9 @@
|
|
|
49
49
|
* `registerUserAuth` — ab da laeuft alles Weitere ueber den ueblichen Weg.
|
|
50
50
|
*/
|
|
51
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
-
exports.endRegisterSession = exports.renewRegisterSession = exports.registerPinLogin = exports.registerUserLogin = exports.unpairRegisterDevice = exports.listRegisterUsersForDevice = exports.pairRegisterDevice = void 0;
|
|
52
|
+
exports.endRegisterSession = exports.renewRegisterSession = exports.registerPinLogin = exports.registerUserLogin = exports.unpairRegisterDevice = exports.listRegisterUsersForDevice = exports.pairRegisterDevice = exports.REGISTER_PERMS = void 0;
|
|
53
53
|
var pairing_js_1 = require("./pairing.js");
|
|
54
|
+
Object.defineProperty(exports, "REGISTER_PERMS", { enumerable: true, get: function () { return pairing_js_1.REGISTER_PERMS; } });
|
|
54
55
|
Object.defineProperty(exports, "pairRegisterDevice", { enumerable: true, get: function () { return pairing_js_1.pairRegisterDevice; } });
|
|
55
56
|
Object.defineProperty(exports, "listRegisterUsersForDevice", { enumerable: true, get: function () { return pairing_js_1.listRegisterUsersForDevice; } });
|
|
56
57
|
Object.defineProperty(exports, "unpairRegisterDevice", { enumerable: true, get: function () { return pairing_js_1.unpairRegisterDevice; } });
|
|
@@ -41,6 +41,11 @@ export interface RegisterGeraeteAngaben {
|
|
|
41
41
|
geo?: RegisterGeo | null;
|
|
42
42
|
}
|
|
43
43
|
export interface PairRegisterDeviceOptions extends RegisterDeviceConnection, RegisterGeraeteAngaben {
|
|
44
|
+
/**
|
|
45
|
+
* Die Kasse ist schon auf einem anderen Geraet geoeffnet (BELEGT-Rueckfrage):
|
|
46
|
+
* `true` uebernimmt sie hierher und widerruft das alte Geraet.
|
|
47
|
+
*/
|
|
48
|
+
takeover?: boolean;
|
|
44
49
|
/**
|
|
45
50
|
* Achtstelliger Kopplungs-Code aus dem Panel. Er ist 15 Minuten gueltig,
|
|
46
51
|
* genau **einmal** verwendbar und gilt fuer eine bestimmte Kasse.
|
|
@@ -107,6 +112,16 @@ export interface RegisterDeviceUsers {
|
|
|
107
112
|
loginMode: RegisterLoginMode;
|
|
108
113
|
/** Der Betrieb verlangt die Ortung beim Login (Standortsperre an). */
|
|
109
114
|
standortsperre: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Darf die gebundene Kasse ueberhaupt Belege erstellen? `bereit: false`
|
|
117
|
+
* nennt den Grund (ausser Betrieb, Schlussbeleg erstellt) — die Kasse
|
|
118
|
+
* sperrt das Kassieren VOR dem ersten Beleg statt an createReceipt zu
|
|
119
|
+
* scheitern. Fehlt das Feld (aelteres Backend), gilt bereit.
|
|
120
|
+
*/
|
|
121
|
+
kasse?: {
|
|
122
|
+
bereit: boolean;
|
|
123
|
+
grund?: string | null;
|
|
124
|
+
} | null;
|
|
110
125
|
}
|
|
111
126
|
/**
|
|
112
127
|
* Rechte eines Kassen-Benutzers (Backend: `perms`, Vorlagen `PERMS_KASSIER`
|
|
@@ -144,6 +159,8 @@ export interface RegisterUserPerms {
|
|
|
144
159
|
tipAssign?: boolean;
|
|
145
160
|
[weiteresRecht: string]: boolean | RegisterScope | undefined;
|
|
146
161
|
}
|
|
162
|
+
/** Alle Rechte-Schluessel, die dieses Paket kennt — die Zwillinge pruefen dagegen. */
|
|
163
|
+
export declare const REGISTER_PERMS: readonly ["sell", "cancel", "articles", "layout", "reports", "takeover", "cancelScope", "receiptsScope", "drawer", "discount", "tipAssign"];
|
|
147
164
|
/** Reichweite lesen, mit der Migration des Backends (register-auth.js). */
|
|
148
165
|
export declare function cancelScopeOf(perms: RegisterUserPerms | null | undefined): RegisterScope;
|
|
149
166
|
export declare function receiptsScopeOf(perms: RegisterUserPerms | null | undefined): RegisterScope;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.REGISTER_PERMS = void 0;
|
|
3
4
|
exports.cancelScopeOf = cancelScopeOf;
|
|
4
5
|
exports.receiptsScopeOf = receiptsScopeOf;
|
|
5
6
|
exports.pairRegisterDevice = pairRegisterDevice;
|
|
@@ -47,6 +48,11 @@ const settings_js_1 = require("../kasse/settings.js");
|
|
|
47
48
|
* es auch halten.
|
|
48
49
|
*/
|
|
49
50
|
const ohneAnmeldung = () => ({ headers: {}, params: {} });
|
|
51
|
+
/** Alle Rechte-Schluessel, die dieses Paket kennt — die Zwillinge pruefen dagegen. */
|
|
52
|
+
exports.REGISTER_PERMS = [
|
|
53
|
+
'sell', 'cancel', 'articles', 'layout', 'reports', 'takeover',
|
|
54
|
+
'cancelScope', 'receiptsScope', 'drawer', 'discount', 'tipAssign',
|
|
55
|
+
];
|
|
50
56
|
/** Reichweite lesen, mit der Migration des Backends (register-auth.js). */
|
|
51
57
|
function cancelScopeOf(perms) {
|
|
52
58
|
if (!perms)
|
|
@@ -71,10 +77,10 @@ function receiptsScopeOf(perms) {
|
|
|
71
77
|
* [PairedRegisterDevice]).
|
|
72
78
|
*/
|
|
73
79
|
async function pairRegisterDevice(options) {
|
|
74
|
-
const { code, label, client, geo, ...verbindung } = options;
|
|
80
|
+
const { code, label, client, geo, takeover, ...verbindung } = options;
|
|
75
81
|
pflicht('pairRegisterDevice', 'code', code);
|
|
76
82
|
// Der Code ist das Geheimnis dieses Aufrufs — siehe Modulkommentar.
|
|
77
|
-
const daten = await transportFuer(verbindung)('pairRegisterDevice', { code, label, client, geo: geo ?? undefined }, undefined, [code]);
|
|
83
|
+
const daten = await transportFuer(verbindung)('pairRegisterDevice', { code, label, client, geo: geo ?? undefined, takeover: takeover === true ? true : undefined }, undefined, [code]);
|
|
78
84
|
return {
|
|
79
85
|
deviceId: pflichtfeld('pairRegisterDevice', daten, 'deviceId'),
|
|
80
86
|
deviceSecret: pflichtfeld('pairRegisterDevice', daten, 'deviceSecret'),
|
|
@@ -135,7 +141,26 @@ async function listRegisterUsersForDevice(options) {
|
|
|
135
141
|
};
|
|
136
142
|
const bd = daten?.betriebsdaten;
|
|
137
143
|
const betriebsdaten = bd && typeof bd === 'object' ? (0, receipt_company_js_1.fromReceiptCompanyPayload)(bd) : null;
|
|
138
|
-
return {
|
|
144
|
+
return {
|
|
145
|
+
users,
|
|
146
|
+
policy: regel(daten?.policy),
|
|
147
|
+
loginMode: daten?.loginMode === 'pin' ? 'pin' : 'auswahl',
|
|
148
|
+
settings,
|
|
149
|
+
betriebsdaten,
|
|
150
|
+
standortsperre: daten?.standortsperre === true,
|
|
151
|
+
// 0.6.27 ergaenzte nur den TYP — hier fiel das Feld beim Zusammenbau
|
|
152
|
+
// stumm weg, und die Kasse sah nie eine Sperre. Fehlt es (aelteres
|
|
153
|
+
// Backend), bleibt es undefined: dann gilt bereit.
|
|
154
|
+
kasse: kasseBereit(daten?.kasse),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function kasseBereit(wert) {
|
|
158
|
+
if (typeof wert !== 'object' || wert === null || Array.isArray(wert))
|
|
159
|
+
return undefined;
|
|
160
|
+
const roh = wert;
|
|
161
|
+
if (typeof roh['bereit'] !== 'boolean')
|
|
162
|
+
return undefined;
|
|
163
|
+
return { bereit: roh['bereit'], grund: typeof roh['grund'] === 'string' ? roh['grund'] : null };
|
|
139
164
|
}
|
|
140
165
|
/** Die Regel aus der Antwort — oder `null`, wenn keine brauchbare kommt. */
|
|
141
166
|
function regel(wert) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { InternerTransport } from '../client/aufrufe.js';
|
|
2
2
|
/**
|
|
3
3
|
* Die beiden Aufrufe der **laufenden** Kassen-Sitzung. Anders als die drei in
|
|
4
4
|
* pairing.ts haben sie eine Identitaet: sie laufen ueber `registerUserAuth`
|
|
@@ -23,7 +23,7 @@ import type { KasseneckTransport } from '../client/transport.js';
|
|
|
23
23
|
* beendet — bitte neu anmelden.") — dann hilft nur eine neue Anmeldung ueber
|
|
24
24
|
* `registerUserLogin`.
|
|
25
25
|
*/
|
|
26
|
-
export declare function renewRegisterSession(rufen:
|
|
26
|
+
export declare function renewRegisterSession(rufen: InternerTransport): Promise<number>;
|
|
27
27
|
/**
|
|
28
28
|
* Sitzung beenden und den Lizenzplatz sofort freigeben — der regulaere Weg des
|
|
29
29
|
* Abmeldens.
|
|
@@ -34,4 +34,4 @@ export declare function renewRegisterSession(rufen: KasseneckTransport): Promise
|
|
|
34
34
|
* einer harmlosen Vertragsaenderung — ausgerechnet beim Abmelden, dem Aufruf,
|
|
35
35
|
* der auch dann durchgehen soll, wenn sonst nichts mehr geht.
|
|
36
36
|
*/
|
|
37
|
-
export declare function endRegisterSession(rufen:
|
|
37
|
+
export declare function endRegisterSession(rufen: InternerTransport): Promise<void>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Die Namen der Backend-Functions, die dieses Paket aufruft — als Daten, nicht
|
|
3
|
+
* als Zeichenketten im Code verstreut. Zwei Gruende:
|
|
4
|
+
*
|
|
5
|
+
* 1. Der Vertrag (`fixtures/oberflaeche.json`) gibt die Liste aus, damit die
|
|
6
|
+
* Zwillinge pruefen koennen, ob sie denselben Aufruf kennen.
|
|
7
|
+
* 2. Die paketinternen Module nehmen [InternerTransport] statt
|
|
8
|
+
* [KasseneckTransport] entgegen; ein Tippfehler im Aufrufnamen ist damit ein
|
|
9
|
+
* Compilerfehler statt eines 404 beim Kunden.
|
|
10
|
+
*
|
|
11
|
+
* **Die oeffentliche Schnittstelle bleibt offen.** `KasseneckTransport` nimmt
|
|
12
|
+
* weiterhin jeden `string`: wer einen Aufruf braucht, den dieses Paket nicht
|
|
13
|
+
* umhuellt, muss ihn weiterhin absetzen koennen.
|
|
14
|
+
*/
|
|
15
|
+
import type { TransportBodyFields } from './transport.js';
|
|
16
|
+
export declare const AUFRUFE: readonly ["cancelReceipt", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getFirstReceiptDate", "getKasseSettings", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listRegisterUsersForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice"];
|
|
17
|
+
export type Aufruf = typeof AUFRUFE[number];
|
|
18
|
+
/** Wie [KasseneckTransport], nur mit bekanntem Aufrufnamen. Nicht exportiert nach aussen. */
|
|
19
|
+
export type InternerTransport = <T = unknown>(functionName: Aufruf, params?: Record<string, unknown>, extraBodyFields?: TransportBodyFields, secretParams?: readonly string[]) => Promise<T>;
|
|
20
|
+
/** Wie [KasseneckBinaryTransport], nur mit bekanntem Aufrufnamen. */
|
|
21
|
+
export type InternerBinaerTransport = (functionName: Aufruf, params?: Record<string, unknown>) => Promise<Uint8Array>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const AUFRUFE = [
|
|
2
|
+
'cancelReceipt',
|
|
3
|
+
'createPaymentLinkStripe',
|
|
4
|
+
'createPrintJob',
|
|
5
|
+
'createReceipt',
|
|
6
|
+
'downloadDailyReport',
|
|
7
|
+
'downloadReport',
|
|
8
|
+
'endRegisterSession',
|
|
9
|
+
'financeWebService',
|
|
10
|
+
'generateFullReceiptId',
|
|
11
|
+
'getFirstReceiptDate',
|
|
12
|
+
'getKasseSettings',
|
|
13
|
+
'getPrintJob',
|
|
14
|
+
'getReceipt',
|
|
15
|
+
'hobexPayApi',
|
|
16
|
+
'hobexRefundApi',
|
|
17
|
+
'listMyArticleGroups',
|
|
18
|
+
'listMyArticles',
|
|
19
|
+
'listMyCashregisters',
|
|
20
|
+
'listMyPrinters',
|
|
21
|
+
'listMyReceipts',
|
|
22
|
+
'listRegisterUsersForDevice',
|
|
23
|
+
'pairRegisterDevice',
|
|
24
|
+
'registerPinLogin',
|
|
25
|
+
'registerUserLogin',
|
|
26
|
+
'renewRegisterSession',
|
|
27
|
+
'setMyKasseSettings',
|
|
28
|
+
'setMyRegisterDeviceSettings',
|
|
29
|
+
'stripeCaptureIntent',
|
|
30
|
+
'unpairRegisterDevice',
|
|
31
|
+
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Cashregister } from '../models/index.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { InternerTransport } from './aufrufe.js';
|
|
3
3
|
/**
|
|
4
4
|
* Kassen-Endpunkte.
|
|
5
5
|
*
|
|
@@ -18,4 +18,4 @@ import type { KasseneckTransport } from './transport.js';
|
|
|
18
18
|
*
|
|
19
19
|
* Ohne diesen Aufruf kann eine Browser-Kasse ihre Kasse nicht auswaehlen.
|
|
20
20
|
*/
|
|
21
|
-
export declare function listMyCashregisters(rufen:
|
|
21
|
+
export declare function listMyCashregisters(rufen: InternerTransport): Promise<Cashregister[]>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, } from './auth.js';
|
|
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
|
+
export { AUFRUFE, type Aufruf, } from './aufrufe.js';
|
|
3
4
|
export { KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, } from './errors.js';
|
|
4
|
-
export { type ReceiptCommonOptions, type SellReceiptOptions, 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, } from './receipts.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, } from './receipts.js';
|
|
5
6
|
export { listMyCashregisters } from './cashregisters.js';
|
|
6
7
|
export { downloadDailyReport, downloadMonthlyReport } from './reports.js';
|
|
7
8
|
export { type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, } from './status.js';
|
package/dist/esm/client/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { apiKeyAuth, registerUserAuth, } from './auth.js';
|
|
2
2
|
export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, createTransport, createBinaryTransport, } from './transport.js';
|
|
3
|
+
export { AUFRUFE, } from './aufrufe.js';
|
|
3
4
|
export { KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, } from './errors.js';
|
|
4
5
|
export { sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, checkVoucherCombinationError, } from './receipts.js';
|
|
5
6
|
export { listMyCashregisters } from './cashregisters.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReceiptType, type ReceiptTypeKey, KeckPaymentMethod, type KeckPaymentMethodKey, CreditCardProvider } from '../enums/index.js';
|
|
2
2
|
import { type Receipt, type ReceiptCompany, type ReceiptItem, type Voucher, type ReceiptSummary, type ReportMonth, type CancellationItem, type CancellationOf, type CancellationReason } from '../models/index.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { InternerTransport } from './aufrufe.js';
|
|
4
4
|
import type { Pruefangaben, ReceiptLayout } from '../receipt/layout.js';
|
|
5
5
|
/**
|
|
6
6
|
* Beleg-Endpunkte — Zwilling der Beleg-Aufrufe in
|
|
@@ -39,6 +39,25 @@ export interface ReceiptCommonOptions {
|
|
|
39
39
|
customProjectId?: string;
|
|
40
40
|
/** Rohdaten der Kartenzahlung (Terminal-/Anbieterantwort). */
|
|
41
41
|
cardPaymentData?: Record<string, unknown>;
|
|
42
|
+
/**
|
|
43
|
+
* Trinkgeld in Cent — als Zahl (an den angemeldeten Kassen-Benutzer, Zahlart
|
|
44
|
+
* des Belegs) oder als [TipOptions]. Das Backend bucht daraus signierte
|
|
45
|
+
* Positionen `kind:'tip'` (Mitarbeiter 0 % als Durchlaeufer, Inhaber
|
|
46
|
+
* anteilig je Steuersatz). Nur auf `standard` und `training`.
|
|
47
|
+
*/
|
|
48
|
+
tip?: number | TipOptions;
|
|
49
|
+
}
|
|
50
|
+
/** Trinkgeld mit eigener Zahlart und/oder Empfaengern (Kassen-Benutzer-IDs, Summe = cents). */
|
|
51
|
+
export interface TipOptions {
|
|
52
|
+
cents: number;
|
|
53
|
+
/** Zahlart des Trinkgelds; ohne Angabe gilt die des Belegs. */
|
|
54
|
+
paymentMethod?: KeckPaymentMethod | KeckPaymentMethodKey;
|
|
55
|
+
/** Empfaenger; ohne Angabe der angemeldete Kassen-Benutzer. Summe der cents = cents. */
|
|
56
|
+
recipients?: TipRecipientShare[];
|
|
57
|
+
}
|
|
58
|
+
export interface TipRecipientShare {
|
|
59
|
+
registerUserId: string;
|
|
60
|
+
cents: number;
|
|
42
61
|
}
|
|
43
62
|
/** Belegtyp und Inhalt — die vollstaendige Eingabe von [createReceipt]. */
|
|
44
63
|
export interface CreateReceiptOptions extends ReceiptCommonOptions {
|
|
@@ -131,29 +150,29 @@ export interface ReceiptWithCompany {
|
|
|
131
150
|
* Bewusst **nicht** Teil der Paketoberflaeche: der Belegtyp gehoert nicht in
|
|
132
151
|
* die Hand des Aufrufers, sondern zu einem der benannten Aufrufe darunter.
|
|
133
152
|
*/
|
|
134
|
-
export declare function createReceipt(rufen:
|
|
153
|
+
export declare function createReceipt(rufen: InternerTransport, options: CreateReceiptOptions): Promise<Receipt>;
|
|
135
154
|
/** Normalbeleg (Verkauf) nach RKSV. */
|
|
136
|
-
export declare function sellReceipt(rufen:
|
|
155
|
+
export declare function sellReceipt(rufen: InternerTransport, options: SellReceiptOptions): Promise<Receipt>;
|
|
137
156
|
/**
|
|
138
157
|
* Normalbeleg wie [sellReceipt], liefert zusaetzlich die Firmen-/Druckdaten
|
|
139
158
|
* aus derselben Antwort — alles, was ein Belegdruck braucht, in einem Aufruf.
|
|
140
159
|
*/
|
|
141
|
-
export declare function sellReceiptWithCompany(rufen:
|
|
160
|
+
export declare function sellReceiptWithCompany(rufen: InternerTransport, options: SellReceiptOptions): Promise<ReceiptWithCompany>;
|
|
142
161
|
/**
|
|
143
162
|
* Storno-Beleg zu einem bestehenden Beleg — voll oder in Teilen. Prueft die
|
|
144
163
|
* Eingabe, bevor etwas hinausgeht; der Server haelt die Restmengen und die
|
|
145
164
|
* Reichweite des Rechts (eigene/alle) und antwortet mit dem fertigen,
|
|
146
165
|
* signierten Storno-Beleg. Gutscheine des Originals wandern nicht mit.
|
|
147
166
|
*/
|
|
148
|
-
export declare function cancelReceipt(rufen:
|
|
167
|
+
export declare function cancelReceipt(rufen: InternerTransport, options: CancelReceiptOptions): Promise<CancelReceiptResult>;
|
|
149
168
|
/**
|
|
150
169
|
* Stornobeleg aus frei uebergebenen Positionen — fuer den Fall, dass der
|
|
151
170
|
* Originalbeleg nicht als Objekt vorliegt. Die Positionen gehen **unveraendert**
|
|
152
171
|
* hinaus; das Vorzeichen setzt der Aufrufer.
|
|
153
172
|
*/
|
|
154
|
-
export declare function createCancelReceipt(rufen:
|
|
173
|
+
export declare function createCancelReceipt(rufen: InternerTransport, options: CreateCancelReceiptOptions): Promise<Receipt>;
|
|
155
174
|
/** Nullbeleg (RKSV-Pruefbeleg) — ohne Positionen und ohne Zahlungsart. */
|
|
156
|
-
export declare function zeroReceipt(rufen:
|
|
175
|
+
export declare function zeroReceipt(rufen: InternerTransport): Promise<Receipt>;
|
|
157
176
|
/** Belegliste einer Kasse samt der Kennzahlen, die dieselbe Antwort mitliefert. */
|
|
158
177
|
export interface ReceiptList {
|
|
159
178
|
/** Letzte Belege, neueste zuerst (Backend: nach `counter` absteigend). */
|
|
@@ -212,21 +231,21 @@ export interface ListMyReceiptsOptions {
|
|
|
212
231
|
* (der Endpunkt laeuft mit `checkCashRegister: false`), ein Kassen-Benutzer
|
|
213
232
|
* bekommt also nur die ihm zugewiesenen Kassen.
|
|
214
233
|
*/
|
|
215
|
-
export declare function listMyReceipts(rufen:
|
|
234
|
+
export declare function listMyReceipts(rufen: InternerTransport, options: ListMyReceiptsOptions): Promise<ReceiptList>;
|
|
216
235
|
/** Einzelnen Beleg der angemeldeten Kasse holen. */
|
|
217
|
-
export declare function getReceipt(rufen:
|
|
236
|
+
export declare function getReceipt(rufen: InternerTransport, receiptId: string): Promise<Receipt>;
|
|
218
237
|
/**
|
|
219
238
|
* Wie [getReceipt], liefert zusaetzlich die Firmen-/Druckdaten aus derselben
|
|
220
239
|
* Antwort (Firma, Anschrift, Steuernummer, UID, Fusszeilen, Logo-Adresse,
|
|
221
240
|
* Kleinunternehmer-Kennzeichen) — die Angaben, die ein Beleg im Kopf und Fuss
|
|
222
241
|
* traegt (siehe models/receipt-company.ts).
|
|
223
242
|
*/
|
|
224
|
-
export declare function getReceiptWithCompany(rufen:
|
|
243
|
+
export declare function getReceiptWithCompany(rufen: InternerTransport, receiptId: string): Promise<ReceiptWithCompany>;
|
|
225
244
|
/**
|
|
226
245
|
* Verschluesselte Volltext-Belegnummer erzeugen — der Bezeichner, unter dem der
|
|
227
246
|
* Beleg oeffentlich abrufbar ist (Beleg-Download, Pruefportal).
|
|
228
247
|
*/
|
|
229
|
-
export declare function generateFullReceiptId(rufen:
|
|
248
|
+
export declare function generateFullReceiptId(rufen: InternerTransport, receiptId: string): Promise<string>;
|
|
230
249
|
/**
|
|
231
250
|
* Berichtsmonat des allerersten Belegs dieser Kasse — die untere Grenze aller
|
|
232
251
|
* Monatsberichte.
|
|
@@ -235,7 +254,7 @@ export declare function generateFullReceiptId(rufen: KasseneckTransport, receipt
|
|
|
235
254
|
* fuehrt kein `allowRegisterUser`, das Backend weist die Browser-Kasse hier ab
|
|
236
255
|
* (siehe Modulkommentar oben). Mit `apiKeyAuth` ist er offen.
|
|
237
256
|
*/
|
|
238
|
-
export declare function getFirstReceiptDate(rufen:
|
|
257
|
+
export declare function getFirstReceiptDate(rufen: InternerTransport): Promise<ReportMonth>;
|
|
239
258
|
/**
|
|
240
259
|
* Prueft die Gutschein-Kombination eines Belegs und liefert den ersten
|
|
241
260
|
* Regelverstoss als Text (oder `null`) — Zwilling von
|