@kreiseck/kasseneck-api 1.7.1 → 1.10.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 +113 -0
- package/README.md +170 -1
- package/dist/cjs/client/api.d.ts +5 -3
- package/dist/cjs/client/api.js +1 -0
- package/dist/cjs/client/aufrufe.d.ts +9 -7
- package/dist/cjs/client/aufrufe.js +60 -2
- package/dist/cjs/client/errors.js +3 -0
- package/dist/cjs/client/index.d.ts +2 -2
- package/dist/cjs/client/index.js +3 -1
- package/dist/cjs/client/reports.d.ts +26 -0
- package/dist/cjs/client/reports.js +47 -0
- package/dist/cjs/client/transport.d.ts +27 -3
- package/dist/cjs/client/transport.js +29 -3
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/inventory/api.d.ts +21 -2
- package/dist/cjs/inventory/api.js +22 -3
- package/dist/cjs/inventory/fehler.d.ts +6 -0
- package/dist/cjs/inventory/fehler.js +12 -0
- package/dist/cjs/inventory/index.d.ts +6 -4
- package/dist/cjs/inventory/index.js +33 -3
- package/dist/cjs/inventory/inventur.d.ts +104 -0
- package/dist/cjs/inventory/inventur.js +245 -0
- package/dist/cjs/inventory/lesen.d.ts +20 -1
- package/dist/cjs/inventory/lesen.js +307 -0
- package/dist/cjs/inventory/typen.d.ts +410 -1
- package/dist/cjs/inventory/vertrag.d.ts +94 -8
- package/dist/cjs/inventory/vertrag.js +118 -5
- package/dist/cjs/invoice/index.d.ts +1 -1
- package/dist/cjs/invoice/typen.d.ts +12 -0
- package/dist/cjs/invoice/vertrag.d.ts +1 -1
- package/dist/cjs/invoice/vertrag.js +3 -0
- package/dist/cjs/models/cancellation.d.ts +1 -1
- package/dist/cjs/models/cancellation.js +3 -0
- package/dist/cjs/models/payment-errors.d.ts +1 -1
- package/dist/cjs/models/payment-errors.js +3 -0
- package/dist/cjs/models/receipt-email.d.ts +1 -1
- package/dist/cjs/models/receipt-email.js +3 -0
- package/dist/cjs/models/receipt-errors.d.ts +1 -1
- package/dist/cjs/models/receipt-errors.js +3 -0
- package/dist/cjs/pos/errors.d.ts +4 -3
- package/dist/cjs/pos/errors.js +24 -2
- package/dist/cjs/pos/index.d.ts +4 -1
- package/dist/cjs/pos/index.js +9 -2
- package/dist/cjs/pos/inventur.d.ts +104 -0
- package/dist/cjs/pos/inventur.js +117 -0
- package/dist/cjs/pos/texte.d.ts +82 -0
- package/dist/cjs/pos/texte.js +35 -0
- package/dist/cjs/register/errors.d.ts +1 -1
- package/dist/cjs/register/errors.js +3 -0
- package/dist/cjs/stored/vokabular.d.ts +1 -1
- package/dist/cjs/stored/vokabular.js +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/client/api.d.ts +5 -3
- package/dist/esm/client/api.js +2 -1
- package/dist/esm/client/aufrufe.d.ts +9 -7
- package/dist/esm/client/aufrufe.js +60 -2
- package/dist/esm/client/errors.js +3 -0
- package/dist/esm/client/index.d.ts +2 -2
- package/dist/esm/client/index.js +2 -2
- package/dist/esm/client/reports.d.ts +26 -0
- package/dist/esm/client/reports.js +46 -0
- package/dist/esm/client/transport.d.ts +27 -3
- package/dist/esm/client/transport.js +28 -3
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/inventory/api.d.ts +21 -2
- package/dist/esm/inventory/api.js +23 -4
- package/dist/esm/inventory/fehler.d.ts +6 -0
- package/dist/esm/inventory/fehler.js +11 -0
- package/dist/esm/inventory/index.d.ts +6 -4
- package/dist/esm/inventory/index.js +5 -3
- package/dist/esm/inventory/inventur.d.ts +104 -0
- package/dist/esm/inventory/inventur.js +226 -0
- package/dist/esm/inventory/lesen.d.ts +20 -1
- package/dist/esm/inventory/lesen.js +301 -0
- package/dist/esm/inventory/typen.d.ts +410 -1
- package/dist/esm/inventory/vertrag.d.ts +94 -8
- package/dist/esm/inventory/vertrag.js +117 -4
- package/dist/esm/invoice/index.d.ts +1 -1
- package/dist/esm/invoice/typen.d.ts +12 -0
- package/dist/esm/invoice/vertrag.d.ts +1 -1
- package/dist/esm/invoice/vertrag.js +3 -0
- package/dist/esm/models/cancellation.d.ts +1 -1
- package/dist/esm/models/cancellation.js +3 -0
- package/dist/esm/models/payment-errors.d.ts +1 -1
- package/dist/esm/models/payment-errors.js +3 -0
- package/dist/esm/models/receipt-email.d.ts +1 -1
- package/dist/esm/models/receipt-email.js +3 -0
- package/dist/esm/models/receipt-errors.d.ts +1 -1
- package/dist/esm/models/receipt-errors.js +3 -0
- package/dist/esm/pos/errors.d.ts +4 -3
- package/dist/esm/pos/errors.js +24 -2
- package/dist/esm/pos/index.d.ts +4 -1
- package/dist/esm/pos/index.js +2 -1
- package/dist/esm/pos/inventur.d.ts +104 -0
- package/dist/esm/pos/inventur.js +109 -0
- package/dist/esm/pos/texte.d.ts +82 -0
- package/dist/esm/pos/texte.js +35 -0
- package/dist/esm/register/errors.d.ts +1 -1
- package/dist/esm/register/errors.js +3 -0
- package/dist/esm/stored/vokabular.d.ts +1 -1
- package/dist/esm/stored/vokabular.js +1 -1
- 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.schema.json +1 -1
- package/fixtures/invoice-texts.json +1 -1
- package/fixtures/pos-texts.json +94 -1
- package/fixtures/stocktake-quantity-cases.json +55 -0
- package/fixtures/surface.json +157 -8
- package/fixtures/v3/antworten/belege.json +1 -1
- package/fixtures/v3/antworten/belegmail.json +1 -1
- package/fixtures/v3/antworten/kasse-belege.json +1 -1
- package/fixtures/v3/antworten/kasse.json +2958 -3
- package/fixtures/v3/antworten/lager.json +1727 -3
- package/fixtures/v3/antworten/rechnungen.json +14 -6
- package/fixtures/v3/antworten/storno.json +1 -1
- package/fixtures/v3/stored/belege.json +1 -1
- package/fixtures/v3/stored/kasse.json +414 -3
- package/fixtures/v3/stored/rechnungen.json +1 -1
- package/fixtures/v3/v3-vokabular.json +530 -8
- package/fixtures/v3/zahlbetrag-faelle.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inventur der Lager-API (Lager-Kern Stufe 3): anlegen, zaehlen, Zaehlungen
|
|
3
|
+
* stornieren, pruefen, nachzaehlen, abschliessen, abbrechen, Inventurprotokoll
|
|
4
|
+
* holen; dazu die Listen der Inventuren, Positionen und Zaehlungen.
|
|
5
|
+
*
|
|
6
|
+
* Ablauf: `createStocktake` → `recordStocktakeCount` (beliebig oft, auch von
|
|
7
|
+
* mehreren Geraeten; je Position addiert) → `reviewStocktake` (erst jetzt Soll
|
|
8
|
+
* und Differenz) → bei Bedarf `recountStocktake` und erneut `reviewStocktake`
|
|
9
|
+
* → `closeStocktake` → `getStocktakePdf`. Pruefen und Abschliessen rechnet der
|
|
10
|
+
* Server im Hintergrund: die Antwort traegt den Zwischenstand
|
|
11
|
+
* (`review.complete: false` bzw. `status: 'closing'`), `getStocktake` den
|
|
12
|
+
* Fortgang.
|
|
13
|
+
*
|
|
14
|
+
* **Blind:** vor `review` traegt keine Antwort ein Soll; `blind: false` zeigt
|
|
15
|
+
* beim Zaehlen nur den heutigen Buchbestand (`bookStockNow`), nie das Soll
|
|
16
|
+
* zur Referenzzeit.
|
|
17
|
+
*
|
|
18
|
+
* Rechte wie in Stufe 5b: Lesen mit jedem Schluessel, alles Schreibende (auch
|
|
19
|
+
* Zaehlen) mit dem Konto-Schalter „Lager-API schreiben“ (Test-Schluessel
|
|
20
|
+
* immer), sonst `inventory_api_not_enabled`; Werte und das Protokoll mit
|
|
21
|
+
* Werten nur mit `lagerApi.kosten`.
|
|
22
|
+
*
|
|
23
|
+
* **Vor dem Senden geprueft wird nur, was ohne Netz sicher falsch ist:**
|
|
24
|
+
* `idempotencyKey` (Pflicht bei jedem Schreiben, 1–120 Zeichen), fehlende
|
|
25
|
+
* Kennungen (`stocktakeId`, `articleId`, `countId`, `locationId`), `scope`
|
|
26
|
+
* kein Objekt, eine Menge, die keine Ganzzahl ist (Tausendstel), ein leerer
|
|
27
|
+
* Grund, `items` beim Nachzaehlen leer oder ohne `articleId`,
|
|
28
|
+
* `serialNumbers` keine Liste, `uncountedAsZero` kein Wahrheitswert. Alles
|
|
29
|
+
* Fachliche (Umfang, Stichtag, Seriennummern, Zustand) prueft der Server.
|
|
30
|
+
*
|
|
31
|
+
* **Wiederholen** wie bei jedem Schreiben: nach `outcome: 'unknown'` denselben
|
|
32
|
+
* Aufruf mit **demselben** `idempotencyKey`. Eine Zaehlung wirkt dann genau
|
|
33
|
+
* einmal (das Zaehldokument ist selbst der Nachweis); ein neuer Schluessel
|
|
34
|
+
* zaehlte die Ware ein zweites Mal.
|
|
35
|
+
*/
|
|
36
|
+
import type { ApiCall, InternerPdfOderDatenTransport, InternerTransport } from '../client/aufrufe.js';
|
|
37
|
+
import type { CancelStocktakeRequest, CloseStocktakeRequest, CloseStocktakeResult, CreateStocktakeRequest, RecordStocktakeCountRequest, RecountStocktakeRequest, ReviewStocktakeRequest, Stocktake, StocktakeCount, StocktakeCountListQuery, StocktakeCountPage, StocktakeCountResult, StocktakeItem, StocktakeItemListQuery, StocktakeItemPage, StocktakeListQuery, StocktakePage, StocktakePdf, VoidStocktakeCountRequest } from './typen.js';
|
|
38
|
+
type Params = Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Legt eine Inventur an. Je Standort hoechstens eine offene
|
|
41
|
+
* (`stocktake_location_busy`, `data.stocktakeId` nennt sie); Umfang `groups`
|
|
42
|
+
* bzw. `articles` nur mit bestandsgefuehrten Artikeln (`article_not_tracked`).
|
|
43
|
+
* Jede Inventur beginnt in `counting`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createStocktake(transport: InternerTransport, request: CreateStocktakeRequest): Promise<Stocktake>;
|
|
46
|
+
/**
|
|
47
|
+
* Inventuren des Kontos. Ohne `updatedSince` zuletzt geaenderte zuerst; mit
|
|
48
|
+
* `updatedSince` aufsteigend nach `updatedAt` und inklusive (Abgleich: das
|
|
49
|
+
* groesste gesehene `updatedAt` als naechstes `updatedSince`). Filter
|
|
50
|
+
* `status` und `locationId`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function listStocktakes(transport: InternerTransport, query?: StocktakeListQuery): Promise<StocktakePage>;
|
|
53
|
+
/** Alle Inventuren der Abfrage, Seite fuer Seite, in der Reihenfolge von [listStocktakes]. */
|
|
54
|
+
export declare function iterateStocktakes(transport: InternerTransport, query?: StocktakeListQuery): AsyncGenerator<Stocktake, void, undefined>;
|
|
55
|
+
/** Eine Inventur samt `progress.counted` (gezaehlte Positionen). */
|
|
56
|
+
export declare function getStocktake(transport: InternerTransport, stocktakeId: string): Promise<Stocktake>;
|
|
57
|
+
/** Positionen einer Inventur nach Kennung; `openOnly` = ungezaehlt bzw. in `review` zum Nachzaehlen offen. */
|
|
58
|
+
export declare function listStocktakeItems(transport: InternerTransport, query: StocktakeItemListQuery): Promise<StocktakeItemPage>;
|
|
59
|
+
export declare function iterateStocktakeItems(transport: InternerTransport, query: StocktakeItemListQuery): AsyncGenerator<StocktakeItem, void, undefined>;
|
|
60
|
+
/** Zaehlungen einer Inventur, neueste zuerst, auch stornierte; mit `articleId` nur die des Artikels. */
|
|
61
|
+
export declare function listStocktakeCounts(transport: InternerTransport, query: StocktakeCountListQuery): Promise<StocktakeCountPage>;
|
|
62
|
+
export declare function iterateStocktakeCounts(transport: InternerTransport, query: StocktakeCountListQuery): AsyncGenerator<StocktakeCount, void, undefined>;
|
|
63
|
+
/** Pruefung einer Zaehlung vor dem Senden, geteilt mit dem Kassenweg. Paketintern. */
|
|
64
|
+
export declare function zaehlungPruefen(name: ApiCall, p: Params): void;
|
|
65
|
+
/** Pruefung eines Stornos vor dem Senden, geteilt mit dem Kassenweg. Paketintern. */
|
|
66
|
+
export declare function stornoPruefen(name: ApiCall, p: Params): void;
|
|
67
|
+
/**
|
|
68
|
+
* Eine Zaehlung. Antwort: die Zaehlung und ihre Position danach (Summe der
|
|
69
|
+
* Runde in `item.quantity`). Gezaehlt wird in `counting`, in `review` nur an
|
|
70
|
+
* Positionen, die zum Nachzaehlen frei sind (sonst `stocktake_not_open`).
|
|
71
|
+
*/
|
|
72
|
+
export declare function recordStocktakeCount(transport: InternerTransport, request: RecordStocktakeCountRequest): Promise<StocktakeCountResult>;
|
|
73
|
+
/** Storniert eine Zaehlung mit Grund; die Position wird aus den uebrigen Zaehlungen neu summiert. */
|
|
74
|
+
export declare function voidStocktakeCount(transport: InternerTransport, request: VoidStocktakeCountRequest): Promise<StocktakeCountResult>;
|
|
75
|
+
/**
|
|
76
|
+
* Pruefen: `counting` → `review`, in `review` neu rechnen (nach dem
|
|
77
|
+
* Nachzaehlen). Die Antwort kommt sofort mit `review.complete: false`; Soll
|
|
78
|
+
* und Differenz stehen an den Positionen, sobald `complete` `true` ist.
|
|
79
|
+
*/
|
|
80
|
+
export declare function reviewStocktake(transport: InternerTransport, request: ReviewStocktakeRequest): Promise<Stocktake>;
|
|
81
|
+
/** Nachzaehlen: je genannter Position eine neue Runde; danach zaehlen und erneut [reviewStocktake]. */
|
|
82
|
+
export declare function recountStocktake(transport: InternerTransport, request: RecountStocktakeRequest): Promise<Stocktake>;
|
|
83
|
+
/**
|
|
84
|
+
* Abschliessen (nur aus `review`, sonst `stocktake_not_in_review`; offene
|
|
85
|
+
* Nachzaehlungen ergeben `stocktake_recount_open`). Der Server bucht in
|
|
86
|
+
* Teilen weiter; die Antwort traegt meist `status: 'closing'`. Ein erneuter
|
|
87
|
+
* Aufruf waehrend `closing` stoesst den Abschluss wieder an.
|
|
88
|
+
*/
|
|
89
|
+
export declare function closeStocktake(transport: InternerTransport, request: CloseStocktakeRequest): Promise<CloseStocktakeResult>;
|
|
90
|
+
/** Abbrechen mit Grund (aus `counting` oder `review`); der Standort ist danach frei. */
|
|
91
|
+
export declare function cancelStocktake(transport: InternerTransport, request: CancelStocktakeRequest): Promise<Stocktake>;
|
|
92
|
+
/**
|
|
93
|
+
* Das Inventurprotokoll (PDF), erst nach dem Abschluss (`stocktake_not_closed`,
|
|
94
|
+
* auch fuer eine abgebrochene Inventur). Mit `lagerApi.kosten` die Fassung mit
|
|
95
|
+
* Werten, sonst die nur mit Mengen. Bis 9 MiB kommt die Datei selbst
|
|
96
|
+
* (`kind: 'pdf'`), darueber ein signierter Lese-Link fuer 15 Minuten
|
|
97
|
+
* (`kind: 'download'`); die geladene Datei an `download.sha256` pruefen.
|
|
98
|
+
*
|
|
99
|
+
* Als freie Funktion braucht sie den Transport aus `createPdfOrDataTransport`
|
|
100
|
+
* (Paketwurzel): ein JSON-Transport laese die Datei als Text, ein reiner
|
|
101
|
+
* Binaer-Transport kennt den Link nicht. [createInventoryClient] bindet ihn selbst.
|
|
102
|
+
*/
|
|
103
|
+
export declare function getStocktakePdf(transport: InternerPdfOderDatenTransport, stocktakeId: string): Promise<StocktakePdf>;
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Inventur der Lager-API (Lager-Kern Stufe 3): anlegen, zaehlen, Zaehlungen
|
|
4
|
+
* stornieren, pruefen, nachzaehlen, abschliessen, abbrechen, Inventurprotokoll
|
|
5
|
+
* holen; dazu die Listen der Inventuren, Positionen und Zaehlungen.
|
|
6
|
+
*
|
|
7
|
+
* Ablauf: `createStocktake` → `recordStocktakeCount` (beliebig oft, auch von
|
|
8
|
+
* mehreren Geraeten; je Position addiert) → `reviewStocktake` (erst jetzt Soll
|
|
9
|
+
* und Differenz) → bei Bedarf `recountStocktake` und erneut `reviewStocktake`
|
|
10
|
+
* → `closeStocktake` → `getStocktakePdf`. Pruefen und Abschliessen rechnet der
|
|
11
|
+
* Server im Hintergrund: die Antwort traegt den Zwischenstand
|
|
12
|
+
* (`review.complete: false` bzw. `status: 'closing'`), `getStocktake` den
|
|
13
|
+
* Fortgang.
|
|
14
|
+
*
|
|
15
|
+
* **Blind:** vor `review` traegt keine Antwort ein Soll; `blind: false` zeigt
|
|
16
|
+
* beim Zaehlen nur den heutigen Buchbestand (`bookStockNow`), nie das Soll
|
|
17
|
+
* zur Referenzzeit.
|
|
18
|
+
*
|
|
19
|
+
* Rechte wie in Stufe 5b: Lesen mit jedem Schluessel, alles Schreibende (auch
|
|
20
|
+
* Zaehlen) mit dem Konto-Schalter „Lager-API schreiben“ (Test-Schluessel
|
|
21
|
+
* immer), sonst `inventory_api_not_enabled`; Werte und das Protokoll mit
|
|
22
|
+
* Werten nur mit `lagerApi.kosten`.
|
|
23
|
+
*
|
|
24
|
+
* **Vor dem Senden geprueft wird nur, was ohne Netz sicher falsch ist:**
|
|
25
|
+
* `idempotencyKey` (Pflicht bei jedem Schreiben, 1–120 Zeichen), fehlende
|
|
26
|
+
* Kennungen (`stocktakeId`, `articleId`, `countId`, `locationId`), `scope`
|
|
27
|
+
* kein Objekt, eine Menge, die keine Ganzzahl ist (Tausendstel), ein leerer
|
|
28
|
+
* Grund, `items` beim Nachzaehlen leer oder ohne `articleId`,
|
|
29
|
+
* `serialNumbers` keine Liste, `uncountedAsZero` kein Wahrheitswert. Alles
|
|
30
|
+
* Fachliche (Umfang, Stichtag, Seriennummern, Zustand) prueft der Server.
|
|
31
|
+
*
|
|
32
|
+
* **Wiederholen** wie bei jedem Schreiben: nach `outcome: 'unknown'` denselben
|
|
33
|
+
* Aufruf mit **demselben** `idempotencyKey`. Eine Zaehlung wirkt dann genau
|
|
34
|
+
* einmal (das Zaehldokument ist selbst der Nachweis); ein neuer Schluessel
|
|
35
|
+
* zaehlte die Ware ein zweites Mal.
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.createStocktake = createStocktake;
|
|
39
|
+
exports.listStocktakes = listStocktakes;
|
|
40
|
+
exports.iterateStocktakes = iterateStocktakes;
|
|
41
|
+
exports.getStocktake = getStocktake;
|
|
42
|
+
exports.listStocktakeItems = listStocktakeItems;
|
|
43
|
+
exports.iterateStocktakeItems = iterateStocktakeItems;
|
|
44
|
+
exports.listStocktakeCounts = listStocktakeCounts;
|
|
45
|
+
exports.iterateStocktakeCounts = iterateStocktakeCounts;
|
|
46
|
+
exports.zaehlungPruefen = zaehlungPruefen;
|
|
47
|
+
exports.stornoPruefen = stornoPruefen;
|
|
48
|
+
exports.recordStocktakeCount = recordStocktakeCount;
|
|
49
|
+
exports.voidStocktakeCount = voidStocktakeCount;
|
|
50
|
+
exports.reviewStocktake = reviewStocktake;
|
|
51
|
+
exports.recountStocktake = recountStocktake;
|
|
52
|
+
exports.closeStocktake = closeStocktake;
|
|
53
|
+
exports.cancelStocktake = cancelStocktake;
|
|
54
|
+
exports.getStocktakePdf = getStocktakePdf;
|
|
55
|
+
const endpunkte_js_1 = require("./endpunkte.js");
|
|
56
|
+
const lesen_js_1 = require("./lesen.js");
|
|
57
|
+
const schreiben_js_1 = require("./schreiben.js");
|
|
58
|
+
const istObjekt = (w) => w !== null && typeof w === 'object' && !Array.isArray(w);
|
|
59
|
+
const kopfAus = (name, daten) => (0, lesen_js_1.inventur)({ name, pfad: 'stocktake' }, (0, lesen_js_1.objekt)(daten)?.stocktake);
|
|
60
|
+
/** Ein Grund (Storno, Nachzaehlen, Abbruch): nicht leer. Die Laenge prueft der Server. */
|
|
61
|
+
function grund(name, w) {
|
|
62
|
+
if (typeof w !== 'string' || w.trim() === '')
|
|
63
|
+
throw (0, endpunkte_js_1.anfragefehler)(name, 'reason fehlt (Grund mit 1 bis 500 Zeichen)');
|
|
64
|
+
}
|
|
65
|
+
/** Schreibende Anfrage mit `stocktakeId`: Schluessel und Kennung geprueft, flach wie gesendet. */
|
|
66
|
+
function schreibend(name, request) {
|
|
67
|
+
const p = (0, schreiben_js_1.anfrage)(name, request);
|
|
68
|
+
(0, schreiben_js_1.schluessel)(name, p, { pflicht: true });
|
|
69
|
+
(0, endpunkte_js_1.kennung)(name, 'stocktakeId', p.stocktakeId);
|
|
70
|
+
return p;
|
|
71
|
+
}
|
|
72
|
+
/** Eine Liste unter einer Inventur: `stocktakeId` Pflicht, sonst wie jede Abfrage. */
|
|
73
|
+
function abfrageMitInventur(name, query) {
|
|
74
|
+
if (!istObjekt(query))
|
|
75
|
+
throw (0, endpunkte_js_1.anfragefehler)(name, 'Abfrage mit stocktakeId erwartet');
|
|
76
|
+
const p = (0, endpunkte_js_1.abfrage)(name, query);
|
|
77
|
+
(0, endpunkte_js_1.kennung)(name, 'stocktakeId', p.stocktakeId);
|
|
78
|
+
return p;
|
|
79
|
+
}
|
|
80
|
+
// ---- Anlegen und Lesen -------------------------------------------------------------
|
|
81
|
+
/**
|
|
82
|
+
* Legt eine Inventur an. Je Standort hoechstens eine offene
|
|
83
|
+
* (`stocktake_location_busy`, `data.stocktakeId` nennt sie); Umfang `groups`
|
|
84
|
+
* bzw. `articles` nur mit bestandsgefuehrten Artikeln (`article_not_tracked`).
|
|
85
|
+
* Jede Inventur beginnt in `counting`.
|
|
86
|
+
*/
|
|
87
|
+
async function createStocktake(transport, request) {
|
|
88
|
+
const name = 'createStocktake';
|
|
89
|
+
const p = (0, schreiben_js_1.anfrage)(name, request);
|
|
90
|
+
(0, schreiben_js_1.schluessel)(name, p, { pflicht: true });
|
|
91
|
+
(0, endpunkte_js_1.kennung)(name, 'locationId', p.locationId);
|
|
92
|
+
if (!istObjekt(p.scope))
|
|
93
|
+
throw (0, endpunkte_js_1.anfragefehler)(name, 'scope fehlt oder ist kein Objekt { type, groupIds?, articleIds? }');
|
|
94
|
+
return kopfAus(name, await transport(name, p));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Inventuren des Kontos. Ohne `updatedSince` zuletzt geaenderte zuerst; mit
|
|
98
|
+
* `updatedSince` aufsteigend nach `updatedAt` und inklusive (Abgleich: das
|
|
99
|
+
* groesste gesehene `updatedAt` als naechstes `updatedSince`). Filter
|
|
100
|
+
* `status` und `locationId`.
|
|
101
|
+
*/
|
|
102
|
+
async function listStocktakes(transport, query) {
|
|
103
|
+
const name = 'listStocktakes';
|
|
104
|
+
const daten = await transport(name, (0, endpunkte_js_1.abfrage)(name, query));
|
|
105
|
+
return { stocktakes: (0, lesen_js_1.liste)(name, daten, 'stocktakes', lesen_js_1.inventur), nextCursor: (0, lesen_js_1.naechsterCursor)(name, daten) };
|
|
106
|
+
}
|
|
107
|
+
/** Alle Inventuren der Abfrage, Seite fuer Seite, in der Reihenfolge von [listStocktakes]. */
|
|
108
|
+
function iterateStocktakes(transport, query) {
|
|
109
|
+
const { cursor, ...rest } = query ?? {};
|
|
110
|
+
return (0, endpunkte_js_1.seitenweise)('listStocktakes', cursor, async (c) => {
|
|
111
|
+
const s = await listStocktakes(transport, { ...rest, cursor: c });
|
|
112
|
+
return { eintraege: s.stocktakes, nextCursor: s.nextCursor };
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/** Eine Inventur samt `progress.counted` (gezaehlte Positionen). */
|
|
116
|
+
async function getStocktake(transport, stocktakeId) {
|
|
117
|
+
const name = 'getStocktake';
|
|
118
|
+
return kopfAus(name, await transport(name, { stocktakeId: (0, endpunkte_js_1.kennung)(name, 'stocktakeId', stocktakeId) }));
|
|
119
|
+
}
|
|
120
|
+
/** Positionen einer Inventur nach Kennung; `openOnly` = ungezaehlt bzw. in `review` zum Nachzaehlen offen. */
|
|
121
|
+
async function listStocktakeItems(transport, query) {
|
|
122
|
+
const name = 'listStocktakeItems';
|
|
123
|
+
const daten = await transport(name, abfrageMitInventur(name, query));
|
|
124
|
+
return { items: (0, lesen_js_1.liste)(name, daten, 'items', lesen_js_1.inventurPosition), nextCursor: (0, lesen_js_1.naechsterCursor)(name, daten) };
|
|
125
|
+
}
|
|
126
|
+
function iterateStocktakeItems(transport, query) {
|
|
127
|
+
const { cursor, ...rest } = query;
|
|
128
|
+
return (0, endpunkte_js_1.seitenweise)('listStocktakeItems', cursor, async (c) => {
|
|
129
|
+
const s = await listStocktakeItems(transport, { ...rest, cursor: c });
|
|
130
|
+
return { eintraege: s.items, nextCursor: s.nextCursor };
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/** Zaehlungen einer Inventur, neueste zuerst, auch stornierte; mit `articleId` nur die des Artikels. */
|
|
134
|
+
async function listStocktakeCounts(transport, query) {
|
|
135
|
+
const name = 'listStocktakeCounts';
|
|
136
|
+
const daten = await transport(name, abfrageMitInventur(name, query));
|
|
137
|
+
return { counts: (0, lesen_js_1.liste)(name, daten, 'counts', lesen_js_1.inventurZaehlung), nextCursor: (0, lesen_js_1.naechsterCursor)(name, daten) };
|
|
138
|
+
}
|
|
139
|
+
function iterateStocktakeCounts(transport, query) {
|
|
140
|
+
const { cursor, ...rest } = query;
|
|
141
|
+
return (0, endpunkte_js_1.seitenweise)('listStocktakeCounts', cursor, async (c) => {
|
|
142
|
+
const s = await listStocktakeCounts(transport, { ...rest, cursor: c });
|
|
143
|
+
return { eintraege: s.counts, nextCursor: s.nextCursor };
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// ---- Zaehlen und Stornieren ------------------------------------------------------
|
|
147
|
+
/** Pruefung einer Zaehlung vor dem Senden, geteilt mit dem Kassenweg. Paketintern. */
|
|
148
|
+
function zaehlungPruefen(name, p) {
|
|
149
|
+
(0, endpunkte_js_1.kennung)(name, 'articleId', p.articleId);
|
|
150
|
+
(0, schreiben_js_1.ganz)(name, 'quantity', p.quantity, { pflicht: true });
|
|
151
|
+
if (p.serialNumbers !== undefined && p.serialNumbers !== null && !Array.isArray(p.serialNumbers)) {
|
|
152
|
+
throw (0, endpunkte_js_1.anfragefehler)(name, 'serialNumbers muss eine Liste sein');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Pruefung eines Stornos vor dem Senden, geteilt mit dem Kassenweg. Paketintern. */
|
|
156
|
+
function stornoPruefen(name, p) {
|
|
157
|
+
(0, endpunkte_js_1.kennung)(name, 'countId', p.countId);
|
|
158
|
+
grund(name, p.reason);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Eine Zaehlung. Antwort: die Zaehlung und ihre Position danach (Summe der
|
|
162
|
+
* Runde in `item.quantity`). Gezaehlt wird in `counting`, in `review` nur an
|
|
163
|
+
* Positionen, die zum Nachzaehlen frei sind (sonst `stocktake_not_open`).
|
|
164
|
+
*/
|
|
165
|
+
async function recordStocktakeCount(transport, request) {
|
|
166
|
+
const name = 'recordStocktakeCount';
|
|
167
|
+
const p = schreibend(name, request);
|
|
168
|
+
zaehlungPruefen(name, p);
|
|
169
|
+
return (0, lesen_js_1.zaehlungMitPosition)(name, await transport(name, p));
|
|
170
|
+
}
|
|
171
|
+
/** Storniert eine Zaehlung mit Grund; die Position wird aus den uebrigen Zaehlungen neu summiert. */
|
|
172
|
+
async function voidStocktakeCount(transport, request) {
|
|
173
|
+
const name = 'voidStocktakeCount';
|
|
174
|
+
const p = schreibend(name, request);
|
|
175
|
+
stornoPruefen(name, p);
|
|
176
|
+
return (0, lesen_js_1.zaehlungMitPosition)(name, await transport(name, p));
|
|
177
|
+
}
|
|
178
|
+
// ---- Pruefen bis Abbruch ------------------------------------------------------------
|
|
179
|
+
/**
|
|
180
|
+
* Pruefen: `counting` → `review`, in `review` neu rechnen (nach dem
|
|
181
|
+
* Nachzaehlen). Die Antwort kommt sofort mit `review.complete: false`; Soll
|
|
182
|
+
* und Differenz stehen an den Positionen, sobald `complete` `true` ist.
|
|
183
|
+
*/
|
|
184
|
+
async function reviewStocktake(transport, request) {
|
|
185
|
+
const name = 'reviewStocktake';
|
|
186
|
+
return kopfAus(name, await transport(name, schreibend(name, request)));
|
|
187
|
+
}
|
|
188
|
+
/** Nachzaehlen: je genannter Position eine neue Runde; danach zaehlen und erneut [reviewStocktake]. */
|
|
189
|
+
async function recountStocktake(transport, request) {
|
|
190
|
+
const name = 'recountStocktake';
|
|
191
|
+
const p = schreibend(name, request);
|
|
192
|
+
if (!Array.isArray(p.items) || p.items.length === 0)
|
|
193
|
+
throw (0, endpunkte_js_1.anfragefehler)(name, 'items fehlt oder ist leer');
|
|
194
|
+
p.items.forEach((x, i) => {
|
|
195
|
+
if (!istObjekt(x))
|
|
196
|
+
throw (0, endpunkte_js_1.anfragefehler)(name, `items[${i}] muss ein Objekt sein`);
|
|
197
|
+
(0, endpunkte_js_1.kennung)(name, `items[${i}].articleId`, x.articleId);
|
|
198
|
+
});
|
|
199
|
+
grund(name, p.reason);
|
|
200
|
+
return kopfAus(name, await transport(name, p));
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Abschliessen (nur aus `review`, sonst `stocktake_not_in_review`; offene
|
|
204
|
+
* Nachzaehlungen ergeben `stocktake_recount_open`). Der Server bucht in
|
|
205
|
+
* Teilen weiter; die Antwort traegt meist `status: 'closing'`. Ein erneuter
|
|
206
|
+
* Aufruf waehrend `closing` stoesst den Abschluss wieder an.
|
|
207
|
+
*/
|
|
208
|
+
async function closeStocktake(transport, request) {
|
|
209
|
+
const name = 'closeStocktake';
|
|
210
|
+
const p = schreibend(name, request);
|
|
211
|
+
if (p.uncountedAsZero !== undefined && typeof p.uncountedAsZero !== 'boolean') {
|
|
212
|
+
throw (0, endpunkte_js_1.anfragefehler)(name, 'uncountedAsZero muss true oder false sein');
|
|
213
|
+
}
|
|
214
|
+
const daten = await transport(name, p);
|
|
215
|
+
return { stocktake: kopfAus(name, daten), warnings: (0, lesen_js_1.inventurWarnungen)({ name, pfad: 'warnings' }, (0, lesen_js_1.objekt)(daten)?.warnings) };
|
|
216
|
+
}
|
|
217
|
+
/** Abbrechen mit Grund (aus `counting` oder `review`); der Standort ist danach frei. */
|
|
218
|
+
async function cancelStocktake(transport, request) {
|
|
219
|
+
const name = 'cancelStocktake';
|
|
220
|
+
const p = schreibend(name, request);
|
|
221
|
+
grund(name, p.reason);
|
|
222
|
+
return kopfAus(name, await transport(name, p));
|
|
223
|
+
}
|
|
224
|
+
// ---- Protokoll ------------------------------------------------------------------
|
|
225
|
+
/**
|
|
226
|
+
* Das Inventurprotokoll (PDF), erst nach dem Abschluss (`stocktake_not_closed`,
|
|
227
|
+
* auch fuer eine abgebrochene Inventur). Mit `lagerApi.kosten` die Fassung mit
|
|
228
|
+
* Werten, sonst die nur mit Mengen. Bis 9 MiB kommt die Datei selbst
|
|
229
|
+
* (`kind: 'pdf'`), darueber ein signierter Lese-Link fuer 15 Minuten
|
|
230
|
+
* (`kind: 'download'`); die geladene Datei an `download.sha256` pruefen.
|
|
231
|
+
*
|
|
232
|
+
* Als freie Funktion braucht sie den Transport aus `createPdfOrDataTransport`
|
|
233
|
+
* (Paketwurzel): ein JSON-Transport laese die Datei als Text, ein reiner
|
|
234
|
+
* Binaer-Transport kennt den Link nicht. [createInventoryClient] bindet ihn selbst.
|
|
235
|
+
*/
|
|
236
|
+
async function getStocktakePdf(transport, stocktakeId) {
|
|
237
|
+
const name = 'getStocktakePdf';
|
|
238
|
+
const ergebnis = await transport(name, { stocktakeId: (0, endpunkte_js_1.kennung)(name, 'stocktakeId', stocktakeId) });
|
|
239
|
+
if ('pdf' in ergebnis)
|
|
240
|
+
return { kind: 'pdf', pdf: ergebnis.pdf };
|
|
241
|
+
const link = (0, lesen_js_1.objekt)(ergebnis.data)?.download;
|
|
242
|
+
if (link === undefined || link === null)
|
|
243
|
+
throw (0, lesen_js_1.antwortfehler)(name, 'Antwort ist weder ein PDF noch ein Lese-Link (data.download fehlt)');
|
|
244
|
+
return { kind: 'download', download: (0, lesen_js_1.protokollLink)(name, link) };
|
|
245
|
+
}
|
|
@@ -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, GoodsReceiptPreviewLine, InventoryShortfall, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookTestDelivery, Location, Reservation, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockMovement, StockOperation, StockValue, VariantGroup } from './typen.js';
|
|
15
|
+
import type { Article, GoodsReceiptPreviewLine, InventoryShortfall, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookTestDelivery, Location, Reservation, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockMovement, StockOperation, StockValue, Stocktake, StocktakeCount, StocktakeCountResult, StocktakeItem, StocktakePdfDownload, StocktakeWarning, VariantGroup } 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 {
|
|
@@ -44,6 +44,25 @@ export declare function fehlmengen(roh: unknown): InventoryShortfall[];
|
|
|
44
44
|
* bzw. „keine Varianten“).
|
|
45
45
|
*/
|
|
46
46
|
export declare function variantengruppe(ort: Ort, w: unknown): VariantGroup;
|
|
47
|
+
/** Hinweise einer Inventur; fehlt die Liste, gibt es keine. */
|
|
48
|
+
export declare function inventurWarnungen(ort: Ort, w: unknown): StocktakeWarning[];
|
|
49
|
+
/**
|
|
50
|
+
* Kopf einer Inventur. Was erst nach dem Abschluss kommt (Summen, Hinweise,
|
|
51
|
+
* Siegel, Pruefsumme, Protokoll), steht im Modell nur, wenn der Server es
|
|
52
|
+
* sendet; Werte nur mit dem Kosten-Recht.
|
|
53
|
+
*/
|
|
54
|
+
export declare function inventur(ort: Ort, w: unknown): Stocktake;
|
|
55
|
+
/**
|
|
56
|
+
* Eine Position. Soll, Differenz und alles aus Pruefung und Abschluss stehen
|
|
57
|
+
* im Modell nur, wenn der Server sie sendet (blind: vor `review` nie).
|
|
58
|
+
*/
|
|
59
|
+
export declare function inventurPosition(ort: Ort, w: unknown): StocktakeItem;
|
|
60
|
+
/** Eine Zaehlung: Menge, Runde und Kennungen muessen da sein. */
|
|
61
|
+
export declare function inventurZaehlung(ort: Ort, w: unknown): StocktakeCount;
|
|
62
|
+
/** Antwort von Zaehlen und Stornieren: beide Teile sind zugesagt. */
|
|
63
|
+
export declare function zaehlungMitPosition(name: string, daten: unknown): StocktakeCountResult;
|
|
64
|
+
/** Lese-Link auf ein grosses Inventurprotokoll; ohne Adresse, Ablauf, Groesse oder Pruefsumme ist er unbrauchbar. */
|
|
65
|
+
export declare function protokollLink(name: string, w: unknown): StocktakePdfDownload;
|
|
47
66
|
/** Eine zugesagte Liste `data.<feld>`, Eintrag fuer Eintrag gelesen. */
|
|
48
67
|
export declare function liste<T>(name: string, daten: unknown, feld: string, lesen: (ort: Ort, e: unknown) => T): T[];
|
|
49
68
|
/** Der Cursor der naechsten Seite; `null` am Ende. Etwas anderes als Text oder `null` ist kaputt. */
|