@kreiseck/kasseneck-api 1.4.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 (81) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/README.md +192 -11
  3. package/dist/cjs/client/aufrufe.d.ts +2 -2
  4. package/dist/cjs/client/aufrufe.js +28 -0
  5. package/dist/cjs/inventory/api.d.ts +19 -3
  6. package/dist/cjs/inventory/api.js +18 -2
  7. package/dist/cjs/inventory/endpunkte.d.ts +22 -2
  8. package/dist/cjs/inventory/endpunkte.js +6 -1
  9. package/dist/cjs/inventory/fehler.d.ts +11 -1
  10. package/dist/cjs/inventory/fehler.js +19 -0
  11. package/dist/cjs/inventory/index.d.ts +6 -4
  12. package/dist/cjs/inventory/index.js +32 -2
  13. package/dist/cjs/inventory/lesen.d.ts +8 -1
  14. package/dist/cjs/inventory/lesen.js +131 -1
  15. package/dist/cjs/inventory/schreiben.d.ts +83 -0
  16. package/dist/cjs/inventory/schreiben.js +315 -0
  17. package/dist/cjs/inventory/typen.d.ts +371 -11
  18. package/dist/cjs/inventory/vertrag.d.ts +76 -16
  19. package/dist/cjs/inventory/vertrag.js +138 -13
  20. package/dist/cjs/inventory/webhook.d.ts +3 -1
  21. package/dist/cjs/inventory/webhook.js +7 -1
  22. package/dist/cjs/invoice/index.d.ts +2 -2
  23. package/dist/cjs/invoice/index.js +2 -1
  24. package/dist/cjs/invoice/typen.d.ts +46 -2
  25. package/dist/cjs/invoice/vertrag.d.ts +19 -5
  26. package/dist/cjs/invoice/vertrag.js +37 -5
  27. package/dist/cjs/stored/vokabular.d.ts +1 -1
  28. package/dist/cjs/stored/vokabular.js +5 -3
  29. package/dist/cjs/version.d.ts +1 -1
  30. package/dist/cjs/version.js +1 -1
  31. package/dist/esm/client/aufrufe.d.ts +2 -2
  32. package/dist/esm/client/aufrufe.js +28 -0
  33. package/dist/esm/inventory/api.d.ts +19 -3
  34. package/dist/esm/inventory/api.js +18 -2
  35. package/dist/esm/inventory/endpunkte.d.ts +22 -2
  36. package/dist/esm/inventory/endpunkte.js +6 -5
  37. package/dist/esm/inventory/fehler.d.ts +11 -1
  38. package/dist/esm/inventory/fehler.js +18 -1
  39. package/dist/esm/inventory/index.d.ts +6 -4
  40. package/dist/esm/inventory/index.js +5 -3
  41. package/dist/esm/inventory/lesen.d.ts +8 -1
  42. package/dist/esm/inventory/lesen.js +127 -1
  43. package/dist/esm/inventory/schreiben.d.ts +83 -0
  44. package/dist/esm/inventory/schreiben.js +298 -0
  45. package/dist/esm/inventory/typen.d.ts +371 -11
  46. package/dist/esm/inventory/vertrag.d.ts +76 -16
  47. package/dist/esm/inventory/vertrag.js +137 -12
  48. package/dist/esm/inventory/webhook.d.ts +3 -1
  49. package/dist/esm/inventory/webhook.js +8 -2
  50. package/dist/esm/invoice/index.d.ts +2 -2
  51. package/dist/esm/invoice/index.js +1 -1
  52. package/dist/esm/invoice/typen.d.ts +46 -2
  53. package/dist/esm/invoice/vertrag.d.ts +19 -5
  54. package/dist/esm/invoice/vertrag.js +36 -4
  55. package/dist/esm/stored/vokabular.d.ts +1 -1
  56. package/dist/esm/stored/vokabular.js +5 -3
  57. package/dist/esm/version.d.ts +1 -1
  58. package/dist/esm/version.js +1 -1
  59. package/fixtures/hobex-hps-codes.json +1 -1
  60. package/fixtures/invoice-api-examples/credit-error-reservation.json +26 -0
  61. package/fixtures/invoice-api-examples/issue-error-reservation-article.json +25 -0
  62. package/fixtures/invoice-api-examples/issue-error-vat-id-risk.json +26 -0
  63. package/fixtures/invoice-api-examples/issue-reservation.json +24 -0
  64. package/fixtures/invoice-api-examples/issue-vat-id-risk.json +28 -0
  65. package/fixtures/invoice-api.schema.json +15 -2
  66. package/fixtures/invoice-texts.json +1 -1
  67. package/fixtures/pos-texts.json +1 -1
  68. package/fixtures/surface.json +152 -9
  69. package/fixtures/v3/antworten/belege.json +2 -2
  70. package/fixtures/v3/antworten/belegmail.json +2 -2
  71. package/fixtures/v3/antworten/kasse-belege.json +2 -2
  72. package/fixtures/v3/antworten/kasse.json +3 -3
  73. package/fixtures/v3/antworten/lager.json +2491 -130
  74. package/fixtures/v3/antworten/rechnungen.json +267 -44
  75. package/fixtures/v3/antworten/storno.json +2 -2
  76. package/fixtures/v3/stored/belege.json +2 -2
  77. package/fixtures/v3/stored/kasse.json +3 -3
  78. package/fixtures/v3/stored/rechnungen.json +174 -18
  79. package/fixtures/v3/v3-vokabular.json +593 -23
  80. package/fixtures/v3/zahlbetrag-faelle.json +2 -2
  81. package/package.json +1 -1
