@kreiseck/kasseneck-api 1.16.0 → 1.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/client/receipts.js +8 -0
  3. package/dist/cjs/client/reports.d.ts +10 -9
  4. package/dist/cjs/client/reports.js +10 -9
  5. package/dist/cjs/index.d.ts +1 -1
  6. package/dist/cjs/models/voucher.d.ts +46 -4
  7. package/dist/cjs/models/voucher.js +58 -11
  8. package/dist/cjs/pos/artikel.d.ts +9 -0
  9. package/dist/cjs/pos/artikel.js +1 -0
  10. package/dist/cjs/pos/gutschein.d.ts +107 -2
  11. package/dist/cjs/pos/gutschein.js +124 -4
  12. package/dist/cjs/pos/index.d.ts +1 -1
  13. package/dist/cjs/pos/index.js +7 -3
  14. package/dist/cjs/pos/texte.d.ts +39 -0
  15. package/dist/cjs/pos/texte.js +22 -0
  16. package/dist/cjs/receipt/due.d.ts +20 -9
  17. package/dist/cjs/receipt/due.js +1 -0
  18. package/dist/cjs/receipt/gutschein-plan.d.ts +23 -7
  19. package/dist/cjs/receipt/gutschein-plan.js +67 -2
  20. package/dist/cjs/receipt/index.d.ts +1 -1
  21. package/dist/cjs/stored/draht.js +10 -2
  22. package/dist/cjs/stored/vokabular.d.ts +1 -1
  23. package/dist/cjs/stored/vokabular.js +84 -3
  24. package/dist/cjs/version.d.ts +1 -1
  25. package/dist/cjs/version.js +1 -1
  26. package/dist/esm/client/receipts.js +8 -0
  27. package/dist/esm/client/reports.d.ts +10 -9
  28. package/dist/esm/client/reports.js +10 -9
  29. package/dist/esm/index.d.ts +1 -1
  30. package/dist/esm/models/voucher.d.ts +46 -4
  31. package/dist/esm/models/voucher.js +56 -11
  32. package/dist/esm/pos/artikel.d.ts +9 -0
  33. package/dist/esm/pos/artikel.js +1 -0
  34. package/dist/esm/pos/gutschein.d.ts +107 -2
  35. package/dist/esm/pos/gutschein.js +123 -3
  36. package/dist/esm/pos/index.d.ts +1 -1
  37. package/dist/esm/pos/index.js +2 -2
  38. package/dist/esm/pos/texte.d.ts +39 -0
  39. package/dist/esm/pos/texte.js +22 -0
  40. package/dist/esm/receipt/due.d.ts +20 -9
  41. package/dist/esm/receipt/due.js +1 -0
  42. package/dist/esm/receipt/gutschein-plan.d.ts +23 -7
  43. package/dist/esm/receipt/gutschein-plan.js +68 -3
  44. package/dist/esm/receipt/index.d.ts +1 -1
  45. package/dist/esm/stored/draht.js +10 -2
  46. package/dist/esm/stored/vokabular.d.ts +1 -1
  47. package/dist/esm/stored/vokabular.js +84 -3
  48. package/dist/esm/version.d.ts +1 -1
  49. package/dist/esm/version.js +1 -1
  50. package/fixtures/hobex-hps-codes.json +1 -1
  51. package/fixtures/invoice-api.schema.json +1 -1
  52. package/fixtures/invoice-texts.json +1 -1
  53. package/fixtures/pos-texts.json +43 -2
  54. package/fixtures/receipt-due-voucher-generated.json +485 -483
  55. package/fixtures/surface.json +17 -1
  56. package/fixtures/v3/README.md +8 -1
  57. package/fixtures/v3/antworten/belege.json +27 -12
  58. package/fixtures/v3/antworten/belegmail.json +4 -1
  59. package/fixtures/v3/antworten/berichte.json +151 -0
  60. package/fixtures/v3/antworten/kasse-belege.json +27 -12
  61. package/fixtures/v3/antworten/kasse.json +366 -9
  62. package/fixtures/v3/antworten/lager.json +1 -1
  63. package/fixtures/v3/antworten/rechnungen.json +4 -1
  64. package/fixtures/v3/antworten/storno.json +4 -1
  65. package/fixtures/v3/stored/belege.json +4 -1
  66. package/fixtures/v3/stored/kasse.json +2 -2
  67. package/fixtures/v3/stored/rechnungen.json +4 -1
  68. package/fixtures/v3/v3-vokabular.json +417 -10
  69. package/fixtures/v3/zahlbetrag-faelle.json +29 -10
  70. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { VoucherCode } from '@kreiseck/validator';
