@kreiseck/kasseneck-api 0.13.2 → 0.15.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 +98 -0
- package/README.md +96 -5
- package/dist/cjs/client/aufrufe.d.ts +1 -1
- package/dist/cjs/client/aufrufe.js +11 -0
- package/dist/cjs/client/receipts.d.ts +7 -0
- package/dist/cjs/client/receipts.js +1 -0
- package/dist/cjs/kasse/drucker.d.ts +5 -0
- package/dist/cjs/kasse/drucker.js +9 -0
- package/dist/cjs/kasse/settings.js +5 -2
- package/dist/cjs/printing/escpos.d.ts +38 -4
- package/dist/cjs/printing/escpos.js +87 -15
- package/dist/cjs/printing/index.d.ts +2 -2
- package/dist/cjs/printing/index.js +5 -1
- package/dist/cjs/printing/qr-groesse.d.ts +26 -21
- package/dist/cjs/printing/qr-groesse.js +22 -8
- package/dist/cjs/react/index.d.ts +53 -0
- package/dist/cjs/react/index.js +81 -0
- package/dist/cjs/receipt/bild.d.ts +14 -0
- package/dist/cjs/receipt/bild.js +65 -0
- package/dist/cjs/receipt/blatt.d.ts +107 -0
- package/dist/cjs/receipt/blatt.js +137 -0
- package/dist/cjs/receipt/epos.d.ts +19 -8
- package/dist/cjs/receipt/epos.js +39 -20
- package/dist/cjs/receipt/grid.d.ts +1 -1
- package/dist/cjs/receipt/grid.js +9 -1
- package/dist/cjs/receipt/index.d.ts +4 -2
- package/dist/cjs/receipt/index.js +17 -1
- package/dist/cjs/receipt/layout-escpos.d.ts +31 -3
- package/dist/cjs/receipt/layout-escpos.js +58 -18
- package/dist/cjs/rechnung/api.d.ts +43 -0
- package/dist/cjs/rechnung/api.js +35 -0
- package/dist/cjs/rechnung/auth.d.ts +21 -0
- package/dist/cjs/rechnung/auth.js +36 -0
- package/dist/cjs/rechnung/endpunkte.d.ts +48 -0
- package/dist/cjs/rechnung/endpunkte.js +129 -0
- package/dist/cjs/rechnung/fehler.d.ts +21 -0
- package/dist/cjs/rechnung/fehler.js +44 -0
- package/dist/cjs/rechnung/index.d.ts +18 -0
- package/dist/cjs/rechnung/index.js +52 -0
- package/dist/cjs/rechnung/typen.d.ts +224 -0
- package/dist/cjs/rechnung/typen.js +9 -0
- package/dist/cjs/rechnung/vertrag.d.ts +98 -0
- package/dist/cjs/rechnung/vertrag.js +191 -0
- package/dist/esm/client/aufrufe.d.ts +1 -1
- package/dist/esm/client/aufrufe.js +11 -0
- package/dist/esm/client/receipts.d.ts +7 -0
- package/dist/esm/client/receipts.js +1 -0
- package/dist/esm/kasse/drucker.d.ts +5 -0
- package/dist/esm/kasse/drucker.js +9 -0
- package/dist/esm/kasse/settings.js +5 -2
- package/dist/esm/printing/escpos.d.ts +38 -4
- package/dist/esm/printing/escpos.js +84 -15
- package/dist/esm/printing/index.d.ts +2 -2
- package/dist/esm/printing/index.js +2 -2
- package/dist/esm/printing/qr-groesse.d.ts +26 -21
- package/dist/esm/printing/qr-groesse.js +21 -8
- package/dist/esm/react/index.d.ts +53 -0
- package/dist/esm/react/index.js +80 -1
- package/dist/esm/receipt/bild.d.ts +14 -0
- package/dist/esm/receipt/bild.js +62 -0
- package/dist/esm/receipt/blatt.d.ts +107 -0
- package/dist/esm/receipt/blatt.js +128 -0
- package/dist/esm/receipt/epos.d.ts +19 -8
- package/dist/esm/receipt/epos.js +40 -22
- package/dist/esm/receipt/grid.d.ts +1 -1
- package/dist/esm/receipt/grid.js +9 -1
- package/dist/esm/receipt/index.d.ts +4 -2
- package/dist/esm/receipt/index.js +4 -2
- package/dist/esm/receipt/layout-escpos.d.ts +31 -3
- package/dist/esm/receipt/layout-escpos.js +58 -20
- package/dist/esm/rechnung/api.d.ts +43 -0
- package/dist/esm/rechnung/api.js +32 -0
- package/dist/esm/rechnung/auth.d.ts +21 -0
- package/dist/esm/rechnung/auth.js +33 -0
- package/dist/esm/rechnung/endpunkte.d.ts +48 -0
- package/dist/esm/rechnung/endpunkte.js +116 -0
- package/dist/esm/rechnung/fehler.d.ts +21 -0
- package/dist/esm/rechnung/fehler.js +39 -0
- package/dist/esm/rechnung/index.d.ts +18 -0
- package/dist/esm/rechnung/index.js +17 -0
- package/dist/esm/rechnung/typen.d.ts +224 -0
- package/dist/esm/rechnung/typen.js +8 -0
- package/dist/esm/rechnung/vertrag.d.ts +98 -0
- package/dist/esm/rechnung/vertrag.js +188 -0
- package/fixtures/erwartet/karte-eigener.blatt32.json +159 -0
- package/fixtures/erwartet/karte-eigener.blatt48.json +159 -0
- package/fixtures/erwartet/karte-gptom-ios.blatt32.json +231 -0
- package/fixtures/erwartet/karte-gptom-ios.blatt48.json +231 -0
- package/fixtures/erwartet/karte-gptom.blatt32.json +231 -0
- package/fixtures/erwartet/karte-gptom.blatt48.json +231 -0
- package/fixtures/erwartet/karte-hobex-cloud.blatt32.json +201 -0
- package/fixtures/erwartet/karte-hobex-cloud.blatt48.json +201 -0
- package/fixtures/erwartet/karte-hobex-hps.blatt32.json +225 -0
- package/fixtures/erwartet/karte-hobex-hps.blatt48.json +225 -0
- package/fixtures/erwartet/karte-mypos.blatt32.json +255 -0
- package/fixtures/erwartet/karte-mypos.blatt48.json +243 -0
- package/fixtures/erwartet/karte-stripe-eps.blatt32.json +195 -0
- package/fixtures/erwartet/karte-stripe-eps.blatt48.json +195 -0
- package/fixtures/erwartet/karte-stripe.blatt32.json +213 -0
- package/fixtures/erwartet/karte-stripe.blatt48.json +213 -0
- package/fixtures/erwartet/karte-sumup.blatt32.json +219 -0
- package/fixtures/erwartet/karte-sumup.blatt48.json +207 -0
- package/fixtures/erwartet/langer-artikelname.blatt32.json +177 -0
- package/fixtures/erwartet/langer-artikelname.blatt48.json +171 -0
- package/fixtures/erwartet/logo-probe-hoch.raster32.txt +120 -0
- package/fixtures/erwartet/logo-probe.raster32.txt +54 -0
- package/fixtures/erwartet/null-ausfall.blatt32.json +207 -0
- package/fixtures/erwartet/null-ausfall.blatt48.json +189 -0
- package/fixtures/erwartet/null-ausfall.grid32.txt +2 -0
- package/fixtures/erwartet/null-ausfall.grid48.txt +2 -0
- package/fixtures/erwartet/null-jahr.blatt32.json +213 -0
- package/fixtures/erwartet/null-jahr.blatt48.json +189 -0
- package/fixtures/erwartet/null-jahr.grid32.txt +2 -0
- package/fixtures/erwartet/null-jahr.grid48.txt +2 -0
- package/fixtures/erwartet/null-monat.blatt32.json +207 -0
- package/fixtures/erwartet/null-monat.blatt48.json +189 -0
- package/fixtures/erwartet/null-monat.grid32.txt +2 -0
- package/fixtures/erwartet/null-monat.grid48.txt +2 -0
- package/fixtures/erwartet/null-pruef.blatt32.json +207 -0
- package/fixtures/erwartet/null-pruef.blatt48.json +189 -0
- package/fixtures/erwartet/null-pruef.grid32.txt +2 -0
- package/fixtures/erwartet/null-pruef.grid48.txt +2 -0
- package/fixtures/erwartet/null-schluss.blatt32.json +207 -0
- package/fixtures/erwartet/null-schluss.blatt48.json +189 -0
- package/fixtures/erwartet/null-schluss.grid32.txt +2 -0
- package/fixtures/erwartet/null-schluss.grid48.txt +2 -0
- package/fixtures/erwartet/null-start.blatt32.json +207 -0
- package/fixtures/erwartet/null-start.blatt48.json +189 -0
- package/fixtures/erwartet/null-start.grid32.txt +2 -0
- package/fixtures/erwartet/null-start.grid48.txt +2 -0
- package/fixtures/erwartet/rabatt-chef-trinkgeld.blatt32.json +213 -0
- package/fixtures/erwartet/rabatt-chef-trinkgeld.blatt48.json +207 -0
- package/fixtures/erwartet/rabatt-einfach.blatt32.json +183 -0
- package/fixtures/erwartet/rabatt-einfach.blatt48.json +177 -0
- package/fixtures/erwartet/rabatt-trinkgeld.blatt32.json +213 -0
- package/fixtures/erwartet/rabatt-trinkgeld.blatt48.json +207 -0
- package/fixtures/erwartet/rabatt-wertgutschein.blatt32.json +219 -0
- package/fixtures/erwartet/rabatt-wertgutschein.blatt48.json +213 -0
- package/fixtures/erwartet/rabattzeilen.blatt32.json +201 -0
- package/fixtures/erwartet/rabattzeilen.blatt48.json +195 -0
- package/fixtures/erwartet/signaturausfall-verkauf.blatt32.json +195 -0
- package/fixtures/erwartet/signaturausfall-verkauf.blatt48.json +183 -0
- package/fixtures/erwartet/storno-rabatt.blatt32.json +249 -0
- package/fixtures/erwartet/storno-rabatt.blatt48.json +237 -0
- package/fixtures/erwartet/storno-rabatt.grid32.txt +2 -0
- package/fixtures/erwartet/storno-rabatt.grid48.txt +2 -0
- package/fixtures/erwartet/storno-teil.blatt32.json +207 -0
- package/fixtures/erwartet/storno-teil.blatt48.json +201 -0
- package/fixtures/erwartet/storno-teil.grid32.txt +2 -0
- package/fixtures/erwartet/storno-teil.grid48.txt +2 -0
- package/fixtures/erwartet/storno-voll.blatt32.json +219 -0
- package/fixtures/erwartet/storno-voll.blatt48.json +213 -0
- package/fixtures/erwartet/storno-voll.grid32.txt +2 -0
- package/fixtures/erwartet/storno-voll.grid48.txt +2 -0
- package/fixtures/erwartet/testkasse-verkauf.blatt32.json +225 -0
- package/fixtures/erwartet/testkasse-verkauf.blatt48.json +219 -0
- package/fixtures/erwartet/testkasse-verkauf.grid32.txt +5 -1
- package/fixtures/erwartet/testkasse-verkauf.grid48.txt +5 -1
- package/fixtures/erwartet/testsignatur-verkauf.blatt32.json +237 -0
- package/fixtures/erwartet/testsignatur-verkauf.blatt48.json +219 -0
- package/fixtures/erwartet/testsignatur-verkauf.grid32.txt +5 -1
- package/fixtures/erwartet/testsignatur-verkauf.grid48.txt +5 -1
- package/fixtures/erwartet/training.blatt32.json +237 -0
- package/fixtures/erwartet/training.blatt48.json +219 -0
- package/fixtures/erwartet/training.grid32.txt +2 -0
- package/fixtures/erwartet/training.grid48.txt +2 -0
- package/fixtures/erwartet/verkauf-bar.blatt32.json +177 -0
- package/fixtures/erwartet/verkauf-bar.blatt48.json +171 -0
- package/fixtures/erwartet/verkauf-karte.blatt32.json +177 -0
- package/fixtures/erwartet/verkauf-karte.blatt48.json +171 -0
- package/fixtures/erwartet/verkauf-kleinunternehmer.blatt32.json +183 -0
- package/fixtures/erwartet/verkauf-kleinunternehmer.blatt48.json +177 -0
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/kasse-settings-standard.json +1 -1
- package/fixtures/kasse-texte.json +1 -1
- package/fixtures/manifest.json +109 -43
- package/fixtures/oberflaeche.json +87 -1
- package/fixtures/rechnung-api-beispiele/credit-fehler-grund.json +24 -0
- package/fixtures/rechnung-api-beispiele/credit-ok.json +20 -0
- package/fixtures/rechnung-api-beispiele/customer-fehler-uid.json +25 -0
- package/fixtures/rechnung-api-beispiele/customer-get-fehler-beide.json +15 -0
- package/fixtures/rechnung-api-beispiele/customer-ok.json +20 -0
- package/fixtures/rechnung-api-beispiele/customer-search-fehler-leer.json +14 -0
- package/fixtures/rechnung-api-beispiele/issue-brutto-20.json +27 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-cent.json +26 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-menge.json +26 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-negativ.json +26 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-satz.json +26 -0
- package/fixtures/rechnung-api-beispiele/issue-fehler-unbekannt.json +27 -0
- package/fixtures/rechnung-api-beispiele/issue-gemischt.json +33 -0
- package/fixtures/rechnung-api-beispiele/issue-kleinunternehmer.json +27 -0
- package/fixtures/rechnung-api-beispiele/issue-netto-20.json +28 -0
- package/fixtures/rechnung-api-beispiele/issue-rabatt.json +28 -0
- package/fixtures/rechnung-api.schema.json +672 -0
- package/package.json +12 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { ReceiptLayout } from './layout.js';
|
|
2
2
|
import type { PosPaperSize } from '../printing/escpos.js';
|
|
3
|
-
import { type QrModulGroesse } from '../printing/index.js';
|
|
3
|
+
import { type QrModulGroesse, type RasterBild } from '../printing/index.js';
|
|
4
|
+
import { type DruckLogo } from './layout-escpos.js';
|
|
4
5
|
/**
|
|
5
6
|
* ePOS-Print XML (Epson TM-Drucker: Server Direct Print, ePOS-Print ueber
|
|
6
7
|
* HTTP) -- **aus dem Zeichenraster**: jede Rasterzeile wird eine <text>-Zeile
|
|
7
|
-
* mit exakt N Zeichen und Zeilenumbruch, Aufdrucke
|
|
8
|
-
*
|
|
8
|
+
* mit exakt N Zeichen und Zeilenumbruch, Aufdrucke als Rahmen aus
|
|
9
|
+
* Rasterzeilen, QR als <symbol>, Leerraum als <feed>, am Ende Schnitt. Kein
|
|
9
10
|
* eigenes Setzen -- was Bildschirm, ESC/POS und PDF zeigen, druckt der Epson
|
|
10
11
|
* Zeile fuer Zeile genauso.
|
|
11
12
|
*
|
|
@@ -22,16 +23,20 @@ export interface EposPrintXmlOptions {
|
|
|
22
23
|
*/
|
|
23
24
|
qrBreite?: number;
|
|
24
25
|
/**
|
|
25
|
-
* Deckel fuer die gerechnete QR-Modulgroesse; Vorgabe `
|
|
26
|
+
* Deckel fuer die gerechnete QR-Modulgroesse; Vorgabe `auto` (hoechstens 6
|
|
27
|
+
* Punkte je Modul) -- wie ESC/POS, Blatt und der Flutter-Zwilling.
|
|
26
28
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* damit ohne Wahl kein Byte anders herauskommt.
|
|
29
|
+
* Bis 0.13 stand hier `mittel`, weil `auto` damals beim ESC/POS-Wert 4
|
|
30
|
+
* deckelte und dieser Weg seit jeher mit 6 druckt. Seit `auto` ueberall 6
|
|
31
|
+
* heisst, ist das derselbe Wert: ohne Wahl kommt kein Byte anders heraus.
|
|
31
32
|
*/
|
|
32
33
|
qrGroesse?: QrModulGroesse;
|
|
33
34
|
/** Papierschnitt am Ende, Vorgabe true. */
|
|
34
35
|
cut?: boolean;
|
|
36
|
+
/** Firmenlogo; ohne Angabe kein Logo. */
|
|
37
|
+
logo?: DruckLogo | null;
|
|
38
|
+
/** "erstellt mit Kasseneck" am Ende. */
|
|
39
|
+
marke?: boolean;
|
|
35
40
|
}
|
|
36
41
|
/**
|
|
37
42
|
* Das XML **samt** dem, was dem QR unterwegs zugestossen ist -- dieselbe
|
|
@@ -45,6 +50,8 @@ export interface EposPrintErgebnis {
|
|
|
45
50
|
qrAusweich: string | null;
|
|
46
51
|
}
|
|
47
52
|
export declare function eposXmlEscape(text: string): string;
|
|
53
|
+
/** Ein Rasterbild als ePOS-`<image>` (einfarbig, Punktmass, Rasterzeilen Base64). */
|
|
54
|
+
export declare function eposBildXml(bild: RasterBild): string;
|
|
48
55
|
/** Nur das XML; wer die QR-Meldungen braucht, nimmt [eposPrintXmlErgebnis]. */
|
|
49
56
|
export declare function eposPrintXml(layout: ReceiptLayout, options?: EposPrintXmlOptions): string;
|
|
50
57
|
/**
|
|
@@ -77,6 +84,10 @@ export interface EposDirectOptions {
|
|
|
77
84
|
qrBreite?: number;
|
|
78
85
|
/** Deckel fuer die gerechnete QR-Modulgroesse; siehe [EposPrintXmlOptions.qrGroesse]. */
|
|
79
86
|
qrGroesse?: QrModulGroesse;
|
|
87
|
+
/** Firmenlogo; ohne Angabe kein Logo. */
|
|
88
|
+
logo?: DruckLogo | null;
|
|
89
|
+
/** "erstellt mit Kasseneck" am Ende. */
|
|
90
|
+
marke?: boolean;
|
|
80
91
|
timeoutMs?: number;
|
|
81
92
|
}
|
|
82
93
|
export interface EposResponse {
|
package/dist/cjs/receipt/epos.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EposConnectionError = void 0;
|
|
4
4
|
exports.eposXmlEscape = eposXmlEscape;
|
|
5
|
+
exports.eposBildXml = eposBildXml;
|
|
5
6
|
exports.eposPrintXml = eposPrintXml;
|
|
6
7
|
exports.eposPrintXmlErgebnis = eposPrintXmlErgebnis;
|
|
7
8
|
exports.eposServiceUrl = eposServiceUrl;
|
|
@@ -11,9 +12,14 @@ exports.eposDirectPrint = eposDirectPrint;
|
|
|
11
12
|
exports.eposDirectStatus = eposDirectStatus;
|
|
12
13
|
const index_js_1 = require("../printing/index.js");
|
|
13
14
|
const grid_js_1 = require("./grid.js");
|
|
15
|
+
const layout_escpos_js_1 = require("./layout-escpos.js");
|
|
14
16
|
function eposXmlEscape(text) {
|
|
15
17
|
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
16
18
|
}
|
|
19
|
+
/** Ein Rasterbild als ePOS-`<image>` (einfarbig, Punktmass, Rasterzeilen Base64). */
|
|
20
|
+
function eposBildXml(bild) {
|
|
21
|
+
return `<image width="${bild.breite}" height="${bild.hoehe}" color="color_1" mode="mono">${(0, index_js_1.rasterZeilenBase64)(bild)}</image>`;
|
|
22
|
+
}
|
|
17
23
|
const NS = 'http://www.epson-pos.com/schemas/2011/03/epos-print';
|
|
18
24
|
/** Nur das XML; wer die QR-Meldungen braucht, nimmt [eposPrintXmlErgebnis]. */
|
|
19
25
|
function eposPrintXml(layout, options = {}) {
|
|
@@ -30,8 +36,9 @@ function eposPrintXml(layout, options = {}) {
|
|
|
30
36
|
* laesst es weg; genau daran fehlte am echten Beleg der QR.
|
|
31
37
|
*/
|
|
32
38
|
function eposPrintXmlErgebnis(layout, options = {}) {
|
|
33
|
-
const
|
|
34
|
-
const deckel = options.qrGroesse ?? '
|
|
39
|
+
const zeichen = options.zeichen ?? grid_js_1.ZEICHEN_JE_PAPIER[layout.paperSize];
|
|
40
|
+
const deckel = options.qrGroesse ?? 'auto';
|
|
41
|
+
const blatt = (0, layout_escpos_js_1.blattFuerDruck)(layout, { zeichen, logo: options.logo, marke: options.marke, qrGroesse: deckel });
|
|
35
42
|
const fest = options.qrBreite === undefined
|
|
36
43
|
? null
|
|
37
44
|
: Math.min(16, Math.max(3, Math.floor(options.qrBreite)));
|
|
@@ -50,6 +57,12 @@ function eposPrintXmlErgebnis(layout, options = {}) {
|
|
|
50
57
|
return fest;
|
|
51
58
|
if (nutzlast === '')
|
|
52
59
|
return index_js_1.QR_MODUL_DECKEL[deckel];
|
|
60
|
+
// Passt der Inhalt in keine QR-Version, gibt es kein Symbol, das der
|
|
61
|
+
// Drucker setzen koennte -- wie beim Blatt (Anteil 0) geht der Beleg ohne QR.
|
|
62
|
+
if (!(0, index_js_1.qrPasstInVersion)(nutzlast)) {
|
|
63
|
+
qrFehler = 'QR-Inhalt passt in keine QR-Version -- Beleg ohne QR';
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
53
66
|
const mass = (0, index_js_1.qrGroesseFuer)({
|
|
54
67
|
nutzlast,
|
|
55
68
|
papierbreitePunkte: index_js_1.QR_DRUCK_PUNKTE[layout.paperSize],
|
|
@@ -74,32 +87,34 @@ function eposPrintXmlErgebnis(layout, options = {}) {
|
|
|
74
87
|
out.push('<text font="font_a"/>');
|
|
75
88
|
out.push('<text align="left"/>');
|
|
76
89
|
out.push('<text width="1" height="1" reverse="false" em="false"/>');
|
|
77
|
-
for (const
|
|
78
|
-
switch (
|
|
79
|
-
case '
|
|
80
|
-
|
|
90
|
+
for (const block of blatt.bloecke) {
|
|
91
|
+
switch (block.art) {
|
|
92
|
+
case 'zeile':
|
|
93
|
+
if (block.leer)
|
|
94
|
+
out.push('<feed line="1"/>');
|
|
95
|
+
else if (block.fett) {
|
|
96
|
+
out.push(`<text em="true">${eposXmlEscape(block.text)} </text>`);
|
|
97
|
+
out.push('<text em="false"/>');
|
|
98
|
+
}
|
|
99
|
+
else
|
|
100
|
+
out.push(`<text>${eposXmlEscape(block.text)} </text>`);
|
|
101
|
+
break;
|
|
102
|
+
case 'logo':
|
|
103
|
+
if (options.logo) {
|
|
104
|
+
out.push('<text align="center"/>');
|
|
105
|
+
out.push(eposBildXml(options.logo.raster));
|
|
106
|
+
out.push('<text align="left"/>');
|
|
107
|
+
}
|
|
81
108
|
break;
|
|
82
109
|
case 'qr': {
|
|
83
|
-
const breite = qrBreiteFuer(
|
|
110
|
+
const breite = qrBreiteFuer(block.nutzlast);
|
|
84
111
|
if (breite === null)
|
|
85
112
|
break;
|
|
86
113
|
out.push('<text align="center"/>');
|
|
87
|
-
out.push(`<symbol type="qrcode_model_2" level="level_m" width="${breite}" height="0" size="0">${eposXmlEscape(
|
|
114
|
+
out.push(`<symbol type="qrcode_model_2" level="level_m" width="${breite}" height="0" size="0">${eposXmlEscape(block.nutzlast)}</symbol>`);
|
|
88
115
|
out.push('<text align="left"/>');
|
|
89
116
|
break;
|
|
90
117
|
}
|
|
91
|
-
case 'banner':
|
|
92
|
-
out.push(`<text width="1" height="2" reverse="${z.ton === 'warnung' ? 'true' : 'false'}" em="true">${eposXmlEscape(z.text)} </text>`);
|
|
93
|
-
out.push('<text width="1" height="1" reverse="false" em="false"/>');
|
|
94
|
-
break;
|
|
95
|
-
default:
|
|
96
|
-
if (z.bold)
|
|
97
|
-
out.push(`<text em="true">${eposXmlEscape(z.text)} </text>`);
|
|
98
|
-
else
|
|
99
|
-
out.push(`<text>${eposXmlEscape(z.text)} </text>`);
|
|
100
|
-
if (z.bold)
|
|
101
|
-
out.push('<text em="false"/>');
|
|
102
|
-
break;
|
|
103
118
|
}
|
|
104
119
|
}
|
|
105
120
|
if (options.cut !== false) {
|
|
@@ -220,6 +235,10 @@ function eposDirectPrint(layout, o, fetchFn = fetch) {
|
|
|
220
235
|
xmlOptionen.qrBreite = o.qrBreite;
|
|
221
236
|
if (o.qrGroesse !== undefined)
|
|
222
237
|
xmlOptionen.qrGroesse = o.qrGroesse;
|
|
238
|
+
if (o.logo)
|
|
239
|
+
xmlOptionen.logo = o.logo;
|
|
240
|
+
if (o.marke !== undefined)
|
|
241
|
+
xmlOptionen.marke = o.marke;
|
|
223
242
|
return eposDirectSend(eposPrintXml({ ...layout, paperSize: papier }, xmlOptionen), o, fetchFn);
|
|
224
243
|
}
|
|
225
244
|
/** Verbindungstest: leeres Dokument, druckt nichts, liefert den Druckerstatus. */
|
|
@@ -27,7 +27,7 @@ export interface GridLine {
|
|
|
27
27
|
text: string;
|
|
28
28
|
kind: GridLineKind;
|
|
29
29
|
bold: boolean;
|
|
30
|
-
/** Bei `banner
|
|
30
|
+
/** Bei `banner` (Rahmen- und Textzeilen): `warnung` = Test/Ausfall, `belegart` = Storno, Nullbeleg … */
|
|
31
31
|
ton?: 'belegart' | 'warnung';
|
|
32
32
|
/** Bei `qr`: die Nutzlast. */
|
|
33
33
|
qr?: string;
|
package/dist/cjs/receipt/grid.js
CHANGED
|
@@ -67,10 +67,18 @@ function renderReceiptGrid(layout, options = {}) {
|
|
|
67
67
|
for (const t of (0, escpos_js_1.wortzeilenText)(z.text, zeichen))
|
|
68
68
|
lines.push({ text: ausrichten(t, zeichen, z.align), kind: 'text', bold: z.bold });
|
|
69
69
|
break;
|
|
70
|
-
case 'banner':
|
|
70
|
+
case 'banner': {
|
|
71
|
+
// Der Rahmen ist Teil des Rasters: eine Zeile '=' ueber die volle Breite
|
|
72
|
+
// davor und danach. So setzt ihn jeder Weg -- Bildschirm, Bon, ePOS, PDF,
|
|
73
|
+
// myPOS -- Zeichen fuer Zeichen gleich. Vorher zeichnete jeder Weg seinen
|
|
74
|
+
// eigenen Rahmen (Rechteck, doppelt hoch, invers, gefuellt).
|
|
75
|
+
const rahmen = '='.repeat(zeichen);
|
|
76
|
+
lines.push({ text: rahmen, kind: 'banner', bold: true, ton: z.ton });
|
|
71
77
|
for (const t of (0, escpos_js_1.wortzeilenText)(z.text, zeichen))
|
|
72
78
|
lines.push({ text: ausrichten(t, zeichen, 'center'), kind: 'banner', bold: true, ton: z.ton });
|
|
79
|
+
lines.push({ text: rahmen, kind: 'banner', bold: true, ton: z.ton });
|
|
73
80
|
break;
|
|
81
|
+
}
|
|
74
82
|
case 'rule':
|
|
75
83
|
lines.push({ text: (z.char || '-').charAt(0).repeat(zeichen), kind: 'rule', bold: false });
|
|
76
84
|
break;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { type LayoutAlign, type LayoutColumn, type LayoutTextLine, type LayoutColumnsLine, type LayoutRuleLine, type LayoutSpaceLine, type LayoutQrLine, type LayoutLine, type ReceiptLayout, type BuildReceiptLayoutOptions, buildReceiptLayout, receiptSignatureFailed, receiptSignatureIsTest, receiptIsZero, receiptAmountsAreZero, receiptIsSmallBusinessConsistent, receiptZdaText, type Pruefangaben, AKTUELLES_REGELWERK, type LayoutBannerLine, type LayoutRegelwerk, SMALL_BUSINESS_NOTICE, formatCents, } from './layout.js';
|
|
2
|
-
export { type EscPosLayoutOptions, type EscPosLayoutErgebnis, type QrPrintMode, escPosLayoutBytes, escPosLayoutErgebnis, } from './layout-escpos.js';
|
|
2
|
+
export { type EscPosLayoutOptions, type EscPosLayoutErgebnis, type QrPrintMode, type DruckLogo, pruefeLogoRaster, escPosLayoutBytes, escPosLayoutErgebnis, } from './layout-escpos.js';
|
|
3
3
|
export { type GridLine, type GridLineKind, type ReceiptGrid, type RenderReceiptGridOptions, renderReceiptGrid, gridSpaltenBreiten, gridAlsText, ZEICHEN_JE_PAPIER, } from './grid.js';
|
|
4
|
-
export { type EposPrintXmlOptions, type EposPrintErgebnis, type EposDirectOptions, type EposResponse, EposConnectionError, eposPrintXml, eposPrintXmlErgebnis, eposXmlEscape, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
4
|
+
export { type EposPrintXmlOptions, type EposPrintErgebnis, type EposDirectOptions, type EposResponse, EposConnectionError, eposPrintXml, eposPrintXmlErgebnis, eposXmlEscape, eposBildXml, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
5
|
+
export { type LogoStufe, type BlattLogo, type LogoMass, type BlattBlock, type BelegBlatt, type BelegBlattOptionen, LOGO_STUFEN, LOGO_PIXEL_MAX, PUNKTE_JE_ZEICHEN, PUNKTE_JE_ZEILE, MARKE_TEXT, papierFuerZeichen, logoMass, logoPixelZulaessig, logoRasterMass, qrBlattAnteil, belegBlatt, } from './blatt.js';
|
|
6
|
+
export { logoRaster } from './bild.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposXmlEscape = exports.eposPrintXmlErgebnis = exports.eposPrintXml = exports.EposConnectionError = exports.ZEICHEN_JE_PAPIER = exports.gridAlsText = exports.gridSpaltenBreiten = exports.renderReceiptGrid = exports.escPosLayoutErgebnis = exports.escPosLayoutBytes = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.AKTUELLES_REGELWERK = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
|
|
3
|
+
exports.logoRaster = exports.belegBlatt = exports.qrBlattAnteil = exports.logoRasterMass = exports.logoPixelZulaessig = exports.logoMass = exports.papierFuerZeichen = exports.MARKE_TEXT = exports.PUNKTE_JE_ZEILE = exports.PUNKTE_JE_ZEICHEN = exports.LOGO_PIXEL_MAX = exports.LOGO_STUFEN = exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposBildXml = exports.eposXmlEscape = exports.eposPrintXmlErgebnis = exports.eposPrintXml = exports.EposConnectionError = exports.ZEICHEN_JE_PAPIER = exports.gridAlsText = exports.gridSpaltenBreiten = exports.renderReceiptGrid = exports.escPosLayoutErgebnis = exports.escPosLayoutBytes = exports.pruefeLogoRaster = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.AKTUELLES_REGELWERK = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
|
|
4
4
|
var layout_js_1 = require("./layout.js");
|
|
5
5
|
Object.defineProperty(exports, "buildReceiptLayout", { enumerable: true, get: function () { return layout_js_1.buildReceiptLayout; } });
|
|
6
6
|
Object.defineProperty(exports, "receiptSignatureFailed", { enumerable: true, get: function () { return layout_js_1.receiptSignatureFailed; } });
|
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "AKTUELLES_REGELWERK", { enumerable: true, get: f
|
|
|
13
13
|
Object.defineProperty(exports, "SMALL_BUSINESS_NOTICE", { enumerable: true, get: function () { return layout_js_1.SMALL_BUSINESS_NOTICE; } });
|
|
14
14
|
Object.defineProperty(exports, "formatCents", { enumerable: true, get: function () { return layout_js_1.formatCents; } });
|
|
15
15
|
var layout_escpos_js_1 = require("./layout-escpos.js");
|
|
16
|
+
Object.defineProperty(exports, "pruefeLogoRaster", { enumerable: true, get: function () { return layout_escpos_js_1.pruefeLogoRaster; } });
|
|
16
17
|
Object.defineProperty(exports, "escPosLayoutBytes", { enumerable: true, get: function () { return layout_escpos_js_1.escPosLayoutBytes; } });
|
|
17
18
|
Object.defineProperty(exports, "escPosLayoutErgebnis", { enumerable: true, get: function () { return layout_escpos_js_1.escPosLayoutErgebnis; } });
|
|
18
19
|
var grid_js_1 = require("./grid.js");
|
|
@@ -25,8 +26,23 @@ Object.defineProperty(exports, "EposConnectionError", { enumerable: true, get: f
|
|
|
25
26
|
Object.defineProperty(exports, "eposPrintXml", { enumerable: true, get: function () { return epos_js_1.eposPrintXml; } });
|
|
26
27
|
Object.defineProperty(exports, "eposPrintXmlErgebnis", { enumerable: true, get: function () { return epos_js_1.eposPrintXmlErgebnis; } });
|
|
27
28
|
Object.defineProperty(exports, "eposXmlEscape", { enumerable: true, get: function () { return epos_js_1.eposXmlEscape; } });
|
|
29
|
+
Object.defineProperty(exports, "eposBildXml", { enumerable: true, get: function () { return epos_js_1.eposBildXml; } });
|
|
28
30
|
Object.defineProperty(exports, "eposServiceUrl", { enumerable: true, get: function () { return epos_js_1.eposServiceUrl; } });
|
|
29
31
|
Object.defineProperty(exports, "eposSoapEnvelope", { enumerable: true, get: function () { return epos_js_1.eposSoapEnvelope; } });
|
|
30
32
|
Object.defineProperty(exports, "eposParseResponse", { enumerable: true, get: function () { return epos_js_1.eposParseResponse; } });
|
|
31
33
|
Object.defineProperty(exports, "eposDirectPrint", { enumerable: true, get: function () { return epos_js_1.eposDirectPrint; } });
|
|
32
34
|
Object.defineProperty(exports, "eposDirectStatus", { enumerable: true, get: function () { return epos_js_1.eposDirectStatus; } });
|
|
35
|
+
var blatt_js_1 = require("./blatt.js");
|
|
36
|
+
Object.defineProperty(exports, "LOGO_STUFEN", { enumerable: true, get: function () { return blatt_js_1.LOGO_STUFEN; } });
|
|
37
|
+
Object.defineProperty(exports, "LOGO_PIXEL_MAX", { enumerable: true, get: function () { return blatt_js_1.LOGO_PIXEL_MAX; } });
|
|
38
|
+
Object.defineProperty(exports, "PUNKTE_JE_ZEICHEN", { enumerable: true, get: function () { return blatt_js_1.PUNKTE_JE_ZEICHEN; } });
|
|
39
|
+
Object.defineProperty(exports, "PUNKTE_JE_ZEILE", { enumerable: true, get: function () { return blatt_js_1.PUNKTE_JE_ZEILE; } });
|
|
40
|
+
Object.defineProperty(exports, "MARKE_TEXT", { enumerable: true, get: function () { return blatt_js_1.MARKE_TEXT; } });
|
|
41
|
+
Object.defineProperty(exports, "papierFuerZeichen", { enumerable: true, get: function () { return blatt_js_1.papierFuerZeichen; } });
|
|
42
|
+
Object.defineProperty(exports, "logoMass", { enumerable: true, get: function () { return blatt_js_1.logoMass; } });
|
|
43
|
+
Object.defineProperty(exports, "logoPixelZulaessig", { enumerable: true, get: function () { return blatt_js_1.logoPixelZulaessig; } });
|
|
44
|
+
Object.defineProperty(exports, "logoRasterMass", { enumerable: true, get: function () { return blatt_js_1.logoRasterMass; } });
|
|
45
|
+
Object.defineProperty(exports, "qrBlattAnteil", { enumerable: true, get: function () { return blatt_js_1.qrBlattAnteil; } });
|
|
46
|
+
Object.defineProperty(exports, "belegBlatt", { enumerable: true, get: function () { return blatt_js_1.belegBlatt; } });
|
|
47
|
+
var bild_js_1 = require("./bild.js");
|
|
48
|
+
Object.defineProperty(exports, "logoRaster", { enumerable: true, get: function () { return bild_js_1.logoRaster; } });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type PosCodeTable, type PosCutMode, type PosPaperSize, type QrCorrection, type QrMatrix, type QrModulGroesse, type QrSize } from '../printing/index.js';
|
|
1
|
+
import { type PosCodeTable, type PosCutMode, type PosPaperSize, type QrCorrection, type QrMatrix, type QrModulGroesse, type QrSize, type RasterBild } from '../printing/index.js';
|
|
2
2
|
import type { ReceiptLayout } from './layout.js';
|
|
3
|
+
import { type BelegBlatt, type LogoStufe, type LogoMass } from './blatt.js';
|
|
3
4
|
/**
|
|
4
5
|
* Bruecke vom Layout-Modell zu ESC/POS-Bytes — der Bondrucker-Ausgabeweg.
|
|
5
6
|
*
|
|
@@ -28,6 +29,29 @@ import type { ReceiptLayout } from './layout.js';
|
|
|
28
29
|
* (`qrMatrix`), weil dieses Paket keine QR-Codes rechnet.
|
|
29
30
|
*/
|
|
30
31
|
export type QrPrintMode = 'native' | 'nativeModel1' | 'imageRaster';
|
|
32
|
+
/** Firmenlogo fuer den Druck: Stufe, Pixelmass des Originals und das fertige Rasterbild (`logoRaster`). */
|
|
33
|
+
export interface DruckLogo {
|
|
34
|
+
stufe: LogoStufe;
|
|
35
|
+
pxBreite: number;
|
|
36
|
+
pxHoehe: number;
|
|
37
|
+
raster: RasterBild;
|
|
38
|
+
}
|
|
39
|
+
/** Das Rasterbild muss genau so gross sein, wie das Blatt das Logo setzt -- sonst stuende am Bon ein anderes Logo als am Schirm. */
|
|
40
|
+
export declare function pruefeLogoRaster(logo: DruckLogo, mass: LogoMass, zeichen: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Baut das Blatt fuer einen Druckweg (ESC/POS, ePOS) an EINER Stelle: die
|
|
43
|
+
* Zuordnung `DruckLogo` -> `BlattLogo` und die Groessenpruefung des mitgebrachten
|
|
44
|
+
* Rasterbilds teilen sich beide Wege -- ohne das muesste eine Aenderung daran an
|
|
45
|
+
* zwei Stellen nachgezogen werden. Wirft VOR jeder Ausgabe (also bevor der
|
|
46
|
+
* Aufrufer auch nur ein Byte/Zeichen geschrieben hat), wenn das Rasterbild nicht
|
|
47
|
+
* zur Logo-Stufe passt.
|
|
48
|
+
*/
|
|
49
|
+
export declare function blattFuerDruck(layout: ReceiptLayout, optionen: {
|
|
50
|
+
zeichen: number;
|
|
51
|
+
logo?: DruckLogo | null;
|
|
52
|
+
marke?: boolean;
|
|
53
|
+
qrGroesse: QrModulGroesse;
|
|
54
|
+
}): BelegBlatt;
|
|
31
55
|
export interface EscPosLayoutOptions {
|
|
32
56
|
/** Papierbreite; Vorgabe ist die des Layouts (dessen Spaltenbreiten daran haengen). */
|
|
33
57
|
paperSize?: PosPaperSize;
|
|
@@ -40,9 +64,9 @@ export interface EscPosLayoutOptions {
|
|
|
40
64
|
* dann passt der Aufrufer selbst auf, dass das Symbol aufs Papier geht.
|
|
41
65
|
*/
|
|
42
66
|
qrSize?: QrSize;
|
|
43
|
-
/** Fehlerkorrekturstufe des QR-Codes. */
|
|
67
|
+
/** Fehlerkorrekturstufe des QR-Codes; Vorgabe `M` (wie ePOS, Bildweg und Blatt). */
|
|
44
68
|
qrCorrection?: QrCorrection;
|
|
45
|
-
/** Deckel fuer die gerechnete Modulgroesse; Vorgabe `auto
|
|
69
|
+
/** Deckel fuer die gerechnete Modulgroesse; Vorgabe `auto` (hoechstens 6 Punkte je Modul). */
|
|
46
70
|
qrGroesse?: QrModulGroesse;
|
|
47
71
|
/** Druckweg des QR; Vorgabe `native` (der Bestandsweg). */
|
|
48
72
|
qrModus?: QrPrintMode;
|
|
@@ -54,6 +78,10 @@ export interface EscPosLayoutOptions {
|
|
|
54
78
|
* aus der QR-Bibliothek, die er ohnehin fuer den Bildschirm benutzt.
|
|
55
79
|
*/
|
|
56
80
|
qrMatrix?: (nutzlast: string) => QrMatrix;
|
|
81
|
+
/** Firmenlogo; ohne Angabe kein Logo (Bestand). */
|
|
82
|
+
logo?: DruckLogo | null;
|
|
83
|
+
/** "erstellt mit Kasseneck" am Ende (Konto-Flag `kreiseck_logo`). */
|
|
84
|
+
marke?: boolean;
|
|
57
85
|
}
|
|
58
86
|
/**
|
|
59
87
|
* Der Bytestrom **samt** dem, was dem QR unterwegs zugestossen ist.
|
|
@@ -1,9 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pruefeLogoRaster = pruefeLogoRaster;
|
|
4
|
+
exports.blattFuerDruck = blattFuerDruck;
|
|
3
5
|
exports.escPosLayoutBytes = escPosLayoutBytes;
|
|
4
6
|
exports.escPosLayoutErgebnis = escPosLayoutErgebnis;
|
|
5
7
|
const index_js_1 = require("../printing/index.js");
|
|
8
|
+
const blatt_js_1 = require("./blatt.js");
|
|
6
9
|
const grid_js_1 = require("./grid.js");
|
|
10
|
+
/** Das Rasterbild muss genau so gross sein, wie das Blatt das Logo setzt -- sonst stuende am Bon ein anderes Logo als am Schirm. */
|
|
11
|
+
function pruefeLogoRaster(logo, mass, zeichen) {
|
|
12
|
+
const soll = (0, blatt_js_1.logoRasterMass)(mass, zeichen);
|
|
13
|
+
if (logo.raster.breite !== soll.breite || logo.raster.hoehe !== soll.hoehe) {
|
|
14
|
+
throw new Error(`Logo-Raster ${logo.raster.breite}x${logo.raster.hoehe} passt nicht zum Blatt (${soll.breite}x${soll.hoehe})`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Baut das Blatt fuer einen Druckweg (ESC/POS, ePOS) an EINER Stelle: die
|
|
19
|
+
* Zuordnung `DruckLogo` -> `BlattLogo` und die Groessenpruefung des mitgebrachten
|
|
20
|
+
* Rasterbilds teilen sich beide Wege -- ohne das muesste eine Aenderung daran an
|
|
21
|
+
* zwei Stellen nachgezogen werden. Wirft VOR jeder Ausgabe (also bevor der
|
|
22
|
+
* Aufrufer auch nur ein Byte/Zeichen geschrieben hat), wenn das Rasterbild nicht
|
|
23
|
+
* zur Logo-Stufe passt.
|
|
24
|
+
*/
|
|
25
|
+
function blattFuerDruck(layout, optionen) {
|
|
26
|
+
const blattOptionen = {
|
|
27
|
+
zeichen: optionen.zeichen,
|
|
28
|
+
marke: optionen.marke === true,
|
|
29
|
+
qrGroesse: optionen.qrGroesse,
|
|
30
|
+
};
|
|
31
|
+
if (optionen.logo)
|
|
32
|
+
blattOptionen.logo = { stufe: optionen.logo.stufe, pxBreite: optionen.logo.pxBreite, pxHoehe: optionen.logo.pxHoehe };
|
|
33
|
+
const blatt = (0, blatt_js_1.belegBlatt)(layout, blattOptionen);
|
|
34
|
+
const logoBlock = blatt.bloecke.find((b) => b.art === 'logo');
|
|
35
|
+
if (optionen.logo && logoBlock && logoBlock.art === 'logo')
|
|
36
|
+
pruefeLogoRaster(optionen.logo, logoBlock, blatt.zeichen);
|
|
37
|
+
return blatt;
|
|
38
|
+
}
|
|
7
39
|
/**
|
|
8
40
|
* Druckbar gemachtes Layout: Texte durch [escPosPrintableText] (Codepage,
|
|
9
41
|
* "EUR" statt "€", Striche), damit das Raster mit den Zeichen rechnet, die
|
|
@@ -72,6 +104,13 @@ function escPosLayoutErgebnis(layout, options = {}) {
|
|
|
72
104
|
* `qrFehler` aus `escPosQrCode`, und der Beleg geht ohne QR hinaus.
|
|
73
105
|
*/
|
|
74
106
|
const qrZeile = (nutzlast) => {
|
|
107
|
+
// Ein Inhalt, der in keine QR-Version passt, laesst sich weder als Befehl
|
|
108
|
+
// noch als Bild drucken -- beide Wege wuerfen. Der Beleg geht ohne QR
|
|
109
|
+
// hinaus und sagt es ueber `qrFehler`, wie das Blatt (Anteil 0).
|
|
110
|
+
if (nutzlast !== '' && !(0, index_js_1.qrPasstInVersion)(nutzlast)) {
|
|
111
|
+
doc.qrFehler = 'QR-Inhalt passt in keine QR-Version -- Beleg ohne QR';
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
75
114
|
const raster = options.qrMatrix;
|
|
76
115
|
if (nutzlast !== '' && raster !== undefined) {
|
|
77
116
|
if (modus === 'imageRaster') {
|
|
@@ -98,27 +137,28 @@ function escPosLayoutErgebnis(layout, options = {}) {
|
|
|
98
137
|
}
|
|
99
138
|
(0, index_js_1.escPosQrCode)(doc, nutzlast, qrOptionen);
|
|
100
139
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
140
|
+
// `blattFuerDruck` prueft das Logo-Raster bereits VOR der Rueckgabe -- die
|
|
141
|
+
// Schleife unten schreibt darum nie ein Byte auf ein falsch grosses Logo.
|
|
142
|
+
const blatt = blattFuerDruck(druckbaresLayout(layout), {
|
|
143
|
+
zeichen: grid_js_1.ZEICHEN_JE_PAPIER[paperSize],
|
|
144
|
+
logo: options.logo,
|
|
145
|
+
marke: options.marke,
|
|
146
|
+
qrGroesse: options.qrGroesse ?? 'auto',
|
|
147
|
+
});
|
|
148
|
+
for (const block of blatt.bloecke) {
|
|
149
|
+
switch (block.art) {
|
|
107
150
|
case 'qr':
|
|
108
|
-
qrZeile(
|
|
151
|
+
qrZeile(block.nutzlast);
|
|
109
152
|
break;
|
|
110
|
-
case '
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// weiss-auf-schwarz und sah damit anders aus als jede Anzeige).
|
|
114
|
-
const rahmen = '='.repeat(grid_js_1.ZEICHEN_JE_PAPIER[paperSize]);
|
|
115
|
-
(0, index_js_1.escPosText)(doc, rahmen, { styles: { align: 'left', bold: true } });
|
|
116
|
-
(0, index_js_1.escPosText)(doc, zeile.text.trimEnd(), { styles: { align: 'left', bold: true, height: 2 } });
|
|
117
|
-
(0, index_js_1.escPosText)(doc, rahmen, { styles: { align: 'left', bold: true } });
|
|
153
|
+
case 'logo':
|
|
154
|
+
if (options.logo)
|
|
155
|
+
(0, index_js_1.escPosRasterBild)(doc, options.logo.raster, { align: 'center' });
|
|
118
156
|
break;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
157
|
+
case 'zeile':
|
|
158
|
+
if (block.leer)
|
|
159
|
+
(0, index_js_1.escPosFeed)(doc, 1);
|
|
160
|
+
else
|
|
161
|
+
(0, index_js_1.escPosText)(doc, block.text.trimEnd(), { styles: { align: 'left', bold: block.fett } });
|
|
122
162
|
break;
|
|
123
163
|
}
|
|
124
164
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fassade ueber den Aufrufen der Rechnungs-API: Schluessel einmal binden, dann rufen.
|
|
3
|
+
*
|
|
4
|
+
* Wie [createPartnerApi] bewusst **keine** Klasse — die Aufrufe sind freie
|
|
5
|
+
* Funktionen (endpunkte.ts) und bleiben einzeln importierbar.
|
|
6
|
+
*/
|
|
7
|
+
import { type FetchLike } from '../client/transport.js';
|
|
8
|
+
import type { EInvoiceFormat } from './vertrag.js';
|
|
9
|
+
import type { CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, IssueInvoiceRequest, IssueResult } from './typen.js';
|
|
10
|
+
export interface RechnungApiOptions {
|
|
11
|
+
/** `api_key` des Kontos (`kr_live_…` / `kr_test_…`). Gehoert auf einen Server. */
|
|
12
|
+
apiKey: string;
|
|
13
|
+
/** Abweichende Basis-URL; Vorgabe `https://api.kasseneck.at/v1`. */
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
/** Zeitlimit je Aufruf in Millisekunden. */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
/** Eigene `fetch`-Umsetzung (Tests, Proxys). */
|
|
18
|
+
fetch?: FetchLike;
|
|
19
|
+
}
|
|
20
|
+
export interface RechnungApi {
|
|
21
|
+
createCustomer(customer: CustomerInput, optionen?: {
|
|
22
|
+
idempotencyKey?: string;
|
|
23
|
+
}): Promise<Customer>;
|
|
24
|
+
getCustomer(kennung: {
|
|
25
|
+
customerId: string;
|
|
26
|
+
} | {
|
|
27
|
+
externalId: string;
|
|
28
|
+
}): Promise<Customer>;
|
|
29
|
+
updateCustomer(customerId: string, patch: Partial<CustomerInput>): Promise<Customer>;
|
|
30
|
+
searchCustomers(suche: CustomerSearch): Promise<CustomerPage>;
|
|
31
|
+
issueInvoice(anfrage: IssueInvoiceRequest): Promise<IssueResult>;
|
|
32
|
+
cancelInvoice(anfrage: CancelInvoiceRequest): Promise<CancelResult>;
|
|
33
|
+
createCreditNote(anfrage: CreditNoteRequest): Promise<CreditNoteResult>;
|
|
34
|
+
getInvoice(kennung: {
|
|
35
|
+
invoiceId: string;
|
|
36
|
+
} | {
|
|
37
|
+
number: string;
|
|
38
|
+
}): Promise<InvoiceDetail>;
|
|
39
|
+
listInvoices(abfrage?: InvoiceListQuery): Promise<InvoicePage>;
|
|
40
|
+
getInvoicePdf(invoiceId: string): Promise<Uint8Array>;
|
|
41
|
+
getInvoiceXml(invoiceId: string, format?: EInvoiceFormat): Promise<string>;
|
|
42
|
+
}
|
|
43
|
+
export declare function createRechnungApi(optionen: RechnungApiOptions): RechnungApi;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fassade ueber den Aufrufen der Rechnungs-API: Schluessel einmal binden, dann rufen.
|
|
4
|
+
*
|
|
5
|
+
* Wie [createPartnerApi] bewusst **keine** Klasse — die Aufrufe sind freie
|
|
6
|
+
* Funktionen (endpunkte.ts) und bleiben einzeln importierbar.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.createRechnungApi = createRechnungApi;
|
|
10
|
+
const transport_js_1 = require("../client/transport.js");
|
|
11
|
+
const auth_js_1 = require("./auth.js");
|
|
12
|
+
const endpunkte_js_1 = require("./endpunkte.js");
|
|
13
|
+
function createRechnungApi(optionen) {
|
|
14
|
+
const transportOptionen = {
|
|
15
|
+
auth: (0, auth_js_1.rechnungKeyAuth)({ apiKey: optionen.apiKey }),
|
|
16
|
+
baseUrl: optionen.baseUrl,
|
|
17
|
+
timeoutMs: optionen.timeoutMs,
|
|
18
|
+
fetch: optionen.fetch,
|
|
19
|
+
};
|
|
20
|
+
const rufen = (0, transport_js_1.createTransport)(transportOptionen);
|
|
21
|
+
const rufenBinaer = (0, transport_js_1.createBinaryTransport)(transportOptionen);
|
|
22
|
+
return {
|
|
23
|
+
createCustomer: (customer, o) => (0, endpunkte_js_1.createCustomer)(rufen, customer, o),
|
|
24
|
+
getCustomer: (kennung) => (0, endpunkte_js_1.getCustomer)(rufen, kennung),
|
|
25
|
+
updateCustomer: (id, patch) => (0, endpunkte_js_1.updateCustomer)(rufen, id, patch),
|
|
26
|
+
searchCustomers: (suche) => (0, endpunkte_js_1.searchCustomers)(rufen, suche),
|
|
27
|
+
issueInvoice: (anfrage) => (0, endpunkte_js_1.issueInvoice)(rufen, anfrage),
|
|
28
|
+
cancelInvoice: (anfrage) => (0, endpunkte_js_1.cancelInvoice)(rufen, anfrage),
|
|
29
|
+
createCreditNote: (anfrage) => (0, endpunkte_js_1.createCreditNote)(rufen, anfrage),
|
|
30
|
+
getInvoice: (kennung) => (0, endpunkte_js_1.getInvoice)(rufen, kennung),
|
|
31
|
+
listInvoices: (abfrage) => (0, endpunkte_js_1.listInvoices)(rufen, abfrage),
|
|
32
|
+
getInvoicePdf: (id) => (0, endpunkte_js_1.getInvoicePdf)(rufenBinaer, id),
|
|
33
|
+
getInvoiceXml: (id, format) => (0, endpunkte_js_1.getInvoiceXml)(rufen, id, format),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anmeldung fuer die Rechnungs-API: der `api_key` des Kontos als Bearer.
|
|
3
|
+
*
|
|
4
|
+
* Anders als `apiKeyAuth` **ohne** `cashregister-token` — eine Rechnung
|
|
5
|
+
* entsteht nicht an einer Kasse, sondern am Konto.
|
|
6
|
+
*
|
|
7
|
+
* **Der Schluessel gehoert auf einen Server.** Mit ihm entstehen festgeschriebene
|
|
8
|
+
* Rechnungen mit fortlaufender Nummer, die sich nur noch per Gutschrift
|
|
9
|
+
* korrigieren lassen.
|
|
10
|
+
*
|
|
11
|
+
* Geprueft wird nur, was ohne Netz sicher falsch ist: ein leerer Wert, ein
|
|
12
|
+
* Partner-Schluessel (`pk_…`) oder ein Kassen-Token (`cb_…`). Die Form des
|
|
13
|
+
* Kontoschluessels selbst bleibt offen, weil das Backend neben `kr_<env>_…`
|
|
14
|
+
* weiterhin aeltere Formen annimmt. Die Meldung nennt nie den Wert, nur seine Art.
|
|
15
|
+
*/
|
|
16
|
+
import type { KasseneckAuth } from '../client/auth.js';
|
|
17
|
+
export interface RechnungKeyAuthOptions {
|
|
18
|
+
/** `api_key` des Kontos, z. B. `kr_live_…` oder `kr_test_…`. */
|
|
19
|
+
apiKey: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function rechnungKeyAuth(options: RechnungKeyAuthOptions): KasseneckAuth;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Anmeldung fuer die Rechnungs-API: der `api_key` des Kontos als Bearer.
|
|
4
|
+
*
|
|
5
|
+
* Anders als `apiKeyAuth` **ohne** `cashregister-token` — eine Rechnung
|
|
6
|
+
* entsteht nicht an einer Kasse, sondern am Konto.
|
|
7
|
+
*
|
|
8
|
+
* **Der Schluessel gehoert auf einen Server.** Mit ihm entstehen festgeschriebene
|
|
9
|
+
* Rechnungen mit fortlaufender Nummer, die sich nur noch per Gutschrift
|
|
10
|
+
* korrigieren lassen.
|
|
11
|
+
*
|
|
12
|
+
* Geprueft wird nur, was ohne Netz sicher falsch ist: ein leerer Wert, ein
|
|
13
|
+
* Partner-Schluessel (`pk_…`) oder ein Kassen-Token (`cb_…`). Die Form des
|
|
14
|
+
* Kontoschluessels selbst bleibt offen, weil das Backend neben `kr_<env>_…`
|
|
15
|
+
* weiterhin aeltere Formen annimmt. Die Meldung nennt nie den Wert, nur seine Art.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.rechnungKeyAuth = rechnungKeyAuth;
|
|
19
|
+
const errors_js_1 = require("../client/errors.js");
|
|
20
|
+
function rechnungKeyAuth(options) {
|
|
21
|
+
const schluessel = typeof options?.apiKey === 'string' ? options.apiKey.trim() : '';
|
|
22
|
+
if (!schluessel) {
|
|
23
|
+
throw new errors_js_1.KasseneckAuthError('rechnungKeyAuth: apiKey fehlt');
|
|
24
|
+
}
|
|
25
|
+
if (/^pk_(live|test)_/i.test(schluessel)) {
|
|
26
|
+
throw new errors_js_1.KasseneckAuthError('rechnungKeyAuth: das ist ein Partner-Schluessel (pk_…) — die Rechnungs-API nimmt den api_key des Kontos (kr_…)');
|
|
27
|
+
}
|
|
28
|
+
if (/^cb_(live|test)_/i.test(schluessel)) {
|
|
29
|
+
throw new errors_js_1.KasseneckAuthError('rechnungKeyAuth: das ist ein Kassen-Token (cb_…) — die Rechnungs-API nimmt den api_key des Kontos (kr_…)');
|
|
30
|
+
}
|
|
31
|
+
// Pro Aufruf ein frisches Objekt, wie bei den anderen Anmeldungen.
|
|
32
|
+
return () => ({
|
|
33
|
+
headers: { Authorization: `Bearer ${schluessel}` },
|
|
34
|
+
params: {},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Die Aufrufe der Rechnungs-API — Kunden, Rechnungen, Gutschriften, Dateien.
|
|
3
|
+
*
|
|
4
|
+
* Jede Funktion nimmt den Transport als ersten Parameter und ist einzeln
|
|
5
|
+
* importierbar; die Fassade [createRechnungApi] bindet ihn nur einmal.
|
|
6
|
+
*
|
|
7
|
+
* **Geprueft wird hier nichts Fachliches.** Die Anfrage geht unveraendert an
|
|
8
|
+
* das Backend, das sie gegen denselben Vertrag prueft (`vertrag.ts`) und einen
|
|
9
|
+
* Formfehler als `validation` mit `errors[]` zurueckgibt — zwei Pruefungen
|
|
10
|
+
* hiessen zwei Wahrheiten, von denen eine veraltet.
|
|
11
|
+
*
|
|
12
|
+
* **Nicht automatisch wiederholen.** Wer nach einem Zeitlimit erneut
|
|
13
|
+
* ausstellt, tut das mit **demselben** `idempotencyKey`: dann kommt die schon
|
|
14
|
+
* ausgestellte Rechnung zurueck (`replayed: true`) statt einer zweiten.
|
|
15
|
+
*
|
|
16
|
+
* Nach dem Senden wird nichts hart gecastet: fehlt ein zugesagtes Feld, wirft
|
|
17
|
+
* der Aufruf `KasseneckValidationError` mit `scope:'response'`.
|
|
18
|
+
*/
|
|
19
|
+
import type { InternerBinaerTransport, InternerTransport } from '../client/aufrufe.js';
|
|
20
|
+
import type { EInvoiceFormat } from './vertrag.js';
|
|
21
|
+
import type { CancelInvoiceRequest, CancelResult, CreditNoteRequest, CreditNoteResult, Customer, CustomerInput, CustomerPage, CustomerSearch, InvoiceDetail, InvoiceListQuery, InvoicePage, IssueInvoiceRequest, IssueResult } from './typen.js';
|
|
22
|
+
export declare function createCustomer(rufen: InternerTransport, customer: CustomerInput, optionen?: {
|
|
23
|
+
idempotencyKey?: string;
|
|
24
|
+
}): Promise<Customer>;
|
|
25
|
+
export declare function getCustomer(rufen: InternerTransport, kennung: {
|
|
26
|
+
customerId: string;
|
|
27
|
+
} | {
|
|
28
|
+
externalId: string;
|
|
29
|
+
}): Promise<Customer>;
|
|
30
|
+
export declare function updateCustomer(rufen: InternerTransport, customerId: string, patch: Partial<CustomerInput>): Promise<Customer>;
|
|
31
|
+
export declare function searchCustomers(rufen: InternerTransport, suche: CustomerSearch): Promise<CustomerPage>;
|
|
32
|
+
export declare function issueInvoice(rufen: InternerTransport, anfrage: IssueInvoiceRequest): Promise<IssueResult>;
|
|
33
|
+
export declare function cancelInvoice(rufen: InternerTransport, anfrage: CancelInvoiceRequest): Promise<CancelResult>;
|
|
34
|
+
export declare function createCreditNote(rufen: InternerTransport, anfrage: CreditNoteRequest): Promise<CreditNoteResult>;
|
|
35
|
+
export declare function getInvoice(rufen: InternerTransport, kennung: {
|
|
36
|
+
invoiceId: string;
|
|
37
|
+
} | {
|
|
38
|
+
number: string;
|
|
39
|
+
}): Promise<InvoiceDetail>;
|
|
40
|
+
export declare function listInvoices(rufen: InternerTransport, abfrage?: InvoiceListQuery): Promise<InvoicePage>;
|
|
41
|
+
/** Das PDF der Rechnung (bei Gutschriften: der Gutschrift), mit eingebetteter Factur-X-Datei. */
|
|
42
|
+
export declare function getInvoicePdf(rufenBinaer: InternerBinaerTransport, invoiceId: string): Promise<Uint8Array>;
|
|
43
|
+
/**
|
|
44
|
+
* Die E-Rechnung als XML-Text. Sie kommt im gewohnten Umschlag (`data.xml`)
|
|
45
|
+
* und nicht als rohe Datei: so bleibt ein fachlicher Fehler
|
|
46
|
+
* (`einvoice_incomplete` mit `missing[]`) ein gewoehnlicher Fehler.
|
|
47
|
+
*/
|
|
48
|
+
export declare function getInvoiceXml(rufen: InternerTransport, invoiceId: string, format?: EInvoiceFormat): Promise<string>;
|