@hartl-services/medusa-base 1.0.0 → 2.0.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.
Files changed (79) hide show
  1. package/.medusa/server/src/admin/index.js +117 -1
  2. package/.medusa/server/src/admin/index.mjs +118 -2
  3. package/.medusa/server/src/documents/plugin-features.js +15 -1
  4. package/.medusa/server/src/documents/templates/financial-document.js +69 -51
  5. package/.medusa/server/src/documents/templates/format.js +44 -2
  6. package/.medusa/server/src/documents/templates/html-factory.js +7 -5
  7. package/.medusa/server/src/documents/templates/html-utils.js +12 -2
  8. package/.medusa/server/src/documents/templates/layout.js +115 -70
  9. package/.medusa/server/src/documents/templates/packing-list.js +10 -8
  10. package/.medusa/server/src/documents/utils/document-merchant.js +5 -5
  11. package/.medusa/server/src/documents/utils/document-render-settings.js +59 -0
  12. package/.medusa/server/src/email/application/handle-invite-event.js +8 -2
  13. package/.medusa/server/src/email/application/handle-password-reset-event.js +16 -4
  14. package/.medusa/server/src/email/domain/order-summary.js +103 -0
  15. package/.medusa/server/src/email/domain/refund-summary.js +43 -0
  16. package/.medusa/server/src/email/domain/return-summary.js +118 -0
  17. package/.medusa/server/src/email/domain/shipment-summary.js +74 -0
  18. package/.medusa/server/src/email/plugin-features.js +9 -1
  19. package/.medusa/server/src/email/rendering/default-templates.js +693 -65
  20. package/.medusa/server/src/email/rendering/load-email-shop-details.js +36 -0
  21. package/.medusa/server/src/email/rendering/render-email.js +16 -3
  22. package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +20 -1
  23. package/.medusa/server/src/email/types/template-data.js +155 -2
  24. package/.medusa/server/src/modules/documents/domain/merchant.js +2 -33
  25. package/.medusa/server/src/modules/documents/domain/options.js +1 -7
  26. package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +4 -3
  27. package/.medusa/server/src/public/descriptor.js +3 -1
  28. package/.medusa/server/src/public/shop-master-data.js +7 -7
  29. package/.medusa/server/src/shop-config/build-food-shop-config.js +6 -6
  30. package/.medusa/server/src/shop-config/options.js +5 -15
  31. package/.medusa/server/src/workflows/documents/issue-cancellation-after-refund.js +2 -3
  32. package/.medusa/server/src/workflows/documents/issue-document.js +6 -5
  33. package/.medusa/server/src/workflows/documents/issue-packing-list.js +9 -3
  34. package/.medusa/server/src/workflows/email/dispatch-email-message.js +4 -2
  35. package/.medusa/server/src/workflows/email/prepare-order-canceled-email.js +42 -4
  36. package/.medusa/server/src/workflows/email/prepare-order-received-email.js +31 -5
  37. package/.medusa/server/src/workflows/email/prepare-refund-email.js +25 -1
  38. package/.medusa/server/src/workflows/email/prepare-return-email.js +64 -3
  39. package/.medusa/server/src/workflows/email/prepare-shipment-email.js +36 -3
  40. package/README.md +180 -43
  41. package/dist/admin-components/features/plugin-features/components/ImageSettingInput.d.ts +15 -0
  42. package/dist/admin-components/features/plugin-features/components/ImageSettingInput.js +42 -0
  43. package/dist/admin-components/features/plugin-features/components/PluginSettingsForm.js +4 -2
  44. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +1 -1
  45. package/dist/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +4 -4
  46. package/dist/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +1 -1
  47. package/dist/admin-components/features/plugin-features/lib/image-upload.d.ts +6 -0
  48. package/dist/admin-components/features/plugin-features/lib/image-upload.js +17 -0
  49. package/dist/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +4 -4
  50. package/dist/admin-components/i18n/texts.d.ts +6 -0
  51. package/dist/admin-components/i18n/texts.js +6 -0
  52. package/dist/documents/templates/financial-document.d.ts +3 -3
  53. package/dist/documents/templates/financial-document.js +68 -50
  54. package/dist/documents/templates/format.d.ts +14 -0
  55. package/dist/documents/templates/format.js +43 -1
  56. package/dist/documents/templates/html-factory.d.ts +6 -2
  57. package/dist/documents/templates/html-factory.js +6 -4
  58. package/dist/documents/templates/html-utils.d.ts +6 -0
  59. package/dist/documents/templates/html-utils.js +11 -1
  60. package/dist/documents/templates/layout.d.ts +21 -3
  61. package/dist/documents/templates/layout.js +114 -69
  62. package/dist/documents/templates/packing-list.js +9 -7
  63. package/dist/documents/types/documents.d.ts +11 -16
  64. package/dist/documents/types/html-factory.d.ts +1 -0
  65. package/dist/email/types/shop-configuration.d.ts +25 -0
  66. package/dist/email/types/template-data.d.ts +509 -0
  67. package/dist/email/types/template-data.js +154 -1
  68. package/dist/modules/documents/domain/options.d.ts +1 -9
  69. package/dist/modules/documents/domain/options.js +0 -6
  70. package/dist/public/descriptor.js +2 -0
  71. package/dist/public/shop-master-data.d.ts +5 -6
  72. package/dist/public/shop-master-data.js +6 -6
  73. package/dist/public/types.d.ts +2 -1
  74. package/dist/shop-config/build-food-shop-config.js +5 -5
  75. package/dist/shop-config/options.d.ts +13 -8
  76. package/dist/shop-config/options.js +4 -14
  77. package/package.json +2 -2
  78. package/dist/modules/documents/domain/merchant.d.ts +0 -22
  79. package/dist/modules/documents/domain/merchant.js +0 -85
