@kreiseck/kasseneck-api 1.1.0 → 1.2.0

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 (143) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +70 -0
  3. package/dist/cjs/client/aufrufe.d.ts +5 -5
  4. package/dist/cjs/client/aufrufe.js +21 -2
  5. package/dist/cjs/client/errors.d.ts +1 -1
  6. package/dist/cjs/client/errors.js +2 -1
  7. package/dist/cjs/client/receipts.d.ts +9 -1
  8. package/dist/cjs/client/receipts.js +18 -3
  9. package/dist/cjs/client/transport.d.ts +3 -3
  10. package/dist/cjs/client/transport.js +2 -2
  11. package/dist/cjs/index.d.ts +2 -2
  12. package/dist/cjs/index.js +6 -3
  13. package/dist/cjs/invoice/index.d.ts +2 -2
  14. package/dist/cjs/invoice/index.js +3 -1
  15. package/dist/cjs/invoice/typen.d.ts +13 -2
  16. package/dist/cjs/invoice/vertrag.d.ts +10 -1
  17. package/dist/cjs/invoice/vertrag.js +39 -2
  18. package/dist/cjs/models/cancellation.d.ts +14 -2
  19. package/dist/cjs/models/cancellation.js +15 -1
  20. package/dist/cjs/models/cashregister.d.ts +3 -0
  21. package/dist/cjs/models/cashregister.js +1 -0
  22. package/dist/cjs/models/index.d.ts +1 -1
  23. package/dist/cjs/models/index.js +4 -2
  24. package/dist/cjs/models/payment-errors.d.ts +1 -1
  25. package/dist/cjs/models/payment-errors.js +1 -0
  26. package/dist/cjs/models/receipt-email.d.ts +1 -1
  27. package/dist/cjs/models/receipt-email.js +1 -0
  28. package/dist/cjs/models/receipt-errors.d.ts +1 -1
  29. package/dist/cjs/models/receipt-errors.js +1 -0
  30. package/dist/cjs/models/receipt-item.d.ts +9 -0
  31. package/dist/cjs/models/receipt-item.js +5 -0
  32. package/dist/cjs/models/receipt.d.ts +1 -1
  33. package/dist/cjs/models/receipt.js +6 -1
  34. package/dist/cjs/pos/artikel.d.ts +14 -0
  35. package/dist/cjs/pos/artikel.js +13 -2
  36. package/dist/cjs/pos/errors.d.ts +3 -3
  37. package/dist/cjs/pos/errors.js +6 -2
  38. package/dist/cjs/pos/index.d.ts +5 -2
  39. package/dist/cjs/pos/index.js +13 -2
  40. package/dist/cjs/pos/lager.d.ts +95 -0
  41. package/dist/cjs/pos/lager.js +160 -0
  42. package/dist/cjs/pos/texte.d.ts +22 -3
  43. package/dist/cjs/pos/texte.js +22 -6
  44. package/dist/cjs/printing/code-table-preview.d.ts +15 -0
  45. package/dist/cjs/printing/code-table-preview.js +24 -0
  46. package/dist/cjs/printing/index.d.ts +1 -0
  47. package/dist/cjs/printing/index.js +3 -1
  48. package/dist/cjs/receipt/code-table-test-sheet.d.ts +8 -2
  49. package/dist/cjs/receipt/code-table-test-sheet.js +2 -0
  50. package/dist/cjs/register/errors.d.ts +1 -1
  51. package/dist/cjs/register/errors.js +1 -0
  52. package/dist/cjs/register/pairing.d.ts +27 -1
  53. package/dist/cjs/register/pairing.js +18 -1
  54. package/dist/cjs/stored/draht.d.ts +4 -2
  55. package/dist/cjs/stored/draht.js +46 -5
  56. package/dist/cjs/stored/vokabular.d.ts +1 -1
  57. package/dist/cjs/stored/vokabular.js +5 -3
  58. package/dist/cjs/version.d.ts +1 -1
  59. package/dist/cjs/version.js +1 -1
  60. package/dist/esm/client/aufrufe.d.ts +5 -5
  61. package/dist/esm/client/aufrufe.js +21 -2
  62. package/dist/esm/client/errors.d.ts +1 -1
  63. package/dist/esm/client/errors.js +2 -1
  64. package/dist/esm/client/receipts.d.ts +9 -1
  65. package/dist/esm/client/receipts.js +19 -4
  66. package/dist/esm/client/transport.d.ts +3 -3
  67. package/dist/esm/client/transport.js +2 -2
  68. package/dist/esm/index.d.ts +2 -2
  69. package/dist/esm/index.js +2 -2
  70. package/dist/esm/invoice/index.d.ts +2 -2
  71. package/dist/esm/invoice/index.js +1 -1
  72. package/dist/esm/invoice/typen.d.ts +13 -2
  73. package/dist/esm/invoice/vertrag.d.ts +10 -1
  74. package/dist/esm/invoice/vertrag.js +38 -1
  75. package/dist/esm/models/cancellation.d.ts +14 -2
  76. package/dist/esm/models/cancellation.js +13 -0
  77. package/dist/esm/models/cashregister.d.ts +3 -0
  78. package/dist/esm/models/cashregister.js +1 -0
  79. package/dist/esm/models/index.d.ts +1 -1
  80. package/dist/esm/models/index.js +1 -1
  81. package/dist/esm/models/payment-errors.d.ts +1 -1
  82. package/dist/esm/models/payment-errors.js +1 -0
  83. package/dist/esm/models/receipt-email.d.ts +1 -1
  84. package/dist/esm/models/receipt-email.js +1 -0
  85. package/dist/esm/models/receipt-errors.d.ts +1 -1
  86. package/dist/esm/models/receipt-errors.js +1 -0
  87. package/dist/esm/models/receipt-item.d.ts +9 -0
  88. package/dist/esm/models/receipt-item.js +5 -0
  89. package/dist/esm/models/receipt.d.ts +1 -1
  90. package/dist/esm/models/receipt.js +6 -1
  91. package/dist/esm/pos/artikel.d.ts +14 -0
  92. package/dist/esm/pos/artikel.js +13 -3
  93. package/dist/esm/pos/errors.d.ts +3 -3
  94. package/dist/esm/pos/errors.js +6 -2
  95. package/dist/esm/pos/index.d.ts +5 -2
  96. package/dist/esm/pos/index.js +6 -2
  97. package/dist/esm/pos/lager.d.ts +95 -0
  98. package/dist/esm/pos/lager.js +154 -0
  99. package/dist/esm/pos/texte.d.ts +22 -3
  100. package/dist/esm/pos/texte.js +22 -6
  101. package/dist/esm/printing/code-table-preview.d.ts +15 -0
  102. package/dist/esm/printing/code-table-preview.js +21 -0
  103. package/dist/esm/printing/index.d.ts +1 -0
  104. package/dist/esm/printing/index.js +1 -0
  105. package/dist/esm/receipt/code-table-test-sheet.d.ts +8 -2
  106. package/dist/esm/receipt/code-table-test-sheet.js +2 -0
  107. package/dist/esm/register/errors.d.ts +1 -1
  108. package/dist/esm/register/errors.js +1 -0
  109. package/dist/esm/register/pairing.d.ts +27 -1
  110. package/dist/esm/register/pairing.js +17 -1
  111. package/dist/esm/stored/draht.d.ts +4 -2
  112. package/dist/esm/stored/draht.js +45 -4
  113. package/dist/esm/stored/vokabular.d.ts +1 -1
  114. package/dist/esm/stored/vokabular.js +5 -3
  115. package/dist/esm/version.d.ts +1 -1
  116. package/dist/esm/version.js +1 -1
  117. package/fixtures/code-table-preview.json +14 -0
  118. package/fixtures/expected/code-table-test-sheet.lines.json +22 -4
  119. package/fixtures/expected/code-table-test-sheet.mm58.hex +58 -55
  120. package/fixtures/expected/code-table-test-sheet.mm80.hex +59 -56
  121. package/fixtures/hobex-hps-codes.json +1 -1
  122. package/fixtures/invoice-api-examples/cancel-error-return-disposition.json +17 -0
  123. package/fixtures/invoice-api-examples/credit-error-return-disposition.json +26 -0
  124. package/fixtures/invoice-api-examples/credit-return-disposition.json +23 -0
  125. package/fixtures/invoice-api-examples/issue-error-return-disposition.json +25 -0
  126. package/fixtures/invoice-api-examples/issue-error-stock-id.json +27 -0
  127. package/fixtures/invoice-api-examples/issue-stock.json +22 -0
  128. package/fixtures/invoice-api.schema.json +37 -1
  129. package/fixtures/invoice-texts.json +1 -1
  130. package/fixtures/pos-texts.json +25 -4
  131. package/fixtures/surface.json +48 -4
  132. package/fixtures/v3/antworten/belege.json +1 -1
  133. package/fixtures/v3/antworten/belegmail.json +1 -1
  134. package/fixtures/v3/antworten/kasse-belege.json +1 -1
  135. package/fixtures/v3/antworten/kasse.json +662 -3
  136. package/fixtures/v3/antworten/rechnungen.json +1 -1
  137. package/fixtures/v3/antworten/storno.json +1 -1
  138. package/fixtures/v3/stored/belege.json +1 -1
  139. package/fixtures/v3/stored/kasse.json +58 -3
  140. package/fixtures/v3/stored/rechnungen.json +1 -1
  141. package/fixtures/v3/v3-vokabular.json +249 -16
  142. package/fixtures/v3/zahlbetrag-faelle.json +1 -1
  143. package/package.json +1 -1
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPosSettings = exports.allowedQuantity = exports.quantityDefaults = 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.POS_DEVICE_DEFAULTS = exports.POS_BUSINESS_DEFAULTS = exports.POS_SHORTCUT_DEFAULTS = exports.POS_SHORTCUT_ACTIONS = void 0;
4
- exports.labelText = exports.LABELS = 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.listMyTipRecipients = exports.getPrintJob = exports.createPrintJob = exports.listMyPrinters = exports.isPrintJobFinished = exports.PRINT_JOB_SOURCES = exports.PRINT_JOB_STATUSES = 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 = void 0;
4
+ exports.labelText = exports.LABELS = 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.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.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 = void 0;
5
5
  /**
6
6
  * Kachel-Kasse: Einstellungen, Artikelgruppen/Artikel fuer Kacheln,
7
- * Rabattverteilung, Drucker, Trinkgeld-Empfaenger. Die Aufrufe heissen 1:1 wie
7
+ * Rabattverteilung, Drucker, Trinkgeld-Empfaenger, Lager (Standorte, Bestand,
8
+ * Standort der Kasse). Die Aufrufe heissen 1:1 wie
8
9
  * die Backend-Functions (die Rewrites-Waechter der Web-App leiten daraus ab)
9
10
  * und sprechen den Kassenweg `/api/v3` (Schluessel und Werte englisch).
10
11
  */
