tango-app-api-trax 3.3.1-hotfix-19 → 3.3.1-hotfix-21

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.3.1-hotfix-19",
3
+ "version": "3.3.1-hotfix-21",
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.90",
29
+ "tango-api-schema": "^2.2.91",
30
30
  "tango-app-api-middleware": "^3.1.70",
31
31
  "url": "^0.11.4",
32
32
  "winston": "^3.13.1",
@@ -304,7 +304,7 @@ async function insertData( requestData ) {
304
304
  },
305
305
  } );
306
306
  let getSections = await CLquestions.aggregate( sectionQuery );
307
- if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert' ].includes( getCLconfig.checkListType ) ) {
307
+ if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum' ].includes( getCLconfig.checkListType ) ) {
308
308
  if ( getSections.length ) {
309
309
  for ( let element3 of getSections ) {
310
310
  let collectQuestions = {};
@@ -342,7 +342,7 @@ async function insertData( requestData ) {
342
342
  },
343
343
  } );
344
344
  let allQuestion = await CLassign.aggregate( getquestionQuery );
345
- if ( allQuestion.length ) {
345
+ if ( allQuestion.length && getCLconfig.checkListType == 'custom' ) {
346
346
  let assignList = [];
347
347
  if ( getCLconfig.coverage == 'store' ) {
348
348
  let clusterList = allQuestion.filter( ( ele ) => ele?.clusterName ).map( ( item ) => item.assignId );
@@ -597,8 +597,19 @@ async function insertData( requestData ) {
597
597
  // }
598
598
  }
599
599
  } else {
600
- if ( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert' ].includes( getCLconfig.checkListType ) ) {
601
- let storeDetails = await storeService.find( { clientId: getCLconfig.client_id, status: 'active' }, { storeId: 1 } );
600
+ if ( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum' ].includes( getCLconfig.checkListType ) ) {
601
+ let storeNameList = allQuestion.map( ( item ) => item.store_id );
602
+ let storeDetails = await storeService.find( { clientId: getCLconfig.client_id, status: 'active', ...( [ 'storeopenandclose', 'mobileusagedetection', 'cleaning', 'scrum' ].includes( getCLconfig.checkListType ) ) ? { storeId: { $in: storeNameList } } : {} }, { storeId: 1 } );
603
+ let storeList = storeDetails.map( ( store ) => store.storeId );
604
+ if ( [ 'storeopenandclose', 'mobileusagedetection', 'cleaning', 'scrum' ].includes( getCLconfig.checkListType ) ) {
605
+ allQuestion = allQuestion.filter( ( ele ) => storeList.includes( ele?.store_id ) );
606
+ } else {
607
+ allQuestion = storeDetails.map( ( item ) => {
608
+ return {
609
+ store_id: item.storeId,
610
+ };
611
+ } );
612
+ }
602
613
  let data = {
603
614
  checkListId: updatedchecklist._id,
604
615
  checkListName: getCLconfig.checkListName,
@@ -606,6 +617,7 @@ async function insertData( requestData ) {
606
617
  date_string: currentdate,
607
618
  allowedOverTime: getCLconfig.allowedOverTime,
608
619
  allowedStoreLocation: getCLconfig.allowedStoreLocation,
620
+ checkListDescription: getCLconfig.checkListDescription,
609
621
  scheduleStartTime: getCLconfig.scheduleStartTime,
610
622
  scheduleStartTime_iso: startTimeIso.format(),
611
623
  scheduleEndTime: getCLconfig.scheduleEndTime,
@@ -621,8 +633,17 @@ async function insertData( requestData ) {
621
633
  scheduleRepeatedType: getCLconfig.scheduleRepeatedType,
622
634
  storeCount: storeDetails.length,
623
635
  client_id: getCLconfig.client_id,
624
- aiStoreList: storeDetails ? storeDetails.map( ( store ) => store.storeId ) : [],
636
+ aiStoreList: allQuestion.length ? allQuestion.map( ( store ) => store.store_id ) : [],
625
637
  };
638
+ if ( [ 'storeopenandclose', 'mobileusagedetection', 'cleaning', 'scrum' ].includes( getCLconfig.checkListType ) ) {
639
+ let processData = {
640
+ aiStoreList: allQuestion.length ? allQuestion.map( ( store ) => {
641
+ return { storeName: store.storeName, storeId: store.store_id, events: store.events };
642
+ } ) : [],
643
+ aiConfig: getCLconfig?.aiConfig,
644
+ };
645
+ await PCLconfig.updateOne( { _id: updatedchecklist._id }, processData );
646
+ }
626
647
  // await processedchecklist.create( data );
627
648
  await processedchecklist.updateOne( { date_string: currentdate, checkListId: updatedchecklist._id, sourceCheckList_id: getCLconfig._id, checkListType: getCLconfig.checkListType }, data );
628
649
  }
@@ -1648,9 +1669,9 @@ async function getUserToken( clientId, userEmail ) {
1648
1669
  export async function internalAISendPushNotification( req, res ) {
1649
1670
  try {
1650
1671
  let requestData = req.body;
1651
- // if ( !requestData.clientId ) {
1652
- // return res.sendError( 'clientId is Required', 400 );
1653
- // }
1672
+ if ( !requestData.clientId ) {
1673
+ return res.sendError( 'clientId is Required', 400 );
1674
+ }
1654
1675
  if ( !( requestData?.email || requestData?.storeId ) ) {
1655
1676
  return res.sendError( 'Email or StoreId is Required', 400 );
1656
1677
  }
@@ -1666,15 +1687,12 @@ export async function internalAISendPushNotification( req, res ) {
1666
1687
  let userData;
1667
1688
  if ( requestData.email && requestData.email !='' ) {
1668
1689
  // fcmToken = await getUserToken( requestData.clientId, requestData.email );
1669
- // userData = await userService.findOne( { clientId: requestData.clientId, email: requestData.email }, { fcmToken: 1, loginFrom: 1 } );
1670
- userData = await userService.findOne( { email: requestData.email }, { fcmToken: 1, loginFrom: 1 } );
1690
+ userData = await userService.findOne( { clientId: requestData.clientId, email: requestData.email }, { fcmToken: 1, loginFrom: 1 } );
1671
1691
  } else {
1672
- // let storeData = await storeService.findOne( { clientId: requestData.clientId, storeId: requestData.storeId }, { spocDetails: 1 } );
1673
- let storeData = await storeService.findOne( { storeId: requestData.storeId }, { spocDetails: 1 } );
1692
+ let storeData = await storeService.findOne( { clientId: requestData.clientId, storeId: requestData.storeId }, { spocDetails: 1 } );
1674
1693
  if ( storeData && storeData.spocDetails.length > 0 && storeData.spocDetails[0].email ) {
1675
1694
  // fcmToken = await getUserToken( storeData.spocDetails[0].email );
1676
- // userData = await userService.findOne( { clientId: requestData.clientId, email: requestData.email }, { fcmToken: 1, loginFrom: 1 } );
1677
- userData = await userService.findOne( { email: requestData.email }, { fcmToken: 1, loginFrom: 1 } );
1695
+ userData = await userService.findOne( { clientId: requestData.clientId, email: requestData.email }, { fcmToken: 1, loginFrom: 1 } );
1678
1696
  }
1679
1697
  }
1680
1698
  if ( !userData ) {
@@ -3397,8 +3397,8 @@ export async function clientConfig( req, res ) {
3397
3397
  try {
3398
3398
  let requestData = req.body;
3399
3399
  if ( requestData.clientId && requestData.clientId !='' ) {
3400
- let getClientData = await clientService.findOne( { clientId: requestData.clientId }, { traxRAWImageUpload: 1, clientId: 1, clientName: 1, traxBlockMobileTimeUpdate: 1 } );
3401
- // console.log( ' getClientData=>', getClientData );
3400
+ let getClientData = await clientService.findOne( { clientId: requestData.clientId }, { traxRAWImageUpload: 1, clientId: 1, clientName: 1 } );
3401
+ console.log( ' getClientData=>', getClientData );
3402
3402
  if ( getClientData ) {
3403
3403
  return res.sendSuccess( getClientData );
3404
3404
  } else {
@@ -2091,7 +2091,7 @@ export const validateUserv1 = async ( req, res ) => {
2091
2091
  let newStoreList = storeList.filter( ( ele ) => ele != null && !existsStore.includes( ele.toLowerCase() ) );
2092
2092
  if ( req.body.coverage == 'store' ) {
2093
2093
  assignDetails.forEach( ( item ) => {
2094
- let getStoreDetails = storeDetails.find( ( store ) => store.storeName.toLowerCase() == item.storeName.toLowerCase() );
2094
+ let getStoreDetails = storeDetails.find( ( store ) => store.storeName.toLowerCase() == item.storeName.trim().toLowerCase() );
2095
2095
  if ( getStoreDetails ) {
2096
2096
  let storeUserDetails = userDetails.find( ( ele ) => ele.newEmail.toLowerCase() == item.userEmail.toLowerCase() );
2097
2097
  item._id = getStoreDetails._id;
@@ -3426,11 +3426,11 @@ async function updateOpenSearch( user, data ) {
3426
3426
  export const aiChecklist = async ( req, res ) => {
3427
3427
  try {
3428
3428
  let storeDetails = await storeService.count( { clientId: req.query.clientId, status: 'active' } );
3429
- let aiList = [ 'mobileusagedetection', 'storeopenandclose', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert' ];
3429
+ let aiList = [ 'mobileusagedetection', 'storeopenandclose', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum' ];
3430
3430
  let checklistDetails = [];
3431
3431
  let publishList = [];
3432
3432
  let unpublishList = [];
3433
- publishList = await checklistService.find( { client_id: req.query.clientId, checkListType: { $in: aiList } }, { publish: 1, checkListName: 1, checkListType: 1, client_id: 1, checkListDescription: 1 } );
3433
+ publishList = await checklistService.find( { client_id: req.query.clientId, checkListType: { $in: aiList } }, { publish: 1, checkListName: 1, checkListType: 1, client_id: 1, checkListDescription: 1, storeCount: 1 } );
3434
3434
  if ( publishList.length ) {
3435
3435
  let existList = publishList.map( ( item ) => item.checkListType );
3436
3436
  aiList = aiList.filter( ( item ) => !existList.includes( item ) );
@@ -3439,7 +3439,9 @@ export const aiChecklist = async ( req, res ) => {
3439
3439
  checklistDetails = [ ...publishList, ...unpublishList ];
3440
3440
 
3441
3441
  checklistDetails.forEach( ( item ) => {
3442
- item.storeCount = storeDetails;
3442
+ if ( ![ 'mobileusagedetection', 'storeopenandclose', 'cleaning', 'scrum' ].includes( item.checkListType ) ) {
3443
+ item.storeCount = storeDetails;
3444
+ }
3443
3445
  } );
3444
3446
 
3445
3447
  return res.sendSuccess( checklistDetails );
@@ -3633,6 +3635,8 @@ export const selectAssign = async ( req, res ) => {
3633
3635
  userEmail: { $arrayElemAt: [ '$spocDetails.email', 0 ] },
3634
3636
  contact: { $arrayElemAt: [ '$spocDetails.contact', 0 ] },
3635
3637
  city: '$storeProfile.city',
3638
+ openTime: '$storeProfile.open',
3639
+ closeTime: '$storeProfile.close',
3636
3640
  },
3637
3641
  },
3638
3642
 
@@ -3858,3 +3862,185 @@ export async function updateAssign( req, res ) {
3858
3862
  return res.sendError( e, 500 );
3859
3863
  }
3860
3864
  }
3865
+
3866
+ export async function updateAiConfigure( req, res ) {
3867
+ try {
3868
+ if ( !req.body.storeList.length && req.body.publish ) {
3869
+ return res.sendError( 'Please assign a store', 400 );
3870
+ }
3871
+ let query;
3872
+ query = req.body.type ? { checkListType: req.body.type, client_id: { $exists: false } } : { _id: req.body.id, client_id: req.body.clientId };
3873
+ let aiChecklistDetails = await checklistService.findOne( query );
3874
+ if ( aiChecklistDetails ) {
3875
+ let details = {
3876
+ checkListName: aiChecklistDetails.checkListName,
3877
+ checkListDescription: aiChecklistDetails.checkListDescription,
3878
+ client_id: req.body.clientId,
3879
+ publish: req.body.publish,
3880
+ aiConfig: req.body.aiConfig,
3881
+ createdBy: req.user._id,
3882
+ createdByName: req.user.userName,
3883
+ questionCount: 0,
3884
+ storeCount: req.body.storeList.length,
3885
+ type: 'checklist',
3886
+ checkListType: aiChecklistDetails.checkListType,
3887
+ schedule: 'daily',
3888
+ ...( req.body.publish ) ? { publishDate: new Date() } :{},
3889
+ approver: req.body?.approver || [],
3890
+ scheduleRepeatedDay: [ '01' ],
3891
+ scheduleStartTime: '06:00 AM',
3892
+ scheduleEndTime: '11:59 PM',
3893
+ };
3894
+ let aiResponse = await checklistService.updateOne( { checkListType: aiChecklistDetails.checkListType, client_id: req.body.clientId }, details );
3895
+ let checklistId = req.body?.id || aiResponse?.upsertedId;
3896
+ if ( req.body.storeList ) {
3897
+ let storeData = [];
3898
+ req.body.storeList.forEach( ( ele ) => {
3899
+ let eventTime = [];
3900
+ Object.keys( ele ).forEach( ( key ) => {
3901
+ let keyValue ={};
3902
+ if ( req.body.aiConfig?.assignConfig && req.body.aiConfig?.assignConfig == 'store' && key.includes( 'startTime' ) ) {
3903
+ let num = key.slice( -1 );
3904
+ keyValue['time'] = ele[key];
3905
+ keyValue['duration'] = ele[`configTime${num}`];
3906
+ eventTime.push( keyValue );
3907
+ }
3908
+ } );
3909
+ if ( req.body.aiConfig?.assignConfig && req.body.aiConfig?.assignConfig == 'global' ) {
3910
+ req.body.aiConfig.events.forEach( ( event ) => {
3911
+ let keyValue ={};
3912
+ keyValue['time'] = event.time;
3913
+ keyValue['duration'] = event.duration;
3914
+ eventTime.push( keyValue );
3915
+ } );
3916
+ }
3917
+ storeData.push( {
3918
+ storeName: ele.storeName,
3919
+ ...( req.body.aiConfig?.assignConfig ) ? { events: eventTime } : { events: [] },
3920
+ checkListId: checklistId,
3921
+ client_id: req.body.clientId,
3922
+ checkListName: aiChecklistDetails.checkListName,
3923
+ store_id: ele.storeId,
3924
+ assignId: ele._id,
3925
+ } );
3926
+ } );
3927
+ await assignedService.deleteMany( { checkListId: checklistId } );
3928
+ await assignedService.insertMany( storeData );
3929
+ if ( req.body.publish ) {
3930
+ let processedData = {
3931
+ client_id: req.body.clientId,
3932
+ date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ),
3933
+ date_string: dayjs().format( 'YYYY-MM-DD' ),
3934
+ sourceCheckList_id: checklistId,
3935
+ checkListName: aiChecklistDetails.checkListName,
3936
+ checkListDescription: aiChecklistDetails.checkListDescription,
3937
+ scheduleStartTime: '06:00 AM',
3938
+ scheduleEndTime: '11:59 PM',
3939
+ scheduleStartTime_iso: dayjs.utc( '06:00 AM', 'hh:mm A' ).format(),
3940
+ scheduleEndTime_iso: dayjs.utc( '11:59 PM', 'hh:mm A' ).format(),
3941
+ allowedOverTime: false,
3942
+ allowedStoreLocation: false,
3943
+ createdBy: req.user._id,
3944
+ createdByName: req.user.userName,
3945
+ questionAnswers: [],
3946
+ isdeleted: false,
3947
+ questionCount: 0,
3948
+ storeCount: req.body.storeList.length,
3949
+ publishDate: details?.publishDate,
3950
+ locationCount: 1,
3951
+ checkListType: aiChecklistDetails.checkListType,
3952
+ scheduleRepeatedType: 'daily',
3953
+ aiStoreList: storeData.length? storeData.map( ( store ) => {
3954
+ return { storeName: store.storeName, events: store.events, storeId: store.store_id };
3955
+ } ) : [],
3956
+ aiConfig: req.body.aiConfig,
3957
+ approver: req.body?.approver || [],
3958
+ };
3959
+ let configResponse = await processedchecklistConfig.updateOne( { date_string: dayjs().format( 'YYYY-MM-DD' ), sourceCheckList_id: checklistId, checkListType: aiChecklistDetails.checkListType }, processedData );
3960
+ let data = {
3961
+ ...( configResponse?.upsertedId ) ? { checkListId: configResponse?.upsertedId } : {},
3962
+ checkListName: aiChecklistDetails.checkListName,
3963
+ checkListDescription: aiChecklistDetails.checkListDescription,
3964
+ date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ),
3965
+ date_string: dayjs().format( 'YYYY-MM-DD' ),
3966
+ allowedOverTime: false,
3967
+ allowedStoreLocation: false,
3968
+ scheduleStartTime: '06:00 AM',
3969
+ scheduleStartTime_iso: dayjs.utc( '06:00 AM', 'hh:mm A' ).format(),
3970
+ scheduleEndTime: '11:59 PM',
3971
+ scheduleEndTime_iso: dayjs.utc( '11:59 PM', 'hh:mm A' ).format(),
3972
+ createdBy: req.user._id,
3973
+ createdByName: req.user.userName,
3974
+ sourceCheckList_id: checklistId,
3975
+ checkListType: aiChecklistDetails.checkListType,
3976
+ storeCount: req.body.storeList.length,
3977
+ questionCount: 0,
3978
+ publishDate: new Date(),
3979
+ locationCount: 0,
3980
+ scheduleRepeatedType: 'daily',
3981
+ client_id: req.body.clientId,
3982
+ aiStoreList: req.body.storeList ? req.body.storeList.map( ( store ) => store.storeId ) : [],
3983
+ };
3984
+ await processedchecklist.updateOne( { date_string: dayjs().format( 'YYYY-MM-DD' ), sourceCheckList_id: checklistId, checkListType: aiChecklistDetails.checkListType }, data );
3985
+ }
3986
+ }
3987
+ return res.sendSuccess( 'Checklist updated successfully' );
3988
+ } else {
3989
+ return res.sendError( 'No data found', 204 );
3990
+ }
3991
+ } catch ( e ) {
3992
+ logger.error( { functionName: 'updateAiConfigure', error: e } );
3993
+ return res.sendError( e, 500 );
3994
+ }
3995
+ }
3996
+
3997
+
3998
+ export async function getAiDetails( req, res ) {
3999
+ try {
4000
+ let storeList = [];
4001
+ if ( !req.query.id && !req.query.type ) {
4002
+ return res.sendError( 'Type/Id is required', 400 );
4003
+ }
4004
+ let query = req.query.type ? { checkListType: req.query.type, client_id: { $exists: false } } : { _id: req.query.id, client_id: req.query.clientId };
4005
+ let checklistDetails = await checklistService.findOne( query );
4006
+ if ( !checklistDetails ) {
4007
+ return res.sendError( 'No data found', 204 );
4008
+ }
4009
+ if ( req.query?.id ) {
4010
+ storeList = await assignedService.find( { checkListId: req.query?.id } );
4011
+ let data = [];
4012
+ await Promise.all( ( storeList.map( async ( ele ) => {
4013
+ let element = {};
4014
+ element['storeName'] = ele.storeName,
4015
+ element['store_id'] = ele.store_id;
4016
+ element['_id'] = ele.assignId;
4017
+ let getStoreDetails = await storeService.findOne( { storeId: ele.store_id, status: 'active', clientId: req.query.clientId } );
4018
+ if ( getStoreDetails ) {
4019
+ element['openTime'] = getStoreDetails?.storeProfile?.open;
4020
+ element['closeTime'] = getStoreDetails?.storeProfile?.close;
4021
+ }
4022
+ if ( [ 'cleaning', 'scrum' ].includes( checklistDetails.checkListType ) && checklistDetails?.aiConfig?.assignConfig == 'store' ) {
4023
+ ele.events.forEach( ( event, index ) => {
4024
+ element[`startTime${index+1}`] = event.time;
4025
+ element[`configTime${index+1}`] = event.duration;
4026
+ } );
4027
+ }
4028
+ data.push( element );
4029
+ } ) ) );
4030
+ storeList = data;
4031
+ }
4032
+
4033
+ let response = {
4034
+ checkListName: checklistDetails?.checkListName,
4035
+ checkListDescription: checklistDetails?.checkListDescription,
4036
+ publish: checklistDetails?.publish,
4037
+ aiConfig: checklistDetails?.aiConfig,
4038
+ storeList: storeList,
4039
+ approver: checklistDetails?.approver,
4040
+ };
4041
+ return res.sendSuccess( response );
4042
+ } catch ( e ) {
4043
+ logger.error( { functionName: getAiDetails, error: e } );
4044
+ return res.sendError( e, 500 );
4045
+ }
4046
+ }
@@ -28,7 +28,9 @@ traxRouter
28
28
  .post( '/selectAssign', validate( selectAssign ), traxController.selectAssign )
29
29
  .post( '/assign', isAllowedSessionHandler, traxController.checklistAssign )
30
30
  // .post( '/assignUpload', isAllowedSessionHandler, traxController.assignChecklistUser )
31
- .post( '/updateAssign', isAllowedSessionHandler, traxController.updateAssign );
31
+ .post( '/updateAssign', isAllowedSessionHandler, traxController.updateAssign )
32
+ .post( '/updateAiConfigure', isAllowedSessionHandler, traxController.updateAiConfigure )
33
+ .get( '/getAiDetails', isAllowedSessionHandler, traxController.getAiDetails );
32
34
  ;
33
35
 
34
36
  // isAllowedSessionHandler, isAllowedClient, accessVerification( { userType: [ 'tango', 'client' ], access: [ { featureName: 'TangoTrax', name: 'checklist', permissions: [ ] } ] } ),
@@ -9,7 +9,7 @@ export const findOne = ( query = {}, record = {} ) => {
9
9
  };
10
10
 
11
11
  export const updateOne = ( query = {}, record = {} ) => {
12
- return model.processedchecklistconfigModel.updateOne( query, { $set: record } );
12
+ return model.processedchecklistconfigModel.updateOne( query, { $set: record }, { upsert: true } );
13
13
  };
14
14
 
15
15
  export const updateMany = ( query = {}, record = {} ) => {