tango-app-api-store-builder 1.0.0-beta-42 → 1.0.0-beta-44

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-store-builder",
3
- "version": "1.0.0-beta-42",
3
+ "version": "1.0.0-beta-44",
4
4
  "description": "storeBuilder",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,7 +23,7 @@
23
23
  "joi": "^17.13.3",
24
24
  "mongodb": "^6.12.0",
25
25
  "nodemon": "^3.1.9",
26
- "tango-api-schema": "^2.2.72",
26
+ "tango-api-schema": "^2.2.73",
27
27
  "tango-app-api-middleware": "^3.1.48",
28
28
  "winston": "^3.17.0",
29
29
  "winston-daily-rotate-file": "^5.0.0",
@@ -57,12 +57,12 @@ export async function createFixtureConfig( req, res ) {
57
57
  const proportionRaw = item['Proportion'];
58
58
 
59
59
  const availableSections = typeof sectionDetailsRaw === 'string' ?
60
- sectionDetailsRaw.replace( /[{}]/g, '' ).split( ', ' ).map( ( s ) => s.trim() ) :
61
- [];
60
+ sectionDetailsRaw.replace( /[{}]/g, '' ).split( ', ' ).map( ( s ) => s.trim() ) :
61
+ [];
62
62
 
63
63
  const proportions = typeof proportionRaw === 'string' ?
64
- proportionRaw.replace( /[{}%]/g, '' ).split( ', ' ).map( ( num ) => parseInt( num.trim(), 10 ) ) :
65
- [];
64
+ proportionRaw.replace( /[{}%]/g, '' ).split( ', ' ).map( ( num ) => parseInt( num.trim(), 10 ) ) :
65
+ [];
66
66
 
67
67
  const sectionNames = [ 'Top', 'Mid', 'Bottom' ];
68
68
  const sectionKeys = [ 'Top_Section', 'Middle_Section', 'Bottom_Section' ];
@@ -207,36 +207,63 @@ export async function createFloors( req, res ) {
207
207
 
208
208
  const constantFixtureLength = 1220;
209
209
  const constantDetailedFixtureLength = 1220;
210
+
210
211
  const constantFixtureWidth = 610;
211
212
  const constantDetailedFixtureWidth = 1524;
213
+
212
214
  const mmToFeet = 305;
213
215
 
214
216
  const storeList = await planoService.find( {} );
215
217
 
218
+ function roundToTwo( num ) {
219
+ return Math.round( num * 100 ) / 100;
220
+ }
221
+
216
222
  await Promise.all( storeList.map( async ( store ) => {
217
223
  const planoDoc = store.toObject();
218
- const leftWalls = raw.filter( ( entry ) => entry['Store ID'] === planoDoc.storeName && entry.Wall === 'Left' );
219
- const leftWallCount = leftWalls.length;
224
+ const leftFixtures = raw.filter( ( entry ) => entry['Store ID'] === planoDoc.storeName && entry.Wall === 'Left' );
225
+ const rightFixtures = raw.filter( ( entry ) => entry['Store ID'] === planoDoc.storeName && entry.Wall === 'Right' );
226
+ const floorFixtures = raw.filter( ( entry ) => entry['Store ID'] === planoDoc.storeName && entry.Wall === 'Centre' );
227
+ const backFixtures = raw.filter( ( entry ) => entry['Store ID'] === planoDoc.storeName && entry.Wall === 'Back' );
220
228
 
221
- const totalLeftDistanceFeet = Math.round( ( leftWallCount * ( constantFixtureLength / mmToFeet ) ) );
222
- const totalLeftDetailedDistanceFeet = Math.round( ( leftWallCount * ( constantDetailedFixtureLength / mmToFeet ) ) );
229
+ const leftXDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
230
+ const leftXDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
223
231
 
224
- const rightWalls = raw.filter( ( entry ) => entry['Store ID'] === planoDoc.storeName && entry.Wall === 'Right' );
225
- const rightWallCount = rightWalls.length;
232
+ const leftYDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantFixtureWidth / mmToFeet ) ) ) : 0;
233
+ const leftYDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantDetailedFixtureWidth / mmToFeet ) ) ) : 0;
226
234
 
227
- const totalRightDistanceFeet = Math.round( ( rightWallCount * ( constantFixtureLength / mmToFeet ) ) );
228
- const totalRightDetailedDistanceFeet = Math.round( ( rightWallCount * ( constantDetailedFixtureLength / mmToFeet ) ) );
235
+ const rightXDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
236
+ const rightXDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
229
237
 
230
- const totalDistanceFeet = Math.max( totalLeftDistanceFeet, totalRightDistanceFeet );
231
- const totalDetailedDistanceFeet = Math.max( totalLeftDetailedDistanceFeet, totalRightDetailedDistanceFeet );
238
+ const rightYDistanceFeet = rightFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
239
+ const rightYDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( constantDetailedFixtureWidth / mmToFeet ) ): 0;
232
240
 
233
- const floorFixtures = raw.filter( ( entry ) => entry['Store ID'] === planoDoc.storeName && entry.Wall === 'Centre' );
234
- const floorFixtureLength = floorFixtures.length;
235
- const maxFixturesPerRow = floorFixtureLength > 4 ? 3 : 2;
236
- const totalRows = Math.ceil( floorFixtureLength / maxFixturesPerRow );
241
+ const maxFixturesPerRow = floorFixtures.length > 4 ? 3 : 2;
242
+ const totalRows = Math.ceil( floorFixtures.length / maxFixturesPerRow );
243
+ const floorXDistanceFeet = floorFixtures.length ? roundToTwo( ( maxFixturesPerRow * ( constantFixtureLength / mmToFeet ) ) ) : 0;
244
+ const floorXDetailedDistanceFeet = floorFixtures.length ? roundToTwo( ( maxFixturesPerRow * ( constantDetailedFixtureLength / mmToFeet ) ) ): 0;
245
+
246
+ const floorYDistanceFeet = floorFixtures.length ? roundToTwo( ( totalRows * ( constantFixtureWidth/ mmToFeet ) ) ): 0;
247
+ const floorYDetailedDistanceFeet = floorFixtures.length ? roundToTwo( totalRows * ( constantDetailedFixtureWidth/mmToFeet ) ): 0;
248
+
249
+ const backXDistanceFeet = backFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
250
+ const backXDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( constantDetailedFixtureLength / mmToFeet ) ) : 0;
237
251
 
238
- const yDistance = Math.round( ( ( totalRows + 6 ) * ( constantFixtureWidth / mmToFeet ) ) );
239
- const detailedyDistance = Math.round( ( ( totalRows + 4 ) * ( constantDetailedFixtureWidth / mmToFeet ) ) );
252
+ const backYDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantFixtureLength / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantFixtureWidth )/mmToFeet ) ) ) : 0;
253
+ const backYDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantDetailedFixtureWidth / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantDetailedFixtureWidth )/mmToFeet ) ) ): 0;
254
+
255
+ const maxXDistance = Math.max( leftXDistanceFeet, rightXDistanceFeet, floorXDistanceFeet );
256
+ const maxXDetailedDistance = Math.max( leftXDetailedDistanceFeet, rightXDetailedDistanceFeet, floorXDetailedDistanceFeet );
257
+
258
+ const maxYDistance = Math.max( floorYDistanceFeet, backYDistanceFeet );
259
+ const maxYDetailedDistance = Math.max( floorYDetailedDistanceFeet, backYDetailedDistanceFeet );
260
+
261
+
262
+ const finalXDistance = maxXDistance < ( backXDistanceFeet + floorXDistanceFeet )? ( ( backXDistanceFeet + floorXDistanceFeet ) + ( ( 2 * constantFixtureLength )/mmToFeet ) ) : maxXDistance;
263
+ const finalXDetailedDistance = maxXDetailedDistance < ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet )? ( ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureLength )/mmToFeet ) ) : maxXDetailedDistance;
264
+
265
+ const finalYDistance = maxYDistance < ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) ? ( ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) + ( ( 2 * constantFixtureWidth )/mmToFeet ) ) : ( maxYDistance + ( ( constantFixtureWidth )/mmToFeet ) );
266
+ const finalYDetailedDistance = maxYDetailedDistance < ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) ? ( ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureWidth )/mmToFeet ) ) : ( maxYDetailedDistance + ( ( constantDetailedFixtureWidth )/mmToFeet ) );
240
267
 
