tango-app-api-trax 3.6.0-task-3 → 3.6.1-runai-1

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-trax",
3
- "version": "3.6.0-task-3",
3
+ "version": "3.6.1-runai-1",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "mongodb": "^6.8.0",
27
27
  "nodemon": "^3.1.4",
28
28
  "path": "^0.12.7",
29
- "tango-api-schema": "^2.2.144",
29
+ "tango-api-schema": "^2.2.197",
30
30
  "tango-app-api-middleware": "^3.1.77",
31
31
  "url": "^0.11.4",
32
32
  "winston": "^3.13.1",
@@ -18,11 +18,6 @@ import mongoose from 'mongoose';
18
18
  export const downloadInsert = async ( req, res ) => {
19
19
  try {
20
20
  let requestData = req.body;
21
- let fromDate = new Date( requestData.fromDate );
22
- let toDate = new Date( requestData.toDate );
23
- let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
24
- toDate = new Date( toDate.getTime() - userTimezoneOffset );
25
- toDate.setUTCHours( 23, 59, 59, 59 );
26
21
  let name;
27
22
  let fileType = requestData?.fileType || 'pdfzip';
28
23
 
@@ -44,55 +39,60 @@ export const downloadInsert = async ( req, res ) => {
44
39
  }
45
40
  }
46
41
  // console.log( requestData );
47
-
48
- if ( requestData.sourceCheckList_id && requestData.sourceCheckList_id != '' ) {
49
- let getChecklistQuery = [];
50
- getChecklistQuery.push( { $project: { sourceCheckList_id: 1, date_iso: 1, store_id: 1, userEmail: 1, checklistStatus: 1, redoStatus: 1 } } );
51
-
52
- if ( requestData.filtertype ==='Clusters' ) {
53
- getChecklistQuery.push( {
54
- $match: {
55
- $and: [
56
- { sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ) },
57
- { date_iso: { $gte: fromDate, $lte: toDate } },
58
- { store_id: { $in: requestData.storeIds } },
59
- ],
60
- $or: [
61
- { checklistStatus: 'submit' },
62
- { redoStatus: true },
63
- ],
64
- },
65
- } );
66
- } else {
67
- // console.log( requestData );
68
- getChecklistQuery.push( {
69
- $match: {
70
- $and: [
71
- { sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ) },
72
- { date_iso: { $gte: fromDate, $lte: toDate } },
73
- { userEmail: { $in: requestData.userEmailList } },
74
- ],
75
- $or: [
76
- { checklistStatus: 'submit' },
77
- { redoStatus: true },
78
- ],
79
- },
80
- } );
81
- }
82
- getChecklistQuery.push( { $count: 'totalCount' } );
83
-
84
- let getChecklistCount = await processedchecklistService.aggregate( getChecklistQuery );
85
- // console.log( getChecklistCount );
86
- if ( requestData.insertType === 'task' ) {
87
- getChecklistCount = await processedTaskService.aggregate( getChecklistQuery );
88
- }
89
- if ( getChecklistCount && getChecklistCount[0]?.totalCount && getChecklistCount[0].totalCount > 0 ) {
90
- // console.log( 'if' );
91
- // console.log( 'getChecklistCountgetChecklistCount[0].totalCount =>', getChecklistCount[0]?.totalCount );
92
- } else {
93
- return res.sendError( { error: 'No Data Found' }, 400 );
94
- }
95
- }
42
+ // // No Need to Check
43
+ // let fromDate = new Date( requestData.fromDate );
44
+ // let toDate = new Date( requestData.toDate );
45
+ // let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
46
+ // toDate = new Date( toDate.getTime() - userTimezoneOffset );
47
+ // toDate.setUTCHours( 23, 59, 59, 59 );
48
+ // if ( requestData.sourceCheckList_id && requestData.sourceCheckList_id != '' ) {
49
+ // let getChecklistQuery = [];
50
+ // getChecklistQuery.push( { $project: { sourceCheckList_id: 1, date_iso: 1, store_id: 1, userEmail: 1, checklistStatus: 1, redoStatus: 1 } } );
51
+
52
+ // if ( requestData.filtertype ==='Clusters' ) {
53
+ // getChecklistQuery.push( {
54
+ // $match: {
55
+ // $and: [
56
+ // { sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ) },
57
+ // { date_iso: { $gte: fromDate, $lte: toDate } },
58
+ // { store_id: { $in: requestData.storeIds } },
59
+ // ],
60
+ // $or: [
61
+ // { checklistStatus: 'submit' },
62
+ // { redoStatus: true },
63
+ // ],
64
+ // },
65
+ // } );
66
+ // } else {
67
+ // // console.log( requestData );
68
+ // getChecklistQuery.push( {
69
+ // $match: {
70
+ // $and: [
71
+ // { sourceCheckList_id: new mongoose.Types.ObjectId( requestData.sourceCheckList_id ) },
72
+ // { date_iso: { $gte: fromDate, $lte: toDate } },
73
+ // { userEmail: { $in: requestData.userEmailList } },
74
+ // ],
75
+ // $or: [
76
+ // { checklistStatus: 'submit' },
77
+ // { redoStatus: true },
78
+ // ],
79
+ // },
80
+ // } );
81
+ // }
82
+ // // getChecklistQuery.push( { $count: 'totalCount' } );
83
+
84
+ // let getChecklistCount = await processedchecklistService.aggregate( getChecklistQuery );
85
+ // // console.log( getChecklistCount );
86
+ // if ( requestData.insertType === 'task' ) {
87
+ // getChecklistCount = await processedTaskService.aggregate( getChecklistQuery );
88
+ // }
89
+ // if ( getChecklistCount && getChecklistCount.length > 0 ) {
90
+ // // console.log( 'if' );
91
+ // // console.log( 'getChecklistCountgetChecklistCount[0].totalCount =>', getChecklistCount[0]?.totalCount );
92
+ // } else {
93
+ // return res.sendError( { error: 'No Data Found' }, 400 );
94
+ // }
95
+ // }
96
96
 