@@ -73,6 +73,12 @@ const texts = {
73
73
  numberMax: (max) => `Höchstens ${max}.`,
74
74
  numberRange: (min, max) => `Zwischen ${min} und ${max}.`,
75
75
  selectPlaceholder: "Bitte auswählen",
76
+ imageUpload: "Bild hochladen",
77
+ imageReplace: "Anderes Bild hochladen",
78
+ imageRemove: "Entfernen",
79
+ imageNone: "Kein Bild hinterlegt",
80
+ imageUploadFailed: "Das Bild konnte nicht hochgeladen werden.",
81
+ imagePreviewAlt: (label) => `Vorschau ${label}`,
76
82
  clearHint: "Ein leeres Feld speichern entfernt den gespeicherten Wert (dann gilt Konfiguration oder Standard).",
77
83
  source: {
78
84
  stored: "gespeichert",
@@ -383,6 +389,106 @@ function usePluginSettingsForm(plugin2) {
383
389
  mutation
384
390
  };
385
391
  }
392
+ const SETTING_IMAGE_MAX_BYTES = 2 * 1024 * 1024;
393
+ const IMAGE_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg"]);
394
+ const validateSettingImage = (file) => {
395
+ if (!IMAGE_TYPES.has(file.type)) {
396
+ return "Bitte eine PNG- oder JPG-Datei auswählen.";
397
+ }
398
+ if (file.size === 0) {
399
+ return "Die Bilddatei ist leer.";
400
+ }
401
+ if (file.size > SETTING_IMAGE_MAX_BYTES) {
402
+ return "Die Bilddatei darf maximal 2 MiB groß sein.";
403
+ }
404
+ return null;
405
+ };
406
+ const ImageSettingInput = ({
407
+ id,
408
+ hintId,
409
+ label,
410
+ value,
411
+ disabled,
412
+ onChange
413
+ }) => {
414
+ const fileInput = react.useRef(null);
415
+ const [error, setError] = react.useState(null);
416
+ const upload = reactQuery.useMutation({
417
+ mutationFn: async (file) => {
418
+ const { files } = await sdk.admin.upload.create({ files: [file] });
419
+ const url = files[0]?.url;
420
+ if (!url) {
421
+ throw new Error("upload returned no file");
422
+ }
423
+ return url;
424
+ },
425
+ onSuccess: (url) => onChange(url),
426
+ onError: () => setError(texts.settings.imageUploadFailed)
427
+ });
428
+ const busy = disabled || upload.isPending;
429
+ const selectFile = (file) => {
430
+ if (!file) {
431
+ return;
432
+ }
433
+ const invalid = validateSettingImage(file);
434
+ setError(invalid);
435
+ if (!invalid) {
436
+ upload.mutate(file);
437
+ }
438
+ };
439
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-2", children: [
440
+ value && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-ui-bg-subtle flex items-center justify-center rounded-md border p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
441
+ "img",
442
+ {
443
+ src: value,
444
+ alt: texts.settings.imagePreviewAlt(label),
445
+ className: "max-h-24 max-w-full object-contain"
446
+ }
447
+ ) }),
448
+ /* @__PURE__ */ jsxRuntime.jsx(
449
+ "input",
450
+ {
451
+ ref: fileInput,
452
+ id,
453
+ "aria-describedby": hintId,
454
+ type: "file",
455
+ accept: "image/png,image/jpeg",
456
+ className: "hidden",
457
+ onChange: (event) => {
458
+ selectFile(event.target.files?.[0]);
459
+ event.target.value = "";
460
+ }
461
+ }
462
+ ),
463
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
464
+ /* @__PURE__ */ jsxRuntime.jsx(
465
+ ui.Button,
466
+ {
467
+ type: "button",
468
+ size: "small",
469
+ variant: "secondary",
470
+ isLoading: upload.isPending,
471
+ disabled: busy,
472
+ onClick: () => fileInput.current?.click(),
473
+ children: value ? texts.settings.imageReplace : texts.settings.imageUpload
474
+ }
475
+ ),
476
+ value && /* @__PURE__ */ jsxRuntime.jsx(
477
+ ui.Button,
478
+ {
479
+ type: "button",
480
+ size: "small",
481
+ variant: "transparent",
482
+ disabled: busy,
483
+ onClick: () => onChange(""),
484
+ children: texts.settings.imageRemove
485
+ }
486
+ ),
487
+ !value && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: texts.settings.imageNone })
488
+ ] }),
489
+ error && /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { variant: "error", children: error })
490
+ ] });
491
+ };
386
492
  const fieldId = (pluginKey, key) => `plugin-setting-${pluginKey}-${key}`;
387
493
  const missingLabels = (plugin2) => plugin2.missing.map(
388
494
  (key) => plugin2.settings.find((setting) => setting.key === key)?.label ?? key
@@ -463,6 +569,16 @@ const SettingField = ({
463
569
  /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: setting.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: option.value, children: option.label }, option.value)) })
464
570
  ]
465
571
  }
572
+ ) : setting.type === "image" ? /* @__PURE__ */ jsxRuntime.jsx(
573
+ ImageSettingInput,
574
+ {
575
+ id,
576
+ hintId,
577
+ label: setting.label,
578
+ value: typeof value === "string" ? value : "",
579
+ disabled,
580
+ onChange: (url) => onChange(url)
581
+ }
466
582
  ) : setting.type === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
467
583
  ui.Input,