241
268
  const floorInsertData = {
242
269
  storeName: planoDoc.storeName,
@@ -248,57 +275,57 @@ export async function createFloors( req, res ) {
248
275
  layoutPolygon: [
249
276
  {
250
277
  elementType: 'wall',
251
- distance: totalDistanceFeet + 3,
278
+ distance: finalXDistance,
252
279
  unit: 'ft',
253
280
  direction: 'right',
254
281
  angle: 90,
255
282
  elementNumber: 1,
256
- detailedDistance: totalDetailedDistanceFeet + 3,
283
+ detailedDistance: finalXDetailedDistance,
257
284
  },
258
285
  {
259
286
  elementType: 'wall',
260
- distance: yDistance,
287
+ distance: finalYDistance,
261
288
  unit: 'ft',
262
289
  direction: 'down',
263
290
  angle: 90,
264
291
  elementNumber: 2,
265
- detailedDistance: detailedyDistance,
292
+ detailedDistance: finalYDetailedDistance,
266
293
  },
267
294
  {
268
295
  elementType: 'wall',
269
- distance: totalDistanceFeet + 3,
296
+ distance: finalXDistance,
270
297
  unit: 'ft',
271
298
  direction: 'left',
272
299
  angle: 90,
273
300
  elementNumber: 3,
274
- detailedDistance: totalDetailedDistanceFeet + 3,
301
+ detailedDistance: finalXDetailedDistance,
275
302
  },
276
303
  {
277
304
  elementType: 'wall',
278
- distance: Math.round( ( yDistance * 40 ) / 100 ),
305
+ distance: roundToTwo( ( ( finalYDistance * 40 ) / 100 ) ),
279
306
  unit: 'ft',
280
307
  direction: 'up',
281
308
  angle: 90,
282
309
  elementNumber: 4,
283
- detailedDistance: Math.round( ( detailedyDistance * 35 ) / 100 ),
310
+ detailedDistance: roundToTwo( ( ( finalYDetailedDistance * 35 ) / 100 ) ),
284
311
  },
285
312
  {
286
313
  elementType: 'entrance',
287
- distance: Math.round( ( yDistance * 20 ) / 100 ),
314
+ distance: roundToTwo( ( ( finalYDistance * 20 ) / 100 ) ),
288
315
  unit: 'ft',
289
316
  direction: 'up',
290
317
  angle: 90,
291
318
  elementNumber: 1,
292
- detailedDistance: Math.round( ( detailedyDistance * 30 ) / 100 ),
319
+ detailedDistance: roundToTwo( ( ( finalYDetailedDistance * 30 ) / 100 ) ),
293
320
  },
294
321
  {
295
322
  elementType: 'wall',
296
- distance: Math.round( ( yDistance * 40 ) / 100 ),
323
+ distance: roundToTwo( ( ( finalYDistance * 40 ) / 100 ) ),
297
324
  unit: 'ft',
298
325
  direction: 'up',
299
326
  angle: 90,
300
327
  elementNumber: 5,
301
- detailedDistance: Math.round( ( detailedyDistance * 35 ) / 100 ),
328
+ detailedDistance: roundToTwo( ( ( finalYDetailedDistance * 35 ) / 100 ) ),
302
329
  },
303
330
  ],
304
331
  createdBy: new mongoose.Types.ObjectId( '66a78cd82734f4f857cd6db6' ),
@@ -310,7 +337,7 @@ export async function createFloors( req, res ) {
310
337
 
311
338
  await storeBuilderService.create( floorInsertData );
312
339
 
313
- console.log( floorInsertData );
340
+ // console.log( floorInsertData );
314
341
  } ) );
315
342
 
316
343
  return res.sendSuccess( { message: 'Floor data inserted successfully' } );
@@ -320,6 +347,7 @@ export async function createFloors( req, res ) {
320
347
  }
321
348
  }
322
349
 
350
+
323
351
  export async function createFixturesShelves( req, res ) {
324
352
  try {
325
353
  if ( !req.files.file ) {
@@ -373,57 +401,67 @@ export async function createFixturesShelves( req, res ) {
373
401
 
374
402
  const constantFixtureLength = 1220;
375
403
  const constantDetailedFixtureLength = 1220;
376
- const constantDetailedFloorFixtureLength = 1524;
377
404
 
378
405
 
379
406
  const constantFixtureWidth = 610;
380
407
  const constantDetailedFixtureWidth = 1524;
381
- const constantDetailedFloorFixtureWidth = 1220;
382
408
 
383
409
 
384
410
  const mmToFeet = 305;
385
411
  const layoutList = await storeBuilderService.find( {} );
386
412
 
413
+ function roundToTwo( num ) {
414
+ return Math.round( num * 100 ) / 100;
415
+ }
416
+
387
417
  for ( let i = 0; i < layoutList.length; i++ ) {
388
418
  const layout = layoutList[i];
389
419
 
390
420
  const layoutDoc = layout.toObject();
391
421
 
392
422
  const leftFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Left' );
393
- const leftWallCount = leftFixtures.length;
394
-
395
423
  const rightFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Right' );
396
- const rightWallCount = rightFixtures.length;
424
+ const floorFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Centre' );
425
+ const backFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Back' );
397
426
 
427
+ const leftXDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
428
+ const leftXDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
398
429
 
399
- const floorFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Centre' );
400
- const floorFixtureCount = floorFixtures.length;
430
+ const leftYDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantFixtureWidth / mmToFeet ) ) ) : 0;
431
+ const leftYDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantDetailedFixtureWidth / mmToFeet ) ) ) : 0;
432
+
433
+ const rightXDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
434
+ const rightXDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
401
435
 
402
- const maxFixturesPerRow = floorFixtureCount > 4 ? 3 : 2;
436
+ const rightYDistanceFeet = rightFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
437
+ const rightYDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( constantDetailedFixtureWidth / mmToFeet ) ): 0;
403
438
 
404
- const totalRows = Math.ceil( floorFixtureCount / maxFixturesPerRow );
405
- const centerRow = Math.floor( totalRows / 2 );
439
+ const maxFixturesPerRow = floorFixtures.length > 4 ? 3 : 2;
440
+ const totalRows = Math.ceil( floorFixtures.length / maxFixturesPerRow );
441
+ const floorXDistanceFeet = floorFixtures.length ? roundToTwo( ( maxFixturesPerRow * ( constantFixtureLength / mmToFeet ) ) ) : 0;
442
+ const floorXDetailedDistanceFeet = floorFixtures.length ? roundToTwo( ( maxFixturesPerRow * ( constantDetailedFixtureLength / mmToFeet ) ) ): 0;
406
443
 
407
- const totalLeftDistanceFeet = Math.round( ( leftWallCount * ( constantFixtureLength/mmToFeet ) ) );
408
- const totalLeftDetailedDistanceFeet = Math.round( ( leftWallCount * ( constantDetailedFixtureLength/mmToFeet ) ) );
444
+ const floorYDistanceFeet = floorFixtures.length ? roundToTwo( ( totalRows * ( constantFixtureWidth/ mmToFeet ) ) ): 0;
445
+ const floorYDetailedDistanceFeet = floorFixtures.length ? roundToTwo( totalRows * ( constantDetailedFixtureWidth/mmToFeet ) ): 0;
409
446
 
410
- const totalRightDistanceFeet = Math.round( ( rightWallCount * ( constantFixtureLength/mmToFeet ) ) );
411
- const totalRightDetailedDistanceFeet = Math.round( ( rightWallCount * ( constantDetailedFixtureLength/mmToFeet ) ) );
447
+ const backXDistanceFeet = backFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
448
+ const backXDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( constantDetailedFixtureLength / mmToFeet ) ) : 0;
412
449
 
