tango-app-api-trax 3.4.1-beta-2 → 3.5.0-alpha-0

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 ) => {
@@ -3719,7 +4071,7 @@ export const selectAssign = async ( req, res ) => {
3719
4071
  }
3720
4072
  return res.sendSuccess( { 'totalCount': resuldData.length, 'data': resuldData } );
3721
4073
  } catch ( e ) {
3722
- console.log( 'e =>', e );
4074
+ // console.log( 'e =>', e );
3723
4075
  logger.error( 'selectAssign =>', e );
3724
4076
  return res.sendError( e, 500 );
3725
4077
  }
@@ -3731,7 +4083,9 @@ async function assignUsers( data ) {
3731
4083
  let clusterDetails = await clusterServices.findcluster( { clientId: data.clientId, _id: new mongoose.Types.ObjectId( data.id ) } );
3732
4084
  if ( clusterDetails.length ) {
3733
4085
  let clusterList = clusterDetails[0].stores.map( ( ele ) => ele.store );
4086
+ // console.log( clusterList );
3734
4087
  let storeDetails = await storeService.find( { _id: { $in: clusterList }, status: 'active' } );
4088
+ // console.log( storeDetails.length );
3735
4089
  assignedData = await Promise.all( storeDetails.map( async ( store ) => {
3736
4090
  let userData = {
3737
4091
  storeId: store.storeId,
@@ -3739,7 +4093,7 @@ async function assignUsers( data ) {
3739
4093
  userName: store.spocDetails?.[0]?.name,
3740
4094
  userEmail: store.spocDetails?.[0]?.email,
3741
4095
  clusterName: clusterDetails?.[0]?.clusterName,
3742
- id: clusterDetails?.[0]?._id,
4096
+ id: [ clusterDetails?.[0]?._id ],
3743
4097
  };
3744
4098
  return userData;
3745
4099
  } ) );
@@ -3754,7 +4108,7 @@ async function assignUsers( data ) {
3754
4108
  userName: user.userName,
3755
4109
  userEmail: user.email,
3756
4110
  teamName: teamDetails?.[0]?.teamName,
3757
- id: teamDetails?.[0]?._id,
4111
+ id: [ teamDetails?.[0]?._id ],
3758
4112
  };
3759
4113
  return userData;
3760
4114
  } );
@@ -3792,12 +4146,12 @@ export async function checklistAssign( req, res ) {
3792
4146
  uniqueArr.push( ...uploadData );
3793
4147
  }
3794
4148
  } ) );
3795
-
3796
4149
  if ( uniqueArr.length ) {
3797
4150
  if ( req.body.coverage == 'store' ) {
3798
4151
  uniqueArr = uniqueArr.reduce( ( acc, obj ) => {
3799
4152
  if ( acc[obj.storeName] ) {
3800
4153
  acc[obj.storeName].clusterName += ',' + obj.clusterName;
4154
+ acc[obj.storeName].id.push( ...obj.id );
3801
4155
  } else {
3802
4156
  acc[obj.storeName] = { ...obj };
3803
4157
  }
@@ -3809,6 +4163,7 @@ export async function checklistAssign( req, res ) {
3809
4163
  uniqueArr = uniqueArr.reduce( ( acc, obj ) => {
3810
4164
  if ( acc[obj.userEmail] ) {
3811
4165
  acc[obj.userEmail].teamName += ','+ obj.teamName;
4166
+ acc[obj.userEmail].id.push( ...obj.id );
3812
4167
  } else {
3813
4168
  acc[obj.userEmail] = { ...obj };
3814
4169
  }
@@ -3834,10 +4189,83 @@ export async function updateAssign( req, res ) {
3834
4189
  if ( !checklistDetails ) {
3835
4190
  return res.sendError( 'No data found', 204 );
3836
4191
  }
3837
- req.body.assignedGroup = [ ...new Set( req.body.assignedGroup.map( ( item ) => item.id ) ) ];
3838
- // req.body.assignedGroup = req.body.assignedGroup.map( ( ele ) => {
3839
- // return { id: ele };
3840
- // } );
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
+
3841
4269
  await assignedService.deleteMany( { checkListId: req.body.checkListId } );
3842
4270
  let assignedUserList = [];
3843
4271
  let userEmailList = req.body.assignedList.map( ( ele ) => ele.userEmail.toLowerCase() );
@@ -3856,7 +4284,6 @@ export async function updateAssign( req, res ) {
3856
4284
  ];
3857
4285
  let assignUserDetails = await userService.aggregate( query );
3858
4286
  for ( let assign of req.body.assignedList ) {
3859
- // await Promise.all( req.body.assignedList.map( async ( assign ) => {
3860
4287
  let userDetails = assignUserDetails.find( ( ele ) => ele.email.toLowerCase() == assign.userEmail.toLowerCase() );
3861
4288
  if ( !userDetails ) {
3862
4289
  let userData = {
@@ -3866,11 +4293,10 @@ export async function updateAssign( req, res ) {
3866
4293
  clientId: req.body.clientId,
3867
4294
  };
3868
4295
  userDetails = await createUser( userData );
3869
- userDetails = userDetails;
4296
+ assignUserDetails.push( userDetails );
3870
4297
  }
3871
4298
  let data = {
3872
4299
  ...assign,
3873
- userEmail: userDetails?.email,
3874
4300
  store_id: assign?.storeId,
3875
4301
  client_id: req.body.clientId,
3876
4302
  checkListId: req.body.checkListId,
@@ -3881,7 +4307,6 @@ export async function updateAssign( req, res ) {
3881
4307
  };
3882
4308
  delete data._id;
3883
4309
  assignedUserList.push( data );
3884
- // } ) );
3885
4310
  }
3886
4311
  let assignGroupDetails = [];
3887
4312
  if ( req.body.coverage == 'store' ) {
@@ -3904,7 +4329,7 @@ export async function updateAssign( req, res ) {
3904
4329
  }
3905
4330
  } ) );
3906
4331
  await assignedService.insertMany( assignedUserList );
3907
- return res.sendSuccess( 'Assign details updated successfully' );
4332
+ return res.sendSuccess( { messgage: 'Assign details updated successfully', added, removed } );
3908
4333
  } catch ( e ) {
3909
4334
  logger.error( { functionName: 'updateAssign', error: e } );
3910
4335
  return res.sendError( e, 500 );