@kreiseck/kasseneck-api 1.21.0 → 1.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ 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
+ ## 1.21.1 - 2026-10-31
8
+
9
+ Paying out a voucher that is no longer active names its status (twin of the backend rule `gutschein-core.darfAuszahlen`, keck, same day). Nothing else changes.
10
+
11
+ - **A payout checks `cancelled` and `blocked` first.** `receiptDueCents` and `receiptDueBreakdown` with a `payout` wish reject a cancelled voucher with `voucher_cancelled` and a blocked one with `voucher_blocked`, before the balance and before `payout: 'never'`. Reason: cancelling a voucher sale sets its balance to 0, so the register told the cashier "already used up" (`voucher_used_up`) for a cancelled voucher. Used up and paid out stay `voucher_used_up`.
12
+ - `fixtures/receipt-due-voucher-generated.json` regenerated from the backend with that rule (486 cases): four fixed payout cases at the end (`gen_voucher_482` to `485`: cancelled, cancelled with `never`, blocked with `never`, used up). The generator now maps the stored status into the check (`STATUS`); the random cases stay `active` and keep their bytes.
13
+
7
14
  ## 1.21.0 - 2026-10-31
8
15
 
9
16
  DEP export at the cash register (*Kassennachschau*, stage 2): the five DEP calls now also run on the register path, for the manager only, plus the words and the folder name both registers use. Additive.
