tango-app-api-infra 3.9.5-vms.54 → 3.9.5-vms.56
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
|
@@ -856,6 +856,7 @@ export async function ticketList( req, res ) {
|
|
|
856
856
|
size: limit, // or use parseInt(req.query.limit) for dynamic
|
|
857
857
|
from: offset, // or use parseInt(req.query.offset) for dynamic
|
|
858
858
|
sort: [ { 'createdAt': { order: 'desc' } } ],
|
|
859
|
+
|
|
859
860
|
query: {
|
|
860
861
|
bool: {
|
|
861
862
|
must: [
|
|
@@ -881,7 +882,24 @@ export async function ticketList( req, res ) {
|
|
|
881
882
|
},
|
|
882
883
|
};
|
|
883
884
|
|
|
885
|
+
if ( inputData.sortBy ) {
|
|
886
|
+
let sortOrder = inputData.sortOrder === 1? 'asc': 'desc';
|
|
887
|
+
|
|
888
|
+
// Remove default sort so we don't duplicate/conflict
|
|
889
|
+
// INSERT_YOUR_CODE
|
|
890
|
+
// If sortBy is present, check if the field needs ".keyword" (for string fields like storeName, storeId, ticketId)
|
|
891
|
+
// This avoids OpenSearch errors about sorting on text fields.
|
|
892
|
+
const stringKeywordFields = [ 'storeName', 'storeId', 'ticketId', 'status', 'type', 'clientId' ];
|
|
893
|
+
let sortField = inputData.sortBy == 'footfall'? 'footfallCount' :inputData.sortBy == 'issueDate'?'dateString':inputData.sortBy;
|
|
894
|
+
if ( stringKeywordFields.includes( sortField ) ) {
|
|
895
|
+
sortField = `${sortField}.keyword`;
|
|
896
|
+
}
|
|
884
897
|
|
|
898
|
+
// Remove default sort so we don't duplicate/conflict
|
|
899
|
+
searchQuery.sort = [
|
|
900
|
+
{ [sortField]: { order: sortOrder } },
|
|
901
|
+
];
|
|
902
|
+
}
|
|
885
903
|
// Example: Filtering by storeId if present in the query
|
|
886
904
|
if ( inputData.storeId ) {
|
|
887
905
|
inputData.storeId = inputData?.storeId?.split( ',' );
|
|
@@ -963,7 +981,7 @@ export async function ticketList( req, res ) {
|
|
|
963
981
|
}
|
|
964
982
|
// You can add more filters as needed
|
|
965
983
|
const searchResult = await getOpenSearchData( openSearch.footfallDirectory, searchQuery );
|
|
966
|
-
|
|
984
|
+
logger.info( { searchResult } );
|
|
967
985
|
const count = searchResult?.body?.hits?.total?.value || 0;
|
|
968
986
|
|
|
969
987
|
if ( count === 0 ) {
|
|
@@ -1318,10 +1336,153 @@ export async function getTickets( req, res ) {
|
|
|
1318
1336
|
|
|
1319
1337
|
) {
|
|
1320
1338
|
item._source.mappingInfo.revisedDetail = processedRevopSources;
|
|
1339
|
+
const vmsCommentsLogIndex = openSearch.vmsCommentsLog || 'vms-comments-log-dev';
|
|
1340
|
+
let commentsResponse = [];
|
|
1341
|
+
const commentsFilter = [
|
|
1342
|
+
{ term: { 'storeId.keyword': item?._source?.storeId } },
|
|
1343
|
+
{ term: { dateString: item?._source?.dateString } },
|
|
1344
|
+
|
|
1345
|
+
];
|
|
1346
|
+
|
|
1347
|
+
const commentsQuery = {
|
|
1348
|
+
size: 10000,
|
|
1349
|
+
sort: [
|
|
1350
|
+
{ createdAt: { order: 'desc' } }, // Sort descending by createdAt
|
|
1351
|
+
],
|
|
1352
|
+
query: {
|
|
1353
|
+
bool: {
|
|
1354
|
+
filter: commentsFilter,
|
|
1355
|
+
},
|
|
1356
|
+
},
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
const commentsRes = await getOpenSearchData( vmsCommentsLogIndex, commentsQuery );
|
|
1321
1360
|
// If mappingInfo is an array, update revisedDetail for each mappingInfo object
|
|
1322
1361
|
if ( Array.isArray( item._source.mappingInfo ) ) {
|
|
1323
1362
|
item._source.mappingInfo.forEach( ( mappingObj ) => {
|
|
1324
|
-
if (
|
|
1363
|
+
if ( mappingObj.status == 'In-Progress' ) {
|
|
1364
|
+
commentsResponse = commentsRes?.body?.hits?.hits?.map( ( hit ) => hit._source ) || [];
|
|
1365
|
+
|
|
1366
|
+
// Check if duplicate condition exists in commentsResponse
|
|
1367
|
+
const isDuplicate = Array.isArray( commentsResponse ) &&
|
|
1368
|
+
commentsResponse.some( ( c ) => c.category === 'duplicate' );
|
|
1369
|
+
|
|
1370
|
+
// Structure comments output
|
|
1371
|
+
let commentsDetails = [];
|
|
1372
|
+
if ( isDuplicate ) {
|
|
1373
|
+
// Duplicate case - check from commentsResponse
|
|
1374
|
+
// Collect for each type (tagging, review, approve)
|
|
1375
|
+
const types = [ 'tagging', 'review', 'approve' ];
|
|
1376
|
+
commentsDetails = types.map( ( typeValue ) => {
|
|
1377
|
+
// parent value from original comment structure
|
|
1378
|
+
let parent = null;
|
|
1379
|
+
// Get all comments of this type (no filter by category)
|
|
1380
|
+
let comms = commentsResponse
|
|
1381
|
+
.filter( ( c ) => c.type === typeValue )
|
|
1382
|
+
.map( ( c ) => {
|
|
1383
|
+
if ( typeValue === 'tagging' ) {
|
|
1384
|
+
parent = c.parent;
|
|
1385
|
+
return {
|
|
1386
|
+
createdByEmail: c.createdByEmail,
|
|
1387
|
+
createdByUserName: c.createdByUserName,
|
|
1388
|
+
createdByRole: c.createdByRole,
|
|
1389
|
+
message: c.message,
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
if ( typeValue === 'review' || typeValue === 'approve' ) {
|
|
1393
|
+
return {
|
|
1394
|
+
parent: c.parent,
|
|
1395
|
+
category: c.category,
|
|
1396
|
+
taggedImages: Array.isArray( c.taggedImages ) ?
|
|
1397
|
+
c.taggedImages.map( ( img ) => ( {
|
|
1398
|
+
id: img?._source?.id,
|
|
1399
|
+
tempId: img?._source?.tempId,
|
|
1400
|
+
timeRange: img?._source?.timeRange,
|
|
1401
|
+
entryTime: img?._source?.entryTime,
|
|
1402
|
+
exitTime: img?._source?.exitTime,
|
|
1403
|
+
filePath: img?._source?.filePath,
|
|
1404
|
+
isChecked: img?._source?.isChecked,
|
|
1405
|
+
} ) ) :
|
|
1406
|
+
[],
|
|
1407
|
+
createdByEmail: c.createdByEmail,
|
|
1408
|
+
createdByUserName: c.createdByUserName,
|
|
1409
|
+
createdByRole: c.createdByRole,
|
|
1410
|
+
status: c.status,
|
|
1411
|
+
message: c.message,
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
return {};
|
|
1415
|
+
} );
|
|
1416
|
+
return {
|
|
1417
|
+
...( typeValue === 'tagging' ? { category: 'duplicate' } : {} ),
|
|
1418
|
+
type: typeValue,
|
|
1419
|
+
...( typeValue === 'tagging' ? { parent } : {} ),
|
|
1420
|
+
comments: comms,
|
|
1421
|
+
};
|
|
1422
|
+
} );
|
|
1423
|
+
} else {
|
|
1424
|
+
// For non-duplicate categories
|
|
1425
|
+
// Collect by type/tag (tagging/review/approve) and build similar structure
|
|
1426
|
+
const types = [ 'tagging', 'review', 'approve' ];
|
|
1427
|
+
commentsDetails = types.map( ( typeValue ) => {
|
|
1428
|
+
// parent for these non-duplicate is always null
|
|
1429
|
+
let comms = commentsResponse
|
|
1430
|
+
.filter( ( c ) => c.type === typeValue )
|
|
1431
|
+
.map( ( c ) => {
|
|
1432
|
+
if ( typeValue === 'tagging' ) {
|
|
1433
|
+
return {
|
|
1434
|
+
id: c.id,
|
|
1435
|
+
tempId: c.tempId,
|
|
1436
|
+
timeRange: c.timeRange,
|
|
1437
|
+
entryTime: c.entryTime,
|
|
1438
|
+
exitTime: c.exitTime,
|
|
1439
|
+
filePath: c.filePath,
|
|
1440
|
+
isChecked: c.isChecked,
|
|
1441
|
+
createdAt: c.createdAt,
|
|
1442
|
+
message: c.message,
|
|
1443
|
+
createdByEmail: c.createdByEmail,
|
|
1444
|
+
createdByUserName: c.createdByUserName,
|
|
1445
|
+
createdByRole: c.createdByRole,
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
if ( typeValue === 'review' || typeValue === 'approve' ) {
|
|
1449
|
+
return {
|
|
1450
|
+
category: c.category,
|
|
1451
|
+
taggedImages: Array.isArray( c.taggedImages ) ?
|
|
1452
|
+
c.taggedImages.map( ( img ) => ( {
|
|
1453
|
+
id: img?._source?.id,
|
|
1454
|
+
tempId: img?._source?.tempId,
|
|
1455
|
+
timeRange: img?._source?.timeRange,
|
|
1456
|
+
entryTime: img?._source?.entryTime,
|
|
1457
|
+
exitTime: img?._source?.exitTime,
|
|
1458
|
+
filePath: img?._source?.filePath,
|
|
1459
|
+
isChecked: img?._source?.isChecked,
|
|
1460
|
+
} ) ) :
|
|
1461
|
+
[],
|
|
1462
|
+
createdByEmail: c.createdByEmail,
|
|
1463
|
+
createdByUserName: c.createdByUserName,
|
|
1464
|
+
createdByRole: c.createdByRole,
|
|
1465
|
+
status: c.status,
|
|
1466
|
+
message: c.message,
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
return {};
|
|
1470
|
+
} );
|
|
1471
|
+
return {
|
|
1472
|
+
...( typeValue === 'tagging' ? { category: 'duplicate' } : {} ),
|
|
1473
|
+
parent: null,
|
|
1474
|
+
type: typeValue,
|
|
1475
|
+
comments: comms,
|
|
1476
|
+
};
|
|
1477
|
+
} );
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
item._source.commentsDetails = commentsDetails;
|
|
1481
|
+
}
|
|
1482
|
+
if (
|
|
1483
|
+
Object.prototype.hasOwnProperty.call( mappingObj, 'revisedDetail' ) &&
|
|
1484
|
+
mappingObj.type !== 'tangoreview'
|
|
1485
|
+
) {
|
|
1325
1486
|
mappingObj.revisedDetail = processedRevopSources;
|
|
1326
1487
|
}
|
|
1327
1488
|
} );
|
|
@@ -2171,6 +2332,16 @@ export async function openTicketList( req, res ) {
|
|
|
2171
2332
|
clientId: Array.isArray( clientId ) ? clientId : [ clientId ],
|
|
2172
2333
|
},
|
|
2173
2334
|
},
|
|
2335
|
+
{
|
|
2336
|
+
term: {
|
|
2337
|
+
'mappingInfo.type': inputData.type,
|
|
2338
|
+
},
|
|
2339
|
+
},
|
|
2340
|
+
{
|
|
2341
|
+
term: {
|
|
2342
|
+
'mappingInfo.status.keyword': 'Open',
|
|
2343
|
+
},
|
|
2344
|
+
},
|
|
2174
2345
|
{
|
|
2175
2346
|
range: {
|
|
2176
2347
|
dateString: {
|
|
@@ -2191,10 +2362,16 @@ export async function openTicketList( req, res ) {
|
|
|
2191
2362
|
},
|
|
2192
2363
|
_source: [ 'ticketId', 'storeName', 'storeId', 'dateString', 'revicedFootfall', 'footfallCount', 'revicedPerc', 'type' ],
|
|
2193
2364
|
};
|
|
2365
|
+
// INSERT_YOUR_CODE
|
|
2366
|
+
// Add sorting by revicedPerc descending (highest revised accuracy first)
|
|
2367
|
+
openSearchQuery.sort = [
|
|
2368
|
+
{ 'revicedPerc.keyword': { order: inputData?.sortOrder === 1? 'asc':'desc' } },
|
|
2369
|
+
];
|
|
2194
2370
|
|
|
2195
2371
|
|
|
2196
2372
|
// Assuming getOpenSearchData and openSearch.footfallDirectoryTagging are available
|
|
2197
2373
|
const result = await getOpenSearchData( openSearch.footfallDirectory, openSearchQuery );
|
|
2374
|
+
logger.info( { result } );
|
|
2198
2375
|
const getUserlist = result?.body?.hits?.hits?.map( ( hit ) => hit._source ) || [];
|
|
2199
2376
|
return res.sendSuccess( getUserlist || [] );
|
|
2200
2377
|
} catch ( error ) {
|
|
@@ -509,6 +509,8 @@ export const openTicketListSchema = Joi.object().keys( {
|
|
|
509
509
|
clientId: Joi.array().items(
|
|
510
510
|
Joi.string().required(),
|
|
511
511
|
).required(),
|
|
512
|
+
type: Joi.string().required().allow( 'review', 'approve' ),
|
|
513
|
+
sortOrder: Joi.number().allow( 1, -1 ).optional(),
|
|
512
514
|
|
|
513
515
|
|
|
514
516
|
} );
|