@kreiseck/kasseneck-api 0.7.0 → 0.7.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 +32 -0
- package/README.md +87 -15
- package/dist/cjs/client/aufrufe.d.ts +1 -1
- package/dist/cjs/client/aufrufe.js +1 -0
- package/dist/cjs/client/errors.d.ts +8 -4
- package/dist/cjs/client/errors.js +12 -9
- package/dist/cjs/client/receipts.d.ts +22 -0
- package/dist/cjs/client/receipts.js +16 -0
- package/dist/cjs/client/transport.js +5 -4
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/models/cancellation.d.ts +28 -0
- package/dist/cjs/models/cancellation.js +31 -1
- package/dist/cjs/models/hobex-receipt.js +9 -2
- package/dist/cjs/models/index.d.ts +1 -1
- package/dist/cjs/models/index.js +3 -1
- package/dist/cjs/models/receipt-summary.d.ts +2 -0
- package/dist/cjs/models/receipt-summary.js +4 -1
- package/dist/cjs/models/receipt.js +8 -1
- package/dist/cjs/models/voucher.js +18 -2
- package/dist/cjs/payments/hobex-hps/connect-client.d.ts +104 -0
- package/dist/cjs/payments/hobex-hps/connect-client.js +159 -0
- package/dist/cjs/payments/hobex-hps/errors.d.ts +122 -0
- package/dist/cjs/payments/hobex-hps/errors.js +158 -0
- package/dist/cjs/payments/hobex-hps/events.d.ts +22 -0
- package/dist/cjs/payments/hobex-hps/events.js +2 -0
- package/dist/cjs/payments/hobex-hps/index.d.ts +27 -0
- package/dist/cjs/payments/hobex-hps/index.js +67 -0
- package/dist/cjs/payments/hobex-hps/outcome.d.ts +46 -0
- package/dist/cjs/payments/hobex-hps/outcome.js +7 -0
- package/dist/cjs/payments/hobex-hps/payments.d.ts +149 -0
- package/dist/cjs/payments/hobex-hps/payments.js +573 -0
- package/dist/cjs/payments/hobex-hps/receipt.d.ts +28 -0
- package/dist/cjs/payments/hobex-hps/receipt.js +60 -0
- package/dist/cjs/payments/hobex-hps/transaction-id.d.ts +65 -0
- package/dist/cjs/payments/hobex-hps/transaction-id.js +91 -0
- package/dist/cjs/payments/hobex-hps/transaction-response.d.ts +175 -0
- package/dist/cjs/payments/hobex-hps/transaction-response.js +266 -0
- package/dist/cjs/payments/hobex.js +9 -6
- package/dist/cjs/payments/index.d.ts +26 -14
- package/dist/cjs/payments/index.js +59 -15
- package/dist/cjs/printing/index.d.ts +1 -1
- package/dist/cjs/printing/index.js +2 -1
- package/dist/cjs/printing/webusb.d.ts +37 -7
- package/dist/cjs/printing/webusb.js +76 -18
- package/dist/cjs/receipt/epos.d.ts +18 -0
- package/dist/cjs/receipt/epos.js +78 -6
- package/dist/cjs/receipt/index.d.ts +1 -1
- package/dist/cjs/receipt/index.js +2 -1
- package/dist/cjs/receipt/layout.js +19 -0
- package/dist/cjs/register/index.d.ts +1 -1
- package/dist/cjs/register/index.js +2 -1
- package/dist/cjs/register/pairing.d.ts +59 -0
- package/dist/cjs/register/pairing.js +51 -2
- package/dist/esm/client/aufrufe.d.ts +1 -1
- package/dist/esm/client/aufrufe.js +1 -0
- package/dist/esm/client/errors.d.ts +8 -4
- package/dist/esm/client/errors.js +12 -9
- package/dist/esm/client/receipts.d.ts +22 -0
- package/dist/esm/client/receipts.js +16 -0
- package/dist/esm/client/transport.js +5 -4
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/models/cancellation.d.ts +28 -0
- package/dist/esm/models/cancellation.js +29 -0
- package/dist/esm/models/hobex-receipt.js +10 -3
- package/dist/esm/models/index.d.ts +1 -1
- package/dist/esm/models/index.js +1 -1
- package/dist/esm/models/receipt-summary.d.ts +2 -0
- package/dist/esm/models/receipt-summary.js +4 -1
- package/dist/esm/models/receipt.js +8 -1
- package/dist/esm/models/voucher.js +18 -2
- package/dist/esm/payments/hobex-hps/connect-client.d.ts +104 -0
- package/dist/esm/payments/hobex-hps/connect-client.js +156 -0
- package/dist/esm/payments/hobex-hps/errors.d.ts +122 -0
- package/dist/esm/payments/hobex-hps/errors.js +149 -0
- package/dist/esm/payments/hobex-hps/events.d.ts +22 -0
- package/dist/esm/payments/hobex-hps/events.js +1 -0
- package/dist/esm/payments/hobex-hps/index.d.ts +27 -0
- package/dist/esm/payments/hobex-hps/index.js +26 -0
- package/dist/esm/payments/hobex-hps/outcome.d.ts +46 -0
- package/dist/esm/payments/hobex-hps/outcome.js +4 -0
- package/dist/esm/payments/hobex-hps/payments.d.ts +149 -0
- package/dist/esm/payments/hobex-hps/payments.js +570 -0
- package/dist/esm/payments/hobex-hps/receipt.d.ts +28 -0
- package/dist/esm/payments/hobex-hps/receipt.js +57 -0
- package/dist/esm/payments/hobex-hps/transaction-id.d.ts +65 -0
- package/dist/esm/payments/hobex-hps/transaction-id.js +86 -0
- package/dist/esm/payments/hobex-hps/transaction-response.d.ts +175 -0
- package/dist/esm/payments/hobex-hps/transaction-response.js +254 -0
- package/dist/esm/payments/hobex.js +9 -6
- package/dist/esm/payments/index.d.ts +26 -14
- package/dist/esm/payments/index.js +26 -14
- package/dist/esm/printing/index.d.ts +1 -1
- package/dist/esm/printing/index.js +1 -1
- package/dist/esm/printing/webusb.d.ts +37 -7
- package/dist/esm/printing/webusb.js +74 -17
- package/dist/esm/receipt/epos.d.ts +18 -0
- package/dist/esm/receipt/epos.js +76 -6
- package/dist/esm/receipt/index.d.ts +1 -1
- package/dist/esm/receipt/index.js +1 -1
- package/dist/esm/receipt/layout.js +19 -0
- package/dist/esm/register/index.d.ts +1 -1
- package/dist/esm/register/index.js +1 -1
- package/dist/esm/register/pairing.d.ts +59 -0
- package/dist/esm/register/pairing.js +50 -2
- package/fixtures/belege/storno-rabatt.json +3 -2
- package/fixtures/belege/storno-teil.json +2 -1
- package/fixtures/belege/storno-voll.json +2 -1
- package/fixtures/erwartet/storno-rabatt.grid32.txt +1 -0
- package/fixtures/erwartet/storno-rabatt.grid48.txt +1 -0
- package/fixtures/erwartet/storno-rabatt.lines.json +6 -0
- package/fixtures/erwartet/storno-teil.grid32.txt +1 -0
- package/fixtures/erwartet/storno-teil.grid48.txt +1 -0
- package/fixtures/erwartet/storno-teil.lines.json +6 -0
- package/fixtures/erwartet/storno-voll.grid32.txt +1 -0
- package/fixtures/erwartet/storno-voll.grid48.txt +1 -0
- package/fixtures/erwartet/storno-voll.lines.json +6 -0
- package/fixtures/hobex-hps-codes.json +83 -0
- package/fixtures/manifest.json +12 -12
- package/fixtures/oberflaeche.json +2 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,38 @@ 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.7.2
|
|
8
|
+
|
|
9
|
+
### `55` („PIN falsch") ist eine gemessene Host-Ablehnung → `declined`
|
|
10
|
+
|
|
11
|
+
**Anlass:** Vorfall vom 02.09.2026 am Produktivterminal 3556988 (HPS 1.11.4,
|
|
12
|
+
Firmware 2.3.9), vom Dart-Zwilling `kasseneck_api` 6.4.0 übernommen — die
|
|
13
|
+
erste echte Host-Ablehnung, die je beobachtet wurde. Die Zahlung antwortete
|
|
14
|
+
direkt mit `55`, die Statusabfrage danach elfmal in Folge ebenfalls. Als
|
|
15
|
+
Wissenslücke kostete der Code 90 s Klärung ins Budget, `unresolved`, einen
|
|
16
|
+
stehenden Merker und eine Rückfrage an den Bediener — für eine falsch
|
|
17
|
+
getippte PIN.
|
|
18
|
+
|
|
19
|
+
- Neu: `WRONG_PIN_CODE`, in `HPS_MEASURED_CODES` als schlüssig geführt.
|
|
20
|
+
- Bewusst **keine** Familienregel für zweistellige Host-Codes: ISO 8583 führt
|
|
21
|
+
dort auch Genehmigungen (`08`, `10`, `11`, `85`). Die Zwei-`9027`-Regel
|
|
22
|
+
greift bei Host-Codes nicht (der Status antwortet mit dem Code selbst);
|
|
23
|
+
ungemessene Host-Codes enden weiterhin bei `unresolved`.
|
|
24
|
+
- `fixtures/hobex-hps-codes.json` neu erzeugt; die Vertragsdatei nennt jetzt
|
|
25
|
+
unter `ergaenztAn`, welcher Code von welchem Gerät stammt.
|
|
26
|
+
|
|
27
|
+
### Neu: `HpsPaymentResult.lastResponse` und Terminal-Klartext im Nachweis
|
|
28
|
+
|
|
29
|
+
Am 02.09.2026 sah der Bediener bei einer Antwort `55` „PIN falsch" nur
|
|
30
|
+
„Ausgang unklar", musste raten und buchte die abgelehnte Zahlung als bezahlt;
|
|
31
|
+
75 EUR Umsatz waren weg. Der Klartext hätte die Entscheidung getragen.
|
|
32
|
+
|
|
33
|
+
- `lastResponse`: die letzte Terminal-Antwort bei `unresolved`, auch wenn sie
|
|
34
|
+
nichts entschied — Material für Anzeige und Katalog, nie ein Beleg.
|
|
35
|
+
`response` bleibt bei `unresolved` weiterhin ungesetzt.
|
|
36
|
+
- Der Nachweis nennt bei einem unbekannten Code den Klartext des Terminals:
|
|
37
|
+
`Terminal nennt einen unbekannten Code (55) "PIN falsch"`.
|
|
38
|
+
|
|
7
39
|
## 0.7.0
|
|
8
40
|
|
|
9
41
|
### Neu: Unterpfad `./partner` — die Partner-API
|
package/README.md
CHANGED
|
@@ -162,12 +162,55 @@ ergebnis.cancellationOf; // Bezug auf das Original
|
|
|
162
162
|
ergebnis.remaining; // Restmengen des Originals danach
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
+
**Veraltet:** `createCancelReceipt` (Storno über `createReceipt` mit frei
|
|
166
|
+
übergebenen, negierten Positionen) bleibt aus Kompatibilität erreichbar, ist aber
|
|
167
|
+
`@deprecated` — kein Bezug zum Original, keine Restmengen, kein Schutz vor
|
|
168
|
+
doppeltem Storno, keine Gutscheine. Das Backend legt bei diesem Weg
|
|
169
|
+
`deprecation` in die Antwort.
|
|
170
|
+
|
|
165
171
|
Der Server negiert die Positionen, prüft Restmengen und Rechte („nur eigene
|
|
166
172
|
Belege" oder „alle") und verkettet Original und Storno. Ein Storno-Beleg lässt
|
|
167
173
|
sich nicht stornieren, ein voll stornierter Beleg nicht noch einmal. Am
|
|
168
174
|
gelesenen Original liefert `remainingQuantities(receipt)` die Reste vorab (für
|
|
169
175
|
den Storno-Dialog); die Wahrheit hat der Server.
|
|
170
176
|
|
|
177
|
+
**Fehler entscheidet man am Code, nicht am Text.** Jeder fachliche Fehler von
|
|
178
|
+
`cancelReceipt` trägt `KasseneckApiError.code` aus `CANCELLATION_ERROR_CODES`
|
|
179
|
+
(z. B. `bereits_storniert`, `menge_ueber_rest`, `nur_eigene_belege`). Die
|
|
180
|
+
deutsche Meldung (`serverMessage`) ist Anzeige und darf sich ändern.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
import { isKasseneckApiError, isCancellationErrorCode } from '@kreiseck/kasseneck-api';
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
await api.cancelReceipt({ receipt: beleg, reason: 'fehleingabe' });
|
|
187
|
+
} catch (fehler) {
|
|
188
|
+
if (isKasseneckApiError(fehler) && isCancellationErrorCode(fehler.code)) {
|
|
189
|
+
switch (fehler.code) {
|
|
190
|
+
case 'bereits_storniert': // Beleg im Dialog als „storniert" zeigen, Knopf sperren
|
|
191
|
+
case 'menge_ueber_rest': // Restmengen neu laden (jemand war schneller)
|
|
192
|
+
case 'nur_eigene_belege': // Chef holen
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
throw fehler;
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Gutscheine.** Ein Wertgutschein wird nur beim Vollstorno (ohne `items`)
|
|
201
|
+
gespiegelt — er ist unteilbar. Ein Rabattgutschein ist am Original bereits in
|
|
202
|
+
den Umsatz eingerechnet; **jeder** Storno nimmt ihn anteilig der stornierten
|
|
203
|
+
Menge zurück: bei 3 Stück à 10 € mit 6 € Rabatt sind 8 € je Stück Entgelt, der
|
|
204
|
+
Storno-Beleg trägt dann „−10,00" plus eine Zeile „Gutschein-Ausgleich +2,00".
|
|
205
|
+
Was ein Storno gewährt hat, steht am Eintrag in `receipt.cancellations[]` als
|
|
206
|
+
`promoAdjustmentCents` (Cent je Steuertopf) — die Kasse kann es im Dialog
|
|
207
|
+
zeigen, rechnen muss sie nichts.
|
|
208
|
+
|
|
209
|
+
**Bon.** Der Kopfblock des Storno-Bons nennt Bezug, Datum des Originals und
|
|
210
|
+
Grund: „STORNOBELEG / Stornobuchung zu Beleg KASSE1-ID-42 / vom 11.08.2026,
|
|
211
|
+
09:02 Uhr / Grund: Fehleingabe". Das Datum kommt aus `cancellationOf.timeStamp`
|
|
212
|
+
(Backend seit 2026-09-04); Altbelege ohne bleiben ohne die Zeile.
|
|
213
|
+
|
|
171
214
|
## Partner-API (`./partner`)
|
|
172
215
|
|
|
173
216
|
Für Softwarehäuser, die Kasseneck in ihr eigenes Produkt einbauen: Betriebe
|
|
@@ -292,7 +335,7 @@ app.post('/kasseneck-webhook', express.raw({ type: '*/*' }), async (req, res) =>
|
|
|
292
335
|
| `@kreiseck/kasseneck-api` | Endpunkte, Anmeldung, Transport, Modelle, Enums, Fehler — alles, was mit dem Backend spricht. |
|
|
293
336
|
| `…/receipt` | Beleg-Layout als Datenmodell (framework-frei) und die Brücke zu ESC/POS. |
|
|
294
337
|
| `…/printing` | ESC/POS-Erzeugung: Bytefolgen für Bondrucker, ohne jeden Transport. |
|
|
295
|
-
| `…/payments` | Stripe-Zahllinks
|
|
338
|
+
| `…/payments` | Stripe-Zahllinks, Hobex-Cloud (beides HTTP-Endpunkte des Backends) und Hobex **HPS** über **Kasseneck Connect** (lokaler Geräte-Agent, spricht mit dem Terminal). |
|
|
296
339
|
| `…/register` | Anmeldung der Browser-Kasse: Gerät koppeln und entkoppeln, Benutzer auflisten, per PIN anmelden, Sitzung erneuern und beenden. |
|
|
297
340
|
| `…/kasse` | Kachel-Kasse: Kassen-Einstellungen (betriebsweit / je Gerät), Artikelgruppen und Artikel für Kacheln, Rabattverteilung je Steuersatz, Reichweiten der Kassen-Rechte |
|
|
298
341
|
| `…/partner` | Partner-API: Betriebe anlegen, FinanzOnline-Link, Signatur, Kassen, Zugangsdaten, Webhooks samt Signaturprüfung. **Gehört auf einen Server.** |
|
|
@@ -301,16 +344,40 @@ app.post('/kasseneck-webhook', express.raw({ type: '*/*' }), async (req, res) =>
|
|
|
301
344
|
|
|
302
345
|
So zieht sich niemand den React-Adapter in ein Node-Programm.
|
|
303
346
|
|
|
304
|
-
##
|
|
347
|
+
## Hobex HPS über Kasseneck Connect
|
|
348
|
+
|
|
349
|
+
Ein Browser hat weiterhin keine rohen TCP-Sockets — ein **direkter**
|
|
350
|
+
Terminal-Kontakt wie beim Flutter-Paket `kasseneck_api` (`HpsClient`) bleibt
|
|
351
|
+
deshalb außerhalb der Reichweite dieses Pakets. **Kasseneck Connect** ist aber
|
|
352
|
+
ein lokaler Geräte-Agent mit gewöhnlicher HTTP-Schnittstelle, der für die Kasse
|
|
353
|
+
mit dem Terminal spricht — und darüber geht es:
|
|
354
|
+
|
|
355
|
+
```ts
|
|
356
|
+
import { createHpsConnectClient, createHpsPayments } from '@kreiseck/kasseneck-api/payments';
|
|
357
|
+
|
|
358
|
+
const client = createHpsConnectClient({ token: kopplungsToken });
|
|
359
|
+
const zahlweg = createHpsPayments(client, { host: '192.168.1.50', tid: '3600335' });
|
|
305
360
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
361
|
+
const ergebnis = await zahlweg.pay({ amountCents: 1050 });
|
|
362
|
+
// ergebnis.outcome: 'approved' | 'declined' | 'unresolved' — nie geraten.
|
|
363
|
+
// ergebnis.transactionId ist IMMER gesetzt, auch bei 'unresolved'.
|
|
364
|
+
```
|
|
310
365
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
366
|
+
Der Ausgang ist immer einer von drei: `approved`, `declined` (beweisbar nichts
|
|
367
|
+
belastet) oder `unresolved` (Ausgang unbekannt, eine Wiederholung könnte ein
|
|
368
|
+
zweites Mal belasten). Was das bedeutet und warum es so gebaut ist, steht in
|
|
369
|
+
`src/payments/hobex-hps/payments.ts` — dort ist die Dokumentation der Maßstab,
|
|
370
|
+
nicht dieses README.
|
|
371
|
+
|
|
372
|
+
**Nur `pay` — bewusst kein `refund`/`cancel`.** Kasseneck Connect exponiert
|
|
373
|
+
dafür (noch) keinen Endpunkt; eine Gutschrift oder ein Storno am HPS-Terminal
|
|
374
|
+
braucht weiterhin die Flutter-App. **myPOS** und **SumUp** bleiben
|
|
375
|
+
Android-SDKs ohne Entsprechung hier.
|
|
376
|
+
|
|
377
|
+
## Was hier grundsätzlich nicht dazugehört
|
|
378
|
+
|
|
379
|
+
Die Druckeransteuerung selbst (dieses Paket erzeugt die Bytes, es verschickt
|
|
380
|
+
sie nicht), Firmenlogos und Rasterbilder, und die PDF-Erzeugung.
|
|
314
381
|
|
|
315
382
|
## Entwicklung
|
|
316
383
|
|
|
@@ -348,19 +415,24 @@ Wird eine Ausnahme erreichbar, schlägt die Prüfung an: Sonst sänke die Zahl n
|
|
|
348
415
|
## Vertragsdateien für die Zwillinge
|
|
349
416
|
|
|
350
417
|
Dieses Paket ist die Quelle für das Dart-Paket `kasseneck_api` und den
|
|
351
|
-
Backend-Validator `kasse-settings-core.js`.
|
|
352
|
-
im Tarball mit und sagen in Maschinenform, worauf sich
|
|
418
|
+
Backend-Validator `kasse-settings-core.js`. Drei Dateien in `fixtures/` reisen
|
|
419
|
+
im Tarball mit und sagen in Maschinenform, worauf sich beide Seiten geeinigt haben:
|
|
353
420
|
|
|
354
421
|
| Datei | Inhalt |
|
|
355
422
|
|---|---|
|
|
356
423
|
| `kasse-settings-standard.json` | Feldnamen und Standardwerte der Kassen-Einstellungen |
|
|
424
|
+
| `oberflaeche.json` | Aufrufnamen, Enum-Werte, Rechte-Schlüssel, Tasten-Aktionen |
|
|
425
|
+
| `hobex-hps-codes.json` | Gemessene HPS-Ergebniscodes, ihre Bedeutung und ob sie einen Ausgang festschreiben — der Vertrag hinter `.../payments/hobex-hps`s `isConclusive`. |
|
|
426
|
+
|
|
357
427
|
| `oberflaeche.json` | Aufrufnamen, Enum-Werte, Rechte-Schlüssel, Tasten-Aktionen, Partner-Listen |
|
|
358
428
|
|
|
359
|
-
|
|
360
|
-
und nie von Hand geändert; die CI prüft
|
|
429
|
+
Alle drei werden erzeugt (`npm run fixtures:kasse`, `npm run fixtures:oberflaeche`,
|
|
430
|
+
`npm run fixtures:hobex-hps-codes`) und nie von Hand geändert; die CI prüft
|
|
431
|
+
nach jedem Lauf, dass sie zum Code passen.
|
|
361
432
|
|
|
362
|
-
`oberflaeche.json`
|
|
363
|
-
|
|
433
|
+
`oberflaeche.json` und `hobex-hps-codes.json` tragen die Paketversion. **Nach
|
|
434
|
+
jedem `npm version` müssen deshalb alle drei Dateien neu erzeugt und
|
|
435
|
+
mitcommittet werden**, sonst wird die CI rot.
|
|
364
436
|
|
|
365
437
|
### Und die Gegenrichtung
|
|
366
438
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* umhuellt, muss ihn weiterhin absetzen koennen.
|
|
14
14
|
*/
|
|
15
15
|
import type { TransportBodyFields } from './transport.js';
|
|
16
|
-
export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
|
|
16
|
+
export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
|
|
17
17
|
export type Aufruf = typeof AUFRUFE[number];
|
|
18
18
|
/** Wie [KasseneckTransport], nur mit bekanntem Aufrufnamen. Nicht exportiert nach aussen. */
|
|
19
19
|
export type InternerTransport = <T = unknown>(functionName: Aufruf, params?: Record<string, unknown>, extraBodyFields?: TransportBodyFields, secretParams?: readonly string[]) => Promise<T>;
|
|
@@ -95,9 +95,13 @@ export declare class KasseneckApiError extends Error {
|
|
|
95
95
|
/** Meldung des Backends, unveraendert (`message` aus der Huelle). */
|
|
96
96
|
readonly serverMessage: string;
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
98
|
+
* Stabiler, maschinenlesbarer Fehlercode des Backends, wenn der Endpunkt
|
|
99
|
+
* einen legt. Zwei Ablageorte kommen vor und beide zaehlen: das Feld `code`
|
|
100
|
+
* neben `message` (cancelReceipt, siehe CANCELLATION_ERROR_CODES) und
|
|
101
|
+
* `data.code` (Partner-API: `vertrag_offen`, `rate_limited`, …). Nur
|
|
102
|
+
* Bezeichner gelten — ein Freitext waere kein Code. Die aelteren Endpunkte
|
|
103
|
+
* antworten ohne Code — dann `undefined`. **Daran entscheiden, nie an
|
|
104
|
+
* [serverMessage]:** der Text darf sich aendern, der Code nicht.
|
|
101
105
|
*/
|
|
102
106
|
readonly code: string | undefined;
|
|
103
107
|
/**
|
|
@@ -106,7 +110,7 @@ export declare class KasseneckApiError extends Error {
|
|
|
106
110
|
* beilegt. Immer ein Objekt, notfalls ein leeres.
|
|
107
111
|
*/
|
|
108
112
|
readonly details: Record<string, unknown>;
|
|
109
|
-
constructor(functionName: string, serverMessage: string, details?: Record<string, unknown
|
|
113
|
+
constructor(functionName: string, serverMessage: string, details?: Record<string, unknown>, code?: string);
|
|
110
114
|
}
|
|
111
115
|
/** Warum die Antwort keine verwertbare Huelle war. */
|
|
112
116
|
export type HttpFailureReason = 'server-error' | 'empty-body' | 'not-json' | 'missing-status';
|
|
@@ -181,9 +181,13 @@ class KasseneckApiError extends Error {
|
|
|
181
181
|
/** Meldung des Backends, unveraendert (`message` aus der Huelle). */
|
|
182
182
|
serverMessage;
|
|
183
183
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
184
|
+
* Stabiler, maschinenlesbarer Fehlercode des Backends, wenn der Endpunkt
|
|
185
|
+
* einen legt. Zwei Ablageorte kommen vor und beide zaehlen: das Feld `code`
|
|
186
|
+
* neben `message` (cancelReceipt, siehe CANCELLATION_ERROR_CODES) und
|
|
187
|
+
* `data.code` (Partner-API: `vertrag_offen`, `rate_limited`, …). Nur
|
|
188
|
+
* Bezeichner gelten — ein Freitext waere kein Code. Die aelteren Endpunkte
|
|
189
|
+
* antworten ohne Code — dann `undefined`. **Daran entscheiden, nie an
|
|
190
|
+
* [serverMessage]:** der Text darf sich aendern, der Code nicht.
|
|
187
191
|
*/
|
|
188
192
|
code;
|
|
189
193
|
/**
|
|
@@ -192,16 +196,15 @@ class KasseneckApiError extends Error {
|
|
|
192
196
|
* beilegt. Immer ein Objekt, notfalls ein leeres.
|
|
193
197
|
*/
|
|
194
198
|
details;
|
|
195
|
-
constructor(functionName, serverMessage, details = {}) {
|
|
199
|
+
constructor(functionName, serverMessage, details = {}, code) {
|
|
196
200
|
super(`${functionName} fehlgeschlagen: ${serverMessage}`);
|
|
197
201
|
this.functionName = functionName;
|
|
198
202
|
this.serverMessage = serverMessage;
|
|
199
203
|
this.details = details;
|
|
200
|
-
// Der Code
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
this.code = typeof code === 'string' && BEZEICHNER.test(code) ? code : undefined;
|
|
204
|
+
// Der Code neben `message` hat Vorrang; fehlt er, gilt `data.code` aus
|
|
205
|
+
// den Details. So bleibt die Klasse fuer beide Ablageorte dieselbe.
|
|
206
|
+
const kandidat = code !== undefined ? code : details['code'];
|
|
207
|
+
this.code = typeof kandidat === 'string' && BEZEICHNER.test(kandidat) ? kandidat : undefined;
|
|
205
208
|
}
|
|
206
209
|
}
|
|
207
210
|
exports.KasseneckApiError = KasseneckApiError;
|
|
@@ -54,6 +54,22 @@ export interface TipOptions {
|
|
|
54
54
|
paymentMethod?: KeckPaymentMethod | KeckPaymentMethodKey;
|
|
55
55
|
/** Empfaenger; ohne Angabe der angemeldete Kassen-Benutzer. Summe der cents = cents. */
|
|
56
56
|
recipients?: TipRecipientShare[];
|
|
57
|
+
/**
|
|
58
|
+
* Hat der Empfaenger das Geld schon? `true` = ja (Bargeld mitgenommen,
|
|
59
|
+
* Kartentrinkgeld sofort aus der Lade ausgezahlt), `false` = der Betrieb
|
|
60
|
+
* behaelt es und schuldet es.
|
|
61
|
+
*
|
|
62
|
+
* Entscheidend ist NICHT die Zahlart, sondern der Besitz -- § 2j Abs 2 AVRAG
|
|
63
|
+
* kennt beide Faelle. Ohne Angabe gilt die Voreinstellung des Betriebs (bar:
|
|
64
|
+
* schon erhalten, bargeldlos: einbehalten); diese Angabe braucht es nur fuer
|
|
65
|
+
* die Ausnahme.
|
|
66
|
+
*
|
|
67
|
+
* NUR mit dem Recht `tipAssign` bei persoenlicher Anmeldung: das Merkmal
|
|
68
|
+
* entscheidet, ob der Betrieb Geld schuldet, und gewoehnliches Personal soll
|
|
69
|
+
* das nicht am Geraet umstellen koennen. Ueber einen Geraete-API-Schluessel
|
|
70
|
+
* (ohne angemeldeten Kassen-Benutzer) gilt die Einschraenkung nicht.
|
|
71
|
+
*/
|
|
72
|
+
sofortErhalten?: boolean;
|
|
57
73
|
}
|
|
58
74
|
export interface TipRecipientShare {
|
|
59
75
|
registerUserId: string;
|
|
@@ -169,6 +185,12 @@ export declare function cancelReceipt(rufen: InternerTransport, options: CancelR
|
|
|
169
185
|
* Stornobeleg aus frei uebergebenen Positionen — fuer den Fall, dass der
|
|
170
186
|
* Originalbeleg nicht als Objekt vorliegt. Die Positionen gehen **unveraendert**
|
|
171
187
|
* hinaus; das Vorzeichen setzt der Aufrufer.
|
|
188
|
+
*
|
|
189
|
+
* @deprecated Alter Storno-Weg ohne Bezug: kein Verweis auf das Original,
|
|
190
|
+
* keine Restmengen, kein Schutz vor doppeltem Storno, Gutscheine werden nicht
|
|
191
|
+
* zurueckgenommen. Das Backend nimmt ihn weiter an und legt `deprecation` in
|
|
192
|
+
* die Antwort. Stattdessen [cancelReceipt] (Endpunkt `cancelReceipt`): Bezug,
|
|
193
|
+
* Grund, Teilstorno, Fehlercodes.
|
|
172
194
|
*/
|
|
173
195
|
export declare function createCancelReceipt(rufen: InternerTransport, options: CreateCancelReceiptOptions): Promise<Receipt>;
|
|
174
196
|
/** Nullbeleg (RKSV-Pruefbeleg) — ohne Positionen und ohne Zahlungsart. */
|
|
@@ -174,6 +174,12 @@ async function cancelReceipt(rufen, options) {
|
|
|
174
174
|
* Stornobeleg aus frei uebergebenen Positionen — fuer den Fall, dass der
|
|
175
175
|
* Originalbeleg nicht als Objekt vorliegt. Die Positionen gehen **unveraendert**
|
|
176
176
|
* hinaus; das Vorzeichen setzt der Aufrufer.
|
|
177
|
+
*
|
|
178
|
+
* @deprecated Alter Storno-Weg ohne Bezug: kein Verweis auf das Original,
|
|
179
|
+
* keine Restmengen, kein Schutz vor doppeltem Storno, Gutscheine werden nicht
|
|
180
|
+
* zurueckgenommen. Das Backend nimmt ihn weiter an und legt `deprecation` in
|
|
181
|
+
* die Antwort. Stattdessen [cancelReceipt] (Endpunkt `cancelReceipt`): Bezug,
|
|
182
|
+
* Grund, Teilstorno, Fehlercodes.
|
|
177
183
|
*/
|
|
178
184
|
function createCancelReceipt(rufen, options) {
|
|
179
185
|
return createReceipt(rufen, { ...options, receiptType: index_js_1.ReceiptType.cancellation });
|
|
@@ -399,6 +405,16 @@ function gepruefterTip(tip) {
|
|
|
399
405
|
const nutzlast = { cents: tip.cents };
|
|
400
406
|
if (tip.paymentMethod != null)
|
|
401
407
|
nutzlast['paymentMethod'] = gepruefteZahlungsart(tip.paymentMethod);
|
|
408
|
+
// Nur mitschicken, wenn gesetzt: fehlt das Feld, entscheidet die
|
|
409
|
+
// Voreinstellung des Betriebs. Ein `false` waere dort eine Aussage, kein
|
|
410
|
+
// Weglassen. Der Wortlaut des Fehlers ist der des Backends
|
|
411
|
+
// (tip-core.normalizeTip) -- wer ihn hier sieht, sieht denselben Satz.
|
|
412
|
+
if (tip.sofortErhalten != null) {
|
|
413
|
+
if (typeof tip.sofortErhalten !== 'boolean') {
|
|
414
|
+
throw eingabefehler('Trinkgeld: sofortErhalten muss true oder false sein.');
|
|
415
|
+
}
|
|
416
|
+
nutzlast['sofortErhalten'] = tip.sofortErhalten;
|
|
417
|
+
}
|
|
402
418
|
if (tip.recipients != null) {
|
|
403
419
|
if (!Array.isArray(tip.recipients) || tip.recipients.length === 0) {
|
|
404
420
|
throw eingabefehler('Trinkgeld: recipients darf nicht leer sein.');
|
|
@@ -181,7 +181,7 @@ function jsonAuswerten(text, functionName, statusCode, inhaltstyp, geheimnisse)
|
|
|
181
181
|
}
|
|
182
182
|
// Alles, was nicht ausdruecklich Erfolg ist, gilt als fachlicher Fehler —
|
|
183
183
|
// ein unbekannter Statuswert darf nie stillschweigend als Erfolg durchgehen.
|
|
184
|
-
throw fachfehler(functionName, huelle.message, huelle.data, geheimnisse);
|
|
184
|
+
throw fachfehler(functionName, huelle.message, huelle.data, geheimnisse, huelle.code);
|
|
185
185
|
}
|
|
186
186
|
/**
|
|
187
187
|
* Auswertung des Binaerwegs. Der Kern der Zusage: **ein Aufrufer bekommt nie
|
|
@@ -227,7 +227,7 @@ function pdfAuswerten(bytes, functionName, statusCode, inhaltstyp, geheimnisse)
|
|
|
227
227
|
}
|
|
228
228
|
// Derselbe fachliche Fehler wie auf dem JSON-Weg — fuer den Aufrufer macht
|
|
229
229
|
// es keinen Unterschied, ob er ein PDF oder eine Nutzlast erwartet hat.
|
|
230
|
-
throw fachfehler(functionName, huelle.message, huelle.data, geheimnisse);
|
|
230
|
+
throw fachfehler(functionName, huelle.message, huelle.data, geheimnisse, huelle.code);
|
|
231
231
|
}
|
|
232
232
|
/** `%PDF` am Anfang — die Kennung jeder PDF-Datei. */
|
|
233
233
|
function istPdf(bytes) {
|
|
@@ -240,9 +240,10 @@ function alsHuelle(wert) {
|
|
|
240
240
|
}
|
|
241
241
|
return wert;
|
|
242
242
|
}
|
|
243
|
-
function fachfehler(functionName, message, daten, geheimnisse) {
|
|
243
|
+
function fachfehler(functionName, message, daten, geheimnisse, code) {
|
|
244
244
|
const meldung = typeof message === 'string' && message.trim() ? message : 'Unbekannter Fehler';
|
|
245
|
-
|
|
245
|
+
// Nur ein Text zaehlt als Code -- alles andere waere ein geratener Vertrag.
|
|
246
|
+
return new errors_js_1.KasseneckApiError(functionName, meldung, (0, errors_js_1.fehlerDetails)(daten, geheimnisse), typeof code === 'string' && code ? code : undefined);
|
|
246
247
|
}
|
|
247
248
|
/**
|
|
248
249
|
* Nutzlast aus Auth- und Aufruferparametern. Auth-Parameter bilden die
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ReceiptType, type ReceiptTypeKey, VatRate, type VatRateKey, KeckPaymentMethod, type KeckPaymentMethodKey, CreditCardProvider, type CreditCardProviderKey, VoucherType, type VoucherTypeKey, VoucherAction, type VoucherActionKey, StripeLinkMode, type StripeLinkModeKey, } from './enums/index.js';
|
|
2
|
-
export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, CANCELLATION_REASONS, CANCELLATION_RESERVATION_MS, isCancellationReason, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
|
|
2
|
+
export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
|
|
3
3
|
export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
|
|
4
4
|
export { parseServerTimeStamp, toViennaWallClock, type ViennaWallClock } from './vienna-time.js';
|
|
5
5
|
export { type KasseSettingsBetrieb, type KasseSettingsGeraet, type KasseSettings, type ArticleGroup, type KasseArtikel, KASSE_BETRIEB_STANDARD, KASSE_GERAET_STANDARD, mergeKasseSettings, fromArticleGroupPayload, fromKasseArtikelPayload, listMyArticleGroups, listMyArticles, getKasseSettings, setMyKasseSettings, setMyRegisterDeviceSettings, verteileRabatt, cancelScopeOf, receiptsScopeOf, } from './kasse/index.js';
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = void 0;
|
|
3
|
+
exports.createBinaryTransport = exports.createTransport = exports.AUFRUFE = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
|
|
4
|
+
exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = void 0;
|
|
5
5
|
var index_js_1 = require("./enums/index.js");
|
|
6
6
|
Object.defineProperty(exports, "ReceiptType", { enumerable: true, get: function () { return index_js_1.ReceiptType; } });
|
|
7
7
|
Object.defineProperty(exports, "VatRate", { enumerable: true, get: function () { return index_js_1.VatRate; } });
|
|
@@ -25,8 +25,10 @@ Object.defineProperty(exports, "fromReceiptPayload", { enumerable: true, get: fu
|
|
|
25
25
|
Object.defineProperty(exports, "receiptSubSumCents", { enumerable: true, get: function () { return index_js_2.receiptSubSumCents; } });
|
|
26
26
|
Object.defineProperty(exports, "receiptSumCents", { enumerable: true, get: function () { return index_js_2.receiptSumCents; } });
|
|
27
27
|
Object.defineProperty(exports, "CANCELLATION_REASONS", { enumerable: true, get: function () { return index_js_2.CANCELLATION_REASONS; } });
|
|
28
|
+
Object.defineProperty(exports, "CANCELLATION_ERROR_CODES", { enumerable: true, get: function () { return index_js_2.CANCELLATION_ERROR_CODES; } });
|
|
28
29
|
Object.defineProperty(exports, "CANCELLATION_RESERVATION_MS", { enumerable: true, get: function () { return index_js_2.CANCELLATION_RESERVATION_MS; } });
|
|
29
30
|
Object.defineProperty(exports, "isCancellationReason", { enumerable: true, get: function () { return index_js_2.isCancellationReason; } });
|
|
31
|
+
Object.defineProperty(exports, "isCancellationErrorCode", { enumerable: true, get: function () { return index_js_2.isCancellationErrorCode; } });
|
|
30
32
|
Object.defineProperty(exports, "remainingQuantities", { enumerable: true, get: function () { return index_js_2.remainingQuantities; } });
|
|
31
33
|
Object.defineProperty(exports, "fromReceiptCompanyPayload", { enumerable: true, get: function () { return index_js_2.fromReceiptCompanyPayload; } });
|
|
32
34
|
Object.defineProperty(exports, "receiptCompanyTaxInfo", { enumerable: true, get: function () { return index_js_2.receiptCompanyTaxInfo; } });
|
|
@@ -18,10 +18,29 @@ export declare const CANCELLATION_REASONS: Readonly<{
|
|
|
18
18
|
}>;
|
|
19
19
|
export type CancellationReason = keyof typeof CANCELLATION_REASONS;
|
|
20
20
|
export declare function isCancellationReason(value: unknown): value is CancellationReason;
|
|
21
|
+
/**
|
|
22
|
+
* Stabile Fehlercodes von `cancelReceipt` — Zwilling von
|
|
23
|
+
* `functions/storno-core.js` STORNO_FEHLERCODES. Das Backend legt sie bei
|
|
24
|
+
* jedem fachlichen Fehler als `code` neben die Meldung; das Paket reicht sie
|
|
25
|
+
* als [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** —
|
|
26
|
+
* die deutsche Meldung darf sich aendern, der Code nicht.
|
|
27
|
+
*
|
|
28
|
+
* Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
|
|
29
|
+
* ohne Code; dort bleibt `code` undefined.
|
|
30
|
+
*/
|
|
31
|
+
export declare const CANCELLATION_ERROR_CODES: readonly ["beleg_nicht_gefunden", "belegart_nicht_stornierbar", "trainingsbeleg", "bereits_storniert", "position_ungueltig", "menge_ueber_rest", "grund_unbekannt", "anmerkung_zu_lang", "items_ungueltig", "kasse_nicht_zugewiesen", "keine_berechtigung", "nur_eigene_belege", "kasse_unvollstaendig", "storno_fehlgeschlagen"];
|
|
32
|
+
export type CancellationErrorCode = (typeof CANCELLATION_ERROR_CODES)[number];
|
|
33
|
+
export declare function isCancellationErrorCode(value: unknown): value is CancellationErrorCode;
|
|
21
34
|
/** Bezug eines Storno-Belegs auf sein Original. */
|
|
22
35
|
export interface CancellationOf {
|
|
23
36
|
receiptId: string;
|
|
24
37
|
fullReceiptId: string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Zeitstempel des Originals (Server-Format, Wiener Wanduhr) — das Layout
|
|
40
|
+
* nennt ihn im Kopfblock des Storno-Bons („vom 11.08.2026, 09:02 Uhr").
|
|
41
|
+
* Fehlt bei Altbelegen; dann bleibt die Zeile weg.
|
|
42
|
+
*/
|
|
43
|
+
timeStamp?: string;
|
|
25
44
|
}
|
|
26
45
|
/** Eine stornierte Position: Index im Original und Menge. */
|
|
27
46
|
export interface CancellationItem {
|
|
@@ -40,6 +59,15 @@ export interface Cancellation {
|
|
|
40
59
|
by: string | null;
|
|
41
60
|
note: string | null;
|
|
42
61
|
items: CancellationItem[];
|
|
62
|
+
/**
|
|
63
|
+
* Rabattgutschein-Ausgleich, den DIESER Storno gewaehrt hat — Cent je
|
|
64
|
+
* Steuertopf des Backends (`amountRateStandard`, `amountRateReduced1`, …).
|
|
65
|
+
* Ein Rabattgutschein ist am Original schon in den Umsatz eingerechnet;
|
|
66
|
+
* jeder Storno nimmt ihn anteilig der stornierten Menge zurueck (bei 3 Stueck
|
|
67
|
+
* a 10 EUR mit 6 EUR Rabatt: 2,00 je Stueck). Fehlt das Feld, hat der Eintrag
|
|
68
|
+
* nichts gewaehrt (Altbestand vor dieser Regel) — der naechste Storno holt nach.
|
|
69
|
+
*/
|
|
70
|
+
promoAdjustmentCents?: Record<string, number>;
|
|
43
71
|
}
|
|
44
72
|
/** Ab wann eine liegengebliebene Reservierung nicht mehr zaehlt (wie im Backend). */
|
|
45
73
|
export declare const CANCELLATION_RESERVATION_MS = 120000;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_REASONS = void 0;
|
|
3
|
+
exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = void 0;
|
|
4
4
|
exports.isCancellationReason = isCancellationReason;
|
|
5
|
+
exports.isCancellationErrorCode = isCancellationErrorCode;
|
|
5
6
|
exports.remainingQuantities = remainingQuantities;
|
|
6
7
|
/**
|
|
7
8
|
* Storno-Metadaten — Zwilling von `functions/storno-core.js`.
|
|
@@ -23,6 +24,35 @@ exports.CANCELLATION_REASONS = Object.freeze({
|
|
|
23
24
|
function isCancellationReason(value) {
|
|
24
25
|
return typeof value === 'string' && Object.prototype.hasOwnProperty.call(exports.CANCELLATION_REASONS, value);
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Stabile Fehlercodes von `cancelReceipt` — Zwilling von
|
|
29
|
+
* `functions/storno-core.js` STORNO_FEHLERCODES. Das Backend legt sie bei
|
|
30
|
+
* jedem fachlichen Fehler als `code` neben die Meldung; das Paket reicht sie
|
|
31
|
+
* als [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** —
|
|
32
|
+
* die deutsche Meldung darf sich aendern, der Code nicht.
|
|
33
|
+
*
|
|
34
|
+
* Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
|
|
35
|
+
* ohne Code; dort bleibt `code` undefined.
|
|
36
|
+
*/
|
|
37
|
+
exports.CANCELLATION_ERROR_CODES = [
|
|
38
|
+
'beleg_nicht_gefunden', // Original fehlt oder gehoert nicht zu dieser Kasse
|
|
39
|
+
'belegart_nicht_stornierbar', // Original ist selbst Storno-, Null- oder Startbeleg
|
|
40
|
+
'trainingsbeleg', // Trainingsbelege werden nicht storniert
|
|
41
|
+
'bereits_storniert', // keine Restmenge mehr (auch beim positionslosen Beleg)
|
|
42
|
+
'position_ungueltig', // Index unbekannt oder doppelt
|
|
43
|
+
'menge_ueber_rest', // Menge nicht ganzzahlig >= 1 oder groesser als der Rest
|
|
44
|
+
'grund_unbekannt', // reason fehlt oder nicht im Katalog
|
|
45
|
+
'anmerkung_zu_lang', // note laenger als 200 Zeichen
|
|
46
|
+
'items_ungueltig', // items ist keine Liste
|
|
47
|
+
'kasse_nicht_zugewiesen', // Register-Benutzer darf diese Kasse nicht
|
|
48
|
+
'keine_berechtigung', // Register-Benutzer ohne Storno-Recht
|
|
49
|
+
'nur_eigene_belege', // Recht "eigene", fremder Beleg
|
|
50
|
+
'kasse_unvollstaendig', // api_key/token fehlen am Konto bzw. an der Kasse
|
|
51
|
+
'storno_fehlgeschlagen', // der Storno-Beleg selbst wurde abgelehnt (z. B. Signatur)
|
|
52
|
+
];
|
|
53
|
+
function isCancellationErrorCode(value) {
|
|
54
|
+
return typeof value === 'string' && exports.CANCELLATION_ERROR_CODES.includes(value);
|
|
55
|
+
}
|
|
26
56
|
/** Ab wann eine liegengebliebene Reservierung nicht mehr zaehlt (wie im Backend). */
|
|
27
57
|
exports.CANCELLATION_RESERVATION_MS = 120_000;
|
|
28
58
|
/**
|
|
@@ -44,8 +44,15 @@ function fromHobexReceiptPayload(payload) {
|
|
|
44
44
|
responseCode: payload.responseCode,
|
|
45
45
|
transactionType: payload.transactionType,
|
|
46
46
|
currency: payload.currency,
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
// Euro->Cent ueber die eine gehaertete Stelle im Paket ([euroToCents],
|
|
48
|
+
// money.ts) statt einer eigenen `Math.round(x * 100)` -- die Hobex-Antwort
|
|
49
|
+
// ist eine fremde Antwort und wird hier nur auf transactionId/
|
|
50
|
+
// transactionDate geprueft (siehe payments/hobex.ts, belegAusNutzlast);
|
|
51
|
+
// amount/tip bleiben ungeprueft. Ein nicht-numerischer oder
|
|
52
|
+
// nicht-endlicher Wert ergab bis zu dieser Fassung `NaN` -- lautlos, ohne
|
|
53
|
+
// dass irgendwo geworfen wurde. [euroToCents] liefert dafuer `0`.
|
|
54
|
+
amountCents: (0, money_js_1.euroToCents)(payload.amount),
|
|
55
|
+
tipCents: (0, money_js_1.euroToCents)(payload.tip),
|
|
49
56
|
cvm: String(payload.cvm),
|
|
50
57
|
// Die Cloud-API-Nutzlast traegt keinen eigenen Provider-Schluessel — der
|
|
51
58
|
// Provider ergibt sich aus dem Transportweg (Cloud vs. HPS), nicht aus
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, isDiscountItem, } from './receipt-item.js';
|
|
2
2
|
export { type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid } from './voucher.js';
|
|
3
3
|
export { type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, } from './receipt.js';
|
|
4
|
-
export { type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, CANCELLATION_REASONS, CANCELLATION_RESERVATION_MS, isCancellationReason, remainingQuantities, } from './cancellation.js';
|
|
4
|
+
export { type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, } from './cancellation.js';
|
|
5
5
|
export { type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, } from './receipt-company.js';
|
|
6
6
|
export { type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, } from './cashregister.js';
|
|
7
7
|
export { type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind } from './receipt-summary.js';
|
package/dist/cjs/models/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isDiscountItem = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = void 0;
|
|
3
|
+
exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isDiscountItem = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = void 0;
|
|
4
4
|
var receipt_item_js_1 = require("./receipt-item.js");
|
|
5
5
|
Object.defineProperty(exports, "toReceiptItemPayload", { enumerable: true, get: function () { return receipt_item_js_1.toReceiptItemPayload; } });
|
|
6
6
|
Object.defineProperty(exports, "fromReceiptItemPayload", { enumerable: true, get: function () { return receipt_item_js_1.fromReceiptItemPayload; } });
|
|
@@ -20,8 +20,10 @@ Object.defineProperty(exports, "receiptSubSumCents", { enumerable: true, get: fu
|
|
|
20
20
|
Object.defineProperty(exports, "receiptSumCents", { enumerable: true, get: function () { return receipt_js_1.receiptSumCents; } });
|
|
21
21
|
var cancellation_js_1 = require("./cancellation.js");
|
|
22
22
|
Object.defineProperty(exports, "CANCELLATION_REASONS", { enumerable: true, get: function () { return cancellation_js_1.CANCELLATION_REASONS; } });
|
|
23
|
+
Object.defineProperty(exports, "CANCELLATION_ERROR_CODES", { enumerable: true, get: function () { return cancellation_js_1.CANCELLATION_ERROR_CODES; } });
|
|
23
24
|
Object.defineProperty(exports, "CANCELLATION_RESERVATION_MS", { enumerable: true, get: function () { return cancellation_js_1.CANCELLATION_RESERVATION_MS; } });
|
|
24
25
|
Object.defineProperty(exports, "isCancellationReason", { enumerable: true, get: function () { return cancellation_js_1.isCancellationReason; } });
|
|
26
|
+
Object.defineProperty(exports, "isCancellationErrorCode", { enumerable: true, get: function () { return cancellation_js_1.isCancellationErrorCode; } });
|
|
25
27
|
Object.defineProperty(exports, "remainingQuantities", { enumerable: true, get: function () { return cancellation_js_1.remainingQuantities; } });
|
|
26
28
|
var receipt_company_js_1 = require("./receipt-company.js");
|
|
27
29
|
Object.defineProperty(exports, "fromReceiptCompanyPayload", { enumerable: true, get: function () { return receipt_company_js_1.fromReceiptCompanyPayload; } });
|
|
@@ -56,6 +56,7 @@ export interface ReceiptSummary {
|
|
|
56
56
|
/** Nur am Storno-Beleg: das Original. */
|
|
57
57
|
cancellationOf?: {
|
|
58
58
|
receiptId: string | null;
|
|
59
|
+
timeStamp?: string;
|
|
59
60
|
};
|
|
60
61
|
cancellationReason?: string;
|
|
61
62
|
/** offen | teil | voll -- Storno-Stand des Originals. */
|
|
@@ -84,6 +85,7 @@ export interface ReceiptSummaryPayload {
|
|
|
84
85
|
} | null;
|
|
85
86
|
cancellationOf?: {
|
|
86
87
|
receiptId?: string | null;
|
|
88
|
+
timeStamp?: string | null;
|
|
87
89
|
} | null;
|
|
88
90
|
cancellationReason?: string | null;
|
|
89
91
|
stornoStand?: string | null;
|
|
@@ -46,7 +46,10 @@ function fromReceiptSummaryPayload(payload) {
|
|
|
46
46
|
signatureOk: payload.signature_ok !== false,
|
|
47
47
|
items: Array.isArray(payload.items) ? payload.items.map((i) => ({ name: i?.name ?? '', quantity: typeof i?.quantity === 'number' ? i.quantity : 0 })) : [],
|
|
48
48
|
...(payload.operator ? { operator: { uid: payload.operator.uid ?? null, name: payload.operator.name ?? '' } } : {}),
|
|
49
|
-
...(payload.cancellationOf ? { cancellationOf: {
|
|
49
|
+
...(payload.cancellationOf ? { cancellationOf: {
|
|
50
|
+
receiptId: payload.cancellationOf.receiptId ?? null,
|
|
51
|
+
...(typeof payload.cancellationOf.timeStamp === 'string' && payload.cancellationOf.timeStamp ? { timeStamp: payload.cancellationOf.timeStamp } : {}),
|
|
52
|
+
} } : {}),
|
|
50
53
|
...(payload.cancellationReason ? { cancellationReason: payload.cancellationReason } : {}),
|
|
51
54
|
stornoStand: payload.stornoStand === 'teil' || payload.stornoStand === 'voll' ? payload.stornoStand : 'offen',
|
|
52
55
|
...(istZeroKind(payload.zeroKind) ? { zeroKind: payload.zeroKind } : {}),
|