2
- import { isNewFormVoucher, voucherIsValid, voucherServerFields } from '../models/voucher.js';
2
+ import { isNewFormVoucher, istWertVerkauf, voucherIsValid, voucherServerFields, wunschFormGueltig } from '../models/voucher.js';
3
3
  /**
4
4
  * Stichtag des 0-%-Topfs fuer Mehrzweck-Verkaeufe (Backend
5
5
  * `gutschein-core.NULLTOPF_AB`). Solange er in der Zukunft liegt, zaehlt ein
@@ -44,6 +44,23 @@ function satzBp(vat) {
44
44
  function position(satzBpWert, cents, kind) {
45
45
  return { amount: 1, priceOne: cents / 100, vat: satzBpWert / 100, tip: null, kind };
46
46
  }
47
+ /** Reservierte Kennung (`__…__`): gibt es am Server nie als Sorte (gutschein-core.RESERVIERTE_ID). */
48
+ const RESERVIERTE_ID = /^__.*__$/;
49
+ /**
50
+ * Die Sorte zum Wunsch, wie der Server sie verkaufen wuerde, oder null
51
+ * (unbekannt): Mehrzweck ohne Satz, Einzweck mit Satz > 0, Betrag frei oder
52
+ * fest von 1,00 bis 10.000,00 €. Eine unstimmige Sorte verkauft der Server
53
+ * nicht (`gutschein-beleg.sorteFuerVerkauf` ueber `gutschein-core.pruefeSorte`).
54
+ */
55
+ function sorteZumWunsch(typen, typeId) {
56
+ const t = (typen ?? []).find((x) => x.id === typeId);
57
+ if (t == null)
58
+ return null;
59
+ const satzOk = t.kind === 'multi_purpose' ? t.vatRateBp == null : t.kind === 'single_purpose' && Number.isInteger(t.vatRateBp) && t.vatRateBp > 0;
60
+ const betragOk = t.amount?.mode === 'free'
61
+ || (t.amount?.mode === 'fixed' && Number.isInteger(t.amount.cents) && t.amount.cents >= 100 && t.amount.cents <= 1_000_000);
62
+ return satzOk && betragOk ? t : null;
63
+ }
47
64
  /** Code in Normalform (tolerant eingelesen, Pruefzeichen stimmt) oder null. */
