@kreiseck/kasseneck-api 0.26.0 → 0.27.1

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,32 @@ 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.27.1
8
+
9
+ - Drei Beispiele zum Mikropreis in `fixtures/rechnung-api-beispiele/`: der Sub-Cent-Fall
10
+ (3.500.000 × 0,000004 € = 14,00 € netto), beide Preise gesetzt und kein Preis gesetzt. Sie sind
11
+ zugleich die Prüfvektoren, die Server und Dart-Zwilling gegen ihre eigene Prüfung fahren — ein
12
+ Beispiel, das nur in der Doku steht, veraltet unbemerkt.
13
+
14
+ ## 0.27.0
15
+
16
+ - **Rechnungs-API: der Einzelpreis einer Position darf in Mikro-Euro stehen** (`unitPriceMicros`,
17
+ 10⁻⁶ €). Genau eines von `unitPriceCents` und `unitPriceMicros` — beide Felder sind dafür
18
+ optional, und die neue Genau-eins-Regel am Positions-Objekt wird im JSON Schema zu
19
+ `oneOf: [{required:['unitPriceCents']}, {required:['unitPriceMicros']}]`. Grund: Preise unterhalb
20
+ eines Cents (Verbrauchsabrechnung, Stückpreise im Zehntelcent) mussten bisher schon beim
21
+ Einreichen gerundet werden; der Rundungsfehler steckte danach in jeder Zeile.
22
+ **Bricht die Form:** wer den Typ `IssueInvoiceItem` selbst baut, bekommt `unitPriceCents` jetzt
23
+ als optionales Feld. Anfragen, die es setzen, bleiben unverändert gültig.
24
+ - Der Mikropreis deckt denselben Betragsbereich wie die Cent-Angabe (10¹² Mikro-Euro = 10⁸ Cent =
25
+ 10.000.000,00 €). Eine eigene Obergrenze wäre eine stille Bereichsänderung, je nachdem welches
26
+ Feld ein Aufrufer benutzt.
27
+ - Die Menge reicht bis 10⁹ statt 10⁶, passend zu `quantityMilli` der gespeicherten Form.
28
+ - **Noch nicht enthalten:** `rechnungSummen` rechnet weiterhin wie bisher, nicht über den exakten
29
+ Kern. Das gehört zum Stichtag der Umstellung (Schalter `ganzzahlPflicht`): solange der Server
30
+ eine Rechnung nach dem alten Weg ausstellt, darf eine Vorschau im Aufrufer nicht schon exakt
31
+ runden — sie zeigte sonst an Halbcent-Grenzen einen anderen Cent als die Rechnung.
32
+
7
33
  ## 0.26.0
8
34
 
9
35
  - Beleg: Am Ende steht das Kasseneck-Logo als Bild statt der Zeile „erstellt mit Kasseneck".
@@ -18,4 +18,4 @@ export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, Cred
18
18
  export { RECHNUNG_TEXTE, rechnungText, type RechnungTextSchluessel } from './texte.js';
19
19
  export { rechnungSummen, STEUERFREIE_FAELLE, type SummenPosition } from './summen.js';
20
20
  export { anteiligerPreis, BETRAG_GRENZE_CENTS, positionAusEuro, preisText, RechenFehler, rechnungRechnen, rund, satzSchluessel, satzText, type RechenErgebnis, type RechenFehlerCode, type RechenOptionen, type RechenPosition, type SatzSumme, type Umwandlung, type UmwandlungsGrund, type ZeilenBetrag, } from './rechnen.js';