413
- const totalCentreDistanceFeet = Math.round( ( ( totalRows + 6 ) * ( constantFixtureWidth/mmToFeet ) ) );
414
- const totalCentreDetailedDistanceFeet = Math.round( ( ( totalRows + 4 ) * ( constantDetailedFixtureWidth/mmToFeet ) ) );
450
+ const backYDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantFixtureLength / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantFixtureWidth )/mmToFeet ) ) ) : 0;
451
+ const backYDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantDetailedFixtureWidth / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantDetailedFixtureWidth )/mmToFeet ) ) ): 0;
415
452
 
416
- const totalDistanceFeetX = Math.max( totalLeftDistanceFeet, totalRightDistanceFeet );
417
- const totalDetailedDistanceFeetX = Math.max( totalLeftDetailedDistanceFeet, totalRightDetailedDistanceFeet );
453
+ const maxXDistance = Math.max( leftXDistanceFeet, rightXDistanceFeet, floorXDistanceFeet );
454
+ const maxXDetailedDistance = Math.max( leftXDetailedDistanceFeet, rightXDetailedDistanceFeet, floorXDetailedDistanceFeet );
418
455
 
419
- const totalDistanceFeetY = totalCentreDistanceFeet;
420
- const totalDetailedDistanceFeetY = totalCentreDetailedDistanceFeet;
456
+ const maxYDistance = Math.max( floorYDistanceFeet, backYDistanceFeet );
457
+ const maxYDetailedDistance = Math.max( floorYDetailedDistanceFeet, backYDetailedDistanceFeet );
421
458
 
422
- const startingX = ( totalDistanceFeetX / 2 ) - ( Math.floor( maxFixturesPerRow / 2 ) * ( constantFixtureLength / mmToFeet ) );
423
- const startingY = ( totalDistanceFeetY / 2 ) - ( centerRow * ( constantFixtureWidth / mmToFeet ) );
459
+ const finalXDistance = maxXDistance < ( backXDistanceFeet + floorXDistanceFeet )? ( ( backXDistanceFeet + floorXDistanceFeet ) + ( ( 2 * constantFixtureLength )/mmToFeet ) ) : maxXDistance;
460
+ const finalXDetailedDistance = maxXDetailedDistance < ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet )? ( ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureLength )/mmToFeet ) ) : maxXDistance;
461
+
462
+ const finalYDistance = maxYDistance < ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) ? ( ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) + ( ( 2 * constantFixtureWidth )/mmToFeet ) ) : ( maxYDistance + ( ( constantFixtureWidth )/mmToFeet ) );
463
+ const finalYDetailedDistance = maxYDetailedDistance < ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) ? ( ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureWidth )/mmToFeet ) ) : ( maxYDetailedDistance + ( ( constantDetailedFixtureWidth )/mmToFeet ) );
424
464
 
425
- const detailedStartingX = ( totalDetailedDistanceFeetX / 2 ) - ( Math.floor( maxFixturesPerRow / 2 ) * ( constantDetailedFloorFixtureLength / mmToFeet ) );
426
- const detailedStartingY = ( totalDetailedDistanceFeetY / 2 ) - ( centerRow * ( constantDetailedFloorFixtureWidth / mmToFeet ) );
427
465
 
428
466
  let fixtureCounter = 1;
429
467
 
@@ -458,7 +496,7 @@ export async function createFixturesShelves( req, res ) {
458
496
  'associatedElementType': 'wall',
459
497
  'associatedElementNumber': 1,
460
498
  'relativePosition': {
461
- 'x': Math.round( ( index * ( constantFixtureLength/mmToFeet ) ) ),
499
+ 'x': roundToTwo( ( index * ( constantFixtureLength / mmToFeet ) ) ),
462
500
  'y': 0,
463
501
  'unit': 'ft',
464
502
  },
@@ -472,7 +510,7 @@ export async function createFixturesShelves( req, res ) {
472
510
  'unit': 'mm',
473
511
  },
474
512
  'relativeDetailedPosition': {
475
- 'x': Math.round( ( index * ( constantDetailedFixtureLength/mmToFeet ) ) ),
513
+ 'x': roundToTwo( ( index * ( constantDetailedFixtureLength / mmToFeet ) ) ),
476
514
  'y': 0,
477
515
  'unit': 'ft',
478
516
  },
@@ -543,6 +581,117 @@ export async function createFixturesShelves( req, res ) {
543
581
  }
544
582
  }
545
583
 
