tango-app-api-infra 3.9.5-vms.75 → 3.9.5-vms.77
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,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-infra",
|
|
3
|
-
"version": "3.9.5-vms.
|
|
3
|
+
"version": "3.9.5-vms.77",
|
|
4
4
|
"description": "infra",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"start": "nodemon --exec \"eslint --fix . && node
|
|
8
|
+
"start": "nodemon --exec \"eslint --fix . && node index.js\""
|
|
9
9
|
},
|
|
10
10
|
"engines": {
|
|
11
11
|
"node": ">=18.10.0"
|
|
@@ -86,6 +86,10 @@ export async function createinternalTicket( req, res ) {
|
|
|
86
86
|
mappingInfo: [],
|
|
87
87
|
};
|
|
88
88
|
const id = `${inputData.storeId}_${inputData.dateString}_internal_footfall-directory-tagging`;
|
|
89
|
+
let getExistingOne = await getOpenSearchById( openSearch.footfallDirectory, id );
|
|
90
|
+
if ( getExistingOne?.body?._source ) {
|
|
91
|
+
return res.sendError( 'Ticket Already Exists', 500 );
|
|
92
|
+
}
|
|
89
93
|
const insertResult = await insertWithId( openSearch.footfallDirectory, id, record );
|
|
90
94
|
if ( insertResult && insertResult.statusCode === 201 ) {
|
|
91
95
|
return res.sendSuccess( 'Ticket raised successfully' );
|
|
@@ -380,11 +384,15 @@ export async function tangoReviewTicket( req, res ) {
|
|
|
380
384
|
// return;
|
|
381
385
|
|
|
382
386
|
let id = `${inputData.storeId}_${inputData.dateString}_footfall-directory-tagging`;
|
|
383
|
-
|
|
387
|
+
let getExistingOne = await getOpenSearchById( openSearch.footfallDirectory, id );
|
|
388
|
+
console.log( '🚀 ~ tangoReviewTicket ~ getExistingOne:', getExistingOne );
|
|
389
|
+
if ( inputData.ticketType === 'internal'&&!getExistingOne?.body?._source ) {
|
|
384
390
|
id = `${inputData.storeId}_${inputData.dateString}_internal_footfall-directory-tagging`;
|
|
385
391
|
}
|
|
386
392
|
|
|
393
|
+
|
|
387
394
|
const insertResult = await updateOpenSearchData( openSearch.footfallDirectory, id, { doc: record } );
|
|
395
|
+
console.log( insertResult );
|
|
388
396
|
|
|
389
397
|
if ( insertResult && ( insertResult.statusCode === 201 || insertResult.statusCode === 200 ) ) {
|
|
390
398
|
return res.sendSuccess( 'Ticket closed successfully' );
|
|
@@ -392,6 +400,7 @@ export async function tangoReviewTicket( req, res ) {
|
|
|
392
400
|
return res.sendError( 'Internal Server Error', 500 );
|
|
393
401
|
}
|
|
394
402
|
} catch ( error ) {
|
|
403
|
+
console.log( '🚀 ~ tangoReviewTicket ~ error:', error );
|
|
395
404
|
const err = error.message || 'Internal Server Error';
|
|
396
405
|
logger.error( { error: error, funtion: 'tangoReviewTicket' } );
|
|
397
406
|
return res.sendError( err, 500 );
|
|
@@ -1065,7 +1074,7 @@ export async function ticketList( req, res ) {
|
|
|
1065
1074
|
if ( req.user.userType === 'tango' ) {
|
|
1066
1075
|
searchQuery.query.bool.must.push( {
|
|
1067
1076
|
terms: {
|
|
1068
|
-
'status': Array.isArray( inputData?.status ) ?
|
|
1077
|
+
'status.keyword': Array.isArray( inputData?.status ) ?
|
|
1069
1078
|
inputData?.status :
|
|
1070
1079
|
[ inputData?.status ],
|
|
1071
1080
|
},
|
|
@@ -1162,7 +1171,9 @@ export async function ticketList( req, res ) {
|
|
|
1162
1171
|
}
|
|
1163
1172
|
|
|
1164
1173
|
if ( inputData.filterByStatus && inputData.filterByStatus!=='' ) {
|
|
1165
|
-
|
|
1174
|
+
inputData.filterByStatus = inputData?.filterByStatus?.split( ',' );
|
|
1175
|
+
|
|
1176
|
+
if ( req?.user?.userType === 'tango' ) {
|
|
1166
1177
|
{
|
|
1167
1178
|
switch ( inputData?.tangoType ) {
|
|
1168
1179
|
case 'store':
|
|
@@ -1191,7 +1202,7 @@ export async function ticketList( req, res ) {
|
|
|
1191
1202
|
case 'internal':
|
|
1192
1203
|
searchQuery.query.bool.must.push( {
|
|
1193
1204
|
'terms': {
|
|
1194
|
-
'status': Array.isArray( inputData?.filterByStatus ) ?
|
|
1205
|
+
'status.keyword': Array.isArray( inputData?.filterByStatus ) ?
|
|
1195
1206
|
inputData?.filterByStatus :
|
|
1196
1207
|
[ inputData?.filterByStatus ],
|
|
1197
1208
|
},
|
|
@@ -1315,6 +1326,285 @@ export async function ticketList( req, res ) {
|
|
|
1315
1326
|
}
|
|
1316
1327
|
}
|
|
1317
1328
|
|
|
1329
|
+
if ( inputData?.filterByReviewer && inputData?.filterByReviewer !== '' ) {
|
|
1330
|
+
let percQuery = null;
|
|
1331
|
+
const value = inputData.filterByReviewer;
|
|
1332
|
+
|
|
1333
|
+
// Helper function: remove trailing '%' and convert to number
|
|
1334
|
+
const percValue = ( val ) => {
|
|
1335
|
+
if ( typeof val === 'string' ) {
|
|
1336
|
+
return parseFloat( val.replace( '%', '' ).trim() );
|
|
1337
|
+
}
|
|
1338
|
+
return parseFloat( val );
|
|
1339
|
+
};
|
|
1340
|
+
|
|
1341
|
+
// Example filter values: "<90", "<=90", ">=90", "50 to 90"
|
|
1342
|
+
if ( /^<=?\d+$/.test( value ) ) {
|
|
1343
|
+
// "<90" or "<=90"
|
|
1344
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1345
|
+
const op = value.includes( '=' ) ? 'lte' : 'lt';
|
|
1346
|
+
percQuery = {
|
|
1347
|
+
script: {
|
|
1348
|
+
script: {
|
|
1349
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'lt' ? '<' : '<='} params.num`,
|
|
1350
|
+
params: { num },
|
|
1351
|
+
},
|
|
1352
|
+
},
|
|
1353
|
+
};
|
|
1354
|
+
} else if ( /^>=?\d+$/.test( value ) ) {
|
|
1355
|
+
// ">=90"
|
|
1356
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1357
|
+
const op = value.includes( '=' ) ? 'gte' : 'gt';
|
|
1358
|
+
percQuery = {
|
|
1359
|
+
script: {
|
|
1360
|
+
script: {
|
|
1361
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'gt' ? '>' : '>='} params.num`,
|
|
1362
|
+
params: { num },
|
|
1363
|
+
},
|
|
1364
|
+
},
|
|
1365
|
+
};
|
|
1366
|
+
} else if ( /^(\d+)\s*to\s*(\d+)$/.test( value ) ) {
|
|
1367
|
+
// "50 to 90"
|
|
1368
|
+
const match = value.match( /^(\d+)\s*to\s*(\d+)$/ );
|
|
1369
|
+
const from = percValue( match[1] );
|
|
1370
|
+
const to = percValue( match[2] );
|
|
1371
|
+
percQuery = {
|
|
1372
|
+
script: {
|
|
1373
|
+
script: {
|
|
1374
|
+
source:
|
|
1375
|
+
`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`,
|
|
1376
|
+
params: { from, to },
|
|
1377
|
+
},
|
|
1378
|
+
},
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
// fallback: treat as exact match (e.g., "90")
|
|
1382
|
+
if ( !percQuery && /^\d+$/.test( value ) ) {
|
|
1383
|
+
percQuery = {
|
|
1384
|
+
script: {
|
|
1385
|
+
script: {
|
|
1386
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) == params.num`,
|
|
1387
|
+
params: { num: percValue( value ) },
|
|
1388
|
+
},
|
|
1389
|
+
},
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
if ( percQuery ) {
|
|
1394
|
+
searchQuery.query.bool.must.push( {
|
|
1395
|
+
nested: {
|
|
1396
|
+
path: 'mappingInfo',
|
|
1397
|
+
query: {
|
|
1398
|
+
bool: {
|
|
1399
|
+
must: [
|
|
1400
|
+
{ term: { 'mappingInfo.type': 'review' } },
|
|
1401
|
+
percQuery,
|
|
1402
|
+
],
|
|
1403
|
+
},
|
|
1404
|
+
},
|
|
1405
|
+
},
|
|
1406
|
+
} );
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
if ( inputData?.filterByApprover && inputData?.filterByApprover !== '' ) {
|
|
1411
|
+
let percQuery = null;
|
|
1412
|
+
const value = inputData.filterByApprover;
|
|
1413
|
+
|
|
1414
|
+
// Helper function: remove trailing '%' and convert to number
|
|
1415
|
+
const percValue = ( val ) => {
|
|
1416
|
+
if ( typeof val === 'string' ) {
|
|
1417
|
+
return parseFloat( val.replace( '%', '' ).trim() );
|
|
1418
|
+
}
|
|
1419
|
+
return parseFloat( val );
|
|
1420
|
+
};
|
|
1421
|
+
|
|
1422
|
+
// Example filter values: "<90", "<=90", ">=90", "50 to 90"
|
|
1423
|
+
if ( /^<=?\d+$/.test( value ) ) {
|
|
1424
|
+
// "<90" or "<=90"
|
|
1425
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1426
|
+
const op = value.includes( '=' ) ? 'lte' : 'lt';
|
|
1427
|
+
percQuery = {
|
|
1428
|
+
script: {
|
|
1429
|
+
script: {
|
|
1430
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'lt' ? '<' : '<='} params.num`,
|
|
1431
|
+
params: { num },
|
|
1432
|
+
},
|
|
1433
|
+
},
|
|
1434
|
+
};
|
|
1435
|
+
} else if ( /^>=?\d+$/.test( value ) ) {
|
|
1436
|
+
// ">=90"
|
|
1437
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1438
|
+
const op = value.includes( '=' ) ? 'gte' : 'gt';
|
|
1439
|
+
percQuery = {
|
|
1440
|
+
script: {
|
|
1441
|
+
script: {
|
|
1442
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'gt' ? '>' : '>='} params.num`,
|
|
1443
|
+
params: { num },
|
|
1444
|
+
},
|
|
1445
|
+
},
|
|
1446
|
+
};
|
|
1447
|
+
} else if ( /^(\d+)\s*to\s*(\d+)$/.test( value ) ) {
|
|
1448
|
+
// "50 to 90"
|
|
1449
|
+
const match = value.match( /^(\d+)\s*to\s*(\d+)$/ );
|
|
1450
|
+
const from = percValue( match[1] );
|
|
1451
|
+
const to = percValue( match[2] );
|
|
1452
|
+
percQuery = {
|
|
1453
|
+
script: {
|
|
1454
|
+
script: {
|
|
1455
|
+
source:
|
|
1456
|
+
`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`,
|
|
1457
|
+
params: { from, to },
|
|
1458
|
+
},
|
|
1459
|
+
},
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
// fallback: treat as exact match (e.g., "90")
|
|
1463
|
+
if ( !percQuery && /^\d+$/.test( value ) ) {
|
|
1464
|
+
percQuery = {
|
|
1465
|
+
script: {
|
|
1466
|
+
script: {
|
|
1467
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) == params.num`,
|
|
1468
|
+
params: { num: percValue( value ) },
|
|
1469
|
+
},
|
|
1470
|
+
},
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
if ( percQuery ) {
|
|
1475
|
+
searchQuery.query.bool.must.push( {
|
|
1476
|
+
nested: {
|
|
1477
|
+
path: 'mappingInfo',
|
|
1478
|
+
query: {
|
|
1479
|
+
bool: {
|
|
1480
|
+
must: [
|
|
1481
|
+
{ term: { 'mappingInfo.type': 'approve' } },
|
|
1482
|
+
percQuery,
|
|
1483
|
+
],
|
|
1484
|
+
},
|
|
1485
|
+
},
|
|
1486
|
+
},
|
|
1487
|
+
} );
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
if ( inputData?.filterByTango && inputData?.filterByTango !== '' ) {
|
|
1492
|
+
let percQuery = null;
|
|
1493
|
+
const value = inputData.filterByTango;
|
|
1494
|
+
|
|
1495
|
+
// Helper function: remove trailing '%' and convert to number
|
|
1496
|
+
const percValue = ( val ) => {
|
|
1497
|
+
if ( typeof val === 'string' ) {
|
|
1498
|
+
return parseFloat( val.replace( '%', '' ).trim() );
|
|
1499
|
+
}
|
|
1500
|
+
return parseFloat( val );
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
// Example filter values: "<90", "<=90", ">=90", "50 to 90"
|
|
1504
|
+
if ( /^<=?\d+$/.test( value ) ) {
|
|
1505
|
+
// "<90" or "<=90"
|
|
1506
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1507
|
+
const op = value.includes( '=' ) ? 'lte' : 'lt';
|
|
1508
|
+
percQuery = {
|
|
1509
|
+
script: {
|
|
1510
|
+
script: {
|
|
1511
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'lt' ? '<' : '<='} params.num`,
|
|
1512
|
+
params: { num },
|
|
1513
|
+
},
|
|
1514
|
+
},
|
|
1515
|
+
};
|
|
1516
|
+
} else if ( /^>=?\d+$/.test( value ) ) {
|
|
1517
|
+
// ">=90"
|
|
1518
|
+
const num = percValue( value.replace( /[^\d]/g, '' ) );
|
|
1519
|
+
const op = value.includes( '=' ) ? 'gte' : 'gt';
|
|
1520
|
+
percQuery = {
|
|
1521
|
+
script: {
|
|
1522
|
+
script: {
|
|
1523
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) ${op === 'gt' ? '>' : '>='} params.num`,
|
|
1524
|
+
params: { num },
|
|
1525
|
+
},
|
|
1526
|
+
},
|
|
1527
|
+
};
|
|
1528
|
+
} else if ( /^(\d+)\s*to\s*(\d+)$/.test( value ) ) {
|
|
1529
|
+
// "50 to 90"
|
|
1530
|
+
const match = value.match( /^(\d+)\s*to\s*(\d+)$/ );
|
|
1531
|
+
const from = percValue( match[1] );
|
|
1532
|
+
const to = percValue( match[2] );
|
|
1533
|
+
percQuery = {
|
|
1534
|
+
script: {
|
|
1535
|
+
script: {
|
|
1536
|
+
source:
|
|
1537
|
+
`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`,
|
|
1538
|
+
params: { from, to },
|
|
1539
|
+
},
|
|
1540
|
+
},
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
// fallback: treat as exact match (e.g., "90")
|
|
1544
|
+
if ( !percQuery && /^\d+$/.test( value ) ) {
|
|
1545
|
+
percQuery = {
|
|
1546
|
+
script: {
|
|
1547
|
+
script: {
|
|
1548
|
+
source: `doc['mappingInfo.revicedPerc.keyword'].size()!=0 && Integer.parseInt(doc['mappingInfo.revicedPerc.keyword'].value.replace('%','')) == params.num`,
|
|
1549
|
+
params: { num: percValue( value ) },
|
|
1550
|
+
},
|
|
1551
|
+
},
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
if ( percQuery ) {
|
|
1556
|
+
searchQuery.query.bool.must.push( {
|
|
1557
|
+
nested: {
|
|
1558
|
+
path: 'mappingInfo',
|
|
1559
|
+
query: {
|
|
1560
|
+
bool: {
|
|
1561
|
+
must: [
|
|
1562
|
+
{ term: { 'mappingInfo.type': 'tangoreview' } },
|
|
1563
|
+
percQuery,
|
|
1564
|
+
],
|
|
1565
|
+
},
|
|
1566
|
+
},
|
|
1567
|
+
},
|
|
1568
|
+
} );
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
if ( inputData?.filterByReviewedBy && inputData?.filterByReviewedBy !== '' ) {
|
|
1573
|
+
inputData.filterByReviewedBy = inputData?.filterByReviewedBy?.split( ',' );
|
|
1574
|
+
searchQuery.query.bool.must.push( {
|
|
1575
|
+
nested: {
|
|
1576
|
+
path: 'mappingInfo',
|
|
1577
|
+
query: {
|
|
1578
|
+
bool: {
|
|
1579
|
+
must: [
|
|
1580
|
+
{ term: { 'mappingInfo.type': 'review' } },
|
|
1581
|
+
{ terms: { 'mappingInfo.createdByEmail': inputData?.filterByReviewedBy } },
|
|
1582
|
+
|
|
1583
|
+
],
|
|
1584
|
+
},
|
|
1585
|
+
},
|
|
1586
|
+
},
|
|
1587
|
+
} );
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
if ( inputData?.fileterByApprovedBy && inputData?.fileterByApprovedBy !== '' ) {
|
|
1591
|
+
inputData.fileterByApprovedBy = inputData?.fileterByApprovedBy?.split( ',' );
|
|
1592
|
+
searchQuery.query.bool.must.push( {
|
|
1593
|
+
nested: {
|
|
1594
|
+
path: 'mappingInfo',
|
|
1595
|
+
query: {
|
|
1596
|
+
bool: {
|
|
1597
|
+
must: [
|
|
1598
|
+
{ term: { 'mappingInfo.type': 'approve' } },
|
|
1599
|
+
{ terms: { 'mappingInfo.createdByEmail': inputData?.fileterByApprovedBy } },
|
|
1600
|
+
|
|
1601
|
+
],
|
|
1602
|
+
},
|
|
1603
|
+
},
|
|
1604
|
+
},
|
|
1605
|
+
} );
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1318
1608
|
if ( req?.user?.userType === 'tango' && inputData.tangoType !== 'internal' ) {
|
|
1319
1609
|
searchQuery.query.bool.must.push(
|
|
1320
1610
|
{
|
|
@@ -1428,7 +1718,7 @@ export async function ticketList( req, res ) {
|
|
|
1428
1718
|
// You can add more filters as needed
|
|
1429
1719
|
const searchResult = await getOpenSearchData( openSearch.footfallDirectory, searchQuery );
|
|
1430
1720
|
const count = searchResult?.body?.hits?.total?.value || 0;
|
|
1431
|
-
|
|
1721
|
+
logger.info( { searchResult } );
|
|
1432
1722
|
if ( count === 0 ) {
|
|
1433
1723
|
return res.sendError( 'no data found', 204 );
|
|
1434
1724
|
}
|
|
@@ -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()
|