tango-app-api-store-builder 1.0.0-beta-208 → 1.0.0-beta-210

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-208",
3
+ "version": "1.0.0-beta-210",
4
4
  "description": "storeBuilder",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  "path": "^0.12.7",
33
33
  "selenium-webdriver": "^4.31.0",
34
34
  "sharp": "^0.34.1",
35
- "tango-api-schema": "^2.4.3",
35
+ "tango-api-schema": "^2.4.6",
36
36
  "tango-app-api-middleware": "3.1.48",
37
37
  "url": "^0.11.4",
38
38
  "winston": "^3.17.0",
@@ -1,5 +1,5 @@
1
1
  import * as floorService from '../service/storeBuilder.service.js';
2
- import { logger, insertOpenSearchData } from 'tango-app-api-middleware';
2
+ import { logger, insertOpenSearchData, getOpenSearchData } from 'tango-app-api-middleware';
3
3
  // import * as storeService from '../service/store.service.js';
4
4
  import * as planoService from '../service/planogram.service.js';
5
5
  import * as storeFixtureService from '../service/storeFixture.service.js';
@@ -17,6 +17,7 @@ import * as planoGlobalCommentService from '../service/planoGlobalComment.servic
17
17
  import mongoose from 'mongoose';
18
18
  import * as planoRevisionService from '../service/planoRevision.service.js';
19
19
  import * as planoVmDuplicateService from '../service/planoVmDuplicate.service.js';
20
+ import * as vmTypeService from '../service/vmType.service.js';
20
21
  export async function getplanoFeedback( req, res ) {
21
22
  try {
22
23
  const taskTypes = req.body.filterByTask && req.body.filterByTask.length > 0 ? req.body.filterByTask : [ 'layout', 'fixture', 'vm' ];
@@ -66,6 +67,43 @@ export async function getplanoFeedback( req, res ) {
66
67
  vmComment: commentMap['vm'] || [],
67
68
  };
68
69
 
70
+ response.fixtureData = await Promise.all( response.fixtureData.map( async ( ele ) => {
71
+ if ( ele?.FixtureData ) {
72
+ if ( !ele?.FixtureData._id ) {
73
+ return res.sendError( 'Fixture Id is required', 400 );
74
+ }
75
+ let query = {
76
+ query: {
77
+ bool: {
78
+ must: [
79
+ {
80
+ term: {
81
+ fixtureId: ele?.FixtureData._id,
82
+ },
83
+ },
84
+ ],
85
+ },
86
+ },
87
+ sort: [
88
+ { storeDate: { order: 'desc' } },
89
+ ],
90
+ };
91
+
92
+
93
+ let aiDetails = await getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).planoAIValidation, query );
94
+ if ( aiDetails.statusCode == 200 ) {
95
+ let data = {};
96
+ if ( aiDetails?.body?.hits?.hits.length ) {
97
+ data = aiDetails?.body?.hits?.hits?.[0]?._source;
98
+ delete data.isEmpty;
99
+ delete data.fixtureFound;
100
+ }
101
+ ele.fixtureAIData = data;
102
+ }
103
+ }
104
+ return ele;
105
+ } ) );
106
+
69
107
  res.sendSuccess( response );