@@ -85,6 +85,20 @@ export const ALL_CALLS = [
85
85
  'sendWebhookTest',
86
86
  'rotateWebhookSecret',
87
87
  'listWebhookDeliveries',
88
+ // Lager-API schreiben und Reservierung (Stufe 5b, ./inventory)
89
+ 'createArticle',
90
+ 'updateArticle',
91
+ 'deactivateArticle',
92
+ 'receiveGoods',
93
+ 'transferStock',
94
+ 'recordStockLoss',
95
+ 'changeStockCondition',
96
+ 'reverseStockMovement',
97
+ 'createReservation',
98
+ 'extendReservation',
99
+ 'releaseReservation',
100
+ 'getReservation',
101
+ 'listReservations',
88
102
  ];
89
103
  /**
90
104
  * Die oeffentlichen Endpunkte unter `/v3` (`https://api.kasseneck.at/v3/<name>`),
@@ -171,6 +185,20 @@ export const PUBLIC_CALLS = [
171
185
  'sendWebhookTest',
172
186
  'rotateWebhookSecret',
173
187
  'listWebhookDeliveries',
188
+ // Lager-API schreiben und Reservierung (Backend Stufe 5b), umhuellt in `./inventory`.
189
+ 'createArticle',
190
+ 'updateArticle',
191
+ 'deactivateArticle',
192
+ 'receiveGoods',
193
+ 'transferStock',
194
+ 'recordStockLoss',
195
+ 'changeStockCondition',
196
+ 'reverseStockMovement',
197
+ 'createReservation',
198
+ 'extendReservation',
199
+ 'releaseReservation',
200
+ 'getReservation',
201
+ 'listReservations',
174
202
  ];
175
203
  /**
176
204
  * Die Endpunkte des Kassenwegs (`https://kasse.kasseneck.at/api/v3/<name>`,
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Fassade ueber den Aufrufen der Lager-API: Schluessel einmal binden, dann
3
- * rufen. Wie [createInvoiceApi] bewusst keine Klasse; die Aufrufe sind freie
2
+ * Fassade ueber den Aufrufen der Lager-API (lesen, Webhooks, schreiben,
3
+ * reservieren): Schluessel einmal binden, dann rufen. Wie [createInvoiceApi] bewusst keine Klasse; die Aufrufe sind freie
4
4
  * Funktionen (endpunkte.ts) und bleiben einzeln importierbar.
5
5
  */
6
6
  import { type FetchLike } from '../client/transport.js';
7
- import type { Article, ArticleListQuery, ArticleLookup, ArticlePage, CreateInventoryWebhookOptions, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookList, InventoryWebhookPatch, InventoryWebhookTestResult, InventoryWebhookWithSecret, Location, StockLevel, StockListQuery, StockMovement, StockMovementPage, StockMovementQuery, StockPage, StockResult } from './typen.js';
7
+ import type { Article, ChangeStockConditionRequest, CreateArticleRequest, CreateReservationRequest, DeactivateArticleRequest, ExtendReservationRequest, GoodsReceiptPreview, GoodsReceiptPreviewRequest, ReceiveGoodsRequest, RecordStockLossRequest, ReleaseReservationRequest, Reservation, ReservationListQuery, ReservationPage, ReverseStockMovementRequest, StockOperation, TransferStockRequest, UpdateArticleRequest, ArticleListQuery, ArticleLookup, ArticlePage, CreateInventoryWebhookOptions, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookList, InventoryWebhookPatch, InventoryWebhookTestResult, InventoryWebhookWithSecret, Location, StockLevel, StockListQuery, StockMovement, StockMovementPage, StockMovementQuery, StockPage, StockResult } from './typen.js';
8
8
  import type { InventoryWebhookEventType } from './vertrag.js';
9
9
  export interface InventoryClientOptions {
10
10
  /** `api_key` des Kontos (`kr_live_…` / `kr_test_…`). Gehoert auf einen Server. */
@@ -41,5 +41,21 @@ export interface InventoryClient {
41
41
  webhookId?: string;
42
42
  limit?: number;
43
43
  }): Promise<InventoryWebhookDelivery[]>;
44
+ createArticle(request: CreateArticleRequest): Promise<Article>;
45
+ updateArticle(request: UpdateArticleRequest): Promise<Article>;
46
+ deactivateArticle(request: DeactivateArticleRequest): Promise<Article>;
47
+ receiveGoods(request: ReceiveGoodsRequest): Promise<StockOperation>;
48
+ /** `receiveGoods` mit `dryRun: true`: rechnet, schreibt nichts, Schluessel freigestellt. */
49
+ previewGoodsReceipt(request: GoodsReceiptPreviewRequest): Promise<GoodsReceiptPreview>;
50
+ transferStock(request: TransferStockRequest): Promise<StockOperation>;
51
+ recordStockLoss(request: RecordStockLossRequest): Promise<StockOperation>;
52
+ changeStockCondition(request: ChangeStockConditionRequest): Promise<StockOperation>;
53
+ reverseStockMovement(request: ReverseStockMovementRequest): Promise<StockOperation>;
54
+ createReservation(request: CreateReservationRequest): Promise<Reservation>;
55
+ extendReservation(request: ExtendReservationRequest): Promise<Reservation>;
56
+ releaseReservation(request: ReleaseReservationRequest): Promise<Reservation>;
57
+ getReservation(reservationId: string): Promise<Reservation>;
58
+ listReservations(query?: ReservationListQuery): Promise<ReservationPage>;
59
+ iterateReservations(query?: ReservationListQuery): AsyncGenerator<Reservation, void, undefined>;
44
60
  }
45
61
  export declare function createInventoryClient(options: InventoryClientOptions): InventoryClient;
@@ -1,11 +1,12 @@
1
1
  /**
2
- * Fassade ueber den Aufrufen der Lager-API: Schluessel einmal binden, dann
3
- * rufen. Wie [createInvoiceApi] bewusst keine Klasse; die Aufrufe sind freie
2
+ * Fassade ueber den Aufrufen der Lager-API (lesen, Webhooks, schreiben,
3
+ * reservieren): Schluessel einmal binden, dann rufen. Wie [createInvoiceApi] bewusst keine Klasse; die Aufrufe sind freie
4
4
  * Funktionen (endpunkte.ts) und bleiben einzeln importierbar.
5
5
  */