468
584
  {
@@ -502,7 +618,7 @@ const PluginSettingsForm = ({ plugin: plugin2 }) => {
502
618
  const form = usePluginSettingsForm(plugin2);
503
619
  const pending = form.mutation.isPending;
504
620
  const hasTextFields = plugin2.settings.some(
505
- (setting) => setting.type !== "boolean" && setting.type !== "secret" && setting.type !== "select"
621
+ (setting) => setting.type !== "boolean" && setting.type !== "secret" && setting.type !== "select" && setting.type !== "image"
506
622
  );
507
623
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", "aria-busy": pending, children: [
508
624
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4", children: [
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useState, useEffect, useMemo, useRef } from "react";
3
3
  import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
4
- import { toast, Container, Heading, Text, Alert, Button, Label, Switch, Input, Select, Hint, StatusBadge, usePrompt, FocusModal, Prompt } from "@medusajs/ui";
4
+ import { toast, Button, Text, Hint, Container, Heading, Alert, Label, Switch, Input, Select, StatusBadge, usePrompt, FocusModal, Prompt } from "@medusajs/ui";
5
5
  import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query";
6
6
  import { documentsPaths, packingListsPaths } from "@hartl-services/medusa-food-supplements-contracts/paths/documents";
7
7
  import Medusa from "@medusajs/js-sdk";
@@ -70,6 +70,12 @@ const texts = {
70
70
  numberMax: (max) => `Höchstens ${max}.`,
71
71
  numberRange: (min, max) => `Zwischen ${min} und ${max}.`,
72
72
  selectPlaceholder: "Bitte auswählen",
73
+ imageUpload: "Bild hochladen",
74
+ imageReplace: "Anderes Bild hochladen",
75
+ imageRemove: "Entfernen",
76
+ imageNone: "Kein Bild hinterlegt",
77
+ imageUploadFailed: "Das Bild konnte nicht hochgeladen werden.",
78
+ imagePreviewAlt: (label) => `Vorschau ${label}`,
73
79
  clearHint: "Ein leeres Feld speichern entfernt den gespeicherten Wert (dann gilt Konfiguration oder Standard).",
74
80
  source: {
75
81
  stored: "gespeichert",
@@ -380,6 +386,106 @@ function usePluginSettingsForm(plugin2) {
380
386
  mutation
381
387
  };
382
388
  }
389
+ const SETTING_IMAGE_MAX_BYTES = 2 * 1024 * 1024;
390
+ const IMAGE_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg"]);
391
+ const validateSettingImage = (file) => {
392
+ if (!IMAGE_TYPES.has(file.type)) {
393
+ return "Bitte eine PNG- oder JPG-Datei auswählen.";
394
+ }
395
+ if (file.size === 0) {
396
+ return "Die Bilddatei ist leer.";
397
+ }
398
+ if (file.size > SETTING_IMAGE_MAX_BYTES) {
399
+ return "Die Bilddatei darf maximal 2 MiB groß sein.";
400
+ }
401
+ return null;
402
+ };
403
+ const ImageSettingInput = ({
404
+ id,
405
+ hintId,
406
+ label,
407
+ value,
408
+ disabled,
409
+ onChange
410
+ }) => {
411
+ const fileInput = useRef(null);
412
+ const [error, setError] = useState(null);
413
+ const upload = useMutation({
414
+ mutationFn: async (file) => {
415
+ const { files } = await sdk.admin.upload.create({ files: [file] });
416
+ const url = files[0]?.url;
417
+ if (!url) {
418
+ throw new Error("upload returned no file");
419
+ }
420
+ return url;
421
+ },
422
+ onSuccess: (url) => onChange(url),
423
+ onError: () => setError(texts.settings.imageUploadFailed)
424
+ });
425
+ const busy = disabled || upload.isPending;
426
+ const selectFile = (file) => {
427
+ if (!file) {
428
+ return;
429
+ }
430
+ const invalid = validateSettingImage(file);
431
+ setError(invalid);
432
+ if (!invalid) {
433
+ upload.mutate(file);
434
+ }
435
+ };
436
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
437
+ value && /* @__PURE__ */ jsx("div", { className: "bg-ui-bg-subtle flex items-center justify-center rounded-md border p-4", children: /* @__PURE__ */ jsx(
438
+ "img",
439
+ {
440
+ src: value,
441
+ alt: texts.settings.imagePreviewAlt(label),
442
+ className: "max-h-24 max-w-full object-contain"
443
+ }
444
+ ) }),
445
+ /* @__PURE__ */ jsx(
446
+ "input",
447
+ {
448
+ ref: fileInput,
449
+ id,
450
+ "aria-describedby": hintId,
451
+ type: "file",
452
+ accept: "image/png,image/jpeg",
453
+ className: "hidden",
454
+ onChange: (event) => {
455
+ selectFile(event.target.files?.[0]);
456
+ event.target.value = "";
457
+ }
458
+ }
459
+ ),
460
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
461
+ /* @__PURE__ */ jsx(
462
+ Button,
463
+ {
464
+ type: "button",
465
+ size: "small",
466
+ variant: "secondary",
467
+ isLoading: upload.isPending,
468
+ disabled: busy,
469
+ onClick: () => fileInput.current?.click(),
470
+ children: value ? texts.settings.imageReplace : texts.settings.imageUpload
471
+ }
472
+ ),
473
+ value && /* @__PURE__ */ jsx(
474
+ Button,
475
+ {
476
+ type: "button",
477
+ size: "small",
478
+ variant: "transparent",
479
+ disabled: busy,
480
+ onClick: () => onChange(""),
481
+ children: texts.settings.imageRemove
482
+ }
483
+ ),
484
+ !value && /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: texts.settings.imageNone })
485
+ ] }),
486
+ error && /* @__PURE__ */ jsx(Hint, { variant: "error", children: error })
487
+ ] });
488
+ };
383
489
  const fieldId = (pluginKey, key) => `plugin-setting-${pluginKey}-${key}`;
