@kreiseck/kasseneck-api 0.11.0 → 0.13.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 CHANGED
@@ -4,6 +4,63 @@ Was vor 0.7.0 geschah, steht in der Commit-Historie (`git log`); ab hier wird
4
4
  es hier geführt. Ein Eintrag nennt die Änderung **und ihren Grund** —
5
5
  nur der Grund überlebt den nächsten Umbau.
6
6
 
7
+ ## 0.13.0
8
+
9
+ ### Beleg per E-Mail an den Gast (`sendReceiptEmail`)
10
+
11
+ **Anlass:** Der Endpunkt ist im Backend live (keck#361), beide Kassen haben den
12
+ Weg gebaut — hinter einer Schnittstelle, hinter der nichts stand, weil kein
13
+ Paket den Aufruf kannte. Verschickt wird ein **Link auf die öffentliche
14
+ Belegseite**, kein PDF im Anhang: die Belegseite führt dasselbe Zeilenmodell
15
+ wie Bildschirm und Bon, ein mitgeschicktes PDF wäre dieselbe Sache ein zweites
16
+ Mal, nur unveränderlich veraltet. Der Beleg selbst bleibt unberührt (BAO §131 /
17
+ RKSV); das Versandprotokoll führt das Backend neben ihm.
18
+
19
+ - **`sendReceiptEmail({ fullReceiptId, to, sprache? })`** — auch auf der
20
+ Fassade `createKasseneckApi`. Antwort: `{ to, at, via }` — Adresse in der
21
+ protokollierten Form, Zeitpunkt als ISO mit Wiener Zonenoffset, Versandweg
22
+ (`eigen`, `plattform`, `plattform-fallback`; fehlt er, ist `via` `null` und
23
+ nicht etwa ein Fehler — er sagt etwas über den Weg, nichts über den Erfolg).
24
+ - **Kein `cashregisterId` in den Optionen.** Die Kasse kommt aus der Anmeldung:
25
+ beim Gerät über die Kopfzeile `cashregister-token`, beim Kassen-Benutzer über
26
+ den Parameter, den `registerUserAuth` ohnehin setzt. Eine dritte Stelle wäre
27
+ nur eine Gelegenheit, eine andere Kasse zu behaupten als die, an der man
28
+ angemeldet ist — und das Backend nimmt den Belegpfad aus der angemeldeten.
29
+ - **`RECEIPT_EMAIL_ERROR_CODES`**, Typ `ReceiptEmailErrorCode` und der Wächter
30
+ `isReceiptEmailErrorCode`: `adresse_ungueltig`, `beleg_nicht_gefunden`
31
+ (auch für einen Beleg einer fremden Kasse — das Backend gibt darüber bewusst
32
+ keine Auskunft), `zu_oft` (5 Mails je Beleg in 24 Stunden, 30 je Kasse und
33
+ Stunde) und `versand_fehlgeschlagen`. Die Codes kommen unverändert als
34
+ `KasseneckApiError.code` heraus; das Paket legt keine eigenen an. **Am Code
35
+ entscheiden, nie am deutschen Text.**
36
+ - Die Adresse prüft das Paket **nicht** selbst — nur leer/fehlend wird vor dem
37
+ Senden abgewiesen (`fullReceiptId`, `to`; beides getrimmt, weil es von Hand
38
+ ins Feld kommt). Eine zweite, eigene Adressregel könnte strenger sein als die
39
+ des Backends und eine gültige Adresse abweisen, ohne dass es auffällt.
40
+ - `sendReceiptEmail` steht in `AUFRUFE` und damit in
41
+ `fixtures/oberflaeche.json` — der Zwilling `kasseneck_api` (Dart) prüft
42
+ dagegen.
43
+
44
+ ## 0.12.0
45
+
46
+ ### Storno mit Kartendaten der Erstattung
47
+
48
+ **Anlass:** sastre zieht vom alten Storno-Weg (`createCancelReceipt`, ohne
49
+ Bezug) auf `cancelReceipt` um. Bei einer Kartenerstattung haengt sastre heute
50
+ die Terminaldaten der Gutschrift/Aufhebung an den Stornobeleg -- ueber den
51
+ neuen Endpunkt ging das bisher nicht, der Kartenblock fiele vom Storno-Bon.
52
+ Backend: keck#371.
53
+
54
+ - **`cancelReceipt` nimmt `creditCardProvider`, `cardPaymentId` und
55
+ `cardPaymentData` an** -- die Daten der ERSTATTUNG, nie der Originalzahlung.
56
+ Nur bei Rueckzahlweg Karte: ein ausdruecklich anderer `paymentMethod` wird
57
+ schon hier abgewiesen, ohne Angabe entscheidet das Backend an der
58
+ Zahlungsart des Originals. Ein unbekannter Kartenanbieter geht gar nicht erst
59
+ raus.
60
+ - Ohne Kartendaten aendert sich nichts.
61
+ - `package-lock.json` traegt wieder die Paketversion (stand seit 0.11.0 auf
62
+ 0.10.0).
63
+
7
64
  ## 0.11.0
8
65
 
9
66
  ### Die QR-Modulgröße wird gerechnet, nicht gesetzt — samt Notausgang und Modell 1
package/README.md CHANGED
@@ -211,6 +211,32 @@ Grund: „STORNOBELEG / Stornobuchung zu Beleg KASSE1-ID-42 / vom 11.08.2026,
211
211
  09:02 Uhr / Grund: Fehleingabe". Das Datum kommt aus `cancellationOf.timeStamp`
212
212
  (Backend seit 2026-09-04); Altbelege ohne bleiben ohne die Zeile.
213
213
 
214
+ ## Beleg per E-Mail an den Gast
215
+
216
+ ```ts
217
+ const bestaetigung = await api.sendReceiptEmail({
218
+ fullReceiptId: beleg.fullReceiptId, // oder api.generateFullReceiptId(receiptId)
219
+ to: 'gast@example.at',
220
+ sprache: 'de', // optional; heute wertet das Backend nur 'de' aus
221
+ });
222
+ bestaetigung.to; // Adresse, wie das Backend sie protokolliert hat
223
+ bestaetigung.at; // Zeitpunkt, ISO mit Wiener Zonenoffset
224
+ bestaetigung.via; // 'eigen' | 'plattform' | 'plattform-fallback' | null
225
+ ```
226
+
227
+ Verschickt wird ein **Link auf die öffentliche Belegseite**, kein PDF im
228
+ Anhang: die Belegseite führt dasselbe Zeilenmodell wie Bildschirm und Bon und
229
+ liefert dort auf Wunsch ein PDF. Der Beleg selbst bleibt unberührt (BAO §131 /
230
+ RKSV) — das Versandprotokoll führt das Backend neben ihm.
231
+
232
+ Die Kasse kommt aus der Anmeldung (Kopfzeile `cashregister-token` bzw. der
233
+ Parameter, den `registerUserAuth` setzt), nicht aus den Optionen; ein Beleg
234
+ einer anderen Kasse ist deshalb dieselbe Auskunft wie ein Beleg, den es nicht
235
+ gibt. Auch hier gilt: **am Code entscheiden, nicht am Text.** Die Codes stehen
236
+ in `RECEIPT_EMAIL_ERROR_CODES` (`isReceiptEmailErrorCode`):
237
+ `adresse_ungueltig`, `beleg_nicht_gefunden`, `zu_oft` (5 Mails je Beleg in 24
238
+ Stunden, 30 je Kasse und Stunde) und `versand_fehlgeschlagen`.
239
+
214
240
  ## Partner-API (`./partner`)
215
241
 
216
242
  Für Softwarehäuser, die Kasseneck in ihr eigenes Produkt einbauen: Betriebe
@@ -3,7 +3,7 @@ import { type CreateStripeLinkOptions, type StripeCaptureResult } from '../payme
3
3
  import { type HobexPayOptions, type HobexRefundOptions } from '../payments/hobex.js';
4
4
  import { type TransportOptions } from './transport.js';
5
5
  import { type CashboxStatus, type SignatureStatus } from './status.js';
6
- import { type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
6
+ import { type SendReceiptEmailOptions, type SendReceiptEmailResult, type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
7
7
  /**
8
8
  * Schlichte Factory ueber den Endpunkt-Funktionen: bindet einen Transport
9
9
  * einmal und liefert die Aufrufe ohne den wiederkehrenden ersten Parameter.
@@ -47,6 +47,8 @@ export interface KasseneckApi {
47
47
  generateFullReceiptId(receiptId: string): Promise<string>;
48
48
  /** Berichtsmonat des ersten Belegs (nicht fuer den Kassen-Benutzer-Weg). */
49
49
  getFirstReceiptDate(): Promise<ReportMonth>;
50
+ /** Beleg als Link auf die oeffentliche Belegseite per E-Mail schicken. */
51
+ sendReceiptEmail(options: SendReceiptEmailOptions): Promise<SendReceiptEmailResult>;
50
52
  /** Belegliste einer Kasse samt Kennzahlen (nur mit ID-Token, siehe receipts.ts). */
51
53
  listMyReceipts(options: ListMyReceiptsOptions): Promise<ReceiptList>;
52
54
  /** Kassen des angemeldeten Benutzers (nur mit ID-Token, siehe cashregisters.ts). */
@@ -25,6 +25,7 @@ function createKasseneckApi(options) {
25
25
  generateFullReceiptId: (receiptId) => (0, receipts_js_1.generateFullReceiptId)(rufen, receiptId),
26
26
  getFirstReceiptDate: () => (0, receipts_js_1.getFirstReceiptDate)(rufen),
27
27
  listMyReceipts: (o) => (0, receipts_js_1.listMyReceipts)(rufen, o),
28
+ sendReceiptEmail: (o) => (0, receipts_js_1.sendReceiptEmail)(rufen, o),
28
29
  listMyCashregisters: () => (0, cashregisters_js_1.listMyCashregisters)(rufen),
29
30
  downloadDailyReport: (date) => (0, reports_js_1.downloadDailyReport)(rufenBinaer, date),
30
31
  downloadMonthlyReport: (reportMonth) => (0, reports_js_1.downloadMonthlyReport)(rufenBinaer, reportMonth),
@@ -13,7 +13,7 @@
13
13
  * umhuellt, muss ihn weiterhin absetzen koennen.
14
14
  */
15
15
  import type { TransportBodyFields } from './transport.js';
16
- export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
16
+ export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "sendReceiptEmail", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
17
17
  export type Aufruf = typeof AUFRUFE[number];
18
18
  /** Wie [KasseneckTransport], nur mit bekanntem Aufrufnamen. Nicht exportiert nach aussen. */
19
19
  export type InternerTransport = <T = unknown>(functionName: Aufruf, params?: Record<string, unknown>, extraBodyFields?: TransportBodyFields, secretParams?: readonly string[]) => Promise<T>;
@@ -46,6 +46,7 @@ exports.AUFRUFE = [
46
46
  'requestCustomerSignature',
47
47
  'sendPartnerCustomerFonLink',
48
48
  'sendPartnerWebhookTest',
49
+ 'sendReceiptEmail',
49
50
  'setMyKasseSettings',
50
51
  'setMyRegisterDeviceSettings',
51
52
  'stripeCaptureIntent',
@@ -2,7 +2,7 @@ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type
2
2
  export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, createTransport, createBinaryTransport, } from './transport.js';
3
3
  export { AUFRUFE, type Aufruf, } from './aufrufe.js';
4
4
  export { KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, } from './errors.js';
5
- export { type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, } from './receipts.js';
5
+ export { type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, } from './receipts.js';
6
6
  export { listMyCashregisters } from './cashregisters.js';
7
7
  export { downloadDailyReport, downloadMonthlyReport } from './reports.js';
8
8
  export { type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, } from './status.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.listMyCashregisters = exports.checkVoucherCombinationError = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.AUFRUFE = exports.createBinaryTransport = exports.createTransport = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = void 0;
3
+ exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.listMyCashregisters = exports.sendReceiptEmail = exports.checkVoucherCombinationError = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.AUFRUFE = exports.createBinaryTransport = exports.createTransport = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = void 0;
4
4
  var auth_js_1 = require("./auth.js");
5
5
  Object.defineProperty(exports, "apiKeyAuth", { enumerable: true, get: function () { return auth_js_1.apiKeyAuth; } });
6
6
  Object.defineProperty(exports, "registerUserAuth", { enumerable: true, get: function () { return auth_js_1.registerUserAuth; } });
@@ -34,6 +34,7 @@ Object.defineProperty(exports, "generateFullReceiptId", { enumerable: true, get:
34
34
  Object.defineProperty(exports, "getFirstReceiptDate", { enumerable: true, get: function () { return receipts_js_1.getFirstReceiptDate; } });
35
35
  Object.defineProperty(exports, "listMyReceipts", { enumerable: true, get: function () { return receipts_js_1.listMyReceipts; } });
36
36
  Object.defineProperty(exports, "checkVoucherCombinationError", { enumerable: true, get: function () { return receipts_js_1.checkVoucherCombinationError; } });
37
+ Object.defineProperty(exports, "sendReceiptEmail", { enumerable: true, get: function () { return receipts_js_1.sendReceiptEmail; } });
37
38
  var cashregisters_js_1 = require("./cashregisters.js");
38
39
  Object.defineProperty(exports, "listMyCashregisters", { enumerable: true, get: function () { return cashregisters_js_1.listMyCashregisters; } });
39
40
  var reports_js_1 = require("./reports.js");
@@ -117,6 +117,14 @@ export type CancelReceiptOptions = {
117
117
  note?: string;
118
118
  /** Rueckzahlweg; ohne Angabe die Zahlungsart des stornierten Belegs. */
119
119
  paymentMethod?: KeckPaymentMethod | KeckPaymentMethodKey;
120
+ /**
121
+ * Kartendaten der ERSTATTUNG (Gutschrift oder Aufhebung am Terminal) fuer
122
+ * den Kartenblock am Storno-Bon -- nur bei Rueckzahlweg Karte. Beschreiben
123
+ * nie die Originalzahlung; das Backend uebernimmt sie nicht vom Original.
124
+ */
125
+ creditCardProvider?: CreditCardProvider;
126
+ cardPaymentId?: string;
127
+ cardPaymentData?: Record<string, unknown>;
120
128
  } & ({
121
129
  receipt: Receipt;
122
130
  cashregisterId?: string;
@@ -277,6 +285,63 @@ export declare function generateFullReceiptId(rufen: InternerTransport, receiptI
277
285
  * (siehe Modulkommentar oben). Mit `apiKeyAuth` ist er offen.
278
286
  */
279
287
  export declare function getFirstReceiptDate(rufen: InternerTransport): Promise<ReportMonth>;
288
+ /**
289
+ * Beleg per E-Mail an den Endkunden — die Eingabe von [sendReceiptEmail].
290
+ *
291
+ * `cashregisterId` steht hier bewusst **nicht**: der Geraeteweg bindet die
292
+ * Kasse ueber die Kopfzeile `cashregister-token`, der Kassen-Benutzer-Weg
293
+ * ueber den Parameter, den `registerUserAuth` ohnehin schon setzt. Eine
294
+ * dritte Stelle waere nur eine Gelegenheit, eine andere Kasse zu behaupten,
295
+ * als die, an der man angemeldet ist — und das Backend nimmt den Belegpfad aus
296
+ * der angemeldeten Kasse, nicht aus der Nutzlast.
297
+ */
298
+ export interface SendReceiptEmailOptions {
299
+ /** Verschluesselte Volltext-Belegnummer (siehe [generateFullReceiptId]). */
300
+ fullReceiptId: string;
301
+ /** Empfaengeradresse, wie der Gast sie am Tresen nennt. */
302
+ to: string;
303
+ /**
304
+ * Sprache der Mail. Heute wertet das Backend genau `'de'` aus; der Parameter
305
+ * steht im Vertrag, damit eine zweite Sprache spaeter kein neuer Vertrag ist.
306
+ * Ohne Angabe geht das Feld gar nicht erst hinaus.
307
+ */
308
+ sprache?: string;
309
+ }
310
+ /** Was der Versand bestaetigt (Backend: beleg-mail-endpoints.js). */
311
+ export interface SendReceiptEmailResult {
312
+ /** Adresse in der Form, in der das Backend sie protokolliert hat (getrimmt, klein). */
313
+ to: string;
314
+ /** Zeitpunkt des Versands, ISO mit Wiener Zonenoffset (`2026-09-11T14:05:00+02:00`). */
315
+ at: string;
316
+ /**
317
+ * Versandweg: `eigen` (Postfach des Betriebs), `plattform` oder
318
+ * `plattform-fallback`. `null`, wenn die Antwort ihn nicht nennt — das ist
319
+ * eine Auskunft ueber den Weg, keine ueber den Erfolg, und darf den
320
+ * bestaetigten Versand nicht zu einem Fehler machen.
321
+ */
322
+ via: string | null;
323
+ }
324
+ /**
325
+ * Schickt einen bereits ausgestellten Beleg als **Link auf die oeffentliche
326
+ * Belegseite** an eine Adresse (Endpunkt `sendReceiptEmail`, Backend
327
+ * beleg-mail-endpoints.js). Kein PDF im Anhang: die Belegseite fuehrt dasselbe
328
+ * Zeilenmodell wie Bildschirm und Bon und liefert dort auf Wunsch ein PDF.
329
+ *
330
+ * **Der Beleg bleibt unberuehrt** (BAO §131/RKSV): das Versandprotokoll fuehrt
331
+ * das Backend in einer Unter-Sammlung neben dem Beleg.
332
+ *
333
+ * **Am Code entscheiden, nie am Text:** fachliche Fehler kommen als
334
+ * [KasseneckApiError] mit `code` aus [RECEIPT_EMAIL_ERROR_CODES] heraus —
335
+ * `adresse_ungueltig`, `beleg_nicht_gefunden` (auch fuer einen Beleg einer
336
+ * fremden Kasse: das Backend gibt darueber bewusst keine Auskunft), `zu_oft`
337
+ * (5 Mails je Beleg in 24 Stunden, 30 je Kasse und Stunde) und
338
+ * `versand_fehlgeschlagen`. Dieses Paket reicht sie unveraendert durch und
339
+ * legt keine eigenen Codes an.
340
+ *
341
+ * **Kein Wiederholen ohne Zutun des Bedieners:** ein zweiter Versuch schickt
342
+ * eine zweite Mail und zaehlt auf die Schleuse.
343
+ */
344
+ export declare function sendReceiptEmail(rufen: InternerTransport, options: SendReceiptEmailOptions): Promise<SendReceiptEmailResult>;
280
345
  /**
281
346
  * Prueft die Gutschein-Kombination eines Belegs und liefert den ersten
282
347
  * Regelverstoss als Text (oder `null`) — Zwilling von
@@ -11,6 +11,7 @@ exports.getReceipt = getReceipt;
11
11
  exports.getReceiptWithCompany = getReceiptWithCompany;
12
12
  exports.generateFullReceiptId = generateFullReceiptId;
13
13
  exports.getFirstReceiptDate = getFirstReceiptDate;
14
+ exports.sendReceiptEmail = sendReceiptEmail;
14
15
  exports.checkVoucherCombinationError = checkVoucherCombinationError;
15
16
  const index_js_1 = require("../enums/index.js");
16
17
  const index_js_2 = require("../models/index.js");
@@ -154,6 +155,24 @@ async function cancelReceipt(rufen, options) {
154
155
  params.note = options.note;
155
156
  if (options.paymentMethod != null)
156
157
  params.paymentMethod = gepruefteZahlungsart(options.paymentMethod);
158
+ const karte = options.creditCardProvider != null || options.cardPaymentId != null || options.cardPaymentData != null;
159
+ if (karte) {
160
+ // Ohne paymentMethod entscheidet das Backend an der Zahlungsart des
161
+ // Originals; ein ausdruecklich anderer Rueckzahlweg ist hier schon falsch.
162
+ if (params.paymentMethod != null && params.paymentMethod !== index_js_1.KeckPaymentMethod.creditCard.value) {
163
+ throw new errors_js_1.KasseneckValidationError('cancelReceipt', 'Kartendaten gibt es nur bei paymentMethod creditCard', 'request');
164
+ }
165
+ if (options.creditCardProvider != null) {
166
+ if (!Object.prototype.hasOwnProperty.call(index_js_1.CreditCardProvider, options.creditCardProvider)) {
167
+ throw new errors_js_1.KasseneckValidationError('cancelReceipt', `Kartenanbieter: unbekannter Schluessel "${options.creditCardProvider}"`, 'request');
168
+ }
169
+ params.creditCardProvider = options.creditCardProvider;
170
+ }
171
+ if (options.cardPaymentId != null && options.cardPaymentId !== '')
172
+ params.cardPaymentId = options.cardPaymentId;
173
+ if (options.cardPaymentData != null)
174
+ params.cardPaymentData = options.cardPaymentData;
175
+ }
157
176
  const daten = await rufen('cancelReceipt', params);
158
177
  const receipt = belegAusHuelle(daten, 'cancelReceipt');
159
178
  const huelle = daten;
@@ -309,6 +328,54 @@ async function getFirstReceiptDate(rufen) {
309
328
  throw antwortfehler('getFirstReceiptDate', 'Antwort enthaelt keinen lesbaren Zeitstempel');
310
329
  }
311
330
  }
331
+ /**
332
+ * Schickt einen bereits ausgestellten Beleg als **Link auf die oeffentliche
333
+ * Belegseite** an eine Adresse (Endpunkt `sendReceiptEmail`, Backend
334
+ * beleg-mail-endpoints.js). Kein PDF im Anhang: die Belegseite fuehrt dasselbe
335
+ * Zeilenmodell wie Bildschirm und Bon und liefert dort auf Wunsch ein PDF.
336
+ *
337
+ * **Der Beleg bleibt unberuehrt** (BAO §131/RKSV): das Versandprotokoll fuehrt
338
+ * das Backend in einer Unter-Sammlung neben dem Beleg.
339
+ *
340
+ * **Am Code entscheiden, nie am Text:** fachliche Fehler kommen als
341
+ * [KasseneckApiError] mit `code` aus [RECEIPT_EMAIL_ERROR_CODES] heraus —
342
+ * `adresse_ungueltig`, `beleg_nicht_gefunden` (auch fuer einen Beleg einer
343
+ * fremden Kasse: das Backend gibt darueber bewusst keine Auskunft), `zu_oft`
344
+ * (5 Mails je Beleg in 24 Stunden, 30 je Kasse und Stunde) und
345
+ * `versand_fehlgeschlagen`. Dieses Paket reicht sie unveraendert durch und
346
+ * legt keine eigenen Codes an.
347
+ *
348
+ * **Kein Wiederholen ohne Zutun des Bedieners:** ein zweiter Versuch schickt
349
+ * eine zweite Mail und zaehlt auf die Schleuse.
350
+ */
351
+ async function sendReceiptEmail(rufen, options) {
352
+ // Getrimmt, weil beides von Hand oder per Scanner ins Feld kommt und ein
353
+ // angehaengtes Leerzeichen sonst als ungueltige Adresse zurueckkaeme --
354
+ // nach einem Aufruf, der schon eine Zeile im Protokoll gekostet hat.
355
+ const fullReceiptId = typeof options.fullReceiptId === 'string' ? options.fullReceiptId.trim() : '';
356
+ const to = typeof options.to === 'string' ? options.to.trim() : '';
357
+ if (fullReceiptId === '') {
358
+ throw new errors_js_1.KasseneckValidationError('sendReceiptEmail', 'fullReceiptId fehlt', 'request');
359
+ }
360
+ if (to === '') {
361
+ throw new errors_js_1.KasseneckValidationError('sendReceiptEmail', 'to fehlt (Empfaengeradresse)', 'request');
362
+ }
363
+ // Die Adresse selbst wird hier NICHT geprueft: das Backend prueft sie mit
364
+ // kreiseck_validator und antwortet mit `adresse_ungueltig`. Eine zweite,
365
+ // eigene Regel im Paket koennte strenger sein als die des Backends und eine
366
+ // gueltige Adresse abweisen, ohne dass jemand die Abweichung bemerkt.
367
+ const params = { fullReceiptId, to };
368
+ if (options.sprache !== undefined && options.sprache !== '')
369
+ params.sprache = options.sprache;
370
+ const daten = await rufen('sendReceiptEmail', params);
371
+ if (typeof daten?.to !== 'string' || daten.to === '') {
372
+ throw antwortfehler('sendReceiptEmail', 'Antwort nennt keine Empfaengeradresse (data.to fehlt)');
373
+ }
374
+ if (typeof daten.at !== 'string' || daten.at === '') {
375
+ throw antwortfehler('sendReceiptEmail', 'Antwort nennt keinen Zeitpunkt (data.at fehlt)');
376
+ }
377
+ return { to: daten.to, at: daten.at, via: typeof daten.via === 'string' && daten.via !== '' ? daten.via : null };
378
+ }
312
379
  /**
313
380
  * Prueft die Gutschein-Kombination eines Belegs und liefert den ersten
314
381
  * Regelverstoss als Text (oder `null`) — Zwilling von
@@ -1,5 +1,5 @@
1
1
  export { ReceiptType, type ReceiptTypeKey, VatRate, type VatRateKey, KeckPaymentMethod, type KeckPaymentMethodKey, CreditCardProvider, type CreditCardProviderKey, VoucherType, type VoucherTypeKey, VoucherAction, type VoucherActionKey, StripeLinkMode, type StripeLinkModeKey, } from './enums/index.js';
2
- export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
- export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
2
+ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
+ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
4
4
  export { parseServerTimeStamp, toViennaWallClock, type ViennaWallClock } from './vienna-time.js';
5
5
  export { type KasseSettingsBetrieb, type KasseSettingsGeraet, type KasseSettings, type ArticleGroup, type KasseArtikel, KASSE_BETRIEB_STANDARD, KASSE_GERAET_STANDARD, mergeKasseSettings, fromArticleGroupPayload, fromKasseArtikelPayload, listMyArticleGroups, listMyArticles, getKasseSettings, setMyKasseSettings, setMyRegisterDeviceSettings, verteileRabatt, cancelScopeOf, receiptsScopeOf, } from './kasse/index.js';
package/dist/cjs/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBinaryTransport = exports.createTransport = exports.AUFRUFE = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
4
- exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = void 0;
3
+ exports.AUFRUFE = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = exports.registerUserAuth = exports.apiKeyAuth = exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isReceiptEmailErrorCode = exports.RECEIPT_EMAIL_ERROR_CODES = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
4
+ exports.receiptsScopeOf = exports.cancelScopeOf = exports.verteileRabatt = exports.setMyRegisterDeviceSettings = exports.setMyKasseSettings = exports.getKasseSettings = exports.listMyArticles = exports.listMyArticleGroups = exports.fromKasseArtikelPayload = exports.fromArticleGroupPayload = exports.mergeKasseSettings = exports.KASSE_GERAET_STANDARD = exports.KASSE_BETRIEB_STANDARD = exports.toViennaWallClock = exports.parseServerTimeStamp = exports.createKasseneckApi = exports.getSignatureStatus = exports.getCashboxStatus = exports.downloadMonthlyReport = exports.downloadDailyReport = exports.sendReceiptEmail = exports.checkVoucherCombinationError = exports.listMyCashregisters = exports.listMyReceipts = exports.getFirstReceiptDate = exports.generateFullReceiptId = exports.getReceiptWithCompany = exports.getReceipt = exports.zeroReceipt = exports.createCancelReceipt = exports.cancelReceipt = exports.sellReceiptWithCompany = exports.sellReceipt = exports.isKasseneckValidationError = exports.isKasseneckNetworkError = exports.isKasseneckHttpError = exports.isKasseneckAuthError = exports.isKasseneckApiError = exports.KasseneckValidationError = exports.KasseneckNetworkError = exports.KasseneckHttpError = exports.KasseneckAuthError = exports.KasseneckApiError = exports.createBinaryTransport = exports.createTransport = void 0;
5
5
  var index_js_1 = require("./enums/index.js");
6
6
  Object.defineProperty(exports, "ReceiptType", { enumerable: true, get: function () { return index_js_1.ReceiptType; } });
7
7
  Object.defineProperty(exports, "VatRate", { enumerable: true, get: function () { return index_js_1.VatRate; } });
@@ -29,6 +29,8 @@ Object.defineProperty(exports, "CANCELLATION_ERROR_CODES", { enumerable: true, g
29
29
  Object.defineProperty(exports, "CANCELLATION_RESERVATION_MS", { enumerable: true, get: function () { return index_js_2.CANCELLATION_RESERVATION_MS; } });
30
30
  Object.defineProperty(exports, "isCancellationReason", { enumerable: true, get: function () { return index_js_2.isCancellationReason; } });
31
31
  Object.defineProperty(exports, "isCancellationErrorCode", { enumerable: true, get: function () { return index_js_2.isCancellationErrorCode; } });
32
+ Object.defineProperty(exports, "RECEIPT_EMAIL_ERROR_CODES", { enumerable: true, get: function () { return index_js_2.RECEIPT_EMAIL_ERROR_CODES; } });
33
+ Object.defineProperty(exports, "isReceiptEmailErrorCode", { enumerable: true, get: function () { return index_js_2.isReceiptEmailErrorCode; } });
32
34
  Object.defineProperty(exports, "remainingQuantities", { enumerable: true, get: function () { return index_js_2.remainingQuantities; } });
33
35
  Object.defineProperty(exports, "fromReceiptCompanyPayload", { enumerable: true, get: function () { return index_js_2.fromReceiptCompanyPayload; } });
34
36
  Object.defineProperty(exports, "receiptCompanyTaxInfo", { enumerable: true, get: function () { return index_js_2.receiptCompanyTaxInfo; } });
@@ -77,6 +79,7 @@ Object.defineProperty(exports, "getFirstReceiptDate", { enumerable: true, get: f
77
79
  Object.defineProperty(exports, "listMyReceipts", { enumerable: true, get: function () { return index_js_3.listMyReceipts; } });
78
80
  Object.defineProperty(exports, "listMyCashregisters", { enumerable: true, get: function () { return index_js_3.listMyCashregisters; } });
79
81
  Object.defineProperty(exports, "checkVoucherCombinationError", { enumerable: true, get: function () { return index_js_3.checkVoucherCombinationError; } });
82
+ Object.defineProperty(exports, "sendReceiptEmail", { enumerable: true, get: function () { return index_js_3.sendReceiptEmail; } });
80
83
  Object.defineProperty(exports, "downloadDailyReport", { enumerable: true, get: function () { return index_js_3.downloadDailyReport; } });
81
84
  Object.defineProperty(exports, "downloadMonthlyReport", { enumerable: true, get: function () { return index_js_3.downloadMonthlyReport; } });
82
85
  Object.defineProperty(exports, "getCashboxStatus", { enumerable: true, get: function () { return index_js_3.getCashboxStatus; } });
@@ -2,6 +2,7 @@ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead,
2
2
  export { type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid } from './voucher.js';
3
3
  export { type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, } from './receipt.js';
4
4
  export { type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, } from './cancellation.js';
5
+ export { type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, } from './receipt-email.js';
5
6
  export { type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, } from './receipt-company.js';
6
7
  export { type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, } from './cashregister.js';
7
8
  export { type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind } from './receipt-summary.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isDiscountItem = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = void 0;
3
+ exports.hobexReceiptNeedsSignature = exports.hobexReceiptToCardPaymentData = exports.fromHobexReceiptPayload = exports.toHobexReceiptPayload = exports.fromStripeUrlSessionPayload = exports.toStripeUrlSessionPayload = exports.reportMonthReadable = exports.reportMonthKey = exports.nextReportMonth = exports.previousReportMonth = exports.reportMonthFromDate = exports.istZeroKind = exports.ZERO_KINDS = exports.fromReceiptSummaryPayload = exports.fromCashregisterPayload = exports.receiptCompanyTaxInfo = exports.fromReceiptCompanyPayload = exports.isReceiptEmailErrorCode = exports.RECEIPT_EMAIL_ERROR_CODES = exports.remainingQuantities = exports.isCancellationErrorCode = exports.isCancellationReason = exports.CANCELLATION_RESERVATION_MS = exports.CANCELLATION_ERROR_CODES = exports.CANCELLATION_REASONS = exports.receiptSumCents = exports.receiptSubSumCents = exports.fromReceiptPayload = exports.toReceiptPayload = exports.voucherIsValid = exports.fromVoucherPayload = exports.toVoucherPayload = exports.isDiscountItem = exports.isTipItem = exports.negateReceiptItem = exports.receiptItemIsValid = exports.receiptItemTotalCents = exports.fromReceiptItemPayload = exports.toReceiptItemPayload = void 0;
4
4
  var receipt_item_js_1 = require("./receipt-item.js");
5
5
  Object.defineProperty(exports, "toReceiptItemPayload", { enumerable: true, get: function () { return receipt_item_js_1.toReceiptItemPayload; } });
6
6
  Object.defineProperty(exports, "fromReceiptItemPayload", { enumerable: true, get: function () { return receipt_item_js_1.fromReceiptItemPayload; } });
@@ -25,6 +25,9 @@ Object.defineProperty(exports, "CANCELLATION_RESERVATION_MS", { enumerable: true
25
25
  Object.defineProperty(exports, "isCancellationReason", { enumerable: true, get: function () { return cancellation_js_1.isCancellationReason; } });
26
26
  Object.defineProperty(exports, "isCancellationErrorCode", { enumerable: true, get: function () { return cancellation_js_1.isCancellationErrorCode; } });
27
27
  Object.defineProperty(exports, "remainingQuantities", { enumerable: true, get: function () { return cancellation_js_1.remainingQuantities; } });
28
+ var receipt_email_js_1 = require("./receipt-email.js");
29
+ Object.defineProperty(exports, "RECEIPT_EMAIL_ERROR_CODES", { enumerable: true, get: function () { return receipt_email_js_1.RECEIPT_EMAIL_ERROR_CODES; } });
30
+ Object.defineProperty(exports, "isReceiptEmailErrorCode", { enumerable: true, get: function () { return receipt_email_js_1.isReceiptEmailErrorCode; } });
28
31
  var receipt_company_js_1 = require("./receipt-company.js");
29
32
  Object.defineProperty(exports, "fromReceiptCompanyPayload", { enumerable: true, get: function () { return receipt_company_js_1.fromReceiptCompanyPayload; } });
30
33
  Object.defineProperty(exports, "receiptCompanyTaxInfo", { enumerable: true, get: function () { return receipt_company_js_1.receiptCompanyTaxInfo; } });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Beleg per E-Mail — Zwilling von `functions/beleg-mail-core.js`.
3
+ *
4
+ * Hier steht nur der Fehlercode-Katalog: der Aufruf selbst ist
5
+ * [sendReceiptEmail] (client/receipts.ts), und was verschickt wird, ist ein
6
+ * **Link auf die oeffentliche Belegseite** — der Beleg selbst bleibt
7
+ * unberuehrt (BAO §131/RKSV), das Versandprotokoll fuehrt das Backend in einer
8
+ * Unter-Sammlung neben ihm.
9
+ */
10
+ /**
11
+ * Stabile Fehlercodes von `sendReceiptEmail` — Zwilling von
12
+ * `beleg-mail-core.js` FEHLERCODES. Das Backend legt sie bei jedem fachlichen
13
+ * Fehler als `code` neben die Meldung; das Paket reicht sie als
14
+ * [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** — die
15
+ * deutsche Meldung darf sich aendern, der Code nicht.
16
+ *
17
+ * Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
18
+ * ohne Code; dort bleibt `code` undefined.
19
+ */
20
+ export declare const RECEIPT_EMAIL_ERROR_CODES: readonly ["adresse_ungueltig", "beleg_nicht_gefunden", "zu_oft", "versand_fehlgeschlagen"];
21
+ export type ReceiptEmailErrorCode = (typeof RECEIPT_EMAIL_ERROR_CODES)[number];
22
+ export declare function isReceiptEmailErrorCode(value: unknown): value is ReceiptEmailErrorCode;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Beleg per E-Mail — Zwilling von `functions/beleg-mail-core.js`.
4
+ *
5
+ * Hier steht nur der Fehlercode-Katalog: der Aufruf selbst ist
6
+ * [sendReceiptEmail] (client/receipts.ts), und was verschickt wird, ist ein
7
+ * **Link auf die oeffentliche Belegseite** — der Beleg selbst bleibt
8
+ * unberuehrt (BAO §131/RKSV), das Versandprotokoll fuehrt das Backend in einer
9
+ * Unter-Sammlung neben ihm.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RECEIPT_EMAIL_ERROR_CODES = void 0;
13
+ exports.isReceiptEmailErrorCode = isReceiptEmailErrorCode;
14
+ /**
15
+ * Stabile Fehlercodes von `sendReceiptEmail` — Zwilling von
16
+ * `beleg-mail-core.js` FEHLERCODES. Das Backend legt sie bei jedem fachlichen
17
+ * Fehler als `code` neben die Meldung; das Paket reicht sie als
18
+ * [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** — die
19
+ * deutsche Meldung darf sich aendern, der Code nicht.
20
+ *
21
+ * Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
22
+ * ohne Code; dort bleibt `code` undefined.
23
+ */
24
+ exports.RECEIPT_EMAIL_ERROR_CODES = [
25
+ 'adresse_ungueltig', // Empfaengeradresse unbrauchbar (Pruefung im Backend)
26
+ 'beleg_nicht_gefunden', // Beleg gibt es nicht ODER er gehoert einer anderen Kasse
27
+ 'zu_oft', // Schleuse: 5 Mails je Beleg (24 h), 30 je Kasse und Stunde
28
+ 'versand_fehlgeschlagen', // die Mail selbst ging nicht hinaus
29
+ ];
30
+ function isReceiptEmailErrorCode(value) {
31
+ return typeof value === 'string' && exports.RECEIPT_EMAIL_ERROR_CODES.includes(value);
32
+ }
@@ -3,7 +3,7 @@ import { type CreateStripeLinkOptions, type StripeCaptureResult } from '../payme
3
3
  import { type HobexPayOptions, type HobexRefundOptions } from '../payments/hobex.js';
4
4
  import { type TransportOptions } from './transport.js';
5
5
  import { type CashboxStatus, type SignatureStatus } from './status.js';
6
- import { type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
6
+ import { type SendReceiptEmailOptions, type SendReceiptEmailResult, type ListMyReceiptsOptions, type ReceiptList, type ReceiptWithCompany, type SellReceiptOptions, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions } from './receipts.js';
7
7
  /**
8
8
  * Schlichte Factory ueber den Endpunkt-Funktionen: bindet einen Transport
9
9
  * einmal und liefert die Aufrufe ohne den wiederkehrenden ersten Parameter.
@@ -47,6 +47,8 @@ export interface KasseneckApi {
47
47
  generateFullReceiptId(receiptId: string): Promise<string>;
48
48
  /** Berichtsmonat des ersten Belegs (nicht fuer den Kassen-Benutzer-Weg). */
49
49
  getFirstReceiptDate(): Promise<ReportMonth>;
50
+ /** Beleg als Link auf die oeffentliche Belegseite per E-Mail schicken. */
51
+ sendReceiptEmail(options: SendReceiptEmailOptions): Promise<SendReceiptEmailResult>;
50
52
  /** Belegliste einer Kasse samt Kennzahlen (nur mit ID-Token, siehe receipts.ts). */
51
53
  listMyReceipts(options: ListMyReceiptsOptions): Promise<ReceiptList>;
52
54
  /** Kassen des angemeldeten Benutzers (nur mit ID-Token, siehe cashregisters.ts). */
@@ -3,7 +3,7 @@ import { hobexPay, hobexRefund } from '../payments/hobex.js';
3
3
  import { createTransport, createBinaryTransport } from './transport.js';
4
4
  import { downloadDailyReport, downloadMonthlyReport } from './reports.js';
5
5
  import { getCashboxStatus, getSignatureStatus } from './status.js';
6
- import { sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, } from './receipts.js';
6
+ import { sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, sendReceiptEmail, } from './receipts.js';
7
7
  import { listMyCashregisters } from './cashregisters.js';
8
8
  import { renewRegisterSession, endRegisterSession } from '../register/session.js';
9
9
  export function createKasseneckApi(options) {
@@ -22,6 +22,7 @@ export function createKasseneckApi(options) {
22
22
  generateFullReceiptId: (receiptId) => generateFullReceiptId(rufen, receiptId),
23
23
  getFirstReceiptDate: () => getFirstReceiptDate(rufen),
24
24
  listMyReceipts: (o) => listMyReceipts(rufen, o),
25
+ sendReceiptEmail: (o) => sendReceiptEmail(rufen, o),
25
26
  listMyCashregisters: () => listMyCashregisters(rufen),
26
27
  downloadDailyReport: (date) => downloadDailyReport(rufenBinaer, date),
27
28
  downloadMonthlyReport: (reportMonth) => downloadMonthlyReport(rufenBinaer, reportMonth),
@@ -13,7 +13,7 @@
13
13
  * umhuellt, muss ihn weiterhin absetzen koennen.
14
14
  */
15
15
  import type { TransportBodyFields } from './transport.js';
16
- export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
16
+ export declare const AUFRUFE: readonly ["activateCashregister", "cancelReceipt", "createCustomerCashregister", "createPartnerCustomer", "checkPartnerCustomerEmail", "createPartnerWebhook", "createPaymentLinkStripe", "createPrintJob", "createReceipt", "deletePartnerWebhook", "downloadDailyReport", "downloadReport", "endRegisterSession", "financeWebService", "generateFullReceiptId", "getCustomerCredentials", "getCustomerSignatureStatus", "getFirstReceiptDate", "getKasseSettings", "getPartnerCustomer", "getPartnerInfo", "getPrintJob", "getReceipt", "hobexPayApi", "hobexRefundApi", "listCustomerCashregisters", "listMyArticleGroups", "listMyArticles", "listMyCashregisters", "listMyPrinters", "listMyReceipts", "listMyTipRecipients", "listPartnerCustomers", "listPartnerWebhookDeliveries", "listPartnerWebhooks", "listRegisterUsersForDevice", "listRegisterSessionsForDevice", "pairRegisterDevice", "registerPinLogin", "registerUserLogin", "renewRegisterSession", "requestCustomerSignature", "sendPartnerCustomerFonLink", "sendPartnerWebhookTest", "sendReceiptEmail", "setMyKasseSettings", "setMyRegisterDeviceSettings", "stripeCaptureIntent", "unpairRegisterDevice", "rotatePartnerWebhookSecret", "updatePartnerWebhook"];
17
17
  export type Aufruf = typeof AUFRUFE[number];
18
18
  /** Wie [KasseneckTransport], nur mit bekanntem Aufrufnamen. Nicht exportiert nach aussen. */
19
19
  export type InternerTransport = <T = unknown>(functionName: Aufruf, params?: Record<string, unknown>, extraBodyFields?: TransportBodyFields, secretParams?: readonly string[]) => Promise<T>;
@@ -43,6 +43,7 @@ export const AUFRUFE = [
43
43
  'requestCustomerSignature',
44
44
  'sendPartnerCustomerFonLink',
45
45
  'sendPartnerWebhookTest',
46
+ 'sendReceiptEmail',
46
47
  'setMyKasseSettings',
47
48
  'setMyRegisterDeviceSettings',
48
49
  'stripeCaptureIntent',
@@ -2,7 +2,7 @@ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type
2
2
  export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, createTransport, createBinaryTransport, } from './transport.js';
3
3
  export { AUFRUFE, type Aufruf, } from './aufrufe.js';
4
4
  export { KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, } from './errors.js';
5
- export { type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, } from './receipts.js';
5
+ export { type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, type CancelReceiptResult, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, } from './receipts.js';
6
6
  export { listMyCashregisters } from './cashregisters.js';
7
7
  export { downloadDailyReport, downloadMonthlyReport } from './reports.js';
8
8
  export { type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, } from './status.js';
@@ -2,7 +2,7 @@ export { apiKeyAuth, registerUserAuth, } from './auth.js';
2
2
  export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, createTransport, createBinaryTransport, } from './transport.js';
3
3
  export { AUFRUFE, } from './aufrufe.js';
4
4
  export { KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, } from './errors.js';
5
- export { sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, checkVoucherCombinationError, } from './receipts.js';
5
+ export { sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, checkVoucherCombinationError, sendReceiptEmail, } from './receipts.js';
6
6
  export { listMyCashregisters } from './cashregisters.js';
7
7
  export { downloadDailyReport, downloadMonthlyReport } from './reports.js';
8
8
  export { getCashboxStatus, getSignatureStatus, } from './status.js';
@@ -117,6 +117,14 @@ export type CancelReceiptOptions = {
117
117
  note?: string;
118
118
  /** Rueckzahlweg; ohne Angabe die Zahlungsart des stornierten Belegs. */
119
119
  paymentMethod?: KeckPaymentMethod | KeckPaymentMethodKey;
120
+ /**
121
+ * Kartendaten der ERSTATTUNG (Gutschrift oder Aufhebung am Terminal) fuer
122
+ * den Kartenblock am Storno-Bon -- nur bei Rueckzahlweg Karte. Beschreiben
123
+ * nie die Originalzahlung; das Backend uebernimmt sie nicht vom Original.
124
+ */
125
+ creditCardProvider?: CreditCardProvider;
126
+ cardPaymentId?: string;
127
+ cardPaymentData?: Record<string, unknown>;
120
128
  } & ({
121
129
  receipt: Receipt;
122
130
  cashregisterId?: string;
@@ -277,6 +285,63 @@ export declare function generateFullReceiptId(rufen: InternerTransport, receiptI
277
285
  * (siehe Modulkommentar oben). Mit `apiKeyAuth` ist er offen.
278
286
  */
279
287
  export declare function getFirstReceiptDate(rufen: InternerTransport): Promise<ReportMonth>;
288
+ /**
289
+ * Beleg per E-Mail an den Endkunden — die Eingabe von [sendReceiptEmail].
290
+ *
291
+ * `cashregisterId` steht hier bewusst **nicht**: der Geraeteweg bindet die
292
+ * Kasse ueber die Kopfzeile `cashregister-token`, der Kassen-Benutzer-Weg
293
+ * ueber den Parameter, den `registerUserAuth` ohnehin schon setzt. Eine
294
+ * dritte Stelle waere nur eine Gelegenheit, eine andere Kasse zu behaupten,
295
+ * als die, an der man angemeldet ist — und das Backend nimmt den Belegpfad aus
296
+ * der angemeldeten Kasse, nicht aus der Nutzlast.
297
+ */
298
+ export interface SendReceiptEmailOptions {
299
+ /** Verschluesselte Volltext-Belegnummer (siehe [generateFullReceiptId]). */
300
+ fullReceiptId: string;
301
+ /** Empfaengeradresse, wie der Gast sie am Tresen nennt. */
302
+ to: string;
303
+ /**
304
+ * Sprache der Mail. Heute wertet das Backend genau `'de'` aus; der Parameter
305
+ * steht im Vertrag, damit eine zweite Sprache spaeter kein neuer Vertrag ist.
306
+ * Ohne Angabe geht das Feld gar nicht erst hinaus.
307
+ */
308
+ sprache?: string;
309
+ }
310
+ /** Was der Versand bestaetigt (Backend: beleg-mail-endpoints.js). */
311
+ export interface SendReceiptEmailResult {
312
+ /** Adresse in der Form, in der das Backend sie protokolliert hat (getrimmt, klein). */
313
+ to: string;
314
+ /** Zeitpunkt des Versands, ISO mit Wiener Zonenoffset (`2026-09-11T14:05:00+02:00`). */
315
+ at: string;
316
+ /**
317
+ * Versandweg: `eigen` (Postfach des Betriebs), `plattform` oder
318
+ * `plattform-fallback`. `null`, wenn die Antwort ihn nicht nennt — das ist
319
+ * eine Auskunft ueber den Weg, keine ueber den Erfolg, und darf den
320
+ * bestaetigten Versand nicht zu einem Fehler machen.
321
+ */
322
+ via: string | null;
323
+ }
324
+ /**
325
+ * Schickt einen bereits ausgestellten Beleg als **Link auf die oeffentliche
326
+ * Belegseite** an eine Adresse (Endpunkt `sendReceiptEmail`, Backend
327
+ * beleg-mail-endpoints.js). Kein PDF im Anhang: die Belegseite fuehrt dasselbe
328
+ * Zeilenmodell wie Bildschirm und Bon und liefert dort auf Wunsch ein PDF.
329
+ *
330
+ * **Der Beleg bleibt unberuehrt** (BAO §131/RKSV): das Versandprotokoll fuehrt
331
+ * das Backend in einer Unter-Sammlung neben dem Beleg.
332
+ *
333
+ * **Am Code entscheiden, nie am Text:** fachliche Fehler kommen als
334
+ * [KasseneckApiError] mit `code` aus [RECEIPT_EMAIL_ERROR_CODES] heraus —
335
+ * `adresse_ungueltig`, `beleg_nicht_gefunden` (auch fuer einen Beleg einer
336
+ * fremden Kasse: das Backend gibt darueber bewusst keine Auskunft), `zu_oft`
337
+ * (5 Mails je Beleg in 24 Stunden, 30 je Kasse und Stunde) und
338
+ * `versand_fehlgeschlagen`. Dieses Paket reicht sie unveraendert durch und
339
+ * legt keine eigenen Codes an.
340
+ *
341
+ * **Kein Wiederholen ohne Zutun des Bedieners:** ein zweiter Versuch schickt
342
+ * eine zweite Mail und zaehlt auf die Schleuse.
343
+ */
344
+ export declare function sendReceiptEmail(rufen: InternerTransport, options: SendReceiptEmailOptions): Promise<SendReceiptEmailResult>;
280
345
  /**
281
346
  * Prueft die Gutschein-Kombination eines Belegs und liefert den ersten
282
347
  * Regelverstoss als Text (oder `null`) — Zwilling von
@@ -140,6 +140,24 @@ export async function cancelReceipt(rufen, options) {
140
140
  params.note = options.note;
141
141
  if (options.paymentMethod != null)
142
142
  params.paymentMethod = gepruefteZahlungsart(options.paymentMethod);
143
+ const karte = options.creditCardProvider != null || options.cardPaymentId != null || options.cardPaymentData != null;
144
+ if (karte) {
145
+ // Ohne paymentMethod entscheidet das Backend an der Zahlungsart des
146
+ // Originals; ein ausdruecklich anderer Rueckzahlweg ist hier schon falsch.
147
+ if (params.paymentMethod != null && params.paymentMethod !== KeckPaymentMethod.creditCard.value) {
148
+ throw new KasseneckValidationError('cancelReceipt', 'Kartendaten gibt es nur bei paymentMethod creditCard', 'request');
149
+ }
150
+ if (options.creditCardProvider != null) {
151
+ if (!Object.prototype.hasOwnProperty.call(CreditCardProvider, options.creditCardProvider)) {
152
+ throw new KasseneckValidationError('cancelReceipt', `Kartenanbieter: unbekannter Schluessel "${options.creditCardProvider}"`, 'request');
153
+ }
154
+ params.creditCardProvider = options.creditCardProvider;
155
+ }
156
+ if (options.cardPaymentId != null && options.cardPaymentId !== '')
157
+ params.cardPaymentId = options.cardPaymentId;
158
+ if (options.cardPaymentData != null)
159
+ params.cardPaymentData = options.cardPaymentData;
160
+ }
143
161
  const daten = await rufen('cancelReceipt', params);
144
162
  const receipt = belegAusHuelle(daten, 'cancelReceipt');
145
163
  const huelle = daten;
@@ -295,6 +313,54 @@ export async function getFirstReceiptDate(rufen) {
295
313
  throw antwortfehler('getFirstReceiptDate', 'Antwort enthaelt keinen lesbaren Zeitstempel');
296
314
  }
297
315
  }
316
+ /**
317
+ * Schickt einen bereits ausgestellten Beleg als **Link auf die oeffentliche
318
+ * Belegseite** an eine Adresse (Endpunkt `sendReceiptEmail`, Backend
319
+ * beleg-mail-endpoints.js). Kein PDF im Anhang: die Belegseite fuehrt dasselbe
320
+ * Zeilenmodell wie Bildschirm und Bon und liefert dort auf Wunsch ein PDF.
321
+ *
322
+ * **Der Beleg bleibt unberuehrt** (BAO §131/RKSV): das Versandprotokoll fuehrt
323
+ * das Backend in einer Unter-Sammlung neben dem Beleg.
324
+ *
325
+ * **Am Code entscheiden, nie am Text:** fachliche Fehler kommen als
326
+ * [KasseneckApiError] mit `code` aus [RECEIPT_EMAIL_ERROR_CODES] heraus —
327
+ * `adresse_ungueltig`, `beleg_nicht_gefunden` (auch fuer einen Beleg einer
328
+ * fremden Kasse: das Backend gibt darueber bewusst keine Auskunft), `zu_oft`
329
+ * (5 Mails je Beleg in 24 Stunden, 30 je Kasse und Stunde) und
330
+ * `versand_fehlgeschlagen`. Dieses Paket reicht sie unveraendert durch und
331
+ * legt keine eigenen Codes an.
332
+ *
333
+ * **Kein Wiederholen ohne Zutun des Bedieners:** ein zweiter Versuch schickt
334
+ * eine zweite Mail und zaehlt auf die Schleuse.
335
+ */
336
+ export async function sendReceiptEmail(rufen, options) {
337
+ // Getrimmt, weil beides von Hand oder per Scanner ins Feld kommt und ein
338
+ // angehaengtes Leerzeichen sonst als ungueltige Adresse zurueckkaeme --
339
+ // nach einem Aufruf, der schon eine Zeile im Protokoll gekostet hat.
340
+ const fullReceiptId = typeof options.fullReceiptId === 'string' ? options.fullReceiptId.trim() : '';
341
+ const to = typeof options.to === 'string' ? options.to.trim() : '';
342
+ if (fullReceiptId === '') {
343
+ throw new KasseneckValidationError('sendReceiptEmail', 'fullReceiptId fehlt', 'request');
344
+ }
345
+ if (to === '') {
346
+ throw new KasseneckValidationError('sendReceiptEmail', 'to fehlt (Empfaengeradresse)', 'request');
347
+ }
348
+ // Die Adresse selbst wird hier NICHT geprueft: das Backend prueft sie mit
349
+ // kreiseck_validator und antwortet mit `adresse_ungueltig`. Eine zweite,
350
+ // eigene Regel im Paket koennte strenger sein als die des Backends und eine
351
+ // gueltige Adresse abweisen, ohne dass jemand die Abweichung bemerkt.
352
+ const params = { fullReceiptId, to };
353
+ if (options.sprache !== undefined && options.sprache !== '')
354
+ params.sprache = options.sprache;
355
+ const daten = await rufen('sendReceiptEmail', params);
356
+ if (typeof daten?.to !== 'string' || daten.to === '') {
357
+ throw antwortfehler('sendReceiptEmail', 'Antwort nennt keine Empfaengeradresse (data.to fehlt)');
358
+ }
359
+ if (typeof daten.at !== 'string' || daten.at === '') {
360
+ throw antwortfehler('sendReceiptEmail', 'Antwort nennt keinen Zeitpunkt (data.at fehlt)');
361
+ }
362
+ return { to: daten.to, at: daten.at, via: typeof daten.via === 'string' && daten.via !== '' ? daten.via : null };
363
+ }
298
364
  /**
299
365
  * Prueft die Gutschein-Kombination eines Belegs und liefert den ersten
300
366
  * Regelverstoss als Text (oder `null`) — Zwilling von
@@ -1,5 +1,5 @@
1
1
  export { ReceiptType, type ReceiptTypeKey, VatRate, type VatRateKey, KeckPaymentMethod, type KeckPaymentMethodKey, CreditCardProvider, type CreditCardProviderKey, VoucherType, type VoucherTypeKey, VoucherAction, type VoucherActionKey, StripeLinkMode, type StripeLinkModeKey, } from './enums/index.js';
2
- export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
- export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
2
+ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, type TipRecipient, isTipItem, type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid, type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, remainingQuantities, type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind, type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
+ export { type AuthCredentials, type KasseneckAuth, type ApiKeyAuthOptions, type RegisterUserAuthOptions, apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type HttpResponseLike, type HttpRequestInit, type FetchLike, type TransportOptions, type TransportBodyFields, type KasseneckTransport, type KasseneckBinaryTransport, AUFRUFE, type Aufruf, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, type ValidationScope, type KasseneckError, type HttpFailureReason, type CauseDigest, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, type ReceiptCommonOptions, type SellReceiptOptions, type TipOptions, type TipRecipientShare, type CancelReceiptOptions, type CancelReceiptResult, type CreateCancelReceiptOptions, type ReceiptWithCompany, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, type ListMyReceiptsOptions, type ReceiptList, type ReceiptListStats, listMyCashregisters, checkVoucherCombinationError, type SendReceiptEmailOptions, type SendReceiptEmailResult, sendReceiptEmail, downloadDailyReport, downloadMonthlyReport, type CashboxStatus, type SignatureStatus, getCashboxStatus, getSignatureStatus, type KasseneckApi, createKasseneckApi, } from './client/index.js';
4
4
  export { parseServerTimeStamp, toViennaWallClock, type ViennaWallClock } from './vienna-time.js';
5
5
  export { type KasseSettingsBetrieb, type KasseSettingsGeraet, type KasseSettings, type ArticleGroup, type KasseArtikel, KASSE_BETRIEB_STANDARD, KASSE_GERAET_STANDARD, mergeKasseSettings, fromArticleGroupPayload, fromKasseArtikelPayload, listMyArticleGroups, listMyArticles, getKasseSettings, setMyKasseSettings, setMyRegisterDeviceSettings, verteileRabatt, cancelScopeOf, receiptsScopeOf, } from './kasse/index.js';
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { ReceiptType, VatRate, KeckPaymentMethod, CreditCardProvider, VoucherType, VoucherAction, StripeLinkMode, } from './enums/index.js';
2
- export { toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, isTipItem, toVoucherPayload, fromVoucherPayload, voucherIsValid, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, fromReceiptCompanyPayload, receiptCompanyTaxInfo, fromCashregisterPayload, fromReceiptSummaryPayload, ZERO_KINDS, istZeroKind, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
- export { apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, AUFRUFE, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, listMyCashregisters, checkVoucherCombinationError, downloadDailyReport, downloadMonthlyReport, getCashboxStatus, getSignatureStatus, createKasseneckApi, } from './client/index.js';
2
+ export { toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, isTipItem, toVoucherPayload, fromVoucherPayload, voucherIsValid, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, remainingQuantities, fromReceiptCompanyPayload, receiptCompanyTaxInfo, fromCashregisterPayload, fromReceiptSummaryPayload, ZERO_KINDS, istZeroKind, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './models/index.js';
3
+ export { apiKeyAuth, registerUserAuth, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, AUFRUFE, createTransport, createBinaryTransport, KasseneckApiError, KasseneckAuthError, KasseneckHttpError, KasseneckNetworkError, KasseneckValidationError, isKasseneckApiError, isKasseneckAuthError, isKasseneckHttpError, isKasseneckNetworkError, isKasseneckValidationError, sellReceipt, sellReceiptWithCompany, cancelReceipt, createCancelReceipt, zeroReceipt, getReceipt, getReceiptWithCompany, generateFullReceiptId, getFirstReceiptDate, listMyReceipts, listMyCashregisters, checkVoucherCombinationError, sendReceiptEmail, downloadDailyReport, downloadMonthlyReport, getCashboxStatus, getSignatureStatus, createKasseneckApi, } from './client/index.js';
4
4
  export { parseServerTimeStamp, toViennaWallClock } from './vienna-time.js';
5
5
  export { KASSE_BETRIEB_STANDARD, KASSE_GERAET_STANDARD, mergeKasseSettings, fromArticleGroupPayload, fromKasseArtikelPayload, listMyArticleGroups, listMyArticles, getKasseSettings, setMyKasseSettings, setMyRegisterDeviceSettings, verteileRabatt, cancelScopeOf, receiptsScopeOf, } from './kasse/index.js';
@@ -2,6 +2,7 @@ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead,
2
2
  export { type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid } from './voucher.js';
3
3
  export { type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, } from './receipt.js';
4
4
  export { type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, type CancellationErrorCode, CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, } from './cancellation.js';
5
+ export { type ReceiptEmailErrorCode, RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, } from './receipt-email.js';
5
6
  export { type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, } from './receipt-company.js';
6
7
  export { type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, } from './cashregister.js';
7
8
  export { type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind } from './receipt-summary.js';
@@ -2,6 +2,7 @@ export { toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, re
2
2
  export { toVoucherPayload, fromVoucherPayload, voucherIsValid } from './voucher.js';
3
3
  export { toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, } from './receipt.js';
4
4
  export { CANCELLATION_REASONS, CANCELLATION_ERROR_CODES, CANCELLATION_RESERVATION_MS, isCancellationReason, isCancellationErrorCode, remainingQuantities, } from './cancellation.js';
5
+ export { RECEIPT_EMAIL_ERROR_CODES, isReceiptEmailErrorCode, } from './receipt-email.js';
5
6
  export { fromReceiptCompanyPayload, receiptCompanyTaxInfo, } from './receipt-company.js';
6
7
  export { fromCashregisterPayload, } from './cashregister.js';
7
8
  export { fromReceiptSummaryPayload, ZERO_KINDS, istZeroKind } from './receipt-summary.js';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Beleg per E-Mail — Zwilling von `functions/beleg-mail-core.js`.
3
+ *
4
+ * Hier steht nur der Fehlercode-Katalog: der Aufruf selbst ist
5
+ * [sendReceiptEmail] (client/receipts.ts), und was verschickt wird, ist ein
6
+ * **Link auf die oeffentliche Belegseite** — der Beleg selbst bleibt
7
+ * unberuehrt (BAO §131/RKSV), das Versandprotokoll fuehrt das Backend in einer
8
+ * Unter-Sammlung neben ihm.
9
+ */
10
+ /**
11
+ * Stabile Fehlercodes von `sendReceiptEmail` — Zwilling von
12
+ * `beleg-mail-core.js` FEHLERCODES. Das Backend legt sie bei jedem fachlichen
13
+ * Fehler als `code` neben die Meldung; das Paket reicht sie als
14
+ * [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** — die
15
+ * deutsche Meldung darf sich aendern, der Code nicht.
16
+ *
17
+ * Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
18
+ * ohne Code; dort bleibt `code` undefined.
19
+ */
20
+ export declare const RECEIPT_EMAIL_ERROR_CODES: readonly ["adresse_ungueltig", "beleg_nicht_gefunden", "zu_oft", "versand_fehlgeschlagen"];
21
+ export type ReceiptEmailErrorCode = (typeof RECEIPT_EMAIL_ERROR_CODES)[number];
22
+ export declare function isReceiptEmailErrorCode(value: unknown): value is ReceiptEmailErrorCode;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Beleg per E-Mail — Zwilling von `functions/beleg-mail-core.js`.
3
+ *
4
+ * Hier steht nur der Fehlercode-Katalog: der Aufruf selbst ist
5
+ * [sendReceiptEmail] (client/receipts.ts), und was verschickt wird, ist ein
6
+ * **Link auf die oeffentliche Belegseite** — der Beleg selbst bleibt
7
+ * unberuehrt (BAO §131/RKSV), das Versandprotokoll fuehrt das Backend in einer
8
+ * Unter-Sammlung neben ihm.
9
+ */
10
+ /**
11
+ * Stabile Fehlercodes von `sendReceiptEmail` — Zwilling von
12
+ * `beleg-mail-core.js` FEHLERCODES. Das Backend legt sie bei jedem fachlichen
13
+ * Fehler als `code` neben die Meldung; das Paket reicht sie als
14
+ * [KasseneckApiError.code] durch. **Entscheide am Code, nie am Text** — die
15
+ * deutsche Meldung darf sich aendern, der Code nicht.
16
+ *
17
+ * Nur Auth-/Parameterfehler (Sitzung abgelaufen, Pflichtfeld fehlt) kommen
18
+ * ohne Code; dort bleibt `code` undefined.
19
+ */
20
+ export const RECEIPT_EMAIL_ERROR_CODES = [
21
+ 'adresse_ungueltig', // Empfaengeradresse unbrauchbar (Pruefung im Backend)
22
+ 'beleg_nicht_gefunden', // Beleg gibt es nicht ODER er gehoert einer anderen Kasse
23
+ 'zu_oft', // Schleuse: 5 Mails je Beleg (24 h), 30 je Kasse und Stunde
24
+ 'versand_fehlgeschlagen', // die Mail selbst ging nicht hinaus
25
+ ];
26
+ export function isReceiptEmailErrorCode(value) {
27
+ return typeof value === 'string' && RECEIPT_EMAIL_ERROR_CODES.includes(value);
28
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.11.0",
2
+ "version": "0.13.0",
3
3
  "gemessenAn": {
4
4
  "tid": "3600335",
5
5
  "hpsVersion": "1.10.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.11.0",
2
+ "version": "0.13.0",
3
3
  "meldungen": {
4
4
  "netz.keine_verbindung": {
5
5
  "text": "Keine Verbindung zum Server. Bitte die Internetverbindung prüfen und erneut versuchen."
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.11.0",
2
+ "version": "0.13.0",
3
3
  "aufrufe": [
4
4
  "activateCashregister",
5
5
  "cancelReceipt",
@@ -45,6 +45,7 @@
45
45
  "requestCustomerSignature",
46
46
  "sendPartnerCustomerFonLink",
47
47
  "sendPartnerWebhookTest",
48
+ "sendReceiptEmail",
48
49
  "setMyKasseSettings",
49
50
  "setMyRegisterDeviceSettings",
50
51
  "stripeCaptureIntent",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kreiseck/kasseneck-api",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "JavaScript-Zwilling von kasseneck_api (Flutter) fuer das Kasseneck-Backend",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Kreiseck",