@@ -325,7 +325,12 @@ function planeGutscheine(kunde, vouchers, art, o) {
325
325
  if ('fehler' in check)
326
326
  return check;
327
327
  if (v.action === 'payout') {
328
- // `gutschein-core.darfAuszahlen`: Auszahlung nicht gesperrt, aktiv oder abgelaufen bis zum Ende der Rueckzahlbarkeit.
328
+ // `gutschein-core.darfAuszahlen`: storniert und gesperrt zuerst (der Storno setzt den Saldo auf 0, die Kasse soll
329
+ // „storniert“ sagen, nicht „aufgebraucht“), dann Auszahlung nicht gesperrt, aktiv oder abgelaufen bis zum Ende der
330
+ // Rueckzahlbarkeit.
331
+ if (check.status === 'cancelled' || check.status === 'blocked') {
332
+ return nein(STATUS_FEHLER[check.status] ?? 'voucher_invalid', `Gutschein ${i + 1}: Status ${check.status}.`);
333
+ }
329
334
  if (check.payout === 'never')
330
335
  return nein('voucher_payout_not_allowed', `Gutschein ${i + 1}: dieser Gutschein wird nie ausgezahlt.`);
331
336
  if (!((check.balanceCents ?? 0) > 0))
@@ -4,4 +4,4 @@
4
4
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
5
5
  * beim Anheben der Version beide Stellen aendern.
6
6
  */
7
- export declare const PACKAGE_VERSION = "1.21.0";
7
+ export declare const PACKAGE_VERSION = "1.21.1";
@@ -7,4 +7,4 @@ exports.PACKAGE_VERSION = void 0;
7
7
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
8
8
  * beim Anheben der Version beide Stellen aendern.
9
9
  */
10
- exports.PACKAGE_VERSION = '1.21.0';
10
+ exports.PACKAGE_VERSION = '1.21.1';
@@ -316,7 +316,12 @@ export function planeGutscheine(kunde, vouchers, art, o) {
316
316
  if ('fehler' in check)
317
317
  return check;
318
318
  if (v.action === 'payout') {
319
- // `gutschein-core.darfAuszahlen`: Auszahlung nicht gesperrt, aktiv oder abgelaufen bis zum Ende der Rueckzahlbarkeit.
319
+ // `gutschein-core.darfAuszahlen`: storniert und gesperrt zuerst (der Storno setzt den Saldo auf 0, die Kasse soll
320
+ // „storniert“ sagen, nicht „aufgebraucht“), dann Auszahlung nicht gesperrt, aktiv oder abgelaufen bis zum Ende der
321
+ // Rueckzahlbarkeit.
322
+ if (check.status === 'cancelled' || check.status === 'blocked') {
323
+ return nein(STATUS_FEHLER[check.status] ?? 'voucher_invalid', `Gutschein ${i + 1}: Status ${check.status}.`);
324
+ }
320
325
  if (check.payout === 'never')
321
326
  return nein('voucher_payout_not_allowed', `Gutschein ${i + 1}: dieser Gutschein wird nie ausgezahlt.`);
322
327
  if (!((check.balanceCents ?? 0) > 0))
@@ -4,4 +4,4 @@
4
4
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
5
5
  * beim Anheben der Version beide Stellen aendern.
6
6
  */
7
- export declare const PACKAGE_VERSION = "1.21.0";
7
+ export declare const PACKAGE_VERSION = "1.21.1";
@@ -4,4 +4,4 @@
4
4
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
5
5
  * beim Anheben der Version beide Stellen aendern.
6
6
  */
7
- export const PACKAGE_VERSION = '1.21.0';
7
+ export const PACKAGE_VERSION = '1.21.1';
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.21.0",
2
+ "version": "1.21.1",
3
3
  "measuredOn": {
4
4
  "tid": "3600335",
5
5
  "hpsVersion": "1.10.0",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "title": "Kasseneck Rechnungs-API",
4
4
  "version": 2,
5
- "package": "1.21.0",
5
+ "package": "1.21.1",
6
6
  "endpoints": {
7
7
  "createCustomer": {
8
8
  "request": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.21.0",
2
+ "version": "1.21.1",
3
3
  "languages": [
4
4
  "de",
5
5
  "en"
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.21.0",
2
+ "version": "1.21.1",
3
3
  "messages": {
4
4
  "network.no_connection": {
5
5
  "text": "Keine Verbindung zum Server. Bitte die Internetverbindung prüfen und erneut versuchen."
@@ -3,7 +3,7 @@
3
3
  "_source": {
4
4
  "beleg-toepfe.js": "60630493a589469d1cdfeea6fef667d20feb8f3a156819ba4d90b21501fdc4ea",
5
5
  "gutschein-beleg.js": "36750aa4eec8d94f57c2eebce0d34d13c7ffb3f0f5ea558fac1f56f15ff50004",
6
- "gutschein-core.js": "8eeb04a12f771c6b70b23ab7a361354745182ab18235213d3c2f1f9191ebadef",
6
+ "gutschein-core.js": "b4d3188c666a43e3be8cc1c2c54e5b8de24e10db785e33bb2ce81aa38ae47929",
7
7
  "tip-core.js": "2d5b65c3cbe96935c8537d35f02b30906a7477afa340e18325b60bd60af1c7d9",
8
8
  "vat-buckets.js": "92c69632c0120dbb09a22cef5a36b052e81605d99907eeda7289b0d3db78454c",
9
9
  "zahlungen-core.js": "7ea8b07dfd222741049a47bec0149953d5696b0e1e089bf9919d4bd2cafff530"
@@ -491,6 +491,10 @@
491
491
  {"name":"gen_voucher_478_single_purpose_exempt","input":{"receiptType":"standard","items":[{"name":"P","quantity":1,"priceCents":2521,"vatRate":4.9,"articleId":"item_mani"},{"name":"P","quantity":2.75,"priceCents":2266,"vatRate":13},{"name":"P","quantity":2,"priceCents":64,"vatRate":10,"articleId":"item_mani"},{"name":"Discount","quantity":1,"priceCents":-146,"vatRate":13,"kind":"discount"}],"vouchers":[{"type":"single_purpose","action":"redeem","code":"DTD5-9ECF-5KNZ","amountCents":58}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"single_purpose","status":"active","codeSuffix":"5KNZ","balanceCents":2402,"vatRateBp":0,"exempt":true}}]},"expected":{"dueCents":8677,"counterDeltaCents":8677,"valueVoucherFlowCents":0,"bucketsCents":{"amountRateStandard":0,"amountRateReduced1":127,"amountRateReduced2":6046,"amountRateZero":0,"amountRateSpecial":2504,"amountRatOthers":0}}},
492
492
  {"name":"gen_voucher_479_sell_multi_purpose","input":{"receiptType":"standard","items":[{"name":"P","quantity":3,"priceCents":80,"vatRate":4.9}],"vouchers":[{"action":"sell","type":"multi_purpose","typeId":"vt_mehrzweck_479","amountCents":7217}],"today":"2100-01-04","voucherTypes":[{"id":"vt_mehrzweck_479","kind":"multi_purpose","vatRateBp":null,"amount":{"mode":"fixed","cents":7217}}],"smallBusiness":true},"expected":{"dueCents":7457,"counterDeltaCents":7457,"valueVoucherFlowCents":0,"bucketsCents":{"amountRateStandard":0,"amountRateReduced1":0,"amountRateReduced2":0,"amountRateZero":7217,"amountRateSpecial":240,"amountRatOthers":0}}},
493
493
  {"name":"gen_voucher_480_redeem_wrong_kind","input":{"receiptType":"standard","items":[{"name":"P","quantity":1,"priceCents":2000,"vatRate":20}],"vouchers":[{"type":"single_purpose","action":"redeem","code":"DTD5-9ECF-5KNZ","amountCents":1000}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"multi_purpose","status":"active","codeSuffix":"5KNZ","balanceCents":5000}}]},"expected":{"voucherError":"voucher_invalid"}},
494
- {"name":"gen_voucher_481_redeem_wrong_kind","input":{"receiptType":"standard","items":[{"name":"P","quantity":1,"priceCents":2000,"vatRate":20}],"vouchers":[{"type":"multi_purpose","action":"redeem","code":"DTD5-9ECF-5KNZ","amountCents":1000}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"single_purpose","status":"active","codeSuffix":"5KNZ","balanceCents":5000,"vatRateBp":2000}}]},"expected":{"voucherError":"voucher_invalid"}}
494
+ {"name":"gen_voucher_481_redeem_wrong_kind","input":{"receiptType":"standard","items":[{"name":"P","quantity":1,"priceCents":2000,"vatRate":20}],"vouchers":[{"type":"multi_purpose","action":"redeem","code":"DTD5-9ECF-5KNZ","amountCents":1000}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"single_purpose","status":"active","codeSuffix":"5KNZ","balanceCents":5000,"vatRateBp":2000}}]},"expected":{"voucherError":"voucher_invalid"}},
495
+ {"name":"gen_voucher_482_payout_multi_purpose_cancelled","input":{"receiptType":"standard","items":[],"vouchers":[{"type":"multi_purpose","action":"payout","code":"DTD5-9ECF-5KNZ","amountCents":1000,"reason":"Goodwill"}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"multi_purpose","status":"cancelled","codeSuffix":"5KNZ","balanceCents":0}}]},"expected":{"voucherError":"voucher_cancelled"}},
496
+ {"name":"gen_voucher_483_payout_single_purpose_cancelled","input":{"receiptType":"standard","items":[],"vouchers":[{"type":"single_purpose","action":"payout","code":"DTD5-9ECF-5KNZ","amountCents":1000,"reason":"Goodwill"}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"single_purpose","status":"cancelled","codeSuffix":"5KNZ","payout":"never","balanceCents":0,"vatRateBp":2000}}]},"expected":{"voucherError":"voucher_cancelled"}},
497
+ {"name":"gen_voucher_484_payout_multi_purpose_blocked","input":{"receiptType":"standard","items":[],"vouchers":[{"type":"multi_purpose","action":"payout","code":"DTD5-9ECF-5KNZ","amountCents":1000,"reason":"Goodwill"}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"multi_purpose","status":"blocked","codeSuffix":"5KNZ","payout":"never","balanceCents":5000}}]},"expected":{"voucherError":"voucher_blocked"}},
498
+ {"name":"gen_voucher_485_payout_multi_purpose_used_up","input":{"receiptType":"standard","items":[],"vouchers":[{"type":"multi_purpose","action":"payout","code":"DTD5-9ECF-5KNZ","amountCents":1000,"reason":"Goodwill"}],"today":"2026-10-19","voucherInfo":[{"code":"DTD5-9ECF-5KNZ","check":{"type":"multi_purpose","status":"used_up","codeSuffix":"5KNZ","balanceCents":0}}]},"expected":{"voucherError":"voucher_used_up"}}
495
499
  ]
496
500
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.21.0",
2
+ "version": "1.21.1",
3
3
  "baseUrls": {
4
4
  "public": "https://api.kasseneck.at/v3",
5
5
  "pos": "https://kasse.kasseneck.at/api/v3"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kreiseck/kasseneck-api",
3
- "version": "1.21.0",
3
+ "version": "1.21.1",
4
4
  "description": "Austrian fiscal cash register (RKSV) client for JavaScript and TypeScript: signed receipts, cancellations, card payments, receipt printing (ESC/POS), invoices, inventory. RKSV-Registrierkasse für JavaScript und TypeScript.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Kreiseck",