584
+ for ( let index = 0; index < backFixtures.length; index++ ) {
585
+ const fixture = rightFixtures[index];
586
+
587
+ const fixtureData = {
588
+ 'clientId': layoutDoc.clientId,
589
+ 'storeName': layoutDoc.storeName,
590
+ 'storeId': layoutDoc.storeId,
591
+ 'planoId': layoutDoc.planoId,
592
+ 'floorId': layoutDoc._id,
593
+ 'fixtureName': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
594
+ 'fixtureCategory': fixture?.['Fixture Category'] ? fixture?.['Fixture Category'] : 'nil',
595
+ 'fixtureBrandCategory': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
596
+ 'fixtureBrandSubCategory': fixture?.['Brand - Sub Category'] ? fixture?.['Brand - Sub Category'] : 'nil',
597
+ 'fixtureCode': fixture?.['Fixture ID'],
598
+ 'fixtureCapacity': fixture?.['Capacity'],
599
+ 'fixtureType': 'wall',
600
+ 'fixtureHeight': {
601
+ 'value': 0,
602
+ 'unit': 'mm',
603
+ },
604
+ 'fixtureLength': {
605
+ 'value': constantFixtureWidth,
606
+ 'unit': 'mm',
607
+ },
608
+ 'fixtureWidth': {
609
+ 'value': constantFixtureLength,
610
+ 'unit': 'mm',
611
+ },
612
+ 'associatedElementType': 'wall',
613
+ 'associatedElementNumber': 2,
614
+ 'relativePosition': {
615
+ 'x': roundToTwo( ( finalXDistance - ( constantFixtureWidth/mmToFeet ) ) ),
616
+ 'y': roundToTwo( ( ( index * ( ( constantFixtureLength/mmToFeet ) ) ) + ( ( leftFixtures.length ? 1 : 0 ) * constantFixtureWidth/mmToFeet ) ) ),
617
+ 'unit': 'ft',
618
+ },
619
+ 'fixtureNumber': fixtureCounter++,
620
+ 'detailedFixtureLength': {
621
+ 'value': constantDetailedFixtureLength,
622
+ 'unit': 'mm',
623
+ },
624
+ 'detailedFixtureWidth': {
625
+ 'value': constantDetailedFixtureWidth,
626
+ 'unit': 'mm',
627
+ },
628
+ 'relativeDetailedPosition': {
629
+ 'x': roundToTwo( ( finalXDistance - ( constantDetailedFixtureLength/mmToFeet ) ) ),
630
+ 'y': roundToTwo( ( ( index * ( ( constantDetailedFixtureWidth/mmToFeet ) ) ) + ( ( leftFixtures.length ? 1 : 0 ) * constantDetailedFixtureWidth/mmToFeet ) ) ),
631
+ 'unit': 'ft',
632
+ },
633
+ 'productResolutionLevel': 'L2',
634
+ };
635
+
636
+ const createdFixture = await storeFixtureService.create( fixtureData );
637
+
638
+ // console.log( 'Fixture Data', fixtureData );
639
+
640
+ const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
641
+
642
+ for ( let i = 0; i < vms?.length; i++ ) {
643
+ const vmTemplate = await planoProductService.findOne( { productId: vms[i] } );
644
+
645
+ if ( vmTemplate ) {
646
+ const vmData = {
647
+ 'clientId': layoutDoc.clientId,
648
+ 'storeName': layoutDoc.storeName,
649
+ 'storeId': layoutDoc.storeId,
650
+ 'planoId': layoutDoc.planoId,
651
+ 'floorId': layoutDoc._id,
652
+ 'type': 'vm',
653
+ 'fixtureId': createdFixture._id,
654
+ 'productId': vmTemplate._id,
655
+ };
656
+
657
+ await planoMappingService.create( vmData );
658
+ }
659
+ }
660
+
661
+ const fixtureConfig = await fixtureConfigService.findOne( { fixtureCode: fixture?.['Fixture ID'] } );
662
+
663
+ if ( fixtureConfig ) {
664
+ let shelfIndex = 0;
665
+
666
+ for ( const section of fixtureConfig.sections ) {
667
+ const storeCategory = fixture.categories.find( ( cat ) => cat.Zone === section.sectionId );
668
+ for ( let j = 0; j < section.sectionShelves; j++ ) {
669
+ if ( shelfIndex >= fixtureConfig.shelfCount ) break;
670
+
671
+ const shelfData = {
672
+ 'clientId': fixtureConfig.clientId,
673
+ 'storeName': layoutDoc.storeName,
674
+ 'storeId': layoutDoc.storeId,
675
+ 'planoId': layoutDoc.planoId,
676
+ 'floorId': layoutDoc._id,
677
+ 'fixtureId': createdFixture._id,
678
+ 'shelfNumber': shelfIndex + 1,
679
+ 'shelfOrder': 'LTR',
680
+ 'shelfCapacity': fixtureConfig.productPerShelf,
681
+ 'sectionName': storeCategory ? storeCategory?.['Allocation'] : 'Unknown',
682
+ 'sectionZone': section.sectionId,
683
+ };
684
+
685
+ const createdShelf = await fixtureShelfService.create( shelfData );
686
+
687
+ // console.log( 'Shelf Data:', createdShelf );
688
+
689
+ shelfIndex++;
690
+ }
691
+ }
692
+ }
693
+ }
694
+
546
695
  for ( let index = 0; index < rightFixtures.length; index++ ) {
547
696
  const fixture = rightFixtures[index];
548
697
 
@@ -574,8 +723,8 @@ export async function createFixturesShelves( req, res ) {
574
723
  'associatedElementType': 'wall',
575
724
  'associatedElementNumber': 3,
576
725
  'relativePosition': {
577
- 'x': Math.round( ( index * ( constantFixtureLength/mmToFeet ) ) ),
578
- 'y': Math.round( ( ( ( totalRows + 6 ) * ( constantFixtureWidth/mmToFeet ) ) - ( constantFixtureWidth/mmToFeet ) ) ),
726
+ 'x': roundToTwo( ( index * ( constantFixtureLength / mmToFeet ) ) ),
727
+ 'y': roundToTwo( ( finalYDistance - ( constantFixtureWidth / mmToFeet ) ) ),
579
728
  'unit': 'ft',
580
729
  },
581
730
  'fixtureNumber': fixtureCounter++,
@@ -588,8 +737,8 @@ export async function createFixturesShelves( req, res ) {
588
737
  'unit': 'mm',
589
738
  },
590
739
  'relativeDetailedPosition': {
591
- 'x': Math.round( ( index * ( constantDetailedFixtureLength/mmToFeet ) ) ),
592
- 'y': Math.round( ( ( ( totalRows + 4 ) * ( constantDetailedFixtureWidth/mmToFeet ) ) - ( constantDetailedFixtureWidth/mmToFeet ) ) ),
740
+ 'x': roundToTwo( ( index * ( constantDetailedFixtureLength / mmToFeet ) ) ),
741
+ 'y': roundToTwo( ( finalYDetailedDistance - ( constantDetailedFixtureWidth / mmToFeet ) ) ),
593
742
  'unit': 'ft',
594
743
  },
595
744
  'productResolutionLevel': 'L2',
@@ -657,14 +806,22 @@ export async function createFixturesShelves( req, res ) {
657
806
  for ( let index = 0; index < floorFixtures.length; index++ ) {
658
807
  const fixture = floorFixtures[index];
659
808
 
809
+ const centerRow = Math.floor( totalRows / 2 );
810
+
811
+ const startingX =roundToTwo( ( ( finalXDistance / 2 ) - ( ( maxFixturesPerRow / 2 ) * ( constantFixtureLength / mmToFeet ) ) ) );
812
+ const detailedStartingX = roundToTwo( ( ( finalXDetailedDistance / 2 ) - ( ( maxFixturesPerRow / 2 ) * ( constantDetailedFixtureLength / mmToFeet ) ) ) );
813
+
814
+ const startingY = ( finalYDistance / 2 ) - ( centerRow * ( constantFixtureWidth / mmToFeet ) );
815
+ const detailedStartingY = ( finalYDetailedDistance / 2 ) - ( centerRow * ( constantDetailedFixtureWidth / mmToFeet ) );
816
+
660
817
  const rowIndex = Math.floor( index / maxFixturesPerRow );
661
818
  const colIndex = index % maxFixturesPerRow;
662
819
 
663
- const xPos = Math.round( startingX + colIndex * ( constantFixtureLength / mmToFeet ) );
664
- const yPos = Math.round( startingY + rowIndex * ( constantFixtureWidth / mmToFeet ) );
820
+ const xPos = roundToTwo( ( startingX + colIndex * ( constantFixtureLength / mmToFeet ) ) );
821
+ const yPos = roundToTwo( ( startingY + rowIndex * ( constantFixtureWidth / mmToFeet ) ) );
665
822
 
666
- const detailedXPos = Math.round( detailedStartingX + colIndex * ( constantDetailedFloorFixtureLength / mmToFeet ) );
667
- const detailedYPos = Math.round( detailedStartingY + rowIndex * ( constantDetailedFloorFixtureWidth / mmToFeet ) );
823
+ const detailedXPos = roundToTwo( ( detailedStartingX + colIndex * ( constantDetailedFixtureLength / mmToFeet ) ) );
824
+ const detailedYPos = roundToTwo( ( detailedStartingY + rowIndex * ( constantDetailedFixtureWidth / mmToFeet ) ) );
668
825
 
669
826
  const fixtureData = {
670
827
  'clientId': layoutDoc.clientId,
@@ -698,11 +855,11 @@ export async function createFixturesShelves( req, res ) {
698
855
  },
699
856
  'fixtureNumber': fixtureCounter++,
700
857
  'detailedFixtureLength': {
701
- 'value': constantDetailedFloorFixtureLength,
858
+ 'value': constantDetailedFixtureLength,
702
859
  'unit': 'mm',
703
860
  },
704
861
  'detailedFixtureWidth': {
705
- 'value': constantDetailedFloorFixtureWidth,
862
+ 'value': constantDetailedFixtureWidth,
706
863
  'unit': 'mm',
707
864
  },
708
865
  'relativeDetailedPosition': {
@@ -781,6 +938,597 @@ export async function createFixturesShelves( req, res ) {
781
938
  }
782
939
  }
783
940
 
941
+ export async function updateFixturesShelves( req, res ) {
942
+ try {
943
+ if ( !req.files.file ) {
944
+ return res.sendError( 'Invalid or missing Excel file', 400 );
945
+ }
946
+
947
+ const workbook = xlsx.read( req.files.file.data, { type: 'buffer' } );
948
+ const sheetName = 'Layout,Fixture&VM';
949
+ if ( !workbook.Sheets[sheetName] ) {
950
+ return res.sendError( `Sheet "${sheetName}" not found`, 400 );
951
+ }
952
+
953
+ const rawData = xlsx.utils.sheet_to_json( workbook.Sheets[sheetName] );
954
+
955
+ const groupedData = {};
956
+
957
+ rawData.forEach( ( item ) => {
958
+ const fixtureId = item['Store Fixture ID'];
959
+
960
+ if ( !groupedData[fixtureId] ) {
961
+ groupedData[fixtureId] = {
962
+ 'Store ID': item['Store ID'],
963
+ 'Store Fixture ID': fixtureId,
964
+ 'Fixture ID': item['Fixture ID ( For ref only)'],
965
+ 'Fixture Category': item['Fixture Category'],
966
+ 'Fixture Size (feet)': item['Fixture Size (feet)'],
967
+ 'Fixture Count': item['Fixture Count'],
968
+ 'Effective Fixture Count': item['Effective Fixture Count'],
969
+ 'Capacity': item['Capacity'],
970
+ 'Store Fixture Locator': item['Store Fixture Locator'],
971
+ 'Wall': item['Wall'],
972
+ 'Brand-Category': item['Brand-Category'],
973
+ 'Brand - Sub Category': item['Brand - Sub Category'],
974
+ 'VM Template ID': item['VM Template ID '],
975
+ 'categories': [],
976
+ 'fixtureNumber': item['fixtureNumber'],
977
+ };
978
+ }
979
+
980
+ const categories = groupedData[fixtureId]['categories'];
981
+ const existingCategory = categories.find( ( cat ) => cat['Zone'] === item['Section Allocation '] );
982
+
983
+ if ( !existingCategory ) {
984
+ categories.push( {
985
+ 'Allocation': item['Shelf Allocation'],
986
+ 'Zone': item['Section Allocation '],
987
+ } );
988
+ }
989
+ } );
990
+
991
+ const raw = Object.values( groupedData );
992
+
993
+ const constantFixtureLength = 1220;
994
+ const constantDetailedFixtureLength = 1220;
995
+
996
+
997
+ const constantFixtureWidth = 610;
998
+ const constantDetailedFixtureWidth = 1524;
999
+
1000
+
1001
+ const mmToFeet = 305;
1002
+ const layoutList = await storeBuilderService.find( {} );
1003
+
1004
+ function roundToTwo( num ) {
1005
+ return Math.round( num * 100 ) / 100;
1006
+ }
1007
+
1008
+ for ( let i = 0; i < layoutList.length; i++ ) {
1009
+ const layout = layoutList[i];
1010
+
1011
+ const layoutDoc = layout.toObject();
1012
+
1013
+ const leftFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Left' );
1014
+ const rightFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Right' );
1015
+ const floorFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Centre' );
1016
+ const backFixtures = raw.filter( ( entry ) => entry['Store ID'] === layoutDoc.storeName && entry.Wall === 'Back' );
1017
+
1018
+ const leftXDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
1019
+ const leftXDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( leftFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
1020
+
1021
+ const leftYDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantFixtureWidth / mmToFeet ) ) ) : 0;
1022
+ const leftYDetailedDistanceFeet = leftFixtures.length ? roundToTwo( ( ( constantDetailedFixtureWidth / mmToFeet ) ) ) : 0;
1023
+
1024
+ const rightXDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantFixtureLength / mmToFeet ) ) ) : 0;
1025
+ const rightXDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( rightFixtures.length * ( constantDetailedFixtureLength / mmToFeet ) ) ) : 0;
1026
+
1027
+ const rightYDistanceFeet = rightFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
1028
+ const rightYDetailedDistanceFeet = rightFixtures.length ? roundToTwo( ( constantDetailedFixtureWidth / mmToFeet ) ): 0;
1029
+
1030
+ const maxFixturesPerRow = floorFixtures.length > 4 ? 3 : 2;
1031
+ const totalRows = Math.ceil( floorFixtures.length / maxFixturesPerRow );
1032
+ const floorXDistanceFeet = floorFixtures.length ? roundToTwo( ( maxFixturesPerRow * ( constantFixtureLength / mmToFeet ) ) ) : 0;
1033
+ const floorXDetailedDistanceFeet = floorFixtures.length ? roundToTwo( ( maxFixturesPerRow * ( constantDetailedFixtureLength / mmToFeet ) ) ): 0;
1034
+
1035
+ const floorYDistanceFeet = floorFixtures.length ? roundToTwo( ( totalRows * ( constantFixtureWidth/ mmToFeet ) ) ): 0;
1036
+ const floorYDetailedDistanceFeet = floorFixtures.length ? roundToTwo( totalRows * ( constantDetailedFixtureWidth/mmToFeet ) ): 0;
1037
+
1038
+ const backXDistanceFeet = backFixtures.length ? roundToTwo( ( constantFixtureWidth / mmToFeet ) ) : 0;
1039
+ const backXDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( constantDetailedFixtureLength / mmToFeet ) ) : 0;
1040
+
1041
+ const backYDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantFixtureLength / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantFixtureWidth )/mmToFeet ) ) ) : 0;
1042
+ const backYDetailedDistanceFeet = backFixtures.length ? roundToTwo( ( ( backFixtures.length * ( constantDetailedFixtureWidth / mmToFeet ) ) + ( ( ( leftFixtures.length ? 1 : 0 ) + ( rightFixtures.length ? 1 : 0 ) * constantDetailedFixtureWidth )/mmToFeet ) ) ): 0;
1043
+
1044
+ const maxXDistance = Math.max( leftXDistanceFeet, rightXDistanceFeet, floorXDistanceFeet );
1045
+ const maxXDetailedDistance = Math.max( leftXDetailedDistanceFeet, rightXDetailedDistanceFeet, floorXDetailedDistanceFeet );
1046
+
1047
+ const maxYDistance = Math.max( floorYDistanceFeet, backYDistanceFeet );
1048
+ const maxYDetailedDistance = Math.max( floorYDetailedDistanceFeet, backYDetailedDistanceFeet );
1049
+
1050
+ const finalXDistance = maxXDistance < ( backXDistanceFeet + floorXDistanceFeet )? ( ( backXDistanceFeet + floorXDistanceFeet ) + ( ( 2 * constantFixtureLength )/mmToFeet ) ) : maxXDistance;
1051
+ const finalXDetailedDistance = maxXDetailedDistance < ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet )? ( ( backXDetailedDistanceFeet + floorXDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureLength )/mmToFeet ) ) : maxXDistance;
1052
+
1053
+ const finalYDistance = maxYDistance < ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) ? ( ( leftYDistanceFeet + rightYDistanceFeet + floorYDistanceFeet ) + ( ( 2 * constantFixtureWidth )/mmToFeet ) ) : ( maxYDistance + ( ( constantFixtureWidth )/mmToFeet ) );
1054
+ const finalYDetailedDistance = maxYDetailedDistance < ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) ? ( ( leftYDetailedDistanceFeet + rightYDetailedDistanceFeet + floorYDetailedDistanceFeet ) + ( ( 2 * constantDetailedFixtureWidth )/mmToFeet ) ) : ( maxYDetailedDistance + ( ( constantDetailedFixtureWidth )/mmToFeet ) );
1055
+
1056
+
1057
+ let fixtureCounter = 1;
1058
+
1059
+ for ( let index = 0; index < leftFixtures.length; index++ ) {
1060
+ const fixture = leftFixtures[index];
1061
+
1062
+ const fixtureData = {
1063
+ 'clientId': layoutDoc.clientId,
1064
+ 'storeName': layoutDoc.storeName,
1065
+ 'storeId': layoutDoc.storeId,
1066
+ 'planoId': layoutDoc.planoId,
1067
+ 'floorId': layoutDoc._id,
1068
+ 'fixtureName': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1069
+ 'fixtureCategory': fixture?.['Fixture Category'] ? fixture?.['Fixture Category'] : 'nil',
1070
+ 'fixtureBrandCategory': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1071
+ 'fixtureBrandSubCategory': fixture?.['Brand - Sub Category'] ? fixture?.['Brand - Sub Category'] : 'nil',
1072
+ 'fixtureCode': fixture?.['Fixture ID'],
1073
+ 'fixtureCapacity': fixture?.['Capacity'],
1074
+ 'fixtureType': 'wall',
1075
+ 'fixtureHeight': {
1076
+ 'value': 0,
1077
+ 'unit': 'mm',
1078
+ },
1079
+ 'fixtureLength': {
1080
+ 'value': constantFixtureLength,
1081
+ 'unit': 'mm',
1082
+ },
1083
+ 'fixtureWidth': {
1084
+ 'value': constantFixtureWidth,
1085
+ 'unit': 'mm',
1086
+ },
1087
+ 'associatedElementType': 'wall',
1088
+ 'associatedElementNumber': 1,
1089
+ 'relativePosition': {
1090
+ 'x': roundToTwo( ( index * ( constantFixtureLength / mmToFeet ) ) ),
1091
+ 'y': 0,
1092
+ 'unit': 'ft',
1093
+ },
1094
+ 'fixtureNumber': fixtureCounter++,
1095
+ 'detailedFixtureLength': {
1096
+ 'value': constantDetailedFixtureLength,
1097
+ 'unit': 'mm',
1098
+ },
1099
+ 'detailedFixtureWidth': {
1100
+ 'value': constantDetailedFixtureWidth,
1101
+ 'unit': 'mm',
1102
+ },
1103
+ 'relativeDetailedPosition': {
1104
+ 'x': roundToTwo( ( index * ( constantDetailedFixtureLength / mmToFeet ) ) ),
1105
+ 'y': 0,
1106
+ 'unit': 'ft',
1107
+ },
1108
+ 'productResolutionLevel': 'L2',
1109
+ };
1110
+
1111
+ const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
1112
+
1113
+ // console.log( 'Fixture Data', fixtureData );
1114
+
1115
+
1116
+ const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
1117
+
1118
+ for ( let i = 0; i < vms?.length; i++ ) {
1119
+ const vmTemplate = await planoProductService.findOne( { productId: vms[i] } );
1120
+
1121
+ if ( vmTemplate ) {
1122
+ const vmData = {
1123
+ 'clientId': layoutDoc.clientId,
1124
+ 'storeName': layoutDoc.storeName,
1125
+ 'storeId': layoutDoc.storeId,
1126
+ 'planoId': layoutDoc.planoId,
1127
+ 'floorId': layoutDoc._id,
1128
+ 'type': 'vm',
1129
+ 'fixtureId': createdFixture._id,
1130
+ 'productId': vmTemplate._id,
1131
+ };
1132
+
1133
+ await planoMappingService.create( vmData );
1134
+ }
1135
+ }
1136
+
1137
+
1138
+ const fixtureConfig = await fixtureConfigService.findOne( { fixtureCode: fixture?.['Fixture ID'] } );
1139
+
1140
+ if ( fixtureConfig ) {
1141
+ let shelfIndex = 0;
1142
+
1143
+ for ( const section of fixtureConfig.sections ) {
1144
+ const storeCategory = fixture.categories.find( ( cat ) => cat.Zone === section.sectionId );
1145
+
1146
+ for ( let j = 0; j < section.sectionShelves; j++ ) {
1147
+ if ( shelfIndex >= fixtureConfig.shelfCount ) break;
1148
+
1149
+
1150
+ const shelfData = {
1151
+ 'clientId': fixtureConfig.clientId,
1152
+ 'storeName': layoutDoc.storeName,
1153
+ 'storeId': layoutDoc.storeId,
1154
+ 'planoId': layoutDoc.planoId,
1155
+ 'floorId': layoutDoc._id,
1156
+ 'fixtureId': createdFixture._id,
1157
+ 'shelfNumber': shelfIndex + 1,
1158
+ 'shelfOrder': 'LTR',
1159
+ 'shelfCapacity': fixtureConfig.productPerShelf,
1160
+ 'sectionName': storeCategory ? storeCategory?.['Allocation'] : 'Unknown',
1161
+ 'sectionZone': section.sectionId,
1162
+ };
1163
+
1164
+
1165
+ await fixtureShelfService.create( shelfData );
1166
+
1167
+ // console.log( 'Shelf Data:', createdShelf );
1168
+
1169
+ shelfIndex++;
1170
+ }
1171
+ }
1172
+ }
1173
+ }
1174
+
1175
+ for ( let index = 0; index < backFixtures.length; index++ ) {
1176
+ const fixture = rightFixtures[index];
1177
+
1178
+ const fixtureData = {
1179
+ 'clientId': layoutDoc.clientId,
1180
+ 'storeName': layoutDoc.storeName,
1181
+ 'storeId': layoutDoc.storeId,
1182
+ 'planoId': layoutDoc.planoId,
1183
+ 'floorId': layoutDoc._id,
1184
+ 'fixtureName': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1185
+ 'fixtureCategory': fixture?.['Fixture Category'] ? fixture?.['Fixture Category'] : 'nil',
1186
+ 'fixtureBrandCategory': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1187
+ 'fixtureBrandSubCategory': fixture?.['Brand - Sub Category'] ? fixture?.['Brand - Sub Category'] : 'nil',
1188
+ 'fixtureCode': fixture?.['Fixture ID'],
1189
+ 'fixtureCapacity': fixture?.['Capacity'],
1190
+ 'fixtureType': 'wall',
1191
+ 'fixtureHeight': {
1192
+ 'value': 0,
1193
+ 'unit': 'mm',
1194
+ },
1195
+ 'fixtureLength': {
1196
+ 'value': constantFixtureWidth,
1197
+ 'unit': 'mm',
1198
+ },
1199
+ 'fixtureWidth': {
1200
+ 'value': constantFixtureLength,
1201
+ 'unit': 'mm',
1202
+ },
1203
+ 'associatedElementType': 'wall',
1204
+ 'associatedElementNumber': 2,
1205
+ 'relativePosition': {
1206
+ 'x': roundToTwo( ( finalXDistance - ( constantFixtureWidth/mmToFeet ) ) ),
1207
+ 'y': roundToTwo( ( ( index * ( ( constantFixtureLength/mmToFeet ) ) ) + ( ( leftFixtures.length ? 1 : 0 ) * constantFixtureWidth/mmToFeet ) ) ),
1208
+ 'unit': 'ft',
1209
+ },
1210
+ 'fixtureNumber': fixtureCounter++,
1211
+ 'detailedFixtureLength': {
1212
+ 'value': constantDetailedFixtureLength,
1213
+ 'unit': 'mm',
1214
+ },
1215
+ 'detailedFixtureWidth': {
1216
+ 'value': constantDetailedFixtureWidth,
1217
+ 'unit': 'mm',
1218
+ },
1219
+ 'relativeDetailedPosition': {
1220
+ 'x': roundToTwo( ( finalXDistance - ( constantDetailedFixtureLength/mmToFeet ) ) ),
1221
+ 'y': roundToTwo( ( ( index * ( ( constantDetailedFixtureWidth/mmToFeet ) ) ) + ( ( leftFixtures.length ? 1 : 0 ) * constantDetailedFixtureWidth/mmToFeet ) ) ),
1222
+ 'unit': 'ft',
1223
+ },
1224
+ 'productResolutionLevel': 'L2',
1225
+ };
1226
+
1227
+ const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
1228
+
1229
+ // console.log( 'Fixture Data', fixtureData );
1230
+
1231
+ const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
1232
+
1233
+ for ( let i = 0; i < vms?.length; i++ ) {
1234
+ const vmTemplate = await planoProductService.findOne( { productId: vms[i] } );
1235
+
1236
+ if ( vmTemplate ) {
1237
+ const vmData = {
1238
+ 'clientId': layoutDoc.clientId,
1239
+ 'storeName': layoutDoc.storeName,
1240
+ 'storeId': layoutDoc.storeId,
1241
+ 'planoId': layoutDoc.planoId,
1242
+ 'floorId': layoutDoc._id,
1243
+ 'type': 'vm',
1244
+ 'fixtureId': createdFixture._id,
1245
+ 'productId': vmTemplate._id,
1246
+ };
1247
+
1248
+ await planoMappingService.create( vmData );
1249
+ }
1250
+ }
1251
+
1252
+ const fixtureConfig = await fixtureConfigService.findOne( { fixtureCode: fixture?.['Fixture ID'] } );
1253
+
1254
+ if ( fixtureConfig ) {
1255
+ let shelfIndex = 0;
1256
+
1257
+ for ( const section of fixtureConfig.sections ) {
1258
+ const storeCategory = fixture.categories.find( ( cat ) => cat.Zone === section.sectionId );
1259
+ for ( let j = 0; j < section.sectionShelves; j++ ) {
1260
+ if ( shelfIndex >= fixtureConfig.shelfCount ) break;
1261
+
1262
+ const shelfData = {
1263
+ 'clientId': fixtureConfig.clientId,
1264
+ 'storeName': layoutDoc.storeName,
1265
+ 'storeId': layoutDoc.storeId,
1266
+ 'planoId': layoutDoc.planoId,
1267
+ 'floorId': layoutDoc._id,
1268
+ 'fixtureId': createdFixture._id,
1269
+ 'shelfNumber': shelfIndex + 1,
1270
+ 'shelfOrder': 'LTR',
1271
+ 'shelfCapacity': fixtureConfig.productPerShelf,
1272
+ 'sectionName': storeCategory ? storeCategory?.['Allocation'] : 'Unknown',
1273
+ 'sectionZone': section.sectionId,
1274
+ };
1275
+
1276
+ const createdShelf = await fixtureShelfService.create( shelfData );
1277
+
1278
+ // console.log( 'Shelf Data:', createdShelf );
1279
+
1280
+ shelfIndex++;
1281
+ }
1282
+ }
1283
+ }
1284
+ }
1285
+
1286
+ for ( let index = 0; index < rightFixtures.length; index++ ) {
1287
+ const fixture = rightFixtures[index];
1288
+
1289
+ const fixtureData = {
1290
+ 'clientId': layoutDoc.clientId,
1291
+ 'storeName': layoutDoc.storeName,
1292
+ 'storeId': layoutDoc.storeId,
1293
+ 'planoId': layoutDoc.planoId,
1294
+ 'floorId': layoutDoc._id,
1295
+ 'fixtureName': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1296
+ 'fixtureCategory': fixture?.['Fixture Category'] ? fixture?.['Fixture Category'] : 'nil',
1297
+ 'fixtureBrandCategory': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1298
+ 'fixtureBrandSubCategory': fixture?.['Brand - Sub Category'] ? fixture?.['Brand - Sub Category'] : 'nil',
1299
+ 'fixtureCode': fixture?.['Fixture ID'],
1300
+ 'fixtureCapacity': fixture?.['Capacity'],
1301
+ 'fixtureType': 'wall',
1302
+ 'fixtureHeight': {
1303
+ 'value': 0,
1304
+ 'unit': 'mm',
1305
+ },
1306
+ 'fixtureLength': {
1307
+ 'value': constantFixtureLength,
1308
+ 'unit': 'mm',
1309
+ },
1310
+ 'fixtureWidth': {
1311
+ 'value': constantFixtureWidth,
1312
+ 'unit': 'mm',
1313
+ },
1314
+ 'associatedElementType': 'wall',
1315
+ 'associatedElementNumber': 3,
1316
+ 'relativePosition': {
1317
+ 'x': roundToTwo( ( index * ( constantFixtureLength / mmToFeet ) ) ),
1318
+ 'y': roundToTwo( ( finalYDistance - ( constantFixtureWidth / mmToFeet ) ) ),
1319
+ 'unit': 'ft',
1320
+ },
1321
+ 'fixtureNumber': fixtureCounter++,
1322
+ 'detailedFixtureLength': {
1323
+ 'value': constantDetailedFixtureLength,
1324
+ 'unit': 'mm',
1325
+ },
1326
+ 'detailedFixtureWidth': {
1327
+ 'value': constantDetailedFixtureWidth,
1328
+ 'unit': 'mm',
1329
+ },
1330
+ 'relativeDetailedPosition': {
1331
+ 'x': roundToTwo( ( index * ( constantDetailedFixtureLength / mmToFeet ) ) ),
1332
+ 'y': roundToTwo( ( finalYDetailedDistance - ( constantDetailedFixtureWidth / mmToFeet ) ) ),
1333
+ 'unit': 'ft',
1334
+ },
1335
+ 'productResolutionLevel': 'L2',
1336
+ };
1337
+
1338
+ const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
1339
+
1340
+ // console.log( 'Fixture Data', fixtureData );
1341
+
1342
+ const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
1343
+
1344
+ for ( let i = 0; i < vms?.length; i++ ) {
1345
+ const vmTemplate = await planoProductService.findOne( { productId: vms[i] } );
1346
+
1347
+ if ( vmTemplate ) {
1348
+ const vmData = {
1349
+ 'clientId': layoutDoc.clientId,
1350
+ 'storeName': layoutDoc.storeName,
1351
+ 'storeId': layoutDoc.storeId,
1352
+ 'planoId': layoutDoc.planoId,
1353
+ 'floorId': layoutDoc._id,
1354
+ 'type': 'vm',
1355
+ 'fixtureId': createdFixture._id,
1356
+ 'productId': vmTemplate._id,
1357
+ };
1358
+
1359
+ await planoMappingService.create( vmData );
1360
+ }
1361
+ }
1362
+
1363
+ const fixtureConfig = await fixtureConfigService.findOne( { fixtureCode: fixture?.['Fixture ID'] } );
1364
+
1365
+ if ( fixtureConfig ) {
1366
+ let shelfIndex = 0;
1367
+
1368
+ for ( const section of fixtureConfig.sections ) {
1369
+ const storeCategory = fixture.categories.find( ( cat ) => cat.Zone === section.sectionId );
1370
+ for ( let j = 0; j < section.sectionShelves; j++ ) {
1371
+ if ( shelfIndex >= fixtureConfig.shelfCount ) break;
1372
+
1373
+ const shelfData = {
1374
+ 'clientId': fixtureConfig.clientId,
1375
+ 'storeName': layoutDoc.storeName,
1376
+ 'storeId': layoutDoc.storeId,
1377
+ 'planoId': layoutDoc.planoId,
1378
+ 'floorId': layoutDoc._id,
1379
+ 'fixtureId': createdFixture._id,
1380
+ 'shelfNumber': shelfIndex + 1,
1381
+ 'shelfOrder': 'LTR',
1382
+ 'shelfCapacity': fixtureConfig.productPerShelf,
1383
+ 'sectionName': storeCategory ? storeCategory?.['Allocation'] : 'Unknown',
1384
+ 'sectionZone': section.sectionId,
1385
+ };
1386
+
1387
+ await fixtureShelfService.create( shelfData );
1388
+
1389
+ // console.log( 'Shelf Data:', createdShelf );
1390
+
1391
+ shelfIndex++;
1392
+ }
1393
+ }
1394
+ }
1395
+ }
1396
+
1397
+ for ( let index = 0; index < floorFixtures.length; index++ ) {
1398
+ const fixture = floorFixtures[index];
1399
+
1400
+ const centerRow = Math.floor( totalRows / 2 );
1401
+
1402
+ const startingX =roundToTwo( ( ( finalXDistance / 2 ) - ( ( maxFixturesPerRow / 2 ) * ( constantFixtureLength / mmToFeet ) ) ) );
1403
+ const detailedStartingX = roundToTwo( ( ( finalXDetailedDistance / 2 ) - ( ( maxFixturesPerRow / 2 ) * ( constantDetailedFixtureLength / mmToFeet ) ) ) );
1404
+
1405
+ const startingY = ( finalYDistance / 2 ) - ( centerRow * ( constantFixtureWidth / mmToFeet ) );
1406
+ const detailedStartingY = ( finalYDetailedDistance / 2 ) - ( centerRow * ( constantDetailedFixtureWidth / mmToFeet ) );
1407
+
1408
+ const rowIndex = Math.floor( index / maxFixturesPerRow );
1409
+ const colIndex = index % maxFixturesPerRow;
1410
+
1411
+ const xPos = roundToTwo( ( startingX + colIndex * ( constantFixtureLength / mmToFeet ) ) );
1412
+ const yPos = roundToTwo( ( startingY + rowIndex * ( constantFixtureWidth / mmToFeet ) ) );
1413
+
1414
+ const detailedXPos = roundToTwo( ( detailedStartingX + colIndex * ( constantDetailedFixtureLength / mmToFeet ) ) );
1415
+ const detailedYPos = roundToTwo( ( detailedStartingY + rowIndex * ( constantDetailedFixtureWidth / mmToFeet ) ) );
1416
+
1417
+ const fixtureData = {
1418
+ 'clientId': layoutDoc.clientId,
1419
+ 'storeName': layoutDoc.storeName,
1420
+ 'storeId': layoutDoc.storeId,
1421
+ 'planoId': layoutDoc.planoId,
1422
+ 'floorId': layoutDoc._id,
1423
+ 'fixtureName': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1424
+ 'fixtureCategory': fixture?.['Fixture Category'] ? fixture?.['Fixture Category'] : 'nil',
1425
+ 'fixtureBrandCategory': fixture?.['Brand-Category'] ? fixture?.['Brand-Category'] : 'nil',
1426
+ 'fixtureBrandSubCategory': fixture?.['Brand - Sub Category'] ? fixture?.['Brand - Sub Category'] : 'nil',
1427
+ 'fixtureCode': fixture?.['Fixture ID'],
1428
+ 'fixtureCapacity': fixture?.['Capacity'],
1429
+ 'fixtureType': 'floor',
1430
+ 'fixtureHeight': {
1431
+ 'value': 0,
1432
+ 'unit': 'mm',
1433
+ },
1434
+ 'fixtureLength': {
1435
+ 'value': constantFixtureLength,
1436
+ 'unit': 'mm',
1437
+ },
1438
+ 'fixtureWidth': {
1439
+ 'value': constantFixtureWidth,
1440
+ 'unit': 'mm',
1441
+ },
1442
+ 'relativePosition': {
1443
+ 'x': xPos,
1444
+ 'y': yPos,
1445
+ 'unit': 'ft',
1446
+ },
1447
+ 'fixtureNumber': fixtureCounter++,
1448
+ 'detailedFixtureLength': {
1449
+ 'value': constantDetailedFixtureLength,
1450
+ 'unit': 'mm',
1451
+ },
1452
+ 'detailedFixtureWidth': {
1453
+ 'value': constantDetailedFixtureWidth,
1454
+ 'unit': 'mm',
1455
+ },
1456
+ 'relativeDetailedPosition': {
1457
+ 'x': detailedXPos,
1458
+ 'y': detailedYPos,
1459
+ 'unit': 'ft',
1460
+ },
1461
+ 'productResolutionLevel': 'L2',
1462
+ };
1463
+
1464
+ const createdFixture = await storeFixtureService.findOneAndUpdate2( { storeName: layoutDoc.storeName, fixtureNumber: fixture?.['fixtureNumber'] }, { fixtureCode: fixture?.['Fixture ID'] } );
1465
+ // console.log( 'Fixture Data', fixtureData );
1466
+
1467
+ const vms = typeof fixture?.['VM Template ID'] === 'string' ? fixture?.['VM Template ID']?.split( ', ' ).map( ( item ) => item.trim() ) : [];
1468
+
1469
+ for ( let i = 0; i < vms?.length; i++ ) {
1470
+ const vmTemplate = await planoProductService.findOne( { productId: vms[i] } );
1471
+
1472
+ if ( vmTemplate ) {
1473
+ const vmData = {
1474
+ 'clientId': layoutDoc.clientId,
1475
+ 'storeName': layoutDoc.storeName,
1476
+ 'storeId': layoutDoc.storeId,
1477
+ 'planoId': layoutDoc.planoId,
1478
+ 'floorId': layoutDoc._id,
1479
+ 'type': 'vm',
1480
+ 'fixtureId': createdFixture._id,
1481
+ 'productId': vmTemplate._id,
1482
+ };
1483
+
1484
+ await planoMappingService.create( vmData );
1485
+ }
1486
+ }
1487
+
1488
+
1489
+ const fixtureConfig = await fixtureConfigService.findOne( { fixtureCode: fixture?.['Fixture ID'] } );
1490
+
1491
+ if ( fixtureConfig ) {
1492
+ let shelfIndex = 0;
1493
+
1494
+ for ( const section of fixtureConfig.sections ) {
1495
+ const storeCategory = fixture.categories.find( ( cat ) => cat.Zone === section.sectionId );
1496
+ for ( let j = 0; j < section.sectionShelves; j++ ) {
1497
+ if ( shelfIndex >= fixtureConfig.shelfCount ) break;
1498
+
1499
+ const shelfData = {
1500
+ 'clientId': fixtureConfig.clientId,
1501
+ 'storeName': layoutDoc.storeName,
1502
+ 'storeId': layoutDoc.storeId,
1503
+ 'planoId': layoutDoc.planoId,
1504
+ 'floorId': layoutDoc._id,
1505
+ 'fixtureId': createdFixture._id,
1506
+ 'shelfNumber': shelfIndex + 1,
1507
+ 'shelfOrder': 'LTR',
1508
+ 'shelfCapacity': fixtureConfig.productPerShelf,
1509
+ 'sectionName': storeCategory ? storeCategory?.['Allocation'] : 'Unknown',
1510
+ 'sectionZone': section.sectionId,
1511
+ };
1512
+
1513
+ await fixtureShelfService.create( shelfData );
1514
+
1515
+ // console.log( 'Shelf Data:', createdShelf );
1516
+
1517
+ shelfIndex++;
1518
+ }
1519
+ }
1520
+ }
1521
+ }
1522
+ }
1523
+
1524
+
1525
+ return res.sendSuccess( 'Updated successfully' );
1526
+ } catch ( e ) {
1527
+ logger.error( { functionName: 'createFixturesShelves', error: e } );
1528
+ return res.sendError( e.message || 'Internal Server Error', 500 );
1529
+ }
1530
+ }
1531
+
784
1532
  export async function createVmData( req, res ) {
785
1533
  try {
786
1534
  if ( !req.files.file ) {
@@ -598,7 +598,7 @@ export async function storeFixturesv1( req, res ) {
598
598
  date: currentDate,
599
599
  } );
600
600
 
601
- const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1, sectionName: 1, sectionZone: 1 } );
601
+ const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1, sectionName: 1, sectionZone: 1, shelfCapacity: 1 } );
602
602
 