384
490
  const missingLabels = (plugin2) => plugin2.missing.map(
385
491
  (key) => plugin2.settings.find((setting) => setting.key === key)?.label ?? key
@@ -460,6 +566,16 @@ const SettingField = ({
460
566
  /* @__PURE__ */ jsx(Select.Content, { children: setting.options.map((option) => /* @__PURE__ */ jsx(Select.Item, { value: option.value, children: option.label }, option.value)) })
461
567
  ]
462
568
  }
569
+ ) : setting.type === "image" ? /* @__PURE__ */ jsx(
570
+ ImageSettingInput,
571
+ {
572
+ id,
573
+ hintId,
574
+ label: setting.label,
575
+ value: typeof value === "string" ? value : "",
576
+ disabled,
577
+ onChange: (url) => onChange(url)
578
+ }
463
579
  ) : setting.type === "number" ? /* @__PURE__ */ jsx(
464
580
  Input,
465
581
  {
@@ -499,7 +615,7 @@ const PluginSettingsForm = ({ plugin: plugin2 }) => {
499
615
  const form = usePluginSettingsForm(plugin2);
500
616
  const pending = form.mutation.isPending;
501
617
  const hasTextFields = plugin2.settings.some(
502
- (setting) => setting.type !== "boolean" && setting.type !== "secret" && setting.type !== "select"
618
+ (setting) => setting.type !== "boolean" && setting.type !== "secret" && setting.type !== "select" && setting.type !== "image"
503
619
  );
504
620
  return /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", "aria-busy": pending, children: [
505
621
  /* @__PURE__ */ jsxs("div", { className: "px-6 py-4", children: [
@@ -20,5 +20,19 @@ exports.documentsPluginFeatures = (0, public_1.definePluginFeatures)({
20
20
  default_enabled: true,
21
21
  },
22
22
  ],
23
+ settings: [
24
+ {
25
+ key: "logo",
26
+ label: "Logo",
27
+ description: "PNG oder JPG, erscheint oben links auf Rechnungen, Stornos und Packlisten. Am besten mindestens 1000 px breit, auf weißem oder transparentem Hintergrund. Ohne Logo steht dort der Firmenname.",
28
+ type: "image",
29
+ },
30
+ {
31
+ key: "payment_terms",
32
+ label: "Zahlungskonditionen",
33
+ description: "Erscheint auf Rechnungen unter den Summen, z. B. „Der Betrag wurde bei der Bestellung per Kreditkarte bezahlt.“ Leer lassen, wenn nichts stehen soll. Gilt für neu erstellte und neu erzeugte Rechnungen.",
34
+ type: "string",
35
+ },
36
+ ],
23
37
  });
24
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWZlYXR1cmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvY3VtZW50cy9wbHVnaW4tZmVhdHVyZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0NBQWdEO0FBRW5DLFFBQUEsdUJBQXVCLEdBQUcsSUFBQSw2QkFBb0IsRUFBQztJQUMxRCxVQUFVLEVBQUUsV0FBVztJQUN2QixLQUFLLEVBQUUsV0FBVztJQUNsQixXQUFXLEVBQ1QscVNBQXFTO0lBQ3ZTLFFBQVEsRUFBRTtRQUNSO1lBQ0UsR0FBRyxFQUFFLFVBQVU7WUFDZixLQUFLLEVBQUUsc0JBQXNCO1lBQzdCLFdBQVcsRUFDVCxzYkFBc2I7WUFDeGIsZUFBZSxFQUFFLElBQUk7U0FDdEI7UUFDRDtZQUNFLEdBQUcsRUFBRSxlQUFlO1lBQ3BCLEtBQUssRUFBRSxZQUFZO1lBQ25CLFdBQVcsRUFDVCwyRUFBMkU7WUFDN0UsZUFBZSxFQUFFLElBQUk7U0FDdEI7S0FDRjtDQUNGLENBQUMsQ0FBQSJ9
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWZlYXR1cmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvY3VtZW50cy9wbHVnaW4tZmVhdHVyZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0NBQWdEO0FBRW5DLFFBQUEsdUJBQXVCLEdBQUcsSUFBQSw2QkFBb0IsRUFBQztJQUMxRCxVQUFVLEVBQUUsV0FBVztJQUN2QixLQUFLLEVBQUUsV0FBVztJQUNsQixXQUFXLEVBQ1QscVNBQXFTO0lBQ3ZTLFFBQVEsRUFBRTtRQUNSO1lBQ0UsR0FBRyxFQUFFLFVBQVU7WUFDZixLQUFLLEVBQUUsc0JBQXNCO1lBQzdCLFdBQVcsRUFDVCxzYkFBc2I7WUFDeGIsZUFBZSxFQUFFLElBQUk7U0FDdEI7UUFDRDtZQUNFLEdBQUcsRUFBRSxlQUFlO1lBQ3BCLEtBQUssRUFBRSxZQUFZO1lBQ25CLFdBQVcsRUFDVCwyRUFBMkU7WUFDN0UsZUFBZSxFQUFFLElBQUk7U0FDdEI7S0FDRjtJQUNELFFBQVEsRUFBRTtRQUNSO1lBQ0UsR0FBRyxFQUFFLE1BQU07WUFDWCxLQUFLLEVBQUUsTUFBTTtZQUNiLFdBQVcsRUFDVCxnTUFBZ007WUFDbE0sSUFBSSxFQUFFLE9BQU87U0FDZDtRQUNEO1lBQ0UsR0FBRyxFQUFFLGVBQWU7WUFDcEIsS0FBSyxFQUFFLHFCQUFxQjtZQUM1QixXQUFXLEVBQ1QsMk1BQTJNO1lBQzdNLElBQUksRUFBRSxRQUFRO1NBQ2Y7S0FDRjtDQUNGLENBQUMsQ0FBQSJ9
@@ -3,20 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.renderFinancialDocument = void 0;
4
4
  const format_1 = require("./format");
5
5
  const html_utils_1 = require("./html-utils");
6
+ const layout_1 = require("./layout");
6
7
  const labelsByKind = {
7
8
  cancellation: {
8
- date: "Stornodatum",
9
- recipient: "Stornorechnung an",
9
+ number: "Stornonummer",
10
10
  title: "Stornorechnung",
11
11
  },
12
12
  credit_note: {
13
- date: "Gutschriftsdatum",
14
- recipient: "Gutschrift an",
13
+ number: "Gutschriftnummer",
15
14
  title: "Gutschrift",
16
15
  },
17
16
  invoice: {
18
- date: "Rechnungsdatum",
19
- recipient: "Rechnung an",
17
+ number: "Rechnungsnummer",
20
18
  title: "Rechnung",
21
19
  },
22
20
  };
@@ -26,7 +24,8 @@ const renderAddress = (input) => {
26
24
  return (0, html_utils_1.escapeHtml)(input.order.email);
27
25
  }
28
26
  return [
29
- [address.company, address.first_name, address.last_name]
27
+ address.company,
28
+ [address.first_name, address.last_name]
30
29
  .filter((part) => Boolean(part))
31
30
  .join(" "),
32
31
  address.address_1,
@@ -34,34 +33,43 @@ const renderAddress = (input) => {
34
33
  [address.postal_code, address.city]
35
34
  .filter((part) => Boolean(part))
36
35
  .join(" "),
37
- address.country_code?.toUpperCase(),
36
+ address.country_code ? (0, layout_1.formatCountryName)(address.country_code) : null,
38
37
  ]
39
38
  .filter((part) => Boolean(part))
40
39
  .map(html_utils_1.escapeHtml)
41
40
  .join("<br />");
42
41
  };
43
- const renderLines = (input, timeZone) => input.lines
44
- .map((line) => {
45
- const batchDetails = line.batch_allocations
46
- .map((allocation) => `<div class="batch">Charge: ${(0, html_utils_1.escapeHtml)(allocation.lot_number)} · MHD: ${(0, html_utils_1.escapeHtml)((0, format_1.formatDate)(allocation.expiry_date, { timeZone }))} · ${(0, html_utils_1.escapeHtml)(allocation.quantity)}</div>`)
42
+ /** "Charge: L-1, MHD: 30.06.2027"; the quantity only when a line has several batches. */
43
+ const renderBatchDetails = (line, timeZone) => {
44
+ const showQuantity = line.batch_allocations.length > 1;
45
+ return line.batch_allocations
46
+ .map((allocation) => {
47
+ const parts = [
48
+ `Charge: ${allocation.lot_number}`,
49
+ `MHD: ${(0, format_1.formatDocumentDate)(allocation.expiry_date, timeZone)}`,
50
+ showQuantity ? `Menge: ${allocation.quantity}` : null,
51
+ ].filter((part) => Boolean(part));
52
+ return `<div class="batch">${(0, html_utils_1.escapeHtml)(parts.join(", "))}</div>`;
53
+ })
47
54
  .join("");
48
- return `<tr>
49
- <td>
50
- <strong>${(0, html_utils_1.escapeHtml)(line.title)}</strong>
55
+ };
56
+ const renderLines = (input, timeZone) => input.lines
57
+ .map((line) => `<tr>
58
+ <td class="item">
59
+ <div class="item-title">${(0, html_utils_1.escapeHtml)(line.title)}</div>
51
60
  ${line.sku ? `<div class="sku">SKU: ${(0, html_utils_1.escapeHtml)(line.sku)}</div>` : ""}
52
- ${batchDetails}
61
+ ${renderBatchDetails(line, timeZone)}
53
62
  </td>
54
- <td class="number">${(0, html_utils_1.escapeHtml)(line.quantity)}</td>
55
- <td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: line.unit_price.amount, currencyCode: line.unit_price.currency_code }))}</td>
56
- <td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: line.total.amount, currencyCode: line.total.currency_code }))}</td>
57
- </tr>`;
58
- })
63
+ <td class="number quantity">${(0, html_utils_1.escapeHtml)(line.quantity)}</td>
64
+ <td class="number">${(0, html_utils_1.renderMoney)(line.unit_price)}</td>
65
+ <td class="number">${(0, html_utils_1.renderMoney)(line.total)}</td>
66
+ </tr>`)
59
67
  .join("");
