@kreiseck/kasseneck-api 1.3.0 → 1.5.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 (88) hide show
  1. package/CHANGELOG.md +176 -0
  2. package/README.md +293 -1
  3. package/dist/cjs/client/aufrufe.d.ts +2 -2
  4. package/dist/cjs/client/aufrufe.js +58 -0
  5. package/dist/cjs/inventory/api.d.ts +61 -0
  6. package/dist/cjs/inventory/api.js +54 -0
  7. package/dist/cjs/inventory/auth.d.ts +17 -0
  8. package/dist/cjs/inventory/auth.js +27 -0
  9. package/dist/cjs/inventory/endpunkte.d.ts +91 -0
  10. package/dist/cjs/inventory/endpunkte.js +290 -0
  11. package/dist/cjs/inventory/fehler.d.ts +43 -0
  12. package/dist/cjs/inventory/fehler.js +66 -0
  13. package/dist/cjs/inventory/index.d.ts +21 -0
  14. package/dist/cjs/inventory/index.js +94 -0
  15. package/dist/cjs/inventory/lesen.d.ts +45 -0
  16. package/dist/cjs/inventory/lesen.js +424 -0
  17. package/dist/cjs/inventory/schreiben.d.ts +83 -0
  18. package/dist/cjs/inventory/schreiben.js +315 -0
  19. package/dist/cjs/inventory/typen.d.ts +679 -0
  20. package/dist/cjs/inventory/typen.js +14 -0
  21. package/dist/cjs/inventory/vertrag.d.ts +136 -0
  22. package/dist/cjs/inventory/vertrag.js +291 -0
  23. package/dist/cjs/inventory/webhook.d.ts +52 -0
  24. package/dist/cjs/inventory/webhook.js +116 -0
  25. package/dist/cjs/invoice/index.d.ts +2 -2
  26. package/dist/cjs/invoice/index.js +2 -1
  27. package/dist/cjs/invoice/typen.d.ts +46 -2
  28. package/dist/cjs/invoice/vertrag.d.ts +19 -5
  29. package/dist/cjs/invoice/vertrag.js +37 -5
  30. package/dist/cjs/stored/vokabular.d.ts +1 -1
  31. package/dist/cjs/stored/vokabular.js +5 -3
  32. package/dist/cjs/version.d.ts +1 -1
  33. package/dist/cjs/version.js +1 -1
  34. package/dist/esm/client/aufrufe.d.ts +2 -2
  35. package/dist/esm/client/aufrufe.js +58 -0
  36. package/dist/esm/inventory/api.d.ts +61 -0
  37. package/dist/esm/inventory/api.js +51 -0
  38. package/dist/esm/inventory/auth.d.ts +17 -0
  39. package/dist/esm/inventory/auth.js +24 -0
  40. package/dist/esm/inventory/endpunkte.d.ts +91 -0
  41. package/dist/esm/inventory/endpunkte.js +267 -0
  42. package/dist/esm/inventory/fehler.d.ts +43 -0
  43. package/dist/esm/inventory/fehler.js +57 -0
  44. package/dist/esm/inventory/index.d.ts +21 -0
  45. package/dist/esm/inventory/index.js +20 -0
  46. package/dist/esm/inventory/lesen.d.ts +45 -0
  47. package/dist/esm/inventory/lesen.js +404 -0
  48. package/dist/esm/inventory/schreiben.d.ts +83 -0
  49. package/dist/esm/inventory/schreiben.js +298 -0
  50. package/dist/esm/inventory/typen.d.ts +679 -0
  51. package/dist/esm/inventory/typen.js +13 -0
  52. package/dist/esm/inventory/vertrag.d.ts +136 -0
  53. package/dist/esm/inventory/vertrag.js +288 -0
  54. package/dist/esm/inventory/webhook.d.ts +52 -0
  55. package/dist/esm/inventory/webhook.js +107 -0
  56. package/dist/esm/invoice/index.d.ts +2 -2
  57. package/dist/esm/invoice/index.js +1 -1
  58. package/dist/esm/invoice/typen.d.ts +46 -2
  59. package/dist/esm/invoice/vertrag.d.ts +19 -5
  60. package/dist/esm/invoice/vertrag.js +36 -4
  61. package/dist/esm/stored/vokabular.d.ts +1 -1
  62. package/dist/esm/stored/vokabular.js +5 -3
  63. package/dist/esm/version.d.ts +1 -1
  64. package/dist/esm/version.js +1 -1
  65. package/fixtures/hobex-hps-codes.json +1 -1
  66. package/fixtures/invoice-api-examples/credit-error-reservation.json +26 -0
  67. package/fixtures/invoice-api-examples/issue-error-reservation-article.json +25 -0
  68. package/fixtures/invoice-api-examples/issue-error-vat-id-risk.json +26 -0
  69. package/fixtures/invoice-api-examples/issue-reservation.json +24 -0
  70. package/fixtures/invoice-api-examples/issue-vat-id-risk.json +28 -0
  71. package/fixtures/invoice-api.schema.json +15 -2
  72. package/fixtures/invoice-texts.json +1 -1
  73. package/fixtures/pos-texts.json +1 -1
  74. package/fixtures/surface.json +306 -5
  75. package/fixtures/v3/README.md +9 -1
  76. package/fixtures/v3/antworten/belege.json +2 -2
  77. package/fixtures/v3/antworten/belegmail.json +2 -2
  78. package/fixtures/v3/antworten/kasse-belege.json +2 -2
  79. package/fixtures/v3/antworten/kasse.json +3 -3
  80. package/fixtures/v3/antworten/lager.json +3881 -0
  81. package/fixtures/v3/antworten/rechnungen.json +267 -44
  82. package/fixtures/v3/antworten/storno.json +2 -2
  83. package/fixtures/v3/stored/belege.json +2 -2
  84. package/fixtures/v3/stored/kasse.json +404 -4
  85. package/fixtures/v3/stored/rechnungen.json +174 -18
  86. package/fixtures/v3/v3-vokabular.json +1007 -20
  87. package/fixtures/v3/zahlbetrag-faelle.json +2 -2
  88. package/package.json +14 -2
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `@kreiseck/kasseneck-api/inventory` – die Lager-API: Artikel, Standorte,
3
+ * Bestand und Lagerprotokoll lesen, Konto-Webhooks verwalten und eingehende
4
+ * Zustellungen pruefen (Backend Stufe 5a); Artikel anlegen und aendern,
5
+ * Bestand buchen und Ware reservieren (Stufe 5b, seit 1.5.0).
6
+ *
7
+ * Ein eigener Unterpfad wie `invoice`: der `api_key` eines Kontos gehoert auf
8
+ * einen **Server** (etwa das Backend eines Online-Shops) und soll nicht
9
+ * versehentlich in ein Browser-Buendel wandern.
10
+ *
11
+ * Mengen in Tausendstel der Basiseinheit, Geld in Cent, Einkaufspreise in
12
+ * Mikro-Euro; alles Ganzzahlen.
13
+ */
14
+ export { createInventoryClient, type InventoryClient, type InventoryClientOptions } from './api.js';
15
+ export { inventoryKeyAuth, type InventoryKeyAuthOptions } from './auth.js';
16
+ export { isInventoryError, isInventoryErrorCode, inventoryErrorCode, inventoryFieldErrors, inventoryRetryAfterSec, inventoryShortfalls, isInventoryWarningCode, type InventoryApiErrorCode, type InventoryFieldError, } from './fehler.js';
17
+ export { createWebhook, deleteWebhook, getArticle, getStock, iterateArticles, iterateStock, iterateStockMovements, listArticles, listLocations, listStock, listStockMovements, listWebhookDeliveries, listWebhooks, lookupArticleByCode, rotateWebhookSecret, sendWebhookTest, updateWebhook, } from './endpunkte.js';
18
+ export { changeStockCondition, createArticle, createReservation, deactivateArticle, extendReservation, getReservation, iterateReservations, listReservations, previewGoodsReceipt, receiveGoods, recordStockLoss, releaseReservation, reverseStockMovement, transferStock, updateArticle, } from './schreiben.js';
19
+ export { verifyInventoryWebhookSignature, parseInventoryWebhookEvent, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_TOLERANCE_SEC, type VerifyInventoryWebhookOptions, } from './webhook.js';
20
+ export type { Article, ArticleInput, ArticleListQuery, ArticleLookup, ArticlePage, ChangeStockConditionRequest, CreateArticleRequest, CreateInventoryWebhookOptions, CreateReservationRequest, DeactivateArticleRequest, ExtendReservationRequest, GoodsReceiptItem, GoodsReceiptPreview, GoodsReceiptPreviewLine, GoodsReceiptPreviewRequest, InventoryShortfall, InventoryWarning, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookEnvelope, InventoryWebhookEvent, InventoryWebhookList, InventoryWebhookPatch, InventoryWebhookTestDelivery, InventoryWebhookTestResult, InventoryWebhookWithSecret, LandedCost, Location, LocationAddress, ReceiveGoodsRequest, RecordStockLossRequest, ReleaseReservationItem, ReleaseReservationRequest, Reservation, ReservationItem, ReservationItemInput, ReservationListQuery, ReservationPage, ReverseStockMovementRequest, StockBelowMinimumEventData, StockChangedEventData, StockItem, StockLevel, StockListQuery, StockMovement, StockMovementLot, StockMovementPage, StockMovementQuery, StockMovementSourceRef, StockOperation, StockPage, StockResult, StockValue, TransferStockRequest, UpdateArticleRequest, } from './typen.js';
21
+ export { INVENTORY_ENDPOINTS, INVENTORY_ERROR_CODES, INVENTORY_REQUEST_ERROR_CODES, INVENTORY_WEBHOOK_EVENTS, INVENTORY_WEBHOOK_ENVELOPE_FIELDS, INVENTORY_WEBHOOK_LIMIT, INVENTORY_LIST_LIMIT_MAX, LOCATION_TYPES, STOCK_MOVEMENT_TYPES, STOCK_MOVEMENT_SOURCES, STOCK_CONDITIONS, STOCK_CHANGE_CAUSES, WEBHOOK_DELIVERY_STATUSES, INVENTORY_WARNING_CODES, STOCK_KINDS, STOCK_LOSS_REASONS, WITHDRAWAL_TYPES, LANDED_COST_TYPES, LANDED_COST_ALLOCATIONS, RESERVATION_STATUSES, INVENTORY_IDEMPOTENCY_KEY_MAX, RESERVATION_MINUTES_MIN, RESERVATION_MINUTES_MAX, type InventoryEndpoint, type InventoryErrorCode, type InventoryRequestErrorCode, type InventoryWebhookEventType, type LocationType, type StockMovementType, type StockMovementSource, type StockCondition, type StockChangeCause, type WebhookDeliveryStatus, type InventoryWarningCode, type StockKind, type StockLossReason, type WithdrawalType, type LandedCostType, type LandedCostAllocation, type ReservationStatus, } from './vertrag.js';
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ /**
3
+ * `@kreiseck/kasseneck-api/inventory` – die Lager-API: Artikel, Standorte,
4
+ * Bestand und Lagerprotokoll lesen, Konto-Webhooks verwalten und eingehende
5
+ * Zustellungen pruefen (Backend Stufe 5a); Artikel anlegen und aendern,
6
+ * Bestand buchen und Ware reservieren (Stufe 5b, seit 1.5.0).
7
+ *
8
+ * Ein eigener Unterpfad wie `invoice`: der `api_key` eines Kontos gehoert auf
9
+ * einen **Server** (etwa das Backend eines Online-Shops) und soll nicht
10
+ * versehentlich in ein Browser-Buendel wandern.
11
+ *
12
+ * Mengen in Tausendstel der Basiseinheit, Geld in Cent, Einkaufspreise in
13
+ * Mikro-Euro; alles Ganzzahlen.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.INVENTORY_REQUEST_ERROR_CODES = exports.INVENTORY_ERROR_CODES = exports.INVENTORY_ENDPOINTS = exports.WEBHOOK_TOLERANCE_SEC = exports.WEBHOOK_DELIVERY_HEADER = exports.WEBHOOK_EVENT_HEADER = exports.WEBHOOK_SIGNATURE_HEADER = exports.parseInventoryWebhookEvent = exports.verifyInventoryWebhookSignature = exports.updateArticle = exports.transferStock = exports.reverseStockMovement = exports.releaseReservation = exports.recordStockLoss = exports.receiveGoods = exports.previewGoodsReceipt = exports.listReservations = exports.iterateReservations = exports.getReservation = exports.extendReservation = exports.deactivateArticle = exports.createReservation = exports.createArticle = exports.changeStockCondition = exports.updateWebhook = exports.sendWebhookTest = exports.rotateWebhookSecret = exports.lookupArticleByCode = exports.listWebhooks = exports.listWebhookDeliveries = exports.listStockMovements = exports.listStock = exports.listLocations = exports.listArticles = exports.iterateStockMovements = exports.iterateStock = exports.iterateArticles = exports.getStock = exports.getArticle = exports.deleteWebhook = exports.createWebhook = exports.isInventoryWarningCode = exports.inventoryShortfalls = exports.inventoryRetryAfterSec = exports.inventoryFieldErrors = exports.inventoryErrorCode = exports.isInventoryErrorCode = exports.isInventoryError = exports.inventoryKeyAuth = exports.createInventoryClient = void 0;
17
+ exports.RESERVATION_MINUTES_MAX = exports.RESERVATION_MINUTES_MIN = exports.INVENTORY_IDEMPOTENCY_KEY_MAX = exports.RESERVATION_STATUSES = exports.LANDED_COST_ALLOCATIONS = exports.LANDED_COST_TYPES = exports.WITHDRAWAL_TYPES = exports.STOCK_LOSS_REASONS = exports.STOCK_KINDS = exports.INVENTORY_WARNING_CODES = exports.WEBHOOK_DELIVERY_STATUSES = exports.STOCK_CHANGE_CAUSES = exports.STOCK_CONDITIONS = exports.STOCK_MOVEMENT_SOURCES = exports.STOCK_MOVEMENT_TYPES = exports.LOCATION_TYPES = exports.INVENTORY_LIST_LIMIT_MAX = exports.INVENTORY_WEBHOOK_LIMIT = exports.INVENTORY_WEBHOOK_ENVELOPE_FIELDS = exports.INVENTORY_WEBHOOK_EVENTS = void 0;
18
+ var api_js_1 = require("./api.js");
19
+ Object.defineProperty(exports, "createInventoryClient", { enumerable: true, get: function () { return api_js_1.createInventoryClient; } });
20
+ var auth_js_1 = require("./auth.js");
21
+ Object.defineProperty(exports, "inventoryKeyAuth", { enumerable: true, get: function () { return auth_js_1.inventoryKeyAuth; } });
22
+ var fehler_js_1 = require("./fehler.js");
23
+ Object.defineProperty(exports, "isInventoryError", { enumerable: true, get: function () { return fehler_js_1.isInventoryError; } });
24
+ Object.defineProperty(exports, "isInventoryErrorCode", { enumerable: true, get: function () { return fehler_js_1.isInventoryErrorCode; } });
25
+ Object.defineProperty(exports, "inventoryErrorCode", { enumerable: true, get: function () { return fehler_js_1.inventoryErrorCode; } });
26
+ Object.defineProperty(exports, "inventoryFieldErrors", { enumerable: true, get: function () { return fehler_js_1.inventoryFieldErrors; } });
27
+ Object.defineProperty(exports, "inventoryRetryAfterSec", { enumerable: true, get: function () { return fehler_js_1.inventoryRetryAfterSec; } });
28
+ Object.defineProperty(exports, "inventoryShortfalls", { enumerable: true, get: function () { return fehler_js_1.inventoryShortfalls; } });
29
+ Object.defineProperty(exports, "isInventoryWarningCode", { enumerable: true, get: function () { return fehler_js_1.isInventoryWarningCode; } });
30
+ var endpunkte_js_1 = require("./endpunkte.js");
31
+ Object.defineProperty(exports, "createWebhook", { enumerable: true, get: function () { return endpunkte_js_1.createWebhook; } });
32
+ Object.defineProperty(exports, "deleteWebhook", { enumerable: true, get: function () { return endpunkte_js_1.deleteWebhook; } });
33
+ Object.defineProperty(exports, "getArticle", { enumerable: true, get: function () { return endpunkte_js_1.getArticle; } });
34
+ Object.defineProperty(exports, "getStock", { enumerable: true, get: function () { return endpunkte_js_1.getStock; } });
35
+ Object.defineProperty(exports, "iterateArticles", { enumerable: true, get: function () { return endpunkte_js_1.iterateArticles; } });
36
+ Object.defineProperty(exports, "iterateStock", { enumerable: true, get: function () { return endpunkte_js_1.iterateStock; } });
37
+ Object.defineProperty(exports, "iterateStockMovements", { enumerable: true, get: function () { return endpunkte_js_1.iterateStockMovements; } });
38
+ Object.defineProperty(exports, "listArticles", { enumerable: true, get: function () { return endpunkte_js_1.listArticles; } });
39
+ Object.defineProperty(exports, "listLocations", { enumerable: true, get: function () { return endpunkte_js_1.listLocations; } });
40
+ Object.defineProperty(exports, "listStock", { enumerable: true, get: function () { return endpunkte_js_1.listStock; } });
41
+ Object.defineProperty(exports, "listStockMovements", { enumerable: true, get: function () { return endpunkte_js_1.listStockMovements; } });
42
+ Object.defineProperty(exports, "listWebhookDeliveries", { enumerable: true, get: function () { return endpunkte_js_1.listWebhookDeliveries; } });
43
+ Object.defineProperty(exports, "listWebhooks", { enumerable: true, get: function () { return endpunkte_js_1.listWebhooks; } });
44
+ Object.defineProperty(exports, "lookupArticleByCode", { enumerable: true, get: function () { return endpunkte_js_1.lookupArticleByCode; } });
45
+ Object.defineProperty(exports, "rotateWebhookSecret", { enumerable: true, get: function () { return endpunkte_js_1.rotateWebhookSecret; } });
46
+ Object.defineProperty(exports, "sendWebhookTest", { enumerable: true, get: function () { return endpunkte_js_1.sendWebhookTest; } });
47
+ Object.defineProperty(exports, "updateWebhook", { enumerable: true, get: function () { return endpunkte_js_1.updateWebhook; } });
48
+ var schreiben_js_1 = require("./schreiben.js");
49
+ Object.defineProperty(exports, "changeStockCondition", { enumerable: true, get: function () { return schreiben_js_1.changeStockCondition; } });
50
+ Object.defineProperty(exports, "createArticle", { enumerable: true, get: function () { return schreiben_js_1.createArticle; } });
51
+ Object.defineProperty(exports, "createReservation", { enumerable: true, get: function () { return schreiben_js_1.createReservation; } });
52
+ Object.defineProperty(exports, "deactivateArticle", { enumerable: true, get: function () { return schreiben_js_1.deactivateArticle; } });
53
+ Object.defineProperty(exports, "extendReservation", { enumerable: true, get: function () { return schreiben_js_1.extendReservation; } });
54
+ Object.defineProperty(exports, "getReservation", { enumerable: true, get: function () { return schreiben_js_1.getReservation; } });
55
+ Object.defineProperty(exports, "iterateReservations", { enumerable: true, get: function () { return schreiben_js_1.iterateReservations; } });
56
+ Object.defineProperty(exports, "listReservations", { enumerable: true, get: function () { return schreiben_js_1.listReservations; } });
57
+ Object.defineProperty(exports, "previewGoodsReceipt", { enumerable: true, get: function () { return schreiben_js_1.previewGoodsReceipt; } });
58
+ Object.defineProperty(exports, "receiveGoods", { enumerable: true, get: function () { return schreiben_js_1.receiveGoods; } });
59
+ Object.defineProperty(exports, "recordStockLoss", { enumerable: true, get: function () { return schreiben_js_1.recordStockLoss; } });
60
+ Object.defineProperty(exports, "releaseReservation", { enumerable: true, get: function () { return schreiben_js_1.releaseReservation; } });
61
+ Object.defineProperty(exports, "reverseStockMovement", { enumerable: true, get: function () { return schreiben_js_1.reverseStockMovement; } });
62
+ Object.defineProperty(exports, "transferStock", { enumerable: true, get: function () { return schreiben_js_1.transferStock; } });
63
+ Object.defineProperty(exports, "updateArticle", { enumerable: true, get: function () { return schreiben_js_1.updateArticle; } });
64
+ var webhook_js_1 = require("./webhook.js");
65
+ Object.defineProperty(exports, "verifyInventoryWebhookSignature", { enumerable: true, get: function () { return webhook_js_1.verifyInventoryWebhookSignature; } });
66
+ Object.defineProperty(exports, "parseInventoryWebhookEvent", { enumerable: true, get: function () { return webhook_js_1.parseInventoryWebhookEvent; } });
67
+ Object.defineProperty(exports, "WEBHOOK_SIGNATURE_HEADER", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_SIGNATURE_HEADER; } });
68
+ Object.defineProperty(exports, "WEBHOOK_EVENT_HEADER", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_EVENT_HEADER; } });
69
+ Object.defineProperty(exports, "WEBHOOK_DELIVERY_HEADER", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_DELIVERY_HEADER; } });
70
+ Object.defineProperty(exports, "WEBHOOK_TOLERANCE_SEC", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_TOLERANCE_SEC; } });
71
+ var vertrag_js_1 = require("./vertrag.js");
72
+ Object.defineProperty(exports, "INVENTORY_ENDPOINTS", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_ENDPOINTS; } });
73
+ Object.defineProperty(exports, "INVENTORY_ERROR_CODES", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_ERROR_CODES; } });
74
+ Object.defineProperty(exports, "INVENTORY_REQUEST_ERROR_CODES", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_REQUEST_ERROR_CODES; } });
75
+ Object.defineProperty(exports, "INVENTORY_WEBHOOK_EVENTS", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_WEBHOOK_EVENTS; } });
76
+ Object.defineProperty(exports, "INVENTORY_WEBHOOK_ENVELOPE_FIELDS", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_WEBHOOK_ENVELOPE_FIELDS; } });
77
+ Object.defineProperty(exports, "INVENTORY_WEBHOOK_LIMIT", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_WEBHOOK_LIMIT; } });
78
+ Object.defineProperty(exports, "INVENTORY_LIST_LIMIT_MAX", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_LIST_LIMIT_MAX; } });
79
+ Object.defineProperty(exports, "LOCATION_TYPES", { enumerable: true, get: function () { return vertrag_js_1.LOCATION_TYPES; } });
80
+ Object.defineProperty(exports, "STOCK_MOVEMENT_TYPES", { enumerable: true, get: function () { return vertrag_js_1.STOCK_MOVEMENT_TYPES; } });
81
+ Object.defineProperty(exports, "STOCK_MOVEMENT_SOURCES", { enumerable: true, get: function () { return vertrag_js_1.STOCK_MOVEMENT_SOURCES; } });
82
+ Object.defineProperty(exports, "STOCK_CONDITIONS", { enumerable: true, get: function () { return vertrag_js_1.STOCK_CONDITIONS; } });
83
+ Object.defineProperty(exports, "STOCK_CHANGE_CAUSES", { enumerable: true, get: function () { return vertrag_js_1.STOCK_CHANGE_CAUSES; } });
84
+ Object.defineProperty(exports, "WEBHOOK_DELIVERY_STATUSES", { enumerable: true, get: function () { return vertrag_js_1.WEBHOOK_DELIVERY_STATUSES; } });
85
+ Object.defineProperty(exports, "INVENTORY_WARNING_CODES", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_WARNING_CODES; } });
86
+ Object.defineProperty(exports, "STOCK_KINDS", { enumerable: true, get: function () { return vertrag_js_1.STOCK_KINDS; } });
87
+ Object.defineProperty(exports, "STOCK_LOSS_REASONS", { enumerable: true, get: function () { return vertrag_js_1.STOCK_LOSS_REASONS; } });
88
+ Object.defineProperty(exports, "WITHDRAWAL_TYPES", { enumerable: true, get: function () { return vertrag_js_1.WITHDRAWAL_TYPES; } });
89
+ Object.defineProperty(exports, "LANDED_COST_TYPES", { enumerable: true, get: function () { return vertrag_js_1.LANDED_COST_TYPES; } });
90
+ Object.defineProperty(exports, "LANDED_COST_ALLOCATIONS", { enumerable: true, get: function () { return vertrag_js_1.LANDED_COST_ALLOCATIONS; } });
91
+ Object.defineProperty(exports, "RESERVATION_STATUSES", { enumerable: true, get: function () { return vertrag_js_1.RESERVATION_STATUSES; } });
92
+ Object.defineProperty(exports, "INVENTORY_IDEMPOTENCY_KEY_MAX", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_IDEMPOTENCY_KEY_MAX; } });
93
+ Object.defineProperty(exports, "RESERVATION_MINUTES_MIN", { enumerable: true, get: function () { return vertrag_js_1.RESERVATION_MINUTES_MIN; } });
94
+ Object.defineProperty(exports, "RESERVATION_MINUTES_MAX", { enumerable: true, get: function () { return vertrag_js_1.RESERVATION_MINUTES_MAX; } });
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Leser der Lager-Antworten: aus dem Draht `/v3` werden die Modelle in
3
+ * `typen.ts`. Paketintern, nicht Teil der Oberflaeche.
4
+ *
5
+ * Regel wie beim Lager an der Kasse (`pos/lager.ts`): eine Menge, ein Betrag
6
+ * oder eine Folgenummer ist eine Ganzzahl, sonst endet der Aufruf mit
7
+ * `KasseneckValidationError` (`scope: 'response'`). Ein Ersatzwert wie `0`
8
+ * waere eine falsche Aussage („kein Bestand“ statt „Antwort kaputt“). Texte
9
+ * sind nachsichtiger: ein fehlender oder fremder Wert wird `null`.
10
+ *
11
+ * Optionale Felder (Einkaufswerte, `externalIds` …) erscheinen im Modell nur,
12
+ * wenn der Server sie sendet: „fehlt“ heisst dort „kein Recht“, nicht „leer“.
13
+ */
14
+ import { KasseneckValidationError } from '../client/errors.js';
15
+ import type { Article, GoodsReceiptPreviewLine, InventoryShortfall, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookTestDelivery, Location, Reservation, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockMovement, StockOperation, StockValue } from './typen.js';
16
+ type Roh = Record<string, unknown>;
17
+ /** Ein Leser bekommt den Vorgang (fuer die Meldung) und den Pfad im Rumpf. */
18
+ export interface Ort {
19
+ name: string;
20
+ pfad: string;
21
+ }
22
+ export declare function antwortfehler(name: string, grund: string): KasseneckValidationError;
23
+ export declare function objekt(w: unknown): Roh | null;
24
+ export declare function artikel(ort: Ort, w: unknown): Article;
25
+ export declare function standort(ort: Ort, w: unknown): Location;
26
+ export declare function bestand(ort: Ort, w: unknown): StockLevel;
27
+ export declare function wert(ort: Ort, w: unknown): StockValue;
28
+ export declare function bewegung(ort: Ort, w: unknown): StockMovement;
29
+ export declare function webhook(ort: Ort, w: unknown): InventoryWebhook;
30
+ export declare function zustellung(ort: Ort, w: unknown): InventoryWebhookDelivery;
31
+ export declare function probeZustellung(ort: Ort, w: unknown, webhookId: string): InventoryWebhookTestDelivery;
32
+ export declare function bestandGeaendert(ort: Ort, w: unknown): StockChangedEventData;
33
+ export declare function unterMindestbestand(ort: Ort, w: unknown): StockBelowMinimumEventData;
34
+ /** Antwort einer Buchung; ohne `operationId` ist nicht belegt, dass gebucht wurde. */
35
+ export declare function vorgang(name: string, daten: unknown): StockOperation;
36
+ /** Eine Zeile der Wareneingangs-Vorschau; Werte nur, wenn der Server sie sendet (Recht `costs`). */
37
+ export declare function vorschauZeile(ort: Ort, w: unknown): GoodsReceiptPreviewLine;
38
+ export declare function reservierung(ort: Ort, w: unknown): Reservation;
39
+ /** Die fehlenden Positionen aus `insufficient_available` (`data.details[]`); ein kaputter Eintrag faellt weg. */
40
+ export declare function fehlmengen(roh: unknown): InventoryShortfall[];
41
+ /** Eine zugesagte Liste `data.<feld>`, Eintrag fuer Eintrag gelesen. */
42
+ export declare function liste<T>(name: string, daten: unknown, feld: string, lesen: (ort: Ort, e: unknown) => T): T[];
43
+ /** Der Cursor der naechsten Seite; `null` am Ende. Etwas anderes als Text oder `null` ist kaputt. */
44
+ export declare function naechsterCursor(name: string, daten: unknown): string | null;
45
+ export {};
@@ -0,0 +1,424 @@
1
+ "use strict";
2
+ /**
3
+ * Leser der Lager-Antworten: aus dem Draht `/v3` werden die Modelle in
4
+ * `typen.ts`. Paketintern, nicht Teil der Oberflaeche.
5
+ *
6
+ * Regel wie beim Lager an der Kasse (`pos/lager.ts`): eine Menge, ein Betrag
7
+ * oder eine Folgenummer ist eine Ganzzahl, sonst endet der Aufruf mit
8
+ * `KasseneckValidationError` (`scope: 'response'`). Ein Ersatzwert wie `0`
9
+ * waere eine falsche Aussage („kein Bestand“ statt „Antwort kaputt“). Texte
10
+ * sind nachsichtiger: ein fehlender oder fremder Wert wird `null`.
11
+ *
12
+ * Optionale Felder (Einkaufswerte, `externalIds` …) erscheinen im Modell nur,
13
+ * wenn der Server sie sendet: „fehlt“ heisst dort „kein Recht“, nicht „leer“.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.antwortfehler = antwortfehler;
17
+ exports.objekt = objekt;
18
+ exports.artikel = artikel;
19
+ exports.standort = standort;
20
+ exports.bestand = bestand;
21
+ exports.wert = wert;
22
+ exports.bewegung = bewegung;
23
+ exports.webhook = webhook;
24
+ exports.zustellung = zustellung;
25
+ exports.probeZustellung = probeZustellung;
26
+ exports.bestandGeaendert = bestandGeaendert;
27
+ exports.unterMindestbestand = unterMindestbestand;
28
+ exports.vorgang = vorgang;
29
+ exports.vorschauZeile = vorschauZeile;
30
+ exports.reservierung = reservierung;
31
+ exports.fehlmengen = fehlmengen;
32
+ exports.liste = liste;
33
+ exports.naechsterCursor = naechsterCursor;
34
+ const errors_js_1 = require("../client/errors.js");
35
+ const vertrag_js_1 = require("./vertrag.js");
36
+ const hat = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
37
+ function antwortfehler(name, grund) {
38
+ return new errors_js_1.KasseneckValidationError(name, grund, 'response');
39
+ }
40
+ function objekt(w) {
41
+ return w !== null && typeof w === 'object' && !Array.isArray(w) ? w : null;
42
+ }
43
+ /** Ein Eintrag, der ein Objekt sein muss. */
44
+ function eintrag(ort, w) {
45
+ const o = objekt(w);
46
+ if (!o)
47
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad} ist kein Objekt)`);
48
+ return o;
49
+ }
50
+ const text = (w) => (typeof w === 'string' ? w : null);
51
+ /** Eine Kennung, die da sein muss; ohne sie ist der Eintrag nicht zuzuordnen. */
52
+ function kennung(ort, feld, w) {
53
+ if (typeof w !== 'string' || w === '') {
54
+ throw antwortfehler(ort.name, `Antwort enthaelt keine Kennung (data.${ort.pfad}.${feld} fehlt)`);
55
+ }
56
+ return w;
57
+ }
58
+ /** Eine Ganzzahl, die da sein muss. */
59
+ function ganzzahl(ort, feld, w) {
60
+ if (typeof w !== 'number' || !Number.isSafeInteger(w)) {
61
+ throw antwortfehler(ort.name, `Antwort enthaelt keine ganze Zahl (data.${ort.pfad}.${feld})`);
62
+ }
63
+ return w;
64
+ }
65
+ /** Eine Ganzzahl oder `null`; fehlt der Wert, gilt `null`. */
66
+ function ganzzahlOderNull(ort, feld, w) {
67
+ if (w === undefined || w === null)
68
+ return null;
69
+ return ganzzahl(ort, feld, w);
70
+ }
71
+ /** Eine Textabbildung (`externalIds`, `metadata`, `variantAttributes`): nur Texteintraege. */
72
+ function textAbbildung(w) {
73
+ const o = objekt(w);
74
+ if (!o)
75
+ return undefined;
76
+ const raus = {};
77
+ for (const [k, v] of Object.entries(o))
78
+ if (typeof v === 'string')
79
+ raus[k] = v;
80
+ return raus;
81
+ }
82
+ /**
83
+ * Mengen je Standort (`minStockByLocation`): jeder Wert eine Ganzzahl. Fehlt
84
+ * das Feld (Server vor Stufe 5b), gilt „keiner“ (`{}`).
85
+ */
86
+ function mengenJeStandort(ort, feld, w) {
87
+ if (w === undefined || w === null)
88
+ return {};
89
+ const o = objekt(w);
90
+ if (!o)
91
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.${feld} ist kein Objekt)`);
92
+ const raus = {};
93
+ for (const [k, v] of Object.entries(o))
94
+ raus[k] = ganzzahl(ort, `${feld}.${k}`, v);
95
+ return raus;
96
+ }
97
+ /** Eine Liste von Kennungen (`movementIds`, `lotIds`); fehlt sie, ist sie leer. */
98
+ function kennungsliste(ort, feld, w) {
99
+ if (w === undefined || w === null)
100
+ return [];
101
+ if (!Array.isArray(w) || !w.every((x) => typeof x === 'string')) {
102
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}${ort.pfad ? '.' : ''}${feld} ist keine Liste von Kennungen)`);
103
+ }
104
+ return [...w];
105
+ }
106
+ // ---- Artikel ------------------------------------------------------------------
107
+ function artikel(ort, w) {
108
+ const a = eintrag(ort, w);
109
+ let standorte = [];
110
+ if (a.stockLocationIds !== undefined && a.stockLocationIds !== null) {
111
+ if (!Array.isArray(a.stockLocationIds) || !a.stockLocationIds.every((s) => typeof s === 'string')) {
112
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.stockLocationIds ist keine Liste von Kennungen)`);
113
+ }
114
+ standorte = [...a.stockLocationIds];
115
+ }
116
+ const vatRate = a.vatRate;
117
+ if (vatRate !== undefined && vatRate !== null && (typeof vatRate !== 'number' || !Number.isFinite(vatRate))) {
118
+ throw antwortfehler(ort.name, `Antwort enthaelt keinen USt-Satz (data.${ort.pfad}.vatRate)`);
119
+ }
120
+ const raus = {
121
+ id: kennung(ort, 'id', a.id),
122
+ name: text(a.name),
123
+ description: text(a.description),
124
+ unitPriceCents: ganzzahlOderNull(ort, 'unitPriceCents', a.unitPriceCents),
125
+ vatRate: typeof vatRate === 'number' ? vatRate : null,
126
+ unit: text(a.unit),
127
+ number: text(a.number),
128
+ ean: text(a.ean),
129
+ internalCode: text(a.internalCode),
130
+ groupId: text(a.groupId),
131
+ revenueGroupId: text(a.revenueGroupId),
132
+ stockTracked: a.stockTracked === true,
133
+ stockKind: textOderNull(a.stockKind),
134
+ stockLocationIds: standorte,
135
+ minStock: ganzzahlOderNull(ort, 'minStock', a.minStock),
136
+ minStockByLocation: mengenJeStandort(ort, 'minStockByLocation', a.minStockByLocation),
137
+ active: a.active !== false,
138
+ createdAt: text(a.createdAt),
139
+ updatedAt: text(a.updatedAt),
140
+ };
141
+ for (const feld of ['externalIds', 'metadata', 'variantAttributes']) {
142
+ const abb = textAbbildung(a[feld]);
143
+ if (abb)
144
+ raus[feld] = abb;
145
+ }
146
+ if (typeof a.variantGroupId === 'string')
147
+ raus.variantGroupId = a.variantGroupId;
148
+ // Nur mit dem Recht `costs`; ohne fehlt das Feld ganz.
149
+ if (hat(a, 'purchasePriceMicros'))
150
+ raus.purchasePriceMicros = ganzzahlOderNull(ort, 'purchasePriceMicros', a.purchasePriceMicros);
151
+ return raus;
152
+ }
153
+ // ---- Standorte ------------------------------------------------------------------
154
+ const TYPEN = new Set(vertrag_js_1.LOCATION_TYPES);
155
+ const textOderNull = (w) => (typeof w === 'string' && w !== '' ? w : null);
156
+ function standort(ort, w) {
157
+ const s = eintrag(ort, w);
158
+ const a = objekt(s.address);
159
+ const teile = a ? { street: textOderNull(a.street), zip: textOderNull(a.zip), city: textOderNull(a.city), country: textOderNull(a.country) } : null;
160
+ return {
161
+ id: kennung(ort, 'id', s.id),
162
+ name: typeof s.name === 'string' ? s.name : '',
163
+ type: typeof s.type === 'string' && TYPEN.has(s.type) ? s.type : null,
164
+ // Eine Adresse ohne einen einzigen Teil ist keine Adresse.
165
+ address: teile && Object.values(teile).some((t) => t !== null) ? teile : null,
166
+ licensePlate: textOderNull(s.licensePlate),
167
+ active: s.active !== false,
168
+ virtual: s.virtual === true,
169
+ };
170
+ }
171
+ // ---- Bestand ------------------------------------------------------------------
172
+ function bestand(ort, w) {
173
+ const b = eintrag(ort, w);
174
+ return {
175
+ articleId: kennung(ort, 'articleId', b.articleId),
176
+ locationId: kennung(ort, 'locationId', b.locationId),
177
+ onHand: ganzzahl(ort, 'onHand', b.onHand),
178
+ reserved: ganzzahl(ort, 'reserved', b.reserved),
179
+ available: ganzzahl(ort, 'available', b.available),
180
+ defective: ganzzahl(ort, 'defective', b.defective),
181
+ sequence: ganzzahl(ort, 'sequence', b.sequence),
182
+ updatedAt: text(b.updatedAt),
183
+ };
184
+ }
185
+ function wert(ort, w) {
186
+ const v = eintrag(ort, w);
187
+ return {
188
+ articleId: kennung(ort, 'articleId', v.articleId),
189
+ stockValueCents: ganzzahl(ort, 'stockValueCents', v.stockValueCents),
190
+ averageCostMicros: ganzzahlOderNull(ort, 'averageCostMicros', v.averageCostMicros),
191
+ };
192
+ }
193
+ // ---- Bewegungen ------------------------------------------------------------------
194
+ function los(ort, w) {
195
+ const l = eintrag(ort, w);
196
+ const raus = {
197
+ lotId: text(l.lotId),
198
+ quantity: ganzzahl(ort, 'quantity', l.quantity),
199
+ expiresOn: text(l.expiresOn),
200
+ batch: text(l.batch),
201
+ serialNumber: text(l.serialNumber),
202
+ receivedAt: text(l.receivedAt),
203
+ };
204
+ if (hat(l, 'valueCents'))
205
+ raus.valueCents = ganzzahlOderNull(ort, 'valueCents', l.valueCents);
206
+ return raus;
207
+ }
208
+ function bewegung(ort, w) {
209
+ const b = eintrag(ort, w);
210
+ const nachher = objekt(b.stockAfter);
211
+ const quelle = objekt(b.source);
212
+ const lose = b.lots === undefined || b.lots === null ? [] : b.lots;
213
+ if (!Array.isArray(lose))
214
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.lots ist keine Liste)`);
215
+ const nachherOrt = { name: ort.name, pfad: `${ort.pfad}.stockAfter` };
216
+ const raus = {
217
+ id: kennung(ort, 'id', b.id),
218
+ type: text(b.type),
219
+ articleId: text(b.articleId),
220
+ locationId: text(b.locationId),
221
+ condition: text(b.condition),
222
+ quantityDelta: ganzzahl(ort, 'quantityDelta', b.quantityDelta),
223
+ // Server vor Stufe 5b senden das Feld nicht: dort aenderte keine Bewegung `reserved`.
224
+ reservedDelta: b.reservedDelta === undefined ? 0 : ganzzahl(ort, 'reservedDelta', b.reservedDelta),
225
+ stockAfter: nachher
226
+ ? {
227
+ sellable: ganzzahl(nachherOrt, 'sellable', nachher.sellable),
228
+ defective: ganzzahl(nachherOrt, 'defective', nachher.defective),
229
+ reserved: ganzzahlOderNull(nachherOrt, 'reserved', nachher.reserved),
230
+ }
231
+ : null,
232
+ operationId: text(b.operationId),
233
+ source: quelle
234
+ ? {
235
+ type: text(quelle.type),
236
+ id: text(quelle.id),
237
+ register: text(quelle.register),
238
+ position: typeof quelle.position === 'number' && Number.isSafeInteger(quelle.position) ? quelle.position : null,
239
+ }
240
+ : null,
241
+ viennaDay: text(b.viennaDay),
242
+ time: text(b.time),
243
+ lots: lose.map((l, i) => los({ name: ort.name, pfad: `${ort.pfad}.lots[${i}]` }, l)),
244
+ };
245
+ if (hat(b, 'valueDeltaCents'))
246
+ raus.valueDeltaCents = ganzzahlOderNull(ort, 'valueDeltaCents', b.valueDeltaCents);
247
+ if (hat(b, 'consumedValueCents'))
248
+ raus.consumedValueCents = ganzzahlOderNull(ort, 'consumedValueCents', b.consumedValueCents);
249
+ return raus;
250
+ }
251
+ // ---- Webhooks ------------------------------------------------------------------
252
+ const zahlOderNull = (w) => (typeof w === 'number' && Number.isFinite(w) ? w : null);
253
+ function webhook(ort, w) {
254
+ const h = eintrag(ort, w);
255
+ const z = objekt(h.lastDelivery);
256
+ return {
257
+ id: kennung(ort, 'id', h.id),
258
+ url: typeof h.url === 'string' ? h.url : '',
259
+ events: Array.isArray(h.events) ? h.events.filter((e) => typeof e === 'string') : [],
260
+ active: h.active !== false,
261
+ description: text(h.description),
262
+ createdAt: text(h.createdAt),
263
+ lastDelivery: z ? { at: text(z.at), status: text(z.status), statusCode: zahlOderNull(z.statusCode) } : null,
264
+ consecutiveFailures: typeof h.consecutiveFailures === 'number' && Number.isSafeInteger(h.consecutiveFailures) ? h.consecutiveFailures : 0,
265
+ };
266
+ }
267
+ function zustellung(ort, w) {
268
+ const z = eintrag(ort, w);
269
+ return {
270
+ deliveryId: kennung(ort, 'deliveryId', z.deliveryId),
271
+ webhookId: text(z.webhookId),
272
+ event: text(z.event),
273
+ eventId: text(z.eventId),
274
+ status: text(z.status),
275
+ attempts: typeof z.attempts === 'number' && Number.isSafeInteger(z.attempts) ? z.attempts : 0,
276
+ statusCode: zahlOderNull(z.statusCode),
277
+ response: text(z.response),
278
+ error: text(z.error),
279
+ createdAt: text(z.createdAt),
280
+ lastAttemptAt: text(z.lastAttemptAt),
281
+ nextAttemptAt: text(z.nextAttemptAt),
282
+ test: z.test === true,
283
+ };
284
+ }
285
+ function probeZustellung(ort, w, webhookId) {
286
+ const z = eintrag(ort, w);
287
+ return {
288
+ deliveryId: kennung(ort, 'deliveryId', z.deliveryId),
289
+ webhookId: typeof z.webhookId === 'string' && z.webhookId ? z.webhookId : webhookId,
290
+ status: text(z.status),
291
+ statusCode: zahlOderNull(z.statusCode),
292
+ };
293
+ }
294
+ // ---- Ereignisse ------------------------------------------------------------------
295
+ function bestandGeaendert(ort, w) {
296
+ const d = eintrag(ort, w);
297
+ const ursache = d.cause;
298
+ if (typeof ursache !== 'string' || ursache === '')
299
+ throw antwortfehler(ort.name, `Ereignis ohne Ursache (${ort.pfad}.cause)`);
300
+ return { ...bestand(ort, d), cause: ursache, movementId: textOderNull(d.movementId) };
301
+ }
302
+ function unterMindestbestand(ort, w) {
303
+ const d = eintrag(ort, w);
304
+ return {
305
+ articleId: kennung(ort, 'articleId', d.articleId),
306
+ locationId: kennung(ort, 'locationId', d.locationId),
307
+ available: ganzzahl(ort, 'available', d.available),
308
+ minStock: ganzzahl(ort, 'minStock', d.minStock),
309
+ };
310
+ }
311
+ // ---- Schreiben (Stufe 5b) ------------------------------------------------------------
312
+ function warnung(ort, w) {
313
+ const h = eintrag(ort, w);
314
+ if (typeof h.code !== 'string' || h.code === '')
315
+ throw antwortfehler(ort.name, `Hinweis ohne Code (data.${ort.pfad}.code)`);
316
+ return {
317
+ code: h.code,
318
+ articleId: textOderNull(h.articleId),
319
+ locationId: textOderNull(h.locationId),
320
+ message: typeof h.message === 'string' ? h.message : '',
321
+ };
322
+ }
323
+ /** Antwort einer Buchung; ohne `operationId` ist nicht belegt, dass gebucht wurde. */
324
+ function vorgang(name, daten) {
325
+ const d = objekt(daten);
326
+ if (!d)
327
+ throw antwortfehler(name, 'Antwort ist unbrauchbar (data ist kein Objekt)');
328
+ const ort = { name, pfad: '' };
329
+ if (typeof d.operationId !== 'string' || d.operationId === '') {
330
+ throw antwortfehler(name, 'Antwort enthaelt keine Kennung (data.operationId fehlt)');
331
+ }
332
+ const hinweise = d.warnings === undefined || d.warnings === null ? [] : d.warnings;
333
+ if (!Array.isArray(hinweise))
334
+ throw antwortfehler(name, 'Antwort ist unbrauchbar (data.warnings ist keine Liste)');
335
+ return {
336
+ operationId: d.operationId,
337
+ movementIds: kennungsliste(ort, 'movementIds', d.movementIds),
338
+ lotIds: kennungsliste(ort, 'lotIds', d.lotIds),
339
+ warnings: hinweise.map((h, i) => warnung({ name, pfad: `warnings[${i}]` }, h)),
340
+ };
341
+ }
342
+ /** Eine Zeile der Wareneingangs-Vorschau; Werte nur, wenn der Server sie sendet (Recht `costs`). */
343
+ function vorschauZeile(ort, w) {
344
+ const z = eintrag(ort, w);
345
+ const serien = z.serialNumbers === undefined || z.serialNumbers === null ? [] : z.serialNumbers;
346
+ if (!Array.isArray(serien) || !serien.every((x) => typeof x === 'string')) {
347
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.serialNumbers ist keine Liste)`);
348
+ }
349
+ const raus = {
350
+ articleId: kennung(ort, 'articleId', z.articleId),
351
+ quantity: ganzzahl(ort, 'quantity', z.quantity),
352
+ expiresOn: textOderNull(z.expiresOn),
353
+ batch: textOderNull(z.batch),
354
+ serialNumbers: [...serien],
355
+ priceFromArticle: z.priceFromArticle === true,
356
+ };
357
+ for (const feld of ['baseCents', 'landedCostCents', 'valueCents', 'unitCostMicros']) {
358
+ if (hat(z, feld))
359
+ raus[feld] = ganzzahlOderNull(ort, feld, z[feld]);
360
+ }
361
+ return raus;
362
+ }
363
+ function reservierungsPosition(ort, w) {
364
+ const p = eintrag(ort, w);
365
+ return {
366
+ articleId: kennung(ort, 'articleId', p.articleId),
367
+ locationId: kennung(ort, 'locationId', p.locationId),
368
+ quantity: ganzzahl(ort, 'quantity', p.quantity),
369
+ redeemed: ganzzahl(ort, 'redeemed', p.redeemed),
370
+ released: ganzzahl(ort, 'released', p.released),
371
+ };
372
+ }
373
+ function reservierung(ort, w) {
374
+ const r = eintrag(ort, w);
375
+ if (!Array.isArray(r.items))
376
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.items ist keine Liste)`);
377
+ return {
378
+ id: kennung(ort, 'id', r.id),
379
+ status: textOderNull(r.status),
380
+ reference: text(r.reference),
381
+ items: r.items.map((p, i) => reservierungsPosition({ name: ort.name, pfad: `${ort.pfad}.items[${i}]` }, p)),
382
+ expiresAt: text(r.expiresAt),
383
+ createdAt: text(r.createdAt),
384
+ };
385
+ }
386
+ /** Die fehlenden Positionen aus `insufficient_available` (`data.details[]`); ein kaputter Eintrag faellt weg. */
387
+ function fehlmengen(roh) {
388
+ if (!Array.isArray(roh))
389
+ return [];
390
+ const raus = [];
391
+ for (const e of roh) {
392
+ const o = objekt(e);
393
+ if (!o)
394
+ continue;
395
+ const { articleId, locationId, requested, available } = o;
396
+ if (typeof articleId !== 'string' || typeof locationId !== 'string')
397
+ continue;
398
+ if (!Number.isSafeInteger(requested) || !Number.isSafeInteger(available))
399
+ continue;
400
+ raus.push({ articleId, locationId, requested: requested, available: available });
401
+ }
402
+ return raus;
403
+ }
404
+ // ---- Listen ------------------------------------------------------------------
405
+ /** Eine zugesagte Liste `data.<feld>`, Eintrag fuer Eintrag gelesen. */
406
+ function liste(name, daten, feld, lesen) {
407
+ const roh = objekt(daten)?.[feld];
408
+ if (!Array.isArray(roh)) {
409
+ const grund = roh === undefined || roh === null
410
+ ? `Antwort enthaelt keine Liste (data.${feld} fehlt)`
411
+ : `Antwort ist unbrauchbar (data.${feld} ist keine Liste)`;
412
+ throw antwortfehler(name, grund);
413
+ }
414
+ return roh.map((e, i) => lesen({ name, pfad: `${feld}[${i}]` }, e));
415
+ }
416
+ /** Der Cursor der naechsten Seite; `null` am Ende. Etwas anderes als Text oder `null` ist kaputt. */
417
+ function naechsterCursor(name, daten) {
418
+ const c = objekt(daten)?.nextCursor;
419
+ if (c === undefined || c === null)
420
+ return null;
421
+ if (typeof c !== 'string' || c === '')
422
+ throw antwortfehler(name, 'Antwort ist unbrauchbar (data.nextCursor)');
423
+ return c;
424
+ }