tango-app-api-infra 3.9.5-vms.70 → 3.9.5-vms.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -302,7 +302,7 @@ export async function tangoReviewTicket( req, res ) {
|
|
|
302
302
|
} else if ( revised < tangoReview ) {
|
|
303
303
|
// If ticket is closed, do not proceed with revision mapping
|
|
304
304
|
|
|
305
|
-
record.status = '
|
|
305
|
+
record.status = 'Open - Accuracy Issue';
|
|
306
306
|
// Only keep or modify mappingInfo items with type "review"
|
|
307
307
|
if ( Array.isArray( record.mappingInfo ) ) {
|
|
308
308
|
const temp = record.mappingInfo
|
|
@@ -322,14 +322,14 @@ export async function tangoReviewTicket( req, res ) {
|
|
|
322
322
|
|
|
323
323
|
record.mappingInfo = [ ...ticketData?.[0]?._source?.mappingInfo.slice( 0, -1 ),
|
|
324
324
|
...temp ];
|
|
325
|
-
if ( Array.isArray( record.mappingInfo ) ) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
325
|
+
// if ( Array.isArray( record.mappingInfo ) ) {
|
|
326
|
+
// record.mappingInfo = record.mappingInfo.map( ( item ) => {
|
|
327
|
+
// return {
|
|
328
|
+
// ...item,
|
|
329
|
+
// status: 'Closed',
|
|
330
|
+
// };
|
|
331
|
+
// } );
|
|
332
|
+
// }
|
|
333
333
|
// If no review mapping existed, push a new one
|
|
334
334
|
// if ( record.mappingInfo.length === 0 ) {
|
|
335
335
|
// record.mappingInfo.push( {
|
|
@@ -445,7 +445,170 @@ export async function tangoReviewTicket( req, res ) {
|
|
|
445
445
|
}
|
|
446
446
|
} catch ( error ) {
|
|
447
447
|
const err = error.message || 'Internal Server Error';
|
|
448
|
-
logger.error( { error:
|
|
448
|
+
logger.error( { error: error, funtion: 'tangoReviewTicket' } );
|
|
449
|
+
return res.sendError( err, 500 );
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export async function tangoReviewAccuracyClosedTicket( req, res ) {
|
|
454
|
+
try {
|
|
455
|
+
const inputData = req.body;
|
|
456
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
457
|
+
|
|
458
|
+
let findQuery = {
|
|
459
|
+
size: 10000,
|
|
460
|
+
query: {
|
|
461
|
+
bool: {
|
|
462
|
+
must: [
|
|
463
|
+
{
|
|
464
|
+
term: {
|
|
465
|
+
'storeId.keyword': inputData.storeId,
|
|
466
|
+
},
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
term: {
|
|
470
|
+
'dateString': inputData.dateString,
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
],
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
let findTicket = await getOpenSearchData( openSearch.footfallDirectory, findQuery );
|
|
478
|
+
let Ticket = findTicket.body?.hits?.hits;
|
|
479
|
+
|
|
480
|
+
if ( Ticket.length === 0 ) {
|
|
481
|
+
return res.sendError( 'Ticket not found', 400 );
|
|
482
|
+
}
|
|
483
|
+
const getTicket = {
|
|
484
|
+
size: 10000,
|
|
485
|
+
query: {
|
|
486
|
+
bool: {
|
|
487
|
+
must: [
|
|
488
|
+
{
|
|
489
|
+
term: {
|
|
490
|
+
'storeId.keyword': inputData.storeId,
|
|
491
|
+
},
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
term: {
|
|
495
|
+
'dateString': inputData.dateString,
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
|
|
499
|
+
],
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
};
|
|
503
|
+
if ( Ticket[0]?._source?.type != 'internal' ) {
|
|
504
|
+
getTicket.query.bool.must.push(
|
|
505
|
+
{
|
|
506
|
+
nested: {
|
|
507
|
+
path: 'mappingInfo',
|
|
508
|
+
query: {
|
|
509
|
+
bool: {
|
|
510
|
+
must: [
|
|
511
|
+
{
|
|
512
|
+
term: {
|
|
513
|
+
'mappingInfo.type': 'tangoreview',
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
|
|
517
|
+
],
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
const getFootfallticketData = await getOpenSearchData( openSearch.footfallDirectory, getTicket );
|
|
525
|
+
const ticketData = getFootfallticketData?.body?.hits?.hits;
|
|
526
|
+
|
|
527
|
+
if ( !ticketData || ticketData?.length == 0 ) {
|
|
528
|
+
return res.sendError( 'You don’t have any tagged images right now', 400 );
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const record = {
|
|
532
|
+
|
|
533
|
+
status: 'Closed - Accuracy Issue',
|
|
534
|
+
createdByEmail: req?.user?.email,
|
|
535
|
+
createdByUserName: req?.user?.userName,
|
|
536
|
+
createdByRole: req?.user?.role,
|
|
537
|
+
mappingInfo: ticketData?.[0]?._source?.mappingInfo,
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// If autoclose enabled and revisedPercentage meets/exceeds threshold, close ticket and skip revision
|
|
541
|
+
|
|
542
|
+
if ( Array.isArray( record.mappingInfo ) ) {
|
|
543
|
+
const temp = record.mappingInfo
|
|
544
|
+
.filter( ( item ) => item.type === 'tangoreview' )
|
|
545
|
+
.map( ( item ) => ( {
|
|
546
|
+
...item,
|
|
547
|
+
status: 'Closed',
|
|
548
|
+
createdByEmail: req?.user?.email,
|
|
549
|
+
createdByUserName: req?.user?.userName,
|
|
550
|
+
createdByRole: req?.user?.role,
|
|
551
|
+
} ) );
|
|
552
|
+
|
|
553
|
+
record.mappingInfo = [ ...ticketData?.[0]?._source?.mappingInfo.slice( 0, -1 ),
|
|
554
|
+
...temp ];
|
|
555
|
+
if ( Array.isArray( record.mappingInfo ) ) {
|
|
556
|
+
record.mappingInfo = record.mappingInfo.map( ( item ) => {
|
|
557
|
+
return {
|
|
558
|
+
...item,
|
|
559
|
+
status: 'Closed',
|
|
560
|
+
};
|
|
561
|
+
} );
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
// If no review mapping existed, push a new one
|
|
566
|
+
// if ( record.mappingInfo.length === 0 ) {
|
|
567
|
+
// record.mappingInfo.push( {
|
|
568
|
+
// type: 'tangoreview',
|
|
569
|
+
// mode: inputData.mappingInfo?.mode,
|
|
570
|
+
// revicedFootfall: temp?.mappingInfo?.revicedFootfall,
|
|
571
|
+
// revicedPerc: temp?.mappingInfo?.revicedPerc,
|
|
572
|
+
// count: temp?.mappingInfo?.count,
|
|
573
|
+
// revisedDetail: temp?.mappingInfo?.revisedDetail,
|
|
574
|
+
// status: 'Closed',
|
|
575
|
+
// createdByEmail: req?.user?.email,
|
|
576
|
+
// createdByUserName: req?.user?.userName,
|
|
577
|
+
// createdByRole: req?.user?.role,
|
|
578
|
+
// } );
|
|
579
|
+
// }
|
|
580
|
+
record.mappingInfo.push(
|
|
581
|
+
{
|
|
582
|
+
type: 'finalRevision',
|
|
583
|
+
mode: 'web',
|
|
584
|
+
revicedFootfall: temp?.[0]?.revicedFootfall,
|
|
585
|
+
revicedPerc: temp?.[0].revicedPerc,
|
|
586
|
+
count: temp?.[0].count,
|
|
587
|
+
revisedDetail: temp?.[0]?.revisedDetail,
|
|
588
|
+
status: 'Closed',
|
|
589
|
+
createdByEmail: req?.user?.email,
|
|
590
|
+
createdByUserName: req?.user?.userName,
|
|
591
|
+
createdByRole: req?.user?.role,
|
|
592
|
+
createdAt: new Date(),
|
|
593
|
+
},
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
// return;
|
|
599
|
+
|
|
600
|
+
let id = `${inputData.storeId}_${inputData.dateString}_footfall-directory-tagging`;
|
|
601
|
+
|
|
602
|
+
const insertResult = await updateOpenSearchData( openSearch.footfallDirectory, id, { doc: record } );
|
|
603
|
+
|
|
604
|
+
if ( insertResult && ( insertResult.statusCode === 201 || insertResult.statusCode === 200 ) ) {
|
|
605
|
+
return res.sendSuccess( 'Ticket closed successfully' );
|
|
606
|
+
} else {
|
|
607
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
608
|
+
}
|
|
609
|
+
} catch ( error ) {
|
|
610
|
+
const err = error.message || 'Internal Server Error';
|
|
611
|
+
logger.error( { error: error, funtion: 'tangoReviewAccuracyClosedTicket' } );
|
|
449
612
|
return res.sendError( err, 500 );
|
|
450
613
|
}
|
|
451
614
|
}
|
|
@@ -1053,7 +1216,7 @@ export async function ticketList( req, res ) {
|
|
|
1053
1216
|
}
|
|
1054
1217
|
}
|
|
1055
1218
|
|
|
1056
|
-
if ( req?.user?.userType
|
|
1219
|
+
if ( req?.user?.userType === 'tango' && inputData.tangoType !== 'internal' ) {
|
|
1057
1220
|
searchQuery.query.bool.must.push(
|
|
1058
1221
|
{
|
|
1059
1222
|
term: {
|
|
@@ -1081,7 +1244,7 @@ export async function ticketList( req, res ) {
|
|
|
1081
1244
|
|
|
1082
1245
|
|
|
1083
1246
|
);
|
|
1084
|
-
} else if ( req?.user?.userType
|
|
1247
|
+
} else if ( req?.user?.userType === 'client' && inputData.tangoType !== 'internal' ) {
|
|
1085
1248
|
searchQuery.query.bool.must.push(
|
|
1086
1249
|
{
|
|
1087
1250
|
term: {
|
|
@@ -1173,8 +1336,8 @@ export async function ticketList( req, res ) {
|
|
|
1173
1336
|
const ticketListData = searchResult?.body?.hits?.hits?.map( ( hit ) => hit._source ) || [];
|
|
1174
1337
|
|
|
1175
1338
|
let temp = [];
|
|
1176
|
-
if ( req.user.userType
|
|
1177
|
-
if ( inputData.
|
|
1339
|
+
if ( req.user.userType === 'tango' ) {
|
|
1340
|
+
if ( inputData.tangoType === 'store' ) {
|
|
1178
1341
|
for ( let item of ticketListData ) {
|
|
1179
1342
|
temp.push( {
|
|
1180
1343
|
|
|
@@ -1189,7 +1352,7 @@ export async function ticketList( req, res ) {
|
|
|
1189
1352
|
reviewerRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.revicedPerc || '--',
|
|
1190
1353
|
approverRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'approve' )?.revicedPerc || '--',
|
|
1191
1354
|
tangoRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
|
|
1192
|
-
status: item?.status,
|
|
1355
|
+
status: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.status || '--',
|
|
1193
1356
|
|
|
1194
1357
|
} );
|
|
1195
1358
|
}
|
|
@@ -1211,7 +1374,7 @@ export async function ticketList( req, res ) {
|
|
|
1211
1374
|
approverRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'approve' )?.revicedPerc || '--',
|
|
1212
1375
|
tangoRevisedAccuracy: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
|
|
1213
1376
|
status: item?.status,
|
|
1214
|
-
tangoStatus: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.
|
|
1377
|
+
tangoStatus: item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.status || '--',
|
|
1215
1378
|
|
|
1216
1379
|
} );
|
|
1217
1380
|
}
|
|
@@ -72,6 +72,17 @@ export const tangoReviewTicketSchema = Joi.object().keys( {
|
|
|
72
72
|
export const tangoReviewTicketValid = {
|
|
73
73
|
body: tangoReviewTicketSchema,
|
|
74
74
|
};
|
|
75
|
+
export const tangoReviewAccuracyClosedTicketSchema = Joi.object().keys( {
|
|
76
|
+
storeId: Joi.string().required(),
|
|
77
|
+
dateString: Joi.string().required(),
|
|
78
|
+
comments: Joi.string().required(),
|
|
79
|
+
subComment: Joi.string().required(),
|
|
80
|
+
|
|
81
|
+
} );
|
|
82
|
+
|
|
83
|
+
export const tangoReviewAccuracyClosedTicketValid = {
|
|
84
|
+
body: tangoReviewAccuracyClosedTicketSchema,
|
|
85
|
+
};
|
|
75
86
|
|
|
76
87
|
export const ticketSummarySchema = Joi.object().keys( {
|
|
77
88
|
clientId: Joi.string().required(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { getClusters, getConfig, isGrantedUsers, isTicketExists, ticketApprove, ticketCreation, ticketReview } from '../validations/footfallDirectory.validation.js';
|
|
3
|
-
import { assignTicket, createTicket, downloadTickets, getTaggedStores, getTickets, multiCloseTicket, openTicketList, reviewerList, tangoReviewTicket, ticketList, ticketSummary, updateStatus, updateTempStatus, updateUserTicketStatus, createinternalTicket, checkTicketExists } from '../controllers/footfallDirectory.controllers.js';
|
|
4
|
-
import { createTicketValid, downloadTicketsValid, getTaggedStoresValid, getTicketsValid, openTicketListValid, reviewerListValid, ticketListValid, ticketSummaryValid, updateStatusValid, assignTicketValid, updateTempStatusValid, updateTicketStatusValid, tangoReviewTicketValid, multiCloseTicketValid } from '../dtos/footfallDirectory.dtos.js';
|
|
3
|
+
import { assignTicket, createTicket, downloadTickets, getTaggedStores, getTickets, multiCloseTicket, openTicketList, reviewerList, tangoReviewTicket, ticketList, ticketSummary, updateStatus, updateTempStatus, updateUserTicketStatus, createinternalTicket, checkTicketExists, tangoReviewAccuracyClosedTicket } from '../controllers/footfallDirectory.controllers.js';
|
|
4
|
+
import { createTicketValid, downloadTicketsValid, getTaggedStoresValid, getTicketsValid, openTicketListValid, reviewerListValid, ticketListValid, ticketSummaryValid, updateStatusValid, assignTicketValid, updateTempStatusValid, updateTicketStatusValid, tangoReviewTicketValid, multiCloseTicketValid, tangoReviewAccuracyClosedTicketValid } from '../dtos/footfallDirectory.dtos.js';
|
|
5
5
|
import { bulkValidate, getAssinedStore, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
6
6
|
|
|
7
7
|
export const footfallDirectoryRouter = express.Router();
|
|
@@ -11,6 +11,7 @@ footfallDirectoryRouter.post( '/create-internalticket', isAllowedSessionHandler,
|
|
|
11
11
|
footfallDirectoryRouter.post( '/checkTicketExists', isAllowedSessionHandler, checkTicketExists );
|
|
12
12
|
|
|
13
13
|
footfallDirectoryRouter.post( '/tango-review-ticket', isAllowedSessionHandler, validate( tangoReviewTicketValid ), tangoReviewTicket );
|
|
14
|
+
footfallDirectoryRouter.post( '/tango-review-accuracy-ticket', isAllowedSessionHandler, validate( tangoReviewAccuracyClosedTicketValid ), tangoReviewAccuracyClosedTicket );
|
|
14
15
|
|
|
15
16
|
footfallDirectoryRouter.get( '/ticket-summary', isAllowedSessionHandler, bulkValidate( ticketSummaryValid ), ticketSummary );
|
|
16
17
|
|