tango-app-api-task 1.0.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.
- package/.eslintrc.cjs +41 -0
- package/README.md +29 -0
- package/index.js +10 -0
- package/package.json +39 -0
- package/src/controllers/internalAPI.controller.js +304 -0
- package/src/controllers/task.controller.js +1059 -0
- package/src/controllers/taskActionCenter.controllers.js +383 -0
- package/src/controllers/taskDashboard.controllers.js +747 -0
- package/src/routes/internalAPI.routes.js +11 -0
- package/src/routes/task.routes.js +19 -0
- package/src/routes/taskActionCenter.routes.js +16 -0
- package/src/routes/taskDashboard.routes.js +18 -0
- package/src/service/approver.service.js +17 -0
- package/src/service/checklistLog.service.js +33 -0
- package/src/service/domain.service.js +23 -0
- package/src/service/processedChecklist.service.js +6 -0
- package/src/service/processedTaskConfig.service.js +32 -0
- package/src/service/processedTaskList.service.js +26 -0
- package/src/service/store.service.js +29 -0
- package/src/service/task.service.js +23 -0
- package/src/service/taskAssign.service.js +33 -0
- package/src/service/taskQuestion.service.js +31 -0
- package/src/service/user.service.js +26 -0
|
@@ -0,0 +1,1059 @@
|
|
|
1
|
+
import { logger, fileUpload, signedUrl } from 'tango-app-api-middleware';
|
|
2
|
+
import * as taskService from '../service/task.service.js';
|
|
3
|
+
import * as checklistLogs from '../service/checklistLog.service.js';
|
|
4
|
+
import * as taskQuestionService from '../service/taskQuestion.service.js';
|
|
5
|
+
import * as taskAssignService from '../service/taskAssign.service.js';
|
|
6
|
+
import * as userService from '../service/user.service.js';
|
|
7
|
+
import * as storeService from '../service/store.service.js';
|
|
8
|
+
import * as traxApprover from '../service/approver.service.js';
|
|
9
|
+
// import * as domainService from '../service/domain.service.js';
|
|
10
|
+
import mongoose from 'mongoose';
|
|
11
|
+
const ObjectId = mongoose.Types.ObjectId;
|
|
12
|
+
import dayjs from 'dayjs';
|
|
13
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat.js';
|
|
14
|
+
import utc from 'dayjs/plugin/utc.js';
|
|
15
|
+
dayjs.extend( utc );
|
|
16
|
+
dayjs.extend( customParseFormat );
|
|
17
|
+
import * as taskProcessedConfigService from '../service/processedTaskConfig.service.js';
|
|
18
|
+
import * as taskProcessedService from '../service/processedTaskList.service.js';
|
|
19
|
+
|
|
20
|
+
export async function createUpdateTask( req, res ) {
|
|
21
|
+
try {
|
|
22
|
+
let inputBody = req.body;
|
|
23
|
+
let questionCount = 0;
|
|
24
|
+
let checkListId;
|
|
25
|
+
let query;
|
|
26
|
+
let checkExistsQuery = { client_id: req.body.clientId, checkListName: inputBody.checklistName, isdeleted: false };
|
|
27
|
+
let checkExists;
|
|
28
|
+
if ( req.body._id ) {
|
|
29
|
+
checkExistsQuery['_id'] = { $nin: [ new ObjectId( req.body._id ) ] };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
checkExists = await taskService.findOne( checkExistsQuery );
|
|
33
|
+
|
|
34
|
+
if ( checkExists ) {
|
|
35
|
+
return res.sendError( { message: 'Task name already exists' }, 400 );
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
inputBody.sections.forEach( async ( element ) => {
|
|
39
|
+
if ( !element?.questions?.length && inputBody.submitType == 'configure' ) {
|
|
40
|
+
return res.sendError( { message: 'Question is required' }, 400 );
|
|
41
|
+
}
|
|
42
|
+
if ( element?.questions?.length ) {
|
|
43
|
+
questionCount = questionCount + element?.questions?.length;
|
|
44
|
+
}
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
let checkListDetails = {
|
|
48
|
+
checkListName: inputBody.checklistName,
|
|
49
|
+
checkListDescription: inputBody.checklistDescription,
|
|
50
|
+
createdBy: req.user._id,
|
|
51
|
+
createdByName: req.user.userName,
|
|
52
|
+
questionCount: questionCount,
|
|
53
|
+
client_id: req.body?.clientId,
|
|
54
|
+
};
|
|
55
|
+
if ( req.body._id ) {
|
|
56
|
+
query = { _id: req.body._id, client_id: req.body?.clientId };
|
|
57
|
+
} else {
|
|
58
|
+
query = { checkListName: inputBody.checklistName, client_id: req.body?.clientId };
|
|
59
|
+
}
|
|
60
|
+
let data = await taskService.updateOne( query, checkListDetails );
|
|
61
|
+
if ( data.upsertedId || req.body._id ) {
|
|
62
|
+
checkListId = data?.upsertedId || req.body._id;
|
|
63
|
+
let logInsertData = {
|
|
64
|
+
action: req.body?._id ? 'checklistupdate' : 'checklistCreate',
|
|
65
|
+
checklistId: checkListId,
|
|
66
|
+
checkListName: inputBody.checklistName,
|
|
67
|
+
createdBy: req.user._id,
|
|
68
|
+
createdByName: req.user.userName,
|
|
69
|
+
client_id: req.body.clientId,
|
|
70
|
+
sections: inputBody?.sections,
|
|
71
|
+
};
|
|
72
|
+
await checklistLogs.create( logInsertData );
|
|
73
|
+
let sectionList = [];
|
|
74
|
+
if ( inputBody.sections.length ) {
|
|
75
|
+
for ( let i = 0; i < inputBody?.sections?.length; i++ ) {
|
|
76
|
+
let section = inputBody.sections[i];
|
|
77
|
+
section.questions.forEach( ( section ) => {
|
|
78
|
+
if ( section.questionReferenceImage && section.questionReferenceImage !='' ) {
|
|
79
|
+
let imgUrl = decodeURIComponent( section.questionReferenceImage.split( '?' )[0] );
|
|
80
|
+
let url = imgUrl.split( '/' );
|
|
81
|
+
url.splice( 0, 3 );
|
|
82
|
+
section.questionReferenceImage = url.join( '/' );
|
|
83
|
+
}
|
|
84
|
+
section.answers.forEach( ( answer ) => {
|
|
85
|
+
if ( answer.referenceImage != '' ) {
|
|
86
|
+
let imgUrl = decodeURIComponent( answer.referenceImage.split( '?' )[0] );
|
|
87
|
+
let url = imgUrl.split( '/' );
|
|
88
|
+
url.splice( 0, 3 );
|
|
89
|
+
answer.referenceImage = url.join( '/' );
|
|
90
|
+
}
|
|
91
|
+
} );
|
|
92
|
+
} );
|
|
93
|
+
|
|
94
|
+
for ( let [ index, question ] of section.questions.entries() ) {
|
|
95
|
+
await processNested( index, question );
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function processNested( qIdx, question, nestedIndex=-1 ) {
|
|
99
|
+
if ( question?.answers?.length ) {
|
|
100
|
+
for ( let [ index, answer ] of question?.answers?.entries() ) {
|
|
101
|
+
if ( !section.questions[qIdx].answers[index]?.nestedQuestion && nestedIndex == -1 ) {
|
|
102
|
+
section.questions[qIdx].answers[index].nestedQuestion = [];
|
|
103
|
+
}
|
|
104
|
+
if ( answer.showLinked ) {
|
|
105
|
+
if ( nestedIndex != -1 ) {
|
|
106
|
+
section.questions[qIdx].answers[nestedIndex].nestedQuestion.push( answer.linkedQuestion );
|
|
107
|
+
} else {
|
|
108
|
+
section.questions[qIdx].answers[index].nestedQuestion.push( answer.linkedQuestion );
|
|
109
|
+
}
|
|
110
|
+
let nestedLinkedQuestion = section.questions.find( ( item ) => item.qno == answer.linkedQuestion );
|
|
111
|
+
if ( nestedLinkedQuestion ) {
|
|
112
|
+
let findNestedAnswers = nestedLinkedQuestion.answers.find( ( item ) => item.showLinked );
|
|
113
|
+
if ( findNestedAnswers ) {
|
|
114
|
+
if ( nestedIndex != -1 ) {
|
|
115
|
+
await processNested( qIdx, nestedLinkedQuestion, nestedIndex );
|
|
116
|
+
} else {
|
|
117
|
+
await processNested( qIdx, nestedLinkedQuestion, index );
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
sectionList.push( {
|
|
127
|
+
section: section?.name || 'Section 1',
|
|
128
|
+
createdBy: req.user._id,
|
|
129
|
+
createdByName: req.user.userName,
|
|
130
|
+
client_id: req.body.clientId,
|
|
131
|
+
checkListId: checkListId,
|
|
132
|
+
question: section.questions,
|
|
133
|
+
checkList: inputBody.checklistName,
|
|
134
|
+
} );
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if ( req.body._id ) {
|
|
138
|
+
await taskQuestionService.deleteMany( { checkListId: checkListId } );
|
|
139
|
+
}
|
|
140
|
+
await taskQuestionService.insertMany( sectionList );
|
|
141
|
+
let message = req.body?._id ? 'Task Updated Successfully' : 'Task Created Successfully';
|
|
142
|
+
return res.sendSuccess( { checklistId: checkListId, message: message } );
|
|
143
|
+
} else {
|
|
144
|
+
if ( inputBody.submitType == 'save' ) {
|
|
145
|
+
return res.sendSuccess( { checklistId: checkListId, message: message } );
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} catch ( e ) {
|
|
150
|
+
logger.error( { functionName: 'createTask', error: e } );
|
|
151
|
+
return res.sendError( e, 500 );
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export async function deleteTask( req, res ) {
|
|
156
|
+
try {
|
|
157
|
+
let taskDetails = await taskService.findOne( { _id: req.params.taskId }, { isdeleted: 1 } );
|
|
158
|
+
if ( !taskDetails ) {
|
|
159
|
+
return res.sendError( 'No data found', 204 );
|
|
160
|
+
}
|
|
161
|
+
taskDetails.isdeleted = true;
|
|
162
|
+
taskDetails.save().then( async () => {
|
|
163
|
+
await taskAssignService.updateMany( { checkListId: req.params.taskId }, { isdeleted: true } );
|
|
164
|
+
await taskQuestionService.updateMany( { checkListId: req.params.taskId }, { isdeleted: true } );
|
|
165
|
+
return res.sendSuccess( 'Task Deleted Successfully' );
|
|
166
|
+
} ).catch( ( e ) => {
|
|
167
|
+
logger.error( { functionName: 'deleteTask', error: e } );
|
|
168
|
+
return res.sendError( e, 500 );
|
|
169
|
+
} );
|
|
170
|
+
} catch ( e ) {
|
|
171
|
+
logger.error( { functionName: 'deleteTask', error: e } );
|
|
172
|
+
return res.sendError( e, 500 );
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export async function taskDetails( req, res ) {
|
|
177
|
+
try {
|
|
178
|
+
let result = {};
|
|
179
|
+
let sectionList = [];
|
|
180
|
+
let storechecklistdetails;
|
|
181
|
+
let query = {};
|
|
182
|
+
|
|
183
|
+
if ( !req.query.taskId ) {
|
|
184
|
+
return res.sendError( { message: 'Task Id is required' }, 400 );
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if ( !req.query.clientId ) {
|
|
188
|
+
return res.sendError( { message: 'Client Id is required' }, 400 );
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
query._id = req.query.taskId,
|
|
192
|
+
query.client_id = req.query.clientId;
|
|
193
|
+
|
|
194
|
+
storechecklistdetails = await taskService.findOne( query );
|
|
195
|
+
|
|
196
|
+
if ( !storechecklistdetails ) {
|
|
197
|
+
return res.sendError( 'No data found', 204 );
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
query = {
|
|
201
|
+
checkListId: storechecklistdetails._id,
|
|
202
|
+
isdeleted: false,
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
let questionDetails = await taskQuestionService.find( query );
|
|
206
|
+
if ( questionDetails.length ) {
|
|
207
|
+
let sections = [];
|
|
208
|
+
let bucket = JSON.parse( process.env.BUCKET );
|
|
209
|
+
questionDetails.forEach( ( item ) => {
|
|
210
|
+
item.question.forEach( async ( question ) => {
|
|
211
|
+
if ( question.questionReferenceImage && question.questionReferenceImage !='' ) {
|
|
212
|
+
let inputData = {
|
|
213
|
+
Bucket: bucket.sop,
|
|
214
|
+
file_path: decodeURIComponent( question.questionReferenceImage ),
|
|
215
|
+
};
|
|
216
|
+
question.questionReferenceImage = await signedUrl( inputData );
|
|
217
|
+
}
|
|
218
|
+
question.answers.forEach( async ( answer ) => {
|
|
219
|
+
if ( answer.referenceImage != '' ) {
|
|
220
|
+
let inputData = {
|
|
221
|
+
Bucket: bucket.sop,
|
|
222
|
+
file_path: decodeURIComponent( answer.referenceImage ),
|
|
223
|
+
};
|
|
224
|
+
answer.referenceImage = await signedUrl( inputData );
|
|
225
|
+
}
|
|
226
|
+
} );
|
|
227
|
+
} );
|
|
228
|
+
sections.push( {
|
|
229
|
+
id: item._id,
|
|
230
|
+
name: item.section,
|
|
231
|
+
questions: item.question,
|
|
232
|
+
} );
|
|
233
|
+
} );
|
|
234
|
+
sectionList = sections;
|
|
235
|
+
}
|
|
236
|
+
if ( storechecklistdetails ) {
|
|
237
|
+
result.checkListDetails = { ...storechecklistdetails._doc };
|
|
238
|
+
let removedUsers = await taskAssignService.find( { checkFlag: false, checkListId: storechecklistdetails._id }, { _id: 1 } );
|
|
239
|
+
removedUsers = removedUsers?.map( ( item ) => item._id );
|
|
240
|
+
result.checkListDetails = { ...result.checkListDetails, ...{ sections: sectionList }, ...{ removedUsers: removedUsers } };
|
|
241
|
+
}
|
|
242
|
+
return res.sendSuccess( result );
|
|
243
|
+
} catch ( e ) {
|
|
244
|
+
logger.error( { functionName: 'taskDetails', error: e } );
|
|
245
|
+
return res.sendError( e, 500 );
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export async function validateUser( req, res ) {
|
|
250
|
+
try {
|
|
251
|
+
if ( !req.body.assignedUsers.length ) {
|
|
252
|
+
return res.sendError( 'Please Enter User Details', 400 );
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
let users = req.body.assignedUsers;
|
|
256
|
+
let userEmail = [];
|
|
257
|
+
let storeId = [];
|
|
258
|
+
let domainExists = [];
|
|
259
|
+
|
|
260
|
+
const duplicateStore = users.reduce( ( acc, obj ) => {
|
|
261
|
+
if ( !acc[obj.storeName.toLowerCase()] ) {
|
|
262
|
+
acc[obj.storeName.toLowerCase()] = {
|
|
263
|
+
email: [ obj.userEmail.toLowerCase() ],
|
|
264
|
+
count: 1,
|
|
265
|
+
};
|
|
266
|
+
} else {
|
|
267
|
+
if ( acc[obj.storeName.toLowerCase()] ) {
|
|
268
|
+
if ( acc[obj.storeName.toLowerCase()].email.includes( obj.userEmail.toLowerCase() ) ) {
|
|
269
|
+
acc[obj.storeName.toLowerCase()].count++;
|
|
270
|
+
} else {
|
|
271
|
+
acc[obj.storeName.toLowerCase()].email.push( obj.userEmail.toLowerCase() );
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return acc;
|
|
276
|
+
}, {} );
|
|
277
|
+
|
|
278
|
+
const duplicateStores = Object.keys( duplicateStore ).filter( ( storeName ) => duplicateStore[storeName].count > 1 );
|
|
279
|
+
if ( duplicateStores.length ) {
|
|
280
|
+
return res.sendSuccess( { validate: false, ExistsEmail: duplicateStores, message: 'Store and email are duplicated' } );
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if ( !req.body?.addUser ) {
|
|
284
|
+
await Promise.all( users.map( async ( chunk ) => {
|
|
285
|
+
await processUser( [ chunk ] );
|
|
286
|
+
} ) );
|
|
287
|
+
|
|
288
|
+
if ( userEmail.length || storeId.length || domainExists.length ) {
|
|
289
|
+
if ( userEmail.length ) {
|
|
290
|
+
let data = [];
|
|
291
|
+
let alreadyExist = [];
|
|
292
|
+
for ( let user of userEmail ) {
|
|
293
|
+
let checkExistEmail = await userService.findOne( { email: user.userEmail } );
|
|
294
|
+
if ( checkExistEmail ) {
|
|
295
|
+
alreadyExist.push( user.userEmail );
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if ( alreadyExist.length ) {
|
|
299
|
+
let email = [ ...new Set( alreadyExist ) ];
|
|
300
|
+
return res.sendError( `${email.join()} - email already exist`, 500 );
|
|
301
|
+
} else {
|
|
302
|
+
userEmail.forEach( ( item ) => {
|
|
303
|
+
data.push( {
|
|
304
|
+
userName: item.userName,
|
|
305
|
+
email: item.userEmail,
|
|
306
|
+
mobileNumber: '',
|
|
307
|
+
clientId: req.body.clientId,
|
|
308
|
+
} );
|
|
309
|
+
} );
|
|
310
|
+
await Promise.all( data.map( async ( chunk ) => {
|
|
311
|
+
await createUser( chunk );
|
|
312
|
+
} ) );
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return res.sendSuccess( { validate: false, user: userEmail, store: storeId, domain: domainExists } );
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
let id = await uploadUser( req, res );
|
|
319
|
+
if ( id ) {
|
|
320
|
+
return res.sendSuccess( { validate: true, id } );
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async function processUser( data ) {
|
|
324
|
+
await Promise.all( data.map( async ( item ) => {
|
|
325
|
+
let email = item.userEmail.toLowerCase();
|
|
326
|
+
let query = [
|
|
327
|
+
{
|
|
328
|
+
$project: {
|
|
329
|
+
newEmail: { $toLower: '$email' },
|
|
330
|
+
isActive: 1,
|
|
331
|
+
clientId: 1,
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
$match: {
|
|
336
|
+
newEmail: email,
|
|
337
|
+
isActive: true,
|
|
338
|
+
clientId: req.body.clientId,
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
];
|
|
342
|
+
let userDetails = await userService.aggregate( query );
|
|
343
|
+
if ( !userDetails.length ) {
|
|
344
|
+
// let checkDomain = item.userEmail.split( '@' )[1].toLowerCase();
|
|
345
|
+
// let brandDomainExists = await domainService.findOne( { domain: { $regex: checkDomain } } );
|
|
346
|
+
// if ( !brandDomainExists ) {
|
|
347
|
+
// domainExists.push( { message: 'Domain is not exists', email: item.userEmail } );
|
|
348
|
+
// }
|
|
349
|
+
let filteredEmail = userEmail.find( ( ele ) => ele.userEmail.toLowerCase() == item.userEmail.toLowerCase() );
|
|
350
|
+
if ( !filteredEmail ) {
|
|
351
|
+
userEmail.push( { userName: item.userName, userEmail: item.userEmail } );
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
let storeName = item.storeName.toLowerCase();
|
|
355
|
+
let storeQuery = [
|
|
356
|
+
{
|
|
357
|
+
$project: {
|
|
358
|
+
'storeName': { $toLower: '$storeName' },
|
|
359
|
+
'clientId': 1,
|
|
360
|
+
'storeProfile.city': 1,
|
|
361
|
+
'status': 1,
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
$match: {
|
|
366
|
+
clientId: req.body.clientId,
|
|
367
|
+
storeName: storeName,
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
];
|
|
371
|
+
let storeExists = await storeService.aggregate( storeQuery );
|
|
372
|
+
if ( !storeExists.length ) {
|
|
373
|
+
storeId.push( { store: item.storeName, message: '' } );
|
|
374
|
+
}
|
|
375
|
+
if ( storeExists.length && !storeExists[0]?.storeProfile?.city && !item.city ) {
|
|
376
|
+
storeId.push( { store: item.storeName, message: 'city is required' } );
|
|
377
|
+
}
|
|
378
|
+
if ( storeExists.length && storeExists[0].status != 'active' ) {
|
|
379
|
+
storeId.push( { store: item.storeName, message: 'store is inactive' } );
|
|
380
|
+
}
|
|
381
|
+
} ) );
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
if ( req.body.hasOwnProperty( 'delete' ) ) {
|
|
385
|
+
let checkExists = await taskAssignService.findOne( { userEmail: req.body.assignedUsers[0].userEmail, storeName: req.body.assignedUsers[0].storeName } );
|
|
386
|
+
if ( checkExists ) {
|
|
387
|
+
return res.sendSuccess( 'User already exists' );
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
let id = await uploadUser( req, res );
|
|
392
|
+
if ( id ) {
|
|
393
|
+
return res.sendSuccess( { validate: true, id } );
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
} catch ( e ) {
|
|
397
|
+
logger.error( { functionName: 'validateUser 2=>', error: e } );
|
|
398
|
+
return res.sendSuccess( e );
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
async function uploadUser( req, res ) {
|
|
403
|
+
try {
|
|
404
|
+
let inputBody = req.body;
|
|
405
|
+
let checklistDetails;
|
|
406
|
+
let assignedList = [];
|
|
407
|
+
checklistDetails = await taskService.findOne( { _id: inputBody.id, isdeleted: false } );
|
|
408
|
+
if ( !checklistDetails ) {
|
|
409
|
+
return res.sendError( 'No data found', 204 );
|
|
410
|
+
}
|
|
411
|
+
if ( inputBody.assignedUsers.length ) {
|
|
412
|
+
if ( !inputBody.hasOwnProperty( 'delete' ) ) {
|
|
413
|
+
await taskAssignService.deleteMany( { checkListId: inputBody.id, client_id: req.body.clientId } );
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
await Promise.all( inputBody.assignedUsers.map( async ( chunk ) => {
|
|
417
|
+
await insertUsers( chunk );
|
|
418
|
+
} ) );
|
|
419
|
+
|
|
420
|
+
await taskAssignService.insertMany( assignedList );
|
|
421
|
+
let storeList = assignedList.map( ( store ) => store.store_id );
|
|
422
|
+
let storeCount = storeList.length;
|
|
423
|
+
let locationCount;
|
|
424
|
+
if ( storeList.length ) {
|
|
425
|
+
let query = [
|
|
426
|
+
{
|
|
427
|
+
$match: {
|
|
428
|
+
'client_id': req.body.clientId,
|
|
429
|
+
'id': { $in: storeList },
|
|
430
|
+
'storeProfile.city': { $exists: true },
|
|
431
|
+
'status': 'active',
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
$group: {
|
|
436
|
+
_id: '$storeProfile.city',
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
$project: {
|
|
441
|
+
'_id': 0,
|
|
442
|
+
'storeProfile.city': '$_id',
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
];
|
|
446
|
+
let storeDetails = await storeService.aggregate( query );
|
|
447
|
+
locationCount = storeDetails.length;
|
|
448
|
+
}
|
|
449
|
+
await taskService.updateOne( { _id: inputBody.id }, { storeCount: storeCount, locationCount: locationCount } );
|
|
450
|
+
return inputBody.id;
|
|
451
|
+
|
|
452
|
+
async function insertUsers( data ) {
|
|
453
|
+
let user = data;
|
|
454
|
+
let storeName = user.storeName.toLowerCase();
|
|
455
|
+
let email = user.userEmail.toLowerCase();
|
|
456
|
+
let query = [
|
|
457
|
+
{
|
|
458
|
+
$project: {
|
|
459
|
+
newEmail: { $toLower: '$email' },
|
|
460
|
+
isActive: 1,
|
|
461
|
+
email: 1,
|
|
462
|
+
mobileNumber: 1,
|
|
463
|
+
userName: 1,
|
|
464
|
+
clientId: 1,
|
|
465
|
+
},
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
$match: {
|
|
469
|
+
newEmail: email,
|
|
470
|
+
isActive: true,
|
|
471
|
+
clientId: req.body.clientId,
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
];
|
|
475
|
+
let getUserDetails = await userService.aggregate( query );
|
|
476
|
+
let storeQuery = [
|
|
477
|
+
{
|
|
478
|
+
$project: {
|
|
479
|
+
store: { $toLower: '$storeName' },
|
|
480
|
+
clientId: 1,
|
|
481
|
+
storeId: 1,
|
|
482
|
+
storeProfile: 1,
|
|
483
|
+
storeName: 1,
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
$match: {
|
|
488
|
+
clientId: req.body.clientId,
|
|
489
|
+
store: storeName,
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
];
|
|
493
|
+
let storeDetails = await storeService.aggregate( storeQuery );
|
|
494
|
+
|
|
495
|
+
if ( !storeDetails[0].storeProfile?.city ) {
|
|
496
|
+
let city = user.city;
|
|
497
|
+
await storeService.updateOne( { storeName: storeDetails[0].storeName }, { 'storeProfile.city': city } );
|
|
498
|
+
storeDetails = await storeService.aggregate( storeQuery );
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
let storeId = storeDetails[0].storeId;
|
|
502
|
+
if ( getUserDetails[0]._id ) {
|
|
503
|
+
let userDetails = {
|
|
504
|
+
store_id: storeId,
|
|
505
|
+
storeName: storeDetails[0]?.storeName ? storeDetails[0].storeName : user.storeName,
|
|
506
|
+
userId: getUserDetails[0]._id,
|
|
507
|
+
userEmail: getUserDetails[0]?.email ? getUserDetails[0]?.email : user.userEmail,
|
|
508
|
+
userName: getUserDetails[0]?.userName ? getUserDetails[0]?.userName : user.userName,
|
|
509
|
+
userPhone: getUserDetails[0]?.mobileNumber ? getUserDetails[0].mobileNumber : user.userPhone,
|
|
510
|
+
city: storeDetails[0]?.storeProfile?.city,
|
|
511
|
+
country: storeDetails[0]?.storeProfile?.country,
|
|
512
|
+
checkFlag: true,
|
|
513
|
+
checkListId: inputBody.id,
|
|
514
|
+
checkListName: checklistDetails.checkListName,
|
|
515
|
+
client_id: req.body.clientId,
|
|
516
|
+
};
|
|
517
|
+
assignedList.push( userDetails );
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
} catch ( e ) {
|
|
522
|
+
logger.error( { functionName: 'upload User', error: e } );
|
|
523
|
+
return res.sendError( e, 500 );
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export async function userDetails( req, res ) {
|
|
528
|
+
try {
|
|
529
|
+
if ( !req.query.taskId ) {
|
|
530
|
+
return res.sendError( { message: 'Task Id is required' }, 400 );
|
|
531
|
+
}
|
|
532
|
+
let limit = parseInt( req.query.limit ) || 5;
|
|
533
|
+
let page = parseInt( req.query.offset ) || 0;
|
|
534
|
+
let skip = limit * page;
|
|
535
|
+
|
|
536
|
+
let query = [ { $match: { checkListId: new ObjectId( req.query.taskId ) } } ];
|
|
537
|
+
if ( req.query?.search?.trim() && req.query?.search?.trim() != '' ) {
|
|
538
|
+
let searchValue = req.query.search;
|
|
539
|
+
searchValue = searchValue.split( ',' ).map( ( item ) => item.trim().toLowerCase() );
|
|
540
|
+
if ( searchValue.length > 1 ) {
|
|
541
|
+
query.push( { $addFields: { storeLower: { $toLower: '$storeName' } } } );
|
|
542
|
+
query.push( { $match: { storeLower: { $in: searchValue } } } );
|
|
543
|
+
} else {
|
|
544
|
+
query.push( { $match: { storeName: { $regex: req.query.search.trim(), $options: 'i' } } } );
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
query.push( {
|
|
549
|
+
$facet: {
|
|
550
|
+
data: [
|
|
551
|
+
{ $skip: skip }, { $limit: limit },
|
|
552
|
+
],
|
|
553
|
+
count: [
|
|
554
|
+
{ $count: 'total' },
|
|
555
|
+
],
|
|
556
|
+
},
|
|
557
|
+
} );
|
|
558
|
+
|
|
559
|
+
let taskDetails = await taskAssignService.aggregate( query );
|
|
560
|
+
|
|
561
|
+
if ( !taskDetails[0].data.length ) {
|
|
562
|
+
return res.sendError( 'No data found', 204 );
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
let userDetails = [];
|
|
566
|
+
taskDetails[0].data.forEach( ( item ) => {
|
|
567
|
+
userDetails.push( {
|
|
568
|
+
id: item._id,
|
|
569
|
+
userName: item.userName,
|
|
570
|
+
userEmail: item.userEmail,
|
|
571
|
+
store_id: item.store_id,
|
|
572
|
+
storeName: item.storeName,
|
|
573
|
+
userPhone: item.userPhone,
|
|
574
|
+
city: item.city,
|
|
575
|
+
checkFlag: item.checkFlag,
|
|
576
|
+
} );
|
|
577
|
+
} );
|
|
578
|
+
return res.sendSuccess( { users: userDetails, count: taskDetails[0].count[0].total } );
|
|
579
|
+
} catch ( e ) {
|
|
580
|
+
logger.error( { functionName: 'userDetails', error: e } );
|
|
581
|
+
return res.sendError( e, 500 );
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
export async function taskConfig( req, res ) {
|
|
586
|
+
try {
|
|
587
|
+
let inputBody = req.body;
|
|
588
|
+
let storeCount = 0;
|
|
589
|
+
let locationCount = 0;
|
|
590
|
+
let checklistDetails;
|
|
591
|
+
if ( !inputBody._id ) {
|
|
592
|
+
return res.sendError( { message: 'Task Id is Required' }, 400 );
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if ( inputBody.submitType == 'publish' ) {
|
|
596
|
+
let checkUserAssigned = await taskAssignService.findOne( { checkListId: inputBody._id, checkFlag: true } );
|
|
597
|
+
if ( !checkUserAssigned ) {
|
|
598
|
+
return res.sendError( { message: 'Please assign a user' }, 400 );
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
let logInsertData = {
|
|
603
|
+
action: inputBody.submitType == 'publish' ? 'checklistPublishUsingConfigPage' : 'checklistConfigDraft',
|
|
604
|
+
checklistId: inputBody._id,
|
|
605
|
+
checkListName: inputBody?.checkListName,
|
|
606
|
+
createdBy: req.user._id,
|
|
607
|
+
createdByName: req.user.userName,
|
|
608
|
+
client_id: req.body.client_id,
|
|
609
|
+
};
|
|
610
|
+
await checklistLogs.create( logInsertData );
|
|
611
|
+
|
|
612
|
+
checklistDetails = await taskService.findOne( { _id: inputBody._id, isdeleted: false } );
|
|
613
|
+
|
|
614
|
+
if ( !checklistDetails ) {
|
|
615
|
+
return res.sendError( 'No data found', 204 );
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
let configDetails = { ...req.body };
|
|
619
|
+
configDetails.scheduleEndTimeISO = dayjs.utc( configDetails.scheduleEndTime, 'hh:mm A' ).format();
|
|
620
|
+
|
|
621
|
+
let response = await taskService.updateOne( { _id: inputBody._id }, configDetails );
|
|
622
|
+
if ( inputBody?.approver.length ) {
|
|
623
|
+
let data = [];
|
|
624
|
+
let existEmail = await traxApprover.find( { checkListId: inputBody._id, isDeleted: false } );
|
|
625
|
+
let mailList = existEmail.map( ( item ) => item.userEmail );
|
|
626
|
+
existEmail = inputBody?.approver.filter( ( item ) => mailList.includes( item.value ) ).map( ( item ) => item.value );
|
|
627
|
+
let userMailList = inputBody?.approver.map( ( ele ) => ele.value );
|
|
628
|
+
inputBody?.approver.forEach( ( ele ) => {
|
|
629
|
+
if ( !existEmail.includes( ele.value ) ) {
|
|
630
|
+
data.push( {
|
|
631
|
+
userEmail: ele.value,
|
|
632
|
+
checkListId: inputBody._id,
|
|
633
|
+
type: 'task',
|
|
634
|
+
client_id: req.body.client_id,
|
|
635
|
+
} );
|
|
636
|
+
}
|
|
637
|
+
} );
|
|
638
|
+
|
|
639
|
+
await traxApprover.updateMany( { checkListId: inputBody._id, userEmail: { $nin: userMailList } }, { isDeleted: true } );
|
|
640
|
+
if ( data.length ) {
|
|
641
|
+
await traxApprover.insertMany( data );
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
await taskAssignService.updateMany( { checkListId: inputBody._id }, { checkFlag: true } );
|
|
645
|
+
if ( inputBody.removedUsers.length ) {
|
|
646
|
+
await taskAssignService.updateMany( { _id: { $in: inputBody.removedUsers } }, { checkFlag: false } );
|
|
647
|
+
}
|
|
648
|
+
let storeDetails = await taskAssignService.find( { checkListId: inputBody._id, checkFlag: true }, { _id: 0, store_id: 1, userEmail: 1 } );
|
|
649
|
+
let storeList = storeDetails.map( ( store ) => store.store_id );
|
|
650
|
+
|
|
651
|
+
storeCount = storeList.length;
|
|
652
|
+
if ( storeList.length ) {
|
|
653
|
+
let query = [
|
|
654
|
+
{
|
|
655
|
+
$match: {
|
|
656
|
+
client_id: req.body.clientId,
|
|
657
|
+
id: { $in: storeList },
|
|
658
|
+
city: { $exists: true },
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
$group: {
|
|
663
|
+
_id: '$city',
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
$project: {
|
|
668
|
+
_id: 0,
|
|
669
|
+
city: '$_id',
|
|
670
|
+
},
|
|
671
|
+
},
|
|
672
|
+
];
|
|
673
|
+
let storeDetails = await storeService.aggregate( query );
|
|
674
|
+
locationCount = storeDetails.length;
|
|
675
|
+
}
|
|
676
|
+
await taskService.updateOne( { _id: inputBody._id }, { storeCount, locationCount } );
|
|
677
|
+
if ( inputBody.submitType == 'publish' ) {
|
|
678
|
+
let currentDate = dayjs.utc().format();
|
|
679
|
+
let updatedscheduleEndTimeISO = dayjs( checklistDetails?.scheduleDate ).format( 'YYYY-MM-DD' ) + ' ' + checklistDetails.scheduleEndTime;
|
|
680
|
+
updatedscheduleEndTimeISO = dayjs.utc( updatedscheduleEndTimeISO, 'YYYY-MM-DD hh:mm A' ).format();
|
|
681
|
+
if ( updatedscheduleEndTimeISO >= currentDate ) {
|
|
682
|
+
let deleteQuery = {
|
|
683
|
+
$and: [
|
|
684
|
+
{ date_string: dayjs().format( 'YYYY-MM-DD' ) },
|
|
685
|
+
{ sourceCheckList_id: new ObjectId( req.params.checklistId ) },
|
|
686
|
+
{ scheduleEndTime_iso: { $gt: currentDate } },
|
|
687
|
+
],
|
|
688
|
+
};
|
|
689
|
+
deleteQuery.$and.push( { checklistStatus: { $ne: 'submit' } } );
|
|
690
|
+
await taskProcessedService.deleteMany( deleteQuery );
|
|
691
|
+
await insertSingleProcessData( inputBody._id );
|
|
692
|
+
} else {
|
|
693
|
+
logger.info( `Schudled End Time Breached Checklist publish true => Checklist Name: ${checklistDetails.checkListName}` );
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
futureDaysDataRemove( currentDate, req.params.checklistId );
|
|
697
|
+
}
|
|
698
|
+
if ( response?.modifiedCount || response?.matchedCount || response?.upsertedCount ) {
|
|
699
|
+
return res.sendSuccess( { id: inputBody._id, message: 'Configuration Updated Successfully' } );
|
|
700
|
+
}
|
|
701
|
+
if ( inputBody.submitType == 'save' ) {
|
|
702
|
+
if ( response?.modifiedCount || response?.matchedCount || response?.upsertedCount ) {
|
|
703
|
+
return res.sendSuccess( { message: 'Configuration Updated Successfully' } );
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
} catch ( e ) {
|
|
707
|
+
logger.error( { functionName: 'updateConfigure =>', error: e } );
|
|
708
|
+
return res.sendError( e, 500 );
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
export async function insertSingleProcessData( checklistId ) {
|
|
713
|
+
try {
|
|
714
|
+
let currentdate = new Date();
|
|
715
|
+
let date = dayjs( currentdate ).format();
|
|
716
|
+
let getCLconfig = await taskService.findOne( { _id: new ObjectId( checklistId ), publish: true } );
|
|
717
|
+
if ( getCLconfig ) {
|
|
718
|
+
let startTimeIso; let endTimeIso;
|
|
719
|
+
let endDate = dayjs( getCLconfig?.scheduleDate ).format( 'YYYY-MM-DD' ) + ' ' + getCLconfig.scheduleEndTime;
|
|
720
|
+
endDate = dayjs.utc( endDate, 'YYYY-MM-DD hh:mm A' ).format();
|
|
721
|
+
if ( endDate >= date ) {
|
|
722
|
+
if ( dayjs( getCLconfig?.scheduleDate ).format( 'YYYY-MM-DD' ) != dayjs( currentdate ).format( 'YYYY-MM-DD' ) ) {
|
|
723
|
+
getCLconfig.scheduleEndTime = '11:59 PM';
|
|
724
|
+
}
|
|
725
|
+
} else {
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
startTimeIso = dayjs.utc( '12:00 AM', 'hh:mm A' );
|
|
730
|
+
endTimeIso = dayjs.utc( getCLconfig.scheduleEndTime, 'hh:mm A' );
|
|
731
|
+
let insertdata = {};
|
|
732
|
+
insertdata.date_iso = startTimeIso.format();
|
|
733
|
+
insertdata.date_string = dayjs( currentdate ).format( 'YYYY-MM-DD' );
|
|
734
|
+
insertdata.sourceCheckList_id = getCLconfig._id;
|
|
735
|
+
insertdata.checkListName = getCLconfig.checkListName;
|
|
736
|
+
insertdata.publish = getCLconfig.publish;
|
|
737
|
+
insertdata.scheduleStartTime = '12:00 AM';
|
|
738
|
+
insertdata.scheduleStartTime_iso = startTimeIso.format();
|
|
739
|
+
insertdata.scheduleEndTime = getCLconfig.scheduleEndTime;
|
|
740
|
+
insertdata.scheduleEndTime_iso = endTimeIso.format();
|
|
741
|
+
insertdata.allowedOverTime = false;
|
|
742
|
+
insertdata.allowedStoreLocation = getCLconfig.allowedStoreLocation;
|
|
743
|
+
insertdata.client_id = getCLconfig.client_id;
|
|
744
|
+
insertdata.createdBy = new ObjectId( getCLconfig.createdBy );
|
|
745
|
+
insertdata.createdByName = getCLconfig.createdByName;
|
|
746
|
+
insertdata.checkListType = getCLconfig.checkListType;
|
|
747
|
+
insertdata.storeCount = getCLconfig.storeCount;
|
|
748
|
+
insertdata.questionCount = getCLconfig.questionCount;
|
|
749
|
+
insertdata.publishDate = getCLconfig.publishDate;
|
|
750
|
+
insertdata.locationCount = getCLconfig.locationCount;
|
|
751
|
+
insertdata.allowedMultiSubmit = false;
|
|
752
|
+
insertdata.scheduleRepeatedType = 'daily';
|
|
753
|
+
let collectSections = [];
|
|
754
|
+
let sectionQuery = [];
|
|
755
|
+
sectionQuery.push( {
|
|
756
|
+
$match: {
|
|
757
|
+
checkListId: new ObjectId( checklistId ),
|
|
758
|
+
isdeleted: false,
|
|
759
|
+
},
|
|
760
|
+
} );
|
|
761
|
+
let getSections = await taskQuestionService.aggregate( sectionQuery );
|
|
762
|
+
if ( getSections.length ) {
|
|
763
|
+
if ( getSections.length ) {
|
|
764
|
+
for ( let element3 of getSections ) {
|
|
765
|
+
let collectQuestions = {};
|
|
766
|
+
collectQuestions.section_id = element3._id;
|
|
767
|
+
collectQuestions.sectionName = element3.section;
|
|
768
|
+
collectQuestions.questions = element3.question;
|
|
769
|
+
collectSections.push( collectQuestions );
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
insertdata.questionAnswers = collectSections;
|
|
773
|
+
insertdata.updatedAt = new Date();
|
|
774
|
+
let insertdataquery = {};
|
|
775
|
+
insertdataquery.date_string = insertdata.date_string;
|
|
776
|
+
insertdataquery.date_iso = insertdata.date_iso;
|
|
777
|
+
insertdataquery.client_id = insertdata.client_id;
|
|
778
|
+
insertdataquery.sourceCheckList_id = insertdata.sourceCheckList_id;
|
|
779
|
+
let updatedchecklist;
|
|
780
|
+
let checklistDetails = await taskProcessedConfigService.findOne( insertdataquery );
|
|
781
|
+
if ( !checklistDetails ) {
|
|
782
|
+
updatedchecklist = await taskProcessedConfigService.insert( insertdata );
|
|
783
|
+
} else {
|
|
784
|
+
await taskProcessedConfigService.updateOne( { _id: checklistDetails._id }, insertdata );
|
|
785
|
+
updatedchecklist = checklistDetails;
|
|
786
|
+
}
|
|
787
|
+
if ( updatedchecklist ) {
|
|
788
|
+
insertPCBulkV3( getCLconfig, checklistId, currentdate, updatedchecklist, date, startTimeIso, endTimeIso, insertdata );
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return true;
|
|
793
|
+
} catch ( error ) {
|
|
794
|
+
logger.error( 'PCLchecklistCreationValidator error =>', error );
|
|
795
|
+
return false;
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
async function insertPCBulkV3( getCLconfig, checklistId, currentdate, updatedchecklist, date, startTimeIso, endTimeIso, insertdata ) {
|
|
800
|
+
let getquestionQuery = [];
|
|
801
|
+
getquestionQuery.push( {
|
|
802
|
+
$match: {
|
|
803
|
+
checkListId: new ObjectId( checklistId ),
|
|
804
|
+
checkFlag: true,
|
|
805
|
+
isdeleted: false,
|
|
806
|
+
...( getCLconfig?.reinitiate ) ? { reinitiate: true } : {},
|
|
807
|
+
},
|
|
808
|
+
} );
|
|
809
|
+
let allQuestion = await taskAssignService.aggregate( getquestionQuery );
|
|
810
|
+
if ( allQuestion ) {
|
|
811
|
+
let userIdList = [];
|
|
812
|
+
for ( let element4 of allQuestion ) {
|
|
813
|
+
let query;
|
|
814
|
+
query = {
|
|
815
|
+
date_string: date,
|
|
816
|
+
sourceCheckList_id: getCLconfig._id,
|
|
817
|
+
$or: [ {
|
|
818
|
+
checklistStatus: { $in: [ 'submit' ] } },
|
|
819
|
+
{ submitTime: { $exists: true } },
|
|
820
|
+
],
|
|
821
|
+
userId: element4.userId,
|
|
822
|
+
store_id: element4.store_id,
|
|
823
|
+
};
|
|
824
|
+
let getsubmitDetails = await taskProcessedService.find( query );
|
|
825
|
+
if ( getsubmitDetails.length ) {
|
|
826
|
+
userIdList.push( element4._id );
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
829
|
+
delete element4._id;
|
|
830
|
+
delete element4.checkFlag;
|
|
831
|
+
delete element4.isdeleted;
|
|
832
|
+
delete element4.createdAt;
|
|
833
|
+
delete element4.updatedAt;
|
|
834
|
+
element4.checkListId = updatedchecklist._id;
|
|
835
|
+
element4.checkListName = getCLconfig.checkListName;
|
|
836
|
+
element4.date_iso = startTimeIso.format();
|
|
837
|
+
element4.date_string = dayjs( currentdate ).format( 'YYYY-MM-DD' );
|
|
838
|
+
element4.allowedOverTime = false;
|
|
839
|
+
element4.allowedStoreLocation = getCLconfig.allowedStoreLocation;
|
|
840
|
+
element4.scheduleStartTime = '12:00 AM';
|
|
841
|
+
element4.scheduleStartTime_iso = startTimeIso.format();
|
|
842
|
+
element4.scheduleEndTime = getCLconfig.scheduleEndTime;
|
|
843
|
+
element4.scheduleEndTime_iso = endTimeIso.format();
|
|
844
|
+
element4.createdBy = new ObjectId( getCLconfig.createdBy );
|
|
845
|
+
element4.createdByName = getCLconfig.createdByName;
|
|
846
|
+
element4.sourceCheckList_id = getCLconfig._id;
|
|
847
|
+
element4.checkListType = getCLconfig.checkListType;
|
|
848
|
+
element4.storeCount = getCLconfig.storeCount;
|
|
849
|
+
element4.questionCount = getCLconfig.questionCount;
|
|
850
|
+
element4.publishDate = getCLconfig.publishDate;
|
|
851
|
+
element4.locationCount = getCLconfig.locationCount;
|
|
852
|
+
element4.scheduleRepeatedType = 'daily';
|
|
853
|
+
}
|
|
854
|
+
if ( userIdList.length ) {
|
|
855
|
+
allQuestion = allQuestion.filter( ( item ) => typeof item._id == 'undefined' );
|
|
856
|
+
}
|
|
857
|
+
if ( allQuestion ) {
|
|
858
|
+
let assigndeletequery = {};
|
|
859
|
+
assigndeletequery.date_string = insertdata.date_string;
|
|
860
|
+
assigndeletequery.date_iso = insertdata.date_iso;
|
|
861
|
+
assigndeletequery.client_id = insertdata.client_id;
|
|
862
|
+
assigndeletequery.brandId = insertdata.brandId;
|
|
863
|
+
assigndeletequery.checkListId = updatedchecklist._id;
|
|
864
|
+
assigndeletequery.checklistStatus = { $nin: [ 'submit' ] };
|
|
865
|
+
await taskProcessedService.deleteMany( assigndeletequery );
|
|
866
|
+
await taskProcessedService.insertMany( allQuestion );
|
|
867
|
+
logger.info( { function: 'insertPCBulk_v3', query: assigndeletequery } );
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
async function futureDaysDataRemove( currentDate, checklistId ) {
|
|
873
|
+
// //Delete Future Datas////
|
|
874
|
+
let futureDataDeleteQuery = {
|
|
875
|
+
$and: [
|
|
876
|
+
{ date_iso: { $gt: currentDate } },
|
|
877
|
+
{ sourceCheckList_id: new ObjectId( checklistId ) },
|
|
878
|
+
],
|
|
879
|
+
};
|
|
880
|
+
await taskProcessedConfigService.deleteMany( futureDataDeleteQuery );
|
|
881
|
+
futureDataDeleteQuery.$and.push( { checklistStatus: { $ne: 'submit' } } );
|
|
882
|
+
await taskProcessedService.deleteMany( futureDataDeleteQuery );
|
|
883
|
+
logger.info( { function: 'futureDaysDataRemove', query: futureDataDeleteQuery } );
|
|
884
|
+
// ///////////////////////////////
|
|
885
|
+
return true;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
export async function uploadImage( req, res ) {
|
|
889
|
+
try {
|
|
890
|
+
let imgUrl;
|
|
891
|
+
if ( typeof req.files.file == 'undefined' ) {
|
|
892
|
+
return res.sendError( { message: 'Please upload a file' }, 400 );
|
|
893
|
+
}
|
|
894
|
+
req.files.file.name = req.files.file.name.replace( /\s/g, '' );
|
|
895
|
+
let name = req.files.file.name.split( '.' )[0];
|
|
896
|
+
let imageFormat = req.files.file.name.split( '.' )[1];
|
|
897
|
+
|
|
898
|
+
let bucket = JSON.parse( process.env.BUCKET );
|
|
899
|
+
|
|
900
|
+
let params = {
|
|
901
|
+
fileName: `/${name}_${( Date.now() )}.${imageFormat}`,
|
|
902
|
+
Key: `task`,
|
|
903
|
+
Bucket: bucket.sop,
|
|
904
|
+
ContentType: req.files.file.mimetype,
|
|
905
|
+
body: req.files.file.data,
|
|
906
|
+
};
|
|
907
|
+
imgUrl = await fileUpload( params );
|
|
908
|
+
|
|
909
|
+
let inputData = {
|
|
910
|
+
Bucket: bucket.sop,
|
|
911
|
+
file_path: imgUrl.Key,
|
|
912
|
+
};
|
|
913
|
+
imgUrl = await signedUrl( inputData );
|
|
914
|
+
if ( !imgUrl ) {
|
|
915
|
+
return res.sendError( { message: 'Something went wrong' }, 500 );
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
return res.sendSuccess( { message: 'Uploaded Successfully', imgUrl: imgUrl } );
|
|
919
|
+
} catch ( e ) {
|
|
920
|
+
logger.error( 'uploadImage =>', e );
|
|
921
|
+
return res.sendError( e, 500 );
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
async function createUser( data ) {
|
|
926
|
+
try {
|
|
927
|
+
let params = {
|
|
928
|
+
userName: data.userName,
|
|
929
|
+
email: data.email,
|
|
930
|
+
mobileNumber: data?.mobileNumber || '',
|
|
931
|
+
clientId: data.clientId,
|
|
932
|
+
role: 'user',
|
|
933
|
+
password: '5dqFKAJj29PsV6P+kL+3Dw==',
|
|
934
|
+
isActive: true,
|
|
935
|
+
};
|
|
936
|
+
let response = await userService.create( params );
|
|
937
|
+
return response._id;
|
|
938
|
+
} catch ( e ) {
|
|
939
|
+
logger.error( 'createUser =>', e );
|
|
940
|
+
return false;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
export async function reinitiateTask( req, res ) {
|
|
945
|
+
try {
|
|
946
|
+
let taskDetails = await taskService.findOne( { _id: req.body.taskId, isDeleted: false } );
|
|
947
|
+
if ( !taskDetails ) {
|
|
948
|
+
return res.sendError( 'no data found', 204 );
|
|
949
|
+
}
|
|
950
|
+
let data = {};
|
|
951
|
+
data.scheduleDate = req.body.scheduleDate;
|
|
952
|
+
data.scheduleEndTime = req.body.scheduleEndTime;
|
|
953
|
+
data.scheduleEndTimeISO = dayjs.utc( req.body.scheduleEndTime, 'hh:mm A' ).format();
|
|
954
|
+
data.allowedStoreLocation = req.body.allowedStoreLocation;
|
|
955
|
+
data.approver = req.body.approver;
|
|
956
|
+
data.priorityType = req.body.priorityType;
|
|
957
|
+
data.restrictAttendance = req.body.restrictAttendance;
|
|
958
|
+
data.reinitiate = true;
|
|
959
|
+
|
|
960
|
+
if ( req.body?.approver.length ) {
|
|
961
|
+
let data = [];
|
|
962
|
+
let existEmail = await traxApprover.find( { checkListId: req.body.taskId, isDeleted: false } );
|
|
963
|
+
let mailList = existEmail.map( ( item ) => item.userEmail );
|
|
964
|
+
existEmail = req.body?.approver.filter( ( item ) => mailList.includes( item.value ) ).map( ( item ) => item.value );
|
|
965
|
+
let userMailList = req.body?.approver.map( ( ele ) => ele.value );
|
|
966
|
+
req.body?.approver.forEach( ( ele ) => {
|
|
967
|
+
if ( !existEmail.includes( ele.value ) ) {
|
|
968
|
+
data.push( {
|
|
969
|
+
userEmail: ele.value,
|
|
970
|
+
checkListId: req.body.taskId,
|
|
971
|
+
type: 'task',
|
|
972
|
+
client_id: req.body.client_id,
|
|
973
|
+
} );
|
|
974
|
+
}
|
|
975
|
+
} );
|
|
976
|
+
|
|
977
|
+
await traxApprover.updateMany( { checkListId: req.body.taskId, userEmail: { $nin: userMailList } }, { isDeleted: true } );
|
|
978
|
+
if ( data.length ) {
|
|
979
|
+
await traxApprover.insertMany( data );
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
await taskService.updateOne( { _id: req.body.taskId }, data );
|
|
984
|
+
await taskAssignService.updateOne( { userEmail: req.body.userEmail, storeName: req.body.storeName, checkListId: req.body.taskId }, { reinitiate: true } );
|
|
985
|
+
await insertSingleProcessData( req.body.taskId );
|
|
986
|
+
return res.sendSuccess( 'Task reinitaite SUccessfully' );
|
|
987
|
+
} catch ( e ) {
|
|
988
|
+
logger.error( { functionName: 'reinitiateTask', error: e } );
|
|
989
|
+
return res.sendError( e, 500 );
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
export async function createChecklistTask( req, res ) {
|
|
994
|
+
try {
|
|
995
|
+
let inputBody = req.body;
|
|
996
|
+
let data = {
|
|
997
|
+
checkListName: inputBody.checkListName,
|
|
998
|
+
checkListDescription: inputBody.checkListDescription,
|
|
999
|
+
createdBy: req.user._id,
|
|
1000
|
+
createdByName: req.user.userName,
|
|
1001
|
+
publish: true,
|
|
1002
|
+
questionCount: 1,
|
|
1003
|
+
storeCount: 1,
|
|
1004
|
+
scheduleDate: inputBody?.scheduleDate || dayjs().format( 'YYYY-MM-DD' ),
|
|
1005
|
+
scheduleEndTime: inputBody?.scheduleEndTime || '11:59 PM',
|
|
1006
|
+
scheduleEndTimeISO: dayjs.utc( inputBody.scheduleEndTime, 'hh:mm A' ).format(),
|
|
1007
|
+
priorityType: 'high',
|
|
1008
|
+
client_id: inputBody.clientId,
|
|
1009
|
+
checkListType: inputBody.checkListType,
|
|
1010
|
+
publishDate: new Date(),
|
|
1011
|
+
locationCount: 1,
|
|
1012
|
+
referenceCheckListId: inputBody?.checkListId,
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
let response = await taskService.create( data );
|
|
1016
|
+
|
|
1017
|
+
if ( response?._id ) {
|
|
1018
|
+
if ( inputBody.question[0].questionReferenceImage.length ) {
|
|
1019
|
+
let images = [];
|
|
1020
|
+
inputBody.question[0].questionReferenceImage.forEach( ( ele ) => {
|
|
1021
|
+
let imgUrl = decodeURIComponent( ele.split( '?' )[0] );
|
|
1022
|
+
let url = imgUrl.split( '/' );
|
|
1023
|
+
url.splice( 0, 3 );
|
|
1024
|
+
images.push( url.join( '/' ) );
|
|
1025
|
+
} );
|
|
1026
|
+
inputBody.question[0].questionReferenceImage = images;
|
|
1027
|
+
}
|
|
1028
|
+
let question = {
|
|
1029
|
+
checkListId: response?._id,
|
|
1030
|
+
question: inputBody.question,
|
|
1031
|
+
section: 'Section 1',
|
|
1032
|
+
checkList: inputBody.checkListName,
|
|
1033
|
+
client_id: inputBody.clientId,
|
|
1034
|
+
};
|
|
1035
|
+
await taskQuestionService.create( question );
|
|
1036
|
+
let storeDetails = await storeService.findOne( { storeName: inputBody.storeName }, { storeId: 1, storeProfile: 1 } );
|
|
1037
|
+
if ( !storeDetails ) {
|
|
1038
|
+
return res.sendError( 'No data found', 204 );
|
|
1039
|
+
}
|
|
1040
|
+
let userDetails = {
|
|
1041
|
+
userName: inputBody.userName,
|
|
1042
|
+
userEmail: inputBody.userEmail,
|
|
1043
|
+
store_id: storeDetails.storeId,
|
|
1044
|
+
storeName: inputBody.storeName,
|
|
1045
|
+
city: storeDetails?.storeProfile?.city,
|
|
1046
|
+
checkFlag: true,
|
|
1047
|
+
checkListId: response?._id,
|
|
1048
|
+
checkListName: inputBody.checkListName,
|
|
1049
|
+
client_id: inputBody.clientId,
|
|
1050
|
+
};
|
|
1051
|
+
await taskAssignService.create( userDetails );
|
|
1052
|
+
await insertSingleProcessData( response?._id );
|
|
1053
|
+
return res.sendSuccess( 'Task created successfully' );
|
|
1054
|
+
}
|
|
1055
|
+
} catch ( e ) {
|
|
1056
|
+
logger.error( { functionName: 'createChecklistTask', error: e } );
|
|
1057
|
+
return res.sendError( e, 500 );
|
|
1058
|
+
}
|
|
1059
|
+
}
|