tango-app-api-trax 3.7.99 → 3.8.0

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.7.99",
3
+ "version": "3.8.0",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -29,7 +29,7 @@
29
29
  "nodemon": "^3.1.4",
30
30
  "path": "^0.12.7",
31
31
  "puppeteer": "^24.39.1",
32
- "tango-api-schema": "^2.5.68",
32
+ "tango-api-schema": "^2.5.72",
33
33
  "tango-app-api-middleware": "^3.5.2",
34
34
  "url": "^0.11.4",
35
35
  "winston": "^3.13.1",
@@ -322,7 +322,7 @@ export async function PCLconfigCreation( req, res ) {
322
322
  },
323
323
  } );
324
324
  let getSections = await CLquestions.aggregate( sectionQuery );
325
- if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert' ].includes( getCLconfig.checkListType ) ) {
325
+ if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'storehygienemonitoring' ].includes( getCLconfig.checkListType ) ) {
326
326
  if ( getSections.length ) {
327
327
  for ( let element3 of getSections ) {
328
328
  let collectQuestions = {};
@@ -2147,6 +2147,36 @@ export async function AiPushNotificationAlert( req, res ) {
2147
2147
  }
2148
2148
  }
2149
2149
 
2150
+ export async function liveAiPushNotificationAlert( req, res ) {
2151
+ try {
2152
+ // console.log( req.body );
2153
+ let findAichecklist = await PCLconfig.findOne( { checkListType: req.body.checkListType, client_id: req.body.clientId, date_string: req.body.Date }, { aiConfig: 1 } );
2154
+ if ( findAichecklist?.aiConfig?.alertConfig?.mobile.length ) {
2155
+ // console.log( findAichecklist.aiConfig.alerts.users );
2156
+ for ( let user of findAichecklist?.aiConfig?.alertConfig?.mobile ) {
2157
+ let findOneUser = await userService.findOne( { email: user.value }, { fcmToken: 1 } );
2158
+ // console.log( findOneUser );
2159
+ if ( findOneUser&&findOneUser.fcmToken&&findOneUser.fcmToken!='' ) {
2160
+ // console.log( findOneUser.fcmToken );
2161
+ try {
2162
+ await sendPushNotification( req.body.title, req.body.description, findOneUser.fcmToken );
2163
+ } catch ( e ) {
2164
+ logger.error( {
2165
+ message: 'push notification',
2166
+ error: e,
2167
+ details: data,
2168
+ } );
2169
+ }
2170
+ } ;
2171
+ }
2172
+ }
2173
+ return res.sendSuccess( 'Push notification send successfully' );
2174
+ } catch ( e ) {
2175
+ logger.error( { function: 'AiPushNotificationAlert', error: e } );
2176
+ return res.sendError( e, 500 );
2177
+ }
2178
+ }
2179
+
2150
2180
 
2151
2181
  export async function taskPushNotification( req, res ) {
2152
2182
  try {
@@ -3585,9 +3615,16 @@ export const downloadInsertPdf = async ( req, res ) => {
3585
3615
  pdfBuffer :
3586
3616
  Buffer.from( pdfBuffer );
3587
3617
 
3588
- const pdfName = `${safeName(
3589
- doc.store_id + '_' + ( doc.storeName || 'store' ),
3590
- )}.pdf`;
3618
+ let pdfName;
3619
+ if ( doc.store_id ) {
3620
+ pdfName = `${safeName(
3621
+ doc.store_id + '_' + ( doc.storeName || 'store' ),
3622
+ )}.pdf`;
3623
+ } else {
3624
+ pdfName = `${safeName(
3625
+ doc.userName + '_' + ( doc.sourceCheckList_id || 'store' ),
3626
+ )}.pdf`;
3627
+ }
3591
3628
 
3592
3629
  res.set( {
3593
3630
  'Content-Type': 'application/pdf',
@@ -4002,3 +4039,125 @@ async function LamdaServiceCall( url, data ) {
4002
4039
  return false;
4003
4040
  }
4004
4041
  }
4042
+
4043
+ export async function sendAIEmailList( req, res ) {
4044
+ try {
4045
+ let spocList = [];
4046
+ let result = [];
4047
+ let getChecklistDetails = await CLconfig.findOne( { client_id: req.body.clientId, publish: true, checkListName: req.body.checklistName }, { aiConfig: 1 } );
4048
+ if ( getChecklistDetails && getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.enabled && getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.email?.type?.length ) {
4049
+ let userList = [ ...getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.email?.users.map( ( ele ) => ele.value ) ];
4050
+ if ( getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.email?.type.includes( 'store' ) ) {
4051
+ let checklistAssignList = await CLassign.find( { checkListId: getChecklistDetails._id } );
4052
+ let storeSpoc = await storeService.find( { storeName: { $in: checklistAssignList.map( ( ele ) => ele.storeName ) } }, { spocDetails: 1, storeName: 1, storeId: 1 } );
4053
+ if ( storeSpoc.length ) {
4054
+ spocList = storeSpoc.map( ( ele ) => {
4055
+ return { email: ele?.spocDetails?.[0]?.email, store: ele?.storeId };
4056
+ } );
4057
+ }
4058
+ }
4059
+ if ( getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.email?.type.includes( 'teams' ) ) {
4060
+ let teamDetails = await teamsServices.findteams( { teamName: { $in: getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.email?.teams } }, { spocDetails: 1 } );
4061
+ if ( teamDetails.length ) {
4062
+ userList.push( teamDetails.flatMap( ( team ) => team.users.map( ( user ) => user.email ) ) );
4063
+ }
4064
+ }
4065
+ if ( getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.email?.type.includes( 'users' ) ) {
4066
+ userList.push( getChecklistDetails?.aiConfig?.alertConfig?.alertSendTo?.email.users.map( ( team ) => team.value ) );
4067
+ }
4068
+
4069
+
4070
+ await Promise.all( userList.map( async ( email ) => {
4071
+ let stores = [];
4072
+ let userDetails = await userService.findOne( { email: email } );
4073
+ if ( userDetails ) {
4074
+ if ( userDetails.userType === 'client' && userDetails.role !== 'superadmin' ) {
4075
+ let storeIds = new Set( userDetails.assignedStores.map( ( store ) => store.storeId ) );
4076
+
4077
+ // Fetch clusters and teams in parallel
4078
+ const [ clustersList, teamsList ] = await Promise.all( [
4079
+ clusterServices.findcluster( { clientId: userDetails.clientId, Teamlead: { $elemMatch: { email: userDetails.email } } } ),
4080
+ teamsServices.findteams( { clientId: userDetails.clientId, Teamlead: { $elemMatch: { email: userDetails.email } } } ),
4081
+ ] );
4082
+
4083
+ // Process clusters
4084
+ if ( clustersList.length > 0 ) {
4085
+ for ( let cluster of clustersList ) {
4086
+ cluster.stores.forEach( ( store ) => storeIds.add( store.storeId ) );
4087
+ }
4088
+ }
4089
+
4090
+ // Process teams
4091
+ if ( teamsList.length > 0 ) {
4092
+ for ( let team of teamsList ) {
4093
+ for ( let user of team.users ) {
4094
+ let findUser = await userService.findOne( { _id: user.userId } );
4095
+ if ( findUser && findUser.assignedStores?.length > 0 ) {
4096
+ findUser.assignedStores.forEach( ( store ) => storeIds.add( store.storeId ) );
4097
+ }
4098
+
4099
+ // Fetch clusters for the user
4100
+ let userClustersList = await clusterServices.findcluster( { clientId: userDetails.clientId, Teamlead: { $elemMatch: { email: findUser.email } } } );
4101
+ if ( userClustersList.length > 0 ) {
4102
+ for ( let cluster of userClustersList ) {
4103
+ cluster.stores.forEach( ( store ) => storeIds.add( store.storeId ) );
4104
+ }
4105
+ }
4106
+ }
4107
+ }
4108
+ }
4109
+ let TeamMember = await teamsServices.findteams( { clientId: userDetails.clientId, users: { $elemMatch: { email: userDetails.email } } } );
4110
+ if ( TeamMember&&TeamMember.length>0 ) {
4111
+ for ( let team of TeamMember ) {
4112
+ let clusterList = await clusterServices.findcluster( { clientId: userDetails.clientId, teams: { $elemMatch: { name: team.teamName } } } );
4113
+ if ( clusterList.length > 0 ) {
4114
+ for ( let cluster of clusterList ) {
4115
+ cluster.stores.forEach( ( store ) => storeIds.add( store.storeId ) );
4116
+ }
4117
+ }
4118
+ }
4119
+ }
4120
+ let TeamLeader = await teamsServices.findteams( { clientId: userDetails.clientId, Teamlead: { $elemMatch: { email: userDetails.email } } } );
4121
+ if ( TeamLeader&&TeamLeader.length>0 ) {
4122
+ for ( let team of TeamLeader ) {
4123
+ let clusterList = await clusterServices.findcluster( { clientId: userDetails.clientId, teams: { $elemMatch: { name: team.teamName } } } );
4124
+ if ( clusterList.length > 0 ) {
4125
+ for ( let cluster of clusterList ) {
4126
+ cluster.stores.forEach( ( store ) => storeIds.add( store.storeId ) );
4127
+ }
4128
+ }
4129
+ }
4130
+ }
4131
+ stores = Array.from( storeIds );
4132
+ }
4133
+ let data = {
4134
+ id: getChecklistDetails?._id,
4135
+ email: email,
4136
+ stores,
4137
+ role: userDetails.role,
4138
+ };
4139
+ result.push( data );
4140
+ }
4141
+ } ) );
4142
+
4143
+ spocList.forEach( ( ele ) => {
4144
+ let findIndex = result.findIndex( ( element ) => element.email == ele.email );
4145
+ if ( findIndex != -1 ) {
4146
+ result[findIndex].stores = new Set( ...result[findIndex].stores, ele.store );
4147
+ } else {
4148
+ result.push( {
4149
+ id: getChecklistDetails?._id,
4150
+ email: ele.email,
4151
+ stores: ele.store,
4152
+ role: 'admin',
4153
+ } );
4154
+ }
4155
+ } );
4156
+ }
4157
+
4158
+ return res.sendSuccess( result );
4159
+ } catch ( e ) {
4160
+ logger.error( { functionName: 'sendAIEmailList', error: e } );
4161
+ return res.sendError( e, 500 );
4162
+ }
4163
+ }
@@ -3822,6 +3822,7 @@ export async function taskQuestionList( req, res ) {
3822
3822
  rawImageUpload: { $ifNull: [ '$rawImageUpload', false ] },
3823
3823
  rawVideoUpload: { $ifNull: [ '$rawVideoUpload', false ] },
3824
3824
  videoUploadTimeLimit: { $ifNull: [ '$videoUploadTimeLimit', 0 ] },
3825
+ aiType: 1,
3825
3826
  },
3826
3827
  } );
3827
3828
 
@@ -608,6 +608,9 @@ export const zoneList = async ( req, res ) => {
608
608
  'Mobile usage detection',
609
609
  'Store TV Compliance',
610
610
  'Queue Wait Time Breach',
611
+ 'Uniform detection',
612
+ 'Store Hygiene Monitoring',
613
+ 'Camera Infra Compliance',
611
614
  ];
612
615
  const allowedChecklistsStreams = [
613
616
  'Camera Angle Change Compliance',
@@ -5163,3 +5166,14 @@ export async function downloadQuestionTemplate( req, res ) {
5163
5166
  return res.sendError( e, 500 );
5164
5167
  }
5165
5168
  }
5169
+
5170
+
5171
+ export async function getTeamList( req, res ) {
5172
+ try {
5173
+ let teamsDetails = await teamsServices.findteams( { clientId: req.query.clientId, status: 'active' } );
5174
+ return res.sendSuccess( teamsDetails );
5175
+ } catch ( e ) {
5176
+ logger.error( { functionName: 'getTeamList', error: e } );
5177
+ return res.sendError( e, 500 );
5178
+ }
5179
+ }
@@ -39,6 +39,8 @@ internalTraxRouter
39
39
  .post( '/runAIFlag', isAllowedInternalAPIHandler, internalController.runAIFlag )
40
40
  .post( '/downloadInsertPdf', isAllowedInternalAPIHandler, internalController.downloadInsertPdf )
41
41
  .get( '/checklistAutoMailList', isAllowedInternalAPIHandler, internalController.checklistAutoMailList )
42
+ .post( '/sendAIEmailList', isAllowedInternalAPIHandler, internalController.sendAIEmailList )
43
+ .post( '/liveAiPushNotificationAlert', isAllowedInternalAPIHandler, internalController.liveAiPushNotificationAlert )
42
44
  ;
43
45
 
44
46
 
@@ -36,6 +36,8 @@ traxRouter
36
36
  .post( '/updateRunAIRequest', isAllowedSessionHandler, validate( runAIRequestValidation ), traxController.updateRunAIRequest )
37
37
  .post( '/createChecklistName', isAllowedSessionHandler, validate( createChecklistNameValidation ), traxController.createChecklistName )
38
38
  .post( '/updateOSProcessedData', isAllowedInternalAPIHandler, validate( updateOSDataValidation ), traxController.updateOSProcessedData )
39
- .post( '/exportQuestions', isAllowedSessionHandler, traxController.downloadQuestionTemplate );
39
+ .post( '/exportQuestions', isAllowedSessionHandler, traxController.downloadQuestionTemplate )
40
+ .get( '/getTeamList', isAllowedSessionHandler, traxController.getTeamList )
41
+ ;
40
42
 
41
43
  // isAllowedSessionHandler, isAllowedClient, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ),
@@ -447,7 +447,6 @@ export function buildVisitChecklistTemplateDataFromProcessed( processedDoc, bran
447
447
 
448
448
  let referenceId = doc.coverage == 'store' ? doc?.storeName : doc?.userName;
449
449
 
450
-
451
450
  return {
452
451
 
453
452