@@ -79,6 +80,7 @@ Object.defineProperty(exports, "distributeDiscount", { enumerable: true, get: fu
79
80
  var pairing_js_1 = require("../register/pairing.js");
80
81
  Object.defineProperty(exports, "cancelScopeOf", { enumerable: true, get: function () { return pairing_js_1.cancelScopeOf; } });
81
82
  Object.defineProperty(exports, "receiptsScopeOf", { enumerable: true, get: function () { return pairing_js_1.receiptsScopeOf; } });
83
+ Object.defineProperty(exports, "stockViewOf", { enumerable: true, get: function () { return pairing_js_1.stockViewOf; } });
82
84
  var drucker_js_1 = require("./drucker.js");
83
85
  Object.defineProperty(exports, "PRINT_JOB_STATUSES", { enumerable: true, get: function () { return drucker_js_1.PRINT_JOB_STATUSES; } });
84
86
  Object.defineProperty(exports, "PRINT_JOB_SOURCES", { enumerable: true, get: function () { return drucker_js_1.PRINT_JOB_SOURCES; } });
@@ -88,6 +90,15 @@ Object.defineProperty(exports, "createPrintJob", { enumerable: true, get: functi
88
90
  Object.defineProperty(exports, "getPrintJob", { enumerable: true, get: function () { return drucker_js_1.getPrintJob; } });
89
91
  var trinkgeld_js_1 = require("./trinkgeld.js");
90
92
  Object.defineProperty(exports, "listMyTipRecipients", { enumerable: true, get: function () { return trinkgeld_js_1.listMyTipRecipients; } });
93
+ var lager_js_1 = require("./lager.js");
94
+ Object.defineProperty(exports, "STOCK_LOCATION_TYPES", { enumerable: true, get: function () { return lager_js_1.STOCK_LOCATION_TYPES; } });
95
+ Object.defineProperty(exports, "listMyStockLocations", { enumerable: true, get: function () { return lager_js_1.listMyStockLocations; } });
96
+ Object.defineProperty(exports, "listMyStock", { enumerable: true, get: function () { return lager_js_1.listMyStock; } });
97
+ Object.defineProperty(exports, "setMyCashregisterStockLocation", { enumerable: true, get: function () { return lager_js_1.setMyCashregisterStockLocation; } });
98
+ // Rueckgabe-Wahl beim Storno (Kassen-Dialog); dieselbe Liste wie an der Wurzel.
99
+ var cancellation_js_1 = require("../models/cancellation.js");
100
+ Object.defineProperty(exports, "RETURN_DISPOSITIONS", { enumerable: true, get: function () { return cancellation_js_1.RETURN_DISPOSITIONS; } });
101
+ Object.defineProperty(exports, "isReturnDisposition", { enumerable: true, get: function () { return cancellation_js_1.isReturnDisposition; } });
91
102
  // Was die Kasse selbst sagt: ein Katalog fuer Browser-Kasse und App.
92
103
  var texte_js_1 = require("./texte.js");
93
104
  Object.defineProperty(exports, "MESSAGES", { enumerable: true, get: function () { return texte_js_1.MESSAGES; } });
@@ -0,0 +1,95 @@
1
+ import type { InternerTransport } from '../client/aufrufe.js';
2
+ /**
3
+ * Lager an der Kasse (Lager-Kern Stufe 2, Backend lager-endpoints.js):
4
+ * Standorte, Bestand und der Standort der Kasse. Alle drei Aufrufe gibt es
5
+ * nur ueber den Kassenweg `/api/v3` (registerInternal); Rechte am Server:
6
+ * `stockView` (lesen), `stockCosts` (Werte), `stockLocation` (Standort setzen).
7
+ *
8
+ * **Ganzzahlen:** Mengen sind Tausendstel der Basiseinheit (`1000` = 1 Stueck,
9
+ * `250` = 0,250 kg), Werte ganze Cent bzw. Mikro-Euro. Nichts wird geteilt,
10
+ * gerundet oder geklemmt -- ein negativer Bestand (mehr verkauft als gebucht)
11
+ * ist eine Aussage des Servers und bleibt negativ. Eine Zahl, die keine
12
+ * Ganzzahl ist, oder eine fehlende Menge wird **nie** zu `0`: der Aufruf
13
+ * endet mit `KasseneckValidationError` (`scope: 'response'`), denn „kein
14
+ * Bestand“ und „Antwort kaputt“ sind verschiedene Aussagen.
15
+ */
16
+ /** Standort-Typen (Katalog `STANDORT_TYP`), englisch wie am Draht. */
17
+ export declare const STOCK_LOCATION_TYPES: readonly ["warehouse", "store", "vehicle", "other"];
18
+ export type StockLocationType = (typeof STOCK_LOCATION_TYPES)[number];
19
+ export interface StockLocationAddress {
20
+ street: string | null;
21
+ zip: string | null;
22
+ city: string | null;
23
+ country: string | null;
24
+ }
25
+ export interface StockLocation {
26
+ id: string;
27
+ name: string;
28
+ /** `null`: ein Typ, den dieses Paket nicht kennt. */
29
+ type: StockLocationType | null;
30
+ /** Fahrzeuge haben keine Adresse. */
31
+ address: StockLocationAddress | null;
32
+ /** Kennzeichen, nur bei `vehicle`. */
33
+ licensePlate: string | null;
34
+ /** `false` = aufgeloest; als Standort der Kasse abgewiesen (`location_inactive`). */
35
+ active: boolean;
36
+ /** `true` = Hauptstandort, den der Server ohne eigenes Dokument ergaenzt. */
37
+ virtual: boolean;
38
+ }
39
+ /** Bestand eines Artikels an einem Standort, in Tausendstel der Basiseinheit. */
40
+ export interface StockLevel {
41
+ articleId: string;
42
+ locationId: string;
43
+ sellable: number;
44
+ defective: number;
45
+ reserved: number;
46
+ /** `sellable - reserved`, vom Server gerechnet. */
47
+ available: number;
48
+ }
49
+ /** Lagerwert eines Artikels -- nur mit dem Recht `stockCosts`. */
50
+ export interface StockValue {
51
+ articleId: string;
52
+ stockValueCents: number;
53
+ /** Durchschnittlicher Einstandspreis je Basiseinheit in Mikro-Euro; `null` bei Menge 0. */
54
+ averageCostMicros: number | null;
55
+ }
56
+ export interface StockList {
57
+ stock: StockLevel[];
58
+ /**
59
+ * `null`, wenn der Aufrufer das Recht `stockCosts` nicht hat (der Server
60
+ * laesst das Feld weg); `[]`, wenn er es hat und nichts bewertet ist. Eine
61
+ * Oberflaeche zeigt bei `null` keinen Wert, nie „0,00 €“.
62
+ */
63
+ values: StockValue[] | null;
64
+ }
65
+ export interface ListMyStockOptions {
66
+ /** Nur dieser Standort; `''` gilt wie nicht angegeben. */
67
+ locationId?: string;
68
+ /** Nur dieser Artikel; `''` gilt wie nicht angegeben. */
69
+ articleId?: string;
70
+ /** Nur Zeilen unter dem Mindestbestand. */
71
+ belowMinimum?: boolean;
72
+ }
73
+ export interface SetMyCashregisterStockLocationOptions {
74
+ /** Standort-Kennung; `null` setzt auf den Standard-Standort des Betriebs zurueck. */
75
+ stockLocationId: string | null;
76
+ /** Ohne Angabe gilt die Kasse der Anmeldung (`registerUserAuth`). */
77
+ cashregisterId?: string;
78
+ }
79
+ export interface CashregisterStockLocation {
80
+ cashregisterId: string;
81
+ /** `null` = Standard-Standort des Betriebs. */
82
+ stockLocationId: string | null;
83
+ }
84
+ /** Standorte des Betriebs, samt aufgeloesten (`active: false`) und dem Hauptstandort. */
85
+ export declare function listMyStockLocations(transport: InternerTransport): Promise<StockLocation[]>;
86
+ /** Bestand je Artikel und Standort; Werte nur mit dem Recht `stockCosts`. */
87
+ export declare function listMyStock(transport: InternerTransport, options?: ListMyStockOptions): Promise<StockList>;
88
+ /**
89
+ * Standort der Kasse setzen -- von dort bucht der Server Verkauf und Storno
90
+ * ab. `stockLocationId: null` setzt zurueck (am Draht der leere Text).
91
+ * Fehler am Code: `location_not_found`, `location_inactive`,
92
+ * `cashregister_not_found`, `cashregister_not_assigned`, `not_permitted`,
93
+ * `module_inactive`.
94
+ */
95
+ export declare function setMyCashregisterStockLocation(transport: InternerTransport, options: SetMyCashregisterStockLocationOptions): Promise<CashregisterStockLocation>;
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.STOCK_LOCATION_TYPES = void 0;
4
+ exports.listMyStockLocations = listMyStockLocations;
5
+ exports.listMyStock = listMyStock;
6
+ exports.setMyCashregisterStockLocation = setMyCashregisterStockLocation;
7
+ const errors_js_1 = require("../client/errors.js");
8
+ const artikel_js_1 = require("./artikel.js");
9
+ /**
10
+ * Lager an der Kasse (Lager-Kern Stufe 2, Backend lager-endpoints.js):
11
+ * Standorte, Bestand und der Standort der Kasse. Alle drei Aufrufe gibt es
12
+ * nur ueber den Kassenweg `/api/v3` (registerInternal); Rechte am Server:
13
+ * `stockView` (lesen), `stockCosts` (Werte), `stockLocation` (Standort setzen).
14
+ *
15
+ * **Ganzzahlen:** Mengen sind Tausendstel der Basiseinheit (`1000` = 1 Stueck,
16
+ * `250` = 0,250 kg), Werte ganze Cent bzw. Mikro-Euro. Nichts wird geteilt,
17
+ * gerundet oder geklemmt -- ein negativer Bestand (mehr verkauft als gebucht)
18
+ * ist eine Aussage des Servers und bleibt negativ. Eine Zahl, die keine
19
+ * Ganzzahl ist, oder eine fehlende Menge wird **nie** zu `0`: der Aufruf
20
+ * endet mit `KasseneckValidationError` (`scope: 'response'`), denn „kein
21
+ * Bestand“ und „Antwort kaputt“ sind verschiedene Aussagen.
22
+ */
23
+ /** Standort-Typen (Katalog `STANDORT_TYP`), englisch wie am Draht. */
24
+ exports.STOCK_LOCATION_TYPES = Object.freeze(['warehouse', 'store', 'vehicle', 'other']);
25
+ const TYPEN = new Set(exports.STOCK_LOCATION_TYPES);
26
+ function antwortfehler(name, grund) {
27
+ return new errors_js_1.KasseneckValidationError(name, grund, 'response');
28
+ }
29
+ const objekt = (w) => (w !== null && typeof w === 'object' && !Array.isArray(w) ? w : null);
30
+ /** Freitext, der fehlen darf (Name, Adressteile, Kennzeichen): leer = `null`. */
31
+ const textOderNull = (w) => (typeof w === 'string' && w !== '' ? w : null);
32
+ /**
33
+ * Eine Kennung, die da sein muss: ohne sie ist die Zeile nicht zuzuordnen,
34
+ * und ein leerer Text als `stockLocationId` setzte die Kasse zurueck.
35
+ */
36
+ function kennung(name, pfad, w) {
37
+ if (typeof w !== 'string' || w === '')
38
+ throw antwortfehler(name, `Antwort enthaelt keine Kennung (data.${pfad} fehlt)`);
39
+ return w;
40
+ }
41
+ /** Eine Zahl des Servers: Ganzzahl oder Antwortfehler, nie ein Ersatzwert. */
42
+ function ganzzahl(name, pfad, w) {
43
+ if (typeof w !== 'number' || !Number.isInteger(w)) {
44
+ throw antwortfehler(name, `Antwort enthaelt keine ganze Zahl (data.${pfad})`);
45
+ }
46
+ return w;
47
+ }
48
+ function standort(name, e, i) {
49
+ const s = objekt(e) ?? {};
50
+ const pfad = `locations[${i}]`;
51
+ const a = objekt(s.address);
52
+ const teile = a ? { street: textOderNull(a.street), zip: textOderNull(a.zip), city: textOderNull(a.city), country: textOderNull(a.country) } : null;
53
+ // Eine Adresse ohne einen einzigen Teil ist keine Adresse.
54
+ const address = teile && Object.values(teile).some((t) => t !== null) ? teile : null;
55
+ return {
56
+ id: kennung(name, `${pfad}.id`, s.id),
57
+ name: typeof s.name === 'string' ? s.name : '',
58
+ type: typeof s.type === 'string' && TYPEN.has(s.type) ? s.type : null,
59
+ address,
60
+ licensePlate: textOderNull(s.licensePlate),
61
+ active: s.active !== false,
62
+ virtual: s.virtual === true,
63
+ };
64
+ }
65
+ function bestand(name, e, i) {
66
+ const b = objekt(e) ?? {};
67
+ const pfad = `stock[${i}]`;
68
+ return {
69
+ articleId: kennung(name, `${pfad}.articleId`, b.articleId),
70
+ locationId: kennung(name, `${pfad}.locationId`, b.locationId),
71
+ sellable: ganzzahl(name, `${pfad}.sellable`, b.sellable),
72
+ defective: ganzzahl(name, `${pfad}.defective`, b.defective),
73
+ reserved: ganzzahl(name, `${pfad}.reserved`, b.reserved),
74
+ available: ganzzahl(name, `${pfad}.available`, b.available),
75
+ };
76
+ }
77
+ function wert(name, e, i) {
78
+ const w = objekt(e) ?? {};
79
+ const pfad = `values[${i}]`;
80
+ return {
81
+ articleId: kennung(name, `${pfad}.articleId`, w.articleId),
82
+ stockValueCents: ganzzahl(name, `${pfad}.stockValueCents`, w.stockValueCents),
83
+ // Fehlt der Durchschnitt oder ist er null, ist die Menge 0 -- eine
84
+ // vorhandene, aber unbrauchbare Zahl ist dagegen ein Antwortfehler.
85
+ averageCostMicros: w.averageCostMicros === undefined || w.averageCostMicros === null
86
+ ? null
87
+ : ganzzahl(name, `${pfad}.averageCostMicros`, w.averageCostMicros),
88
+ };
89
+ }
90
+ /** Standorte des Betriebs, samt aufgeloesten (`active: false`) und dem Hauptstandort. */
91
+ async function listMyStockLocations(transport) {
92
+ const name = 'listMyStockLocations';
93
+ const daten = await transport(name);
94
+ return (0, artikel_js_1.liste)(daten, 'locations', name, (e, i) => standort(name, e, i));
95
+ }
96
+ /** Bestand je Artikel und Standort; Werte nur mit dem Recht `stockCosts`. */
97
+ async function listMyStock(transport, options = {}) {
98
+ const name = 'listMyStock';
99
+ if (options === null || typeof options !== 'object')
100
+ throw new errors_js_1.KasseneckValidationError(name, 'options muss ein Objekt sein', 'request');
101
+ const params = {};
102
+ for (const feld of ['locationId', 'articleId']) {
103
+ const w = options[feld];
104
+ if (w === undefined || w === '')
105
+ continue;
106
+ if (typeof w !== 'string')
107
+ throw new errors_js_1.KasseneckValidationError(name, `${feld} muss Text sein`, 'request');
108
+ params[feld] = w;
109
+ }
110
+ if (options.belowMinimum !== undefined) {
111
+ if (typeof options.belowMinimum !== 'boolean')
112
+ throw new errors_js_1.KasseneckValidationError(name, 'belowMinimum muss true oder false sein', 'request');
113
+ // false filtert am Server nicht; gesendet wird nur der Filter selbst.
114
+ if (options.belowMinimum)
115
+ params.belowMinimum = true;
116
+ }
117
+ const daten = await transport(name, params);
118
+ const stock = (0, artikel_js_1.liste)(daten, 'stock', name, (e, i) => bestand(name, e, i));
119
+ const roh = objekt(daten)?.values;
120
+ // Fehlt `values`, fehlt dem Aufrufer das Recht `stockCosts`: `null`, nie `[]`.
121
+ // Etwas anderes als eine Liste ist dagegen kein „kein Recht“, sondern kaputt.
122
+ if (roh === undefined || roh === null)
123
+ return { stock, values: null };
124
+ return { stock, values: (0, artikel_js_1.liste)(daten, 'values', name, (e, i) => wert(name, e, i)) };
125
+ }
126
+ /**
127
+ * Standort der Kasse setzen -- von dort bucht der Server Verkauf und Storno
128
+ * ab. `stockLocationId: null` setzt zurueck (am Draht der leere Text).
129
+ * Fehler am Code: `location_not_found`, `location_inactive`,
130
+ * `cashregister_not_found`, `cashregister_not_assigned`, `not_permitted`,
131
+ * `module_inactive`.
132
+ */
133
+ async function setMyCashregisterStockLocation(transport, options) {
134
+ const name = 'setMyCashregisterStockLocation';
135
+ const ziel = options?.stockLocationId;
136
+ if (ziel !== null && typeof ziel !== 'string') {
137
+ throw new errors_js_1.KasseneckValidationError(name, 'stockLocationId fehlt (Kennung, oder null zum Zuruecksetzen)', 'request');
138
+ }
139
+ // Leer setzt zurueck. Nur Leerraum wuerde der Server kuerzen und damit still
140
+ // auf den Standard-Standort zuruecksetzen: das ist kein Standort, sondern ein Fehler.
141
+ if (ziel !== null && ziel !== '' && ziel.trim() === '') {
142
+ throw new errors_js_1.KasseneckValidationError(name, 'stockLocationId ist nur Leerraum (Kennung angeben, oder null zum Zuruecksetzen)', 'request');
143
+ }
144
+ const params = { stockLocationId: ziel === null ? '' : ziel };
145
+ if (options.cashregisterId !== undefined) {
146
+ if (typeof options.cashregisterId !== 'string' || options.cashregisterId.trim() === '') {
147
+ throw new errors_js_1.KasseneckValidationError(name, 'cashregisterId ist leer', 'request');
148
+ }
149
+ params.cashregisterId = options.cashregisterId;
150
+ }
151
+ const daten = objekt(await transport(name, params));
152
+ if (!daten || typeof daten.cashregisterId !== 'string' || daten.cashregisterId === '') {
153
+ throw antwortfehler(name, 'Antwort enthaelt keine Kasse (data.cashregisterId fehlt)');
154
+ }
155
+ const stand = daten.stockLocationId;
156
+ if (stand !== null && stand !== undefined && typeof stand !== 'string') {
157
+ throw antwortfehler(name, 'Antwort enthaelt einen unbrauchbaren Standort (data.stockLocationId)');
158
+ }
159
+ return { cashregisterId: daten.cashregisterId, stockLocationId: textOderNull(stand) };
160
+ }
@@ -470,10 +470,17 @@ declare const MELDUNGEN_ROH: {
470
470
  readonly text: "Nichts gespeichert.";
471
471
  };
472
472
  readonly 'codetable.question': {
473
- readonly text: "Welche Zeile sieht auf dem Papier aus wie oben?";
473
+ readonly text: "In welcher Zeile steht kein falsches Zeichen?";
474
+ };
475
+ readonly 'codetable.question_hint': {
476
+ readonly text: "Lücken sind in Ordnung.";
474
477
  };
475
478
  readonly 'codetable.instruction': {
476
- readonly text: "Die Nummer der ersten Zeile, die genau wie oben aussieht, in der Kasse antippen.";
479
+ readonly text: "Die Zeile, in der KEIN falsches Zeichen steht. Eine Lücke ist in Ordnung. Passen mehrere, die mit den wenigsten Lücken.";
480
+ };
481
+ readonly 'codetable.instruction_none': {
482
+ readonly text: "Passt keine: {number}.";
483
+ readonly placeholders: readonly ["number"];
477
484
  };
478
485
  readonly 'bluetooth.off': {
479
486
  readonly text: "Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.";
@@ -974,7 +981,7 @@ declare const BESCHRIFTUNGEN_ROH: {
974
981
  readonly text: "ZEICHENSATZ-TEST";
975
982
  };
976
983
  readonly 'codetable.reference': {
977
- readonly text: "So muss jede Zeile aussehen:";
984
+ readonly text: "So sehen die Zeichen richtig aus";
978
985
  };
979
986
  readonly 'codetable.replacement_note': {
980
987
  readonly text: "(Ersatz, passt immer)";
@@ -996,6 +1003,18 @@ declare const BESCHRIFTUNGEN_ROH: {
996
1003
  readonly text: "Zeichensatz: Nr. {number}";
997
1004
  readonly placeholders: readonly ["number"];
998
1005
  };
1006
+ readonly 'codetable.instruction_title': {
1007
+ readonly text: "Welche Zeile nehmen?";
1008
+ };
1009
+ readonly 'codetable.preview_title': {
1010
+ readonly text: "So steht es dann am Bon:";
1011
+ };
1012
+ readonly 'codetable.apply': {
1013
+ readonly text: "Übernehmen";
1014
+ };
1015
+ readonly 'codetable.other_row': {
1016
+ readonly text: "Andere Zeile";
1017
+ };
999
1018
  };
1000
1019
  export type LabelKey = keyof typeof BESCHRIFTUNGEN_ROH;
1001
1020
  export declare const LABELS: Record<LabelKey, TextEntry>;
@@ -256,9 +256,17 @@ const MELDUNGEN_ROH = {
256
256
  // damit niemand einen halb eingerichteten Drucker vermutet.
257
257
  'print.wizard_cancelled': { text: 'Nichts gespeichert.' },
258
258
  // Zeichensatz-Test im Drucker-Wizard: das Testblatt nennt die Anleitung,
259
- // der Bildschirm stellt die Frage daneben.
260
- 'codetable.question': { text: 'Welche Zeile sieht auf dem Papier aus wie oben?' },
261
- 'codetable.instruction': { text: 'Die Nummer der ersten Zeile, die genau wie oben aussieht, in der Kasse antippen.' },
259
+ // der Bildschirm stellt die Frage daneben. Die Regel ist „kein falsches
260
+ // Zeichen“, nicht „erste Zeile“ und nicht „Umlaute richtig“: ein Drucker
261
+ // mit nur PC437 druckt Zeile 2 und 3 mit richtigen Umlauten, aber falschem
262
+ // € und § (╒, ⌡); richtig ist dort Zeile 4, mit Luecken fuer € und §.
263
+ // Am Papier steht „Lücke“ als „Luecke“ (Ersatzbuchstaben wie jeder Text
264
+ // ausserhalb der Testzeilen), am Bildschirm mit Umlaut.
265
+ 'codetable.question': { text: 'In welcher Zeile steht kein falsches Zeichen?' },
266
+ 'codetable.question_hint': { text: 'Lücken sind in Ordnung.' },
267
+ 'codetable.instruction': { text: 'Die Zeile, in der KEIN falsches Zeichen steht. Eine Lücke ist in Ordnung. Passen mehrere, die mit den wenigsten Lücken.' },
268
+ // `{number}` ist die Ersatz-Zeile (6), die immer passt.
269
+ 'codetable.instruction_none': { text: 'Passt keine: {number}.', placeholders: ['number'] },
262
270
  'bluetooth.off': { text: 'Bluetooth ist ausgeschaltet. Bitte einschalten und erneut suchen.', only: ['app'] },
263
271
  'bluetooth.permission_missing': { text: 'Bitte die Freigabe in den Geräte-Einstellungen erteilen.', only: ['app'] },
264
272
  'bluetooth.search_failed': { text: 'Die Suche ist fehlgeschlagen: {reason}', placeholders: ['reason'], only: ['app'] },
@@ -571,17 +579,25 @@ const BESCHRIFTUNGEN_ROH = {
571
579
  'cancellation.payment_remainder': { text: 'Rest {amount}', placeholders: ['amount'] },
572
580
  'cancellation.difference': { text: 'Differenz' },
573
581
  // --- Zeichensatz-Test (Testblatt und Drucker & Lade) ----------------------
574
- // Das Testblatt druckt diese Texte; sie bleiben reines ASCII bis auf die
575
- // Knoepfe am Bildschirm. `{chars}` sind die fehlenden Zeichen einer Zeile
582
+ // Das Testblatt druckt diese Texte mit Ersatzbuchstaben (reines ASCII);
583
+ // die Knoepfe stehen nur am Bildschirm. `{chars}` sind die fehlenden Zeichen einer Zeile
576
584
  // („€“ bzw. „€ §“), `{number}` die gewaehlte Zeile (1-6).
577
585
  'codetable.title': { text: 'ZEICHENSATZ-TEST' },
578
- 'codetable.reference': { text: 'So muss jede Zeile aussehen:' },
586
+ // Genau 32 Spalten: mit Doppelpunkt waeren es 33, die Ueberschrift braeche um.
587
+ 'codetable.reference': { text: 'So sehen die Zeichen richtig aus' },
579
588
  'codetable.replacement_note': { text: '(Ersatz, passt immer)' },
580
589
  'codetable.missing': { text: 'ohne {chars}', placeholders: ['chars'] },
581
590
  'codetable.print_again': { text: 'Nochmal drucken' },
582
591
  'codetable.not_checked': { text: 'Umlaute noch nicht geprüft' },
583
592
  'codetable.check': { text: 'Umlaute prüfen' },
584
593
  'codetable.current': { text: 'Zeichensatz: Nr. {number}', placeholders: ['number'] },
594
+ // Ueberschrift der Anleitung am Testblatt.
595
+ 'codetable.instruction_title': { text: 'Welche Zeile nehmen?' },
596
+ // Nach der Wahl: das Beispiel so, wie es mit der Zeile am Bon steht
597
+ // (`codeTablePreviewText`), dann uebernehmen oder zurueck zur Frage.
598
+ 'codetable.preview_title': { text: 'So steht es dann am Bon:' },
599
+ 'codetable.apply': { text: 'Übernehmen' },
600
+ 'codetable.other_row': { text: 'Andere Zeile' },
585
601
  };
586
602
  exports.LABELS = BESCHRIFTUNGEN_ROH;
587
603
  /** Die Beschriftung zum Schluessel, Platzhalter ersetzt; fehlt ein Wert, wirft es wie `messageText`. */
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Die Vorschau im Drucker-Wizard: nach der Wahl einer Zeile zeigt der
3
+ * Bildschirm ein Beispiel so, wie es mit dieser Tabelle am Bon steht. Wer
4
+ * Zeile 4 (PC437) waehlt, sieht „3,50 EUR“ statt „3,50 €“, bevor er
5
+ * uebernimmt. Gemeinsamer Prueffall mit dem Dart-Zwilling:
6
+ * `fixtures/code-table-preview.json`.
7
+ */
8
+ import { type CodeTableId } from './code-tables.js';
9
+ /**
10
+ * Das Beispiel mit den Ersetzungen der Tabelle, Zeilen durch `\n` getrennt:
11
+ * fehlt der Tabelle ein Zeichen, stehen seine Ersatzbuchstaben da
12
+ * (`pc437` -> „Käsekrainer 3,50 EUR“, `replacement` -> „Kaesekrainer 3,50 EUR“).
13
+ * Eine unbekannte Kennung wird gemeldet.
14
+ */
15
+ export declare function codeTablePreviewText(table: CodeTableId): string;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.codeTablePreviewText = codeTablePreviewText;
4
+ /**
5
+ * Die Vorschau im Drucker-Wizard: nach der Wahl einer Zeile zeigt der
6
+ * Bildschirm ein Beispiel so, wie es mit dieser Tabelle am Bon steht. Wer
7
+ * Zeile 4 (PC437) waehlt, sieht „3,50 EUR“ statt „3,50 €“, bevor er
8
+ * uebernimmt. Gemeinsamer Prueffall mit dem Dart-Zwilling:
9
+ * `fixtures/code-table-preview.json`.
10
+ */
11
+ const code_tables_js_1 = require("./code-tables.js");
12
+ const printable_js_1 = require("./printable.js");
13
+ /** Das Beispiel: Umlaut, €, °. */
14
+ const BEISPIEL = ['Käsekrainer 3,50 €', 'Tee 80°'];
15
+ /**
16
+ * Das Beispiel mit den Ersetzungen der Tabelle, Zeilen durch `\n` getrennt:
17
+ * fehlt der Tabelle ein Zeichen, stehen seine Ersatzbuchstaben da
18
+ * (`pc437` -> „Käsekrainer 3,50 EUR“, `replacement` -> „Kaesekrainer 3,50 EUR“).
19
+ * Eine unbekannte Kennung wird gemeldet.
20
+ */
21
+ function codeTablePreviewText(table) {
22
+ (0, code_tables_js_1.codeTableById)(table);
23
+ return BEISPIEL.map((zeile) => (0, printable_js_1.escPosPrintableText)(zeile, table)).join('\n');
24
+ }
@@ -2,4 +2,5 @@ export { type PosPaperSize, type PosAlign, type PosFont, type PosCutMode, type P
2
2
  export { type CodeTableId, type CodeTable, CODE_TABLES, codeTableById, codeTableFromSetting, encodeForCodeTable, } from './code-tables.js';
3
3
  export { type QrModuleSize, type QrSizing, QR_MODULE_SIZE_CAP, QR_QUIET_ZONE_MODULES, QR_MIN_MODULE_DOTS, QR_EXCEPTION_MODULE_DOTS, QR_MAX_MODULE_DOTS, QR_PRINT_WIDTH_DOTS, qrModuleCount, qrFitsInVersion, computeQrSizing, qrSizingFor, } from './qr-groesse.js';
4
4
  export { escPosPrintableText } from './printable.js';
5
+ export { codeTablePreviewText } from './code-table-preview.js';
5
6
  export { type UsbEndpointLike, type UsbAlternateLike, type UsbInterfaceLike, type UsbConfigurationLike, type UsbTransferOutResultLike, type UsbWriterLike, type UsbIdentityLike, type UsbDeviceLike, type UsbPrinterEndpoint, type UsbPrinterConnection, USB_VENDOR_EPSON, USB_CLASS_PRINTER, UsbTimeoutError, usbDeviceKey, usbFindPrinterEndpoint, usbWriteAll, usbConnectPrinter, usbPrint, usbDisconnect, } from './webusb.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.usbDisconnect = exports.usbPrint = exports.usbConnectPrinter = exports.usbWriteAll = exports.usbFindPrinterEndpoint = exports.usbDeviceKey = exports.UsbTimeoutError = exports.USB_CLASS_PRINTER = exports.USB_VENDOR_EPSON = exports.escPosPrintableText = exports.qrSizingFor = exports.computeQrSizing = exports.qrFitsInVersion = exports.qrModuleCount = exports.QR_PRINT_WIDTH_DOTS = exports.QR_MAX_MODULE_DOTS = exports.QR_EXCEPTION_MODULE_DOTS = exports.QR_MIN_MODULE_DOTS = exports.QR_QUIET_ZONE_MODULES = exports.QR_MODULE_SIZE_CAP = exports.encodeForCodeTable = exports.codeTableFromSetting = exports.codeTableById = exports.CODE_TABLES = exports.wrapText = exports.escPosWrapLines = exports.escPosMaxCharsPerLine = exports.qrCodeBytes = exports.encodeEscPosText = exports.escPosRasterImage = exports.rasterRowsBase64 = exports.rasterRowsBytes = exports.qrRasterDots = exports.escPosQrRaster = exports.escPosQrCode = exports.escPosRow = exports.escPosHr = exports.escPosCut = exports.escPosFeed = exports.escPosEmptyLines = exports.escPosText = exports.escPosSetStyles = exports.escPosSetGlobalFont = exports.escPosSetGlobalCodeTable = exports.escPosReset = exports.escPosBytes = exports.createEscPosDocument = void 0;
3
+ exports.usbDisconnect = exports.usbPrint = exports.usbConnectPrinter = exports.usbWriteAll = exports.usbFindPrinterEndpoint = exports.usbDeviceKey = exports.UsbTimeoutError = exports.USB_CLASS_PRINTER = exports.USB_VENDOR_EPSON = exports.codeTablePreviewText = exports.escPosPrintableText = exports.qrSizingFor = exports.computeQrSizing = exports.qrFitsInVersion = exports.qrModuleCount = exports.QR_PRINT_WIDTH_DOTS = exports.QR_MAX_MODULE_DOTS = exports.QR_EXCEPTION_MODULE_DOTS = exports.QR_MIN_MODULE_DOTS = exports.QR_QUIET_ZONE_MODULES = exports.QR_MODULE_SIZE_CAP = exports.encodeForCodeTable = exports.codeTableFromSetting = exports.codeTableById = exports.CODE_TABLES = exports.wrapText = exports.escPosWrapLines = exports.escPosMaxCharsPerLine = exports.qrCodeBytes = exports.encodeEscPosText = exports.escPosRasterImage = exports.rasterRowsBase64 = exports.rasterRowsBytes = exports.qrRasterDots = exports.escPosQrRaster = exports.escPosQrCode = exports.escPosRow = exports.escPosHr = exports.escPosCut = exports.escPosFeed = exports.escPosEmptyLines = exports.escPosText = exports.escPosSetStyles = exports.escPosSetGlobalFont = exports.escPosSetGlobalCodeTable = exports.escPosReset = exports.escPosBytes = exports.createEscPosDocument = void 0;
4
4
  var escpos_js_1 = require("./escpos.js");
5
5
  Object.defineProperty(exports, "createEscPosDocument", { enumerable: true, get: function () { return escpos_js_1.createEscPosDocument; } });
6
6
  Object.defineProperty(exports, "escPosBytes", { enumerable: true, get: function () { return escpos_js_1.escPosBytes; } });
@@ -43,6 +43,8 @@ Object.defineProperty(exports, "computeQrSizing", { enumerable: true, get: funct
43
43
  Object.defineProperty(exports, "qrSizingFor", { enumerable: true, get: function () { return qr_groesse_js_1.qrSizingFor; } });
44
44
  var printable_js_1 = require("./printable.js");
45
45
  Object.defineProperty(exports, "escPosPrintableText", { enumerable: true, get: function () { return printable_js_1.escPosPrintableText; } });
46
+ var code_table_preview_js_1 = require("./code-table-preview.js");
47
+ Object.defineProperty(exports, "codeTablePreviewText", { enumerable: true, get: function () { return code_table_preview_js_1.codeTablePreviewText; } });
46
48
  var webusb_js_1 = require("./webusb.js");
47
49
  Object.defineProperty(exports, "USB_VENDOR_EPSON", { enumerable: true, get: function () { return webusb_js_1.USB_VENDOR_EPSON; } });
48
50
  Object.defineProperty(exports, "USB_CLASS_PRINTER", { enumerable: true, get: function () { return webusb_js_1.USB_CLASS_PRINTER; } });
@@ -5,8 +5,14 @@
5
5
  * Oben steht die Vorlage-Zeile als Rasterbild -- ein Bild druckt jeder
6
6
  * Drucker gleich, egal welche Tabelle er gerade hat. Darunter je Tabelle des
7
7
  * Katalogs eine Zeile mit ihrer Nummer (gross), umgeschaltet mit `ESC t n`
8
- * und mit den Bytes dieser Tabelle. Die erste Zeile, die aussieht wie die
9
- * Vorlage, ist die richtige; Zeile 6 (Ersatzbuchstaben) passt immer.
8
+ * und mit den Bytes dieser Tabelle. Richtig ist die Zeile ohne falsches
9
+ * Zeichen; eine Luecke (Zeichen fehlt der Tabelle) ist in Ordnung, bei
10
+ * mehreren die mit den wenigsten Luecken, sonst Zeile 6 (Ersatzbuchstaben).
11
+ * Nicht „die erste Zeile mit richtigen Umlauten“: ein Drucker mit nur PC437
12
+ * druckt Zeile 2 und 3 mit richtigen Umlauten, aber falschem € und §.
13
+ *
14
+ * Alles ausserhalb der Testzeilen steht mit Ersatzbuchstaben (reines ASCII),
15
+ * auch die Anleitung: „Lücke“ aus dem Katalog steht am Blatt als „Luecke“.
10
16
  *
11
17
  * Bildschirm und Papier zeigen dasselbe Blatt: `codeTableTestSheet` liefert
12
18
  * es im Zeilenmodell des Beleg-Blatts (`ReceiptSheet`), `codeTableTestSheetBytes`
@@ -93,7 +93,9 @@ function blattBauen(options) {
93
93
  bloecke.push(zeile(einzug + t));
94
94
  bloecke.push(zeile(einzug + nurAscii((0, texte_js_1.labelText)('codetable.replacement_note'))));
95
95
  bloecke.push(doppelt);
96
+ bloecke.push(...zeilen((0, texte_js_1.labelText)('codetable.instruction_title'), true));
96
97
  bloecke.push(...zeilen((0, texte_js_1.messageText)('codetable.instruction')));
98
+ bloecke.push(...zeilen((0, texte_js_1.messageText)('codetable.instruction_none', { number: ersatz.number })));
97
99
  bloecke.push(doppelt);
98
100
  return {
99
101
  blatt: {
@@ -22,7 +22,7 @@ import { KasseneckApiError } from '../client/errors.js';
22
22
  * ueber `KasseneckApiError.code` lesbar; die Kasse braucht dafuer einen
23
23
  * Rueckfallzweig.
24
24
  */
25
- export declare const REGISTER_ERROR_CODES: readonly ["account_not_found", "admin_required", "cashregister_in_use", "cashregister_not_assigned", "cashregister_not_found", "cashregister_token_invalid", "cashregister_token_missing", "device_bound_elsewhere", "device_not_found", "device_not_paired", "device_takeover_required", "dialect_mismatch", "internal_translation_error", "licenses_exhausted", "live_not_enabled", "location_outside", "location_required", "login_failed", "login_mode_select_user", "login_unavailable", "method_not_allowed", "mfa_required", "not_found", "pairing_code_expired", "pairing_code_unknown", "pairing_code_used", "pairing_failed", "register_user_no_business", "register_user_not_allowed", "register_user_not_found", "register_user_only", "response_translation_failed", "session_ended", "session_expired", "session_not_running", "session_other_cashregister", "too_many_attempts", "unauthorized", "user_disabled", "user_verification_failed", "validation", "route_missing"];
25
+ export declare const REGISTER_ERROR_CODES: readonly ["account_not_found", "admin_required", "api_not_approved", "cashregister_in_use", "cashregister_not_assigned", "cashregister_not_found", "cashregister_token_invalid", "cashregister_token_missing", "device_bound_elsewhere", "device_not_found", "device_not_paired", "device_takeover_required", "dialect_mismatch", "internal_translation_error", "licenses_exhausted", "live_not_enabled", "location_outside", "location_required", "login_failed", "login_mode_select_user", "login_unavailable", "method_not_allowed", "mfa_required", "not_found", "pairing_code_expired", "pairing_code_unknown", "pairing_code_used", "pairing_failed", "register_user_no_business", "register_user_not_allowed", "register_user_not_found", "register_user_only", "response_translation_failed", "session_ended", "session_expired", "session_not_running", "session_other_cashregister", "too_many_attempts", "unauthorized", "user_disabled", "user_verification_failed", "validation", "route_missing"];
26
26
  export type RegisterErrorCode = typeof REGISTER_ERROR_CODES[number];
27
27
  export declare function isRegisterErrorCode(value: unknown): value is RegisterErrorCode;
28
28
  /** Der Code eines geworfenen Fehlers, wenn es einer der Kassen-Anmeldung ist; sonst `undefined`. */
@@ -34,6 +34,7 @@ const fehlercodes_js_1 = require("../client/fehlercodes.js");
34
34
  exports.REGISTER_ERROR_CODES = Object.freeze([
35
35
  'account_not_found',
36
36
  'admin_required',
37
+ 'api_not_approved',
37
38
  'cashregister_in_use',
38
39
  'cashregister_not_assigned',
39
40
  'cashregister_not_found',
@@ -137,10 +137,12 @@ export interface RegisterDeviceUsers {
137
137
  * nennt den Grund als Menschentext (ausser Betrieb, keine Signaturkarte,
138
138
  * Startbeleg fehlt): die Kasse sperrt das Kassieren VOR dem ersten Beleg
139
139
  * statt an createReceipt zu scheitern. Fehlt das Feld, gilt bereit.
140
+ * `stockLocationId`: Lager-Standort der Kasse, fehlt = Standard-Standort.
140
141
  */
141
142
  cashregister?: {
142
143
  ready: boolean;
143
144
  reason?: string | null;
145
+ stockLocationId?: string;
144
146
  };
145
147
  /** Das Geraet haengt an der Test-Umgebung des Betriebs. */
146
148
  testEnvironment: boolean;
@@ -179,6 +181,24 @@ export interface RegisterUserPerms {
179
181
  discount?: boolean;
180
182
  /** Trinkgeld anderen zuweisen. */
181
183
  tipAssign?: boolean;
184
+ /**
185
+ * Lager: Standorte und Mengen sehen (listMyStockLocations, listMyStock).
186
+ * Fehlt das Recht, gilt es als erteilt – anders als alle anderen
187
+ * (siehe [stockViewOf]); ein ausdrueckliches `false` sperrt.
188
+ */
189
+ stockView?: boolean;
190
+ /** Lager: Einkaufswerte sehen (`values` in listMyStock); gibt nur der Inhaber frei. */
191
+ stockCosts?: boolean;
192
+ /** Lager: Wareneingang, Umbuchen. */
193
+ stockMove?: boolean;
194
+ /** Lager: Abgang, Zustand, Gegenbuchung. */
195
+ stockLoss?: boolean;
196
+ /** Inventur: zaehlen. */
197
+ stocktakeCount?: boolean;
198
+ /** Inventur: abschliessen. */
199
+ stocktakeClose?: boolean;
200
+ /** Standort der Kasse waehlen (setMyCashregisterStockLocation). */
201
+ stockLocation?: boolean;
182
202
  [weiteresRecht: string]: boolean | RegisterScope | undefined;
183
203
  }
184
204
  /**
@@ -189,10 +209,16 @@ export interface RegisterUserPerms {
189
209
  * nicht fuehrt (Tippfehler, umbenanntes Recht), kommt hier nicht durch.
190
210
  * Die Gegenrichtung schliesst [_RechteVollstaendig] direkt darunter.
191
211
  */
192
- export declare const REGISTER_PERMS: readonly ["sell", "cancel", "articles", "layout", "reports", "takeover", "cancelScope", "receiptsScope", "drawer", "discount", "tipAssign"];
212
+ export declare const REGISTER_PERMS: readonly ["sell", "cancel", "articles", "layout", "reports", "takeover", "cancelScope", "receiptsScope", "drawer", "discount", "tipAssign", "stockView", "stockCosts", "stockMove", "stockLoss", "stocktakeCount", "stocktakeClose", "stockLocation"];
193
213
  /** Reichweite lesen, mit der Migration des Backends (register-auth.js). */
194
214
  export declare function cancelScopeOf(perms: RegisterUserPerms | null | undefined): RegisterScope;
195
215
  export declare function receiptsScopeOf(perms: RegisterUserPerms | null | undefined): RegisterScope;
216
+ /**
217
+ * Darf der Benutzer Standorte und Mengen sehen? Wie im Backend (lager-core):
218
+ * ohne Schluessel gilt `stockView` als erteilt, ein ausdrueckliches `false`
219
+ * sperrt; alle anderen Lager-Rechte gelten ohne Schluessel als verweigert.
220
+ */
221
+ export declare function stockViewOf(perms: RegisterUserPerms | null | undefined): boolean;
196
222
  /** Der angemeldete Kassen-Benutzer. */
197
223
  export interface RegisterUser {
198
224
  id: string;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.REGISTER_PERMS = void 0;
4
4
  exports.cancelScopeOf = cancelScopeOf;
5
5
  exports.receiptsScopeOf = receiptsScopeOf;
6
+ exports.stockViewOf = stockViewOf;
6
7
  exports.pairRegisterDevice = pairRegisterDevice;
7
8
  exports.unpairRegisterDevice = unpairRegisterDevice;
8
9
  exports.listRegisterSessionsForDevice = listRegisterSessionsForDevice;
@@ -60,6 +61,7 @@ const ohneAnmeldung = () => ({ headers: {}, params: {} });
60
61
  exports.REGISTER_PERMS = [
61
62
  'sell', 'cancel', 'articles', 'layout', 'reports', 'takeover',
62
63
  'cancelScope', 'receiptsScope', 'drawer', 'discount', 'tipAssign',
64
+ 'stockView', 'stockCosts', 'stockMove', 'stockLoss', 'stocktakeCount', 'stocktakeClose', 'stockLocation',
63
65
  ];
64
66
  /** Reichweite lesen, mit der Migration des Backends (register-auth.js). */
65
67
  function cancelScopeOf(perms) {
@@ -76,6 +78,16 @@ function receiptsScopeOf(perms) {
76
78
  return 'all';
77
79
  return ['none', 'own', 'all'].includes(perms.receiptsScope) ? perms.receiptsScope : 'none';
78
80
  }
81
+ /**
82
+ * Darf der Benutzer Standorte und Mengen sehen? Wie im Backend (lager-core):
83
+ * ohne Schluessel gilt `stockView` als erteilt, ein ausdrueckliches `false`
84
+ * sperrt; alle anderen Lager-Rechte gelten ohne Schluessel als verweigert.
85
+ */
86
+ function stockViewOf(perms) {
87
+ if (!perms)
88
+ return false;
89
+ return perms.stockView === undefined ? true : perms.stockView === true;
90
+ }
79
91
  /**
80
92
  * Geraet koppeln: der Kopplungs-Code wird gegen den dauerhaften Ausweis dieses
81
93
  * Geraets getauscht. **Ohne Anmeldung** — der Code ist der Nachweis.
@@ -210,7 +222,12 @@ function kasseBereit(wert) {
210
222
  const roh = wert;
211
223
  if (typeof roh['ready'] !== 'boolean')
212
224
  return undefined;
213
- return { ready: roh['ready'], reason: typeof roh['reason'] === 'string' ? roh['reason'] : null };
225
+ const standort = roh['stockLocationId'];
226
+ return {
227
+ ready: roh['ready'],
228
+ reason: typeof roh['reason'] === 'string' ? roh['reason'] : null,
229
+ ...(typeof standort === 'string' && standort !== '' ? { stockLocationId: standort } : {}),
230
+ };
214
231
  }
215
232
  /** Die Regel aus der Antwort — oder `null`, wenn keine brauchbare kommt. */
216
233
  function regel(wert) {