68
+ const isExemptIntraCommunitySupply = (input) => input.order.tax_compliance?.exemption_wording ===
69
+ "steuerfreie_innergemeinschaftliche_lieferung";
60
70
  const renderTaxCompliance = (input) => {
61
71
  const evidence = input.order.tax_compliance;
62
- if (!evidence ||
63
- evidence.exemption_wording !==
64
- "steuerfreie_innergemeinschaftliche_lieferung") {
72
+ if (!evidence || !isExemptIntraCommunitySupply(input)) {
65
73
  return "";
66
74
  }
67
75
  return `<section class="tax-compliance">
@@ -72,16 +80,18 @@ const renderTaxCompliance = (input) => {
72
80
  </section>`;
73
81
  };
74
82
  const renderDiscountTotal = (input) => {
75
- const { amount, currency_code: currencyCode } = input.totals.discount_total;
76
- const displayAmount = input.document.kind === "invoice" && Number(amount) > 0
77
- ? `-${amount}`
78
- : amount;
79
- return (0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: displayAmount, currencyCode }));
83
+ const discount = input.totals.discount_total;
84
+ const displayAmount = input.document.kind === "invoice" && Number(discount.amount) > 0
85
+ ? `-${discount.amount}`
86
+ : discount.amount;
87
+ return (0, html_utils_1.renderMoney)(discount, displayAmount);
80
88
  };
81
89
  const formatTaxRate = (rate) => new Intl.NumberFormat(format_1.DEFAULT_FORMAT_LOCALE, {
82
90
  maximumFractionDigits: 2,
83
91
  style: "percent",
84
92
  }).format(rate / 100);
93
+ /** One totals row below the Menge/Einzelpreis columns; the amount sits under "Summe". */
94
+ const renderTotalRow = (label, value, className) => `<tr${className ? ` class="${className}"` : ""}><td class="spacer"></td><td class="label" colspan="2">${(0, html_utils_1.escapeHtml)(label)}</td><td class="number">${value}</td></tr>`;
85
95
  const renderTaxRows = (input) => {
86
96
  const { tax_breakdown: breakdown, tax_total: taxTotal } = input.totals;
87
97
  const rows = breakdown.length > 0
@@ -91,16 +101,17 @@ const renderTaxRows = (input) => {
91
101
  }))
92
102
  : [{ label: "Umsatzsteuer", money: taxTotal }];
93
103
  return rows
94
- .map(({ label, money }) => `<tr><td>${(0, html_utils_1.escapeHtml)(label)}</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: money.amount, currencyCode: money.currency_code }))}</td></tr>`)
104
+ .map(({ label, money }) => renderTotalRow(label, (0, html_utils_1.renderMoney)(money)))
95
105
  .join("");
96
106
  };
