@kreiseck/kasseneck-api 0.16.0 → 0.18.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 +57 -0
- package/README.md +61 -0
- package/dist/cjs/client/aufrufe.d.ts +1 -1
- package/dist/cjs/client/aufrufe.js +2 -0
- package/dist/cjs/rechnung/api.d.ts +10 -3
- package/dist/cjs/rechnung/api.js +3 -1
- package/dist/cjs/rechnung/endpunkte.d.ts +23 -4
- package/dist/cjs/rechnung/endpunkte.js +41 -3
- package/dist/cjs/rechnung/index.d.ts +4 -3
- package/dist/cjs/rechnung/index.js +11 -1
- package/dist/cjs/rechnung/texte.d.ts +202 -0
- package/dist/cjs/rechnung/texte.js +377 -0
- package/dist/cjs/rechnung/typen.d.ts +70 -2
- package/dist/cjs/rechnung/vertrag.d.ts +47 -2
- package/dist/cjs/rechnung/vertrag.js +181 -2
- package/dist/esm/client/aufrufe.d.ts +1 -1
- package/dist/esm/client/aufrufe.js +2 -0
- package/dist/esm/rechnung/api.d.ts +10 -3
- package/dist/esm/rechnung/api.js +4 -2
- package/dist/esm/rechnung/endpunkte.d.ts +23 -4
- package/dist/esm/rechnung/endpunkte.js +39 -3
- package/dist/esm/rechnung/index.d.ts +4 -3
- package/dist/esm/rechnung/index.js +3 -2
- package/dist/esm/rechnung/texte.d.ts +202 -0
- package/dist/esm/rechnung/texte.js +373 -0
- package/dist/esm/rechnung/typen.d.ts +70 -2
- package/dist/esm/rechnung/vertrag.d.ts +47 -2
- package/dist/esm/rechnung/vertrag.js +180 -1
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/kasse-texte.json +1 -1
- package/fixtures/oberflaeche.json +75 -3
- package/fixtures/rechnung-api-beispiele/brands-ok.json +8 -0
- package/fixtures/rechnung-api-beispiele/issue-bezahlt.json +32 -0
- package/fixtures/rechnung-api-beispiele/issue-englisch.json +30 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-einheit.json +26 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-sprache.json +26 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-zahlungsart.json +26 -0
- package/fixtures/rechnung-api-beispiele/issue-netto-20.json +1 -1
- package/fixtures/rechnung-api-beispiele/zahlung-fehler-ohne-schluessel.json +14 -0
- package/fixtures/rechnung-api-beispiele/zahlung-nachtrag.json +14 -0
- package/fixtures/rechnung-api.schema.json +222 -6
- package/fixtures/rechnung-texte.json +424 -0
- package/package.json +2 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Betraege sind ueberall ganze Cent. Datumsangaben sind `YYYY-MM-DD` nach
|
|
6
6
|
* Wiener Kalender.
|
|
7
7
|
*/
|
|
8
|
-
import type { CreditNoteReason, CustomerType, DocType, InvoiceSetupRequirement, InvoiceListStatus, PriceMode, TaxScheme, VatRatePercent } from './vertrag.js';
|
|
8
|
+
import type { CreditNoteReason, CustomerType, DocType, InvoiceLanguage, InvoiceNoticeCode, InvoicePaymentMethod, InvoiceUnit, InvoiceSetupRequirement, InvoiceListStatus, PriceMode, TaxScheme, VatRatePercent } from './vertrag.js';
|
|
9
9
|
export interface CustomerInput {
|
|
10
10
|
type: CustomerType;
|
|
11
11
|
name: string;
|
|
@@ -27,6 +27,8 @@ export interface CustomerInput {
|
|
|
27
27
|
note?: string;
|
|
28
28
|
/** Kennung im eigenen System; je Konto eindeutig. */
|
|
29
29
|
externalId?: string;
|
|
30
|
+
/** Sprache der Rechnungen an diesen Kunden; fehlt = `de`. Behoerden immer `de`. */
|
|
31
|
+
language?: InvoiceLanguage;
|
|
30
32
|
}
|
|
31
33
|
export interface Customer {
|
|
32
34
|
id: string;
|
|
@@ -45,6 +47,7 @@ export interface Customer {
|
|
|
45
47
|
isAuthority: boolean;
|
|
46
48
|
note: string | null;
|
|
47
49
|
externalId: string | null;
|
|
50
|
+
language: InvoiceLanguage;
|
|
48
51
|
createdAt: string | null;
|
|
49
52
|
updatedAt: string | null;
|
|
50
53
|
}
|
|
@@ -66,7 +69,8 @@ export interface InvoiceItemInput {
|
|
|
66
69
|
subtitle?: string;
|
|
67
70
|
/** Hoechstens drei Nachkommastellen. */
|
|
68
71
|
quantity: number;
|
|
69
|
-
|
|
72
|
+
/** Einheit aus `INVOICE_UNITS`; ohne Angabe `piece`. */
|
|
73
|
+
unit?: InvoiceUnit;
|
|
70
74
|
/** Einzelpreis in ganzen Cent, im `priceMode` der Rechnung (netto oder brutto). */
|
|
71
75
|
unitPriceCents: number;
|
|
72
76
|
vatRate: VatRatePercent;
|
|
@@ -94,6 +98,53 @@ export interface IssueInvoiceRequest {
|
|
|
94
98
|
items: InvoiceItemInput[];
|
|
95
99
|
/** Eigene Merkmale (hoechstens 20), nie gedruckt. */
|
|
96
100
|
metadata?: Record<string, string>;
|
|
101
|
+
/** Sprache dieser Rechnung; sonst die des Kunden, sonst `de`. Eine Rechnung, eine Nummer, eine Sprache. */
|
|
102
|
+
language?: InvoiceLanguage;
|
|
103
|
+
/** Marke (Kennung aus `listBrands`); sonst die Standardmarke. Unbekannt = `brand_not_found`. */
|
|
104
|
+
brandId?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Schon bezahlt (Shop kassiert online, Rechnung folgt). Die Zahlung entsteht
|
|
107
|
+
* in derselben Transaktion wie das Festschreiben: das PDF traegt dann keine
|
|
108
|
+
* Zahlungsinformationen und keinen Giro-QR.
|
|
109
|
+
*/
|
|
110
|
+
payment?: PaymentInput;
|
|
111
|
+
}
|
|
112
|
+
/** Eine Zahlung, wie das Fremdsystem sie meldet. */
|
|
113
|
+
export interface PaymentInput {
|
|
114
|
+
method: InvoicePaymentMethod;
|
|
115
|
+
/** Ohne Angabe der volle Bruttobetrag. */
|
|
116
|
+
amountCents?: number;
|
|
117
|
+
/** Ohne Angabe der heutige Wiener Tag; nie in der Zukunft. */
|
|
118
|
+
paidAt?: string;
|
|
119
|
+
/** Zahlungskennung des Fremdsystems — gespeichert, aber nicht gedruckt. */
|
|
120
|
+
reference?: string;
|
|
121
|
+
}
|
|
122
|
+
export interface RecordPaymentRequest extends PaymentInput {
|
|
123
|
+
/** Pflicht: ohne ihn bucht eine Wiederholung eine zweite Zahlung. */
|
|
124
|
+
idempotencyKey: string;
|
|
125
|
+
invoiceId: string;
|
|
126
|
+
}
|
|
127
|
+
/** Eine gebuchte Zahlung, wie die API sie zurueckgibt. */
|
|
128
|
+
export interface InvoicePayment {
|
|
129
|
+
id: string;
|
|
130
|
+
amountCents: number;
|
|
131
|
+
paidAt: string;
|
|
132
|
+
method: InvoicePaymentMethod;
|
|
133
|
+
reference: string | null;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Ein Hinweis zu einer erfolgreichen Antwort — kein Fehler, sondern etwas,
|
|
137
|
+
* das der Aufrufer wissen sollte (heute nur `cash_receipt_required`).
|
|
138
|
+
*/
|
|
139
|
+
export interface InvoiceNotice {
|
|
140
|
+
code: InvoiceNoticeCode;
|
|
141
|
+
message: string;
|
|
142
|
+
}
|
|
143
|
+
export interface RecordPaymentResult {
|
|
144
|
+
invoice: Invoice;
|
|
145
|
+
payment: InvoicePayment;
|
|
146
|
+
replayed: boolean;
|
|
147
|
+
notice?: InvoiceNotice;
|
|
97
148
|
}
|
|
98
149
|
export interface CancelInvoiceRequest {
|
|
99
150
|
idempotencyKey: string;
|
|
@@ -132,6 +183,23 @@ export interface Invoice {
|
|
|
132
183
|
statusUrl: string | null;
|
|
133
184
|
statusPassword: string | null;
|
|
134
185
|
metadata: Record<string, string>;
|
|
186
|
+
/** Beim Festschreiben eingefroren; aeltere Rechnungen `de`. */
|
|
187
|
+
language: InvoiceLanguage;
|
|
188
|
+
/** Die eingefrorene Marke; `id` ist `null` bei der Ersatzmarke ohne eigene Einrichtung. */
|
|
189
|
+
brand: {
|
|
190
|
+
id: string | null;
|
|
191
|
+
name: string | null;
|
|
192
|
+
} | null;
|
|
193
|
+
/** Summe der gebuchten Zahlungen. */
|
|
194
|
+
paidCents: number;
|
|
195
|
+
/** Was noch offen ist; `0` heisst bezahlt. */
|
|
196
|
+
openCents: number;
|
|
197
|
+
}
|
|
198
|
+
/** Eine Marke des Kontos (Logo, Farbe, Absender) — `id` geht als `brandId` in `issueInvoice`. */
|
|
199
|
+
export interface Brand {
|
|
200
|
+
id: string;
|
|
201
|
+
name: string;
|
|
202
|
+
isDefault: boolean;
|
|
135
203
|
}
|
|
136
204
|
export interface InvoiceRecipient {
|
|
137
205
|
name: string;
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
* Nummer, Summen — ist bewusst **nicht** setzbar.
|
|
19
19
|
*/
|
|
20
20
|
export declare const RECHNUNG_VERTRAG_VERSION = 1;
|
|
21
|
-
export declare const RECHNUNG_AUFRUFE: readonly ["createCustomer", "getCustomer", "updateCustomer", "searchCustomers", "issueInvoice", "cancelInvoice", "createCreditNote", "getInvoice", "listInvoices", "getInvoicePdf", "getInvoiceXml", "getInvoiceSetupStatus"];
|
|
21
|
+
export declare const RECHNUNG_AUFRUFE: readonly ["createCustomer", "getCustomer", "updateCustomer", "searchCustomers", "issueInvoice", "cancelInvoice", "createCreditNote", "getInvoice", "listInvoices", "getInvoicePdf", "getInvoiceXml", "getInvoiceSetupStatus", "listBrands", "recordInvoicePayment"];
|
|
22
22
|
export type RechnungAufruf = (typeof RECHNUNG_AUFRUFE)[number];
|
|
23
23
|
/**
|
|
24
24
|
* Stabile Fehlercodes. Das Fremdsystem verzweigt am Code, der Text darf sich
|
|
25
25
|
* aendern. `validation` traegt zusaetzlich `errors: [{ field, message }]`.
|
|
26
26
|
*/
|
|
27
|
-
export declare const INVOICE_ERROR_CODES: readonly ["validation", "idempotency_conflict", "module_inactive", "customer_not_found", "customer_exists", "short_code_taken", "short_code_immutable", "recipient_required", "invoice_requirements_missing", "invoice_not_found", "invoice_ambiguous", "not_cancellable", "partial_credit_exists", "credit_exceeds_invoice", "einvoice_incomplete", "invoice_api_not_enabled", "invoice_setup_incomplete"];
|
|
27
|
+
export declare const INVOICE_ERROR_CODES: readonly ["validation", "idempotency_conflict", "module_inactive", "customer_not_found", "customer_exists", "short_code_taken", "short_code_immutable", "recipient_required", "invoice_requirements_missing", "invoice_not_found", "invoice_ambiguous", "not_cancellable", "partial_credit_exists", "credit_exceeds_invoice", "einvoice_incomplete", "invoice_api_not_enabled", "invoice_setup_incomplete", "language_not_allowed", "brand_not_found", "not_payable", "payment_exceeds_invoice"];
|
|
28
28
|
export type InvoiceErrorCode = (typeof INVOICE_ERROR_CODES)[number];
|
|
29
29
|
/** Gruende einer Gutschrift. Der Server druckt den deutschen Anzeigetext. */
|
|
30
30
|
export declare const CREDIT_NOTE_REASONS: readonly ["cancellation", "price_reduction", "return", "incorrect_invoice", "other"];
|
|
@@ -43,6 +43,43 @@ export declare const DOC_TYPES: readonly ["RE", "GU"];
|
|
|
43
43
|
export type DocType = (typeof DOC_TYPES)[number];
|
|
44
44
|
export declare const EINVOICE_FORMATS: readonly ["ubl", "cii"];
|
|
45
45
|
export type EInvoiceFormat = (typeof EINVOICE_FORMATS)[number];
|
|
46
|
+
/**
|
|
47
|
+
* Sprachen einer Rechnung. Die Sprache wird beim Festschreiben eingefroren;
|
|
48
|
+
* fehlt sie an Kunde oder Rechnung, gilt `de`. Behoerden bekommen immer `de`
|
|
49
|
+
* (`language_not_allowed`). Datum und Betraege bleiben in jeder Sprache
|
|
50
|
+
* oesterreichisch formatiert.
|
|
51
|
+
*/
|
|
52
|
+
export declare const INVOICE_LANGUAGES: readonly ["de", "en"];
|
|
53
|
+
export type InvoiceLanguage = (typeof INVOICE_LANGUAGES)[number];
|
|
54
|
+
/**
|
|
55
|
+
* Wie eine Rechnung bezahlt wurde. Der Vermerk ist Buchhaltung, kein Beleg:
|
|
56
|
+
* `cash` wird gebucht, die Antwort traegt dann zusaetzlich den Hinweis
|
|
57
|
+
* `cash_receipt_required` — eine Barzahlung ist ein Barumsatz und braucht
|
|
58
|
+
* einen Beleg (§ 132a BAO), bei Registrierkassenpflicht ueber die Kasse.
|
|
59
|
+
*/
|
|
60
|
+
export declare const INVOICE_PAYMENT_METHODS: readonly ["transfer", "card", "online", "cash"];
|
|
61
|
+
export type InvoicePaymentMethod = (typeof INVOICE_PAYMENT_METHODS)[number];
|
|
62
|
+
/**
|
|
63
|
+
* Hinweise, die eine erfolgreiche Antwort zusaetzlich tragen kann (`data.notice`).
|
|
64
|
+
* Sie sind keine Fehler: der Aufruf hat gewirkt, es gibt nur etwas zu wissen.
|
|
65
|
+
*/
|
|
66
|
+
export declare const INVOICE_NOTICE_CODES: readonly ["cash_receipt_required"];
|
|
67
|
+
export type InvoiceNoticeCode = (typeof INVOICE_NOTICE_CODES)[number];
|
|
68
|
+
/**
|
|
69
|
+
* Einheiten einer Position. Die API nimmt nur diese Schluessel an; gedruckt
|
|
70
|
+
* wird das Kuerzel in der Sprache der Rechnung (`RECHNUNG_TEXTE`,
|
|
71
|
+
* `einheit.<schluessel>`), die E-Rechnung fuehrt den UN/ECE-Code
|
|
72
|
+
* (`RECHNUNG_EINHEITEN_CODES`). Ohne Angabe gilt `piece`.
|
|
73
|
+
*/
|
|
74
|
+
export declare const INVOICE_UNITS: readonly ["piece", "pair", "set", "dozen", "second", "minute", "hour", "day", "night", "week", "month", "quarter", "half_year", "year", "milligram", "gram", "kilogram", "tonne", "millimetre", "centimetre", "metre", "running_metre", "kilometre", "square_metre", "hectare", "millilitre", "litre", "cubic_metre", "kilowatt_hour", "megawatt_hour", "gigabyte", "terabyte", "flat_rate", "person", "licence", "user", "device", "session", "trip", "page", "sheet", "package", "box", "carton", "bottle", "can", "roll", "bag", "pallet"];
|
|
75
|
+
export type InvoiceUnit = (typeof INVOICE_UNITS)[number];
|
|
76
|
+
/**
|
|
77
|
+
* UN/ECE-Code je Einheit (Recommendation 20, Verpackungen aus Recommendation 21
|
|
78
|
+
* mit `X`). Mehrere Einheiten duerfen denselben Code tragen (Meter und
|
|
79
|
+
* Laufmeter; Lizenz, Benutzer, Geraet als Stueck). Die Validatoren der
|
|
80
|
+
* E-Rechnung pruefen jeden Code im Backend (Beispiel `api-einheiten`).
|
|
81
|
+
*/
|
|
82
|
+
export declare const RECHNUNG_EINHEITEN_CODES: Readonly<Record<InvoiceUnit, string>>;
|
|
46
83
|
/**
|
|
47
84
|
* Was erfuellt sein muss, bevor ueber die API ausgestellt werden darf — in
|
|
48
85
|
* dieser Reihenfolge meldet `getInvoiceSetupStatus`, was fehlt, und dieselben
|
|
@@ -106,6 +143,14 @@ export type Feld = {
|
|
|
106
143
|
export declare const KUNDE_FELDER: Readonly<Record<string, Feld>>;
|
|
107
144
|
/** Eine Rechnungs- oder Gutschriftsposition. Preise in ganzen Cent. */
|
|
108
145
|
export declare const POSITION_FELDER: Readonly<Record<string, Feld>>;
|
|
146
|
+
/**
|
|
147
|
+
* Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
|
|
148
|
+
* Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
|
|
149
|
+
* Zahlungskennung des Fremdsystems (z. B. `pi_3Q...`) — sie wird gespeichert,
|
|
150
|
+
* aber **nicht gedruckt**: die Rechnung wird aufbewahrt und vervielfaeltigt,
|
|
151
|
+
* und dem Empfaenger nuetzt sie nichts.
|
|
152
|
+
*/
|
|
153
|
+
export declare const PAYMENT_FELDER: Readonly<Record<string, Feld>>;
|
|
109
154
|
export declare const RECHNUNG_ANFRAGEN: Readonly<Record<RechnungAufruf, Readonly<Record<string, Feld>>>>;
|
|
110
155
|
/** Genau eines dieser Felder muss gesetzt sein (je Aufruf, je Gruppe). */
|
|
111
156
|
export declare const RECHNUNG_GENAU_EINS: Readonly<Partial<Record<RechnungAufruf, readonly (readonly string[])[]>>>;
|
|
@@ -31,6 +31,8 @@ export const RECHNUNG_AUFRUFE = [
|
|
|
31
31
|
'getInvoicePdf',
|
|
32
32
|
'getInvoiceXml',
|
|
33
33
|
'getInvoiceSetupStatus',
|
|
34
|
+
'listBrands',
|
|
35
|
+
'recordInvoicePayment',
|
|
34
36
|
];
|
|
35
37
|
/**
|
|
36
38
|
* Stabile Fehlercodes. Das Fremdsystem verzweigt am Code, der Text darf sich
|
|
@@ -54,6 +56,10 @@ export const INVOICE_ERROR_CODES = [
|
|
|
54
56
|
'einvoice_incomplete',
|
|
55
57
|
'invoice_api_not_enabled',
|
|
56
58
|
'invoice_setup_incomplete',
|
|
59
|
+
'language_not_allowed',
|
|
60
|
+
'brand_not_found',
|
|
61
|
+
'not_payable',
|
|
62
|
+
'payment_exceeds_invoice',
|
|
57
63
|
];
|
|
58
64
|
/** Gruende einer Gutschrift. Der Server druckt den deutschen Anzeigetext. */
|
|
59
65
|
export const CREDIT_NOTE_REASONS = [
|
|
@@ -70,6 +76,142 @@ export const CUSTOMER_TYPES = ['private', 'company'];
|
|
|
70
76
|
export const INVOICE_LIST_STATUS = ['final', 'paid', 'cancelled', 'open', 'overdue'];
|
|
71
77
|
export const DOC_TYPES = ['RE', 'GU'];
|
|
72
78
|
export const EINVOICE_FORMATS = ['ubl', 'cii'];
|
|
79
|
+
/**
|
|
80
|
+
* Sprachen einer Rechnung. Die Sprache wird beim Festschreiben eingefroren;
|
|
81
|
+
* fehlt sie an Kunde oder Rechnung, gilt `de`. Behoerden bekommen immer `de`
|
|
82
|
+
* (`language_not_allowed`). Datum und Betraege bleiben in jeder Sprache
|
|
83
|
+
* oesterreichisch formatiert.
|
|
84
|
+
*/
|
|
85
|
+
export const INVOICE_LANGUAGES = ['de', 'en'];
|
|
86
|
+
/**
|
|
87
|
+
* Wie eine Rechnung bezahlt wurde. Der Vermerk ist Buchhaltung, kein Beleg:
|
|
88
|
+
* `cash` wird gebucht, die Antwort traegt dann zusaetzlich den Hinweis
|
|
89
|
+
* `cash_receipt_required` — eine Barzahlung ist ein Barumsatz und braucht
|
|
90
|
+
* einen Beleg (§ 132a BAO), bei Registrierkassenpflicht ueber die Kasse.
|
|
91
|
+
*/
|
|
92
|
+
export const INVOICE_PAYMENT_METHODS = ['transfer', 'card', 'online', 'cash'];
|
|
93
|
+
/**
|
|
94
|
+
* Hinweise, die eine erfolgreiche Antwort zusaetzlich tragen kann (`data.notice`).
|
|
95
|
+
* Sie sind keine Fehler: der Aufruf hat gewirkt, es gibt nur etwas zu wissen.
|
|
96
|
+
*/
|
|
97
|
+
export const INVOICE_NOTICE_CODES = ['cash_receipt_required'];
|
|
98
|
+
/**
|
|
99
|
+
* Einheiten einer Position. Die API nimmt nur diese Schluessel an; gedruckt
|
|
100
|
+
* wird das Kuerzel in der Sprache der Rechnung (`RECHNUNG_TEXTE`,
|
|
101
|
+
* `einheit.<schluessel>`), die E-Rechnung fuehrt den UN/ECE-Code
|
|
102
|
+
* (`RECHNUNG_EINHEITEN_CODES`). Ohne Angabe gilt `piece`.
|
|
103
|
+
*/
|
|
104
|
+
export const INVOICE_UNITS = [
|
|
105
|
+
'piece',
|
|
106
|
+
'pair',
|
|
107
|
+
'set',
|
|
108
|
+
'dozen',
|
|
109
|
+
'second',
|
|
110
|
+
'minute',
|
|
111
|
+
'hour',
|
|
112
|
+
'day',
|
|
113
|
+
'night',
|
|
114
|
+
'week',
|
|
115
|
+
'month',
|
|
116
|
+
'quarter',
|
|
117
|
+
'half_year',
|
|
118
|
+
'year',
|
|
119
|
+
'milligram',
|
|
120
|
+
'gram',
|
|
121
|
+
'kilogram',
|
|
122
|
+
'tonne',
|
|
123
|
+
'millimetre',
|
|
124
|
+
'centimetre',
|
|
125
|
+
'metre',
|
|
126
|
+
'running_metre',
|
|
127
|
+
'kilometre',
|
|
128
|
+
'square_metre',
|
|
129
|
+
'hectare',
|
|
130
|
+
'millilitre',
|
|
131
|
+
'litre',
|
|
132
|
+
'cubic_metre',
|
|
133
|
+
'kilowatt_hour',
|
|
134
|
+
'megawatt_hour',
|
|
135
|
+
'gigabyte',
|
|
136
|
+
'terabyte',
|
|
137
|
+
'flat_rate',
|
|
138
|
+
'person',
|
|
139
|
+
'licence',
|
|
140
|
+
'user',
|
|
141
|
+
'device',
|
|
142
|
+
'session',
|
|
143
|
+
'trip',
|
|
144
|
+
'page',
|
|
145
|
+
'sheet',
|
|
146
|
+
'package',
|
|
147
|
+
'box',
|
|
148
|
+
'carton',
|
|
149
|
+
'bottle',
|
|
150
|
+
'can',
|
|
151
|
+
'roll',
|
|
152
|
+
'bag',
|
|
153
|
+
'pallet',
|
|
154
|
+
];
|
|
155
|
+
/**
|
|
156
|
+
* UN/ECE-Code je Einheit (Recommendation 20, Verpackungen aus Recommendation 21
|
|
157
|
+
* mit `X`). Mehrere Einheiten duerfen denselben Code tragen (Meter und
|
|
158
|
+
* Laufmeter; Lizenz, Benutzer, Geraet als Stueck). Die Validatoren der
|
|
159
|
+
* E-Rechnung pruefen jeden Code im Backend (Beispiel `api-einheiten`).
|
|
160
|
+
*/
|
|
161
|
+
export const RECHNUNG_EINHEITEN_CODES = Object.freeze({
|
|
162
|
+
piece: 'C62',
|
|
163
|
+
pair: 'PR',
|
|
164
|
+
set: 'SET',
|
|
165
|
+
dozen: 'DZN',
|
|
166
|
+
second: 'SEC',
|
|
167
|
+
minute: 'MIN',
|
|
168
|
+
hour: 'HUR',
|
|
169
|
+
day: 'DAY',
|
|
170
|
+
night: 'C62',
|
|
171
|
+
week: 'WEE',
|
|
172
|
+
month: 'MON',
|
|
173
|
+
quarter: 'QAN',
|
|
174
|
+
half_year: 'SAN',
|
|
175
|
+
year: 'ANN',
|
|
176
|
+
milligram: 'MGM',
|
|
177
|
+
gram: 'GRM',
|
|
178
|
+
kilogram: 'KGM',
|
|
179
|
+
tonne: 'TNE',
|
|
180
|
+
millimetre: 'MMT',
|
|
181
|
+
centimetre: 'CMT',
|
|
182
|
+
metre: 'MTR',
|
|
183
|
+
running_metre: 'MTR',
|
|
184
|
+
kilometre: 'KMT',
|
|
185
|
+
square_metre: 'MTK',
|
|
186
|
+
// Rec 20 fuehrt fuer Hektar HAR, EN 16931 laesst davon nur H18
|
|
187
|
+
// („square hectometre", Synonym hectare) zu.
|
|
188
|
+
hectare: 'H18',
|
|
189
|
+
millilitre: 'MLT',
|
|
190
|
+
litre: 'LTR',
|
|
191
|
+
cubic_metre: 'MTQ',
|
|
192
|
+
kilowatt_hour: 'KWH',
|
|
193
|
+
megawatt_hour: 'MWH',
|
|
194
|
+
gigabyte: 'E34',
|
|
195
|
+
terabyte: 'E35',
|
|
196
|
+
flat_rate: 'LS',
|
|
197
|
+
person: 'IE',
|
|
198
|
+
licence: 'C62',
|
|
199
|
+
user: 'C62',
|
|
200
|
+
device: 'C62',
|
|
201
|
+
session: 'C62',
|
|
202
|
+
trip: 'C62',
|
|
203
|
+
page: 'ZP',
|
|
204
|
+
// Ebenso: ST („sheet") steht nicht in der Liste von EN 16931, LEF („leaf") schon.
|
|
205
|
+
sheet: 'LEF',
|
|
206
|
+
package: 'XPK',
|
|
207
|
+
box: 'XBX',
|
|
208
|
+
carton: 'XCT',
|
|
209
|
+
bottle: 'XBO',
|
|
210
|
+
can: 'XCA',
|
|
211
|
+
roll: 'XRO',
|
|
212
|
+
bag: 'XSA',
|
|
213
|
+
pallet: 'XPX',
|
|
214
|
+
});
|
|
73
215
|
/**
|
|
74
216
|
* Was erfuellt sein muss, bevor ueber die API ausgestellt werden darf — in
|
|
75
217
|
* dieser Reihenfolge meldet `getInvoiceSetupStatus`, was fehlt, und dieselben
|
|
@@ -117,6 +259,8 @@ export const KUNDE_FELDER = Object.freeze({
|
|
|
117
259
|
isAuthority: { typ: 'boolean', pflicht: false },
|
|
118
260
|
note: text(1000),
|
|
119
261
|
externalId: { typ: 'string', pflicht: false, min: 1, max: 120 },
|
|
262
|
+
/** Sprache der Rechnungen an diesen Kunden; fehlt = `de`. */
|
|
263
|
+
language: { typ: 'enum', pflicht: false, werte: INVOICE_LANGUAGES },
|
|
120
264
|
});
|
|
121
265
|
/** Beim Aendern ist jedes Kundenfeld optional. */
|
|
122
266
|
const KUNDE_PATCH = Object.freeze(Object.fromEntries(Object.entries(KUNDE_FELDER).map(([name, feld]) => [name, { ...feld, pflicht: false }])));
|
|
@@ -125,12 +269,26 @@ export const POSITION_FELDER = Object.freeze({
|
|
|
125
269
|
description: text(300, true),
|
|
126
270
|
subtitle: text(1000),
|
|
127
271
|
quantity: { typ: 'number', pflicht: true, min: 0, exklusivMin: true, max: 1_000_000, nachkomma: 3 },
|
|
128
|
-
|
|
272
|
+
/** Einheit aus `INVOICE_UNITS`; ohne Angabe `piece`. */
|
|
273
|
+
unit: { typ: 'enum', pflicht: false, werte: INVOICE_UNITS },
|
|
129
274
|
unitPriceCents: { typ: 'integer', pflicht: true, min: 0, max: 100_000_000 },
|
|
130
275
|
vatRate: { typ: 'enum', pflicht: true, werte: VAT_RATES },
|
|
131
276
|
discountPct: { typ: 'number', pflicht: false, min: 0, max: 100, nachkomma: 2 },
|
|
132
277
|
});
|
|
133
278
|
const positionen = { typ: 'list', pflicht: true, min: 1, max: 500, eintrag: { typ: 'object', pflicht: true, felder: POSITION_FELDER } };
|
|
279
|
+
/**
|
|
280
|
+
* Eine Zahlung zu einer Rechnung. Ohne `amountCents` gilt der volle
|
|
281
|
+
* Bruttobetrag, ohne `paidAt` der heutige Wiener Tag. `reference` ist die
|
|
282
|
+
* Zahlungskennung des Fremdsystems (z. B. `pi_3Q...`) — sie wird gespeichert,
|
|
283
|
+
* aber **nicht gedruckt**: die Rechnung wird aufbewahrt und vervielfaeltigt,
|
|
284
|
+
* und dem Empfaenger nuetzt sie nichts.
|
|
285
|
+
*/
|
|
286
|
+
export const PAYMENT_FELDER = Object.freeze({
|
|
287
|
+
method: { typ: 'enum', pflicht: true, werte: INVOICE_PAYMENT_METHODS },
|
|
288
|
+
amountCents: { typ: 'integer', pflicht: false, min: 1, max: 100_000_000 },
|
|
289
|
+
paidAt: datum(),
|
|
290
|
+
reference: text(100),
|
|
291
|
+
});
|
|
134
292
|
export const RECHNUNG_ANFRAGEN = Object.freeze({
|
|
135
293
|
createCustomer: {
|
|
136
294
|
customer: { typ: 'object', pflicht: true, felder: KUNDE_FELDER },
|
|
@@ -168,6 +326,16 @@ export const RECHNUNG_ANFRAGEN = Object.freeze({
|
|
|
168
326
|
tracking: { typ: 'boolean', pflicht: false },
|
|
169
327
|
items: positionen,
|
|
170
328
|
metadata: { typ: 'map', pflicht: false, maxSchluessel: 20, schluesselMuster: '^[a-zA-Z0-9_]{1,40}$', wertMax: 500 },
|
|
329
|
+
/** Sprache dieser Rechnung; sonst die des Kunden, sonst `de`. */
|
|
330
|
+
language: { typ: 'enum', pflicht: false, werte: INVOICE_LANGUAGES },
|
|
331
|
+
/** Marke (Kennung aus `listBrands`); sonst die Standardmarke. */
|
|
332
|
+
brandId: id,
|
|
333
|
+
/**
|
|
334
|
+
* Schon bezahlt: die Zahlung entsteht in **derselben** Transaktion wie das
|
|
335
|
+
* Festschreiben. Sonst gaebe es einen Moment, in dem die Rechnung offen ist
|
|
336
|
+
* und ein sofort geholtes PDF Zahlungsinformationen traegt.
|
|
337
|
+
*/
|
|
338
|
+
payment: { typ: 'object', pflicht: false, felder: PAYMENT_FELDER },
|
|
171
339
|
},
|
|
172
340
|
cancelInvoice: {
|
|
173
341
|
idempotencyKey: idempotencyKey(true),
|
|
@@ -197,12 +365,23 @@ export const RECHNUNG_ANFRAGEN = Object.freeze({
|
|
|
197
365
|
},
|
|
198
366
|
getInvoicePdf: {
|
|
199
367
|
invoiceId: idPflicht,
|
|
368
|
+
/** Andere Sprache als die der Rechnung: gekennzeichnete Uebersetzungskopie, keine eigene Rechnung. */
|
|
369
|
+
language: { typ: 'enum', pflicht: false, werte: INVOICE_LANGUAGES },
|
|
200
370
|
},
|
|
201
371
|
getInvoiceXml: {
|
|
202
372
|
invoiceId: idPflicht,
|
|
203
373
|
format: { typ: 'enum', pflicht: false, werte: EINVOICE_FORMATS },
|
|
204
374
|
},
|
|
205
375
|
getInvoiceSetupStatus: {},
|
|
376
|
+
listBrands: {},
|
|
377
|
+
recordInvoicePayment: {
|
|
378
|
+
idempotencyKey: idempotencyKey(true),
|
|
379
|
+
invoiceId: idPflicht,
|
|
380
|
+
method: { typ: 'enum', pflicht: true, werte: INVOICE_PAYMENT_METHODS },
|
|
381
|
+
amountCents: { typ: 'integer', pflicht: false, min: 1, max: 100_000_000 },
|
|
382
|
+
paidAt: datum(),
|
|
383
|
+
reference: text(100),
|
|
384
|
+
},
|
|
206
385
|
});
|
|
207
386
|
/** Genau eines dieser Felder muss gesetzt sein (je Aufruf, je Gruppe). */
|
|
208
387
|
export const RECHNUNG_GENAU_EINS = Object.freeze({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.18.0",
|
|
3
3
|
"aufrufe": [
|
|
4
4
|
"activateCashregister",
|
|
5
5
|
"cancelInvoice",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"issueInvoice",
|
|
38
38
|
"listCustomerCashregisters",
|
|
39
39
|
"listInvoices",
|
|
40
|
+
"listBrands",
|
|
40
41
|
"listMyArticleGroups",
|
|
41
42
|
"listMyArticles",
|
|
42
43
|
"listMyCashregisters",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"listRegisterUsersForDevice",
|
|
50
51
|
"listRegisterSessionsForDevice",
|
|
51
52
|
"pairRegisterDevice",
|
|
53
|
+
"recordInvoicePayment",
|
|
52
54
|
"registerPinLogin",
|
|
53
55
|
"registerUserLogin",
|
|
54
56
|
"renewRegisterSession",
|
|
@@ -398,7 +400,15 @@
|
|
|
398
400
|
"credit_exceeds_invoice",
|
|
399
401
|
"einvoice_incomplete",
|
|
400
402
|
"invoice_api_not_enabled",
|
|
401
|
-
"invoice_setup_incomplete"
|
|
403
|
+
"invoice_setup_incomplete",
|
|
404
|
+
"language_not_allowed",
|
|
405
|
+
"brand_not_found",
|
|
406
|
+
"not_payable",
|
|
407
|
+
"payment_exceeds_invoice"
|
|
408
|
+
],
|
|
409
|
+
"invoiceLanguages": [
|
|
410
|
+
"de",
|
|
411
|
+
"en"
|
|
402
412
|
],
|
|
403
413
|
"invoiceListStatus": [
|
|
404
414
|
"final",
|
|
@@ -407,6 +417,15 @@
|
|
|
407
417
|
"open",
|
|
408
418
|
"overdue"
|
|
409
419
|
],
|
|
420
|
+
"invoiceNoticeCodes": [
|
|
421
|
+
"cash_receipt_required"
|
|
422
|
+
],
|
|
423
|
+
"invoicePaymentMethods": [
|
|
424
|
+
"transfer",
|
|
425
|
+
"card",
|
|
426
|
+
"online",
|
|
427
|
+
"cash"
|
|
428
|
+
],
|
|
410
429
|
"invoiceSetupRequirements": [
|
|
411
430
|
"module_active",
|
|
412
431
|
"api_enabled",
|
|
@@ -417,6 +436,57 @@
|
|
|
417
436
|
"bank_account",
|
|
418
437
|
"number_format"
|
|
419
438
|
],
|
|
439
|
+
"invoiceUnits": [
|
|
440
|
+
"piece",
|
|
441
|
+
"pair",
|
|
442
|
+
"set",
|
|
443
|
+
"dozen",
|
|
444
|
+
"second",
|
|
445
|
+
"minute",
|
|
446
|
+
"hour",
|
|
447
|
+
"day",
|
|
448
|
+
"night",
|
|
449
|
+
"week",
|
|
450
|
+
"month",
|
|
451
|
+
"quarter",
|
|
452
|
+
"half_year",
|
|
453
|
+
"year",
|
|
454
|
+
"milligram",
|
|
455
|
+
"gram",
|
|
456
|
+
"kilogram",
|
|
457
|
+
"tonne",
|
|
458
|
+
"millimetre",
|
|
459
|
+
"centimetre",
|
|
460
|
+
"metre",
|
|
461
|
+
"running_metre",
|
|
462
|
+
"kilometre",
|
|
463
|
+
"square_metre",
|
|
464
|
+
"hectare",
|
|
465
|
+
"millilitre",
|
|
466
|
+
"litre",
|
|
467
|
+
"cubic_metre",
|
|
468
|
+
"kilowatt_hour",
|
|
469
|
+
"megawatt_hour",
|
|
470
|
+
"gigabyte",
|
|
471
|
+
"terabyte",
|
|
472
|
+
"flat_rate",
|
|
473
|
+
"person",
|
|
474
|
+
"licence",
|
|
475
|
+
"user",
|
|
476
|
+
"device",
|
|
477
|
+
"session",
|
|
478
|
+
"trip",
|
|
479
|
+
"page",
|
|
480
|
+
"sheet",
|
|
481
|
+
"package",
|
|
482
|
+
"box",
|
|
483
|
+
"carton",
|
|
484
|
+
"bottle",
|
|
485
|
+
"can",
|
|
486
|
+
"roll",
|
|
487
|
+
"bag",
|
|
488
|
+
"pallet"
|
|
489
|
+
],
|
|
420
490
|
"priceModes": [
|
|
421
491
|
"net",
|
|
422
492
|
"gross"
|
|
@@ -433,7 +503,9 @@
|
|
|
433
503
|
"listInvoices",
|
|
434
504
|
"getInvoicePdf",
|
|
435
505
|
"getInvoiceXml",
|
|
436
|
-
"getInvoiceSetupStatus"
|
|
506
|
+
"getInvoiceSetupStatus",
|
|
507
|
+
"listBrands",
|
|
508
|
+
"recordInvoicePayment"
|
|
437
509
|
],
|
|
438
510
|
"taxSchemes": [
|
|
439
511
|
"normal",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"aufruf": "issueInvoice",
|
|
3
|
+
"beschreibung": "Shop kassiert per Karte, Rechnung entsteht bezahlt",
|
|
4
|
+
"anfrage": {
|
|
5
|
+
"idempotencyKey": "bsp-bezahlt",
|
|
6
|
+
"customerId": "kunde_beispiel",
|
|
7
|
+
"taxScheme": "normal",
|
|
8
|
+
"priceMode": "net",
|
|
9
|
+
"serviceStart": "2026-09-16",
|
|
10
|
+
"items": [
|
|
11
|
+
{
|
|
12
|
+
"description": "Beratung",
|
|
13
|
+
"quantity": 2,
|
|
14
|
+
"unitPriceCents": 5000,
|
|
15
|
+
"vatRate": 20,
|
|
16
|
+
"unit": "hour"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"payment": {
|
|
20
|
+
"method": "card",
|
|
21
|
+
"reference": "pi_3QbeispielXYZ"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"erwartet": {
|
|
25
|
+
"ok": true,
|
|
26
|
+
"totals": {
|
|
27
|
+
"netCents": 10000,
|
|
28
|
+
"vatCents": 2000,
|
|
29
|
+
"grossCents": 12000
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"aufruf": "issueInvoice",
|
|
3
|
+
"beschreibung": "Englische Rechnung mit gewählter Marke",
|
|
4
|
+
"anfrage": {
|
|
5
|
+
"idempotencyKey": "bsp-en-1",
|
|
6
|
+
"customerId": "kunde_beispiel",
|
|
7
|
+
"taxScheme": "normal",
|
|
8
|
+
"priceMode": "net",
|
|
9
|
+
"serviceStart": "2026-09-15",
|
|
10
|
+
"language": "en",
|
|
11
|
+
"brandId": "marke_beispiel",
|
|
12
|
+
"items": [
|
|
13
|
+
{
|
|
14
|
+
"description": "Consulting",
|
|
15
|
+
"quantity": 2,
|
|
16
|
+
"unitPriceCents": 5000,
|
|
17
|
+
"vatRate": 20,
|
|
18
|
+
"unit": "hour"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"erwartet": {
|
|
23
|
+
"ok": true,
|
|
24
|
+
"totals": {
|
|
25
|
+
"netCents": 10000,
|
|
26
|
+
"vatCents": 2000,
|
|
27
|
+
"grossCents": 12000
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"aufruf": "issueInvoice",
|
|
3
|
+
"beschreibung": "Einheit als freier Text statt Schlüssel",
|
|
4
|
+
"anfrage": {
|
|
5
|
+
"idempotencyKey": "bsp-einheit",
|
|
6
|
+
"taxScheme": "normal",
|
|
7
|
+
"priceMode": "net",
|
|
8
|
+
"serviceStart": "2026-09-15",
|
|
9
|
+
"items": [
|
|
10
|
+
{
|
|
11
|
+
"description": "Beratung",
|
|
12
|
+
"quantity": 2,
|
|
13
|
+
"unit": "Std",
|
|
14
|
+
"unitPriceCents": 5000,
|
|
15
|
+
"vatRate": 20
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"erwartet": {
|
|
20
|
+
"ok": false,
|
|
21
|
+
"code": "validation",
|
|
22
|
+
"fields": [
|
|
23
|
+
"items[0].unit"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|