tango-app-api-infra 3.9.5-vms.64 β 3.9.5-vms.66
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
|
@@ -1387,101 +1387,116 @@ export async function getTickets( req, res ) {
|
|
|
1387
1387
|
commentsResponse = commentsRes?.body?.hits?.hits?.map( ( hit ) => hit._source ) || [];
|
|
1388
1388
|
|
|
1389
1389
|
// Check if duplicate condition exists in commentsResponse
|
|
1390
|
-
const isDuplicate = Array.isArray( commentsResponse ) &&
|
|
1391
|
-
commentsResponse.some( ( c ) => c.category === 'duplicate' );
|
|
1392
1390
|
|
|
1393
1391
|
// Structure comments output
|
|
1394
1392
|
let commentsDetails = [];
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
//
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
const types = [ 'tagging', 'review', 'approve' ];
|
|
1396
|
+
|
|
1397
|
+
// Process each type
|
|
1398
|
+
types.forEach( ( typeValue ) => {
|
|
1399
|
+
if ( typeValue === 'tagging' ) {
|
|
1400
|
+
// For tagging, group by category and create separate objects for each category
|
|
1401
|
+
const taggingComments = commentsResponse.filter( ( c ) => c.type === typeValue );
|
|
1402
|
+
|
|
1403
|
+
// Group by category
|
|
1404
|
+
const categoryGroups = {};
|
|
1405
|
+
taggingComments.forEach( ( c ) => {
|
|
1406
|
+
const category = c.category || 'other';
|
|
1407
|
+
if ( !categoryGroups[category] ) {
|
|
1408
|
+
categoryGroups[category] = [];
|
|
1409
|
+
}
|
|
1410
|
+
categoryGroups[category].push( c );
|
|
1411
|
+
} );
|
|
1412
|
+
|
|
1413
|
+
// Create separate objects for each category
|
|
1414
|
+
Object.keys( categoryGroups ).forEach( ( category ) => {
|
|
1415
|
+
const categoryComments = categoryGroups[category];
|
|
1416
|
+
let parent = null;
|
|
1417
|
+
|
|
1418
|
+
const comms = categoryComments.map( ( c ) => {
|
|
1419
|
+
if ( category === 'duplicate' ) {
|
|
1420
|
+
if ( !parent && c.parent ) {
|
|
1407
1421
|
parent = c.parent;
|
|
1408
|
-
return {
|
|
1409
|
-
createdByEmail: c.createdByEmail,
|
|
1410
|
-
createdByUserName: c.createdByUserName,
|
|
1411
|
-
createdByRole: c.createdByRole,
|
|
1412
|
-
message: c.message,
|
|
1413
|
-
};
|
|
1414
1422
|
}
|
|
1415
|
-
|
|
1423
|
+
return {
|
|
1424
|
+
createdByEmail: c.createdByEmail,
|
|
1425
|
+
createdByUserName: c.createdByUserName,
|
|
1426
|
+
createdByRole: c.createdByRole,
|
|
1427
|
+
message: c.message,
|
|
1428
|
+
};
|
|
1429
|
+
} else {
|
|
1430
|
+
return {
|
|
1431
|
+
id: c.id,
|
|
1432
|
+
tempId: c.tempId,
|
|
1433
|
+
timeRange: c.timeRange,
|
|
1434
|
+
entryTime: c.entryTime,
|
|
1435
|
+
exitTime: c.exitTime,
|
|
1436
|
+
filePath: c.filePath,
|
|
1437
|
+
isChecked: c.isChecked,
|
|
1438
|
+
createdAt: c.createdAt,
|
|
1439
|
+
message: c.message,
|
|
1440
|
+
createdByEmail: c.createdByEmail,
|
|
1441
|
+
createdByUserName: c.createdByUserName,
|
|
1442
|
+
createdByRole: c.createdByRole,
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
} );
|
|
1446
|
+
|
|
1447
|
+
const taggingObj = {
|
|
1448
|
+
category: category,
|
|
1449
|
+
type: typeValue,
|
|
1450
|
+
comments: comms,
|
|
1451
|
+
};
|
|
1452
|
+
|
|
1453
|
+
// Add parent only for duplicate category
|
|
1454
|
+
if ( category === 'duplicate' && parent !== null ) {
|
|
1455
|
+
taggingObj.parent = parent;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
commentsDetails.push( taggingObj );
|
|
1459
|
+
} );
|
|
1460
|
+
} else if ( typeValue === 'review' || typeValue === 'approve' ) {
|
|
1461
|
+
// For review and approve, keep existing structure
|
|
1462
|
+
const comms = commentsResponse
|
|
1463
|
+
.filter( ( c ) => c.type === typeValue )
|
|
1464
|
+
.map( ( c ) => {
|
|
1465
|
+
if ( c.category === 'duplicate' ) {
|
|
1416
1466
|
return {
|
|
1417
|
-
parent: c
|
|
1467
|
+
parent: c?.taggedImages[0]?._source?.parent,
|
|
1418
1468
|
category: c.category,
|
|
1419
1469
|
taggedImages: Array.isArray( c.taggedImages ) ?
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1470
|
+
c.taggedImages.map( ( img ) => ( {
|
|
1471
|
+
id: img?._source?.id,
|
|
1472
|
+
tempId: img?._source?.tempId,
|
|
1473
|
+
timeRange: img?._source?.timeRange,
|
|
1474
|
+
entryTime: img?._source?.entryTime,
|
|
1475
|
+
exitTime: img?._source?.exitTime,
|
|
1476
|
+
filePath: img?._source?.filePath,
|
|
1477
|
+
isChecked: img?._source?.isChecked,
|
|
1478
|
+
} ) ) :
|
|
1479
|
+
[],
|
|
1430
1480
|
createdByEmail: c.createdByEmail,
|
|
1431
1481
|
createdByUserName: c.createdByUserName,
|
|
1432
1482
|
createdByRole: c.createdByRole,
|
|
1433
1483
|
status: c.status,
|
|
1434
1484
|
message: c.message,
|
|
1435
1485
|
};
|
|
1436
|
-
}
|
|
1437
|
-
return {};
|
|
1438
|
-
} );
|
|
1439
|
-
return {
|
|
1440
|
-
...( typeValue === 'tagging' ? { category: 'duplicate' } : {} ),
|
|
1441
|
-
type: typeValue,
|
|
1442
|
-
...( typeValue === 'tagging' ? { parent } : {} ),
|
|
1443
|
-
comments: comms,
|
|
1444
|
-
};
|
|
1445
|
-
} );
|
|
1446
|
-
} else {
|
|
1447
|
-
// For non-duplicate categories
|
|
1448
|
-
// Collect by type/tag (tagging/review/approve) and build similar structure
|
|
1449
|
-
const types = [ 'tagging', 'review', 'approve' ];
|
|
1450
|
-
commentsDetails = types.map( ( typeValue ) => {
|
|
1451
|
-
// parent for these non-duplicate is always null
|
|
1452
|
-
let comms = commentsResponse
|
|
1453
|
-
.filter( ( c ) => c.type === typeValue )
|
|
1454
|
-
.map( ( c ) => {
|
|
1455
|
-
if ( typeValue === 'tagging' ) {
|
|
1456
|
-
return {
|
|
1457
|
-
id: c.id,
|
|
1458
|
-
tempId: c.tempId,
|
|
1459
|
-
timeRange: c.timeRange,
|
|
1460
|
-
entryTime: c.entryTime,
|
|
1461
|
-
exitTime: c.exitTime,
|
|
1462
|
-
filePath: c.filePath,
|
|
1463
|
-
isChecked: c.isChecked,
|
|
1464
|
-
createdAt: c.createdAt,
|
|
1465
|
-
message: c.message,
|
|
1466
|
-
createdByEmail: c.createdByEmail,
|
|
1467
|
-
createdByUserName: c.createdByUserName,
|
|
1468
|
-
createdByRole: c.createdByRole,
|
|
1469
|
-
};
|
|
1470
|
-
}
|
|
1471
|
-
if ( typeValue === 'review' || typeValue === 'approve' ) {
|
|
1486
|
+
} else {
|
|
1472
1487
|
return {
|
|
1473
1488
|
category: c.category,
|
|
1474
1489
|
taggedImages: Array.isArray( c.taggedImages ) ?
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1490
|
+
c.taggedImages.map( ( img ) => ( {
|
|
1491
|
+
id: img?._source?.id,
|
|
1492
|
+
tempId: img?._source?.tempId,
|
|
1493
|
+
timeRange: img?._source?.timeRange,
|
|
1494
|
+
entryTime: img?._source?.entryTime,
|
|
1495
|
+
exitTime: img?._source?.exitTime,
|
|
1496
|
+
filePath: img?._source?.filePath,
|
|
1497
|
+
isChecked: img?._source?.isChecked,
|
|
1498
|
+
} ) ) :
|
|
1499
|
+
[],
|
|
1485
1500
|
createdByEmail: c.createdByEmail,
|
|
1486
1501
|
createdByUserName: c.createdByUserName,
|
|
1487
1502
|
createdByRole: c.createdByRole,
|
|
@@ -1489,16 +1504,24 @@ export async function getTickets( req, res ) {
|
|
|
1489
1504
|
message: c.message,
|
|
1490
1505
|
};
|
|
1491
1506
|
}
|
|
1492
|
-
return {};
|
|
1493
1507
|
} );
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1508
|
+
|
|
1509
|
+
// Only add if there are comments
|
|
1510
|
+
if ( comms.length > 0 ) {
|
|
1511
|
+
commentsDetails.push( {
|
|
1512
|
+
type: typeValue,
|
|
1513
|
+
comments: comms,
|
|
1514
|
+
} );
|
|
1515
|
+
} else {
|
|
1516
|
+
// Add empty comments array if no comments
|
|
1517
|
+
commentsDetails.push( {
|
|
1518
|
+
type: typeValue,
|
|
1519
|
+
comments: [],
|
|
1520
|
+
} );
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
} );
|
|
1524
|
+
|
|
1502
1525
|
|
|
1503
1526
|
item._source.commentsDetails = commentsDetails;
|
|
1504
1527
|
}
|
|
@@ -508,8 +508,8 @@ export async function ticketCreation( req, res, next ) {
|
|
|
508
508
|
if ( r.actionType === 'reviewer' && r.isChecked === true ) {
|
|
509
509
|
revisionMapping = {
|
|
510
510
|
type: 'review',
|
|
511
|
-
revicedFootfall: revisedFootfall,
|
|
512
|
-
revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
511
|
+
// revicedFootfall: revisedFootfall,
|
|
512
|
+
// revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
513
513
|
count: tempAcc,
|
|
514
514
|
revisedDetail: formattedTaggingData,
|
|
515
515
|
status: 'Open',
|
|
@@ -526,8 +526,8 @@ export async function ticketCreation( req, res, next ) {
|
|
|
526
526
|
} else if ( r.actionType === 'tango' && r.isChecked === true ) {
|
|
527
527
|
tangoReviewMapping = {
|
|
528
528
|
type: 'tangoreview',
|
|
529
|
-
revicedFootfall: revisedFootfall,
|
|
530
|
-
revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
529
|
+
// revicedFootfall: revisedFootfall,
|
|
530
|
+
// revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
531
531
|
count: tempAcc,
|
|
532
532
|
revisedDetail: formattedTaggingData,
|
|
533
533
|
status: 'Open',
|
|
@@ -570,7 +570,7 @@ export async function ticketCreation( req, res, next ) {
|
|
|
570
570
|
];
|
|
571
571
|
|
|
572
572
|
const finduserList = await aggregateUser( userQuery );
|
|
573
|
-
|
|
573
|
+
|
|
574
574
|
|
|
575
575
|
const createdOn = dayjs().format( 'DD MMM YYYY' );
|
|
576
576
|
const title = `${getstoreName?.storeName} Have raised a ticket for a Footfall Mismatch`;
|
|
@@ -596,12 +596,12 @@ export async function ticketCreation( req, res, next ) {
|
|
|
596
596
|
m.name === 'reviewer' && ( m.isAdd === true || m.isEdit === true ),
|
|
597
597
|
),
|
|
598
598
|
);
|
|
599
|
-
|
|
599
|
+
|
|
600
600
|
|
|
601
601
|
if ( !ticketsFeature ) return;
|
|
602
602
|
|
|
603
603
|
const notifyUser = await getAssinedStore( userData, req.body.storeId );
|
|
604
|
-
|
|
604
|
+
|
|
605
605
|
if ( !notifyUser || !userData?.fcmToken ) return;
|
|
606
606
|
|
|
607
607
|
await sendPushNotification( title, description, userData.fcmToken, Data );
|
|
@@ -1223,8 +1223,8 @@ export async function ticketReview( req, res, next ) {
|
|
|
1223
1223
|
if ( r.actionType === 'approver' && r.isChecked === true ) {
|
|
1224
1224
|
approverMapping = {
|
|
1225
1225
|
type: 'approve',
|
|
1226
|
-
revicedFootfall: revisedFootfall,
|
|
1227
|
-
revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
1226
|
+
// revicedFootfall: revisedFootfall,
|
|
1227
|
+
// revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
1228
1228
|
count: tempAcc,
|
|
1229
1229
|
revisedDetail: formattedTaggingData,
|
|
1230
1230
|
status: 'Open',
|
|
@@ -1232,8 +1232,8 @@ export async function ticketReview( req, res, next ) {
|
|
|
1232
1232
|
} else if ( r.actionType === 'tango' && r.isChecked === true ) {
|
|
1233
1233
|
tangoReviewMapping = {
|
|
1234
1234
|
type: 'tangoreview',
|
|
1235
|
-
revicedFootfall: revisedFootfall,
|
|
1236
|
-
revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
1235
|
+
// revicedFootfall: revisedFootfall,
|
|
1236
|
+
// revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
1237
1237
|
count: tempAcc,
|
|
1238
1238
|
revisedDetail: formattedTaggingData,
|
|
1239
1239
|
status: 'Open',
|
|
@@ -1269,7 +1269,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1269
1269
|
},
|
|
1270
1270
|
];
|
|
1271
1271
|
let finduserList = await aggregateUser( userQuery );
|
|
1272
|
-
|
|
1272
|
+
|
|
1273
1273
|
|
|
1274
1274
|
// return;
|
|
1275
1275
|
for ( let userData of finduserList ) {
|
|
@@ -1499,7 +1499,7 @@ export async function ticketApprove( req, res, next ) {
|
|
|
1499
1499
|
if ( !taggingImages || taggingImages?.length == 0 ) {
|
|
1500
1500
|
return res.sendError( 'You donβt have any tagged images right now', 400 );
|
|
1501
1501
|
}
|
|
1502
|
-
|
|
1502
|
+
|
|
1503
1503
|
const formattedTaggingData = formatRevopTaggingHits( taggingImages );
|
|
1504
1504
|
|
|
1505
1505
|
const getTicket = {
|
|
@@ -1647,14 +1647,14 @@ export async function ticketApprove( req, res, next ) {
|
|
|
1647
1647
|
|
|
1648
1648
|
record.mappingInfo = [ ...ticketData?.[0]?._source?.mappingInfo.slice( 0, -1 ),
|
|
1649
1649
|
...temp ];
|
|
1650
|
-
if ( Array.isArray( record.mappingInfo ) ) {
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
}
|
|
1650
|
+
// if ( Array.isArray( record.mappingInfo ) ) {
|
|
1651
|
+
// record.mappingInfo = record.mappingInfo.map( ( item ) => {
|
|
1652
|
+
// return {
|
|
1653
|
+
// ...item,
|
|
1654
|
+
// status: 'Closed',
|
|
1655
|
+
// };
|
|
1656
|
+
// } );
|
|
1657
|
+
// }
|
|
1658
1658
|
// If no review mapping existed, push a new one
|
|
1659
1659
|
if ( record.mappingInfo.length === 0 ) {
|
|
1660
1660
|
record.mappingInfo.push( {
|
|
@@ -1678,8 +1678,8 @@ export async function ticketApprove( req, res, next ) {
|
|
|
1678
1678
|
// if ( r.actionType === 'tango' && r.isChecked === true ) {
|
|
1679
1679
|
tangoReviewMapping = {
|
|
1680
1680
|
type: 'tangoreview',
|
|
1681
|
-
revicedFootfall: revisedFootfall,
|
|
1682
|
-
revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
1681
|
+
// revicedFootfall: revisedFootfall,
|
|
1682
|
+
// revicedPerc: Math.round( ( revisedFootfall / footfallCount ) * 100 || 0 ) + '%',
|
|
1683
1683
|
count: tempAcc,
|
|
1684
1684
|
revisedDetail: formattedTaggingData,
|
|
1685
1685
|
status: 'Open',
|
|
@@ -1769,13 +1769,13 @@ export async function ticketApprove( req, res, next ) {
|
|
|
1769
1769
|
},
|
|
1770
1770
|
];
|
|
1771
1771
|
let finduserList = await aggregateUser( userQuery );
|
|
1772
|
-
|
|
1772
|
+
|
|
1773
1773
|
|
|
1774
1774
|
for ( let userData of finduserList ) {
|
|
1775
1775
|
let title = `${getstoreName?.storeName} Have raised a ticket for a Footfall Mismatch`;
|
|
1776
1776
|
let createdOn = dayjs().format( 'DD MMM YYYY' );
|
|
1777
1777
|
let description = `Created on ${createdOn}`;
|
|
1778
|
-
|
|
1778
|
+
|
|
1779
1779
|
let Data = {
|
|
1780
1780
|
'title': title,
|
|
1781
1781
|
'body': description,
|
|
@@ -1787,7 +1787,7 @@ export async function ticketApprove( req, res, next ) {
|
|
|
1787
1787
|
};
|
|
1788
1788
|
|
|
1789
1789
|
const ticketsFeature = userData?.rolespermission?.some( ( f ) => f.featureName === 'FootfallDirectory' && ( f.modules.find( ( m ) => m.name == 'approver' && ( m.isAdd == true || m.isEdit == true ) ) ) );
|
|
1790
|
-
|
|
1790
|
+
|
|
1791
1791
|
if ( ticketsFeature ) {
|
|
1792
1792
|
let notifyuser = await getAssinedStore( userData, req.body.storeId );
|
|
1793
1793
|
if ( userData && userData.fcmToken && notifyuser ) {
|
|
@@ -1801,7 +1801,7 @@ export async function ticketApprove( req, res, next ) {
|
|
|
1801
1801
|
const id = `${inputData.storeId}_${inputData.dateString}_footfall-directory-tagging`;
|
|
1802
1802
|
const insertResult = await updateOpenSearchData( openSearch.footfallDirectory, id, { doc: record } );
|
|
1803
1803
|
|
|
1804
|
-
|
|
1804
|
+
|
|
1805
1805
|
if ( insertResult && ( insertResult.statusCode === 201 || insertResult.statusCode === 200 ) ) {
|
|
1806
1806
|
return res.sendSuccess( 'Ticket closed successfully' );
|
|
1807
1807
|
} else {
|