tango-app-api-trax 3.4.0-alpha-5 → 3.4.0-beta-1

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 { fileUpload, chunkArray, logger, sendPushNotification } from 'tango-app-api-middleware';
1
+ import { fileUpload, chunkArray, logger, sendPushNotification, 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';
@@ -190,7 +190,7 @@ export const create = async ( req, res ) => {
190
190
  checkListDescription: inputBody.checklistDescription,
191
191
  createdBy: req.user._id,
192
192
  createdByName: req.user.userName,
193
- questionCount: questionCount,
193
+ // questionCount: questionCount,
194
194
  client_id: req.body?.clientId,
195
195
  owner: req.user.userType == 'client' ? [ { name: req.user.userName, value: req.user.email } ] : [],
196
196
  // configStartDate:new Date(),
@@ -282,20 +282,38 @@ export const create = async ( req, res ) => {
282
282
  } );
283
283
 
284
284
  if ( checkNestedLevel ) {
285
- return res.sendError( { message: 'Unable to create more than 20 linked questions.' }, 400 );
285
+ await checklistService.deleteOne( { _id: checkListId } );
286
+ return res.sendError( { message: `This ${section.name} contains more than 20 nested linked questions` }, 400 );
286
287
  }
287
288
 
288
289
  let sectionList = {
289
290
  section: section.name,
290
291
  createdBy: req.user._id,
291
292
  createdByName: req.user.userName,
292
- client_id: req.body.clientId,
293
+ client_id: inputBody.clientId,
293
294
  checkListId: checkListId,
294
295
  question: section.questions,
295
296
  checkList: inputBody.checklistName,
296
297
  };
297
298
  await questionService.create( sectionList ).then( async ( data ) => {
298
299
  if ( i == inputBody.sections.length - 1 ) {
300
+ await checklistService.updateOne( { _id: checkListId }, { questionCount: questionCount } );
301
+ let logObj = {
302
+ client_id: inputBody.clientId,
303
+ createAt: new Date(),
304
+ sourceCheckList_id: checkListId,
305
+ checkListName: inputBody.checklistName,
306
+ fromCheckListName: '',
307
+ type: 'checklist',
308
+ action: 'created',
309
+ storeName: '',
310
+ store_id: '',
311
+ createdByEmail: req.user.email,
312
+ createdBy: req.user.userName,
313
+ coverage: 'store',
314
+ logDetails: {},
315
+ };
316
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
299
317
  return res.sendSuccess( { checklistId: checkListId, msg: 'CheckList Created Successfully' } );
300
318
  }
301
319
  } ).catch( ( e ) => {
@@ -309,7 +327,6 @@ export const create = async ( req, res ) => {
309
327
  }
310
328
  }
311
329
  } ).catch( async ( e ) => {
312
- console.log( e );
313
330
  await checklistService.deleteOne( { _id: checkListId } );
314
331
  return res.sendError( e, 500 );
315
332
  } );
