tango-app-api-trax 1.0.0-task.120 → 1.0.0-task.121
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/fir-51e77-firebase-adminsdk-x3sdp-fd902b74ae.json +14 -0
- package/package.json +6 -2
- package/src/controllers/internalTrax.controller.js +116 -0
- package/src/controllers/mobileTrax.controller.js +66 -7
- package/src/controllers/teaxFlag.controller.js +99 -27
- package/src/controllers/trax.controller.js +50 -16
- package/src/controllers/traxDashboard.controllers.js +105 -1
- package/src/hbs/login-otp.hbs +943 -943
- package/src/routes/internalTraxApi.router.js +2 -1
- package/src/services/approver.service.js +17 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
{
|
|
3
|
+
"type": "service_account",
|
|
4
|
+
"project_id": "tango-trax",
|
|
5
|
+
"private_key_id": "2bf70eb4a3b9f4e74138bce76063c78c75e166d7",
|
|
6
|
+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXwmrIk6t5vfdE\niIskCwdg9Q1EyugQQeA5ve8z6hKrXng/goz+gpkonPI5pHHNELgIoOaC6+3QvxRA\nKB30ETqMKkZJQORy0zUaDQq+qyqNTj5AgNizAtnxMOAf46PIe5gWvDaXkyiHN/cE\ngfFdRyW7ctm4EDub7Ii69fr96X9mmbhOtuP/4tG+MhGIe5JmHnVvM75kC1aWb+ob\n8EaQfLeWpxYqXtsEZoCHbVTm+pDUWMGqiMko7C84BcxKOT4RFk4MeV99T0UaZtab\ncgQlWFmbcvev4KeNkkkmbVCSbBawAe1EsY8QMSj1telikh0NExNodeatIbuYBtc1\nnFqaxv7zAgMBAAECggEAHBtr/54qAjBG3bCUZKaORUzdmkIiXPB2gPtGlEzkDE1A\n5DJfvruddkIrMrXcRei0zRRP3SupLiJVs9Q6R/vw5gjmX6bfKM0pZpvHw6ycAvPc\n38F9YRpEF0HAIOfea8FIV92gFs6wkOqym2kdtPL6cA9Dd625/JUAdfAc/m4CpJPG\n4mjPoNEwMi2a66RW1CghmkQ8VgnxGk05UawZ4f6r+ABko5Q/hX/B+crApbriGPo6\nMBVtqxKGcrAmdTXWF8Bpua3I8hwGRqenLc6CY1kPHCb3XleOj+BkGGxzUGRKkJcU\nwkIiLub//XlTnM8V4R72VqKOP0Zo9SUrqPtPEg8FcQKBgQDI8SWGg5NMAsGhmopl\naUtkAKrZEK/waNBVxeFfKmXhq+hZYZ0Fj4ewI/jvKRPF0zPNWuwQuYSb3LxqmaFc\ng0iQT/crlF1skU7a0vZm7wumSxuMJq+qVcEmG8e8tD9hUGAZDImWeLqZ5UfSNbcb\nF82IeFoB5LWBAq8W2ecST4QA1wKBgQDBV2puSB1jqa9ZVgUIiEGsWzgQLSJ43AmM\nLRy058kuGr11XxLXZvc0v3rB8MhMoaNurFXcUjX67dAV3F8ejqL65dCQHwBDiS32\nsMiMmHfCGBHUn/MsjsZ3LTljLC08ltAoeEuluaW9v8sT93BbrIhpdEmD+tDegqdU\nv/QMKAnDRQKBgQClTgyK3k8cpt/YLCRSTQ7iU9I5BAtZAUDybvl6qoxp3Fwmu7DL\nVEpR0yYEyYwkoBzrgTLWh2faOPsfzwb57l6RqdcymLlKiTePuSFPiLPSt9MPtvuo\nayecTBpC2R2S1uZXdQLzMJqB5CbzfZEGzswcyrVw/U97tFOJvvTjEVsMvQKBgHdj\nWHhzFZrWTE45HPCQ2yToSy1KAbBqB4dE0CYxvvw2TOmuZL8YeOxclRwvaDBR287a\nokZjiavCsCzfoOkIoUGXKfvk+M+7ZOOhdKXE/KahIFmQz6OjIpCzH23K+MAiTLXA\n2s2iXuNWDLvunrYtSyr7QO47skDEozllMvlSu/yVAoGAWKjKVyJZeX1yh6ndzfRh\nszTRQ31W77guZm3j0CJtA7SO8eRWLdeg4BwlMT1YFer/Z65QvhJUgAdnh0Iu4Yv/\niFJ6ZwkNWnWg0239WhSroeVwIobafB/0maILkax5NcBcBvIZxBbvS4Y7bR3HqA7r\nxKbTG5i67w5TetuhLWQjt10=\n-----END PRIVATE KEY-----\n",
|
|
7
|
+
"client_email": "firebase-adminsdk-k7lom@tango-trax.iam.gserviceaccount.com",
|
|
8
|
+
"client_id": "112026772051782321525",
|
|
9
|
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
10
|
+
"token_uri": "https://oauth2.googleapis.com/token",
|
|
11
|
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
|
12
|
+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-k7lom%40tango-trax.iam.gserviceaccount.com",
|
|
13
|
+
"universe_domain": "googleapis.com"
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-trax",
|
|
3
|
-
"version": "1.0.0-task.
|
|
3
|
+
"version": "1.0.0-task.121",
|
|
4
4
|
"description": "Trax",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,11 @@
|
|
|
26
26
|
"tango-api-schema": "^2.1.87",
|
|
27
27
|
"tango-app-api-middleware": "^3.1.43-alpha.10",
|
|
28
28
|
"winston": "^3.13.1",
|
|
29
|
-
"winston-daily-rotate-file": "^5.0.0"
|
|
29
|
+
"winston-daily-rotate-file": "^5.0.0",
|
|
30
|
+
"url": "^0.11.4",
|
|
31
|
+
"path": "^0.12.7",
|
|
32
|
+
"firebase-admin": "^13.0.0",
|
|
33
|
+
"fs": "^0.0.1-security"
|
|
30
34
|
},
|
|
31
35
|
"devDependencies": {
|
|
32
36
|
"eslint": "^8.57.0",
|
|
@@ -6,12 +6,23 @@ import * as CLassign from '../services/checklistAssign.service.js';
|
|
|
6
6
|
import * as checklistLogs from '../services/checklistlog.service.js';
|
|
7
7
|
import * as lenskartEmployeeMapping from '../services/lenskartEmployeeMapping.service.js';
|
|
8
8
|
import * as storeService from '../services/store.service.js';
|
|
9
|
+
import * as userService from '../services/user.service.js';
|
|
9
10
|
import dayjs from 'dayjs';
|
|
10
11
|
import customParseFormat from 'dayjs/plugin/customParseFormat.js';
|
|
11
12
|
import timeZone from 'dayjs/plugin/timezone.js';
|
|
12
13
|
import utc from 'dayjs/plugin/utc.js';
|
|
13
14
|
import { logger } from 'tango-app-api-middleware';
|
|
14
15
|
import mongoose from 'mongoose';
|
|
16
|
+
import admin from 'firebase-admin';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
19
|
+
const __filename = fileURLToPath( import.meta.url ); // Get the current file path
|
|
20
|
+
const __dirname = path.dirname( __filename );
|
|
21
|
+
const serviceAccountPath = path.join( __dirname, '..', '..', 'fir-51e77-firebase-adminsdk-x3sdp-fd902b74ae.json' );
|
|
22
|
+
admin.initializeApp( {
|
|
23
|
+
credential: admin.credential.cert( serviceAccountPath ),
|
|
24
|
+
} );
|
|
25
|
+
|
|
15
26
|
const ObjectId = mongoose.Types.ObjectId;
|
|
16
27
|
dayjs.extend( customParseFormat );
|
|
17
28
|
dayjs.extend( utc );
|
|
@@ -407,6 +418,8 @@ async function insertData( requestData ) {
|
|
|
407
418
|
element4.publishDate = getCLconfig.publishDate;
|
|
408
419
|
element4.locationCount = getCLconfig.locationCount;
|
|
409
420
|
element4.scheduleRepeatedType = getCLconfig.scheduleRepeatedType;
|
|
421
|
+
element4.approvalEnable = getCLconfig.approver.length ? true : false;
|
|
422
|
+
element4.remainder = getCLconfig?.remainder || [];
|
|
410
423
|
}
|
|
411
424
|
if ( userIdList.length ) {
|
|
412
425
|
allQuestion = allQuestion.filter( ( item ) => typeof item._id == 'undefined' );
|
|
@@ -867,3 +880,106 @@ export async function getUserStoreList( req, res ) {
|
|
|
867
880
|
return res.sendError( error, 500 );
|
|
868
881
|
}
|
|
869
882
|
};
|
|
883
|
+
|
|
884
|
+
export async function pushNotification( req, res ) {
|
|
885
|
+
try {
|
|
886
|
+
let query = [ {
|
|
887
|
+
$match: {
|
|
888
|
+
date_iso: new Date( req.body.date ),
|
|
889
|
+
$expr: { $gt: [ { $size: '$remainder' }, 0 ] },
|
|
890
|
+
checklistStatus: { $ne: 'submit' },
|
|
891
|
+
checkListType: { $in: [ 'custom' ] },
|
|
892
|
+
timeFlag: 0,
|
|
893
|
+
},
|
|
894
|
+
} ];
|
|
895
|
+
|
|
896
|
+
if ( req.body.client_id && req.body.client_id.length ) {
|
|
897
|
+
query.push( {
|
|
898
|
+
$match: {
|
|
899
|
+
client_id: { $in: req.body.client_id },
|
|
900
|
+
},
|
|
901
|
+
} );
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
query.push( {
|
|
905
|
+
$project: {
|
|
906
|
+
scheduleEndTime_iso: 1,
|
|
907
|
+
store_id: 1,
|
|
908
|
+
storeName: 1,
|
|
909
|
+
checkListId: 1,
|
|
910
|
+
checkListName: 1,
|
|
911
|
+
client_id: 1,
|
|
912
|
+
date_iso: 1,
|
|
913
|
+
userId: 1,
|
|
914
|
+
scheduleEndTime: 1,
|
|
915
|
+
remainder: 1,
|
|
916
|
+
},
|
|
917
|
+
} );
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
let checkList = await processedchecklist.aggregate( query );
|
|
921
|
+
|
|
922
|
+
if ( !checkList.length ) {
|
|
923
|
+
return res.sendError( 'no data', 204 );
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
let checklistDetails = [];
|
|
927
|
+
|
|
928
|
+
let promises = checkList.map( async ( item ) => {
|
|
929
|
+
await checkTimeZone( [ item ] );
|
|
930
|
+
} );
|
|
931
|
+
|
|
932
|
+
await Promise.all( promises );
|
|
933
|
+
|
|
934
|
+
async function checkTimeZone( ele ) {
|
|
935
|
+
return Promise.all(
|
|
936
|
+
ele.map( async ( data ) => {
|
|
937
|
+
let getStoreZone = await storeService.findOne(
|
|
938
|
+
{ storeId: data.store_id, clientId: data.client_id },
|
|
939
|
+
{ storeProfile: 1 },
|
|
940
|
+
);
|
|
941
|
+
if ( getStoreZone ) {
|
|
942
|
+
let checklistDate = dayjs( dayjs( data.scheduleEndTime, 'hh:mm A' ) ).tz( getStoreZone.storeProfile.timeZone, true );
|
|
943
|
+
let date = dayjs().tz( getStoreZone.storeProfile.timeZone );
|
|
944
|
+
if ( data?.remainder?.length && data.remainder.includes( checklistDate.diff( date, 'minute' ) ) ) {
|
|
945
|
+
let getToken = await userService.findOne( { _id: data.userId }, { fcmToken: 1 } );
|
|
946
|
+
if ( getToken?.fcmToken ) {
|
|
947
|
+
let existCheck = checklistDetails.findIndex( ( item ) => item.checklistName == data.checkListName );
|
|
948
|
+
if ( existCheck ) {
|
|
949
|
+
checklistDetails[existCheck].token.push( getToken.fcmToken );
|
|
950
|
+
} else {
|
|
951
|
+
checklistDetails.push( { checklistName: data.checkListName, token: [ getToken.fcmToken ] } );
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
} ),
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
if ( !checklistDetails.length ) {
|
|
961
|
+
return res.sendError( 'no data found', 204 );
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
checklistDetails.forEach( async ( item ) => {
|
|
965
|
+
const message = {
|
|
966
|
+
tokens: item.token,
|
|
967
|
+
notification: {
|
|
968
|
+
title: 'Remainder to Fil checklist',
|
|
969
|
+
body: `${item.checklistName} checklist is going to breach within few minutes`,
|
|
970
|
+
},
|
|
971
|
+
data: {
|
|
972
|
+
customKey: 'customValue',
|
|
973
|
+
},
|
|
974
|
+
};
|
|
975
|
+
const response = await admin.messaging().sendEachForMulticast( message );
|
|
976
|
+
if ( response.successCount ) {
|
|
977
|
+
return res.sendSuccess( 'Push notification send successfully' );
|
|
978
|
+
}
|
|
979
|
+
return res.sendError( 'Push notification send Failed', 500 );
|
|
980
|
+
} );
|
|
981
|
+
} catch ( e ) {
|
|
982
|
+
logger.error( { function: 'pushNotification', error: e } );
|
|
983
|
+
return res.sendError( e, 500 );
|
|
984
|
+
}
|
|
985
|
+
}
|
|
@@ -29,7 +29,7 @@ export async function storeList( req, res ) {
|
|
|
29
29
|
if ( !req.query?.date ) {
|
|
30
30
|
return res.sendError( 'date is required', 400 );
|
|
31
31
|
}
|
|
32
|
-
let userChecklist = await processedchecklist.find( { userId: req.user._id, userEmail: req.user.email, date_string: dayjs( req.query.date ).format( 'YYYY-MM-DD' ) }, { store_id: 1, storeName: 1 } );
|
|
32
|
+
let userChecklist = await processedchecklist.find( { userId: req.user._id, userEmail: req.user.email, client_id: req.user.clientId, date_string: dayjs( req.query.date ).format( 'YYYY-MM-DD' ) }, { store_id: 1, storeName: 1 } );
|
|
33
33
|
if ( !userChecklist.length ) {
|
|
34
34
|
return res.sendSuccess( [] );
|
|
35
35
|
}
|
|
@@ -39,7 +39,7 @@ export async function storeList( req, res ) {
|
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
let storeIdList = userChecklist.map( ( item ) => item.store_id );
|
|
42
|
-
let storeStatus = await storeService.find( { storeId: { $in: storeIdList }, status: 'active' }, { storeId: 1, storeName: 1 } );
|
|
42
|
+
let storeStatus = await storeService.find( { storeId: { $in: storeIdList }, status: 'active', clientId: req.user.clientId }, { storeId: 1, storeName: 1 } );
|
|
43
43
|
if ( storeStatus.length ) {
|
|
44
44
|
storeStatus = storeStatus.map( ( item ) => {
|
|
45
45
|
return { store_id: item.storeId, storeName: item.storeName };
|
|
@@ -1271,7 +1271,7 @@ export async function submitTask( req, res ) {
|
|
|
1271
1271
|
};
|
|
1272
1272
|
await checklistLogs.create( logInsertData );
|
|
1273
1273
|
|
|
1274
|
-
|
|
1274
|
+
updateOpenSearchTask( user, requestData );
|
|
1275
1275
|
|
|
1276
1276
|
return res.sendSuccess( 'Task Updated Successfully' );
|
|
1277
1277
|
} else {
|
|
@@ -1329,6 +1329,51 @@ async function updateOpenSearch( user, data ) {
|
|
|
1329
1329
|
}
|
|
1330
1330
|
}
|
|
1331
1331
|
|
|
1332
|
+
async function updateOpenSearchTask( user, data ) {
|
|
1333
|
+
let findQuery = [ {
|
|
1334
|
+
$match: {
|
|
1335
|
+
$and: [
|
|
1336
|
+
{ _id: new ObjectId( data.processedcheckListId ) },
|
|
1337
|
+
{ userId: user._id },
|
|
1338
|
+
{ date_string: data.date },
|
|
1339
|
+
],
|
|
1340
|
+
},
|
|
1341
|
+
} ];
|
|
1342
|
+
|
|
1343
|
+
let getchecklist = await processedTask.aggregate( findQuery );
|
|
1344
|
+
if ( getchecklist.length ) {
|
|
1345
|
+
let logInsertData = {
|
|
1346
|
+
store_id: getchecklist[0].store_id,
|
|
1347
|
+
storeName: getchecklist[0].storeName,
|
|
1348
|
+
action: 'OpenSearch insert Triggered',
|
|
1349
|
+
checklistId: getchecklist[0].checkListId,
|
|
1350
|
+
checkListName: getchecklist[0].checkListName,
|
|
1351
|
+
client_id: user.clientId,
|
|
1352
|
+
};
|
|
1353
|
+
await checklistLogs.create( logInsertData );
|
|
1354
|
+
const requestOptions = {
|
|
1355
|
+
method: 'POST',
|
|
1356
|
+
headers: {
|
|
1357
|
+
'Content-Type': 'application/json',
|
|
1358
|
+
},
|
|
1359
|
+
body: JSON.stringify( { doc: { ...getchecklist[0] } } ),
|
|
1360
|
+
};
|
|
1361
|
+
let url = JSON.parse( process.env.LAMBDAURL );
|
|
1362
|
+
let searchResponse = await fetch( url.submitTask, requestOptions );
|
|
1363
|
+
if ( searchResponse.ok ) {
|
|
1364
|
+
let logInsertData = {
|
|
1365
|
+
store_id: getchecklist[0].store_id,
|
|
1366
|
+
storeName: getchecklist[0].storeName,
|
|
1367
|
+
action: 'OpenSearch inserted Successfully',
|
|
1368
|
+
checklistId: getchecklist[0].checkListId,
|
|
1369
|
+
checkListName: getchecklist[0].checkListName,
|
|
1370
|
+
client_id: user.clientId,
|
|
1371
|
+
};
|
|
1372
|
+
await checklistLogs.create( logInsertData );
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1332
1377
|
export async function dashboard( req, res ) {
|
|
1333
1378
|
try {
|
|
1334
1379
|
let requestData = req.query;
|
|
@@ -1930,7 +1975,7 @@ export async function taskQuestionList( req, res ) {
|
|
|
1930
1975
|
}
|
|
1931
1976
|
}
|
|
1932
1977
|
|
|
1933
|
-
return res.sendSuccess( checklist );
|
|
1978
|
+
return res.sendSuccess( [ checklist ] );
|
|
1934
1979
|
} catch ( error ) {
|
|
1935
1980
|
logger.error( { function: 'taskQuestionList', error } );
|
|
1936
1981
|
return res.sendError( error.message || 'Internal Server Error', 500 );
|
|
@@ -1955,10 +2000,17 @@ export async function uploadAnswerImage( req, res ) {
|
|
|
1955
2000
|
}
|
|
1956
2001
|
|
|
1957
2002
|
let date = dayjs().format( 'YYYY-MM-DD' );
|
|
2003
|
+
let folder;
|
|
2004
|
+
|
|
2005
|
+
if ( input.type == 'custom' ) {
|
|
2006
|
+
folder = 'checklist-answers';
|
|
2007
|
+
} else {
|
|
2008
|
+
folder = 'task-answers';
|
|
2009
|
+
}
|
|
1958
2010
|
|
|
1959
2011
|
if ( req.files && req.files.answerImage ) {
|
|
1960
2012
|
let imageUrl;
|
|
1961
|
-
let filePath =
|
|
2013
|
+
let filePath = `${folder}/${req.user.clientId}/${date}/${input.checklistId}/${input.sectionName.replace( ' ', '' )}/${input.questionNo}/`;
|
|
1962
2014
|
let params = {
|
|
1963
2015
|
fileName: `${Date.now()}-${Math.floor( 1000 + Math.random() * 9000 )}.${req.files.answerImage.name.split( '.' )[1]}`,
|
|
1964
2016
|
Key: filePath,
|
|
@@ -2095,8 +2147,15 @@ export async function login( req, res ) {
|
|
|
2095
2147
|
refreshToken: token?.refreshToken,
|
|
2096
2148
|
type: 'retail',
|
|
2097
2149
|
};
|
|
2150
|
+
|
|
2151
|
+
let userDetails = await userService.findOne( { fcmToken: inputData.fcmToken } );
|
|
2152
|
+
|
|
2153
|
+
if ( userDetails ) {
|
|
2154
|
+
await userService.updateOne( { _id: userDetails?._id }, { fcmToken: '' } );
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2098
2157
|
const auth = await create( record );
|
|
2099
|
-
await userService.updateOne( { _id: result?._id }, { refreshToken: token?.refreshToken } );
|
|
2158
|
+
await userService.updateOne( { _id: result?._id }, { refreshToken: token?.refreshToken, fcmToken: inputData.fcmToken } );
|
|
2100
2159
|
|
|
2101
2160
|
if ( auth ) {
|
|
2102
2161
|
return res.sendSuccess( { result: token } );
|
|
@@ -2201,7 +2260,7 @@ export async function getStoreLocation( req, res, next ) {
|
|
|
2201
2260
|
return res.sendError( 'No store/Checklist assigned to the user!', 400 );
|
|
2202
2261
|
}
|
|
2203
2262
|
} catch ( error ) {
|
|
2204
|
-
|
|
2263
|
+
logger.error( { function: 'SOP Mobile store check middleware error', error: error } );
|
|
2205
2264
|
let msg = error.error ? error.error : error;
|
|
2206
2265
|
return res.sendError( msg, 500 );
|
|
2207
2266
|
}
|
|
@@ -3,7 +3,6 @@ import { aggregate } from '../services/processedchecklist.services.js';
|
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import * as processedchecklistService from '../services/processedchecklist.services.js';
|
|
5
5
|
import * as processedchecklistconfigService from '../services/processedchecklistconfig.services.js';
|
|
6
|
-
import * as checklistconfigService from '../services/checklist.service.js';
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
import utc from 'dayjs/plugin/utc.js';
|
|
@@ -783,7 +782,9 @@ export const flagTablesV1 = async ( req, res ) => {
|
|
|
783
782
|
{ date_iso: { $lte: toDate } },
|
|
784
783
|
);
|
|
785
784
|
|
|
786
|
-
if ( requestData?.filter === '
|
|
785
|
+
if ( requestData?.filter === 'all' ) {
|
|
786
|
+
findAndQuery.push( { $or: [ { questionFlag: { $gte: 1 } }, { timeFlag: { $gte: 1 } }, { checkListType: { $ne: 'custom' } } ] } );
|
|
787
|
+
} else if ( requestData?.filter === 'question' ) {
|
|
787
788
|
findAndQuery.push( { checkListType: 'custom' } );
|
|
788
789
|
findAndQuery.push( { questionFlag: { $gte: 1 } } );
|
|
789
790
|
} else if ( requestData?.filter === 'time' ) {
|
|
@@ -2585,34 +2586,105 @@ export const checklistDropdownSourceChecklist = async ( req, res ) => {
|
|
|
2585
2586
|
export const checklistDropdownV1 = async ( req, res ) => {
|
|
2586
2587
|
try {
|
|
2587
2588
|
let requestData = req.body;
|
|
2589
|
+
let fromDate = new Date( requestData.fromDate );
|
|
2590
|
+
let toDate = new Date( requestData.toDate );
|
|
2591
|
+
let userTimezoneOffset = toDate.getTimezoneOffset() * 60000;
|
|
2592
|
+
toDate = new Date( toDate.getTime() - userTimezoneOffset );
|
|
2593
|
+
toDate.setUTCHours( 23, 59, 59, 59 );
|
|
2588
2594
|
let result = {};
|
|
2589
|
-
|
|
2590
|
-
let
|
|
2591
|
-
|
|
2595
|
+
|
|
2596
|
+
let findQuery = [
|
|
2597
|
+
{ $match: { $and: [
|
|
2592
2598
|
{ client_id: requestData.clientId },
|
|
2593
|
-
{
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2599
|
+
{
|
|
2600
|
+
$or: [
|
|
2601
|
+
{ store_id: { $in: requestData.storeId } },
|
|
2602
|
+
{ aiStoreList: { $in: requestData.storeId } },
|
|
2603
|
+
],
|
|
2604
|
+
},
|
|
2605
|
+
{ date_iso: { $gte: fromDate } },
|
|
2606
|
+
{ date_iso: { $lte: toDate } },
|
|
2607
|
+
{
|
|
2608
|
+
$or: [
|
|
2609
|
+
{ questionFlag: { $gte: 1 } },
|
|
2610
|
+
{ timeFlag: { $gte: 1 } },
|
|
2611
|
+
{ checkListType: { $ne: 'custom' } },
|
|
2612
|
+
],
|
|
2613
|
+
},
|
|
2614
|
+
] } },
|
|
2615
|
+
{
|
|
2616
|
+
$project: {
|
|
2617
|
+
sourceCheckList_id: 1,
|
|
2618
|
+
checkListName: 1,
|
|
2619
|
+
},
|
|
2608
2620
|
},
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2621
|
+
{
|
|
2622
|
+
$group: {
|
|
2623
|
+
_id: '$sourceCheckList_id',
|
|
2624
|
+
checkListName: { $last: '$checkListName' },
|
|
2625
|
+
},
|
|
2626
|
+
},
|
|
2627
|
+
{
|
|
2628
|
+
$project: {
|
|
2629
|
+
_id: 0,
|
|
2630
|
+
sourceCheckList_id: '$_id',
|
|
2631
|
+
checkListName: 1,
|
|
2632
|
+
},
|
|
2633
|
+
},
|
|
2634
|
+
{
|
|
2635
|
+
$lookup: {
|
|
2636
|
+
from: 'checklistconfigs',
|
|
2637
|
+
let: { sourceId: '$sourceCheckList_id' },
|
|
2638
|
+
pipeline: [
|
|
2639
|
+
{
|
|
2640
|
+
$match: {
|
|
2641
|
+
$expr: {
|
|
2642
|
+
$and: [
|
|
2643
|
+
{ $eq: [ '$_id', '$$sourceId' ] },
|
|
2644
|
+
],
|
|
2645
|
+
},
|
|
2646
|
+
},
|
|
2647
|
+
},
|
|
2648
|
+
{
|
|
2649
|
+
$project: {
|
|
2650
|
+
_id: 1,
|
|
2651
|
+
checkListName: 1,
|
|
2652
|
+
checkListNameLowercase: { $toLower: '$checkListName' },
|
|
2653
|
+
checkListType: 1,
|
|
2654
|
+
createdByName: 1,
|
|
2655
|
+
publish: 1,
|
|
2656
|
+
scheduleEndTime: 1,
|
|
2657
|
+
scheduleRepeatedType: 1,
|
|
2658
|
+
scheduleStartTime: 1,
|
|
2659
|
+
sourceCheckList_id: '$_id',
|
|
2660
|
+
storeCount: 1,
|
|
2661
|
+
},
|
|
2662
|
+
},
|
|
2663
|
+
], as: 'checklistData',
|
|
2664
|
+
},
|
|
2665
|
+
},
|
|
2666
|
+
{ $unwind: { path: '$checklistData', preserveNullAndEmptyArrays: true } },
|
|
2667
|
+
{
|
|
2668
|
+
$project: {
|
|
2669
|
+
_id: '$checklistData._id',
|
|
2670
|
+
checkListName: '$checklistData.checkListName',
|
|
2671
|
+
checkListNameLowercase: { $toLower: '$checkListName' },
|
|
2672
|
+
checkListType: '$checklistData.checkListType',
|
|
2673
|
+
createdByName: '$checklistData.createdByName',
|
|
2674
|
+
publish: '$checklistData.publish',
|
|
2675
|
+
scheduleEndTime: '$checklistData.scheduleEndTime',
|
|
2676
|
+
scheduleRepeatedType: '$checklistData.scheduleRepeatedType',
|
|
2677
|
+
scheduleStartTime: '$checklistData.scheduleStartTime',
|
|
2678
|
+
sourceCheckList_id: '$checklistData._id',
|
|
2679
|
+
storeCount: '$checklistData.storeCount',
|
|
2680
|
+
},
|
|
2681
|
+
},
|
|
2682
|
+
];
|
|
2683
|
+
|
|
2684
|
+
findQuery.push( { $sort: { checkListName: 1 } } );
|
|
2685
|
+
|
|
2686
|
+
let getChecklistData = await processedchecklistService.aggregate( findQuery );
|
|
2687
|
+
|
|
2616
2688
|
if ( !getChecklistData.length ) {
|
|
2617
2689
|
return res.sendError( { error: 'No Data Found' }, 204 );
|
|
2618
2690
|
}
|
|
@@ -5,7 +5,7 @@ import * as assignedService from '../services/checklistAssign.service.js';
|
|
|
5
5
|
import * as clientService from '../services/clients.services.js';
|
|
6
6
|
import * as reisedTicketService from '../services/ticket.service.js';
|
|
7
7
|
import * as userService from '../services/user.service.js';
|
|
8
|
-
import * as domainService from '../services/domain.service.js';
|
|
8
|
+
// import * as domainService from '../services/domain.service.js';
|
|
9
9
|
import * as storeService from '../services/store.service.js';
|
|
10
10
|
import mongoose from 'mongoose';
|
|
11
11
|
import * as processedchecklistConfig from '../services/processedchecklistconfig.services.js';
|
|
@@ -13,6 +13,7 @@ import * as processedchecklist from '../services/processedchecklist.services.js'
|
|
|
13
13
|
import * as checklistLogs from '../services/checklistlog.service.js';
|
|
14
14
|
import * as tagService from '../services/tagging.service.js';
|
|
15
15
|
import * as alertsServices from '../services/clientRequest.service.js';
|
|
16
|
+
import * as traxApprover from '../services/approver.service.js';
|
|
16
17
|
const ObjectId = mongoose.Types.ObjectId;
|
|
17
18
|
import dayjs from 'dayjs';
|
|
18
19
|
import customParseFormat from 'dayjs/plugin/customParseFormat.js';
|
|
@@ -779,18 +780,25 @@ export const assignedUserDetails = async ( req, res ) => {
|
|
|
779
780
|
}
|
|
780
781
|
}
|
|
781
782
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
783
|
+
query.push( {
|
|
784
|
+
$facet: {
|
|
785
|
+
data: [
|
|
786
|
+
{ $skip: skip }, { $limit: limit },
|
|
787
|
+
],
|
|
788
|
+
count: [
|
|
789
|
+
{ $count: 'total' },
|
|
790
|
+
],
|
|
791
|
+
},
|
|
792
|
+
} );
|
|
785
793
|
|
|
786
794
|
let checklistDetails = await assignedService.aggregate( query );
|
|
787
795
|
|
|
788
|
-
if ( !checklistDetails.length ) {
|
|
796
|
+
if ( !checklistDetails[0].data.length ) {
|
|
789
797
|
return res.sendError( 'no data found', 204 );
|
|
790
798
|
}
|
|
791
799
|
|
|
792
800
|
let userDetails = [];
|
|
793
|
-
checklistDetails.forEach( ( item ) => {
|
|
801
|
+
checklistDetails[0].data.forEach( ( item ) => {
|
|
794
802
|
userDetails.push( {
|
|
795
803
|
id: item._id,
|
|
796
804
|
userName: item.userName,
|
|
@@ -802,7 +810,7 @@ export const assignedUserDetails = async ( req, res ) => {
|
|
|
802
810
|
checkFlag: item.checkFlag,
|
|
803
811
|
} );
|
|
804
812
|
} );
|
|
805
|
-
return res.sendSuccess( { users: userDetails, count:
|
|
813
|
+
return res.sendSuccess( { users: userDetails, count: checklistDetails[0].count[0].total } );
|
|
806
814
|
} catch ( e ) {
|
|
807
815
|
logger.error( 'assignedUserDetails =>', e );
|
|
808
816
|
return res.sendError( e, 500 );
|
|
@@ -892,7 +900,7 @@ export const updateConfigure =async ( req, res ) => {
|
|
|
892
900
|
let logInsertData = {
|
|
893
901
|
action: inputBody.submitType == 'publish' ? 'checklistPublishUsingConfigPage' : 'checklistConfigDraft',
|
|
894
902
|
checklistId: inputBody.checkListDetails._id,
|
|
895
|
-
checkListName: inputBody?.checkListDetails.
|
|
903
|
+
checkListName: inputBody?.checkListDetails.checkListName,
|
|
896
904
|
createdBy: req.user._id,
|
|
897
905
|
createdByName: req.user.userName,
|
|
898
906
|
client_id: req.body.clientId,
|
|
@@ -939,8 +947,32 @@ export const updateConfigure =async ( req, res ) => {
|
|
|
939
947
|
configEndDate: inputBody?.checkListDetails?.configEndDate || '',
|
|
940
948
|
specificDate: inputBody?.checkListDetails?.specificDate || [],
|
|
941
949
|
allowOnce: inputBody?.checkListDetails?.allowOnce || false,
|
|
950
|
+
approver: inputBody?.checkListDetails?.approver || [],
|
|
951
|
+
remainder: inputBody?.checkListDetails?.remainder || [],
|
|
942
952
|
};
|
|
943
953
|
|
|
954
|
+
if ( inputBody?.checkListDetails?.approver.length ) {
|
|
955
|
+
let data = [];
|
|
956
|
+
let existEmail = await traxApprover.find( { checkListId: inputBody.checkListDetails._id, isDeleted: false } );
|
|
957
|
+
let mailList = existEmail.map( ( item ) => item.userEmail );
|
|
958
|
+
existEmail = inputBody?.checkListDetails?.approver.filter( ( item ) => mailList.includes( item.value ) ).map( ( item ) => item.value );
|
|
959
|
+
let userMailList = inputBody?.checkListDetails?.approver.map( ( ele ) => ele.value );
|
|
960
|
+
inputBody?.checkListDetails?.approver.forEach( ( ele ) => {
|
|
961
|
+
if ( !existEmail.includes( ele.value ) ) {
|
|
962
|
+
data.push( {
|
|
963
|
+
userEmail: ele.value,
|
|
964
|
+
checkListId: inputBody.checkListDetails._id,
|
|
965
|
+
type: 'checklist',
|
|
966
|
+
} );
|
|
967
|
+
}
|
|
968
|
+
} );
|
|
969
|
+
|
|
970
|
+
await traxApprover.updateMany( { checkListId: inputBody.checkListDetails._id, userEmail: { $nin: userMailList } }, { isDeleted: true } );
|
|
971
|
+
if ( data.length ) {
|
|
972
|
+
await traxApprover.insertMany( data );
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
944
976
|
|
|
945
977
|
if ( checklistDetails.checkListType != 'custom' && !checklistDetails.client_id ) {
|
|
946
978
|
let getchecklistNumber = await checklistService.findOne( { client_id: req.body.clientId, type: 'checklist' }, { checkListNumber: 1 } );
|
|
@@ -1282,7 +1314,7 @@ export const validateUser = async ( req, res ) => {
|
|
|
1282
1314
|
|
|
1283
1315
|
if ( !req.body?.addUser ) {
|
|
1284
1316
|
if ( req.body.hasOwnProperty( 'delete' ) ) {
|
|
1285
|
-
let checkExists = await assignedService.findOne( { userEmail: req.body.assignedUsers[0].userEmail, storeName: req.body.assignedUsers[0].storeName } );
|
|
1317
|
+
let checkExists = await assignedService.findOne( { userEmail: req.body.assignedUsers[0].userEmail, storeName: req.body.assignedUsers[0].storeName, checkListId: req.body.id } );
|
|
1286
1318
|
if ( checkExists ) {
|
|
1287
1319
|
return res.sendError( 'User already Exists', 400 );
|
|
1288
1320
|
}
|
|
@@ -1349,11 +1381,11 @@ export const validateUser = async ( req, res ) => {
|
|
|
1349
1381
|
];
|
|
1350
1382
|
let userDetails = await userService.aggregate( query );
|
|
1351
1383
|
if ( !userDetails.length ) {
|
|
1352
|
-
let checkDomain = item.userEmail.split( '@' )[1].toLowerCase();
|
|
1353
|
-
let brandDomainExists = await domainService.
|
|
1354
|
-
if ( !brandDomainExists ) {
|
|
1355
|
-
|
|
1356
|
-
}
|
|
1384
|
+
// let checkDomain = item.userEmail.split( '@' )[1].toLowerCase();
|
|
1385
|
+
// let brandDomainExists = await domainService.findOne( { domain: { $regex: checkDomain } } );
|
|
1386
|
+
// if ( !brandDomainExists ) {
|
|
1387
|
+
// domainExists.push( { message: 'Domain is not exists', email: item.userEmail } );
|
|
1388
|
+
// }
|
|
1357
1389
|
let filteredEmail = userEmail.find( ( ele ) => ele.userEmail.toLowerCase() == item.userEmail.toLowerCase() );
|
|
1358
1390
|
if ( !filteredEmail ) {
|
|
1359
1391
|
userEmail.push( { userName: item.userName, userEmail: item.userEmail } );
|
|
@@ -1390,7 +1422,7 @@ export const validateUser = async ( req, res ) => {
|
|
|
1390
1422
|
}
|
|
1391
1423
|
} else {
|
|
1392
1424
|
if ( req.body.hasOwnProperty( 'delete' ) ) {
|
|
1393
|
-
let checkExists = await assignedService.findOne( { userEmail: req.body.assignedUsers[0].userEmail, storeName: req.body.assignedUsers[0].storeName } );
|
|
1425
|
+
let checkExists = await assignedService.findOne( { userEmail: req.body.assignedUsers[0].userEmail, storeName: req.body.assignedUsers[0].storeName, checkListId: req.body.id } );
|
|
1394
1426
|
if ( checkExists ) {
|
|
1395
1427
|
return res.sendError( 'User already Exists', 400 );
|
|
1396
1428
|
}
|
|
@@ -1956,6 +1988,8 @@ async function insertPCBulkV3( getCLconfig, checklistId, currentdate, updatedche
|
|
|
1956
1988
|
element4.publishDate = getCLconfig.publishDate;
|
|
1957
1989
|
element4.locationCount = getCLconfig.locationCount;
|
|
1958
1990
|
element4.scheduleRepeatedType = getCLconfig.scheduleRepeatedType;
|
|
1991
|
+
element4.approvalEnable = getCLconfig.approver.length ? true : false;
|
|
1992
|
+
element4.remainder = getCLconfig?.remainder || [];
|
|
1959
1993
|
}
|
|
1960
1994
|
if ( userIdList.length ) {
|
|
1961
1995
|
allQuestion = allQuestion.filter( ( item ) => typeof item._id == 'undefined' );
|
|
@@ -2011,7 +2045,7 @@ export const aiChecklist = async ( req, res ) => {
|
|
|
2011
2045
|
|
|
2012
2046
|
export const preDefinedChecklist = async ( req, res ) => {
|
|
2013
2047
|
try {
|
|
2014
|
-
let data = [ 'opertaionchecklist', 'storehygiene', 'dailystorechecklist', 'lossprevention' ];
|
|
2048
|
+
let data = [ 'opertaionchecklist', 'storehygiene', 'dailystorechecklist', 'lossprevention', 'Infrastructure', 'dailystoreweekday' ];
|
|
2015
2049
|
let details = [];
|
|
2016
2050
|
let predefinedWithoutClient = [];
|
|
2017
2051
|
let predefinedDetails = [];
|