tango-app-api-store-builder 1.1.6 → 1.1.7

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.
@@ -1,10 +1 @@
1
- [
2
- {
3
- "storeName": "LKST2235",
4
- "header": "Lenskart"
5
- },
6
- {
7
- "storeName": "LKST2571",
8
- "header": "Aqualens"
9
- }
10
- ]
1
+ []
@@ -2248,7 +2248,7 @@
2248
2248
  {
2249
2249
  "Header": "Work Essentials",
2250
2250
  "Top": "VC/Studio Non Metals",
2251
- "Mid": "Air PIDs",
2251
+ "Mid": "Air PIDs + Air Pids PIDs",
2252
2252
  "Bottom": "VC/Studio Full Rim Metals & HR &RL"
2253
2253
  }
2254
2254
  ]
@@ -2265,7 +2265,7 @@
2265
2265
  },
2266
2266
  {
2267
2267
  "Header": "Work Essentials",
2268
- "Top": "Air PIDs",
2268
+ "Top": "Air PIDs + Air Pids PIDs",
2269
2269
  "Mid": "VC Eye Full Rim Metals",
2270
2270
  "Bottom": "HR & RL"
2271
2271
  }
@@ -2284,7 +2284,7 @@
2284
2284
  {
2285
2285
  "Header": "Work Essentials",
2286
2286
  "Top": "VC Eye Acetate",
2287
- "Mid": "Air PIDs",
2287
+ "Mid": "Air PIDs + Air Pids PIDs",
2288
2288
  "Bottom": "Air PIDs"
2289
2289
  },
2290
2290
  {
@@ -5850,13 +5850,6 @@
5850
5850
  "Top panel": "Make every look extraordinary",
5851
5851
  "1X3 talker": "Bold acetate"
5852
5852
  },
5853
- {
5854
- "Header": "Trending",
5855
- "Fixture": "Trending 3",
5856
- "PID Allocation": "Studio eye + sun",
5857
- "Top panel": "Dark Knight",
5858
- "1X3 talker": "Dark Knight"
5859
- },
5860
5853
  {
5861
5854
  "Header": "Work essentials",
5862
5855
  "Fixture": "Air 1",
@@ -5899,20 +5892,6 @@
5899
5892
  "Top panel": "Barely there perfectly present",
5900
5893
  "1X3 talker": "Half rim and rimless 2"
5901
5894
  },