21
- export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoicePaymentMethod, type ItemKind, type ReverseChargeReason, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
21
+ export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, POSITION_PREIS_GENAU_EINS, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoicePaymentMethod, type ItemKind, type ReverseChargeReason, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
@@ -13,7 +13,7 @@
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.INVOICE_UNITS = exports.INVOICE_NOTICE_CODES = exports.REVERSE_CHARGE_REASONS = exports.ITEM_KINDS = exports.INVOICE_PAYMENT_METHODS = exports.INVOICE_LANGUAGES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_ERROR_CODES = exports.RECHNUNG_AUFRUFE = exports.RECHNUNG_VERTRAG_VERSION = exports.satzText = exports.satzSchluessel = exports.rund = exports.rechnungRechnen = exports.RechenFehler = exports.preisText = exports.positionAusEuro = exports.BETRAG_GRENZE_CENTS = exports.anteiligerPreis = exports.STEUERFREIE_FAELLE = exports.rechnungSummen = exports.rechnungText = exports.RECHNUNG_TEXTE = exports.updateCustomer = exports.searchCustomers = exports.recordInvoicePayment = exports.previewInvoice = exports.listInvoices = exports.listBrands = exports.issueInvoice = exports.getInvoiceXml = exports.getInvoiceSetupStatus = exports.getInvoicePdf = exports.getInvoice = exports.getCustomer = exports.createCustomer = exports.createCreditNote = exports.cancelInvoice = exports.rechnungFeldFehler = exports.rechnungFehlerCode = exports.istRechnungFehler = exports.rechnungKeyAuth = exports.createRechnungApi = void 0;
16
- exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = void 0;
16
+ exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.POSITION_PREIS_GENAU_EINS = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = void 0;
17
17
  var api_js_1 = require("./api.js");
18
18
  Object.defineProperty(exports, "createRechnungApi", { enumerable: true, get: function () { return api_js_1.createRechnungApi; } });
19
19
  var auth_js_1 = require("./auth.js");
