@kreiseck/kasseneck-api 1.20.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/client/aufrufe.d.ts +4 -3
  3. package/dist/cjs/client/aufrufe.js +9 -2
  4. package/dist/cjs/client/dep-export.d.ts +1 -1
  5. package/dist/cjs/client/dep-export.js +1 -0
  6. package/dist/cjs/client/transport.d.ts +4 -4
  7. package/dist/cjs/client/transport.js +3 -3
  8. package/dist/cjs/pos/dep.d.ts +10 -0
  9. package/dist/cjs/pos/dep.js +27 -0
  10. package/dist/cjs/pos/index.d.ts +1 -0
  11. package/dist/cjs/pos/index.js +5 -2
  12. package/dist/cjs/pos/texte.d.ts +109 -0
  13. package/dist/cjs/pos/texte.js +42 -0
  14. package/dist/cjs/receipt/gutschein-plan.js +6 -1
  15. package/dist/cjs/stored/vokabular.d.ts +1 -1
  16. package/dist/cjs/stored/vokabular.js +1 -1
  17. package/dist/cjs/version.d.ts +1 -1
  18. package/dist/cjs/version.js +1 -1
  19. package/dist/esm/client/aufrufe.d.ts +4 -3
  20. package/dist/esm/client/aufrufe.js +9 -2
  21. package/dist/esm/client/dep-export.d.ts +1 -1
  22. package/dist/esm/client/dep-export.js +1 -0
  23. package/dist/esm/client/transport.d.ts +4 -4
  24. package/dist/esm/client/transport.js +3 -3
  25. package/dist/esm/pos/dep.d.ts +10 -0
  26. package/dist/esm/pos/dep.js +24 -0
  27. package/dist/esm/pos/index.d.ts +1 -0
  28. package/dist/esm/pos/index.js +2 -0
  29. package/dist/esm/pos/texte.d.ts +109 -0
  30. package/dist/esm/pos/texte.js +42 -0
  31. package/dist/esm/receipt/gutschein-plan.js +6 -1
  32. package/dist/esm/stored/vokabular.d.ts +1 -1
  33. package/dist/esm/stored/vokabular.js +1 -1
  34. package/dist/esm/version.d.ts +1 -1
  35. package/dist/esm/version.js +1 -1
  36. package/fixtures/dep-folder-cases.json +14 -0
  37. package/fixtures/hobex-hps-codes.json +1 -1
  38. package/fixtures/invoice-api.schema.json +1 -1
  39. package/fixtures/invoice-texts.json +1 -1
  40. package/fixtures/pos-message-cases.json +9 -0
  41. package/fixtures/pos-texts.json +127 -1
  42. package/fixtures/receipt-due-voucher-generated.json +6 -2
  43. package/fixtures/surface.json +12 -2
  44. package/fixtures/v3/antworten/belege.json +1 -1
  45. package/fixtures/v3/antworten/belegmail.json +1 -1
  46. package/fixtures/v3/antworten/berichte.json +1 -1
  47. package/fixtures/v3/antworten/kasse-belege.json +1 -1
  48. package/fixtures/v3/antworten/kasse.json +802 -3
  49. package/fixtures/v3/antworten/lager.json +1 -1
  50. package/fixtures/v3/antworten/rechnungen.json +1 -1
  51. package/fixtures/v3/antworten/storno.json +1 -1
  52. package/fixtures/v3/stored/belege.json +1 -1
  53. package/fixtures/v3/stored/kasse.json +153 -6
  54. package/fixtures/v3/stored/rechnungen.json +1 -1
  55. package/fixtures/v3/v3-vokabular.json +81 -3
  56. package/fixtures/v3/zahlbetrag-faelle.json +1 -1
  57. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ 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
+
14
+ ## 1.21.0 - 2026-10-31
15
+
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.
17
+
18
+ - **`POS_CALLS` gains `createDepExport`, `getDepExport`, `getDepExportFile`, `createDepHandoverLink` and `revokeDepHandoverLink`** (now 47, eleven of them also public). Signed in with `registerUserAuth` they go to `https://kasse.kasseneck.at/api/v3/<name>` (the web register: `/api/v3`), with `apiKeyAuth` they stay on the public base as before. Reason: the web register and the register app export the DEP during an inspection themselves instead of sending the owner to the customer area.
19
+ - **New error code `manager_only`** in `DEP_EXPORT_ERROR_CODES` (contract `errorCodes.depExport`): on the register path only the manager exports, that is the owner or a register user with the permission `layout` (the one both registers call *Kassen-Chef*). A device with an API key is not affected.
20
+ - **Words of the screen *Prüfung (DEP)*** in `LABELS` (`nav.dep`, `dep.*`: title, period choice, create, save to USB stick, link for the inspector, code, valid until, revoke, checksum) and `MESSAGES` (`dep.*`: manager only, offline with the two working days, creating, running, failed, daily limit, period invalid, USB hint, saved, save failed, ZIP fallback in the browser, code shown once, revoked). `ERROR_CODE_RULES` map `manager_only`, `export_running` and `too_many_exports` to the register's own sentence; deliberately not `export_failed` (also a code of the payment paths, where the outcome can be unknown) and not `too_many_links` (the backend's sentence names the limit). Reason: web register and app say the same.
21
+ - **`depFolderName(cashregisterId, from?, to?)`** (`./pos`): the folder on the USB stick, `DEP_<cash register id>_<from>_<to>`, `DEP_<id>_alles` without a period, `bis_`/`ab_` with one end only; characters FAT32 or exFAT refuse become `_`. Cases in `fixtures/dep-folder-cases.json` (also used by the Dart twin).
22
+ - Contract `v3` re-fetched from the backend (the five calls in `endpoints.register`, `manager_only`, register-path cases).
23
+
7
24
  ## 1.20.0 - 2026-10-30
8
25
 
9
26
  DEP export for the cash register inspection (*Kassennachschau*): `createDepExport`, `getDepExport`, `waitForDepExport`, `getDepExportFile`, `createDepHandoverLink` and `revokeDepHandoverLink` for the five new public endpoints (`/v3` only). Additive.
