@devx-commerce/plugin-gati 0.0.31-beta.1 → 0.0.31-beta.3

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.
@@ -23,9 +23,10 @@ async function processVariantOptionSync(container) {
23
23
  const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
24
24
  const syncQueueService = container.resolve(variant_option_sync_queue_1.VARIANT_OPTION_SYNC_QUEUE_MODULE);
25
25
  logger.info("------Starting variant option sync job------");
26
+ let pendingRecords = [];
26
27
  try {
27
28
  // Query all pending tracking records
28
- const { data: pendingRecords } = await query.graph({
29
+ const { data: records } = await query.graph({
29
30
  entity: "variant_option_sync_queue",
30
31
  fields: [
31
32
  "id",
@@ -42,6 +43,7 @@ async function processVariantOptionSync(container) {
42
43
  take: 50, // Process 50 records at a time
43
44
  },
44
45
  });
46
+ pendingRecords = records || [];
45
47
  if (!pendingRecords || pendingRecords.length === 0) {
46
48
  logger.info("------No pending variant option sync records found------");
47
49
  return;
@@ -85,344 +87,385 @@ async function processVariantOptionSync(container) {
85
87
  itemSizeMasterMap,
86
88
  shapeMasterMap,
87
89
  };
88
- // Process each tracking record
90
+ // STEP 1: Collect all affected products across all records
91
+ // Update all records to processing status
92
+ await syncQueueService.updateVariantOptionSyncQueues(pendingRecords.map((r) => ({
93
+ id: r.id,
94
+ status: "processing",
95
+ })));
96
+ logger.info(`------Processing ${pendingRecords.length} records in batch------`);
97
+ // Collect all affected products across all records
98
+ const affectedProductsSet = new Set();
99
+ const recordAffectedVariantsMap = new Map();
89
100
  for (const record of pendingRecords) {
90
- try {
91
- // Update status to processing
92
- await syncQueueService.updateVariantOptionSyncQueues([
93
- {
94
- id: record.id,
95
- status: "processing",
96
- },
97
- ]);
98
- logger.info(`------Processing record ${record.id}: ${record.master_type} - ${record.master_code}------`);
99
- // Find affected variants
100
- const affectedVariants = await (0, variant_helper_1.findVariantsAffectedByMasterUpdate)(query, record.master_type, record.master_code);
101
- if (affectedVariants.length === 0) {
102
- logger.info(`------No affected variants found for ${record.master_type} - ${record.master_code}------ (record id: ${record.id})`);
103
- // Mark as completed with 0 affected variants
104
- await syncQueueService.updateVariantOptionSyncQueues([
105
- {
106
- id: record.id,
107
- status: "completed",
108
- affected_variant_count: 0,
109
- processed_at: new Date(),
110
- },
111
- ]);
112
- continue;
113
- }
114
- logger.info(`------Found ${affectedVariants.length} affected variants for record ${record.id}------`);
115
- // Group variants by product_id
116
- const variantsByProduct = new Map();
117
- for (const variant of affectedVariants) {
118
- if (!variantsByProduct.has(variant.productId)) {
119
- variantsByProduct.set(variant.productId, []);
120
- }
121
- variantsByProduct.get(variant.productId).push(variant);
122
- }
123
- // Get all affected products with their options
124
- const productIds = Array.from(variantsByProduct.keys());
125
- const { data: products } = await query.graph({
126
- entity: "product",
127
- fields: ["id", "external_id", "options.*"],
101
+ logger.info(`------Finding affected variants for record ${record.id}: ${record.master_type} - ${record.master_code}------`);
102
+ // Find affected variants
103
+ const affectedVariants = await (0, variant_helper_1.findVariantsAffectedByMasterUpdate)(query, record.master_type, record.master_code);
104
+ if (affectedVariants.length === 0) {
105
+ logger.info(`------No affected variants found for ${record.master_type} - ${record.master_code}------ (record id: ${record.id})`);
106
+ recordAffectedVariantsMap.set(record.id, {
107
+ recordId: record.id,
108
+ affectedVariants: [],
109
+ });
110
+ continue;
111
+ }
112
+ // Collect affected product IDs
113
+ affectedVariants.forEach((v) => affectedProductsSet.add(v.productId));
114
+ recordAffectedVariantsMap.set(record.id, {
115
+ recordId: record.id,
116
+ affectedVariants,
117
+ });
118
+ logger.info(`------Found ${affectedVariants.length} affected variants for record ${record.id}------`);
119
+ }
120
+ const productIds = Array.from(affectedProductsSet);
121
+ if (productIds.length === 0) {
122
+ logger.info("------No affected products found, marking all records as completed------");
123
+ // Mark all records as completed with 0 affected variants
124
+ await syncQueueService.updateVariantOptionSyncQueues(pendingRecords.map((r) => ({
125
+ id: r.id,
126
+ status: "completed",
127
+ affected_variant_count: 0,
128
+ processed_at: new Date(),
129
+ })));
130
+ return;
131
+ }
132
+ logger.info(`------Found ${productIds.length} unique products affected across all records------`);
133
+ // STEP 2: Process products in batches
134
+ const PRODUCT_BATCH_SIZE = 10;
135
+ const productBatches = [];
136
+ for (let i = 0; i < productIds.length; i += PRODUCT_BATCH_SIZE) {
137
+ productBatches.push(productIds.slice(i, i + PRODUCT_BATCH_SIZE));
138
+ }
139
+ logger.info(`------Processing ${productIds.length} products in ${productBatches.length} batches of ${PRODUCT_BATCH_SIZE}------`);
140
+ // Process each product batch
141
+ for (let productBatchIndex = 0; productBatchIndex < productBatches.length; productBatchIndex++) {
142
+ const productBatch = productBatches[productBatchIndex];
143
+ logger.info(`------Processing product batch ${productBatchIndex + 1}/${productBatches.length} (${productBatch.length} products)------`);
144
+ // Get product all options for this batch
145
+ const { data: products } = await query.graph({
146
+ entity: "product",
147
+ fields: ["id", "external_id", "options.*"],
148
+ filters: {
149
+ id: productBatch,
150
+ },
151
+ });
152
+ // Get all variants for products in this batch
153
+ const { data: variants } = await query.graph({
154
+ entity: "product_variant",
155
+ fields: [
156
+ "id",
157
+ "product_id",
158
+ "extended_variant.id",
159
+ "extended_variant.item_size",
160
+ "extended_variant.party_style_details.*",
161
+ ],
162
+ filters: {
163
+ product_id: productBatch,
164
+ },
165
+ });
166
+ logger.info(`------Found ${variants?.length || 0} variants for product batch ${productBatchIndex + 1}------`);
167
+ if (!variants || variants.length === 0) {
168
+ continue;
169
+ }
170
+ // Get extended variant IDs
171
+ const extendedVariantIds = variants
172
+ .map((v) => v.extended_variant?.id)
173
+ .filter(Boolean);
174
+ // Get extended variants with party_style_details in batches
175
+ const EXTENDED_VARIANT_BATCH_SIZE = 100;
176
+ const extendedVariantBatches = [];
177
+ for (let i = 0; i < extendedVariantIds.length; i += EXTENDED_VARIANT_BATCH_SIZE) {
178
+ extendedVariantBatches.push(extendedVariantIds.slice(i, i + EXTENDED_VARIANT_BATCH_SIZE));
179
+ }
180
+ const allExtendedVariants = [];
181
+ for (let evBatchIndex = 0; evBatchIndex < extendedVariantBatches.length; evBatchIndex++) {
182
+ const evBatch = extendedVariantBatches[evBatchIndex];
183
+ const { data: extendedVariants } = await query.graph({
184
+ entity: "extended_variant",
185
+ fields: ["id", "item_size", "stock_type", "party_style_details.*"],
128
186
  filters: {
129
- id: productIds,
187
+ id: evBatch,
130
188
  },
131
189
  });
132
- // Process variants in batches
133
- const BATCH_SIZE = 25;
134
- const variantBatches = [];
135
- for (let i = 0; i < affectedVariants.length; i += BATCH_SIZE) {
136
- variantBatches.push(affectedVariants.slice(i, i + BATCH_SIZE));
190
+ if (extendedVariants) {
191
+ allExtendedVariants.push(...extendedVariants);
137
192
  }
138
- const variantsToUpdate = [];
139
- // Collect all new option values that will be used across all affected variants
140
- // This is needed to update product options BEFORE updating variants
141
- const newOptionValuesByProduct = new Map();
142
- // For each batch of variants
143
- let batchIndex = 0;
144
- for (const batch of variantBatches) {
145
- batchIndex++;
146
- // Get extended variants data for this batch
147
- const extendedVariantIds = batch.map((v) => v.extendedVariantId);
148
- const { data: extendedVariants } = await query.graph({
149
- entity: "extended_variant",
150
- fields: [
151
- "id",
152
- "mapping_id",
153
- "party_style_id",
154
- "style_id",
155
- "item_size",
156
- "party_style_details.*",
157
- ],
158
- filters: {
159
- id: extendedVariantIds,
160
- },
161
- });
162
- logger.info(`------Found ${extendedVariants?.length} extended variants for batch : ${batchIndex}------`);
163
- // For each variant, regenerate options
164
- for (const variant of batch) {
165
- const extendedVariant = extendedVariants?.find((ev) => ev.id === variant.extendedVariantId);
166
- const product = products?.find((p) => p.id === variant.productId);
167
- if (!extendedVariant || !product) {
168
- logger.warn(`------Extended variant or product not found for variant ${variant.variantId} (product id: ${variant.productId}) batch: ${batchIndex}------`);
169
- continue;
170
- }
171
- // Initialize product's option map if not exists
172
- if (!newOptionValuesByProduct.has(variant.productId)) {
173
- newOptionValuesByProduct.set(variant.productId, new Map());
174
- }
175
- const productOptionMap = newOptionValuesByProduct.get(variant.productId);
176
- // Generate options directly from extended_variant data
177
- const variantOptions = {};
178
- // Size
179
- if (extendedVariant.item_size) {
180
- const sizeTitle = (masterMaps.itemSizeMasterMap.get(extendedVariant.item_size) ||
181
- String(extendedVariant.item_size)).trim();
182
- // Always set on variant and track for product options update
183
- variantOptions["Size"] = sizeTitle;
184
- if (!productOptionMap.has("Size")) {
185
- productOptionMap.set("Size", new Set());
186
- }
187
- productOptionMap.get("Size").add(sizeTitle);
193
+ }
194
+ logger.info(`------Found ${allExtendedVariants.length} extended variants for product batch ${productBatchIndex + 1}------`);
195
+ // Calculate variant options for this batch
196
+ const productOptionsMap = new Map();
197
+ const variantsToUpdate = [];
198
+ for (const variant of variants) {
199
+ const productId = variant.product_id;
200
+ if (!productId)
201
+ continue;
202
+ const product = products?.find((p) => p.id === productId);
203
+ const extendedVariant = allExtendedVariants.find((ev) => ev.id === variant.extended_variant?.id);
204
+ if (!product || !extendedVariant)
205
+ continue;
206
+ // Initialize product options map if not exists
207
+ if (!productOptionsMap.has(productId)) {
208
+ productOptionsMap.set(productId, new Map());
209
+ }
210
+ const productOptionMap = productOptionsMap.get(productId);
211
+ // Generate options from extended variant data
212
+ const variantOptions = {};
213
+ // Detect solitaire styles based on stock_type
214
+ const stockType = extendedVariant?.stock_type;
215
+ const isSolitaire = stockType === "LGSOLITAIRE" || stockType === "SOLITAIRE";
216
+ // Size
217
+ if (extendedVariant.item_size) {
218
+ const sizeTitle = (masterMaps.itemSizeMasterMap.get(extendedVariant.item_size) ||
219
+ String(extendedVariant.item_size)).trim();
220
+ const sizeOption = product.options?.find((opt) => opt.title === "Size");
221
+ if (sizeOption) {
222
+ variantOptions["Size"] = sizeTitle;
223
+ if (!productOptionMap.has("Size")) {
224
+ productOptionMap.set("Size", new Set());
188
225
  }
189
- // Process party_style_details for metals, metal colors, diamond qualities, and shapes
190
- let hasMetalOption = false;
191
- let hasDiamondOption = false;
192
- if (extendedVariant.party_style_details) {
193
- for (const detail of extendedVariant.party_style_details) {
194
- // Metal options
195
- if (detail.raw_type === "Metal" && detail.is_base) {
196
- hasMetalOption = true;
197
- const qualityTitle = (masterMaps.qualityMasterMap.get(detail.qly_code) ||
198
- detail.qly_code).trim();
199
- const rawTitle = (masterMaps.rawMasterMap.get(detail.raw_code) ||
200
- detail.raw_code).trim();
201
- const metalValue = `${qualityTitle} ${rawTitle}`.trim();
202
- const metalOption = product.options?.find((opt) => opt.title === "Metal");
203
- if (metalOption) {
204
- variantOptions["Metal"] = metalValue;
205
- // Track this value for product options update
206
- if (!productOptionMap.has("Metal")) {
207
- productOptionMap.set("Metal", new Set());
208
- }
209
- productOptionMap.get("Metal").add(metalValue);
210
- }
211
- // Metal Color
212
- if (detail.tone_code) {
213
- let colorTitle = masterMaps.toneMasterMap.get(detail.tone_code) ||
214
- detail.tone_code;
215
- // Fallback to static mappings if not in master
216
- if (!masterMaps.toneMasterMap.has(detail.tone_code)) {
217
- if (detail.tone_code === "R")
218
- colorTitle = "Rose";
219
- else if (detail.tone_code === "Y")
220
- colorTitle = "Yellow";
221
- else if (detail.tone_code === "W")
222
- colorTitle = "White";
223
- else if (detail.tone_code === "YRW")
224
- colorTitle = "YELLOW/ROSE/WHITE";
225
- else if (detail.tone_code === "YW")
226
- colorTitle = "YELLOW/WHITE";
227
- else if (detail.tone_code === "RW")
228
- colorTitle = "ROSE/WHITE";
229
- else if (detail.tone_code === "BU")
230
- colorTitle = "BLUE";
231
- else if (detail.tone_code === "BL")
232
- colorTitle = "BLACK";
233
- }
234
- colorTitle = colorTitle.trim();
235
- const metalColorOption = product.options?.find((opt) => opt.title === "Metal Color");
236
- if (metalColorOption) {
237
- variantOptions["Metal Color"] = colorTitle;
238
- // Track this value for product options update
239
- if (!productOptionMap.has("Metal Color")) {
240
- productOptionMap.set("Metal Color", new Set());
241
- }
242
- productOptionMap.get("Metal Color").add(colorTitle);
243
- }
244
- }
226
+ productOptionMap.get("Size").add(sizeTitle);
227
+ }
228
+ }
229
+ // Process party_style_details for metals, metal colors, diamond qualities, shapes and solitaire caret
230
+ if (extendedVariant.party_style_details) {
231
+ for (const detail of extendedVariant.party_style_details) {
232
+ // Metal options
233
+ if (detail.raw_type === "Metal" && detail.is_base) {
234
+ const qualityTitle = (masterMaps.qualityMasterMap.get(detail.qly_code) ||
235
+ detail.qly_code).trim();
236
+ const rawTitle = (masterMaps.rawMasterMap.get(detail.raw_code) || detail.raw_code).trim();
237
+ const metalValue = `${qualityTitle} ${rawTitle}`.trim();
238
+ const metalOption = product.options?.find((opt) => opt.title === "Metal");
239
+ if (metalOption) {
240
+ variantOptions["Metal"] = metalValue;
241
+ if (!productOptionMap.has("Metal")) {
242
+ productOptionMap.set("Metal", new Set());
245
243
  }
246
- // Diamond Quality
247
- if (detail.raw_type === "Diamond" &&
248
- detail.tone_code &&
249
- detail.qly_code &&
250
- detail.is_base) {
251
- hasDiamondOption = true;
252
- const toneTitle = (masterMaps.toneMasterMap.get(detail.tone_code) ||
253
- detail.tone_code).trim();
254
- const qualityTitle = (masterMaps.qualityMasterMap.get(detail.qly_code) ||
255
- detail.qly_code).trim();
256
- const diamondValue = `${toneTitle} ${qualityTitle}`.trim();
257
- const diamondOption = product.options?.find((opt) => opt.title === "Diamond Quality");
258
- if (diamondOption) {
259
- variantOptions["Diamond Quality"] = diamondValue;
260
- // Track this value for product options update
261
- if (!productOptionMap.has("Diamond Quality")) {
262
- productOptionMap.set("Diamond Quality", new Set());
263
- }
264
- productOptionMap.get("Diamond Quality").add(diamondValue);
265
- }
244
+ productOptionMap.get("Metal").add(metalValue);
245
+ }
246
+ // Metal Color
247
+ if (detail.tone_code) {
248
+ let colorTitle = masterMaps.toneMasterMap.get(detail.tone_code) ||
249
+ detail.tone_code;
250
+ // Fallback to static mappings if not in master
251
+ if (!masterMaps.toneMasterMap.has(detail.tone_code)) {
252
+ if (detail.tone_code === "R")
253
+ colorTitle = "Rose";
254
+ else if (detail.tone_code === "Y")
255
+ colorTitle = "Yellow";
256
+ else if (detail.tone_code === "W")
257
+ colorTitle = "White";
258
+ else if (detail.tone_code === "YRW")
259
+ colorTitle = "YELLOW/ROSE/WHITE";
260
+ else if (detail.tone_code === "YW")
261
+ colorTitle = "YELLOW/WHITE";
262
+ else if (detail.tone_code === "RW")
263
+ colorTitle = "ROSE/WHITE";
264
+ else if (detail.tone_code === "BU")
265
+ colorTitle = "BLUE";
266
+ else if (detail.tone_code === "BL")
267
+ colorTitle = "BLACK";
266
268
  }
267
- if (detail.raw_type === "Diamond" &&
268
- detail.is_base) {
269
- const shapeTitle = (masterMaps.shapeMasterMap.get(detail.shape_code) ||
270
- String(detail.shape_code || "")).trim();
271
- if (shapeTitle) {
272
- const shapeOption = product.options?.find((opt) => opt.title === "Shape");
273
- if (shapeOption) {
274
- variantOptions["Shape"] = shapeTitle;
275
- if (!productOptionMap.has("Shape")) {
276
- productOptionMap.set("Shape", new Set());
277
- }
278
- productOptionMap.get("Shape").add(shapeTitle);
279
- }
269
+ colorTitle = colorTitle.trim();
270
+ const metalColorOption = product.options?.find((opt) => opt.title === "Metal Color");
271
+ if (metalColorOption) {
272
+ variantOptions["Metal Color"] = colorTitle;
273
+ if (!productOptionMap.has("Metal Color")) {
274
+ productOptionMap.set("Metal Color", new Set());
280
275
  }
276
+ productOptionMap.get("Metal Color").add(colorTitle);
281
277
  }
282
278
  }
283
279
  }
284
- variantsToUpdate.push({
285
- variant: {
286
- id: variant.variantId,
287
- options: variantOptions,
288
- },
289
- });
290
- }
291
- }
292
- // STEP 1: Update product options FIRST to include all new values
293
- // This ensures option values exist before assigning them to variants
294
- const productsToUpdate = [];
295
- for (const productId of productIds) {
296
- const product = products?.find((p) => p.id === productId);
297
- if (!product)
298
- continue;
299
- // Get all existing variants for this product to preserve existing option values
300
- const { data: allVariants } = await query.graph({
301
- entity: "product_variant",
302
- fields: ["id", "options.*"],
303
- filters: {
304
- product_id: productId,
305
- },
306
- });
307
- // Collect unique option values from existing variants
308
- const productOptionsMap = new Map();
309
- // Map option_id -> canonical product option title
310
- const optionIdToTitle = new Map();
311
- const canonicalTitleByLower = new Map();
312
- for (const po of product.options || []) {
313
- if (po?.id && po?.title) {
314
- const t = String(po.title).trim();
315
- optionIdToTitle.set(po.id, t);
316
- canonicalTitleByLower.set(t.toLowerCase(), t);
317
- }
318
- }
319
- // First, collect from existing variants
320
- for (const variant of allVariants || []) {
321
- if (variant.options) {
322
- for (const opt of variant.options) {
323
- // Resolve canonical title: prefer option_id mapping, then normalize provided title
324
- let resolvedTitle = undefined;
325
- if (opt.option_id) {
326
- resolvedTitle = optionIdToTitle.get(opt.option_id);
327
- }
328
- if (!resolvedTitle && opt.title) {
329
- const t = String(opt.title).trim();
330
- resolvedTitle = canonicalTitleByLower.get(t.toLowerCase()) || t;
331
- }
332
- const value = opt.value ? String(opt.value).trim() : "";
333
- if (resolvedTitle && value) {
334
- if (!productOptionsMap.has(resolvedTitle)) {
335
- productOptionsMap.set(resolvedTitle, new Set());
336
- }
337
- productOptionsMap.get(resolvedTitle).add(value);
280
+ // Diamond Quality
281
+ if (detail.raw_type === "Diamond" &&
282
+ detail.tone_code &&
283
+ detail.qly_code &&
284
+ detail.is_base) {
285
+ const toneTitle = (masterMaps.toneMasterMap.get(detail.tone_code) ||
286
+ detail.tone_code).trim();
287
+ const qualityTitle = (masterMaps.qualityMasterMap.get(detail.qly_code) ||
288
+ detail.qly_code).trim();
289
+ const diamondValue = `${toneTitle} ${qualityTitle}`.trim();
290
+ const diamondOption = product.options?.find((opt) => opt.title === "Diamond Quality");
291
+ if (diamondOption) {
292
+ variantOptions["Diamond Quality"] = diamondValue;
293
+ if (!productOptionMap.has("Diamond Quality")) {
294
+ productOptionMap.set("Diamond Quality", new Set());
338
295
  }
296
+ productOptionMap.get("Diamond Quality").add(diamondValue);
339
297
  }
340
298
  }
341
- }
342
- // Then, merge in the new option values we'll be using
343
- const newValuesForProduct = newOptionValuesByProduct.get(productId);
344
- if (newValuesForProduct) {
345
- for (const [optionTitle, newValues,] of newValuesForProduct.entries()) {
346
- if (!productOptionsMap.has(optionTitle)) {
347
- productOptionsMap.set(optionTitle, new Set());
299
+ // Shape and Caret logic
300
+ if (isSolitaire &&
301
+ detail.raw_type === "Diamond" &&
302
+ detail.raw_code === "LGS" &&
303
+ detail.is_base) {
304
+ // Use the shape from the LGS base diamond detail
305
+ const shapeTitle = (masterMaps.shapeMasterMap.get(detail.shape_code) ||
306
+ String(detail.shape_code || "")).trim();
307
+ if (shapeTitle) {
308
+ const shapeOption = product.options?.find((opt) => opt.title === "Shape");
309
+ if (shapeOption) {
310
+ variantOptions["Shape"] = shapeTitle;
311
+ if (!productOptionMap.has("Shape")) {
312
+ productOptionMap.set("Shape", new Set());
313
+ }
314
+ productOptionMap.get("Shape").add(shapeTitle);
315
+ }
348
316
  }
349
- // Merge new values into existing set
350
- for (const value of newValues) {
351
- productOptionsMap.get(optionTitle).add(value.trim());
317
+ // Caret from detail weight
318
+ const weightStr = String(detail?.weight || "").trim();
319
+ if (weightStr) {
320
+ variantOptions["Caret"] = weightStr;
321
+ if (!productOptionMap.has("Caret")) {
322
+ productOptionMap.set("Caret", new Set());
323
+ }
324
+ productOptionMap.get("Caret").add(weightStr);
352
325
  }
353
326
  }
354
327
  }
355
- // Convert to options format, filtering out empty strings
356
- const productOptions = Array.from(productOptionsMap.entries())
357
- .map(([title, values]) => ({
358
- title,
359
- values: Array.from(values).filter((v) => v.length > 0),
360
- }))
361
- .filter((opt) => opt.values.length > 0); // Only include options with values
362
- productsToUpdate.push({
363
- product: {
364
- id: productId,
365
- options: productOptions,
366
- },
367
- });
368
328
  }
369
- // Update products FIRST
370
- if (productsToUpdate.length > 0) {
371
- logger.info(`------Updating ${productsToUpdate.length} products with new option values before variant update------`);
372
- await (0, core_flows_1.updateProductsWorkflow)(container).run({
373
- input: {
374
- products: productsToUpdate.map((p) => p.product),
375
- },
376
- });
377
- logger.info(`------Updated ${productsToUpdate.length} products for record ${record.id}------`);
329
+ // Sort variant options keys alphabetically for consistent ordering
330
+ const sortedVariantOptions = {};
331
+ const sortedKeys = Object.keys(variantOptions).sort((a, b) => a.localeCompare(b));
332
+ for (const key of sortedKeys) {
333
+ sortedVariantOptions[key] = variantOptions[key];
378
334
  }
379
- // STEP 2: Now update variants with the new option values
380
- // The option values now exist in the products, so this will succeed
381
- if (variantsToUpdate.length > 0) {
382
- logger.info(`------Updating ${variantsToUpdate.length} variants with new option values------`);
383
- await (0, core_flows_1.updateProductVariantsWorkflow)(container).run({
384
- input: {
385
- product_variants: variantsToUpdate.map((v) => v.variant),
386
- },
387
- });
388
- logger.info(`------Updated ${variantsToUpdate.length} variants for record ${record.id}------`);
389
- }
390
- // Mark record as completed
391
- await syncQueueService.updateVariantOptionSyncQueues([
392
- {
393
- id: record.id,
394
- status: "completed",
395
- affected_variant_count: affectedVariants.length,
396
- processed_at: new Date(),
335
+ variantsToUpdate.push({
336
+ variant: {
337
+ id: variant.id,
338
+ options: sortedVariantOptions,
397
339
  },
398
- ]);
399
- logger.info(`------Completed processing record ${record.id}: ${affectedVariants.length} variants affected------`);
340
+ });
400
341
  }
401
- catch (recordError) {
402
- const affectedVariants = await (0, variant_helper_1.findVariantsAffectedByMasterUpdate)(query, record.master_type, record.master_code);
403
- logger.error(`------Error processing record ${record.id}: ${recordError?.message}------ (affected variants: ${affectedVariants.length})`, recordError);
404
- // Mark record as failed
405
- await syncQueueService.updateVariantOptionSyncQueues([
406
- {
407
- id: record.id,
408
- status: "failed",
409
- error_message: recordError?.message || "Unknown error",
410
- affected_variant_count: affectedVariants.length,
411
- processed_at: new Date(),
342
+ // Update products for this batch FIRST
343
+ const productsToUpdate = Array.from(productOptionsMap.entries()).map(([productId, optionsMap]) => {
344
+ const options = Array.from(optionsMap.entries())
345
+ .sort(([titleA], [titleB]) => titleA.localeCompare(titleB)) // Sort option titles alphabetically
346
+ .map(([title, values]) => ({
347
+ title,
348
+ values: Array.from(values).sort((a, b) => a.localeCompare(b)), // Sort option values alphabetically
349
+ }));
350
+ return {
351
+ id: productId,
352
+ options,
353
+ };
354
+ });
355
+ if (productsToUpdate.length > 0) {
356
+ logger.info(`------Updating ${productsToUpdate.length} products in batch ${productBatchIndex + 1}------`);
357
+ await (0, core_flows_1.updateProductsWorkflow)(container).run({
358
+ input: {
359
+ products: productsToUpdate,
412
360
  },
413
- ]);
361
+ });
362
+ }
363
+ // Update all variants for this batch at once
364
+ if (variantsToUpdate.length > 0) {
365
+ logger.info(`------Updating ${variantsToUpdate.length} variants for product batch ${productBatchIndex + 1}------`);
366
+ await (0, core_flows_1.updateProductVariantsWorkflow)(container).run({
367
+ input: {
368
+ product_variants: variantsToUpdate.map((v) => v.variant),
369
+ },
370
+ });
371
+ logger.info(`------Completed variant updates for product batch ${productBatchIndex + 1}------`);
414
372
  }
415
373
  }
416
- logger.info("Variant option sync job completed");
374
+ logger.info(`------Completed processing all product batches------`);
375
+ // Final consistency check - recalculate product options from all updated variants
376
+ logger.info(`------Performing final consistency check for all ${productIds.length} products------`);
377
+ // Process final recalculation in batches
378
+ for (let productBatchIndex = 0; productBatchIndex < productBatches.length; productBatchIndex++) {
379
+ const productBatch = productBatches[productBatchIndex];
380
+ // Get all variants again after update to collect latest option values
381
+ const { data: updatedVariants } = await query.graph({
382
+ entity: "product_variant",
383
+ fields: ["id", "product_id", "options.*", "options.option.title"],
384
+ filters: {
385
+ product_id: productBatch,
386
+ },
387
+ });
388
+ // Group options by product_id, then by title within each product
389
+ const finalProductOptionsMap = new Map();
390
+ updatedVariants.forEach((variant) => {
391
+ const productId = variant.product_id;
392
+ if (!productId)
393
+ return;
394
+ if (!finalProductOptionsMap.has(productId)) {
395
+ finalProductOptionsMap.set(productId, new Map());
396
+ }
397
+ const optionsMap = finalProductOptionsMap.get(productId);
398
+ variant.options?.forEach((optionValue) => {
399
+ const title = optionValue.option?.title;
400
+ const value = optionValue.value;
401
+ if (title && value) {
402
+ if (!optionsMap.has(title)) {
403
+ optionsMap.set(title, new Set());
404
+ }
405
+ optionsMap.get(title).add(value);
406
+ }
407
+ });
408
+ });
409
+ // Convert to products array format for final update
410
+ const finalProductsToUpdate = Array.from(finalProductOptionsMap.entries()).map(([productId, optionsMap]) => {
411
+ const options = Array.from(optionsMap.entries())
412
+ .sort(([titleA], [titleB]) => titleA.localeCompare(titleB)) // Sort option titles alphabetically
413
+ .map(([title, values]) => ({
414
+ title,
415
+ values: Array.from(values).sort((a, b) => a.localeCompare(b)), // Sort option values alphabetically
416
+ }));
417
+ return {
418
+ id: productId,
419
+ options,
420
+ };
421
+ });
422
+ // Final update of products with all option values from updated variants
423
+ if (finalProductsToUpdate.length > 0) {
424
+ logger.info(`------Final update of ${finalProductsToUpdate.length} products in batch ${productBatchIndex + 1}------`);
425
+ await (0, core_flows_1.updateProductsWorkflow)(container).run({
426
+ input: {
427
+ products: finalProductsToUpdate,
428
+ },
429
+ });
430
+ }
431
+ }
432
+ logger.info(`------Final consistency check completed for all products------`);
433
+ // STEP 7: Mark all records as completed
434
+ const recordsToComplete = [];
435
+ for (const record of pendingRecords) {
436
+ const recordData = recordAffectedVariantsMap.get(record.id);
437
+ const affectedCount = recordData?.affectedVariants.length || 0;
438
+ recordsToComplete.push({
439
+ id: record.id,
440
+ status: "completed",
441
+ affected_variant_count: affectedCount,
442
+ processed_at: new Date(),
443
+ });
444
+ }
445
+ await syncQueueService.updateVariantOptionSyncQueues(recordsToComplete);
446
+ logger.info(`------Completed processing ${pendingRecords.length} records------`);
447
+ logger.info("------Variant option sync job completed------");
417
448
  }
418
449
  catch (error) {
419
- logger.error("Error in variant option sync job:", error);
450
+ logger.error("------Error in variant option sync job:------", error);
451
+ // Mark all records as failed
452
+ try {
453
+ await syncQueueService.updateVariantOptionSyncQueues(pendingRecords.map((r) => ({
454
+ id: r.id,
455
+ status: "failed",
456
+ error_message: error?.message || "Unknown error",
457
+ processed_at: new Date(),
458
+ })));
459
+ }
460
+ catch (updateError) {
461
+ logger.error("------Error marking records as failed:------", updateError);
462
+ }
420
463
  throw error;
421
464
  }
422
465
  }
423
466
  exports.config = {
424
467
  name: "process-variant-option-sync",
425
- // schedule: "0 3 * * *", // At 3:00 AM every day
426
468
  schedule: "*/30 * * * *", // Every 30 minutes
469
+ // schedule: "0 3 * * *", // Every day at 3:00 AM
427
470
  };
428
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvY2Vzcy12YXJpYW50LW9wdGlvbi1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2pvYnMvcHJvY2Vzcy12YXJpYW50LW9wdGlvbi1zeW5jLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTBCQSwyQ0FvaUJDO0FBN2pCRCxxREFBc0U7QUFDdEUsNERBR3FDO0FBRXJDLG9GQUF3RjtBQUN4Rix3RUFHNkM7QUFHN0M7Ozs7Ozs7Ozs7O0lBV0k7QUFDVyxLQUFLLFVBQVUsd0JBQXdCLENBQ3BELFNBQTBCO0lBRTFCLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakUsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuRSxNQUFNLGdCQUFnQixHQUFrQyxTQUFTLENBQUMsT0FBTyxDQUN2RSw0REFBZ0MsQ0FDakMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxJQUFJLENBQUMsOENBQThDLENBQUMsQ0FBQztJQUU1RCxJQUFJLENBQUM7UUFDSCxxQ0FBcUM7UUFDckMsTUFBTSxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7WUFDakQsTUFBTSxFQUFFLDJCQUEyQjtZQUNuQyxNQUFNLEVBQUU7Z0JBQ04sSUFBSTtnQkFDSixhQUFhO2dCQUNiLGFBQWE7Z0JBQ2IsV0FBVztnQkFDWCxXQUFXO2dCQUNYLFdBQVc7YUFDWjtZQUNELE9BQU8sRUFBRTtnQkFDUCxNQUFNLEVBQUUsU0FBUzthQUNsQjtZQUNELFVBQVUsRUFBRTtnQkFDVixJQUFJLEVBQUUsRUFBRSxFQUFFLCtCQUErQjthQUMxQztTQUNGLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZ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
471
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvY2Vzcy12YXJpYW50LW9wdGlvbi1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2pvYnMvcHJvY2Vzcy12YXJpYW50LW9wdGlvbi1zeW5jLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTBCQSwyQ0FnbkJDO0FBem9CRCxxREFBc0U7QUFDdEUsNERBR3FDO0FBRXJDLG9GQUF3RjtBQUN4Rix3RUFHNkM7QUFHN0M7Ozs7Ozs7Ozs7O0lBV0k7QUFDVyxLQUFLLFVBQVUsd0JBQXdCLENBQ3BELFNBQTBCO0lBRTFCLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakUsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuRSxNQUFNLGdCQUFnQixHQUFrQyxTQUFTLENBQUMsT0FBTyxDQUN2RSw0REFBZ0MsQ0FDakMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxJQUFJLENBQUMsOENBQThDLENBQUMsQ0FBQztJQUU1RCxJQUFJLGNBQWMsR0FBVSxFQUFFLENBQUM7SUFFL0IsSUFBSSxDQUFDO1FBQ0gscUNBQXFDO1FBQ3JDLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQzFDLE1BQU0sRUFBRSwyQkFBMkI7WUFDbkMsTUFBTSxFQUFFO2dCQUNOLElBQUk7Z0JBQ0osYUFBYTtnQkFDYixhQUFhO2dCQUNiLFdBQVc7Z0JBQ1gsV0FBVztnQkFDWCxXQUFXO2FBQ1o7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsTUFBTSxFQUFFLFNBQVM7YUFDbEI7WUFDRCxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFLEVBQUUsRUFBRSwrQkFBK0I7YUFDMUM7U0FDRixDQUFDLENBQUM7UUFFSCxjQUFjLEdBQUcsT0FBTyxJQUFJLEVBQUUs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