tango-app-api-infra 3.8.1-beta.2 → 3.8.1-beta.21
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 +2 -2
- package/src/controllers/footfallDirectory.controllers.js +1033 -224
- package/src/docs/footfallDirectory.docs.js +166 -12
- package/src/dtos/footfallDirectory.dtos.js +137 -45
- package/src/routes/footfallDirectory.routes.js +7 -7
- package/src/services/camera.service.js +3 -0
- package/src/services/revopDownload.service.js +9 -0
- package/src/validations/footfallDirectory.validation.js +91 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { download, logger } from 'tango-app-api-middleware';
|
|
2
|
-
import { bulkUpdate, getOpenSearchCount, getOpenSearchData, insertWithId, updateOpenSearchData } from 'tango-app-api-middleware/src/utils/openSearch.js';
|
|
1
|
+
import { chunkArray, download, logger, sendMessageToFIFOQueue, sendMessageToQueue } from 'tango-app-api-middleware';
|
|
2
|
+
import { bulkUpdate, getOpenSearchById, getOpenSearchCount, getOpenSearchData, insertWithId, updateOpenSearchData } from 'tango-app-api-middleware/src/utils/openSearch.js';
|
|
3
3
|
import { findOneStore } from '../services/store.service.js';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
|
+
import { countDocumnetsCamera } from '../services/camera.service.js';
|
|
6
|
+
import { findOneRevopDownload, upsertRevopDownload } from '../services/revopDownload.service.js';
|
|
5
7
|
|
|
6
8
|
export async function createTicket( req, res ) {
|
|
7
9
|
try {
|
|
@@ -10,11 +12,12 @@ export async function createTicket( req, res ) {
|
|
|
10
12
|
const getStoreName = await findOneStore( { storeId: inputData.storeId }, { storeName: 1, _id: 0 } );
|
|
11
13
|
inputData.ticketId = 'TE_FDT_' + new Date().valueOf();
|
|
12
14
|
inputData.clientId = inputData?.storeId?.split( '-' )[0];
|
|
13
|
-
inputData.storeName =getStoreName?.storeName;
|
|
15
|
+
inputData.storeName = getStoreName?.storeName;
|
|
14
16
|
inputData.createdAt = new Date();
|
|
15
17
|
inputData.updatedAt = new Date();
|
|
16
|
-
inputData.userName = req
|
|
17
|
-
inputData.
|
|
18
|
+
inputData.userName = req?.user?.userName;
|
|
19
|
+
inputData.email = req?.user?.email;
|
|
20
|
+
inputData.role = req?.user?.role;
|
|
18
21
|
inputData.status = 'open';
|
|
19
22
|
if ( inputData.houseKeepingCount > 0 ) {
|
|
20
23
|
inputData.houseKeepingStatus = 'pending';
|
|
@@ -67,12 +70,19 @@ async function bulkUpdateStatusToPending( indexName, inputData ) {
|
|
|
67
70
|
|
|
68
71
|
// 3. Duplicate Images > data[]
|
|
69
72
|
if ( inputData.duplicateCount > 0 ) {
|
|
73
|
+
let updatedDuplicateImages = [];
|
|
70
74
|
for ( const dup of inputData.duplicateImages || [] ) {
|
|
71
75
|
const id = `${inputData.storeId}_${inputData.dateString}_${dup.timeRange}_${dup.tempId}`;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
dup?.data?.map( ( item ) => {
|
|
77
|
+
updatedDuplicateImages.push( {
|
|
78
|
+
...item,
|
|
79
|
+
status: 'pending',
|
|
80
|
+
} );
|
|
81
|
+
bulkBody.push(
|
|
82
|
+
{ update: { _index: indexName, _id: `${inputData.storeId}_${inputData.dateString}_${item.timeRange}_${item.tempId}` } },
|
|
83
|
+
{ doc: { status: 'pending' } },
|
|
84
|
+
);
|
|
85
|
+
} );
|
|
76
86
|
bulkBody.push(
|
|
77
87
|
{ update: { _index: indexName, _id: id } },
|
|
78
88
|
{ doc: { status: 'pending', duplicateImage: updatedDuplicateImages } },
|
|
@@ -174,120 +184,211 @@ export async function ticketSummary( req, res ) {
|
|
|
174
184
|
|
|
175
185
|
export async function ticketList( req, res ) {
|
|
176
186
|
try {
|
|
177
|
-
// let count = 0;
|
|
178
|
-
// const array =[
|
|
179
|
-
// { A: '3c88e8eb6d499a26d37ca075c390bd2d', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/101' },
|
|
180
|
-
// { A: 'c3dd981f485ccd25221c7da704f35d24', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/101' },
|
|
181
|
-
// { A: 'ee887e5546ab0e96ca0adbf8c2453c8d', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/1001' },
|
|
182
|
-
// { A: 'a59ddeb30d158602d6c672994af2f79a', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/1001' },
|
|
183
|
-
// { A: '1f3318280025f5456262b0322b806940', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/201' },
|
|
184
|
-
// { A: '925a70751a0988793057148b20158186', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/201',
|
|
185
|
-
// }, { A: 'd6d4ab301c322212fb612a7d9661b6be', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/301',
|
|
186
|
-
// }, { A: 'cb09aeedfa5ade043922634eb1c35e46', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/301',
|
|
187
|
-
// }, { A: '58f81e33f66ef7af15424c1dc44e7de1', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/401',
|
|
188
|
-
// }, { A: '7ac8f73f02347d29f6f2bff3c52275f5', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/401',
|
|
189
|
-
// }, { A: '9599acd19a48eb28957ad18e40a0a5b1', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/401',
|
|
190
|
-
// }, { A: '36584a3ce215a5fbd1c0e6535201020c', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/501',
|
|
191
|
-
// }, { A: 'cb7e91870e0a72d4eb691e2618aa5979', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/501',
|
|
192
|
-
// }, { A: 'cd072627e6924df745cba004616ec3c9', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/601',
|
|
193
|
-
// }, { A: 'a5891519a50f68a9d73a774539fe8496', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/601',
|
|
194
|
-
// }, { A: '2008517125b03b1b9a66348e6d017523', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/701',
|
|
195
|
-
// }, { A: '79fc93551b59f9ed07eab48d190ba7f4', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/701',
|
|
196
|
-
// }, { A: '89365abcfc8dc663b26471d81a7f68eb', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/801',
|
|
197
|
-
// }, { A: 'e9fb3b989a245994bd48b97287aad096', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/801',
|
|
198
|
-
// }, { A: '4493fb6dc07611bab03630b154ca2483', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/801',
|
|
199
|
-
// }, { A: 'e31caf56bb86f6e12377db006ac61756', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/901',
|
|
200
|
-
// }, { A: 'fe66c637bc8da296485494e371f67b99', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/901' },
|
|
201
|
-
// ];
|
|
202
|
-
|
|
203
|
-
// for ( const item of array ) {
|
|
204
|
-
// const a = await updateOneCamera( { streamName: item.A, clientId: '370' }, { RTSP: item.B } );
|
|
205
|
-
// count++;
|
|
206
|
-
// logger.info( { aaa: a, count: count } );
|
|
207
|
-
// }
|
|
208
|
-
|
|
209
|
-
// process.exit();
|
|
210
187
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
211
188
|
const inputData = req.query;
|
|
212
189
|
const limit = inputData.limit || 10;
|
|
213
|
-
const
|
|
190
|
+
const offset = inputData.offset == 0 ? 0 : ( inputData.offset - 1 ) * limit || 0;
|
|
191
|
+
const order = inputData?.sortOrder || -1;
|
|
192
|
+
|
|
214
193
|
inputData.clientId = inputData.clientId.split( ',' ); // convert strig to array
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
dateString: {
|
|
226
|
-
gte: inputData.fromDate,
|
|
227
|
-
lte: inputData.toDate,
|
|
228
|
-
format: 'yyyy-MM-dd',
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
],
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
let filter = [
|
|
197
|
+
{
|
|
198
|
+
'range': {
|
|
199
|
+
'dateString': {
|
|
200
|
+
'gte': inputData.fromDate,
|
|
201
|
+
'lte': inputData.toDate,
|
|
202
|
+
'format': 'yyyy-MM-dd',
|
|
203
|
+
},
|
|
233
204
|
},
|
|
234
205
|
},
|
|
235
|
-
|
|
206
|
+
{
|
|
207
|
+
terms: {
|
|
208
|
+
'clientId.keyword': Array.isArray( inputData.clientId ) ?
|
|
209
|
+
inputData.clientId :
|
|
210
|
+
[ inputData.clientId ],
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
];
|
|
236
214
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
215
|
+
if ( inputData?.storeId ) {
|
|
216
|
+
filter.push(
|
|
217
|
+
{
|
|
218
|
+
terms: {
|
|
219
|
+
'storeId.keyword': Array.isArray( inputData.storeId ) ?
|
|
220
|
+
inputData.storeId :
|
|
221
|
+
[ inputData.storeId ],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
);
|
|
240
225
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
lte: inputData.toDate,
|
|
255
|
-
format: 'yyyy-MM-dd',
|
|
256
|
-
},
|
|
226
|
+
|
|
227
|
+
let search = {
|
|
228
|
+
'must': filter,
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
if ( inputData.searchValue && inputData.searchValue !== '' ) {
|
|
232
|
+
search = {
|
|
233
|
+
'must': filter,
|
|
234
|
+
'should': [
|
|
235
|
+
{
|
|
236
|
+
'wildcard': {
|
|
237
|
+
'storeName.keyword': {
|
|
238
|
+
'value': `*${inputData.searchValue}*`,
|
|
257
239
|
},
|
|
258
240
|
},
|
|
259
|
-
|
|
260
|
-
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
'wildcard': {
|
|
244
|
+
'storeId.keyword': {
|
|
245
|
+
'value': `*${inputData.searchValue}*`,
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
'wildcard': {
|
|
251
|
+
'ticketId.keyword': {
|
|
252
|
+
'value': `*${inputData.searchValue}*`,
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
'wildcard': {
|
|
258
|
+
'status.keyword': {
|
|
259
|
+
'value': `*${inputData.searchValue}*`,
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
],
|
|
265
|
+
'minimum_should_match': 1,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
let searchQuery = {
|
|
270
|
+
'_source': [
|
|
271
|
+
'storeName',
|
|
272
|
+
'storeId',
|
|
273
|
+
'ticketId',
|
|
274
|
+
'createdAt',
|
|
275
|
+
'updatedAt',
|
|
276
|
+
'footfallCount',
|
|
277
|
+
'duplicateCount',
|
|
278
|
+
'employeeCount',
|
|
279
|
+
'houseKeepingCount',
|
|
280
|
+
'employeeACCount',
|
|
281
|
+
'duplicateACCount',
|
|
282
|
+
'houseKeepingACCount',
|
|
283
|
+
'status',
|
|
284
|
+
'dateString',
|
|
285
|
+
],
|
|
286
|
+
'from': offset,
|
|
287
|
+
'size': limit,
|
|
288
|
+
'query': {
|
|
289
|
+
'bool': search,
|
|
261
290
|
},
|
|
262
|
-
|
|
291
|
+
'sort': [
|
|
292
|
+
{ dateString: { order: 'desc' } },
|
|
293
|
+
],
|
|
263
294
|
};
|
|
264
295
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
for ( const item of response ) {
|
|
273
|
-
temp.push( {
|
|
274
|
-
'Store Name': item.storeName,
|
|
275
|
-
'Store ID': item.storeId,
|
|
276
|
-
'Ticket ID': item.ticketId,
|
|
277
|
-
'Ticket raised on': dayjs( item.createdAt ).format( 'dd MMM, yyyy' ),
|
|
278
|
-
'Total Footfalls': item.footfallCount,
|
|
279
|
-
'Duplicates': item.duplicateCount,
|
|
280
|
-
'Employee/Staff': item.employeeCount,
|
|
281
|
-
'HouseKeeping': item.houseKeepingCount,
|
|
282
|
-
'Revised Footfalls': item.footfallCount-( item.duplicateCount+item.employeeCount+item.houseKeepingCount ),
|
|
283
|
-
'Status': item.status,
|
|
284
|
-
} );
|
|
296
|
+
if ( inputData.sortBy && inputData.sortBy !== '' ) {
|
|
297
|
+
let sortByValue = '';
|
|
298
|
+
|
|
299
|
+
if ( [ 'storeName', 'storeId', 'ticketId', 'status' ].includes( inputData?.sortBy ) ) {
|
|
300
|
+
sortByValue = `${inputData.sortBy}.keyword`;
|
|
301
|
+
} else {
|
|
302
|
+
sortByValue = inputData.sortBy;
|
|
285
303
|
}
|
|
286
|
-
|
|
287
|
-
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
searchQuery = {
|
|
307
|
+
'_source': [
|
|
308
|
+
'storeName',
|
|
309
|
+
'storeId',
|
|
310
|
+
'ticketId',
|
|
311
|
+
'createdAt',
|
|
312
|
+
'updatedAt',
|
|
313
|
+
'footfallCount',
|
|
314
|
+
'duplicateCount',
|
|
315
|
+
'employeeCount',
|
|
316
|
+
'houseKeepingCount',
|
|
317
|
+
'status',
|
|
318
|
+
'employeeACCount',
|
|
319
|
+
'duplicateACCount',
|
|
320
|
+
'houseKeepingACCount',
|
|
321
|
+
'dateString',
|
|
322
|
+
],
|
|
323
|
+
'from': offset,
|
|
324
|
+
'size': limit,
|
|
325
|
+
'query': {
|
|
326
|
+
'bool': search,
|
|
327
|
+
},
|
|
328
|
+
'sort': [
|
|
329
|
+
{ [sortByValue]: { order: order === -1 ? 'desc' : 'asc' } },
|
|
330
|
+
],
|
|
331
|
+
};
|
|
288
332
|
}
|
|
289
333
|
|
|
290
|
-
|
|
334
|
+
if ( inputData.isExport == true ) {
|
|
335
|
+
searchQuery = {
|
|
336
|
+
'_source': [
|
|
337
|
+
'storeName',
|
|
338
|
+
'storeId',
|
|
339
|
+
'ticketId',
|
|
340
|
+
'createdAt',
|
|
341
|
+
'updatedAt',
|
|
342
|
+
'footfallCount',
|
|
343
|
+
'duplicateCount',
|
|
344
|
+
'employeeACCount',
|
|
345
|
+
'duplicateACCount',
|
|
346
|
+
'employeeCount',
|
|
347
|
+
'houseKeepingACCount',
|
|
348
|
+
'houseKeepingCount',
|
|
349
|
+
'status',
|
|
350
|
+
'dateString',
|
|
351
|
+
],
|
|
352
|
+
'from': 0,
|
|
353
|
+
'size': 10000,
|
|
354
|
+
'query': {
|
|
355
|
+
'bool': search,
|
|
356
|
+
},
|
|
357
|
+
'sort': [
|
|
358
|
+
{ 'storeName.keyword': { order: 'desc' } },
|
|
359
|
+
],
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
const getData = await getOpenSearchData( openSearch.footfallDirectory, searchQuery );
|
|
363
|
+
const count = getData?.body?.hits?.total?.value;
|
|
364
|
+
if ( !count || count == 0 ) {
|
|
365
|
+
return res.sendError( 'No data found', 204 );
|
|
366
|
+
}
|
|
367
|
+
const searchValue = getData?.body?.hits?.hits;
|
|
368
|
+
if ( !searchValue || searchValue?.length == 0 ) {
|
|
369
|
+
return res.sendError( 'No data found', 204 );
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if ( inputData.isExport == true ) {
|
|
373
|
+
const exportData = [];
|
|
374
|
+
for ( const item of searchValue ) {
|
|
375
|
+
exportData.push( {
|
|
376
|
+
'Store Name': item._source.storeName || '--',
|
|
377
|
+
'Store ID': item._source.storeId,
|
|
378
|
+
'Ticket ID': item._source.ticketId,
|
|
379
|
+
'Ticket raised on': dayjs( item._source.createdAt ).format( 'DD MMM, YYYY' ),
|
|
380
|
+
'Total Footfalls': item._source.footfallCount,
|
|
381
|
+
'Duplicates': item._source.duplicateCount,
|
|
382
|
+
'Employee/Staff': item._source.employeeCount,
|
|
383
|
+
'HouseKeeping': item._source.houseKeepingCount,
|
|
384
|
+
'Revised Footfalls': item._source.footfallCount - ( item._source.duplicateCount + item._source.employeeCount + item._source.houseKeepingCount ),
|
|
385
|
+
'Status': item._source.status,
|
|
386
|
+
'Ticket%': item?._source?.status === 'closed'?Math.round( ( ( item._source.duplicateACCount + item._source.employeeACCount + item._source.houseKeepingACCount )/ item._source.footfallCount )*100 ).toFixed( 0 ) : 'NA',
|
|
387
|
+
} );
|
|
388
|
+
}
|
|
389
|
+
return await download( exportData, res );
|
|
390
|
+
}
|
|
391
|
+
return res.sendSuccess( { result: searchValue, count: count } );
|
|
291
392
|
} catch ( error ) {
|
|
292
393
|
const err = error.message || 'Internal Server Error';
|
|
293
394
|
logger.error( { error: error, messgage: req.query } );
|
|
@@ -299,16 +400,13 @@ export async function getTickets( req, res ) {
|
|
|
299
400
|
try {
|
|
300
401
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
301
402
|
const inputData = req.query;
|
|
302
|
-
const limit = inputData.limit
|
|
303
|
-
const skip= inputData.offset == 0? 0:( inputData.offset - 1 ) *limit || 0;
|
|
403
|
+
const limit = inputData.limit;
|
|
404
|
+
const skip = inputData.offset == 0 ? 0 : ( inputData.offset - 1 ) * limit || 0;
|
|
304
405
|
inputData.storeId = inputData.storeId.split( ',' ); // convert strig to array
|
|
305
406
|
logger.info( { inputData: inputData, limit: limit, skip: skip } );
|
|
407
|
+
let source = [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'employeeCount', 'houseKeepingCount', 'duplicateCount', 'comments', 'employee', 'houseKeeping', 'duplicateImages', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus', 'houseKeepingACCount', 'houseKeepingCount', 'employeeCount', 'employeeACCount', 'duplicateCount', 'duplicateACCount', 'approverRole', 'approverUserName', 'approverEmail' ];
|
|
408
|
+
let filter = [
|
|
306
409
|
|
|
307
|
-
let filter =[
|
|
308
|
-
{ terms: { 'storeId.keyword': Array.isArray( inputData.storeId ) ?
|
|
309
|
-
inputData.storeId :
|
|
310
|
-
inputData.storeId },
|
|
311
|
-
},
|
|
312
410
|
{
|
|
313
411
|
range: {
|
|
314
412
|
dateString: {
|
|
@@ -319,6 +417,26 @@ export async function getTickets( req, res ) {
|
|
|
319
417
|
},
|
|
320
418
|
},
|
|
321
419
|
];
|
|
420
|
+
if ( inputData?.storeId ) {
|
|
421
|
+
filter.push(
|
|
422
|
+
{
|
|
423
|
+
terms: {
|
|
424
|
+
'storeId.keyword': Array.isArray( inputData.storeId ) ?
|
|
425
|
+
inputData.storeId :
|
|
426
|
+
inputData.storeId,
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
if ( inputData?.dateString ) {
|
|
432
|
+
filter.push(
|
|
433
|
+
{
|
|
434
|
+
term: {
|
|
435
|
+
'dateString': inputData.dateString,
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
);
|
|
439
|
+
}
|
|
322
440
|
if ( inputData.status ) {
|
|
323
441
|
filter.push(
|
|
324
442
|
{
|
|
@@ -336,6 +454,32 @@ export async function getTickets( req, res ) {
|
|
|
336
454
|
field: inputData.revopsType,
|
|
337
455
|
},
|
|
338
456
|
} );
|
|
457
|
+
inputData.revopsType === 'employee' ?
|
|
458
|
+
filter.push( {
|
|
459
|
+
range: {
|
|
460
|
+
employeeCount: {
|
|
461
|
+
gt: 0,
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
} ) :
|
|
465
|
+
inputData.revopsType === 'housekeeping' ?
|
|
466
|
+
filter.push( {
|
|
467
|
+
range: {
|
|
468
|
+
housekeepingCount: {
|
|
469
|
+
gt: 0,
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
} ) :
|
|
473
|
+
filter.push( {
|
|
474
|
+
range: {
|
|
475
|
+
duplicateCount: {
|
|
476
|
+
gt: 0,
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
} );
|
|
480
|
+
source = inputData.revopsType == 'employee' ? [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'employeeCount', 'comments', 'employee', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus', 'houseKeepingACCount', 'houseKeepingCount', 'employeeCount', 'employeeACCount', 'duplicateCoun', 'duplicateACCount', 'approverRole', 'approverUserName', 'approverEmail' ] :
|
|
481
|
+
inputData.revopsType == 'houseKeeping' ? [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'houseKeepingCount', 'comments', 'houseKeeping', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus', 'houseKeepingACCount', 'houseKeepingCount', 'employeeCount', 'employeeACCount', 'duplicateCount', 'duplicateACCount', 'approverRole', 'approverUserName', 'approverEmail' ] :
|
|
482
|
+
inputData.revopsType == 'duplicateImages' ? [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'duplicateCount', 'comments', 'duplicateImages', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus', 'houseKeepingACCount', 'houseKeepingCount', 'employeeCount', 'employeeACCount', 'duplicateCount', 'duplicateACCount', 'approverRole', 'approverUserName', 'approverEmail' ] : [];
|
|
339
483
|
}
|
|
340
484
|
|
|
341
485
|
if ( inputData.action ) {
|
|
@@ -343,27 +487,52 @@ export async function getTickets( req, res ) {
|
|
|
343
487
|
bool: {
|
|
344
488
|
should: [
|
|
345
489
|
{
|
|
346
|
-
|
|
347
|
-
'houseKeepingStatus.keyword': inputData.action,
|
|
490
|
+
constant_score: {
|
|
491
|
+
filter: { term: { 'houseKeepingStatus.keyword': inputData.action } },
|
|
492
|
+
boost: 1,
|
|
493
|
+
_name: 'matched_housekeeping',
|
|
348
494
|
},
|
|
349
495
|
},
|
|
350
496
|
{
|
|
351
|
-
|
|
352
|
-
'employeeStatus.keyword': inputData.action,
|
|
497
|
+
constant_score: {
|
|
498
|
+
filter: { term: { 'employeeStatus.keyword': inputData.action } },
|
|
499
|
+
boost: 1,
|
|
500
|
+
_name: 'matched_employee',
|
|
353
501
|
},
|
|
354
502
|
},
|
|
355
503
|
{
|
|
356
|
-
|
|
357
|
-
'duplicateStatus.keyword': inputData.action,
|
|
504
|
+
constant_score: {
|
|
505
|
+
filter: { term: { 'duplicateStatus.keyword': inputData.action } },
|
|
506
|
+
boost: 1,
|
|
507
|
+
_name: 'matched_duplicate',
|
|
358
508
|
},
|
|
359
509
|
},
|
|
360
510
|
],
|
|
361
|
-
minimum_should_match: 1,
|
|
511
|
+
minimum_should_match: 1,
|
|
362
512
|
},
|
|
363
513
|
} );
|
|
364
514
|
}
|
|
365
515
|
|
|
366
|
-
|
|
516
|
+
|
|
517
|
+
let getRevCount = {};
|
|
518
|
+
if ( inputData.revopsType ) {
|
|
519
|
+
getRevCount = {
|
|
520
|
+
size: 0,
|
|
521
|
+
query: {
|
|
522
|
+
bool: {
|
|
523
|
+
filter: filter,
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
aggs: {
|
|
527
|
+
totalCount: {
|
|
528
|
+
sum: {
|
|
529
|
+
field: inputData.revopsType == 'employee' ? 'employeeCount' : inputData.revopsType == 'houseKeeping' ? 'houseKeepingCount' : 'duplicateCount',
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
const getCount = {
|
|
367
536
|
query: {
|
|
368
537
|
bool: {
|
|
369
538
|
filter: filter,
|
|
@@ -371,8 +540,12 @@ export async function getTickets( req, res ) {
|
|
|
371
540
|
},
|
|
372
541
|
};
|
|
373
542
|
|
|
543
|
+
|
|
374
544
|
const geteDataCount = await getOpenSearchCount( openSearch.footfallDirectory, getCount );
|
|
375
|
-
|
|
545
|
+
const geteRevDataCount = inputData?.revopsType ? await getOpenSearchData( openSearch.footfallDirectory, getRevCount ) : null;
|
|
546
|
+
const revCount = inputData?.revopsType ? geteRevDataCount?.body?.aggregations?.totalCount?.value : 0;
|
|
547
|
+
const count = geteDataCount?.body?.count;
|
|
548
|
+
if ( !geteDataCount || count == 0 ) {
|
|
376
549
|
return res.sendError( 'No data found', 204 );
|
|
377
550
|
}
|
|
378
551
|
|
|
@@ -384,34 +557,88 @@ export async function getTickets( req, res ) {
|
|
|
384
557
|
filter: filter,
|
|
385
558
|
},
|
|
386
559
|
},
|
|
560
|
+
_source: source,
|
|
387
561
|
};
|
|
388
562
|
|
|
389
563
|
const getData = await getOpenSearchData( openSearch.footfallDirectory, getQuery );
|
|
564
|
+
|
|
390
565
|
const response = getData?.body?.hits?.hits;
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
if ( inputData.isExport=== true ) {
|
|
395
|
-
const temp = [];
|
|
396
|
-
for ( const item of response ) {
|
|
397
|
-
temp.push( {
|
|
398
|
-
'Store Name': item.storeName,
|
|
399
|
-
'Store ID': item.storeId,
|
|
400
|
-
'Ticket ID': item.ticketId,
|
|
401
|
-
'Ticket raised on': dayjs( item.createdAt ).format( 'dd MMM, yyyy' ),
|
|
402
|
-
'Total Footfalls': item.footfallCount,
|
|
403
|
-
'Duplicates': item.duplicateCount,
|
|
404
|
-
'Employee/Staff': item.employeeCount,
|
|
405
|
-
'HouseKeeping': item.houseKeepingCount,
|
|
406
|
-
'Revised Footfalls': item.footfallCount-( item.duplicateCount+item.employeeCount+item.houseKeepingCount ),
|
|
407
|
-
'Status': item.status,
|
|
408
|
-
} );
|
|
409
|
-
}
|
|
410
|
-
await download( temp, res );
|
|
411
|
-
return;
|
|
566
|
+
if ( !response || response.length == 0 ) {
|
|
567
|
+
return res.sendError( 'No data', 204 );
|
|
412
568
|
}
|
|
569
|
+
let temp = [];
|
|
570
|
+
if ( inputData?.action ) {
|
|
571
|
+
response.map( ( hit ) => {
|
|
572
|
+
const defaultData = {
|
|
573
|
+
storeId: hit._source.storeId,
|
|
574
|
+
dateString: hit?._source?.dateString,
|
|
575
|
+
ticketName: hit?._source?.ticketName,
|
|
576
|
+
status: hit?._source?.status,
|
|
577
|
+
employeeStatus: hit?._source?.employeeStatus,
|
|
578
|
+
houseKeepingStatus: hit?._source?.houseKeepingStatus,
|
|
579
|
+
duplicateStatus: hit?._source?.duplicateStatus,
|
|
580
|
+
storeName: hit?._source?.storeName,
|
|
581
|
+
ticketId: hit?._source?.ticketId,
|
|
582
|
+
footfallCount: hit?._source?.footfallCount,
|
|
583
|
+
comments: hit?._source?.comments,
|
|
584
|
+
userName: hit?._source?.userName,
|
|
585
|
+
role: hit?._source?.role,
|
|
586
|
+
createdAt: hit?._source?.createdAt,
|
|
587
|
+
updatedAt: hit?._source?.updatedAt,
|
|
588
|
+
tempId: hit?._source?.tempId,
|
|
589
|
+
houseKeepingCount: hit?._source?.houseKeepingCount,
|
|
590
|
+
employeeCount: hit?._source?.employeeCount,
|
|
591
|
+
duplicateCount: hit?._source?.duplicateCount,
|
|
592
|
+
houseKeepingACCount: hit?._source?.houseKeepingACCount,
|
|
593
|
+
employeeACCount: hit?._source?.employeeACCount,
|
|
594
|
+
duplicateACCount: hit?._source?.duplicateACCount,
|
|
595
|
+
approverUserName: hit?._source?.approverUserName,
|
|
596
|
+
approverEmail: hit?._source?.approverEmail,
|
|
597
|
+
approverRole: hit?._source?.approverRole,
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
};
|
|
601
|
+
let result;
|
|
413
602
|
|
|
414
|
-
|
|
603
|
+
const matched = hit.matched_queries;
|
|
604
|
+
// Add only matched data array
|
|
605
|
+
if ( matched.includes( 'matched_employee' )&& ( !inputData.revopsType || inputData.revopsType == 'employee' ) ) {
|
|
606
|
+
result = defaultData;
|
|
607
|
+
result.employee = hit?._source?.employee;
|
|
608
|
+
// result.type = 'employee';
|
|
609
|
+
result.matched = matched;
|
|
610
|
+
}
|
|
611
|
+
if ( matched.includes( 'matched_housekeeping' )&& ( !inputData.revopsType || inputData.revopsType == 'houseKeeping' ) ) {
|
|
612
|
+
result = defaultData;
|
|
613
|
+
result.houseKeeping = hit?._source?.houseKeeping;
|
|
614
|
+
// result.type = 'houseKeeping';
|
|
615
|
+
result.matched = matched;
|
|
616
|
+
}
|
|
617
|
+
if ( matched.includes( 'matched_duplicate' )&& ( !inputData.revopsType || inputData.revopsType == 'duplicateImages' ) ) {
|
|
618
|
+
result = defaultData;
|
|
619
|
+
result.duplicateImages = hit?._source?.duplicateImages;
|
|
620
|
+
// result.type = 'duplicateImages';
|
|
621
|
+
result.matched = matched;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
if ( result ) {
|
|
625
|
+
const nested = [
|
|
626
|
+
{
|
|
627
|
+
_id: hit._id,
|
|
628
|
+
_index: hit._index,
|
|
629
|
+
_score: 0,
|
|
630
|
+
_source: result,
|
|
631
|
+
},
|
|
632
|
+
];
|
|
633
|
+
temp.push( ...nested );
|
|
634
|
+
}
|
|
635
|
+
} );
|
|
636
|
+
}
|
|
637
|
+
const finalResponse = inputData.action ? temp : response;
|
|
638
|
+
if ( finalResponse?.length == 0 || !finalResponse ) {
|
|
639
|
+
return res.sendError( 'No Data found', 204 );
|
|
640
|
+
}
|
|
641
|
+
return res.sendSuccess( { result: finalResponse, count: count, revopCount: revCount } );
|
|
415
642
|
} catch ( error ) {
|
|
416
643
|
const err = error.message || 'Internal Server Error';
|
|
417
644
|
logger.error( { error: error, messgage: req.query } );
|
|
@@ -421,45 +648,274 @@ export async function getTickets( req, res ) {
|
|
|
421
648
|
|
|
422
649
|
export async function updateStatus( req, res ) {
|
|
423
650
|
try {
|
|
651
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
424
652
|
const inputData = req.body;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
653
|
+
let temp = [];
|
|
654
|
+
let result;
|
|
655
|
+
for ( let data of inputData?.data ) {
|
|
656
|
+
result = await updateTicketStatus( data, openSearch, temp, req.user );
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if ( temp.length == inputData?.data?.length ) {
|
|
660
|
+
return res.sendSuccess( 'Ticket has been updated successfully' );
|
|
661
|
+
}
|
|
662
|
+
if ( result == false ) {
|
|
663
|
+
logger.info( { 'Note': `Queue Doesn't send` } );
|
|
664
|
+
}
|
|
665
|
+
} catch ( error ) {
|
|
666
|
+
const err = error.messgae || 'Internal Server Error';
|
|
667
|
+
logger.error( { error: error, data: req.body, function: 'infra-footfallDirectory-updateStatus' } );
|
|
668
|
+
return res.sendError( err, 500 );
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
export async function updateTicketStatus( data, openSearch, temp, user ) {
|
|
672
|
+
const id = data._id;
|
|
673
|
+
const splitId = id.split( '_' );
|
|
674
|
+
const storeId = splitId[0];
|
|
675
|
+
const dateString = splitId[1];
|
|
676
|
+
const {
|
|
677
|
+
duplicateStatus,
|
|
678
|
+
employeeStatus,
|
|
679
|
+
houseKeepingStatus,
|
|
680
|
+
} = data;
|
|
681
|
+
const statusList = [ duplicateStatus, employeeStatus, houseKeepingStatus ];
|
|
682
|
+
// Filter out undefined/null statuses
|
|
683
|
+
const existingStatuses = statusList.filter( ( status ) => status != null );
|
|
684
|
+
|
|
685
|
+
// Check if **none** of the existing statuses are 'pending'
|
|
686
|
+
const allNotPending = existingStatuses.every( ( status ) => status !== 'pending' );
|
|
687
|
+
|
|
688
|
+
if ( allNotPending && existingStatuses.length > 0 ) {
|
|
689
|
+
data.status = 'closed';
|
|
690
|
+
data.approverUserName = user?.userName || '';
|
|
691
|
+
data.approverEmail = user?.email || '';
|
|
692
|
+
data.approverRole = user?.role || '';
|
|
693
|
+
}
|
|
694
|
+
let tempId = [];
|
|
695
|
+
const { _id, ...updateData } = data;
|
|
696
|
+
let getExistingOne = await getOpenSearchById( openSearch.footfallDirectory, _id );
|
|
697
|
+
const source = getExistingOne?.body?._source;
|
|
698
|
+
let bulkBody = [];
|
|
699
|
+
if ( data?.duplicateImages?.length > 0 ) {
|
|
700
|
+
updateData.duplicateImages = await mergeDuplicateImagesWithUncheck( getExistingOne?.body?._source?.duplicateImages, data?.duplicateImages, data?.duplicateStatus );
|
|
701
|
+
logger.info( { updateData: updateData, existeg: getExistingOne?.body?._source?.duplicateImages, sttaus: data?.duplicateStatus } );
|
|
702
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: updateData } );
|
|
703
|
+
for ( let duplicate of updateData?.duplicateImages ) {
|
|
435
704
|
bulkBody.push(
|
|
436
705
|
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${duplicate.timeRange}_${duplicate.tempId}` } },
|
|
437
|
-
{ doc: { duplicateImage: duplicate.
|
|
706
|
+
{ doc: { duplicateImage: duplicate.duplicateImages } },
|
|
438
707
|
);
|
|
439
|
-
duplicate
|
|
708
|
+
duplicate?.data?.map( ( item ) => {
|
|
709
|
+
item.isChecked == true ? tempId.push( { tempId: item.tempId, timeRange: item.timeRange } ) : null;
|
|
440
710
|
bulkBody.push(
|
|
441
711
|
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${item.timeRange}_${item.tempId}` } },
|
|
442
|
-
{ doc: { isChecked: item.isChecked } },
|
|
712
|
+
{ doc: { isChecked: item.isChecked, status: item?.isChecked == true? 'approved':'rejected' } },
|
|
443
713
|
);
|
|
444
714
|
} );
|
|
445
715
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
716
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: { duplicateACCount: tempId?.length || 0 } } );
|
|
717
|
+
}
|
|
718
|
+
if ( data?.employee?.length > 0 ) {
|
|
719
|
+
const updatedEmployee = updateEmployeeCheckFlags(
|
|
720
|
+
source.employee,
|
|
721
|
+
updateData.employee,
|
|
722
|
+
data.employeeStatus,
|
|
723
|
+
);
|
|
724
|
+
updateData.employee = updatedEmployee;
|
|
725
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: updateData } );
|
|
726
|
+
for ( let employee of updateData?.employee ) {
|
|
727
|
+
( employee.isChecked == true ) ? tempId.push( { tempId: employee.tempId, timeRange: employee.timeRange } ) : null;
|
|
728
|
+
bulkBody.push(
|
|
729
|
+
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${employee.timeRange}_${employee.tempId}` } },
|
|
730
|
+
{ doc: { isChecked: employee.isChecked, status: employee?.isChecked == true? 'approved':'rejected' } },
|
|
731
|
+
);
|
|
451
732
|
}
|
|
452
|
-
|
|
733
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: { employeeACCount: tempId?.length || 0 } } );
|
|
734
|
+
}
|
|
735
|
+
if ( data?.houseKeeping?.length > 0 ) {
|
|
736
|
+
const updatedHouseKeeping = updateEmployeeCheckFlags(
|
|
737
|
+
source?.houseKeeping,
|
|
738
|
+
updateData?.houseKeeping,
|
|
739
|
+
data.houseKeepingStatus,
|
|
740
|
+
);
|
|
741
|
+
updateData.houseKeeping = updatedHouseKeeping;
|
|
742
|
+
|
|
743
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: updateData } );
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
for ( let houseKeeping of updateData?.houseKeeping ) {
|
|
747
|
+
houseKeeping.isChecked == true ? tempId.push( { tempId: houseKeeping.tempId, timeRange: houseKeeping.timeRange } ) : null;
|
|
453
748
|
bulkBody.push(
|
|
454
749
|
{ update: { _index: openSearch.revop, _id: `${storeId}_${dateString}_${houseKeeping.timeRange}_${houseKeeping.tempId}` } },
|
|
455
|
-
{ doc: { isChecked: houseKeeping.isChecked } },
|
|
750
|
+
{ doc: { isChecked: houseKeeping.isChecked, status: houseKeeping?.isChecked == true? 'approved':'rejected' } },
|
|
456
751
|
);
|
|
457
752
|
}
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
753
|
+
await updateOpenSearchData( openSearch.footfallDirectory, _id, { doc: { houseKeepingACCount: tempId?.length || 0 } } );
|
|
754
|
+
}
|
|
755
|
+
temp.push( storeId );
|
|
756
|
+
if ( bulkBody.length > 0 ) {
|
|
757
|
+
const res = await bulkUpdate( bulkBody );
|
|
758
|
+
if ( res?.errors ) {
|
|
759
|
+
logger.error( 'Bulk update errors:', res.items );
|
|
760
|
+
return { success: false, errors: res.items };
|
|
761
|
+
} else {
|
|
762
|
+
logger.error( 'Bulk status update successful.' );
|
|
763
|
+
// return { success: true };
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
if ( data.status == 'closed' ) {
|
|
767
|
+
const query = {
|
|
768
|
+
storeId: storeId,
|
|
769
|
+
isVideoStream: true,
|
|
770
|
+
};
|
|
771
|
+
const getStoreType = await countDocumnetsCamera( query );
|
|
772
|
+
const tempIdList = await extractCheckedTempIds( getExistingOne?.body );
|
|
773
|
+
const isSendMessge = await sendSqsMessage( data, tempIdList, getStoreType, storeId );
|
|
774
|
+
if ( isSendMessge ==true ) {
|
|
775
|
+
return true; // res.sendSuccess( 'Ticket has been updated successfully' );
|
|
776
|
+
} else {
|
|
777
|
+
return false; // res.sendError( 'No SQS message sent', 500 );
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
async function extractCheckedTempIds( document ) {
|
|
783
|
+
const source = document?._source || {};
|
|
784
|
+
const result = [];
|
|
785
|
+
|
|
786
|
+
// Employee
|
|
787
|
+
if ( source.employeeACCount > 0 && Array.isArray( source.employee ) ) {
|
|
788
|
+
for ( const emp of source.employee ) {
|
|
789
|
+
if ( emp.isChecked === true ) {
|
|
790
|
+
result.push( { tempId: emp.tempId, timeRange: emp.timeRange } );
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// Housekeeping
|
|
796
|
+
if ( source.houseKeepingACCount > 0 && Array.isArray( source.houseKeeping ) ) {
|
|
797
|
+
for ( const hk of source.houseKeeping ) {
|
|
798
|
+
if ( hk.isChecked === true ) {
|
|
799
|
+
result.push( { tempId: hk.tempId, timeRange: hk.timeRange } );
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// Duplicate Images
|
|
805
|
+
if ( source.duplicateACCount > 0 && Array.isArray( source.duplicateImages ) ) {
|
|
806
|
+
for ( const image of source.duplicateImages ) {
|
|
807
|
+
if ( Array.isArray( image.data ) ) {
|
|
808
|
+
for ( const dup of image.data ) {
|
|
809
|
+
if ( dup.isChecked === true ) {
|
|
810
|
+
result.push( { tempId: dup.tempId, timeRange: dup.timeRange } );
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
return result;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
function updateEmployeeCheckFlags( existingEmployees, inputEmployees, status ) {
|
|
822
|
+
// Step 1: Create a Set of tempIds from input (which are all isChecked: true)
|
|
823
|
+
const checkedTempIds = new Set( inputEmployees.map( ( emp ) => emp.tempId ) );
|
|
824
|
+
|
|
825
|
+
// Step 2: Loop through all existing and update isChecked accordingly
|
|
826
|
+
const updatedEmployees = existingEmployees.map( ( emp ) => ( {
|
|
827
|
+
...emp,
|
|
828
|
+
isChecked: status === 'rejected'? !checkedTempIds.has( emp.tempId ):checkedTempIds.has( emp.tempId ),
|
|
829
|
+
} ) );
|
|
830
|
+
|
|
831
|
+
return updatedEmployees;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
function mergeDuplicateImagesWithUncheck( existingData, inputData, status ) {
|
|
836
|
+
const inputImageMap = new Map();
|
|
837
|
+
|
|
838
|
+
// Step 1: Build map of parentTempId -> Set of selected childTempIds
|
|
839
|
+
for ( const parent of inputData ) {
|
|
840
|
+
const selectedChildIds = new Set(
|
|
841
|
+
( parent.data || [] )
|
|
842
|
+
.filter( ( child ) => child.selected )
|
|
843
|
+
.map( ( child ) => child.tempId ),
|
|
844
|
+
);
|
|
845
|
+
inputImageMap.set( parent.tempId, selectedChildIds );
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Step 2: Merge isChecked correctly per parent-child match
|
|
849
|
+
return existingData.map( ( existingParent ) => {
|
|
850
|
+
const parentTempId = existingParent.tempId;
|
|
851
|
+
|
|
852
|
+
// Get selected children for this specific parent
|
|
853
|
+
const selectedChildIds = inputImageMap.get( parentTempId ) || new Set();
|
|
854
|
+
|
|
855
|
+
const updatedData = ( existingParent.data || [] ).map( ( child ) => {
|
|
856
|
+
return {
|
|
857
|
+
...child,
|
|
858
|
+
isChecked:
|
|
859
|
+
status === 'approved' ? selectedChildIds.has( child.tempId ) : false,
|
|
860
|
+
};
|
|
861
|
+
} );
|
|
862
|
+
|
|
863
|
+
// Also update the parent isChecked if all children are false
|
|
864
|
+
const anyChildChecked = updatedData.some( ( child ) => child.isChecked );
|
|
865
|
+
|
|
866
|
+
return {
|
|
867
|
+
...existingParent,
|
|
868
|
+
isChecked: anyChildChecked,
|
|
869
|
+
data: updatedData,
|
|
870
|
+
};
|
|
871
|
+
} );
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
export async function sendSqsMessage( inputData, tempId, getStoreType, storeId ) {
|
|
876
|
+
const sqs = JSON.parse( process.env.SQS );
|
|
877
|
+
const sqsName = getStoreType > 0? sqs.revopTrackTicket: sqs.revopTicket;
|
|
878
|
+
const sqsProduceQueue = getStoreType > 0 ? {
|
|
879
|
+
QueueUrl: `${sqs.url}${sqsName}`,
|
|
880
|
+
MessageBody: JSON.stringify( {
|
|
881
|
+
store_id: storeId,
|
|
882
|
+
store_date: inputData.dateString.split( '-' ).reverse().join( '-' ),
|
|
883
|
+
bucket_name: '',
|
|
884
|
+
zone_id: 'traffic_zone',
|
|
885
|
+
process_type: 'reduction',
|
|
886
|
+
revop_type: 'footfall',
|
|
887
|
+
temp_id: tempId,
|
|
888
|
+
time: Date.now(),
|
|
889
|
+
} ),
|
|
890
|
+
MessageGroupId: 'revops',
|
|
891
|
+
MessageDeduplicationId: Date.now().toString(),
|
|
892
|
+
} : {
|
|
893
|
+
QueueUrl: `${sqs.url}${sqsName}`,
|
|
894
|
+
MessageBody: JSON.stringify( {
|
|
895
|
+
store_id: storeId,
|
|
896
|
+
store_date: inputData.dateString.split( '-' ).reverse().join( '-' ),
|
|
897
|
+
bucket_name: '',
|
|
898
|
+
zone_id: 'traffic_zone',
|
|
899
|
+
process_type: 'reduction',
|
|
900
|
+
revop_type: 'footfall',
|
|
901
|
+
temp_id: tempId,
|
|
902
|
+
|
|
903
|
+
} ),
|
|
904
|
+
};
|
|
905
|
+
const sqsQueue = getStoreType > 0? await sendMessageToFIFOQueue( sqsProduceQueue ):
|
|
906
|
+
await sendMessageToQueue(
|
|
907
|
+
sqsProduceQueue.QueueUrl,
|
|
908
|
+
sqsProduceQueue.MessageBody,
|
|
909
|
+
|
|
910
|
+
);
|
|
911
|
+
if ( sqsQueue.statusCode ) {
|
|
912
|
+
logger.error( {
|
|
913
|
+
error: `${sqsQueue}`,
|
|
914
|
+
type: 'UPLOAD_ERROR',
|
|
915
|
+
} );
|
|
916
|
+
return false;
|
|
917
|
+
} else {
|
|
918
|
+
return true;
|
|
463
919
|
}
|
|
464
920
|
}
|
|
465
921
|
|
|
@@ -467,89 +923,442 @@ export async function getTaggedStores( req, res ) {
|
|
|
467
923
|
try {
|
|
468
924
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
469
925
|
const inputData = req.query;
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
926
|
+
inputData.clientId = inputData?.clientId?.split( ',' );
|
|
927
|
+
logger.info( { inputData: inputData.clientId } );
|
|
928
|
+
let filter = [
|
|
929
|
+
{
|
|
930
|
+
terms: { 'clientId.keyword': inputData.clientId },
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
range: {
|
|
934
|
+
dateString: {
|
|
935
|
+
gte: inputData.fromDate,
|
|
936
|
+
lte: inputData.toDate,
|
|
937
|
+
format: 'yyyy-MM-dd',
|
|
938
|
+
},
|
|
939
|
+
},
|
|
940
|
+
},
|
|
941
|
+
|
|
942
|
+
{
|
|
943
|
+
exists: {
|
|
944
|
+
field: 'storeId',
|
|
945
|
+
},
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
exists: {
|
|
949
|
+
field: 'storeName',
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
];
|
|
953
|
+
// if ( req?.user?.userType == 'client' && req?.user?.role !== 'superadmin' && req?.stores?.length > 0 ) {
|
|
954
|
+
// filter.push(
|
|
955
|
+
// {
|
|
956
|
+
// terms: { 'storeId.keyword': req.stores },
|
|
957
|
+
// },
|
|
958
|
+
// );
|
|
959
|
+
// }
|
|
960
|
+
filter.push(
|
|
961
|
+
{
|
|
962
|
+
terms: { 'storeId.keyword': req?.stores || [] },
|
|
963
|
+
},
|
|
964
|
+
);
|
|
965
|
+
|
|
966
|
+
if ( inputData.searchValue && inputData.searchValue !== '' ) {
|
|
967
|
+
filter.push( {
|
|
968
|
+
regexp: {
|
|
969
|
+
'storeName': {
|
|
970
|
+
value: `.*${inputData.searchValue.toLowerCase()}.*`,
|
|
971
|
+
flags: 'ALL',
|
|
972
|
+
},
|
|
973
|
+
},
|
|
974
|
+
} );
|
|
975
|
+
}
|
|
976
|
+
const getCount = {
|
|
977
|
+
size: 0,
|
|
475
978
|
query: {
|
|
476
979
|
bool: {
|
|
477
|
-
filter:
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
980
|
+
filter: filter,
|
|
981
|
+
},
|
|
982
|
+
},
|
|
983
|
+
aggs: {
|
|
984
|
+
unique_stores: {
|
|
985
|
+
composite: {
|
|
986
|
+
size: 1000,
|
|
987
|
+
sources: [
|
|
988
|
+
{
|
|
989
|
+
storeId: {
|
|
990
|
+
terms: { field: 'storeId.keyword' },
|
|
991
|
+
},
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
storeName: {
|
|
995
|
+
terms: { field: 'storeName.keyword' },
|
|
487
996
|
},
|
|
488
997
|
},
|
|
998
|
+
],
|
|
999
|
+
},
|
|
1000
|
+
aggs: {
|
|
1001
|
+
totalCount: {
|
|
1002
|
+
sum: {
|
|
1003
|
+
script: {
|
|
1004
|
+
source: `
|
|
1005
|
+
return (doc.containsKey('duplicateCount') ? doc['duplicateCount'].value : 0)
|
|
1006
|
+
+ (doc.containsKey('houseKeepingCount') ? doc['houseKeepingCount'].value : 0)
|
|
1007
|
+
+ (doc.containsKey('employeeCount') ? doc['employeeCount'].value : 0);
|
|
1008
|
+
`,
|
|
1009
|
+
lang: 'painless',
|
|
1010
|
+
},
|
|
1011
|
+
},
|
|
1012
|
+
},
|
|
1013
|
+
},
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
1016
|
+
};
|
|
1017
|
+
|
|
1018
|
+
let temp = [];
|
|
1019
|
+
|
|
1020
|
+
const geteDataCount = await getOpenSearchData( openSearch.footfallDirectory, getCount );
|
|
1021
|
+
if ( !geteDataCount && geteDataCount?.body?.aggregations?.unique_stores?.buckets?.length > 0 ) {
|
|
1022
|
+
return res.sendError( 'No data found', 204 );
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
const response = geteDataCount?.body?.aggregations?.unique_stores?.buckets;
|
|
1026
|
+
const sorted = sortByTotalCount( response, inputData.sortOrder );
|
|
1027
|
+
sorted?.map( ( item ) => temp.push( { storeId: item.key.storeId, storeName: item.key.storeName, totalCount: item?.totalCount?.value } ) );
|
|
1028
|
+
|
|
1029
|
+
if ( response?.length > 0 ) {
|
|
1030
|
+
return res.sendSuccess( { result: temp, count: response?.length } );
|
|
1031
|
+
} else {
|
|
1032
|
+
return res.sendError( 'NO Data', 204 );
|
|
1033
|
+
}
|
|
1034
|
+
} catch ( error ) {
|
|
1035
|
+
const err = error.message || 'Internal Server Error';
|
|
1036
|
+
logger.error( { error: error, messgage: req.query } );
|
|
1037
|
+
return res.sendSuccess( err, 500 );
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
function sortByTotalCount( response, sortOrder = -1 ) {
|
|
1042
|
+
return response.sort( ( a, b ) => {
|
|
1043
|
+
const aVal = a.totalCount.value;
|
|
1044
|
+
const bVal = b.totalCount.value;
|
|
1045
|
+
|
|
1046
|
+
return sortOrder === 1 ? aVal - bVal : bVal - aVal;
|
|
1047
|
+
} );
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
export async function downloadTickets( req, res ) {
|
|
1051
|
+
try {
|
|
1052
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1053
|
+
const inputData = req.query;
|
|
1054
|
+
const limit = inputData.limit;
|
|
1055
|
+
const skip = inputData.offset == 0 ? 0 : ( inputData.offset - 1 ) * limit || 0;
|
|
1056
|
+
inputData.storeId = inputData?.storeId?.split( ',' ); // convert strig to array
|
|
1057
|
+
logger.info( { inputData: inputData, limit: limit, skip: skip } );
|
|
1058
|
+
let source = [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'employeeCount', 'houseKeepingCount', 'duplicateCount', 'comments', 'employee', 'houseKeeping', 'duplicateImages', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus' ];
|
|
1059
|
+
let filter = [
|
|
1060
|
+
|
|
1061
|
+
{
|
|
1062
|
+
range: {
|
|
1063
|
+
dateString: {
|
|
1064
|
+
gte: inputData.fromDate,
|
|
1065
|
+
lte: inputData.toDate,
|
|
1066
|
+
format: 'yyyy-MM-dd',
|
|
1067
|
+
},
|
|
1068
|
+
},
|
|
1069
|
+
},
|
|
1070
|
+
];
|
|
1071
|
+
if ( inputData?.storeId ) {
|
|
1072
|
+
filter.push(
|
|
1073
|
+
{
|
|
1074
|
+
terms: {
|
|
1075
|
+
'storeId.keyword': Array.isArray( inputData.storeId ) ?
|
|
1076
|
+
inputData.storeId :
|
|
1077
|
+
inputData.storeId,
|
|
1078
|
+
},
|
|
1079
|
+
},
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
if ( inputData?.dateString ) {
|
|
1083
|
+
filter.push(
|
|
1084
|
+
{
|
|
1085
|
+
term: {
|
|
1086
|
+
'dateString': inputData.dateString,
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1091
|
+
if ( inputData.status ) {
|
|
1092
|
+
filter.push(
|
|
1093
|
+
{
|
|
1094
|
+
term: {
|
|
1095
|
+
'status.keyword': inputData.status,
|
|
1096
|
+
},
|
|
1097
|
+
},
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
if (
|
|
1101
|
+
inputData.revopsType
|
|
1102
|
+
) {
|
|
1103
|
+
filter.push( {
|
|
1104
|
+
exists: {
|
|
1105
|
+
field: inputData.revopsType,
|
|
1106
|
+
},
|
|
1107
|
+
} );
|
|
1108
|
+
inputData.revopsType === 'employee' ?
|
|
1109
|
+
filter.push( {
|
|
1110
|
+
range: {
|
|
1111
|
+
employeeCount: {
|
|
1112
|
+
gt: 0,
|
|
1113
|
+
},
|
|
1114
|
+
},
|
|
1115
|
+
} ) :
|
|
1116
|
+
inputData.revopsType === 'housekeeping' ?
|
|
1117
|
+
filter.push( {
|
|
1118
|
+
range: {
|
|
1119
|
+
housekeepingCount: {
|
|
1120
|
+
gt: 0,
|
|
1121
|
+
},
|
|
1122
|
+
},
|
|
1123
|
+
} ) :
|
|
1124
|
+
filter.push( {
|
|
1125
|
+
range: {
|
|
1126
|
+
duplicateCount: {
|
|
1127
|
+
gt: 0,
|
|
1128
|
+
},
|
|
1129
|
+
},
|
|
1130
|
+
} );
|
|
1131
|
+
source = inputData.revopsType == 'employee' ? [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'employeeCount', 'comments', 'employee', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus' ] :
|
|
1132
|
+
inputData.revopsType == 'houseKeeping' ? [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'houseKeepingCount', 'comments', 'houseKeeping', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus' ] :
|
|
1133
|
+
inputData.revopsType == 'duplicateImages' ? [ 'storeId', 'dateString', 'ticketName', 'footfallCount', 'duplicateCount', 'comments', 'duplicateImages', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus' ] : [];
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
if ( inputData.action ) {
|
|
1137
|
+
filter.push( {
|
|
1138
|
+
bool: {
|
|
1139
|
+
should: [
|
|
1140
|
+
{
|
|
1141
|
+
constant_score: {
|
|
1142
|
+
filter: { term: { 'houseKeepingStatus.keyword': inputData.action } },
|
|
1143
|
+
boost: 1,
|
|
1144
|
+
_name: 'matched_housekeeping',
|
|
1145
|
+
},
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
constant_score: {
|
|
1149
|
+
filter: { term: { 'employeeStatus.keyword': inputData.action } },
|
|
1150
|
+
boost: 1,
|
|
1151
|
+
_name: 'matched_employee',
|
|
1152
|
+
},
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
constant_score: {
|
|
1156
|
+
filter: { term: { 'duplicateStatus.keyword': inputData.action } },
|
|
1157
|
+
boost: 1,
|
|
1158
|
+
_name: 'matched_duplicate',
|
|
1159
|
+
},
|
|
489
1160
|
},
|
|
490
1161
|
],
|
|
1162
|
+
minimum_should_match: 1,
|
|
1163
|
+
},
|
|
1164
|
+
} );
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
const getCount = {
|
|
1169
|
+
query: {
|
|
1170
|
+
bool: {
|
|
1171
|
+
filter: filter,
|
|
491
1172
|
},
|
|
492
1173
|
},
|
|
493
1174
|
};
|
|
494
1175
|
|
|
1176
|
+
|
|
495
1177
|
const geteDataCount = await getOpenSearchCount( openSearch.footfallDirectory, getCount );
|
|
496
|
-
|
|
1178
|
+
const count = geteDataCount?.body?.count;
|
|
1179
|
+
if ( !geteDataCount || count == 0 ) {
|
|
497
1180
|
return res.sendError( 'No data found', 204 );
|
|
498
1181
|
}
|
|
1182
|
+
|
|
499
1183
|
const getQuery = {
|
|
500
1184
|
size: limit,
|
|
501
1185
|
from: skip,
|
|
502
1186
|
query: {
|
|
503
1187
|
bool: {
|
|
504
|
-
filter:
|
|
505
|
-
{ terms: { 'storeId.keyword': Array.isArray( inputData.storeId ) ?
|
|
506
|
-
inputData.storeId :
|
|
507
|
-
inputData.storeId } },
|
|
508
|
-
{
|
|
509
|
-
range: {
|
|
510
|
-
dateString: {
|
|
511
|
-
gte: inputData.fromDate,
|
|
512
|
-
lte: inputData.toDate,
|
|
513
|
-
format: 'yyyy-MM-dd',
|
|
514
|
-
},
|
|
515
|
-
},
|
|
516
|
-
},
|
|
517
|
-
],
|
|
1188
|
+
filter: filter,
|
|
518
1189
|
},
|
|
519
1190
|
},
|
|
520
|
-
|
|
1191
|
+
_source: source,
|
|
521
1192
|
};
|
|
522
1193
|
|
|
523
1194
|
const getData = await getOpenSearchData( openSearch.footfallDirectory, getQuery );
|
|
1195
|
+
|
|
524
1196
|
const response = getData?.body?.hits?.hits;
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
1197
|
+
if ( !response || response.length == 0 ) {
|
|
1198
|
+
return res.sendError( 'No data', 204 );
|
|
1199
|
+
}
|
|
1200
|
+
let temp = [];
|
|
1201
|
+
if ( inputData?.action ) {
|
|
1202
|
+
response.map( ( hit ) => {
|
|
1203
|
+
const defaultData ={
|
|
1204
|
+
storeId: hit._source.storeId,
|
|
1205
|
+
dateString: hit?._source?.dateString,
|
|
1206
|
+
ticketName: hit?._source?.ticketName,
|
|
1207
|
+
status: hit?._source?.status,
|
|
1208
|
+
employeeStatus: hit?._source?.employeeStatus,
|
|
1209
|
+
houseKeepingStatus: hit?._source?.houseKeepingStatus,
|
|
1210
|
+
duplicateStatus: hit?._source?.duplicateStatus,
|
|
1211
|
+
storeName: hit?._source?.storeName,
|
|
1212
|
+
ticketId: hit?._source?.ticketId,
|
|
1213
|
+
footfallCount: hit?._source?.footfallCount,
|
|
1214
|
+
comments: hit?._source?.comments,
|
|
1215
|
+
userName: hit?._source?.userName,
|
|
1216
|
+
role: hit?._source?.role,
|
|
1217
|
+
createdAt: hit?._source?.createdAt,
|
|
1218
|
+
updatedAt: hit?._source?.updatedAt,
|
|
1219
|
+
tempId: hit?._source?.tempId,
|
|
1220
|
+
};
|
|
1221
|
+
let result;
|
|
1222
|
+
|
|
1223
|
+
const matched = hit.matched_queries;
|
|
1224
|
+
// Add only matched data array
|
|
1225
|
+
if ( matched.includes( 'matched_employee' ) && ( !inputData.revopsType || inputData.revopsType == 'employee' ) ) {
|
|
1226
|
+
logger.info( { revop: inputData.revopsType } );
|
|
1227
|
+
result = defaultData;
|
|
1228
|
+
result.employee = hit?._source?.employee;
|
|
1229
|
+
// result.type = 'employee';
|
|
1230
|
+
result.matched = matched;
|
|
1231
|
+
}
|
|
1232
|
+
if ( matched.includes( 'matched_housekeeping' )&& ( !inputData.revopsType || inputData.revopsType == 'houseKeeping' ) ) {
|
|
1233
|
+
logger.info( { revop: inputData.revopsType } );
|
|
1234
|
+
result = defaultData;
|
|
1235
|
+
result.houseKeeping = hit?._source?.houseKeeping;
|
|
1236
|
+
// result.type = 'houseKeeping';
|
|
1237
|
+
result.matched = matched;
|
|
1238
|
+
}
|
|
1239
|
+
if ( matched.includes( 'matched_duplicate' )&& ( !inputData.revopsType || inputData.revopsType == 'duplicateImages' ) ) {
|
|
1240
|
+
logger.info( { revop: inputData.revopsType } );
|
|
1241
|
+
result = defaultData;
|
|
1242
|
+
result.duplicateImages = hit?._source?.duplicateImages;
|
|
1243
|
+
// result.type = 'duplicateImages';
|
|
1244
|
+
result.matched = matched;
|
|
1245
|
+
}
|
|
1246
|
+
if ( result ) {
|
|
1247
|
+
logger.info( { revop: inputData.revopsType, result: result } );
|
|
1248
|
+
const nested = [
|
|
1249
|
+
{
|
|
1250
|
+
_id: hit._id,
|
|
1251
|
+
_index: hit._index,
|
|
1252
|
+
_score: 0,
|
|
1253
|
+
_source: result,
|
|
1254
|
+
},
|
|
1255
|
+
];
|
|
1256
|
+
|
|
1257
|
+
temp.push( ...nested );
|
|
1258
|
+
}
|
|
1259
|
+
} );
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
const result = inputData.action ? temp : response;
|
|
1263
|
+
|
|
1264
|
+
if ( !result || result?.length == 0 ) {
|
|
1265
|
+
return res.sendError( 'no data', 204 );
|
|
546
1266
|
}
|
|
1267
|
+
let allResults = [];
|
|
1268
|
+
const chunks = await chunkArray( result, 500 );
|
|
547
1269
|
|
|
548
|
-
|
|
1270
|
+
for ( const chunk of chunks ) {
|
|
1271
|
+
const results = await Promise.all( chunk.map( extractTempIds ) );
|
|
1272
|
+
allResults.push( ...results.flat() );
|
|
1273
|
+
}
|
|
1274
|
+
if ( allResults?.length == 0 ) {
|
|
1275
|
+
return res.sendError( 'no data found', 204 );
|
|
1276
|
+
}
|
|
1277
|
+
const query = {
|
|
1278
|
+
stores: { $in: inputData.storeId },
|
|
1279
|
+
fromDate: inputData?.fromDate,
|
|
1280
|
+
toDate: inputData?.toDate,
|
|
1281
|
+
ticketStatus: inputData?.status,
|
|
1282
|
+
ticketAction: inputData?.action,
|
|
1283
|
+
revopsType: inputData?.revopsType,
|
|
1284
|
+
type: 'get-tickets',
|
|
1285
|
+
};
|
|
1286
|
+
const record={
|
|
1287
|
+
stores: inputData?.storeId,
|
|
1288
|
+
fromDate: inputData?.fromDate,
|
|
1289
|
+
toDate: inputData?.toDate,
|
|
1290
|
+
ticketStatus: inputData?.status,
|
|
1291
|
+
ticketAction: inputData?.action,
|
|
1292
|
+
revopsType: inputData?.revopsType,
|
|
1293
|
+
type: 'get-tickets',
|
|
1294
|
+
userEmail: req?.user?.email,
|
|
1295
|
+
};
|
|
1296
|
+
await upsertRevopDownload( query, record );
|
|
1297
|
+
const getId = await findOneRevopDownload( query, { _id: 1, status: 1 } );
|
|
1298
|
+
if ( !getId ) {
|
|
1299
|
+
return res.sendError( 'download record is missing', 400 );
|
|
1300
|
+
}
|
|
1301
|
+
const sqs = JSON.parse( process.env.SQS );
|
|
1302
|
+
const sqsName = getStoreType > 0? sqs.revopTrackTicket: sqs.revopTicket;
|
|
1303
|
+
|
|
1304
|
+
const sqsProduceQueue ={
|
|
1305
|
+
QueueUrl: `${sqs.url}${sqsName}`,
|
|
1306
|
+
MessageBody: JSON.stringify( {
|
|
1307
|
+
_id: getId?._id,
|
|
1308
|
+
data: allResults,
|
|
1309
|
+
|
|
1310
|
+
} ),
|
|
1311
|
+
};
|
|
1312
|
+
const sqsQueue = await sendMessageToQueue(
|
|
1313
|
+
sqsProduceQueue.QueueUrl,
|
|
1314
|
+
sqsProduceQueue.MessageBody,
|
|
1315
|
+
|
|
1316
|
+
);
|
|
1317
|
+
if ( sqsQueue.statusCode ) {
|
|
1318
|
+
logger.error( {
|
|
1319
|
+
error: `${sqsQueue}`,
|
|
1320
|
+
type: 'UPLOAD_ERROR',
|
|
1321
|
+
} );
|
|
1322
|
+
return false;
|
|
1323
|
+
}
|
|
1324
|
+
return res.sendSuccess( { result: { status: getId?.status, outputFilePath: getId?.outputFilePath } } );
|
|
549
1325
|
} catch ( error ) {
|
|
550
1326
|
const err = error.message || 'Internal Server Error';
|
|
551
|
-
logger.error( { error: error, messgage: req.query } );
|
|
1327
|
+
logger.error( { error: error, messgage: req.query, function: 'downloadTickets-infra-footfallDirectory' } );
|
|
552
1328
|
return res.sendSuccess( err, 500 );
|
|
553
1329
|
}
|
|
554
1330
|
}
|
|
555
1331
|
|
|
1332
|
+
async function extractTempIds( document ) {
|
|
1333
|
+
logger.info( { document: document } );
|
|
1334
|
+
const source = document?._source || {};
|
|
1335
|
+
const result = [];
|
|
1336
|
+
|
|
1337
|
+
// Employee
|
|
1338
|
+
if ( Array.isArray( source.employee ) ) {
|
|
1339
|
+
for ( const emp of source.employee ) {
|
|
1340
|
+
result.push( emp.filePath );
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// Housekeeping
|
|
1345
|
+
if ( Array.isArray( source.houseKeeping ) ) {
|
|
1346
|
+
for ( const hk of source.houseKeeping ) {
|
|
1347
|
+
result.push( hk.filePath );
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// Duplicate Images
|
|
1352
|
+
if ( Array.isArray( source.duplicateImages ) ) {
|
|
1353
|
+
for ( const image of source.duplicateImages ) {
|
|
1354
|
+
if ( Array.isArray( image.data ) ) {
|
|
1355
|
+
for ( const dup of image.data ) {
|
|
1356
|
+
result.push( dup.filePath );
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
return result;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
|