48
65
  function normalerCode(code) {
49
66
  if (typeof code !== 'string')
@@ -152,7 +169,23 @@ export function planeGutscheine(kunde, vouchers, art, o) {
152
169
  for (const [i, v] of vouchers.entries()) {
153
170
  if (istGelesen(v))
154
171
  return nein('voucher_invalid', `Gutschein ${i + 1}: Serverfelder an einem Wunsch.`);
155
- if (isNewFormVoucher(v) && !voucherIsValid(v))
172
+ if (!isNewFormVoucher(v))
173
+ continue;
174
+ if (istWertVerkauf(v) && v.typeId == null) {
175
+ // Wie gutschein-beleg.pruefeWuensche: ein Wert-Verkauf ohne Sorte ist voucher_type_required.
176
+ // Nur eine alte Gutschein-Einstellung MIT Art (Aufrufer bis 1.16) rechnet wie bisher; ein Server ab
177
+ // Stufe 4b schickt `valueVoucherType` immer null, dort hilft kein Neuladen – die Sorte fehlt.
178
+ if (o.voucherSettings?.valueVoucherType == null)
179
+ return nein('voucher_type_required', `Gutschein ${i + 1}: die Gutschein-Sorte fehlt (typeId).`);
180
+ if (!wunschFormGueltig(v, false))
181
+ return nein('voucher_invalid', `Gutschein ${i + 1} ist unvollstaendig.`);
182
+ continue;
183
+ }
184
+ // Eine reservierte Kennung weist der Server vor jeder anderen Pruefung als unbekannt ab.
185
+ if (istWertVerkauf(v) && typeof v.typeId === 'string' && RESERVIERTE_ID.test(v.typeId)) {
186
+ return nein('voucher_type_not_found', `Gutschein ${i + 1}: diese Gutschein-Sorte gibt es nicht.`);
187
+ }
188
+ if (!voucherIsValid(v))
156
189
  return nein('voucher_invalid', `Gutschein ${i + 1} ist unvollstaendig.`);
157
190
  }
158
191
  // Kein Gutschein mit Gutschein bezahlen, sobald einer der beiden die neue Form hat.
@@ -210,6 +243,34 @@ export function planeGutscheine(kunde, vouchers, art, o) {
210
243
  gutscheine.push(g);
211
244
  continue;
212
245
  }
246
+ if (istWertVerkauf(v) && v.typeId != null) {
247
+ // Verkauf ueber eine Sorte (gutschein-beleg.plane): unbekannt, andere Art, falscher Fixbetrag. Eine andere Art
248
+ // heisst: die Kasse hat eine alte Sicht (Sorte umgestellt) – wie ein anderer Fixbetrag voucher_amount_mismatch,
249
+ // die Kasse laedt die Sorten neu.
250
+ const sorte = sorteZumWunsch(o.voucherTypes, v.typeId);
251
+ if (sorte == null)
252
+ return nein('voucher_type_not_found', `Gutschein ${i + 1}: die Gutschein-Sorte fehlt (voucherTypes).`);
253
+ if (v.type != null && v.type !== sorte.kind)
254
+ return nein('voucher_amount_mismatch', `Gutschein ${i + 1}: die Art passt nicht (mehr) zur Gutschein-Sorte.`);
255
+ if (sorte.amount.mode === 'fixed' && v.amountCents !== sorte.amount.cents) {
256
+ return nein('voucher_amount_mismatch', `Gutschein ${i + 1}: der Betrag passt nicht zum Fixbetrag der Gutschein-Sorte.`);
257
+ }
258
+ const c = v.amountCents;
259
+ if (sorte.kind === 'multi_purpose') {
260
+ if (nulltopf) {
261
+ zusatz.push(position(0, c, 'voucher_float'));
262
+ gutscheine.push({ action: 'sell', type: 'value', value: c / 100, imNullTopf: true });
263
+ }
264
+ else {
265
+ gutscheine.push({ action: 'sell', type: 'value', value: c / 100 });
266
+ }
267
+ }
268
+ else {
269
+ // Kleinunternehmer: befreit verkauft, der Satz der Sorte legt nur fest, wofuer der Gutschein gilt.
270
+ zusatz.push(position(ku ? 0 : sorte.vatRateBp, c, 'voucher'));
271
+ }
272
+ continue;
273
+ }
213
274
  if (!ARTEN.includes(String(v.type)))
214
275
  return nein('voucher_invalid', `Gutschein ${i + 1}: unbekannte Art.`);
215
276
  if (v.action === 'sell') {
@@ -239,6 +300,8 @@ export function planeGutscheine(kunde, vouchers, art, o) {
239
300
  const a = (o.voucherArticles ?? []).find((x) => x.id === v.articleId);
240
301
  if (a == null)
241
302
  return nein('voucher_item_mismatch', `Gutschein ${i + 1}: der Artikel fehlt (voucherArticles).`);
303
+ if (a.serviceVoucher === false)
304
+ return nein('voucher_service_not_allowed', `Gutschein ${i + 1}: der Artikel ist nicht als Leistungsgutschein freigegeben.`);
242
305
  if (!Number.isInteger(a.priceCents) || a.priceCents <= 0 || !Number.isInteger(a.vatRateBp) || a.vatRateBp < 0) {
243
306
  return nein('voucher_invalid', `Gutschein ${i + 1}: Artikel ohne Preis oder Satz.`);
244
307
  }
@@ -253,7 +316,9 @@ export function planeGutscheine(kunde, vouchers, art, o) {
253
316
  if ('fehler' in check)
254
317
  return check;
255
318
  if (v.action === 'payout') {
256
- // `gutschein-core.darfAuszahlen`: aktiv, oder abgelaufen bis zum Ende der Rueckzahlbarkeit.
319
+ // `gutschein-core.darfAuszahlen`: Auszahlung nicht gesperrt, aktiv oder abgelaufen bis zum Ende der Rueckzahlbarkeit.
320
+ if (check.payout === 'never')
321
+ return nein('voucher_payout_not_allowed', `Gutschein ${i + 1}: dieser Gutschein wird nie ausgezahlt.`);
257
322
  if (!((check.balanceCents ?? 0) > 0))
258
323
  return nein('voucher_used_up', `Gutschein ${i + 1}: kein Saldo.`);
259
324
  if (check.status === 'expired') {
@@ -8,4 +8,4 @@ export { rasterizeLogo } from './bild.js';
8
8
  export { type BrandMarkRaster, BRAND_MARK_RASTERS, BRAND_MARK_PATHS } from './marke-daten.js';
9
9
  export { brandMarkImage } from './marke.js';
10
10
  export { type CodeTableTestSheetInput, type CodeTableTestSheetRow, type CodeTableTestSheet, CODE_TABLE_TEST_SHEET_CHARS, codeTableTestSheet, codeTableTestSheetBytes, codeTableReferenceImage, } from './code-table-test-sheet.js';
11
- export { type ReceiptDueTip, type ReceiptDueTipRecipient, type ReceiptDueOptions, type ReceiptDueBuckets, type ReceiptDueBreakdown, type ReceiptDueErrorReason, receiptDueCents, receiptDueBreakdown, ReceiptDueError, RECEIPT_DUE_ERROR_REASONS, isReceiptDueError, type VoucherDueInfo, type VoucherDueArticle, type VoucherRedeemContext, voucherRedeemMaxCents, VOUCHER_ZERO_RATE_BUCKET_FROM, } from './due.js';
11
+ export { type ReceiptDueTip, type ReceiptDueTipRecipient, type ReceiptDueOptions, type ReceiptDueBuckets, type ReceiptDueBreakdown, type ReceiptDueErrorReason, receiptDueCents, receiptDueBreakdown, ReceiptDueError, RECEIPT_DUE_ERROR_REASONS, isReceiptDueError, type VoucherDueInfo, type VoucherDueArticle, type VoucherDueType, type VoucherRedeemContext, voucherRedeemMaxCents, VOUCHER_ZERO_RATE_BUCKET_FROM, } from './due.js';
@@ -137,12 +137,17 @@ function belegRueckgabeNachAussen(beleg) {
137
137
  return raus;
138
138
  }
139
139
  // ---- Gutschein-Eintraege am Beleg ---------------------------------------------
140
- /** Zwilling von `BELEG_GUTSCHEIN` (api-vokabular-v3): aussen -> innen. */
140
+ /**
141
+ * Zwilling von `BELEG_GUTSCHEIN` (api-vokabular-v3): aussen -> innen. Sorte,
142
+ * Sortenname und Auszahlung friert der Server beim Verkauf ueber eine Sorte
143
+ * ein (Gutscheine Stufe 4b); die Auszahlung traegt dazu einen Wert aus dem
144
+ * Katalog `GUTSCHEIN_AUSZAHLUNG` (erlaubt/nie).
145
+ */
141
146
  const BELEG_GUTSCHEIN = {
142
147
  voucherType: 'art', voucherId: 'gutscheinId', codeSuffix: 'codeEnde', amountCents: 'betragCents', vatRateBp: 'satzBp',
143
148
  article: 'artikel', articleId: 'artikelId', quantity: 'stueck', positions: 'positionen',
144
149
  balanceAfterCents: 'saldoNachCents', remainingQuantityAfter: 'stueckOffenNach', taxedWith: 'versteuertMit', exempt: 'befreit',
145
- reason: 'grund', zeroRateBucket: 'imNullTopf',
150
+ reason: 'grund', zeroRateBucket: 'imNullTopf', typeId: 'sorteId', typeName: 'sorteName', payout: 'auszahlung',
146
151
  };
147
152
  const BELEG_GUTSCHEIN_AUSSEN = Object.fromEntries(Object.entries(BELEG_GUTSCHEIN).map(([aussen, innen]) => [innen, aussen]));
148
153
  const GUTSCHEIN_ARTIKEL_AUSSEN = { satzBp: 'vatRateBp', preisCents: 'priceCents' };
@@ -154,6 +159,7 @@ function gutscheinEintragNachAussen(v) {
154
159
  if (!istObjekt(v))
155
160
  return v;
156
161
  const art = KATALOGE.GUTSCHEIN_ART ?? {};
162
+ const auszahlung = KATALOGE.GUTSCHEIN_AUSZAHLUNG ?? {};
157
163
  const typNeu = typeof v.type === 'string' && hat(art, v.type);
158
164
  if (!typNeu && !Object.keys(v).some((k) => hat(BELEG_GUTSCHEIN_AUSSEN, k)))
159
165
  return v;
@@ -165,6 +171,8 @@ function gutscheinEintragNachAussen(v) {
165
171
  raus.voucherType = typeof w === 'string' && hat(art, w) ? art[w] : w;
166
172
  else if (k === 'artikel')
167
173
  raus.article = istObjekt(w) ? umbenannt(w, GUTSCHEIN_ARTIKEL_AUSSEN) : w;
174
+ else if (k === 'auszahlung')
175
+ raus.payout = typeof w === 'string' && hat(auszahlung, w) ? auszahlung[w] : w;
168
176
  else
169
177
  raus[hat(BELEG_GUTSCHEIN_AUSSEN, k) ? BELEG_GUTSCHEIN_AUSSEN[k] : k] = w;
170
178
  }
@@ -1,5 +1,5 @@
1
1
  /** Fingerabdruck des Vertrags-Exports, aus dem diese Datei stammt (`_quelle.sha256`). */
2
- export declare const VOKABULAR_QUELLE = "d11de425770bc431be9766199e4c9b3e712eb8e0eea84658f771a0f79d98e90e";
2
+ export declare const VOKABULAR_QUELLE = "3088cb472f3fef3ed4ff969bf0d37d051363714096616a9263270c58266bde14";
3
3
  /** Schema-Notation des Vertrags: Blatt 'aussen': 'innen', Objekt { __: 'innen', ... }, Liste [ { __: 'innen', ... } ]. */
4
4
  export type SchemaEintrag = string | SchemaObjekt | readonly [SchemaObjekt];
5
5
  export interface SchemaObjekt {
@@ -1,7 +1,7 @@
1
1
  // Erzeugt von scripts/stored-vokabular.mjs aus fixtures/v3/v3-vokabular.json.
2
2
  // Nicht von Hand aendern: test/stored.test.ts vergleicht mit dem Vertrag.
3
3
  /** Fingerabdruck des Vertrags-Exports, aus dem diese Datei stammt (`_quelle.sha256`). */
4
- export const VOKABULAR_QUELLE = "d11de425770bc431be9766199e4c9b3e712eb8e0eea84658f771a0f79d98e90e";
4
+ export const VOKABULAR_QUELLE = "3088cb472f3fef3ed4ff969bf0d37d051363714096616a9263270c58266bde14";
5
5
  /** Schema je Endpunkt (aussen -> innen) und Wertverweise auf die Kataloge. */
6
6
  export const SCHEMAS = {
7
7
  "getReceipt": {
@@ -51,9 +51,12 @@ export const SCHEMAS = {
51
51
  "faceValueCents": "nennwertCents",
52
52
  "quantity": "stueck",
53
53
  "articleName": "artikelName",
54
+ "typeId": "sorteId",
55
+ "typeName": "sorteName",
54
56
  "validity": {
55
57
  "__": "gueltigkeit",
56
58
  "pattern": "muster",
59
+ "redeemableYears": "jahre",
57
60
  "redeemableUntil": "einloesbarBis",
58
61
  "refundableUntil": "rueckzahlbarBis",
59
62
  "validUntil": "gueltigBis"
@@ -201,20 +204,72 @@ export const SCHEMAS = {
201
204
  "vouchers": {
202
205
  "__": "gutscheine",
203
206
  "sale": "verkauf",
207
+ "typeSale": "sortenVerkauf",
204
208
  "valueVoucherType": "wertArt",
205
209
  "vatRateBp": "satzBp",
206
210
  "label": {
207
211
  "__": "etikett",
208
212
  "size": "groesse",
213
+ "rotation": "drehung",
209
214
  "fields": {
210
215
  "__": "felder",
211
216
  "business": "betrieb",
212
217
  "value": "wert",
213
218
  "validity": "gueltigkeit",
214
- "checkPage": "pruefseite"
219
+ "checkPage": "pruefseite",
220
+ "designation": "bezeichnung"
215
221
  },
216
222
  "freeText": "freitext"
217
- }
223
+ },
224
+ "labelDefault": {
225
+ "__": "etikettStandard",
226
+ "size": "groesse",
227
+ "rotation": "drehung",
228
+ "fields": {
229
+ "__": "felder",
230
+ "business": "betrieb",
231
+ "value": "wert",
232
+ "validity": "gueltigkeit",
233
+ "checkPage": "pruefseite",
234
+ "designation": "bezeichnung"
235
+ },
236
+ "freeText": "freitext"
237
+ },
238
+ "types": [
239
+ {
240
+ "__": "sorten",
241
+ "kind": "art",
242
+ "vatRateBp": "satzBp",
243
+ "amount": {
244
+ "__": "betrag",
245
+ "mode": "modus"
246
+ },
247
+ "validity": {
248
+ "__": "gueltigkeit",
249
+ "pattern": "muster",
250
+ "years": "jahre"
251
+ },
252
+ "payout": "auszahlung",
253
+ "label": {
254
+ "__": "etikett",
255
+ "size": "groesse",
256
+ "rotation": "drehung",
257
+ "fields": {
258
+ "__": "felder",
259
+ "business": "betrieb",
260
+ "value": "wert",
261
+ "validity": "gueltigkeit",
262
+ "checkPage": "pruefseite",
263
+ "designation": "bezeichnung"
264
+ },
265
+ "freeText": "freitext"
266
+ },
267
+ "order": "reihenfolge",
268
+ "active": "aktiv",
269
+ "soldCount": "verkauft"
270
+ }
271
+ ],
272
+ "serviceArticles": "leistungsArtikel"
218
273
  }
219
274
  },
220
275
  "werte": {
@@ -269,6 +324,18 @@ export const SCHEMAS = {
269
324
  "vouchers.valueVoucherType": {
270
325
  "mehrzweck": "multi_purpose",
271
326
  "einzweck": "single_purpose"
327
+ },
328
+ "vouchers.types[].kind": {
329
+ "$catalog": "GUTSCHEIN_ART"
330
+ },
331
+ "vouchers.types[].amount.mode": {
332
+ "$catalog": "GUTSCHEIN_BETRAG_MODUS"
333
+ },
334
+ "vouchers.types[].validity.pattern": {
335
+ "$catalog": "GUTSCHEIN_SORTE_MUSTER"
336
+ },
337
+ "vouchers.types[].payout": {
338
+ "$catalog": "GUTSCHEIN_AUSZAHLUNG"
272
339
  }
273
340
  }
274
341
  },
@@ -279,6 +346,7 @@ export const SCHEMAS = {
279
346
  "__": "articles",
280
347
  "quantityRule": "mengenregel",
281
348
  "askQuantity": "mengeFragen",
349
+ "serviceVoucher": "gutscheinLeistung",
282
350
  "maxQuantity": "maxMenge",
283
351
  "tile": {
284
352
  "__": "kasse",
@@ -321,6 +389,7 @@ export const ARTIKEL_FELDER = [
321
389
  "askQuantity",
322
390
  "maxQuantity",
323
391
  "revenueGroupId",
392
+ "serviceVoucher",
324
393
  "active",
325
394
  "groupId",
326
395
  "tile",
@@ -481,11 +550,23 @@ export const KATALOGE = {
481
550
  "leistung": "service",
482
551
  "aktion": "promotion"
483
552
  },
553
+ "GUTSCHEIN_AUSZAHLUNG": {
554
+ "erlaubt": "allowed",
555
+ "nie": "never"
556
+ },
557
+ "GUTSCHEIN_BETRAG_MODUS": {
558
+ "frei": "free",
559
+ "fix": "fixed"
560
+ },
484
561
  "GUTSCHEIN_MUSTER": {
485
562
  "unbefristet": "unlimited",
486
563
  "1+3": "1+3",
487
564
  "frei": "custom"
488
565
  },
566
+ "GUTSCHEIN_SORTE_MUSTER": {
567
+ "unbefristet": "unlimited",
568
+ "jahre": "years"
569
+ },
489
570
  "KASSE_BETRIEB_WERTE.cardProvider": {
490
571
  "keiner": "none",
491
572
  "extern": "external",
@@ -4,4 +4,4 @@
4
4
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
5
5
  * beim Anheben der Version beide Stellen aendern.
6
6
  */
7
- export declare const PACKAGE_VERSION = "1.16.0";
7
+ export declare const PACKAGE_VERSION = "1.17.1";
@@ -4,4 +4,4 @@
4
4
  * Client-Version, Nachtrag §6). Ein Test haelt sie gleich mit `package.json`;
5
5
  * beim Anheben der Version beide Stellen aendern.
6
6
  */
7
- export const PACKAGE_VERSION = '1.16.0';
7
+ export const PACKAGE_VERSION = '1.17.1';
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.16.0",
2
+ "version": "1.17.1",
3
3
  "measuredOn": {
4
4
  "tid": "3600335",
5
5
  "hpsVersion": "1.10.0",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "title": "Kasseneck Rechnungs-API",
4
4
  "version": 2,
5
- "package": "1.16.0",
5
+ "package": "1.17.1",
6
6
  "endpoints": {
7
7
  "createCustomer": {
8
8
  "request": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.16.0",
2
+ "version": "1.17.1",
3
3
  "languages": [
4
4
  "de",
5
5
  "en"
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.16.0",
2
+ "version": "1.17.1",
3
3
  "messages": {
4
4
  "network.no_connection": {
5
5
  "text": "Keine Verbindung zum Server. Bitte die Internetverbindung prüfen und erneut versuchen."
@@ -405,6 +405,24 @@
405
405
  "voucher_error.sale_off": {
406
406
  "text": "Gutscheine verkaufen geht hier noch nicht."
407
407
  },
408
+ "voucher_error.type_required": {
409
+ "text": "Bitte eine Gutschein-Sorte wählen."
410
+ },
411
+ "voucher_error.type_not_found": {
412
+ "text": "Diese Gutschein-Sorte gibt es nicht mehr. Die Kasse lädt die Sorten neu."
413
+ },
414
+ "voucher_error.amount_mismatch": {
415
+ "text": "Die Gutschein-Sorte hat sich geändert. Die Kasse lädt die Sorten neu."
416
+ },
417
+ "voucher_error.service_not_allowed": {
418
+ "text": "Dieser Artikel ist nicht als Leistungsgutschein freigegeben."
419
+ },
420
+ "voucher_error.payout_not_allowed": {
421
+ "text": "Dieser Gutschein kann nicht ausgezahlt werden."
422
+ },
423
+ "voucher.type_changed": {
424
+ "text": "Diese Gutschein-Sorte hat sich geändert. Bitte die Zeile entfernen und die Kachel neu antippen."
425
+ },
408
426
  "voucher.reentry_needed": {
409
427
  "text": "Die Karte ist belastet, der Beleg fehlt noch: zu jedem Gutschein den Code erneut eingeben, dann den Beleg abschließen."
410
428
  },
@@ -1141,7 +1159,12 @@
1141
1159
  "voucher_already_used": "voucher_error.already_used",
1142
1160
  "voucher_partial_cancel": "voucher_error.partial_cancel",
1143
1161
  "voucher_settings_missing": "voucher_error.settings_missing",
1144
- "too_many_voucher_checks": "voucher_error.too_many_checks"
1162
+ "too_many_voucher_checks": "voucher_error.too_many_checks",
1163
+ "voucher_type_required": "voucher_error.type_required",
1164
+ "voucher_type_not_found": "voucher_error.type_not_found",
1165
+ "voucher_amount_mismatch": "voucher_error.amount_mismatch",
1166
+ "voucher_service_not_allowed": "voucher_error.service_not_allowed",
1167
+ "voucher_payout_not_allowed": "voucher_error.payout_not_allowed"
1145
1168
  },
1146
1169
  "labels": {
1147
1170
  "common.cancel": {
@@ -2061,6 +2084,24 @@
2061
2084
  "voucher.add": {
2062
2085
  "text": "Hinzufügen"
2063
2086
  },
2087
+ "voucher.tab": {
2088
+ "text": "Gutscheine"
2089
+ },
2090
+ "voucher.enter_amount": {
2091
+ "text": "Betrag eingeben"
2092
+ },
2093
+ "voucher.service_tile": {
2094
+ "text": "Leistungsgutschein"
2095
+ },
2096
+ "voucher.kind_multi_short": {
2097
+ "text": "Mehrzweck"
2098
+ },
2099
+ "voucher.kind_single_short": {
2100
+ "text": "Einzweck {rate} %",
2101
+ "placeholders": [
2102
+ "rate"
2103
+ ]
2104
+ },
2064
2105
  "shift.all_payments": {
2065
2106
  "text": "Alle Zahlungen dieser Schicht (bar + unbar)"
2066
2107
  },