@kreiseck/kasseneck-api 0.6.7

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.
Files changed (294) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +2 -0
  3. package/README.md +206 -0
  4. package/dist/cjs/client/api.d.ts +75 -0
  5. package/dist/cjs/client/api.js +40 -0
  6. package/dist/cjs/client/auth.d.ts +52 -0
  7. package/dist/cjs/client/auth.js +72 -0
  8. package/dist/cjs/client/cashregisters.d.ts +21 -0
  9. package/dist/cjs/client/cashregisters.js +36 -0
  10. package/dist/cjs/client/errors.d.ts +159 -0
  11. package/dist/cjs/client/errors.js +226 -0
  12. package/dist/cjs/client/index.d.ts +8 -0
  13. package/dist/cjs/client/index.js +44 -0
  14. package/dist/cjs/client/receipts.d.ts +245 -0
  15. package/dist/cjs/client/receipts.js +452 -0
  16. package/dist/cjs/client/reports.d.ts +43 -0
  17. package/dist/cjs/client/reports.js +73 -0
  18. package/dist/cjs/client/status.d.ts +43 -0
  19. package/dist/cjs/client/status.js +47 -0
  20. package/dist/cjs/client/transport.d.ts +117 -0
  21. package/dist/cjs/client/transport.js +312 -0
  22. package/dist/cjs/enums/credit-card-provider.d.ts +22 -0
  23. package/dist/cjs/enums/credit-card-provider.js +23 -0
  24. package/dist/cjs/enums/define-enum.d.ts +15 -0
  25. package/dist/cjs/enums/define-enum.js +16 -0
  26. package/dist/cjs/enums/index.d.ts +7 -0
  27. package/dist/cjs/enums/index.js +17 -0
  28. package/dist/cjs/enums/keck-payment-method.d.ts +57 -0
  29. package/dist/cjs/enums/keck-payment-method.js +23 -0
  30. package/dist/cjs/enums/receipt-type.d.ts +41 -0
  31. package/dist/cjs/enums/receipt-type.js +18 -0
  32. package/dist/cjs/enums/stripe-link-mode.d.ts +17 -0
  33. package/dist/cjs/enums/stripe-link-mode.js +18 -0
  34. package/dist/cjs/enums/vat-rate.d.ts +40 -0
  35. package/dist/cjs/enums/vat-rate.js +19 -0
  36. package/dist/cjs/enums/voucher-action.d.ts +10 -0
  37. package/dist/cjs/enums/voucher-action.js +11 -0
  38. package/dist/cjs/enums/voucher-type.d.ts +9 -0
  39. package/dist/cjs/enums/voucher-type.js +10 -0
  40. package/dist/cjs/index.d.ts +5 -0
  41. package/dist/cjs/index.js +97 -0
  42. package/dist/cjs/kasse/artikel.d.ts +83 -0
  43. package/dist/cjs/kasse/artikel.js +79 -0
  44. package/dist/cjs/kasse/client.d.ts +10 -0
  45. package/dist/cjs/kasse/client.js +38 -0
  46. package/dist/cjs/kasse/drucker.d.ts +54 -0
  47. package/dist/cjs/kasse/drucker.js +41 -0
  48. package/dist/cjs/kasse/index.d.ts +11 -0
  49. package/dist/cjs/kasse/index.js +38 -0
  50. package/dist/cjs/kasse/settings.d.ts +115 -0
  51. package/dist/cjs/kasse/settings.js +62 -0
  52. package/dist/cjs/models/cancellation.d.ts +51 -0
  53. package/dist/cjs/models/cancellation.js +45 -0
  54. package/dist/cjs/models/cashregister.d.ts +77 -0
  55. package/dist/cjs/models/cashregister.js +53 -0
  56. package/dist/cjs/models/enum-payload.d.ts +26 -0
  57. package/dist/cjs/models/enum-payload.js +50 -0
  58. package/dist/cjs/models/hobex-receipt.d.ts +63 -0
  59. package/dist/cjs/models/hobex-receipt.js +86 -0
  60. package/dist/cjs/models/index.d.ts +10 -0
  61. package/dist/cjs/models/index.js +46 -0
  62. package/dist/cjs/models/receipt-company.d.ts +71 -0
  63. package/dist/cjs/models/receipt-company.js +52 -0
  64. package/dist/cjs/models/receipt-item.d.ts +100 -0
  65. package/dist/cjs/models/receipt-item.js +108 -0
  66. package/dist/cjs/models/receipt-summary.d.ts +92 -0
  67. package/dist/cjs/models/receipt-summary.js +54 -0
  68. package/dist/cjs/models/receipt.d.ts +108 -0
  69. package/dist/cjs/models/receipt.js +119 -0
  70. package/dist/cjs/models/report-month.d.ts +32 -0
  71. package/dist/cjs/models/report-month.js +65 -0
  72. package/dist/cjs/models/stripe-url-session.d.ts +18 -0
  73. package/dist/cjs/models/stripe-url-session.js +20 -0
  74. package/dist/cjs/models/voucher.d.ts +41 -0
  75. package/dist/cjs/models/voucher.js +56 -0
  76. package/dist/cjs/money.d.ts +23 -0
  77. package/dist/cjs/money.js +35 -0
  78. package/dist/cjs/package.json +1 -0
  79. package/dist/cjs/payments/hobex.d.ts +87 -0
  80. package/dist/cjs/payments/hobex.js +167 -0
  81. package/dist/cjs/payments/index.d.ts +33 -0
  82. package/dist/cjs/payments/index.js +42 -0
  83. package/dist/cjs/payments/stripe.d.ts +61 -0
  84. package/dist/cjs/payments/stripe.js +157 -0
  85. package/dist/cjs/printing/escpos.d.ts +219 -0
  86. package/dist/cjs/printing/escpos.js +636 -0
  87. package/dist/cjs/printing/index.d.ts +3 -0
  88. package/dist/cjs/printing/index.js +33 -0
  89. package/dist/cjs/printing/printable.d.ts +27 -0
  90. package/dist/cjs/printing/printable.js +90 -0
  91. package/dist/cjs/printing/webusb.d.ts +89 -0
  92. package/dist/cjs/printing/webusb.js +110 -0
  93. package/dist/cjs/react/index.d.ts +46 -0
  94. package/dist/cjs/react/index.js +51 -0
  95. package/dist/cjs/receipt/discount.d.ts +12 -0
  96. package/dist/cjs/receipt/discount.js +54 -0
  97. package/dist/cjs/receipt/epos.d.ts +53 -0
  98. package/dist/cjs/receipt/epos.js +95 -0
  99. package/dist/cjs/receipt/grid.d.ts +47 -0
  100. package/dist/cjs/receipt/grid.js +122 -0
  101. package/dist/cjs/receipt/index.d.ts +4 -0
  102. package/dist/cjs/receipt/index.js +29 -0
  103. package/dist/cjs/receipt/layout-escpos.d.ts +35 -0
  104. package/dist/cjs/receipt/layout-escpos.js +67 -0
  105. package/dist/cjs/receipt/layout.d.ts +180 -0
  106. package/dist/cjs/receipt/layout.js +594 -0
  107. package/dist/cjs/register/index.d.ts +51 -0
  108. package/dist/cjs/register/index.js +61 -0
  109. package/dist/cjs/register/pairing.d.ts +248 -0
  110. package/dist/cjs/register/pairing.js +279 -0
  111. package/dist/cjs/register/session.d.ts +37 -0
  112. package/dist/cjs/register/session.js +52 -0
  113. package/dist/cjs/vienna-time.d.ts +23 -0
  114. package/dist/cjs/vienna-time.js +114 -0
  115. package/dist/esm/client/api.d.ts +75 -0
  116. package/dist/esm/client/api.js +37 -0
  117. package/dist/esm/client/auth.d.ts +52 -0
  118. package/dist/esm/client/auth.js +68 -0
  119. package/dist/esm/client/cashregisters.d.ts +21 -0
  120. package/dist/esm/client/cashregisters.js +33 -0
  121. package/dist/esm/client/errors.d.ts +159 -0
  122. package/dist/esm/client/errors.js +212 -0
  123. package/dist/esm/client/index.d.ts +8 -0
  124. package/dist/esm/client/index.js +8 -0
  125. package/dist/esm/client/receipts.d.ts +245 -0
  126. package/dist/esm/client/receipts.js +438 -0
  127. package/dist/esm/client/reports.d.ts +43 -0
  128. package/dist/esm/client/reports.js +69 -0
  129. package/dist/esm/client/status.d.ts +43 -0
  130. package/dist/esm/client/status.js +43 -0
  131. package/dist/esm/client/transport.d.ts +117 -0
  132. package/dist/esm/client/transport.js +307 -0
  133. package/dist/esm/enums/credit-card-provider.d.ts +22 -0
  134. package/dist/esm/enums/credit-card-provider.js +20 -0
  135. package/dist/esm/enums/define-enum.d.ts +15 -0
  136. package/dist/esm/enums/define-enum.js +13 -0
  137. package/dist/esm/enums/index.d.ts +7 -0
  138. package/dist/esm/enums/index.js +7 -0
  139. package/dist/esm/enums/keck-payment-method.d.ts +57 -0
  140. package/dist/esm/enums/keck-payment-method.js +20 -0
  141. package/dist/esm/enums/receipt-type.d.ts +41 -0
  142. package/dist/esm/enums/receipt-type.js +15 -0
  143. package/dist/esm/enums/stripe-link-mode.d.ts +17 -0
  144. package/dist/esm/enums/stripe-link-mode.js +15 -0
  145. package/dist/esm/enums/vat-rate.d.ts +40 -0
  146. package/dist/esm/enums/vat-rate.js +16 -0
  147. package/dist/esm/enums/voucher-action.d.ts +10 -0
  148. package/dist/esm/enums/voucher-action.js +8 -0
  149. package/dist/esm/enums/voucher-type.d.ts +9 -0
  150. package/dist/esm/enums/voucher-type.js +7 -0
  151. package/dist/esm/index.d.ts +5 -0
  152. package/dist/esm/index.js +5 -0
  153. package/dist/esm/kasse/artikel.d.ts +83 -0
  154. package/dist/esm/kasse/artikel.js +70 -0
  155. package/dist/esm/kasse/client.d.ts +10 -0
  156. package/dist/esm/kasse/client.js +33 -0
  157. package/dist/esm/kasse/drucker.d.ts +54 -0
  158. package/dist/esm/kasse/drucker.js +36 -0
  159. package/dist/esm/kasse/index.d.ts +11 -0
  160. package/dist/esm/kasse/index.js +13 -0
  161. package/dist/esm/kasse/settings.d.ts +115 -0
  162. package/dist/esm/kasse/settings.js +58 -0
  163. package/dist/esm/models/cancellation.d.ts +51 -0
  164. package/dist/esm/models/cancellation.js +40 -0
  165. package/dist/esm/models/cashregister.d.ts +77 -0
  166. package/dist/esm/models/cashregister.js +50 -0
  167. package/dist/esm/models/enum-payload.d.ts +26 -0
  168. package/dist/esm/models/enum-payload.js +44 -0
  169. package/dist/esm/models/hobex-receipt.d.ts +63 -0
  170. package/dist/esm/models/hobex-receipt.js +80 -0
  171. package/dist/esm/models/index.d.ts +10 -0
  172. package/dist/esm/models/index.js +10 -0
  173. package/dist/esm/models/receipt-company.d.ts +71 -0
  174. package/dist/esm/models/receipt-company.js +48 -0
  175. package/dist/esm/models/receipt-item.d.ts +100 -0
  176. package/dist/esm/models/receipt-item.js +101 -0
  177. package/dist/esm/models/receipt-summary.d.ts +92 -0
  178. package/dist/esm/models/receipt-summary.js +49 -0
  179. package/dist/esm/models/receipt.d.ts +108 -0
  180. package/dist/esm/models/receipt.js +113 -0
  181. package/dist/esm/models/report-month.d.ts +32 -0
  182. package/dist/esm/models/report-month.js +58 -0
  183. package/dist/esm/models/stripe-url-session.d.ts +18 -0
  184. package/dist/esm/models/stripe-url-session.js +16 -0
  185. package/dist/esm/models/voucher.d.ts +41 -0
  186. package/dist/esm/models/voucher.js +51 -0
  187. package/dist/esm/money.d.ts +23 -0
  188. package/dist/esm/money.js +31 -0
  189. package/dist/esm/payments/hobex.d.ts +87 -0
  190. package/dist/esm/payments/hobex.js +162 -0
  191. package/dist/esm/payments/index.d.ts +33 -0
  192. package/dist/esm/payments/index.js +33 -0
  193. package/dist/esm/payments/stripe.d.ts +61 -0
  194. package/dist/esm/payments/stripe.js +153 -0
  195. package/dist/esm/printing/escpos.d.ts +219 -0
  196. package/dist/esm/printing/escpos.js +616 -0
  197. package/dist/esm/printing/index.d.ts +3 -0
  198. package/dist/esm/printing/index.js +3 -0
  199. package/dist/esm/printing/printable.d.ts +27 -0
  200. package/dist/esm/printing/printable.js +87 -0
  201. package/dist/esm/printing/webusb.d.ts +89 -0
  202. package/dist/esm/printing/webusb.js +101 -0
  203. package/dist/esm/react/index.d.ts +46 -0
  204. package/dist/esm/react/index.js +47 -0
  205. package/dist/esm/receipt/discount.d.ts +12 -0
  206. package/dist/esm/receipt/discount.js +51 -0
  207. package/dist/esm/receipt/epos.d.ts +53 -0
  208. package/dist/esm/receipt/epos.js +86 -0
  209. package/dist/esm/receipt/grid.d.ts +47 -0
  210. package/dist/esm/receipt/grid.js +116 -0
  211. package/dist/esm/receipt/index.d.ts +4 -0
  212. package/dist/esm/receipt/index.js +4 -0
  213. package/dist/esm/receipt/layout-escpos.d.ts +35 -0
  214. package/dist/esm/receipt/layout-escpos.js +64 -0
  215. package/dist/esm/receipt/layout.d.ts +180 -0
  216. package/dist/esm/receipt/layout.js +583 -0
  217. package/dist/esm/register/index.d.ts +51 -0
  218. package/dist/esm/register/index.js +51 -0
  219. package/dist/esm/register/pairing.d.ts +248 -0
  220. package/dist/esm/register/pairing.js +270 -0
  221. package/dist/esm/register/session.d.ts +37 -0
  222. package/dist/esm/register/session.js +48 -0
  223. package/dist/esm/vienna-time.d.ts +23 -0
  224. package/dist/esm/vienna-time.js +110 -0
  225. package/fixtures/belege/langer-artikelname.json +43 -0
  226. package/fixtures/belege/null-ausfall.json +41 -0
  227. package/fixtures/belege/null-jahr.json +41 -0
  228. package/fixtures/belege/null-monat.json +41 -0
  229. package/fixtures/belege/null-pruef.json +41 -0
  230. package/fixtures/belege/null-schluss.json +41 -0
  231. package/fixtures/belege/null-start.json +40 -0
  232. package/fixtures/belege/rabattzeilen.json +61 -0
  233. package/fixtures/belege/signaturausfall-verkauf.json +49 -0
  234. package/fixtures/belege/storno-teil.json +48 -0
  235. package/fixtures/belege/storno-voll.json +54 -0
  236. package/fixtures/belege/testkasse-verkauf.json +50 -0
  237. package/fixtures/belege/testsignatur-verkauf.json +50 -0
  238. package/fixtures/belege/training.json +49 -0
  239. package/fixtures/belege/verkauf-bar.json +49 -0
  240. package/fixtures/belege/verkauf-karte.json +49 -0
  241. package/fixtures/belege/verkauf-kleinunternehmer.json +42 -0
  242. package/fixtures/erwartet/langer-artikelname.grid32.txt +25 -0
  243. package/fixtures/erwartet/langer-artikelname.grid48.txt +24 -0
  244. package/fixtures/erwartet/langer-artikelname.lines.json +216 -0
  245. package/fixtures/erwartet/null-ausfall.grid32.txt +28 -0
  246. package/fixtures/erwartet/null-ausfall.grid48.txt +25 -0
  247. package/fixtures/erwartet/null-ausfall.lines.json +220 -0
  248. package/fixtures/erwartet/null-jahr.grid32.txt +29 -0
  249. package/fixtures/erwartet/null-jahr.grid48.txt +25 -0
  250. package/fixtures/erwartet/null-jahr.lines.json +220 -0
  251. package/fixtures/erwartet/null-monat.grid32.txt +28 -0
  252. package/fixtures/erwartet/null-monat.grid48.txt +25 -0
  253. package/fixtures/erwartet/null-monat.lines.json +220 -0
  254. package/fixtures/erwartet/null-pruef.grid32.txt +28 -0
  255. package/fixtures/erwartet/null-pruef.grid48.txt +25 -0
  256. package/fixtures/erwartet/null-pruef.lines.json +220 -0
  257. package/fixtures/erwartet/null-schluss.grid32.txt +28 -0
  258. package/fixtures/erwartet/null-schluss.grid48.txt +25 -0
  259. package/fixtures/erwartet/null-schluss.lines.json +220 -0
  260. package/fixtures/erwartet/null-start.grid32.txt +28 -0
  261. package/fixtures/erwartet/null-start.grid48.txt +25 -0
  262. package/fixtures/erwartet/null-start.lines.json +220 -0
  263. package/fixtures/erwartet/rabattzeilen.grid32.txt +27 -0
  264. package/fixtures/erwartet/rabattzeilen.grid48.txt +26 -0
  265. package/fixtures/erwartet/rabattzeilen.lines.json +286 -0
  266. package/fixtures/erwartet/signaturausfall-verkauf.grid32.txt +28 -0
  267. package/fixtures/erwartet/signaturausfall-verkauf.grid48.txt +26 -0
  268. package/fixtures/erwartet/signaturausfall-verkauf.lines.json +266 -0
  269. package/fixtures/erwartet/storno-teil.grid32.txt +27 -0
  270. package/fixtures/erwartet/storno-teil.grid48.txt +26 -0
  271. package/fixtures/erwartet/storno-teil.lines.json +237 -0
  272. package/fixtures/erwartet/storno-voll.grid32.txt +29 -0
  273. package/fixtures/erwartet/storno-voll.grid48.txt +28 -0
  274. package/fixtures/erwartet/storno-voll.lines.json +277 -0
  275. package/fixtures/erwartet/testkasse-verkauf.grid32.txt +28 -0
  276. package/fixtures/erwartet/testkasse-verkauf.grid48.txt +27 -0
  277. package/fixtures/erwartet/testkasse-verkauf.lines.json +270 -0
  278. package/fixtures/erwartet/testsignatur-verkauf.grid32.txt +30 -0
  279. package/fixtures/erwartet/testsignatur-verkauf.grid48.txt +27 -0
  280. package/fixtures/erwartet/testsignatur-verkauf.lines.json +270 -0
  281. package/fixtures/erwartet/training.grid32.txt +33 -0
  282. package/fixtures/erwartet/training.grid48.txt +30 -0
  283. package/fixtures/erwartet/training.lines.json +277 -0
  284. package/fixtures/erwartet/verkauf-bar.grid32.txt +25 -0
  285. package/fixtures/erwartet/verkauf-bar.grid48.txt +24 -0
  286. package/fixtures/erwartet/verkauf-bar.lines.json +256 -0
  287. package/fixtures/erwartet/verkauf-karte.grid32.txt +25 -0
  288. package/fixtures/erwartet/verkauf-karte.grid48.txt +24 -0
  289. package/fixtures/erwartet/verkauf-karte.lines.json +256 -0
  290. package/fixtures/erwartet/verkauf-kleinunternehmer.grid32.txt +26 -0
  291. package/fixtures/erwartet/verkauf-kleinunternehmer.grid48.txt +25 -0
  292. package/fixtures/erwartet/verkauf-kleinunternehmer.lines.json +226 -0
  293. package/fixtures/manifest.json +107 -0
  294. package/package.json +135 -0