603
603
  const shelfDetails = await Promise.all(
604
604
  shelves.map( async ( shelf ) => {
@@ -692,7 +692,7 @@ export async function storeFixturesv1( req, res ) {
692
692
  date: currentDate,
693
693
  } );
694
694
 
695
- const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1, sectionName: 1, sectionZone: 1 } );
695
+ const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1, sectionName: 1, sectionZone: 1, shelfCapacity: 1 } );
696
696
 
697
697
  const shelfDetails = await Promise.all(
698
698
  shelves.map( async ( shelf ) => {
@@ -2017,7 +2017,7 @@ export async function storeFixturesTask( req, res ) {
2017
2017
  type: req.body?.type ? req.body.type : 'fixture',
2018
2018
  }, { status: 1 } );
2019
2019
 
2020
- const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1 } );
2020
+ const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1, sectionName: 1, sectionZone: 1, shelfCapacity: 1 } );
2021
2021
 
2022
2022
  const shelfDetails = await Promise.all(
2023
2023
  shelves.map( async ( shelf ) => {
@@ -2084,7 +2084,7 @@ export async function storeFixturesTask( req, res ) {
2084
2084
  type: req.body?.type ? req.body.type : 'fixture',
2085
2085
  }, { status: 1 } );
2086
2086
 
2087
- const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1 } );
2087
+ const shelves = await fixtureShelfService.find( { fixtureId: fixture._id }, { shelfNumber: 1, sectionName: 1, sectionZone: 1, shelfCapacity: 1 } );
2088
2088
 
2089
2089
  const shelfDetails = await Promise.all(
2090
2090
  shelves.map( async ( shelf ) => {
@@ -10,4 +10,5 @@ scriptRouter
10
10
  .post( '/bulkInsertPlanoData', scriptController.createPlano )
11
11
  .post( '/bulkIinsertFloorData', scriptController.createFloors )
12
12
  .post( '/bulkIinsertVmTemplateData', scriptController.createVmData )
13
- .post( '/bulkIinsertFixturesShelvesVmsData', scriptController.createFixturesShelves );
13
+ .post( '/bulkIinsertFixturesShelvesVmsData', scriptController.createFixturesShelves )
14
+ .post( '/updateFixturesShelvesVms', scriptController.updateFixturesShelves );
@@ -24,6 +24,10 @@ export async function findOneAndUpdate( query={}, field={} ) {
24
24
  return model.storeFixtureModel.findOneAndUpdate( query, field );
25
25
  }
26
26
 
27
+ export async function findOneAndUpdate2( query={}, field={} ) {
28
+ return model.storeFixtureModel.findOneAndUpdate( query, field, { new: true } );
29
+ }
30
+
27
31
  export async function create( data ) {
28
32
  return model.storeFixtureModel.create( data );
29
33
  }