@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.
- package/CHANGELOG.md +176 -0
- package/README.md +293 -1
- package/dist/cjs/client/aufrufe.d.ts +2 -2
- package/dist/cjs/client/aufrufe.js +58 -0
- package/dist/cjs/inventory/api.d.ts +61 -0
- package/dist/cjs/inventory/api.js +54 -0
- package/dist/cjs/inventory/auth.d.ts +17 -0
- package/dist/cjs/inventory/auth.js +27 -0
- package/dist/cjs/inventory/endpunkte.d.ts +91 -0
- package/dist/cjs/inventory/endpunkte.js +290 -0
- package/dist/cjs/inventory/fehler.d.ts +43 -0
- package/dist/cjs/inventory/fehler.js +66 -0
- package/dist/cjs/inventory/index.d.ts +21 -0
- package/dist/cjs/inventory/index.js +94 -0
- package/dist/cjs/inventory/lesen.d.ts +45 -0
- package/dist/cjs/inventory/lesen.js +424 -0
- package/dist/cjs/inventory/schreiben.d.ts +83 -0
- package/dist/cjs/inventory/schreiben.js +315 -0
- package/dist/cjs/inventory/typen.d.ts +679 -0
- package/dist/cjs/inventory/typen.js +14 -0
- package/dist/cjs/inventory/vertrag.d.ts +136 -0
- package/dist/cjs/inventory/vertrag.js +291 -0
- package/dist/cjs/inventory/webhook.d.ts +52 -0
- package/dist/cjs/inventory/webhook.js +116 -0
- package/dist/cjs/invoice/index.d.ts +2 -2
- package/dist/cjs/invoice/index.js +2 -1
- package/dist/cjs/invoice/typen.d.ts +46 -2
- package/dist/cjs/invoice/vertrag.d.ts +19 -5
- package/dist/cjs/invoice/vertrag.js +37 -5
- package/dist/cjs/stored/vokabular.d.ts +1 -1
- package/dist/cjs/stored/vokabular.js +5 -3
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/client/aufrufe.d.ts +2 -2
- package/dist/esm/client/aufrufe.js +58 -0
- package/dist/esm/inventory/api.d.ts +61 -0
- package/dist/esm/inventory/api.js +51 -0
- package/dist/esm/inventory/auth.d.ts +17 -0
- package/dist/esm/inventory/auth.js +24 -0
- package/dist/esm/inventory/endpunkte.d.ts +91 -0
- package/dist/esm/inventory/endpunkte.js +267 -0
- package/dist/esm/inventory/fehler.d.ts +43 -0
- package/dist/esm/inventory/fehler.js +57 -0
- package/dist/esm/inventory/index.d.ts +21 -0
- package/dist/esm/inventory/index.js +20 -0
- package/dist/esm/inventory/lesen.d.ts +45 -0
- package/dist/esm/inventory/lesen.js +404 -0
- package/dist/esm/inventory/schreiben.d.ts +83 -0
- package/dist/esm/inventory/schreiben.js +298 -0
- package/dist/esm/inventory/typen.d.ts +679 -0
- package/dist/esm/inventory/typen.js +13 -0
- package/dist/esm/inventory/vertrag.d.ts +136 -0
- package/dist/esm/inventory/vertrag.js +288 -0
- package/dist/esm/inventory/webhook.d.ts +52 -0
- package/dist/esm/inventory/webhook.js +107 -0
- package/dist/esm/invoice/index.d.ts +2 -2
- package/dist/esm/invoice/index.js +1 -1
- package/dist/esm/invoice/typen.d.ts +46 -2
- package/dist/esm/invoice/vertrag.d.ts +19 -5
- package/dist/esm/invoice/vertrag.js +36 -4
- package/dist/esm/stored/vokabular.d.ts +1 -1
- package/dist/esm/stored/vokabular.js +5 -3
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/invoice-api-examples/credit-error-reservation.json +26 -0
- package/fixtures/invoice-api-examples/issue-error-reservation-article.json +25 -0
- package/fixtures/invoice-api-examples/issue-error-vat-id-risk.json +26 -0
- package/fixtures/invoice-api-examples/issue-reservation.json +24 -0
- package/fixtures/invoice-api-examples/issue-vat-id-risk.json +28 -0
- package/fixtures/invoice-api.schema.json +15 -2
- package/fixtures/invoice-texts.json +1 -1
- package/fixtures/pos-texts.json +1 -1
- package/fixtures/surface.json +306 -5
- package/fixtures/v3/README.md +9 -1
- package/fixtures/v3/antworten/belege.json +2 -2
- package/fixtures/v3/antworten/belegmail.json +2 -2
- package/fixtures/v3/antworten/kasse-belege.json +2 -2
- package/fixtures/v3/antworten/kasse.json +3 -3
- package/fixtures/v3/antworten/lager.json +3881 -0
- package/fixtures/v3/antworten/rechnungen.json +267 -44
- package/fixtures/v3/antworten/storno.json +2 -2
- package/fixtures/v3/stored/belege.json +2 -2
- package/fixtures/v3/stored/kasse.json +404 -4
- package/fixtures/v3/stored/rechnungen.json +174 -18
- package/fixtures/v3/v3-vokabular.json +1007 -20
- package/fixtures/v3/zahlbetrag-faelle.json +2 -2
- package/package.json +14 -2
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Der Vertrag der Lager-API (Backend Stufe 5a lesen, 5b schreiben und
|
|
3
|
+
* reservieren) als Daten: Endpunkte, Wertkataloge, Ereignisse, Fehler- und
|
|
4
|
+
* Hinweiscodes, englisch wie am Draht `/v3`.
|
|
5
|
+
*
|
|
6
|
+
* Quelle ist der Vertrags-Export des Backends (`fixtures/v3/v3-vokabular.json`):
|
|
7
|
+
* `endpoints.public`, die Kataloge `STANDORT_TYP`, `BEWEGUNG_ART`,
|
|
8
|
+
* `BEWEGUNG_QUELLE`, `LAGER_ZUSTAND`, `LAGER_URSACHE`, `ZUSTELLUNG`,
|
|
9
|
+
* `LAGER_ABGANG_GRUND`, `LAGER_ENTNAHME_ART`, `LAGER_NEBENKOSTEN_ART`,
|
|
10
|
+
* `LAGER_VERTEILUNG`, `RESERVIERUNG_STATUS`, dazu `events`, `errorCodes.inventory`
|
|
11
|
+
* und `warningCodes.inventory`. `test/inventory.test.ts` haelt jede Liste
|
|
12
|
+
* deckungsgleich mit dieser Datei; nichts hier wird geraten.
|
|
13
|
+
*/
|
|
14
|
+
/** Die 27 Endpunkte (14 aus 5a, 13 aus 5b), in der Reihenfolge von `endpoints.public`. */
|
|
15
|
+
export declare const INVENTORY_ENDPOINTS: readonly ["getArticle", "listArticles", "lookupArticleByCode", "listLocations", "getStock", "listStock", "listStockMovements", "createWebhook", "updateWebhook", "deleteWebhook", "listWebhooks", "sendWebhookTest", "rotateWebhookSecret", "listWebhookDeliveries", "createArticle", "updateArticle", "deactivateArticle", "receiveGoods", "transferStock", "recordStockLoss", "changeStockCondition", "reverseStockMovement", "createReservation", "extendReservation", "releaseReservation", "getReservation", "listReservations"];
|
|
16
|
+
export type InventoryEndpoint = (typeof INVENTORY_ENDPOINTS)[number];
|
|
17
|
+
/** Art eines Standorts (Katalog `STANDORT_TYP`). */
|
|
18
|
+
export declare const LOCATION_TYPES: readonly ["warehouse", "store", "vehicle", "other"];
|
|
19
|
+
export type LocationType = (typeof LOCATION_TYPES)[number];
|
|
20
|
+
/**
|
|
21
|
+
* Art einer Lagerbewegung (Katalog `BEWEGUNG_ART`); zugleich der Filter `type`.
|
|
22
|
+
* `goods_receipt` ist der Wareneingang, `takeover` der uebernommene Anfangsbestand
|
|
23
|
+
* (auch per Import). `receipt` gibt es hier nicht: das ist der Kassenbeleg (Quelle).
|
|
24
|
+
* `reservation` (seit 1.5.0) aendert nur `reserved`: `quantityDelta` ist 0, die
|
|
25
|
+
* Menge steht in `reservedDelta`.
|
|
26
|
+
*/
|
|
27
|
+
export declare const STOCK_MOVEMENT_TYPES: readonly ["sale", "goods_receipt", "loss", "return", "transfer_out", "transfer_in", "condition_out", "condition_in", "stocktake", "adjustment", "takeover", "reversal", "revaluation", "method_change", "reservation"];
|
|
28
|
+
export type StockMovementType = (typeof STOCK_MOVEMENT_TYPES)[number];
|
|
29
|
+
/**
|
|
30
|
+
* Woher eine Bewegung kommt (Katalog `BEWEGUNG_QUELLE`); zugleich der Filter
|
|
31
|
+
* `source`. `receipt` ist der Kassenbeleg wie ueberall in der API (der
|
|
32
|
+
* Wareneingang ist die Bewegungsart `goods_receipt`).
|
|
33
|
+
*/
|
|
34
|
+
export declare const STOCK_MOVEMENT_SOURCES: readonly ["receipt", "invoice", "cancellation", "credit_note", "panel", "register", "api", "stocktake", "system"];
|
|
35
|
+
export type StockMovementSource = (typeof STOCK_MOVEMENT_SOURCES)[number];
|
|
36
|
+
/** Zustand der Ware an einer Bewegung (Katalog `LAGER_ZUSTAND`). */
|
|
37
|
+
export declare const STOCK_CONDITIONS: readonly ["sellable", "defective"];
|
|
38
|
+
export type StockCondition = (typeof STOCK_CONDITIONS)[number];
|
|
39
|
+
/**
|
|
40
|
+
* Ursache eines `stock.changed` (Katalog `LAGER_URSACHE`), abgeleitet aus der
|
|
41
|
+
* juengsten Bewegung mit Mengenwirkung. `other`: keine Regel passt oder es
|
|
42
|
+
* gibt keine Bewegung (dann ist `movementId` `null`).
|
|
43
|
+
*/
|
|
44
|
+
export declare const STOCK_CHANGE_CAUSES: readonly ["sale", "invoice", "credit_note", "cancellation", "goods_receipt", "transfer", "loss", "condition", "reversal", "reservation", "stocktake", "takeover", "other"];
|
|
45
|
+
export type StockChangeCause = (typeof STOCK_CHANGE_CAUSES)[number];
|
|
46
|
+
/** Stand einer Zustellung (Katalog `ZUSTELLUNG`, derselbe wie bei Partner-Webhooks). */
|
|
47
|
+
export declare const WEBHOOK_DELIVERY_STATUSES: readonly ["delivered", "pending", "failed", "dropped"];
|
|
48
|
+
export type WebhookDeliveryStatus = (typeof WEBHOOK_DELIVERY_STATUSES)[number];
|
|
49
|
+
/**
|
|
50
|
+
* Die Ereignisse, die ein Konto-Webhook abonnieren kann, in der Reihenfolge von
|
|
51
|
+
* `listWebhooks().events`. `reservation.*` (seit 1.5.0) tragen die Reservierung
|
|
52
|
+
* wie `getReservation`, mit dem Status danach: `reservation.released` und
|
|
53
|
+
* `reservation.redeemed` kommen bei jeder wirksamen Freigabe bzw. Einloesung,
|
|
54
|
+
* auch einer teilweisen (dann bleibt der Status `active`).
|
|
55
|
+
*/
|
|
56
|
+
export declare const INVENTORY_WEBHOOK_EVENTS: readonly ["stock.changed", "stock.below_minimum", "article.created", "article.updated", "article.deactivated", "reservation.expired", "reservation.released", "reservation.redeemed"];
|
|
57
|
+
export type InventoryWebhookEventType = (typeof INVENTORY_WEBHOOK_EVENTS)[number];
|
|
58
|
+
/**
|
|
59
|
+
* Die Felder der Huelle jeder Zustellung, in der Reihenfolge am Draht. Statt
|
|
60
|
+
* `partnerId` (Partner-Webhooks) traegt sie `accountId`; `test` steht nur auf
|
|
61
|
+
* Probesendungen.
|
|
62
|
+
*/
|
|
63
|
+
export declare const INVENTORY_WEBHOOK_ENVELOPE_FIELDS: readonly ["id", "type", "createdAt", "accountId", "test", "data"];
|
|
64
|
+
/** Hoechstzahl der Webhooks je Konto (`webhook_limit`, wie bei Partner-Webhooks). */
|
|
65
|
+
export declare const INVENTORY_WEBHOOK_LIMIT = 5;
|
|
66
|
+
/** Groesstes `limit` einer Liste; ohne Angabe liefert der Server 50. */
|
|
67
|
+
export declare const INVENTORY_LIST_LIMIT_MAX = 200;
|
|
68
|
+
/**
|
|
69
|
+
* Die Codes, die die Lager-Endpunkte selbst senden (`errorCodes.inventory`;
|
|
70
|
+
* `register_user_not_allowed` steht bei [INVENTORY_REQUEST_ERROR_CODES]).
|
|
71
|
+
* `validation` traegt `errors: [{ field, message }]`, `rate_limited` traegt
|
|
72
|
+
* `retryAfterSec` (dazu die Kopfzeile `Retry-After`) – auch bei
|
|
73
|
+
* `sendWebhookTest` nach 20 Probesendungen je Wiener Kalendertag (dann bis
|
|
74
|
+
* Mitternacht in Wien).
|
|
75
|
+
*
|
|
76
|
+
* Seit 1.5.0 hinten angehaengt, in der Reihenfolge des Vertrags: die Codes
|
|
77
|
+
* der schreibenden Endpunkte. `idempotency_key_required` (Schluessel fehlt),
|
|
78
|
+
* `idempotency_conflict` (derselbe Schluessel mit anderem Inhalt),
|
|
79
|
+
* `exceeds_stock` (Abgang, Umbuchung und Zustandswechsel ueberziehen nie),
|
|
80
|
+
* `insufficient_available` (Reservierung; `data.details[]`, siehe
|
|
81
|
+
* [inventoryShortfalls]), `code_taken` und `external_id_taken` (mit `field` und
|
|
82
|
+
* `articleId` des Artikels, dem der Code gehoert), `stock_kind_locked`,
|
|
83
|
+
* `reservation_not_found`, `reservation_not_active` …
|
|
84
|
+
*/
|
|
85
|
+
export declare const INVENTORY_ERROR_CODES: readonly ["validation", "invalid_cursor", "article_not_found", "webhook_not_found", "webhook_limit", "invalid_webhook_url", "event_not_subscribed", "webhook_inactive", "inventory_api_not_enabled", "module_inactive", "rate_limited", "server_error", "idempotency_key_required", "idempotency_conflict", "location_not_found", "location_inactive", "invalid_location", "invalid_locations", "invalid_transfer", "operation_not_found", "already_reversed", "reversal_not_possible", "reversal_not_supported", "exceeds_stock", "no_positions", "too_many_positions", "invalid_step", "invalid_quantity", "invalid_amount", "invalid_price", "negative_value", "invalid_reason", "note_required", "withdrawal_type_required", "invalid_method", "invalid_stock_kind", "invalid_minimum", "invalid_dimensions", "weight_missing", "invalid_landed_cost", "invalid_distribution", "landed_costs_mismatch", "return_totals_mismatch", "lot_not_found", "invalid_serial", "serial_required", "serial_not_allowed", "serial_already_exists", "serial_not_in_stock", "code_taken", "external_id_taken", "group_not_found", "revenue_group_not_found", "stock_kind_locked", "article_inactive", "invalid_position", "invalid_condition", "reason_required", "insufficient_available", "reservation_not_found", "reservation_not_active"];
|
|
86
|
+
export type InventoryErrorCode = (typeof INVENTORY_ERROR_CODES)[number];
|
|
87
|
+
/**
|
|
88
|
+
* Codes, die Anmeldung und Rand auf jedem Lager-Aufruf erzeugen koennen,
|
|
89
|
+
* soweit sie nicht schon in [INVENTORY_ERROR_CODES] stehen: `errorCodes.auth`
|
|
90
|
+
* ohne die des Partner-Zugangs und `errorCodes.edge` (sortiert), zuletzt
|
|
91
|
+
* `route_missing` (Code des Pakets). Dieselbe Ableitung wie bei der
|
|
92
|
+
* Rechnungs-API.
|
|
93
|
+
*/
|
|
94
|
+
export declare const INVENTORY_REQUEST_ERROR_CODES: readonly ["account_not_found", "admin_required", "api_not_approved", "cashregister_not_assigned", "cashregister_not_found", "cashregister_token_invalid", "cashregister_token_missing", "dialect_mismatch", "internal_translation_error", "live_not_enabled", "method_not_allowed", "mfa_required", "not_found", "register_user_no_business", "register_user_not_allowed", "register_user_not_found", "response_translation_failed", "session_expired", "session_other_cashregister", "unauthorized", "user_disabled", "user_verification_failed", "route_missing"];
|
|
95
|
+
export type InventoryRequestErrorCode = (typeof INVENTORY_REQUEST_ERROR_CODES)[number];
|
|
96
|
+
/**
|
|
97
|
+
* Hinweise einer Buchung (`warnings[].code`, `warningCodes.inventory`). Sie sind
|
|
98
|
+
* keine Fehler: die Buchung hat gewirkt. `insufficient_stock` gibt es nur beim
|
|
99
|
+
* Verkauf (Abgang, Umbuchung und Zustandswechsel weisen mit `exceeds_stock` ab),
|
|
100
|
+
* `below_minimum` misst am verfuegbaren Bestand (`onHand − reserved`) gegen den
|
|
101
|
+
* Mindestbestand des Standorts, `reservation_exceeded` meldet eine Rechnung, die
|
|
102
|
+
* mehr verkauft als reserviert war.
|
|
103
|
+
*/
|
|
104
|
+
export declare const INVENTORY_WARNING_CODES: readonly ["insufficient_stock", "below_minimum", "return_exceeds_sale", "reservation_exceeded"];
|
|
105
|
+
export type InventoryWarningCode = (typeof INVENTORY_WARNING_CODES)[number];
|
|
106
|
+
/**
|
|
107
|
+
* Bestandsart eines Artikels (`stockKind`): `quantity` = Menge, `serial` =
|
|
108
|
+
* Einzelstueck mit Seriennummer. Kein Katalog des Vokabulars, der Server
|
|
109
|
+
* uebersetzt das Feld selbst; nach der ersten Bewegung fest (`stock_kind_locked`).
|
|
110
|
+
*/
|
|
111
|
+
export declare const STOCK_KINDS: readonly ["quantity", "serial"];
|
|
112
|
+
export type StockKind = (typeof STOCK_KINDS)[number];
|
|
113
|
+
/** Grund eines Abgangs (`recordStockLoss.reason`, Katalog `LAGER_ABGANG_GRUND`). `other` braucht `note`. */
|
|
114
|
+
export declare const STOCK_LOSS_REASONS: readonly ["breakage", "shrinkage", "theft", "expired", "withdrawal", "disposal", "other"];
|
|
115
|
+
export type StockLossReason = (typeof STOCK_LOSS_REASONS)[number];
|
|
116
|
+
/** Art einer Entnahme (`withdrawalType`, Katalog `LAGER_ENTNAHME_ART`); Pflicht bei `reason: 'withdrawal'`, sonst nicht erlaubt. */
|
|
117
|
+
export declare const WITHDRAWAL_TYPES: readonly ["private", "staff", "gift", "sample"];
|
|
118
|
+
export type WithdrawalType = (typeof WITHDRAWAL_TYPES)[number];
|
|
119
|
+
/** Art von Nebenkosten eines Wareneingangs (`landedCosts[].type`, Katalog `LAGER_NEBENKOSTEN_ART`). */
|
|
120
|
+
export declare const LANDED_COST_TYPES: readonly ["freight", "customs", "insurance", "other", "discount", "cash_discount"];
|
|
121
|
+
export type LandedCostType = (typeof LANDED_COST_TYPES)[number];
|
|
122
|
+
/** Verteilung der Nebenkosten (`allocation`, Katalog `LAGER_VERTEILUNG`); Vorgabe des Servers `value`. */
|
|
123
|
+
export declare const LANDED_COST_ALLOCATIONS: readonly ["value", "quantity", "weight", "manual"];
|
|
124
|
+
export type LandedCostAllocation = (typeof LANDED_COST_ALLOCATIONS)[number];
|
|
125
|
+
/**
|
|
126
|
+
* Stand einer Reservierung (Katalog `RESERVIERUNG_STATUS`). Nur `active` haelt
|
|
127
|
+
* Ware zurueck; die drei anderen sind endgueltig: `redeemed` (ueber eine
|
|
128
|
+
* Rechnung eingeloest), `released` (freigegeben), `expired` (abgelaufen).
|
|
129
|
+
*/
|
|
130
|
+
export declare const RESERVATION_STATUSES: readonly ["active", "redeemed", "released", "expired"];
|
|
131
|
+
export type ReservationStatus = (typeof RESERVATION_STATUSES)[number];
|
|
132
|
+
/** Laengster `idempotencyKey` (Zeichen); laenger weist der Server ab, er schneidet nie ab. */
|
|
133
|
+
export declare const INVENTORY_IDEMPOTENCY_KEY_MAX = 120;
|
|
134
|
+
/** Kuerzeste und laengste Haltedauer einer Reservierung in Minuten (`expiresInMinutes`, 30 Tage). */
|
|
135
|
+
export declare const RESERVATION_MINUTES_MIN = 5;
|
|
136
|
+
export declare const RESERVATION_MINUTES_MAX = 43200;
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Der Vertrag der Lager-API (Backend Stufe 5a lesen, 5b schreiben und
|
|
4
|
+
* reservieren) als Daten: Endpunkte, Wertkataloge, Ereignisse, Fehler- und
|
|
5
|
+
* Hinweiscodes, englisch wie am Draht `/v3`.
|
|
6
|
+
*
|
|
7
|
+
* Quelle ist der Vertrags-Export des Backends (`fixtures/v3/v3-vokabular.json`):
|
|
8
|
+
* `endpoints.public`, die Kataloge `STANDORT_TYP`, `BEWEGUNG_ART`,
|
|
9
|
+
* `BEWEGUNG_QUELLE`, `LAGER_ZUSTAND`, `LAGER_URSACHE`, `ZUSTELLUNG`,
|
|
10
|
+
* `LAGER_ABGANG_GRUND`, `LAGER_ENTNAHME_ART`, `LAGER_NEBENKOSTEN_ART`,
|
|
11
|
+
* `LAGER_VERTEILUNG`, `RESERVIERUNG_STATUS`, dazu `events`, `errorCodes.inventory`
|
|
12
|
+
* und `warningCodes.inventory`. `test/inventory.test.ts` haelt jede Liste
|
|
13
|
+
* deckungsgleich mit dieser Datei; nichts hier wird geraten.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
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.INVENTORY_REQUEST_ERROR_CODES = exports.INVENTORY_ERROR_CODES = exports.INVENTORY_LIST_LIMIT_MAX = exports.INVENTORY_WEBHOOK_LIMIT = exports.INVENTORY_WEBHOOK_ENVELOPE_FIELDS = exports.INVENTORY_WEBHOOK_EVENTS = exports.WEBHOOK_DELIVERY_STATUSES = exports.STOCK_CHANGE_CAUSES = exports.STOCK_CONDITIONS = exports.STOCK_MOVEMENT_SOURCES = exports.STOCK_MOVEMENT_TYPES = exports.LOCATION_TYPES = exports.INVENTORY_ENDPOINTS = void 0;
|
|
17
|
+
/** Die 27 Endpunkte (14 aus 5a, 13 aus 5b), in der Reihenfolge von `endpoints.public`. */
|
|
18
|
+
exports.INVENTORY_ENDPOINTS = [
|
|
19
|
+
'getArticle',
|
|
20
|
+
'listArticles',
|
|
21
|
+
'lookupArticleByCode',
|
|
22
|
+
'listLocations',
|
|
23
|
+
'getStock',
|
|
24
|
+
'listStock',
|
|
25
|
+
'listStockMovements',
|
|
26
|
+
'createWebhook',
|
|
27
|
+
'updateWebhook',
|
|
28
|
+
'deleteWebhook',
|
|
29
|
+
'listWebhooks',
|
|
30
|
+
'sendWebhookTest',
|
|
31
|
+
'rotateWebhookSecret',
|
|
32
|
+
'listWebhookDeliveries',
|
|
33
|
+
'createArticle',
|
|
34
|
+
'updateArticle',
|
|
35
|
+
'deactivateArticle',
|
|
36
|
+
'receiveGoods',
|
|
37
|
+
'transferStock',
|
|
38
|
+
'recordStockLoss',
|
|
39
|
+
'changeStockCondition',
|
|
40
|
+
'reverseStockMovement',
|
|
41
|
+
'createReservation',
|
|
42
|
+
'extendReservation',
|
|
43
|
+
'releaseReservation',
|
|
44
|
+
'getReservation',
|
|
45
|
+
'listReservations',
|
|
46
|
+
];
|
|
47
|
+
/** Art eines Standorts (Katalog `STANDORT_TYP`). */
|
|
48
|
+
exports.LOCATION_TYPES = ['warehouse', 'store', 'vehicle', 'other'];
|
|
49
|
+
/**
|
|
50
|
+
* Art einer Lagerbewegung (Katalog `BEWEGUNG_ART`); zugleich der Filter `type`.
|
|
51
|
+
* `goods_receipt` ist der Wareneingang, `takeover` der uebernommene Anfangsbestand
|
|
52
|
+
* (auch per Import). `receipt` gibt es hier nicht: das ist der Kassenbeleg (Quelle).
|
|
53
|
+
* `reservation` (seit 1.5.0) aendert nur `reserved`: `quantityDelta` ist 0, die
|
|
54
|
+
* Menge steht in `reservedDelta`.
|
|
55
|
+
*/
|
|
56
|
+
exports.STOCK_MOVEMENT_TYPES = [
|
|
57
|
+
'sale',
|
|
58
|
+
'goods_receipt',
|
|
59
|
+
'loss',
|
|
60
|
+
'return',
|
|
61
|
+
'transfer_out',
|
|
62
|
+
'transfer_in',
|
|
63
|
+
'condition_out',
|
|
64
|
+
'condition_in',
|
|
65
|
+
'stocktake',
|
|
66
|
+
'adjustment',
|
|
67
|
+
'takeover',
|
|
68
|
+
'reversal',
|
|
69
|
+
'revaluation',
|
|
70
|
+
'method_change',
|
|
71
|
+
'reservation',
|
|
72
|
+
];
|
|
73
|
+
/**
|
|
74
|
+
* Woher eine Bewegung kommt (Katalog `BEWEGUNG_QUELLE`); zugleich der Filter
|
|
75
|
+
* `source`. `receipt` ist der Kassenbeleg wie ueberall in der API (der
|
|
76
|
+
* Wareneingang ist die Bewegungsart `goods_receipt`).
|
|
77
|
+
*/
|
|
78
|
+
exports.STOCK_MOVEMENT_SOURCES = [
|
|
79
|
+
'receipt',
|
|
80
|
+
'invoice',
|
|
81
|
+
'cancellation',
|
|
82
|
+
'credit_note',
|
|
83
|
+
'panel',
|
|
84
|
+
'register',
|
|
85
|
+
'api',
|
|
86
|
+
'stocktake',
|
|
87
|
+
'system',
|
|
88
|
+
];
|
|
89
|
+
/** Zustand der Ware an einer Bewegung (Katalog `LAGER_ZUSTAND`). */
|
|
90
|
+
exports.STOCK_CONDITIONS = ['sellable', 'defective'];
|
|
91
|
+
/**
|
|
92
|
+
* Ursache eines `stock.changed` (Katalog `LAGER_URSACHE`), abgeleitet aus der
|
|
93
|
+
* juengsten Bewegung mit Mengenwirkung. `other`: keine Regel passt oder es
|
|
94
|
+
* gibt keine Bewegung (dann ist `movementId` `null`).
|
|
95
|
+
*/
|
|
96
|
+
exports.STOCK_CHANGE_CAUSES = [
|
|
97
|
+
'sale',
|
|
98
|
+
'invoice',
|
|
99
|
+
'credit_note',
|
|
100
|
+
'cancellation',
|
|
101
|
+
'goods_receipt',
|
|
102
|
+
'transfer',
|
|
103
|
+
'loss',
|
|
104
|
+
'condition',
|
|
105
|
+
'reversal',
|
|
106
|
+
'reservation',
|
|
107
|
+
'stocktake',
|
|
108
|
+
'takeover',
|
|
109
|
+
'other',
|
|
110
|
+
];
|
|
111
|
+
/** Stand einer Zustellung (Katalog `ZUSTELLUNG`, derselbe wie bei Partner-Webhooks). */
|
|
112
|
+
exports.WEBHOOK_DELIVERY_STATUSES = ['delivered', 'pending', 'failed', 'dropped'];
|
|
113
|
+
/**
|
|
114
|
+
* Die Ereignisse, die ein Konto-Webhook abonnieren kann, in der Reihenfolge von
|
|
115
|
+
* `listWebhooks().events`. `reservation.*` (seit 1.5.0) tragen die Reservierung
|
|
116
|
+
* wie `getReservation`, mit dem Status danach: `reservation.released` und
|
|
117
|
+
* `reservation.redeemed` kommen bei jeder wirksamen Freigabe bzw. Einloesung,
|
|
118
|
+
* auch einer teilweisen (dann bleibt der Status `active`).
|
|
119
|
+
*/
|
|
120
|
+
exports.INVENTORY_WEBHOOK_EVENTS = [
|
|
121
|
+
'stock.changed',
|
|
122
|
+
'stock.below_minimum',
|
|
123
|
+
'article.created',
|
|
124
|
+
'article.updated',
|
|
125
|
+
'article.deactivated',
|
|
126
|
+
'reservation.expired',
|
|
127
|
+
'reservation.released',
|
|
128
|
+
'reservation.redeemed',
|
|
129
|
+
];
|
|
130
|
+
/**
|
|
131
|
+
* Die Felder der Huelle jeder Zustellung, in der Reihenfolge am Draht. Statt
|
|
132
|
+
* `partnerId` (Partner-Webhooks) traegt sie `accountId`; `test` steht nur auf
|
|
133
|
+
* Probesendungen.
|
|
134
|
+
*/
|
|
135
|
+
exports.INVENTORY_WEBHOOK_ENVELOPE_FIELDS = ['id', 'type', 'createdAt', 'accountId', 'test', 'data'];
|
|
136
|
+
/** Hoechstzahl der Webhooks je Konto (`webhook_limit`, wie bei Partner-Webhooks). */
|
|
137
|
+
exports.INVENTORY_WEBHOOK_LIMIT = 5;
|
|
138
|
+
/** Groesstes `limit` einer Liste; ohne Angabe liefert der Server 50. */
|
|
139
|
+
exports.INVENTORY_LIST_LIMIT_MAX = 200;
|
|
140
|
+
/**
|
|
141
|
+
* Die Codes, die die Lager-Endpunkte selbst senden (`errorCodes.inventory`;
|
|
142
|
+
* `register_user_not_allowed` steht bei [INVENTORY_REQUEST_ERROR_CODES]).
|
|
143
|
+
* `validation` traegt `errors: [{ field, message }]`, `rate_limited` traegt
|
|
144
|
+
* `retryAfterSec` (dazu die Kopfzeile `Retry-After`) – auch bei
|
|
145
|
+
* `sendWebhookTest` nach 20 Probesendungen je Wiener Kalendertag (dann bis
|
|
146
|
+
* Mitternacht in Wien).
|
|
147
|
+
*
|
|
148
|
+
* Seit 1.5.0 hinten angehaengt, in der Reihenfolge des Vertrags: die Codes
|
|
149
|
+
* der schreibenden Endpunkte. `idempotency_key_required` (Schluessel fehlt),
|
|
150
|
+
* `idempotency_conflict` (derselbe Schluessel mit anderem Inhalt),
|
|
151
|
+
* `exceeds_stock` (Abgang, Umbuchung und Zustandswechsel ueberziehen nie),
|
|
152
|
+
* `insufficient_available` (Reservierung; `data.details[]`, siehe
|
|
153
|
+
* [inventoryShortfalls]), `code_taken` und `external_id_taken` (mit `field` und
|
|
154
|
+
* `articleId` des Artikels, dem der Code gehoert), `stock_kind_locked`,
|
|
155
|
+
* `reservation_not_found`, `reservation_not_active` …
|
|
156
|
+
*/
|
|
157
|
+
exports.INVENTORY_ERROR_CODES = [
|
|
158
|
+
'validation',
|
|
159
|
+
'invalid_cursor',
|
|
160
|
+
'article_not_found',
|
|
161
|
+
'webhook_not_found',
|
|
162
|
+
'webhook_limit',
|
|
163
|
+
'invalid_webhook_url',
|
|
164
|
+
'event_not_subscribed',
|
|
165
|
+
'webhook_inactive',
|
|
166
|
+
'inventory_api_not_enabled',
|
|
167
|
+
'module_inactive',
|
|
168
|
+
'rate_limited',
|
|
169
|
+
'server_error',
|
|
170
|
+
'idempotency_key_required',
|
|
171
|
+
'idempotency_conflict',
|
|
172
|
+
'location_not_found',
|
|
173
|
+
'location_inactive',
|
|
174
|
+
'invalid_location',
|
|
175
|
+
'invalid_locations',
|
|
176
|
+
'invalid_transfer',
|
|
177
|
+
'operation_not_found',
|
|
178
|
+
'already_reversed',
|
|
179
|
+
'reversal_not_possible',
|
|
180
|
+
'reversal_not_supported',
|
|
181
|
+
'exceeds_stock',
|
|
182
|
+
'no_positions',
|
|
183
|
+
'too_many_positions',
|
|
184
|
+
'invalid_step',
|
|
185
|
+
'invalid_quantity',
|
|
186
|
+
'invalid_amount',
|
|
187
|
+
'invalid_price',
|
|
188
|
+
'negative_value',
|
|
189
|
+
'invalid_reason',
|
|
190
|
+
'note_required',
|
|
191
|
+
'withdrawal_type_required',
|
|
192
|
+
'invalid_method',
|
|
193
|
+
'invalid_stock_kind',
|
|
194
|
+
'invalid_minimum',
|
|
195
|
+
'invalid_dimensions',
|
|
196
|
+
'weight_missing',
|
|
197
|
+
'invalid_landed_cost',
|
|
198
|
+
'invalid_distribution',
|
|
199
|
+
'landed_costs_mismatch',
|
|
200
|
+
'return_totals_mismatch',
|
|
201
|
+
'lot_not_found',
|
|
202
|
+
'invalid_serial',
|
|
203
|
+
'serial_required',
|
|
204
|
+
'serial_not_allowed',
|
|
205
|
+
'serial_already_exists',
|
|
206
|
+
'serial_not_in_stock',
|
|
207
|
+
'code_taken',
|
|
208
|
+
'external_id_taken',
|
|
209
|
+
'group_not_found',
|
|
210
|
+
'revenue_group_not_found',
|
|
211
|
+
'stock_kind_locked',
|
|
212
|
+
'article_inactive',
|
|
213
|
+
'invalid_position',
|
|
214
|
+
'invalid_condition',
|
|
215
|
+
'reason_required',
|
|
216
|
+
'insufficient_available',
|
|
217
|
+
'reservation_not_found',
|
|
218
|
+
'reservation_not_active',
|
|
219
|
+
];
|
|
220
|
+
/**
|
|
221
|
+
* Codes, die Anmeldung und Rand auf jedem Lager-Aufruf erzeugen koennen,
|
|
222
|
+
* soweit sie nicht schon in [INVENTORY_ERROR_CODES] stehen: `errorCodes.auth`
|
|
223
|
+
* ohne die des Partner-Zugangs und `errorCodes.edge` (sortiert), zuletzt
|
|
224
|
+
* `route_missing` (Code des Pakets). Dieselbe Ableitung wie bei der
|
|
225
|
+
* Rechnungs-API.
|
|
226
|
+
*/
|
|
227
|
+
exports.INVENTORY_REQUEST_ERROR_CODES = [
|
|
228
|
+
'account_not_found',
|
|
229
|
+
'admin_required',
|
|
230
|
+
'api_not_approved',
|
|
231
|
+
'cashregister_not_assigned',
|
|
232
|
+
'cashregister_not_found',
|
|
233
|
+
'cashregister_token_invalid',
|
|
234
|
+
'cashregister_token_missing',
|
|
235
|
+
'dialect_mismatch',
|
|
236
|
+
'internal_translation_error',
|
|
237
|
+
'live_not_enabled',
|
|
238
|
+
'method_not_allowed',
|
|
239
|
+
'mfa_required',
|
|
240
|
+
'not_found',
|
|
241
|
+
'register_user_no_business',
|
|
242
|
+
'register_user_not_allowed',
|
|
243
|
+
'register_user_not_found',
|
|
244
|
+
'response_translation_failed',
|
|
245
|
+
'session_expired',
|
|
246
|
+
'session_other_cashregister',
|
|
247
|
+
'unauthorized',
|
|
248
|
+
'user_disabled',
|
|
249
|
+
'user_verification_failed',
|
|
250
|
+
'route_missing',
|
|
251
|
+
];
|
|
252
|
+
// ---- Schreiben und Reservierung (Backend Stufe 5b, seit 1.5.0) -----------------
|
|
253
|
+
/**
|
|
254
|
+
* Hinweise einer Buchung (`warnings[].code`, `warningCodes.inventory`). Sie sind
|
|
255
|
+
* keine Fehler: die Buchung hat gewirkt. `insufficient_stock` gibt es nur beim
|
|
256
|
+
* Verkauf (Abgang, Umbuchung und Zustandswechsel weisen mit `exceeds_stock` ab),
|
|
257
|
+
* `below_minimum` misst am verfuegbaren Bestand (`onHand − reserved`) gegen den
|
|
258
|
+
* Mindestbestand des Standorts, `reservation_exceeded` meldet eine Rechnung, die
|
|
259
|
+
* mehr verkauft als reserviert war.
|
|
260
|
+
*/
|
|
261
|
+
exports.INVENTORY_WARNING_CODES = [
|
|
262
|
+
'insufficient_stock',
|
|
263
|
+
'below_minimum',
|
|
264
|
+
'return_exceeds_sale',
|
|
265
|
+
'reservation_exceeded',
|
|
266
|
+
];
|
|
267
|
+
/**
|
|
268
|
+
* Bestandsart eines Artikels (`stockKind`): `quantity` = Menge, `serial` =
|
|
269
|
+
* Einzelstueck mit Seriennummer. Kein Katalog des Vokabulars, der Server
|
|
270
|
+
* uebersetzt das Feld selbst; nach der ersten Bewegung fest (`stock_kind_locked`).
|
|
271
|
+
*/
|
|
272
|
+
exports.STOCK_KINDS = ['quantity', 'serial'];
|
|
273
|
+
/** Grund eines Abgangs (`recordStockLoss.reason`, Katalog `LAGER_ABGANG_GRUND`). `other` braucht `note`. */
|
|
274
|
+
exports.STOCK_LOSS_REASONS = ['breakage', 'shrinkage', 'theft', 'expired', 'withdrawal', 'disposal', 'other'];
|
|
275
|
+
/** Art einer Entnahme (`withdrawalType`, Katalog `LAGER_ENTNAHME_ART`); Pflicht bei `reason: 'withdrawal'`, sonst nicht erlaubt. */
|
|
276
|
+
exports.WITHDRAWAL_TYPES = ['private', 'staff', 'gift', 'sample'];
|
|
277
|
+
/** Art von Nebenkosten eines Wareneingangs (`landedCosts[].type`, Katalog `LAGER_NEBENKOSTEN_ART`). */
|
|
278
|
+
exports.LANDED_COST_TYPES = ['freight', 'customs', 'insurance', 'other', 'discount', 'cash_discount'];
|
|
279
|
+
/** Verteilung der Nebenkosten (`allocation`, Katalog `LAGER_VERTEILUNG`); Vorgabe des Servers `value`. */
|
|
280
|
+
exports.LANDED_COST_ALLOCATIONS = ['value', 'quantity', 'weight', 'manual'];
|
|
281
|
+
/**
|
|
282
|
+
* Stand einer Reservierung (Katalog `RESERVIERUNG_STATUS`). Nur `active` haelt
|
|
283
|
+
* Ware zurueck; die drei anderen sind endgueltig: `redeemed` (ueber eine
|
|
284
|
+
* Rechnung eingeloest), `released` (freigegeben), `expired` (abgelaufen).
|
|
285
|
+
*/
|
|
286
|
+
exports.RESERVATION_STATUSES = ['active', 'redeemed', 'released', 'expired'];
|
|
287
|
+
/** Laengster `idempotencyKey` (Zeichen); laenger weist der Server ab, er schneidet nie ab. */
|
|
288
|
+
exports.INVENTORY_IDEMPOTENCY_KEY_MAX = 120;
|
|
289
|
+
/** Kuerzeste und laengste Haltedauer einer Reservierung in Minuten (`expiresInMinutes`, 30 Tage). */
|
|
290
|
+
exports.RESERVATION_MINUTES_MIN = 5;
|
|
291
|
+
exports.RESERVATION_MINUTES_MAX = 43_200;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eingehende Konto-Webhooks der Lager-API: Signatur pruefen, Ereignis lesen.
|
|
3
|
+
*
|
|
4
|
+
* Dasselbe Verfahren wie bei Partner-Webhooks (Backend
|
|
5
|
+
* `gemeinsam/webhook-core.js`, `signaturKopf`/`pruefeSignatur`): Kopf
|
|
6
|
+
* `X-Kasseneck-Signature: t=<unix-sekunden>,v1=<hex>` mit
|
|
7
|
+
* `v1 = HMAC-SHA256(secret, "<t>.<roher Rumpf>")`, Zeitfenster 300 Sekunden in
|
|
8
|
+
* beide Richtungen, zeitkonstanter Vergleich, mehrere `v1=`-Anteile erlaubt.
|
|
9
|
+
* Die Pruefung selbst liegt in `partner/webhook-signatur.ts` und wird hier nur
|
|
10
|
+
* mit der Form `(secret, kopf, rumpf, optionen)` angeboten.
|
|
11
|
+
*
|
|
12
|
+
* Reihenfolge im Empfaenger: **erst pruefen, dann lesen**, und dabei den
|
|
13
|
+
* **rohen** Rumpf nehmen (in Express `express.raw({ type: '*\/*' })` vor jedem
|
|
14
|
+
* JSON-Parser).
|
|
15
|
+
*/
|
|
16
|
+
import type { InventoryWebhookEvent } from './typen.js';
|
|
17
|
+
export { WEBHOOK_SIGNATURE_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_TOLERANCE_SEC, } from '../partner/webhook-signatur.js';
|
|
18
|
+
export interface VerifyInventoryWebhookOptions {
|
|
19
|
+
/** Erlaubte Abweichung des Zeitstempels in Sekunden, in beide Richtungen; Vorgabe 300. */
|
|
20
|
+
toleranceSec?: number;
|
|
21
|
+
/** Jetzt: ein `Date` oder Millisekunden seit 1970 (wie `Date.now()`). Vorgabe: die Systemuhr. */
|
|
22
|
+
now?: Date | number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Prueft die Signatur einer Zustellung. `true` nur, wenn Kopf, Zeitfenster
|
|
26
|
+
* und HMAC stimmen; jede schlechte Eingabe und jede Ausnahme ist `false`,
|
|
27
|
+
* nie ein Wurf.
|
|
28
|
+
*
|
|
29
|
+
* **Asynchron**, weil die Pruefung WebCrypto (`crypto.subtle`) benutzt: das
|
|
30
|
+
* Paket hat keine Laufzeitabhaengigkeit und laeuft auch im Browser.
|
|
31
|
+
*
|
|
32
|
+
* @param secret das Secret aus `createWebhook`/`rotateWebhookSecret`; eine
|
|
33
|
+
* Liste erlaubt den Wechsel (es reicht, wenn eines passt)
|
|
34
|
+
* @param header der Wert von `X-Kasseneck-Signature`, unveraendert
|
|
35
|
+
* @param rawBody der **rohe** Rumpf (Text oder Bytes), nicht `JSON.parse` + `stringify`
|
|
36
|
+
*/
|
|
37
|
+
export declare function verifyInventoryWebhookSignature(secret: string | readonly string[], header: string | null | undefined, rawBody: string | Uint8Array, options?: VerifyInventoryWebhookOptions): Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* Liest eine Zustellung als typisiertes Ereignis. Vorher die Signatur pruefen
|
|
40
|
+
* ([verifyInventoryWebhookSignature]).
|
|
41
|
+
*
|
|
42
|
+
* - Ein Ereignis, das diese Paketversion nicht kennt (etwa `variant_group.*`
|
|
43
|
+
* einer spaeteren Stufe), ergibt `null`: mit 2xx antworten und uebergehen.
|
|
44
|
+
* - `reservation.expired|released|redeemed` tragen die Reservierung wie
|
|
45
|
+
* `getReservation`, mit dem Status nach dem Vorgang (seit 1.5.0).
|
|
46
|
+
* - Ein Rumpf, der keine Huelle ist, oder eine Bruchzahl in einer Menge wirft
|
|
47
|
+
* `KasseneckValidationError` (`scope: 'response'`).
|
|
48
|
+
*
|
|
49
|
+
* **Entdoppeln** auf `event.id`; **Stand statt Aenderung**: einen gespeicherten
|
|
50
|
+
* Bestand nur ueberschreiben, wenn `data.sequence` groesser ist.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseInventoryWebhookEvent(rawBody: string | Uint8Array): InventoryWebhookEvent | null;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Eingehende Konto-Webhooks der Lager-API: Signatur pruefen, Ereignis lesen.
|
|
4
|
+
*
|
|
5
|
+
* Dasselbe Verfahren wie bei Partner-Webhooks (Backend
|
|
6
|
+
* `gemeinsam/webhook-core.js`, `signaturKopf`/`pruefeSignatur`): Kopf
|
|
7
|
+
* `X-Kasseneck-Signature: t=<unix-sekunden>,v1=<hex>` mit
|
|
8
|
+
* `v1 = HMAC-SHA256(secret, "<t>.<roher Rumpf>")`, Zeitfenster 300 Sekunden in
|
|
9
|
+
* beide Richtungen, zeitkonstanter Vergleich, mehrere `v1=`-Anteile erlaubt.
|
|
10
|
+
* Die Pruefung selbst liegt in `partner/webhook-signatur.ts` und wird hier nur
|
|
11
|
+
* mit der Form `(secret, kopf, rumpf, optionen)` angeboten.
|
|
12
|
+
*
|
|
13
|
+
* Reihenfolge im Empfaenger: **erst pruefen, dann lesen**, und dabei den
|
|
14
|
+
* **rohen** Rumpf nehmen (in Express `express.raw({ type: '*\/*' })` vor jedem
|
|
15
|
+
* JSON-Parser).
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.WEBHOOK_TOLERANCE_SEC = exports.WEBHOOK_DELIVERY_HEADER = exports.WEBHOOK_EVENT_HEADER = exports.WEBHOOK_SIGNATURE_HEADER = void 0;
|
|
19
|
+
exports.verifyInventoryWebhookSignature = verifyInventoryWebhookSignature;
|
|
20
|
+
exports.parseInventoryWebhookEvent = parseInventoryWebhookEvent;
|
|
21
|
+
const errors_js_1 = require("../client/errors.js");
|
|
22
|
+
const webhook_signatur_js_1 = require("../partner/webhook-signatur.js");
|
|
23
|
+
const lesen_js_1 = require("./lesen.js");
|
|
24
|
+
const vertrag_js_1 = require("./vertrag.js");
|
|
25
|
+
var webhook_signatur_js_2 = require("../partner/webhook-signatur.js");
|
|
26
|
+
Object.defineProperty(exports, "WEBHOOK_SIGNATURE_HEADER", { enumerable: true, get: function () { return webhook_signatur_js_2.WEBHOOK_SIGNATURE_HEADER; } });
|
|
27
|
+
Object.defineProperty(exports, "WEBHOOK_EVENT_HEADER", { enumerable: true, get: function () { return webhook_signatur_js_2.WEBHOOK_EVENT_HEADER; } });
|
|
28
|
+
Object.defineProperty(exports, "WEBHOOK_DELIVERY_HEADER", { enumerable: true, get: function () { return webhook_signatur_js_2.WEBHOOK_DELIVERY_HEADER; } });
|
|
29
|
+
Object.defineProperty(exports, "WEBHOOK_TOLERANCE_SEC", { enumerable: true, get: function () { return webhook_signatur_js_2.WEBHOOK_TOLERANCE_SEC; } });
|
|
30
|
+
/**
|
|
31
|
+
* Prueft die Signatur einer Zustellung. `true` nur, wenn Kopf, Zeitfenster
|
|
32
|
+
* und HMAC stimmen; jede schlechte Eingabe und jede Ausnahme ist `false`,
|
|
33
|
+
* nie ein Wurf.
|
|
34
|
+
*
|
|
35
|
+
* **Asynchron**, weil die Pruefung WebCrypto (`crypto.subtle`) benutzt: das
|
|
36
|
+
* Paket hat keine Laufzeitabhaengigkeit und laeuft auch im Browser.
|
|
37
|
+
*
|
|
38
|
+
* @param secret das Secret aus `createWebhook`/`rotateWebhookSecret`; eine
|
|
39
|
+
* Liste erlaubt den Wechsel (es reicht, wenn eines passt)
|
|
40
|
+
* @param header der Wert von `X-Kasseneck-Signature`, unveraendert
|
|
41
|
+
* @param rawBody der **rohe** Rumpf (Text oder Bytes), nicht `JSON.parse` + `stringify`
|
|
42
|
+
*/
|
|
43
|
+
async function verifyInventoryWebhookSignature(secret, header, rawBody, options = {}) {
|
|
44
|
+
try {
|
|
45
|
+
const jetzt = options.now instanceof Date ? options.now.getTime() : options.now;
|
|
46
|
+
const nowSec = typeof jetzt === 'number' && Number.isFinite(jetzt) ? Math.floor(jetzt / 1000) : undefined;
|
|
47
|
+
const r = await (0, webhook_signatur_js_1.verifyWebhookSignature)({
|
|
48
|
+
secret,
|
|
49
|
+
signatureHeader: header,
|
|
50
|
+
body: rawBody,
|
|
51
|
+
...(nowSec === undefined ? {} : { nowSec }),
|
|
52
|
+
...(options.toleranceSec === undefined ? {} : { toleranceSec: options.toleranceSec }),
|
|
53
|
+
});
|
|
54
|
+
return r.ok;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const BEKANNT = new Set(vertrag_js_1.INVENTORY_WEBHOOK_EVENTS);
|
|
61
|
+
function kaputt(grund) {
|
|
62
|
+
return new errors_js_1.KasseneckValidationError('parseInventoryWebhookEvent', grund, 'response');
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Liest eine Zustellung als typisiertes Ereignis. Vorher die Signatur pruefen
|
|
66
|
+
* ([verifyInventoryWebhookSignature]).
|
|
67
|
+
*
|
|
68
|
+
* - Ein Ereignis, das diese Paketversion nicht kennt (etwa `variant_group.*`
|
|
69
|
+
* einer spaeteren Stufe), ergibt `null`: mit 2xx antworten und uebergehen.
|
|
70
|
+
* - `reservation.expired|released|redeemed` tragen die Reservierung wie
|
|
71
|
+
* `getReservation`, mit dem Status nach dem Vorgang (seit 1.5.0).
|
|
72
|
+
* - Ein Rumpf, der keine Huelle ist, oder eine Bruchzahl in einer Menge wirft
|
|
73
|
+
* `KasseneckValidationError` (`scope: 'response'`).
|
|
74
|
+
*
|
|
75
|
+
* **Entdoppeln** auf `event.id`; **Stand statt Aenderung**: einen gespeicherten
|
|
76
|
+
* Bestand nur ueberschreiben, wenn `data.sequence` groesser ist.
|
|
77
|
+
*/
|
|
78
|
+
function parseInventoryWebhookEvent(rawBody) {
|
|
79
|
+
const text = typeof rawBody === 'string' ? rawBody : new TextDecoder('utf-8').decode(rawBody);
|
|
80
|
+
let roh;
|
|
81
|
+
try {
|
|
82
|
+
roh = JSON.parse(text);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw kaputt('Rumpf ist kein JSON');
|
|
86
|
+
}
|
|
87
|
+
const e = (0, lesen_js_1.objekt)(roh);
|
|
88
|
+
if (!e)
|
|
89
|
+
throw kaputt('Rumpf ist kein Ereignis (kein Objekt)');
|
|
90
|
+
const { id, type, createdAt, accountId, data } = e;
|
|
91
|
+
if (typeof id !== 'string' || id === '' || typeof type !== 'string' || type === '')
|
|
92
|
+
throw kaputt('Ereignis ohne id oder type');
|
|
93
|
+
if (typeof createdAt !== 'number' || !Number.isFinite(createdAt))
|
|
94
|
+
throw kaputt('Ereignis ohne createdAt');
|
|
95
|
+
if (typeof accountId !== 'string' || accountId === '')
|
|
96
|
+
throw kaputt('Ereignis ohne accountId');
|
|
97
|
+
if (!BEKANNT.has(type))
|
|
98
|
+
return null;
|
|
99
|
+
const ort = { name: 'parseInventoryWebhookEvent', pfad: 'data' };
|
|
100
|
+
if (!(0, lesen_js_1.objekt)(data))
|
|
101
|
+
throw kaputt('Ereignis ohne data');
|
|
102
|
+
// Nur ein ausdrueckliches `true` ist eine Probe; im Zweifel der Ernstfall.
|
|
103
|
+
const huelle = { id, type: type, createdAt, accountId, test: e.test === true };
|
|
104
|
+
switch (huelle.type) {
|
|
105
|
+
case 'stock.changed':
|
|
106
|
+
return { ...huelle, type: huelle.type, data: (0, lesen_js_1.bestandGeaendert)(ort, data) };
|
|
107
|
+
case 'stock.below_minimum':
|
|
108
|
+
return { ...huelle, type: huelle.type, data: (0, lesen_js_1.unterMindestbestand)(ort, data) };
|
|
109
|
+
case 'reservation.expired':
|
|
110
|
+
case 'reservation.released':
|
|
111
|
+
case 'reservation.redeemed':
|
|
112
|
+
return { ...huelle, type: huelle.type, data: (0, lesen_js_1.reservierung)(ort, data) };
|
|
113
|
+
default:
|
|
114
|
+
return { ...huelle, type: huelle.type, data: (0, lesen_js_1.artikel)(ort, data) };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -14,8 +14,8 @@ export { createInvoiceApi, type InvoiceApi, type InvoiceApiOptions } from './api
|
|
|
14
14
|
export { invoiceKeyAuth, type InvoiceKeyAuthOptions } from './auth.js';
|
|
15
15
|
export { isInvoiceError, isInvoiceErrorCode, invoiceErrorCode, invoiceFieldErrors, type InvoiceApiErrorCode, type InvoiceFieldError, } from './fehler.js';
|
|
16
16
|
export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoice, getInvoicePdf, getInvoiceSetupStatus, getInvoiceXml, issueInvoice, listBrands, listInvoices, previewInvoice, recordInvoicePayment, searchCustomers, updateCustomer, } from './endpunkte.js';
|
|
17
|
-
export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteItemInput, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, EInvoiceStatus, Invoice, InvoiceDetail, InvoiceDetailPayment, InvoiceItem, InvoiceItemInput, InvoiceListQuery, InvoicePage, InvoiceRecipient, InvoiceSetupGap, InvoiceSetupStatus, InvoiceTotals, InvoiceXml, InvoiceNotice, InvoicePayment, InvoicePreview, InvoiceRateTotals, IssueInvoiceRequest, IssueResult, PaymentInput, PreviewResult, RecordPaymentRequest, RecordPaymentResult, } from './typen.js';
|
|
17
|
+
export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteItemInput, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, EInvoiceStatus, Invoice, InvoiceDetail, InvoiceDetailPayment, InvoiceItem, InvoiceItemInput, IssueInvoiceItemInput, InvoiceListQuery, InvoicePage, InvoiceRecipient, InvoiceSetupGap, InvoiceSetupStatus, InvoiceTotals, InvoiceXml, InvoiceNotice, InvoicePayment, InvoicePreview, InvoiceRateTotals, InvoiceVatIdProof, InvoiceVatIdRisk, IssueInvoiceRequest, IssueResult, PaymentInput, PreviewResult, RecordPaymentRequest, RecordPaymentResult, } from './typen.js';
|
|
18
18
|
export { INVOICE_TEXTS, invoiceText, type InvoiceTextKey } from './texte.js';
|
|
19
19
|
export { computeInvoiceTotals, ZERO_RATED_TAX_SCHEMES, type TotalsItem } from './summen.js';
|
|
20
20
|
export { proratedPriceMicros, MAX_AMOUNT_CENTS, itemFromEuro, formatUnitPrice, CalcError, calculateInvoice, roundDiv, vatRateMapKey, formatVatRate, type CalcResult, type CalcErrorCode, type CalcOptions, type CalcItem, type RateTotal, type ItemConversion, type ConversionReason, type LineAmount, } from './calc.js';
|
|
21
|
-
export { INVOICE_CONTRACT_VERSION, INVOICE_ENDPOINTS, INVOICE_ERROR_CODES, INVOICE_REQUEST_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, EINVOICE_MISSING_CODES, WRITE_OFF_REASON_CODES, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, INVOICE_UNIT_CODES, INVOICE_SETUP_REQUIREMENTS, CUSTOMER_FIELDS, ITEM_FIELDS, CREDIT_NOTE_ITEM_FIELDS, RETURN_DISPOSITIONS, ITEM_PRICE_EXACTLY_ONE, INVOICE_REQUESTS, INVOICE_EXACTLY_ONE, INVOICE_AT_LEAST_ONE, type InvoiceEndpoint, type InvoiceErrorCode, type InvoiceRequestErrorCode, type CreditNoteReason, type ReturnDisposition, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type EInvoiceMissingCode, type WriteOffReasonCode, type InvoiceLanguage, type InvoicePaymentMethod, type ItemKind, type ReverseChargeReason, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type FieldFormat, type Field, } from './vertrag.js';
|
|
21
|
+
export { INVOICE_CONTRACT_VERSION, INVOICE_ENDPOINTS, INVOICE_ERROR_CODES, INVOICE_REQUEST_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, EINVOICE_MISSING_CODES, WRITE_OFF_REASON_CODES, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, INVOICE_UNIT_CODES, INVOICE_SETUP_REQUIREMENTS, CUSTOMER_FIELDS, ITEM_FIELDS, INVOICE_ITEM_FIELDS, CREDIT_NOTE_ITEM_FIELDS, RETURN_DISPOSITIONS, ITEM_PRICE_EXACTLY_ONE, INVOICE_REQUESTS, INVOICE_EXACTLY_ONE, INVOICE_AT_LEAST_ONE, type InvoiceEndpoint, type InvoiceErrorCode, type InvoiceRequestErrorCode, type CreditNoteReason, type ReturnDisposition, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type EInvoiceMissingCode, type WriteOffReasonCode, type InvoiceLanguage, type InvoicePaymentMethod, type ItemKind, type ReverseChargeReason, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type FieldFormat, type Field, } from './vertrag.js';
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.INVOICE_PAYMENT_METHODS = exports.INVOICE_LANGUAGES = exports.WRITE_OFF_REASON_CODES = exports.EINVOICE_MISSING_CODES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_REQUEST_ERROR_CODES = exports.INVOICE_ERROR_CODES = exports.INVOICE_ENDPOINTS = exports.INVOICE_CONTRACT_VERSION = exports.formatVatRate = exports.vatRateMapKey = exports.roundDiv = exports.calculateInvoice = exports.CalcError = exports.formatUnitPrice = exports.itemFromEuro = exports.MAX_AMOUNT_CENTS = exports.proratedPriceMicros = exports.ZERO_RATED_TAX_SCHEMES = exports.computeInvoiceTotals = exports.invoiceText = exports.INVOICE_TEXTS = exports.updateCustomer = exports.searchCustomers = exports.recordInvoicePayment = exports.previewInvoice = exports.listInvoices = exports.listBrands = exports.issueInvoice = exports.getInvoiceXml = exports.getInvoiceSetupStatus = exports.getInvoicePdf = exports.getInvoice = exports.getCustomer = exports.createCustomer = exports.createCreditNote = exports.cancelInvoice = exports.invoiceFieldErrors = exports.invoiceErrorCode = exports.isInvoiceErrorCode = exports.isInvoiceError = exports.invoiceKeyAuth = exports.createInvoiceApi = void 0;
|
|
16
|
-
exports.INVOICE_AT_LEAST_ONE = exports.INVOICE_EXACTLY_ONE = exports.INVOICE_REQUESTS = exports.ITEM_PRICE_EXACTLY_ONE = exports.RETURN_DISPOSITIONS = exports.CREDIT_NOTE_ITEM_FIELDS = exports.ITEM_FIELDS = exports.CUSTOMER_FIELDS = exports.INVOICE_SETUP_REQUIREMENTS = exports.INVOICE_UNIT_CODES = exports.INVOICE_UNITS = exports.INVOICE_NOTICE_CODES = exports.REVERSE_CHARGE_REASONS = exports.ITEM_KINDS = void 0;
|
|
16
|
+
exports.INVOICE_AT_LEAST_ONE = exports.INVOICE_EXACTLY_ONE = exports.INVOICE_REQUESTS = exports.ITEM_PRICE_EXACTLY_ONE = exports.RETURN_DISPOSITIONS = exports.CREDIT_NOTE_ITEM_FIELDS = exports.INVOICE_ITEM_FIELDS = exports.ITEM_FIELDS = exports.CUSTOMER_FIELDS = exports.INVOICE_SETUP_REQUIREMENTS = exports.INVOICE_UNIT_CODES = exports.INVOICE_UNITS = exports.INVOICE_NOTICE_CODES = exports.REVERSE_CHARGE_REASONS = exports.ITEM_KINDS = void 0;
|
|
17
17
|
var api_js_1 = require("./api.js");
|
|
18
18
|
Object.defineProperty(exports, "createInvoiceApi", { enumerable: true, get: function () { return api_js_1.createInvoiceApi; } });
|
|
19
19
|
var auth_js_1 = require("./auth.js");
|
|
@@ -80,6 +80,7 @@ Object.defineProperty(exports, "INVOICE_UNIT_CODES", { enumerable: true, get: fu
|
|
|
80
80
|
Object.defineProperty(exports, "INVOICE_SETUP_REQUIREMENTS", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_SETUP_REQUIREMENTS; } });
|
|
81
81
|
Object.defineProperty(exports, "CUSTOMER_FIELDS", { enumerable: true, get: function () { return vertrag_js_1.CUSTOMER_FIELDS; } });
|
|
82
82
|
Object.defineProperty(exports, "ITEM_FIELDS", { enumerable: true, get: function () { return vertrag_js_1.ITEM_FIELDS; } });
|
|
83
|
+
Object.defineProperty(exports, "INVOICE_ITEM_FIELDS", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_ITEM_FIELDS; } });
|
|
83
84
|
Object.defineProperty(exports, "CREDIT_NOTE_ITEM_FIELDS", { enumerable: true, get: function () { return vertrag_js_1.CREDIT_NOTE_ITEM_FIELDS; } });
|
|
84
85
|
Object.defineProperty(exports, "RETURN_DISPOSITIONS", { enumerable: true, get: function () { return vertrag_js_1.RETURN_DISPOSITIONS; } });
|
|
85
86
|
Object.defineProperty(exports, "ITEM_PRICE_EXACTLY_ONE", { enumerable: true, get: function () { return vertrag_js_1.ITEM_PRICE_EXACTLY_ONE; } });
|