@@ -25,10 +25,11 @@ export declare const PUBLIC_CALLS: readonly ["createReceipt", "getReceipt", "can
25
25
  /**
26
26
  * Die Endpunkte des Kassenwegs (`https://kasse.kasseneck.at/api/v3/<name>`,
27
27
  * Web-Kasse: gleicher Ursprung `/api/v3`), in der Reihenfolge von
28
- * `endpoints.register`. Sechs davon sind zugleich oeffentlich; die Kasse ruft
29
- * sie trotzdem ueber diesen Weg (ein Dialekt je Client, Nachtrag §5.2).
28
+ * `endpoints.register`. Elf davon sind zugleich oeffentlich (sechs Beleg-Aufrufe und
29
+ * die fuenf DEP-Aufrufe); die Kasse ruft sie trotzdem ueber diesen Weg (ein Dialekt
30
+ * je Client, Nachtrag §5.2).
30
31
  */
31
- export declare const POS_CALLS: readonly ["pairRegisterDevice", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "registerUserLogin", "registerPinLogin", "renewRegisterSession", "endRegisterSession", "unpairRegisterDevice", "listMyCashregisters", "listMyReceipts", "getReceipt", "createReceipt", "generateFullReceiptId", "cancelReceipt", "sendReceiptEmail", "listMyArticleGroups", "listMyArticles", "getKasseSettings", "setMyKasseSettings", "setMyKasseLogo", "setMyRegisterDeviceSettings", "listMyPrinters", "createPrintJob", "getPrintJob", "listMyTipRecipients", "listMyStockLocations", "listMyStock", "setMyCashregisterStockLocation", "listMyStocktakes", "listMyStocktakeItems", "listMyStocktakeCounts", "recordMyStocktakeCount", "voidMyStocktakeCount", "checkVoucher", "reprintVoucherLabel", "getMyDrawerState", "openMyShift", "recordMyCashMovement", "logMyDrawerOpenings", "getMyShiftReport", "closeMyShift", "logReceiptOutputs"];
32
+ export declare const POS_CALLS: readonly ["pairRegisterDevice", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "registerUserLogin", "registerPinLogin", "renewRegisterSession", "endRegisterSession", "unpairRegisterDevice", "listMyCashregisters", "listMyReceipts", "getReceipt", "createReceipt", "generateFullReceiptId", "cancelReceipt", "sendReceiptEmail", "listMyArticleGroups", "listMyArticles", "getKasseSettings", "setMyKasseSettings", "setMyKasseLogo", "setMyRegisterDeviceSettings", "listMyPrinters", "createPrintJob", "getPrintJob", "listMyTipRecipients", "listMyStockLocations", "listMyStock", "setMyCashregisterStockLocation", "listMyStocktakes", "listMyStocktakeItems", "listMyStocktakeCounts", "recordMyStocktakeCount", "voidMyStocktakeCount", "checkVoucher", "reprintVoucherLabel", "getMyDrawerState", "openMyShift", "recordMyCashMovement", "logMyDrawerOpenings", "getMyShiftReport", "closeMyShift", "logReceiptOutputs", "createDepExport", "getDepExport", "getDepExportFile", "createDepHandoverLink", "revokeDepHandoverLink"];
32
33
  export type PublicCall = typeof PUBLIC_CALLS[number];
33
34
  export type PosCall = typeof POS_CALLS[number];
34
35
  /**
@@ -286,8 +286,9 @@ exports.PUBLIC_CALLS = [
286
286
  /**
287
287
  * Die Endpunkte des Kassenwegs (`https://kasse.kasseneck.at/api/v3/<name>`,
288
288
  * Web-Kasse: gleicher Ursprung `/api/v3`), in der Reihenfolge von
289
- * `endpoints.register`. Sechs davon sind zugleich oeffentlich; die Kasse ruft
290
- * sie trotzdem ueber diesen Weg (ein Dialekt je Client, Nachtrag §5.2).
289
+ * `endpoints.register`. Elf davon sind zugleich oeffentlich (sechs Beleg-Aufrufe und
290
+ * die fuenf DEP-Aufrufe); die Kasse ruft sie trotzdem ueber diesen Weg (ein Dialekt
291
+ * je Client, Nachtrag §5.2).
291
292
  */
292
293
  exports.POS_CALLS = [
293
294
  'pairRegisterDevice',
@@ -337,6 +338,12 @@ exports.POS_CALLS = [
337
338
  'closeMyShift',
338
339
  // Ausgaben eines Belegs melden: nur ueber den Kassenweg.
339
340
  'logReceiptOutputs',
341
+ // DEP fuer die Kassennachschau (Stufe 2): zugleich oeffentlich; an der Kasse nur fuer den Chef (manager_only).
342
+ 'createDepExport',
343
+ 'getDepExport',
344
+ 'getDepExportFile',
345
+ 'createDepHandoverLink',
346
+ 'revokeDepHandoverLink',
340
347
  ];
341
348
  /**
342
349
  * Die Aufrufe **mit Wirkung**, alphabetisch: sie legen etwas an, aendern oder
@@ -30,7 +30,7 @@ export type DepExportFileKind = (typeof DEP_EXPORT_FILES)[number];
30
30
  * Codes von Anmeldung und Rand. Ein Code ausserhalb bleibt ueber
31
31
  * `KasseneckApiError.code` lesbar.
32
32
  */
33
- export declare const DEP_EXPORT_ERROR_CODES: readonly ["validation", "invalid_period", "idempotency_conflict", "export_running", "too_many_exports", "export_not_found", "export_not_ready", "export_failed", "invalid_file", "file_not_available", "too_many_links", "link_not_found", "server_error"];
33
+ export declare const DEP_EXPORT_ERROR_CODES: readonly ["validation", "invalid_period", "idempotency_conflict", "export_running", "too_many_exports", "export_not_found", "export_not_ready", "export_failed", "invalid_file", "file_not_available", "too_many_links", "link_not_found", "manager_only", "server_error"];
34
34
  /**
35
35
  * Warum ein Export fehlgeschlagen ist (`DepExport.error`): die Werte des
36
36
  * Katalogs `DEP_EXPORT_FEHLER` im Vertrag. `export_stalled` = nach 35 Minuten
@@ -48,6 +48,7 @@ exports.DEP_EXPORT_ERROR_CODES = Object.freeze([
48
48
  'file_not_available', // diese Datei gibt es zu diesem Export nicht (etwa Positionen bei einem alten Export)
49
49
  'too_many_links', // Grenze der aktiven Links je Export oder der neuen Links je Tag erreicht
50
50
  'link_not_found', // unbekannt oder einer anderen Kasse (ein schon widerrufener Link ist kein Fehler: der Widerruf ist wiederholbar)
51
+ 'manager_only', // Kassenweg: nur der Chef (Inhaber oder Recht layout) exportiert; ein Kassier sieht den Hinweis
51
52
  'server_error',
52
53
  ]);
53
54
  /**
@@ -91,16 +91,16 @@ export interface TransportOptions {
91
91
  auth: KasseneckAuth;
92
92
  /**
93
93
  * Abweichende Basis der **oeffentlichen** Aufrufe (Vorgabe
94
- * [DEFAULT_BASE_URL]): alles ausser den 33 Aufrufen des Kassenwegs, und die
95
- * sechs oeffentlichen davon nur, wenn nicht mit `registerUserAuth`
94
+ * [DEFAULT_BASE_URL]): alles ausser den 47 Aufrufen des Kassenwegs, und die
95
+ * elf oeffentlichen davon nur, wenn nicht mit `registerUserAuth`
96
96
  * angemeldet. Muss auf `/v3` enden (eigene Proxys erlaubt), sonst wirft das
97
97
  * Anlegen; `/v1` oder `/api` gibt es in der 1.x-Linie nicht.
98
98
  */
99
99
  baseUrl?: string;
100
100
  /**
101
- * Abweichende Basis des **Kassenwegs** (Vorgabe [POS_BASE_URL]): die 27
101
+ * Abweichende Basis des **Kassenwegs** (Vorgabe [POS_BASE_URL]): die 36
102
102
  * reinen Kassenaufrufe (Kopplung, Anmeldung, Einstellungen, Artikel,
103
- * Drucker, ...) und mit `registerUserAuth` alle 33 Aufrufe des Kassenwegs.
103
+ * Drucker, ...) und mit `registerUserAuth` alle 47 Aufrufe des Kassenwegs.
104
104
  * Die Web-Kasse gibt `'/api/v3'` (gleicher Ursprung). Muss auf `/v3` enden
105
105
  * (in der Regel `/api/v3`), sonst wirft das Anlegen.
106
106
  */
@@ -157,10 +157,10 @@ function createCore(options) {
157
157
  pruefeKennung(kennung);
158
158
  const kopfzeilenSenden = options.omitKasseneckHeaders !== true;
159
159
  /**
160
- * Basis je Aufruf. Die 27 reinen Kassenaufrufe gehen immer an den
160
+ * Basis je Aufruf. Die 36 reinen Kassenaufrufe gehen immer an den
161
161
  * Kassenweg (unter der oeffentlichen Basis gibt es sie nicht), und die
162
- * Kassen-Anmeldung ruft alle 33 Aufrufe des Kassenwegs dort, auch die sechs
163
- * oeffentlichen (Kanal `app`). Was der Kassenweg gar nicht fuehrt
162
+ * Kassen-Anmeldung ruft alle 47 Aufrufe des Kassenwegs dort, auch die elf
163
+ * oeffentlichen (Kanal `app`, darunter die DEP-Aufrufe). Was der Kassenweg gar nicht fuehrt
164
164
  * (Berichte, Zahlungen, FinanzOnline), geht an die oeffentliche Basis.
165
165
  */
166
166
  const basisFuer = (functionName) => (0, aufrufe_js_1.isPosOnlyCall)(functionName) || (kassenweg && (0, aufrufe_js_1.isPosCall)(functionName)) ? kassenBasis : oeffentlicheBasis;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Prüfung (DEP) bei der Kassennachschau an der Kasse (Spec dep-nachschau, Stufe 2): der Ordner, in den Web-Kasse
3
+ * und Kassen-App DEP, Übergabeprotokoll und Positionen auf den USB-Stick legen. Beide Kassen benennen ihn gleich;
4
+ * die Prüffälle stehen in `fixtures/dep-folder-cases.json` (auch im Dart-Zwilling).
5
+ */
6
+ /**
7
+ * `DEP_<Kassen-ID>_<von>_<bis>` (Tage JJJJ-MM-TT, wie der Export sie nennt). Ohne Anfang `DEP_<id>_bis_<bis>`, ohne
8
+ * Ende `DEP_<id>_ab_<von>`, ohne beides `DEP_<id>_alles`. Was ein Stick nicht als Namen nimmt, wird zu `_`.
9
+ */
10
+ export declare function depFolderName(cashregisterId: string, from?: string | null, to?: string | null): string;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * Prüfung (DEP) bei der Kassennachschau an der Kasse (Spec dep-nachschau, Stufe 2): der Ordner, in den Web-Kasse
4
+ * und Kassen-App DEP, Übergabeprotokoll und Positionen auf den USB-Stick legen. Beide Kassen benennen ihn gleich;
5
+ * die Prüffälle stehen in `fixtures/dep-folder-cases.json` (auch im Dart-Zwilling).
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.depFolderName = depFolderName;
9
+ /** Zeichen, die FAT32 und exFAT in Namen nicht erlauben, Steuerzeichen und Leerraum. */
10
+ const UNERLAUBT = /[\\/:*?"<>|\u0000-\u001f\u007f\s]/g;
11
+ const teil = (s) => s.trim().replace(UNERLAUBT, '_');
12
+ /**
13
+ * `DEP_<Kassen-ID>_<von>_<bis>` (Tage JJJJ-MM-TT, wie der Export sie nennt). Ohne Anfang `DEP_<id>_bis_<bis>`, ohne
14
+ * Ende `DEP_<id>_ab_<von>`, ohne beides `DEP_<id>_alles`. Was ein Stick nicht als Namen nimmt, wird zu `_`.
15
+ */
16
+ function depFolderName(cashregisterId, from, to) {
17
+ const id = teil(String(cashregisterId ?? '')) || 'Kasse';
18
+ const von = typeof from === 'string' && from.trim() ? teil(from) : null;
19
+ const bis = typeof to === 'string' && to.trim() ? teil(to) : null;
20
+ if (von && bis)
21
+ return `DEP_${id}_${von}_${bis}`;
22
+ if (bis)
23
+ return `DEP_${id}_bis_${bis}`;
24
+ if (von)
25
+ return `DEP_${id}_ab_${von}`;
26
+ return `DEP_${id}_alles`;
27
+ }
@@ -14,6 +14,7 @@ export { distributeDiscount } from '../receipt/discount.js';
14
14
  export { cancelScopeOf, receiptsScopeOf, stockViewOf, voucherPermsOf, type VoucherPerms, type RegisterScope, type RegisterUserPerms } from '../register/pairing.js';
15
15
  export { type NetworkPrinter, type PrintJob, type PrintJobStatus, PRINT_JOB_STATUSES, type PrintJobSource, PRINT_JOB_SOURCES, isPrintJobFinished, type CreatePrintJobOptions, listMyPrinters, createPrintJob, getPrintJob, } from './drucker.js';
16
16
  export { listMyTipRecipients } from './trinkgeld.js';
17
+ export { depFolderName } from './dep.js';
17
18
  export { STOCK_LOCATION_TYPES, type StockLocationType, type StockLocation, type StockLocationAddress, type StockLevel, type StockValue, type StockList, type ListMyStockOptions, type SetMyCashregisterStockLocationOptions, type CashregisterStockLocation, listMyStockLocations, listMyStock, setMyCashregisterStockLocation, } from './lager.js';
18
19
  export { type ListMyStocktakesOptions, type ListMyStocktakeItemsOptions, type ListMyStocktakeCountsOptions, type RecordMyStocktakeCountOptions, type VoidMyStocktakeCountOptions, listMyStocktakes, listMyStocktakeItems, listMyStocktakeCounts, recordMyStocktakeCount, voidMyStocktakeCount, parseQuantityMilli, } from './inventur.js';
19
20
  export type { Stocktake, StocktakeItem, StocktakeCount, StocktakeCountResult, StocktakeItemPage, StocktakeCountPage, StocktakeActor, StocktakeProgress, StocktakeReview, StocktakeRecount, StocktakeScope, } from '../inventory/typen.js';
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.quantityRuleForUnit = exports.QUANTITY_RULES = exports.listMyArticles = exports.listMyArticleGroups = exports.fromPosArticlePayload = exports.fromArticleGroupPayload = exports.DONE_SCREEN_SECONDS = exports.WATERMARK_SCALE = exports.LOGO_SCALE = exports.WATERMARK_STRENGTH = exports.WATERMARK_SIDE = exports.DISCOUNT = exports.AUTO_LOGOUT_MINUTES = exports.TILE_STYLE = exports.SETTINGS_FONT_SIZE = exports.LOGO_SIZE = exports.QR_MODE = exports.DRAWER_AUTO_OPEN = exports.CUT = exports.CODE_PAGE = exports.PAPER_SIZE = exports.TERMINAL_TYPE = exports.TERMINAL_VIA = exports.PRINTER_TYPE = exports.TILE_HEIGHT = exports.CATEGORY_POSITION = exports.LAYOUT = exports.RECEIPT_OUTPUT = exports.CARD_PROVIDER = exports.CHECKOUT_MODE = exports.TIP_MODE = exports.QUANTITY = exports.WATERMARK = exports.FONT_SIZE = exports.THEME = exports.posShortcutConflict = exports.POS_SHORTCUT_SHARED_PAIRS = exports.posSettingsChanges = exports.unknownPosSettingValues = exports.sanitizePosSettings = exports.mergePosSettings = exports.POS_DEVICE_VALUES = exports.POS_BUSINESS_VALUES = exports.posTipKeptByDefault = exports.POS_BUSINESS_OPTIONAL_FIELDS = exports.POS_DEVICE_OPTIONAL_FIELDS = exports.POS_DEVICE_DEFAULTS = exports.POS_BUSINESS_DEFAULTS = exports.POS_SHORTCUT_DEFAULTS = exports.POS_SHORTCUT_ACTIONS = void 0;
4
- exports.closeMyShift = exports.getMyShiftReport = exports.logMyDrawerOpenings = exports.recordMyCashMovement = exports.openMyShift = exports.getMyDrawerState = exports.VOUCHER_TYPE_VALIDITY_PATTERNS = exports.VOUCHER_AMOUNT_MODES = exports.VOUCHER_TYPE_KINDS = exports.VOUCHER_PAYOUTS = exports.posVoucherSettingsFromWire = exports.VOUCHER_SETTINGS_DEFAULTS = exports.reprintVoucherLabel = exports.checkVoucher = exports.VOUCHER_STATUSES = exports.VOUCHER_KINDS = exports.parseQuantityMilli = exports.voidMyStocktakeCount = exports.recordMyStocktakeCount = exports.listMyStocktakeCounts = exports.listMyStocktakeItems = exports.listMyStocktakes = exports.setMyCashregisterStockLocation = exports.listMyStock = exports.listMyStockLocations = exports.STOCK_LOCATION_TYPES = exports.listMyTipRecipients = exports.getPrintJob = exports.createPrintJob = exports.listMyPrinters = exports.isPrintJobFinished = exports.PRINT_JOB_SOURCES = exports.PRINT_JOB_STATUSES = exports.voucherPermsOf = exports.stockViewOf = exports.receiptsScopeOf = exports.cancelScopeOf = exports.distributeDiscount = exports.posFieldErrors = exports.isPosError = exports.posErrorCode = exports.isPosErrorCode = exports.POS_ERROR_CODES = exports.posSettingsFromWire = exports.setMyPosLogo = exports.setMyRegisterDeviceSettings = exports.setMyPosSettings = exports.getPosSettings = exports.allowedQuantity = exports.quantityDefaults = void 0;
5
- exports.receiptOutputLabel = exports.RETURN_DISPOSITION_LABELS = exports.labelText = exports.LABELS = exports.voucherErrorMessage = exports.VOUCHER_ERROR_MESSAGES = exports.cancellationPaymentErrorMessage = exports.CANCELLATION_PAYMENT_ERROR_MESSAGES = exports.receiptEmailErrorMessage = exports.RECEIPT_EMAIL_ERROR_MESSAGES = exports.messageAppliesTo = exports.messageText = exports.messageOutcome = exports.findErrorRule = exports.CALLS_WITH_EFFECT = exports.ERROR_OUTCOME_RULES = exports.ERROR_CODE_RULES = exports.ERROR_RULES = exports.MESSAGES = exports.isReturnDisposition = exports.RETURN_DISPOSITIONS = exports.RECEIPT_OUTPUT_RESULTS = exports.RECEIPT_OUTPUT_KINDS = exports.cashMovementLayout = exports.shiftReceiptLayout = exports.AFTER_COUNT_TYPES = exports.SHIFT_RECEIPT_KINDS = exports.MANUAL_OPENING_REASONS = exports.OPENING_REASONS = exports.CASH_LOCATIONS = exports.MANUAL_MOVEMENT_TYPES = exports.MOVEMENT_TYPES = exports.EUR_DENOMINATIONS = exports.durationText = exports.shiftTipLines = exports.newIdempotencyKey = exports.parseCentsAllowZero = exports.sumDenominations = void 0;
4
+ exports.getMyShiftReport = exports.logMyDrawerOpenings = exports.recordMyCashMovement = exports.openMyShift = exports.getMyDrawerState = exports.VOUCHER_TYPE_VALIDITY_PATTERNS = exports.VOUCHER_AMOUNT_MODES = exports.VOUCHER_TYPE_KINDS = exports.VOUCHER_PAYOUTS = exports.posVoucherSettingsFromWire = exports.VOUCHER_SETTINGS_DEFAULTS = exports.reprintVoucherLabel = exports.checkVoucher = exports.VOUCHER_STATUSES = exports.VOUCHER_KINDS = exports.parseQuantityMilli = exports.voidMyStocktakeCount = exports.recordMyStocktakeCount = exports.listMyStocktakeCounts = exports.listMyStocktakeItems = exports.listMyStocktakes = exports.setMyCashregisterStockLocation = exports.listMyStock = exports.listMyStockLocations = exports.STOCK_LOCATION_TYPES = exports.depFolderName = exports.listMyTipRecipients = exports.getPrintJob = exports.createPrintJob = exports.listMyPrinters = exports.isPrintJobFinished = exports.PRINT_JOB_SOURCES = exports.PRINT_JOB_STATUSES = exports.voucherPermsOf = exports.stockViewOf = exports.receiptsScopeOf = exports.cancelScopeOf = exports.distributeDiscount = exports.posFieldErrors = exports.isPosError = exports.posErrorCode = exports.isPosErrorCode = exports.POS_ERROR_CODES = exports.posSettingsFromWire = exports.setMyPosLogo = exports.setMyRegisterDeviceSettings = exports.setMyPosSettings = exports.getPosSettings = exports.allowedQuantity = exports.quantityDefaults = void 0;
5
+ exports.receiptOutputLabel = exports.RETURN_DISPOSITION_LABELS = exports.labelText = exports.LABELS = exports.voucherErrorMessage = exports.VOUCHER_ERROR_MESSAGES = exports.cancellationPaymentErrorMessage = exports.CANCELLATION_PAYMENT_ERROR_MESSAGES = exports.receiptEmailErrorMessage = exports.RECEIPT_EMAIL_ERROR_MESSAGES = exports.messageAppliesTo = exports.messageText = exports.messageOutcome = exports.findErrorRule = exports.CALLS_WITH_EFFECT = exports.ERROR_OUTCOME_RULES = exports.ERROR_CODE_RULES = exports.ERROR_RULES = exports.MESSAGES = exports.isReturnDisposition = exports.RETURN_DISPOSITIONS = exports.RECEIPT_OUTPUT_RESULTS = exports.RECEIPT_OUTPUT_KINDS = exports.cashMovementLayout = exports.shiftReceiptLayout = exports.AFTER_COUNT_TYPES = exports.SHIFT_RECEIPT_KINDS = exports.MANUAL_OPENING_REASONS = exports.OPENING_REASONS = exports.CASH_LOCATIONS = exports.MANUAL_MOVEMENT_TYPES = exports.MOVEMENT_TYPES = exports.EUR_DENOMINATIONS = exports.durationText = exports.shiftTipLines = exports.newIdempotencyKey = exports.parseCentsAllowZero = exports.sumDenominations = exports.closeMyShift = void 0;
6
6
  /**
7
7
  * Kachel-Kasse: Einstellungen, Artikelgruppen/Artikel fuer Kacheln,
8
8
  * Rabattverteilung, Drucker, Trinkgeld-Empfaenger, Lager (Standorte, Bestand,
@@ -96,6 +96,9 @@ Object.defineProperty(exports, "createPrintJob", { enumerable: true, get: functi
96
96
  Object.defineProperty(exports, "getPrintJob", { enumerable: true, get: function () { return drucker_js_1.getPrintJob; } });
97
97
  var trinkgeld_js_1 = require("./trinkgeld.js");
98
98
  Object.defineProperty(exports, "listMyTipRecipients", { enumerable: true, get: function () { return trinkgeld_js_1.listMyTipRecipients; } });
99
+ // Prüfung (DEP) an der Kasse: Ordner auf dem USB-Stick (gleich in Web-Kasse und Kassen-App).
100
+ var dep_js_1 = require("./dep.js");
101
+ Object.defineProperty(exports, "depFolderName", { enumerable: true, get: function () { return dep_js_1.depFolderName; } });
99
102
  var lager_js_1 = require("./lager.js");
100
103
  Object.defineProperty(exports, "STOCK_LOCATION_TYPES", { enumerable: true, get: function () { return lager_js_1.STOCK_LOCATION_TYPES; } });
101
104
  Object.defineProperty(exports, "listMyStockLocations", { enumerable: true, get: function () { return lager_js_1.listMyStockLocations; } });
@@ -802,6 +802,47 @@ declare const MELDUNGEN_ROH: {
802
802
  readonly text: "Es fehlen {amount} bis zum Wechselgeld von {total}.";
803
803
  readonly placeholders: readonly ["amount", "total"];
804
804
  };
805
+ readonly 'dep.manager_only': {
806
+ readonly text: "Den Export für die Prüfung macht der Chef. Ist er nicht da, darf die Behörde bis zu zwei Werktage warten.";
807
+ };
808
+ readonly 'dep.offline': {
809
+ readonly text: "Ohne Internet ist kein Export möglich. Die Behörde muss dann bis zu zwei Werktage warten; der Export geht später hier oder unter mein.kasseneck.at.";
810
+ };
811
+ readonly 'dep.creating': {
812
+ readonly text: "Wird erstellt …";
813
+ };
814
+ readonly 'dep.running': {
815
+ readonly text: "Für diese Kasse läuft schon ein Export. Bitte kurz warten, er wird gleich fertig.";
816
+ };
817
+ readonly 'dep.failed': {
818
+ readonly text: "Der Export ist fehlgeschlagen. Bitte erneut erstellen.";
819
+ };
820
+ readonly 'dep.too_many_exports': {
821
+ readonly text: "Heute sind an diesem Konto keine weiteren Exporte möglich – morgen geht es wieder. Ein schon erstellter Export bleibt nutzbar.";
822
+ };
823
+ readonly 'dep.period_invalid': {
824
+ readonly text: "Bitte einen gültigen Zeitraum wählen: „Von“ nicht in der Zukunft, „Bis“ nicht vor „Von“.";
825
+ };
826
+ readonly 'dep.usb_hint': {
827
+ readonly text: "USB-Stick anstecken (FAT32 oder exFAT). Der Prüfer behält den Stick.";
828
+ };
829
+ readonly 'dep.saved': {
830
+ readonly text: "Gespeichert im Ordner {folder}.";
831
+ readonly placeholders: readonly ["folder"];
832
+ };
833
+ readonly 'dep.save_failed': {
834
+ readonly text: "Speichern hat nicht geklappt. Bitte den Stick prüfen und erneut speichern.";
835
+ };
836
+ readonly 'dep.zip_fallback': {
837
+ readonly text: "Dieser Browser kann keinen Ordner wählen – der Export kommt als ZIP-Datei in den Download-Ordner.";
838
+ readonly only: readonly ["web"];
839
+ };
840
+ readonly 'dep.code_once': {
841
+ readonly text: "Code und QR-Code gibt es nur auf diesem Bildschirm. Wer zurückgeht, erstellt beim nächsten Mal einen neuen Link.";
842
+ };
843
+ readonly 'dep.revoked': {
844
+ readonly text: "Der Link ist widerrufen.";
845
+ };
805
846
  readonly 'app.not_in_browser': {
806
847
  readonly text: "Die Kassen-App läuft nicht im Browser – dafür gibt es kasse.kasseneck.at.";
807
848
  readonly only: readonly ["app"];
@@ -935,6 +976,18 @@ export declare const ERROR_CODE_RULES: readonly [{
935
976
  readonly kind: "api";
936
977
  readonly codes: readonly ["drawer_inactive"];
937
978
  readonly key: "drawer.inactive";
979
+ }, {
980
+ readonly kind: "api";
981
+ readonly codes: readonly ["manager_only"];
982
+ readonly key: "dep.manager_only";
983
+ }, {
984
+ readonly kind: "api";
985
+ readonly codes: readonly ["export_running"];
986
+ readonly key: "dep.running";
987
+ }, {
988
+ readonly kind: "api";
989
+ readonly codes: readonly ["too_many_exports"];
990
+ readonly key: "dep.too_many_exports";
938
991
  }];
939
992
  /**
940
993
  * Regeln je Ausgang, nach den Code-Regeln und vor der Regel der Art: eine
@@ -1848,6 +1901,9 @@ declare const BESCHRIFTUNGEN_ROH: {
1848
1901
  readonly 'nav.stocktake': {
1849
1902
  readonly text: "Inventur";
1850
1903
  };
1904
+ readonly 'nav.dep': {
1905
+ readonly text: "Prüfung (DEP)";
1906
+ };
1851
1907
  readonly 'nav.settings': {
1852
1908
  readonly text: "Einstellungen";
1853
1909
  };
@@ -2133,6 +2189,59 @@ declare const BESCHRIFTUNGEN_ROH: {
2133
2189
  readonly 'receipt.output_failed': {
2134
2190
  readonly text: "fehlgeschlagen";
2135
2191
  };
2192
+ readonly 'dep.title': {
2193
+ readonly text: "Prüfung (DEP)";
2194
+ };
2195
+ readonly 'dep.period': {
2196
+ readonly text: "Zeitraum";
2197
+ };
2198
+ readonly 'dep.period_all': {
2199
+ readonly text: "Alles seit Inbetriebnahme";
2200
+ };
2201
+ readonly 'dep.period_year': {
2202
+ readonly text: "Ein Jahr";
2203
+ };
2204
+ readonly 'dep.period_quarter': {
2205
+ readonly text: "Ein Quartal";
2206
+ };
2207
+ readonly 'dep.period_custom': {
2208
+ readonly text: "Eigener Zeitraum";
2209
+ };
2210
+ readonly 'dep.from': {
2211
+ readonly text: "Von";
2212
+ };
2213
+ readonly 'dep.to': {
2214
+ readonly text: "Bis";
2215
+ };
2216
+ readonly 'dep.create': {
2217
+ readonly text: "Export erstellen";
2218
+ };
2219
+ readonly 'dep.receipts': {
2220
+ readonly text: "{count} Belege";
2221
+ readonly placeholders: readonly ["count"];
2222
+ };
2223
+ readonly 'dep.save_usb': {
2224
+ readonly text: "Auf USB-Stick speichern";
2225
+ };
2226
+ readonly 'dep.handover_link': {
2227
+ readonly text: "Link für den Prüfer";
2228
+ };
2229
+ readonly 'dep.code': {
2230
+ readonly text: "Code";
2231
+ };
2232
+ readonly 'dep.valid_until': {
2233
+ readonly text: "gültig bis {date}";
2234
+ readonly placeholders: readonly ["date"];
2235
+ };
2236
+ readonly 'dep.revoke': {
2237
+ readonly text: "Widerrufen";
2238
+ };
2239
+ readonly 'dep.checksum': {
2240
+ readonly text: "Prüfsumme (SHA-256)";
2241
+ };
2242
+ readonly 'dep.new_export': {
2243
+ readonly text: "Neuer Export";
2244
+ };
2136
2245
  };
2137
2246
  export type LabelKey = keyof typeof BESCHRIFTUNGEN_ROH;
2138
2247
  export declare const LABELS: Record<LabelKey, TextEntry>;
@@ -397,6 +397,22 @@ const MELDUNGEN_ROH = {
397
397
  // Wechselgeld der Lade (1.11.0): beim Öffnen der Schicht liegt weniger in der Lade als eingestellt.
398
398
  // `{amount}` was fehlt, `{total}` das eingestellte Wechselgeld, beide samt Euro-Zeichen.
399
399
  'shift.change_float_missing': { text: 'Es fehlen {amount} bis zum Wechselgeld von {total}.', placeholders: ['amount', 'total'] },
400
+ // --- Prüfung (DEP) bei der Kassennachschau ---------------------------------
401
+ // Nur der Chef exportiert (Inhaber oder Recht „Einstellungen“); ein Kassier
402
+ // sieht nur den Hinweis. Ohne Internet gilt die Frist von zwei Werktagen.
403
+ 'dep.manager_only': { text: 'Den Export für die Prüfung macht der Chef. Ist er nicht da, darf die Behörde bis zu zwei Werktage warten.' },
404
+ 'dep.offline': { text: 'Ohne Internet ist kein Export möglich. Die Behörde muss dann bis zu zwei Werktage warten; der Export geht später hier oder unter mein.kasseneck.at.' },
405
+ 'dep.creating': { text: 'Wird erstellt …' },
406
+ 'dep.running': { text: 'Für diese Kasse läuft schon ein Export. Bitte kurz warten, er wird gleich fertig.' },
407
+ 'dep.failed': { text: 'Der Export ist fehlgeschlagen. Bitte erneut erstellen.' },
408
+ 'dep.too_many_exports': { text: 'Heute sind an diesem Konto keine weiteren Exporte möglich – morgen geht es wieder. Ein schon erstellter Export bleibt nutzbar.' },
409
+ 'dep.period_invalid': { text: 'Bitte einen gültigen Zeitraum wählen: „Von“ nicht in der Zukunft, „Bis“ nicht vor „Von“.' },
410
+ 'dep.usb_hint': { text: 'USB-Stick anstecken (FAT32 oder exFAT). Der Prüfer behält den Stick.' },
411
+ 'dep.saved': { text: 'Gespeichert im Ordner {folder}.', placeholders: ['folder'] },
412
+ 'dep.save_failed': { text: 'Speichern hat nicht geklappt. Bitte den Stick prüfen und erneut speichern.' },
413
+ 'dep.zip_fallback': { text: 'Dieser Browser kann keinen Ordner wählen – der Export kommt als ZIP-Datei in den Download-Ordner.', only: ['web'] },
414
+ 'dep.code_once': { text: 'Code und QR-Code gibt es nur auf diesem Bildschirm. Wer zurückgeht, erstellt beim nächsten Mal einen neuen Link.' },
415
+ 'dep.revoked': { text: 'Der Link ist widerrufen.' },
400
416
  // --- Nur App -------------------------------------------------------------
401
417
  'app.not_in_browser': { text: 'Die Kassen-App läuft nicht im Browser – dafür gibt es kasse.kasseneck.at.', only: ['app'] },
402
418
  'app.open_in_browser': { text: 'Bitte im Browser öffnen: {target}', placeholders: ['target'], only: ['app'] },
@@ -467,6 +483,13 @@ exports.ERROR_CODE_RULES = [
467
483
  { kind: 'api', codes: ['invalid_amount'], key: 'amount.invalid' },
468
484
  { kind: 'api', codes: ['drawer_not_found'], key: 'drawer.not_found' },
469
485
  { kind: 'api', codes: ['drawer_inactive'], key: 'drawer.inactive' },
486
+ // Prüfung (DEP, 1.21.0): nur der Chef; die Tagesgrenze und ein laufender
487
+ // Export sagen, was zu tun ist. Der Server hat nichts angelegt. Bewusst
488
+ // ohne export_failed (kommt auch von Zahlungswegen mit unklarem Ausgang)
489
+ // und ohne too_many_links (der Satz des Backends nennt die Grenze).
490
+ { kind: 'api', codes: ['manager_only'], key: 'dep.manager_only' },
491
+ { kind: 'api', codes: ['export_running'], key: 'dep.running' },
492
+ { kind: 'api', codes: ['too_many_exports'], key: 'dep.too_many_exports' },
470
493
  ];
471
494
  /**
472
495
  * Regeln je Ausgang, nach den Code-Regeln und vor der Regel der Art: eine
@@ -945,6 +968,7 @@ const BESCHRIFTUNGEN_ROH = {
945
968
  'nav.vouchers': { text: 'Gutscheine' },
946
969
  'nav.open_drawer': { text: 'Kassenlade öffnen' },
947
970
  'nav.stocktake': { text: 'Inventur' },
971
+ 'nav.dep': { text: 'Prüfung (DEP)' },
948
972
  'nav.settings': { text: 'Einstellungen' },
949
973
  'nav.settings_locked': { text: 'nur mit Chef-Anmeldung' },
950
974
  'nav.logout': { text: 'Abmelden' },
@@ -1046,6 +1070,24 @@ const BESCHRIFTUNGEN_ROH = {
1046
1070
  'receipt.output_pdf_shared': { text: 'PDF geteilt' },
1047
1071
  'receipt.output_opened': { text: 'Link geöffnet ({count}×)', placeholders: ['count'] },
1048
1072
  'receipt.output_failed': { text: 'fehlgeschlagen' },
1073
+ // --- Prüfung (DEP) bei der Kassennachschau -----------------------------------
1074
+ 'dep.title': { text: 'Prüfung (DEP)' },
1075
+ 'dep.period': { text: 'Zeitraum' },
1076
+ 'dep.period_all': { text: 'Alles seit Inbetriebnahme' },
1077
+ 'dep.period_year': { text: 'Ein Jahr' },
1078
+ 'dep.period_quarter': { text: 'Ein Quartal' },
1079
+ 'dep.period_custom': { text: 'Eigener Zeitraum' },
1080
+ 'dep.from': { text: 'Von' },
1081
+ 'dep.to': { text: 'Bis' },
1082
+ 'dep.create': { text: 'Export erstellen' },
1083
+ 'dep.receipts': { text: '{count} Belege', placeholders: ['count'] },
1084
+ 'dep.save_usb': { text: 'Auf USB-Stick speichern' },
1085
+ 'dep.handover_link': { text: 'Link für den Prüfer' },
1086
+ 'dep.code': { text: 'Code' },
1087
+ 'dep.valid_until': { text: 'gültig bis {date}', placeholders: ['date'] },
1088
+ 'dep.revoke': { text: 'Widerrufen' },
1089
+ 'dep.checksum': { text: 'Prüfsumme (SHA-256)' },
1090
+ 'dep.new_export': { text: 'Neuer Export' },
1049
1091
  };
1050
1092
  exports.LABELS = BESCHRIFTUNGEN_ROH;
1051
1093
  /**
@@ -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))
@@ -1,5 +1,5 @@
1
1
  /** Fingerabdruck des Vertrags-Exports, aus dem diese Datei stammt (`_quelle.sha256`). */
2
- export declare const VOKABULAR_QUELLE = "b06a8be2fe8c96e7e266a4e237c77588e9bef4e3272a9343ed2969ba722a87f4";
2
+ export declare const VOKABULAR_QUELLE = "ff400b73f31d963cb2051ca8b7a06cef0bf126483b528320e2a503a6035a7c59";
3
3
  /** Schema-Notation des Vertrags: Blatt 'aussen': 'innen', Objekt { __: 'innen', ... }, Liste [ { __: 'innen', ... } ]. */
4
4
  export type SchemaEintrag = string | SchemaObjekt | readonly [SchemaObjekt];
5
5
  export interface SchemaObjekt {
@@ -4,7 +4,7 @@
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.KATALOGE = exports.ARTIKEL_FELDER = exports.SCHEMAS = exports.VOKABULAR_QUELLE = void 0;
6
6
  /** Fingerabdruck des Vertrags-Exports, aus dem diese Datei stammt (`_quelle.sha256`). */
7
- exports.VOKABULAR_QUELLE = "b06a8be2fe8c96e7e266a4e237c77588e9bef4e3272a9343ed2969ba722a87f4";
7
+ exports.VOKABULAR_QUELLE = "ff400b73f31d963cb2051ca8b7a06cef0bf126483b528320e2a503a6035a7c59";
8
8
  /** Schema je Endpunkt (aussen -> innen) und Wertverweise auf die Kataloge. */
9
9
  exports.SCHEMAS = {
10
10
  "getReceipt": {
@@ -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.20.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.20.0';
10
+ exports.PACKAGE_VERSION = '1.21.1';
@@ -25,10 +25,11 @@ export declare const PUBLIC_CALLS: readonly ["createReceipt", "getReceipt", "can
25
25
  /**
26
26
  * Die Endpunkte des Kassenwegs (`https://kasse.kasseneck.at/api/v3/<name>`,
27
27
  * Web-Kasse: gleicher Ursprung `/api/v3`), in der Reihenfolge von
28
- * `endpoints.register`. Sechs davon sind zugleich oeffentlich; die Kasse ruft
29
- * sie trotzdem ueber diesen Weg (ein Dialekt je Client, Nachtrag §5.2).
28
+ * `endpoints.register`. Elf davon sind zugleich oeffentlich (sechs Beleg-Aufrufe und
29
+ * die fuenf DEP-Aufrufe); die Kasse ruft sie trotzdem ueber diesen Weg (ein Dialekt
30
+ * je Client, Nachtrag §5.2).
30
31
  */
31
- export declare const POS_CALLS: readonly ["pairRegisterDevice", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "registerUserLogin", "registerPinLogin", "renewRegisterSession", "endRegisterSession", "unpairRegisterDevice", "listMyCashregisters", "listMyReceipts", "getReceipt", "createReceipt", "generateFullReceiptId", "cancelReceipt", "sendReceiptEmail", "listMyArticleGroups", "listMyArticles", "getKasseSettings", "setMyKasseSettings", "setMyKasseLogo", "setMyRegisterDeviceSettings", "listMyPrinters", "createPrintJob", "getPrintJob", "listMyTipRecipients", "listMyStockLocations", "listMyStock", "setMyCashregisterStockLocation", "listMyStocktakes", "listMyStocktakeItems", "listMyStocktakeCounts", "recordMyStocktakeCount", "voidMyStocktakeCount", "checkVoucher", "reprintVoucherLabel", "getMyDrawerState", "openMyShift", "recordMyCashMovement", "logMyDrawerOpenings", "getMyShiftReport", "closeMyShift", "logReceiptOutputs"];
32
+ export declare const POS_CALLS: readonly ["pairRegisterDevice", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "registerUserLogin", "registerPinLogin", "renewRegisterSession", "endRegisterSession", "unpairRegisterDevice", "listMyCashregisters", "listMyReceipts", "getReceipt", "createReceipt", "generateFullReceiptId", "cancelReceipt", "sendReceiptEmail", "listMyArticleGroups", "listMyArticles", "getKasseSettings", "setMyKasseSettings", "setMyKasseLogo", "setMyRegisterDeviceSettings", "listMyPrinters", "createPrintJob", "getPrintJob", "listMyTipRecipients", "listMyStockLocations", "listMyStock", "setMyCashregisterStockLocation", "listMyStocktakes", "listMyStocktakeItems", "listMyStocktakeCounts", "recordMyStocktakeCount", "voidMyStocktakeCount", "checkVoucher", "reprintVoucherLabel", "getMyDrawerState", "openMyShift", "recordMyCashMovement", "logMyDrawerOpenings", "getMyShiftReport", "closeMyShift", "logReceiptOutputs", "createDepExport", "getDepExport", "getDepExportFile", "createDepHandoverLink", "revokeDepHandoverLink"];
32
33
  export type PublicCall = typeof PUBLIC_CALLS[number];
33
34
  export type PosCall = typeof POS_CALLS[number];
34
35
  /**
@@ -280,8 +280,9 @@ export const PUBLIC_CALLS = [
280
280
  /**
281
281
  * Die Endpunkte des Kassenwegs (`https://kasse.kasseneck.at/api/v3/<name>`,
282
282
  * Web-Kasse: gleicher Ursprung `/api/v3`), in der Reihenfolge von
283
- * `endpoints.register`. Sechs davon sind zugleich oeffentlich; die Kasse ruft
284
- * sie trotzdem ueber diesen Weg (ein Dialekt je Client, Nachtrag §5.2).
283
+ * `endpoints.register`. Elf davon sind zugleich oeffentlich (sechs Beleg-Aufrufe und
284
+ * die fuenf DEP-Aufrufe); die Kasse ruft sie trotzdem ueber diesen Weg (ein Dialekt
285
+ * je Client, Nachtrag §5.2).
285
286
  */
286
287
  export const POS_CALLS = [
287
288
  'pairRegisterDevice',
@@ -331,6 +332,12 @@ export const POS_CALLS = [
331
332
  'closeMyShift',
332
333
  // Ausgaben eines Belegs melden: nur ueber den Kassenweg.
333
334
  'logReceiptOutputs',
335
+ // DEP fuer die Kassennachschau (Stufe 2): zugleich oeffentlich; an der Kasse nur fuer den Chef (manager_only).
336
+ 'createDepExport',
337
+ 'getDepExport',
338
+ 'getDepExportFile',
339
+ 'createDepHandoverLink',
340
+ 'revokeDepHandoverLink',
334
341
  ];
335
342
  /**
336
343
  * Die Aufrufe **mit Wirkung**, alphabetisch: sie legen etwas an, aendern oder
@@ -30,7 +30,7 @@ export type DepExportFileKind = (typeof DEP_EXPORT_FILES)[number];
30
30
  * Codes von Anmeldung und Rand. Ein Code ausserhalb bleibt ueber
31
31
  * `KasseneckApiError.code` lesbar.
32
32
  */
33
- export declare const DEP_EXPORT_ERROR_CODES: readonly ["validation", "invalid_period", "idempotency_conflict", "export_running", "too_many_exports", "export_not_found", "export_not_ready", "export_failed", "invalid_file", "file_not_available", "too_many_links", "link_not_found", "server_error"];
33
+ export declare const DEP_EXPORT_ERROR_CODES: readonly ["validation", "invalid_period", "idempotency_conflict", "export_running", "too_many_exports", "export_not_found", "export_not_ready", "export_failed", "invalid_file", "file_not_available", "too_many_links", "link_not_found", "manager_only", "server_error"];
34
34
  /**
35
35
  * Warum ein Export fehlgeschlagen ist (`DepExport.error`): die Werte des
36
36
  * Katalogs `DEP_EXPORT_FEHLER` im Vertrag. `export_stalled` = nach 35 Minuten
@@ -39,6 +39,7 @@ export const DEP_EXPORT_ERROR_CODES = Object.freeze([
39
39
  'file_not_available', // diese Datei gibt es zu diesem Export nicht (etwa Positionen bei einem alten Export)
40
40
  'too_many_links', // Grenze der aktiven Links je Export oder der neuen Links je Tag erreicht
41
41
  'link_not_found', // unbekannt oder einer anderen Kasse (ein schon widerrufener Link ist kein Fehler: der Widerruf ist wiederholbar)
42
+ 'manager_only', // Kassenweg: nur der Chef (Inhaber oder Recht layout) exportiert; ein Kassier sieht den Hinweis
42
43
  'server_error',
43
44
  ]);
44
45
  /**
@@ -91,16 +91,16 @@ export interface TransportOptions {
91
91
  auth: KasseneckAuth;
92
92
  /**
93
93
  * Abweichende Basis der **oeffentlichen** Aufrufe (Vorgabe
94
- * [DEFAULT_BASE_URL]): alles ausser den 33 Aufrufen des Kassenwegs, und die
95
- * sechs oeffentlichen davon nur, wenn nicht mit `registerUserAuth`
94
+ * [DEFAULT_BASE_URL]): alles ausser den 47 Aufrufen des Kassenwegs, und die
95
+ * elf oeffentlichen davon nur, wenn nicht mit `registerUserAuth`
96
96
  * angemeldet. Muss auf `/v3` enden (eigene Proxys erlaubt), sonst wirft das
97
97
  * Anlegen; `/v1` oder `/api` gibt es in der 1.x-Linie nicht.
98
98
  */
99
99
  baseUrl?: string;
100
100
  /**
101
- * Abweichende Basis des **Kassenwegs** (Vorgabe [POS_BASE_URL]): die 27
101
+ * Abweichende Basis des **Kassenwegs** (Vorgabe [POS_BASE_URL]): die 36
102
102
  * reinen Kassenaufrufe (Kopplung, Anmeldung, Einstellungen, Artikel,
103
- * Drucker, ...) und mit `registerUserAuth` alle 33 Aufrufe des Kassenwegs.
103
+ * Drucker, ...) und mit `registerUserAuth` alle 47 Aufrufe des Kassenwegs.
104
104
  * Die Web-Kasse gibt `'/api/v3'` (gleicher Ursprung). Muss auf `/v3` enden
105
105
  * (in der Regel `/api/v3`), sonst wirft das Anlegen.
106
106
  */
@@ -150,10 +150,10 @@ function createCore(options) {
150
150
  pruefeKennung(kennung);
151
151
  const kopfzeilenSenden = options.omitKasseneckHeaders !== true;
152
152
  /**
153
- * Basis je Aufruf. Die 27 reinen Kassenaufrufe gehen immer an den
153
+ * Basis je Aufruf. Die 36 reinen Kassenaufrufe gehen immer an den
154
154
  * Kassenweg (unter der oeffentlichen Basis gibt es sie nicht), und die
155
- * Kassen-Anmeldung ruft alle 33 Aufrufe des Kassenwegs dort, auch die sechs
156
- * oeffentlichen (Kanal `app`). Was der Kassenweg gar nicht fuehrt
155
+ * Kassen-Anmeldung ruft alle 47 Aufrufe des Kassenwegs dort, auch die elf
156
+ * oeffentlichen (Kanal `app`, darunter die DEP-Aufrufe). Was der Kassenweg gar nicht fuehrt
157
157
  * (Berichte, Zahlungen, FinanzOnline), geht an die oeffentliche Basis.
158
158
  */
159
159
  const basisFuer = (functionName) => isPosOnlyCall(functionName) || (kassenweg && isPosCall(functionName)) ? kassenBasis : oeffentlicheBasis;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Prüfung (DEP) bei der Kassennachschau an der Kasse (Spec dep-nachschau, Stufe 2): der Ordner, in den Web-Kasse
3
+ * und Kassen-App DEP, Übergabeprotokoll und Positionen auf den USB-Stick legen. Beide Kassen benennen ihn gleich;
4
+ * die Prüffälle stehen in `fixtures/dep-folder-cases.json` (auch im Dart-Zwilling).
5
+ */
6
+ /**
7
+ * `DEP_<Kassen-ID>_<von>_<bis>` (Tage JJJJ-MM-TT, wie der Export sie nennt). Ohne Anfang `DEP_<id>_bis_<bis>`, ohne
8
+ * Ende `DEP_<id>_ab_<von>`, ohne beides `DEP_<id>_alles`. Was ein Stick nicht als Namen nimmt, wird zu `_`.
9
+ */
10
+ export declare function depFolderName(cashregisterId: string, from?: string | null, to?: string | null): string;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Prüfung (DEP) bei der Kassennachschau an der Kasse (Spec dep-nachschau, Stufe 2): der Ordner, in den Web-Kasse
3
+ * und Kassen-App DEP, Übergabeprotokoll und Positionen auf den USB-Stick legen. Beide Kassen benennen ihn gleich;
4
+ * die Prüffälle stehen in `fixtures/dep-folder-cases.json` (auch im Dart-Zwilling).
5
+ */
6
+ /** Zeichen, die FAT32 und exFAT in Namen nicht erlauben, Steuerzeichen und Leerraum. */
7
+ const UNERLAUBT = /[\\/:*?"<>|\u0000-\u001f\u007f\s]/g;
8
+ const teil = (s) => s.trim().replace(UNERLAUBT, '_');
9
+ /**
10
+ * `DEP_<Kassen-ID>_<von>_<bis>` (Tage JJJJ-MM-TT, wie der Export sie nennt). Ohne Anfang `DEP_<id>_bis_<bis>`, ohne
11
+ * Ende `DEP_<id>_ab_<von>`, ohne beides `DEP_<id>_alles`. Was ein Stick nicht als Namen nimmt, wird zu `_`.
12
+ */
13
+ export function depFolderName(cashregisterId, from, to) {
14
+ const id = teil(String(cashregisterId ?? '')) || 'Kasse';
15
+ const von = typeof from === 'string' && from.trim() ? teil(from) : null;
16
+ const bis = typeof to === 'string' && to.trim() ? teil(to) : null;
17
+ if (von && bis)
18
+ return `DEP_${id}_${von}_${bis}`;
19
+ if (bis)
20
+ return `DEP_${id}_bis_${bis}`;
21
+ if (von)
22
+ return `DEP_${id}_ab_${von}`;
23
+ return `DEP_${id}_alles`;
24
+ }