97
97
  if ( requestData.fileType == 'pdf' ) {
98
98
  if ( requestData?.sourceCheckList_id && requestData?.sourceCheckList_id != '' ) {
@@ -281,6 +281,7 @@ export async function PCLconfigCreation( req, res ) {
281
281
  insertdata.checkListType = getCLconfig.checkListType;
282
282
  insertdata.storeCount = getCLconfig.storeCount;
283
283
  insertdata.questionCount = getCLconfig.questionCount;
284
+ insertdata.runAIQuestionCount = getCLconfig.runAIQuestionCount;
284
285
  insertdata.publishDate = getCLconfig.publishDate;
285
286
  insertdata.locationCount = getCLconfig.locationCount;
286
287
  insertdata.scheduleRepeatedType = getCLconfig.scheduleRepeatedType;
@@ -295,6 +296,11 @@ export async function PCLconfigCreation( req, res ) {
295
296
  isdeleted: false,
296
297
  },
297
298
  } );
299
+ sectionQuery.push( {
300
+ $sort: {
301
+ sectionNumber: 1,
302
+ },
303
+ } );
298
304
  let getSections = await CLquestions.aggregate( sectionQuery );
299
305
  if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in' ].includes( getCLconfig.checkListType ) ) {
300
306
  if ( getSections.length ) {
@@ -302,7 +308,9 @@ export async function PCLconfigCreation( req, res ) {
302
308
  let collectQuestions = {};
303
309
  collectQuestions.section_id = element3._id;
304
310
  collectQuestions.sectionName = element3.section;
311
+ collectQuestions.sectionOldName = element3.sectionOldName || '';
305
312
  collectQuestions.questions = element3.question;
313
+ collectQuestions.sectionNumber = element3.sectionNumber|| '';
306
314
  collectSections.push( collectQuestions );
307
315
  }
308
316
  }
@@ -552,6 +560,7 @@ export async function PCLconfigCreation( req, res ) {
552
560
  element4.checkListType = getCLconfig.checkListType;
553
561
  element4.storeCount = getCLconfig.storeCount;
554
562
  element4.questionCount = getCLconfig.questionCount;
563
+ element4.runAIQuestionCount = getCLconfig.runAIQuestionCount;
555
564
  element4.publishDate = getCLconfig.publishDate;
556
565
  element4.locationCount = getCLconfig.locationCount;
557
566
  element4.scheduleRepeatedType = getCLconfig.scheduleRepeatedType;
@@ -863,6 +872,11 @@ async function insertData( requestData ) {
863
872
  isdeleted: false,
864
873
  },
865
874
  } );
875
+ sectionQuery.push( {
876
+ $sort: {
877
+ sectionNumber: 1,
878
+ },
879
+ } );
866
880
  let getSections = await CLquestions.aggregate( sectionQuery );
867
881
  if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in' ].includes( getCLconfig.checkListType ) ) {
868
882
  if ( getSections.length ) {
@@ -2462,3 +2476,43 @@ export async function storecheckExists( data ) {
2462
2476
  logger.error( { error: error, function: 'internalAISendPushNotification' } );
2463
2477
  }
2464
2478
  }
