tango-app-api-trax 1.0.0-alpha.76 → 1.0.0-alpha.78

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": "1.0.0-alpha.76",
3
+ "version": "1.0.0-alpha.78",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -11,8 +11,8 @@ import utc from 'dayjs/plugin/utc.js';
11
11
  import { logger } from 'tango-app-api-middleware';
12
12
  import mongoose from 'mongoose';
13
13
  const ObjectId = mongoose.Types.ObjectId;
14
- dayjs.extend( utc );
15
14
  dayjs.extend( customParseFormat );
15
+ dayjs.extend( utc );
16
16
 
17
17
  export async function PCLchecklistCreationValidator( req, res, next ) {
18
18
  try {
@@ -111,6 +111,7 @@ async function insertData( requestData ) {
111
111
  type: 'checklist',
112
112
  isdeleted: false,
113
113
  publish: true,
114
+ checkListType: 'custom',
114
115
  // $and:[{createdAt: { $gte: start }}, {createdAt:{ $lte: end }}]
115
116
  },
116
117
  } );
@@ -253,8 +254,8 @@ async function insertData( requestData ) {
253
254
  let getCLconfig = await CLconfig.findOne( { _id: element2 } );
254
255
  if ( getCLconfig ) {
255
256
  let startTimeIso; let endTimeIso;
256
- startTimeIso = dayjs.utc( `${date} ${getCLconfig.scheduleStartTime}`, 'YYYY-MM-DD hh:mm A' );
257
- endTimeIso = dayjs.utc( `${date} ${getCLconfig.scheduleEndTime}`, 'YYYY-MM-DD hh:mm A' );
257
+ startTimeIso = dayjs.utc( `${currentdate} ${getCLconfig.scheduleStartTime}`, 'YYYY-MM-DD hh:mm A' );
258
+ endTimeIso = dayjs.utc( `${currentdate} ${getCLconfig.scheduleEndTime}`, 'YYYY-MM-DD hh:mm A' );
258
259
  let insertdata = {};
259
260
  insertdata.date_iso = new Date( currentdate );
260
261
  insertdata.date_string = currentdate;
@@ -395,15 +396,6 @@ async function insertData( requestData ) {
395
396
  $lte: new Date( dayjs( getCLconfig.configEndDate ).format( 'YYYY-MM-DD' ) ) },
396
397
  } ],
397
398
  };
398
- // if(getCLconfig.configStartDate != '' && getCLconfig.configStartDate != null) {
399
- // query.$and = [
400
- // {
401
- // date_iso:{
402
- // $gte:new Date(dayjs(getCLconfig.configStartDate).format('YYYY-MM-DD')),
403
- // ...(getCLconfig.configEndDate != '' && getCLconfig.configEndDate != null) ? {$lte:new Date(dayjs(getCLconfig.configEndDate).format('YYYY-MM-DD'))} : {}}
404
- // }
405
- // ]
406
- // }
407
399
  }
408
400
  let getsubmitDetails = await processedchecklist.find( query );
409
401
  if ( getsubmitDetails.length ) {
@@ -499,7 +491,7 @@ export async function insertTimeDelayFlags( req, res ) {
499
491
  } ];
500
492
  let currentTime = dayjs().format( 'HH:mm:ss' );
501
493
  console.log( currentTime );
502
- console.log( dayjs.utc().format( 'HH:mm:ss' ) );
494
+ console.log( dayjs.utc( new Date() ).format( 'HH:mm:ss' ) );
503
495
 