@@ -76,6 +76,7 @@ Object.defineProperty(exports, "RECHNUNG_EINHEITEN_CODES", { enumerable: true, g
76
76
  Object.defineProperty(exports, "INVOICE_SETUP_REQUIREMENTS", { enumerable: true, get: function () { return vertrag_js_1.INVOICE_SETUP_REQUIREMENTS; } });
77
77
  Object.defineProperty(exports, "KUNDE_FELDER", { enumerable: true, get: function () { return vertrag_js_1.KUNDE_FELDER; } });
78
78
  Object.defineProperty(exports, "POSITION_FELDER", { enumerable: true, get: function () { return vertrag_js_1.POSITION_FELDER; } });
79
+ Object.defineProperty(exports, "POSITION_PREIS_GENAU_EINS", { enumerable: true, get: function () { return vertrag_js_1.POSITION_PREIS_GENAU_EINS; } });
79
80
  Object.defineProperty(exports, "RECHNUNG_ANFRAGEN", { enumerable: true, get: function () { return vertrag_js_1.RECHNUNG_ANFRAGEN; } });
80
81
  Object.defineProperty(exports, "RECHNUNG_GENAU_EINS", { enumerable: true, get: function () { return vertrag_js_1.RECHNUNG_GENAU_EINS; } });
81
82
  Object.defineProperty(exports, "RECHNUNG_MINDESTENS_EINS", { enumerable: true, get: function () { return vertrag_js_1.RECHNUNG_MINDESTENS_EINS; } });
@@ -73,8 +73,16 @@ export interface InvoiceItemInput {
73
73
  unit?: InvoiceUnit;
74
74
  /** Ware oder Leistung; ohne Angabe `goods`. Entscheidet ueber den Steuerfall. */
75
75
  kind?: ItemKind;
76
- /** Einzelpreis in ganzen Cent, im `priceMode` der Rechnung (netto oder brutto). */
77
- unitPriceCents: number;
76
+ /**
77
+ * Einzelpreis in ganzen Cent, im `priceMode` der Rechnung (netto oder
78
+ * brutto). Genau eines von `unitPriceCents` und `unitPriceMicros`.
79
+ */
80
+ unitPriceCents?: number;
81
+ /**
82
+ * Einzelpreis in Mikro-Euro (10⁻⁶ €), fuer Preise unterhalb eines Cents.
83
+ * Genau eines von `unitPriceCents` und `unitPriceMicros`.
84
+ */
85
+ unitPriceMicros?: number;
78
86
  vatRate: VatRatePercent;
79
87
  /** Zeilenrabatt in Prozent, hoechstens zwei Nachkommastellen. */
80
88
  discountPct?: number;
@@ -246,7 +254,15 @@ export interface InvoiceItem {
246
254
  unit: string;
247
255
  /** Ware oder Leistung — Altbestand ohne Angabe zaehlt als `goods`. */
248
256
  kind: ItemKind;
257
+ /**
258
+ * Einzelpreis in ganzen Cent — eine ANZEIGEHILFE: kaufmaennisch aus
259
+ * `unitPriceMicros` gerundet, und damit 0, sobald der Preis unter einem
260
+ * halben Cent liegt. Verbindlich sind `unitPriceMicros` und die Betraege je
261
+ * Position (§ 9.3).
262
+ */
249
263
  unitPriceCents: number;
264
+ /** Einzelpreis in Mikro-Euro (10⁻⁶ €) — der verbindliche Preis. */
265
+ unitPriceMicros?: number;
250
266
  vatRate: number;
251
267
  discountPct: number;
252
268
  }
@@ -204,6 +204,17 @@ export type Feld = {
204
204
  typ: 'object';
205
205
  pflicht: boolean;
206
206
  felder: Readonly<Record<string, Feld>>;
207
+ /**
208
+ * Feldgruppen, von denen GENAU EINE gesetzt sein muss (§ 9.1). Jede Gruppe
209
+ * ist eine Liste von Feldnamen; im JSON Schema wird daraus
210
+ * `oneOf: [{ required: [...] }, ...]`.
211
+ *
212
+ * Gebraucht fuer den Preis einer Position: `unitPriceCents` ODER
213
+ * `unitPriceMicros`, nie beides und nie keines. Als zwei Pflichtfelder
214
+ * liesse sich das nicht ausdruecken, und als zwei optionale waere eine
215
+ * Position ohne Preis gueltig.
216
+ */
217
+ genauEins?: readonly (readonly string[])[];
207
218
  } | {
208
219
  typ: 'list';
209
220
  pflicht: boolean;
@@ -219,8 +230,19 @@ export type Feld = {
219
230
  };
220
231
  /** Kunde, wie das Fremdsystem ihn schickt. `vatId` ist die UID-Nummer. */
221
232
  export declare const KUNDE_FELDER: Readonly<Record<string, Feld>>;
222
- /** Eine Rechnungs- oder Gutschriftsposition. Preise in ganzen Cent. */
233
+ /**
234
+ * Eine Rechnungs- oder Gutschriftsposition.
235
+ *
236
+ * Der Preis steht in ganzen Cent (`unitPriceCents`) ODER in Mikro-Euro
237
+ * (`unitPriceMicros`, 10⁻⁶ €) — genau eines von beiden (§ 9.1). Der Mikropreis
238
+ * loest denselben Bereich feiner auf: 10¹² Mikro-Euro sind dieselben
239
+ * 10.000.000,00 €, die 10⁸ Cent ausdruecken. Er ist noetig fuer Preise
240
+ * unterhalb eines Cents (Verbrauchsabrechnung, Stueckpreise im Zehntelcent),
241
+ * die bisher gerundet eingereicht werden mussten.
242
+ */
223
243
  export declare const POSITION_FELDER: Readonly<Record<string, Feld>>;
244
+ /** Genau einer der beiden Preise je Position (§ 9.1). */
245
+ export declare const POSITION_PREIS_GENAU_EINS: readonly (readonly string[])[];
224
246
  /**
225
247
  * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
226
248
  * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
@@ -19,7 +19,7 @@
19
19
  * Nummer, Summen — ist bewusst **nicht** setzbar.
20
20
  */
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.PAYMENT_FELDER = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = exports.INVOICE_UNITS = exports.INVOICE_NOTICE_CODES = exports.INVOICE_PAYMENT_METHODS = exports.INVOICE_LANGUAGES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.ITEM_KINDS = exports.REVERSE_CHARGE_REASONS = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_ERROR_CODES = exports.RECHNUNG_AUFRUFE = exports.RECHNUNG_VERTRAG_VERSION = void 0;
22
+ exports.RECHNUNG_MINDESTENS_EINS = exports.RECHNUNG_GENAU_EINS = exports.RECHNUNG_ANFRAGEN = exports.PAYMENT_FELDER = exports.POSITION_PREIS_GENAU_EINS = exports.POSITION_FELDER = exports.KUNDE_FELDER = exports.INVOICE_SETUP_REQUIREMENTS = exports.RECHNUNG_EINHEITEN_CODES = exports.INVOICE_UNITS = exports.INVOICE_NOTICE_CODES = exports.INVOICE_PAYMENT_METHODS = exports.INVOICE_LANGUAGES = exports.EINVOICE_FORMATS = exports.DOC_TYPES = exports.INVOICE_LIST_STATUS = exports.CUSTOMER_TYPES = exports.VAT_RATES = exports.PRICE_MODES = exports.ITEM_KINDS = exports.REVERSE_CHARGE_REASONS = exports.TAX_SCHEMES = exports.CREDIT_NOTE_REASONS = exports.INVOICE_ERROR_CODES = exports.RECHNUNG_AUFRUFE = exports.RECHNUNG_VERTRAG_VERSION = void 0;
23
23
  exports.RECHNUNG_VERTRAG_VERSION = 1;
24
24
  exports.RECHNUNG_AUFRUFE = [
25
25
  'createCustomer',
@@ -335,20 +335,45 @@ exports.KUNDE_FELDER = Object.freeze({
335
335
  });
336
336
  /** Beim Aendern ist jedes Kundenfeld optional. */
337
337
  const KUNDE_PATCH = Object.freeze(Object.fromEntries(Object.entries(exports.KUNDE_FELDER).map(([name, feld]) => [name, { ...feld, pflicht: false }])));
338
- /** Eine Rechnungs- oder Gutschriftsposition. Preise in ganzen Cent. */
338
+ /**
339
+ * Eine Rechnungs- oder Gutschriftsposition.
340
+ *
341
+ * Der Preis steht in ganzen Cent (`unitPriceCents`) ODER in Mikro-Euro
342
+ * (`unitPriceMicros`, 10⁻⁶ €) — genau eines von beiden (§ 9.1). Der Mikropreis
343
+ * loest denselben Bereich feiner auf: 10¹² Mikro-Euro sind dieselben
344
+ * 10.000.000,00 €, die 10⁸ Cent ausdruecken. Er ist noetig fuer Preise
345
+ * unterhalb eines Cents (Verbrauchsabrechnung, Stueckpreise im Zehntelcent),
346
+ * die bisher gerundet eingereicht werden mussten.
347
+ */
339
348
  exports.POSITION_FELDER = Object.freeze({
340
349
  description: text(300, true),
341
350
  subtitle: text(1000),
342
- quantity: { typ: 'number', pflicht: true, min: 0, exklusivMin: true, max: 1_000_000, nachkomma: 3 },
351
+ quantity: { typ: 'number', pflicht: true, min: 0, exklusivMin: true, max: 1_000_000_000, nachkomma: 3 },
343
352
  /** Einheit aus `INVOICE_UNITS`; ohne Angabe `piece`. */
344
353
  unit: { typ: 'enum', pflicht: false, werte: exports.INVOICE_UNITS },
345
354
  /** Ware oder Leistung; ohne Angabe `goods`. Entscheidet ueber den Steuerfall. */
346
355
  kind: { typ: 'enum', pflicht: false, werte: exports.ITEM_KINDS },
347
- unitPriceCents: { typ: 'integer', pflicht: true, min: 0, max: 100_000_000 },
356
+ /** Einzelpreis in ganzen Cent. Alternative zu `unitPriceMicros`. */
357
+ unitPriceCents: { typ: 'integer', pflicht: false, min: 0, max: 100_000_000 },
358
+ /** Einzelpreis in Mikro-Euro (10⁻⁶ €). Alternative zu `unitPriceCents`. */
359
+ unitPriceMicros: { typ: 'integer', pflicht: false, min: 0, max: 1_000_000_000_000 },
348
360
  vatRate: { typ: 'enum', pflicht: true, werte: exports.VAT_RATES },
349
361
  discountPct: { typ: 'number', pflicht: false, min: 0, max: 100, nachkomma: 2 },
350
362
  });
351
- const positionen = { typ: 'list', pflicht: true, min: 1, max: 500, eintrag: { typ: 'object', pflicht: true, felder: exports.POSITION_FELDER } };
363
+ /** Genau einer der beiden Preise je Position (§ 9.1). */
364
+ exports.POSITION_PREIS_GENAU_EINS = Object.freeze([
365
+ Object.freeze(['unitPriceCents']),
366
+ Object.freeze(['unitPriceMicros']),
367
+ ]);
368
+ const positionen = {
369
+ typ: 'list',
370
+ pflicht: true,
371
+ min: 1,
372
+ max: 500,
373
+ eintrag: {
374
+ typ: 'object', pflicht: true, felder: exports.POSITION_FELDER, genauEins: exports.POSITION_PREIS_GENAU_EINS,
375
+ },
376
+ };
352
377
  /**
353
378
  * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
354
379
  * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
@@ -18,4 +18,4 @@ export type { Brand, CancelInvoiceRequest, CancelResult, CreditNoteRequest, Cred
18
18
  export { RECHNUNG_TEXTE, rechnungText, type RechnungTextSchluessel } from './texte.js';
19
19
  export { rechnungSummen, STEUERFREIE_FAELLE, type SummenPosition } from './summen.js';
20
20
  export { anteiligerPreis, BETRAG_GRENZE_CENTS, positionAusEuro, preisText, RechenFehler, rechnungRechnen, rund, satzSchluessel, satzText, type RechenErgebnis, type RechenFehlerCode, type RechenOptionen, type RechenPosition, type SatzSumme, type Umwandlung, type UmwandlungsGrund, type ZeilenBetrag, } from './rechnen.js';
21
- export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoicePaymentMethod, type ItemKind, type ReverseChargeReason, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
21
+ export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, POSITION_PREIS_GENAU_EINS, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, type RechnungAufruf, type InvoiceErrorCode, type CreditNoteReason, type TaxScheme, type PriceMode, type VatRatePercent, type CustomerType, type InvoiceListStatus, type DocType, type EInvoiceFormat, type InvoiceLanguage, type InvoicePaymentMethod, type ItemKind, type ReverseChargeReason, type InvoiceNoticeCode, type InvoiceUnit, type InvoiceSetupRequirement, type Format, type Feld, } from './vertrag.js';
@@ -17,4 +17,4 @@ export { cancelInvoice, createCreditNote, createCustomer, getCustomer, getInvoic
17
17
  export { RECHNUNG_TEXTE, rechnungText } from './texte.js';
18
18
  export { rechnungSummen, STEUERFREIE_FAELLE } from './summen.js';
19
19
  export { anteiligerPreis, BETRAG_GRENZE_CENTS, positionAusEuro, preisText, RechenFehler, rechnungRechnen, rund, satzSchluessel, satzText, } from './rechnen.js';
20
- export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, } from './vertrag.js';
20
+ export { RECHNUNG_VERTRAG_VERSION, RECHNUNG_AUFRUFE, INVOICE_ERROR_CODES, CREDIT_NOTE_REASONS, TAX_SCHEMES, PRICE_MODES, VAT_RATES, CUSTOMER_TYPES, INVOICE_LIST_STATUS, DOC_TYPES, EINVOICE_FORMATS, INVOICE_LANGUAGES, INVOICE_PAYMENT_METHODS, ITEM_KINDS, REVERSE_CHARGE_REASONS, INVOICE_NOTICE_CODES, INVOICE_UNITS, RECHNUNG_EINHEITEN_CODES, INVOICE_SETUP_REQUIREMENTS, KUNDE_FELDER, POSITION_FELDER, POSITION_PREIS_GENAU_EINS, RECHNUNG_ANFRAGEN, RECHNUNG_GENAU_EINS, RECHNUNG_MINDESTENS_EINS, } from './vertrag.js';
@@ -73,8 +73,16 @@ export interface InvoiceItemInput {
73
73
  unit?: InvoiceUnit;
74
74
  /** Ware oder Leistung; ohne Angabe `goods`. Entscheidet ueber den Steuerfall. */
75
75
  kind?: ItemKind;
76
- /** Einzelpreis in ganzen Cent, im `priceMode` der Rechnung (netto oder brutto). */
77
- unitPriceCents: number;
76
+ /**
77
+ * Einzelpreis in ganzen Cent, im `priceMode` der Rechnung (netto oder
78
+ * brutto). Genau eines von `unitPriceCents` und `unitPriceMicros`.
79
+ */
80
+ unitPriceCents?: number;
81
+ /**
82
+ * Einzelpreis in Mikro-Euro (10⁻⁶ €), fuer Preise unterhalb eines Cents.
83
+ * Genau eines von `unitPriceCents` und `unitPriceMicros`.
84
+ */
85
+ unitPriceMicros?: number;
78
86
  vatRate: VatRatePercent;
79
87
  /** Zeilenrabatt in Prozent, hoechstens zwei Nachkommastellen. */
80
88
  discountPct?: number;
@@ -246,7 +254,15 @@ export interface InvoiceItem {
246
254
  unit: string;
247
255
  /** Ware oder Leistung — Altbestand ohne Angabe zaehlt als `goods`. */
248
256
  kind: ItemKind;
257
+ /**
258
+ * Einzelpreis in ganzen Cent — eine ANZEIGEHILFE: kaufmaennisch aus
259
+ * `unitPriceMicros` gerundet, und damit 0, sobald der Preis unter einem
260
+ * halben Cent liegt. Verbindlich sind `unitPriceMicros` und die Betraege je
261
+ * Position (§ 9.3).
262
+ */
249
263
  unitPriceCents: number;
264
+ /** Einzelpreis in Mikro-Euro (10⁻⁶ €) — der verbindliche Preis. */
265
+ unitPriceMicros?: number;
250
266
  vatRate: number;
251
267
  discountPct: number;
252
268
  }
@@ -204,6 +204,17 @@ export type Feld = {
204
204
  typ: 'object';
205
205
  pflicht: boolean;
206
206
  felder: Readonly<Record<string, Feld>>;
207
+ /**
208
+ * Feldgruppen, von denen GENAU EINE gesetzt sein muss (§ 9.1). Jede Gruppe
209
+ * ist eine Liste von Feldnamen; im JSON Schema wird daraus
210
+ * `oneOf: [{ required: [...] }, ...]`.
211
+ *
212
+ * Gebraucht fuer den Preis einer Position: `unitPriceCents` ODER
213
+ * `unitPriceMicros`, nie beides und nie keines. Als zwei Pflichtfelder
214
+ * liesse sich das nicht ausdruecken, und als zwei optionale waere eine
215
+ * Position ohne Preis gueltig.
216
+ */
217
+ genauEins?: readonly (readonly string[])[];
207
218
  } | {
208
219
  typ: 'list';
209
220
  pflicht: boolean;
@@ -219,8 +230,19 @@ export type Feld = {
219
230
  };
220
231
  /** Kunde, wie das Fremdsystem ihn schickt. `vatId` ist die UID-Nummer. */
221
232
  export declare const KUNDE_FELDER: Readonly<Record<string, Feld>>;
222
- /** Eine Rechnungs- oder Gutschriftsposition. Preise in ganzen Cent. */
233
+ /**
234
+ * Eine Rechnungs- oder Gutschriftsposition.
235
+ *
236
+ * Der Preis steht in ganzen Cent (`unitPriceCents`) ODER in Mikro-Euro
237
+ * (`unitPriceMicros`, 10⁻⁶ €) — genau eines von beiden (§ 9.1). Der Mikropreis
238
+ * loest denselben Bereich feiner auf: 10¹² Mikro-Euro sind dieselben
239
+ * 10.000.000,00 €, die 10⁸ Cent ausdruecken. Er ist noetig fuer Preise
240
+ * unterhalb eines Cents (Verbrauchsabrechnung, Stueckpreise im Zehntelcent),
241
+ * die bisher gerundet eingereicht werden mussten.
242
+ */
223
243
  export declare const POSITION_FELDER: Readonly<Record<string, Feld>>;
244
+ /** Genau einer der beiden Preise je Position (§ 9.1). */
245
+ export declare const POSITION_PREIS_GENAU_EINS: readonly (readonly string[])[];
224
246
  /**
225
247
  * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
226
248
  * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
@@ -332,20 +332,45 @@ export const KUNDE_FELDER = Object.freeze({
332
332
  });
333
333
  /** Beim Aendern ist jedes Kundenfeld optional. */
334
334
  const KUNDE_PATCH = Object.freeze(Object.fromEntries(Object.entries(KUNDE_FELDER).map(([name, feld]) => [name, { ...feld, pflicht: false }])));
335
- /** Eine Rechnungs- oder Gutschriftsposition. Preise in ganzen Cent. */
335
+ /**
336
+ * Eine Rechnungs- oder Gutschriftsposition.
337
+ *
338
+ * Der Preis steht in ganzen Cent (`unitPriceCents`) ODER in Mikro-Euro
339
+ * (`unitPriceMicros`, 10⁻⁶ €) — genau eines von beiden (§ 9.1). Der Mikropreis
340
+ * loest denselben Bereich feiner auf: 10¹² Mikro-Euro sind dieselben
341
+ * 10.000.000,00 €, die 10⁸ Cent ausdruecken. Er ist noetig fuer Preise
342
+ * unterhalb eines Cents (Verbrauchsabrechnung, Stueckpreise im Zehntelcent),
343
+ * die bisher gerundet eingereicht werden mussten.
344
+ */
336
345
  export const POSITION_FELDER = Object.freeze({
337
346
  description: text(300, true),
338
347
  subtitle: text(1000),
339
- quantity: { typ: 'number', pflicht: true, min: 0, exklusivMin: true, max: 1_000_000, nachkomma: 3 },
348
+ quantity: { typ: 'number', pflicht: true, min: 0, exklusivMin: true, max: 1_000_000_000, nachkomma: 3 },
340
349
  /** Einheit aus `INVOICE_UNITS`; ohne Angabe `piece`. */
341
350
  unit: { typ: 'enum', pflicht: false, werte: INVOICE_UNITS },
342
351
  /** Ware oder Leistung; ohne Angabe `goods`. Entscheidet ueber den Steuerfall. */
343
352
  kind: { typ: 'enum', pflicht: false, werte: ITEM_KINDS },
344
- unitPriceCents: { typ: 'integer', pflicht: true, min: 0, max: 100_000_000 },
353
+ /** Einzelpreis in ganzen Cent. Alternative zu `unitPriceMicros`. */
354
+ unitPriceCents: { typ: 'integer', pflicht: false, min: 0, max: 100_000_000 },
355
+ /** Einzelpreis in Mikro-Euro (10⁻⁶ €). Alternative zu `unitPriceCents`. */
356
+ unitPriceMicros: { typ: 'integer', pflicht: false, min: 0, max: 1_000_000_000_000 },
345
357
  vatRate: { typ: 'enum', pflicht: true, werte: VAT_RATES },
346
358
  discountPct: { typ: 'number', pflicht: false, min: 0, max: 100, nachkomma: 2 },
347
359
  });
348
- const positionen = { typ: 'list', pflicht: true, min: 1, max: 500, eintrag: { typ: 'object', pflicht: true, felder: POSITION_FELDER } };
360
+ /** Genau einer der beiden Preise je Position (§ 9.1). */
361
+ export const POSITION_PREIS_GENAU_EINS = Object.freeze([
362
+ Object.freeze(['unitPriceCents']),
363
+ Object.freeze(['unitPriceMicros']),
364
+ ]);
365
+ const positionen = {
366
+ typ: 'list',
367
+ pflicht: true,
368
+ min: 1,
369
+ max: 500,
370
+ eintrag: {
371
+ typ: 'object', pflicht: true, felder: POSITION_FELDER, genauEins: POSITION_PREIS_GENAU_EINS,
372
+ },
373
+ };
349
374
  /**
350
375
  * Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
351
376
  * Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.26.0",
2
+ "version": "0.27.1",
3
3
  "gemessenAn": {
4
4
  "tid": "3600335",
5
5
  "hpsVersion": "1.10.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.26.0",
2
+ "version": "0.27.1",
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.26.0",
2
+ "version": "0.27.1",
3
3
  "aufrufe": [
4
4
  "activateCashregister",
5
5
  "cancelInvoice",
@@ -0,0 +1,26 @@
1
+ {
2
+ "aufruf": "issueInvoice",
3
+ "beschreibung": "Beide Preisfelder gesetzt: genau eines ist erlaubt. Der Feldpfad zeigt auf das zuletzt hinzugekommene.",
4
+ "anfrage": {
5
+ "idempotencyKey": "bsp-mikro-2",
6
+ "customerId": "kunde_beispiel",
7
+ "priceMode": "net",
8
+ "serviceStart": "2026-09-14",
9
+ "items": [
10
+ {
11
+ "description": "Strom",
12
+ "quantity": 1,
13
+ "unitPriceCents": 100,
14
+ "unitPriceMicros": 1000000,
15
+ "vatRate": 20
16
+ }
17
+ ]
18
+ },
19
+ "erwartet": {
20
+ "ok": false,
21
+ "code": "validation",
22
+ "fields": [
23
+ "items[0].unitPriceMicros"
24
+ ]
25
+ }
26
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "aufruf": "issueInvoice",
3
+ "beschreibung": "Kein Preis: der Feldpfad zeigt auf unitPriceCents, den gewohnten Pflichtfehler.",
4
+ "anfrage": {
5
+ "idempotencyKey": "bsp-mikro-3",
6
+ "customerId": "kunde_beispiel",
7
+ "priceMode": "net",
8
+ "serviceStart": "2026-09-14",
9
+ "items": [
10
+ {
11
+ "description": "Strom",
12
+ "quantity": 1,
13
+ "vatRate": 20
14
+ }
15
+ ]
16
+ },
17
+ "erwartet": {
18
+ "ok": false,
19
+ "code": "validation",
20
+ "fields": [
21
+ "items[0].unitPriceCents"
22
+ ]
23
+ }
24
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "aufruf": "issueInvoice",
3
+ "beschreibung": "Preis unter einem Cent: 3.500.000 x 0,000004 EUR = 14,00 EUR netto. In ganzen Cent waere der Einzelpreis 0 und die Rechnung leer.",
4
+ "anfrage": {
5
+ "idempotencyKey": "bsp-mikro-1",
6
+ "customerId": "kunde_beispiel",
7
+ "taxScheme": "normal",
8
+ "priceMode": "net",
9
+ "serviceStart": "2026-09-14",
10
+ "items": [
11
+ {
12
+ "description": "Strom",
13
+ "quantity": 3500000,
14
+ "unitPriceMicros": 4,
15
+ "vatRate": 20
16
+ }
17
+ ]
18
+ },
19
+ "erwartet": {
20
+ "ok": true,
21
+ "totals": {
22
+ "netCents": 1400,
23
+ "vatCents": 280,
24
+ "grossCents": 1680
25
+ }
26
+ }
27
+ }
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "title": "Kasseneck Rechnungs-API",
4
4
  "version": 1,
5
- "paket": "0.26.0",
5
+ "paket": "0.27.1",
6
6
  "aufrufe": {
7
7
  "createCustomer": {
8
8
  "anfrage": {
@@ -376,7 +376,7 @@
376
376
  "quantity": {
377
377
  "type": "number",
378
378
  "exclusiveMinimum": 0,
379
- "maximum": 1000000,
379
+ "maximum": 1000000000,
380
380
  "x-decimals": 3
381
381
  },
382
382
  "unit": {
@@ -443,6 +443,11 @@
443
443
  "minimum": 0,
444
444
  "maximum": 100000000
445
445
  },
446
+ "unitPriceMicros": {
447
+ "type": "integer",
448
+ "minimum": 0,
449
+ "maximum": 1000000000000
450
+ },
446
451
  "vatRate": {
447
452
  "enum": [
448
453
  0,
@@ -461,9 +466,20 @@
461
466
  "required": [
462
467
  "description",
463
468
  "quantity",
464
- "unitPriceCents",
465
469
  "vatRate"
466
470
  ],
471
+ "oneOf": [
472
+ {
473
+ "required": [
474
+ "unitPriceCents"
475
+ ]
476
+ },
477
+ {
478
+ "required": [
479
+ "unitPriceMicros"
480
+ ]
481
+ }
482
+ ],
467
483
  "additionalProperties": false
468
484
  }
469
485
  },
@@ -619,7 +635,7 @@
619
635
  "quantity": {
620
636
  "type": "number",
621
637
  "exclusiveMinimum": 0,
622
- "maximum": 1000000,
638
+ "maximum": 1000000000,
623
639
  "x-decimals": 3
624
640
  },
625
641
  "unit": {
@@ -686,6 +702,11 @@
686
702
  "minimum": 0,
687
703
  "maximum": 100000000
688
704
  },
705
+ "unitPriceMicros": {
706
+ "type": "integer",
707
+ "minimum": 0,
708
+ "maximum": 1000000000000
709
+ },
689
710
  "vatRate": {
690
711
  "enum": [
691
712
  0,
@@ -704,9 +725,20 @@
704
725
  "required": [
705
726
  "description",
706
727
  "quantity",
707
- "unitPriceCents",
708
728
  "vatRate"
709
729
  ],
730
+ "oneOf": [
731
+ {
732
+ "required": [
733
+ "unitPriceCents"
734
+ ]
735
+ },
736
+ {
737
+ "required": [
738
+ "unitPriceMicros"
739
+ ]
740
+ }
741
+ ],
710
742
  "additionalProperties": false
711
743
  }
712
744
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.26.0",
2
+ "version": "0.27.1",
3
3
  "sprachen": [
4
4
  "de",
5
5
  "en"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kreiseck/kasseneck-api",
3
- "version": "0.26.0",
3
+ "version": "0.27.1",
4
4
  "description": "RKSV-Registrierkasse fuer JavaScript und TypeScript: signierte Belege, Storno, Kartenzahlung, Bondruck. Austrian fiscal cash register (RKSV) API client.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Kreiseck",