tango-app-api-store-builder 1.0.60 → 1.1.2

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.
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-store-builder",
3
- "version": "1.0.60",
3
+ "version": "1.1.2",
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.39",
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",
@@ -1930,7 +1930,8 @@ export async function getPlanoRevisionById( req, res ) {
1930
1930
  },
1931
1931
  ];
1932
1932
  let complianceStatus = await planoComplianceService.aggregate( complianceQuery );
1933
- shelf.compliance = complianceStatus?.[0]?.status.length ? ( ( complianceStatus?.[0]?.status?.length < shelf.productPerShelf ) || complianceStatus?.[0]?.status?.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
1933
+ let productCount = shelf.shelfType == 'tray' ? shelf.productPerShelf * shelf.trayRows : shelf.productPerShelf;
1934
+ shelf.compliance = complianceStatus?.[0]?.status.length ? ( ( complianceStatus?.[0]?.status?.length < productCount ) || complianceStatus?.[0]?.status?.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
1934
1935
  return shelf;
1935
1936
  } ) );
1936
1937
  fixture.vmConfig = await Promise.all( fixture.vmConfig.map( async ( vm ) => {
@@ -1971,7 +1972,8 @@ export async function getPlanoRevisionById( req, res ) {
1971
1972
  },
1972
1973
  ];
1973
1974
  let complianceStatus = await planoComplianceService.aggregate( complianceQuery );
1974
- shelf.compliance = complianceStatus?.[0]?.status.length ? ( ( complianceStatus?.[0]?.status?.length < shelf.productPerShelf ) || complianceStatus?.[0]?.status?.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
1975
+ let productCount = shelf.shelfType == 'tray' ? shelf.productPerShelf * shelf.trayRows : shelf.productPerShelf;
1976
+ shelf.compliance = complianceStatus?.[0]?.status.length ? ( ( complianceStatus?.[0]?.status?.length < productCount ) || complianceStatus?.[0]?.status?.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
1975
1977
  return shelf;
1976
1978
  } ) );
1977
1979
  return fixture;
@@ -27,7 +27,7 @@ import * as fixtureConfigDuplicateService from '../service/fixtureConfigDuplicat
27
27
  import * as planoVmDuplicateService from '../service/planoVmDuplicate.service.js';
28
28
  import advancedFormat from 'dayjs/plugin/advancedFormat.js';
29
29
  import * as planoRevisionService from '../service/planoRevision.service.js';
30
- // import xlsx from 'xlsx';
30
+ import xlsx from 'xlsx';
31
31
  // import fs from 'fs';
32
32
 
33
33
  dayjs.extend( advancedFormat );
@@ -8182,6 +8182,10 @@ export async function updateProductMappingNew( req, res ) {
8182
8182
  if ( !storeDetails.length ) {
8183
8183
  return res.sendError( 'No data found', 204 );
8184
8184
  }
8185
+ const inventoryWorkBook = xlsx.readFile( './data/sheet_for_inventory.xlsx' );
8186
+ const productInventorySheet = inventoryWorkBook.SheetNames[0];
8187
+ const inventorySheet = inventoryWorkBook.Sheets[productInventorySheet];
8188
+ const inventoryData = xlsx.utils.sheet_to_json( inventorySheet );
8185
8189
  await Promise.all( storeDetails.map( async ( store ) => {
8186
8190
  // let number = Number( store.storeName.replace( /\D/g, '' ) );
8187
8191
  const getLatestData = await fetch(
@@ -8217,6 +8221,12 @@ export async function updateProductMappingNew( req, res ) {
8217
8221
  'brandName': 'NA',
8218
8222
  'category': 'NA',
8219
8223
  };
8224
+ let getPidFromInventory = inventoryData.find( ( inv ) => inv.barcode == text );
8225
+ if ( getPidFromInventory ) {
8226
+ productData.productBrand = getPidFromInventory.brand;
8227
+ productData.productType = getPidFromInventory.product_type;
8228
+ productData.pid = getPidFromInventory.product_id;
8229
+ }
8220
8230
 
8221
8231
  product = await planoProductService.create( productData );
8222
8232
  }
@@ -8245,7 +8255,7 @@ export async function updateProductMappingNew( req, res ) {
8245
8255
  'planoMappingId': '',
8246
8256
  'date': dayjs().format( 'YYYY-MM-DD' ),
8247
8257
  'clientId': req.body.clientId,
8248
- 'compliance': ele?.shelfType != 'storage' ? ( ele?.productBrandName?.split( ',' )?.map( ( element ) => element.trim() )?.includes( product?.brandName ) || fixtureTemplate?.templateGroupName == product?.brandGroup )? 'proper' : 'misplaced' : '',
8258
+ 'compliance': ele?.shelfType != 'storage' ? ( ele?.productBrandName?.split( ',' )?.map( ( element ) => element.trim() )?.includes( product?.brandName ) || fixtureTemplate?.templateGroupName == product?.brandGroup ) || fixtureTemplate?.templateGroupName?.slice( 0, 2 ) == product?.brandGroup?.slice( 0, 2 ) || fixtureTemplate?.templateGroupName == product.productBrand? 'proper' : 'misplaced' : '',
8249
8259
  'fixtureId': ele?.fixtureId,
8250
8260
  'floorId': ele?.floorId,
8251
8261
  'planoId': ele?.planoId,
@@ -8318,11 +8328,19 @@ export async function calculateCompliance( req, res ) {
8318
8328
  {
8319
8329
  $group: {
8320
8330
  _id: '$createdAt',
8331
+ productCount: { $sum: {
8332
+ $cond: {
8333
+ if: { $eq: [ '$type', 'product' ] },
8334
+ then: 1,
8335
+ else: 0,
8336
+ } },
8337
+ },
8321
8338
  },
8322
8339
  },
8323
8340
  {
8324
8341
  $project: {
8325
8342
  _id: 0,
8343
+ productCount: 1,
8326
8344
  date: '$_id',
8327
8345
  count: 1,
8328
8346
  time: {
@@ -8436,6 +8454,7 @@ export async function calculateCompliance( req, res ) {
8436
8454
  lastCheck: null,
8437
8455
  missedCount: getCompliance?.[0]?.missedCount,
8438
8456
  misplacedCount: getCompliance?.[0]?.misplacedCount,
8457
+ productCount: getCompliance?.[0]?.productCount,
8439
8458
  };
8440
8459
  if ( getCompliance.length ) {
8441
8460
  // let productCountQuery = [
@@ -9491,6 +9510,7 @@ export async function getFixtureShelfRfidDetails( req, res ) {
9491
9510
  fixtureNumber: fixt?.associatedElementFixtureNumber,
9492
9511
  storage: fixt?.footer?.antennaNo,
9493
9512
  header: fixt?.header?.label,
9513
+ brandName: fixt?.templateGroupName,
9494
9514
  shelves: fixtureShelf,
9495
9515
  };
9496
9516
  result.push( data );
@@ -9503,3 +9523,111 @@ export async function getFixtureShelfRfidDetails( req, res ) {
9503
9523
  return res.sendError( e, 500 );
9504
9524
  }
9505
9525
  }
9526
+
9527
+ export async function getFixtureFootfall( req, res ) {
9528
+ try {
9529
+ let inputData = req.body;
9530
+ let response = await fetch( JSON.parse( process.env.LAMBDAURL )?.footfallLambda, {
9531
+ method: 'POST',
9532
+ body: JSON.stringify( inputData ),
9533
+ } );
9534
+ if ( response.status == 200 ) {
9535
+ let data = await response.json();
9536
+ return res.sendSuccess( data );
9537
+ }
9538
+ return res.sendError( 'Something went wrong', 400 );
9539
+ } catch ( e ) {
9540
+ logger.error( { functionName: 'getFixtureFootfall', error: e } );
9541
+ return res.sendError( e, 500 );
9542
+ }
9543
+ }
9544
+
9545
+ export async function getTopPerformingZones( req, res ) {
9546
+ try {
9547
+ let inputData = req.body;
9548
+ let planoDetails = await planoService.findOne( { storeName: 'LKST4487' } );
9549
+ let storeFixtureDetails = await storeFixtureService.find( { planoId: planoDetails._id, fixtureType: { $ne: 'other' } }, { _id: 1, header: 1, associatedElementNumber: 1, associatedElementFixtureNumber: 1 } );
9550
+ let shelfDetails = await fixtureShelfService.find( { planoId: planoDetails._id } );
9551
+ storeFixtureDetails.forEach( ( ele ) => {
9552
+ ele['productName'] = [ ...new Set( shelfDetails.filter( ( shelf ) => shelf.fixtureId.toString() == ele?._id?.toString() )?.flatMap( ( shelf ) => shelf.productBrandName ) ) ];
9553
+ } );
9554
+ let response = await fetch( JSON.parse( process.env.LAMBDAURL )?.zoneLambda, {
9555
+ method: 'POST',
9556
+ body: JSON.stringify( inputData ),
9557
+ } );
9558
+ if ( response.status == 200 ) {
9559
+ let data = await response.json();
9560
+ data?.topPerformingZones?.forEach( ( ele ) => {
9561
+ let fixturedetails = storeFixtureDetails.filter( ( fixt ) => fixt.header.label == ele.zoneName );
9562
+ ele.zoneProduct = [ ...new Set( fixturedetails?.flatMap( ( fixt ) => fixt.productName ) ) ];
9563
+ ele.wallNumber = fixturedetails?.[0]?.associatedElementNumber;
9564
+ ele.position = fixturedetails?.[0]?.associatedElementFixtureNumber;
9565
+ } );
9566
+ return res.sendSuccess( data );
9567
+ }
9568
+ return res.sendError( 'Something went wrong', 400 );
9569
+ } catch ( e ) {
9570
+ logger.error( { functionName: 'getFixtureZoneDetails', error: e } );
9571
+ return res.sendError( e, 500 );
9572
+ }
9573
+ }
9574
+
9575
+ export async function getStoreEngagers( req, res ) {
9576
+ try {
9577
+ let inputData = req.body;
9578
+ let response = await fetch( JSON.parse( process.env.LAMBDAURL )?.engagersLambda, {
9579
+ method: 'POST',
9580
+ body: JSON.stringify( inputData ),
9581
+ } );
9582
+ if ( response.status == 200 ) {
9583
+ let fixtureData = await response.json();
9584
+ let result = {};
9585
+ await Promise.all( Object.keys( fixtureData?.data ).map( async ( ele ) => {
9586
+ result[`${ele}`] = [];
9587
+ fixtureData.data.ele = await Promise.all( fixtureData?.data?.[ele].map( async ( product ) => {
9588
+ let productDetails = await planoProductService.findOne( { brandGroup: product.Brandname, productImageUrl: { $ne: '' } } );
9589
+ if ( productDetails ) {
9590
+ product.imageUrl = productDetails.productImageUrl;
9591
+ }
9592
+ result[ele].push( product );
9593
+ } ) );
9594
+ result[`${ele}`].sort( ( a, b ) => b.count - a.count );
9595
+ } ) );
9596
+ return res.sendSuccess( result );
9597
+ }
9598
+ return res.sendError( 'Something went wrong', 400 );
9599
+ } catch ( e ) {
9600
+ logger.error( { functionName: 'getFixtureEngagersList', error: e } );
9601
+ return res.sendError( e, 500 );
9602
+ }
9603
+ }
9604
+
9605
+ export async function getStoreFixtureEngagers( req, res ) {
9606
+ try {
9607
+ let inputData = req.body;
9608
+ let response = await fetch( JSON.parse( process.env.LAMBDAURL )?.fixtureEngagers, {
9609
+ method: 'POST',
9610
+ body: JSON.stringify( inputData ),
9611
+ } );
9612
+ if ( response.status == 200 ) {
9613
+ let fixtureData = await response.json();
9614
+ let result = {};
9615
+ await Promise.all( Object.keys( fixtureData?.data ).map( async ( ele ) => {
9616
+ result[`${ele}`] = [];
9617
+ fixtureData.data.ele = await Promise.all( fixtureData?.data?.[ele].map( async ( product ) => {
9618
+ let productDetails = await planoProductService.findOne( { brandGroup: product.Brandname, productImageUrl: { $ne: '' } } );
9619
+ if ( productDetails ) {
9620
+ product.imageUrl = productDetails.productImageUrl;
9621
+ }
9622
+ result[ele].push( product );
9623
+ } ) );
9624
+ result[`${ele}`].sort( ( a, b ) => a.count - b.count );
9625
+ } ) );
9626
+ return res.sendSuccess( fixtureData );
9627
+ }
9628
+ return res.sendError( 'Something went wrong', 400 );
9629
+ } catch ( e ) {
9630
+ logger.error( { functionName: 'getFixtureEngagersDetails', error: e } );
9631
+ return res.sendError( e, 500 );
9632
+ }
9633
+ }
@@ -610,6 +610,50 @@ export async function updateStatus( req, res ) {
610
610
  }
611
611
  }
612
612
 
613
+ if ( req.body.status == 'submit' && taskDetails.planoType == 'fixture' ) {
614
+ let fixtureData = await storeFixtureService.find( { planoId: taskDetails.planoId, floorId: taskDetails.floorId } );
615
+ let fixtureList = [];
616
+ await Promise.all( fixtureData.map( async ( fixt ) => {
617
+ let fixtureTask = await planoTaskService.findOne(
618
+ {
619
+ planoId: new mongoose.Types.ObjectId( fixt.planoId ),
620
+ floorId: new mongoose.Types.ObjectId( fixt.floorId ),
621
+ taskId: new mongoose.Types.ObjectId( taskDetails._id ),
622
+ fixtureId: new mongoose.Types.ObjectId( fixt._id ),
623
+ type: 'fixture',
624
+ approvalStatus: 'pending',
625
+ },
626
+ );
627
+
628
+
629
+ fixt = fixt?.toObject();
630
+
631
+ let fixtureShelves = await fixtureShelfService.find( { fixtureId: fixt._id } );
632
+
633
+ if ( fixtureShelves.length ) {
634
+ fixtureShelves = fixtureShelves.map( ( shelf ) => shelf?.toObject() );
635
+ fixt.shelfConfig = fixtureShelves;
636
+ }
637
+ if ( fixtureTask ) {
638
+ fixtureList.push( {
639
+ imagePath: fixtureTask?.answers[0]?.image,
640
+ fixtureId: fixt._id,
641
+ fixtureData: fixt,
642
+ } );
643
+ }
644
+ } ) );
645
+ let sqsData = {
646
+ bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
647
+ date_string: dayjs().format( 'YYYY-MM-DD' ),
648
+ storeName: taskDetails?.storeName,
649
+ taskId: taskDetails?._id,
650
+ fixtureList: fixtureList,
651
+ };
652
+
653
+ const sqs = JSON.parse( process.env.SQS );
654
+ await sendMessageToQueue( `${sqs.url}${sqs.fixtureImageProcess}`, JSON.stringify( sqsData ) );
655
+ }
656
+
613
657
  // if ( req.body.status == 'submit' && [ 'merchRollout', 'vmRollout' ].includes( taskDetails.planoType ) ) {
614
658
  // let merchVmTaskDetails = await planoTaskService.find(
615
659
  // {
@@ -734,33 +778,34 @@ export async function updateAnswersv2( req, res ) {
734
778
  await sendMessageToQueue( `${sqs.url}${sqs.storeBuilder}`, JSON.stringify( sqsData ) );
735
779
  }
736
780
 
737
- if ( req.body.type === 'fixture' ) {
738
- let fixtureData = await storeFixtureService.findOne( { _id: new mongoose.Types.ObjectId( req.body.fixtureId ) } );
781
+ // if ( req.body.type === 'fixture' ) {
782
+ // let fixtureData = await storeFixtureService.findOne( { _id: new mongoose.Types.ObjectId( req.body.fixtureId ) } );
739
783
 
740
- if ( fixtureData ) {
741
- fixtureData = fixtureData?.toObject();
784
+ // if ( fixtureData ) {
785
+ // fixtureData = fixtureData?.toObject();
742
786
 
743
- let fixtureShelves = await fixtureShelfService.find( { fixtureId: fixtureData._id } );
787
+ // let fixtureShelves = await fixtureShelfService.find( { fixtureId: fixtureData._id } );
744
788
 
745
- if ( fixtureShelves.length ) {
746
- fixtureShelves = fixtureShelves.map( ( shelf ) => shelf?.toObject() );
789
+ // if ( fixtureShelves.length ) {
790
+ // fixtureShelves = fixtureShelves.map( ( shelf ) => shelf?.toObject() );
747
791
 
748
- fixtureData.shelfConfig = fixtureShelves;
749
- }
750
- }
792
+ // fixtureData.shelfConfig = fixtureShelves;
793
+ // }
794
+ // }
751
795
 
752
- let sqsData = {
753
- bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
754
- date_string: dayjs().format( 'YYYY-MM-DD' ),
755
- storeName: data?.storeName,
756
- imagePath: data?.answers[0]?.image,
757
- fixtureId: req.body.fixtureId,
758
- fixtureData: fixtureData,
759
- };
796
+ // let sqsData = {
797
+ // bucket: JSON.parse( process.env.BUCKET ).storeBuilder,
798
+ // date_string: dayjs().format( 'YYYY-MM-DD' ),
799
+ // storeName: data?.storeName,
800
+ // fixtureList:[]
801
+ // imagePath: data?.answers[0]?.image,
802
+ // fixtureId: req.body.fixtureId,
803
+ // fixtureData: fixtureData,
804
+ // };
760
805
 
761
- const sqs = JSON.parse( process.env.SQS );
762
- await sendMessageToQueue( `${sqs.url}${sqs.fixtureImageProcess}`, JSON.stringify( sqsData ) );
763
- }
806
+ // const sqs = JSON.parse( process.env.SQS );
807
+ // await sendMessageToQueue( `${sqs.url}${sqs.fixtureImageProcess}`, JSON.stringify( sqsData ) );
808
+ // }
764
809
 
765
810
 
766
811
  return res.sendSuccess( 'Fixture details updated successfully' );
@@ -1136,3 +1181,21 @@ export async function revokeTask( req, res ) {
1136
1181
  return res.sendError( e, 500 );
1137
1182
  }
1138
1183
  }
1184
+
1185
+ export async function validateTask( req, res ) {
1186
+ try {
1187
+ if ( !req.body.fixtureList?.length ) {
1188
+ return res.sendError( 'fixtureId is required', 400 );
1189
+ }
1190
+ if ( !req.body.taskId ) {
1191
+ return res.sendError( 'TaskId is required', 400 );
1192
+ }
1193
+ req.body.fixtureList = req.body.fixtureList.map( ( ele ) => new mongoose.Types.ObjectId( ele ) );
1194
+ await planoTaskService.updateMany( { taskId: req.body.taskId, fixtureId: { $in: req.body.fixtureList }, type: 'fixture' }, { 'answers.0.status': 'disagree', 'approvalStatus': 'approved', 'answers.0.userAction': 'redo' } );
1195
+ await processedService.updateOne( { _id: req.body.taskId }, { checklistStatus: 'open', redoStatus: true, autoRedo: true } );
1196
+ return res.sendSuccess( 'Redo task created successfully' );
1197
+ } catch ( e ) {
1198
+ logger.error( { functionName: 'validateTask', error: e } );
1199
+ return res.sendError( e, 400 );
1200
+ }
1201
+ }
@@ -74,5 +74,9 @@ storeBuilderRouter
74
74
  .get( '/getStoreFloorsList', isAllowedSessionHandler, storeBuilderController.getStoreFloorsList )
75
75
  .post( '/getShelfDetails', isAllowedInternalAPIHandler, storeBuilderController.getShelfDetails )
76
76
  .post( '/getFixtureShelfRfidDetails', isAllowedInternalAPIHandler, storeBuilderController.getFixtureShelfRfidDetails )
77
+ .post( '/getFixtureFootfall', isAllowedSessionHandler, storeBuilderController.getFixtureFootfall )
78
+ .post( '/getTopPerformingZones', isAllowedSessionHandler, storeBuilderController.getTopPerformingZones )
79
+ .post( '/getStoreEngagers', isAllowedSessionHandler, storeBuilderController.getStoreEngagers )
80
+ .post( '/getStoreFixtureEngagers', isAllowedSessionHandler, storeBuilderController.getStoreFixtureEngagers )
77
81
  // .get( '/migrationScript', isAllowedInternalAPIHandler, storeBuilderController.migrationScript )
78
82
  ;
@@ -1,5 +1,5 @@
1
1
  import express from 'express';
2
- import { isAllowedSessionHandler } from 'tango-app-api-middleware';
2
+ import { isAllowedSessionHandler, isAllowedInternalAPIHandler } from 'tango-app-api-middleware';
3
3
  import * as taskController from '../controllers/task.controller.js';
4
4
 
5
5
  export const storeBuilderTaskRouter = express.Router();
@@ -19,4 +19,5 @@ storeBuilderTaskRouter
19
19
  .post( '/redoTask', isAllowedSessionHandler, taskController.redoTask )
20
20
  .post( '/revokeTask', isAllowedSessionHandler, taskController.revokeTask )
21
21
  .get( '/planoTaskDetails', isAllowedSessionHandler, taskController.getPlanoTaskDetails )
22
+ .post( '/validateTask', isAllowedInternalAPIHandler, taskController.validateTask )
22
23
  ;