tango-app-api-task 3.4.0-alpha-1 → 3.4.0-alpha-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-task",
3
- "version": "3.4.0-alpha-1",
3
+ "version": "3.4.0-alpha-3",
4
4
  "description": "Task",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -21,6 +21,7 @@
21
21
  "express": "^4.21.1",
22
22
  "express-fileupload": "^1.5.1",
23
23
  "handlebars": "^4.7.8",
24
+ "lodash": "^4.17.21",
24
25
  "mongodb": "^6.10.0",
25
26
  "nodemon": "^3.1.7",
26
27
  "npm": "^10.9.2",
@@ -25,6 +25,7 @@ import * as ApproverModel from '../service/approver.service.js';
25
25
  import { createTeamsModel, findOneTeams, updateOneTeamModel, findteams } from '../service/teams.service.js';
26
26
  import { sendPushNotification } from 'tango-app-api-middleware';
27
27
  import * as checklistService from '../service/checklist.service.js';
28
+ import isEqual from 'lodash/isEqual.js';
28
29
  async function LamdaServiceCall( url, data ) {
29
30
  try {
30
31
  const requestOptions = {
@@ -52,17 +53,26 @@ export async function createUpdateTask( req, res ) {
52
53
  let questionCount = 0;
53
54
  let checkListId;
54
55
  let query;
55
- let checkExistsQuery = { client_id: req.body.clientId, checkListName: inputBody.checklistName, isdeleted: false };
56
+ let checkExistsQuery = { client_id: inputBody.clientId, checkListName: inputBody.checklistName, isdeleted: false };
56
57
  let checkExists;
57
- if ( req.body._id ) {
58
- checkExistsQuery['_id'] = { $nin: [ new ObjectId( req.body._id ) ] };
58
+ let taskDetails;
59
+ if ( inputBody._id ) {
60
+ checkExistsQuery['_id'] = { $nin: [ new ObjectId( inputBody._id ) ] };
59
61
  }
60
62
 
61
63
  checkExists = await taskService.findOne( checkExistsQuery );
62
-
63
64
  if ( checkExists ) {
64
65
  return res.sendError( { message: 'Task name already exists' }, 400 );
65
66
  }
67
+ if ( inputBody._id ) {
68
+ taskDetails = await taskService.findOne( { _id: inputBody._id } );
69
+
70
+ if ( !taskDetails ) {
71
+ return res.sendError( 'No data found', 204 );
72
+ }
73
+ }
74
+
75
+ let getExistQuestions = await taskQuestionService.find( { checkListId: inputBody._id } );
66
76
 
67
77
  inputBody.sections.forEach( async ( element ) => {
68
78
  if ( !element?.questions?.length && inputBody.submitType == 'configure' ) {
@@ -81,14 +91,14 @@ export async function createUpdateTask( req, res ) {
81
91
  questionCount: questionCount,
82
92
  client_id: req.body?.clientId,
83
93
  };
84
- if ( req.body._id ) {
85
- query = { _id: req.body._id, client_id: req.body?.clientId };
94
+ if ( inputBody._id ) {
95
+ query = { _id: inputBody._id, client_id: req.body?.clientId };
86
96
  } else {
87
97
  query = { checkListName: inputBody.checklistName, client_id: req.body?.clientId };
88
98
  }
89
99
  let data = await taskService.updateOne( query, checkListDetails );
90
- if ( data.upsertedId || req.body._id ) {
91
- checkListId = data?.upsertedId || req.body._id;
100
+ if ( data.upsertedId || inputBody._id ) {
101
+ checkListId = data?.upsertedId || inputBody._id;
92
102
  let logInsertData = {
93
103
  action: req.body?._id ? 'taskUpdate' : 'taskCreate',
94
104
  type: 'task',
@@ -96,7 +106,7 @@ export async function createUpdateTask( req, res ) {
96
106
  checkListName: inputBody.checklistName,
97
107
  createdBy: req.user._id,
98
108
  createdByName: req.user.userName,
99
- client_id: req.body.clientId,
109
+ client_id: inputBody.clientId,
100
110
  sections: inputBody?.sections,
101
111
  createdByEmail: req.user.email,
102
112
  };
@@ -132,31 +142,138 @@ export async function createUpdateTask( req, res ) {
132
142
  section: section?.name || 'Section 1',
133
143
  createdBy: req.user._id,
134
144
  createdByName: req.user.userName,
135
- client_id: req.body.clientId,
145
+ client_id: inputBody.clientId,
136
146
  checkListId: checkListId,
137
147
  question: section.questions,
138
148
  checkList: inputBody.checklistName,
139
149
  } );
140
150
  }
151
+ }
152
+ if ( inputBody._id ) {
153
+ await taskQuestionService.deleteMany( { checkListId: checkListId } );
154
+ await taskAssignService.updateMany( { checkListId: inputBody._id }, { checkListName: inputBody.checklistName } );
155
+ }
156
+ if ( sectionList.length ) {
157
+ await taskQuestionService.insertMany( sectionList );
158
+ }
159
+ let message = req.body?._id ? 'Task Updated Successfully' : 'Task Created Successfully';
160
+ if ( inputBody.submitType == 'save' ) {
161
+ message = 'Saved in draft successfully';
162
+ }
163
+ if ( inputBody._id ) {
164
+ let questionList = {
165
+ questionAdd: [],
166
+ questionEdit: [],
167
+ questionDelete: [],
168
+ };
141
169
 
142
- if ( req.body._id ) {
143
- await taskQuestionService.deleteMany( { checkListId: checkListId } );
144
- await taskAssignService.updateMany( { checkListId: req.body._id }, { checkListName: inputBody.checklistName } );
170
+ function findDifferences( obj1, obj2 ) {
171
+ return Object.keys( obj1 ).reduce( ( diff, key ) => {
172
+ if ( !isEqual( obj1[key], obj2[key] ) ) {
173
+ diff[key] = { previous: obj1[key], new: obj2[key] };
174
+ }
175
+ return diff;
176
+ }, {} );
145
177
  }
146
- await taskQuestionService.insertMany( sectionList );
147
- let message = req.body?._id ? 'Task Updated Successfully' : 'Task Created Successfully';
148
- if ( inputBody.submitType == 'save' ) {
149
- message = 'Saved in draft successfully';
178
+
179
+ console.log( inputBody.sections );
180
+ getExistQuestions.forEach( ( ele ) => {
181
+ ele.question.forEach( ( qn ) => {
182
+ console.log( qn );
183
+ console.log( JSON.stringify( inputBody.sections[0].questions ) );
184
+ let question = inputBody.sections[0].questions.find( ( qns ) => qns.oldQname === qn.qname );
185
+ console.log( question, 'tion' );
186
+ if ( question ) {
187
+ qn.answers.forEach( ( ans ) => {
188
+ delete ans.answeroptionNumber;
189
+ } );
190
+ question.answers.forEach( ( ans ) => {
191
+ delete ans.answeroptionNumber;
192
+ } );
193
+ let compare = findDifferences( qn, question );
194
+ if ( Object.keys( compare ).length && ( compare?.answerType || compare?.answers || compare?.linkType ) ) {
195
+ questionList.questionEdit.push( { sectionName: ele.section, questions: [ { previous: qn }, { new: question } ] } );
196
+ }
197
+ } else {
198
+ let sectionIndex = questionList.questionDelete.findIndex( ( sec ) => sec.sectionName === ele.section );
199
+
200
+ if ( sectionIndex !== -1 ) {
201
+ questionList.questionDelete[sectionIndex].questions.push( qn );
202
+ } else {
203
+ questionList.questionDelete.push( { sectionName: ele?.section || 'Section 1', questions: [ qn ] } );
204
+ }
205
+ }
206
+ } );
207
+ } );
208
+
209
+ console.log( getExistQuestions, 'qns' );
210
+
211
+ inputBody.sections.forEach( ( ele ) => {
212
+ ele.questions.forEach( ( qn ) => {
213
+ let question = getExistQuestions[0].question.find( ( qns ) => qns.qname === qn.oldQname );
214
+
215
+ if ( !question ) {
216
+ let sectionIndex = questionList.questionAdd.findIndex( ( sec ) => sec.sectionName === ele.name );
217
+
218
+ if ( sectionIndex !== -1 ) {
219
+ questionList.questionAdd[sectionIndex].questions.push( qn );
220
+ } else {
221
+ questionList.questionAdd.push( { sectionName: ele?.name || 'Section 1', questions: [ qn ] } );
222
+ }
223
+ }
224
+ } );
225
+ } );
226
+
227
+ if ( questionList.questionAdd.length || questionList.questionEdit.length || questionList.questionDelete.length || inputBody.checklistName.toLowerCase() != checkListDetails.checkListName.toLowerCase() || inputBody.checklistDescription.toLowerCase() != checkListDetails.checkListDescription.toLowerCase() ) {
228
+ let insertLogData = {
229
+ client_id: req.body.clientId,
230
+ createAt: new Date(),
231
+ sourceCheckList_id: inputBody._id,
232
+ checkListName: inputBody.checklistName,
233
+ fromCheckListName: '',
234
+ type: 'checklist',
235
+ action: 'edited',
236
+ storeName: '',
237
+ store_id: '',
238
+ createdByEmail: req.user.email,
239
+ createdBy: req.user.userName,
240
+ coverage: taskDetails?.coverage,
241
+ logDetails: {
242
+ ...( inputBody.checklistName.toLowerCase() == checkListDetails.checkListName.toLowerCase() ) ? { updatedChecklistName: {} } :{ updatedChecklistName: {
243
+ previous: checkListDetails.checkListName,
244
+ new: inputBody.checklistName,
245
+ } },
246
+ ...( inputBody.checklistDescription.toLowerCase() == checkListDetails.checkListDescription.toLowerCase() ) ? { updatedChecklistDescription: {} } :{ updatedChecklistDescription: {
247
+ previous: checkListDetails.checkListDescription,
248
+ new: inputBody.checklistDescription,
249
+ } },
250
+ updatedSectionName: [],
251
+ questionAdd: questionList.questionAdd,
252
+ questionEdit: questionList.questionEdit,
253
+ questionDelete: questionList.questionDelete,
254
+ },
255
+ };
256
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, insertLogData );
150
257
  }
151
- return res.sendSuccess( { checklistId: checkListId, message: message } );
152
258
  } else {
153
- if ( inputBody.submitType == 'save' ) {
154
- let message = 'Saved in draft successfully';
155
- return res.sendSuccess( { checklistId: checkListId, message: message } );
156
- } else {
157
- return res.sendSuccess( { message: 'Question is required' } );
158
- }
259
+ let logObj = {
260
+ client_id: inputBody.clientId,
261
+ createAt: new Date(),
262
+ sourceCheckList_id: inputBody._id,
263
+ checkListName: inputBody.checklistName,
264
+ fromCheckListName: '',
265
+ type: 'task',
266
+ action: 'created',
267
+ storeName: '',
268
+ store_id: '',
269
+ createdByEmail: req.user.email,
270
+ createdBy: req.user.userName,
271
+ coverage: 'store',
272
+ logDetails: {},
273
+ };
274
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
159
275
  }
276
+ return res.sendSuccess( { checklistId: checkListId, message: message } );
160
277
  } else {
161
278
  return res.sendError( { message: 'something went wrong' }, 500 );
162
279
  }
@@ -883,13 +1000,13 @@ export async function taskConfig( req, res ) {
883
1000
  };
884
1001
  await checklistLogs.create( logInsertData );
885
1002
 
886
- checklistDetails = await taskService.findOne( { _id: inputBody._id, isdeleted: false, client_id: inputBody.clientId } );
1003
+ checklistDetails = await taskService.findOne( { _id: inputBody._id, isdeleted: false, client_id: inputBody.clientId, checkListName: 1 } );
887
1004
 
888
1005
  if ( !checklistDetails ) {
889
1006
  return res.sendError( 'No data found', 204 );
890
1007
  }
891
1008
 
892
- let configDetails = { ...req.body };
1009
+ let configDetails = { ...inputBody };
893
1010
  configDetails.approver = configDetails.approver.length ? configDetails.approver.map( ( item ) => {
894
1011
  return { name: item.name, value: item.value };
895
1012
  } ) : [];
@@ -960,6 +1077,81 @@ export async function taskConfig( req, res ) {
960
1077
  }
961
1078
  if ( response?.modifiedCount || response?.matchedCount || response?.upsertedCount ) {
962
1079
  let message = inputBody.submitType == 'publish' ? 'Configuration Updated Successfully' : 'Saved in draft successfully';
1080
+ checklistDetails = checklistDetails.toObject();
1081
+ checklistDetails.scheduleEndTimeISO = checklistDetails?.scheduleEndTime ? dayjs.utc( checklistDetails?.scheduleEndTime, 'hh:mm A' ).format() : '';
1082
+ checklistDetails.scheduleDate = checklistDetails.scheduleDate ? dayjs.utc( checklistDetails?.scheduleDate ).format( 'YYYY-MM-DD' ) : '';
1083
+ configDetails.scheduleDate = configDetails.scheduleDate ? dayjs( configDetails?.scheduleDate ).format( 'YYYY-MM-DD' ) : '';
1084
+ let removedKeys = [ 'publish', 'publishDate', 'storeCount', 'sections', 'createdAt', 'updatedAt', 'scheduleEndTimeISO' ];
1085
+ removedKeys.forEach( ( item ) => {
1086
+ delete checklistDetails?.[item];
1087
+ delete configDetails?.[item];
1088
+ } );
1089
+ let differences = findObjectDifference( checklistDetails, configDetails );
1090
+ if ( Object.keys( differences ).length || inputBody.added.length || inputBody.removed.length ) {
1091
+ let insertData = {
1092
+ client_id: inputBody.clientId,
1093
+ createAt: new Date(),
1094
+ sourceCheckList_id: configDetails._id,
1095
+ checkListName: checklistDetails.checkListName,
1096
+ fromCheckListName: '',
1097
+ type: 'task',
1098
+ action: 'updated',
1099
+ storeName: '',
1100
+ store_id: '',
1101
+ createdByEmail: req.user.email,
1102
+ createdBy: req.user.userName,
1103
+ coverage: configDetails.coverage,
1104
+ logDetails: {
1105
+ schedule: {
1106
+ previous: {
1107
+ ...( differences?.scheduleDate && ( differences?.scheduleDate.previous != '' && differences?.scheduleDate.previous != null ) ) ? { scheduleDate: checklistDetails?.scheduleDate } :{},
1108
+ time: differences?.scheduleEndTime ? checklistDetails.scheduleEndTime : '',
1109
+ priority: differences?.priorityType ? checklistDetails?.priorityType : '',
1110
+ },
1111
+ new: {
1112
+ ...( differences?.scheduleDate && ( differences?.scheduleDate.new != '' && differences?.scheduleDate.new != null ) ) ? { scheduleDate: configDetails?.scheduleDate } :{},
1113
+ time: differences?.scheduleEndTime ? configDetails.scheduleEndTime : '',
1114
+ priority: differences?.priorityType ? configDetails?.priorityType : '',
1115
+ },
1116
+ },
1117
+ response: {
1118
+ previous: [
1119
+ ...( differences?.allowedStoreLocation && checklistDetails.allowedStoreLocation ? [ 'Geo fencing' ] : [] ),
1120
+ ],
1121
+ new: [
1122
+ ...( differences?.allowedStoreLocation && configDetails.allowedStoreLocation ? [ 'Geo fencing' ] : [] ),
1123
+ ],
1124
+ },
1125
+ ...( differences?.approver ) ? { approver:
1126
+ { previous: differences?.approver?.previous.map( ( item ) => item.name ).toString(),
1127
+ new: differences?.approver?.new.map( ( item ) => item.name ).toString() },
1128
+ } : { approver: {} },
1129
+ owner: {},
1130
+ ...( inputBody.coverage == 'store' ) ? { storeAdded: inputBody.added } :{ storeAdded: [] },
1131
+ ...( inputBody.coverage == 'store' ) ? { storeRemoved: inputBody.removed } :{ storeRemoved: [] },
1132
+ ...( inputBody.coverage == 'user' ) ? { userAdded: inputBody.added } :{ userAdded: [] },
1133
+ ...( inputBody.coverage == 'user' ) ? { userRemoved: inputBody.removed } :{ userRemoved: [] },
1134
+ },
1135
+ };
1136
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, insertData );
1137
+ }
1138
+
1139
+ let logObj = {
1140
+ client_id: inputBody.client_id,
1141
+ createAt: new Date(),
1142
+ sourceCheckList_id: inputBody._id,
1143
+ checkListName: checklistDetails.checkListName,
1144
+ fromCheckListName: '',
1145
+ type: 'task',
1146
+ action: inputBody.publish ? 'published' : 'unpublished',
1147
+ storeName: '',
1148
+ store_id: '',
1149
+ createdByEmail: req.user.email,
1150
+ createdBy: req.user.userName,
1151
+ coverage: inputBody.coverage,
1152
+ logDetails: {},
1153
+ };
1154
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
963
1155
  return res.sendSuccess( { id: inputBody._id, message: message } );
964
1156
  }
965
1157
  } catch ( e ) {
@@ -969,6 +1161,32 @@ export async function taskConfig( req, res ) {
969
1161
  }
970
1162
  }
971
1163
 
1164
+ function findObjectDifference( oldObj, newObj ) {
1165
+ const isEqual = ( a, b ) => JSON.stringify( a ) === JSON.stringify( b );
1166
+
1167
+ const getArrayDiff = ( oldArr, newArr ) => {
1168
+ const removed = oldArr.filter( ( item ) => !newArr.some( ( newItem ) => isEqual( newItem, item ) ) );
1169
+ const added = newArr.filter( ( item ) => !oldArr.some( ( oldItem ) => isEqual( oldItem, item ) ) );
1170
+ if ( removed.length || added.length ) {
1171
+ return { previous: oldArr, new: newArr };
1172
+ }
1173
+ return [];
1174
+ };
1175
+ const difference = Object.keys( oldObj ).reduce( ( diff, key ) => {
1176
+ oldObj[key] = oldObj[key] == null ? '' : oldObj[key];
1177
+ if ( !isEqual( oldObj[key], newObj[key] ) ) {
1178
+ if ( !Array.isArray( newObj[key] ) ) {
1179
+ diff[key] = { previous: oldObj[key], new: newObj[key] };
1180
+ } else {
1181
+ diff[key] = getArrayDiff( oldObj[key] || [], newObj[key] || [] );
1182
+ }
1183
+ }
1184
+ return diff;
1185
+ }, {} );
1186
+
1187
+ return difference;
1188
+ }
1189
+
972
1190
  export async function insertSingleProcessData( checklistId ) {
973
1191
  try {
974
1192
  let currentdate = new Date();
@@ -2571,7 +2789,7 @@ export const updatePublish = async ( req, res ) => {
2571
2789
 
2572
2790
  if ( req.body.checklistId ) {
2573
2791
  query = { _id: req.body.checklistId };
2574
- getCheckDetails = await taskService.findOne( { _id: req.body.checklistId, client_id: req.body.clientId } );
2792
+ getCheckDetails = await taskService.findOne( { _id: req.body.checklistId, client_id: req.body.clientId, checkListName: 1 } );
2575
2793
  }
2576
2794
 
2577
2795
  if ( !getCheckDetails ) {
@@ -2668,6 +2886,22 @@ export const updatePublish = async ( req, res ) => {
2668
2886
  createdByEmail: req.user.email,
2669
2887
  };
2670
2888
  await checklistLogs.create( logInsertData );
2889
+ let logObj = {
2890
+ client_id: req.body.clientId,
2891
+ createAt: new Date(),
2892
+ sourceCheckList_id: req.body.checklistId,
2893
+ checkListName: getCheckDetails.checkListName,
2894
+ fromCheckListName: '',
2895
+ type: 'task',
2896
+ action: req.body.publish ? 'published' : 'unpublished',
2897
+ storeName: '',
2898
+ store_id: '',
2899
+ createdByEmail: req.user.email,
2900
+ createdBy: req.user.userName,
2901
+ coverage: getCheckDetails.coverage,
2902
+ logDetails: {},
2903
+ };
2904
+ await insertOpenSearchData( JSON.parse( process.env.OPENSEARCH ).traxActivityLog, logObj );
2671
2905
  return res.sendSuccess( { checklistName: getCheckDetails.checkListName, message: 'Updated Successfully' } );
2672
2906
  } catch ( e ) {
2673
2907
  logger.error( 'updatePublish task erroe =>', e );
@@ -4062,6 +4296,43 @@ export async function updateAssign( req, res ) {
4062
4296
  // req.body.assignedGroup = req.body.assignedGroup.map( ( ele ) => {
4063
4297
  // return { id: ele };
4064
4298
  // } );
4299
+ let getAssignedDetails = await taskAssignService.find( { checkListId: req.body.taskId } );
4300
+ if ( getAssignedDetails.length ) {
4301
+ if ( req.body.coverage == 'store' ) {
4302
+ getAssignedDetails = [ ...new Set( getAssignedDetails.map( ( ele ) => ele.storeName ) ) ];
4303
+ } else {
4304
+ getAssignedDetails = [ ...new Set( getAssignedDetails.map( ( ele ) => ele.userName ) ) ];
4305
+ }
4306
+ }
4307
+
4308
+ let added = req.body.assignedList.filter( ( item ) => {
4309
+ let storeUsername;
4310
+ if ( req.body.coverage == 'store' ) {
4311
+ storeUsername = item.storeName;
4312
+ } else {
4313
+ storeUsername = item.userName;
4314
+ }
4315
+ if ( !getAssignedDetails.includes( storeUsername ) ) {
4316
+ return item;
4317
+ }
4318
+ } ).map( ( ele ) => {
4319
+ if ( req.body.coverage == 'store' ) {
4320
+ return ele.storeName;
4321
+ } else {
4322
+ return ele.userName;
4323
+ }
4324
+ } );
4325
+ let removed = getAssignedDetails.filter( ( item ) => {
4326
+ let list;
4327
+ if ( req.body.coverage == 'store' ) {
4328
+ list = req.body.assignedList.map( ( item ) => item.storeName );
4329
+ } else {
4330
+ list = req.body.assignedList.map( ( item ) => item.userName ); ;
4331
+ }
4332
+ if ( !list.includes( item ) ) {
4333
+ return item;
4334
+ }
4335
+ } );
4065
4336
  await taskAssignService.deleteMany( { checkListId: req.body.taskId } );
4066
4337
  let assignedUserList = [];
4067
4338
  let userEmailList = req.body.assignedList.map( ( ele ) => ele.userEmail.toLowerCase() );
@@ -4124,7 +4395,7 @@ export async function updateAssign( req, res ) {
4124
4395
  }
4125
4396
  } ) );
4126
4397
  await taskAssignService.insertMany( assignedUserList );
4127
- return res.sendSuccess( 'Assign details updated successfully' );
4398
+ return res.sendSuccess( { message: 'Assign details updated successfully', added, removed } );
4128
4399
  } catch ( e ) {
4129
4400
  logger.error( { functionName: 'updateAssign', error: e } );
4130
4401
  }