@hartl-services/medusa-base 0.4.0 → 1.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.
- package/.medusa/server/src/admin/index.js +1517 -87
- package/.medusa/server/src/admin/index.mjs +1518 -88
- package/.medusa/server/src/api/admin/email/messages/[id]/resends/route.js +24 -0
- package/.medusa/server/src/api/admin/email/messages/[id]/route.js +12 -0
- package/.medusa/server/src/api/admin/email/messages/route.js +12 -0
- package/.medusa/server/src/api/admin/email/terms-versions/[id]/download/route.js +16 -0
- package/.medusa/server/src/api/admin/email/terms-versions/route.js +47 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/download/route.js +21 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/regenerate/route.js +38 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/regenerate/route.js +32 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/route.js +36 -0
- package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/download/route.js +24 -0
- package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/retry/route.js +44 -0
- package/.medusa/server/src/api/admin/orders/[id]/packing-lists/route.js +82 -0
- package/.medusa/server/src/api/document-download-response.js +16 -0
- package/.medusa/server/src/api/document-response.js +23 -0
- package/.medusa/server/src/api/files/[asset]/route.js +24 -0
- package/.medusa/server/src/api/files/file-response.js +43 -0
- package/.medusa/server/src/api/files/gateway-options.js +31 -0
- package/.medusa/server/src/api/files/private/[token]/route.js +29 -0
- package/.medusa/server/src/api/files/upload/[token]/route.js +66 -0
- package/.medusa/server/src/api/middlewares.js +168 -1
- package/.medusa/server/src/api/packing-list-response.js +22 -0
- package/.medusa/server/src/api/route.js +27 -0
- package/.medusa/server/src/api/store/documents/[id]/download/route.js +21 -0
- package/.medusa/server/src/api/store/documents/[id]/route.js +15 -0
- package/.medusa/server/src/api/store/documents/route.js +11 -0
- package/.medusa/server/src/api/terms-download-response.js +12 -0
- package/.medusa/server/src/documents/config/index.js +18 -0
- package/.medusa/server/src/documents/paths/documents.js +6 -0
- package/.medusa/server/src/documents/paths/index.js +18 -0
- package/.medusa/server/src/documents/plugin-features.js +24 -0
- package/.medusa/server/src/documents/schemas/documents.js +18 -0
- package/.medusa/server/src/documents/schemas/index.js +18 -0
- package/.medusa/server/src/documents/scripts/verify-documents-file-storage.js +55 -0
- package/.medusa/server/src/documents/templates/financial-document.js +142 -0
- package/.medusa/server/src/documents/templates/format.js +31 -0
- package/.medusa/server/src/documents/templates/html-factory.js +40 -0
- package/.medusa/server/src/documents/templates/html-utils.js +13 -0
- package/.medusa/server/src/documents/templates/layout.js +97 -0
- package/.medusa/server/src/documents/templates/packing-list.js +50 -0
- package/.medusa/server/src/documents/types/admin-api.js +3 -0
- package/.medusa/server/src/documents/types/document-summary.js +3 -0
- package/.medusa/server/src/documents/types/documents.js +3 -0
- package/.medusa/server/src/documents/types/html-factory.js +6 -0
- package/.medusa/server/src/documents/types/index.js +22 -0
- package/.medusa/server/src/documents/types/store-api.js +3 -0
- package/.medusa/server/src/documents/utils/document-merchant.js +22 -0
- package/.medusa/server/src/documents/utils/html-to-pdf.js +61 -0
- package/.medusa/server/src/documents/utils/private-file-storage.js +64 -0
- package/.medusa/server/src/documents/utils/resolve-services.js +7 -0
- package/.medusa/server/src/email/application/handle-invite-event.js +312 -0
- package/.medusa/server/src/email/application/handle-password-reset-event.js +354 -0
- package/.medusa/server/src/email/config/index.js +84 -0
- package/.medusa/server/src/email/config/notification-module.js +20 -0
- package/.medusa/server/src/email/domain/business-keys.js +50 -0
- package/.medusa/server/src/email/domain/documents-fact-fingerprint.js +7 -0
- package/.medusa/server/src/email/domain/event-schemas.js +36 -0
- package/.medusa/server/src/email/domain/failure-classification.js +53 -0
- package/.medusa/server/src/email/plugin-features.js +31 -0
- package/.medusa/server/src/email/rendering/default-templates.js +91 -0
- package/.medusa/server/src/email/rendering/render-email.js +37 -0
- package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +48 -0
- package/.medusa/server/src/email/types/email-kinds.js +18 -0
- package/.medusa/server/src/email/types/index.js +21 -0
- package/.medusa/server/src/email/types/shop-configuration.js +3 -0
- package/.medusa/server/src/email/types/smtp-configuration.js +3 -0
- package/.medusa/server/src/email/types/template-data.js +79 -0
- package/.medusa/server/src/files/config/index.js +256 -0
- package/.medusa/server/src/files/gateway/index.js +115 -0
- package/.medusa/server/src/files/types/index.js +6 -0
- package/.medusa/server/src/files/types/public.js +6 -0
- package/.medusa/server/src/jobs/document-fact-publication-reconciliation.js +18 -0
- package/.medusa/server/src/jobs/document-resolution-reconciliation.js +20 -0
- package/.medusa/server/src/jobs/packing-list-reconciliation.js +49 -0
- package/.medusa/server/src/jobs/reconcile-email-attempts.js +63 -0
- package/.medusa/server/src/jobs/reconcile-pending-email-messages.js +41 -0
- package/.medusa/server/src/jobs/retry-email-messages.js +27 -0
- package/.medusa/server/src/migration-scripts/dismiss-orphaned-cart-promotion-links.js +26 -0
- package/.medusa/server/src/modules/documents/domain/cancellation-snapshot.js +97 -0
- package/.medusa/server/src/modules/documents/domain/document-number.js +36 -0
- package/.medusa/server/src/modules/documents/domain/document-resolution.js +24 -0
- package/.medusa/server/src/modules/documents/domain/issuance-rules.js +37 -0
- package/.medusa/server/src/modules/documents/domain/merchant.js +86 -0
- package/.medusa/server/src/modules/documents/domain/options.js +40 -0
- package/.medusa/server/src/modules/documents/domain/packing-list.js +90 -0
- package/.medusa/server/src/modules/documents/domain/snapshot-normalization.js +17 -0
- package/.medusa/server/src/modules/documents/domain/tax-breakdown.js +66 -0
- package/.medusa/server/src/modules/documents/index.js +15 -0
- package/.medusa/server/src/modules/documents/loaders/assert-private-file-storage.js +20 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20260827061749.js +75 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20260830111207.js +28 -0
- package/.medusa/server/src/modules/documents/models/document-artifact.js +25 -0
- package/.medusa/server/src/modules/documents/models/document-number-sequence.js +29 -0
- package/.medusa/server/src/modules/documents/models/document.js +82 -0
- package/.medusa/server/src/modules/documents/models/order-cancellation-resolution.js +51 -0
- package/.medusa/server/src/modules/documents/models/packing-list-revision.js +36 -0
- package/.medusa/server/src/modules/documents/models/packing-list.js +27 -0
- package/.medusa/server/src/modules/documents/models/refund-document-resolution.js +66 -0
- package/.medusa/server/src/modules/documents/models/shipment-invoice-assignment.js +51 -0
- package/.medusa/server/src/modules/documents/models/shipment-invoice-coordinator.js +44 -0
- package/.medusa/server/src/modules/documents/service.js +1701 -0
- package/.medusa/server/src/modules/email/domain/attachment.js +25 -0
- package/.medusa/server/src/modules/email/domain/message-state.js +69 -0
- package/.medusa/server/src/modules/email/index.js +13 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260826173422.js +32 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260827172945.js +16 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260827194804.js +22 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260906195205.js +16 -0
- package/.medusa/server/src/modules/email/models/email-attempt.js +56 -0
- package/.medusa/server/src/modules/email/models/email-message.js +71 -0
- package/.medusa/server/src/modules/email/models/email-terms-version.js +37 -0
- package/.medusa/server/src/modules/email/service.js +1285 -0
- package/.medusa/server/src/providers/s3-cache/cache/atomic-write.js +25 -0
- package/.medusa/server/src/providers/s3-cache/cache/cache-manager.js +115 -0
- package/.medusa/server/src/providers/s3-cache/cache/keyed-lock.js +28 -0
- package/.medusa/server/src/providers/s3-cache/index.js +8 -0
- package/.medusa/server/src/providers/s3-cache/object-key.js +53 -0
- package/.medusa/server/src/providers/s3-cache/s3-cache-file.js +229 -0
- package/.medusa/server/src/providers/s3-cache/s3-object-store.js +86 -0
- package/.medusa/server/src/providers/smtp/index.js +8 -0
- package/.medusa/server/src/providers/smtp/service.js +236 -0
- package/.medusa/server/src/providers/smtp/types.js +11 -0
- package/.medusa/server/src/public/config.js +186 -0
- package/.medusa/server/src/public/gateway.js +19 -0
- package/.medusa/server/src/public/instrumentation.js +56 -0
- package/.medusa/server/src/public/shop-config.js +12 -0
- package/.medusa/server/src/public/shop-types.js +24 -0
- package/.medusa/server/src/shop-config/build-food-shop-config.js +248 -0
- package/.medusa/server/src/shop-config/options.js +71 -0
- package/.medusa/server/src/subscribers/affiliate-consignment-reminder-due.js +26 -0
- package/.medusa/server/src/subscribers/documents-order-canceled.js +24 -0
- package/.medusa/server/src/subscribers/documents-order-cancellation-ready.js +26 -0
- package/.medusa/server/src/subscribers/documents-refund-ready.js +24 -0
- package/.medusa/server/src/subscribers/documents-shipment-created.js +36 -0
- package/.medusa/server/src/subscribers/documents-shipment-invoice-assignment-decided.js +26 -0
- package/.medusa/server/src/subscribers/email-order-canceled.js +28 -0
- package/.medusa/server/src/subscribers/email-shipment-created.js +32 -0
- package/.medusa/server/src/subscribers/order-placed.js +27 -0
- package/.medusa/server/src/subscribers/packing-list-allocation-revised.js +32 -0
- package/.medusa/server/src/subscribers/packing-list-fulfillment-canceled.js +54 -0
- package/.medusa/server/src/subscribers/packing-list-fulfillment-created.js +31 -0
- package/.medusa/server/src/subscribers/password-reset.js +23 -0
- package/.medusa/server/src/subscribers/payment-refunded.js +38 -0
- package/.medusa/server/src/subscribers/return-received.js +27 -0
- package/.medusa/server/src/subscribers/return-requested.js +27 -0
- package/.medusa/server/src/subscribers/user-invite.js +23 -0
- package/.medusa/server/src/utils/cart-promotion-links.js +101 -0
- package/.medusa/server/src/workflows/documents/issue-cancellation-after-refund.js +246 -0
- package/.medusa/server/src/workflows/documents/issue-document.js +163 -0
- package/.medusa/server/src/workflows/documents/issue-invoice-after-shipment.js +521 -0
- package/.medusa/server/src/workflows/documents/issue-packing-list.js +384 -0
- package/.medusa/server/src/workflows/documents/publish-document-facts.js +53 -0
- package/.medusa/server/src/workflows/documents/reconcile-document-resolutions.js +48 -0
- package/.medusa/server/src/workflows/documents/reconcile-order-cancellation.js +92 -0
- package/.medusa/server/src/workflows/documents/regenerate-issued-document.js +61 -0
- package/.medusa/server/src/workflows/email/dispatch-email-message.js +299 -0
- package/.medusa/server/src/workflows/email/documents-required-facts.js +30 -0
- package/.medusa/server/src/workflows/email/prepare-affiliate-reminder-email.js +58 -0
- package/.medusa/server/src/workflows/email/prepare-order-canceled-email.js +64 -0
- package/.medusa/server/src/workflows/email/prepare-order-received-email.js +56 -0
- package/.medusa/server/src/workflows/email/prepare-refund-email.js +47 -0
- package/.medusa/server/src/workflows/email/prepare-return-email.js +75 -0
- package/.medusa/server/src/workflows/email/prepare-shipment-email.js +82 -0
- package/.medusa/server/src/workflows/email/retry-email-messages.js +31 -0
- package/.medusa/server/src/workflows/hooks/dismiss-deleted-promotion-cart-links.js +23 -0
- package/README.md +1619 -7
- package/dist/documents/config/index.d.ts +11 -0
- package/dist/documents/config/index.js +17 -0
- package/dist/documents/templates/financial-document.d.ts +3 -0
- package/dist/documents/templates/financial-document.js +141 -0
- package/dist/documents/templates/format.d.ts +16 -0
- package/dist/documents/templates/format.js +30 -0
- package/dist/documents/templates/html-factory.d.ts +11 -0
- package/dist/documents/templates/html-factory.js +39 -0
- package/dist/documents/templates/html-utils.d.ts +2 -0
- package/dist/documents/templates/html-utils.js +12 -0
- package/dist/documents/templates/layout.d.ts +17 -0
- package/dist/documents/templates/layout.js +96 -0
- package/dist/documents/templates/packing-list.d.ts +3 -0
- package/dist/documents/templates/packing-list.js +49 -0
- package/dist/documents/types/admin-api.d.ts +1 -0
- package/dist/documents/types/admin-api.js +2 -0
- package/dist/documents/types/document-summary.d.ts +1 -0
- package/dist/documents/types/document-summary.js +2 -0
- package/dist/documents/types/documents.d.ts +174 -0
- package/dist/documents/types/documents.js +2 -0
- package/dist/documents/types/html-factory.d.ts +7 -0
- package/dist/documents/types/html-factory.js +5 -0
- package/dist/documents/types/index.d.ts +5 -0
- package/dist/documents/types/index.js +21 -0
- package/dist/documents/types/store-api.d.ts +1 -0
- package/dist/documents/types/store-api.js +2 -0
- package/dist/email/config/index.d.ts +17 -0
- package/dist/email/config/index.js +83 -0
- package/dist/email/config/notification-module.d.ts +22 -0
- package/dist/email/config/notification-module.js +19 -0
- package/dist/email/types/email-kinds.d.ts +15 -0
- package/dist/email/types/email-kinds.js +17 -0
- package/dist/email/types/index.d.ts +4 -0
- package/dist/email/types/index.js +20 -0
- package/dist/email/types/shop-configuration.d.ts +43 -0
- package/dist/email/types/shop-configuration.js +2 -0
- package/dist/email/types/smtp-configuration.d.ts +9 -0
- package/dist/email/types/smtp-configuration.js +2 -0
- package/dist/email/types/template-data.d.ts +100 -0
- package/dist/email/types/template-data.js +78 -0
- package/dist/files/config/index.d.ts +32 -0
- package/dist/files/config/index.js +255 -0
- package/dist/files/gateway/index.d.ts +30 -0
- package/dist/files/gateway/index.js +114 -0
- package/dist/files/types/index.d.ts +2 -0
- package/dist/files/types/index.js +5 -0
- package/dist/files/types/public.d.ts +90 -0
- package/dist/files/types/public.js +5 -0
- package/dist/modules/documents/domain/merchant.d.ts +22 -0
- package/dist/modules/documents/domain/merchant.js +85 -0
- package/dist/modules/documents/domain/options.d.ts +34 -0
- package/dist/modules/documents/domain/options.js +39 -0
- package/dist/public/config.d.ts +59 -0
- package/dist/public/config.js +185 -0
- package/dist/public/gateway.d.ts +2 -0
- package/dist/public/gateway.js +18 -0
- package/dist/public/instrumentation.d.ts +12 -0
- package/dist/public/instrumentation.js +55 -0
- package/dist/public/shop-config.d.ts +8 -0
- package/dist/public/shop-config.js +11 -0
- package/dist/public/shop-types.d.ts +7 -0
- package/dist/public/shop-types.js +23 -0
- package/dist/public/types.d.ts +17 -1
- package/dist/shop-config/build-food-shop-config.d.ts +44 -0
- package/dist/shop-config/build-food-shop-config.js +247 -0
- package/dist/shop-config/options.d.ts +41 -0
- package/dist/shop-config/options.js +70 -0
- package/package.json +48 -5
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documents part of the `@hartl-services/medusa-base/config` entry point: values a shop
|
|
3
|
+
* needs in `medusa-config.ts` or in a test, without loading the plugin itself.
|
|
4
|
+
*/
|
|
5
|
+
export { createDefaultDocumentHtmlFactory } from "../templates/html-factory";
|
|
6
|
+
/**
|
|
7
|
+
* Placeholder environment values for `medusa build`. `medusa-config.ts` is
|
|
8
|
+
* evaluated at build time, where the runtime-only Documents PDF executable
|
|
9
|
+
* is not set; spread these under the real environment during the build.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DOCUMENTS_BUILD_PLACEHOLDERS: Readonly<Record<string, string>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DOCUMENTS_BUILD_PLACEHOLDERS = exports.createDefaultDocumentHtmlFactory = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Documents part of the `@hartl-services/medusa-base/config` entry point: values a shop
|
|
6
|
+
* needs in `medusa-config.ts` or in a test, without loading the plugin itself.
|
|
7
|
+
*/
|
|
8
|
+
var html_factory_1 = require("../templates/html-factory");
|
|
9
|
+
Object.defineProperty(exports, "createDefaultDocumentHtmlFactory", { enumerable: true, get: function () { return html_factory_1.createDefaultDocumentHtmlFactory; } });
|
|
10
|
+
/**
|
|
11
|
+
* Placeholder environment values for `medusa build`. `medusa-config.ts` is
|
|
12
|
+
* evaluated at build time, where the runtime-only Documents PDF executable
|
|
13
|
+
* is not set; spread these under the real environment during the build.
|
|
14
|
+
*/
|
|
15
|
+
exports.DOCUMENTS_BUILD_PLACEHOLDERS = {
|
|
16
|
+
DOCUMENT_PDF_EXECUTABLE: "google-chrome",
|
|
17
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderFinancialDocument = void 0;
|
|
4
|
+
const format_1 = require("./format");
|
|
5
|
+
const html_utils_1 = require("./html-utils");
|
|
6
|
+
const labelsByKind = {
|
|
7
|
+
cancellation: {
|
|
8
|
+
date: "Stornodatum",
|
|
9
|
+
recipient: "Stornorechnung an",
|
|
10
|
+
title: "Stornorechnung",
|
|
11
|
+
},
|
|
12
|
+
credit_note: {
|
|
13
|
+
date: "Gutschriftsdatum",
|
|
14
|
+
recipient: "Gutschrift an",
|
|
15
|
+
title: "Gutschrift",
|
|
16
|
+
},
|
|
17
|
+
invoice: {
|
|
18
|
+
date: "Rechnungsdatum",
|
|
19
|
+
recipient: "Rechnung an",
|
|
20
|
+
title: "Rechnung",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const renderAddress = (input) => {
|
|
24
|
+
const address = input.order.billing_address;
|
|
25
|
+
if (!address) {
|
|
26
|
+
return (0, html_utils_1.escapeHtml)(input.order.email);
|
|
27
|
+
}
|
|
28
|
+
return [
|
|
29
|
+
[address.company, address.first_name, address.last_name]
|
|
30
|
+
.filter((part) => Boolean(part))
|
|
31
|
+
.join(" "),
|
|
32
|
+
address.address_1,
|
|
33
|
+
address.address_2,
|
|
34
|
+
[address.postal_code, address.city]
|
|
35
|
+
.filter((part) => Boolean(part))
|
|
36
|
+
.join(" "),
|
|
37
|
+
address.country_code?.toUpperCase(),
|
|
38
|
+
]
|
|
39
|
+
.filter((part) => Boolean(part))
|
|
40
|
+
.map(html_utils_1.escapeHtml)
|
|
41
|
+
.join("<br />");
|
|
42
|
+
};
|
|
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>`)
|
|
47
|
+
.join("");
|
|
48
|
+
return `<tr>
|
|
49
|
+
<td>
|
|
50
|
+
<strong>${(0, html_utils_1.escapeHtml)(line.title)}</strong>
|
|
51
|
+
${line.sku ? `<div class="sku">SKU: ${(0, html_utils_1.escapeHtml)(line.sku)}</div>` : ""}
|
|
52
|
+
${batchDetails}
|
|
53
|
+
</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
|
+
})
|
|
59
|
+
.join("");
|
|
60
|
+
const renderTaxCompliance = (input) => {
|
|
61
|
+
const evidence = input.order.tax_compliance;
|
|
62
|
+
if (!evidence ||
|
|
63
|
+
evidence.exemption_wording !==
|
|
64
|
+
"steuerfreie_innergemeinschaftliche_lieferung") {
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
return `<section class="tax-compliance">
|
|
68
|
+
<h2>Steuerliche Angaben</h2>
|
|
69
|
+
<strong>${(0, html_utils_1.escapeHtml)(evidence.customer_company_name)}</strong><br />
|
|
70
|
+
UID des Kunden: ${(0, html_utils_1.escapeHtml)(evidence.customer_vat_number)}<br />
|
|
71
|
+
Steuerfreie innergemeinschaftliche Lieferung
|
|
72
|
+
</section>`;
|
|
73
|
+
};
|
|
74
|
+
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 }));
|
|
80
|
+
};
|
|
81
|
+
const formatTaxRate = (rate) => new Intl.NumberFormat(format_1.DEFAULT_FORMAT_LOCALE, {
|
|
82
|
+
maximumFractionDigits: 2,
|
|
83
|
+
style: "percent",
|
|
84
|
+
}).format(rate / 100);
|
|
85
|
+
const renderTaxRows = (input) => {
|
|
86
|
+
const { tax_breakdown: breakdown, tax_total: taxTotal } = input.totals;
|
|
87
|
+
const rows = breakdown.length > 0
|
|
88
|
+
? breakdown.map((entry) => ({
|
|
89
|
+
label: `${entry.name} ${formatTaxRate(entry.rate)}`,
|
|
90
|
+
money: entry.tax_total,
|
|
91
|
+
}))
|
|
92
|
+
: [{ label: "Umsatzsteuer", money: taxTotal }];
|
|
93
|
+
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>`)
|
|
95
|
+
.join("");
|
|
96
|
+
};
|
|
97
|
+
const renderFinancialDocument = (input, layout, timeZone) => {
|
|
98
|
+
const labels = labelsByKind[input.document.kind];
|
|
99
|
+
const metadata = [
|
|
100
|
+
{
|
|
101
|
+
label: labels.date,
|
|
102
|
+
value: (0, format_1.formatDate)(input.document.issued_at, { timeZone }),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
label: "Bestellung",
|
|
106
|
+
value: (0, html_utils_1.formatOrderReference)(input.order.display_id),
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
if (input.document.kind !== "invoice") {
|
|
110
|
+
metadata.push({
|
|
111
|
+
label: "Ursprungsrechnung",
|
|
112
|
+
value: input.document.source_document_number ?? "-",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
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>
|
|
129
|
+
${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>
|
|
131
|
+
</tbody>
|
|
132
|
+
</table>`;
|
|
133
|
+
return layout({
|
|
134
|
+
body,
|
|
135
|
+
documentTitle: labels.title,
|
|
136
|
+
metadata,
|
|
137
|
+
number: input.document.number,
|
|
138
|
+
pageTitle: labels.title,
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
exports.renderFinancialDocument = renderFinancialDocument;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const DEFAULT_FORMAT_LOCALE = "de-AT";
|
|
2
|
+
export type FormatMoneyInput = {
|
|
3
|
+
readonly amount: number | string;
|
|
4
|
+
readonly currencyCode: string;
|
|
5
|
+
};
|
|
6
|
+
export type FormatMoneyOptions = {
|
|
7
|
+
readonly locale?: Intl.LocalesArgument;
|
|
8
|
+
};
|
|
9
|
+
export declare const formatMoney: ({ amount, currencyCode }: FormatMoneyInput, { locale }?: FormatMoneyOptions) => string;
|
|
10
|
+
export type FormatDateOptions = {
|
|
11
|
+
readonly locale?: Intl.LocalesArgument;
|
|
12
|
+
/** IANA time zone the date is shown in; there is deliberately no default. */
|
|
13
|
+
readonly timeZone: string;
|
|
14
|
+
readonly options?: Omit<Intl.DateTimeFormatOptions, "timeZone">;
|
|
15
|
+
};
|
|
16
|
+
export declare const formatDate: (value: string | Date, { locale, options, timeZone }: FormatDateOptions) => string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatDate = exports.formatMoney = exports.DEFAULT_FORMAT_LOCALE = void 0;
|
|
4
|
+
exports.DEFAULT_FORMAT_LOCALE = "de-AT";
|
|
5
|
+
const formatMoney = ({ amount, currencyCode }, { locale = exports.DEFAULT_FORMAT_LOCALE } = {}) => {
|
|
6
|
+
const numericAmount = Number(amount);
|
|
7
|
+
const normalizedCurrencyCode = currencyCode.toUpperCase();
|
|
8
|
+
const fallback = `${String(amount)} ${normalizedCurrencyCode}`;
|
|
9
|
+
if (!Number.isFinite(numericAmount)) {
|
|
10
|
+
return fallback;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
return new Intl.NumberFormat(locale, {
|
|
14
|
+
currency: normalizedCurrencyCode,
|
|
15
|
+
style: "currency",
|
|
16
|
+
}).format(numericAmount);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return fallback;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
exports.formatMoney = formatMoney;
|
|
23
|
+
const formatDate = (value, { locale = exports.DEFAULT_FORMAT_LOCALE, options, timeZone }) => {
|
|
24
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
25
|
+
if (Number.isNaN(date.getTime())) {
|
|
26
|
+
return String(value);
|
|
27
|
+
}
|
|
28
|
+
return new Intl.DateTimeFormat(locale, { timeZone, ...options }).format(date);
|
|
29
|
+
};
|
|
30
|
+
exports.formatDate = formatDate;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DocumentHtmlFactory } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* The plugin's default document markup (German, locale de-AT). The legal
|
|
4
|
+
* sender comes with every render input (`input.merchant`, the base plugin's
|
|
5
|
+
* shop master data). `timeZone` is the IANA time zone in which printed dates
|
|
6
|
+
* are shown; the plugin passes its resolved `numbering.timeZone` so the date
|
|
7
|
+
* on a document matches the period its number was allocated in.
|
|
8
|
+
*/
|
|
9
|
+
export declare const createDefaultDocumentHtmlFactory: ({ timeZone, }: {
|
|
10
|
+
timeZone: string;
|
|
11
|
+
}) => DocumentHtmlFactory;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @medusajs/use-medusa-error-not-generic-error -- Invalid render inputs are programmer errors, not HTTP responses. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.createDefaultDocumentHtmlFactory = void 0;
|
|
5
|
+
const layout_1 = require("./layout");
|
|
6
|
+
const financial_document_1 = require("./financial-document");
|
|
7
|
+
const packing_list_1 = require("./packing-list");
|
|
8
|
+
/**
|
|
9
|
+
* The plugin's default document markup (German, locale de-AT). The legal
|
|
10
|
+
* sender comes with every render input (`input.merchant`, the base plugin's
|
|
11
|
+
* shop master data). `timeZone` is the IANA time zone in which printed dates
|
|
12
|
+
* are shown; the plugin passes its resolved `numbering.timeZone` so the date
|
|
13
|
+
* on a document matches the period its number was allocated in.
|
|
14
|
+
*/
|
|
15
|
+
const createDefaultDocumentHtmlFactory = ({ timeZone, }) => {
|
|
16
|
+
return (input) => {
|
|
17
|
+
const kind = input.document.kind;
|
|
18
|
+
switch (kind) {
|
|
19
|
+
case "invoice":
|
|
20
|
+
case "cancellation":
|
|
21
|
+
case "credit_note":
|
|
22
|
+
if ("totals" in input) {
|
|
23
|
+
return (0, financial_document_1.renderFinancialDocument)(input, (0, layout_1.createDocumentLayout)(input.merchant, true), timeZone);
|
|
24
|
+
}
|
|
25
|
+
break;
|
|
26
|
+
case "packing_list":
|
|
27
|
+
if ("fulfillment" in input) {
|
|
28
|
+
return (0, packing_list_1.renderPackingList)(input, (0, layout_1.createDocumentLayout)(input.merchant, false), timeZone);
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
31
|
+
default: {
|
|
32
|
+
const unsupportedKind = kind;
|
|
33
|
+
throw new TypeError(`Unsupported document kind: ${unsupportedKind}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
throw new TypeError(`Invalid input for document kind: ${kind}`);
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
exports.createDefaultDocumentHtmlFactory = createDefaultDocumentHtmlFactory;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatOrderReference = exports.escapeHtml = void 0;
|
|
4
|
+
const escapeHtml = (value) => String(value ?? "")
|
|
5
|
+
.replaceAll("&", "&")
|
|
6
|
+
.replaceAll("<", "<")
|
|
7
|
+
.replaceAll(">", ">")
|
|
8
|
+
.replaceAll('"', """)
|
|
9
|
+
.replaceAll("'", "'");
|
|
10
|
+
exports.escapeHtml = escapeHtml;
|
|
11
|
+
const formatOrderReference = (displayId) => displayId === null ? "-" : `#${displayId}`;
|
|
12
|
+
exports.formatOrderReference = formatOrderReference;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DocumentMerchant } from "../types";
|
|
2
|
+
export type DocumentLayoutInput = {
|
|
3
|
+
readonly body: string;
|
|
4
|
+
readonly documentTitle: string;
|
|
5
|
+
readonly metadata: readonly {
|
|
6
|
+
readonly label: string;
|
|
7
|
+
readonly value: string;
|
|
8
|
+
}[];
|
|
9
|
+
readonly number: string;
|
|
10
|
+
readonly pageTitle: string;
|
|
11
|
+
};
|
|
12
|
+
export type DocumentLayout = (input: DocumentLayoutInput) => string;
|
|
13
|
+
/**
|
|
14
|
+
* `includeLegalDetails` adds UID, company register, contact and bank details
|
|
15
|
+
* to the footer (financial documents); packing lists show only the name.
|
|
16
|
+
*/
|
|
17
|
+
export declare const createDocumentLayout: (merchant: DocumentMerchant, includeLegalDetails: boolean) => DocumentLayout;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDocumentLayout = void 0;
|
|
4
|
+
const html_utils_1 = require("./html-utils");
|
|
5
|
+
const formatCountryName = (countryCode) => new Intl.DisplayNames("de", { type: "region" }).of(countryCode.toUpperCase()) ?? countryCode.toUpperCase();
|
|
6
|
+
const renderMerchantAddress = (merchant) => [
|
|
7
|
+
merchant.address_line1,
|
|
8
|
+
merchant.address_line2,
|
|
9
|
+
[merchant.postal_code, merchant.city].join(" "),
|
|
10
|
+
formatCountryName(merchant.country_code),
|
|
11
|
+
]
|
|
12
|
+
.filter((part) => Boolean(part))
|
|
13
|
+
.map(html_utils_1.escapeHtml)
|
|
14
|
+
.join("<br />");
|
|
15
|
+
/** Legal footer: name, UID, company register, contact and bank details that are set. */
|
|
16
|
+
const renderMerchantFooter = (merchant, includeLegalDetails) => {
|
|
17
|
+
if (!includeLegalDetails) {
|
|
18
|
+
return (0, html_utils_1.escapeHtml)(merchant.legal_name);
|
|
19
|
+
}
|
|
20
|
+
const register = [
|
|
21
|
+
merchant.company_register_number
|
|
22
|
+
? `Firmenbuchnummer: ${merchant.company_register_number}`
|
|
23
|
+
: null,
|
|
24
|
+
merchant.company_register_court
|
|
25
|
+
? `Firmenbuchgericht: ${merchant.company_register_court}`
|
|
26
|
+
: null,
|
|
27
|
+
];
|
|
28
|
+
const lines = [
|
|
29
|
+
[
|
|
30
|
+
merchant.legal_name,
|
|
31
|
+
merchant.vat_number ? `UID: ${merchant.vat_number}` : null,
|
|
32
|
+
...register,
|
|
33
|
+
],
|
|
34
|
+
[merchant.email, merchant.phone, merchant.website],
|
|
35
|
+
[
|
|
36
|
+
merchant.iban ? `IBAN: ${merchant.iban}` : null,
|
|
37
|
+
merchant.bic ? `BIC: ${merchant.bic}` : null,
|
|
38
|
+
],
|
|
39
|
+
];
|
|
40
|
+
return lines
|
|
41
|
+
.map((parts) => parts
|
|
42
|
+
.filter((part) => Boolean(part))
|
|
43
|
+
.map(html_utils_1.escapeHtml)
|
|
44
|
+
.join(" · "))
|
|
45
|
+
.filter(Boolean)
|
|
46
|
+
.join("<br />");
|
|
47
|
+
};
|
|
48
|
+
const renderMetadata = (metadata) => metadata
|
|
49
|
+
.map(({ label, value }) => `<div><strong>${(0, html_utils_1.escapeHtml)(label)}:</strong> ${(0, html_utils_1.escapeHtml)(value)}</div>`)
|
|
50
|
+
.join("");
|
|
51
|
+
/**
|
|
52
|
+
* `includeLegalDetails` adds UID, company register, contact and bank details
|
|
53
|
+
* to the footer (financial documents); packing lists show only the name.
|
|
54
|
+
*/
|
|
55
|
+
const createDocumentLayout = (merchant, includeLegalDetails) => ({ body, documentTitle, metadata, number, pageTitle }) => `<!doctype html>
|
|
56
|
+
<html lang="de">
|
|
57
|
+
<head>
|
|
58
|
+
<meta charset="utf-8" />
|
|
59
|
+
<title>${(0, html_utils_1.escapeHtml)(pageTitle)} ${(0, html_utils_1.escapeHtml)(number)}</title>
|
|
60
|
+
<style>
|
|
61
|
+
@page { margin: 18mm; }
|
|
62
|
+
body { color: #1f2937; font-family: Arial, sans-serif; font-size: 11px; line-height: 1.45; }
|
|
63
|
+
h1 { font-size: 24px; margin: 0 0 6px; }
|
|
64
|
+
h2 { break-after: avoid; font-size: 12px; margin: 22px 0 6px; page-break-after: avoid; text-transform: uppercase; }
|
|
65
|
+
.header { border-bottom: 2px solid #111827; display: flex; gap: 32px; justify-content: space-between; padding-bottom: 16px; }
|
|
66
|
+
.document-metadata { display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 18px 0 22px; }
|
|
67
|
+
.document-metadata div { min-width: 180px; }
|
|
68
|
+
.muted, .sku, .batch { color: #6b7280; }
|
|
69
|
+
.batch, .packing-batch { font-size: 10px; margin-top: 2px; }
|
|
70
|
+
.packing-batch { display: flex; gap: 12px; justify-content: space-between; }
|
|
71
|
+
table { border-collapse: collapse; page-break-inside: auto; width: 100%; }
|
|
72
|
+
thead { display: table-header-group; }
|
|
73
|
+
tfoot { display: table-footer-group; }
|
|
74
|
+
tbody { page-break-inside: auto; }
|
|
75
|
+
tr { break-inside: avoid; page-break-inside: avoid; }
|
|
76
|
+
th { background: #f3f4f6; font-size: 10px; text-align: left; text-transform: uppercase; }
|
|
77
|
+
th, td { border-bottom: 1px solid #d1d5db; padding: 8px 6px; vertical-align: top; }
|
|
78
|
+
.number { text-align: right; white-space: nowrap; }
|
|
79
|
+
.recipient, .tax-compliance, .totals { break-inside: avoid; page-break-inside: avoid; }
|
|
80
|
+
.totals { margin-left: auto; margin-top: 16px; width: 260px; }
|
|
81
|
+
.totals td { border: 0; padding: 3px 0; }
|
|
82
|
+
.totals tr:last-child td { border-top: 2px solid #111827; font-size: 14px; font-weight: 700; padding-top: 7px; }
|
|
83
|
+
footer { border-top: 1px solid #d1d5db; break-inside: avoid; color: #6b7280; font-size: 9px; margin-top: 28px; page-break-inside: avoid; padding-top: 10px; }
|
|
84
|
+
</style>
|
|
85
|
+
</head>
|
|
86
|
+
<body>
|
|
87
|
+
<section class="header">
|
|
88
|
+
<div><h1>${(0, html_utils_1.escapeHtml)(documentTitle)}</h1><div class="muted">${(0, html_utils_1.escapeHtml)(number)}</div></div>
|
|
89
|
+
<div><strong>${(0, html_utils_1.escapeHtml)(merchant.legal_name)}</strong><br />${renderMerchantAddress(merchant)}</div>
|
|
90
|
+
</section>
|
|
91
|
+
<section class="document-metadata">${renderMetadata(metadata)}</section>
|
|
92
|
+
${body}
|
|
93
|
+
<footer>${renderMerchantFooter(merchant, includeLegalDetails)}</footer>
|
|
94
|
+
</body>
|
|
95
|
+
</html>`;
|
|
96
|
+
exports.createDocumentLayout = createDocumentLayout;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderPackingList = void 0;
|
|
4
|
+
const format_1 = require("./format");
|
|
5
|
+
const html_utils_1 = require("./html-utils");
|
|
6
|
+
const renderBatchAllocations = (line, timeZone) => {
|
|
7
|
+
if (line.batch_allocations.length === 0) {
|
|
8
|
+
return '<span class="muted">-</span>';
|
|
9
|
+
}
|
|
10
|
+
return line.batch_allocations
|
|
11
|
+
.map((allocation) => `<div class="packing-batch">
|
|
12
|
+
<strong>${(0, html_utils_1.escapeHtml)(allocation.lot_number)}</strong>
|
|
13
|
+
<span>MHD: ${(0, format_1.formatDate)(allocation.expiry_date, { timeZone })}</span>
|
|
14
|
+
<span>Menge: ${(0, html_utils_1.escapeHtml)(allocation.quantity)}</span>
|
|
15
|
+
</div>`)
|
|
16
|
+
.join("");
|
|
17
|
+
};
|
|
18
|
+
const renderLines = (input, timeZone) => input.lines
|
|
19
|
+
.map((line) => `<tr>
|
|
20
|
+
<td>
|
|
21
|
+
<strong>${(0, html_utils_1.escapeHtml)(line.title)}</strong>
|
|
22
|
+
${line.sku ? `<div class="sku">SKU: ${(0, html_utils_1.escapeHtml)(line.sku)}</div>` : ""}
|
|
23
|
+
</td>
|
|
24
|
+
<td>${renderBatchAllocations(line, timeZone)}</td>
|
|
25
|
+
<td class="number">${(0, html_utils_1.escapeHtml)(line.quantity)}</td>
|
|
26
|
+
</tr>`)
|
|
27
|
+
.join("");
|
|
28
|
+
const renderPackingList = (input, layout, timeZone) => layout({
|
|
29
|
+
body: `<table>
|
|
30
|
+
<thead><tr><th>Bezeichnung</th><th>Charge</th><th class="number">Benötigte Menge</th></tr></thead>
|
|
31
|
+
<tbody>${renderLines(input, timeZone)}</tbody>
|
|
32
|
+
</table>`,
|
|
33
|
+
documentTitle: "Packliste",
|
|
34
|
+
metadata: [
|
|
35
|
+
{
|
|
36
|
+
label: "Bestellung",
|
|
37
|
+
value: (0, html_utils_1.formatOrderReference)(input.order.display_id),
|
|
38
|
+
},
|
|
39
|
+
{ label: "Fulfillment", value: input.fulfillment.id },
|
|
40
|
+
{
|
|
41
|
+
label: "Erstellungsdatum",
|
|
42
|
+
value: (0, format_1.formatDate)(input.document.generated_at, { timeZone }),
|
|
43
|
+
},
|
|
44
|
+
{ label: "Lagerplatz", value: input.fulfillment.location_name },
|
|
45
|
+
],
|
|
46
|
+
number: input.document.number,
|
|
47
|
+
pageTitle: "Packliste",
|
|
48
|
+
});
|
|
49
|
+
exports.renderPackingList = renderPackingList;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from "@hartl-services/medusa-food-supplements-contracts/types/documents-admin";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { StoreDocument as DocumentSummary } from "@hartl-services/medusa-food-supplements-contracts/types/documents-store";
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export type DocumentKind = "invoice" | "cancellation" | "credit_note";
|
|
2
|
+
export type DocumentStatus = "processing" | "issued" | "failed";
|
|
3
|
+
export type ShipmentInvoiceDecision = "pending" | "carrier" | "non_carrier";
|
|
4
|
+
export type RefundResolutionState = "pending_source" | "processing" | "ready" | "not_applicable" | "failed";
|
|
5
|
+
export type RefundCommunicationOwner = "standalone" | "cancellation";
|
|
6
|
+
export type OrderCancellationResolutionState = "pending" | "processing" | "ready" | "failed";
|
|
7
|
+
export type DocumentMoney = {
|
|
8
|
+
amount: string;
|
|
9
|
+
currency_code: string;
|
|
10
|
+
};
|
|
11
|
+
export type DocumentAddress = {
|
|
12
|
+
first_name: string | null;
|
|
13
|
+
last_name: string | null;
|
|
14
|
+
company: string | null;
|
|
15
|
+
address_1: string | null;
|
|
16
|
+
address_2: string | null;
|
|
17
|
+
postal_code: string | null;
|
|
18
|
+
city: string | null;
|
|
19
|
+
country_code: string | null;
|
|
20
|
+
};
|
|
21
|
+
export type DocumentBatchAllocationDTO = {
|
|
22
|
+
batch_id: string;
|
|
23
|
+
lot_number: string;
|
|
24
|
+
expiry_date: string;
|
|
25
|
+
quantity: number;
|
|
26
|
+
};
|
|
27
|
+
export type DocumentTaxComplianceDTO = {
|
|
28
|
+
customer_company_name: string;
|
|
29
|
+
customer_vat_number: string;
|
|
30
|
+
exemption_wording: "steuerfreie_innergemeinschaftliche_lieferung";
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Tax amount of one configured tax rate (name and percentage as calculated on
|
|
34
|
+
* the order's tax lines). Amounts are rounded to the currency's minor unit and
|
|
35
|
+
* sum up exactly to the rounded document tax total.
|
|
36
|
+
*/
|
|
37
|
+
export type DocumentTaxBreakdownEntry = {
|
|
38
|
+
name: string;
|
|
39
|
+
code: string | null;
|
|
40
|
+
rate: number;
|
|
41
|
+
tax_total: DocumentMoney;
|
|
42
|
+
};
|
|
43
|
+
export type DocumentTemplateLine = {
|
|
44
|
+
id: string;
|
|
45
|
+
title: string;
|
|
46
|
+
sku: string | null;
|
|
47
|
+
quantity: number;
|
|
48
|
+
unit_price: DocumentMoney;
|
|
49
|
+
subtotal: DocumentMoney;
|
|
50
|
+
tax_total: DocumentMoney;
|
|
51
|
+
total: DocumentMoney;
|
|
52
|
+
batch_allocations: DocumentBatchAllocationDTO[];
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Stable input contract for the project-owned HTML factory. It is a value
|
|
56
|
+
* snapshot, never a live Medusa order model, so rendering stays isolated from
|
|
57
|
+
* Medusa internals and the Storefront can import the types safely.
|
|
58
|
+
*/
|
|
59
|
+
export type DocumentTemplateInput = {
|
|
60
|
+
document: {
|
|
61
|
+
id: string;
|
|
62
|
+
kind: DocumentKind;
|
|
63
|
+
number: string;
|
|
64
|
+
issued_at: string;
|
|
65
|
+
source_document_number: string | null;
|
|
66
|
+
};
|
|
67
|
+
order: {
|
|
68
|
+
id: string;
|
|
69
|
+
display_id: number | null;
|
|
70
|
+
email: string;
|
|
71
|
+
currency_code: string;
|
|
72
|
+
billing_address: DocumentAddress | null;
|
|
73
|
+
tax_compliance: DocumentTaxComplianceDTO | null;
|
|
74
|
+
};
|
|
75
|
+
lines: DocumentTemplateLine[];
|
|
76
|
+
totals: {
|
|
77
|
+
subtotal: DocumentMoney;
|
|
78
|
+
tax_total: DocumentMoney;
|
|
79
|
+
/** Empty for documents without tax lines and for legacy snapshots. */
|
|
80
|
+
tax_breakdown: DocumentTaxBreakdownEntry[];
|
|
81
|
+
shipping_total: DocumentMoney;
|
|
82
|
+
discount_total: DocumentMoney;
|
|
83
|
+
total: DocumentMoney;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
export type DocumentSnapshot = DocumentTemplateInput;
|
|
87
|
+
export type PackingListLifecycleStatus = "active" | "canceled";
|
|
88
|
+
export type PackingListGenerationStatus = "processing" | "ready" | "failed";
|
|
89
|
+
export type PackingListBatchAllocation = {
|
|
90
|
+
batch_id: string;
|
|
91
|
+
lot_number: string;
|
|
92
|
+
expiry_date: string;
|
|
93
|
+
quantity: number;
|
|
94
|
+
};
|
|
95
|
+
export type PackingListTemplateLine = {
|
|
96
|
+
line_item_id: string;
|
|
97
|
+
inventory_item_id: string | null;
|
|
98
|
+
title: string;
|
|
99
|
+
sku: string | null;
|
|
100
|
+
quantity: number;
|
|
101
|
+
batch_allocations: PackingListBatchAllocation[];
|
|
102
|
+
};
|
|
103
|
+
export type PackingListTemplateInput = {
|
|
104
|
+
document: {
|
|
105
|
+
kind: "packing_list";
|
|
106
|
+
id: string;
|
|
107
|
+
number: string;
|
|
108
|
+
source_revision: number;
|
|
109
|
+
generated_at: string;
|
|
110
|
+
};
|
|
111
|
+
order: {
|
|
112
|
+
id: string;
|
|
113
|
+
display_id: number | null;
|
|
114
|
+
};
|
|
115
|
+
fulfillment: {
|
|
116
|
+
id: string;
|
|
117
|
+
created_at: string;
|
|
118
|
+
location_id: string;
|
|
119
|
+
location_name: string;
|
|
120
|
+
};
|
|
121
|
+
lines: PackingListTemplateLine[];
|
|
122
|
+
};
|
|
123
|
+
export type PackingListSnapshot = PackingListTemplateInput;
|
|
124
|
+
/**
|
|
125
|
+
* The shop's legal sender facts, read from the base plugin's shop master
|
|
126
|
+
* data ("Shop-Stammdaten") when a document is rendered. Not part of the
|
|
127
|
+
* stored snapshot. Optional fields are `null` when not set; the development
|
|
128
|
+
* UID placeholder `ATU00000000` arrives as `vat_number: null`.
|
|
129
|
+
*/
|
|
130
|
+
export type DocumentMerchant = {
|
|
131
|
+
legal_name: string;
|
|
132
|
+
address_line1: string;
|
|
133
|
+
address_line2: string | null;
|
|
134
|
+
postal_code: string;
|
|
135
|
+
city: string;
|
|
136
|
+
/** Lower-case ISO 3166-1 alpha-2 code. */
|
|
137
|
+
country_code: string;
|
|
138
|
+
vat_number: string | null;
|
|
139
|
+
email: string | null;
|
|
140
|
+
phone: string | null;
|
|
141
|
+
website: string | null;
|
|
142
|
+
iban: string | null;
|
|
143
|
+
bic: string | null;
|
|
144
|
+
company_register_number: string | null;
|
|
145
|
+
company_register_court: string | null;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Optional `merchant` plugin option: used per field only where the shop
|
|
149
|
+
* master data in the base plugin has no value (same shape as the demo shop's
|
|
150
|
+
* `merchant` constant in medusa-config).
|
|
151
|
+
*/
|
|
152
|
+
export type DocumentMerchantOption = {
|
|
153
|
+
countryCode: string;
|
|
154
|
+
legalName: string;
|
|
155
|
+
registeredAddress: {
|
|
156
|
+
address1: string;
|
|
157
|
+
address2?: string;
|
|
158
|
+
city: string;
|
|
159
|
+
countryCode: string;
|
|
160
|
+
postalCode: string;
|
|
161
|
+
};
|
|
162
|
+
vatNumber?: string;
|
|
163
|
+
};
|
|
164
|
+
export type FinancialDocumentRenderInput = DocumentTemplateInput & {
|
|
165
|
+
merchant: DocumentMerchant;
|
|
166
|
+
};
|
|
167
|
+
export type PackingListRenderInput = PackingListTemplateInput & {
|
|
168
|
+
merchant: DocumentMerchant;
|
|
169
|
+
};
|
|
170
|
+
export type DocumentRenderInput = FinancialDocumentRenderInput | PackingListRenderInput;
|
|
171
|
+
export type DocumentPdfOptions = {
|
|
172
|
+
/** Absolute executable path or command name for the bundled Chromium renderer. */
|
|
173
|
+
executablePath?: string;
|
|
174
|
+
};
|