107
+ /** Only invoices ask for payment; cancellations and credit notes do not. */
108
+ const renderPaymentTerms = (input) => input.document.kind === "invoice" && input.settings.payment_terms
109
+ ? `<section class="payment-terms">${(0, html_utils_1.escapeHtml)(input.settings.payment_terms)}</section>`
110
+ : "";
97
111
  const renderFinancialDocument = (input, layout, timeZone) => {
98
112
  const labels = labelsByKind[input.document.kind];
99
113
  const metadata = [
100
- {
101
- label: labels.date,
102
- value: (0, format_1.formatDate)(input.document.issued_at, { timeZone }),
103
- },
114
+ { label: labels.number, value: input.document.number },
104
115
  {
105
116
  label: "Bestellung",
106
117
  value: (0, html_utils_1.formatOrderReference)(input.order.display_id),
@@ -112,31 +123,38 @@ const renderFinancialDocument = (input, layout, timeZone) => {
112
123
  value: input.document.source_document_number ?? "-",
113
124
  });
114
125
  }
115
- const body = `<section class="recipient">
116
- <h2>${labels.recipient}</h2>
117
- ${renderAddress(input)}
118
- </section>
119
- ${renderTaxCompliance(input)}
120
- <table>
121
- <thead><tr><th>Artikel</th><th class="number">Menge</th><th class="number">Einzelpreis</th><th class="number">Summe</th></tr></thead>
122
- <tbody>${renderLines(input, timeZone)}</tbody>
123
- </table>
124
- <table class="totals">
125
- <tbody>
126
- <tr><td>Zwischensumme</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: input.totals.subtotal.amount, currencyCode: input.totals.subtotal.currency_code }))}</td></tr>
127
- <tr><td>Versand</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: input.totals.shipping_total.amount, currencyCode: input.totals.shipping_total.currency_code }))}</td></tr>
128
- <tr><td>Rabatt</td><td class="number">${renderDiscountTotal(input)}</td></tr>
126
+ if (input.order.tax_compliance && isExemptIntraCommunitySupply(input)) {
127
+ metadata.push({
128
+ label: "Kunden-UID",
129
+ value: input.order.tax_compliance.customer_vat_number,
130
+ });
131
+ }
132
+ metadata.push({
133
+ label: "Datum",
134
+ value: (0, format_1.formatDocumentDate)(input.document.issued_at, timeZone),
135
+ });
136
+ const { totals } = input;
137
+ const body = `<table class="items financial-items">
138
+ <thead><tr><th class="item">Artikel</th><th class="number quantity">Menge</th><th class="number">Einzelpreis</th><th class="number">Summe</th></tr></thead>
139
+ <tbody class="lines">${renderLines(input, timeZone)}</tbody>
140
+ <tbody class="totals">
141
+ ${renderTotalRow("Zwischensumme", (0, html_utils_1.renderMoney)(totals.subtotal))}
142
+ ${renderTotalRow("Versand", (0, html_utils_1.renderMoney)(totals.shipping_total))}
143
+ ${renderTotalRow("Rabatt", renderDiscountTotal(input))}
129
144
  ${renderTaxRows(input)}
130
- <tr><td>Gesamt</td><td class="number">${(0, html_utils_1.escapeHtml)((0, format_1.formatMoney)({ amount: input.totals.total.amount, currencyCode: input.totals.total.currency_code }))}</td></tr>
145
+ ${renderTotalRow("Gesamt", (0, html_utils_1.renderMoney)(totals.total), "grand-total")}
131
146
  </tbody>
132
- </table>`;
147
+ </table>
148
+ ${renderTaxCompliance(input)}
149
+ ${renderPaymentTerms(input)}`;
133
150
  return layout({
134
151
  body,
135
152
  documentTitle: labels.title,
136
153
  metadata,
137
154
  number: input.document.number,
138
155
  pageTitle: labels.title,
156
+ recipient: renderAddress(input),
139
157
  });
140
158
  };
141
159
  exports.renderFinancialDocument = renderFinancialDocument;
