tango-app-api-trax 3.4.1-beta-1 → 3.5.0-ai-2

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.
@@ -1,4 +1,4 @@
1
- import { signedUrl, fileUpload, chunkArray, logger, sendPushNotification, sendTeamsNotification } from 'tango-app-api-middleware';
1
+ import { signedUrl, fileUpload, chunkArray, logger, sendPushNotification, sendTeamsNotification, insertOpenSearchData } from 'tango-app-api-middleware';
2
2
  import * as checklistService from '../services/checklist.service.js';
3
3
  import * as questionService from '../services/checklistQuestion.service.js';
4
4
  import * as assignedService from '../services/checklistAssign.service.js';
@@ -289,6 +289,45 @@ export const create = async ( req, res ) => {
289
289
  actionType = 'Create';
290
290
  teamsMsg = 'ClientId: '+ req.body.clientId + ', Action: '+ actionType + ', ChecklistId: '+ checkListId + ', Checklist Name: '+ inputBody.checklistName + ', UpDatedBy: '+ req.user.email;
291
291
  sendTeamsNotification( teamsAlertUrls.checklist, teamsMsg );
292
+
293
+ let logObj = {
294
+ client_id: inputBody.clientId,
295
+ createAt: new Date(),
296
+ sourceCheckList_id: checkListId,
297
+ checkListName: inputBody.checklistName,
298
+ fromCheckListName: '',
299
+ type: 'checklist',
300
+ action: 'created',
301
+ storeName: '',
302
+ store_id: '',
303
+ createdByEmail: req.user.email,
304
+ createdBy: req.user.userName,
305
+ coverage: 'store',
306
+ logDetails: {},
307
+ userType: req.user.userType,
308
+ };
309
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
310
+ if ( inputBody.submitType == 'save' ) {
311
+ let logObj = {
312
+ client_id: inputBody.clientId,
313
+ createAt: new Date(),
314
+ sourceCheckList_id: checkListId,
315
+ checkListName: inputBody.checklistName,
316
+ fromCheckListName: '',
317
+ type: 'checklist',
318
+ action: 'draft',
319
+ storeName: '',
320
+ store_id: '',
321
+ createdByEmail: req.user.email,
322
+ createdBy: req.user.userName,
323
+ coverage: 'store',
324
+ logDetails: {},
325
+ userType: req.user.userType,
326
+ };
327
+
328
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
329
+ }
330
+
292
331
  return res.sendSuccess( { checklistId: checkListId, msg: 'CheckList Created Successfully' } );
293
332
  }
294
333
  } ).catch( ( e ) => {
@@ -305,6 +344,7 @@ export const create = async ( req, res ) => {
305
344
  return res.sendError( e, 500 );
306
345
  } );
307
346
  } catch ( e ) {
347
+ // console.log( 'e', e );
308
348
  logger.error( 'create =>', e );
309
349
  return res.sendError( e, 500 );
310
350
  }