@@ -621,6 +638,22 @@ export const deleteChecklist = async ( req, res ) => {
621
638
  await processedchecklist.deleteMany( { date_string: { $ne: date }, date_iso: { $gt: date }, sourceCheckList_id: req.params.checklistId, checklistStatus: { $ne: 'submit' } } );
622
639
  logger.info( { function: 'deleteChecklist', query: { date_string: { $ne: date }, date_iso: { $gt: date }, sourceCheckList_id: req.params.checklistId, checklistStatus: { $ne: 'submit' } } } );
623
640
  checklistDetails.save().then( () => {
641
+ let logObj = {
642
+ client_id: checklistDetails.client_id,
643
+ createAt: new Date(),
644
+ sourceCheckList_id: checklistDetails._id,
645
+ checkListName: checklistDetails.checkListName,
646
+ fromCheckListName: '',
647
+ type: 'checklist',
648
+ action: 'deleted',
649
+ storeName: '',
650
+ store_id: '',
651
+ createdByEmail: req.user.email,
652
+ createdBy: req.user.userName,
653
+ coverage: checklistDetails.coverage,
654
+ logDetails: {},
655
+ };
656
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
624
657
  return res.sendSuccess( { message: 'Checklist Deleted Successfully' } );
625
658
  } ).catch( ( e ) => {
626
659
  return res.sendError( e, 500 );
@@ -694,6 +727,22 @@ export const duplicateChecklist = async ( req, res ) => {
694
727
  sections.push( sectionDetails );
695
728
  }
696
729
  await questionService.insertMany( sections );
730
+ let logObj = {
731
+ client_id: checkDetails.client_id,
732
+ createAt: new Date(),
733
+ sourceCheckList_id: checkDetails._id,
734
+ checkListName: checkDetails.checkListName,
735
+ fromCheckListName: '',
736
+ type: 'checklist',
737
+ action: 'duplicated',
738
+ storeName: '',
739
+ store_id: '',
740
+ createdByEmail: req.user.email,
741
+ createdBy: req.user.userName,
742
+ coverage: checkDetails.coverage,
743
+ logDetails: {},
744
+ };
745
+ insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
697
746
  return res.sendSuccess( { message: 'CheckList Duplicated Successfully' } );
698
747
  } else {
699
748
  return res.sendSuccess( { message: 'duplicated Successfully' } );
@@ -730,6 +779,8 @@ export const update = async ( req, res ) => {
730
779
  return res.sendError( 'no data found', 204 );
731
780
  }
732
781
 
782
+ let getExistQuestions = await questionService.find( { checkListId: req.params.checklistId, client_id: req.body.clientId } );
783
+
733
784
  inputBody.sections.forEach( async ( element ) => {
734
785
  if ( !element.questions.length && inputBody.submitType == 'configure' ) {
735
786
  return res.sendError( { message: 'Question is Required' }, 400 );
@@ -740,131 +791,225 @@ export const update = async ( req, res ) => {
740
791
  }
741
792
  } );
742
793
 
743
- checkListDetails.checkListName = inputBody.checklistName;
744
- checkListDetails.checkListDescription = inputBody.checklistDescription;
745
- checkListDetails.questionCount = questionCount;
794
+ let params = {
795
+ checkListName: inputBody.checklistName,
796
+ checkListDescription: inputBody.checklistDescription,
797
+ questionCount: questionCount,
798
+ };
746
799
 
747
- checkListDetails.save().then( async () => {
748
- let checkListId = req.params.checklistId;
749
- let logInsertData = {
750
- action: 'checklistUpdate',
751
- checklistId: checkListId,
752
- checkListName: inputBody.checklistName,
753
- createdBy: req.user._id,
754
- createdByName: req.user.userName,
755
- client_id: req.body.clientId,
756
- sections: inputBody?.sections,
757
- createdByEmail: req.user.email,
758
- };
759
- await checklistLogs.create( logInsertData );
760
- if ( inputBody.sections.length ) {
761
- let sectionId =[];
762
- for ( let i = 0; i < inputBody?.sections?.length; i++ ) {
763
- let section = inputBody.sections[i];
764
- section.questions.forEach( ( section ) => {
765
- if ( section.questionReferenceImage && section.questionReferenceImage !='' ) {
766
- let imgUrl = section.questionReferenceImage.split( '?' )[0];
800
+ await checklistService.updateOne( { _id: req.params.checklistId }, params );
801
+ let checkListId = req.params.checklistId;
802
+ let logInsertData = {
803
+ action: 'checklistUpdate',
804
+ checklistId: checkListId,
805
+ checkListName: inputBody.checklistName,
806
+ createdBy: req.user._id,
807
+ createdByName: req.user.userName,
808
+ client_id: req.body.clientId,
809
+ sections: inputBody?.sections,
810
+ createdByEmail: req.user.email,
811
+ };
812
+ await checklistLogs.create( logInsertData );
813
+ let sectionList =[];
814
+ if ( inputBody.sections.length ) {
815
+ for ( let i = 0; i < inputBody?.sections?.length; i++ ) {
816
+ let section = inputBody.sections[i];
817
+ section.questions.forEach( ( section ) => {
818
+ if ( section.questionReferenceImage && section.questionReferenceImage !='' ) {
819
+ let imgUrl = section.questionReferenceImage.split( '?' )[0];
820
+ let url = imgUrl.split( '/' );
821
+ url.splice( 0, 3 );
822
+ section.questionReferenceImage = url.join( '/' );
823
+ }
824
+ section.answers.forEach( ( answer ) => {
825
+ if ( answer.referenceImage != '' ) {
826
+ let imgUrl = answer.referenceImage.split( '?' )[0];
767
827
  let url = imgUrl.split( '/' );
768
828
  url.splice( 0, 3 );
769
- section.questionReferenceImage = url.join( '/' );
829
+ answer.referenceImage = url.join( '/' );
770
830
  }
771
- // if (['image', 'descriptiveImage'].includes(section.answerType)) {
772
- section.answers.forEach( ( answer ) => {
773
- if ( answer.referenceImage != '' ) {
774
- let imgUrl = answer.referenceImage.split( '?' )[0];
775
- let url = imgUrl.split( '/' );
776
- url.splice( 0, 3 );
777
- answer.referenceImage = url.join( '/' );
778
- }
779
- } );
780
- // }
781
831
  } );
832
+ } );
782
833
 
783
- for ( let [ index, question ] of section.questions.entries() ) {
784
- await processNested( index, question );
785
- }
834
+ for ( let [ index, question ] of section.questions.entries() ) {
835
+ await processNested( index, question );
836
+ }
786
837
 
787
- async function processNested( qIdx, question, nestedIndex=-1 ) {
788
- if ( question?.answers?.length ) {
789
- for ( let [ index, answer ] of question?.answers?.entries() ) {
790
- if ( !section.questions[qIdx].answers[index]?.nestedQuestion && nestedIndex == -1 ) {
791
- section.questions[qIdx].answers[index].nestedQuestion = [];
838
+ async function processNested( qIdx, question, nestedIndex=-1 ) {
839
+ if ( question?.answers?.length ) {
840
+ for ( let [ index, answer ] of question?.answers?.entries() ) {
841
+ if ( !section.questions[qIdx].answers[index]?.nestedQuestion && nestedIndex == -1 ) {
842
+ section.questions[qIdx].answers[index].nestedQuestion = [];
843
+ }
844
+ if ( answer.showLinked ) {
845
+ // section.questions[qIdx].answers[nestedIndex].nestedQuestion.push( answer.linkedQuestion );
846
+ if ( nestedIndex != -1 ) {
847
+ // if ( !section.questions[qIdx].answers[nestedIndex].nestedQuestion.includes( answer.linkedQuestion ) ) {
848
+ section.questions[qIdx].answers[nestedIndex].nestedQuestion.push( answer.linkedQuestion );
849
+ // }
850
+ } else {
851
+ // if ( !section.questions[qIdx].answers[index].nestedQuestion.includes( answer.linkedQuestion ) ) {
852
+ section.questions[qIdx].answers[index].nestedQuestion.push( answer.linkedQuestion );
853
+ // }
792
854
  }
793
- if ( answer.showLinked ) {
794
- if ( nestedIndex != -1 ) {
795
- // if ( !section.questions[qIdx].answers[nestedIndex].nestedQuestion.includes( answer.linkedQuestion ) ) {
796
- section.questions[qIdx].answers[nestedIndex].nestedQuestion.push( answer.linkedQuestion );
797
- // }
798
- } else {
799
- // if ( !section.questions[qIdx].answers[index].nestedQuestion.includes( answer.linkedQuestion ) ) {
800
- section.questions[qIdx].answers[index].nestedQuestion.push( answer.linkedQuestion );
801
- // }
802
- }
803
- let nestedLinkedQuestion = section.questions.find( ( item ) => item.qno == answer.linkedQuestion );
804
- if ( nestedLinkedQuestion ) {
805
- let findNestedAnswers = nestedLinkedQuestion.answers.find( ( item ) => item.showLinked );
806
- if ( findNestedAnswers ) {
807
- if ( nestedIndex != -1 ) {
808
- await processNested( qIdx, nestedLinkedQuestion, nestedIndex );
809
- } else {
810
- await processNested( qIdx, nestedLinkedQuestion, index );
811
- }
855
+ let nestedLinkedQuestion = section.questions.find( ( item ) => item.qno == answer.linkedQuestion );
856
+ if ( nestedLinkedQuestion ) {
857
+ let findNestedAnswers = nestedLinkedQuestion.answers.find( ( item ) => item.showLinked );
858
+ if ( findNestedAnswers ) {
859
+ if ( nestedIndex != -1 ) {
860
+ await processNested( qIdx, nestedLinkedQuestion, nestedIndex );
861
+ } else {
862
+ await processNested( qIdx, nestedLinkedQuestion, index );
812
863
  }
813
864
  }
814
865
  }
815
866
  }
816
867
  }
817
868
  }
869
+ }
818
870
 
819
- let checkNestedLevel = false;
820
- section.questions.forEach( ( qns ) => {
821
- qns.answers.forEach( ( answ ) => {
822
- if ( answ.nestedQuestion.length > 20 ) {
823
- checkNestedLevel = true;
824
- }
825
- } );
871
+ let checkNestedLevel = false;
872
+ section.questions.forEach( ( qns ) => {
873
+ qns.answers.forEach( ( answ ) => {
874
+ if ( answ.nestedQuestion.length > 20 ) {
875
+ checkNestedLevel = true;
876
+ }
826
877
  } );
878
+ } );
827
879
 
828
- console.log( checkNestedLevel, 'lebej' );
880
+ if ( checkNestedLevel ) {
881
+ return res.sendError( { message: `This ${section.name} contains more than 20 nested linked questions` }, 400 );
882
+ }
829
883
 
830
- if ( checkNestedLevel ) {
831
- return res.sendError( { message: 'Unable to create more than 20 linked questions' }, 400 );
832
- }
884
+ sectionList.push( {
885
+ section: section.name,
886
+ sectionOldName: section.oldName,
887
+ createdBy: req.user._id,
888
+ createdByName: req.user.userName,
889
+ client_id: req.body.clientId,
890
+ checkListId: checkListId,
891
+ question: section.questions,
892
+ checkList: inputBody.checklistName,
893
+ } );
894
+ }
895
+ }
896
+ await questionService.deleteMany( { checkListId: checkListId, client_id: req.body.clientId } );
897
+ if ( sectionList.length ) {
898
+ await questionService.insertMany( sectionList );
899
+ }
833
900
 
834
- let sectionList = {
835
- section: section.name,
836
- sectionOldName: section.oldName,
837
- createdBy: req.user._id,
838
- createdByName: req.user.userName,
839
- client_id: req.body.clientId,
840
- checkListId: checkListId,
841
- question: section.questions,
842
- checkList: inputBody.checklistName,
843
- };
844
- await questionService.create( sectionList ).then( async ( data ) => {
845
- sectionId.push( data._id );
846
- if ( i == inputBody.sections.length - 1 ) {
847
- await questionService.deleteMany( { checkListId: checkListId, client_id: req.body.clientId, _id: { $nin: sectionId } } );
848
- await assignedService.updateMany( { checkListId: checkListId }, { checkListName: inputBody.checklistName } );
849
- return res.sendSuccess( { checklistId: checkListId, msg: 'CheckList Created Successfully' } );
850
- }
851
- } ).catch( ( e ) => {
852
- return res.sendError( e, 500 );
853
- } );
901
+ let questionList = {
902
+ questionAdd: [],
903
+ questionEdit: [],
904
+ questionDelete: [],
905
+ };
906
+ let updateSection = [];
907
+
908
+ function findDifferences( obj1, obj2 ) {
909
+ return Object.keys( obj1 ).reduce( ( diff, key ) => {
910
+ if ( !isEqual( obj1[key], obj2[key] ) ) {
911
+ diff[key] = { previous: obj1[key], new: obj2[key] };
854
912
  }
855
- } else {
856
- if ( inputBody.submitType == 'save' ) {
857
- await questionService.deleteMany( { checkListId: checkListId, client_id: req.body.clientId } );
858
- return res.sendSuccess( { message: 'CheckList Updated Successfully' } );
913
+ return diff;
914
+ }, {} );
915
+ }
916
+
917
+ getExistQuestions.forEach( ( ele ) => {
918
+ let sectionDetails = inputBody.sections.find( ( sec ) => sec.oldName === ele.section );
919
+
920
+ if ( !sectionDetails ) {
921
+ questionList.questionDelete.push( { sectionName: ele.section, questions: ele.question } );
922
+ return;
923
+ }
924
+
925
+ if ( ele.section !== sectionDetails.name ) {
926
+ updateSection.push( { previous: ele.section, new: sectionDetails.name } );
927
+ }
928
+
929
+ ele.question.forEach( ( qn ) => {
930
+ let question = sectionDetails.questions.find( ( qns ) => qns.oldQname === qn.qname );
931
+
932
+ if ( question ) {
933
+ qn.answers.forEach( ( ans ) => {
934
+ delete ans.answeroptionNumber;
935
+ } );
936
+ question.answers.forEach( ( ans ) => {
937
+ delete ans.answeroptionNumber;
938
+ } );
939
+ let compare = findDifferences( qn, question );
940
+ if ( Object.keys( compare ).length && ( compare?.answerType || compare?.answers || compare?.linkType || compare?.qname ) ) {
941
+ questionList.questionEdit.push( { sectionName: ele.section, questions: [ { previous: qn, new: question } ] } );
942
+ }
943
+ } else {
944
+ let sectionIndex = questionList.questionDelete.findIndex( ( sec ) => sec.sectionName === ele.section );
945
+
946
+ if ( sectionIndex !== -1 ) {
947
+ questionList.questionDelete[sectionIndex].questions.push( qn );
948
+ } else {
949
+ questionList.questionDelete.push( { sectionName: ele.section, questions: [ qn ] } );
950
+ }
859
951
  }
952
+ } );
953
+ } );
954
+
955
+ inputBody.sections.forEach( ( ele ) => {
956
+ let sectionDetails = getExistQuestions.find( ( sec ) => sec.section === ele.oldName );
957
+
958
+ if ( !sectionDetails ) {
959
+ questionList.questionAdd.push( { sectionName: ele.name, questions: ele.questions } );
960
+ return;
860
961
  }
861
- } ).catch( ( e ) => {
862
- logger.error( 'update =>', e );
863
- return res.sendError( e, 500 );
962
+
963
+ ele.questions.forEach( ( qn ) => {
964
+ let question = sectionDetails.question.find( ( qns ) => qns.qname === qn.oldQname );
965
+
966
+ if ( !question ) {
967
+ let sectionIndex = questionList.questionAdd.findIndex( ( sec ) => sec.sectionName === ele.name );
968
+
969
+ if ( sectionIndex !== -1 ) {
970
+ questionList.questionAdd[sectionIndex].questions.push( qn );
971
+ } else {
972
+ questionList.questionAdd.push( { sectionName: ele.name, questions: [ qn ] } );
973
+ }
974
+ }
975
+ } );
864
976
  } );
977
+
978
+ if ( updateSection.length || questionList.questionAdd.length || questionList.questionEdit.length || questionList.questionDelete.length || inputBody.checklistName.toLowerCase() != checkListDetails.checkListName.toLowerCase() || inputBody.checklistDescription.toLowerCase() != checkListDetails.checkListDescription.toLowerCase() ) {
979
+ let insertLogData = {
980
+ client_id: req.body.clientId,
981
+ createAt: new Date(),
982
+ sourceCheckList_id: req.params.checklistId,
983
+ checkListName: inputBody.checklistName,
984
+ fromCheckListName: '',
985
+ type: 'checklist',
986
+ action: 'edited',
987
+ storeName: '',
988
+ store_id: '',
989
+ createdByEmail: req.user.email,
990
+ createdBy: req.user.userName,
991
+ coverage: checkListDetails.coverage,
992
+ logDetails: {
993
+ ...( inputBody.checklistName.toLowerCase() == checkListDetails.checkListName.toLowerCase() ) ? { updatedChecklistName: {} } :{ updatedChecklistName: {
994
+ previous: checkListDetails.checkListName,
995
+ new: inputBody.checklistName,
996
+ } },
997
+ ...( inputBody.checklistDescription.toLowerCase() == checkListDetails.checkListDescription.toLowerCase() ) ? { updatedChecklistDescription: {} } :{ updatedChecklistDescription: {
998
+ previous: checkListDetails.checkListDescription,
999
+ new: inputBody.checklistDescription,
1000
+ } },
1001
+ updatedSectionName: updateSection,
1002
+ questionAdd: questionList.questionAdd,
1003
+ questionEdit: questionList.questionEdit,
1004
+ questionDelete: questionList.questionDelete,
1005
+ },
1006
+ };
1007
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, insertLogData );
1008
+ }
1009
+ return res.sendSuccess( { message: 'CheckList Updated Successfully', checklistId: req.params.checklistId } );
865
1010
  } catch ( e ) {
866
- logger.error( 'update =>', e );
867
- return res.sendError( e, 500 );
1011
+ logger.error( { functionName: 'questionUpdate', error: e } );
1012
+ res.sendError( e, 500 );
868
1013
  }
869
1014
  };
870
1015
 
@@ -1465,6 +1610,10 @@ export const updateConfigurev1 =async ( req, res ) => {
1465
1610
  }
1466
1611
  }
1467
1612
 
1613
+ if ( !inputBody.checkListDetails.sections[0].questions.length && inputBody.submitType == 'publish' ) {
1614
+ return res.sendError( 'Please add a question', 400 );
1615
+ }
1616
+
1468
1617
  if ( !inputBody.checkListDetails.assignedUsers.length && inputBody.submitType == 'publish' ) {
1469
1618
  return res.sendError( 'Please Assigned a user', 400 );
1470
1619
  }
@@ -1499,8 +1648,9 @@ export const updateConfigurev1 =async ( req, res ) => {
1499
1648
  if ( inputBody.timeZone ) {
1500
1649
  currentDate = dayjs().tz( inputBody.timeZone ).format();
1501
1650
  } else {
1502
- currentDate = dayjs().format();
1651
+ currentDate = dayjs().format( 'HH:mm:ss' );
1503
1652
  }
1653
+ currentDate = dayjs.utc( currentDate, 'HH:mm:ss' ).format();
1504
1654
  let updatedscheduleEndTimeISO = dayjs.utc( inputBody?.checkListDetails?.scheduleEndTime, 'hh:mm A' ).format( 'HH:mm:ss' );
1505
1655
  let newUpdatedDate = dayjs.utc( updatedscheduleEndTimeISO, 'HH:mm:ss' ).format();
1506
1656
 
@@ -1643,6 +1793,109 @@ export const updateConfigurev1 =async ( req, res ) => {
1643
1793
  futureDaysDataRemove( currentDate, req.params.checklistId, checklistDetails.checkListName, '333' );
1644
1794
  }
1645
1795
  }
1796
+ checklistDetails = checklistDetails.toObject();
1797
+ checklistDetails.configStartDate = checklistDetails.configStartDate ? dayjs.utc( checklistDetails?.configStartDate ).format( 'YYYY-MM-DD' ) : '';
1798
+ checklistDetails.configEndDate = checklistDetails.configEndDate ? dayjs.utc( checklistDetails?.configEndDate ).format( 'YYYY-MM-DD' ) : '';
1799
+ checklistDetails.scheduleDate = checklistDetails.scheduleDate ? dayjs.utc( checklistDetails?.scheduleDate ).format( 'YYYY-MM-DD' ) : '';
1800
+ checklistDetails.scheduleRepeatedDay = Array.isArray( checklistDetails.scheduleRepeatedDay ) ? checklistDetails.scheduleRepeatedDay[0] : checklistDetails.scheduleRepeatedDay;
1801
+ configDetails.scheduleRepeatedDay = Array.isArray( configDetails.scheduleRepeatedDay ) ? configDetails?.scheduleRepeatedDay[0] : configDetails?.scheduleRepeatedDay;
1802
+ configDetails.scheduleDate = configDetails.scheduleDate ? dayjs( configDetails?.scheduleDate ).format( 'YYYY-MM-DD' ) : '';
1803
+ let removedKeys = [ 'publish', 'publishDate', 'storeCount', 'sections', 'createdAt', 'updatedAt', 'scheduleStartTimeISO', 'scheduleEndTimeISO' ];
1804
+ removedKeys.forEach( ( item ) => {
1805
+ delete configDetails?.[item];
1806
+ delete checklistDetails?.[item];
1807
+ } );
1808
+ let differences = findObjectDifference( checklistDetails, configDetails );
1809
+ if ( Object.keys( differences ).length || req.body.added.length || req.body.removed.length ) {
1810
+ let insertData = {
1811
+ client_id: req.body.clientId,
1812
+ createAt: new Date(),
1813
+ sourceCheckList_id: configDetails._id,
1814
+ checkListName: configDetails.checkListName,
1815
+ fromCheckListName: '',
1816
+ type: 'checklist',
1817
+ action: inputBody.checkListDetails.publish ? 'updated' : 'draft',
1818
+ storeName: '',
1819
+ store_id: '',
1820
+ createdByEmail: req.user.email,
1821
+ createdBy: req.user.userName,
1822
+ coverage: configDetails.coverage,
1823
+ logDetails: {
1824
+ schedule: {
1825
+ previous: {
1826
+ ...( differences?.scheduleDate && ( differences?.scheduleDate.previous != '' && differences?.scheduleDate.previous != null ) ) ? { scheduleDate: dayjs( checklistDetails?.scheduleDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1827
+ schedule: differences?.schedule ? checklistDetails.schedule : '',
1828
+ time: ( ( differences?.scheduleEndTime || differences?.scheduleStartTime ) && ( checklistDetails.scheduleStartTime != '' || checklistDetails.scheduleEndTime != '' ) ) ? checklistDetails.scheduleStartTime + ' to ' + checklistDetails.scheduleEndTime : '',
1829
+ scheduleRepeatedDay: differences?.scheduleRepeatedDay ? checklistDetails?.scheduleRepeatedDay : '',
1830
+ scheduleRepeatedType: differences?.scheduleRepeatedType ? checklistDetails?.scheduleRepeatedType : '',
1831
+ ...( differences?.configStartDate && checklistDetails?.configStartDate ) ? { configStartDate: dayjs( checklistDetails?.configStartDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1832
+ ...( differences?.configEndDate && checklistDetails?.configEndDate ) ? { configEndDate: dayjs( checklistDetails?.configEndDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1833
+ scheduleWeekDays: differences?.scheduleWeekDays ? checklistDetails?.scheduleWeekDays : [],
1834
+ scheduleRepeatedMonthWeek: differences?.scheduleRepeatedMonthWeek ? checklistDetails?.scheduleRepeatedMonthWeek : '',
1835
+ specificDate: differences?.specificDate ? checklistDetails?.specificDate : [],
1836
+
1837
+ },
1838
+ new: {
1839
+ ...( differences?.scheduleDate && ( differences?.scheduleDate.new != '' && differences?.scheduleDate.new != null ) ) ? { scheduleDate: dayjs( configDetails?.scheduleDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1840
+ schedule: differences?.schedule ? configDetails.schedule : '',
1841
+ time: ( ( differences?.scheduleEndTime || differences?.scheduleStartTime ) && ( configDetails.scheduleStartTime != '' || configDetails.scheduleEndTime != '' ) ) ? configDetails.scheduleStartTime + ' to ' + configDetails.scheduleEndTime : '',
1842
+ scheduleRepeatedDay: differences?.scheduleRepeatedDay ? configDetails?.scheduleRepeatedDay : '',
1843
+ scheduleRepeatedType: differences?.scheduleRepeatedType ? configDetails?.scheduleRepeatedType : '',
1844
+ ...( differences?.configStartDate && configDetails?.configStartDate ) ? { configStartDate: dayjs( configDetails?.configStartDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1845
+ ...( differences?.configEndDate && configDetails?.configEndDate ) ? { configEndDate: dayjs( configDetails?.configEndDate, 'YYYY-MM-DD' ).format( 'DD MMM, YYYY' ) } :{},
1846
+ scheduleWeekDays: differences?.scheduleWeekDays ? configDetails?.scheduleWeekDays : [],
1847
+ scheduleRepeatedMonthWeek: differences?.scheduleRepeatedMonthWeek ? configDetails?.scheduleRepeatedMonthWeek : '',
1848
+ specificDate: differences?.specificDate ? configDetails?.specificDate : [],
1849
+ },
1850
+ },
1851
+ response: {
1852
+ previous: [
1853
+ ...( differences?.allowedStoreLocation && checklistDetails.allowedStoreLocation ? [ 'Geo fencing' ] : [] ),
1854
+ ...( differences?.allowedMultiSubmit && checklistDetails.allowedMultiSubmit? [ 'Allow multiple responses' ] : [] ),
1855
+ ...( differences?.allowedOverTime && checklistDetails.allowedOverTime ? [ 'Fill response after configure time.' ] : [] ),
1856
+ ...( differences?.allowOnce && checklistDetails.allowOnce ? [ 'Only one time' ] : [] ),
1857
+ ],
1858
+ new: [
1859
+ ...( differences?.allowedStoreLocation && configDetails.allowedStoreLocation ? [ 'Geo fencing' ] : [] ),
1860
+ ...( differences?.allowedMultiSubmit && configDetails.allowedMultiSubmit? [ 'Allow multiple responses' ] : [] ),
1861
+ ...( differences?.allowedOverTime && configDetails.allowedOverTime ? [ 'Fill response after configure time' ] : [] ),
1862
+ ...( differences?.allowOnce && configDetails.allowOnce ? [ 'Only one time' ] : [] ),
1863
+ ],
1864
+ },
1865
+ ...( differences?.approver ) ? { approver:
1866
+ { previous: differences?.approver?.previous.map( ( item ) => item.name ).toString(),
1867
+ new: differences?.approver?.new.map( ( item ) => item.name ).toString() },
1868
+ } : { approver: {} },
1869
+ ...( differences?.owner ) ? { owner:
1870
+ { previous: differences?.owner?.previous.map( ( item ) => item.name ).toString(),
1871
+ new: differences?.owner?.new.map( ( item ) => item.name ).toString() },
1872
+ } : { owner: {} },
1873
+ ...( req.body.checkListDetails.coverage == 'store' ) ? { storeAdded: req.body.added } :{ storeAdded: [] },
1874
+ ...( req.body.checkListDetails.coverage == 'store' ) ? { storeRemoved: req.body.removed } :{ storeRemoved: [] },
1875
+ ...( req.body.checkListDetails.coverage == 'user' ) ? { userAdded: req.body.added } :{ userAdded: [] },
1876
+ ...( req.body.checkListDetails.coverage == 'user' ) ? { userRemoved: req.body.removed } :{ userRemoved: [] },
1877
+ },
1878
+ };
1879
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, insertData );
1880
+ }
1881
+
1882
+ let logObj = {
1883
+ client_id: inputBody.checkListDetails.client_id,
1884
+ createAt: new Date(),
1885
+ sourceCheckList_id: inputBody.checkListDetails._id,
1886
+ checkListName: inputBody.checkListDetails.checkListName,
1887
+ fromCheckListName: '',
1888
+ type: 'checklist',
1889
+ action: inputBody.checkListDetails.publish ? 'published' : 'unpublished',
1890
+ storeName: '',
1891
+ store_id: '',
1892
+ createdByEmail: req.user.email,
1893
+ createdBy: req.user.userName,
1894
+ coverage: inputBody.checkListDetails.coverage,
1895
+ logDetails: {},
1896
+ };
1897
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
1898
+
1646
1899
  if ( response?.modifiedCount || response?.matchedCount || response?.upsertedCount ) {
1647
1900
  return res.sendSuccess( { id, message: 'Configured Updated Successfully' } );
1648
1901
  }
@@ -1655,6 +1908,32 @@ export const updateConfigurev1 =async ( req, res ) => {
1655
1908
  }
1656
1909
  };
1657
1910
 
1911
+ function findObjectDifference( oldObj, newObj ) {
1912
+ const isEqual = ( a, b ) => JSON.stringify( a ) === JSON.stringify( b );
1913
+
1914
+ const getArrayDiff = ( oldArr, newArr ) => {
1915
+ const removed = oldArr.filter( ( item ) => !newArr.some( ( newItem ) => isEqual( newItem, item ) ) );
1916
+ const added = newArr.filter( ( item ) => !oldArr.some( ( oldItem ) => isEqual( oldItem, item ) ) );
1917
+ if ( removed.length || added.length ) {
1918
+ return { previous: oldArr, new: newArr };
1919
+ }
1920
+ return [];
1921
+ };
1922
+ const difference = Object.keys( oldObj ).reduce( ( diff, key ) => {
1923
+ oldObj[key] = oldObj[key] == null ? '' : oldObj[key];
1924
+ if ( !isEqual( oldObj[key], newObj[key] ) ) {
1925
+ if ( !Array.isArray( newObj[key] ) ) {
1926
+ diff[key] = { previous: oldObj[key], new: newObj[key] };
1927
+ } else {
1928
+ diff[key] = getArrayDiff( oldObj[key] || [], newObj[key] || [] );
1929
+ }
1930
+ }
1931
+ return diff;
1932
+ }, {} );
1933
+
1934
+ return difference;
1935
+ }
1936
+
1658
1937
  export const updatePublish = async ( req, res ) => {
1659
1938
  try {
1660
1939
  if ( typeof req?.body?.checklistId == 'undefined' && typeof req.body.type == 'undefined' ) {
@@ -1729,6 +2008,22 @@ export const updatePublish = async ( req, res ) => {
1729
2008
 
1730
2009
 
1731
2010
  await checklistService.updateOne( query, getCheckDetails );
2011
+ let logObj = {
2012
+ client_id: req.body.clientId,
2013
+ createAt: new Date(),
2014
+ sourceCheckList_id: req.body.checklistId,
2015
+ checkListName: getCheckDetails.checkListName,
2016
+ fromCheckListName: '',
2017
+ type: 'checklist',
2018
+ action: req.body.publish ? 'published' : 'unpublished',
2019
+ storeName: '',
2020
+ store_id: '',
2021
+ createdByEmail: req.user.email,
2022
+ createdBy: req.user.userName,
2023
+ coverage: getCheckDetails.coverage,
2024
+ logDetails: {},
2025
+ };
2026
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
1732
2027
  if ( getCheckDetails.checkListType == 'custom' ) {
1733
2028
  let currentDate = dayjs.utc().format();
1734
2029
  let updatedscheduleEndTimeISO = dayjs.utc( getCheckDetails.scheduleEndTimeISO ).format( 'HH:mm:ss' );
@@ -2031,7 +2326,6 @@ export const validateUserv1 = async ( req, res ) => {
2031
2326
  }, {} );
2032
2327
 
2033
2328
  const duplicateUsers = Object.keys( duplicateUser ).filter( ( storeName ) => duplicateUser[storeName].count > 1 );
2034
- console.log( duplicateUsers, 'user' );
2035
2329
  if ( duplicateUsers.length ) {
2036
2330
  return res.sendError( { validate: false, duplicates: duplicateUsers, message: 'Email is Duplicated' }, 400 );
2037
2331
  }
@@ -2070,7 +2364,7 @@ export const validateUserv1 = async ( req, res ) => {
2070
2364
  {
2071
2365
  $project: {
2072
2366
  newEmail: { $toLower: '$email' },
2073
- isActive: 1,
2367
+ // isActive: 1,
2074
2368
  clientId: 1,
2075
2369
  email: 1,
2076
2370
  },
@@ -2078,7 +2372,7 @@ export const validateUserv1 = async ( req, res ) => {
2078
2372
  {
2079
2373
  $match: {
2080
2374
  newEmail: { $in: userEmailList },
2081
- isActive: true,
2375
+ // isActive: true,
2082
2376
  clientId: { $ne: req.body.clientId },
2083
2377
  },
2084
2378
  },
@@ -3933,6 +4227,44 @@ export async function updateAssign( req, res ) {
3933
4227
  // req.body.assignedGroup = req.body.assignedGroup.map( ( ele ) => {
3934
4228
  // return { id: ele };
3935
4229
  // } );
4230
+ let getAssignedDetails = await assignedService.find( { checkListId: req.body.checkListId } );
4231
+ if ( getAssignedDetails.length ) {
4232
+ if ( req.body.coverage == 'store' ) {
4233
+ getAssignedDetails = [ ...new Set( getAssignedDetails.map( ( ele ) => ele.storeName ) ) ];
4234
+ } else {
4235
+ getAssignedDetails = [ ...new Set( getAssignedDetails.map( ( ele ) => ele.userName ) ) ];
4236
+ }
4237
+ }
4238
+
4239
+ let added = req.body.assignedList.filter( ( item ) => {
4240
+ let storeUsername;
4241
+ if ( req.body.coverage == 'store' ) {
4242
+ storeUsername = item.storeName;
4243
+ } else {
4244
+ storeUsername = item.userName;
4245
+ }
4246
+ if ( !getAssignedDetails.includes( storeUsername ) ) {
4247
+ return item;
4248
+ }
4249
+ } ).map( ( ele ) => {
4250
+ if ( req.body.coverage == 'store' ) {
4251
+ return ele.storeName;
4252
+ } else {
4253
+ return ele.userName;
4254
+ }
4255
+ } );
4256
+ let removed = getAssignedDetails.filter( ( item ) => {
4257
+ let list;
4258
+ if ( req.body.coverage == 'store' ) {
4259
+ list = req.body.assignedList.map( ( item ) => item.storeName );
4260
+ } else {
4261
+ list = req.body.assignedList.map( ( item ) => item.userName ); ;
4262
+ }
4263
+ if ( !list.includes( item ) ) {
4264
+ return item;
4265
+ }
4266
+ } );
4267
+
3936
4268
  await assignedService.deleteMany( { checkListId: req.body.checkListId } );
3937
4269
  let assignedUserList = [];
3938
4270
  let userEmailList = req.body.assignedList.map( ( ele ) => ele.userEmail.toLowerCase() );
@@ -3950,7 +4282,7 @@ export async function updateAssign( req, res ) {
3950
4282
  },
3951
4283
  ];
3952
4284
  let assignUserDetails = await userService.aggregate( query );
3953
- await Promise.all( req.body.assignedList.map( async ( assign ) => {
4285
+ for ( let assign of req.body.assignedList ) {
3954
4286
  let userDetails = assignUserDetails.find( ( ele ) => ele.email.toLowerCase() == assign.userEmail.toLowerCase() );
3955
4287
  if ( !userDetails ) {
3956
4288
  let userData = {
@@ -3960,7 +4292,7 @@ export async function updateAssign( req, res ) {
3960
4292
  clientId: req.body.clientId,
3961
4293
  };
3962
4294
  userDetails = await createUser( userData );
3963
- userDetails = userDetails;
4295
+ assignUserDetails.push( userDetails );
3964
4296
  }
3965
4297
  let data = {
3966
4298
  ...assign,
@@ -3974,7 +4306,7 @@ export async function updateAssign( req, res ) {
3974
4306
  };
3975
4307
  delete data._id;
3976
4308
  assignedUserList.push( data );
3977
- } ) );
4309
+ }
3978
4310
  let assignGroupDetails = [];
3979
4311
  if ( req.body.coverage == 'store' ) {
3980
4312
  assignGroupDetails = await clusterServices.findcluster( { _id: { $in: req.body.assignedGroup } } );
@@ -3996,7 +4328,7 @@ export async function updateAssign( req, res ) {
3996
4328
  }
3997
4329
  } ) );
3998
4330
  await assignedService.insertMany( assignedUserList );
3999
- return res.sendSuccess( 'Assign details updated successfully' );
4331
+ return res.sendSuccess( { messgage: 'Assign details updated successfully', added, removed } );
4000
4332
  } catch ( e ) {
4001
4333
  logger.error( { functionName: 'updateAssign', error: e } );
4002
4334
  return res.sendError( e, 500 );