5902
- {
5903
- "Header": "Work essentials",
5904
- "Fixture": "Work essentials 1",
5905
- "PID Allocation": "LK AIR Switch",
5906
- "Top panel": "Specs to sunnies. Sunnies to specs",
5907
- "1X3 talker": "Switch"
5908
- },
5909
- {
5910
- "Header": "Work essentials",
5911
- "Fixture": "Work essentials 1",
5912
- "PID Allocation": "LK air switch",
5913
- "Top panel": "Specs to sunnies. Sunnies to specs",
5914
- "1X3 talker": "Switch"
5915
- },
5916
5895
  {
5917
5896
  "Header": "Innovation",
5918
5897
  "Fixture": "Innovation",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-store-builder",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "storeBuilder",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -33,7 +33,7 @@
33
33
  "path": "^0.12.7",
34
34
  "selenium-webdriver": "^4.31.0",
35
35
  "sharp": "^0.34.1",
36
- "tango-api-schema": "^2.5.45",
36
+ "tango-api-schema": "^2.5.41",
37
37
  "tango-app-api-middleware": "3.1.48",
38
38
  "url": "^0.11.4",
39
39
  "winston": "^3.17.0",
@@ -4229,13 +4229,13 @@ export async function updateTemplateGroup() {
4229
4229
  );
4230
4230
 
4231
4231
 
4232
- const fixture = storeFixtures.find( ( fixture ) => fixture.templateGroupName === 'JJ Sun' );
4232
+ const fixture = storeFixtures.find( ( fixture ) => fixture.header.label === 'JJ Sun' );
4233
4233
 
4234
4234
  if ( !fixture ) {
4235
4235
  continue;
4236
4236
  }
4237
4237
 
4238
- fixture.templateGroupName = 'Meller';
4238
+ fixture.header.label = 'Meller';
4239
4239
 
4240
4240
  await updateFixtures( [ fixture ] );
4241
4241
  console.log( `Updated store: ${store} ${fixture.fixtureType}` );
@@ -4243,579 +4243,3 @@ export async function updateTemplateGroup() {
4243
4243
  }
4244
4244
 
4245
4245
  // updateTemplateGroup();
4246
-
4247
- async function updateKpopNunNCollection() {
4248
- const workbook = xlsx.readFile( './data/Lenskart Offline New launches VM Placement.xlsx' );
4249
-
4250
- const sheetName = 'KPOP (NunN)';
4251
- const sheet = workbook.Sheets[sheetName];
4252
-
4253
- if ( !sheet ) {
4254
- console.error( `Sheet "${sheetName}" not found in workbook` );
4255
- return;
4256
- }
4257
-
4258
- const JsonData = xlsx.utils.sheet_to_json( sheet );
4259
- const data = JSON.parse( JSON.stringify( JsonData, null, 2 ) );
4260
-
4261
- const sortFunc = ( groupFixtures ) => {
4262
- const sortRules = {
4263
- 5: 'desc',
4264
- 1: 'asc',
4265
- 2: 'asc',
4266
- 3: 'asc',
4267
- 4: 'desc',
4268
- floor: 'asc',
4269
- };
4270
-
4271
- const staticOrder = [ '5', '1', '2', '4', '3', 'floor' ];
4272
-
4273
- return groupFixtures.sort( ( a, b ) => {
4274
- const wallA = a.associatedElementNumber !== undefined ? String( a.associatedElementNumber ) : 'floor';
4275
- const wallB = b.associatedElementNumber !== undefined ? String( b.associatedElementNumber ) : 'floor';
4276
-
4277
- // Step 1: enforce static wall order
4278
- if ( wallA !== wallB ) {
4279
- return staticOrder.indexOf( wallA ) - staticOrder.indexOf( wallB );
4280
- }
4281
-
4282
- // Step 2: same wall/floor → apply rule
4283
- const rule = sortRules[wallA];
4284
- const fixtureA = a.associatedElementFixtureNumber;
4285
- const fixtureB = b.associatedElementFixtureNumber;
4286
-
4287
- return rule === 'asc' ?
4288
- fixtureA - fixtureB :
4289
- fixtureB - fixtureA;
4290
- } );
4291
- };
4292
-
4293
- async function getFixtures( query ) {
4294
- let fixtures = await storeFixtureService.find( query );
4295
-
4296
- fixtures = fixtures.map( ( fixture ) => fixture.toObject() );
4297
-
4298
- const fixturesWithShelvesAndVms = await Promise.all(
4299
- fixtures.map( async ( fixture ) => {
4300
- const shelves = await fixtureShelfService.findAndSort( { fixtureId: fixture._id }, { }, { shelfNumber: 1 } );
4301
-
4302
- const shelfDetails = await Promise.all(
4303
- shelves.map( async ( shelf ) => {
4304
- return shelf.toObject();
4305
- } ),
4306
- );
4307
-
4308
-
4309
- const vmDetails = await Promise.all( fixture?.vmConfig?.map( async ( vm ) => {
4310
- const vmInfo = await planoVmService.findOne( { _id: vm.vmId } );
4311
- return {
4312
- ...vm,
4313
- ...vmInfo?.toObject(),
4314
- };
4315
- } ) );
4316
-
4317
- return {
4318
- ...fixture,
4319
- shelfConfig: shelfDetails,
4320
- vmConfig: vmDetails,
4321
- };
4322
- } ),
4323
- );
4324
-
4325
- return fixturesWithShelvesAndVms;
4326
- };
4327
-
4328
- async function updateFixtures( fixtures = [] ) {
4329
- for ( let i = 0; i < fixtures.length; i++ ) {
4330
- const fixture = fixtures[i];
4331
- if ( !fixture ) {
4332
- continue;
4333
- }
4334
-
4335
- const fixtureId = fixture._id;
4336
- delete fixture._id;
4337
-
4338
- const fixtureBrands = new Set();
4339
-
4340
- await Promise.all( fixture.shelfConfig.map( async ( shelf ) => {
4341
- const shelfId = shelf._id;
4342
- delete shelf._id;
4343
- shelf.productBrandName.forEach( ( brand ) => fixtureBrands.add( brand ) );
4344
- return await fixtureShelfService.updateOne( { _id: shelfId }, shelf );
4345
- } ) );
4346
-
4347
- fixture.productBrandName = [ ...fixtureBrands ];
4348
-
4349
- const vmConfig = await Promise.all( fixture.vmConfig.map( async ( vm ) => {
4350
- let isVmExist = await planoVmService.findOne( { vmName: vm.vmName } );
4351
-
4352
- if ( !isVmExist ) {
4353
- const updateData = {
4354
- 'vmName': vm.vmName,
4355
- 'clientId': '11',
4356
- 'status': 'complete',
4357
- 'vmHeight': {
4358
- 'value': 100,
4359
- 'unit': 'mm',
4360
- },
4361
- 'vmType': 'LKVM',
4362
- 'vmWidth': {
4363
- 'value': 230,
4364
- 'unit': 'mm',
4365
- },
4366
- };
4367
-
4368
- isVmExist = await planoVmService.create( updateData );
4369
- }
4370
-
4371
- return { vmId: isVmExist._id, ...vm };
4372
- } ) );
4373
-
4374
- fixture.vmConfig = vmConfig;
4375
- delete fixture.shelfConfig;
4376
-
4377
- await storeFixtureService.updateOne( { _id: fixtureId }, fixture );
4378
- }
4379
- }
4380
-
4381
- const checkVmExistInFixtures = ( fixtures, vmName ) => {
4382
- if ( !vmName || !Array.isArray( fixtures ) ) return false;
4383
-
4384
- const normalizedName = vmName.replace( /\s+/g, '' ).toLowerCase();
4385
-
4386
- return fixtures.some( ( fixture ) =>
4387
- Array.isArray( fixture?.vmConfig ) &&
4388
- fixture.vmConfig.some( ( vm ) => {
4389
- if ( !vm.vmName ) return false;
4390
- const normalizedFixtureVm = vm.vmName.replace( /\s+/g, '' ).toLowerCase();
4391
- return normalizedFixtureVm.includes( normalizedName );
4392
- } ),
4393
- );
4394
- };
4395
-
4396
- const checkBrandExistInShelves = ( fixtures, brandName ) => {
4397
- if ( !brandName || !Array.isArray( fixtures ) ) return false;
4398
-
4399
- const normalizedBrand = brandName.replace( /\s+/g, '' ).toLowerCase();
4400
-
4401
- return fixtures.some( ( fixture ) =>
4402
- Array.isArray( fixture.shelfConfig ) &&
4403
- fixture.shelfConfig.some( ( shelf ) =>
4404
- Array.isArray( shelf.productBrandName ) &&
4405
- shelf.productBrandName.some( ( name ) =>
4406
- name.replace( /\s+/g, '' ).toLowerCase().includes( normalizedBrand ),
4407
- ),
4408
- ),
4409
- );
4410
- };
4411
-
4412
- const writeLog = ( logData, path ) => {
4413
- let logs = [];
4414
-
4415
- try {
4416
- const fileContent = fs.readFileSync( path, "utf8" );
4417
- logs = JSON.parse( fileContent );
4418
-
4419
- if ( !Array.isArray( logs ) ) {
4420
- logs = [];
4421
- }
4422
- } catch ( err ) {
4423
- logs = [];
4424
- }
4425
-
4426
- logs.push( logData );
4427
-
4428
- fs.writeFileSync( path, JSON.stringify( logs, null, 2 ) );
4429
- };
4430
-
4431
- // Handle Tentpole Euro Centers: Replace Hip Hop with KPOP (NuuN), If Hip Hop not found then Replace Bidri, If both not found, then replace existing VM on first Tentpole Euro Centers
4432
- async function handleTentpoleEuroCenters( fixtures, store ) {
4433
- // Filter fixtures that match "Tentpole" OR "VC Eye / LK Air"
4434
- let matchingFixtures = fixtures.filter( ( fixture ) => {
4435
- const rawLabel = fixture.header?.label;
4436
- const label = rawLabel ? rawLabel.replace( /\s+/g, " " ).trim() : "";
4437
-
4438
- const rawDescription = fixture.description;
4439
- const description = rawDescription ? rawDescription.replace( /\s+/g, " " ).trim() : "";
4440
-
4441
- // Check label match
4442
- const labelMatch =
4443
- label === "Tentpole" ||
4444
- label === "VC Eye / LK Air" ||
4445
- label.toLowerCase().includes( "tentpole" ) ||
4446
- label.toLowerCase().includes( "vc eye" ) ||
4447
- label.toLowerCase().includes( "lk air" );
4448
-
4449
- // Check description only if label does NOT exist
4450
- const descriptionMatch =
4451
- ( !label || label.length === 0 ) &&
4452
- ( description === "Tentpole" ||
4453
- description === "VC Eye / LK Air" ||
4454
- description.toLowerCase().includes( "tentpole" ) ||
4455
- description.toLowerCase().includes( "vc eye" ) ||
4456
- description.toLowerCase().includes( "lk air" ) );
4457
-
4458
- return labelMatch || descriptionMatch;
4459
- } );
4460
-
4461
- if ( matchingFixtures.length === 0 ) {
4462
- const logData = {
4463
- store: store?.['Store Code'],
4464
- condition: store?.['Placement'],
4465
- exception: store?.['Exceptions'],
4466
- };
4467
- writeLog( logData, './data/kpop_nunn_update_fails.json' );
4468
- return;
4469
- }
4470
-
4471
- // Check for VM exceptions on all filtered fixtures
4472
- // Priority: 1. Tentpole fixture (if found, use it regardless of Hip Hop or Bidri), 2. Hip Hop, 3. Bidri, 4. Any other fixture
4473
- let tentpoleFixture = matchingFixtures.find( ( fixture ) => {
4474
- const rawLabel = fixture.header?.label;
4475
- const label = rawLabel ? rawLabel.replace( /\s+/g, " " ).trim() : "";
4476
- const rawDescription = fixture.description;
4477
- const description = rawDescription ? rawDescription.replace( /\s+/g, " " ).trim() : "";
4478
-
4479
- // Check if it's a Tentpole fixture (label or description)
4480
- const isTentpole = label === "Tentpole" ||
4481
- label.toLowerCase().includes( "tentpole" ) ||
4482
- ( ( !label || label.length === 0 ) &&
4483
- ( description === "Tentpole" || description.toLowerCase().includes( "tentpole" ) ) );
4484
-
4485
- return isTentpole;
4486
- } );
4487
-
4488
- if ( !tentpoleFixture ) {
4489
- // If no Tentpole found, look for Hip Hop
4490
- tentpoleFixture = matchingFixtures.find( ( fixture ) => {
4491
- return checkVmExistInFixtures( [ fixture ], 'Hip Hop' ) || checkVmExistInFixtures( [ fixture ], 'Hiphop' );
4492
- } );
4493
- }
4494
-
4495
- if ( !tentpoleFixture ) {
4496
- // If no Hip Hop found, look for Bidri
4497
- tentpoleFixture = matchingFixtures.find( ( fixture ) => {
4498
- return checkVmExistInFixtures( [ fixture ], 'Bidri' );
4499
- } );
4500
- }
4501
-
4502
- if ( !tentpoleFixture ) {
4503
- // If none of the above found, use the first matching fixture
4504
- tentpoleFixture = matchingFixtures[0];
4505
- }
4506
-
4507
- // Check if Hip Hop exists on the selected fixture
4508
- const hasHipHop = checkVmExistInFixtures( [ tentpoleFixture ], 'Hip Hop' ) || checkVmExistInFixtures( [ tentpoleFixture ], 'Hiphop' );
4509
- // Check if Bidri exists on the selected fixture
4510
- const hasBidri = checkVmExistInFixtures( [ tentpoleFixture ], 'Bidri' );
4511
-
4512
- // Calculate shelf count for L-shaped VM configuration
4513
- const shelfCount = tentpoleFixture.shelfConfig?.length || 4;
4514
- const verticalEndPosition = Math.max( 1, shelfCount - 1 ); // Vertical part covers shelves 1 to (shelfCount - 1)
4515
- const horizontalPosition = shelfCount; // Horizontal part covers the last shelf
4516
-
4517
- // Create KPOP (NuuN) VM data in L-shape: two VMs
4518
- const kpopVmConfig = [
4519
- {
4520
- vmName: 'KPOP (NuuN) - 1',
4521
- startYPosition: 1,
4522
- endYPosition: verticalEndPosition,
4523
- xZone: 'left',
4524
- yZone: 'stretch',
4525
- },
4526
- {
4527
- vmName: 'KPOP (NuuN) - 2',
4528
- startYPosition: horizontalPosition,
4529
- endYPosition: horizontalPosition,
4530
- xZone: 'stretch',
4531
- yZone: 'stretch',
4532
- },
4533
- ];
4534
-
4535
- if ( hasHipHop ) {
4536
- // Replace Hip Hop VM
4537
- tentpoleFixture.vmConfig = tentpoleFixture.vmConfig.filter( ( vm ) => {
4538
- const normalizedVm = vm.vmName?.replace( /\s+/g, '' ).toLowerCase() || '';
4539
- return !normalizedVm.includes( 'hiphop' ) && !normalizedVm.includes( 'hip hop' );
4540
- } );
4541
- tentpoleFixture.vmConfig.push( ...kpopVmConfig );
4542
- } else if ( hasBidri ) {
4543
- // Replace Bidri VM
4544
- tentpoleFixture.vmConfig = tentpoleFixture.vmConfig.filter( ( vm ) => {
4545
- const normalizedVm = vm.vmName?.replace( /\s+/g, '' ).toLowerCase() || '';
4546
- return !normalizedVm.includes( 'bidri' );
4547
- } );
4548
- tentpoleFixture.vmConfig.push( ...kpopVmConfig );
4549
- } else {
4550
- // Replace existing VM on first Tentpole Euro Centers
4551
- tentpoleFixture.vmConfig = kpopVmConfig;
4552
- }
4553
-
4554
- // Update productBrandName for all shelves to "KPOP (NunN)"
4555
- tentpoleFixture.shelfConfig.forEach( ( shelf ) => {
4556
- shelf.productBrandName = [ 'KPOP (NunN)' ];
4557
- } );
4558
-
4559
- await updateFixtures( [ tentpoleFixture ] );
4560
- }
4561
-
4562
- // Handle Non IVM Wall Talker: First VC Eye+LK Air Eye Fixtures-Mid Zone
4563
- // Exception: If First Fixture is Sale/Almost Gone Fixture/Mid Zone is allocated Hustlr VM/Phonic Full VM then move to Second fixture
4564
- async function handleNonIvmWallTalker( fixtures, store ) {
4565
- let vcLkFixtures = fixtures.filter( ( fixture ) =>
4566
- fixture.header?.label === 'VC Eye / LK Air' || fixture.header?.label?.toLowerCase().includes( 'vc eye' ) || fixture.header?.label?.toLowerCase().includes( 'lk air' ),
4567
- );
4568
-
4569
- if ( vcLkFixtures.length === 0 ) {
4570
- const logData = {
4571
- store: store?.['Store Code'],
4572
- condition: store?.['Placement'],
4573
- exception: store?.['Exceptions'],
4574
- };
4575
- writeLog( logData, './data/kpop_nunn_update_fails.json' );
4576
- return;
4577
- }
4578
-
4579
- let targetFixture = vcLkFixtures[0];
4580
-
4581
- // Check if first fixture should be skipped
4582
- const hasSaleOrAlmostGone =
4583
- checkVmExistInFixtures( [ targetFixture ], 'All Styles at Rs 800' ) ||
4584
- checkVmExistInFixtures( [ targetFixture ], 'Almost Gone' ) ||
4585
- checkBrandExistInShelves( [ targetFixture ], 'discounted' );
4586
-
4587
- // Check if Mid Zone is allocated to Hustlr VM or Phonic Full VM
4588
- const firstFixtureMidShelves = targetFixture.shelfConfig?.filter( ( shelf ) => shelf.zone === 'Mid' ) || [];
4589
- const firstFixtureMidShelfNumbers = new Set( firstFixtureMidShelves.map( ( shelf ) => shelf.shelfNumber ) );
4590
- const midZoneVms = targetFixture.vmConfig?.filter( ( vm ) => firstFixtureMidShelfNumbers.has( vm.startYPosition ) ) || [];
4591
- const hasHustlrOrPhonicInMid = midZoneVms.some( ( vm ) => {
4592
- const normalizedVm = vm.vmName?.replace( /\s+/g, '' ).toLowerCase() || '';
4593
- return normalizedVm.includes( 'hustlr' ) || normalizedVm.includes( 'phonic' );
4594
- } );
4595
-
4596
- const shouldSkipFirst = hasSaleOrAlmostGone || hasHustlrOrPhonicInMid ||
4597
- checkVmExistInFixtures( [ targetFixture ], 'Hustlr' ) ||
4598
- checkVmExistInFixtures( [ targetFixture ], 'Phonic' ) ||
4599
- checkVmExistInFixtures( [ targetFixture ], 'Phonic Full VM' );
4600
-
4601
- if ( shouldSkipFirst && vcLkFixtures.length > 1 ) {
4602
- targetFixture = vcLkFixtures[1];
4603
- }
4604
-
4605
- if ( !targetFixture ) {
4606
- const logData = {
4607
- store: store?.['Store Code'],
4608
- condition: store?.['Placement'],
4609
- exception: store?.['Exceptions'],
4610
- };
4611
- writeLog( logData, './data/kpop_nunn_update_fails.json' );
4612
- return;
4613
- }
4614
-
4615
- // Recalculate midShelves for the selected fixture (might be second fixture)
4616
- const midShelves = targetFixture.shelfConfig?.filter( ( shelf ) => shelf.zone === 'Mid' ).sort( ( a, b ) => a.shelfNumber - b.shelfNumber );
4617
-
4618
- if ( !midShelves || midShelves.length === 0 ) {
4619
- const logData = {
4620
- store: store?.['Store Code'],
4621
- condition: store?.['Placement'],
4622
- exception: store?.['Exceptions'],
4623
- };
4624
- writeLog( logData, './data/kpop_nunn_update_fails.json' );
4625
- return;
4626
- }
4627
-
4628
- const midShelfNumbers = new Set( midShelves.map( ( shelf ) => shelf.shelfNumber ) );
4629
- const existingVms = targetFixture.vmConfig?.filter( ( vm ) => !midShelfNumbers.has( vm.startYPosition ) ) || [];
4630
-
4631
- // Calculate middle shelf of mid shelves
4632
- let midShelfNumber;
4633
- if ( midShelves.length % 2 !== 0 ) {
4634
- // Odd number of mid shelves: use the middle one
4635
- midShelfNumber = midShelves[Math.floor( midShelves.length / 2 )].shelfNumber;
4636
- } else {
4637
- // Even number of mid shelves: use the lower middle one
4638
- midShelfNumber = midShelves[midShelves.length / 2 - 1].shelfNumber;
4639
- }
4640
-
4641
- const kpopVmData = {
4642
- vmName: 'KPOP (NuuN)',
4643
- startYPosition: midShelfNumber,
4644
- endYPosition: midShelfNumber,
4645
- xZone: 'left',
4646
- yZone: 'stretch',
4647
- };
4648
-
4649
- existingVms.push( kpopVmData );
4650
- targetFixture.vmConfig = existingVms;
4651
-
4652
- // Update productBrandName for mid zone shelves to "KPOP (NunN)"
4653
- targetFixture.shelfConfig.forEach( ( shelf ) => {
4654
- if ( shelf.zone === 'Mid' ) {
4655
- shelf.productBrandName = [ 'KPOP (NunN)' ];
4656
- }
4657
- } );
4658
-
4659
- await updateFixtures( [ targetFixture ] );
4660
- }
4661
-
4662
- // Handle IVM Top Masking: First Trending Fixtures
4663
- // Exception: If first Fixture is Sale/Almost Gone then move to Second fixture
4664
- async function handleIvmTopMasking( fixtures, store ) {
4665
- let trendingFixtures = fixtures.filter( ( fixture ) =>
4666
- fixture.header?.label === 'Trending' ||
4667
- fixture.header?.label === 'Trending 1' ||
4668
- fixture.header?.label === 'Trending 2' ||
4669
- fixture.header?.label === 'Trending 3' ||
4670
- fixture.header?.label === 'Trending 4' );
4671
-
4672
- if ( trendingFixtures.length === 0 ) {
4673
- const logData = {
4674
- store: store?.['Store Code'],
4675
- condition: store?.['Placement'],
4676
- exception: store?.['Exceptions'],
4677
- };
4678
- writeLog( logData, './data/kpop_nunn_update_fails.json' );
4679
- return;
4680
- }
4681
-
4682
- let targetFixture = trendingFixtures[0];
4683
-
4684
- // Check if first fixture should be skipped
4685
- const shouldSkipFirst =
4686
- checkVmExistInFixtures( [ targetFixture ], 'All Styles at Rs 800' ) ||
4687
- checkVmExistInFixtures( [ targetFixture ], 'Almost Gone' ) ||
4688
- checkBrandExistInShelves( [ targetFixture ], 'discounted' );
4689
-
4690
- if ( shouldSkipFirst && trendingFixtures.length > 1 ) {
4691
- targetFixture = trendingFixtures[1];
4692
- }
4693
-
4694
- if ( !targetFixture ) {
4695
- const logData = {
4696
- store: store?.['Store Code'],
4697
- condition: store?.['Placement'],
4698
- exception: store?.['Exceptions'],
4699
- };
4700
- writeLog( logData, './data/kpop_nunn_update_fails.json' );
4701
- return;
4702
- }
4703
-
4704
- const topShelves = targetFixture.shelfConfig?.filter( ( shelf ) => shelf.zone === 'Top' ).sort( ( a, b ) => a.shelfNumber - b.shelfNumber );
4705
-
4706
- if ( !topShelves || topShelves.length === 0 ) {
4707
- const logData = {
4708
- store: store?.['Store Code'],
4709
- condition: store?.['Placement'],
4710
- exception: store?.['Exceptions'],
4711
- };
4712
- writeLog( logData, './data/kpop_nunn_update_fails.json' );
4713
- return;
4714
- }
4715
-
4716
- const topShelfNumbers = new Set( topShelves.map( ( shelf ) => shelf.shelfNumber ) );
4717
- const existingVms = targetFixture.vmConfig?.filter( ( vm ) => !topShelfNumbers.has( vm.startYPosition ) ) || [];
4718
-
4719
- const topShelfNumber = topShelves[0].shelfNumber;
4720
- const kpopVmData = {
4721
- vmName: 'KPOP (NuuN)',
4722
- startYPosition: topShelfNumber,
4723
- endYPosition: topShelfNumber,
4724
- xZone: 'stretch',
4725
- yZone: 'stretch',
4726
- };
4727
-
4728
- existingVms.push( kpopVmData );
4729
- targetFixture.vmConfig = existingVms;
4730
-
4731
- // Update productBrandName for top zone shelves to "KPOP (NunN)"
4732
- targetFixture.shelfConfig.forEach( ( shelf ) => {
4733
- if ( shelf.zone === 'Top' ) {
4734
- shelf.productBrandName = [ 'KPOP (NunN)' ];
4735
- }
4736
- } );
4737
-
4738
- await updateFixtures( [ targetFixture ] );
4739
- }
4740
-
4741
-
4742
- // Main processing loop
4743
- for ( let i = 0; i < data.length; i++ ) {
4744
- const store = data[i];
4745
- if ( ![
4746
- "LKST1414",
4747
- "LKST986",
4748
- "LKST1540",
4749
- "LKST1060",
4750
- "LKST1599",
4751
- "LKST1454",
4752
- "LKST1424",
4753
- "LKST154",
4754
- "LKST1025",
4755
- "LKST1086",
4756
- "LKST162",
4757
- "LKST1043",
4758
- "LKST1969",
4759
- "LKST647",
4760
- "LKST1384",
4761
- "LKST788",
4762
- "LKST994",
4763
- "LKST1416",
4764
- "LKST1161",
4765
- "LKST214",
4766
- "LKST246",
4767
- "LKST1535",
4768
- "ST200",
4769
- "LKST127",
4770
- "LKST782",
4771
- "LKST110",
4772
- "LKST1122",
4773
- "LKST191",
4774
- "LKST1084",
4775
- "LKST993",
4776
- "LKST739",
4777
- "LKST1115",
4778
- "LKST953",
4779
- ].includes( store?.['Store Code'] ) ) continue;
4780
- const storePlano = await planoService.findOne( { storeName: store?.['Store Code'] } );
4781
-
4782
- if ( !storePlano ) {
4783
- console.log( `Planogram not found for store: ${store?.['Store Code']}` );
4784
- continue;
4785
- }
4786
-
4787
- let storeFixtures = await getFixtures( { planoId: storePlano._id } );
4788
- storeFixtures = sortFunc( storeFixtures );
4789
-
4790
- const wallFixtures = storeFixtures.filter(
4791
- ( f ) => f.associatedElementType !== undefined && f.associatedElementNumber !== undefined,
4792
- );
4793
-
4794
- const floorFixtures = storeFixtures.filter(
4795
- ( f ) => f.associatedElementType === undefined && f.associatedElementNumber === undefined,
4796
- );
4797
-
4798
- const placement = store?.['Placement'];
4799
-
4800
- // Use only Placement column to determine handler
4801
- if ( placement === 'First Tentpole Euro Centers' ) {
4802
- await handleTentpoleEuroCenters( floorFixtures, store );
4803
- } else if ( placement === 'First VC Eye+LK Air Eye Fixtures-Mid Zone' ) {
4804
- // This placement is used for both Non IVM Wall Talker and Wynk Store
4805
- // Both have similar logic, using handleNonIvmWallTalker
4806
- await handleNonIvmWallTalker( wallFixtures, store );
4807
- } else if ( placement === 'First Trending Fixtures' ) {
4808
- // This placement is used for both IVM Top Masking and Mega Store
4809
- // Both have similar logic, using handleIvmTopMasking
4810
- await handleIvmTopMasking( wallFixtures, store );
4811
- }
4812
-
4813
- console.log( `Processed store: ${store?.['Store Code']}` );
4814
- }
4815
-
4816
- console.log( 'KPOP (NunN) collection update completed' );
4817
- }
4818
-
4819
- // updateKpopNunNCollection();
4820
-
4821
-