@@ -617,6 +657,25 @@ export const deleteChecklist = async ( req, res ) => {
617
657
  let teamsAlertUrls = process.env.teamsAlertURL ? JSON.parse( process.env.teamsAlertURL ) : '';
618
658
  teamsMsg = 'ClientId: '+ checklistDetails.client_id + ', Action: '+ actionType + ', ChecklistId: '+ req.params.checklistId + ', Checklist Name: '+ checklistDetails.checkListName + ', UpDatedBy: '+ req.user.email;
619
659
  sendTeamsNotification( teamsAlertUrls.checklist, teamsMsg );
660
+
661
+ let logObj = {
662
+ client_id: checklistDetails.client_id,
663
+ createAt: new Date(),
664
+ sourceCheckList_id: checklistDetails._id,
665
+ checkListName: checklistDetails.checkListName,
666
+ fromCheckListName: '',
667
+ type: 'checklist',
668
+ action: 'deleted',
669
+ storeName: '',
670
+ store_id: '',
671
+ createdByEmail: req.user.email,
672
+ createdBy: req.user.userName,
673
+ coverage: checklistDetails.coverage,
674
+ logDetails: {},
675
+ userType: req.user.userType,
676
+ };
677
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
678
+
620
679
  return res.sendSuccess( { message: 'Checklist Deleted Successfully' } );
621
680
  } ).catch( ( e ) => {
622
681
  return res.sendError( e, 500 );
@@ -695,6 +754,24 @@ export const duplicateChecklist = async ( req, res ) => {
695
754
  let teamsAlertUrls = process.env.teamsAlertURL ? JSON.parse( process.env.teamsAlertURL ) : '';
696
755
  teamsMsg = 'ClientId: '+ checkDetails.client_id + ', Action: '+ actionType + ', ChecklistId: '+ data._id + ', Checklist Name: '+ checkDetails.checkListName + ', UpDatedBy: '+ req.user.email;
697
756
  sendTeamsNotification( teamsAlertUrls.checklist, teamsMsg );
757
+
758
+ let logObj = {
759
+ client_id: checkDetails.client_id,
760
+ createAt: new Date(),
761
+ sourceCheckList_id: checkDetails._id,
762
+ checkListName: checkDetails.checkListName,
763
+ fromCheckListName: '',
764
+ type: 'checklist',
765
+ action: 'duplicated',
766
+ storeName: '',
767
+ store_id: '',
768
+ createdByEmail: req.user.email,
769
+ createdBy: req.user.userName,
770
+ coverage: checkDetails.coverage,
771
+ logDetails: {},
772
+ userType: req.user.userType,
773
+ };
774
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
698
775
  return res.sendSuccess( { message: 'CheckList Duplicated Successfully' } );
699
776
  } else {
700
777
  return res.sendSuccess( { message: 'duplicated Successfully' } );
@@ -731,6 +808,8 @@ export const update = async ( req, res ) => {
731
808
  return res.sendError( 'no data found', 204 );
732
809
  }
733
810
 
811
+ let getExistQuestions = await questionService.find( { checkListId: req.params.checklistId, client_id: req.body.clientId } );
812
+
734
813
  inputBody.sections.forEach( async ( element ) => {
735
814
  if ( !element.questions.length && inputBody.submitType == 'configure' ) {
736
815
  return res.sendError( { message: 'Question is Required' }, 400 );
@@ -741,118 +820,235 @@ export const update = async ( req, res ) => {
741
820
  }
742
821
  } );
743
822
 
744
- checkListDetails.checkListName = inputBody.checklistName;
745
- checkListDetails.checkListDescription = inputBody.checklistDescription;
746
- checkListDetails.questionCount = questionCount;
747
823
 
748
- checkListDetails.save().then( async () => {
749
- let checkListId = req.params.checklistId;
750
- let logInsertData = {
751
- action: 'checklistUpdate',
752
- checklistId: checkListId,
753
- checkListName: inputBody.checklistName,
754
- createdBy: req.user._id,
755
- createdByName: req.user.userName,
756
- client_id: req.body.clientId,
757
- sections: inputBody?.sections,
758
- createdByEmail: req.user.email,
759
- };
760
- await checklistLogs.create( logInsertData );
761
- if ( inputBody.sections.length ) {
762
- let sectionId =[];
763
- for ( let i = 0; i < inputBody?.sections?.length; i++ ) {
764
- let section = inputBody.sections[i];
765
- section.questions.forEach( ( section ) => {
766
- if ( section.questionReferenceImage && section.questionReferenceImage !='' ) {
767
- let imgUrl = section.questionReferenceImage.split( '?' )[0];
824
+ let params = {
825
+ checkListName: inputBody.checklistName,
826
+ checkListDescription: inputBody.checklistDescription,
827
+ questionCount: questionCount,
828
+ };
829
+
830
+ await checklistService.updateOne( { _id: req.params.checklistId }, params );
831
+ let checkListId = req.params.checklistId;
832
+ let logInsertData = {
833
+ action: 'checklistUpdate',
834
+ checklistId: checkListId,
835
+ checkListName: inputBody.checklistName,
836
+ createdBy: req.user._id,
837
+ createdByName: req.user.userName,
838
+ client_id: req.body.clientId,
839
+ sections: inputBody?.sections,
840
+ createdByEmail: req.user.email,
841
+ };
842
+ await checklistLogs.create( logInsertData );
843
+ let sectionList =[];
844
+ if ( inputBody.sections.length ) {
845
+ for ( let i = 0; i < inputBody?.sections?.length; i++ ) {
846
+ let section = inputBody.sections[i];
847
+ section.questions.forEach( ( section ) => {
848
+ if ( section.questionReferenceImage && section.questionReferenceImage !='' ) {
849
+ let imgUrl = section.questionReferenceImage.split( '?' )[0];
850
+ let url = imgUrl.split( '/' );
851
+ url.splice( 0, 3 );
852
+ section.questionReferenceImage = url.join( '/' );
853
+ }
854
+ section.answers.forEach( ( answer ) => {
855
+ if ( answer.referenceImage != '' ) {
856
+ let imgUrl = answer.referenceImage.split( '?' )[0];
768
857
  let url = imgUrl.split( '/' );
769
858
  url.splice( 0, 3 );
770
- section.questionReferenceImage = url.join( '/' );
859
+ answer.referenceImage = url.join( '/' );
771
860
  }
772
- // if (['image', 'descriptiveImage'].includes(section.answerType)) {
773
- section.answers.forEach( ( answer ) => {
774
- if ( answer.referenceImage != '' ) {
775
- let imgUrl = answer.referenceImage.split( '?' )[0];
776
- let url = imgUrl.split( '/' );
777
- url.splice( 0, 3 );
778
- answer.referenceImage = url.join( '/' );
779
- }
780
- } );
781
- // }
782
861
  } );
862
+ } );
783
863
 
784
- for ( let [ index, question ] of section.questions.entries() ) {
785
- await processNested( index, question );
786
- }
864
+ for ( let [ index, question ] of section.questions.entries() ) {
865
+ await processNested( index, question );
866
+ }
787
867
 
788
- async function processNested( qIdx, question, nestedIndex=-1 ) {
789
- if ( question?.answers?.length ) {
790
- for ( let [ index, answer ] of question?.answers?.entries() ) {
791
- if ( !section.questions[qIdx].answers[index]?.nestedQuestion && nestedIndex == -1 ) {
792
- section.questions[qIdx].answers[index].nestedQuestion = [];
793
- }
794
- if ( answer.showLinked ) {
795
- if ( nestedIndex != -1 ) {
796
- if ( !section.questions[qIdx].answers[nestedIndex].nestedQuestion.includes( answer.linkedQuestion ) ) {
797
- section.questions[qIdx].answers[nestedIndex].nestedQuestion.push( answer.linkedQuestion );
798
- }
799
- } else {
800
- if ( !section.questions[qIdx].answers[index].nestedQuestion.includes( answer.linkedQuestion ) ) {
801
- section.questions[qIdx].answers[index].nestedQuestion.push( answer.linkedQuestion );
802
- }
868
+ async function processNested( qIdx, question, nestedIndex=-1 ) {
869
+ if ( question?.answers?.length ) {
870
+ for ( let [ index, answer ] of question?.answers?.entries() ) {
871
+ if ( !section.questions[qIdx].answers[index]?.nestedQuestion && nestedIndex == -1 ) {
872
+ section.questions[qIdx].answers[index].nestedQuestion = [];
873
+ }
874
+ if ( answer.showLinked ) {
875
+ if ( nestedIndex != -1 ) {
876
+ if ( !section.questions[qIdx].answers[nestedIndex].nestedQuestion.includes( answer.linkedQuestion ) ) {
877
+ section.questions[qIdx].answers[nestedIndex].nestedQuestion.push( answer.linkedQuestion );
803
878
  }
804
- let nestedLinkedQuestion = section.questions.find( ( item ) => item.qno == answer.linkedQuestion );
805
- if ( nestedLinkedQuestion ) {
806
- let findNestedAnswers = nestedLinkedQuestion.answers.find( ( item ) => item.showLinked );
807
- if ( findNestedAnswers ) {
808
- if ( nestedIndex != -1 ) {
809
- await processNested( qIdx, nestedLinkedQuestion, nestedIndex );
810
- } else {
811
- await processNested( qIdx, nestedLinkedQuestion, index );
812
- }
879
+ } else {
880
+ if ( !section.questions[qIdx].answers[index].nestedQuestion.includes( answer.linkedQuestion ) ) {
881
+ section.questions[qIdx].answers[index].nestedQuestion.push( answer.linkedQuestion );
882
+ }
883
+ }
884
+ let nestedLinkedQuestion = section.questions.find( ( item ) => item.qno == answer.linkedQuestion );
885
+ if ( nestedLinkedQuestion ) {
886
+ let findNestedAnswers = nestedLinkedQuestion.answers.find( ( item ) => item.showLinked );
887
+ if ( findNestedAnswers ) {
888
+ if ( nestedIndex != -1 ) {
889
+ await processNested( qIdx, nestedLinkedQuestion, nestedIndex );
890
+ } else {
891
+ await processNested( qIdx, nestedLinkedQuestion, index );
813
892
  }
814
893
  }
815
894
  }
816
895
  }
817
896
  }
818
897
  }
898
+ }
819
899
 
820
- let sectionList = {
821
- section: section.name,
822
- sectionOldName: section.oldName,
823
- createdBy: req.user._id,
824
- createdByName: req.user.userName,
825
- client_id: req.body.clientId,
826
- checkListId: checkListId,
827
- question: section.questions,
828
- checkList: inputBody.checklistName,
829
- };
830
- await questionService.create( sectionList ).then( async ( data ) => {
831
- sectionId.push( data._id );
832
- if ( i == inputBody.sections.length - 1 ) {
833
- let actionType = 'Checklist Updated';
834
- let teamsMsg;
835
- let teamsAlertUrls = process.env.teamsAlertURL ? JSON.parse( process.env.teamsAlertURL ) : '';
836
- teamsMsg = 'ClientId: '+ req.body.clientId + ', Action: '+ actionType + ', ChecklistId: '+ checkListId + ', Checklist Name: '+ inputBody.checklistName + ', UpDatedBy: '+ req.user.email;
837
- sendTeamsNotification( teamsAlertUrls.checklist, teamsMsg );
838
- await questionService.deleteMany( { checkListId: checkListId, client_id: req.body.clientId, _id: { $nin: sectionId } } );
839
- await assignedService.updateMany( { checkListId: checkListId }, { checkListName: inputBody.checklistName } );
840
- return res.sendSuccess( { checklistId: checkListId, msg: 'CheckList Created Successfully' } );
841
- }
842
- } ).catch( ( e ) => {
843
- return res.sendError( e, 500 );
844
- } );
900
+ sectionList.push( {
901
+ section: section.name,
902
+ sectionOldName: section.oldName,
903
+ createdBy: req.user._id,
904
+ createdByName: req.user.userName,
905
+ client_id: req.body.clientId,
906
+ checkListId: checkListId,
907
+ question: section.questions,
908
+ checkList: inputBody.checklistName,
909
+ } );
910
+ }
911
+ }
912
+ await questionService.deleteMany( { checkListId: checkListId, client_id: req.body.clientId } );
913
+ if ( sectionList.length ) {
914
+ await questionService.insertMany( sectionList );
915
+ }
916
+
917
+ let questionList = {
918
+ questionAdd: [],
919
+ questionEdit: [],
920
+ questionDelete: [],
921
+ };
922
+ let updateSection = [];
923
+
924
+ function findDifferences( obj1, obj2 ) {
925
+ return Object.keys( obj1 ).reduce( ( diff, key ) => {
926
+ if ( !isEqual( obj1[key], obj2[key] ) ) {
927
+ diff[key] = { previous: obj1[key], new: obj2[key] };
845
928
  }
846
- } else {
847
- if ( inputBody.submitType == 'save' ) {
848
- await questionService.deleteMany( { checkListId: checkListId, client_id: req.body.clientId } );
849
- return res.sendSuccess( { message: 'CheckList Updated Successfully' } );
929
+ return diff;
930
+ }, {} );
931
+ }
932
+
933
+ getExistQuestions.forEach( ( ele ) => {
934
+ let sectionDetails = inputBody.sections.find( ( sec ) => sec.oldName === ele.section );
935
+
936
+ if ( !sectionDetails ) {
937
+ questionList.questionDelete.push( { sectionName: ele.section, questions: ele.question } );
938
+ return;
939
+ }
940
+
941
+ if ( ele.section !== sectionDetails.name ) {
942
+ updateSection.push( { previous: ele.section, new: sectionDetails.name } );
943
+ }
944
+
945
+ ele.question.forEach( ( qn ) => {
946
+ let question = sectionDetails.questions.find( ( qns ) => qns.oldQname === qn.qname );
947
+
948
+ if ( question ) {
949
+ qn.answers.forEach( ( ans ) => {
950
+ delete ans.answeroptionNumber;
951
+ } );
952
+ question.answers.forEach( ( ans ) => {
953
+ delete ans.answeroptionNumber;
954
+ } );
955
+ let compare = findDifferences( qn, question );
956
+ if ( Object.keys( compare ).length ) {
957
+ questionList.questionEdit.push( { sectionName: ele.section, questions: [ { previous: qn, new: question } ] } );
958
+ }
959
+ } else {
960
+ let sectionIndex = questionList.questionDelete.findIndex( ( sec ) => sec.sectionName === ele.section );
961
+
962
+ if ( sectionIndex !== -1 ) {
963
+ questionList.questionDelete[sectionIndex].questions.push( qn );
964
+ } else {
965
+ questionList.questionDelete.push( { sectionName: ele.section, questions: [ qn ] } );
966
+ }
850
967
  }
968
+ } );
969
+ } );
970
+
971
+ inputBody.sections.forEach( ( ele ) => {
972
+ let sectionDetails = getExistQuestions.find( ( sec ) => sec.section === ele.oldName );
973
+
974
+ if ( !sectionDetails ) {
975
+ questionList.questionAdd.push( { sectionName: ele.name, questions: ele.questions } );
976
+ return;
851
977
  }
852
- } ).catch( ( e ) => {
853
- logger.error( 'update =>', e );
854
- return res.sendError( e, 500 );
978
+
979
+ ele.questions.forEach( ( qn ) => {
980
+ let question = sectionDetails.question.find( ( qns ) => qns.qname === qn.oldQname );
981
+
982
+ if ( !question ) {
983
+ let sectionIndex = questionList.questionAdd.findIndex( ( sec ) => sec.sectionName === ele.name );
984
+
985
+ if ( sectionIndex !== -1 ) {
986
+ questionList.questionAdd[sectionIndex].questions.push( qn );
987
+ } else {
988
+ questionList.questionAdd.push( { sectionName: ele.name, questions: [ qn ] } );
989
+ }
990
+ }
991
+ } );
855
992
  } );
993
+
994
+ if ( updateSection.length || questionList.questionAdd.length || questionList.questionEdit.length || questionList.questionDelete.length || inputBody.checklistName.toLowerCase() != checkListDetails.checkListName.toLowerCase() || inputBody.checklistDescription.toLowerCase() != checkListDetails.checkListDescription.toLowerCase() ) {
995
+ let insertLogData = {
996
+ client_id: req.body.clientId,
997
+ createAt: new Date(),
998
+ sourceCheckList_id: req.params.checklistId,
999
+ checkListName: inputBody.checklistName,
1000
+ fromCheckListName: '',
1001
+ type: 'checklist',
1002
+ action: 'edited',
1003
+ storeName: '',
1004
+ store_id: '',
1005
+ createdByEmail: req.user.email,
1006
+ createdBy: req.user.userName,
1007
+ coverage: checkListDetails.coverage,
1008
+ logDetails: {
1009
+ ...( inputBody.checklistName.toLowerCase() == checkListDetails.checkListName.toLowerCase() ) ? { updatedChecklistName: {} } :{ updatedChecklistName: {
1010
+ previous: checkListDetails.checkListName,
1011
+ new: inputBody.checklistName,
1012
+ } },
1013
+ ...( inputBody.checklistDescription.toLowerCase() == checkListDetails.checkListDescription.toLowerCase() ) ? { updatedChecklistDescription: {} } :{ updatedChecklistDescription: {
1014
+ previous: checkListDetails.checkListDescription,
1015
+ new: inputBody.checklistDescription,
1016
+ } },
1017
+ updatedSectionName: updateSection,
1018
+ questionAdd: questionList.questionAdd,
1019
+ questionEdit: questionList.questionEdit,
1020
+ questionDelete: questionList.questionDelete,
1021
+ },
1022
+ userType: req.user.userType,
1023
+ };
1024
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, insertLogData );
1025
+ }
1026
+
1027
+ if ( inputBody.submitType == 'save' ) {
1028
+ let logObj = {
1029
+ client_id: inputBody.clientId,
1030
+ createAt: new Date(),
1031
+ sourceCheckList_id: req.params.checklistId,
1032
+ checkListName: inputBody.checklistName,
1033
+ fromCheckListName: '',
1034
+ type: 'checklist',
1035
+ action: 'draft',
1036
+ storeName: '',
1037
+ store_id: '',
1038
+ createdByEmail: req.user.email,
1039
+ createdBy: req.user.userName,
1040
+ coverage: 'store',
1041
+ logDetails: {},
1042
+ userType: req.user.userType,
1043
+ };
1044
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
1045
+ }
1046
+ let actionType = 'Checklist Updated';
1047
+ let teamsMsg;
1048
+ let teamsAlertUrls = process.env.teamsAlertURL ? JSON.parse( process.env.teamsAlertURL ) : '';
1049
+ teamsMsg = 'ClientId: '+ req.body.clientId + ', Action: '+ actionType + ', ChecklistId: '+ checkListId + ', Checklist Name: '+ inputBody.checklistName + ', UpDatedBy: '+ req.user.email;
1050
+ sendTeamsNotification( teamsAlertUrls.checklist, teamsMsg );
1051
+ return res.sendSuccess( { message: 'CheckList Updated Successfully', checklistId: req.params.checklistId } );
856
1052
  } catch ( e ) {
857
1053
  logger.error( 'update =>', e );
858
1054
  return res.sendError( e, 500 );
@@ -1478,6 +1674,7 @@ export const updateConfigurev1 =async ( req, res ) => {
1478
1674
  await checklistLogs.create( logInsertData );
1479
1675
 
1480
1676
  checklistDetails = await checklistService.findOne( { _id: inputBody.checkListDetails._id, type: 'checklist', isdeleted: false } );
1677
+ let oldPublish = checklistDetails.publish;
1481
1678
 
1482
1679
  if ( [ 'mobileusagedetection', 'storeopenandclose', 'uniformdetection' ].includes( inputBody.checkListDetails.checkListType ) && inputBody.uploadUser ) {
1483
1680
  checklistDetails = await checklistService.findOne( { _id: inputBody.checkListDetails._id, type: 'checklist' } );
@@ -1635,6 +1832,118 @@ export const updateConfigurev1 =async ( req, res ) => {
1635
1832
  futureDaysDataRemove( currentDate, req.params.checklistId, checklistDetails.checkListName, '333' );
1636
1833
  }
1637
1834
  }
1835
+ checklistDetails = checklistDetails.toObject();
1836
+ checklistDetails.configStartDate = checklistDetails.configStartDate ? dayjs.utc( checklistDetails?.configStartDate ).format( 'YYYY-MM-DD' ) : '';
1837
+ checklistDetails.configEndDate = checklistDetails.configEndDate ? dayjs.utc( checklistDetails?.configEndDate ).format( 'YYYY-MM-DD' ) : '';
1838
+ checklistDetails.scheduleDate = checklistDetails.scheduleDate ? dayjs.utc( checklistDetails?.scheduleDate ).format( 'YYYY-MM-DD' ) : '';
1839
+ checklistDetails.scheduleRepeatedDay = Array.isArray( checklistDetails.scheduleRepeatedDay ) ? checklistDetails.scheduleRepeatedDay[0] : checklistDetails.scheduleRepeatedDay;
1840
+ configDetails.scheduleRepeatedDay = Array.isArray( configDetails.scheduleRepeatedDay ) ? configDetails?.scheduleRepeatedDay?.[0] || '' : configDetails?.scheduleRepeatedDay;
1841
+ configDetails.scheduleDate = configDetails.scheduleDate ? dayjs( configDetails?.scheduleDate ).format( 'YYYY-MM-DD' ) : '';
1842
+ let removedKeys = [ 'publish', 'publishDate', 'storeCount', 'sections', 'createdAt', 'updatedAt', 'scheduleStartTimeISO', 'scheduleEndTimeISO', 'aiConfig' ];
1843
+ removedKeys.forEach( ( item ) => {
1844
+ delete configDetails?.[item];
1845
+ delete checklistDetails?.[item];
1846
+ } );
1847
+ let differences = findObjectDifference( checklistDetails, configDetails );
1848
+ if ( Object.keys( differences ).length || req.body.added.length || req.body.removed?.user?.length || req.body.removed?.store?.length ) {
1849
+ let showSchedule = false;
1850
+ let scheduleKeys = [ 'scheduleDate', 'schedule', 'scheduleEndTime', 'scheduleStartTime', 'scheduleRepeatedDay', 'scheduleRepeatedType', 'configStartDate', 'configEndDate', 'scheduleWeekDays', 'scheduleRepeatedMonthWeek', 'specificDate' ];
1851
+
1852
+ if ( scheduleKeys.some( ( key ) => differences?.[key] ) ) {
1853
+ showSchedule = true;
1854
+ }
1855
+ let insertData = {
1856
+ client_id: req.body.clientId,
1857
+ createAt: new Date(),
1858
+ sourceCheckList_id: configDetails._id,
1859
+ checkListName: configDetails.checkListName,
1860
+ fromCheckListName: '',
1861
+ type: 'checklist',
1862
+ action: inputBody.checkListDetails.publish ? 'updated' : 'draft',
1863
+ storeName: '',
1864
+ store_id: '',
1865
+ createdByEmail: req.user.email,
1866
+ createdBy: req.user.userName,
1867
+ coverage: configDetails.coverage,
1868
+ logDetails: {
1869
+ schedule: {
1870
+ previous: {
1871
+ ...( showSchedule && checklistDetails.schedule == 'onetime' ) ? { scheduleDateString: dayjs( checklistDetails?.scheduleDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1872
+ schedule: showSchedule ? checklistDetails.schedule : '',
1873
+ time: ( ( showSchedule ) && ( checklistDetails.scheduleStartTime != '' || checklistDetails.scheduleEndTime != '' ) ) ? checklistDetails.scheduleStartTime + ' to ' + checklistDetails.scheduleEndTime : '',
1874
+ scheduleRepeatedDay: showSchedule ? checklistDetails?.scheduleRepeatedDay : '',
1875
+ scheduleRepeatedType: showSchedule ? checklistDetails?.scheduleRepeatedType : '',
1876
+ ...( showSchedule && checklistDetails?.configStartDate ) ? { configStartDate: dayjs( checklistDetails?.configStartDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1877
+ ...( showSchedule && checklistDetails?.configEndDate ) ? { configEndDate: dayjs( checklistDetails?.configEndDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1878
+ scheduleWeekDays: showSchedule ? checklistDetails?.scheduleWeekDays : [],
1879
+ scheduleRepeatedMonthWeek: showSchedule ? checklistDetails?.scheduleRepeatedMonthWeek : '',
1880
+ specificDate: showSchedule ? checklistDetails?.specificDate : [],
1881
+
1882
+ },
1883
+ new: {
1884
+ ...( showSchedule && configDetails.schedule == 'onetime' ) ? { scheduleDateString: dayjs( configDetails?.scheduleDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1885
+ schedule: showSchedule ? configDetails.schedule : '',
1886
+ time: ( ( showSchedule ) && ( configDetails.scheduleStartTime != '' || configDetails.scheduleEndTime != '' ) ) ? configDetails.scheduleStartTime + ' to ' + configDetails.scheduleEndTime : '',
1887
+ scheduleRepeatedDay: showSchedule ? configDetails?.scheduleRepeatedDay : '',
1888
+ scheduleRepeatedType: showSchedule ? configDetails?.scheduleRepeatedType : '',
1889
+ ...( showSchedule && configDetails?.configStartDate ) ? { configStartDate: dayjs( configDetails?.configStartDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1890
+ ...( showSchedule && configDetails?.configEndDate ) ? { configEndDate: dayjs( configDetails?.configEndDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1891
+ scheduleWeekDays: showSchedule ? configDetails?.scheduleWeekDays : [],
1892
+ scheduleRepeatedMonthWeek: showSchedule ? configDetails?.scheduleRepeatedMonthWeek : '',
1893
+ specificDate: showSchedule ? configDetails?.specificDate : [],
1894
+ },
1895
+ },
1896
+ response: {
1897
+ previous: [
1898
+ ...( differences?.allowedStoreLocation && checklistDetails.allowedStoreLocation ? [ 'Geo fencing' ] : [] ),
1899
+ ...( differences?.allowedMultiSubmit && checklistDetails.allowedMultiSubmit? [ 'Allow multiple responses' ] : [] ),
1900
+ ...( differences?.allowedOverTime && checklistDetails.allowedOverTime ? [ 'Fill response after configure time.' ] : [] ),
1901
+ ...( differences?.allowOnce && checklistDetails.allowOnce ? [ 'Only one time' ] : [] ),
1902
+ ],
1903
+ new: [
1904
+ ...( differences?.allowedStoreLocation && configDetails.allowedStoreLocation ? [ 'Geo fencing' ] : [] ),
1905
+ ...( differences?.allowedMultiSubmit && configDetails.allowedMultiSubmit? [ 'Allow multiple responses' ] : [] ),
1906
+ ...( differences?.allowedOverTime && configDetails.allowedOverTime ? [ 'Fill response after configure time' ] : [] ),
1907
+ ...( differences?.allowOnce && configDetails.allowOnce ? [ 'Only one time' ] : [] ),
1908
+ ],
1909
+ },
1910
+ ...( differences?.approver ) ? { approver:
1911
+ { previous: checklistDetails?.approver.map( ( item ) => item.name ).toString(),
1912
+ new: configDetails?.approver.map( ( item ) => item.name ).toString() },
1913
+ } : { approver: {} },
1914
+ ...( differences?.owner ) ? { owner:
1915
+ { previous: checklistDetails?.owner.map( ( item ) => item.name ).toString(),
1916
+ new: configDetails?.owner.map( ( item ) => item.name ).toString() },
1917
+ } : { owner: {} },
1918
+ ...( req.body.checkListDetails.coverage == 'store' ) ? { storeAdded: req.body.added } :{ storeAdded: [] },
1919
+ ...( req.body.removed.store.length ) ? { storeRemoved: req.body.removed.store } :{ storeRemoved: [] },
1920
+ ...( req.body.checkListDetails.coverage == 'user' ) ? { userAdded: req.body.added } :{ userAdded: [] },
1921
+ ...( req.body.removed.user.length ) ? { userRemoved: req.body.removed.user } :{ userRemoved: [] },
1922
+ },
1923
+ userType: req.user.userType,
1924
+ };
1925
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, insertData );
1926
+ }
1927
+
1928
+ if ( inputBody.checkListDetails.publish != oldPublish ) {
1929
+ let logObj = {
1930
+ client_id: inputBody.checkListDetails.client_id,
1931
+ createAt: new Date(),
1932
+ sourceCheckList_id: inputBody.checkListDetails._id,
1933
+ checkListName: inputBody.checkListDetails.checkListName,
1934
+ fromCheckListName: '',
1935
+ type: 'checklist',
1936
+ action: inputBody.checkListDetails.publish ? 'published' : 'unpublished',
1937
+ storeName: '',
1938
+ store_id: '',
1939
+ createdByEmail: req.user.email,
1940
+ createdBy: req.user.userName,
1941
+ coverage: inputBody.checkListDetails.coverage,
1942
+ logDetails: {},
1943
+ userType: req.user.userType,
1944
+ };
1945
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
1946
+ }
1638
1947
  let actionType;
1639
1948
  let teamsMsg;
1640
1949
  actionType = inputBody.checkListDetails.publish ? 'configPublish' : 'configDraft';
@@ -1652,6 +1961,31 @@ export const updateConfigurev1 =async ( req, res ) => {
1652
1961
  return res.sendError( e, 500 );
1653
1962
  }
1654
1963
  };
1964
+ function findObjectDifference( oldObj, newObj ) {
1965
+ const isEqual = ( a, b ) => JSON.stringify( a ) === JSON.stringify( b );
1966
+
1967
+ const getArrayDiff = ( oldArr, newArr ) => {
1968
+ const removed = oldArr.filter( ( item ) => !newArr.some( ( newItem ) => isEqual( newItem, item ) ) );
1969
+ const added = newArr.filter( ( item ) => !oldArr.some( ( oldItem ) => isEqual( oldItem, item ) ) );
1970
+ if ( removed.length || added.length ) {
1971
+ return { previous: oldArr, new: newArr };
1972
+ }
1973
+ return [];
1974
+ };
1975
+ const difference = Object.keys( oldObj ).reduce( ( diff, key ) => {
1976
+ oldObj[key] = oldObj[key] == null ? '' : oldObj[key];
1977
+ if ( !isEqual( oldObj[key], newObj[key] ) ) {
1978
+ if ( !Array.isArray( newObj[key] ) ) {
1979
+ diff[key] = { previous: oldObj[key], new: newObj[key] };
1980
+ } else {
1981
+ diff[key] = getArrayDiff( oldObj[key] || [], newObj[key] || [] );
1982
+ }
1983
+ }
1984
+ return diff;
1985
+ }, {} );
1986
+
1987
+ return difference;
1988
+ }
1655
1989
 
1656
1990
  export const updatePublish = async ( req, res ) => {
1657
1991
  try {
@@ -1727,11 +2061,29 @@ export const updatePublish = async ( req, res ) => {
1727
2061
 
1728
2062
 
1729
2063
  await checklistService.updateOne( query, getCheckDetails );
2064
+ let logObj = {
2065
+ client_id: req.body.clientId,
2066
+ createAt: new Date(),
2067
+ sourceCheckList_id: req.body.checklistId,
2068
+ checkListName: getCheckDetails.checkListName,
2069
+ fromCheckListName: '',
2070
+ type: 'checklist',
2071
+ action: req.body.publish ? 'published' : 'unpublished',
2072
+ storeName: '',
2073
+ store_id: '',
2074
+ createdByEmail: req.user.email,
2075
+ createdBy: req.user.userName,
2076
+ coverage: getCheckDetails.coverage,
2077
+ logDetails: {},
2078
+ userType: req.user.userType,
2079
+ };
2080
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
1730
2081
  if ( getCheckDetails.checkListType == 'custom' ) {
1731
2082
  let currentDate = dayjs.utc().format();
1732
2083
  let updatedscheduleEndTimeISO = dayjs.utc( getCheckDetails.scheduleEndTimeISO ).format( 'HH:mm:ss' );
1733
2084
  let newUpdatedDate = dayjs.utc( updatedscheduleEndTimeISO, 'HH:mm:ss' ).format();
1734
2085
 
2086
+
1735
2087
  if ( req.body.publish && req.body.publish == true ) {
1736
2088
  if ( newUpdatedDate > currentDate ) {
1737
2089
  let deleteQuery = {
@@ -2035,7 +2387,7 @@ export const validateUserv1 = async ( req, res ) => {
2035
2387
  }, {} );
2036
2388
 
2037
2389
  const duplicateUsers = Object.keys( duplicateUser ).filter( ( storeName ) => duplicateUser[storeName].count > 1 );
2038
- console.log( duplicateUsers, 'user' );
2390
+ // console.log( duplicateUsers, 'user' );
2039
2391
  if ( duplicateUsers.length ) {
2040
2392
  return res.sendError( { validate: false, duplicates: duplicateUsers, message: 'Email is Duplicated' }, 400 );
2041
2393
  }
@@ -3000,7 +3352,7 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
3000
3352
  if ( getCLconfig.coverage == 'store' ) {
3001
3353
  let clusterList = allQuestion.filter( ( ele ) => ele?.clusterName ).map( ( item ) => item.assignId );
3002
3354
  if ( clusterList.length ) {
3003
- let clusterDetails = await clusterServices.findcluster( { _id: { $in: clusterList } } );
3355
+ let clusterDetails = await clusterServices.findcluster( { _id: { $in: clusterList }, clientId: getCLconfig.client_id } );
3004
3356
  if ( clusterDetails.length ) {
3005
3357
  let idList = clusterDetails.flatMap( ( item ) => item.stores.map( ( ele ) => ele.store ) );
3006
3358
  let getStoreDetails = await storeService.find( { _id: { $in: idList }, status: 'active' } );
@@ -3067,7 +3419,7 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
3067
3419
  if ( getCLconfig.coverage == 'user' ) {
3068
3420
  let teamsList = allQuestion.filter( ( ele ) => ele?.teamName ).map( ( item ) => item.assignId );
3069
3421
  if ( teamsList.length ) {
3070
- let teamDetails = await teamsServices.findteams( { _id: { $in: teamsList } } );
3422
+ let teamDetails = await teamsServices.findteams( { _id: { $in: teamsList }, clientId: getCLconfig.client_id } );
3071
3423
  if ( teamDetails.length ) {
3072
3424
  let idList = [ ...teamDetails.flatMap( ( item ) => item.users.map( ( ele ) => ele.userId ) ), ...teamDetails.flatMap( ( item ) => item.Teamlead.map( ( ele ) => ele.userId ) ) ];
3073
3425
  let userIdList = allQuestion.filter( ( qn ) => !qn?.teamName ).map( ( qn ) => qn.assignId.toString() );
@@ -3184,7 +3536,7 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
3184
3536
  }
3185
3537
  if ( getsubmitDetails ) {
3186
3538
  getsubmitDetails = [ getsubmitDetails ];
3187
- console.log( submittedDetails, getsubmitDetails );
3539
+ // console.log( submittedDetails, getsubmitDetails );
3188
3540
  }
3189
3541
  function findDifferences( obj1, obj2 ) {
3190
3542
  return Object.keys( obj1 ).reduce( ( diff, key ) => {
@@ -3349,25 +3701,19 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
3349
3701
  }
3350
3702
  }
3351
3703
  } else {
3352
- let unAssignedList = assignUserList.reduce( ( acc, item ) => {
3353
- if ( !acc[item.userEmail] ) {
3354
- acc[item.userEmail]=[ item.store_id ];
3355
- } else {
3356
- acc[item.userEmail].push( item.store_id );
3357
- }
3358
- return acc;
3359
- }, {} );
3704
+ let deletedList = [];
3360
3705
 
3361
- let userList = Object.keys( unAssignedList );
3706
+ await processedchecklist.deleteMany( { date_string: insertdata.date_string,
3707
+ date_iso: insertdata.date_iso,
3708
+ client_id: insertdata.client_id,
3709
+ checkListId: updatedchecklist._id, checklistStatus: 'open' } );
3362
3710
 
3363
- await processedchecklist.deleteMany( { userEmail: { $nin: userList }, date_string: insertdata.date_string, date_iso: insertdata.date_iso, client_id: insertdata.client_id, checkListId: updatedchecklist._id, checklistStatus: { $nin: [ 'submit' ] } } );
3364
- if ( getCLconfig.coverage == 'store' ) {
3365
- for ( let key in unAssignedList ) {
3366
- if ( unAssignedList.hasOwnProperty( key ) ) {
3367
- await processedchecklist.deleteMany( { date_string: insertdata.date_string, date_iso: insertdata.date_iso, client_id: insertdata.client_id, checkListId: updatedchecklist._id, $and: [ { userEmail: key }, { store_id: { $nin: unAssignedList[key] } } ], checklistStatus: { $nin: [ 'submit' ] } } );
3368
- }
3369
- }
3370
- }
3711
+
3712
+ let actionType = 'deleteOpenUsers';
3713
+ let teamsMsg;
3714
+ let teamsAlertUrls = process.env.teamsAlertURL ? JSON.parse( process.env.teamsAlertURL ) : '';
3715
+ teamsMsg = 'ClientId: '+ insertdata.client_id + ', Action: '+ actionType + ', ChecklistId: '+ getCLconfig._id + ', Checklist Name: '+ getCLconfig.checkListName;
3716
+ sendTeamsNotification( teamsAlertUrls.checklist, teamsMsg );
3371
3717
 
3372
3718
  let inprogressData = await processedchecklist.find( {
3373
3719
  date_string: insertdata.date_string,
@@ -3378,6 +3724,12 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
3378
3724
  }, { userId: 1, store_id: 1 } );
3379
3725
 
3380
3726
  if ( inprogressData.length ) {
3727
+ inprogressData.forEach( ( item ) => {
3728
+ let checkData = assignUserList.find( ( ele ) => ele.userId.toString() == item.userId.toString() && ele.store_id == item.store_id );
3729
+ if ( !checkData ) {
3730
+ deletedList.push( item._id );
3731
+ }
3732
+ } );
3381
3733
  assignUserList = assignUserList.filter( ( item ) => {
3382
3734
  let findData = inprogressData.find( ( ele ) => ele.userId.toString() == item.userId.toString() && ele.store_id == item.store_id );
3383
3735
  if ( !findData ) {
@@ -3386,11 +3738,15 @@ async function insertPCBulkV4( getCLconfig, checklistId, currentdate, updatedche
3386
3738
  } );
3387
3739
  }
3388
3740
 
3389
- await processedchecklist.deleteMany( { date_string: insertdata.date_string,
3390
- date_iso: insertdata.date_iso,
3391
- client_id: insertdata.client_id,
3392
- checkListId: updatedchecklist._id, checklistStatus: 'open' } );
3741
+ if ( deletedList.length ) {
3742
+ await processedchecklist.deleteMany( { date_string: insertdata.date_string, date_iso: insertdata.date_iso, client_id: insertdata.client_id, checkListId: updatedchecklist._id, _id: { $in: deletedList } } );
3743
+ }
3393
3744
  await processedchecklist.insertMany( assignUserList );
3745
+ actionType = 'insertAssignUsers';
3746
+ teamsMsg;
3747
+ teamsAlertUrls = process.env.teamsAlertURL ? JSON.parse( process.env.teamsAlertURL ) : '';
3748
+ teamsMsg = 'ClientId: '+ insertdata.client_id + ', Action: '+ actionType + ', ChecklistId: '+ getCLconfig._id + ', Checklist Name: '+ getCLconfig.checkListName + ', assignedUserCount:'+ assignUserList.length+', inprogressSubmitCount:' + submittedDetails?.length;
3749
+ sendTeamsNotification( teamsAlertUrls.checklist, teamsMsg );
3394
3750
  }
3395
3751
 
3396
3752
  tokenList.forEach( ( item ) => {
@@ -3465,7 +3821,7 @@ async function updateOpenSearch( user, data ) {
3465
3821
  export const aiChecklist = async ( req, res ) => {
3466
3822
  try {
3467
3823
  let storeDetails = await storeService.count( { clientId: req.query.clientId, status: 'active' } );
3468
- let aiList = [ 'mobileusagedetection', 'storeopenandclose', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert', 'suspiciousfootfall', 'drinking', 'bagdetection' ];
3824
+ let aiList = [ 'mobileusagedetection', 'storeopenandclose', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'queuealert', 'cleaning', 'scrum', 'suspiciousactivity', 'boxalert', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo','vehicle_check_in' ];
3469
3825
  let checklistDetails = [];
3470
3826
  let publishList = [];
3471
3827
  let unpublishList = [];
@@ -3478,11 +3834,13 @@ export const aiChecklist = async ( req, res ) => {
3478
3834
  checklistDetails = [ ...publishList, ...unpublishList ];
3479
3835
 
3480
3836
  checklistDetails.forEach( ( item ) => {
3481
- if ( ![ 'mobileusagedetection', 'storeopenandclose', 'cleaning', 'scrum' ].includes( item.checkListType ) ) {
3837
+ if ( ![ 'mobileusagedetection', 'storeopenandclose', 'cleaning', 'scrum', 'uniformdetection', 'staffleftinthemiddle', 'customerunattended' ].includes( item.checkListType ) ) {
3482
3838
  item.storeCount = storeDetails;
3483
3839
  }
3484
3840
  } );
3485
3841
 
3842
+ checklistDetails.sort( ( a, b ) => a.checkListName.localeCompare( b.checkListName ) );
3843
+
3486
3844
  return res.sendSuccess( checklistDetails );
3487
3845
  } catch ( e ) {
3488
3846
  logger.error( 'aiChecklist =>', e );
@@ -3713,7 +4071,7 @@ export const selectAssign = async ( req, res ) => {
3713
4071
  }
3714
4072
  return res.sendSuccess( { 'totalCount': resuldData.length, 'data': resuldData } );
3715
4073
  } catch ( e ) {
3716
- console.log( 'e =>', e );
4074
+ // console.log( 'e =>', e );
3717
4075
  logger.error( 'selectAssign =>', e );
3718
4076
  return res.sendError( e, 500 );
3719
4077
  }
@@ -3725,7 +4083,9 @@ async function assignUsers( data ) {
3725
4083
  let clusterDetails = await clusterServices.findcluster( { clientId: data.clientId, _id: new mongoose.Types.ObjectId( data.id ) } );
3726
4084
  if ( clusterDetails.length ) {
3727
4085
  let clusterList = clusterDetails[0].stores.map( ( ele ) => ele.store );
4086
+ // console.log( clusterList );
3728
4087
  let storeDetails = await storeService.find( { _id: { $in: clusterList }, status: 'active' } );
4088
+ // console.log( storeDetails.length );
3729
4089
  assignedData = await Promise.all( storeDetails.map( async ( store ) => {
3730
4090
  let userData = {
3731
4091
  storeId: store.storeId,
@@ -3733,7 +4093,7 @@ async function assignUsers( data ) {
3733
4093
  userName: store.spocDetails?.[0]?.name,
3734
4094
  userEmail: store.spocDetails?.[0]?.email,
3735
4095
  clusterName: clusterDetails?.[0]?.clusterName,
3736
- id: clusterDetails?.[0]?._id,
4096
+ id: [ clusterDetails?.[0]?._id ],
3737
4097
  };
3738
4098
  return userData;
3739
4099
  } ) );
@@ -3748,7 +4108,7 @@ async function assignUsers( data ) {
3748
4108
  userName: user.userName,
3749
4109
  userEmail: user.email,
3750
4110
  teamName: teamDetails?.[0]?.teamName,
3751
- id: teamDetails?.[0]?._id,
4111
+ id: [ teamDetails?.[0]?._id ],
3752
4112
  };
3753
4113
  return userData;
3754
4114
  } );
@@ -3786,12 +4146,12 @@ export async function checklistAssign( req, res ) {
3786
4146
  uniqueArr.push( ...uploadData );
3787
4147
  }
3788
4148
  } ) );
3789
-
3790
4149
  if ( uniqueArr.length ) {
3791
4150
  if ( req.body.coverage == 'store' ) {
3792
4151
  uniqueArr = uniqueArr.reduce( ( acc, obj ) => {
3793
4152
  if ( acc[obj.storeName] ) {
3794
4153
  acc[obj.storeName].clusterName += ',' + obj.clusterName;
4154
+ acc[obj.storeName].id.push( ...obj.id );
3795
4155
  } else {
3796
4156
  acc[obj.storeName] = { ...obj };
3797
4157
  }
@@ -3803,6 +4163,7 @@ export async function checklistAssign( req, res ) {
3803
4163
  uniqueArr = uniqueArr.reduce( ( acc, obj ) => {
3804
4164
  if ( acc[obj.userEmail] ) {
3805
4165
  acc[obj.userEmail].teamName += ','+ obj.teamName;
4166
+ acc[obj.userEmail].id.push( ...obj.id );
3806
4167
  } else {
3807
4168
  acc[obj.userEmail] = { ...obj };
3808
4169
  }
@@ -3828,10 +4189,83 @@ export async function updateAssign( req, res ) {
3828
4189
  if ( !checklistDetails ) {
3829
4190
  return res.sendError( 'No data found', 204 );
3830
4191
  }
3831
- req.body.assignedGroup = [ ...new Set( req.body.assignedGroup.map( ( item ) => item.id ) ) ];
3832
- // req.body.assignedGroup = req.body.assignedGroup.map( ( ele ) => {
3833
- // return { id: ele };
3834
- // } );
4192
+ let groupList = [];
4193
+ let groupAssignList = req.body.assignedGroup;
4194
+ req.body.assignedGroup = [ ...new Set( req.body.assignedGroup.flatMap( ( item ) => item.id ) ) ];
4195
+
4196
+ groupAssignList.forEach( ( ele ) => {
4197
+ let gName;
4198
+ if ( ele?.clusterName ) {
4199
+ gName = ele.clusterName.split( ',' );
4200
+ }
4201
+ if ( ele?.teamName ) {
4202
+ gName = ele.teamName.split( ',' );
4203
+ }
4204
+ gName.forEach( ( name ) => {
4205
+ if ( !groupList.includes( name ) ) {
4206
+ groupList.push( name );
4207
+ }
4208
+ } );
4209
+ } );
4210
+
4211
+ let getAssignedDetails = await assignedService.find( { checkListId: req.body.checkListId } );
4212
+ let oldCoverage;
4213
+ if ( getAssignedDetails.length ) {
4214
+ oldCoverage = getAssignedDetails?.[0]?.coverage;
4215
+ let storeClusterDetails = getAssignedDetails.filter( ( ele ) => ele?.storeName || ele?.clusterName );
4216
+ let userTeamDetails = getAssignedDetails.filter( ( ele ) => !ele?.storeName && ( ele?.userName || ele?.teamName ) );
4217
+ storeClusterDetails = [ ...new Set( storeClusterDetails.map( ( ele ) => ele?.storeName || ele?.clusterName ) ) ];
4218
+ userTeamDetails= [ ...new Set( userTeamDetails.map( ( ele ) => ele?.userName || ele?.teamName ) ) ];
4219
+ getAssignedDetails = [ ...storeClusterDetails, ...userTeamDetails ];
4220
+ }
4221
+ let assignedAllList = [ ...req.body.assignedList, ...groupList ];
4222
+ let added = assignedAllList.filter( ( item ) => {
4223
+ let storeUsername;
4224
+ let clusterTeamName;
4225
+ if ( req.body.coverage == 'store' ) {
4226
+ if ( item?.storeName ) {
4227
+ storeUsername = item?.storeName;
4228
+ } else {
4229
+ clusterTeamName = item;
4230
+ }
4231
+ } else {
4232
+ if ( item?.userName ) {
4233
+ storeUsername = item?.userName;
4234
+ } else {
4235
+ clusterTeamName = item;
4236
+ }
4237
+ }
4238
+ if ( !getAssignedDetails.includes( storeUsername ) && !getAssignedDetails.includes( clusterTeamName ) ) {
4239
+ return item;
4240
+ }
4241
+ } ).map( ( ele ) => {
4242
+ if ( req.body.coverage == 'store' ) {
4243
+ return ele?.storeName || ele;
4244
+ } else {
4245
+ return ele?.userName || ele;
4246
+ }
4247
+ } );
4248
+ let removed = getAssignedDetails.filter( ( item ) => {
4249
+ let list;
4250
+ if ( req.body.coverage == 'store' ) {
4251
+ list = assignedAllList.map( ( item ) => item?.storeName );
4252
+ let clusterList = assignedAllList.filter( ( item ) => !item?.storeName );
4253
+ list = [ ...list, ...clusterList ];
4254
+ } else {
4255
+ list = assignedAllList.map( ( item ) => item.userName );
4256
+ let teamList = assignedAllList.filter( ( item ) => !item?.userName );
4257
+ list = [ ...list, ...teamList ];
4258
+ }
4259
+ if ( !list.includes( item ) ) {
4260
+ return item;
4261
+ }
4262
+ } );
4263
+ if ( getAssignedDetails.length ) {
4264
+ removed = { user: oldCoverage == 'user' ? removed : [], store: oldCoverage == 'store' ? removed : [] };
4265
+ } else {
4266
+ removed = { user: [], store: [] };
4267
+ }
4268
+
3835
4269
  await assignedService.deleteMany( { checkListId: req.body.checkListId } );
3836
4270
  let assignedUserList = [];
3837
4271
  let userEmailList = req.body.assignedList.map( ( ele ) => ele.userEmail.toLowerCase() );
@@ -3850,7 +4284,6 @@ export async function updateAssign( req, res ) {
3850
4284
  ];
3851
4285
  let assignUserDetails = await userService.aggregate( query );
3852
4286
  for ( let assign of req.body.assignedList ) {
3853
- // await Promise.all( req.body.assignedList.map( async ( assign ) => {
3854
4287
  let userDetails = assignUserDetails.find( ( ele ) => ele.email.toLowerCase() == assign.userEmail.toLowerCase() );
3855
4288
  if ( !userDetails ) {
3856
4289
  let userData = {
@@ -3860,11 +4293,10 @@ export async function updateAssign( req, res ) {
3860
4293
  clientId: req.body.clientId,
3861
4294
  };
3862
4295
  userDetails = await createUser( userData );
3863
- userDetails = userDetails;
4296
+ assignUserDetails.push( userDetails );
3864
4297
  }
3865
4298
  let data = {
3866
4299
  ...assign,
3867
- userEmail: userDetails?.email,
3868
4300
  store_id: assign?.storeId,
3869
4301
  client_id: req.body.clientId,
3870
4302
  checkListId: req.body.checkListId,
@@ -3875,7 +4307,6 @@ export async function updateAssign( req, res ) {
3875
4307
  };
3876
4308
  delete data._id;
3877
4309
  assignedUserList.push( data );
3878
- // } ) );
3879
4310
  }
3880
4311
  let assignGroupDetails = [];
3881
4312
  if ( req.body.coverage == 'store' ) {
@@ -3898,7 +4329,7 @@ export async function updateAssign( req, res ) {
3898
4329
  }
3899
4330
  } ) );
3900
4331
  await assignedService.insertMany( assignedUserList );
3901
- return res.sendSuccess( 'Assign details updated successfully' );
4332
+ return res.sendSuccess( { messgage: 'Assign details updated successfully', added, removed } );
3902
4333
  } catch ( e ) {
3903
4334
  logger.error( { functionName: 'updateAssign', error: e } );
3904
4335
  return res.sendError( e, 500 );
@@ -3928,8 +4359,7 @@ export async function updateAiConfigure( req, res ) {
3928
4359
  client_id: req.body.clientId,
3929
4360
  publish: req.body.publish,
3930
4361
  aiConfig: req.body.aiConfig,
3931
- createdBy: req.user._id,
3932
- createdByName: req.user.userName,
4362
+ ...( !req.body?.id ) ? { createdBy: req.user._id, createdByName: req.user.userName } : {},
3933
4363
  questionCount: 0,
3934
4364
  storeCount: req.body.storeList.length,
3935
4365
  type: 'checklist',
@@ -3945,6 +4375,29 @@ export async function updateAiConfigure( req, res ) {
3945
4375
  };
3946
4376
  let aiResponse = await checklistService.updateOne( { checkListType: aiChecklistDetails.checkListType, client_id: req.body.clientId }, details );
3947
4377
  let checklistId = req.body?.id || aiResponse?.upsertedId;
4378
+ if ( req.body?.approver ) {
4379
+ let data = [];
4380
+ let existEmail = await traxApprover.find( { checkListId: checklistId, isDeleted: false } );
4381
+ let mailList = existEmail.map( ( item ) => item.userEmail );
4382
+ existEmail = req.body?.approver.filter( ( item ) => mailList.includes( item.value ) ).map( ( item ) => item.value );
4383
+ let userMailList = req.body?.approver.map( ( ele ) => ele.value );
4384
+ req.body?.approver.forEach( ( ele ) => {
4385
+ if ( !existEmail.includes( ele.value ) ) {
4386
+ data.push( {
4387
+ userEmail: ele.value,
4388
+ checkListId: checklistId,
4389
+ type: 'checklist',
4390
+ checkListName: aiChecklistDetails.checkListName,
4391
+ client_id: req.body.clientId,
4392
+ } );
4393
+ }
4394
+ } );
4395
+
4396
+ await traxApprover.updateMany( { checkListId: checklistId, userEmail: { $nin: userMailList } }, { isDeleted: true } );
4397
+ if ( data.length ) {
4398
+ await traxApprover.insertMany( data );
4399
+ }
4400
+ }
3948
4401
  if ( req.body.storeList ) {
3949
4402
  let storeData = [];
3950
4403
  req.body.storeList.forEach( ( ele ) => {
@@ -4034,6 +4487,7 @@ export async function updateAiConfigure( req, res ) {
4034
4487
  scheduleRepeatedType: 'daily',
4035
4488
  client_id: req.body.clientId,
4036
4489
  aiStoreList: storeData?.length ? storeData.map( ( store ) => store.store_id ) : [],
4490
+ approvalEnable: req.body?.approver.length ? true : false,
4037
4491
  };
4038
4492
  await processedchecklist.updateOne( { date_string: dayjs().format( 'YYYY-MM-DD' ), sourceCheckList_id: checklistId, checkListType: aiChecklistDetails.checkListType }, data );
4039
4493
  }