142
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluYW5jaWFsLWRvY3VtZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2RvY3VtZW50cy90ZW1wbGF0ZXMvZmluYW5jaWFsLWRvY3VtZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLHFDQUF5RTtBQUN6RSw2Q0FBK0Q7QUFTL0QsTUFBTSxZQUFZLEdBQUc7SUFDbkIsWUFBWSxFQUFFO1FBQ1osSUFBSSxFQUFFLGFBQWE7UUFDbkIsU0FBUyxFQUFFLG1CQUFtQjtRQUM5QixLQUFLLEVBQUUsZ0JBQWdCO0tBQ3hCO0lBQ0QsV0FBVyxFQUFFO1FBQ1gsSUFBSSxFQUFFLGtCQUFrQjtRQUN4QixTQUFTLEVBQUUsZUFBZTtRQUMxQixLQUFLLEVBQUUsWUFBWTtLQUNwQjtJQUNELE9BQU8sRUFBRTtRQUNQLElBQUksRUFBRSxnQkFBZ0I7UUFDdEIsU0FBUyxFQUFFLGFBQWE7UUFDeEIsS0FBSyxFQUFFLFVBQVU7S0FDbEI7Q0FJRixDQUFBO0FBRUQsTUFBTSxhQUFhLEdBQUcsQ0FBQyxLQUE0QixFQUFVLEVBQUU7SUFDN0QsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUE7SUFDM0MsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2IsT0FBTyxJQUFBLHVCQUFVLEVBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUN0QyxDQUFDO0lBRUQsT0FBTztRQUNMLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUM7YUFDckQsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFrQixFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQy9DLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDWixPQUFPLENBQUMsU0FBUztRQUNqQixPQUFPLENBQUMsU0FBUztRQUNqQixDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQzthQUNoQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQWtCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUNaLE9BQU8sQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFO0tBQ3BDO1NBQ0UsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFrQixFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQy9DLEdBQUcsQ0FBQyx1QkFBVSxDQUFDO1NBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQ25CLENBQUMsQ0FBQTtBQUVELE1BQU0sV0FBVyxHQUFHLENBQUMsS0FBNEIsRUFBRSxRQUFnQixFQUFVLEVBQUUsQ0FDN0UsS0FBSyxDQUFDLEtBQUs7S0FDUixHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtJQUNaLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxpQkFBaUI7U0FDeEMsR0FBRyxDQUNGLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FDYiw4QkFBOEIsSUFBQSx1QkFBVSxFQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsV0FBVyxJQUFBLHVCQUFVLEVBQUMsSUFBQSxtQkFBVSxFQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLE1BQU0sSUFBQSx1QkFBVSxFQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUN0TDtTQUNBLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUVYLE9BQU87O29CQUVPLElBQUEsdUJBQVUsRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQzlCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLHlCQUF5QixJQUFBLHVCQUFVLEVBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDckUsWUFBWTs7NkJBRUssSUFBQSx1QkFBVSxFQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7NkJBQ3pCLElBQUEsdUJBQVUsRUFBQyxJQUFBLG9CQUFXLEVBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQzs2QkFDeEcsSUFBQSx1QkFBVSxFQUFDLElBQUEsb0JBQVcsRUFBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1lBQy9HLENBQUE7QUFDUixDQUFDLENBQUM7S0FDRCxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7QUFFYixNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBNEIsRUFBVSxFQUFFO0lBQ25FLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFBO0lBQzNDLElBQ0UsQ0FBQyxRQUFRO1FBQ1QsUUFBUSxDQUFDLGlCQUFpQjtZQUN4Qiw4Q0FBOEMsRUFDaEQsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFBO0lBQ1gsQ0FBQztJQUVELE9BQU87O2dCQUVPLElBQUEsdUJBQVUsRUFBQyxRQUFRLENBQUMscUJBQXFCLENBQUM7d0JBQ2xDLElBQUEsdUJBQVUsRUFBQyxRQUFRLENBQUMsbUJBQW1CLENBQUM7O2VBRWpELENBQUE7QUFDZixDQUFDLENBQUE7QUFFRCxNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBNEIsRUFBVSxFQUFFO0lBQ25FLE1BQU0sRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFBO0lBQzNFLE1BQU0sYUFBYSxHQUNqQixLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFDckQsQ0FBQyxDQUFDLElBQUksTUFBTSxFQUFFO1FBQ2QsQ0FBQyxDQUFDLE1BQU0sQ0FBQTtJQUVaLE9BQU8sSUFBQSx1QkFBVSxFQUFDLElBQUEsb0JBQVcsRUFBQyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFBO0FBQ3pFLENBQUMsQ0FBQTtBQUVELE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBWSxFQUFVLEVBQUUsQ0FDN0MsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLDhCQUFxQixFQUFFO0lBQzNDLHFCQUFxQixFQUFFLENBQUM7SUFDeEIsS0FBSyxFQUFFLFNBQVM7Q0FDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUE7QUFFdkIsTUFBTSxhQUFhLEdBQUcsQ0FBQyxLQUE0QixFQUFVLEVBQUU7SUFDN0QsTUFBTSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUE7SUFDdEUsTUFBTSxJQUFJLEdBQ1IsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3hCLEtBQUssRUFBRSxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNuRCxLQUFLLEVBQUUsS0FBSyxDQUFDLFNBQVM7U0FDdkIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFBO0lBRWxELE9BQU8sSUFBSTtTQUNSLEdBQUcsQ0FDRixDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FDbkIsV0FBVyxJQUFBLHVCQUFVLEVBQUMsS0FBSyxDQUFDLDJCQUEyQixJQUFBLHVCQUFVLEVBQUMsSUFBQSxvQkFBVyxFQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FDMUo7U0FDQSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7QUFDYixDQUFDLENBQUE7QUFFTSxNQUFNLHVCQUF1QixHQUFHLENBQ3JDLEtBQTRCLEVBQzVCLE1BQXNCLEVBQ3RCLFFBQWdCLEVBQ1IsRUFBRTtJQUNWLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2hELE1BQU0sUUFBUSxHQUFHO1FBQ2Y7WUFDRSxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUk7WUFDbEIsS0FBSyxFQUFFLElBQUEsbUJBQVUsRUFBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDO1NBQzFEO1FBQ0Q7WUFDRSxLQUFLLEVBQUUsWUFBWTtZQUNuQixLQUFLLEVBQUUsSUFBQSxpQ0FBb0IsRUFBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztTQUNwRDtLQUNGLENBQUE7SUFFRCxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3RDLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFDWixLQUFLLEVBQUUsbUJBQW1CO1lBQzFCLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLHNCQUFzQixJQUFJLEdBQUc7U0FDcEQsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHO1lBQ0gsTUFBTSxDQUFDLFNBQVM7UUFDcEIsYUFBYSxDQUFDLEtBQUssQ0FBQzs7TUFFdEIsbUJBQW1CLENBQUMsS0FBSyxDQUFDOzs7ZUFHakIsV0FBVyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7Ozs7dURBSVksSUFBQSx1QkFBVSxFQUFDLElBQUEsb0JBQVcsRUFBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7aURBQzFILElBQUEsdUJBQVUsRUFBQyxJQUFBLG9CQUFXLEVBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO2dEQUNqSSxtQkFBbUIsQ0FBQyxLQUFLLENBQUM7VUFDaEUsYUFBYSxDQUFDLEtBQUssQ0FBQztnREFDa0IsSUFBQSx1QkFBVSxFQUFDLElBQUEsb0JBQVcsRUFBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7O2FBRWpKLENBQUE7SUFFWCxPQUFPLE1BQU0sQ0FBQztRQUNaLElBQUk7UUFDSixhQUFhLEVBQUUsTUFBTSxDQUFDLEtBQUs7UUFDM0IsUUFBUTtRQUNSLE1BQU0sRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU07UUFDN0IsU0FBUyxFQUFFLE1BQU0sQ0FBQyxLQUFLO0tBQ3hCLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQTtBQWxEWSxRQUFBLHVCQUF1QiwyQkFrRG5DIn0=
160
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluYW5jaWFsLWRvY3VtZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2RvY3VtZW50cy90ZW1wbGF0ZXMvZmluYW5jaWFsLWRvY3VtZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQU1BLHFDQUFvRTtBQUNwRSw2Q0FBNEU7QUFDNUUscUNBQWlFO0FBT2pFLE1BQU0sWUFBWSxHQUFHO0lBQ25CLFlBQVksRUFBRTtRQUNaLE1BQU0sRUFBRSxjQUFjO1FBQ3RCLEtBQUssRUFBRSxnQkFBZ0I7S0FDeEI7SUFDRCxXQUFXLEVBQUU7UUFDWCxNQUFNLEVBQUUsa0JBQWtCO1FBQzFCLEtBQUssRUFBRSxZQUFZO0tBQ3BCO0lBQ0QsT0FBTyxFQUFFO1FBQ1AsTUFBTSxFQUFFLGlCQUFpQjtRQUN6QixLQUFLLEVBQUUsVUFBVTtLQUNsQjtDQUlGLENBQUE7QUFFRCxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQTRCLEVBQVUsRUFBRTtJQUM3RCxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQTtJQUMzQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFPLElBQUEsdUJBQVUsRUFBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3RDLENBQUM7SUFFRCxPQUFPO1FBQ0wsT0FBTyxDQUFDLE9BQU87UUFDZixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQzthQUNwQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQWtCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUNaLE9BQU8sQ0FBQyxTQUFTO1FBQ2pCLE9BQU8sQ0FBQyxTQUFTO1FBQ2pCLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDO2FBQ2hDLE1BQU0sQ0FBQyxD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
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatDate = exports.formatMoney = exports.DEFAULT_FORMAT_LOCALE = void 0;
3
+ exports.formatDocumentDate = exports.formatMoneyParts = exports.formatDate = exports.formatMoney = exports.DEFAULT_FORMAT_LOCALE = void 0;
4
4
  exports.DEFAULT_FORMAT_LOCALE = "de-AT";
