tango-app-api-infra 3.9.5-vms.75 → 3.9.5-vms.76
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
|
@@ -1065,7 +1065,7 @@ export async function ticketList( req, res ) {
|
|
|
1065
1065
|
if ( req.user.userType === 'tango' ) {
|
|
1066
1066
|
searchQuery.query.bool.must.push( {
|
|
1067
1067
|
terms: {
|
|
1068
|
-
'status': Array.isArray( inputData?.status ) ?
|
|
1068
|
+
'status.keyword': Array.isArray( inputData?.status ) ?
|
|
1069
1069
|
inputData?.status :
|
|
1070
1070
|
[ inputData?.status ],
|
|
1071
1071
|
},
|
|
@@ -1162,7 +1162,9 @@ export async function ticketList( req, res ) {
|
|
|
1162
1162
|
}
|
|
1163
1163
|
|
|
1164
1164
|
if ( inputData.filterByStatus && inputData.filterByStatus!=='' ) {
|
|
1165
|
-
|
|
1165
|
+
inputData.filterByStatus = inputData?.filterByStatus?.split( ',' );
|
|
1166
|
+
|
|
1167
|
+
if ( req?.user?.userType === 'tango' ) {
|
|
1166
1168
|
{
|
|
1167
1169
|
switch ( inputData?.tangoType ) {
|
|
1168
1170
|
case 'store':
|
|
@@ -1191,7 +1193,7 @@ export async function ticketList( req, res ) {
|
|
|
1191
1193
|
case 'internal':
|
|
1192
1194
|
searchQuery.query.bool.must.push( {
|
|
1193
1195
|
'terms': {
|
|
1194
|
-
'status': Array.isArray( inputData?.filterByStatus ) ?
|
|
1196
|
+
'status.keyword': Array.isArray( inputData?.filterByStatus ) ?
|
|
1195
1197
|
inputData?.filterByStatus :
|
|
1196
1198
|
[ inputData?.filterByStatus ],
|
|
1197
1199
|
},
|
|
@@ -1315,6 +1317,285 @@ export async function ticketList( req, res ) {
|
|
|
1315
1317
|
}
|
|
1316
1318
|
}
|
|
1317
1319
|
|
|
1320
|
+
if ( inputData?.filterByReviewer && inputData?.filterByReviewer !== '' ) {
|
|
1321
|
+
let percQuery = null;
|
|
1322
|
+
const value = inputData.filterByReviewer;
|
|
1323
|
+
|
|
1324
|
+
// Helper function: remove trailing '%' and convert to number
|
|
1325
|
+
const percValue = ( val ) => {
|
|
1326
|
+
if ( typeof val === 'string' ) {
|
|
1327
|
+
return parseFloat( val.replace( '%', '' ).trim() );
|
|
1328
|
+
}
|
|
1329
|
+
return parseFloat( val );
|
|
1330
|
+
};
|
|
1331
|
+
|
|
1332
|
+
// Example filter values: "<90", "<=90", ">=90", "50 to 90"
|
|
1333
|
+
if ( /^<=?\d+$/.test( value ) ) {
|
|
1334
|
+
// "<90" or "<=90"
|
|
1335
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1336
|
+
const op = value.includes( '=' ) ? 'lte' : 'lt';
|
|
1337
|
+
percQuery = {
|
|
1338
|
+
script: {
|
|
1339
|
+
script: {
|
|
1340
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'lt' ? '<' : '<='} params.num`,
|
|
1341
|
+
params: { num },
|
|
1342
|
+
},
|
|
1343
|
+
},
|
|
1344
|
+
};
|
|
1345
|
+
} else if ( /^>=?\d+$/.test( value ) ) {
|
|
1346
|
+
// ">=90"
|
|
1347
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1348
|
+
const op = value.includes( '=' ) ? 'gte' : 'gt';
|
|
1349
|
+
percQuery = {
|
|
1350
|
+
script: {
|
|
1351
|
+
script: {
|
|
1352
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'gt' ? '>' : '>='} params.num`,
|
|
1353
|
+
params: { num },
|
|
1354
|
+
},
|
|
1355
|
+
},
|
|
1356
|
+
};
|
|
1357
|
+
} else if ( /^(\d+)\s*to\s*(\d+)$/.test( value ) ) {
|
|
1358
|
+
// "50 to 90"
|
|
1359
|
+
const match = value.match( /^(\d+)\s*to\s*(\d+)$/ );
|
|
1360
|
+
const from = percValue( match[1] );
|
|
1361
|
+
const to = percValue( match[2] );
|
|
1362
|
+
percQuery = {
|
|
1363
|
+
script: {
|
|
1364
|
+
script: {
|
|
1365
|
+
source:
|
|
1366
|
+
`doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) >= params.from && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) <= params.to`,
|
|
1367
|
+
params: { from, to },
|
|
1368
|
+
},
|
|
1369
|
+
},
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
// fallback: treat as exact match (e.g., "90")
|
|
1373
|
+
if ( !percQuery && /^\d+$/.test( value ) ) {
|
|
1374
|
+
percQuery = {
|
|
1375
|
+
script: {
|
|
1376
|
+
script: {
|
|
1377
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) == params.num`,
|
|
1378
|
+
params: { num: percValue( value ) },
|
|
1379
|
+
},
|
|
1380
|
+
},
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
if ( percQuery ) {
|
|
1385
|
+
searchQuery.query.bool.must.push( {
|
|
1386
|
+
nested: {
|
|
1387
|
+
path: 'mappingInfo',
|
|
1388
|
+
query: {
|
|
1389
|
+
bool: {
|
|
1390
|
+
must: [
|
|
1391
|
+
{ term: { 'mappingInfo.type': 'review' } },
|
|
1392
|
+
percQuery,
|
|
1393
|
+
],
|
|
1394
|
+
},
|
|
1395
|
+
},
|
|
1396
|
+
},
|
|
1397
|
+
} );
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
if ( inputData?.filterByApprover && inputData?.filterByApprover !== '' ) {
|
|
1402
|
+
let percQuery = null;
|
|
1403
|
+
const value = inputData.filterByApprover;
|
|
1404
|
+
|
|
1405
|
+
// Helper function: remove trailing '%' and convert to number
|
|
1406
|
+
const percValue = ( val ) => {
|
|
1407
|
+
if ( typeof val === 'string' ) {
|
|
1408
|
+
return parseFloat( val.replace( '%', '' ).trim() );
|
|
1409
|
+
}
|
|
1410
|
+
return parseFloat( val );
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
// Example filter values: "<90", "<=90", ">=90", "50 to 90"
|
|
1414
|
+
if ( /^<=?\d+$/.test( value ) ) {
|
|
1415
|
+
// "<90" or "<=90"
|
|
1416
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1417
|
+
const op = value.includes( '=' ) ? 'lte' : 'lt';
|
|
1418
|
+
percQuery = {
|
|
1419
|
+
script: {
|
|
1420
|
+
script: {
|
|
1421
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'lt' ? '<' : '<='} params.num`,
|
|
1422
|
+
params: { num },
|
|
1423
|
+
},
|
|
1424
|
+
},
|
|
1425
|
+
};
|
|
1426
|
+
} else if ( /^>=?\d+$/.test( value ) ) {
|
|
1427
|
+
// ">=90"
|
|
1428
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1429
|
+
const op = value.includes( '=' ) ? 'gte' : 'gt';
|
|
1430
|
+
percQuery = {
|
|
1431
|
+
script: {
|
|
1432
|
+
script: {
|
|
1433
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'gt' ? '>' : '>='} params.num`,
|
|
1434
|
+
params: { num },
|
|
1435
|
+
},
|
|
1436
|
+
},
|
|
1437
|
+
};
|
|
1438
|
+
} else if ( /^(\d+)\s*to\s*(\d+)$/.test( value ) ) {
|
|
1439
|
+
// "50 to 90"
|
|
1440
|
+
const match = value.match( /^(\d+)\s*to\s*(\d+)$/ );
|
|
1441
|
+
const from = percValue( match[1] );
|
|
1442
|
+
const to = percValue( match[2] );
|
|
1443
|
+
percQuery = {
|
|
1444
|
+
script: {
|
|
1445
|
+
script: {
|
|
1446
|
+
source:
|
|
1447
|
+
`doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) >= params.from && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) <= params.to`,
|
|
1448
|
+
params: { from, to },
|
|
1449
|
+
},
|
|
1450
|
+
},
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
// fallback: treat as exact match (e.g., "90")
|
|
1454
|
+
if ( !percQuery && /^\d+$/.test( value ) ) {
|
|
1455
|
+
percQuery = {
|
|
1456
|
+
script: {
|
|
1457
|
+
script: {
|
|
1458
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) == params.num`,
|
|
1459
|
+
params: { num: percValue( value ) },
|
|
1460
|
+
},
|
|
1461
|
+
},
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
if ( percQuery ) {
|
|
1466
|
+
searchQuery.query.bool.must.push( {
|
|
1467
|
+
nested: {
|
|
1468
|
+
path: 'mappingInfo',
|
|
1469
|
+
query: {
|
|
1470
|
+
bool: {
|
|
1471
|
+
must: [
|
|
1472
|
+
{ term: { 'mappingInfo.type': 'approve' } },
|
|
1473
|
+
percQuery,
|
|
1474
|
+
],
|
|
1475
|
+
},
|
|
1476
|
+
},
|
|
1477
|
+
},
|
|
1478
|
+
} );
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
if ( inputData?.filterByTango && inputData?.filterByTango !== '' ) {
|
|
1483
|
+
let percQuery = null;
|
|
1484
|
+
const value = inputData.filterByTango;
|
|
1485
|
+
|
|
1486
|
+
// Helper function: remove trailing '%' and convert to number
|
|
1487
|
+
const percValue = ( val ) => {
|
|
1488
|
+
if ( typeof val === 'string' ) {
|
|
1489
|
+
return parseFloat( val.replace( '%', '' ).trim() );
|
|
1490
|
+
}
|
|
1491
|
+
return parseFloat( val );
|
|
1492
|
+
};
|
|
1493
|
+
|
|
1494
|
+
// Example filter values: "<90", "<=90", ">=90", "50 to 90"
|
|
1495
|
+
if ( /^<=?\d+$/.test( value ) ) {
|
|
1496
|
+
// "<90" or "<=90"
|
|
1497
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1498
|
+
const op = value.includes( '=' ) ? 'lte' : 'lt';
|
|
1499
|
+
percQuery = {
|
|
1500
|
+
script: {
|
|
1501
|
+
script: {
|
|
1502
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'lt' ? '<' : '<='} params.num`,
|
|
1503
|
+
params: { num },
|
|
1504
|
+
},
|
|
1505
|
+
},
|
|
1506
|
+
};
|
|
1507
|
+
} else if ( /^>=?\d+$/.test( value ) ) {
|
|
1508
|
+
// ">=90"
|
|
1509
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1510
|
+
const op = value.includes( '=' ) ? 'gte' : 'gt';
|
|
1511
|
+
percQuery = {
|
|
1512
|
+
script: {
|
|
1513
|
+
script: {
|
|
1514
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'gt' ? '>' : '>='} params.num`,
|
|
1515
|
+
params: { num },
|
|
1516
|
+
},
|
|
1517
|
+
},
|
|
1518
|
+
};
|
|
1519
|
+
} else if ( /^(\d+)\s*to\s*(\d+)$/.test( value ) ) {
|
|
1520
|
+
// "50 to 90"
|
|
1521
|
+
const match = value.match( /^(\d+)\s*to\s*(\d+)$/ );
|
|
1522
|
+
const from = percValue( match[1] );
|
|
1523
|
+
const to = percValue( match[2] );
|
|
1524
|
+
percQuery = {
|
|
1525
|
+
script: {
|
|
1526
|
+
script: {
|
|
1527
|
+
source:
|
|
1528
|
+
`doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) >= params.from && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) <= params.to`,
|
|
1529
|
+
params: { from, to },
|
|
1530
|
+
},
|
|
1531
|
+
},
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
// fallback: treat as exact match (e.g., "90")
|
|
1535
|
+
if ( !percQuery && /^\d+$/.test( value ) ) {
|
|
1536
|
+
percQuery = {
|
|
1537
|
+
script: {
|
|
1538
|
+
script: {
|
|
1539
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) == params.num`,
|
|
1540
|
+
params: { num: percValue( value ) },
|
|
1541
|
+
},
|
|
1542
|
+
},
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
if ( percQuery ) {
|
|
1547
|
+
searchQuery.query.bool.must.push( {
|
|
1548
|
+
nested: {
|
|
1549
|
+
path: 'mappingInfo',
|
|
1550
|
+
query: {
|
|
1551
|
+
bool: {
|
|
1552
|
+
must: [
|
|
1553
|
+
{ term: { 'mappingInfo.type': 'tangoreview' } },
|
|
1554
|
+
percQuery,
|
|
1555
|
+
],
|
|
1556
|
+
},
|
|
1557
|
+
},
|
|
1558
|
+
},
|
|
1559
|
+
} );
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
if ( inputData?.filterByReviewedBy && inputData?.filterByReviewedBy !== '' ) {
|
|
1564
|
+
inputData.filterByReviewedBy = inputData?.filterByReviewedBy?.split( ',' );
|
|
1565
|
+
searchQuery.query.bool.must.push( {
|
|
1566
|
+
nested: {
|
|
1567
|
+
path: 'mappingInfo',
|
|
1568
|
+
query: {
|
|
1569
|
+
bool: {
|
|
1570
|
+
must: [
|
|
1571
|
+
{ term: { 'mappingInfo.type': 'review' } },
|
|
1572
|
+
{ terms: { 'mappingInfo.createdByEmail': inputData?.filterByReviewedBy } },
|
|
1573
|
+
|
|
1574
|
+
],
|
|
1575
|
+
},
|
|
1576
|
+
},
|
|
1577
|
+
},
|
|
1578
|
+
} );
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
if ( inputData?.fileterByApprovedBy && inputData?.fileterByApprovedBy !== '' ) {
|
|
1582
|
+
inputData.fileterByApprovedBy = inputData?.fileterByApprovedBy?.split( ',' );
|
|
1583
|
+
searchQuery.query.bool.must.push( {
|
|
1584
|
+
nested: {
|
|
1585
|
+
path: 'mappingInfo',
|
|
1586
|
+
query: {
|
|
1587
|
+
bool: {
|
|
1588
|
+
must: [
|
|
1589
|
+
{ term: { 'mappingInfo.type': 'approve' } },
|
|
1590
|
+
{ terms: { 'mappingInfo.createdByEmail': inputData?.fileterByApprovedBy } },
|
|
1591
|
+
|
|
1592
|
+
],
|
|
1593
|
+
},
|
|
1594
|
+
},
|
|
1595
|
+
},
|
|
1596
|
+
} );
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1318
1599
|
if ( req?.user?.userType === 'tango' && inputData.tangoType !== 'internal' ) {
|
|
1319
1600
|
searchQuery.query.bool.must.push(
|
|
1320
1601
|
{
|
|
@@ -1428,7 +1709,7 @@ export async function ticketList( req, res ) {
|
|
|
1428
1709
|
// You can add more filters as needed
|
|
1429
1710
|
const searchResult = await getOpenSearchData( openSearch.footfallDirectory, searchQuery );
|
|
1430
1711
|
const count = searchResult?.body?.hits?.total?.value || 0;
|
|
1431
|
-
|
|
1712
|
+
logger.info( { searchResult } );
|
|
1432
1713
|
if ( count === 0 ) {
|
|
1433
1714
|
return res.sendError( 'no data found', 204 );
|
|
1434
1715
|
}
|
|
@@ -158,12 +158,12 @@ export const ticketListSchema = Joi.object().keys( {
|
|
|
158
158
|
sortOrder: Joi.number().valid( -1, 1 ).optional(),
|
|
159
159
|
tangoType: Joi.string().valid( 'store', 'internal', '' ).optional(),
|
|
160
160
|
permissionType: Joi.string().valid( 'review', 'approve' ).optional(),
|
|
161
|
-
filterByStatus: Joi.
|
|
162
|
-
filterByReviewer: Joi.string().optional(),
|
|
163
|
-
filterByApprover: Joi.string().optional(),
|
|
164
|
-
filterByTango: Joi.string().optional(),
|
|
165
|
-
filterByReviewedBy: Joi.
|
|
166
|
-
fileterByApprovedBy: Joi.
|
|
161
|
+
filterByStatus: Joi.string().optional().allow( '' ),
|
|
162
|
+
filterByReviewer: Joi.string().optional().allow( '' ),
|
|
163
|
+
filterByApprover: Joi.string().optional().allow( '' ),
|
|
164
|
+
filterByTango: Joi.string().optional().allow( '' ),
|
|
165
|
+
filterByReviewedBy: Joi.string().optional().allow( '' ),
|
|
166
|
+
fileterByApprovedBy: Joi.string().optional().allow( '' ),
|
|
167
167
|
fromDate: Joi.string()
|
|
168
168
|
.pattern( /^\d{4}-\d{2}-\d{2}$/, 'YYYY-MM-DD format' )
|
|
169
169
|
.required()
|