tango-app-api-trax 3.7.99 → 3.8.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 +2 -2
- package/src/controllers/internalTrax.controller.js +195 -4
- package/src/controllers/mobileTrax.controller.js +1 -0
- package/src/controllers/trax.controller.js +14 -0
- package/src/routes/internalTraxApi.router.js +3 -0
- package/src/routes/trax.routes.js +3 -1
- package/src/utils/visitChecklistPdf.utils.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-trax",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.1",
|
|
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.
|
|
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
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
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,157 @@ 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
|
+
}
|
|
4164
|
+
|
|
4165
|
+
export async function aiChecklistDetails( req, res ) {
|
|
4166
|
+
try {
|
|
4167
|
+
let query = [
|
|
4168
|
+
{
|
|
4169
|
+
$match: {
|
|
4170
|
+
publish: true,
|
|
4171
|
+
checkListType: { $ne: 'custom' },
|
|
4172
|
+
},
|
|
4173
|
+
},
|
|
4174
|
+
{
|
|
4175
|
+
$group: {
|
|
4176
|
+
_id: '$client_id',
|
|
4177
|
+
checklistName: { $addToSet: '$checkListName' },
|
|
4178
|
+
},
|
|
4179
|
+
},
|
|
4180
|
+
{
|
|
4181
|
+
$project: {
|
|
4182
|
+
clientId: '$_id',
|
|
4183
|
+
checklistName: 1,
|
|
4184
|
+
_id: 0,
|
|
4185
|
+
},
|
|
4186
|
+
},
|
|
4187
|
+
];
|
|
4188
|
+
|
|
4189
|
+
let checklistDetails = await CLconfig.aggregate( query );
|
|
4190
|
+
return res.sendSuccess( checklistDetails );
|
|
4191
|
+
} catch ( e ) {
|
|
4192
|
+
logger.error( { functionName: 'aiChecklistDetails', error: e } );
|
|
4193
|
+
return res.sendError( e, 500 );
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
@@ -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,9 @@ 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 )
|
|
44
|
+
.post( '/aiChecklistDetails', isAllowedInternalAPIHandler, internalController.aiChecklistDetails )
|
|
42
45
|
;
|
|
43
46
|
|
|
44
47
|
|
|
@@ -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: [ ] } ] } ),
|