@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,1701 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.DOCUMENT_ISSUANCE_LEASE_MS = void 0;
|
|
19
|
+
const node_crypto_1 = require("node:crypto");
|
|
20
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
21
|
+
const documents_1 = require("@hartl-services/medusa-food-supplements-contracts/events/documents");
|
|
22
|
+
const document_resolution_1 = require("./domain/document-resolution");
|
|
23
|
+
const document_number_1 = require("./domain/document-number");
|
|
24
|
+
const options_1 = require("./domain/options");
|
|
25
|
+
const snapshot_normalization_1 = require("./domain/snapshot-normalization");
|
|
26
|
+
const plugin_features_1 = require("../../documents/plugin-features");
|
|
27
|
+
const document_1 = __importDefault(require("./models/document"));
|
|
28
|
+
const document_artifact_1 = __importDefault(require("./models/document-artifact"));
|
|
29
|
+
const document_number_sequence_1 = __importDefault(require("./models/document-number-sequence"));
|
|
30
|
+
const order_cancellation_resolution_1 = __importDefault(require("./models/order-cancellation-resolution"));
|
|
31
|
+
const packing_list_1 = __importDefault(require("./models/packing-list"));
|
|
32
|
+
const packing_list_revision_1 = __importDefault(require("./models/packing-list-revision"));
|
|
33
|
+
const refund_document_resolution_1 = __importDefault(require("./models/refund-document-resolution"));
|
|
34
|
+
const shipment_invoice_assignment_1 = __importDefault(require("./models/shipment-invoice-assignment"));
|
|
35
|
+
const shipment_invoice_coordinator_1 = __importDefault(require("./models/shipment-invoice-coordinator"));
|
|
36
|
+
const PACKING_LIST_CLAIM_LEASE_MS = 10 * 60 * 1000;
|
|
37
|
+
exports.DOCUMENT_ISSUANCE_LEASE_MS = 10 * 60 * 1000;
|
|
38
|
+
const DOCUMENT_KINDS = [
|
|
39
|
+
"invoice",
|
|
40
|
+
"cancellation",
|
|
41
|
+
"credit_note",
|
|
42
|
+
];
|
|
43
|
+
const DOCUMENT_STATUSES = ["processing", "issued", "failed"];
|
|
44
|
+
const asNonEmptyString = (value, field) => {
|
|
45
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
46
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Document field '${field}' is invalid.`);
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
};
|
|
50
|
+
const asNullableString = (value) => typeof value === "string" ? value : null;
|
|
51
|
+
const asNullableNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
52
|
+
const asNullableDate = (value) => value instanceof Date ? value : null;
|
|
53
|
+
const asRequiredDate = (value, field) => {
|
|
54
|
+
const date = value instanceof Date ? value : new Date(String(value ?? ""));
|
|
55
|
+
if (Number.isNaN(date.getTime())) {
|
|
56
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Date field '${field}' is invalid.`);
|
|
57
|
+
}
|
|
58
|
+
return date;
|
|
59
|
+
};
|
|
60
|
+
const asNullablePackingListDate = (value) => {
|
|
61
|
+
if (value === null || value === undefined) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
65
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
66
|
+
};
|
|
67
|
+
const asDocumentKind = (value) => {
|
|
68
|
+
if (typeof value !== "string" || !DOCUMENT_KINDS.includes(value)) {
|
|
69
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Document kind is invalid.");
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
};
|
|
73
|
+
const asDocumentStatus = (value) => {
|
|
74
|
+
if (typeof value !== "string" ||
|
|
75
|
+
!DOCUMENT_STATUSES.includes(value)) {
|
|
76
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Document status is invalid.");
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
};
|
|
80
|
+
const asDocumentSnapshot = (value) => {
|
|
81
|
+
if (value === null || value === undefined) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
85
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Document snapshot is invalid.");
|
|
86
|
+
}
|
|
87
|
+
return (0, snapshot_normalization_1.normalizeDocumentSnapshot)(value);
|
|
88
|
+
};
|
|
89
|
+
const toDocumentRecord = (value) => ({
|
|
90
|
+
id: asNonEmptyString(value.id, "id"),
|
|
91
|
+
kind: asDocumentKind(value.kind),
|
|
92
|
+
status: asDocumentStatus(value.status),
|
|
93
|
+
issuance_key: asNonEmptyString(value.issuance_key, "issuance_key"),
|
|
94
|
+
order_id: asNonEmptyString(value.order_id, "order_id"),
|
|
95
|
+
order_display_id: asNullableNumber(value.order_display_id),
|
|
96
|
+
customer_id: asNullableString(value.customer_id),
|
|
97
|
+
recipient_email: asNonEmptyString(value.recipient_email, "recipient_email"),
|
|
98
|
+
document_number: asNonEmptyString(value.document_number, "document_number"),
|
|
99
|
+
source_document_id: asNullableString(value.source_document_id),
|
|
100
|
+
refund_id: asNullableString(value.refund_id),
|
|
101
|
+
snapshot: asDocumentSnapshot(value.snapshot),
|
|
102
|
+
file_id: asNullableString(value.file_id),
|
|
103
|
+
filename: asNullableString(value.filename),
|
|
104
|
+
current_artifact_id: asNullableString(value.current_artifact_id),
|
|
105
|
+
attempt_token: asNullableString(value.attempt_token),
|
|
106
|
+
lease_started_at: asNullableDate(value.lease_started_at),
|
|
107
|
+
lease_expires_at: asNullableDate(value.lease_expires_at),
|
|
108
|
+
issued_at: asRequiredDate(value.issued_at, "issued_at"),
|
|
109
|
+
failure_reason: asNullableString(value.failure_reason),
|
|
110
|
+
created_at: asNullableDate(value.created_at) ?? new Date(0),
|
|
111
|
+
});
|
|
112
|
+
const toArtifactRecord = (value) => ({
|
|
113
|
+
id: asNonEmptyString(value.id, "id"),
|
|
114
|
+
document_id: asNonEmptyString(value.document_id, "document_id"),
|
|
115
|
+
file_id: asNonEmptyString(value.file_id, "file_id"),
|
|
116
|
+
filename: asNonEmptyString(value.filename, "filename"),
|
|
117
|
+
content_type: "application/pdf",
|
|
118
|
+
communication_locked: value.communication_locked === true,
|
|
119
|
+
created_at: asNullableDate(value.created_at) ?? new Date(0),
|
|
120
|
+
});
|
|
121
|
+
const asShipmentDecision = (value) => {
|
|
122
|
+
if (value !== "pending" && value !== "carrier" && value !== "non_carrier") {
|
|
123
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Shipment invoice decision is invalid.");
|
|
124
|
+
}
|
|
125
|
+
return value;
|
|
126
|
+
};
|
|
127
|
+
const toShipmentAssignmentRecord = (value) => ({
|
|
128
|
+
id: asNonEmptyString(value.id, "id"),
|
|
129
|
+
order_id: asNonEmptyString(value.order_id, "order_id"),
|
|
130
|
+
fulfillment_id: asNonEmptyString(value.fulfillment_id, "fulfillment_id"),
|
|
131
|
+
decision: asShipmentDecision(value.decision),
|
|
132
|
+
invoice_document_id: asNullableString(value.invoice_document_id),
|
|
133
|
+
invoice_artifact_id: asNullableString(value.invoice_artifact_id),
|
|
134
|
+
event_emitted_at: asNullableDate(value.event_emitted_at),
|
|
135
|
+
created_at: asNullableDate(value.created_at) ?? new Date(0),
|
|
136
|
+
});
|
|
137
|
+
const toRefundResolutionRecord = (value) => ({
|
|
138
|
+
id: asNonEmptyString(value.id, "id"),
|
|
139
|
+
refund_id: asNonEmptyString(value.refund_id, "refund_id"),
|
|
140
|
+
order_id: asNonEmptyString(value.order_id, "order_id"),
|
|
141
|
+
payment_id: asNonEmptyString(value.payment_id, "payment_id"),
|
|
142
|
+
state: asNonEmptyString(value.state, "state"),
|
|
143
|
+
attempt_token: asNullableString(value.attempt_token),
|
|
144
|
+
lease_started_at: asNullableDate(value.lease_started_at),
|
|
145
|
+
lease_expires_at: asNullableDate(value.lease_expires_at),
|
|
146
|
+
document_id: asNullableString(value.document_id),
|
|
147
|
+
artifact_id: asNullableString(value.artifact_id),
|
|
148
|
+
communication_owner: asNullableString(value.communication_owner),
|
|
149
|
+
event_emitted_at: asNullableDate(value.event_emitted_at),
|
|
150
|
+
failure_code: asNullableString(value.failure_code),
|
|
151
|
+
});
|
|
152
|
+
const asStringArray = (value, field) => {
|
|
153
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
154
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Document field '${field}' is invalid.`);
|
|
155
|
+
}
|
|
156
|
+
return [...value];
|
|
157
|
+
};
|
|
158
|
+
const toCancellationResolutionRecord = (value) => ({
|
|
159
|
+
id: asNonEmptyString(value.id, "id"),
|
|
160
|
+
order_id: asNonEmptyString(value.order_id, "order_id"),
|
|
161
|
+
state: asNonEmptyString(value.state, "state"),
|
|
162
|
+
expected_refund_ids: asStringArray(value.expected_refund_ids, "expected_refund_ids"),
|
|
163
|
+
attachments: Array.isArray(value.attachments)
|
|
164
|
+
? value.attachments
|
|
165
|
+
: [],
|
|
166
|
+
attempt_token: asNullableString(value.attempt_token),
|
|
167
|
+
lease_started_at: asNullableDate(value.lease_started_at),
|
|
168
|
+
lease_expires_at: asNullableDate(value.lease_expires_at),
|
|
169
|
+
event_emitted_at: asNullableDate(value.event_emitted_at),
|
|
170
|
+
failure_code: asNullableString(value.failure_code),
|
|
171
|
+
});
|
|
172
|
+
const asPackingListLifecycleStatus = (value) => {
|
|
173
|
+
if (value !== "active" && value !== "canceled") {
|
|
174
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Packing-list lifecycle status is invalid.");
|
|
175
|
+
}
|
|
176
|
+
return value;
|
|
177
|
+
};
|
|
178
|
+
const asPackingListGenerationStatus = (value) => {
|
|
179
|
+
if (value !== "processing" && value !== "ready" && value !== "failed") {
|
|
180
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Packing-list generation status is invalid.");
|
|
181
|
+
}
|
|
182
|
+
return value;
|
|
183
|
+
};
|
|
184
|
+
const asPackingListSnapshot = (value) => {
|
|
185
|
+
if (value === null || value === undefined) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
189
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Packing-list snapshot is invalid.");
|
|
190
|
+
}
|
|
191
|
+
return value;
|
|
192
|
+
};
|
|
193
|
+
const toPackingListRecord = (value) => ({
|
|
194
|
+
id: asNonEmptyString(value.id, "id"),
|
|
195
|
+
order_id: asNonEmptyString(value.order_id, "order_id"),
|
|
196
|
+
order_display_id: asNullableNumber(value.order_display_id),
|
|
197
|
+
fulfillment_id: asNonEmptyString(value.fulfillment_id, "fulfillment_id"),
|
|
198
|
+
fulfillment_created_at: asRequiredDate(value.fulfillment_created_at, "fulfillment_created_at"),
|
|
199
|
+
lifecycle_status: asPackingListLifecycleStatus(value.lifecycle_status),
|
|
200
|
+
created_at: asNullablePackingListDate(value.created_at) ?? new Date(0),
|
|
201
|
+
});
|
|
202
|
+
const toPackingListRevisionRecord = (value) => {
|
|
203
|
+
const sourceRevision = asNullableNumber(value.source_revision);
|
|
204
|
+
if (!Number.isInteger(sourceRevision) || (sourceRevision ?? 0) <= 0) {
|
|
205
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Packing-list source revision is invalid.");
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
id: asNonEmptyString(value.id, "id"),
|
|
209
|
+
packing_list_id: asNonEmptyString(value.packing_list_id, "packing_list_id"),
|
|
210
|
+
source_revision: sourceRevision,
|
|
211
|
+
generation_status: asPackingListGenerationStatus(value.generation_status),
|
|
212
|
+
snapshot: asPackingListSnapshot(value.snapshot),
|
|
213
|
+
file_id: asNullableString(value.file_id),
|
|
214
|
+
filename: asNullableString(value.filename),
|
|
215
|
+
attempt_token: asNullableString(value.attempt_token),
|
|
216
|
+
attempt_started_at: asNullablePackingListDate(value.attempt_started_at),
|
|
217
|
+
generated_at: asNullablePackingListDate(value.generated_at),
|
|
218
|
+
failure_code: asNullableString(value.failure_code),
|
|
219
|
+
failure_reason: asNullableString(value.failure_reason),
|
|
220
|
+
created_at: asNullablePackingListDate(value.created_at) ?? new Date(0),
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
class DocumentsModuleService extends (0, utils_1.MedusaService)({
|
|
224
|
+
Document: document_1.default,
|
|
225
|
+
DocumentArtifact: document_artifact_1.default,
|
|
226
|
+
DocumentNumberSequence: document_number_sequence_1.default,
|
|
227
|
+
ShipmentInvoiceAssignment: shipment_invoice_assignment_1.default,
|
|
228
|
+
ShipmentInvoiceCoordinator: shipment_invoice_coordinator_1.default,
|
|
229
|
+
RefundDocumentResolution: refund_document_resolution_1.default,
|
|
230
|
+
OrderCancellationResolution: order_cancellation_resolution_1.default,
|
|
231
|
+
PackingList: packing_list_1.default,
|
|
232
|
+
PackingListRevision: packing_list_revision_1.default,
|
|
233
|
+
}) {
|
|
234
|
+
/**
|
|
235
|
+
* Medusa passes the plugin options of the base plugin to every module; this
|
|
236
|
+
* service reads only its own `documents` namespace.
|
|
237
|
+
*/
|
|
238
|
+
constructor(container, options) {
|
|
239
|
+
super(container);
|
|
240
|
+
/** Discovered by @hartl-services/medusa-base for the feature toggles. */
|
|
241
|
+
this.pluginFeatures = plugin_features_1.documentsPluginFeatures;
|
|
242
|
+
this.pluginOptions_ = (0, options_1.resolveDocumentPluginOptions)(options?.documents);
|
|
243
|
+
}
|
|
244
|
+
async getPluginOptions() {
|
|
245
|
+
return this.pluginOptions_;
|
|
246
|
+
}
|
|
247
|
+
async claimPackingListRevision(input, sharedContext = {}) {
|
|
248
|
+
if (!Number.isInteger(input.source_revision) ||
|
|
249
|
+
input.source_revision <= 0) {
|
|
250
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "A positive packing-list source revision is required.");
|
|
251
|
+
}
|
|
252
|
+
await this.acquirePackingListLock(input.fulfillment_id, sharedContext);
|
|
253
|
+
const existingPackingLists = (await this.listPackingLists({ fulfillment_id: input.fulfillment_id }, { take: 1 }, sharedContext));
|
|
254
|
+
let packingList = existingPackingLists[0]
|
|
255
|
+
? toPackingListRecord(existingPackingLists[0])
|
|
256
|
+
: null;
|
|
257
|
+
if (packingList && packingList.order_id !== input.order_id) {
|
|
258
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Fulfillment ${input.fulfillment_id} already belongs to another packing-list order.`);
|
|
259
|
+
}
|
|
260
|
+
if (!packingList) {
|
|
261
|
+
const created = (await this.createPackingLists({
|
|
262
|
+
order_id: input.order_id,
|
|
263
|
+
order_display_id: input.order_display_id,
|
|
264
|
+
fulfillment_id: input.fulfillment_id,
|
|
265
|
+
fulfillment_created_at: input.fulfillment_created_at,
|
|
266
|
+
lifecycle_status: "active",
|
|
267
|
+
}, sharedContext));
|
|
268
|
+
packingList = toPackingListRecord(created);
|
|
269
|
+
}
|
|
270
|
+
if (packingList.lifecycle_status === "canceled") {
|
|
271
|
+
return {
|
|
272
|
+
action: "canceled",
|
|
273
|
+
packing_list: packingList,
|
|
274
|
+
revision: null,
|
|
275
|
+
attempt_token: null,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const existingRevisions = (await this.listPackingListRevisions({
|
|
279
|
+
packing_list_id: packingList.id,
|
|
280
|
+
source_revision: input.source_revision,
|
|
281
|
+
}, { take: 1 }, sharedContext));
|
|
282
|
+
const existingRevision = existingRevisions[0]
|
|
283
|
+
? toPackingListRevisionRecord(existingRevisions[0])
|
|
284
|
+
: null;
|
|
285
|
+
if (existingRevision?.generation_status === "ready") {
|
|
286
|
+
return {
|
|
287
|
+
action: "ready",
|
|
288
|
+
packing_list: packingList,
|
|
289
|
+
revision: existingRevision,
|
|
290
|
+
attempt_token: null,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const now = new Date();
|
|
294
|
+
const claimIsFresh = existingRevision?.generation_status === "processing" &&
|
|
295
|
+
existingRevision.attempt_started_at &&
|
|
296
|
+
now.getTime() - existingRevision.attempt_started_at.getTime() <
|
|
297
|
+
PACKING_LIST_CLAIM_LEASE_MS;
|
|
298
|
+
if (claimIsFresh) {
|
|
299
|
+
return {
|
|
300
|
+
action: "in_progress",
|
|
301
|
+
packing_list: packingList,
|
|
302
|
+
revision: existingRevision,
|
|
303
|
+
attempt_token: null,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const attemptToken = (0, node_crypto_1.randomUUID)();
|
|
307
|
+
let rawRevision;
|
|
308
|
+
if (existingRevision) {
|
|
309
|
+
let revisionToClaim = existingRevision;
|
|
310
|
+
let claimed = null;
|
|
311
|
+
for (let attempt = 0; attempt < 2 && !claimed; attempt += 1) {
|
|
312
|
+
claimed = await this.tryClaimPackingListRevision(revisionToClaim, attemptToken, now, sharedContext);
|
|
313
|
+
if (claimed) {
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
const currentRevisions = (await this.listPackingListRevisions({ id: existingRevision.id }, { take: 1 }, sharedContext));
|
|
317
|
+
if (!currentRevisions[0]) {
|
|
318
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Packing-list revision ${existingRevision.id} can no longer be claimed.`);
|
|
319
|
+
}
|
|
320
|
+
const current = toPackingListRevisionRecord(currentRevisions[0]);
|
|
321
|
+
if (current.generation_status === "ready") {
|
|
322
|
+
return {
|
|
323
|
+
action: "ready",
|
|
324
|
+
packing_list: packingList,
|
|
325
|
+
revision: current,
|
|
326
|
+
attempt_token: null,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
if (current.generation_status === "processing") {
|
|
330
|
+
return {
|
|
331
|
+
action: "in_progress",
|
|
332
|
+
packing_list: packingList,
|
|
333
|
+
revision: current,
|
|
334
|
+
attempt_token: null,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
revisionToClaim = current;
|
|
338
|
+
}
|
|
339
|
+
if (!claimed) {
|
|
340
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Packing-list revision ${existingRevision.id} can no longer be claimed.`);
|
|
341
|
+
}
|
|
342
|
+
rawRevision = claimed;
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
rawRevision = (await this.createPackingListRevisions({
|
|
346
|
+
packing_list_id: packingList.id,
|
|
347
|
+
source_revision: input.source_revision,
|
|
348
|
+
generation_status: "processing",
|
|
349
|
+
attempt_token: attemptToken,
|
|
350
|
+
attempt_started_at: now,
|
|
351
|
+
}, sharedContext));
|
|
352
|
+
}
|
|
353
|
+
return {
|
|
354
|
+
action: "render",
|
|
355
|
+
packing_list: packingList,
|
|
356
|
+
revision: toPackingListRevisionRecord(rawRevision),
|
|
357
|
+
attempt_token: attemptToken,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
async savePackingListRevisionSnapshot(input, sharedContext = {}) {
|
|
361
|
+
const revisionId = asNonEmptyString(input.revision_id, "revision_id");
|
|
362
|
+
const attemptToken = asNonEmptyString(input.attempt_token, "attempt_token");
|
|
363
|
+
const packingListId = asNonEmptyString(input.snapshot.document.id, "snapshot.document.id");
|
|
364
|
+
const sourceRevision = input.snapshot.document.source_revision;
|
|
365
|
+
if (!Number.isInteger(sourceRevision) || sourceRevision <= 0) {
|
|
366
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "A positive packing-list snapshot source revision is required.");
|
|
367
|
+
}
|
|
368
|
+
const manager = this.requireManager(sharedContext);
|
|
369
|
+
const updated = await manager.execute(`update "documents_packing_list_revision"
|
|
370
|
+
set "snapshot" = cast(? as jsonb), "updated_at" = now()
|
|
371
|
+
where "id" = ? and "packing_list_id" = ? and "source_revision" = ?
|
|
372
|
+
and "generation_status" = 'processing' and "attempt_token" = ?
|
|
373
|
+
and "deleted_at" is null
|
|
374
|
+
returning *`, [
|
|
375
|
+
JSON.stringify(input.snapshot),
|
|
376
|
+
revisionId,
|
|
377
|
+
packingListId,
|
|
378
|
+
sourceRevision,
|
|
379
|
+
attemptToken,
|
|
380
|
+
]);
|
|
381
|
+
if (!updated[0]) {
|
|
382
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Packing-list revision ${revisionId} is owned by another generation attempt.`);
|
|
383
|
+
}
|
|
384
|
+
return toPackingListRevisionRecord(updated[0]);
|
|
385
|
+
}
|
|
386
|
+
async publishPackingListRevision(input, sharedContext = {}) {
|
|
387
|
+
const manager = this.requireManager(sharedContext);
|
|
388
|
+
const updated = await manager.execute(`update "documents_packing_list_revision" as "revision"
|
|
389
|
+
set "generation_status" = 'ready', "file_id" = ?, "filename" = ?,
|
|
390
|
+
"generated_at" = now(), "attempt_token" = null,
|
|
391
|
+
"attempt_started_at" = null, "failure_code" = null,
|
|
392
|
+
"failure_reason" = null, "updated_at" = now()
|
|
393
|
+
where "revision"."id" = ?
|
|
394
|
+
and "revision"."generation_status" = 'processing'
|
|
395
|
+
and "revision"."attempt_token" = ?
|
|
396
|
+
and "revision"."snapshot" is not null
|
|
397
|
+
and "revision"."deleted_at" is null
|
|
398
|
+
and exists (
|
|
399
|
+
select 1 from "documents_packing_list" as "packing_list"
|
|
400
|
+
where "packing_list"."id" = "revision"."packing_list_id"
|
|
401
|
+
and "packing_list"."lifecycle_status" = 'active'
|
|
402
|
+
and "packing_list"."deleted_at" is null
|
|
403
|
+
)
|
|
404
|
+
returning "revision".*`, [input.file_id, input.filename, input.revision_id, input.attempt_token]);
|
|
405
|
+
if (!updated[0]) {
|
|
406
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Packing-list revision ${input.revision_id} can no longer be published.`);
|
|
407
|
+
}
|
|
408
|
+
return toPackingListRevisionRecord(updated[0]);
|
|
409
|
+
}
|
|
410
|
+
async markPackingListRevisionFailed(input, sharedContext = {}) {
|
|
411
|
+
const manager = this.requireManager(sharedContext);
|
|
412
|
+
await manager.execute(`update "documents_packing_list_revision"
|
|
413
|
+
set "generation_status" = 'failed', "attempt_token" = null,
|
|
414
|
+
"attempt_started_at" = null, "failure_code" = ?,
|
|
415
|
+
"failure_reason" = ?, "updated_at" = now()
|
|
416
|
+
where "id" = ? and "generation_status" = 'processing'
|
|
417
|
+
and "attempt_token" = ? and "deleted_at" is null`, [
|
|
418
|
+
input.code,
|
|
419
|
+
input.reason,
|
|
420
|
+
asNonEmptyString(input.revision_id, "revision_id"),
|
|
421
|
+
asNonEmptyString(input.attempt_token, "attempt_token"),
|
|
422
|
+
]);
|
|
423
|
+
}
|
|
424
|
+
async cancelPackingListForFulfillment(input, sharedContext = {}) {
|
|
425
|
+
const orderId = asNonEmptyString(input.order_id, "order_id");
|
|
426
|
+
const fulfillmentId = asNonEmptyString(input.fulfillment_id, "fulfillment_id");
|
|
427
|
+
const fulfillmentCreatedAt = asRequiredDate(input.fulfillment_created_at, "fulfillment_created_at");
|
|
428
|
+
await this.acquirePackingListLock(fulfillmentId, sharedContext);
|
|
429
|
+
const records = (await this.listPackingLists({ fulfillment_id: fulfillmentId }, { take: 1 }, sharedContext));
|
|
430
|
+
if (!records[0]) {
|
|
431
|
+
const created = (await this.createPackingLists({
|
|
432
|
+
order_id: orderId,
|
|
433
|
+
order_display_id: input.order_display_id,
|
|
434
|
+
fulfillment_id: fulfillmentId,
|
|
435
|
+
fulfillment_created_at: fulfillmentCreatedAt,
|
|
436
|
+
lifecycle_status: "canceled",
|
|
437
|
+
}, sharedContext));
|
|
438
|
+
return toPackingListRecord(created);
|
|
439
|
+
}
|
|
440
|
+
const existing = toPackingListRecord(records[0]);
|
|
441
|
+
if (existing.order_id !== orderId) {
|
|
442
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Fulfillment ${fulfillmentId} already belongs to another packing-list order.`);
|
|
443
|
+
}
|
|
444
|
+
if (existing.lifecycle_status === "canceled") {
|
|
445
|
+
return existing;
|
|
446
|
+
}
|
|
447
|
+
const updated = (await this.updatePackingLists({
|
|
448
|
+
id: existing.id,
|
|
449
|
+
lifecycle_status: "canceled",
|
|
450
|
+
}, sharedContext));
|
|
451
|
+
return toPackingListRecord(updated);
|
|
452
|
+
}
|
|
453
|
+
async retrievePackingListRevisionRecord(revisionId) {
|
|
454
|
+
const revision = (await this.retrievePackingListRevision(revisionId));
|
|
455
|
+
return toPackingListRevisionRecord(revision);
|
|
456
|
+
}
|
|
457
|
+
async listPackingListsForOrder(orderId) {
|
|
458
|
+
const rawPackingLists = (await this.listPackingLists({ order_id: orderId }, { order: { fulfillment_created_at: "ASC" } }));
|
|
459
|
+
return await Promise.all(rawPackingLists.map(async (rawPackingList) => {
|
|
460
|
+
const packingList = toPackingListRecord(rawPackingList);
|
|
461
|
+
const revisions = (await this.listPackingListRevisions({ packing_list_id: packingList.id }, { order: { source_revision: "DESC" } }));
|
|
462
|
+
return {
|
|
463
|
+
packing_list: packingList,
|
|
464
|
+
revisions: revisions.map(toPackingListRevisionRecord),
|
|
465
|
+
};
|
|
466
|
+
}));
|
|
467
|
+
}
|
|
468
|
+
async getPackingListForOrderAndFulfillment(orderId, fulfillmentId) {
|
|
469
|
+
const packingLists = (await this.listPackingLists({ order_id: orderId, fulfillment_id: fulfillmentId }, { take: 1 }));
|
|
470
|
+
if (!packingLists[0]) {
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
const packingList = toPackingListRecord(packingLists[0]);
|
|
474
|
+
const revisions = (await this.listPackingListRevisions({ packing_list_id: packingList.id }, { order: { source_revision: "DESC" } }));
|
|
475
|
+
return {
|
|
476
|
+
packing_list: packingList,
|
|
477
|
+
revisions: revisions.map(toPackingListRevisionRecord),
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
async acquirePackingListLock(fulfillmentId, sharedContext) {
|
|
481
|
+
if (typeof fulfillmentId !== "string" || !fulfillmentId.trim()) {
|
|
482
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "A non-empty fulfillment ID is required.");
|
|
483
|
+
}
|
|
484
|
+
const manager = this.requireManager(sharedContext);
|
|
485
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
486
|
+
`documents:packing-list:${fulfillmentId.trim()}`,
|
|
487
|
+
]);
|
|
488
|
+
}
|
|
489
|
+
async tryClaimPackingListRevision(revision, attemptToken, startedAt, sharedContext) {
|
|
490
|
+
const manager = this.requireManager(sharedContext);
|
|
491
|
+
const updated = await manager.execute(`update "documents_packing_list_revision"
|
|
492
|
+
set "generation_status" = 'processing', "snapshot" = null,
|
|
493
|
+
"file_id" = null, "filename" = null, "attempt_token" = ?,
|
|
494
|
+
"attempt_started_at" = ?, "generated_at" = null,
|
|
495
|
+
"failure_code" = null, "failure_reason" = null,
|
|
496
|
+
"updated_at" = now()
|
|
497
|
+
where "id" = ? and "generation_status" = ?
|
|
498
|
+
and "attempt_token" is not distinct from ? and "deleted_at" is null
|
|
499
|
+
returning *`, [
|
|
500
|
+
attemptToken,
|
|
501
|
+
startedAt,
|
|
502
|
+
revision.id,
|
|
503
|
+
revision.generation_status,
|
|
504
|
+
revision.attempt_token,
|
|
505
|
+
]);
|
|
506
|
+
return updated[0] ?? null;
|
|
507
|
+
}
|
|
508
|
+
requireManager(sharedContext) {
|
|
509
|
+
const manager = sharedContext.transactionManager;
|
|
510
|
+
if (!manager) {
|
|
511
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Document operation requires a database transaction manager.");
|
|
512
|
+
}
|
|
513
|
+
return manager;
|
|
514
|
+
}
|
|
515
|
+
async lockCoreOrder(manager, orderId) {
|
|
516
|
+
const rows = await manager.execute(`select "status", "canceled_at", "version" from "order"
|
|
517
|
+
where "id" = ? limit 1 for share`, [orderId]);
|
|
518
|
+
if (!rows[0]) {
|
|
519
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Order ${orderId} was not found.`);
|
|
520
|
+
}
|
|
521
|
+
const version = Number(rows[0].version);
|
|
522
|
+
if (!Number.isInteger(version) || version <= 0) {
|
|
523
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Order ${orderId} has an invalid version.`);
|
|
524
|
+
}
|
|
525
|
+
return {
|
|
526
|
+
canceled: Boolean(rows[0].canceled_at) || rows[0].status === "canceled",
|
|
527
|
+
version,
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
async lockCompleteShipmentAggregate(manager, orderId, orderVersion, fulfillmentId) {
|
|
531
|
+
const fulfillmentRows = await manager.execute(`select f."id", f."shipped_at", f."delivered_at", f."canceled_at"
|
|
532
|
+
from "order_fulfillment" ofl
|
|
533
|
+
join "fulfillment" f on f."id" = ofl."fulfillment_id"
|
|
534
|
+
where ofl."order_id" = ? and ofl."deleted_at" is null
|
|
535
|
+
and f."deleted_at" is null
|
|
536
|
+
for share of f`, [orderId]);
|
|
537
|
+
const activeFulfillments = fulfillmentRows.filter((row) => !row.canceled_at);
|
|
538
|
+
const selected = activeFulfillments.find((row) => row.id === fulfillmentId);
|
|
539
|
+
if (!selected ||
|
|
540
|
+
(!selected.shipped_at && !selected.delivered_at) ||
|
|
541
|
+
activeFulfillments.some((row) => !row.shipped_at && !row.delivered_at)) {
|
|
542
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Order ${orderId} is no longer completely shipped for invoice assignment.`);
|
|
543
|
+
}
|
|
544
|
+
const itemRows = await manager.execute(`select ("fulfilled_quantity" < "quantity") as "unfulfilled"
|
|
545
|
+
from "order_item"
|
|
546
|
+
where "order_id" = ? and "version" = ? and "deleted_at" is null
|
|
547
|
+
for share`, [orderId, orderVersion]);
|
|
548
|
+
if (!itemRows.length || itemRows.some((row) => row.unfulfilled)) {
|
|
549
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Order ${orderId} is no longer completely fulfilled for invoice assignment.`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async upsertShipmentInvoiceAssignment(input, sharedContext = {}) {
|
|
553
|
+
const orderId = asNonEmptyString(input.order_id, "order_id");
|
|
554
|
+
const fulfillmentId = asNonEmptyString(input.fulfillment_id, "fulfillment_id");
|
|
555
|
+
const manager = this.requireManager(sharedContext);
|
|
556
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
557
|
+
`documents:shipment:${fulfillmentId}`,
|
|
558
|
+
]);
|
|
559
|
+
const rows = await manager.execute(`select * from "documents_shipment_invoice_assignment"
|
|
560
|
+
where "fulfillment_id" = ? for update`, [fulfillmentId]);
|
|
561
|
+
if (rows[0]) {
|
|
562
|
+
const assignment = toShipmentAssignmentRecord(rows[0]);
|
|
563
|
+
if (assignment.order_id !== orderId) {
|
|
564
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Fulfillment ${fulfillmentId} already belongs to another invoice assignment.`);
|
|
565
|
+
}
|
|
566
|
+
return assignment;
|
|
567
|
+
}
|
|
568
|
+
const created = (await this.createShipmentInvoiceAssignments({
|
|
569
|
+
order_id: orderId,
|
|
570
|
+
fulfillment_id: fulfillmentId,
|
|
571
|
+
decision: "pending",
|
|
572
|
+
}, sharedContext));
|
|
573
|
+
return toShipmentAssignmentRecord(created);
|
|
574
|
+
}
|
|
575
|
+
async claimShipmentInvoiceDecision(input, sharedContext = {}) {
|
|
576
|
+
const manager = this.requireManager(sharedContext);
|
|
577
|
+
const orderId = asNonEmptyString(input.order_id, "order_id");
|
|
578
|
+
const fulfillmentId = asNonEmptyString(input.fulfillment_id, "fulfillment_id");
|
|
579
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
580
|
+
`documents:invoice-coordinator:${orderId}`,
|
|
581
|
+
]);
|
|
582
|
+
const assignmentRows = await manager.execute(`select * from "documents_shipment_invoice_assignment"
|
|
583
|
+
where "fulfillment_id" = ? and "order_id" = ? and "deleted_at" is null
|
|
584
|
+
for update`, [fulfillmentId, orderId]);
|
|
585
|
+
if (!assignmentRows[0]) {
|
|
586
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Shipment invoice assignment ${fulfillmentId} was not registered.`);
|
|
587
|
+
}
|
|
588
|
+
const assignment = toShipmentAssignmentRecord(assignmentRows[0]);
|
|
589
|
+
if (assignment.decision !== "pending") {
|
|
590
|
+
return { action: "decided", assignment, coordinator_token: null };
|
|
591
|
+
}
|
|
592
|
+
let coordinatorRows = await manager.execute(`select * from "documents_shipment_invoice_coordinator"
|
|
593
|
+
where "order_id" = ? and "deleted_at" is null for update`, [orderId]);
|
|
594
|
+
if (!coordinatorRows[0]) {
|
|
595
|
+
coordinatorRows = [
|
|
596
|
+
(await this.createShipmentInvoiceCoordinators({ order_id: orderId, state: "idle" }, sharedContext)),
|
|
597
|
+
];
|
|
598
|
+
}
|
|
599
|
+
const coordinator = coordinatorRows[0];
|
|
600
|
+
const state = asNonEmptyString(coordinator.state, "state");
|
|
601
|
+
const leaseExpiresAt = asNullableDate(coordinator.lease_expires_at);
|
|
602
|
+
const now = new Date();
|
|
603
|
+
if (state === "processing" &&
|
|
604
|
+
leaseExpiresAt &&
|
|
605
|
+
leaseExpiresAt.getTime() > now.getTime()) {
|
|
606
|
+
return { action: "in_progress", assignment, coordinator_token: null };
|
|
607
|
+
}
|
|
608
|
+
const carrierRows = await manager.execute(`select "id" from "documents_shipment_invoice_assignment"
|
|
609
|
+
where "order_id" = ? and "decision" = 'carrier'
|
|
610
|
+
limit 1 for update`, [orderId]);
|
|
611
|
+
if (!input.order_complete || carrierRows[0] || state === "completed") {
|
|
612
|
+
const updated = (await this.updateShipmentInvoiceAssignments({ id: assignment.id, decision: "non_carrier" }, sharedContext));
|
|
613
|
+
await this.updateShipmentInvoiceCoordinators({
|
|
614
|
+
id: asNonEmptyString(coordinator.id, "coordinator.id"),
|
|
615
|
+
state: state === "completed" ? "completed" : "idle",
|
|
616
|
+
attempt_token: null,
|
|
617
|
+
lease_started_at: null,
|
|
618
|
+
lease_expires_at: null,
|
|
619
|
+
}, sharedContext);
|
|
620
|
+
return {
|
|
621
|
+
action: "decided",
|
|
622
|
+
assignment: toShipmentAssignmentRecord(updated),
|
|
623
|
+
coordinator_token: null,
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
await manager.execute(`update "documents_shipment_invoice_assignment" a
|
|
627
|
+
set "decision" = 'non_carrier', "updated_at" = now()
|
|
628
|
+
where a."order_id" = ? and a."decision" = 'pending'
|
|
629
|
+
and a."deleted_at" is null
|
|
630
|
+
and not exists (
|
|
631
|
+
select 1 from "fulfillment" f
|
|
632
|
+
where f."id" = a."fulfillment_id" and f."deleted_at" is null
|
|
633
|
+
and f."canceled_at" is null
|
|
634
|
+
and (f."shipped_at" is not null or f."delivered_at" is not null)
|
|
635
|
+
)`, [orderId]);
|
|
636
|
+
const persistedCandidate = asNullableString(coordinator.candidate_fulfillment_id);
|
|
637
|
+
const attemptToken = (0, node_crypto_1.randomUUID)();
|
|
638
|
+
let candidateRows = persistedCandidate
|
|
639
|
+
? await manager.execute(`select a.* from "documents_shipment_invoice_assignment" a
|
|
640
|
+
join "fulfillment" f on f."id" = a."fulfillment_id"
|
|
641
|
+
where a."order_id" = ? and a."fulfillment_id" = ?
|
|
642
|
+
and a."decision" = 'pending' and a."deleted_at" is null
|
|
643
|
+
and f."deleted_at" is null and f."canceled_at" is null
|
|
644
|
+
and (f."shipped_at" is not null or f."delivered_at" is not null)
|
|
645
|
+
limit 1 for update of a`, [orderId, persistedCandidate])
|
|
646
|
+
: [];
|
|
647
|
+
if (!candidateRows[0]) {
|
|
648
|
+
candidateRows = await manager.execute(`select a.* from "documents_shipment_invoice_assignment" a
|
|
649
|
+
join "fulfillment" f on f."id" = a."fulfillment_id"
|
|
650
|
+
where a."order_id" = ? and a."decision" = 'pending'
|
|
651
|
+
and a."deleted_at" is null and f."deleted_at" is null
|
|
652
|
+
and f."canceled_at" is null
|
|
653
|
+
and (f."shipped_at" is not null or f."delivered_at" is not null)
|
|
654
|
+
order by a."created_at" asc, a."fulfillment_id" asc
|
|
655
|
+
limit 1 for update of a`, [orderId]);
|
|
656
|
+
}
|
|
657
|
+
if (!candidateRows[0]) {
|
|
658
|
+
await this.updateShipmentInvoiceCoordinators({
|
|
659
|
+
id: asNonEmptyString(coordinator.id, "coordinator.id"),
|
|
660
|
+
state: "idle",
|
|
661
|
+
candidate_fulfillment_id: null,
|
|
662
|
+
attempt_token: null,
|
|
663
|
+
lease_started_at: null,
|
|
664
|
+
lease_expires_at: null,
|
|
665
|
+
}, sharedContext);
|
|
666
|
+
const currentRows = await manager.execute(`select * from "documents_shipment_invoice_assignment"
|
|
667
|
+
where "id" = ? and "deleted_at" is null limit 1`, [assignment.id]);
|
|
668
|
+
return {
|
|
669
|
+
action: "decided",
|
|
670
|
+
assignment: toShipmentAssignmentRecord(currentRows[0]),
|
|
671
|
+
coordinator_token: null,
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
const candidate = toShipmentAssignmentRecord(candidateRows[0]);
|
|
675
|
+
await this.updateShipmentInvoiceCoordinators({
|
|
676
|
+
id: asNonEmptyString(coordinator.id, "coordinator.id"),
|
|
677
|
+
state: "processing",
|
|
678
|
+
candidate_fulfillment_id: candidate.fulfillment_id,
|
|
679
|
+
attempt_token: attemptToken,
|
|
680
|
+
lease_started_at: now,
|
|
681
|
+
lease_expires_at: new Date(now.getTime() + exports.DOCUMENT_ISSUANCE_LEASE_MS),
|
|
682
|
+
}, sharedContext);
|
|
683
|
+
return {
|
|
684
|
+
action: "render_invoice",
|
|
685
|
+
assignment: candidate,
|
|
686
|
+
coordinator_token: attemptToken,
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
async releaseShipmentInvoiceDecision(input, sharedContext = {}) {
|
|
690
|
+
await this.requireManager(sharedContext).execute(`update "documents_shipment_invoice_coordinator"
|
|
691
|
+
set "state" = 'idle', "attempt_token" = null,
|
|
692
|
+
"lease_started_at" = null, "lease_expires_at" = null,
|
|
693
|
+
"updated_at" = now()
|
|
694
|
+
where "state" = 'processing' and "attempt_token" = ?
|
|
695
|
+
and "deleted_at" is null`, [asNonEmptyString(input.coordinator_token, "coordinator_token")]);
|
|
696
|
+
}
|
|
697
|
+
async startInvoiceIssuance(input, sharedContext = {}) {
|
|
698
|
+
return await this.startDocumentIssuance({
|
|
699
|
+
...input,
|
|
700
|
+
kind: "invoice",
|
|
701
|
+
issuance_key: `invoice:${input.order_id}`,
|
|
702
|
+
}, sharedContext);
|
|
703
|
+
}
|
|
704
|
+
async startCancellationIssuance(input, sharedContext = {}) {
|
|
705
|
+
const sourceInvoice = input.source_invoice;
|
|
706
|
+
if (sourceInvoice.kind !== "invoice") {
|
|
707
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "A cancellation document must reference an invoice.");
|
|
708
|
+
}
|
|
709
|
+
return await this.startDocumentIssuance({
|
|
710
|
+
kind: "cancellation",
|
|
711
|
+
issuance_key: `cancellation:${input.refund_id}`,
|
|
712
|
+
order_id: sourceInvoice.order_id,
|
|
713
|
+
order_display_id: sourceInvoice.order_display_id,
|
|
714
|
+
customer_id: sourceInvoice.customer_id,
|
|
715
|
+
recipient_email: sourceInvoice.recipient_email,
|
|
716
|
+
source_document_id: sourceInvoice.id,
|
|
717
|
+
refund_id: input.refund_id,
|
|
718
|
+
}, sharedContext);
|
|
719
|
+
}
|
|
720
|
+
async startDocumentIssuance(input, sharedContext) {
|
|
721
|
+
const manager = this.requireManager(sharedContext);
|
|
722
|
+
const issuanceKey = asNonEmptyString(input.issuance_key, "issuance_key");
|
|
723
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
724
|
+
`documents:issuance:${issuanceKey}`,
|
|
725
|
+
]);
|
|
726
|
+
const rows = await manager.execute(`select * from "documents_document" where "issuance_key" = ? for update`, [issuanceKey]);
|
|
727
|
+
if (rows[0]?.deleted_at) {
|
|
728
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The document issuance key was already consumed.");
|
|
729
|
+
}
|
|
730
|
+
const now = new Date();
|
|
731
|
+
const existing = rows[0] ? toDocumentRecord(rows[0]) : null;
|
|
732
|
+
if (existing?.status === "issued") {
|
|
733
|
+
return { document: existing, action: "issued", attempt_token: null };
|
|
734
|
+
}
|
|
735
|
+
if (existing?.status === "processing" &&
|
|
736
|
+
existing.attempt_token &&
|
|
737
|
+
existing.lease_expires_at &&
|
|
738
|
+
existing.lease_expires_at.getTime() > now.getTime()) {
|
|
739
|
+
return { document: existing, action: "in_progress", attempt_token: null };
|
|
740
|
+
}
|
|
741
|
+
const attemptToken = (0, node_crypto_1.randomUUID)();
|
|
742
|
+
const leaseExpiresAt = new Date(now.getTime() + exports.DOCUMENT_ISSUANCE_LEASE_MS);
|
|
743
|
+
if (existing) {
|
|
744
|
+
const retried = (await this.updateDocuments({
|
|
745
|
+
id: existing.id,
|
|
746
|
+
status: "processing",
|
|
747
|
+
attempt_token: attemptToken,
|
|
748
|
+
lease_started_at: now,
|
|
749
|
+
lease_expires_at: leaseExpiresAt,
|
|
750
|
+
failure_reason: null,
|
|
751
|
+
}, sharedContext));
|
|
752
|
+
return {
|
|
753
|
+
document: toDocumentRecord(retried),
|
|
754
|
+
action: "new",
|
|
755
|
+
attempt_token: attemptToken,
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
const documentNumber = await this.allocateDocumentNumber(input.kind, now, sharedContext);
|
|
759
|
+
const created = (await this.createDocuments({
|
|
760
|
+
kind: input.kind,
|
|
761
|
+
status: "processing",
|
|
762
|
+
issuance_key: issuanceKey,
|
|
763
|
+
order_id: input.order_id,
|
|
764
|
+
order_display_id: input.order_display_id,
|
|
765
|
+
customer_id: input.customer_id,
|
|
766
|
+
recipient_email: input.recipient_email,
|
|
767
|
+
document_number: documentNumber,
|
|
768
|
+
source_document_id: input.source_document_id ?? null,
|
|
769
|
+
refund_id: input.refund_id ?? null,
|
|
770
|
+
attempt_token: attemptToken,
|
|
771
|
+
lease_started_at: now,
|
|
772
|
+
lease_expires_at: leaseExpiresAt,
|
|
773
|
+
issued_at: now,
|
|
774
|
+
}, sharedContext));
|
|
775
|
+
return {
|
|
776
|
+
document: toDocumentRecord(created),
|
|
777
|
+
action: "new",
|
|
778
|
+
attempt_token: attemptToken,
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
async allocateDocumentNumber(kind, issuedAt, sharedContext) {
|
|
782
|
+
const periodYear = (0, document_number_1.resolveDocumentNumberPeriodYear)(issuedAt, this.pluginOptions_.numbering.timeZone);
|
|
783
|
+
const rows = await this.requireManager(sharedContext).execute(`insert into "documents_document_number_sequence"
|
|
784
|
+
("id", "kind", "period_year", "last_value", "created_at", "updated_at")
|
|
785
|
+
values (?, ?, ?, 1, now(), now())
|
|
786
|
+
on conflict ("kind", "period_year") do update
|
|
787
|
+
set "last_value" = "documents_document_number_sequence"."last_value" + 1,
|
|
788
|
+
"updated_at" = now()
|
|
789
|
+
where "documents_document_number_sequence"."deleted_at" is null
|
|
790
|
+
returning "last_value"`, [`docseq_${(0, node_crypto_1.randomUUID)()}`, kind, periodYear]);
|
|
791
|
+
const sequenceValue = Number(rows[0]?.last_value);
|
|
792
|
+
if (!Number.isInteger(sequenceValue) || sequenceValue <= 0) {
|
|
793
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `The ${kind} document-number sequence for ${periodYear} is unavailable.`);
|
|
794
|
+
}
|
|
795
|
+
return (0, document_number_1.formatDocumentNumber)({ kind, periodYear, sequenceValue });
|
|
796
|
+
}
|
|
797
|
+
async claimDocumentRegeneration(documentId, sharedContext = {}) {
|
|
798
|
+
const manager = this.requireManager(sharedContext);
|
|
799
|
+
const rows = await manager.execute(`select * from "documents_document"
|
|
800
|
+
where "id" = ? and "deleted_at" is null for update`, [asNonEmptyString(documentId, "document_id")]);
|
|
801
|
+
if (!rows[0]) {
|
|
802
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Document not found.");
|
|
803
|
+
}
|
|
804
|
+
const document = toDocumentRecord(rows[0]);
|
|
805
|
+
if (document.status !== "issued") {
|
|
806
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Document ${document.id} is not available for regeneration.`);
|
|
807
|
+
}
|
|
808
|
+
const now = new Date();
|
|
809
|
+
if (document.attempt_token &&
|
|
810
|
+
document.lease_expires_at &&
|
|
811
|
+
document.lease_expires_at.getTime() > now.getTime()) {
|
|
812
|
+
return { action: "in_progress", document, attempt_token: null };
|
|
813
|
+
}
|
|
814
|
+
const attemptToken = (0, node_crypto_1.randomUUID)();
|
|
815
|
+
const updated = (await this.updateDocuments({
|
|
816
|
+
id: document.id,
|
|
817
|
+
attempt_token: attemptToken,
|
|
818
|
+
lease_started_at: now,
|
|
819
|
+
lease_expires_at: new Date(now.getTime() + exports.DOCUMENT_ISSUANCE_LEASE_MS),
|
|
820
|
+
}, sharedContext));
|
|
821
|
+
return {
|
|
822
|
+
action: "render",
|
|
823
|
+
document: toDocumentRecord(updated),
|
|
824
|
+
attempt_token: attemptToken,
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
async finalizeShipmentInvoice(input, sharedContext = {}) {
|
|
828
|
+
const manager = this.requireManager(sharedContext);
|
|
829
|
+
const order = await this.lockCoreOrder(manager, input.order_id);
|
|
830
|
+
if (order.canceled) {
|
|
831
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Order ${input.order_id} is no longer eligible for invoice issuance.`);
|
|
832
|
+
}
|
|
833
|
+
await this.lockCompleteShipmentAggregate(manager, input.order_id, order.version, input.fulfillment_id);
|
|
834
|
+
const rows = await manager.execute(`select c."id" as "coordinator_id", a.*, d."id" as "document_id",
|
|
835
|
+
d."document_number" as "claimed_document_number",
|
|
836
|
+
d."issued_at" as "claimed_issued_at"
|
|
837
|
+
from "documents_shipment_invoice_coordinator" c
|
|
838
|
+
join "documents_shipment_invoice_assignment" a
|
|
839
|
+
on a."order_id" = c."order_id"
|
|
840
|
+
and a."fulfillment_id" = c."candidate_fulfillment_id"
|
|
841
|
+
join "documents_document" d on d."id" = ?
|
|
842
|
+
where c."order_id" = ? and c."state" = 'processing'
|
|
843
|
+
and c."attempt_token" = ? and c."lease_expires_at" > now()
|
|
844
|
+
and a."fulfillment_id" = ? and a."decision" = 'pending'
|
|
845
|
+
and d."status" = 'processing' and d."attempt_token" = ?
|
|
846
|
+
and d."lease_expires_at" > now()
|
|
847
|
+
and c."deleted_at" is null and a."deleted_at" is null
|
|
848
|
+
and d."deleted_at" is null
|
|
849
|
+
for update of c, a, d`, [
|
|
850
|
+
input.document_id,
|
|
851
|
+
input.order_id,
|
|
852
|
+
input.coordinator_token,
|
|
853
|
+
input.fulfillment_id,
|
|
854
|
+
input.document_token,
|
|
855
|
+
]);
|
|
856
|
+
if (!rows[0]) {
|
|
857
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The shipment invoice is owned by another issuance attempt.");
|
|
858
|
+
}
|
|
859
|
+
this.validatePreparedSnapshot(input.document_id, input.snapshot, {
|
|
860
|
+
document_number: asNonEmptyString(rows[0].claimed_document_number, "document_number"),
|
|
861
|
+
issued_at: asRequiredDate(rows[0].claimed_issued_at, "issued_at"),
|
|
862
|
+
});
|
|
863
|
+
const artifact = toArtifactRecord((await this.createDocumentArtifacts({
|
|
864
|
+
document_id: input.document_id,
|
|
865
|
+
file_id: input.file_id,
|
|
866
|
+
filename: input.filename,
|
|
867
|
+
content_type: "application/pdf",
|
|
868
|
+
communication_locked: true,
|
|
869
|
+
}, sharedContext)));
|
|
870
|
+
const rawDocument = (await this.updateDocuments({
|
|
871
|
+
id: input.document_id,
|
|
872
|
+
status: "issued",
|
|
873
|
+
snapshot: input.snapshot,
|
|
874
|
+
file_id: input.file_id,
|
|
875
|
+
filename: input.filename,
|
|
876
|
+
current_artifact_id: artifact.id,
|
|
877
|
+
attempt_token: null,
|
|
878
|
+
lease_started_at: null,
|
|
879
|
+
lease_expires_at: null,
|
|
880
|
+
failure_reason: null,
|
|
881
|
+
}, sharedContext));
|
|
882
|
+
const rawAssignment = (await this.updateShipmentInvoiceAssignments({
|
|
883
|
+
id: asNonEmptyString(rows[0].id, "assignment.id"),
|
|
884
|
+
decision: "carrier",
|
|
885
|
+
invoice_document_id: input.document_id,
|
|
886
|
+
invoice_artifact_id: artifact.id,
|
|
887
|
+
}, sharedContext));
|
|
888
|
+
await this.updateShipmentInvoiceCoordinators({
|
|
889
|
+
id: asNonEmptyString(rows[0].coordinator_id, "coordinator.id"),
|
|
890
|
+
state: "completed",
|
|
891
|
+
carrier_assignment_id: asNonEmptyString(rows[0].id, "assignment.id"),
|
|
892
|
+
invoice_document_id: input.document_id,
|
|
893
|
+
invoice_artifact_id: artifact.id,
|
|
894
|
+
attempt_token: null,
|
|
895
|
+
lease_started_at: null,
|
|
896
|
+
lease_expires_at: null,
|
|
897
|
+
}, sharedContext);
|
|
898
|
+
return {
|
|
899
|
+
document: toDocumentRecord(rawDocument),
|
|
900
|
+
artifact,
|
|
901
|
+
assignment: toShipmentAssignmentRecord(rawAssignment),
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
async finalizeDocumentRegeneration(input, sharedContext = {}) {
|
|
905
|
+
const manager = this.requireManager(sharedContext);
|
|
906
|
+
const rows = await manager.execute(`select d.*, a."id" as "old_artifact_id",
|
|
907
|
+
a."document_id" as "old_document_id", a."file_id" as "old_file_id",
|
|
908
|
+
a."filename" as "old_filename", a."content_type" as "old_content_type",
|
|
909
|
+
a."communication_locked" as "old_communication_locked",
|
|
910
|
+
a."created_at" as "old_created_at"
|
|
911
|
+
from "documents_document" d
|
|
912
|
+
left join "documents_document_artifact" a
|
|
913
|
+
on a."id" = d."current_artifact_id" and a."deleted_at" is null
|
|
914
|
+
where d."id" = ? and d."status" = 'issued'
|
|
915
|
+
and d."attempt_token" = ? and d."lease_expires_at" > now()
|
|
916
|
+
and d."deleted_at" is null for update of d`, [input.id, input.attempt_token]);
|
|
917
|
+
if (!rows[0]) {
|
|
918
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The document is owned by another regeneration attempt.");
|
|
919
|
+
}
|
|
920
|
+
const current = toDocumentRecord(rows[0]);
|
|
921
|
+
this.validatePreparedSnapshot(input.id, input.snapshot, current);
|
|
922
|
+
const replacedArtifact = rows[0].old_artifact_id
|
|
923
|
+
? toArtifactRecord({
|
|
924
|
+
id: rows[0].old_artifact_id,
|
|
925
|
+
document_id: rows[0].old_document_id,
|
|
926
|
+
file_id: rows[0].old_file_id,
|
|
927
|
+
filename: rows[0].old_filename,
|
|
928
|
+
content_type: rows[0].old_content_type,
|
|
929
|
+
communication_locked: rows[0].old_communication_locked,
|
|
930
|
+
created_at: rows[0].old_created_at,
|
|
931
|
+
})
|
|
932
|
+
: null;
|
|
933
|
+
const artifact = toArtifactRecord((await this.createDocumentArtifacts({
|
|
934
|
+
document_id: input.id,
|
|
935
|
+
file_id: input.file_id,
|
|
936
|
+
filename: input.filename,
|
|
937
|
+
content_type: "application/pdf",
|
|
938
|
+
communication_locked: false,
|
|
939
|
+
}, sharedContext)));
|
|
940
|
+
const updated = (await this.updateDocuments({
|
|
941
|
+
id: input.id,
|
|
942
|
+
snapshot: input.snapshot,
|
|
943
|
+
file_id: input.file_id,
|
|
944
|
+
filename: input.filename,
|
|
945
|
+
current_artifact_id: artifact.id,
|
|
946
|
+
attempt_token: null,
|
|
947
|
+
lease_started_at: null,
|
|
948
|
+
lease_expires_at: null,
|
|
949
|
+
failure_reason: null,
|
|
950
|
+
}, sharedContext));
|
|
951
|
+
return {
|
|
952
|
+
document: toDocumentRecord(updated),
|
|
953
|
+
artifact,
|
|
954
|
+
replaced_artifact: replacedArtifact,
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
async markDocumentIssuanceFailed(input, sharedContext = {}) {
|
|
958
|
+
await this.requireManager(sharedContext).execute(`update "documents_document"
|
|
959
|
+
set "status" = case when "status" = 'issued' then 'issued' else 'failed' end,
|
|
960
|
+
"attempt_token" = null, "lease_started_at" = null,
|
|
961
|
+
"lease_expires_at" = null, "failure_reason" = ?, "updated_at" = now()
|
|
962
|
+
where "id" = ? and "attempt_token" = ? and "deleted_at" is null`, [input.reason, input.document_id, input.attempt_token]);
|
|
963
|
+
}
|
|
964
|
+
validatePreparedSnapshot(documentId, snapshot, expected) {
|
|
965
|
+
if (snapshot.document.id !== documentId || !snapshot.document.number) {
|
|
966
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Document ${documentId} has an invalid snapshot.`);
|
|
967
|
+
}
|
|
968
|
+
const issuedAt = new Date(snapshot.document.issued_at);
|
|
969
|
+
if (Number.isNaN(issuedAt.getTime())) {
|
|
970
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Document ${documentId} snapshot has an invalid issue date.`);
|
|
971
|
+
}
|
|
972
|
+
if (expected &&
|
|
973
|
+
(snapshot.document.number !== expected.document_number ||
|
|
974
|
+
issuedAt.getTime() !== expected.issued_at.getTime())) {
|
|
975
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Document ${documentId} must retain its reserved number and issue date.`);
|
|
976
|
+
}
|
|
977
|
+
return issuedAt;
|
|
978
|
+
}
|
|
979
|
+
async upsertRefundDocumentResolution(input, sharedContext = {}) {
|
|
980
|
+
const refundId = asNonEmptyString(input.refund_id, "refund_id");
|
|
981
|
+
const orderId = asNonEmptyString(input.order_id, "order_id");
|
|
982
|
+
const paymentId = asNonEmptyString(input.payment_id, "payment_id");
|
|
983
|
+
const manager = this.requireManager(sharedContext);
|
|
984
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
985
|
+
`documents:refund:${refundId}`,
|
|
986
|
+
]);
|
|
987
|
+
const rows = await manager.execute(`select * from "documents_refund_document_resolution"
|
|
988
|
+
where "refund_id" = ? for update`, [refundId]);
|
|
989
|
+
if (rows[0]) {
|
|
990
|
+
const existing = toRefundResolutionRecord(rows[0]);
|
|
991
|
+
if (existing.order_id !== orderId || existing.payment_id !== paymentId) {
|
|
992
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Refund ${refundId} already has another document resolution identity.`);
|
|
993
|
+
}
|
|
994
|
+
return existing;
|
|
995
|
+
}
|
|
996
|
+
const created = (await this.createRefundDocumentResolutions({
|
|
997
|
+
refund_id: refundId,
|
|
998
|
+
order_id: orderId,
|
|
999
|
+
payment_id: paymentId,
|
|
1000
|
+
state: "pending_source",
|
|
1001
|
+
}, sharedContext));
|
|
1002
|
+
return toRefundResolutionRecord(created);
|
|
1003
|
+
}
|
|
1004
|
+
async claimRefundDocumentResolution(resolutionId, sharedContext = {}) {
|
|
1005
|
+
const manager = this.requireManager(sharedContext);
|
|
1006
|
+
const rows = await manager.execute(`select * from "documents_refund_document_resolution"
|
|
1007
|
+
where "id" = ? and "deleted_at" is null for update`, [asNonEmptyString(resolutionId, "resolution_id")]);
|
|
1008
|
+
if (!rows[0]) {
|
|
1009
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Refund document resolution not found.");
|
|
1010
|
+
}
|
|
1011
|
+
const resolution = toRefundResolutionRecord(rows[0]);
|
|
1012
|
+
if (resolution.state === "ready" || resolution.state === "not_applicable") {
|
|
1013
|
+
return { action: "final", resolution, attempt_token: null };
|
|
1014
|
+
}
|
|
1015
|
+
const now = new Date();
|
|
1016
|
+
if (resolution.state === "processing" &&
|
|
1017
|
+
resolution.attempt_token &&
|
|
1018
|
+
resolution.lease_expires_at &&
|
|
1019
|
+
resolution.lease_expires_at.getTime() > now.getTime()) {
|
|
1020
|
+
return { action: "in_progress", resolution, attempt_token: null };
|
|
1021
|
+
}
|
|
1022
|
+
const attemptToken = (0, node_crypto_1.randomUUID)();
|
|
1023
|
+
const updated = (await this.updateRefundDocumentResolutions({
|
|
1024
|
+
id: resolution.id,
|
|
1025
|
+
state: "processing",
|
|
1026
|
+
attempt_token: attemptToken,
|
|
1027
|
+
lease_started_at: now,
|
|
1028
|
+
lease_expires_at: new Date(now.getTime() + exports.DOCUMENT_ISSUANCE_LEASE_MS),
|
|
1029
|
+
failure_code: null,
|
|
1030
|
+
}, sharedContext));
|
|
1031
|
+
return {
|
|
1032
|
+
action: "process",
|
|
1033
|
+
resolution: toRefundResolutionRecord(updated),
|
|
1034
|
+
attempt_token: attemptToken,
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
async finalizeRefundWithoutDocument(input, sharedContext = {}) {
|
|
1038
|
+
const manager = this.requireManager(sharedContext);
|
|
1039
|
+
const identityRows = await manager.execute(`select "order_id" from "documents_refund_document_resolution"
|
|
1040
|
+
where "id" = ? and "deleted_at" is null limit 1`, [input.resolution_id]);
|
|
1041
|
+
if (!identityRows[0]) {
|
|
1042
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Refund document resolution not found.");
|
|
1043
|
+
}
|
|
1044
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
1045
|
+
`documents:cancellation:${identityRows[0].order_id}`,
|
|
1046
|
+
]);
|
|
1047
|
+
const order = await this.lockCoreOrder(manager, identityRows[0].order_id);
|
|
1048
|
+
const rows = await manager.execute(`select * from "documents_refund_document_resolution"
|
|
1049
|
+
where "id" = ? and "state" = 'processing' and "attempt_token" = ?
|
|
1050
|
+
and "lease_expires_at" > now() and "deleted_at" is null for update`, [input.resolution_id, input.attempt_token]);
|
|
1051
|
+
if (!rows[0]) {
|
|
1052
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The refund is owned by another resolution attempt.");
|
|
1053
|
+
}
|
|
1054
|
+
const resolution = toRefundResolutionRecord(rows[0]);
|
|
1055
|
+
const cancellationRows = await manager.execute(`select "id" from "documents_order_cancellation_resolution"
|
|
1056
|
+
where "order_id" = ? limit 1 for update`, [resolution.order_id]);
|
|
1057
|
+
const owner = (0, document_resolution_1.resolveRefundCommunicationOwner)({
|
|
1058
|
+
order_canceled: input.order_canceled || order.canceled,
|
|
1059
|
+
cancellation_resolution_exists: Boolean(cancellationRows[0]),
|
|
1060
|
+
});
|
|
1061
|
+
const updated = (await this.updateRefundDocumentResolutions({
|
|
1062
|
+
id: resolution.id,
|
|
1063
|
+
state: "not_applicable",
|
|
1064
|
+
communication_owner: owner,
|
|
1065
|
+
attempt_token: null,
|
|
1066
|
+
lease_started_at: null,
|
|
1067
|
+
lease_expires_at: null,
|
|
1068
|
+
failure_code: null,
|
|
1069
|
+
}, sharedContext));
|
|
1070
|
+
return toRefundResolutionRecord(updated);
|
|
1071
|
+
}
|
|
1072
|
+
async finalizeRefundDocument(input, sharedContext = {}) {
|
|
1073
|
+
const manager = this.requireManager(sharedContext);
|
|
1074
|
+
const identityRows = await manager.execute(`select "order_id" from "documents_refund_document_resolution"
|
|
1075
|
+
where "id" = ? and "deleted_at" is null limit 1`, [input.resolution_id]);
|
|
1076
|
+
if (!identityRows[0]) {
|
|
1077
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Refund document resolution not found.");
|
|
1078
|
+
}
|
|
1079
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
1080
|
+
`documents:cancellation:${identityRows[0].order_id}`,
|
|
1081
|
+
]);
|
|
1082
|
+
const order = await this.lockCoreOrder(manager, identityRows[0].order_id);
|
|
1083
|
+
const rows = await manager.execute(`select r.*, d."id" as "claimed_document_id",
|
|
1084
|
+
d."document_number" as "claimed_document_number",
|
|
1085
|
+
d."issued_at" as "claimed_issued_at"
|
|
1086
|
+
from "documents_refund_document_resolution" r
|
|
1087
|
+
join "documents_document" d on d."id" = ? and d."refund_id" = r."refund_id"
|
|
1088
|
+
where r."id" = ? and r."state" = 'processing'
|
|
1089
|
+
and r."attempt_token" = ? and r."lease_expires_at" > now()
|
|
1090
|
+
and d."status" = 'processing' and d."attempt_token" = ?
|
|
1091
|
+
and d."lease_expires_at" > now()
|
|
1092
|
+
and r."deleted_at" is null and d."deleted_at" is null
|
|
1093
|
+
for update of r, d`, [
|
|
1094
|
+
input.document_id,
|
|
1095
|
+
input.resolution_id,
|
|
1096
|
+
input.resolution_token,
|
|
1097
|
+
input.document_token,
|
|
1098
|
+
]);
|
|
1099
|
+
if (!rows[0]) {
|
|
1100
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The refund document is owned by another resolution attempt.");
|
|
1101
|
+
}
|
|
1102
|
+
const resolution = toRefundResolutionRecord(rows[0]);
|
|
1103
|
+
this.validatePreparedSnapshot(input.document_id, input.snapshot, {
|
|
1104
|
+
document_number: asNonEmptyString(rows[0].claimed_document_number, "document_number"),
|
|
1105
|
+
issued_at: asRequiredDate(rows[0].claimed_issued_at, "issued_at"),
|
|
1106
|
+
});
|
|
1107
|
+
const cancellationRows = await manager.execute(`select "id" from "documents_order_cancellation_resolution"
|
|
1108
|
+
where "order_id" = ? limit 1 for update`, [resolution.order_id]);
|
|
1109
|
+
const owner = (0, document_resolution_1.resolveRefundCommunicationOwner)({
|
|
1110
|
+
order_canceled: input.order_canceled || order.canceled,
|
|
1111
|
+
cancellation_resolution_exists: Boolean(cancellationRows[0]),
|
|
1112
|
+
});
|
|
1113
|
+
const artifact = toArtifactRecord((await this.createDocumentArtifacts({
|
|
1114
|
+
document_id: input.document_id,
|
|
1115
|
+
file_id: input.file_id,
|
|
1116
|
+
filename: input.filename,
|
|
1117
|
+
content_type: "application/pdf",
|
|
1118
|
+
communication_locked: true,
|
|
1119
|
+
}, sharedContext)));
|
|
1120
|
+
const rawDocument = (await this.updateDocuments({
|
|
1121
|
+
id: input.document_id,
|
|
1122
|
+
status: "issued",
|
|
1123
|
+
snapshot: input.snapshot,
|
|
1124
|
+
file_id: input.file_id,
|
|
1125
|
+
filename: input.filename,
|
|
1126
|
+
current_artifact_id: artifact.id,
|
|
1127
|
+
attempt_token: null,
|
|
1128
|
+
lease_started_at: null,
|
|
1129
|
+
lease_expires_at: null,
|
|
1130
|
+
failure_reason: null,
|
|
1131
|
+
}, sharedContext));
|
|
1132
|
+
const rawResolution = (await this.updateRefundDocumentResolutions({
|
|
1133
|
+
id: resolution.id,
|
|
1134
|
+
state: "ready",
|
|
1135
|
+
document_id: input.document_id,
|
|
1136
|
+
artifact_id: artifact.id,
|
|
1137
|
+
communication_owner: owner,
|
|
1138
|
+
attempt_token: null,
|
|
1139
|
+
lease_started_at: null,
|
|
1140
|
+
lease_expires_at: null,
|
|
1141
|
+
failure_code: null,
|
|
1142
|
+
}, sharedContext));
|
|
1143
|
+
return {
|
|
1144
|
+
resolution: toRefundResolutionRecord(rawResolution),
|
|
1145
|
+
document: toDocumentRecord(rawDocument),
|
|
1146
|
+
artifact,
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
async markRefundResolutionFailed(input, sharedContext = {}) {
|
|
1150
|
+
await this.requireManager(sharedContext).execute(`update "documents_refund_document_resolution"
|
|
1151
|
+
set "state" = 'failed', "attempt_token" = null,
|
|
1152
|
+
"lease_started_at" = null, "lease_expires_at" = null,
|
|
1153
|
+
"failure_code" = ?, "updated_at" = now()
|
|
1154
|
+
where "id" = ? and "state" = 'processing' and "attempt_token" = ?
|
|
1155
|
+
and "deleted_at" is null`, [input.failure_code, input.resolution_id, input.attempt_token]);
|
|
1156
|
+
}
|
|
1157
|
+
async upsertOrderCancellationResolution(input, sharedContext = {}) {
|
|
1158
|
+
const orderId = asNonEmptyString(input.order_id, "order_id");
|
|
1159
|
+
const expectedRefundIds = (0, document_resolution_1.canonicalizeRefundIds)(input.expected_refund_ids);
|
|
1160
|
+
const manager = this.requireManager(sharedContext);
|
|
1161
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
1162
|
+
`documents:cancellation:${orderId}`,
|
|
1163
|
+
]);
|
|
1164
|
+
const rows = await manager.execute(`select * from "documents_order_cancellation_resolution"
|
|
1165
|
+
where "order_id" = ? for update`, [orderId]);
|
|
1166
|
+
if (rows[0]) {
|
|
1167
|
+
const existing = toCancellationResolutionRecord(rows[0]);
|
|
1168
|
+
if (JSON.stringify(existing.expected_refund_ids) !==
|
|
1169
|
+
JSON.stringify(expectedRefundIds)) {
|
|
1170
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Order ${orderId} cancellation refund set is already frozen.`);
|
|
1171
|
+
}
|
|
1172
|
+
return existing;
|
|
1173
|
+
}
|
|
1174
|
+
const created = (await this.createOrderCancellationResolutions({
|
|
1175
|
+
order_id: orderId,
|
|
1176
|
+
state: "pending",
|
|
1177
|
+
expected_refund_ids: expectedRefundIds,
|
|
1178
|
+
attachments: [],
|
|
1179
|
+
}, sharedContext));
|
|
1180
|
+
return toCancellationResolutionRecord(created);
|
|
1181
|
+
}
|
|
1182
|
+
async claimOrderCancellationResolution(resolutionId, sharedContext = {}) {
|
|
1183
|
+
const manager = this.requireManager(sharedContext);
|
|
1184
|
+
const rows = await manager.execute(`select * from "documents_order_cancellation_resolution"
|
|
1185
|
+
where "id" = ? and "deleted_at" is null for update`, [resolutionId]);
|
|
1186
|
+
if (!rows[0]) {
|
|
1187
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Order cancellation resolution not found.");
|
|
1188
|
+
}
|
|
1189
|
+
const resolution = toCancellationResolutionRecord(rows[0]);
|
|
1190
|
+
if (resolution.state === "ready") {
|
|
1191
|
+
return { action: "ready", resolution, attempt_token: null };
|
|
1192
|
+
}
|
|
1193
|
+
const now = new Date();
|
|
1194
|
+
if (resolution.state === "processing" &&
|
|
1195
|
+
resolution.attempt_token &&
|
|
1196
|
+
resolution.lease_expires_at &&
|
|
1197
|
+
resolution.lease_expires_at.getTime() > now.getTime()) {
|
|
1198
|
+
return { action: "in_progress", resolution, attempt_token: null };
|
|
1199
|
+
}
|
|
1200
|
+
const attemptToken = (0, node_crypto_1.randomUUID)();
|
|
1201
|
+
const updated = (await this.updateOrderCancellationResolutions({
|
|
1202
|
+
id: resolution.id,
|
|
1203
|
+
state: "processing",
|
|
1204
|
+
attempt_token: attemptToken,
|
|
1205
|
+
lease_started_at: now,
|
|
1206
|
+
lease_expires_at: new Date(now.getTime() + exports.DOCUMENT_ISSUANCE_LEASE_MS),
|
|
1207
|
+
failure_code: null,
|
|
1208
|
+
}, sharedContext));
|
|
1209
|
+
return {
|
|
1210
|
+
action: "process",
|
|
1211
|
+
resolution: toCancellationResolutionRecord(updated),
|
|
1212
|
+
attempt_token: attemptToken,
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
async finalizeOrderCancellationResolution(input, sharedContext = {}) {
|
|
1216
|
+
const manager = this.requireManager(sharedContext);
|
|
1217
|
+
const identityRows = await manager.execute(`select "order_id" from "documents_order_cancellation_resolution"
|
|
1218
|
+
where "id" = ? and "deleted_at" is null limit 1`, [input.resolution_id]);
|
|
1219
|
+
if (!identityRows[0]) {
|
|
1220
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Order cancellation resolution not found.");
|
|
1221
|
+
}
|
|
1222
|
+
await manager.execute("select pg_advisory_xact_lock(hashtext(?))", [
|
|
1223
|
+
`documents:cancellation:${identityRows[0].order_id}`,
|
|
1224
|
+
]);
|
|
1225
|
+
const rows = await manager.execute(`select * from "documents_order_cancellation_resolution"
|
|
1226
|
+
where "id" = ? and "state" = 'processing' and "attempt_token" = ?
|
|
1227
|
+
and "lease_expires_at" > now() and "deleted_at" is null for update`, [input.resolution_id, input.attempt_token]);
|
|
1228
|
+
if (!rows[0]) {
|
|
1229
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "The cancellation is owned by another resolution attempt.");
|
|
1230
|
+
}
|
|
1231
|
+
const resolution = toCancellationResolutionRecord(rows[0]);
|
|
1232
|
+
const refundRows = resolution.expected_refund_ids.length
|
|
1233
|
+
? await manager.execute(`select * from "documents_refund_document_resolution"
|
|
1234
|
+
where "refund_id" = any(?) and "deleted_at" is null for update`, [resolution.expected_refund_ids])
|
|
1235
|
+
: [];
|
|
1236
|
+
const refunds = refundRows.map(toRefundResolutionRecord);
|
|
1237
|
+
if (!(0, document_resolution_1.isCancellationResolutionReady)(resolution.expected_refund_ids, refunds)) {
|
|
1238
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Order ${resolution.order_id} cancellation documents are not ready.`);
|
|
1239
|
+
}
|
|
1240
|
+
const attachments = refunds
|
|
1241
|
+
.filter((refund) => refund.state === "ready" && Boolean(refund.artifact_id))
|
|
1242
|
+
.map((refund) => ({
|
|
1243
|
+
payment_id: refund.payment_id,
|
|
1244
|
+
refund_id: refund.refund_id,
|
|
1245
|
+
artifact_id: refund.artifact_id,
|
|
1246
|
+
}))
|
|
1247
|
+
.sort((left, right) => left.refund_id.localeCompare(right.refund_id));
|
|
1248
|
+
if (attachments.length) {
|
|
1249
|
+
await manager.execute(`update "documents_document_artifact"
|
|
1250
|
+
set "communication_locked" = true, "updated_at" = now()
|
|
1251
|
+
where "id" = any(?) and "deleted_at" is null`, [attachments.map((attachment) => attachment.artifact_id)]);
|
|
1252
|
+
}
|
|
1253
|
+
const updated = (await this.updateOrderCancellationResolutions({
|
|
1254
|
+
id: resolution.id,
|
|
1255
|
+
state: "ready",
|
|
1256
|
+
attachments,
|
|
1257
|
+
attempt_token: null,
|
|
1258
|
+
lease_started_at: null,
|
|
1259
|
+
lease_expires_at: null,
|
|
1260
|
+
failure_code: null,
|
|
1261
|
+
}, sharedContext));
|
|
1262
|
+
return toCancellationResolutionRecord(updated);
|
|
1263
|
+
}
|
|
1264
|
+
async markOrderCancellationResolutionFailed(input, sharedContext = {}) {
|
|
1265
|
+
await this.requireManager(sharedContext).execute(`update "documents_order_cancellation_resolution"
|
|
1266
|
+
set "state" = 'failed', "attempt_token" = null,
|
|
1267
|
+
"lease_started_at" = null, "lease_expires_at" = null,
|
|
1268
|
+
"failure_code" = ?, "updated_at" = now()
|
|
1269
|
+
where "id" = ? and "state" = 'processing' and "attempt_token" = ?
|
|
1270
|
+
and "deleted_at" is null`, [input.failure_code, input.resolution_id, input.attempt_token]);
|
|
1271
|
+
}
|
|
1272
|
+
async retrieveDocumentRecord(documentId) {
|
|
1273
|
+
const document = (await this.retrieveDocument(documentId));
|
|
1274
|
+
return toDocumentRecord(document);
|
|
1275
|
+
}
|
|
1276
|
+
async listIssuedDocumentsForCustomer(customerId) {
|
|
1277
|
+
const documents = (await this.listDocuments({ customer_id: customerId, status: "issued" }, { order: { issued_at: "DESC" } }));
|
|
1278
|
+
return documents.map(toDocumentRecord);
|
|
1279
|
+
}
|
|
1280
|
+
async getDocumentForCustomer(documentId, customerId) {
|
|
1281
|
+
const documents = (await this.listDocuments({ id: documentId, customer_id: customerId, status: "issued" }, { take: 1 }));
|
|
1282
|
+
return documents[0] ? toDocumentRecord(documents[0]) : null;
|
|
1283
|
+
}
|
|
1284
|
+
async listIssuedDocumentsForOrder(orderId) {
|
|
1285
|
+
const documents = (await this.listDocuments({ order_id: orderId, status: "issued" }, { order: { issued_at: "DESC" } }));
|
|
1286
|
+
return documents.map(toDocumentRecord);
|
|
1287
|
+
}
|
|
1288
|
+
async getDocumentForOrder(documentId, orderId) {
|
|
1289
|
+
const documents = (await this.listDocuments({ id: documentId, order_id: orderId, status: "issued" }, { take: 1 }));
|
|
1290
|
+
return documents[0] ? toDocumentRecord(documents[0]) : null;
|
|
1291
|
+
}
|
|
1292
|
+
async getIssuedInvoiceForOrder(orderId) {
|
|
1293
|
+
const documents = (await this.listDocuments({ order_id: orderId, kind: "invoice", status: "issued" }, { take: 1 }));
|
|
1294
|
+
return documents[0] ? toDocumentRecord(documents[0]) : null;
|
|
1295
|
+
}
|
|
1296
|
+
async isDocumentFileDeletable(input, sharedContext = {}) {
|
|
1297
|
+
const rows = await this.requireManager(sharedContext).execute(`select a."id", a."communication_locked",
|
|
1298
|
+
d."id" as "current_document_id",
|
|
1299
|
+
(
|
|
1300
|
+
exists (
|
|
1301
|
+
select 1 from "documents_shipment_invoice_assignment" s
|
|
1302
|
+
where s."invoice_artifact_id" = a."id"
|
|
1303
|
+
and s."decision" = 'carrier'
|
|
1304
|
+
) or exists (
|
|
1305
|
+
select 1 from "documents_refund_document_resolution" r
|
|
1306
|
+
where r."artifact_id" = a."id" and r."state" = 'ready'
|
|
1307
|
+
) or exists (
|
|
1308
|
+
select 1 from "documents_order_cancellation_resolution" c
|
|
1309
|
+
where c."state" = 'ready'
|
|
1310
|
+
and c."attachments" @> jsonb_build_array(
|
|
1311
|
+
jsonb_build_object('artifact_id', a."id")
|
|
1312
|
+
)
|
|
1313
|
+
)
|
|
1314
|
+
) as "fact_referenced"
|
|
1315
|
+
from "documents_document_artifact" a
|
|
1316
|
+
left join "documents_document" d
|
|
1317
|
+
on d."current_artifact_id" = a."id" and d."deleted_at" is null
|
|
1318
|
+
where a."file_id" = ? limit 1 for update of a`, [asNonEmptyString(input.file_id, "file_id")]);
|
|
1319
|
+
if (!rows[0]) {
|
|
1320
|
+
return true;
|
|
1321
|
+
}
|
|
1322
|
+
return (rows[0].id === input.replaced_artifact_id &&
|
|
1323
|
+
!rows[0].communication_locked &&
|
|
1324
|
+
!rows[0].current_document_id &&
|
|
1325
|
+
!rows[0].fact_referenced);
|
|
1326
|
+
}
|
|
1327
|
+
async listUnpublishedDocumentFacts(input, sharedContext = {}) {
|
|
1328
|
+
if (!Number.isInteger(input.limit) || input.limit <= 0 || input.limit > 100) {
|
|
1329
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Document fact publication limit must be between 1 and 100.");
|
|
1330
|
+
}
|
|
1331
|
+
const manager = this.requireManager(sharedContext);
|
|
1332
|
+
const assignmentRows = await manager.execute(`select a.*, d."document_number", ar."file_id", ar."filename",
|
|
1333
|
+
ar."content_type"
|
|
1334
|
+
from "documents_shipment_invoice_assignment" a
|
|
1335
|
+
left join "documents_document" d on d."id" = a."invoice_document_id"
|
|
1336
|
+
left join "documents_document_artifact" ar
|
|
1337
|
+
on ar."id" = a."invoice_artifact_id"
|
|
1338
|
+
where a."decision" in ('carrier', 'non_carrier')
|
|
1339
|
+
and a."event_emitted_at" is null and a."deleted_at" is null
|
|
1340
|
+
order by a."created_at" asc, a."id" asc limit ?`, [input.limit]);
|
|
1341
|
+
const assignmentFacts = [];
|
|
1342
|
+
for (const row of assignmentRows) {
|
|
1343
|
+
const assignment = toShipmentAssignmentRecord(row);
|
|
1344
|
+
if (assignment.decision === "non_carrier") {
|
|
1345
|
+
assignmentFacts.push({
|
|
1346
|
+
kind: "shipment_assignment",
|
|
1347
|
+
id: assignment.id,
|
|
1348
|
+
event_name: documents_1.DOCUMENTS_SHIPMENT_INVOICE_ASSIGNMENT_DECIDED_EVENT,
|
|
1349
|
+
payload: {
|
|
1350
|
+
schema_version: 1,
|
|
1351
|
+
order_id: assignment.order_id,
|
|
1352
|
+
fulfillment_id: assignment.fulfillment_id,
|
|
1353
|
+
decision: "non_carrier",
|
|
1354
|
+
},
|
|
1355
|
+
});
|
|
1356
|
+
continue;
|
|
1357
|
+
}
|
|
1358
|
+
try {
|
|
1359
|
+
assignmentFacts.push({
|
|
1360
|
+
kind: "shipment_assignment",
|
|
1361
|
+
id: assignment.id,
|
|
1362
|
+
event_name: documents_1.DOCUMENTS_SHIPMENT_INVOICE_ASSIGNMENT_DECIDED_EVENT,
|
|
1363
|
+
payload: {
|
|
1364
|
+
schema_version: 1,
|
|
1365
|
+
order_id: assignment.order_id,
|
|
1366
|
+
fulfillment_id: assignment.fulfillment_id,
|
|
1367
|
+
decision: "carrier",
|
|
1368
|
+
invoice_fulfillment_id: assignment.fulfillment_id,
|
|
1369
|
+
invoice_artifact: this.artifactDescriptorFromRow(row),
|
|
1370
|
+
},
|
|
1371
|
+
});
|
|
1372
|
+
}
|
|
1373
|
+
catch {
|
|
1374
|
+
continue;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
const refundRows = await manager.execute(`select r.*, d."document_number", ar."file_id", ar."filename",
|
|
1378
|
+
ar."content_type", ar."document_id" as "artifact_document_id"
|
|
1379
|
+
from "documents_refund_document_resolution" r
|
|
1380
|
+
left join "documents_document" d on d."id" = r."document_id"
|
|
1381
|
+
left join "documents_document_artifact" ar on ar."id" = r."artifact_id"
|
|
1382
|
+
where r."state" in ('ready', 'not_applicable')
|
|
1383
|
+
and r."communication_owner" = 'standalone'
|
|
1384
|
+
and r."event_emitted_at" is null and r."deleted_at" is null
|
|
1385
|
+
order by r."updated_at" asc, r."id" asc limit ?`, [input.limit]);
|
|
1386
|
+
const refundFacts = [];
|
|
1387
|
+
for (const row of refundRows) {
|
|
1388
|
+
const refund = toRefundResolutionRecord(row);
|
|
1389
|
+
try {
|
|
1390
|
+
refundFacts.push({
|
|
1391
|
+
kind: "refund",
|
|
1392
|
+
id: refund.id,
|
|
1393
|
+
event_name: documents_1.DOCUMENTS_REFUND_DOCUMENT_READY_EVENT,
|
|
1394
|
+
payload: {
|
|
1395
|
+
schema_version: 1,
|
|
1396
|
+
order_id: refund.order_id,
|
|
1397
|
+
payment_id: refund.payment_id,
|
|
1398
|
+
refund_id: refund.refund_id,
|
|
1399
|
+
artifact: refund.state === "ready"
|
|
1400
|
+
? this.artifactDescriptorFromRow(row)
|
|
1401
|
+
: null,
|
|
1402
|
+
},
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
catch {
|
|
1406
|
+
continue;
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
const cancellationRows = await manager.execute(`select * from "documents_order_cancellation_resolution"
|
|
1410
|
+
where "state" = 'ready' and "event_emitted_at" is null
|
|
1411
|
+
and "deleted_at" is null
|
|
1412
|
+
order by "updated_at" asc, "id" asc limit ?`, [input.limit]);
|
|
1413
|
+
const cancellationFacts = [];
|
|
1414
|
+
cancellationLoop: for (const row of cancellationRows) {
|
|
1415
|
+
const cancellation = toCancellationResolutionRecord(row);
|
|
1416
|
+
const attachments = [];
|
|
1417
|
+
for (const attachment of cancellation.attachments) {
|
|
1418
|
+
const artifactRows = await manager.execute(`select ar.*, d."document_number"
|
|
1419
|
+
from "documents_document_artifact" ar
|
|
1420
|
+
join "documents_document" d on d."id" = ar."document_id"
|
|
1421
|
+
where ar."id" = ? and ar."communication_locked" = true
|
|
1422
|
+
and ar."deleted_at" is null and d."deleted_at" is null`, [attachment.artifact_id]);
|
|
1423
|
+
if (!artifactRows[0]) {
|
|
1424
|
+
continue cancellationLoop;
|
|
1425
|
+
}
|
|
1426
|
+
try {
|
|
1427
|
+
attachments.push({
|
|
1428
|
+
payment_id: attachment.payment_id,
|
|
1429
|
+
refund_id: attachment.refund_id,
|
|
1430
|
+
artifact: this.artifactDescriptorFromRow(artifactRows[0]),
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
catch {
|
|
1434
|
+
continue cancellationLoop;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
cancellationFacts.push({
|
|
1438
|
+
kind: "order_cancellation",
|
|
1439
|
+
id: cancellation.id,
|
|
1440
|
+
event_name: documents_1.DOCUMENTS_ORDER_CANCELLATION_DOCUMENTS_READY_EVENT,
|
|
1441
|
+
payload: {
|
|
1442
|
+
schema_version: 1,
|
|
1443
|
+
order_id: cancellation.order_id,
|
|
1444
|
+
expected_refund_ids: cancellation.expected_refund_ids,
|
|
1445
|
+
attachments,
|
|
1446
|
+
},
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
const queues = [assignmentFacts, refundFacts, cancellationFacts];
|
|
1450
|
+
const facts = [];
|
|
1451
|
+
for (let index = 0; facts.length < input.limit; index += 1) {
|
|
1452
|
+
let added = false;
|
|
1453
|
+
for (const queue of queues) {
|
|
1454
|
+
const fact = queue[index];
|
|
1455
|
+
if (fact && facts.length < input.limit) {
|
|
1456
|
+
facts.push(fact);
|
|
1457
|
+
added = true;
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
if (!added) {
|
|
1461
|
+
break;
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
return facts;
|
|
1465
|
+
}
|
|
1466
|
+
async markDocumentFactEmitted(input, sharedContext = {}) {
|
|
1467
|
+
const tables = {
|
|
1468
|
+
shipment_assignment: "documents_shipment_invoice_assignment",
|
|
1469
|
+
refund: "documents_refund_document_resolution",
|
|
1470
|
+
order_cancellation: "documents_order_cancellation_resolution",
|
|
1471
|
+
};
|
|
1472
|
+
await this.requireManager(sharedContext).execute(`update "${tables[input.kind]}" set "event_emitted_at" = ?, "updated_at" = now()
|
|
1473
|
+
where "id" = ? and "event_emitted_at" is null and "deleted_at" is null`, [input.emitted_at, input.id]);
|
|
1474
|
+
}
|
|
1475
|
+
async listDocumentResolutionReconciliationCandidates(input, sharedContext = {}) {
|
|
1476
|
+
const manager = this.requireManager(sharedContext);
|
|
1477
|
+
const assignmentRows = await manager.execute(`select a."fulfillment_id"
|
|
1478
|
+
from "documents_shipment_invoice_assignment" a
|
|
1479
|
+
left join "documents_shipment_invoice_coordinator" c
|
|
1480
|
+
on c."order_id" = a."order_id"
|
|
1481
|
+
where a."decision" = 'pending' and a."deleted_at" is null
|
|
1482
|
+
and (c."state" is null or c."state" <> 'processing'
|
|
1483
|
+
or c."lease_expires_at" <= now())
|
|
1484
|
+
order by a."created_at" asc limit ?`, [input.limit]);
|
|
1485
|
+
const refundRows = await manager.execute(`select "payment_id", "refund_id"
|
|
1486
|
+
from "documents_refund_document_resolution"
|
|
1487
|
+
where ("state" in ('pending_source', 'failed')
|
|
1488
|
+
or ("state" = 'processing' and "lease_expires_at" <= now()))
|
|
1489
|
+
and "deleted_at" is null order by "updated_at" asc limit ?`, [input.limit]);
|
|
1490
|
+
const cancellationRows = await manager.execute(`select "order_id" from "documents_order_cancellation_resolution"
|
|
1491
|
+
where ("state" in ('pending', 'failed')
|
|
1492
|
+
or ("state" = 'processing' and "lease_expires_at" <= now()))
|
|
1493
|
+
and "deleted_at" is null order by "updated_at" asc limit ?`, [input.limit]);
|
|
1494
|
+
return {
|
|
1495
|
+
fulfillment_ids: assignmentRows.map((row) => row.fulfillment_id),
|
|
1496
|
+
refunds: refundRows,
|
|
1497
|
+
order_ids: cancellationRows.map((row) => row.order_id),
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
artifactDescriptorFromRow(row) {
|
|
1501
|
+
return {
|
|
1502
|
+
artifact_id: asNonEmptyString(row.invoice_artifact_id ?? row.artifact_id ?? row.id, "artifact_id"),
|
|
1503
|
+
document_id: asNonEmptyString(row.invoice_document_id ?? row.artifact_document_id ?? row.document_id, "document_id"),
|
|
1504
|
+
document_number: asNonEmptyString(row.document_number, "document_number"),
|
|
1505
|
+
file_id: asNonEmptyString(row.file_id, "file_id"),
|
|
1506
|
+
filename: asNonEmptyString(row.filename, "filename"),
|
|
1507
|
+
content_type: "application/pdf",
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
__decorate([
|
|
1512
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1513
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1514
|
+
__metadata("design:type", Function),
|
|
1515
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1516
|
+
__metadata("design:returntype", Promise)
|
|
1517
|
+
], DocumentsModuleService.prototype, "claimPackingListRevision", null);
|
|
1518
|
+
__decorate([
|
|
1519
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1520
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1521
|
+
__metadata("design:type", Function),
|
|
1522
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1523
|
+
__metadata("design:returntype", Promise)
|
|
1524
|
+
], DocumentsModuleService.prototype, "savePackingListRevisionSnapshot", null);
|
|
1525
|
+
__decorate([
|
|
1526
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1527
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1528
|
+
__metadata("design:type", Function),
|
|
1529
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1530
|
+
__metadata("design:returntype", Promise)
|
|
1531
|
+
], DocumentsModuleService.prototype, "publishPackingListRevision", null);
|
|
1532
|
+
__decorate([
|
|
1533
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1534
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1535
|
+
__metadata("design:type", Function),
|
|
1536
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1537
|
+
__metadata("design:returntype", Promise)
|
|
1538
|
+
], DocumentsModuleService.prototype, "markPackingListRevisionFailed", null);
|
|
1539
|
+
__decorate([
|
|
1540
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1541
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1542
|
+
__metadata("design:type", Function),
|
|
1543
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1544
|
+
__metadata("design:returntype", Promise)
|
|
1545
|
+
], DocumentsModuleService.prototype, "cancelPackingListForFulfillment", null);
|
|
1546
|
+
__decorate([
|
|
1547
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1548
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1549
|
+
__metadata("design:type", Function),
|
|
1550
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1551
|
+
__metadata("design:returntype", Promise)
|
|
1552
|
+
], DocumentsModuleService.prototype, "upsertShipmentInvoiceAssignment", null);
|
|
1553
|
+
__decorate([
|
|
1554
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1555
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1556
|
+
__metadata("design:type", Function),
|
|
1557
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1558
|
+
__metadata("design:returntype", Promise)
|
|
1559
|
+
], DocumentsModuleService.prototype, "claimShipmentInvoiceDecision", null);
|
|
1560
|
+
__decorate([
|
|
1561
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1562
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1563
|
+
__metadata("design:type", Function),
|
|
1564
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1565
|
+
__metadata("design:returntype", Promise)
|
|
1566
|
+
], DocumentsModuleService.prototype, "releaseShipmentInvoiceDecision", null);
|
|
1567
|
+
__decorate([
|
|
1568
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1569
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1570
|
+
__metadata("design:type", Function),
|
|
1571
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1572
|
+
__metadata("design:returntype", Promise)
|
|
1573
|
+
], DocumentsModuleService.prototype, "startInvoiceIssuance", null);
|
|
1574
|
+
__decorate([
|
|
1575
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1576
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1577
|
+
__metadata("design:type", Function),
|
|
1578
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1579
|
+
__metadata("design:returntype", Promise)
|
|
1580
|
+
], DocumentsModuleService.prototype, "startCancellationIssuance", null);
|
|
1581
|
+
__decorate([
|
|
1582
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1583
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1584
|
+
__metadata("design:type", Function),
|
|
1585
|
+
__metadata("design:paramtypes", [String, Object]),
|
|
1586
|
+
__metadata("design:returntype", Promise)
|
|
1587
|
+
], DocumentsModuleService.prototype, "claimDocumentRegeneration", null);
|
|
1588
|
+
__decorate([
|
|
1589
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1590
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1591
|
+
__metadata("design:type", Function),
|
|
1592
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1593
|
+
__metadata("design:returntype", Promise)
|
|
1594
|
+
], DocumentsModuleService.prototype, "finalizeShipmentInvoice", null);
|
|
1595
|
+
__decorate([
|
|
1596
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1597
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1598
|
+
__metadata("design:type", Function),
|
|
1599
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1600
|
+
__metadata("design:returntype", Promise)
|
|
1601
|
+
], DocumentsModuleService.prototype, "finalizeDocumentRegeneration", null);
|
|
1602
|
+
__decorate([
|
|
1603
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1604
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1605
|
+
__metadata("design:type", Function),
|
|
1606
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1607
|
+
__metadata("design:returntype", Promise)
|
|
1608
|
+
], DocumentsModuleService.prototype, "markDocumentIssuanceFailed", null);
|
|
1609
|
+
__decorate([
|
|
1610
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1611
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1612
|
+
__metadata("design:type", Function),
|
|
1613
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1614
|
+
__metadata("design:returntype", Promise)
|
|
1615
|
+
], DocumentsModuleService.prototype, "upsertRefundDocumentResolution", null);
|
|
1616
|
+
__decorate([
|
|
1617
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1618
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1619
|
+
__metadata("design:type", Function),
|
|
1620
|
+
__metadata("design:paramtypes", [String, Object]),
|
|
1621
|
+
__metadata("design:returntype", Promise)
|
|
1622
|
+
], DocumentsModuleService.prototype, "claimRefundDocumentResolution", null);
|
|
1623
|
+
__decorate([
|
|
1624
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1625
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1626
|
+
__metadata("design:type", Function),
|
|
1627
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1628
|
+
__metadata("design:returntype", Promise)
|
|
1629
|
+
], DocumentsModuleService.prototype, "finalizeRefundWithoutDocument", null);
|
|
1630
|
+
__decorate([
|
|
1631
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1632
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1633
|
+
__metadata("design:type", Function),
|
|
1634
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1635
|
+
__metadata("design:returntype", Promise)
|
|
1636
|
+
], DocumentsModuleService.prototype, "finalizeRefundDocument", null);
|
|
1637
|
+
__decorate([
|
|
1638
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1639
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1640
|
+
__metadata("design:type", Function),
|
|
1641
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1642
|
+
__metadata("design:returntype", Promise)
|
|
1643
|
+
], DocumentsModuleService.prototype, "markRefundResolutionFailed", null);
|
|
1644
|
+
__decorate([
|
|
1645
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1646
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1647
|
+
__metadata("design:type", Function),
|
|
1648
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1649
|
+
__metadata("design:returntype", Promise)
|
|
1650
|
+
], DocumentsModuleService.prototype, "upsertOrderCancellationResolution", null);
|
|
1651
|
+
__decorate([
|
|
1652
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1653
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1654
|
+
__metadata("design:type", Function),
|
|
1655
|
+
__metadata("design:paramtypes", [String, Object]),
|
|
1656
|
+
__metadata("design:returntype", Promise)
|
|
1657
|
+
], DocumentsModuleService.prototype, "claimOrderCancellationResolution", null);
|
|
1658
|
+
__decorate([
|
|
1659
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1660
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1661
|
+
__metadata("design:type", Function),
|
|
1662
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1663
|
+
__metadata("design:returntype", Promise)
|
|
1664
|
+
], DocumentsModuleService.prototype, "finalizeOrderCancellationResolution", null);
|
|
1665
|
+
__decorate([
|
|
1666
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1667
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1668
|
+
__metadata("design:type", Function),
|
|
1669
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1670
|
+
__metadata("design:returntype", Promise)
|
|
1671
|
+
], DocumentsModuleService.prototype, "markOrderCancellationResolutionFailed", null);
|
|
1672
|
+
__decorate([
|
|
1673
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1674
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1675
|
+
__metadata("design:type", Function),
|
|
1676
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1677
|
+
__metadata("design:returntype", Promise)
|
|
1678
|
+
], DocumentsModuleService.prototype, "isDocumentFileDeletable", null);
|
|
1679
|
+
__decorate([
|
|
1680
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1681
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1682
|
+
__metadata("design:type", Function),
|
|
1683
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1684
|
+
__metadata("design:returntype", Promise)
|
|
1685
|
+
], DocumentsModuleService.prototype, "listUnpublishedDocumentFacts", null);
|
|
1686
|
+
__decorate([
|
|
1687
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1688
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1689
|
+
__metadata("design:type", Function),
|
|
1690
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1691
|
+
__metadata("design:returntype", Promise)
|
|
1692
|
+
], DocumentsModuleService.prototype, "markDocumentFactEmitted", null);
|
|
1693
|
+
__decorate([
|
|
1694
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
1695
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
1696
|
+
__metadata("design:type", Function),
|
|
1697
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1698
|
+
__metadata("design:returntype", Promise)
|
|
1699
|
+
], DocumentsModuleService.prototype, "listDocumentResolutionReconciliationCandidates", null);
|
|
1700
|
+
exports.default = DocumentsModuleService;
|
|
1701
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2RvY3VtZW50cy9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUF3QztBQUd4QyxxREFLa0M7QUFjbEMsa0dBUTJFO0FBQzNFLHNFQUlxQztBQUNyQyw4REFHaUM7QUFDakMsOENBR3lCO0FBRXpCLDRFQUEyRTtBQUMzRSxxRUFBeUU7QUFDekUsaUVBQXdDO0FBQ3hDLG1GQUF5RDtBQUN6RCxpR0FBc0U7QUFDdEUsMkdBQWdGO0FBQ2hGLHlFQUErQztBQUMvQywyRkFBZ0U7QUFDaEUscUdBQTBFO0FBQzFFLHVHQUE0RTtBQUM1RSx5R0FBOEU7QUFROUUsTUFBTSwyQkFBMkIsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQTtBQUNyQyxRQUFBLDBCQUEwQixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFBO0FBK0x4RCxNQUFNLGNBQWMsR0FBbUI7SUFDckMsU0FBUztJQUNULGNBQWM7SUFDZCxhQUFhO0NBQ2QsQ0FBQTtBQUVELE1BQU0saUJBQWlCLEdBQXFCLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQTtBQUU5RSxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBYyxFQUFFLEtBQWEsRUFBVSxFQUFFO0lBQ2pFLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFDL0MsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyxtQkFBbUIsS0FBSyxlQUFlLENBQ3hDLENBQUE7SUFDSCxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUE7QUFDZCxDQUFDLENBQUE7QUFFRCxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBYyxFQUFp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
|