5
5
  const formatMoney = ({ amount, currencyCode }, { locale = exports.DEFAULT_FORMAT_LOCALE } = {}) => {
6
6
  const numericAmount = Number(amount);
@@ -28,4 +28,46 @@ const formatDate = (value, { locale = exports.DEFAULT_FORMAT_LOCALE, options, ti
28
28
  return new Intl.DateTimeFormat(locale, { timeZone, ...options }).format(date);
29
29
  };
30
30
  exports.formatDate = formatDate;
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2RvY3VtZW50cy90ZW1wbGF0ZXMvZm9ybWF0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFhLFFBQUEscUJBQXFCLEdBQUcsT0FBTyxDQUFBO0FBV3JDLE1BQU0sV0FBVyxHQUFHLENBQ3pCLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBb0IsRUFDMUMsRUFBRSxNQUFNLEdBQUcsNkJBQXFCLEtBQXlCLEVBQUUsRUFDbkQsRUFBRTtJQUNWLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNwQyxNQUFNLHNCQUFzQixHQUFHLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUN6RCxNQUFNLFFBQVEsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxzQkFBc0IsRUFBRSxDQUFBO0lBRTlELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7UUFDcEMsT0FBTyxRQUFRLENBQUE7SUFDakIsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILE9BQU8sSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRTtZQUNuQyxRQUFRLEVBQUUsc0JBQXNCO1lBQ2hDLEtBQUssRUFBRSxVQUFVO1NBQ2xCLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDMUIsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7QUFDSCxDQUFDLENBQUE7QUFwQlksUUFBQSxXQUFXLGVBb0J2QjtBQVNNLE1BQU0sVUFBVSxHQUFHLENBQ3hCLEtBQW9CLEVBQ3BCLEVBQUUsTUFBTSxHQUFHLDZCQUFxQixFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQXFCLEVBQ2hFLEVBQUU7SUFDVixNQUFNLElBQUksR0FBRyxLQUFLLFlBQVksSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBRTVELElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3RCLENBQUM7SUFFRCxPQUFPLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxRQUFRLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQTtBQUMvRSxDQUFDLENBQUE7QUFYWSxRQUFBLFVBQVUsY0FXdEIifQ==
31
+ /**
32
+ * `formatMoney` split into currency and number, so a template can align the
33
+ * currency and the amount separately. Falls back to the whole
34
+ * `formatMoney` text as `amount`.
35
+ */
36
+ const formatMoneyParts = ({ amount, currencyCode }, { locale = exports.DEFAULT_FORMAT_LOCALE } = {}) => {
37
+ const numericAmount = Number(amount);
38
+ const fallback = {
39
+ currency: "",
40
+ amount: (0, exports.formatMoney)({ amount, currencyCode }, { locale }),
41
+ };
42
+ if (!Number.isFinite(numericAmount)) {
43
+ return fallback;
44
+ }
45
+ try {
46
+ const parts = new Intl.NumberFormat(locale, {
47
+ currency: currencyCode.toUpperCase(),
48
+ style: "currency",
49
+ }).formatToParts(numericAmount);
50
+ return {
51
+ currency: parts
52
+ .filter((part) => part.type === "currency")
53
+ .map((part) => part.value)
54
+ .join(""),
55
+ amount: parts
56
+ .filter((part) => part.type !== "currency" &&
57
+ !(part.type === "literal" && !part.value.trim()))
58
+ .map((part) => part.value)
59
+ .join(""),
60
+ };
61
+ }
62
+ catch {
63
+ return fallback;
64
+ }
65
+ };
66
+ exports.formatMoneyParts = formatMoneyParts;
67
+ /** A document date as "01.01.2027" in the given time zone. */
68
+ const formatDocumentDate = (value, timeZone) => (0, exports.formatDate)(value, {
69
+ timeZone,
70
+ options: { day: "2-digit", month: "2-digit", year: "numeric" },
71
+ });
72
+ exports.formatDocumentDate = formatDocumentDate;
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2RvY3VtZW50cy90ZW1wbGF0ZXMvZm9ybWF0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFhLFFBQUEscUJBQXFCLEdBQUcsT0FBTyxDQUFBO0FBV3JDLE1BQU0sV0FBVyxHQUFHLENBQ3pCLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBb0IsRUFDMUMsRUFBRSxNQUFNLEdBQUcsNkJBQXFCLEtBQXlCLEVBQUUsRUFDbkQsRUFBRTtJQUNWLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNwQyxNQUFNLHNCQUFzQixHQUFHLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUN6RCxNQUFNLFFBQVEsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxzQkFBc0IsRUFBRSxDQUFBO0lBRTlELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7UUFDcEMsT0FBTyxRQUFRLENBQUE7SUFDakIsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILE9BQU8sSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRTtZQUNuQyxRQUFRLEVBQUUsc0JBQXNCO1lBQ2hDLEtBQUssRUFBRSxVQUFVO1NBQ2xCLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDMUIsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7QUFDSCxDQUFDLENBQUE7QUFwQlksUUFBQSxXQUFXLGVBb0J2QjtBQVNNLE1BQU0sVUFBVSxHQUFHLENBQ3hCLEtBQW9CLEVBQ3BCLEVBQUUsTUFBTSxHQUFHLDZCQUFxQixFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQXFCLEVBQ2hFLEVBQUU7SUFDVixNQUFNLElBQUksR0FBRyxLQUFLLFlBQVksSUFBSSxDQUFDLENB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