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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-infra",
3
- "version": "3.9.5-vms.70",
3
+ "version": "3.9.5-vms.72",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -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 = 'Closed - Accuracy Issue';
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
- record.mappingInfo = record.mappingInfo.map( ( item ) => {
327
- return {
328
- ...item,
329
- status: 'Closed',
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: err, funtion: 'tangoReviewTicket' } );
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 == 'tango' && inputData.tangoType !== 'internal' ) {
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 == 'client' && inputData.tangoType !== 'internal' ) {
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 == 'tango' ) {
1177
- if ( inputData.tangotype == 'store' ) {
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' )?.revicedPerc || '--',
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