@@ -0,0 +1,51 @@
1
+ import type { Receipt } from './receipt.js';
2
+ /**
3
+ * Storno-Metadaten — Zwilling von `functions/storno-core.js`.
4
+ *
5
+ * Ein Storno ist ein eigener, signierter Beleg vom Typ `cancellation` mit
6
+ * negativen Betraegen. Was NICHT signiert ist und hier als Metadaten laeuft:
7
+ * der Bezug zum Original (`cancellationOf`, `cancellationReason` am
8
+ * Storno-Beleg) und die Liste der Stornos am Original (`cancellations`), aus
9
+ * der sich die Restmengen ergeben.
10
+ */
11
+ /** Grund-Katalog: Codes wie im Backend, Anzeigetext fuer Bon und Bedienung. */
12
+ export declare const CANCELLATION_REASONS: Readonly<{
13
+ readonly fehleingabe: "Fehleingabe";
14
+ readonly kunde_storniert: "Kunde hat storniert";
15
+ readonly falsche_zahlart: "Falsche Zahlart";
16
+ readonly doppelt_erfasst: "Doppelt erfasst";
17
+ readonly sonstiges: "Sonstiges";
18
+ }>;
19
+ export type CancellationReason = keyof typeof CANCELLATION_REASONS;
20
+ export declare function isCancellationReason(value: unknown): value is CancellationReason;
21
+ /** Bezug eines Storno-Belegs auf sein Original. */
22
+ export interface CancellationOf {
23
+ receiptId: string;
24
+ fullReceiptId: string | null;
25
+ }
26
+ /** Eine stornierte Position: Index im Original und Menge. */
27
+ export interface CancellationItem {
28
+ index: number;
29
+ quantity: number;
30
+ }
31
+ /**
32
+ * Eintrag in `cancellations[]` am Original. `pending` = Reservierung, die
33
+ * das Backend vor der Buchung setzt und danach ersetzt; sie zaehlt fuer die
34
+ * Restmengen nur, solange sie frisch ist (siehe [remainingQuantities]).
35
+ */
36
+ export interface Cancellation {
37
+ receiptId?: string;
38
+ pending?: boolean;
39
+ at: number;
40
+ by: string | null;
41
+ note: string | null;
42
+ items: CancellationItem[];
43
+ }
44
+ /** Ab wann eine liegengebliebene Reservierung nicht mehr zaehlt (wie im Backend). */
45
+ export declare const CANCELLATION_RESERVATION_MS = 120000;
46
+ /**
47
+ * Restmenge je Position eines Belegs — Belegmenge minus alles, was storniert
48
+ * oder frisch reserviert ist; nie unter null. Fuer den Storno-Dialog der Kasse
49
+ * (Reste anzeigen, bevor der Server gefragt wird). Die Wahrheit hat der Server.
50
+ */
51
+ export declare function remainingQuantities(receipt: Receipt, nowMs?: number): number[];
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Storno-Metadaten — Zwilling von `functions/storno-core.js`.
3
+ *
4
+ * Ein Storno ist ein eigener, signierter Beleg vom Typ `cancellation` mit
5
+ * negativen Betraegen. Was NICHT signiert ist und hier als Metadaten laeuft:
6
+ * der Bezug zum Original (`cancellationOf`, `cancellationReason` am
7
+ * Storno-Beleg) und die Liste der Stornos am Original (`cancellations`), aus
8
+ * der sich die Restmengen ergeben.
9
+ */
10
+ /** Grund-Katalog: Codes wie im Backend, Anzeigetext fuer Bon und Bedienung. */
11
+ export const CANCELLATION_REASONS = Object.freeze({
12
+ fehleingabe: 'Fehleingabe',
13
+ kunde_storniert: 'Kunde hat storniert',
14
+ falsche_zahlart: 'Falsche Zahlart',
15
+ doppelt_erfasst: 'Doppelt erfasst',
16
+ sonstiges: 'Sonstiges',
17
+ });
18
+ export function isCancellationReason(value) {
19
+ return typeof value === 'string' && Object.prototype.hasOwnProperty.call(CANCELLATION_REASONS, value);
20
+ }
21
+ /** Ab wann eine liegengebliebene Reservierung nicht mehr zaehlt (wie im Backend). */
22
+ export const CANCELLATION_RESERVATION_MS = 120_000;
23
+ /**
24
+ * Restmenge je Position eines Belegs — Belegmenge minus alles, was storniert
25
+ * oder frisch reserviert ist; nie unter null. Fuer den Storno-Dialog der Kasse
26
+ * (Reste anzeigen, bevor der Server gefragt wird). Die Wahrheit hat der Server.
27
+ */
28
+ export function remainingQuantities(receipt, nowMs = Date.now()) {
29
+ const rest = receipt.items.map((item) => item.quantity);
30
+ for (const eintrag of receipt.cancellations ?? []) {
31
+ if (eintrag.pending === true && eintrag.at < nowMs - CANCELLATION_RESERVATION_MS)
32
+ continue;
33
+ for (const pos of eintrag.items) {
34
+ if (Number.isInteger(pos.index) && pos.index >= 0 && pos.index < rest.length) {
35
+ rest[pos.index] = Math.max(0, (rest[pos.index] ?? 0) - pos.quantity);
36
+ }
37
+ }
38
+ }
39
+ return rest;
40
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Kasse — die Antwortform von `listMyCashregisters` (functions/index.js).
3
+ *
4
+ * Das Dart-Vorbild (`Cashregister` in kasseneck_api/lib/models/cashregister.dart)
5
+ * liest das **Firestore-Dokument** direkt ueber das `cloud_firestore`-SDK und
6
+ * kommt deshalb an `token` und `aes_key`. Dieses Paket spricht das Backend
7
+ * ausschliesslich ueber die HTTPS-Endpunkte, und die geben beides nicht her:
8
+ *
9
+ * - **`aes_key` steht in dieser Antwort ueberhaupt nicht** (nur im
10
+ * Admin-Export). Ein Feld dafuer versprach hier einen `string` und lieferte
11
+ * `undefined` — deshalb gibt es keines mehr.
12
+ * - **`token` ist fuer Kassen-Benutzer bewusst `null`**: im Browser traegt die
13
+ * Sitzung die Identitaet, und ein einmal ausgelieferter Kassen-Token liesse
14
+ * sich ohne Sitzung und ohne PIN weiterverwenden (so steht es im Backend an
15
+ * der Stelle selbst).
16
+ *
17
+ * `create_time` kommt aus `isoTs(...)` und ist **`null`**, wenn das Dokument
18
+ * keinen Zeitstempel traegt. Aus `null` wird hier kein Zeitpunkt: `new Date(null)`
19
+ * ergaebe still den 1.1.1970, und ein erfundenes Datum ist schlechter als ein
20
+ * fehlendes.
21
+ *
22
+ * Aus demselben Grund fehlt `userId`: das Dart-Vorbild traegt es, weil es den
23
+ * Firestore-**Pfad** kennt (`users/{uid}/cashregisters/{id}`). In dieser
24
+ * Antwort steht es nicht, und ein Kassen-Benutzer erfaehrt die Kennung seines
25
+ * Betriebs bewusst nie — sie steckt allein im Token.
26
+ */
27
+ export interface Cashregister {
28
+ id: string;
29
+ /** Anzeigename der Kasse, sofern gepflegt. */
30
+ label?: string;
31
+ /** Freie Beschreibung, sofern gepflegt. */
32
+ description?: string;
33
+ /** Anlagezeitpunkt; fehlt, wenn die Antwort keinen lesbaren traegt. */
34
+ createTime?: Date;
35
+ /** Kassen-Token; fuer Kassen-Benutzer nie enthalten (siehe Klassenkommentar). */
36
+ token?: string;
37
+ /** Zugeordnete Signatureinheit. */
38
+ signatureId?: string;
39
+ onboarding: CashregisterOnboarding;
40
+ }
41
+ /**
42
+ * Stand der Inbetriebnahme (RKSV): Kasse bei FinanzOnline registriert,
43
+ * Startbeleg erzeugt, Startbeleg uebermittelt. Die drei Kennzeichen entscheiden
44
+ * in der Browser-Kasse, ob ueberhaupt schon kassiert werden darf.
45
+ */
46
+ export interface CashregisterOnboarding {
47
+ cashboxRegistered: boolean;
48
+ startbelegCreated: boolean;
49
+ startbelegTransmitted: boolean;
50
+ cashboxRegisteredAt?: Date;
51
+ startbelegCreatedAt?: Date;
52
+ startbelegTransmittedAt?: Date;
53
+ }
54
+ /** Nutzlast-Form, die dieses Paket liest — die Feldnamen von `listMyCashregisters`. */
55
+ export interface CashregisterPayload {
56
+ id?: string | null;
57
+ label?: string | null;
58
+ description?: string | null;
59
+ create_time?: string | null;
60
+ signature_id?: string | null;
61
+ token?: string | null;
62
+ onboarding?: CashregisterOnboardingPayload | null;
63
+ }
64
+ export interface CashregisterOnboardingPayload {
65
+ cashbox_registered?: boolean | null;
66
+ startbeleg_created?: boolean | null;
67
+ startbeleg_transmitted?: boolean | null;
68
+ cashbox_registered_at?: string | null;
69
+ startbeleg_created_at?: string | null;
70
+ startbeleg_transmitted_at?: string | null;
71
+ }
72
+ /**
73
+ * Liest eine Kasse aus der Antwort. `id` gewinnt aus der Nutzlast, faellt aber
74
+ * auf den uebergebenen Wert zurueck — die Liste fuehrt die Dokument-ID mit,
75
+ * ein einzeln gelesenes Dokument nicht.
76
+ */
77
+ export declare function fromCashregisterPayload(payload: CashregisterPayload, id: string): Cashregister;
@@ -0,0 +1,50 @@
1
+ import { parseServerTimeStamp } from '../vienna-time.js';
2
+ /**
3
+ * Liest eine Kasse aus der Antwort. `id` gewinnt aus der Nutzlast, faellt aber
4
+ * auf den uebergebenen Wert zurueck — die Liste fuehrt die Dokument-ID mit,
5
+ * ein einzeln gelesenes Dokument nicht.
6
+ */
7
+ export function fromCashregisterPayload(payload, id) {
8
+ const ob = payload.onboarding ?? {};
9
+ return {
10
+ id: payload.id ?? id,
11
+ ...(payload.label ? { label: payload.label } : {}),
12
+ ...(payload.description ? { description: payload.description } : {}),
13
+ ...zeitfeld('createTime', payload.create_time),
14
+ ...(payload.token ? { token: payload.token } : {}),
15
+ ...(payload.signature_id ? { signatureId: payload.signature_id } : {}),
16
+ onboarding: {
17
+ cashboxRegistered: ob.cashbox_registered === true,
18
+ startbelegCreated: ob.startbeleg_created === true,
19
+ startbelegTransmitted: ob.startbeleg_transmitted === true,
20
+ ...zeitfeld('cashboxRegisteredAt', ob.cashbox_registered_at),
21
+ ...zeitfeld('startbelegCreatedAt', ob.startbeleg_created_at),
22
+ ...zeitfeld('startbelegTransmittedAt', ob.startbeleg_transmitted_at),
23
+ },
24
+ };
25
+ }
26
+ /**
27
+ * Ein Zeitfeld, das es nur gibt, wenn die Nutzlast einen lesbaren Zeitstempel
28
+ * traegt. `null` (der Normalfall aus `isoTs`) und unlesbarer Unsinn ergeben
29
+ * **kein** Feld statt eines erfundenen Zeitpunkts — die Kassenliste soll sich
30
+ * auch dann anzeigen lassen, wenn ein einzelner Eintrag ein kaputtes Datum
31
+ * fuehrt (dieselbe tolerante Leserichtung wie beim Enum-Lesen).
32
+ */
33
+ function zeitfeld(name, roh) {
34
+ const wert = zeitpunkt(roh);
35
+ return (wert === undefined ? {} : { [name]: wert });
36
+ }
37
+ function zeitpunkt(roh) {
38
+ if (typeof roh !== 'string' || roh.trim() === '') {
39
+ return undefined;
40
+ }
41
+ try {
42
+ // Ueber parseServerTimeStamp und nie ueber `new Date(text)`: ein
43
+ // offsetloser Zeitstempel waere sonst die lokale Zeit des ausfuehrenden
44
+ // Rechners (siehe ../vienna-time.ts).
45
+ return parseServerTimeStamp(roh);
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ }
@@ -0,0 +1,26 @@
1
+ import { VatRate } from '../enums/index.js';
2
+ /**
3
+ * Loest einen Enum-Eintrag anhand seines Nutzlast-Schluessels auf (z. B.
4
+ * `receiptType: 'standard'` — bei den mit `defineEnum()` gebauten Enums ist
5
+ * der Objekt-Schluessel selbst die Nutzlast).
6
+ *
7
+ * Nur fuer den **Schreibpfad**: bevor dieses Paket selbst einen Wert nach
8
+ * aussen traegt, muss er bekannt sein — ein unbekannter Schluessel wirft.
9
+ * Fuer den Lesepfad (Daten, die vom Backend hereinkommen) siehe
10
+ * [readEnumKey]: dort darf ein einzelner unbekannter Wert nicht die ganze
11
+ * Belegliste zum Absturz bringen.
12
+ */
13
+ export declare function requireEnumKey<T extends Record<string, unknown>>(enumObj: T, key: string, label: string): T[keyof T];
14
+ /**
15
+ * Lesepfad-Pendant zu [requireEnumKey]: ein unbekannter Schluessel (z. B. ein
16
+ * neuer Belegtyp oder eine neue Zahlungsart, die dieses Paket noch nicht
17
+ * kennt) wirft nicht und wird auch nicht still zu `undefined` — der rohe
18
+ * Nutzlast-Schluessel bleibt als String erhalten. Ein Aufrufer, der eine
19
+ * Belegliste anzeigt, kann so alle Positionen weiterlesen; nur die unbekannte
20
+ * bleibt (erkennbar) unaufgeloest.
21
+ */
22
+ export declare function readEnumKey<T extends Record<string, unknown>>(enumObj: T, key: string): T[keyof T] | string;
23
+ /** Schreibpfad: loest einen Steuersatz anhand seines `rate`-Werts auf, wirft bei unbekanntem Satz. */
24
+ export declare function requireVatRateByRate(rate: number): VatRate;
25
+ /** Lesepfad: unbekannter Satz bleibt als roher `rate`-Wert erhalten statt zu werfen oder `undefined` zu werden. */
26
+ export declare function readVatRateByRate(rate: number): VatRate | number;
@@ -0,0 +1,44 @@
1
+ import { VatRate } from '../enums/index.js';
2
+ /**
3
+ * Loest einen Enum-Eintrag anhand seines Nutzlast-Schluessels auf (z. B.
4
+ * `receiptType: 'standard'` — bei den mit `defineEnum()` gebauten Enums ist
5
+ * der Objekt-Schluessel selbst die Nutzlast).
6
+ *
7
+ * Nur fuer den **Schreibpfad**: bevor dieses Paket selbst einen Wert nach
8
+ * aussen traegt, muss er bekannt sein — ein unbekannter Schluessel wirft.
9
+ * Fuer den Lesepfad (Daten, die vom Backend hereinkommen) siehe
10
+ * [readEnumKey]: dort darf ein einzelner unbekannter Wert nicht die ganze
11
+ * Belegliste zum Absturz bringen.
12
+ */
13
+ export function requireEnumKey(enumObj, key, label) {
14
+ if (!Object.prototype.hasOwnProperty.call(enumObj, key)) {
15
+ throw new Error(`${label}: unbekannter Schluessel "${key}" in der Nutzlast`);
16
+ }
17
+ return enumObj[key];
18
+ }
19
+ /**
20
+ * Lesepfad-Pendant zu [requireEnumKey]: ein unbekannter Schluessel (z. B. ein
21
+ * neuer Belegtyp oder eine neue Zahlungsart, die dieses Paket noch nicht
22
+ * kennt) wirft nicht und wird auch nicht still zu `undefined` — der rohe
23
+ * Nutzlast-Schluessel bleibt als String erhalten. Ein Aufrufer, der eine
24
+ * Belegliste anzeigt, kann so alle Positionen weiterlesen; nur die unbekannte
25
+ * bleibt (erkennbar) unaufgeloest.
26
+ */
27
+ export function readEnumKey(enumObj, key) {
28
+ return Object.prototype.hasOwnProperty.call(enumObj, key) ? enumObj[key] : key;
29
+ }
30
+ function findVatRate(rate) {
31
+ return Object.values(VatRate).find((v) => v.rate === rate);
32
+ }
33
+ /** Schreibpfad: loest einen Steuersatz anhand seines `rate`-Werts auf, wirft bei unbekanntem Satz. */
34
+ export function requireVatRateByRate(rate) {
35
+ const eintrag = findVatRate(rate);
36
+ if (!eintrag) {
37
+ throw new Error(`Steuersatz: unbekannter Satz "${rate}" in der Nutzlast`);
38
+ }
39
+ return eintrag;
40
+ }
41
+ /** Lesepfad: unbekannter Satz bleibt als roher `rate`-Wert erhalten statt zu werfen oder `undefined` zu werden. */
42
+ export function readVatRateByRate(rate) {
43
+ return findVatRate(rate) ?? rate;
44
+ }
@@ -0,0 +1,63 @@
1
+ import { CreditCardProvider } from '../enums/index.js';
2
+ /**
3
+ * Hobex-Kartenzahlungsbeleg — Zwilling von `HobexReceipt` in
4
+ * kasseneck_api/lib/models/hobex_receipt.dart.
5
+ *
6
+ * `amount`/`tip` kommen vom Hobex-Terminal als Euro-Gleitkommazahl ueber die
7
+ * Leitung (Terminal-API, nicht das Kasseneck-Backend) — das Nutzlast-Format
8
+ * bleibt deshalb bewusst Euro (siehe [toHobexReceiptPayload]/
9
+ * [fromHobexReceiptPayload]), intern wird ab hier exakt in Cent gefuehrt.
10
+ *
11
+ * Nur der Cloud-API-Pfad (`fromJson` im Dart-Vorbild) ist Teil dieses Pakets;
12
+ * das lokale HPS-Terminal (`fromHps`, TCP-Anbindung an ein physisches Geraet)
13
+ * ist wie SumUp/myPOS eine Android/Desktop-Geraete-Anbindung, die ein
14
+ * Browser-/Node-Paket nicht bedienen kann.
15
+ */
16
+ export interface HobexReceipt {
17
+ transactionId: string;
18
+ tid: string;
19
+ receipt: string;
20
+ approvalCode: string;
21
+ reference?: string;
22
+ /** Normalisiert wie im Dart-Vorbild: `"YYYY-MM-DD HH:mm:ss"` (Bruchteil und `T` entfernt). */
23
+ transactionDate: string;
24
+ cardNumber: string;
25
+ cardExpiry: string;
26
+ brand: string;
27
+ cardIssuer: string;
28
+ responseCode: string;
29
+ transactionType: string;
30
+ currency: string;
31
+ amountCents: number;
32
+ tipCents: number;
33
+ cvm: string;
34
+ creditCardProvider: CreditCardProvider;
35
+ }
36
+ export interface HobexReceiptPayload {
37
+ transactionId: string;
38
+ tid: string;
39
+ receipt: string;
40
+ approvalCode: string;
41
+ reference: string | null | undefined;
42
+ transactionDate: string;
43
+ cardNumber: string;
44
+ cardExpiry: string;
45
+ brand: string;
46
+ cardIssuer: string;
47
+ responseCode: string;
48
+ transactionType: string;
49
+ currency: string;
50
+ amount: number;
51
+ tip: number;
52
+ cvm: string | number;
53
+ }
54
+ export declare function toHobexReceiptPayload(beleg: HobexReceipt): HobexReceiptPayload;
55
+ export declare function fromHobexReceiptPayload(payload: HobexReceiptPayload): HobexReceipt;
56
+ /**
57
+ * Wandelt den Beleg in die `cardPaymentData`-Map, die auf dem Kasseneck-Beleg
58
+ * landet (siehe [Receipt.cardPaymentData]). Bei HPS-Zahlungen kommen weitere
59
+ * Felder dazu, die nur das lokale Terminal liefert.
60
+ */
61
+ export declare function hobexReceiptToCardPaymentData(beleg: HobexReceipt): Record<string, string>;
62
+ /** Kartenzahlung erfordert eine Unterschrift (CVM-Code `"1"`). */
63
+ export declare function hobexReceiptNeedsSignature(beleg: HobexReceipt): boolean;
@@ -0,0 +1,80 @@
1
+ import { CreditCardProvider } from '../enums/index.js';
2
+ import { centsToEuro } from '../money.js';
3
+ export function toHobexReceiptPayload(beleg) {
4
+ return {
5
+ transactionId: beleg.transactionId,
6
+ tid: beleg.tid,
7
+ receipt: beleg.receipt,
8
+ approvalCode: beleg.approvalCode,
9
+ reference: beleg.reference ?? null,
10
+ transactionDate: beleg.transactionDate,
11
+ cardNumber: beleg.cardNumber,
12
+ cardExpiry: beleg.cardExpiry,
13
+ brand: beleg.brand,
14
+ cardIssuer: beleg.cardIssuer,
15
+ responseCode: beleg.responseCode,
16
+ transactionType: beleg.transactionType,
17
+ currency: beleg.currency,
18
+ // Euro-Umwandlung nur hier, an der Terminal-API-Grenze — siehe Kommentar oben.
19
+ amount: centsToEuro(beleg.amountCents),
20
+ tip: centsToEuro(beleg.tipCents),
21
+ cvm: beleg.cvm,
22
+ };
23
+ }
24
+ export function fromHobexReceiptPayload(payload) {
25
+ return {
26
+ transactionId: payload.transactionId,
27
+ tid: payload.tid,
28
+ receipt: payload.receipt,
29
+ approvalCode: payload.approvalCode,
30
+ reference: payload.reference ?? undefined,
31
+ // Kappt Bruchteilssekunden/Offset und ersetzt "T" durch ein Leerzeichen,
32
+ // exakt wie im Dart-Vorbild (transactionDate.split('.')[0].replaceAll('T', ' ')).
33
+ transactionDate: payload.transactionDate.split('.')[0].split('T').join(' '),
34
+ cardNumber: payload.cardNumber,
35
+ cardExpiry: payload.cardExpiry,
36
+ brand: payload.brand,
37
+ cardIssuer: payload.cardIssuer,
38
+ responseCode: payload.responseCode,
39
+ transactionType: payload.transactionType,
40
+ currency: payload.currency,
41
+ amountCents: Math.round((payload.amount ?? 0) * 100),
42
+ tipCents: Math.round((payload.tip ?? 0) * 100),
43
+ cvm: String(payload.cvm),
44
+ // Die Cloud-API-Nutzlast traegt keinen eigenen Provider-Schluessel — der
45
+ // Provider ergibt sich aus dem Transportweg (Cloud vs. HPS), nicht aus
46
+ // dem JSON. Das Dart-Vorbild setzt ihn in `fromJson` deshalb ebenfalls
47
+ // nicht, sondern belaesst den Konstruktor-Default.
48
+ creditCardProvider: CreditCardProvider.hobexCloudApi,
49
+ };
50
+ }
51
+ /**
52
+ * Wandelt den Beleg in die `cardPaymentData`-Map, die auf dem Kasseneck-Beleg
53
+ * landet (siehe [Receipt.cardPaymentData]). Bei HPS-Zahlungen kommen weitere
54
+ * Felder dazu, die nur das lokale Terminal liefert.
55
+ */
56
+ export function hobexReceiptToCardPaymentData(beleg) {
57
+ const data = {
58
+ transactionId: beleg.transactionId,
59
+ date: beleg.transactionDate,
60
+ tid: beleg.tid,
61
+ no: beleg.receipt,
62
+ type: beleg.transactionType,
63
+ cardBrand: beleg.brand,
64
+ cardNumber: beleg.cardNumber,
65
+ responseCode: beleg.responseCode,
66
+ cvm: beleg.cvm,
67
+ };
68
+ if (beleg.creditCardProvider === CreditCardProvider.hobexHps) {
69
+ data.approvalCode = beleg.approvalCode;
70
+ data.cardExpiry = beleg.cardExpiry;
71
+ data.cardIssuer = beleg.cardIssuer;
72
+ data.amount = centsToEuro(beleg.amountCents).toFixed(2);
73
+ data.currency = beleg.currency;
74
+ }
75
+ return data;
76
+ }
77
+ /** Kartenzahlung erfordert eine Unterschrift (CVM-Code `"1"`). */
78
+ export function hobexReceiptNeedsSignature(beleg) {
79
+ return beleg.cvm === '1';
80
+ }
@@ -0,0 +1,10 @@
1
+ export { type ReceiptItem, type ReceiptItemPayload, type ReceiptItemPayloadRead, toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, } from './receipt-item.js';
2
+ export { type Voucher, type VoucherPayload, toVoucherPayload, fromVoucherPayload, voucherIsValid } from './voucher.js';
3
+ export { type Receipt, type ReceiptPayload, type ReceiptPayloadRead, toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, } from './receipt.js';
4
+ export { type CancellationOf, type CancellationItem, type Cancellation, type CancellationReason, CANCELLATION_REASONS, CANCELLATION_RESERVATION_MS, isCancellationReason, remainingQuantities, } from './cancellation.js';
5
+ export { type ReceiptCompany, type ReceiptCompanyPayload, fromReceiptCompanyPayload, receiptCompanyTaxInfo, } from './receipt-company.js';
6
+ export { type Cashregister, type CashregisterOnboarding, type CashregisterPayload, type CashregisterOnboardingPayload, fromCashregisterPayload, } from './cashregister.js';
7
+ export { type ReceiptSummary, type ReceiptSummaryPayload, fromReceiptSummaryPayload, type ZeroKind, ZERO_KINDS, istZeroKind } from './receipt-summary.js';
8
+ export { type ReportMonth, reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, } from './report-month.js';
9
+ export { type StripeUrlSession, type StripeUrlSessionPayload, toStripeUrlSessionPayload, fromStripeUrlSessionPayload, } from './stripe-url-session.js';
10
+ export { type HobexReceipt, type HobexReceiptPayload, toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './hobex-receipt.js';
@@ -0,0 +1,10 @@
1
+ export { toReceiptItemPayload, fromReceiptItemPayload, receiptItemTotalCents, receiptItemIsValid, negateReceiptItem, } from './receipt-item.js';
2
+ export { toVoucherPayload, fromVoucherPayload, voucherIsValid } from './voucher.js';
3
+ export { toReceiptPayload, fromReceiptPayload, receiptSubSumCents, receiptSumCents, } from './receipt.js';
4
+ export { CANCELLATION_REASONS, CANCELLATION_RESERVATION_MS, isCancellationReason, remainingQuantities, } from './cancellation.js';
5
+ export { fromReceiptCompanyPayload, receiptCompanyTaxInfo, } from './receipt-company.js';
6
+ export { fromCashregisterPayload, } from './cashregister.js';
7
+ export { fromReceiptSummaryPayload, ZERO_KINDS, istZeroKind } from './receipt-summary.js';
8
+ export { reportMonthFromDate, previousReportMonth, nextReportMonth, reportMonthKey, reportMonthReadable, } from './report-month.js';
9
+ export { toStripeUrlSessionPayload, fromStripeUrlSessionPayload, } from './stripe-url-session.js';
10
+ export { toHobexReceiptPayload, fromHobexReceiptPayload, hobexReceiptToCardPaymentData, hobexReceiptNeedsSignature, } from './hobex-receipt.js';
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Firmen- und Druckdaten eines Belegs — Zwilling der Metadaten von
3
+ * `KasseneckReceipt` in kasseneck_api/lib/models/kasseneck_receipt.dart
4
+ * (`toMetadataJson`/`fromMetadata`).
5
+ *
6
+ * Das Backend liefert sie **neben** dem Beleg: `getReceipt` und `createReceipt`
7
+ * legen Firma, Anschrift, Steuernummer, UID, Fusszeilen, Logo-Adresse und das
8
+ * Kleinunternehmer-Kennzeichen direkt in die Antwort (functions/index.js).
9
+ * Zum RKSV-Kernbeleg gehoeren sie nicht — sie betreffen ausschliesslich die
10
+ * Darstellung. Deshalb stehen sie hier als eigenes Modell und nicht in
11
+ * [Receipt]: derselbe Beleg, spaeter erneut gedruckt, kann eine
12
+ * zwischenzeitlich geaenderte Fusszeile tragen.
13
+ *
14
+ * **Gotcha:** `thanks_message` liefert nur `getReceipt`, `createReceipt`
15
+ * nicht (functions/index.js, Antwortbloecke von `getReceipt` bzw.
16
+ * `createReceipt`). Das Feld ist deshalb kein Pflichtfeld der Nutzlast; ohne
17
+ * es bleibt [thanksMessage] leer.
18
+ */
19
+ export interface ReceiptCompany {
20
+ companyName: string;
21
+ street: string;
22
+ zip: string;
23
+ city: string;
24
+ phone: string;
25
+ /** UID (Umsatzsteuer-Identifikationsnummer); fehlt bei Kleinunternehmern. */
26
+ uid?: string;
27
+ /** Steuernummer des Finanzamts. */
28
+ taxnr: string;
29
+ /** Kleinunternehmer nach § 6 Abs 1 Z 27 UStG (keine USt im Ausweis). */
30
+ isSmallBusiness: boolean;
31
+ footer1: string;
32
+ footer2: string;
33
+ footer3?: string;
34
+ footer4?: string;
35
+ /** Adresse des Firmenlogos; dieses Paket laedt und zeichnet es nicht. */
36
+ logoUrl?: string;
37
+ /** Dankestext am Belegende, je Zeile ein Eintrag. */
38
+ thanksMessage: string[];
39
+ /** Kreiseck-Branding am Belegende (Firestore-Flag `branding.kreiseck_logo`). */
40
+ showKreiseckLogo: boolean;
41
+ }
42
+ /**
43
+ * Nutzlast-Form, die dieses Paket **liest** — die Feldnamen der Backend-
44
+ * Antwort. Alles ist optional: ein Kundendokument ohne gepflegte Anschrift
45
+ * oder Fusszeile liefert die Felder als `null` oder gar nicht, und ein
46
+ * fehlender Firmenname darf keinen Belegdruck verhindern.
47
+ */
48
+ export interface ReceiptCompanyPayload {
49
+ company?: string | null;
50
+ street?: string | null;
51
+ zip?: string | null;
52
+ city?: string | null;
53
+ phone?: string | null;
54
+ uid?: string | null;
55
+ taxnr?: string | null;
56
+ is_small_business?: boolean | null;
57
+ footer1?: string | null;
58
+ footer2?: string | null;
59
+ footer3?: string | null;
60
+ footer4?: string | null;
61
+ logo_url?: string | null;
62
+ /** Nur `getReceipt` liefert dieses Feld — siehe Modulkommentar. */
63
+ thanks_message?: string | null;
64
+ kreiseck_logo?: boolean | null;
65
+ }
66
+ export declare function fromReceiptCompanyPayload(payload: ReceiptCompanyPayload): ReceiptCompany;
67
+ /**
68
+ * Steuerangabe im Belegkopf — Zwilling von `KasseneckReceipt.taxInfo`: die UID,
69
+ * wenn es eine gibt, sonst die Steuernummer.
70
+ */
71
+ export declare function receiptCompanyTaxInfo(company: ReceiptCompany): string;
@@ -0,0 +1,48 @@
1
+ /** Leere Zeichenkette statt `undefined` — siehe [ReceiptCompanyPayload]. */
2
+ const text = (wert) => (typeof wert === 'string' ? wert : '');
3
+ /**
4
+ * Zerlegt den Dankestext in Zeilen. Das Vorbild trennt an der **Zeichenfolge**
5
+ * `\n` (Backslash + n), nicht am Zeilenumbruch — so legt es die Flutter-Seite
6
+ * auch wieder ab (`toMetadataJson`). Ein echter Zeilenumbruch wird zusaetzlich
7
+ * getrennt: er kommt aus einem mehrzeiligen Eingabefeld im Panel und wuerde
8
+ * sonst als Umbruch **innerhalb** einer Layout-Zeile weiterwandern.
9
+ */
10
+ function zeilen(wert) {
11
+ if (typeof wert !== 'string' || wert.length === 0) {
12
+ return [];
13
+ }
14
+ return wert.split(/\\n|\r?\n/);
15
+ }
16
+ export function fromReceiptCompanyPayload(payload) {
17
+ const firma = {
18
+ companyName: text(payload.company),
19
+ street: text(payload.street),
20
+ zip: text(payload.zip),
21
+ city: text(payload.city),
22
+ phone: text(payload.phone),
23
+ taxnr: text(payload.taxnr),
24
+ isSmallBusiness: payload.is_small_business === true,
25
+ footer1: text(payload.footer1),
26
+ footer2: text(payload.footer2),
27
+ thanksMessage: zeilen(payload.thanks_message),
28
+ showKreiseckLogo: payload.kreiseck_logo === true,
29
+ };
30
+ // Die vier Kann-Felder bleiben weg, wenn sie leer sind — ein leerer String
31
+ // in `footer3` erzeugte sonst eine leere Zeile auf dem Beleg.
32
+ if (payload.uid)
33
+ firma.uid = payload.uid;
34
+ if (payload.footer3)
35
+ firma.footer3 = payload.footer3;
36
+ if (payload.footer4)
37
+ firma.footer4 = payload.footer4;
38
+ if (payload.logo_url)
39
+ firma.logoUrl = payload.logo_url;
40
+ return firma;
41
+ }
42
+ /**
43
+ * Steuerangabe im Belegkopf — Zwilling von `KasseneckReceipt.taxInfo`: die UID,
44
+ * wenn es eine gibt, sonst die Steuernummer.
45
+ */
46
+ export function receiptCompanyTaxInfo(company) {
47
+ return company.uid !== undefined && company.uid.length > 0 ? company.uid : company.taxnr;
48
+ }