@kreiseck/kasseneck-api 0.6.49 → 0.6.50

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 CHANGED
@@ -199,6 +199,11 @@ Was ein Storno gewährt hat, steht am Eintrag in `receipt.cancellations[]` als
199
199
  `promoAdjustmentCents` (Cent je Steuertopf) — die Kasse kann es im Dialog
200
200
  zeigen, rechnen muss sie nichts.
201
201
 
202
+ **Bon.** Der Kopfblock des Storno-Bons nennt Bezug, Datum des Originals und
203
+ Grund: „STORNOBELEG / Stornobuchung zu Beleg KASSE1-ID-42 / vom 11.08.2026,
204
+ 09:02 Uhr / Grund: Fehleingabe". Das Datum kommt aus `cancellationOf.timeStamp`
205
+ (Backend seit 2026-09-04); Altbelege ohne bleiben ohne die Zeile.
206
+
202
207
  ## Unterpfade
203
208
 
204
209
  | Unterpfad | Inhalt |
@@ -35,6 +35,12 @@ export declare function isCancellationErrorCode(value: unknown): value is Cancel
35
35
  export interface CancellationOf {
36
36
  receiptId: string;
37
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;
38
44
  }
39
45
  /** Eine stornierte Position: Index im Original und Menge. */
40
46
  export interface CancellationItem {
@@ -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: { receiptId: payload.cancellationOf.receiptId ?? null } } : {}),
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 } : {}),
@@ -76,7 +76,11 @@ function fromReceiptPayload(payload) {
76
76
  signatureSuccess: payload.signatureSuccess ?? undefined,
77
77
  customProjectId: payload.customProjectId ?? undefined,
78
78
  ...(typeof payload.tipCents === 'number' ? { tipCents: payload.tipCents } : {}),
79
- ...(payload.cancellationOf ? { cancellationOf: { receiptId: payload.cancellationOf.receiptId, fullReceiptId: payload.cancellationOf.fullReceiptId ?? null } } : {}),
79
+ ...(payload.cancellationOf ? { cancellationOf: {
80
+ receiptId: payload.cancellationOf.receiptId,
81
+ fullReceiptId: payload.cancellationOf.fullReceiptId ?? null,
82
+ ...(typeof payload.cancellationOf.timeStamp === 'string' && payload.cancellationOf.timeStamp ? { timeStamp: payload.cancellationOf.timeStamp } : {}),
83
+ } } : {}),
80
84
  ...(payload.cancellationReason ? { cancellationReason: payload.cancellationReason } : {}),
81
85
  ...((0, receipt_summary_js_1.istZeroKind)(payload.zeroKind) ? { zeroKind: payload.zeroKind } : {}),
82
86
  ...(payload.cancellations ? { cancellations: payload.cancellations.map(leseStorno) } : {}),
@@ -48,6 +48,21 @@ function belegZeit(timeStamp) {
48
48
  const zwei = (n) => String(n).padStart(2, '0');
49
49
  return `${zwei(t.day)}.${zwei(t.month)}.${t.year} ${zwei(t.hour)}:${zwei(t.minute)}:${zwei(t.second)}`;
50
50
  }
51
+ /**
52
+ * Datum des stornierten Originals fuer den Kopfblock: „11.08.2026, 09:02 Uhr".
53
+ * Ein unlesbarer Zeitstempel am BEZUG ist kein Grund, den Storno-Bon zu
54
+ * verweigern (der Beleg selbst ist gueltig) — dann bleibt die Zeile weg.
55
+ */
56
+ function originalDatum(timeStamp) {
57
+ try {
58
+ const t = (0, vienna_time_js_1.toViennaWallClock)((0, vienna_time_js_1.parseServerTimeStamp)(timeStamp));
59
+ const zwei = (n) => String(n).padStart(2, '0');
60
+ return `${zwei(t.day)}.${zwei(t.month)}.${t.year}, ${zwei(t.hour)}:${zwei(t.minute)} Uhr`;
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
51
66
  /**
52
67
  * Zahlungsart als Anzeigetext. Drei Faelle, und alle drei kommen vor:
53
68
  * bekannter Eintrag (Beschriftung), unbekannter Schluessel (roh — besser als
@@ -415,6 +430,10 @@ function belegartBlock(receipt) {
415
430
  if (t === 'cancellation') {
416
431
  aus.push(bannerZeile('STORNOBELEG'));
417
432
  aus.push(textZeile(receipt.cancellationOf ? `Stornobuchung zu Beleg ${receipt.cancellationOf.receiptId}` : 'Stornobuchung', 'center'));
433
+ // Datum des Originals, wenn der Bezug es traegt (Backend seit 2026-09-04).
434
+ const datum = receipt.cancellationOf?.timeStamp ? originalDatum(receipt.cancellationOf.timeStamp) : null;
435
+ if (datum)
436
+ aus.push(textZeile(`vom ${datum}`, 'center'));
418
437
  const grund = stornoGrundText(typeof receipt.cancellationReason === 'string' ? receipt.cancellationReason : undefined);
419
438
  if (grund)
420
439
  aus.push(textZeile(`Grund: ${grund}`, 'center'));
@@ -35,6 +35,12 @@ export declare function isCancellationErrorCode(value: unknown): value is Cancel
35
35
  export interface CancellationOf {
36
36
  receiptId: string;
37
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;
38
44
  }
39
45
  /** Eine stornierte Position: Index im Original und Menge. */
40
46
  export interface CancellationItem {
@@ -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;
@@ -41,7 +41,10 @@ export function fromReceiptSummaryPayload(payload) {
41
41
  signatureOk: payload.signature_ok !== false,
42
42
  items: Array.isArray(payload.items) ? payload.items.map((i) => ({ name: i?.name ?? '', quantity: typeof i?.quantity === 'number' ? i.quantity : 0 })) : [],
43
43
  ...(payload.operator ? { operator: { uid: payload.operator.uid ?? null, name: payload.operator.name ?? '' } } : {}),
44
- ...(payload.cancellationOf ? { cancellationOf: { receiptId: payload.cancellationOf.receiptId ?? null } } : {}),
44
+ ...(payload.cancellationOf ? { cancellationOf: {
45
+ receiptId: payload.cancellationOf.receiptId ?? null,
46
+ ...(typeof payload.cancellationOf.timeStamp === 'string' && payload.cancellationOf.timeStamp ? { timeStamp: payload.cancellationOf.timeStamp } : {}),
47
+ } } : {}),
45
48
  ...(payload.cancellationReason ? { cancellationReason: payload.cancellationReason } : {}),
46
49
  stornoStand: payload.stornoStand === 'teil' || payload.stornoStand === 'voll' ? payload.stornoStand : 'offen',
47
50
  ...(istZeroKind(payload.zeroKind) ? { zeroKind: payload.zeroKind } : {}),
@@ -70,7 +70,11 @@ export function fromReceiptPayload(payload) {
70
70
  signatureSuccess: payload.signatureSuccess ?? undefined,
71
71
  customProjectId: payload.customProjectId ?? undefined,
72
72
  ...(typeof payload.tipCents === 'number' ? { tipCents: payload.tipCents } : {}),
73
- ...(payload.cancellationOf ? { cancellationOf: { receiptId: payload.cancellationOf.receiptId, fullReceiptId: payload.cancellationOf.fullReceiptId ?? null } } : {}),
73
+ ...(payload.cancellationOf ? { cancellationOf: {
74
+ receiptId: payload.cancellationOf.receiptId,
75
+ fullReceiptId: payload.cancellationOf.fullReceiptId ?? null,
76
+ ...(typeof payload.cancellationOf.timeStamp === 'string' && payload.cancellationOf.timeStamp ? { timeStamp: payload.cancellationOf.timeStamp } : {}),
77
+ } } : {}),
74
78
  ...(payload.cancellationReason ? { cancellationReason: payload.cancellationReason } : {}),
75
79
  ...(istZeroKind(payload.zeroKind) ? { zeroKind: payload.zeroKind } : {}),
76
80
  ...(payload.cancellations ? { cancellations: payload.cancellations.map(leseStorno) } : {}),
@@ -37,6 +37,21 @@ function belegZeit(timeStamp) {
37
37
  const zwei = (n) => String(n).padStart(2, '0');
38
38
  return `${zwei(t.day)}.${zwei(t.month)}.${t.year} ${zwei(t.hour)}:${zwei(t.minute)}:${zwei(t.second)}`;
39
39
  }
40
+ /**
41
+ * Datum des stornierten Originals fuer den Kopfblock: „11.08.2026, 09:02 Uhr".
42
+ * Ein unlesbarer Zeitstempel am BEZUG ist kein Grund, den Storno-Bon zu
43
+ * verweigern (der Beleg selbst ist gueltig) — dann bleibt die Zeile weg.
44
+ */
45
+ function originalDatum(timeStamp) {
46
+ try {
47
+ const t = toViennaWallClock(parseServerTimeStamp(timeStamp));
48
+ const zwei = (n) => String(n).padStart(2, '0');
49
+ return `${zwei(t.day)}.${zwei(t.month)}.${t.year}, ${zwei(t.hour)}:${zwei(t.minute)} Uhr`;
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
40
55
  /**
41
56
  * Zahlungsart als Anzeigetext. Drei Faelle, und alle drei kommen vor:
42
57
  * bekannter Eintrag (Beschriftung), unbekannter Schluessel (roh — besser als
@@ -404,6 +419,10 @@ function belegartBlock(receipt) {
404
419
  if (t === 'cancellation') {
405
420
  aus.push(bannerZeile('STORNOBELEG'));
406
421
  aus.push(textZeile(receipt.cancellationOf ? `Stornobuchung zu Beleg ${receipt.cancellationOf.receiptId}` : 'Stornobuchung', 'center'));
422
+ // Datum des Originals, wenn der Bezug es traegt (Backend seit 2026-09-04).
423
+ const datum = receipt.cancellationOf?.timeStamp ? originalDatum(receipt.cancellationOf.timeStamp) : null;
424
+ if (datum)
425
+ aus.push(textZeile(`vom ${datum}`, 'center'));
407
426
  const grund = stornoGrundText(typeof receipt.cancellationReason === 'string' ? receipt.cancellationReason : undefined);
408
427
  if (grund)
409
428
  aus.push(textZeile(`Grund: ${grund}`, 'center'));
@@ -58,11 +58,12 @@
58
58
  "legalMessage": [],
59
59
  "cancellationOf": {
60
60
  "receiptId": "AT0-KASSE1-55",
61
- "fullReceiptId": null
61
+ "fullReceiptId": null,
62
+ "timeStamp": "2026-08-11T09:02:17"
62
63
  },
63
64
  "cancellationReason": "fehleingabe"
64
65
  },
65
66
  "options": {
66
67
  "paperSize": "mm80"
67
68
  }
68
- }
69
+ }
@@ -38,7 +38,8 @@
38
38
  "legalMessage": [],
39
39
  "cancellationOf": {
40
40
  "receiptId": "AT0-KASSE1-42",
41
- "fullReceiptId": null
41
+ "fullReceiptId": null,
42
+ "timeStamp": "2026-08-11T09:02:17"
42
43
  },
43
44
  "cancellationReason": "fehleingabe"
44
45
  },
@@ -44,7 +44,8 @@
44
44
  "legalMessage": [],
45
45
  "cancellationOf": {
46
46
  "receiptId": "AT0-KASSE1-42",
47
- "fullReceiptId": null
47
+ "fullReceiptId": null,
48
+ "timeStamp": "2026-08-11T09:02:17"
48
49
  },
49
50
  "cancellationReason": "kunde_storniert"
50
51
  },
@@ -7,6 +7,7 @@
7
7
  STORNOBELEG
8
8
  Stornobuchung zu Beleg
9
9
  AT0-KASSE1-55
10
+ vom 11.08.2026, 09:02 Uhr
10
11
  Grund: Fehleingabe
11
12
 
12
13
  Datum: 13.08.2026 10:15:30
@@ -6,6 +6,7 @@
6
6
 
7
7
  STORNOBELEG
8
8
  Stornobuchung zu Beleg AT0-KASSE1-55
9
+ vom 11.08.2026, 09:02 Uhr
9
10
  Grund: Fehleingabe
10
11
 
11
12
  Datum: 13.08.2026 10:15:30
@@ -45,6 +45,12 @@
45
45
  "align": "center",
46
46
  "bold": false
47
47
  },
48
+ {
49
+ "kind": "text",
50
+ "text": "vom 11.08.2026, 09:02 Uhr",
51
+ "align": "center",
52
+ "bold": false
53
+ },
48
54
  {
49
55
  "kind": "text",
50
56
  "text": "Grund: Fehleingabe",
@@ -7,6 +7,7 @@
7
7
  STORNOBELEG
8
8
  Stornobuchung zu Beleg
9
9
  AT0-KASSE1-42
10
+ vom 11.08.2026, 09:02 Uhr
10
11
  Grund: Fehleingabe
11
12
 
12
13
  Datum: 13.08.2026 10:15:30
@@ -6,6 +6,7 @@
6
6
 
7
7
  STORNOBELEG
8
8
  Stornobuchung zu Beleg AT0-KASSE1-42
9
+ vom 11.08.2026, 09:02 Uhr
9
10
  Grund: Fehleingabe
10
11
 
11
12
  Datum: 13.08.2026 10:15:30
@@ -45,6 +45,12 @@
45
45
  "align": "center",
46
46
  "bold": false
47
47
  },
48
+ {
49
+ "kind": "text",
50
+ "text": "vom 11.08.2026, 09:02 Uhr",
51
+ "align": "center",
52
+ "bold": false
53
+ },
48
54
  {
49
55
  "kind": "text",
50
56
  "text": "Grund: Fehleingabe",
@@ -7,6 +7,7 @@
7
7
  STORNOBELEG
8
8
  Stornobuchung zu Beleg
9
9
  AT0-KASSE1-42
10
+ vom 11.08.2026, 09:02 Uhr
10
11
  Grund: Kunde hat storniert
11
12
 
12
13
  Datum: 13.08.2026 10:15:30
@@ -6,6 +6,7 @@
6
6
 
7
7
  STORNOBELEG
8
8
  Stornobuchung zu Beleg AT0-KASSE1-42
9
+ vom 11.08.2026, 09:02 Uhr
9
10
  Grund: Kunde hat storniert
10
11
 
11
12
  Datum: 13.08.2026 10:15:30
@@ -45,6 +45,12 @@
45
45
  "align": "center",
46
46
  "bold": false
47
47
  },
48
+ {
49
+ "kind": "text",
50
+ "text": "vom 11.08.2026, 09:02 Uhr",
51
+ "align": "center",
52
+ "bold": false
53
+ },
48
54
  {
49
55
  "kind": "text",
50
56
  "text": "Grund: Kunde hat storniert",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.6.49",
2
+ "version": "0.6.50",
3
3
  "gemessenAn": {
4
4
  "tid": "3600335",
5
5
  "hpsVersion": "1.10.0",
@@ -80,22 +80,22 @@
80
80
  "grid48": "e0f4e73c873ae0a70623c7c05673a5ca9b736822375c13f6ed0cd3351ab767f9"
81
81
  },
82
82
  "storno-rabatt": {
83
- "eingabe": "80021cbf2da292c6d82baf92c51fb7fb67ad5bb3d55a452efaa67bf2cc6b4c72",
84
- "erwartet": "7a0ce1111094dcc8effb1fffde56f0f69de621318212eec3ac375cc188a5cb56",
85
- "grid32": "85a0dae903f3bf81b8c1736f4d5ea252472b684d14c26cc77483818080c59a69",
86
- "grid48": "6cb23805cff69c09d7941f184b5b741667010a9da660eb3e06fec095995988dc"
83
+ "eingabe": "d6bd978f4cc3e9c8c4315c573c7a3f5c8dfea4bf65fce6789f268056a521ec15",
84
+ "erwartet": "a10fc0dbbfd46366feab7431ab1608ad5a76418e80b50d2903c574ee2cb70040",
85
+ "grid32": "5f932ee49c9b7ee1e1dfc5fe703a18da43c782072012280ca93b177b0c535c20",
86
+ "grid48": "dc84efa238626d782cb049df6299d65fa2a5740795e610ecaf903ac4ca296434"
87
87
  },
88
88
  "storno-teil": {
89
- "eingabe": "80320cbc1f48fa6b1668662f8aad766733ae7e0695c9c1680f8a115e0c927239",
90
- "erwartet": "5638fe514e620d8bad9531f706d9a986fff386b41b8cfd1126302272fca55f5b",
91
- "grid32": "d36d0e37bf342a1e50d6b8aa41f4664196fa61fa1c5c43fc0097db77d8e89c90",
92
- "grid48": "2e2b691119144cbb5e7c4d5ccadee7e46454723a62371fabc2d30766d7d42e1b"
89
+ "eingabe": "2f4cab11c1c9e8bb4722dd6c4a279825a9e31e3b6a9335c017bc587d97af0fd4",
90
+ "erwartet": "dcf388d74261171b3b004f1abb51650dd7d2d53f7b2c8a4ae453ce47ec3e01e6",
91
+ "grid32": "e340077738bb0e336cc64a5c8e15a6712624e7d3ecbe7a3f981580c2efe446c7",
92
+ "grid48": "c62513749f18d8cb230b96607cfae46e49e99b50799b57308c747f8a12973d0a"
93
93
  },
94
94
  "storno-voll": {
95
- "eingabe": "53ecbfa12576bee3e3077bbf104324794790008e5d54efe6135664388fdab80d",
96
- "erwartet": "069700f0321116b427d47ee38bc2a3d9a1cacc49673d482b3bbb82e5d1cc62ab",
97
- "grid32": "cb9950d335a90d58a0445014100ac1c9040326928965053d079fb6144dede380",
98
- "grid48": "7509be1eb23ceedff40edc5b070e4bc20cd72d15b6d6d4acb4d7771bc86dec21"
95
+ "eingabe": "11f4f58f4f06cd2d414f982b85a017c2a3f62cd23fb8c54d000c16ce1490d2f8",
96
+ "erwartet": "8e595d6afb36e9c2d2dd77ec71927a039435d74eafe2321c73fff48d321d3602",
97
+ "grid32": "e8c20dc0ea199b6ee5418205e498dcda3e1bb8fb8b1d0d639af353b1df98740c",
98
+ "grid48": "81aa151523ae7fa542d58b8c4835a690b686a9aeb9fb7872950419cd370f418c"
99
99
  },
100
100
  "testkasse-verkauf": {
101
101
  "eingabe": "5cd594029a3d7af4a7c502719763d8b5df0063ff7e46da43c9c7dc4fd2638e1f",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.6.49",
2
+ "version": "0.6.50",
3
3
  "aufrufe": [
4
4
  "cancelReceipt",
5
5
  "createPaymentLinkStripe",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kreiseck/kasseneck-api",
3
- "version": "0.6.49",
3
+ "version": "0.6.50",
4
4
  "description": "JavaScript-Zwilling von kasseneck_api (Flutter) fuer das Kasseneck-Backend",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Kreiseck",