504
496
  if ( req.body.time ) {
505
497
  query.push( {
@@ -13,6 +13,7 @@ const ObjectId = mongoose.Types.ObjectId;
13
13
  import customParseFormat from 'dayjs/plugin/customParseFormat.js';
14
14
  import timeZone from 'dayjs/plugin/timezone.js';
15
15
  import { findOTP, updateOneOTP } from '../services/otp.service.js';
16
+ import * as clientService from '../services/clients.services.js';
16
17
  import { create } from '../services/authentication.service.js';
17
18
  import { readFileSync } from 'fs';
18
19
  import { join } from 'path';
@@ -1264,3 +1265,84 @@ export const sendSignInOtpEmail = async ( emailVars ) => {
1264
1265
  return error;
1265
1266
  }
1266
1267
  };
1268
+
1269
+
1270
+ export async function location( req, res ) {
1271
+ try {
1272
+ let input = req.body;
1273
+ if ( input.latitude && input.longitude ) {
1274
+ let storeLatitude = req.sop_assigned_store.latitude;
1275
+ let storeLongitude = req.sop_assigned_store.longitude;
1276
+
1277
+ function degreesToRadians( degrees ) {
1278
+ let radians = ( degrees * Math.PI ) / 180;
1279
+ return radians;
1280
+ }
1281
+
1282
+ function calcDistance( startingCoords, destinationCoords ) {
1283
+ let startingLat = degreesToRadians( startingCoords.latitude );
1284
+ let startingLong = degreesToRadians( startingCoords.longitude );
1285
+ let destinationLat = degreesToRadians( destinationCoords.latitude );
1286
+ let destinationLong = degreesToRadians( destinationCoords.longitude );
1287
+
1288
+ // Radius of the Earth in kilometers
1289
+ let radius = 6571;
1290
+
1291
+ // Haversine equation
1292
+ let distanceInKilometers =
1293
+ Math.acos( Math.sin( startingLat ) * Math.sin( destinationLat ) +
1294
+ Math.cos( startingLat ) * Math.cos( destinationLat ) *
1295
+ Math.cos( startingLong - destinationLong ) ) * radius;
1296
+ return distanceInKilometers*1000; // to metres
1297
+ }
1298
+
1299
+ let sCoords = {
1300
+ latitude: storeLatitude,
1301
+ longitude: storeLongitude,
1302
+ };
1303
+
1304
+ let dCoords = {
1305
+ latitude: input.latitude,
1306
+ longitude: input.longitude,
1307
+ };
1308
+
1309
+ let distance = calcDistance( sCoords, dCoords );
1310
+
1311
+ let brand = await clientService.findOne( { clientId: req.user.clientId } );
1312
+
1313
+ let radiusConfigured = brand ? ( brand.storeRadiusConfig ? brand.storeRadiusConfig : 500 ) : 500;
1314
+
1315
+ if ( distance<=radiusConfigured ) {
1316
+ return res.sendSuccess( { locationRadiusCheck: true, distance: distance, unit: 'metre' } );
1317
+ } else {
1318
+ return res.sendSuccess( { locationRadiusCheck: false, distance: distance, unit: 'metre' } );
1319
+ }
1320
+ } else {
1321
+ return res.sendError( 'Please include latitude and longitude!', 400 );
1322
+ }
1323
+ } catch ( e ) {
1324
+ logger.error( { error: error, function: 'location' } );
1325
+ return sendError( error, 500 );
1326
+ }
1327
+ }
1328
+
1329
+ export async function getStoreLocation( req, res, next ) {
1330
+ try {
1331
+ let input = req.body;
1332
+ if ( input.store_id ) {
1333
+ let storeDetails = await storeService.findOne( { storeId: input.store_id }, { storeProfile: 1 } );
1334
+ if ( storeDetails ) {
1335
+ req.sop_assigned_store = storeDetails.storeProfile;
1336
+ next();
1337
+ } else {
1338
+ return res.sendError( 'Invalid store_id provided!', 400 );
1339
+ }
1340
+ } else {
1341
+ return res.sendError( 'No store/Checklist assigned to the user!', 400 );
1342
+ }
1343
+ } catch ( error ) {
1344
+ console.log( 'SOP Mobile store check middleware error=>', error );
1345
+ let msg = error.error ? error.error : error;
1346
+ return res.sendError( msg, 500 );
1347
+ }
1348
+ };
@@ -585,7 +585,21 @@ export const flagCardsV1 = async ( req, res ) => {
585
585
  const getOverallChecklistData = await processedchecklistService.aggregate( findQuery );
586
586
 
587
587
  if ( !getOverallChecklistData.length ) {
588
- return res.sendError( { error: 'No Data Found' }, 204 );
588
+ const resVal = {
589
+ 'flagCards': {
590
+ 'totalFlag': 0,
591
+ 'questionFlag': {
592
+ 'count': 0,
593
+ },
594
+ 'delayInSubmission': {
595
+ 'count': 0,
596
+ },
597
+ 'detectionFlag': {
598
+ 'count': 0,
599
+ },
600
+ },
601
+ };
602
+ return res.sendSuccess( resVal );
589
603
  }
590
604
 
591
605
  const [ data ] = getOverallChecklistData;
@@ -2060,8 +2074,6 @@ export const flagChecklistComparisonCardsV1 = async ( req, res ) => {
2060
2074
  },
2061
2075
  ];
2062
2076
 
2063
- const rangeOneData = await processedchecklistService.aggregate( range1pipeline );
2064
-
2065
2077
  const range2pipeline = [
2066
2078
  {
2067
2079
  $match: {
@@ -2142,7 +2154,8 @@ export const flagChecklistComparisonCardsV1 = async ( req, res ) => {
2142
2154
  },
2143
2155
  ];
2144
2156
 
2145
- const rangeTwoData = await processedchecklistService.aggregate( range2pipeline );
2157
+ const [ rangeOneData, rangeTwoData ] = await Promise.all( [ processedchecklistService.aggregate( range1pipeline ), processedchecklistService.aggregate( range2pipeline ) ] );
2158
+
2146
2159
 
2147
2160
  if ( rangeOneData.length >0 && rangeTwoData.length >0 ) {
2148
2161
  flagComparisonCards.totalAssignedStores.comparisonData = ( ( ( rangeOneData[0].totalAssignedStores - rangeTwoData[0].totalAssignedStores )/rangeOneData[0].totalAssignedStores )*100 ).toFixed( 2 );
@@ -2151,7 +2164,7 @@ export const flagChecklistComparisonCardsV1 = async ( req, res ) => {
2151
2164
  } else {
2152
2165
  flagComparisonCards.totalAssignedStores.ComparisonFlag = false;
2153
2166
  }
2154
- flagComparisonCards.flagIncidents.comparisonData = ( ( ( rangeOneData[0].totalAssignedStores - rangeTwoData[0].totalAssignedStores )/rangeOneData[0].totalAssignedStores )*100 ).toFixed( 2 );
2167
+ flagComparisonCards.flagIncidents.comparisonData = ( ( ( rangeOneData[0].flagIncidents - rangeTwoData[0].flagIncidents )/rangeOneData[0].flagIncidents )*100 ).toFixed( 2 );
2155
2168
  if ( flagComparisonCards.flagIncidents.comparisonData > 0 ) {
2156
2169
  flagComparisonCards.flagIncidents.ComparisonFlag = true;
2157
2170
  } else {
@@ -2265,24 +2278,31 @@ export const flagChecklistTableV1 = async ( req, res ) => {
2265
2278
  try {
2266
2279
  let reqestData = req.body;
2267
2280
  if ( reqestData.ChecklistType == 'custom' ) {
2268
- const pipeline = [
2269
- {
2270
- $match: {
2271
- $and: [
2272
- { client_id: reqestData?.clientId },
2273
- { store_id: { $in: reqestData?.storeId } },
2274
- { date_iso: { $gte: new Date( reqestData?.fromDate ) } },
2275
- { date_iso: { $lte: dayjs.utc( reqestData.toDate ).endOf( 'day' ).toDate() } },
2276
- { sourceCheckList_id: new mongoose.Types.ObjectId( reqestData.sourceCheckList_id ) },
2277
- // {
2278
- // $or: [
2279
- // { timeFlag: { $gt: 0 } },
2280
- // { questionFlag: { $gt: 0 } },
2281
- // ],
2282
- // },
2283
- ],
2284
- },
2281
+ const match = {
2282
+ $match: {
2283
+ $and: [
2284
+ { client_id: reqestData?.clientId },
2285
+ { store_id: { $in: reqestData?.storeId } },
2286
+ { date_iso: { $gte: new Date( reqestData?.fromDate ) } },
2287
+ { date_iso: { $lte: dayjs.utc( reqestData.toDate ).endOf( 'day' ).toDate() } },
2288
+ { sourceCheckList_id: new mongoose.Types.ObjectId( reqestData.sourceCheckList_id ) },
2289
+ // {
2290
+ // $or: [
2291
+ // { timeFlag: { $gt: 0 } },
2292
+ // { questionFlag: { $gt: 0 } },
2293
+ // ],
2294
+ // },
2295
+ ],
2285
2296
  },
2297
+ };
2298
+
2299
+ if ( reqestData?.filter === 'question' ) {
2300
+ match.$match.$and.push( { questionFlag: { $gte: 1 } } );
2301
+ } else if ( reqestData?.filter === 'time' ) {
2302
+ match.$match.$and.push( { timeFlag: { $gte: 1 } } );
2303
+ }
2304
+ const pipeline = [
2305
+ match,
2286
2306
  {
2287
2307
  $project: {
2288
2308
  storeSpocEmail: '$userEmail',
@@ -910,23 +910,18 @@ export const updateConfigure =async ( req, res ) => {
910
910
  if ( inputBody?.checkListDetails?.scheduleDate ) {
911
911
  inputBody.checkListDetails.scheduleDate = new Date( inputBody?.checkListDetails?.scheduleDate );
912
912
  }
913
- let scheduleStartTime; let scheduleEndTime;
914
- if ( inputBody?.checkListDetails?.scheduleRepeatedType == 'range' ) {
915
- scheduleStartTime = inputBody?.checkListDetails?.scheduleStartTime ? dayjs.utc( inputBody?.checkListDetails?.scheduleStartTime, 'YYYY-MM-DD hh:mm A' ) : dayjs();
916
- scheduleEndTime = inputBody?.checkListDetails?.scheduleEndTime ? dayjs.utc( inputBody?.checkListDetails?.scheduleEndTime, 'YYYY-MM-DD hh:mm A' ) : dayjs();
917
- }
918
913
  let configDetails = {
919
914
  publish: inputBody?.checkListDetails?.publish,
920
915
  publishDate: inputBody.checkListDetails.publish ? new Date() : '',
921
916
  schedule: inputBody?.checkListDetails?.schedule,
922
- scheduleRepeatedType: inputBody?.checkListDetails?.scheduleRepeatedType,
917
+ scheduleRepeatedType: inputBody?.checkListDetails?.schedule,
923
918
  scheduleRepeatedMonthSetup: inputBody?.checkListDetails?.scheduleRepeatedMonthSetup,
924
919
  scheduleRepeatedMonthWeek: inputBody?.checkListDetails?.scheduleRepeatedMonthWeek,
925
920
  scheduleRepeatedDay: inputBody?.checkListDetails?.scheduleRepeatedDay,
926
921
  scheduleStartTime: inputBody?.checkListDetails?.scheduleStartTime,
927
- scheduleStartTimeISO: inputBody?.checkListDetails?.scheduleRepeatedType == 'range' ? scheduleStartTime : inputBody?.checkListDetails?.scheduleStartTime ? dayjs.utc( inputBody?.checkListDetails?.scheduleStartTime, 'hh:mm A' ).format() : dayjs.utc().format(),
922
+ scheduleStartTimeISO: dayjs.utc().format(),
928
923
  scheduleEndTime: inputBody?.checkListDetails?.scheduleEndTime,
929
- scheduleEndTimeISO: inputBody?.checkListDetails?.scheduleRepeatedType == 'range' ? scheduleEndTime : inputBody?.checkListDetails?.scheduleEndTime ? dayjs.utc( inputBody?.checkListDetails?.scheduleEndTime, 'hh:mm A' ).format() : dayjs.utc().format(),
924
+ scheduleEndTimeISO: dayjs.utc().format(),
930
925
  scheduleDate: inputBody?.checkListDetails?.scheduleDate ? dayjs( inputBody.checkListDetails.scheduleDate ).format() : '',
931
926
  allowedOverTime: inputBody?.checkListDetails?.allowedOverTime,
932
927
  allowedStoreLocation: inputBody?.checkListDetails?.allowedStoreLocation,
@@ -74,6 +74,7 @@ export const validateChecklistInfoSchema = joi.object( {
74
74
  groupByType: joi.string().required(),
75
75
  groupByValue: joi.string().required(),
76
76
  checklistStatus: joi.string().required(),
77
+
77
78
  } );
78
79
 
79
80
  export const validateChecklistInfoParams = {
@@ -93,6 +94,7 @@ export const validateInfoComparisonCardsSchema = joi.object( {
93
94
  ...baseSchema,
94
95
  groupByType: joi.string().required(),
95
96
  groupByValue: joi.string().required(),
97
+ dateType: joi.string().required(),
96
98
  } );
97
99
 
98
100
  export const validateInfoComparisonCardsParams = {
@@ -15,4 +15,5 @@ mobileRouter
15
15
  .post( '/uploadAnswerImage', isAllowedSessionHandler, mobileController.uploadAnswerImage )
16
16
  .get( '/appVersion', mobileController.appVersion )
17
17
  .post( '/appVersion', mobileController.updateappVersion )
18
+ .post( '/verifylocation', isAllowedSessionHandler, mobileController.getStoreLocation, mobileController.location )
18
19
  .post( '/login', mobileController.login );
@@ -1,24 +1,24 @@
1
1
  import express from 'express';
2
- import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
2
+ import { isAllowedSessionHandler, validate, accessVerification } from 'tango-app-api-middleware';
3
3
  import { checklistValidation, checklistDetailsValidation, runaiValidation, checklistPageSchema, duplicateValidation, updateChecklistValidation, uploadUserValidation, aichecklistValidation, publishValidation } from '../dtos/validation.dtos.js';
4
4
  import * as traxController from '../controllers/trax.controller.js';
5
5
 
6
6
  export const traxRouter = express.Router();
7
7
 
8
8
  traxRouter
9
- .get( '/checklist', isAllowedSessionHandler, validate( checklistPageSchema ), traxController.checklist )
10
- .post( '/checklist/create', isAllowedSessionHandler, validate( checklistValidation ), traxController.create )
11
- .get( '/getConfigDetails', isAllowedSessionHandler, validate( checklistDetailsValidation ), traxController.getConfigDetails )
12
- .post( '/upload', isAllowedSessionHandler, traxController.uploadImage )
13
- .post( '/runAIInsert', isAllowedSessionHandler, validate( runaiValidation ), traxController.runAIInsert )
14
- .get( '/duplicateChecklist/:checklistId', isAllowedSessionHandler, validate( duplicateValidation ), traxController.duplicateChecklist )
15
- .put( '/checklist/update/:checklistId', isAllowedSessionHandler, validate( updateChecklistValidation ), traxController.update )
16
- .post( '/validateUser', isAllowedSessionHandler, validate( uploadUserValidation ), traxController.validateUser )
17
- .get( '/userDetails/:checklistId', isAllowedSessionHandler, validate( duplicateValidation ), traxController.assignedUserDetails )
18
- .post( '/checklistConfigure', isAllowedSessionHandler, traxController.updateConfigure )
19
- .delete( '/deleteChecklist/:checklistId', isAllowedSessionHandler, validate( duplicateValidation ), traxController.deleteChecklist )
20
- .put( '/publish', isAllowedSessionHandler, validate( publishValidation ), traxController.updatePublish )
21
- .get( '/userList', isAllowedSessionHandler, traxController.userlist )
22
- .get( '/zoneList', isAllowedSessionHandler, traxController.zoneList )
23
- .get( '/aichecklist', isAllowedSessionHandler, validate( aichecklistValidation ), traxController.aiChecklist )
24
- .get( '/predefinedChecklist', isAllowedSessionHandler, validate( aichecklistValidation ), traxController.preDefinedChecklist );
9
+ .get( '/checklist', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ), validate( checklistPageSchema ), traxController.checklist )
10
+ .post( '/checklist/create', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isAdd' ] } ] } ), validate( checklistValidation ), traxController.create )
11
+ .get( '/getConfigDetails', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ), validate( checklistDetailsValidation ), traxController.getConfigDetails )
12
+ .post( '/upload', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), traxController.uploadImage )
13
+ .post( '/runAIInsert', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), validate( runaiValidation ), traxController.runAIInsert )
14
+ .get( '/duplicateChecklist/:checklistId', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), validate( duplicateValidation ), traxController.duplicateChecklist )
15
+ .put( '/checklist/update/:checklistId', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), validate( updateChecklistValidation ), traxController.update )
16
+ .post( '/validateUser', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), validate( uploadUserValidation ), traxController.validateUser )
17
+ .get( '/userDetails/:checklistId', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ), validate( duplicateValidation ), traxController.assignedUserDetails )
18
+ .post( '/checklistConfigure', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), traxController.updateConfigure )
19
+ .delete( '/deleteChecklist/:checklistId', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), validate( duplicateValidation ), traxController.deleteChecklist )
20
+ .put( '/publish', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ 'isEdit' ] } ] } ), validate( publishValidation ), traxController.updatePublish )
21
+ .get( '/userList', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ), traxController.userlist )
22
+ .get( '/zoneList', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ), traxController.zoneList )
23
+ .get( '/aichecklist', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ), validate( aichecklistValidation ), traxController.aiChecklist )
24
+ .get( '/predefinedChecklist', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ), validate( aichecklistValidation ), traxController.preDefinedChecklist );