@xbstracts/medusa-coupons 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +3207 -0
- package/.medusa/server/src/admin/index.mjs +3253 -0
- package/.medusa/server/src/api/admin/coupon-products/[product_id]/entitlements/route.js +9 -0
- package/.medusa/server/src/api/admin/coupon-products/[product_id]/mirror-promotion/route.js +132 -0
- package/.medusa/server/src/api/admin/coupon-products/[product_id]/preview/route.js +28 -0
- package/.medusa/server/src/api/admin/coupon-products/[product_id]/route.js +18 -0
- package/.medusa/server/src/api/admin/coupon-products/[product_id]/variants/[variant_config_id]/route.js +14 -0
- package/.medusa/server/src/api/admin/coupon-products/[product_id]/variants/route.js +14 -0
- package/.medusa/server/src/api/admin/coupon-products/configs/[id]/route.js +53 -0
- package/.medusa/server/src/api/admin/coupon-products/configs/[id]/variants/[variant_config_id]/route.js +26 -0
- package/.medusa/server/src/api/admin/coupon-products/configs/[id]/variants/route.js +27 -0
- package/.medusa/server/src/api/admin/coupon-products/configs/route.js +36 -0
- package/.medusa/server/src/api/admin/coupon-products/entitlements/[id]/cancel/route.js +15 -0
- package/.medusa/server/src/api/admin/coupon-products/entitlements/[id]/redeem/route.js +15 -0
- package/.medusa/server/src/api/admin/coupon-products/entitlements/[id]/route.js +16 -0
- package/.medusa/server/src/api/admin/coupon-products/entitlements/route.js +22 -0
- package/.medusa/server/src/api/admin/coupon-products/options/route.js +9 -0
- package/.medusa/server/src/api/admin/coupon-products/products/route.js +16 -0
- package/.medusa/server/src/api/admin/coupon-products/route.js +13 -0
- package/.medusa/server/src/api/admin/coupon-products/uploads/route.js +7 -0
- package/.medusa/server/src/api/coupon-product-routes.js +546 -0
- package/.medusa/server/src/api/entitlement-utils.js +90 -0
- package/.medusa/server/src/api/media-upload.js +57 -0
- package/.medusa/server/src/api/middlewares.js +92 -0
- package/.medusa/server/src/api/product-utils.js +304 -0
- package/.medusa/server/src/api/promotion-code-resolver.js +225 -0
- package/.medusa/server/src/api/seller-utils.js +101 -0
- package/.medusa/server/src/api/utils.js +25 -0
- package/.medusa/server/src/api/validators.js +199 -0
- package/.medusa/server/src/api/vendor/coupon-products/[product_id]/entitlements/route.js +9 -0
- package/.medusa/server/src/api/vendor/coupon-products/[product_id]/route.js +18 -0
- package/.medusa/server/src/api/vendor/coupon-products/[product_id]/variants/[variant_config_id]/route.js +14 -0
- package/.medusa/server/src/api/vendor/coupon-products/[product_id]/variants/route.js +14 -0
- package/.medusa/server/src/api/vendor/coupon-products/configs/[id]/route.js +60 -0
- package/.medusa/server/src/api/vendor/coupon-products/configs/[id]/variants/[variant_config_id]/route.js +41 -0
- package/.medusa/server/src/api/vendor/coupon-products/configs/[id]/variants/route.js +45 -0
- package/.medusa/server/src/api/vendor/coupon-products/configs/route.js +51 -0
- package/.medusa/server/src/api/vendor/coupon-products/entitlements/[id]/route.js +25 -0
- package/.medusa/server/src/api/vendor/coupon-products/entitlements/route.js +45 -0
- package/.medusa/server/src/api/vendor/coupon-products/options/route.js +9 -0
- package/.medusa/server/src/api/vendor/coupon-products/products/route.js +19 -0
- package/.medusa/server/src/api/vendor/coupon-products/route.js +13 -0
- package/.medusa/server/src/api/vendor/coupon-products/uploads/route.js +7 -0
- package/.medusa/server/src/jobs/retry-coupon-media-deletes.js +14 -0
- package/.medusa/server/src/links/coupon-issuance-order-line-item.js +17 -0
- package/.medusa/server/src/links/coupon-issuance-order.js +15 -0
- package/.medusa/server/src/links/coupon-product-config-product.js +17 -0
- package/.medusa/server/src/links/coupon-product-variant-config-variant.js +17 -0
- package/.medusa/server/src/links/coupon-promotion-mirror-promotion.js +17 -0
- package/.medusa/server/src/links/customer-coupon-entitlement-customer.js +15 -0
- package/.medusa/server/src/modules/coupon/constants.js +46 -0
- package/.medusa/server/src/modules/coupon/index.js +16 -0
- package/.medusa/server/src/modules/coupon/loaders/reconcile-coupon-products.js +65 -0
- package/.medusa/server/src/modules/coupon/migrations/Migration20260709000000.js +40 -0
- package/.medusa/server/src/modules/coupon/migrations/Migration20260710000000.js +22 -0
- package/.medusa/server/src/modules/coupon/migrations/Migration20260711000000.js +25 -0
- package/.medusa/server/src/modules/coupon/migrations/Migration20260712000000.js +78 -0
- package/.medusa/server/src/modules/coupon/migrations/Migration20260719000000.js +19 -0
- package/.medusa/server/src/modules/coupon/migrations/Migration20260722000000.js +17 -0
- package/.medusa/server/src/modules/coupon/migrations/Migration20260723000000.js +18 -0
- package/.medusa/server/src/modules/coupon/models/coupon-entitlement-promotion.js +31 -0
- package/.medusa/server/src/modules/coupon/models/coupon-entitlement-seller.js +28 -0
- package/.medusa/server/src/modules/coupon/models/coupon-issuance.js +35 -0
- package/.medusa/server/src/modules/coupon/models/coupon-media-asset.js +41 -0
- package/.medusa/server/src/modules/coupon/models/coupon-product-config.js +45 -0
- package/.medusa/server/src/modules/coupon/models/coupon-product-variant-config.js +36 -0
- package/.medusa/server/src/modules/coupon/models/coupon-promotion-mirror.js +27 -0
- package/.medusa/server/src/modules/coupon/models/customer-coupon-entitlement.js +56 -0
- package/.medusa/server/src/modules/coupon/models/index.js +23 -0
- package/.medusa/server/src/modules/coupon/payment-order-utils.js +76 -0
- package/.medusa/server/src/modules/coupon/product-metadata.js +24 -0
- package/.medusa/server/src/modules/coupon/purchase-conditions.js +138 -0
- package/.medusa/server/src/modules/coupon/service.js +628 -0
- package/.medusa/server/src/modules/coupon/types.js +3 -0
- package/.medusa/server/src/modules/coupon/utils.js +302 -0
- package/.medusa/server/src/subscribers/issue-coupons-from-order.js +88 -0
- package/.medusa/server/src/vendor/index.mjs +3237 -0
- package/.medusa/server/src/workflows/hooks/validate-coupon-add-to-cart.js +13 -0
- package/.medusa/server/src/workflows/hooks/validate-coupon-complete-cart.js +8 -0
- package/.medusa/server/src/workflows/index.js +21 -0
- package/.medusa/server/src/workflows/steps.js +27 -0
- package/.medusa/server/src/workflows/validate-coupon-purchase.js +85 -0
- package/README.md +84 -0
- package/package.json +102 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeProductInput = normalizeProductInput;
|
|
4
|
+
exports.normalizeProductUpdateInput = normalizeProductUpdateInput;
|
|
5
|
+
exports.listCouponProducts = listCouponProducts;
|
|
6
|
+
exports.createCouponProduct = createCouponProduct;
|
|
7
|
+
exports.retrieveCouponProduct = retrieveCouponProduct;
|
|
8
|
+
exports.updateCouponProduct = updateCouponProduct;
|
|
9
|
+
exports.deleteCouponProduct = deleteCouponProduct;
|
|
10
|
+
exports.listCouponProductVariants = listCouponProductVariants;
|
|
11
|
+
exports.upsertCouponProductVariant = upsertCouponProductVariant;
|
|
12
|
+
exports.updateCouponProductVariant = updateCouponProductVariant;
|
|
13
|
+
exports.deleteCouponProductVariant = deleteCouponProductVariant;
|
|
14
|
+
exports.listProductEntitlements = listProductEntitlements;
|
|
15
|
+
exports.optionsForCouponProducts = optionsForCouponProducts;
|
|
16
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
17
|
+
const core_flows_1 = require("@medusajs/medusa/core-flows");
|
|
18
|
+
const coupon_1 = require("../modules/coupon");
|
|
19
|
+
const constants_1 = require("../modules/coupon/constants");
|
|
20
|
+
const product_metadata_1 = require("../modules/coupon/product-metadata");
|
|
21
|
+
const entitlement_utils_1 = require("./entitlement-utils");
|
|
22
|
+
const product_utils_1 = require("./product-utils");
|
|
23
|
+
const utils_2 = require("./utils");
|
|
24
|
+
const validators_1 = require("./validators");
|
|
25
|
+
const seller_utils_1 = require("./seller-utils");
|
|
26
|
+
function compact(value) {
|
|
27
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
|
|
28
|
+
}
|
|
29
|
+
async function prepareManagedProductMedia(service, input, options = {}) {
|
|
30
|
+
const product = { ...input };
|
|
31
|
+
const selection = {};
|
|
32
|
+
const hasThumbnail = Object.prototype.hasOwnProperty.call(input, "thumbnail") ||
|
|
33
|
+
Object.prototype.hasOwnProperty.call(input, "thumbnail_asset_id");
|
|
34
|
+
const hasImages = Object.prototype.hasOwnProperty.call(input, "images");
|
|
35
|
+
if (hasThumbnail) {
|
|
36
|
+
selection.thumbnail = input.thumbnail_asset_id || null;
|
|
37
|
+
}
|
|
38
|
+
if (hasImages) {
|
|
39
|
+
selection.images = (input.images || [])
|
|
40
|
+
.map((image) => image.asset_id)
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
}
|
|
43
|
+
const assets = await service.validateMediaSelection(selection, options);
|
|
44
|
+
if (selection.thumbnail) {
|
|
45
|
+
product.thumbnail = assets[selection.thumbnail].url;
|
|
46
|
+
}
|
|
47
|
+
if (hasImages) {
|
|
48
|
+
product.images = (input.images || []).map((image) => ({
|
|
49
|
+
...image,
|
|
50
|
+
url: image.asset_id ? assets[image.asset_id].url : image.url,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
return { product, selection };
|
|
54
|
+
}
|
|
55
|
+
function normalizeProductInput(input, configId, salesChannelIds) {
|
|
56
|
+
const options = input.options?.length
|
|
57
|
+
? input.options
|
|
58
|
+
: [{ title: "Coupon", values: ["Default"] }];
|
|
59
|
+
return compact({
|
|
60
|
+
title: input.title,
|
|
61
|
+
subtitle: input.subtitle || undefined,
|
|
62
|
+
handle: input.handle || undefined,
|
|
63
|
+
description: input.description || undefined,
|
|
64
|
+
status: input.status,
|
|
65
|
+
thumbnail: input.thumbnail || undefined,
|
|
66
|
+
images: input.images
|
|
67
|
+
?.filter((image) => image.url)
|
|
68
|
+
.map((image) => ({ url: image.url })),
|
|
69
|
+
discountable: input.discountable ?? false,
|
|
70
|
+
is_giftcard: false,
|
|
71
|
+
type_id: input.type_id || undefined,
|
|
72
|
+
collection_id: input.collection_id || undefined,
|
|
73
|
+
shipping_profile_id: undefined,
|
|
74
|
+
category_ids: input.categories?.map((item) => item.id).filter(Boolean),
|
|
75
|
+
tag_ids: input.tags?.map((item) => item.id).filter(Boolean),
|
|
76
|
+
sales_channels: (salesChannelIds ?? input.sales_channels?.map((item) => item.id))
|
|
77
|
+
?.map((id) => ({ id }))
|
|
78
|
+
.filter((item) => item.id),
|
|
79
|
+
options,
|
|
80
|
+
variants: input.variants?.map((variant, index) => {
|
|
81
|
+
const fallbackOptions = Object.fromEntries(options.map((option) => [
|
|
82
|
+
option.title,
|
|
83
|
+
option.values[Math.min(index, option.values.length - 1)] ||
|
|
84
|
+
option.values[0],
|
|
85
|
+
]));
|
|
86
|
+
return compact({
|
|
87
|
+
title: variant.title,
|
|
88
|
+
sku: variant.sku || undefined,
|
|
89
|
+
manage_inventory: variant.manage_inventory ?? false,
|
|
90
|
+
allow_backorder: variant.allow_backorder ?? true,
|
|
91
|
+
options: variant.options || fallbackOptions,
|
|
92
|
+
prices: (variant.prices || []).map((price) => ({
|
|
93
|
+
currency_code: price.currency_code.toLowerCase(),
|
|
94
|
+
amount: price.amount,
|
|
95
|
+
})),
|
|
96
|
+
metadata: variant.metadata || undefined,
|
|
97
|
+
});
|
|
98
|
+
}),
|
|
99
|
+
metadata: {
|
|
100
|
+
...(input.metadata || {}),
|
|
101
|
+
[constants_1.COUPON_METADATA_KEY]: (0, product_metadata_1.buildCouponProductMarker)(configId),
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function normalizeProductUpdateInput(input, existingProduct, configId, salesChannelIds) {
|
|
106
|
+
const metadata = {
|
|
107
|
+
...(existingProduct?.metadata || {}),
|
|
108
|
+
...(input.metadata || {}),
|
|
109
|
+
[constants_1.COUPON_METADATA_KEY]: (0, product_metadata_1.buildCouponProductMarker)(configId),
|
|
110
|
+
};
|
|
111
|
+
return compact({
|
|
112
|
+
id: existingProduct.id,
|
|
113
|
+
title: input.title,
|
|
114
|
+
subtitle: input.subtitle,
|
|
115
|
+
handle: input.handle,
|
|
116
|
+
description: input.description,
|
|
117
|
+
status: input.status,
|
|
118
|
+
thumbnail: input.thumbnail,
|
|
119
|
+
images: input.images
|
|
120
|
+
?.filter((image) => image.url)
|
|
121
|
+
.map((image) => ({ url: image.url })),
|
|
122
|
+
discountable: input.discountable,
|
|
123
|
+
type_id: input.type_id,
|
|
124
|
+
collection_id: input.collection_id,
|
|
125
|
+
shipping_profile_id: null,
|
|
126
|
+
category_ids: input.categories?.map((item) => item.id).filter(Boolean),
|
|
127
|
+
tag_ids: input.tags?.map((item) => item.id).filter(Boolean),
|
|
128
|
+
sales_channels: (salesChannelIds ?? input.sales_channels?.map((item) => item.id))
|
|
129
|
+
?.map((id) => ({ id }))
|
|
130
|
+
.filter((item) => item.id),
|
|
131
|
+
metadata,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
async function resolveCampaign(req, campaignInput, enabled) {
|
|
135
|
+
const mode = enabled ? campaignInput?.mode || "none" : "none";
|
|
136
|
+
if (mode === "none") {
|
|
137
|
+
return {
|
|
138
|
+
campaign_mode: "none",
|
|
139
|
+
campaign_id: null,
|
|
140
|
+
campaign_snapshot: null,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (mode === "new") {
|
|
144
|
+
if (!campaignInput?.campaign) {
|
|
145
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Campaign details are required");
|
|
146
|
+
}
|
|
147
|
+
const { result } = await (0, core_flows_1.createCampaignsWorkflow)(req.scope).run({
|
|
148
|
+
input: {
|
|
149
|
+
campaignsData: [
|
|
150
|
+
{
|
|
151
|
+
...campaignInput.campaign,
|
|
152
|
+
starts_at: campaignInput.campaign.starts_at
|
|
153
|
+
? new Date(campaignInput.campaign.starts_at)
|
|
154
|
+
: undefined,
|
|
155
|
+
ends_at: campaignInput.campaign.ends_at
|
|
156
|
+
? new Date(campaignInput.campaign.ends_at)
|
|
157
|
+
: undefined,
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
additional_data: {
|
|
161
|
+
source: "medusa-coupons",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
const campaign = result[0];
|
|
166
|
+
return {
|
|
167
|
+
campaign_mode: "new",
|
|
168
|
+
campaign_id: campaign.id,
|
|
169
|
+
campaign_snapshot: campaign,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
if (!campaignInput?.campaign_id) {
|
|
173
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Campaign id is required");
|
|
174
|
+
}
|
|
175
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
176
|
+
const { data } = await query.graph({
|
|
177
|
+
entity: "campaign",
|
|
178
|
+
fields: [
|
|
179
|
+
"id",
|
|
180
|
+
"name",
|
|
181
|
+
"campaign_identifier",
|
|
182
|
+
"starts_at",
|
|
183
|
+
"ends_at",
|
|
184
|
+
"budget.*",
|
|
185
|
+
],
|
|
186
|
+
filters: {
|
|
187
|
+
id: campaignInput.campaign_id,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
const campaign = data?.[0];
|
|
191
|
+
if (!campaign) {
|
|
192
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Campaign was not found");
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
campaign_mode: "existing",
|
|
196
|
+
campaign_id: campaign.id,
|
|
197
|
+
campaign_snapshot: campaign,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
async function readCouponProductRows(req, service, configs) {
|
|
201
|
+
const products = await (0, product_utils_1.listProductsByIds)(req, configs.map((config) => config.product_id));
|
|
202
|
+
const productsById = Object.fromEntries(products.map((product) => [product.id, product]));
|
|
203
|
+
const configIds = configs.map((config) => config.id).filter(Boolean);
|
|
204
|
+
const productIds = configs.map((config) => config.product_id).filter(Boolean);
|
|
205
|
+
const [variantConfigs, entitlements, mediaAssets] = await Promise.all([
|
|
206
|
+
configIds.length
|
|
207
|
+
? service.listCouponProductVariantConfigs({
|
|
208
|
+
product_config_id: configIds,
|
|
209
|
+
})
|
|
210
|
+
: [],
|
|
211
|
+
productIds.length
|
|
212
|
+
? service.listCustomerCouponEntitlements({
|
|
213
|
+
product_id: productIds,
|
|
214
|
+
})
|
|
215
|
+
: [],
|
|
216
|
+
productIds.length
|
|
217
|
+
? service.listCouponMediaAssets({
|
|
218
|
+
product_id: productIds,
|
|
219
|
+
status: "attached",
|
|
220
|
+
})
|
|
221
|
+
: [],
|
|
222
|
+
]);
|
|
223
|
+
const variantsByConfigId = (variantConfigs || []).reduce((result, item) => {
|
|
224
|
+
result[item.product_config_id] = result[item.product_config_id] || [];
|
|
225
|
+
result[item.product_config_id].push(item);
|
|
226
|
+
return result;
|
|
227
|
+
}, {});
|
|
228
|
+
const entitlementCountByProduct = (entitlements || []).reduce((result, item) => {
|
|
229
|
+
result[item.product_id] = (result[item.product_id] || 0) + 1;
|
|
230
|
+
return result;
|
|
231
|
+
}, {});
|
|
232
|
+
const mediaByProductId = (mediaAssets || []).reduce((result, asset) => {
|
|
233
|
+
result[asset.product_id] = result[asset.product_id] || [];
|
|
234
|
+
result[asset.product_id].push(asset);
|
|
235
|
+
return result;
|
|
236
|
+
}, {});
|
|
237
|
+
return configs.map((config) => {
|
|
238
|
+
const product = productsById[config.product_id] || { id: config.product_id };
|
|
239
|
+
const assets = mediaByProductId[config.product_id] || [];
|
|
240
|
+
const thumbnailAsset = assets.find((asset) => asset.role === "thumbnail" && asset.url === product.thumbnail);
|
|
241
|
+
const imageAssets = assets.filter((asset) => asset.role === "image");
|
|
242
|
+
return (0, product_utils_1.buildCouponProductRecord)(config, {
|
|
243
|
+
...product,
|
|
244
|
+
thumbnail_asset_id: thumbnailAsset?.id || null,
|
|
245
|
+
images: (product.images || []).map((image) => ({
|
|
246
|
+
...image,
|
|
247
|
+
asset_id: imageAssets.find((asset) => asset.url === image.url)?.id ||
|
|
248
|
+
null,
|
|
249
|
+
})),
|
|
250
|
+
}, variantsByConfigId[config.id] || [], entitlementCountByProduct[config.product_id] || 0);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
async function getConfigForProduct(service, productId) {
|
|
254
|
+
const [config] = await service.listCouponProductConfigs({
|
|
255
|
+
product_id: productId,
|
|
256
|
+
});
|
|
257
|
+
if (!config) {
|
|
258
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Coupon product was not found");
|
|
259
|
+
}
|
|
260
|
+
return config;
|
|
261
|
+
}
|
|
262
|
+
async function listConfigsForAccess(req, access) {
|
|
263
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
264
|
+
if (access === "vendor") {
|
|
265
|
+
const productIds = await (0, seller_utils_1.listSellerProductIds)(req);
|
|
266
|
+
if (!productIds.length) {
|
|
267
|
+
return { service, configs: [] };
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
service,
|
|
271
|
+
configs: await service.listCouponProductConfigs({
|
|
272
|
+
product_id: productIds,
|
|
273
|
+
}),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
service,
|
|
278
|
+
configs: await service.listCouponProductConfigs({}),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
async function loadCouponOptionsForAccess(req, access) {
|
|
282
|
+
if (access === "vendor") {
|
|
283
|
+
const sellerId = (0, seller_utils_1.getSellerId)(req);
|
|
284
|
+
const productIds = await (0, seller_utils_1.listSellerProductIds)(req);
|
|
285
|
+
return (0, product_utils_1.listCouponProductOptions)(req, productIds, sellerId);
|
|
286
|
+
}
|
|
287
|
+
return (0, product_utils_1.listCouponProductOptions)(req);
|
|
288
|
+
}
|
|
289
|
+
async function listCouponProducts(req, res, access) {
|
|
290
|
+
const { service, configs } = await listConfigsForAccess(req, access);
|
|
291
|
+
const rows = await readCouponProductRows(req, service, configs);
|
|
292
|
+
res.json({
|
|
293
|
+
coupon_products: rows,
|
|
294
|
+
count: rows.length,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
async function createCouponProduct(req, res, access) {
|
|
298
|
+
const body = (0, utils_2.parseBody)(validators_1.CreateCouponProductBody, req.body);
|
|
299
|
+
const campaign = await resolveCampaign(req, body.campaign, access === "admin");
|
|
300
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
301
|
+
const sellerId = access === "vendor" ? (0, seller_utils_1.getSellerId)(req) : body.seller_id;
|
|
302
|
+
const couponOptions = await loadCouponOptionsForAccess(req, access);
|
|
303
|
+
const purchaseConditions = (0, product_utils_1.validateCouponPurchaseOptions)(body.coupon, couponOptions);
|
|
304
|
+
const salesChannelIds = (0, product_utils_1.resolveCouponSalesChannelIds)(purchaseConditions, couponOptions);
|
|
305
|
+
const preparedMedia = await prepareManagedProductMedia(service, body.product, access === "vendor" ? { seller_id: sellerId } : {});
|
|
306
|
+
const productInput = normalizeProductInput(preparedMedia.product, null, salesChannelIds);
|
|
307
|
+
const { result } = await (0, core_flows_1.createProductsWorkflow)(req.scope).run({
|
|
308
|
+
input: {
|
|
309
|
+
products: [productInput],
|
|
310
|
+
additional_data: compact({
|
|
311
|
+
seller_id: sellerId || undefined,
|
|
312
|
+
source: "medusa-coupons",
|
|
313
|
+
}),
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
const product = result[0];
|
|
317
|
+
const config = await service.createProductConfig({
|
|
318
|
+
...body.coupon,
|
|
319
|
+
purchase_conditions: purchaseConditions,
|
|
320
|
+
...campaign,
|
|
321
|
+
product_id: product.id,
|
|
322
|
+
});
|
|
323
|
+
const createdVariantConfigs = [];
|
|
324
|
+
for (const override of body.variant_overrides || []) {
|
|
325
|
+
const variantId = override.variant_id ||
|
|
326
|
+
product.variants?.[Number(override.variant_index || 0)]?.id;
|
|
327
|
+
if (!variantId)
|
|
328
|
+
continue;
|
|
329
|
+
createdVariantConfigs.push(await service.createVariantConfig(config.id, {
|
|
330
|
+
...override,
|
|
331
|
+
variant_id: variantId,
|
|
332
|
+
}));
|
|
333
|
+
}
|
|
334
|
+
await service.reconcileProductMedia(product.id, preparedMedia.selection, access === "vendor" ? { seller_id: sellerId } : {});
|
|
335
|
+
const [row] = await readCouponProductRows(req, service, [config]);
|
|
336
|
+
res.status(201).json({
|
|
337
|
+
coupon_product: {
|
|
338
|
+
...row,
|
|
339
|
+
coupon_product_variant_configs: createdVariantConfigs.length
|
|
340
|
+
? createdVariantConfigs
|
|
341
|
+
: row.coupon_product_variant_configs,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
async function retrieveCouponProduct(req, res, access) {
|
|
346
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
347
|
+
if (access === "vendor") {
|
|
348
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
349
|
+
}
|
|
350
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
351
|
+
const config = await getConfigForProduct(service, productId);
|
|
352
|
+
const [row] = await readCouponProductRows(req, service, [config]);
|
|
353
|
+
res.json({ coupon_product: row });
|
|
354
|
+
}
|
|
355
|
+
async function updateCouponProduct(req, res, access) {
|
|
356
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
357
|
+
if (access === "vendor") {
|
|
358
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
359
|
+
}
|
|
360
|
+
const body = (0, utils_2.parseBody)(validators_1.UpdateCouponProductBody, req.body);
|
|
361
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
362
|
+
const config = await getConfigForProduct(service, productId);
|
|
363
|
+
const [existingProduct] = await (0, product_utils_1.listProductsByIds)(req, [productId]);
|
|
364
|
+
if (!existingProduct) {
|
|
365
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Coupon product was not found");
|
|
366
|
+
}
|
|
367
|
+
const preparedMedia = body.product
|
|
368
|
+
? await prepareManagedProductMedia(service, body.product, {
|
|
369
|
+
product_id: productId,
|
|
370
|
+
...(access === "vendor"
|
|
371
|
+
? { seller_id: (0, seller_utils_1.getSellerId)(req) }
|
|
372
|
+
: {}),
|
|
373
|
+
})
|
|
374
|
+
: null;
|
|
375
|
+
let salesChannelIds;
|
|
376
|
+
if (body.coupon?.purchase_conditions !== undefined) {
|
|
377
|
+
const couponOptions = await loadCouponOptionsForAccess(req, access);
|
|
378
|
+
const purchaseConditions = (0, product_utils_1.validateCouponPurchaseOptions)({ ...config, ...body.coupon }, couponOptions);
|
|
379
|
+
body.coupon.purchase_conditions = purchaseConditions;
|
|
380
|
+
salesChannelIds = (0, product_utils_1.resolveCouponSalesChannelIds)(purchaseConditions, couponOptions);
|
|
381
|
+
}
|
|
382
|
+
if (body.product || salesChannelIds) {
|
|
383
|
+
const productUpdate = preparedMedia?.product || body.product || {};
|
|
384
|
+
const fixedVariant = productUpdate.variants?.[0];
|
|
385
|
+
await (0, core_flows_1.updateProductsWorkflow)(req.scope).run({
|
|
386
|
+
input: {
|
|
387
|
+
products: [
|
|
388
|
+
normalizeProductUpdateInput(productUpdate, existingProduct, config.id, salesChannelIds),
|
|
389
|
+
],
|
|
390
|
+
additional_data: compact({
|
|
391
|
+
seller_id: access === "vendor" ? (0, seller_utils_1.getSellerId)(req) : undefined,
|
|
392
|
+
source: "medusa-coupons",
|
|
393
|
+
}),
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
const existingVariant = existingProduct.variants?.[0];
|
|
397
|
+
if (fixedVariant && existingVariant?.id) {
|
|
398
|
+
await (0, core_flows_1.updateProductVariantsWorkflow)(req.scope).run({
|
|
399
|
+
input: {
|
|
400
|
+
product_variants: [
|
|
401
|
+
{
|
|
402
|
+
id: existingVariant.id,
|
|
403
|
+
title: "Default",
|
|
404
|
+
sku: fixedVariant.sku || null,
|
|
405
|
+
manage_inventory: false,
|
|
406
|
+
allow_backorder: true,
|
|
407
|
+
prices: fixedVariant.prices,
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
additional_data: compact({
|
|
411
|
+
seller_id: access === "vendor" ? (0, seller_utils_1.getSellerId)(req) : undefined,
|
|
412
|
+
source: "medusa-coupons",
|
|
413
|
+
}),
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
const campaign = body.campaign
|
|
419
|
+
? await resolveCampaign(req, body.campaign, access === "admin")
|
|
420
|
+
: {};
|
|
421
|
+
const updatedConfig = body.coupon
|
|
422
|
+
? await service.updateProductConfig(config.id, {
|
|
423
|
+
...body.coupon,
|
|
424
|
+
...campaign,
|
|
425
|
+
})
|
|
426
|
+
: Object.keys(campaign).length
|
|
427
|
+
? await service.updateProductConfig(config.id, campaign)
|
|
428
|
+
: config;
|
|
429
|
+
if (preparedMedia) {
|
|
430
|
+
await service.reconcileProductMedia(productId, preparedMedia.selection, access === "vendor" ? { seller_id: (0, seller_utils_1.getSellerId)(req) } : {});
|
|
431
|
+
}
|
|
432
|
+
const [row] = await readCouponProductRows(req, service, [updatedConfig]);
|
|
433
|
+
res.json({ coupon_product: row });
|
|
434
|
+
}
|
|
435
|
+
async function deleteCouponProduct(req, res, access) {
|
|
436
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
437
|
+
if (access === "vendor") {
|
|
438
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
439
|
+
}
|
|
440
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
441
|
+
const config = await getConfigForProduct(service, productId);
|
|
442
|
+
await service.deleteProductConfig(config.id);
|
|
443
|
+
res.json({
|
|
444
|
+
id: productId,
|
|
445
|
+
object: "coupon_product",
|
|
446
|
+
deleted: true,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
async function assertVariantBelongsToProduct(req, productId, variantId) {
|
|
450
|
+
const [product] = await (0, product_utils_1.listProductsByIds)(req, [productId]);
|
|
451
|
+
const exists = product?.variants?.some((variant) => variant.id === variantId);
|
|
452
|
+
if (!exists) {
|
|
453
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Product variant was not found");
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
async function listCouponProductVariants(req, res, access) {
|
|
457
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
458
|
+
if (access === "vendor") {
|
|
459
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
460
|
+
}
|
|
461
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
462
|
+
const config = await getConfigForProduct(service, productId);
|
|
463
|
+
const variantConfigs = await service.listCouponProductVariantConfigs({
|
|
464
|
+
product_config_id: config.id,
|
|
465
|
+
});
|
|
466
|
+
res.json({
|
|
467
|
+
coupon_product_variant_configs: variantConfigs,
|
|
468
|
+
count: variantConfigs.length,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
async function upsertCouponProductVariant(req, res, access) {
|
|
472
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
473
|
+
if (access === "vendor") {
|
|
474
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
475
|
+
}
|
|
476
|
+
const body = (0, utils_2.parseBody)(validators_1.UpsertCouponProductVariantBody, req.body);
|
|
477
|
+
await assertVariantBelongsToProduct(req, productId, body.variant_id);
|
|
478
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
479
|
+
const config = await getConfigForProduct(service, productId);
|
|
480
|
+
const [existing] = await service.listCouponProductVariantConfigs({
|
|
481
|
+
product_config_id: config.id,
|
|
482
|
+
variant_id: body.variant_id,
|
|
483
|
+
});
|
|
484
|
+
const variantConfig = existing
|
|
485
|
+
? await service.updateVariantConfig(existing.id, body)
|
|
486
|
+
: await service.createVariantConfig(config.id, body);
|
|
487
|
+
res.status(existing ? 200 : 201).json({
|
|
488
|
+
coupon_product_variant_config: variantConfig,
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
async function updateCouponProductVariant(req, res, access) {
|
|
492
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
493
|
+
const variantConfigId = (0, utils_2.readStringParam)(req.params, "variant_config_id");
|
|
494
|
+
if (access === "vendor") {
|
|
495
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
496
|
+
}
|
|
497
|
+
const body = (0, utils_2.parseBody)(validators_1.UpsertCouponProductVariantBody.partial(), req.body);
|
|
498
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
499
|
+
const config = await getConfigForProduct(service, productId);
|
|
500
|
+
const variantConfig = await service.retrieveCouponProductVariantConfig(variantConfigId);
|
|
501
|
+
if (variantConfig.product_config_id !== config.id) {
|
|
502
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Coupon product variant config was not found");
|
|
503
|
+
}
|
|
504
|
+
const updated = await service.updateVariantConfig(variantConfigId, body);
|
|
505
|
+
res.json({ coupon_product_variant_config: updated });
|
|
506
|
+
}
|
|
507
|
+
async function deleteCouponProductVariant(req, res, access) {
|
|
508
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
509
|
+
const variantConfigId = (0, utils_2.readStringParam)(req.params, "variant_config_id");
|
|
510
|
+
if (access === "vendor") {
|
|
511
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
512
|
+
}
|
|
513
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
514
|
+
const config = await getConfigForProduct(service, productId);
|
|
515
|
+
const variantConfig = await service.retrieveCouponProductVariantConfig(variantConfigId);
|
|
516
|
+
if (variantConfig.product_config_id !== config.id) {
|
|
517
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Coupon product variant config was not found");
|
|
518
|
+
}
|
|
519
|
+
await service.deleteCouponProductVariantConfigs(variantConfigId);
|
|
520
|
+
res.json({
|
|
521
|
+
id: variantConfigId,
|
|
522
|
+
object: "coupon_product_variant_config",
|
|
523
|
+
deleted: true,
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
async function listProductEntitlements(req, res, access) {
|
|
527
|
+
const productId = (0, utils_2.readStringParam)(req.params, "product_id");
|
|
528
|
+
if (access === "vendor") {
|
|
529
|
+
await (0, seller_utils_1.assertSellerOwnsProduct)(req, productId);
|
|
530
|
+
}
|
|
531
|
+
const service = req.scope.resolve(coupon_1.COUPON_MODULE);
|
|
532
|
+
const entitlements = await (0, entitlement_utils_1.listCouponEntitlements)(service, {
|
|
533
|
+
product_id: productId,
|
|
534
|
+
});
|
|
535
|
+
res.json({
|
|
536
|
+
customer_coupon_entitlements: entitlements,
|
|
537
|
+
count: entitlements.length,
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
async function optionsForCouponProducts(req, res, access) {
|
|
541
|
+
const sellerProductIds = access === "vendor" ? await (0, seller_utils_1.listSellerProductIds)(req) : undefined;
|
|
542
|
+
const sellerId = access === "vendor" ? (0, seller_utils_1.getSellerId)(req) : undefined;
|
|
543
|
+
const options = await (0, product_utils_1.listCouponProductOptions)(req, sellerProductIds, sellerId);
|
|
544
|
+
res.json(options);
|
|
545
|
+
}
|
|
546
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291cG9uLXByb2R1Y3Qtcm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwaS9jb3Vwb24tcHJvZHVjdC1yb3V0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFtRkEsc0RBMkRDO0FBRUQsa0VBb0NDO0FBK05ELGdEQVlDO0FBRUQsa0RBOEVDO0FBRUQsc0RBZUM7QUFFRCxrREErR0M7QUFFRCxrREFtQkM7QUFtQkQsOERBb0JDO0FBRUQsZ0VBMkJDO0FBRUQsZ0VBNkJDO0FBRUQsZ0VBOEJDO0FBRUQsMERBbUJDO0FBRUQsNERBZUM7QUE5eUJELHFEQUdrQztBQUNsQyw0REFLb0M7QUFDcEMsOENBQWlEO0FBRWpELDJEQUFpRTtBQUNqRSx5RUFBNkU7QUFDN0UsMkRBQTREO0FBQzVELG1EQU13QjtBQUN4QixtQ0FBb0Q7QUFDcEQsNkNBSXFCO0FBQ3JCLGlEQUl1QjtBQVN2QixTQUFTLE9BQU8sQ0FBZ0MsS0FBUTtJQUN0RCxPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQ3ZCLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQzFELENBQUE7QUFDUixDQUFDO0FBRUQsS0FBSyxVQUFVLDBCQUEwQixDQUN2QyxPQUE0QixFQUM1QixLQUFVLEVBQ1YsVUFBdUQsRUFBRTtJQUV6RCxNQUFNLE9BQU8sR0FBRyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUE7SUFDNUIsTUFBTSxTQUFTLEdBQXlCLEVBQUUsQ0FBQTtJQUMxQyxNQUFNLFlBQVksR0FDaEIsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUM7UUFDeEQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxvQkFB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
|