@devx-commerce/plugin-gati 0.0.34-beta.2 → 0.0.34-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/.medusa/server/development/erp-order-payload-example.js +76 -0
  2. package/.medusa/server/src/api/admin/variant-options/recalculate/route.js +446 -0
  3. package/.medusa/server/src/api/admin/variant-options/sync/route.js +21 -5
  4. package/.medusa/server/src/api/erp/webhook/config.js +6 -1
  5. package/.medusa/server/src/api/erp/webhook/route.js +10 -137
  6. package/.medusa/server/src/jobs/process-erp-events.js +205 -0
  7. package/.medusa/server/src/jobs/process-variant-option-sync.js +43 -28
  8. package/.medusa/server/src/jobs/sync-order-erp.js +2 -2
  9. package/.medusa/server/src/subscribers/cutomer-updated.js +2 -1
  10. package/.medusa/server/src/subscribers/party-master.js +2 -2
  11. package/.medusa/server/src/workflows/helpers/product-helper.js +53 -26
  12. package/.medusa/server/src/workflows/helpers/variant-helper.js +165 -162
  13. package/.medusa/server/src/workflows/hooks/product-updated.js +6 -11
  14. package/.medusa/server/src/workflows/inward-master/workflows/update-inward.js +6 -2
  15. package/.medusa/server/src/workflows/orders/steps/sync-order-to-erp.js +3 -2
  16. package/.medusa/server/src/workflows/orders/utils/order-helper.js +6 -5
  17. package/.medusa/server/src/workflows/orders/workflows/sync-order-to-erp.js +27 -2
  18. package/.medusa/server/src/workflows/party-master/steps/fetch-party-master.js +2 -1
  19. package/.medusa/server/src/workflows/party-master/workflows/create-or-update-party-master.js +2 -2
  20. package/.medusa/server/src/workflows/party-style-master/steps/update-product-options-after-deletion.js +16 -249
  21. package/.medusa/server/src/workflows/party-style-master/steps/update-product-options-after-variant-update.js +103 -22
  22. package/.medusa/server/src/workflows/party-style-master/workflows/create-or-update-party-style-master.js +16 -10
  23. package/.medusa/server/src/workflows/update-extended-product-from-product/index.js +6 -8
  24. package/.medusa/server/src/workflows/update-extended-variant-from-variant/workflows/update-extended-variant-status-from-variant.js +9 -3
  25. package/package.json +1 -1
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const orderPayload = {
4
+ OrderId: 0,
5
+ BranchNo: "0004000711",
6
+ BranchName: "Timeless Jewels",
7
+ OrderPrefix: "",
8
+ OrderNo: "",
9
+ OrderDate: "2025-06-21T00:00:00",
10
+ CustomerId: "0001000056",
11
+ Customer: "",
12
+ PoNo: "ID1111",
13
+ PoDate: "2025-06-21T00:00:00",
14
+ SalesPerson: "",
15
+ WorkOrderNo: "",
16
+ Remarks: "",
17
+ PromocodeSeriesId: 0,
18
+ Promocode: "",
19
+ PromocodePercentage: 0,
20
+ PromocodeAmount: 0,
21
+ OrderDetail: [
22
+ {
23
+ OrderId: 0,
24
+ OrderItemId: 0,
25
+ SrNo: 1,
26
+ StyleId: 33067,
27
+ StyleCode: "DR00962",
28
+ PartyStyleId: 5445,
29
+ PartyStyleCode: "DR00260",
30
+ JewelId: 0,
31
+ JewelCode: "",
32
+ ItemSize: "5",
33
+ OrderQty: 1.0,
34
+ OrderItemPcs: 1,
35
+ Metal: "",
36
+ Tone: "",
37
+ ItemPoNo: "",
38
+ ItemRefNo: "",
39
+ Priority: "N",
40
+ StockType: "LG DIAMOND",
41
+ MakeType: "A",
42
+ CustomerProductionInstruction: "",
43
+ SpecialRemarks: "",
44
+ DesignProductionInstruction: "",
45
+ StampInstruction: "",
46
+ Expecteddeliverydate: "2025-06-25T00:00:00",
47
+ MRP: 36063.0,
48
+ },
49
+ ],
50
+ PaymentOption: [
51
+ {
52
+ OrderId: 0,
53
+ BookName: "UPI TimeLess - P",
54
+ Amount: 37144.89,
55
+ },
56
+ ],
57
+ };
58
+ console.log(JSON.stringify(orderPayload, null, 2));
59
+ // You can use this payload with the ErpService.createOrder method.
60
+ // Example:
61
+ // import ErpService from './src/modules/erp/service';
62
+ // const erpService = new ErpService(
63
+ // {},
64
+ // {
65
+ // authToken: "D7F0A5C3-E229-4BBF-AA62-5D8B858EB887",
66
+ // baseUrl: "http://103.98.6.30:90/api/Svaraa",
67
+ // }
68
+ // );
69
+ // erpService.createOrder(orderPayload)
70
+ // .then(result => {
71
+ // console.log('Order created successfully:', result);
72
+ // })
73
+ // .catch(error => {
74
+ // console.error('Error creating order:', error);
75
+ // });
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJwLW9yZGVyLXBheWxvYWQtZXhhbXBsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2RldmVsb3BtZW50L2VycC1vcmRlci1wYXlsb2FkLWV4YW1wbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxNQUFNLFlBQVksR0FBaUI7SUFDakMsT0FBTyxFQUFFLENBQUM7SUFDVixRQUFRLEVBQUUsWUFBWTtJQUN0QixVQUFVLEVBQUUsaUJBQWlCO0lBQzdCLFdBQVcsRUFBRSxFQUFFO0lBQ2YsT0FBTyxFQUFFLEVBQUU7SUFDWCxTQUFTLEVBQUUscUJBQXFCO0lBQ2hDLFVBQVUsRUFBRSxZQUFZO0lBQ3hCLFFBQVEsRUFBRSxFQUFFO0lBQ1osSUFBSSxFQUFFLFFBQVE7SUFDZCxNQUFNLEVBQUUscUJBQXFCO0lBQzdCLFdBQVcsRUFBRSxFQUFFO0lBQ2YsV0FBVyxFQUFFLEVBQUU7SUFDZixPQUFPLEVBQUUsRUFBRTtJQUNYLGlCQUFpQixFQUFFLENBQUM7SUFDcEIsU0FBUyxFQUFFLEVBQUU7SUFDYixtQkFBbUIsRUFBRSxDQUFDO0lBQ3RCLGVBQWUsRUFBRSxDQUFDO0lBQ2xCLFdBQVcsRUFBRTtRQUNYO1lBQ0UsT0FBTyxFQUFFLENBQUM7WUFDVixXQUFXLEVBQUUsQ0FBQztZQUNkLElBQUksRUFBRSxDQUFDO1lBQ1AsT0FBTyxFQUFFLEtBQUs7WUFDZCxTQUFTLEVBQUUsU0FBUztZQUNwQixZQUFZLEVBQUUsSUFBSTtZQUNsQixjQUFjLEVBQUUsU0FBUztZQUN6QixPQUFPLEVBQUUsQ0FBQztZQUNWLFNBQVMsRUFBRSxFQUFFO1lBQ2IsUUFBUSxFQUFFLEdBQUc7WUFDYixRQUFRLEVBQUUsR0FBRztZQUNiLFlBQVksRUFBRSxDQUFDO1lBQ2YsS0FBSyxFQUFFLEVBQUU7WUFDVCxJQUFJLEVBQUUsRUFBRTtZQUNSLFFBQVEsRUFBRSxFQUFFO1lBQ1osU0FBUyxFQUFFLEVBQUU7WUFDYixRQUFRLEVBQUUsR0FBRztZQUNiLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFFBQVEsRUFBRSxHQUFHO1lBQ2IsNkJBQTZCLEVBQUUsRUFBRTtZQUNqQyxjQUFjLEVBQUUsRUFBRTtZQUNsQiwyQkFBMkIsRUFBRSxFQUFFO1lBQy9CLGdCQUFnQixFQUFFLEVBQUU7WUFDcEIsb0JBQW9CLEVBQUUscUJBQXFCO1lBQzNDLEdBQUcsRUFBRSxPQUFPO1NBQ2I7S0FDRjtJQUNELGFBQWEsRUFBRTtRQUNiO1lBQ0UsT0FBTyxFQUFFLENBQUM7WUFDVixRQUFRLEVBQUUsa0JBQWtCO1lBQzVCLE1BQU0sRUFBRSxRQUFRO1NBQ2pCO0tBQ0Y7Q0FDRixDQUFDO0FBRUYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVuRCxtRUFBbUU7QUFDbkUsV0FBVztBQUVYLHNEQUFzRDtBQUV0RCxxQ0FBcUM7QUFDckMsUUFBUTtBQUNSLE1BQU07QUFDTix5REFBeUQ7QUFDekQsbURBQW1EO0FBQ25ELE1BQU07QUFDTixLQUFLO0FBRUwsdUNBQXVDO0FBQ3ZDLHNCQUFzQjtBQUN0QiwwREFBMEQ7QUFDMUQsT0FBTztBQUNQLHNCQUFzQjtBQUN0QixxREFBcUQ7QUFDckQsUUFBUSJ9
@@ -0,0 +1,446 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const core_flows_1 = require("@medusajs/medusa/core-flows");
6
+ const api_response_1 = require("../../../../lib/api-response");
7
+ const update_variant_option_metadata_1 = require("../../../../workflows/helpers/update-variant-option-metadata");
8
+ const BATCH_SIZE = 10; // Process 10 products at a time
9
+ /**
10
+ * POST /admin/variant-options/recalculate
11
+ *
12
+ * Recalculate product options for one or more products and all their variants.
13
+ * This is useful when:
14
+ * - Options got out of sync
15
+ * - After bulk updates
16
+ * - To fix option mismatch errors
17
+ *
18
+ * Body:
19
+ * { style_id: string } - Single style
20
+ * { style_ids: string[] } - Multiple styles (processed in batches)
21
+ * { product_id: string } - Single product
22
+ * { product_ids: string[] } - Multiple products (processed in batches)
23
+ */
24
+ const POST = async (req, res) => {
25
+ const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
26
+ const logger = req.scope.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
27
+ const { style_id, style_ids, product_id, product_ids } = (req.body || {});
28
+ // Normalize inputs to arrays
29
+ const styleIdList = style_ids || (style_id ? [style_id] : []);
30
+ const productIdList = product_ids || (product_id ? [product_id] : []);
31
+ if (styleIdList.length === 0 && productIdList.length === 0) {
32
+ return (0, api_response_1.sendApiResponse)(res, (0, api_response_1.createErrorResponse)("Provide style_id, style_ids, product_id, or product_ids", api_response_1.HttpStatus.BAD_REQUEST, api_response_1.ErrorCode.VALIDATION_ERROR));
33
+ }
34
+ try {
35
+ const totalItems = styleIdList.length + productIdList.length;
36
+ logger.info(`[recalculate-options] Starting for ${totalItems} item(s)`);
37
+ // Load master maps once - shared across all products
38
+ const masterMaps = await loadMasterMaps(query);
39
+ // Collect all products to process
40
+ const productsToProcess = [];
41
+ // Fetch products by style_ids
42
+ if (styleIdList.length > 0) {
43
+ const { data: productsByStyle } = await query.graph({
44
+ entity: "product",
45
+ fields: ["id", "external_id", "options.*"],
46
+ filters: {
47
+ external_id: styleIdList,
48
+ },
49
+ });
50
+ productsToProcess.push(...(productsByStyle || []));
51
+ }
52
+ // Fetch products by product_ids
53
+ if (productIdList.length > 0) {
54
+ const { data: productsById } = await query.graph({
55
+ entity: "product",
56
+ fields: ["id", "external_id", "options.*"],
57
+ filters: {
58
+ id: productIdList,
59
+ },
60
+ });
61
+ productsToProcess.push(...(productsById || []));
62
+ }
63
+ // Deduplicate by product id
64
+ const uniqueProducts = Array.from(new Map(productsToProcess.map(p => [p.id, p])).values());
65
+ if (uniqueProducts.length === 0) {
66
+ return (0, api_response_1.sendApiResponse)(res, (0, api_response_1.createErrorResponse)("No products found for the provided identifiers", api_response_1.HttpStatus.NOT_FOUND, api_response_1.ErrorCode.NOT_FOUND));
67
+ }
68
+ logger.info(`[recalculate-options] Found ${uniqueProducts.length} unique products to process`);
69
+ // Process in batches
70
+ const results = [];
71
+ const batches = chunkArray(uniqueProducts, BATCH_SIZE);
72
+ for (let batchIdx = 0; batchIdx < batches.length; batchIdx++) {
73
+ const batch = batches[batchIdx];
74
+ logger.info(`[recalculate-options] Processing batch ${batchIdx + 1}/${batches.length} (${batch.length} products)`);
75
+ // Process each product in the batch independently
76
+ const batchResults = await Promise.all(batch.map(product => processProductOptions(req.scope, query, logger, product, masterMaps)));
77
+ results.push(...batchResults);
78
+ }
79
+ // Summary
80
+ const summary = {
81
+ total: results.length,
82
+ success: results.filter(r => r.status === "success").length,
83
+ errors: results.filter(r => r.status === "error").length,
84
+ skipped: results.filter(r => r.status === "skipped").length,
85
+ };
86
+ logger.info(`[recalculate-options] Completed: ${summary.success} success, ${summary.errors} errors, ${summary.skipped} skipped`);
87
+ return (0, api_response_1.sendApiResponse)(res, (0, api_response_1.createSuccessResponse)({
88
+ summary,
89
+ results,
90
+ }, `Processed ${results.length} products: ${summary.success} success, ${summary.errors} errors, ${summary.skipped} skipped`));
91
+ }
92
+ catch (error) {
93
+ logger.error("[recalculate-options] Error:", error);
94
+ const errorMessage = error instanceof Error ? error.message : "Internal server error";
95
+ return (0, api_response_1.sendApiResponse)(res, (0, api_response_1.createErrorResponse)(errorMessage, api_response_1.HttpStatus.INTERNAL_SERVER_ERROR, api_response_1.ErrorCode.INTERNAL_ERROR));
96
+ }
97
+ };
98
+ exports.POST = POST;
99
+ /**
100
+ * Load all master maps once for reuse
101
+ */
102
+ async function loadMasterMaps(query) {
103
+ const [{ data: rawMasterArr }, { data: qualityMasterArr }, { data: toneMasterArr }, { data: itemSizeMasterArr }, { data: shapeMasterArr },] = await Promise.all([
104
+ query.graph({ entity: "raw_master", fields: ["id", "title", "raw_code"] }),
105
+ query.graph({ entity: "quality_master", fields: ["id", "title", "qly_code"] }),
106
+ query.graph({ entity: "tone_master", fields: ["id", "title", "tone_code"] }),
107
+ query.graph({ entity: "item_size_master", fields: ["id", "title", "item_size_code"] }),
108
+ query.graph({ entity: "shape_master", fields: ["id", "title", "shape_code"] }),
109
+ ]);
110
+ const rawMasterMap = new Map();
111
+ rawMasterArr?.forEach((x) => rawMasterMap.set(x.raw_code, x.title));
112
+ const qualityMasterMap = new Map();
113
+ qualityMasterArr?.forEach((x) => qualityMasterMap.set(x.qly_code, x.title));
114
+ const toneMasterMap = new Map();
115
+ toneMasterArr?.forEach((x) => toneMasterMap.set(x.tone_code, x.title));
116
+ const itemSizeMasterMap = new Map();
117
+ itemSizeMasterArr?.forEach((x) => itemSizeMasterMap.set(x.item_size_code, x.title));
118
+ const shapeMasterMap = new Map();
119
+ shapeMasterArr?.forEach((x) => shapeMasterMap.set(x.shape_code, x.title));
120
+ return {
121
+ rawMasterMap,
122
+ qualityMasterMap,
123
+ toneMasterMap,
124
+ itemSizeMasterMap,
125
+ shapeMasterMap,
126
+ };
127
+ }
128
+ /**
129
+ * Process a single product's options
130
+ */
131
+ async function processProductOptions(scope, query, logger, product, masterMaps) {
132
+ const result = {
133
+ product_id: product.id,
134
+ style_id: product.external_id,
135
+ status: "success",
136
+ updated_variants: 0,
137
+ skipped_variants: [],
138
+ };
139
+ try {
140
+ // Capture old product options
141
+ const oldProductOptions = (product.options || []).map((opt) => ({
142
+ title: opt.title,
143
+ values: opt.values?.map((v) => v.value || v) || [],
144
+ })).filter((opt) => opt.title !== "Default");
145
+ // Get all variants for this product with their current options
146
+ const { data: variants } = await query.graph({
147
+ entity: "product_variant",
148
+ fields: [
149
+ "id",
150
+ "product_id",
151
+ "options.*",
152
+ "extended_variant.id",
153
+ "extended_variant.item_size",
154
+ "extended_variant.stock_type",
155
+ "extended_variant.party_style_details.*",
156
+ ],
157
+ filters: {
158
+ product_id: product.id,
159
+ },
160
+ });
161
+ if (!variants || variants.length === 0) {
162
+ result.status = "skipped";
163
+ result.error = "No variants found";
164
+ // Include old product options even when skipped
165
+ result.product_options = {
166
+ old: oldProductOptions,
167
+ new: oldProductOptions, // No change when skipped
168
+ };
169
+ result.variant_options = [];
170
+ return result;
171
+ }
172
+ // Get extended variant IDs
173
+ const extendedVariantIds = variants
174
+ .map((v) => v.extended_variant?.id)
175
+ .filter(Boolean);
176
+ // Get extended variants with party_style_details
177
+ const { data: extendedVariants } = await query.graph({
178
+ entity: "extended_variant",
179
+ fields: ["id", "item_size", "stock_type", "party_style_details.*"],
180
+ filters: {
181
+ id: extendedVariantIds,
182
+ },
183
+ });
184
+ // Capture old variant options
185
+ const oldVariantOptionsMap = new Map();
186
+ for (const variant of variants) {
187
+ const oldOptions = {};
188
+ if (variant.options) {
189
+ for (const opt of variant.options) {
190
+ if (opt.value) {
191
+ oldOptions[opt.title] = opt.value;
192
+ }
193
+ }
194
+ }
195
+ oldVariantOptionsMap.set(variant.id, oldOptions);
196
+ }
197
+ // Calculate options for each variant
198
+ const productOptionsMap = new Map();
199
+ const variantsToUpdate = [];
200
+ const rawValueMappings = [];
201
+ const newVariantOptionsMap = new Map();
202
+ for (const variant of variants) {
203
+ const extendedVariant = extendedVariants?.find((ev) => ev.id === variant.extended_variant?.id);
204
+ if (!extendedVariant) {
205
+ result.skipped_variants.push({
206
+ id: variant.id,
207
+ reason: "No extended_variant found",
208
+ });
209
+ continue;
210
+ }
211
+ const variantOptions = {};
212
+ // Detect solitaire styles based on stock_type
213
+ const stockType = extendedVariant?.stock_type;
214
+ const isSolitaire = stockType === "LG SOLITAIRE" || stockType === "SOLITAIRE";
215
+ // Size
216
+ if (extendedVariant.item_size) {
217
+ const sizeTitle = (masterMaps.itemSizeMasterMap.get(extendedVariant.item_size) ||
218
+ String(extendedVariant.item_size)).trim();
219
+ variantOptions["Size"] = sizeTitle;
220
+ if (!productOptionsMap.has("Size")) {
221
+ productOptionsMap.set("Size", new Set());
222
+ }
223
+ productOptionsMap.get("Size").add(sizeTitle);
224
+ rawValueMappings.push({
225
+ variantId: variant.id,
226
+ optionTitle: "Size",
227
+ optionValue: sizeTitle,
228
+ rawValue: extendedVariant.item_size,
229
+ });
230
+ }
231
+ // Process party_style_details
232
+ if (extendedVariant.party_style_details) {
233
+ for (const detail of extendedVariant.party_style_details) {
234
+ // Metal options
235
+ if (detail.raw_type === "Metal" && detail.is_base) {
236
+ const qualityTitle = (masterMaps.qualityMasterMap.get(detail.qly_code) || detail.qly_code).trim();
237
+ const rawTitle = (masterMaps.rawMasterMap.get(detail.raw_code) || detail.raw_code).trim();
238
+ const metalValue = `${qualityTitle} ${rawTitle}`.trim();
239
+ variantOptions["Metal"] = metalValue;
240
+ if (!productOptionsMap.has("Metal")) {
241
+ productOptionsMap.set("Metal", new Set());
242
+ }
243
+ productOptionsMap.get("Metal").add(metalValue);
244
+ rawValueMappings.push({
245
+ variantId: variant.id,
246
+ optionTitle: "Metal",
247
+ optionValue: metalValue,
248
+ rawValue: `${detail.qly_code || ""}:${detail.raw_code || ""}`.trim(),
249
+ });
250
+ // Metal Color
251
+ if (detail.tone_code) {
252
+ let colorTitle = masterMaps.toneMasterMap.get(detail.tone_code) || detail.tone_code;
253
+ // Fallback to static mappings
254
+ if (!masterMaps.toneMasterMap.has(detail.tone_code)) {
255
+ if (detail.tone_code === "R")
256
+ colorTitle = "Rose";
257
+ else if (detail.tone_code === "Y")
258
+ colorTitle = "Yellow";
259
+ else if (detail.tone_code === "W")
260
+ colorTitle = "White";
261
+ else if (detail.tone_code === "YRW")
262
+ colorTitle = "YELLOW/ROSE/WHITE";
263
+ else if (detail.tone_code === "YW")
264
+ colorTitle = "YELLOW/WHITE";
265
+ else if (detail.tone_code === "RW")
266
+ colorTitle = "ROSE/WHITE";
267
+ else if (detail.tone_code === "BU")
268
+ colorTitle = "BLUE";
269
+ else if (detail.tone_code === "BL")
270
+ colorTitle = "BLACK";
271
+ }
272
+ colorTitle = colorTitle.trim();
273
+ variantOptions["Metal Color"] = colorTitle;
274
+ if (!productOptionsMap.has("Metal Color")) {
275
+ productOptionsMap.set("Metal Color", new Set());
276
+ }
277
+ productOptionsMap.get("Metal Color").add(colorTitle);
278
+ rawValueMappings.push({
279
+ variantId: variant.id,
280
+ optionTitle: "Metal Color",
281
+ optionValue: colorTitle,
282
+ rawValue: detail.tone_code || "",
283
+ });
284
+ }
285
+ }
286
+ // Diamond Quality
287
+ if (detail.raw_type === "Diamond" &&
288
+ detail.tone_code &&
289
+ detail.qly_code &&
290
+ detail.is_base) {
291
+ const toneTitle = (masterMaps.toneMasterMap.get(detail.tone_code) || detail.tone_code).trim();
292
+ const qualityTitle = (masterMaps.qualityMasterMap.get(detail.qly_code) || detail.qly_code).trim();
293
+ const diamondValue = `${toneTitle} ${qualityTitle}`.trim();
294
+ variantOptions["Diamond Quality"] = diamondValue;
295
+ if (!productOptionsMap.has("Diamond Quality")) {
296
+ productOptionsMap.set("Diamond Quality", new Set());
297
+ }
298
+ productOptionsMap.get("Diamond Quality").add(diamondValue);
299
+ rawValueMappings.push({
300
+ variantId: variant.id,
301
+ optionTitle: "Diamond Quality",
302
+ optionValue: diamondValue,
303
+ rawValue: `${detail.tone_code || ""}:${detail.qly_code || ""}`.trim(),
304
+ });
305
+ }
306
+ // Shape and Carat for solitaire
307
+ if (isSolitaire &&
308
+ detail.raw_type === "Diamond" &&
309
+ detail.raw_code === "LGS" &&
310
+ detail.is_base) {
311
+ const shapeTitle = (masterMaps.shapeMasterMap.get(detail.shape_code) ||
312
+ String(detail.shape_code || "")).trim();
313
+ if (shapeTitle) {
314
+ variantOptions["Shape"] = shapeTitle;
315
+ if (!productOptionsMap.has("Shape")) {
316
+ productOptionsMap.set("Shape", new Set());
317
+ }
318
+ productOptionsMap.get("Shape").add(shapeTitle);
319
+ rawValueMappings.push({
320
+ variantId: variant.id,
321
+ optionTitle: "Shape",
322
+ optionValue: shapeTitle,
323
+ rawValue: detail.shape_code || "",
324
+ });
325
+ }
326
+ const weightStr = String(detail?.weight || "").trim();
327
+ if (weightStr) {
328
+ variantOptions["Carat"] = weightStr;
329
+ if (!productOptionsMap.has("Carat")) {
330
+ productOptionsMap.set("Carat", new Set());
331
+ }
332
+ productOptionsMap.get("Carat").add(weightStr);
333
+ rawValueMappings.push({
334
+ variantId: variant.id,
335
+ optionTitle: "Carat",
336
+ optionValue: weightStr,
337
+ rawValue: weightStr,
338
+ });
339
+ }
340
+ }
341
+ }
342
+ }
343
+ // Check if we have all required options
344
+ const productOptionTitles = product.options?.map((opt) => opt.title) || [];
345
+ const hasAllOptions = productOptionTitles.every((title) => variantOptions[title] !== undefined);
346
+ if (!hasAllOptions) {
347
+ const missingOptions = productOptionTitles.filter((title) => variantOptions[title] === undefined);
348
+ result.skipped_variants.push({
349
+ id: variant.id,
350
+ reason: `Missing options: [${missingOptions.join(", ")}]`,
351
+ });
352
+ continue;
353
+ }
354
+ // Sort options alphabetically
355
+ const sortedOptions = {};
356
+ Object.keys(variantOptions)
357
+ .sort((a, b) => a.localeCompare(b))
358
+ .forEach((key) => {
359
+ sortedOptions[key] = variantOptions[key];
360
+ });
361
+ variantsToUpdate.push({
362
+ id: variant.id,
363
+ options: sortedOptions,
364
+ });
365
+ // Store new variant options
366
+ newVariantOptionsMap.set(variant.id, sortedOptions);
367
+ }
368
+ // STEP 1: Update product options to include all values
369
+ const productOptions = Array.from(productOptionsMap.entries())
370
+ .sort(([a], [b]) => a.localeCompare(b))
371
+ .map(([title, values]) => ({
372
+ title,
373
+ values: Array.from(values).sort((a, b) => a.localeCompare(b)),
374
+ }));
375
+ if (productOptions.length > 0) {
376
+ await (0, core_flows_1.updateProductsWorkflow)(scope).run({
377
+ input: {
378
+ products: [{ id: product.id, options: productOptions }],
379
+ },
380
+ });
381
+ }
382
+ // STEP 2: Update variant options
383
+ if (variantsToUpdate.length > 0) {
384
+ await (0, core_flows_1.updateProductVariantsWorkflow)(scope).run({
385
+ input: {
386
+ product_variants: variantsToUpdate,
387
+ },
388
+ });
389
+ // Update variant option metadata with raw values
390
+ if (rawValueMappings.length > 0) {
391
+ await (0, update_variant_option_metadata_1.updateVariantOptionMetadata)(scope, rawValueMappings);
392
+ }
393
+ }
394
+ // Fetch new product options after update
395
+ const { data: updatedProduct } = await query.graph({
396
+ entity: "product",
397
+ fields: ["id", "options.*"],
398
+ filters: {
399
+ id: product.id,
400
+ },
401
+ });
402
+ const newProductOptions = (updatedProduct?.[0]?.options || []).map((opt) => ({
403
+ title: opt.title,
404
+ values: opt.values?.map((v) => v.value || v) || [],
405
+ })).filter((opt) => opt.title !== "Default");
406
+ // Build variant options comparison
407
+ const variantOptionsComparison = [];
408
+ for (const variant of variants) {
409
+ const oldOptions = oldVariantOptionsMap.get(variant.id) || {};
410
+ const newOptions = newVariantOptionsMap.get(variant.id) || {};
411
+ // Only include variants that were updated
412
+ if (variantsToUpdate.some(v => v.id === variant.id)) {
413
+ variantOptionsComparison.push({
414
+ variant_id: variant.id,
415
+ old: oldOptions,
416
+ new: newOptions,
417
+ });
418
+ }
419
+ }
420
+ // Include old and new options in result
421
+ result.product_options = {
422
+ old: oldProductOptions,
423
+ new: newProductOptions,
424
+ };
425
+ result.variant_options = variantOptionsComparison;
426
+ result.updated_variants = variantsToUpdate.length;
427
+ logger.info(`[recalculate-options] Product ${product.external_id || product.id}: ${variantsToUpdate.length} updated, ${result.skipped_variants.length} skipped`);
428
+ }
429
+ catch (error) {
430
+ result.status = "error";
431
+ result.error = error instanceof Error ? error.message : "Unknown error";
432
+ logger.error(`[recalculate-options] Error processing product ${product.external_id || product.id}:`, error);
433
+ }
434
+ return result;
435
+ }
436
+ /**
437
+ * Split array into chunks
438
+ */
439
+ function chunkArray(array, size) {
440
+ const chunks = [];
441
+ for (let i = 0; i < array.length; i += size) {
442
+ chunks.push(array.slice(i, i + size));
443
+ }
444
+ return chunks;
445
+ }
446
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3ZhcmlhbnQtb3B0aW9ucy9yZWNhbGN1bGF0ZS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFBc0U7QUFDdEUsNERBR3FDO0FBRXJDLCtEQU1zQztBQUN0QyxpSEFHc0U7QUFFdEUsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDLENBQUMsZ0NBQWdDO0FBNEJ2RDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNJLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFDdkIsR0FBK0IsRUFDL0IsR0FBbUIsRUFDbkIsRUFBRTtJQUNGLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRW5FLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUt2RSxDQUFDO0lBRUYsNkJBQTZCO0lBQzdCLE1BQU0sV0FBVyxHQUFHLFNBQVMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUQsTUFBTSxhQUFhLEdBQUcsV0FBVyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUV0RSxJQUFJLFdBQVcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDM0QsT0FBTyxJQUFB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