2479
+
2480
+ export async function insertAINotification( req, res ) {
2481
+ try {
2482
+ let requestData = req.body;
2483
+ let insertData= [];
2484
+ let findAllUser = await userService.find( { clientId: requestData.clientId, isActive: true } );
2485
+ for ( let user of findAllUser ) {
2486
+ let data= {};
2487
+ data.userId = user._id;
2488
+ data.storeId = requestData.storeId;
2489
+ data.storeName = requestData.storeName;
2490
+ data.captureTime = requestData.captureTime;
2491
+ data.clientId = requestData.clientId;
2492
+ data.sourceCheckList_id = requestData.sourceCheckList_id;
2493
+ data.checkListName = requestData.checkListName;
2494
+ data.notificationType = requestData.notificationType;
2495
+ let payload = {
2496
+ userType: user.userType,
2497
+ role: user.role,
2498
+ assignedStores: user.assignedStores,
2499
+ clientId: user.clientId,
2500
+ email: user.email,
2501
+ };
2502
+ let result = await storecheckExists( payload );
2503
+ if ( result ) {
2504
+ insertData.push( data );
2505
+ }
2506
+ }
2507
+ // console.log( 'insertData =>', insertData );
2508
+ let create = await notificationModel.insertManynotificationModel( insertData );
2509
+ // console.log( 'create =>', create );
2510
+ if ( create ) {
2511
+ return res.sendSuccess( 'updated successfully' );
2512
+ }
2513
+ } catch ( e ) {
2514
+ logger.error( { error: e, function: 'insertAINotification' } );
2515
+ if ( e.name === 'ValidationError' ) res.sendBadRequest( e );
2516
+ else res.sendError( e, 500 );
2517
+ }
2518
+ }
@@ -155,15 +155,19 @@ export async function startChecklist( req, res ) {
155
155
 
156
156
  let updateData = {};
157
157
  let currentDateTime;
158
- if ( getBeforeChecklist[0].storeName && getBeforeChecklist[0].storeName!='' ) {
159
- let storeTimeZone = await storeService.findOne( { storeName: { $regex: getBeforeChecklist[0].storeName, $options: 'i' }, clientId: getBeforeChecklist[0].client_id }, { 'storeProfile.timeZone': 1 } );
158
+ if ( getBeforeChecklist[0]?.store_id && getBeforeChecklist[0]?.store_id != '' ) {
159
+ let storeTimeZone = await storeService.findOne( { storeId: getBeforeChecklist[0].store_id, clientId: getBeforeChecklist[0].client_id }, { 'storeProfile.timeZone': 1 } );
160
160
  if ( storeTimeZone?.storeProfile?.timeZone ) {
161
161
  currentDateTime = dayjs().tz( storeTimeZone?.storeProfile?.timeZone );
162
162
  } else {
163
163
  currentDateTime = dayjs();
164
164
  }
165
165
  } else {
166
- currentDateTime = dayjs();
166
+ if ( requestData.currentTime && requestData.currentTime !='' ) {
167
+ currentDateTime = requestData?.currentTime ? dayjs( requestData.currentTime, 'HH:mm:ss' ) : dayjs();
168
+ } else {
169
+ currentDateTime = dayjs();
170
+ }
167
171
  }
168
172
  updateData.checklistStatus = 'inprogress';
169
173
  updateData.startMobileTime = requestData?.currentTime;
@@ -347,13 +351,29 @@ export async function startTask( req, res ) {
347
351
  }
348
352
  }
349
353
 
350
- const storeTimeZone = await storeService.findOne(
351
- { storeName: task.storeName },
352
- { 'storeProfile.timeZone': 1 },
353
- );
354
- const currentDateTime = storeTimeZone?.storeProfile?.timeZone ?
355
- dayjs().tz( storeTimeZone.storeProfile.timeZone ) :
356
- dayjs();
354
+ // const storeTimeZone = await storeService.findOne(
355
+ // { storeName: task.storeName },
356
+ // { 'storeProfile.timeZone': 1 },
357
+ // );
358
+ // const currentDateTime = storeTimeZone?.storeProfile?.timeZone ?
359
+ // dayjs().tz( storeTimeZone.storeProfile.timeZone ) :
360
+ // dayjs();
361
+
362
+ let currentDateTime;
363
+ if ( getBeforeTask[0].storeName && getBeforeTask[0].storeName!='' ) {
364
+ let storeTimeZone = await storeService.findOne( { storeName: { $regex: getBeforeTask[0].storeName, $options: 'i' }, clientId: getBeforeTask[0].client_id }, { 'storeProfile.timeZone': 1 } );
365
+ if ( storeTimeZone?.storeProfile?.timeZone ) {
366
+ currentDateTime = dayjs().tz( storeTimeZone?.storeProfile?.timeZone );
367
+ } else {
368
+ currentDateTime = dayjs();
369
+ }
370
+ } else {
371
+ if ( requestData.currentTime && requestData.currentTime !='' ) {
372
+ currentDateTime = requestData?.currentTime ? dayjs( requestData.currentTime, 'HH:mm:ss' ) : dayjs();
373
+ } else {
374
+ currentDateTime = dayjs();
375
+ }
376
+ }
357
377
 
358
378
 
359
379
  let updatedNewData;
@@ -1804,8 +1824,8 @@ export async function submitChecklist( req, res ) {
1804
1824
 
1805
1825
  let currentDateTime;
1806
1826
  let storeTimeZone;
1807
- if ( getchecklist[0].storeName && getchecklist[0].storeName !='' ) {
1808
- storeTimeZone = await storeService.findOne( { storeName: { $regex: getchecklist[0].storeName, $options: 'i' }, clientId: getchecklist[0].client_id }, { 'storeProfile.timeZone': 1 } );
1827
+ if ( getchecklist[0]?.store_id && getchecklist[0]?.store_id !='' ) {
1828
+ storeTimeZone = await storeService.findOne( { storeId: getchecklist[0].store_id, clientId: getchecklist[0].client_id }, { 'storeProfile.timeZone': 1 } );
1809
1829
  if ( storeTimeZone?.storeProfile?.timeZone ) {
1810
1830
  currentDateTime = dayjs().tz( storeTimeZone?.storeProfile?.timeZone );
1811
1831
  } else {
@@ -534,6 +534,7 @@ export const flagCardsV1 = async ( req, res ) => {
534
534
  questionFlag: { count: 0 },
535
535
  delayInSubmission: { count: 0 },
536
536
  detectionFlag: { count: 0 },
537
+ runAIFlag: { flagCount: 0, list: [] },
537
538
  };
538
539
 
539
540
  let requestData = req.body;
@@ -581,6 +582,7 @@ export const flagCardsV1 = async ( req, res ) => {
581
582
  'detectionFlag': {
582
583
  'count': 0,
583
584
  },
585
+ 'runAIFlag': { flagCount: 0, list: [] },
584
586
  },
585
587
  };
586
588
  return res.sendSuccess( resVal );
@@ -617,6 +619,7 @@ export const flagCardsV1 = async ( req, res ) => {
617
619
  }
618
620
  } );
619
621
  flagCards.totalFlag += flagCards.detectionFlag.count;
622
+ flagCards.runAIFlag = resultData?.runAI;
620
623
  }
621
624
 
622
625
  return res.sendSuccess( { flagCards } );
@@ -819,6 +822,8 @@ export const flagTablesV1 = async ( req, res ) => {
819
822
  findAndQuery.push( { timeFlag: { $gte: 1 } } );
820
823
  } else if ( requestData?.filter === 'detection' ) {
821
824
  findAndQuery.push( { checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum' ] } } );
825
+ } else if ( requestData?.filter === 'runAI' ) {
826
+ findAndQuery.push( { runAIQuestionCount: { $gte: 1 } } );
822
827
  }
823
828
 
824
829
  findQuery.push( { $match: { $and: findAndQuery } } );
@@ -1033,7 +1038,7 @@ export const flagTablesV1 = async ( req, res ) => {
1033
1038
  if ( getChecklistPerformanceData.length ) {
1034
1039
  const detectionChecklists = getChecklistPerformanceData?.filter( ( val ) => val?.checkListType !== 'custom' );
1035
1040
 
1036
- if ( detectionChecklists?.length ) {
1041
+ if ( detectionChecklists?.length || requestData?.filter === 'runAI' ) {
1037
1042
  const detectionPayload = {
1038
1043
  'fromDate': requestData.fromDate,
1039
1044
  'toDate': requestData.toDate,
@@ -1046,13 +1051,23 @@ export const flagTablesV1 = async ( req, res ) => {
1046
1051
  if ( resultData ) {
1047
1052
  if ( resultData.status_code == '200' ) {
1048
1053
  for ( let index = 0; index < getChecklistPerformanceData.length; index++ ) {
1049
- if ( getChecklistPerformanceData[index].checkListType !== 'custom' ) {
1050
- getChecklistPerformanceData[index].flagCount = resultData?.[getChecklistPerformanceData[index]?.checkListType] || 0;
1051
- getChecklistPerformanceData[index].flaggedStores = resultData?.[`${getChecklistPerformanceData[index]?.checkListType}_flaggedstores`] || 0;
1052
- getChecklistPerformanceData[index].assignedStores = getChecklistPerformanceData[index]?.aiStoreList?.filter( ( element ) => requestData.storeId.includes( element ) )?.length || 0;
1053
- getChecklistPerformanceData[index].complianceRate = ( 100- ( getChecklistPerformanceData[index].flaggedStores / getChecklistPerformanceData[index].assignedStores ) * 100 );
1054
- getChecklistPerformanceData[index].complianceRate = Math.min( 100, Math.max( 0, getChecklistPerformanceData[index].complianceRate ) );
1055
- getChecklistPerformanceData[index].complianceRate = ( getChecklistPerformanceData[index].complianceRate % 1 === 0 ) ? getChecklistPerformanceData[index].complianceRate.toFixed( 0 ) : getChecklistPerformanceData[index].complianceRate.toFixed( 2 );
1054
+ if ( requestData?.filter === 'runAI' ) {
1055
+ let findCheckList = resultData.runAI.list.find( ( ele ) => ele.checkListName == getChecklistPerformanceData[index].getChecklistPerformanceData );
1056
+ if ( findCheckList ) {
1057
+ getChecklistPerformanceData[index].flaggedStores = findCheckList.flagCount;
1058
+ getChecklistPerformanceData[index].complianceRate = ( 100- ( getChecklistPerformanceData[index].flaggedStores / getChecklistPerformanceData[index].assignedStores ) * 100 );
1059
+ getChecklistPerformanceData[index].complianceRate = Math.min( 100, Math.max( 0, getChecklistPerformanceData[index].complianceRate ) );
1060
+ getChecklistPerformanceData[index].complianceRate = ( getChecklistPerformanceData[index].complianceRate % 1 === 0 ) ? getChecklistPerformanceData[index].complianceRate.toFixed( 0 ) : getChecklistPerformanceData[index].complianceRate.toFixed( 2 );
1061
+ }
1062
+ } else {
1063
+ if ( getChecklistPerformanceData[index].checkListType !== 'custom' ) {
1064
+ getChecklistPerformanceData[index].flagCount = resultData?.[getChecklistPerformanceData[index]?.checkListType] || 0;
1065
+ getChecklistPerformanceData[index].flaggedStores = resultData?.[`${getChecklistPerformanceData[index]?.checkListType}_flaggedstores`] || 0;
1066
+ getChecklistPerformanceData[index].assignedStores = getChecklistPerformanceData[index]?.aiStoreList?.filter( ( element ) => requestData.storeId.includes( element ) )?.length || 0;
1067
+ getChecklistPerformanceData[index].complianceRate = ( 100- ( getChecklistPerformanceData[index].flaggedStores / getChecklistPerformanceData[index].assignedStores ) * 100 );
1068
+ getChecklistPerformanceData[index].complianceRate = Math.min( 100, Math.max( 0, getChecklistPerformanceData[index].complianceRate ) );
1069
+ getChecklistPerformanceData[index].complianceRate = ( getChecklistPerformanceData[index].complianceRate % 1 === 0 ) ? getChecklistPerformanceData[index].complianceRate.toFixed( 0 ) : getChecklistPerformanceData[index].complianceRate.toFixed( 2 );
1070
+ }
1056
1071
  }
1057
1072
  }
1058
1073
  }
@@ -2388,7 +2403,7 @@ export const flagChecklistTableV1 = async ( req, res ) => {
2388
2403
  // let loginUser = { clientId: reqestData.clientId, role: req.user.role, userType: req.user.userType, userEmail: req.user.email };
2389
2404
  // let getUserEmails = await getChecklistUsers( loginUser );
2390
2405
  // End: Get User Based Checklist////
2391
- if ( reqestData.ChecklistType == 'custom' ) {
2406
+ if ( reqestData.ChecklistType == 'custom' && reqestData?.filter !== 'runAI' ) {
2392
2407
  const match = {
2393
2408
  $match: {
2394
2409
  $and: [
@@ -2500,7 +2515,7 @@ export const flagChecklistTableV1 = async ( req, res ) => {
2500
2515
  if ( reqestData.export ) {
2501
2516
  reqestData.limit = 10000;
2502
2517
  reqestData.offset = 0;
2503
- let LamdaURL = 'https://bnauly42yuztzrgtttodzt3bcm0oqrsi.lambda-url.ap-south-1.on.aws/';
2518
+ let LamdaURL = 'https://vpcejaftccr3jzqf5wrdkks7yy0krqix.lambda-url.ap-south-1.on.aws/';
2504
2519
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
2505
2520
  if ( resultData ) {
2506
2521
  if ( resultData.status_code == '200' ) {
@@ -2509,16 +2524,27 @@ export const flagChecklistTableV1 = async ( req, res ) => {
2509
2524
  if ( reqestData.ChecklistType==='scrum'||reqestData.ChecklistType==='cleaning' ) {
2510
2525
  reqestData.ChecklistType = 'scrumdetection';
2511
2526
  }
2512
- resultData[reqestData.ChecklistType + 'Data'].forEach( ( element ) => {
2513
- exportdata.push( {
2514
- 'Date': element?.date,
2515
- 'Store Name': element?.storeName,
2516
- 'Store Id': element?.storeId,
2517
- // 'Store Spoc Email': element?.SpocEmail,
2518
- 'Detections': element?.detections,
2519
- 'Detection Status': element?.detectionStatus,
2527
+ if ( reqestData?.filter === 'runAI' ) {
2528
+ resultData.aiFlagData.forEach( ( element ) => {
2529
+ exportdata.push( {
2530
+ 'Date': element?.dateString,
2531
+ 'Store Name': element?.storeName,
2532
+ 'User Email': element?.spocEmail,
2533
+ 'Detections': element?.detections,
2534
+ } );
2520
2535
  } );
2521
- } );
2536
+ } else {
2537
+ resultData[reqestData.ChecklistType + 'Data'].forEach( ( element ) => {
2538
+ exportdata.push( {
2539
+ 'Date': element?.date,
2540
+ 'Store Name': element?.storeName,
2541
+ 'Store Id': element?.storeId,
2542
+ // 'Store Spoc Email': element?.SpocEmail,
2543
+ 'Detections': element?.detections,
2544
+ 'Detection Status': element?.detectionStatus,
2545
+ } );
2546
+ } );
2547
+ }
2522
2548
  return await download( exportdata, res );
2523
2549
  } else {
2524
2550
  return res.sendError( 'No Content', 204 );
@@ -2529,11 +2555,18 @@ export const flagChecklistTableV1 = async ( req, res ) => {
2529
2555
  }
2530
2556
  // console.log( reqestData );
2531
2557
 
2532
- let LamdaURL = 'https://bnauly42yuztzrgtttodzt3bcm0oqrsi.lambda-url.ap-south-1.on.aws/';
2558
+ let LamdaURL = 'https://vpcejaftccr3jzqf5wrdkks7yy0krqix.lambda-url.ap-south-1.on.aws/';
2533
2559
  let resultData = await LamdaServiceCall( LamdaURL, reqestData );
2534
2560
  // console.log( 'resultData =>', resultData );
2535
2561
  if ( resultData ) {
2536
2562
  if ( resultData.status_code == '200' ) {
2563
+ if ( reqestData?.filter === 'runAI' ) {
2564
+ resultData.aiFlagData = resultData.aiFlagData.map( ( ele ) => {
2565
+ ele = { ...ele, date: ele.dateString, storeSpocEmail: ele?.spocEmail, checklistStatus: 'submit' };
2566
+ return ele;
2567
+ } );
2568
+ resultData = { customData: resultData.aiFlagData, totalCount: resultData.totalCount };
2569
+ }
2537
2570
  return res.sendSuccess( resultData );
2538
2571
  } else {
2539
2572
  return res.sendError( 'No Content', 204 );
@@ -2871,21 +2904,25 @@ export const flagComparisonCardsV2 = async ( req, res ) => {
2871
2904
  },
2872
2905
  { checkListType: 1 },
2873
2906
  );
2874
- if ( !publishedAiChecklists?.length ) {
2875
- return 0;
2876
- }
2907
+ // if ( !publishedAiChecklists?.length ) {
2908
+ // return 0;
2909
+ // }
2877
2910
 
2878
2911
  const LamdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
2879
2912
  const resultData = await LamdaServiceCall( LamdaURL, detectionPayload );
2880
2913
  const published = publishedAiChecklists.map( ( val ) => val?.checkListType );
2881
2914
  if ( resultData?.status_code === '200' ) {
2882
2915
  let result = 0;
2883
- published.forEach( ( item ) => {
2884
- if ( resultData[item] ) {
2885
- result += resultData[item];
2886
- }
2887
- } );
2888
- return result;
2916
+ let ai = 0;
2917
+ if ( !publishedAiChecklists?.length ) {
2918
+ published.forEach( ( item ) => {
2919
+ if ( resultData[item] ) {
2920
+ result += resultData[item];
2921
+ }
2922
+ } );
2923
+ }
2924
+ ai = resultData?.runAI?.flagCount || 0;
2925
+ return { result, ai };
2889
2926
  }
2890
2927
  return 0;
2891
2928
  };
@@ -2910,15 +2947,17 @@ export const flagComparisonCardsV2 = async ( req, res ) => {
2910
2947
  questionComparisonFlag: { comparisonData: 0, ComparisonFlag: false },
2911
2948
  delayInSubmissionComparisonFlag: { comparisonData: 0, ComparisonFlag: false },
2912
2949
  detectionComparisonFlag: { comparisonData: 0, ComparisonFlag: false },
2950
+ runAIComparisonFlag: { comparisonData: 0, ComparisonFlag: false },
2913
2951
  };
2914
2952
 
2915
2953
  if ( rangeOneData.length && rangeTwoData.length ) {
2916
- let rangeOneTotalFlag = rangeOneData[0].totalFlag + rangeOneDetectionCount || 0;
2917
- let rangeTwoTotalFlag = rangeTwoData[0].totalFlag + rangeTwoDetectionCount || 0;
2954
+ let rangeOneTotalFlag = rangeOneData[0].totalFlag + rangeOneDetectionCount.result || 0;
2955
+ let rangeTwoTotalFlag = rangeTwoData[0].totalFlag + rangeTwoDetectionCount.result || 0;
2918
2956
  flagComparisonCards.totalComparisonFlag = calculateComparison( rangeOneTotalFlag, rangeTwoTotalFlag );
2919
2957
  flagComparisonCards.questionComparisonFlag = calculateComparison( rangeOneData[0].questionFlag, rangeTwoData[0].questionFlag );
2920
2958
  flagComparisonCards.delayInSubmissionComparisonFlag = calculateComparison( rangeOneData[0].delayInSubmission, rangeTwoData[0].delayInSubmission );
2921
- flagComparisonCards.detectionComparisonFlag = calculateComparison( rangeOneDetectionCount, rangeTwoDetectionCount );
2959
+ flagComparisonCards.detectionComparisonFlag = calculateComparison( rangeOneDetectionCount.result, rangeTwoDetectionCount.result );
2960
+ flagComparisonCards.runAIComparisonFlag = calculateComparison( rangeOneDetectionCount.ai, rangeTwoDetectionCount.ai );
2922
2961
  }
2923
2962
  flagComparisonCards.traxMonthlyComparison = false;
2924
2963
  let traxMonthlyComparisonData = await clientService.findOne( { clientId: requestData.clientId }, { traxMonthlyComparison: 1 } );
@@ -2961,6 +3000,8 @@ export const flagTablesV2 = async ( req, res ) => {
2961
3000
  findAndQuery.push( { timeFlag: { $gte: 1 } } );
2962
3001
  } else if ( requestData?.filter === 'detection' ) {
2963
3002
  findAndQuery.push( { checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum' ] } } );
3003
+ } else if ( requestData?.filter === 'runAI' ) {
3004
+ findAndQuery.push( { runAIQuestionCount: { $gte: 1 } } );
2964
3005
  }
2965
3006
 
2966
3007
  findQuery.push( { $match: { $and: findAndQuery } } );
@@ -2989,6 +3030,7 @@ export const flagTablesV2 = async ( req, res ) => {
2989
3030
  scheduleRepeatedType: 1,
2990
3031
  store_id: 1,
2991
3032
  aiStoreList: 1,
3033
+ runAIQuestionCount: 1,
2992
3034
  },
2993
3035
  } );
2994
3036
 
@@ -3035,6 +3077,7 @@ export const flagTablesV2 = async ( req, res ) => {
3035
3077
  aiStoreList: { $max: '$aiStoreList' },
3036
3078
  aiStoreListNew: { $sum: { $size: '$aiStoreList' } },
3037
3079
  submittedQuestionCount: { $sum: { $cond: [ { $eq: [ '$checklistStatus', 'submit' ] }, '$questionCount', 0 ] } },
3080
+ runAIQuestionCount: { $last: '$runAIQuestionCount' },
3038
3081
  },
3039
3082
  } );
3040
3083
 
@@ -3056,6 +3099,7 @@ export const flagTablesV2 = async ( req, res ) => {
3056
3099
  customQuestionFlagCount: '$questionFlag',
3057
3100
  customTimeFlagCount: '$timeFlag',
3058
3101
  aiStoreList: 1,
3102
+ runAIQuestionCount: 1,
3059
3103
  },
3060
3104
  } );
3061
3105
 
@@ -3089,6 +3133,7 @@ export const flagTablesV2 = async ( req, res ) => {
3089
3133
  customQuestionFlagCount: 1,
3090
3134
  customTimeFlagCount: 1,
3091
3135
  aiStoreList: 1,
3136
+ runAIQuestionCount: 1,
3092
3137
  },
3093
3138
  } );
3094
3139
 
@@ -3115,7 +3160,7 @@ export const flagTablesV2 = async ( req, res ) => {
3115
3160
  if ( getChecklistPerformanceData.length ) {
3116
3161
  const detectionChecklists = getChecklistPerformanceData?.filter( ( val ) => val?.checkListType !== 'custom' );
3117
3162
 
3118
- if ( detectionChecklists?.length ) {
3163
+ if ( detectionChecklists?.length || [ 'runAI', 'all' ].includes( requestData?.filter ) ) {
3119
3164
  const detectionPayload = {
3120
3165
  'fromDate': requestData.fromDate,
3121
3166
  'toDate': requestData.toDate,
@@ -3128,13 +3173,37 @@ export const flagTablesV2 = async ( req, res ) => {
3128
3173
  if ( resultData ) {
3129
3174
  if ( resultData.status_code == '200' ) {
3130
3175
  for ( let index = 0; index < getChecklistPerformanceData.length; index++ ) {
3131
- if ( getChecklistPerformanceData[index].checkListType !== 'custom' ) {
3132
- getChecklistPerformanceData[index].flagCount = resultData?.[getChecklistPerformanceData[index]?.checkListType] || 0;
3133
- getChecklistPerformanceData[index].flaggedStores = resultData?.[`${getChecklistPerformanceData[index]?.checkListType}_flaggedstores`] || 0;
3134
- getChecklistPerformanceData[index].assignedStores = getChecklistPerformanceData[index]?.aiStoreList?.filter( ( element ) => requestData.storeId.includes( element ) )?.length || 0;
3176
+ if ( [ 'runAI', 'all' ].includes( requestData?.filter ) ) {
3177
+ let findCheckList = resultData.runAI.list.find( ( ele ) => ele.checkListName == getChecklistPerformanceData[index].checkListName );
3178
+ if ( findCheckList ) {
3179
+ if ( requestData?.filter == 'all' ) {
3180
+ getChecklistPerformanceData[index].runAIFlag = findCheckList.flagCount;
3181
+ getChecklistPerformanceData[index].flaggedStores = getChecklistPerformanceData[index].flaggedStores + findCheckList.flagCount;
3182
+ } else {
3183
+ getChecklistPerformanceData[index].flagCount = findCheckList.flagCount;
3184
+ getChecklistPerformanceData[index].flaggedStores = findCheckList.flagCount;
3185
+ }
3186
+ } else {
3187
+ if ( requestData?.filter == 'all' ) {
3188
+ getChecklistPerformanceData[index].runAIFlag = 0;
3189
+ getChecklistPerformanceData[index].runAIFlagStore = 0;
3190
+ } else {
3191
+ getChecklistPerformanceData[index].flagCount = 0;
3192
+ getChecklistPerformanceData[index].flaggedStores = 0;
3193
+ }
3194
+ }
3135
3195
  getChecklistPerformanceData[index].complianceRate = ( 100- ( getChecklistPerformanceData[index].flaggedStores / getChecklistPerformanceData[index].assignedStores ) * 100 );
3136
3196
  getChecklistPerformanceData[index].complianceRate = Math.min( 100, Math.max( 0, getChecklistPerformanceData[index].complianceRate ) );
3137
3197
  getChecklistPerformanceData[index].complianceRate = ( getChecklistPerformanceData[index].complianceRate % 1 === 0 ) ? getChecklistPerformanceData[index].complianceRate.toFixed( 0 ) : getChecklistPerformanceData[index].complianceRate.toFixed( 2 );
3198
+ } else {
3199
+ if ( getChecklistPerformanceData[index].checkListType !== 'custom' ) {
3200
+ getChecklistPerformanceData[index].flagCount = resultData?.[getChecklistPerformanceData[index]?.checkListType] || 0;
3201
+ getChecklistPerformanceData[index].flaggedStores = resultData?.[`${getChecklistPerformanceData[index]?.checkListType}_flaggedstores`] || 0;
3202
+ getChecklistPerformanceData[index].assignedStores = getChecklistPerformanceData[index]?.aiStoreList?.filter( ( element ) => requestData.storeId.includes( element ) )?.length || 0;
3203
+ getChecklistPerformanceData[index].complianceRate = ( 100- ( getChecklistPerformanceData[index].flaggedStores / getChecklistPerformanceData[index].assignedStores ) * 100 );
3204
+ getChecklistPerformanceData[index].complianceRate = Math.min( 100, Math.max( 0, getChecklistPerformanceData[index].complianceRate ) );
3205
+ getChecklistPerformanceData[index].complianceRate = ( getChecklistPerformanceData[index].complianceRate % 1 === 0 ) ? getChecklistPerformanceData[index].complianceRate.toFixed( 0 ) : getChecklistPerformanceData[index].complianceRate.toFixed( 2 );
3206
+ }
3138
3207
  }
3139
3208
  }
3140
3209
  }
@@ -3147,12 +3216,13 @@ export const flagTablesV2 = async ( req, res ) => {
3147
3216
  getChecklistPerformanceData.forEach( ( element ) => {
3148
3217
  const data = {
3149
3218
  'Checklist Name': element.checkListName,
3150
- 'Question Flags': element?.customQuestionFlagCount,
3151
- 'Not Submitted Flags': element?.customTimeFlagCount,
3152
- 'Detection Flags': element?.flagCount,
3153
3219
  'Coverage': element?.coverage,
3154
3220
  'Assigned Stores': element?.checkListType === 'custom' ? element?.assignedStores : element?.assignedStoresAi,
3155
3221
  'Flagged Stores': element?.flaggedStores,
3222
+ 'Question Flags': element?.customQuestionFlagCount,
3223
+ ...( element.runAIFlag ? { 'Run AI Flag': element.runAIFlag } : {} ),
3224
+ 'Not Submitted Flags': element?.customTimeFlagCount,
3225
+ 'Detection Flags': element?.flagCount,
3156
3226
  'Compliance': element?.complianceRate,
3157
3227
  // 'Flag Type': element?.checkListType === 'custom' ? 'Question' : 'Detection',
3158
3228
  };
@@ -3162,18 +3232,21 @@ export const flagTablesV2 = async ( req, res ) => {
3162
3232
  delete data['Flagged Count'];
3163
3233
  delete data['Not Submitted Flags'];
3164
3234
  delete data['Detection Flags'];
3235
+ delete data['Run AI Flag'];
3165
3236
  } else if ( requestData?.filter === 'time' ) {
3166
3237
  data['Flags'] = data['Not Submitted Flags'];
3167
3238
  delete data['Question Flags'];
3168
3239
  delete data['Flagged Count'];
3169
3240
  delete data['Not Submitted Flags'];
3170
3241
  delete data['Detection Flags'];
3242
+ delete data['Run AI Flag'];
3171
3243
  } else if ( requestData?.filter === 'detection' ) {
3172
3244
  data['Flags'] = data['Detection Flags'];
3173
3245
  delete data['Question Flags'];
3174
3246
  delete data['Flagged Count'];
3175
3247
  delete data['Not Submitted Flags'];
3176
3248
  delete data['Detection Flags'];
3249
+ delete data['Run AI Flag'];
3177
3250
  }
3178
3251
  exportdata.push( data );
3179
3252
  } );
@@ -174,6 +174,8 @@ export const create = async ( req, res ) => {
174
174
  checkNumber = 1;
175
175
  }
176
176
 
177
+ let runAIQuestionCount = 0;
178
+
177
179
  inputBody.sections.forEach( async ( element ) => {
178
180
  if ( !element?.questions?.length && inputBody.submitType == 'configure' ) {
179
181
  return res.sendError( { message: 'Question is Required' }, 400 );
@@ -181,6 +183,8 @@ export const create = async ( req, res ) => {
181
183
  if ( element?.questions?.length ) {
182
184
  questionCount = questionCount + element?.questions?.length;
183
185
  }
186
+ let runAiQuestions = element?.questions.filter( ( qn ) => qn.runAI );
187
+ runAIQuestionCount +=runAiQuestions.length;
184
188
  } );
185
189
 
186
190
  let checkListDetails = {
@@ -193,6 +197,7 @@ export const create = async ( req, res ) => {
193
197
  questionCount: questionCount,
194
198
  client_id: req.body?.clientId,
195
199
  owner: req.user.userType == 'client' ? [ { name: req.user.userName, value: req.user.email } ] : [],
200
+ runAIQuestionCount: runAIQuestionCount,
196
201
  // configStartDate:new Date(),
197
202
  // configEndDate:new Date(),
198
203
  };
@@ -402,7 +407,8 @@ export const getConfigDetails = async ( req, res ) => {
402
407
  checkListId: storechecklistdetails._id,
403
408
  isdeleted: false,
404
409
  };
405
- let questionDetails = await questionService.find( query );
410
+ let sectionSort = { sectionNumber: 1 };
411
+ let questionDetails = await questionService.findSort( query, {}, sectionSort );
406
412
  if ( questionDetails.length ) {
407
413
  let sections = [];
408
414
  let bucket = JSON.parse( process.env.BUCKET );
@@ -738,7 +744,7 @@ export const duplicateChecklist = async ( req, res ) => {
738
744
  }
739
745
  await assignedService.insertMany( users );
740
746
  }
741
- let sectionList = await questionService.find( { checkListId: checkDetails._id, client_id: req.query.clientId, isdeleted: false } );
747
+ let sectionList = await questionService.findSort( { checkListId: checkDetails._id, client_id: req.query.clientId, isdeleted: false }, {}, { sectionNumber: 1 } );
742
748
  if ( sectionList.length ) {
743
749
  let sections= [];
744
750
  for ( let i = 0; i < sectionList.length; i++ ) {
@@ -810,8 +816,8 @@ export const update = async ( req, res ) => {
810
816
  return res.sendError( 'no data found', 204 );
811
817
  }
812
818
 
813
- let getExistQuestions = await questionService.find( { checkListId: req.params.checklistId, client_id: req.body.clientId } );
814
-
819
+ let getExistQuestions = await questionService.findSort( { checkListId: req.params.checklistId, client_id: req.body.clientId }, {}, { sectionNumber: 1 } );
820
+ let runAIQuestionCount = 0;
815
821
  inputBody.sections.forEach( async ( element ) => {
816
822
  if ( !element.questions.length && inputBody.submitType == 'configure' ) {
817
823
  return res.sendError( { message: 'Question is Required' }, 400 );
@@ -820,6 +826,8 @@ export const update = async ( req, res ) => {
820
826
  if ( element.questions.length ) {
821
827
  questionCount = questionCount + element.questions.length;
822
828
  }
829
+ let runAiQuestions = element?.questions.filter( ( qn ) => qn.runAI );
830
+ runAIQuestionCount +=runAiQuestions.length;
823
831
  } );
824
832
 
825
833
 
@@ -827,6 +835,7 @@ export const update = async ( req, res ) => {
827
835
  checkListName: inputBody.checklistName,
828
836
  checkListDescription: inputBody.checklistDescription,
829
837
  questionCount: questionCount,
838
+ runAIQuestionCount: runAIQuestionCount,
830
839
  };
831
840
 
832
841
  await checklistService.updateOne( { _id: req.params.checklistId }, params );
@@ -2950,6 +2959,7 @@ export async function insertSingleProcessData( checklistId, processId = 0, oldDa
2950
2959
  insertdata.checkListType = getCLconfig.checkListType;
2951
2960
  insertdata.storeCount = getCLconfig.storeCount;
2952
2961
  insertdata.questionCount = getCLconfig.questionCount;
2962
+ insertdata.runAIQuestionCount = getCLconfig.runAIQuestionCount;
2953
2963
  insertdata.publishDate = getCLconfig.publishDate;
2954
2964
  insertdata.locationCount = getCLconfig.locationCount;
2955
2965
  insertdata.scheduleRepeatedType = getCLconfig.scheduleRepeatedType;
@@ -2969,6 +2979,11 @@ export async function insertSingleProcessData( checklistId, processId = 0, oldDa
2969
2979
  isdeleted: false,
2970
2980
  },
2971
2981
  } );
2982
+ sectionQuery.push( {
2983
+ $sort: {
2984
+ sectionNumber: 1,
2985
+ },
2986
+ } );
2972
2987
  let getSections = await questionService.aggregate( sectionQuery );
2973
2988
  if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection' ].includes( getCLconfig.checkListType ) ) {
2974
2989
  if ( getSections.length ) {
@@ -2978,6 +2993,7 @@ export async function insertSingleProcessData( checklistId, processId = 0, oldDa
2978
2993
  collectQuestions.sectionName = element3.section;
2979
2994
  collectQuestions.sectionOldName = element3.sectionOldName;
2980
2995
  collectQuestions.questions = element3.question;
2996
+ collectQuestions.sectionNumber = element3.sectionNumber || 0;
2981
2997
  collectSections.push( collectQuestions );
2982
2998
  }
2983
2999
  }
@@ -3664,6 +3680,7 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
3664
3680
  element4.checkListType = getCLconfig.checkListType;
3665
3681
  element4.storeCount = getCLconfig.storeCount;
3666
3682
  element4.questionCount = getCLconfig.questionCount;
3683
+ element4.runAIQuestionCount = getCLconfig.runAIQuestionCount;
3667
3684
  element4.publishDate = getCLconfig.publishDate;
3668
3685
  element4.locationCount = getCLconfig.locationCount;
3669
3686
  element4.scheduleRepeatedType = getCLconfig.scheduleRepeatedType;
@@ -728,6 +728,7 @@ export const userPerformance = async ( req, res ) => {
728
728
  userEmail: 1,
729
729
  userName: 1,
730
730
  questionCount: 1,
731
+ redoStatus: 1,
731
732
  },
732
733
  } );
733
734
 
@@ -745,6 +746,7 @@ export const userPerformance = async ( req, res ) => {
745
746
  submittedChecklistQuestionCount: {
746
747
  $sum: { $cond: [ { $eq: [ '$checklistStatus', 'submit' ] }, '$questionCount', 0 ] },
747
748
  },
749
+ redo: { $sum: { $cond: [ { $eq: [ '$redoStatus', true ] }, 1, 0 ] } },
748
750
  },
749
751
  } );
750
752
 
@@ -816,6 +818,7 @@ export const userPerformance = async ( req, res ) => {
816
818
  'Email': element.userEmail || '--',
817
819
  'Checklist Assigned': element.checkListCount || '--',
818
820
  'Flags': element.flaggedCount || '--',
821
+ 'ReDo': element.redo || '--',
819
822
  'Completion %': element.completion || '--',
820
823
  'Compliance %': element.compliance || '--',
821
824
  'Performance %': element.performance || '--',
@@ -1694,7 +1697,7 @@ export const checklistInfo = async ( req, res ) => {
1694
1697
  exportdata.push( {
1695
1698
  'Date': element.date_string || '--',
1696
1699
  'Store Name': element.storeName || '--',
1697
- 'Checklist Owner': element.userName || '--',
1700
+ 'User Name': element.userName || '--',
1698
1701
  'Status': element.checklistStatus || '--',
1699
1702
  'Submitted By': element.userName || '--',
1700
1703
  'Submitted On': element.submitTime_string || '--',
@@ -1705,7 +1708,7 @@ export const checklistInfo = async ( req, res ) => {
1705
1708
  } else if ( requestData.groupByType==='Store' ) {
1706
1709
  exportdata.push( {
1707
1710
  'CheckList Name': element.checkListName || '--',
1708
- 'Checklist Owner': element.userName || '--',
1711
+ 'User Name': element.userName || '--',
1709
1712
  'Status': element.checklistStatus || '--',
1710
1713
  'Submitted By': element.userName || '--',
1711
1714
  'Submitted On': element.submitTime_string || '--',
@@ -1719,7 +1722,7 @@ export const checklistInfo = async ( req, res ) => {
1719
1722
  'Date': element.date_string || '--',
1720
1723
  'CheckList Name': element.checkListName || '--',
1721
1724
  'Store Name': element.storeName || '--',
1722
- 'Checklist Owner': element.userName || '--',
1725
+ 'User Name': element.userName || '--',
1723
1726
  'Status': element.checklistStatus || '--',
1724
1727
  'Submitted On': element.submitTime_string || '--',
1725
1728
  'Flags': element.flaggedChecklist || '--',
@@ -24,6 +24,7 @@ internalTraxRouter
24
24
  .post( '/sendPushNotification', isAllowedInternalAPIHandler, internalController.internalSendPushNotification )
25
25
  .post( '/sendAiPushNotification', isAllowedInternalAPIHandler, internalController.internalAISendPushNotification )
26
26
  .post( '/getLiveChecklistClients', isAllowedInternalAPIHandler, internalController.getLiveChecklistClients )
27
- .post( '/notificationCreate', isAllowedInternalAPIHandler, internalController.notificationCreate );
27
+ .post( '/notificationCreate', isAllowedInternalAPIHandler, internalController.notificationCreate )
28
+ .post( '/insertAINotification', isAllowedInternalAPIHandler, internalController.insertAINotification );
28
29
 
29
30
 
@@ -28,4 +28,8 @@ export const aggregate = async ( query = {} ) => {
28
28
  return model.checklistquestionconfigModel.aggregate( query );
29
29
  };
30
30
 
31
+ export const findSort = async ( query={}, field={}, sort = {} ) => {
32
+ return model.checklistquestionconfigModel.find( query, field ).sort( sort );
33
+ };
34
+
31
35