6
6
  import { createTransport } from '../client/transport.js';
7
7
  import { inventoryKeyAuth } from './auth.js';
8
8
  import { createWebhook, deleteWebhook, getArticle, getStock, iterateArticles, iterateStock, iterateStockMovements, listArticles, listLocations, listStock, listStockMovements, listWebhookDeliveries, listWebhooks, lookupArticleByCode, rotateWebhookSecret, sendWebhookTest, updateWebhook, } from './endpunkte.js';
9
+ import { changeStockCondition, createArticle, createReservation, deactivateArticle, extendReservation, getReservation, iterateReservations, listReservations, previewGoodsReceipt, receiveGoods, recordStockLoss, releaseReservation, reverseStockMovement, transferStock, updateArticle, } from './schreiben.js';
9
10
  export function createInventoryClient(options) {
10
11
  const rufen = createTransport({
11
12
  auth: inventoryKeyAuth({ apiKey: options.apiKey }),
@@ -31,5 +32,20 @@ export function createInventoryClient(options) {
31
32
  sendWebhookTest: (id, event) => sendWebhookTest(rufen, id, event),
32
33
  rotateWebhookSecret: (id) => rotateWebhookSecret(rufen, id),
33
34
  listWebhookDeliveries: (o) => listWebhookDeliveries(rufen, o),
35
+ createArticle: (r) => createArticle(rufen, r),
36
+ updateArticle: (r) => updateArticle(rufen, r),
37
+ deactivateArticle: (r) => deactivateArticle(rufen, r),
38
+ receiveGoods: (r) => receiveGoods(rufen, r),
39
+ previewGoodsReceipt: (r) => previewGoodsReceipt(rufen, r),
40
+ transferStock: (r) => transferStock(rufen, r),
41
+ recordStockLoss: (r) => recordStockLoss(rufen, r),
42
+ changeStockCondition: (r) => changeStockCondition(rufen, r),
43
+ reverseStockMovement: (r) => reverseStockMovement(rufen, r),
44
+ createReservation: (r) => createReservation(rufen, r),
45
+ extendReservation: (r) => extendReservation(rufen, r),
46
+ releaseReservation: (r) => releaseReservation(rufen, r),
47
+ getReservation: (id) => getReservation(rufen, id),
48
+ listReservations: (q) => listReservations(rufen, q),
49
+ iterateReservations: (q) => iterateReservations(rufen, q),
34
50
  };
35
51
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Die Aufrufe der Lager-API: Artikel, Standorte, Bestand und Bewegungen
3
- * lesen, Konto-Webhooks verwalten (Backend Stufe 5a).
3
+ * lesen, Konto-Webhooks verwalten (Backend Stufe 5a). Die schreibenden
4
+ * Aufrufe (Stufe 5b) stehen in `schreiben.ts` und teilen die Helfer hier.
4
5
  *
5
6
  * Jede Funktion nimmt den Transport als ersten Parameter und ist einzeln
6
7
  * importierbar; die Fassade [createInventoryClient] bindet ihn nur einmal.
@@ -14,8 +15,26 @@
14
15
  * wiederholt werden. Bei `rate_limited` vorher `retryAfterSec` warten
15
16
  * ([inventoryRetryAfterSec]).
16
17
  */
17
- import type { InternerTransport } from '../client/aufrufe.js';
18
+ import type { ApiCall, InternerTransport } from '../client/aufrufe.js';
19
+ import { KasseneckValidationError } from '../client/errors.js';
18
20
  import type { Article, ArticleListQuery, ArticleLookup, ArticlePage, CreateInventoryWebhookOptions, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookList, InventoryWebhookPatch, InventoryWebhookTestResult, InventoryWebhookWithSecret, Location, StockLevel, StockListQuery, StockMovement, StockMovementPage, StockMovementQuery, StockPage, StockResult } from './typen.js';
21
+ type Params = Record<string, unknown>;
22
+ export declare function anfragefehler(name: ApiCall, grund: string): KasseneckValidationError;
23
+ /** Eine Kennung, die gesendet werden muss: Text mit mindestens einem Zeichen ausser Leerraum. */
24
+ export declare function kennung(name: ApiCall, feld: string, wert: unknown): string;
25
+ /**
26
+ * Die Abfrage einer Liste als Parameter. Unbekannte Felder gehen unveraendert
27
+ * hinaus (der Server weist sie mit `validation` ab), `undefined` faellt weg.
28
+ */
29
+ export declare function abfrage(name: ApiCall, query: object | undefined): Params;
30
+ /**
31
+ * Blaettert ueber alle Seiten, Eintrag fuer Eintrag. Derselbe Cursor zweimal
32
+ * waere eine Endlosschleife: dann endet die Schleife mit einem Antwortfehler.
33
+ */
34
+ export declare function seitenweise<T>(name: ApiCall, start: string | undefined, seite: (cursor: string | undefined) => Promise<{
35
+ eintraege: T[];
36
+ nextCursor: string | null;
37
+ }>): AsyncGenerator<T, void, undefined>;
19
38
  export declare function getArticle(transport: InternerTransport, articleId: string): Promise<Article>;
20
39
  export declare function listArticles(transport: InternerTransport, query?: ArticleListQuery): Promise<ArticlePage>;
21
40
  /** Alle Artikel der Abfrage, Seite fuer Seite ueber `nextCursor`. */
@@ -69,3 +88,4 @@ export declare function listWebhookDeliveries(transport: InternerTransport, opti
69
88
  webhookId?: string;
70
89
  limit?: number;
71
90
  }): Promise<InventoryWebhookDelivery[]>;
91
+ export {};
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Die Aufrufe der Lager-API: Artikel, Standorte, Bestand und Bewegungen
3
- * lesen, Konto-Webhooks verwalten (Backend Stufe 5a).
3
+ * lesen, Konto-Webhooks verwalten (Backend Stufe 5a). Die schreibenden
4
+ * Aufrufe (Stufe 5b) stehen in `schreiben.ts` und teilen die Helfer hier.
4
5
  *
5
6
  * Jede Funktion nimmt den Transport als ersten Parameter und ist einzeln
6
7
  * importierbar; die Fassade [createInventoryClient] bindet ihn nur einmal.
@@ -17,11 +18,11 @@
17
18
  import { KasseneckValidationError } from '../client/errors.js';
18
19
  import { antwortfehler, artikel, bestand, bewegung, liste, naechsterCursor, objekt, probeZustellung, standort, webhook, wert, zustellung, } from './lesen.js';
19
20
  import { INVENTORY_LIST_LIMIT_MAX } from './vertrag.js';
20
- function anfragefehler(name, grund) {
21
+ export function anfragefehler(name, grund) {
21
22
  return new KasseneckValidationError(name, grund, 'request');
22
23
  }
23
24
  /** Eine Kennung, die gesendet werden muss: Text mit mindestens einem Zeichen ausser Leerraum. */
24
- function kennung(name, feld, wert) {
25
+ export function kennung(name, feld, wert) {
25
26
  if (typeof wert !== 'string' || wert.trim() === '')
26
27
  throw anfragefehler(name, `${feld} fehlt`);
27
28
  return wert;
@@ -32,7 +33,7 @@ const ZEITFELDER = new Set(['updatedSince', 'changedSince', 'from', 'to']);
32
33
  * Die Abfrage einer Liste als Parameter. Unbekannte Felder gehen unveraendert
33
34
  * hinaus (der Server weist sie mit `validation` ab), `undefined` faellt weg.
34
35
  */
35
- function abfrage(name, query) {
36
+ export function abfrage(name, query) {
36
37
  if (query === undefined || query === null)
37
38
  return {};
38
39
  if (typeof query !== 'object' || Array.isArray(query))
@@ -63,7 +64,7 @@ function abfrage(name, query) {
63
64
  * Blaettert ueber alle Seiten, Eintrag fuer Eintrag. Derselbe Cursor zweimal
64
65
  * waere eine Endlosschleife: dann endet die Schleife mit einem Antwortfehler.
65
66
  */
66
- async function* seitenweise(name, start, seite) {
67
+ export async function* seitenweise(name, start, seite) {
67
68
  const gesehen = new Set();
68
69
  // Auch der Startcursor zaehlt: nennt die erste Antwort ihn wieder, waere es dieselbe Seite.
69
70
  if (start)
@@ -8,7 +8,8 @@
8
8
  * `KasseneckApiError.code`.
9
9
  */
10
10
  import type { KasseneckApiError } from '../client/errors.js';
11
- import { type InventoryErrorCode, type InventoryRequestErrorCode } from './vertrag.js';
11
+ import type { InventoryShortfall } from './typen.js';
12
+ import { type InventoryErrorCode, type InventoryRequestErrorCode, type InventoryWarningCode } from './vertrag.js';
12
13
  /** Ein Code, den ein Lager-Aufruf liefern kann. */
13
14
  export type InventoryApiErrorCode = InventoryErrorCode | InventoryRequestErrorCode;
14
15
  export declare function isInventoryErrorCode(value: unknown): value is InventoryApiErrorCode;
@@ -31,3 +32,12 @@ export declare function inventoryFieldErrors(error: unknown): InventoryFieldErro
31
32
  * Konto (etwa 20 Anfragen je Sekunde, kurze Spitzen bis 40).
32
33
  */
33
34
  export declare function inventoryRetryAfterSec(error: unknown): number | undefined;
35
+ /**
36
+ * Die Positionen, fuer die beim Reservieren der verfuegbare Bestand nicht
37
+ * reicht (`insufficient_available`, `data.details[]`): je Artikel und Standort
38
+ * angefragt und verfuegbar, in Tausendstel. Leer, wenn der Fehler ein anderer
39
+ * ist. Es fehlen nur diese Positionen; reserviert wurde nichts.
40
+ */
41
+ export declare function inventoryShortfalls(error: unknown): InventoryShortfall[];
42
+ /** `true` fuer einen Hinweis-Code einer Buchung (`warnings[].code`); Hinweise sind nie Fehler. */
43
+ export declare function isInventoryWarningCode(value: unknown): value is InventoryWarningCode;
@@ -8,7 +8,8 @@
8
8
  * `KasseneckApiError.code`.
9
9
  */
10
10
  import { bekannterCode, feldfehlerVon } from '../client/fehlercodes.js';
11
- import { INVENTORY_ERROR_CODES, INVENTORY_REQUEST_ERROR_CODES, } from './vertrag.js';
11
+ import { fehlmengen } from './lesen.js';
12
+ import { INVENTORY_ERROR_CODES, INVENTORY_REQUEST_ERROR_CODES, INVENTORY_WARNING_CODES, } from './vertrag.js';
12
13
  const BEKANNT = new Set([...INVENTORY_ERROR_CODES, ...INVENTORY_REQUEST_ERROR_CODES]);
13
14
  export function isInventoryErrorCode(value) {
14
15
  return typeof value === 'string' && BEKANNT.has(value);
@@ -38,3 +39,19 @@ export function inventoryRetryAfterSec(error) {
38
39
  const wert = error.details['retryAfterSec'];
39
40
  return typeof wert === 'number' && Number.isFinite(wert) && wert >= 0 ? wert : undefined;
40
41
  }
42
+ /**
43
+ * Die Positionen, fuer die beim Reservieren der verfuegbare Bestand nicht
44
+ * reicht (`insufficient_available`, `data.details[]`): je Artikel und Standort
45
+ * angefragt und verfuegbar, in Tausendstel. Leer, wenn der Fehler ein anderer
46
+ * ist. Es fehlen nur diese Positionen; reserviert wurde nichts.
47
+ */
48
+ export function inventoryShortfalls(error) {
49
+ if (inventoryErrorCode(error) !== 'insufficient_available')
50
+ return [];
51
+ return fehlmengen(error.details['details']);
52
+ }
53
+ const HINWEISE = new Set(INVENTORY_WARNING_CODES);
54
+ /** `true` fuer einen Hinweis-Code einer Buchung (`warnings[].code`); Hinweise sind nie Fehler. */
55
+ export function isInventoryWarningCode(value) {
56
+ return typeof value === 'string' && HINWEISE.has(value);
57
+ }
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * `@kreiseck/kasseneck-api/inventory` – die Lager-API: Artikel, Standorte,
3
3
  * Bestand und Lagerprotokoll lesen, Konto-Webhooks verwalten und eingehende
4
- * Zustellungen pruefen (Backend Stufe 5a).
4
+ * Zustellungen pruefen (Backend Stufe 5a); Artikel anlegen und aendern,
5
+ * Bestand buchen und Ware reservieren (Stufe 5b, seit 1.5.0).
5
6
  *
6
7
  * Ein eigener Unterpfad wie `invoice`: der `api_key` eines Kontos gehoert auf
7
8
  * einen **Server** (etwa das Backend eines Online-Shops) und soll nicht
@@ -12,8 +13,9 @@
12
13
  */
13
14
  export { createInventoryClient, type InventoryClient, type InventoryClientOptions } from './api.js';
14
15
  export { inventoryKeyAuth, type InventoryKeyAuthOptions } from './auth.js';
15
- export { isInventoryError, isInventoryErrorCode, inventoryErrorCode, inventoryFieldErrors, inventoryRetryAfterSec, type InventoryApiErrorCode, type InventoryFieldError, } from './fehler.js';
16
+ export { isInventoryError, isInventoryErrorCode, inventoryErrorCode, inventoryFieldErrors, inventoryRetryAfterSec, inventoryShortfalls, isInventoryWarningCode, type InventoryApiErrorCode, type InventoryFieldError, } from './fehler.js';
16
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';
17
19
  export { verifyInventoryWebhookSignature, parseInventoryWebhookEvent, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_TOLERANCE_SEC, type VerifyInventoryWebhookOptions, } from './webhook.js';
18
- export type { Article, ArticleListQuery, ArticleLookup, ArticlePage, CreateInventoryWebhookOptions, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookEnvelope, InventoryWebhookEvent, InventoryWebhookList, InventoryWebhookPatch, InventoryWebhookTestDelivery, InventoryWebhookTestResult, InventoryWebhookWithSecret, Location, LocationAddress, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockListQuery, StockMovement, StockMovementLot, StockMovementPage, StockMovementQuery, StockMovementSourceRef, StockPage, StockResult, StockValue, } from './typen.js';
19
- 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, type InventoryEndpoint, type InventoryErrorCode, type InventoryRequestErrorCode, type InventoryWebhookEventType, type LocationType, type StockMovementType, type StockMovementSource, type StockCondition, type StockChangeCause, type WebhookDeliveryStatus, } from './vertrag.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';
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * `@kreiseck/kasseneck-api/inventory` – die Lager-API: Artikel, Standorte,
3
3
  * Bestand und Lagerprotokoll lesen, Konto-Webhooks verwalten und eingehende
4
- * Zustellungen pruefen (Backend Stufe 5a).
4
+ * Zustellungen pruefen (Backend Stufe 5a); Artikel anlegen und aendern,
5
+ * Bestand buchen und Ware reservieren (Stufe 5b, seit 1.5.0).
5
6
  *
6
7
  * Ein eigener Unterpfad wie `invoice`: der `api_key` eines Kontos gehoert auf
7
8
  * einen **Server** (etwa das Backend eines Online-Shops) und soll nicht
@@ -12,7 +13,8 @@
12
13
  */
13
14
  export { createInventoryClient } from './api.js';
14
15
  export { inventoryKeyAuth } from './auth.js';
15
- export { isInventoryError, isInventoryErrorCode, inventoryErrorCode, inventoryFieldErrors, inventoryRetryAfterSec, } from './fehler.js';
16
+ export { isInventoryError, isInventoryErrorCode, inventoryErrorCode, inventoryFieldErrors, inventoryRetryAfterSec, inventoryShortfalls, isInventoryWarningCode, } from './fehler.js';
16
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';
17
19
  export { verifyInventoryWebhookSignature, parseInventoryWebhookEvent, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_TOLERANCE_SEC, } from './webhook.js';
18
- 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, } from './vertrag.js';
20
+ 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, } from './vertrag.js';
@@ -12,7 +12,7 @@
12
12
  * wenn der Server sie sendet: „fehlt“ heisst dort „kein Recht“, nicht „leer“.
13
13
  */
14
14
  import { KasseneckValidationError } from '../client/errors.js';
15
- import type { Article, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookTestDelivery, Location, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockMovement, StockValue } from './typen.js';
15
+ import type { Article, GoodsReceiptPreviewLine, InventoryShortfall, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookTestDelivery, Location, Reservation, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockMovement, StockOperation, StockValue } from './typen.js';
16
16
  type Roh = Record<string, unknown>;
17
17
  /** Ein Leser bekommt den Vorgang (fuer die Meldung) und den Pfad im Rumpf. */
18
18
  export interface Ort {
@@ -31,6 +31,13 @@ export declare function zustellung(ort: Ort, w: unknown): InventoryWebhookDelive
31
31
  export declare function probeZustellung(ort: Ort, w: unknown, webhookId: string): InventoryWebhookTestDelivery;
32
32
  export declare function bestandGeaendert(ort: Ort, w: unknown): StockChangedEventData;
33
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[];
34
41
  /** Eine zugesagte Liste `data.<feld>`, Eintrag fuer Eintrag gelesen. */
35
42
  export declare function liste<T>(name: string, daten: unknown, feld: string, lesen: (ort: Ort, e: unknown) => T): T[];
36
43
  /** Der Cursor der naechsten Seite; `null` am Ende. Etwas anderes als Text oder `null` ist kaputt. */
@@ -59,6 +59,30 @@ function textAbbildung(w) {
59
59
  raus[k] = v;
60
60
  return raus;
61
61
  }
62
+ /**
63
+ * Mengen je Standort (`minStockByLocation`): jeder Wert eine Ganzzahl. Fehlt
64
+ * das Feld (Server vor Stufe 5b), gilt „keiner“ (`{}`).
65
+ */
66
+ function mengenJeStandort(ort, feld, w) {
67
+ if (w === undefined || w === null)
68
+ return {};
69
+ const o = objekt(w);
70
+ if (!o)
71
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.${feld} ist kein Objekt)`);
72
+ const raus = {};
73
+ for (const [k, v] of Object.entries(o))
74
+ raus[k] = ganzzahl(ort, `${feld}.${k}`, v);
75
+ return raus;
76
+ }
77
+ /** Eine Liste von Kennungen (`movementIds`, `lotIds`); fehlt sie, ist sie leer. */
78
+ function kennungsliste(ort, feld, w) {
79
+ if (w === undefined || w === null)
80
+ return [];
81
+ if (!Array.isArray(w) || !w.every((x) => typeof x === 'string')) {
82
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}${ort.pfad ? '.' : ''}${feld} ist keine Liste von Kennungen)`);
83
+ }
84
+ return [...w];
85
+ }
62
86
  // ---- Artikel ------------------------------------------------------------------
63
87
  export function artikel(ort, w) {
64
88
  const a = eintrag(ort, w);
@@ -76,6 +100,7 @@ export function artikel(ort, w) {
76
100
  const raus = {
77
101
  id: kennung(ort, 'id', a.id),
78
102
  name: text(a.name),
103
+ description: text(a.description),
79
104
  unitPriceCents: ganzzahlOderNull(ort, 'unitPriceCents', a.unitPriceCents),
80
105
  vatRate: typeof vatRate === 'number' ? vatRate : null,
81
106
  unit: text(a.unit),
@@ -85,8 +110,10 @@ export function artikel(ort, w) {
85
110
  groupId: text(a.groupId),
86
111
  revenueGroupId: text(a.revenueGroupId),
87
112
  stockTracked: a.stockTracked === true,
113
+ stockKind: textOderNull(a.stockKind),
88
114
  stockLocationIds: standorte,
89
115
  minStock: ganzzahlOderNull(ort, 'minStock', a.minStock),
116
+ minStockByLocation: mengenJeStandort(ort, 'minStockByLocation', a.minStockByLocation),
90
117
  active: a.active !== false,
91
118
  createdAt: text(a.createdAt),
92
119
  updatedAt: text(a.updatedAt),
@@ -173,8 +200,14 @@ export function bewegung(ort, w) {
173
200
  locationId: text(b.locationId),
174
201
  condition: text(b.condition),
175
202
  quantityDelta: ganzzahl(ort, 'quantityDelta', b.quantityDelta),
203
+ // Server vor Stufe 5b senden das Feld nicht: dort aenderte keine Bewegung `reserved`.
204
+ reservedDelta: b.reservedDelta === undefined ? 0 : ganzzahl(ort, 'reservedDelta', b.reservedDelta),
176
205
  stockAfter: nachher
177
- ? { sellable: ganzzahl(nachherOrt, 'sellable', nachher.sellable), defective: ganzzahl(nachherOrt, 'defective', nachher.defective) }
206
+ ? {
207
+ sellable: ganzzahl(nachherOrt, 'sellable', nachher.sellable),
208
+ defective: ganzzahl(nachherOrt, 'defective', nachher.defective),
209
+ reserved: ganzzahlOderNull(nachherOrt, 'reserved', nachher.reserved),
210
+ }
178
211
  : null,
179
212
  operationId: text(b.operationId),
180
213
  source: quelle
@@ -255,6 +288,99 @@ export function unterMindestbestand(ort, w) {
255
288
  minStock: ganzzahl(ort, 'minStock', d.minStock),
256
289
  };
257
290
  }
291
+ // ---- Schreiben (Stufe 5b) ------------------------------------------------------------
292
+ function warnung(ort, w) {
293
+ const h = eintrag(ort, w);
294
+ if (typeof h.code !== 'string' || h.code === '')
295
+ throw antwortfehler(ort.name, `Hinweis ohne Code (data.${ort.pfad}.code)`);
296
+ return {
297
+ code: h.code,
298
+ articleId: textOderNull(h.articleId),
299
+ locationId: textOderNull(h.locationId),
300
+ message: typeof h.message === 'string' ? h.message : '',
301
+ };
302
+ }
303
+ /** Antwort einer Buchung; ohne `operationId` ist nicht belegt, dass gebucht wurde. */
304
+ export function vorgang(name, daten) {
305
+ const d = objekt(daten);
306
+ if (!d)
307
+ throw antwortfehler(name, 'Antwort ist unbrauchbar (data ist kein Objekt)');
308
+ const ort = { name, pfad: '' };
309
+ if (typeof d.operationId !== 'string' || d.operationId === '') {
310
+ throw antwortfehler(name, 'Antwort enthaelt keine Kennung (data.operationId fehlt)');
311
+ }
312
+ const hinweise = d.warnings === undefined || d.warnings === null ? [] : d.warnings;
313
+ if (!Array.isArray(hinweise))
314
+ throw antwortfehler(name, 'Antwort ist unbrauchbar (data.warnings ist keine Liste)');
315
+ return {
316
+ operationId: d.operationId,
317
+ movementIds: kennungsliste(ort, 'movementIds', d.movementIds),
318
+ lotIds: kennungsliste(ort, 'lotIds', d.lotIds),
319
+ warnings: hinweise.map((h, i) => warnung({ name, pfad: `warnings[${i}]` }, h)),
320
+ };
321
+ }
322
+ /** Eine Zeile der Wareneingangs-Vorschau; Werte nur, wenn der Server sie sendet (Recht `costs`). */
323
+ export function vorschauZeile(ort, w) {
324
+ const z = eintrag(ort, w);
325
+ const serien = z.serialNumbers === undefined || z.serialNumbers === null ? [] : z.serialNumbers;
326
+ if (!Array.isArray(serien) || !serien.every((x) => typeof x === 'string')) {
327
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.serialNumbers ist keine Liste)`);
328
+ }
329
+ const raus = {
330
+ articleId: kennung(ort, 'articleId', z.articleId),
331
+ quantity: ganzzahl(ort, 'quantity', z.quantity),
332
+ expiresOn: textOderNull(z.expiresOn),
333
+ batch: textOderNull(z.batch),
334
+ serialNumbers: [...serien],
335
+ priceFromArticle: z.priceFromArticle === true,
336
+ };
337
+ for (const feld of ['baseCents', 'landedCostCents', 'valueCents', 'unitCostMicros']) {
338
+ if (hat(z, feld))
339
+ raus[feld] = ganzzahlOderNull(ort, feld, z[feld]);
340
+ }
341
+ return raus;
342
+ }
343
+ function reservierungsPosition(ort, w) {
344
+ const p = eintrag(ort, w);
345
+ return {
346
+ articleId: kennung(ort, 'articleId', p.articleId),
347
+ locationId: kennung(ort, 'locationId', p.locationId),
348
+ quantity: ganzzahl(ort, 'quantity', p.quantity),
349
+ redeemed: ganzzahl(ort, 'redeemed', p.redeemed),
350
+ released: ganzzahl(ort, 'released', p.released),
351
+ };
352
+ }
353
+ export function reservierung(ort, w) {
354
+ const r = eintrag(ort, w);
355
+ if (!Array.isArray(r.items))
356
+ throw antwortfehler(ort.name, `Antwort ist unbrauchbar (data.${ort.pfad}.items ist keine Liste)`);
357
+ return {
358
+ id: kennung(ort, 'id', r.id),
359
+ status: textOderNull(r.status),
360
+ reference: text(r.reference),
361
+ items: r.items.map((p, i) => reservierungsPosition({ name: ort.name, pfad: `${ort.pfad}.items[${i}]` }, p)),
362
+ expiresAt: text(r.expiresAt),
363
+ createdAt: text(r.createdAt),
364
+ };
365
+ }
366
+ /** Die fehlenden Positionen aus `insufficient_available` (`data.details[]`); ein kaputter Eintrag faellt weg. */
367
+ export function fehlmengen(roh) {
368
+ if (!Array.isArray(roh))
369
+ return [];
370
+ const raus = [];
371
+ for (const e of roh) {
372
+ const o = objekt(e);
373
+ if (!o)
374
+ continue;
375
+ const { articleId, locationId, requested, available } = o;
376
+ if (typeof articleId !== 'string' || typeof locationId !== 'string')
377
+ continue;
378
+ if (!Number.isSafeInteger(requested) || !Number.isSafeInteger(available))
379
+ continue;
380
+ raus.push({ articleId, locationId, requested: requested, available: available });
381
+ }
382
+ return raus;
383
+ }
258
384
  // ---- Listen ------------------------------------------------------------------
259
385
  /** Eine zugesagte Liste `data.<feld>`, Eintrag fuer Eintrag gelesen. */
260
386
  export function liste(name, daten, feld, lesen) {
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Die schreibenden Aufrufe der Lager-API (Backend Stufe 5b): Artikel anlegen,
3
+ * aendern und stilllegen, Bestand buchen (Wareneingang, Umbuchung, Abgang,
4
+ * Zustand, Gegenbuchung) und reservieren.
5
+ *
6
+ * Wie in `endpunkte.ts` nimmt jede Funktion den Transport als ersten Parameter
7
+ * und ist einzeln importierbar. Die Anfrage geht flach hinaus, genau mit den
8
+ * Feldern, die der Aufrufer nennt (`undefined` faellt weg, `null` bleibt: es
9
+ * leert ein Feld bzw. heisst bei der Anlage „nicht angegeben“).
10
+ *
11
+ * **Vor dem Senden geprueft wird nur, was ohne Netz sicher falsch ist:**
12
+ * - `idempotencyKey` fehlt, ist leer oder laenger als 120 Zeichen. Ohne
13
+ * Schluessel gaebe es keine sichere Wiederholung, und der Server wiese die
14
+ * Anfrage ohnehin ab (`idempotency_key_required` bzw. `validation`);
15
+ * - eine Pflichtkennung fehlt oder ist leer;
16
+ * - eine Menge, ein Betrag oder ein Preis ist keine Ganzzahl (Tausendstel,
17
+ * Cent, Mikro-Euro): `1.5` waere nie „1,5 Stueck“, sondern ein Fehler;
18
+ * - `expiresInMinutes` liegt ausserhalb 5 … 43 200;
19
+ * - eine Aenderung nennt kein Feld, eine Freigabe eine leere Liste.
20
+ * Alles Fachliche (Pruefziffer der EAN, Kataloge, Bestand, Rechte) prueft der
21
+ * Server und meldet es mit seinem Code.
22
+ *
23
+ * **Wiederholen:** nach einem Zeitlimit oder Netzfehler denselben Aufruf mit
24
+ * **demselben** `idempotencyKey` noch einmal senden. Er wirkt genau einmal und
25
+ * liefert die gespeicherte Antwort; ein neuer Schluessel buchte ein zweites Mal.
26
+ */
27
+ import type { InternerTransport } from '../client/aufrufe.js';
28
+ import type { Article, ChangeStockConditionRequest, CreateArticleRequest, CreateReservationRequest, DeactivateArticleRequest, ExtendReservationRequest, GoodsReceiptPreview, GoodsReceiptPreviewRequest, ReceiveGoodsRequest, RecordStockLossRequest, ReleaseReservationRequest, Reservation, ReservationListQuery, ReservationPage, ReverseStockMovementRequest, StockOperation, TransferStockRequest, UpdateArticleRequest } from './typen.js';
29
+ /**
30
+ * Legt einen Artikel an. Mit `ean` ein Fremdartikel mit diesem Code (gueltige
31
+ * Pruefziffer, frei im Konto), sonst vergibt der Server den naechsten eigenen
32
+ * Code. Antwort: der Artikel wie `getArticle`.
33
+ */
34
+ export declare function createArticle(transport: InternerTransport, request: CreateArticleRequest): Promise<Article>;
35
+ /** Aendert nur die genannten Felder eines Artikels (siehe [UpdateArticleRequest]). */
36
+ export declare function updateArticle(transport: InternerTransport, request: UpdateArticleRequest): Promise<Article>;
37
+ /** Legt einen Artikel still (`active: false`); Code und eigene Kennungen werden frei. */
38
+ export declare function deactivateArticle(transport: InternerTransport, request: DeactivateArticleRequest): Promise<Article>;
39
+ /**
40
+ * Bucht einen Wareneingang. Ohne `locationId` am Standard-Standort; die
41
+ * Antwort traegt keine Werte, auch mit dem Recht `costs` nicht. Fuer die
42
+ * Vorschau mit Werten: [previewGoodsReceipt].
43
+ */
44
+ export declare function receiveGoods(transport: InternerTransport, request: ReceiveGoodsRequest): Promise<StockOperation>;
45
+ /**
46
+ * Vorschau eines Wareneingangs (`receiveGoods` mit `dryRun: true`): prueft
47
+ * Positionen, Artikel, Preise und Nebenkosten und rechnet die Verteilung,
48
+ * schreibt aber nichts. Ein `idempotencyKey` ist freigestellt (`null` wie nicht
49
+ * angegeben, geht nicht hinaus) und wird nicht verbraucht; dieselbe Anfrage
50
+ * laesst sich danach mit ihm buchen. Werte
51
+ * (`baseCents` …) nur mit dem Recht `costs`. Den Standort prueft erst die Buchung.
52
+ */
53
+ export declare function previewGoodsReceipt(transport: InternerTransport, request: GoodsReceiptPreviewRequest): Promise<GoodsReceiptPreview>;
54
+ /** Bucht Ware von einem Standort an einen anderen; ueberzieht nie (`exceeds_stock`). */
55
+ export declare function transferStock(transport: InternerTransport, request: TransferStockRequest): Promise<StockOperation>;
56
+ /** Bucht einen Abgang (Bruch, Schwund, Diebstahl, Entnahme …); ueberzieht nie (`exceeds_stock`). */
57
+ export declare function recordStockLoss(transport: InternerTransport, request: RecordStockLossRequest): Promise<StockOperation>;
58
+ /** Bucht Ware zwischen `sellable` und `defective` um; ueberzieht nie (`exceeds_stock`). */
59
+ export declare function changeStockCondition(transport: InternerTransport, request: ChangeStockConditionRequest): Promise<StockOperation>;
60
+ /** Nimmt einen ganzen Vorgang (`operationId`) mit einer Gegenbuchung zurueck. */
61
+ export declare function reverseStockMovement(transport: InternerTransport, request: ReverseStockMovementRequest): Promise<StockOperation>;
62
+ /**
63
+ * Reserviert Ware (Checkout im Shop): ganz oder gar nicht, gemessen am
64
+ * verfuegbaren Bestand (`onHand − reserved`). Fehlt etwas, entsteht nichts:
65
+ * `insufficient_available`, die fehlenden Positionen in [inventoryShortfalls].
66
+ * Eingeloest wird ueber eine Rechnung (`issueInvoice` mit `items[].reservationId`),
67
+ * sonst laeuft die Reservierung ab und gibt die Ware wieder frei.
68
+ */
69
+ export declare function createReservation(transport: InternerTransport, request: CreateReservationRequest): Promise<Reservation>;
70
+ /** Verlaengert eine aktive Reservierung: neuer Ablauf = jetzt + `expiresInMinutes`. */
71
+ export declare function extendReservation(transport: InternerTransport, request: ExtendReservationRequest): Promise<Reservation>;
72
+ /**
73
+ * Gibt reservierte Ware frei: ohne `items` alles, sonst je Position (ohne
74
+ * `quantity` der ganze offene Rest). Die Antwort traegt den Stand danach;
75
+ * `released` wird der Status erst, wenn nichts mehr offen ist.
76
+ */
77
+ export declare function releaseReservation(transport: InternerTransport, request: ReleaseReservationRequest): Promise<Reservation>;
78
+ /** Eine Reservierung mit ihrem aktuellen Stand. */
79
+ export declare function getReservation(transport: InternerTransport, reservationId: string): Promise<Reservation>;
80
+ /** Reservierungen, neueste zuerst; Filter `status` und/oder `reference`. */
81
+ export declare function listReservations(transport: InternerTransport, query?: ReservationListQuery): Promise<ReservationPage>;
82
+ /** Alle Reservierungen der Abfrage, Seite fuer Seite ueber `nextCursor`. */
83
+ export declare function iterateReservations(transport: InternerTransport, query?: ReservationListQuery): AsyncGenerator<Reservation, void, undefined>;