70
108
  } catch ( e ) {
71
109
  logger.error( { functionName: 'getplanoFeedback', error: e, message: req.body } );
@@ -713,16 +751,38 @@ export async function updateStorePlano( req, res ) {
713
751
  const currentWallFixtures = data.layoutPolygon.flatMap( ( element ) =>
714
752
  ( element.fixtures || [] ).map( ( fixture ) => fixture ),
715
753
  );
716
-
717
754
  const currentFloorFixtures = ( data.centerFixture || [] );
718
-
719
755
  const currentFixtures = [ ...currentWallFixtures, ...currentFloorFixtures ];
720
756
 
721
- const existingFixtures = await storeFixtureService.find( { floorId: new mongoose.Types.ObjectId( floorId ) } );
757
+ const wallOtherElements = data.layoutPolygon.flatMap( ( element ) =>
758
+ ( element.otherElements || [] ).map( ( el ) => el ),
759
+ );
760
+ const floorOtherElements = ( data.otherElements || [] );
761
+ const currentOtherElements = [ ...wallOtherElements, ...floorOtherElements ];
762
+
763
+ const existingFixtures = await storeFixtureService.find( {
764
+ floorId: new mongoose.Types.ObjectId( floorId ),
765
+ fixtureType: { $ne: 'other' },
766
+ } );
767
+
768
+ const existingOtherElements = await storeFixtureService.find( {
769
+ floorId: new mongoose.Types.ObjectId( floorId ),
770
+ fixtureType: 'other',
771
+ } );
772
+
773
+ const currentOtherElementsIds = new Set( currentOtherElements.map( ( f ) => f._id ) );
774
+ const removedOtherElements = existingOtherElements.filter(
775
+ ( f ) => f._id && !currentOtherElementsIds.has( f._id.toString() ),
776
+ );
722
777
 
723
- const currentIds = new Set( currentFixtures.map( ( f ) => f._id ) );
778
+ if ( removedOtherElements.length ) {
779
+ const otherElementIds = removedOtherElements.map( ( ele ) => ele.toObject()._id );
780
+ await storeFixtureService.deleteMany( { _id: { $in: otherElementIds } } );
781
+ }
782
+
783
+ const currentFixtureIds = new Set( currentFixtures.map( ( f ) => f._id ) );
724
784
  const removedFixtures = existingFixtures.filter(
725
- ( f ) => f._id && !currentIds.has( f._id.toString() ),
785
+ ( f ) => f._id && !currentFixtureIds.has( f._id.toString() ),
726
786
  );
727
787
 
728
788
  if ( removedFixtures.length ) {
@@ -731,9 +791,7 @@ export async function updateStorePlano( req, res ) {
731
791
  await fixtureShelfService.deleteMany( { fixtureId: { $in: fixtureIds } } );
732
792
  }
733
793
 
734
-
735
794
  const newWallFixtures = currentWallFixtures.filter( ( fixture ) => fixture?._id?.startsWith( 'new' ) );
736
-
737
795
  const newFloorFixtures = currentFloorFixtures.filter( ( fixture ) => fixture?._id?.startsWith( 'new' ) );
738
796
 
739
797
  const newFixtures = [ ...newWallFixtures, ...newFloorFixtures ];
@@ -759,6 +817,28 @@ export async function updateStorePlano( req, res ) {
759
817
  } );
760
818
  }
761
819
 
820
+
821
+ const newOtherElements = currentOtherElements.filter( ( ele ) => ele?._id?.startsWith( 'new' ) );
822
+
823
+
824
+ currentOtherElements.forEach( async ( ele ) => {
825
+ if ( ele?._id && mongoose.Types.ObjectId.isValid( ele._id ) ) {
826
+ await storeFixtureService.upsertOne( { _id: new mongoose.Types.ObjectId( ele._id ) }, ele );
827
+ }
828
+ } );
829
+
830
+
831
+ if ( newOtherElements.length ) {
832
+ newOtherElements.forEach( async ( ele ) => {
833
+ delete ele._id;
834
+ const payload = {
835
+ ...ele,
836
+ ...additionalMeta,
837
+ };
838
+ await storeFixtureService.create( payload );
839
+ } );
840
+ }
841
+
762
842
  currentFixtures.forEach( async ( fixture ) => {
763
843
  if ( mongoose.Types.ObjectId.isValid( fixture._id ) ) {
764
844
  const updatedFixture = await storeFixtureService.upsertOne( { _id: new mongoose.Types.ObjectId( fixture._id ) }, fixture );
@@ -859,93 +939,115 @@ export async function updateFixtureStatus( req, res ) {
859
939
  comment: req.body.comments,
860
940
  };
861
941
 
862
-
863
- let updateResponse = await planoTaskService.updateOnefilters(
864
- { _id: new mongoose.Types.ObjectId( req.body._id ) },
865
- {
866
- $set: { 'answers.$[ans].issues.$[iss].Details.$[det].status': req.body.type },
867
- },
868
- [
869
- { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
870
- { 'iss._id': new mongoose.Types.ObjectId( req.body.issueId ) },
871
- { 'det._id': new mongoose.Types.ObjectId( req.body.DetailsId ) },
872
-
873
- ] );
874
- if ( updateResponse && updateResponse.answers.length > 0 ) {
875
- let findissuse = updateResponse.answers[0].issues.filter( ( data ) => data._id == req.body.issueId );
876
- let findDetails = findissuse[0].Details.filter( ( det ) => det.status === 'agree' );
877
- if ( findissuse[0].Details.length === findDetails.length ) {
878
- await planoTaskService.updateOnefilters(
879
- { _id: new mongoose.Types.ObjectId( req.body._id ) },
880
- {
881
- $set: { 'answers.$[ans].issues.$[iss].status': 'completed' },
882
- },
883
- [
884
- { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
885
- { 'iss._id': new mongoose.Types.ObjectId( req.body.issueId ) },
886
- ] );
887
- }
888
- let findoneplanoData = await planoTaskService.findOne( { _id: new mongoose.Types.ObjectId( req.body._id ) } );
889
- let totalApproved = findoneplanoData.answers[0].issues.filter( ( data ) => data.status === 'pending' );
890
- if ( totalApproved.length === 0 ) {
891
- await planoTaskService.updateOne(
892
- {
893
- _id: new mongoose.Types.ObjectId( req.body._id ),
894
- },
895
- {
896
- 'status': 'complete',
897
- },
898
- );
899
- if ( req.body.taskType === 'layout' ) {
900
- await planoTaskService.updateMany(
901
- {
902
- planoId: new mongoose.Types.ObjectId( req.body.planoId ),
903
- floorId: new mongoose.Types.ObjectId( req.body.floorId ),
904
- type: 'layout',
905
- },
906
- {
907
- 'status': 'complete',
908
- },
909
- );
910
- }
911
- }
912
- }
913
-
914
- if ( req.body.taskType === 'layout' ) {
942
+ if ( req.body.taskType.includes( 'fixture' ) ) {
915
943
  await planoTaskService.updateOnefilters(
916
944
  { _id: new mongoose.Types.ObjectId( req.body._id ) },
917
945
  {
918
- $push: { 'answers.$[ans].issues.$[iss].Details.$[det].comments': comments },
946
+ $set: { 'answers.$[ans].status': req.body.type },
919
947
  },
920
948
  [
921
949
  { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
922
- { 'iss._id': new mongoose.Types.ObjectId( req.body.issueId ) },
923
- { 'det._id': new mongoose.Types.ObjectId( req.body.DetailsId ) },
924
950
 
951
+ ],
952
+ );
953
+ await planoTaskService.updateOnefilters(
954
+ { _id: new mongoose.Types.ObjectId( req.body._id ) },
955
+ {
956
+ $push: { 'answers.$[ans].comments': comments },
957
+ },
958
+ [
959
+ { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
925
960
  ] );
961
+
962
+ await planoTaskService.updateOne( { _id: req.body._id }, { approvalStatus: 'approved' } );
926
963
  } else {
927
- await planoTaskService.updateOnefilters(
964
+ let updateResponse = await planoTaskService.updateOnefilters(
928
965
  { _id: new mongoose.Types.ObjectId( req.body._id ) },
929
966
  {
930
- $push: { 'answers.$[ans].issues.$[iss].comments': comments },
967
+ $set: { 'answers.$[ans].issues.$[iss].Details.$[det].status': req.body.type },
931
968
  },
932
969
  [
933
970
  { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
934
971
  { 'iss._id': new mongoose.Types.ObjectId( req.body.issueId ) },
972
+ { 'det._id': new mongoose.Types.ObjectId( req.body.DetailsId ) },
973
+
935
974
  ] );
936
- }
937
- let vmTask = await planoTaskService.find(
938
- {
939
- planoId: new mongoose.Types.ObjectId( req.body.planoId ),
940
- floorId: new mongoose.Types.ObjectId( req.body.floorId ),
941
- type: 'vm',
942
- },
975
+ if ( updateResponse && updateResponse.answers.length > 0 ) {
976
+ let findissuse = updateResponse.answers[0].issues.filter( ( data ) => data._id == req.body.issueId );
977
+ let findDetails = findissuse[0].Details.filter( ( det ) => det.status === 'agree' );
978
+ if ( findissuse[0].Details.length === findDetails.length ) {
979
+ await planoTaskService.updateOnefilters(
980
+ { _id: new mongoose.Types.ObjectId( req.body._id ) },
981
+ {
982
+ $set: { 'answers.$[ans].issues.$[iss].status': 'completed' },
983
+ },
984
+ [
985
+ { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
986
+ { 'iss._id': new mongoose.Types.ObjectId( req.body.issueId ) },
987
+ ] );
988
+ }
989
+ let findoneplanoData = await planoTaskService.findOne( { _id: new mongoose.Types.ObjectId( req.body._id ) } );
990
+ let totalApproved = findoneplanoData.answers[0].issues.filter( ( data ) => data.status === 'pending' );
991
+ if ( totalApproved.length === 0 ) {
992
+ await planoTaskService.updateOne(
993
+ {
994
+ _id: new mongoose.Types.ObjectId( req.body._id ),
995
+ },
996
+ {
997
+ 'status': 'complete',
998
+ },
999
+ );
1000
+ if ( req.body.taskType === 'layout' ) {
1001
+ await planoTaskService.updateMany(
1002
+ {
1003
+ planoId: new mongoose.Types.ObjectId( req.body.planoId ),
1004
+ floorId: new mongoose.Types.ObjectId( req.body.floorId ),
1005
+ type: 'layout',
1006
+ },
1007
+ {
1008
+ 'status': 'complete',
1009
+ },
1010
+ );
1011
+ }
1012
+ }
1013
+ }
943
1014
 
944
- );
945
- if ( vmTask.length > 0 ) {
946
- let allTaskDone = vmTask.filter( ( data ) => data.status === 'incomplete' );
947
- if ( allTaskDone.length === 0 ) {
948
- await floorService.updateOne( { _id: new mongoose.Types.ObjectId( req.body.floorId ) }, { planoProgress: 100 } );
1015
+ if ( req.body.taskType === 'layout' ) {
1016
+ await planoTaskService.updateOnefilters(
1017
+ { _id: new mongoose.Types.ObjectId( req.body._id ) },
1018
+ {
1019
+ $push: { 'answers.$[ans].issues.$[iss].Details.$[det].comments': comments },
1020
+ },
1021
+ [
1022
+ { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
1023
+ { 'iss._id': new mongoose.Types.ObjectId( req.body.issueId ) },
1024
+ { 'det._id': new mongoose.Types.ObjectId( req.body.DetailsId ) },
1025
+
1026
+ ] );
1027
+ } else {
1028
+ await planoTaskService.updateOnefilters(
1029
+ { _id: new mongoose.Types.ObjectId( req.body._id ) },
1030
+ {
1031
+ $push: { 'answers.$[ans].issues.$[iss].comments': comments },
1032
+ },
1033
+ [
1034
+ { 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
1035
+ { 'iss._id': new mongoose.Types.ObjectId( req.body.issueId ) },
1036
+ ] );
1037
+ }
1038
+ let vmTask = await planoTaskService.find(
1039
+ {
1040
+ planoId: new mongoose.Types.ObjectId( req.body.planoId ),
1041
+ floorId: new mongoose.Types.ObjectId( req.body.floorId ),
1042
+ type: 'vm',
1043
+ },
1044
+
1045
+ );
1046
+ if ( vmTask.length > 0 ) {
1047
+ let allTaskDone = vmTask.filter( ( data ) => data.status === 'incomplete' );
1048
+ if ( allTaskDone.length === 0 ) {
1049
+ await floorService.updateOne( { _id: new mongoose.Types.ObjectId( req.body.floorId ) }, { planoProgress: 100 } );
1050
+ }
949
1051
  }
950
1052
  }
951
1053
  res.sendSuccess( 'updated successfully' );
@@ -1091,6 +1193,141 @@ export async function updateStoreFixture( req, res ) {
1091
1193
 
1092
1194
  const currentFixture = await storeFixtureService.findOne( { _id: new mongoose.Types.ObjectId( fixtureId ) } );
1093
1195
  let currentFixtureDoc = currentFixture.toObject();
1196
+ if ( req?.body?.taskType?.includes( 'fixture' ) || data?.taskType?.includes( 'fixture' ) ) {
1197
+ let shelfDetails = await fixtureShelfService.find( { fixtureId: fixtureId } );
1198
+ data.shelfConfig.forEach( ( ele ) => {
1199
+ let findShelfProduct = shelfDetails.find( ( shelf ) => shelf.shelfNumber == ele.shelfNumber );
1200
+ ele.productBrandName = findShelfProduct?.productBrandName ?? [];
1201
+ ele.productCategory = findShelfProduct?.productCategory ?? [];
1202
+ ele.productSubCategory = findShelfProduct?.productSubCategory ?? [];
1203
+ ele.zone = findShelfProduct?.zone ?? 'Bottom';
1204
+ } );
1205
+ let vmConfig = [];
1206
+ for ( let vm of data.vmConfig ) {
1207
+ let checkvmType = await vmTypeService.findOne( { vmType: vm.vmType } );
1208
+ if ( !checkvmType ) {
1209
+ let vmData = {
1210
+ vmType: vm.vmType,
1211
+ imageUrls: [ vm.vmImage ],
1212
+ clientId: '11',
1213
+ };
1214
+ checkvmType = await vmTypeService.create( vmData );
1215
+ }
1216
+ let vmDetails = await planoVmService.findOne( { ...( vm.vmName ) ? { vmName: vm.vmName } : { _id: vm.vmId } } );
1217
+ if ( !vmDetails ) {
1218
+ let planovmData = {
1219
+ vmType: vm.vmType,
1220
+ vmName: vm.vmName,
1221
+ clientId: '11',
1222
+ status: 'complete',
1223
+ vmHeight: {
1224
+ 'value': 100,
1225
+ 'unit': 'mm',
1226
+ },
1227
+ vmWidth: {
1228
+ 'value': 100,
1229
+ 'unit': 'mm',
1230
+ },
1231
+ vmImageUrl: vm.vmImage,
1232
+ };
1233
+ vmDetails = await planoVmService.create( planovmData );
1234
+ }
1235
+ vmConfig.push( { ...vm, vmId: vmDetails._id } );
1236
+ }
1237
+ data.vmConfig = vmConfig;
1238
+ let groupName = {
1239
+ 'Vincent Chase Lenskart air': 'VC Eye / LK Air',
1240
+ 'John Jacobs': 'JJ Eye',
1241
+ 'Vincent Chase': 'VC Eye',
1242
+ 'OwnDays': 'OD Eye',
1243
+ };
1244
+ let header = ( data?.header?.label && data?.header?.label != 'Unknown' ) ? groupName?.[data?.header?.label] ? groupName?.[data?.header?.label] : data?.header?.label : currentFixture.header?.label;
1245
+ let mapKey = `${data.fixtureCategory}${currentFixtureDoc.fixtureWidth.value}${currentFixtureDoc.fixtureWidth.unit}${header}`;
1246
+ mapKey += data.shelfConfig.map( ( ele ) => `${ele.shelfNumber}=${ele.productBrandName.toString()}` ).join( '+' );
1247
+ data?.vmConfig?.forEach( ( ele ) => {
1248
+ mapKey += `${ele.vmName}${ele.startYPosition}${ele.endYPosition}${ele.xZone}${ele.yZone}`;
1249
+ } );
1250
+ let query = [
1251
+ {
1252
+ $addFields: {
1253
+ crestMapKey: { $toLower: '$crestMapKey' },
1254
+ },
1255
+ },
1256
+ {
1257
+ $match: {
1258
+ crestMapKey: mapKey.toLowerCase(),
1259
+ templateType: 'sub',
1260
+ },
1261
+ },
1262
+ ];
1263
+ let masterMapKey = `${data.fixtureCategory}${currentFixtureDoc.fixtureWidth.value}${currentFixtureDoc.fixtureWidth.unit}${header}`;
1264
+ let masterQuery = [
1265
+ {
1266
+ $addFields: {
1267
+ crestMapKey: { $toLower: '$crestMapKey' },
1268
+ },
1269
+ },
1270
+ {
1271
+ $match: {
1272
+ crestMapKey: masterMapKey.toLowerCase(),
1273
+ templateType: 'master',
1274
+ },
1275
+ },
1276
+ ];
1277
+ let [ fixturesubTemplate, fixtureMasterTemplate ] = await Promise.all( [
1278
+ await fixtureConfigService.aggregate( query ),
1279
+ await fixtureConfigService.aggregate( masterQuery ),
1280
+ ] );
1281
+
1282
+ if ( !fixturesubTemplate.length ) {
1283
+ let tempGroupName = ( data?.header?.label && data?.header?.label != 'Unknown' ) ? groupName?.[data?.header?.label] ? groupName?.[data?.header?.label] : data?.header?.label : currentFixture.templateGroupName;
1284
+ let templateIndex = 1;
1285
+ let templateData = {
1286
+ ...currentFixtureDoc,
1287
+ ...data,
1288
+ templateGroupName: tempGroupName,
1289
+ fixtureLibraryId: currentFixture.fixtureLibraryId,
1290
+ status: 'complete',
1291
+ templateIndex: fixtureMasterTemplate.length ? fixtureMasterTemplate.length + 1 : 1,
1292
+ crestMapKey: mapKey,
1293
+ };
1294
+ delete templateData._id;
1295
+ delete templateData.masterTemplateId;
1296
+ if ( !fixtureMasterTemplate.length ) {
1297
+ let masterTemplate = {
1298
+ ...templateData,
1299
+ fixtureName: `${templateData.header.label}-${templateData.fixtureCategory}`,
1300
+ templateType: 'master',
1301
+ crestMapKey: masterMapKey,
1302
+ };
1303
+ fixtureMasterTemplate = await fixtureConfigService.create( masterTemplate );
1304
+ } else {
1305
+ fixtureMasterTemplate = fixtureMasterTemplate[0];
1306
+ let tempQuery = [
1307
+ {
1308
+ $match: {
1309
+ masterTemplateId: new mongoose.Types.ObjectId( fixtureMasterTemplate._id ),
1310
+ },
1311
+ },
1312
+ {
1313
+ $group: {
1314
+ _id: '',
1315
+ tempId: { $max: '$templateIndex' },
1316
+ },
1317
+ },
1318
+ ];
1319
+ let getMaxTemp = await fixtureConfigService.aggregate( tempQuery );
1320
+ templateIndex = getMaxTemp?.[0]?.tempId + 1;
1321
+ }
1322
+ templateData.fixtureName= `${header}-${data.fixtureCategory}-varient-${templateIndex}`,
1323
+ templateData.templateType = 'sub';
1324
+ templateData.masterTemplateId = fixtureMasterTemplate._id;
1325
+ let subTemplate = await fixtureConfigService.create( templateData );
1326
+
1327
+ data.fixtureConfigId = subTemplate._id;
1328
+ data.masterTemplateId = fixtureMasterTemplate._id;
1329
+ }
1330
+ }
1094
1331
 
1095
1332
  const productBrandName = new Set();
1096
1333
  const productCategory = new Set();
@@ -1125,7 +1362,7 @@ export async function updateStoreFixture( req, res ) {
1125
1362
  } );
1126
1363
 
1127
1364
 
1128
- if ( currentFixtureDoc.fixtureConfigId.toString() !== data.fixtureConfigId ) {
1365
+ if ( data?.fixtureConfigId && currentFixtureDoc.fixtureConfigId.toString() !== data.fixtureConfigId ) {
1129
1366
  const newTemplate = await fixtureConfigService.findOne( { _id: data.fixtureConfigId } );
1130
1367
  currentFixtureDoc = {
1131
1368
  ...currentFixtureDoc,
@@ -1178,7 +1415,22 @@ export async function updateStoreFixture( req, res ) {
1178
1415
  } );
1179
1416
  }
1180
1417
  await planoService.updateOne( { _id: currentFixtureDoc?.planoId }, { $set: { updatedAt: new Date() } } );
1181
-
1418
+ if ( data?.taskType?.includes( 'fixture' ) ) {
1419
+ let comments = {
1420
+ userId: req.user._id,
1421
+ userName: req.user.userName,
1422
+ role: req.user.role,
1423
+ responsetype: 'agree',
1424
+ comment: '',
1425
+ };
1426
+ await planoTaskService.updateOne( { planoId: currentFixture.planoId, floorId: currentFixture.floorId, fixtureId: currentFixture._id }, { 'answers.0.status': 'agree', 'approvalStatus': 'approved' } );
1427
+ await planoTaskService.updateOnefilters(
1428
+ { planoId: new mongoose.Types.ObjectId( currentFixture.planoId ), floorId: new mongoose.Types.ObjectId( currentFixture.floorId ), fixtureId: new mongoose.Types.ObjectId( currentFixture._id ) },
1429
+ {
1430
+ $push: { 'answers.0.comments': comments },
1431
+ },
1432
+ );
1433
+ }
1182
1434
  res.sendSuccess( 'Updated Successfully' );
1183
1435
  } catch ( e ) {
1184
1436
  logger.error( { functionName: 'updateStoreFixture', error: e } );
@@ -9549,147 +9549,147 @@ async function updateHeaders() {
9549
9549
  } );
9550
9550
  }
9551
9551
 
9552
- export async function productMappings(req, res) {
9552
+ export async function productMappings( req, res ) {
9553
9553
  try {
9554
9554
  const CLEAR_COL_BEFORE_INSERT = false;
9555
- if (req?.headers?.authorization?.split(" ")[1] !== "hwjXfCD6TgMvc82cuSGZ9bNv9MuXsaiQ6uvx") {
9556
- return res.sendError("Unauthorized", 401);
9555
+ if ( req?.headers?.authorization?.split( ' ' )[1] !== 'hwjXfCD6TgMvc82cuSGZ9bNv9MuXsaiQ6uvx' ) {
9556
+ return res.sendError( 'Unauthorized', 401 );
9557
9557
  }
9558
9558
 
9559
- if (!req.files?.file) {
9560
- return res.sendError("Excel file is required", 400);
9559
+ if ( !req.files?.file ) {
9560
+ return res.sendError( 'Excel file is required', 400 );
9561
9561
  }
9562
9562
 
9563
- const payload = JSON.parse(req.body.payload);
9563
+ const payload = JSON.parse( req.body.payload );
9564
9564
 
9565
9565
  const { fixtureId, Top, Mid, Bottom } = payload;
9566
9566
 
9567
- const storeName = "LKST98";
9568
- const storeId = "11-4";
9567
+ const storeName = 'LKST98';
9568
+ const storeId = '11-4';
9569
9569
 
9570
- if (!fixtureId) {
9571
- return res.sendError("fixtureId is required", 400);
9570
+ if ( !fixtureId ) {
9571
+ return res.sendError( 'fixtureId is required', 400 );
9572
9572
  }
9573
9573
 
9574
9574
  const fixtureData = { Top, Mid, Bottom };
9575
9575
 
9576
- const workbook = xlsx.read(req.files.file.data, { type: "buffer" });
9577
- const sheetName = "Unique Mapping";
9578
- const raw = xlsx.utils.sheet_to_json(workbook.Sheets[sheetName]);
9576
+ const workbook = xlsx.read( req.files.file.data, { type: 'buffer' } );
9577
+ const sheetName = 'Unique Mapping';
9578
+ const raw = xlsx.utils.sheet_to_json( workbook.Sheets[sheetName] );
9579
9579
 
9580
- const pidsList = Object.values(fixtureData).flat();
9580
+ const pidsList = Object.values( fixtureData ).flat();
9581
9581
 
9582
9582
  let pDetailsList = [];
9583
- for (const pid of pidsList) {
9584
- const pDetails = raw.find((pd) => pd["product_id"] == pid);
9585
- if (pDetails) {
9586
- pDetailsList.push({
9587
- clientId: "11",
9583
+ for ( const pid of pidsList ) {
9584
+ const pDetails = raw.find( ( pd ) => pd['product_id'] == pid );
9585
+ if ( pDetails ) {
9586
+ pDetailsList.push( {
9587
+ clientId: '11',
9588
9588
  productId: pDetails.product_id,
9589
9589
  productName: pDetails.parent_brand,
9590
9590
  pid: pDetails.product_id,
9591
9591
  rfId: pDetails.barcode,
9592
9592
  productImageUrl: pDetails.image_front,
9593
- productType: pDetails.classification_name ?? "",
9594
- brandName: pDetails.collection ?? "",
9595
- category: pDetails.collection_group ?? "",
9596
- subCategory: pDetails.sub_collection ?? "",
9597
- type: "product",
9598
- });
9593
+ productType: pDetails.classification_name ?? '',
9594
+ brandName: pDetails.collection ?? '',
9595
+ category: pDetails.collection_group ?? '',
9596
+ subCategory: pDetails.sub_collection ?? '',
9597
+ type: 'product',
9598
+ } );
9599
9599
  }
9600
9600
  }
9601
9601
 
9602
- if(CLEAR_COL_BEFORE_INSERT) await planoProductService.deleteMany({});
9602
+ if ( CLEAR_COL_BEFORE_INSERT ) await planoProductService.deleteMany( {} );
9603
9603
 
9604
9604
  // const uniqueProducts = await fixtureShelfService.find();
9605
-
9606
- const fixtureTemplateData = await fixtureShelfService.find({ fixtureId });
9607
9605
 
9608
- if (!fixtureTemplateData?.length) {
9609
- return res.sendError("No shelves found for fixtureId", 404);
9606
+ const fixtureTemplateData = await fixtureShelfService.find( { fixtureId } );
9607
+
9608
+ if ( !fixtureTemplateData?.length ) {
9609
+ return res.sendError( 'No shelves found for fixtureId', 404 );
9610
9610
  }
9611
9611
 
9612
9612
  const planoId = fixtureTemplateData[0].planoId;
9613
9613
  const floorId = fixtureTemplateData[0].floorId;
9614
9614
 
9615
- const fixtureShelve = fixtureTemplateData.map((f) => ({
9615
+ const fixtureShelve = fixtureTemplateData.map( ( f ) => ( {
9616
9616
  id: f._id,
9617
9617
  zone: f.zone,
9618
- }));
9619
-
9620
- const result = await planoProductService.insertMany(pDetailsList);
9618
+ } ) );
9619
+
9620
+ const result = await planoProductService.insertMany( pDetailsList );
9621
9621
 
9622
- let planoMappings = result.map((pd) => ({
9623
- clientId: "11",
9622
+ let planoMappings = result.map( ( pd ) => ( {
9623
+ clientId: '11',
9624
9624
  storeName: storeName,
9625
9625
  storeId: storeId,
9626
- type: "product",
9626
+ type: 'product',
9627
9627
  productId: pd._id,
9628
9628
  pid: pd.pid,
9629
9629
  planoId,
9630
9630
  floorId,
9631
9631
  fixtureId,
9632
- shelfId: "temp", // will be reassigned in transformProducts
9633
- }));
9632
+ shelfId: 'temp', // will be reassigned in transformProducts
9633
+ } ) );
9634
9634
 
9635
- if(CLEAR_COL_BEFORE_INSERT) await planoMappingService.deleteMany({});
9635
+ if ( CLEAR_COL_BEFORE_INSERT ) await planoMappingService.deleteMany( {} );
9636
9636
 
9637
9637
  const shelfGroups = {
9638
- Top: fixtureShelve.filter((f) => f.zone === "Top").map((f) => f.id),
9639
- Mid: fixtureShelve.filter((f) => f.zone === "Mid").map((f) => f.id),
9640
- Bottom: fixtureShelve.filter((f) => f.zone === "Bottom").map((f) => f.id),
9638
+ Top: fixtureShelve.filter( ( f ) => f.zone === 'Top' ).map( ( f ) => f.id ),
9639
+ Mid: fixtureShelve.filter( ( f ) => f.zone === 'Mid' ).map( ( f ) => f.id ),
9640
+ Bottom: fixtureShelve.filter( ( f ) => f.zone === 'Bottom' ).map( ( f ) => f.id ),
9641
9641
  };
9642
9642
 
9643
- const transformed = transformProducts(planoMappings, shelfGroups, fixtureData);
9643
+ const transformed = transformProducts( planoMappings, shelfGroups, fixtureData );
9644
9644
 
9645
- const result2 = await planoMappingService.insertMany(transformed);
9645
+ const result2 = await planoMappingService.insertMany( transformed );
9646
9646
 
9647
- res.sendSuccess({
9647
+ res.sendSuccess( {
9648
9648
  fixtureData,
9649
9649
  shelfGroups,
9650
9650
  planoMappings: result2,
9651
- });
9652
- } catch (error) {
9653
- console.log("@@ ~ error:", error);
9654
- res.sendError("Internal Server Error", 500);
9651
+ } );
9652
+ } catch ( error ) {
9653
+ console.log( '@@ ~ error:', error );
9654
+ res.sendError( 'Internal Server Error', 500 );
9655
9655
  }
9656
9656
  }
9657
9657
 
9658
- function transformProducts(products, shelvesByZone, fixtureData) {
9658
+ function transformProducts( products, shelvesByZone, fixtureData ) {
9659
9659
  const result = [];
9660
9660
 
9661
9661
  // Build lookup: pid → zone
9662
9662
  const pidToZone = {};
9663
- for (const [zone, pids] of Object.entries(fixtureData)) {
9664
- pids.forEach(pid => {
9663
+ for ( const [ zone, pids ] of Object.entries( fixtureData ) ) {
9664
+ pids.forEach( ( pid ) => {
9665
9665
  pidToZone[pid] = zone;
9666
- });
9666
+ } );
9667
9667
  }
9668
9668
 
9669
9669
  // Group products by zone
9670
9670
  const productsByZone = {};
9671
- for (const doc of products) {
9671
+ for ( const doc of products ) {
9672
9672
  const zone = pidToZone[doc.pid];
9673
- if (!zone) continue;
9674
- if (!productsByZone[zone]) productsByZone[zone] = [];
9675
- productsByZone[zone].push(doc);
9673
+ if ( !zone ) continue;
9674
+ if ( !productsByZone[zone] ) productsByZone[zone] = [];
9675
+ productsByZone[zone].push( doc );
9676
9676
  }
9677
9677
 
9678
9678
  // Round-robin distribute products across shelves
9679
- for (const [zone, docs] of Object.entries(productsByZone)) {
9679
+ for ( const [ zone, docs ] of Object.entries( productsByZone ) ) {
9680
9680
  const shelves = shelvesByZone[zone] || [];
9681
- if (shelves.length === 0) {
9682
- result.push(...docs);
9681
+ if ( shelves.length === 0 ) {
9682
+ result.push( ...docs );
9683
9683
  continue;
9684
9684
  }
9685
9685
 
9686
- docs.forEach((doc, idx) => {
9686
+ docs.forEach( ( doc, idx ) => {
9687
9687
  const shelfId = shelves[idx % shelves.length]; // cycle through shelves
9688
- result.push({
9688
+ result.push( {
9689
9689
  ...doc,
9690
- shelfId
9691
- });
9692
- });
9690
+ shelfId,
9691
+ } );
9692
+ } );
9693
9693
  }
9694
9694
 
9695
9695
  return result;
@@ -1,7 +1,7 @@
1
1
  import * as storeBuilderService from '../service/storeBuilder.service.js';
2
2
  import * as storeService from '../service/store.service.js';
3
3
  import * as planoService from '../service/planogram.service.js';
4
- import { logger, fileUpload, signedUrl, sendMessageToQueue } from 'tango-app-api-middleware';
4
+ import { logger, fileUpload, signedUrl, sendMessageToQueue, getOpenSearchData } from 'tango-app-api-middleware';
5
5
  import dayjs from 'dayjs';
6
6
  import customParseFormat from 'dayjs/plugin/customParseFormat.js';
7
7
  import utc from 'dayjs/plugin/utc.js';
@@ -2811,11 +2811,12 @@ export async function storeFixturesv2( req, res ) {
2811
2811
  const masterTemplateIds = new Set();
2812
2812
  const layoutPolygonWithFixtures = await Promise.all(
2813
2813
  floor.layoutPolygon.map( async ( element ) => {
2814
- const fixtures = await storeFixtureService.findAndSort( {
2814
+ const fixtures = await storeFixtureService.findAndSort( {
2815
2815
  floorId: floor._id,
2816
2816
  associatedElementType: element.elementType,
2817
2817
  associatedElementNumber: element.elementNumber,
2818
- }, { shelfcount: 0 }, { associatedElementFixtureNumber: 1 } );
2818
+ fixtureType: { $ne: 'other' },
2819
+ }, { shelfcount: 0 }, { associatedElementFixtureNumber: 1 } );
2819
2820
 
2820
2821
  const fixturesWithStatus = await Promise.all(
2821
2822
  fixtures.map( async ( fixture ) => {
@@ -2916,6 +2917,7 @@ export async function storeFixturesv2( req, res ) {
2916
2917
  $and: [
2917
2918
  { associatedElementType: { $exists: false } },
2918
2919
  { associatedElementNumber: { $exists: false } },
2920
+ { fixtureType: { $ne: 'other' } }
2919
2921
  ],
2920
2922
  }, { shelfcount: 0 }, { associatedElementFixtureNumber: 1 } );
2921
2923
 
@@ -2996,7 +2998,6 @@ export async function storeFixturesv2( req, res ) {
2996
2998
  vmCount: vmCount,
2997
2999
  shelfConfig: shelfDetails,
2998
3000
  vmConfig: vmDetails,
2999
-
3000
3001
  };
3001
3002
  } ),
3002
3003
  );
@@ -3494,6 +3495,7 @@ export async function storeFixturesTaskv2( req, res ) {
3494
3495
  floorId: floor._id,
3495
3496
  associatedElementType: element.elementType,
3496
3497
  associatedElementNumber: element.elementNumber,
3498
+ fixtureType: { $ne: 'other' }
3497
3499
  }, { shelfcount: 0 }, { associatedElementFixtureNumber: 1 } );
3498
3500
 
3499
3501
  const fixturesWithStatus = await Promise.all(
@@ -3571,6 +3573,7 @@ export async function storeFixturesTaskv2( req, res ) {
3571
3573
  vmCount: vmCount,
3572
3574
  shelfConfig: shelfDetails,
3573
3575
  vmConfig: vmDetails,
3576
+ ...( req.body.type == 'fixtureMeasurement' && { fixtureMeasurement: compliance.answers?.[0]?.fixtureWidth } ),
3574
3577
  };
3575
3578
  } ),
3576
3579
  );
@@ -3595,6 +3598,7 @@ export async function storeFixturesTaskv2( req, res ) {
3595
3598
  $and: [
3596
3599
  { associatedElementType: { $exists: false } },
3597
3600
  { associatedElementNumber: { $exists: false } },
3601
+ { fixtureType: { $ne: 'other' } }
3598
3602
  ],
3599
3603
  }, { shelfcount: 0 }, { associatedElementFixtureNumber: 1 } );
3600
3604
 
@@ -3673,6 +3677,7 @@ export async function storeFixturesTaskv2( req, res ) {
3673
3677
  vmCount: vmCount,
3674
3678
  shelfConfig: shelfDetails,
3675
3679
  vmConfig: vmDetails,
3680
+ ...( req.body.type == 'fixtureMeasurement' && { fixtureMeasurement: compliance.answers?.[0]?.fixtureWidth } ),
3676
3681
  };
3677
3682
  } ),
3678
3683
  );
@@ -4121,7 +4126,6 @@ export async function planoList( req, res ) {
4121
4126
  $expr: {
4122
4127
  $and: [
4123
4128
  { $eq: [ '$floorId', '$$floor' ] },
4124
- { $eq: [ '$status', 'incomplete' ] },
4125
4129
  { $in: [ '$type', [ 'layout', 'fixture', 'vm' ] ] },
4126
4130
  ],
4127
4131
  },
@@ -4130,6 +4134,15 @@ export async function planoList( req, res ) {
4130
4134
  { $sort: { _id: -1 } },
4131
4135
  {
4132
4136
  $set: {
4137
+ hasCompletedAnswers: {
4138
+ $anyElementTrue: {
4139
+ $map: {
4140
+ input: '$answers',
4141
+ as: 'ans',
4142
+ in: { $eq: [ { $ifNull: [ '$$ans.status', null ] }, null ] },
4143
+ },
4144
+ },
4145
+ },
4133
4146
  hasPendingIssues: {
4134
4147
  $anyElementTrue: {
4135
4148
  $map: {
@@ -4169,33 +4182,36 @@ export async function planoList( req, res ) {
4169
4182
  $anyElementTrue: {
4170
4183
  $map: {
4171
4184
  input: {
4172
- $reduce: {
4173
- input: '$answers',
4174
- initialValue: [],
4175
- in: {
4176
- $concatArrays: [
4177
- '$$value',
4178
- {
4179
- $reduce: {
4180
- input: { $ifNull: [ '$$this.issues', [] ] },
4181
- initialValue: [],
4182
- in: {
4183
- $concatArrays: [
4184
- '$$value',
4185
- { $ifNull: [ '$$this.Details', [] ] },
4186
- ],
4185
+ $concatArrays: [
4186
+ '$answers',
4187
+ {
4188
+ $reduce: {
4189
+ input: '$answers',
4190
+ initialValue: [],
4191
+ in: {
4192
+ $concatArrays: [
4193
+ '$$value',
4194
+ {
4195
+ $reduce: {
4196
+ input: { $ifNull: [ '$$this.issues', [] ] },
4197
+ initialValue: [],
4198
+ in: {
4199
+ $concatArrays: [
4200
+ '$$value',
4201
+ { $ifNull: [ '$$this.Details', [] ] },
4202
+ ],
4203
+ },
4204
+ },
4187
4205
  },
4188
- },
4206
+ ],
4189
4207
  },
4190
- ],
4208
+ },
4191
4209
  },
4192
- },
4210
+ ],
4193
4211
  },
4194
4212
  as: 'detail',
4195
4213
  in: {
4196
- $or: [
4197
- { $eq: [ '$$detail.status', 'disagree' ] },
4198
- ],
4214
+ $or: [ { $eq: [ '$$detail.status', 'disagree' ] } ],
4199
4215
  },
4200
4216
  },
4201
4217
  },
@@ -4226,12 +4242,26 @@ export async function planoList( req, res ) {
4226
4242
  fixturePending: {
4227
4243
  $sum: {
4228
4244
  $cond: [
4229
- { $and: [ { $eq: [ '$type', 'fixture' ] }, '$hasPendingIssues' ] },
4245
+ { $and: [ { $eq: [ '$type', 'fixture' ] }, { $or: [ '$hasPendingIssues', '$hasCompletedAnswers' ] } ] },
4230
4246
  1,
4231
4247
  0,
4232
4248
  ],
4233
4249
  },
4234
4250
  },
4251
+ fixtureApproved: {
4252
+ $push: {
4253
+ $cond: [
4254
+ {
4255
+ $and: [
4256
+ { $eq: [ '$type', 'fixture' ] },
4257
+ { $eq: [ '$approvalStatus', 'approved' ] },
4258
+ ],
4259
+ },
4260
+ '$approvalStatus',
4261
+ '$$REMOVE',
4262
+ ],
4263
+ },
4264
+ },
4235
4265
  vmPending: {
4236
4266
  $sum: {
4237
4267
  $cond: [
@@ -4333,6 +4363,9 @@ export async function planoList( req, res ) {
4333
4363
  {
4334
4364
  $eq: [ '$fixtureDisagree', 0 ],
4335
4365
  },
4366
+ {
4367
+ $eq: [ { $size: '$fixtureApproved' }, '$fixtureCount' ],
4368
+ },
4336
4369
  ],
4337
4370
  },
4338
4371
  then: 'complete',
@@ -4685,6 +4718,15 @@ export async function planoList( req, res ) {
4685
4718
  },
4686
4719
  {
4687
4720
  $set: {
4721
+ hasCompletedAnswers: {
4722
+ $anyElementTrue: {
4723
+ $map: {
4724
+ input: '$answers',
4725
+ as: 'ans',
4726
+ in: { $eq: [ { $ifNull: [ '$$ans.status', null ] }, null ] },
4727
+ },
4728
+ },
4729
+ },
4688
4730
  hasPendingIssues: {
4689
4731
  $anyElementTrue: {
4690
4732
  $map: {
@@ -4737,7 +4779,7 @@ export async function planoList( req, res ) {
4737
4779
  fixturePending: {
4738
4780
  $sum: {
4739
4781
  $cond: [
4740
- { $and: [ { $eq: [ '$type', 'fixture' ] }, '$hasPendingIssues' ] },
4782
+ { $and: [ { $eq: [ '$type', 'fixture' ] }, { $or: [ '$hasPendingIssues', '$hasCompletedAnswers' ] } ] },
4741
4783
  1,
4742
4784
  0,
4743
4785
  ],
@@ -4872,7 +4914,6 @@ export async function getTaskDetails( req, res ) {
4872
4914
  $and: [
4873
4915
  { $eq: [ '$planoId', new mongoose.Types.ObjectId( req.query.planoId ) ] },
4874
4916
  { $in: [ '$taskId', '$$task' ] },
4875
- { $eq: [ '$status', 'incomplete' ] },
4876
4917
  ],
4877
4918
  },
4878
4919
  },
@@ -4880,6 +4921,15 @@ export async function getTaskDetails( req, res ) {
4880
4921
  { $sort: { _id: -1 } },
4881
4922
  {
4882
4923
  $set: {
4924
+ hasCompletedAnswers: {
4925
+ $anyElementTrue: {
4926
+ $map: {
4927
+ input: '$answers',
4928
+ as: 'ans',
4929
+ in: { $eq: [ { $ifNull: [ '$$ans.status', null ] }, null ] },
4930
+ },
4931
+ },
4932
+ },
4883
4933
  hasPendingIssues: {
4884
4934
  $anyElementTrue: {
4885
4935
  $map: {
@@ -4919,33 +4969,36 @@ export async function getTaskDetails( req, res ) {
4919
4969
  $anyElementTrue: {
4920
4970
  $map: {
4921
4971
  input: {
4922
- $reduce: {
4923
- input: '$answers',
4924
- initialValue: [],
4925
- in: {
4926
- $concatArrays: [
4927
- '$$value',
4928
- {
4929
- $reduce: {
4930
- input: { $ifNull: [ '$$this.issues', [] ] },
4931
- initialValue: [],
4932
- in: {
4933
- $concatArrays: [
4934
- '$$value',
4935
- { $ifNull: [ '$$this.Details', [] ] },
4936
- ],
4972
+ $concatArrays: [
4973
+ '$answers',
4974
+ {
4975
+ $reduce: {
4976
+ input: '$answers',
4977
+ initialValue: [],
4978
+ in: {
4979
+ $concatArrays: [
4980
+ '$$value',
4981
+ {
4982
+ $reduce: {
4983
+ input: { $ifNull: [ '$$this.issues', [] ] },
4984
+ initialValue: [],
4985
+ in: {
4986
+ $concatArrays: [
4987
+ '$$value',
4988
+ { $ifNull: [ '$$this.Details', [] ] },
4989
+ ],
4990
+ },
4991
+ },
4937
4992
  },
4938
- },
4993
+ ],
4939
4994
  },
4940
- ],
4995
+ },
4941
4996
  },
4942
- },
4997
+ ],
4943
4998
  },
4944
4999
  as: 'detail',
4945
5000
  in: {
4946
- $or: [
4947
- { $eq: [ '$$detail.status', 'disagree' ] },
4948
- ],
5001
+ $or: [ { $eq: [ '$$detail.status', 'disagree' ] } ],
4949
5002
  },
4950
5003
  },
4951
5004
  },
@@ -4976,12 +5029,26 @@ export async function getTaskDetails( req, res ) {
4976
5029
  fixturePending: {
4977
5030
  $sum: {
4978
5031
  $cond: [
4979
- { $and: [ { $eq: [ '$type', 'fixture' ] }, '$hasPendingIssues' ] },
5032
+ { $and: [ { $eq: [ '$type', 'fixture' ] }, { $or: [ '$hasPendingIssues', '$hasCompletedAnswers' ] } ] },
4980
5033
  1,
4981
5034
  0,
4982
5035
  ],
4983
5036
  },
4984
5037
  },
5038
+ fixtureApproved: {
5039
+ $push: {
5040
+ $cond: [
5041
+ {
5042
+ $and: [
5043
+ { $eq: [ '$type', 'fixture' ] },
5044
+ { $eq: [ '$approvalStatus', 'approved' ] },
5045
+ ],
5046
+ },
5047
+ '$approvalStatus',
5048
+ '$$REMOVE',
5049
+ ],
5050
+ },
5051
+ },
4985
5052
  vmPending: {
4986
5053
  $sum: {
4987
5054
  $cond: [
@@ -5020,41 +5087,6 @@ export async function getTaskDetails( req, res ) {
5020
5087
  },
5021
5088
  },
5022
5089
  },
5023
- // {
5024
- // $group: {
5025
- // _id: null,
5026
- // layoutCount: { $sum: '$layoutCount' },
5027
- // fixtureCount: { $sum: '$fixtureCount' },
5028
- // vmCount: { $sum: '$vmCount' },
5029
- // completeLayout: {
5030
- // $sum: {
5031
- // $cond: {
5032
- // if: {
5033
- // $and: [
5034
- // { '$gt': [ '$layoutCount', 0 ] },
5035
- // { '$eq': [ '$layoutPending', 0 ] },
5036
- // { '$eq': [ '$layoutDisagree', 0 ] },
5037
- // { '$gt': [ '$fixtureCount', 0 ] },
5038
- // { '$eq': [ '$fixturePending', 0 ] },
5039
- // { '$eq': [ '$fixtureDisagree', 0 ] },
5040
- // { '$gt': [ '$vmCount', 0 ] },
5041
- // { '$eq': [ '$vmPending', 0 ] },
5042
- // { '$eq': [ '$vmDisagree', 0 ] },
5043
- // ],
5044
- // },
5045
- // then: 1,
5046
- // else: 0,
5047
- // },
5048
- // },
5049
- // },
5050
- // layoutPending: { $sum: '$layoutPending' },
5051
- // fixturePending: { $sum: '$fixturePending' },
5052
- // vmPending: { $sum: '$vmPending' },
5053
- // layoutDisagree: { $sum: '$layoutDisagree' },
5054
- // fixtureDisagree: { $sum: '$fixtureDisagree' },
5055
- // vmDisagree: { $sum: '$vmDisagree' },
5056
- // },
5057
- // },
5058
5090
  {
5059
5091
  $project: {
5060
5092
  _id: 0,
@@ -5118,6 +5150,9 @@ export async function getTaskDetails( req, res ) {
5118
5150
  {
5119
5151
  $eq: [ '$fixtureDisagree', 0 ],
5120
5152
  },
5153
+ {
5154
+ $eq: [ { $size: '$fixtureApproved' }, '$fixtureCount' ],
5155
+ },
5121
5156
  ],
5122
5157
  },
5123
5158
  then: 'complete',
@@ -6059,10 +6094,9 @@ export async function getRolloutTaskDetails( req, res ) {
6059
6094
  },
6060
6095
  { $sort: { _id: -1 } },
6061
6096
  ],
6062
- as: 'taskStatus.taskDetails', // ✅ correctly attaches inside taskStatus
6097
+ as: 'taskStatus.taskDetails',
6063
6098
  },
6064
6099
  },
6065
- // 🔹 Group back into array
6066
6100
  {
6067
6101
  $group: {
6068
6102
  _id: null,
@@ -6089,7 +6123,7 @@ export async function getRolloutTaskDetails( req, res ) {
6089
6123
  createdAt: '$$task.createdAt',
6090
6124
  userName: '$$task.userName',
6091
6125
  submitTime_string: '$$task.submitTime_string',
6092
- taskDetails: '$$task.taskDetails', // ✅ fixed reference
6126
+ taskDetails: '$$task.taskDetails',
6093
6127
  },
6094
6128
  },
6095
6129
  },
@@ -6216,3 +6250,39 @@ export async function getScandid( req, res ) {
6216
6250
  return res.sendError( e, 500 );
6217
6251
  }
6218
6252
  }
6253
+
6254
+
6255
+ export async function getFixtureAIDetails( req, res ) {
6256
+ try {
6257
+ if ( !req.query.fixtureId ) {
6258
+ return res.sendError( 'Fixture Id is required', 400 );
6259
+ }
6260
+ let query = {
6261
+ bool: {
6262
+ must: [
6263
+ {
6264
+ term: {
6265
+ fixtureId: req.query.fixtureId,
6266
+ },
6267
+ },
6268
+ ],
6269
+ },
6270
+ };
6271
+
6272
+ let aiDetails = await getOpenSearchData( JSON.parse( process.env.OPENSEARCH ).planoAIValidation, { query } );
6273
+ if ( aiDetails.statusCode == 200 ) {
6274
+ let data = {};
6275
+ if ( aiDetails?.body?.hits?.hits.length ) {
6276
+ data = aiDetails?.body?.hits?.hits?.[0]?._source;
6277
+ delete data.isEmpty;
6278
+ delete data.fixtureFound;
6279
+ }
6280
+ return res.sendSuccess( data );
6281
+ }
6282
+ return res.sendError( 'No data found', 204 );
6283
+ } catch ( e ) {
6284
+ console.log( e );
6285
+ logger.error( { functionName: 'getFixtureAIDetails', error: e } );
6286
+ return res.sendError( e, 500 );
6287
+ }
6288
+ }
@@ -240,6 +240,9 @@ export async function createTask( req, res ) {
240
240
  first = 'merchRollout';
241
241
  }
242
242
  }
243
+ if ( req.body?.checkListName.toLowerCase().includes( 'measurement' ) ) {
244
+ first = 'fixtureMeasurement';
245
+ }
243
246
  let startDate = dayjs().format( 'YYYY-MM-DD hh:mm A' );
244
247
  let data = {
245
248
  client_id: req.body.clientId,
@@ -345,6 +348,7 @@ export async function createTask( req, res ) {
345
348
  } else {
346
349
  let type = req.body.checkListName == 'Fixture Verification' ? 'fixture' : 'vm';
347
350
  await planoTaskService.deleteMany( { planoId: planoDetails?._id, floorId: taskData?.floorId, type: type } );
351
+ await processedService.deleteMany( { planoId: planoDetails?._id, floorId: taskData?.floorId, isPlano: true, type: type } );
348
352
  }
349
353
  await floorService.updateOne( { _id: taskData?.floorId }, { planoProgress } );
350
354
  }
@@ -17,7 +17,7 @@ managePlanoRouter
17
17
  .get( '/fixtureVMListv1', managePlanoController.fixtureVMListv1 )
18
18
  .post( '/updateFixtureStatus', isAllowedSessionHandler, managePlanoController.updateFixtureStatus )
19
19
  .post( '/updateApprovalStatus', isAllowedSessionHandler, managePlanoController.updateApprovalStatus )
20
- .post( '/updateStoreFixture', managePlanoController.updateStoreFixture )
20
+ .post( '/updateStoreFixture', isAllowedSessionHandler, managePlanoController.updateStoreFixture )
21
21
  .post( '/updateredostatus', managePlanoController.updateredostatus )
22
22
  .post( '/updateGlobalComment', isAllowedSessionHandler, managePlanoController.updateGlobalComment )
23
23
  .post( '/getGlobalComment', isAllowedSessionHandler, managePlanoController.getGlobalComment )
@@ -59,4 +59,5 @@ storeBuilderRouter
59
59
  .post( '/planoRolloutList', isAllowedSessionHandler, storeBuilderController.getRolloutDetails )
60
60
  .get( '/getRolloutTaskDetails', isAllowedSessionHandler, storeBuilderController.getRolloutTaskDetails )
61
61
  .get( '/getScandid', storeBuilderController.getScandid )
62
- .get( '/getPlanoStoreList', isAllowedSessionHandler, storeBuilderController.getPlanoStoreList );
62
+ .get( '/getPlanoStoreList', isAllowedSessionHandler, storeBuilderController.getPlanoStoreList )
63
+ .get( '/getFixtureAIDetails', isAllowedSessionHandler, storeBuilderController.getFixtureAIDetails );
@@ -68,3 +68,17 @@ export async function count( query ) {
68
68
  export async function updateOneArrayItem( query, record, filter ) {
69
69
  return model.storeFixtureModel.updateOne( query, record, filter );
70
70
  }
71
+
72
+ export async function bulkUpsert(dataList = [], matchKey = '_id') {
73
+ if (!Array.isArray(dataList) || dataList.length === 0) return [];
74
+
75
+ const operations = dataList.map(item => ({
76
+ updateOne: {
77
+ filter: { [matchKey]: item[matchKey] },
78
+ update: { $set: item },
79
+ upsert: true,
80
+ },
81
+ }));
82
+
83
+ return model.storeFixtureModel.bulkWrite(operations);
84
+ }