tango-app-api-infra 3.9.5-vms.90 → 3.9.5-vms.91
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
|
@@ -3033,6 +3033,7 @@ export async function ticketList( req, res ) {
|
|
|
3033
3033
|
if ( inputData?.isExport ) {
|
|
3034
3034
|
const exportData = [];
|
|
3035
3035
|
for ( let item of ticketListData ) {
|
|
3036
|
+
console.log( item );
|
|
3036
3037
|
exportData.push( {
|
|
3037
3038
|
|
|
3038
3039
|
'Ticket ID': item?.ticketId,
|
|
@@ -3054,25 +3055,26 @@ export async function ticketList( req, res ) {
|
|
|
3054
3055
|
'Reviewer (%)': item?.mappingInfo?.find( ( f ) => f.type === 'review' )?.revicedPerc || '--',
|
|
3055
3056
|
'Approver (%)': item?.mappingInfo?.find( ( f ) => f.type === 'approve' )?.revicedPerc || '--',
|
|
3056
3057
|
'Tango (%)': item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.revicedPerc || '--',
|
|
3057
|
-
'Ticket Status': item?.status,
|
|
3058
|
-
'Tango Status': item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.status || '--',
|
|
3058
|
+
'Ticket Status': item?.type === 'store'? item?.status : '',
|
|
3059
|
+
'Tango Status': item?.type === 'store'? item?.mappingInfo?.find( ( f ) => f.type === 'tangoreview' )?.status || '--' : item.status,
|
|
3059
3060
|
|
|
3060
3061
|
} );
|
|
3061
3062
|
}
|
|
3062
3063
|
return await download( exportData, res );
|
|
3063
3064
|
} else {
|
|
3064
3065
|
for ( let item of ticketListData ) {
|
|
3066
|
+
console.log( '🚀 ~ ticketList ~ item:', item );
|
|
3065
3067
|
temp.push( {
|
|
3066
3068
|
|
|
3067
3069
|
ticketId: item?.ticketId,
|
|
3068
3070
|
storeId: item?.storeId,
|
|
3069
3071
|
storeName: item?.storeName,
|
|
3070
|
-
ticketRaised: item?.mappingInfo?.find( ( f ) => f
|
|
3072
|
+
ticketRaised: item?.mappingInfo?.find( ( f ) => f?.type === 'tagging' )?.createdAt,
|
|
3071
3073
|
issueDate: item?.dateString,
|
|
3072
3074
|
footfall: item?.footfallCount,
|
|
3073
3075
|
dueDate: ( () => {
|
|
3074
3076
|
if ( Array.isArray( item?.mappingInfo ) ) {
|
|
3075
|
-
const filtered = item.mappingInfo.filter( ( f ) => f
|
|
3077
|
+
const filtered = item.mappingInfo.filter( ( f ) => f?.dueDate && f?.type !== 'finalRevisoon' );
|
|
3076
3078
|
return filtered.length > 0 ? filtered[filtered.length - 1].dueDate : '';
|
|
3077
3079
|
}
|
|
3078
3080
|
return '';
|
|
@@ -3287,7 +3289,7 @@ export async function getTickets( req, res ) {
|
|
|
3287
3289
|
const inputData = req.query;
|
|
3288
3290
|
|
|
3289
3291
|
|
|
3290
|
-
let source = [ 'storeId', 'type', 'dateString', 'ticketName', 'revicedFootfall', 'revicedPerc', 'mappingInfo', 'footfallCount', 'employeeCount', 'houseKeepingCount', 'duplicateCount', 'junkCount', 'junkACCount', 'comments', 'employee', 'houseKeeping', 'junk', 'duplicateImages', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'email', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus', 'junkStatus', 'houseKeepingACCount', 'houseKeepingCount', 'employeeCount', 'employeeACCount', 'duplicateCount', 'duplicateACCount', 'approverRole', 'approverUserName', 'approverEmail', 'type' ];
|
|
3292
|
+
let source = [ 'storeId', 'createdByEmail', 'type', 'dateString', 'ticketName', 'revicedFootfall', 'revicedPerc', 'mappingInfo', 'footfallCount', 'employeeCount', 'houseKeepingCount', 'duplicateCount', 'junkCount', 'junkACCount', 'comments', 'employee', 'houseKeeping', 'junk', 'duplicateImages', 'ticketId', 'clientId', 'storeName', 'createdAt', 'updatedAt', 'userName', 'email', 'role', 'status', 'employeeStatus', 'houseKeepingStatus', 'duplicateStatus', 'junkStatus', 'houseKeepingACCount', 'houseKeepingCount', 'employeeCount', 'employeeACCount', 'duplicateCount', 'duplicateACCount', 'approverRole', 'approverUserName', 'approverEmail', 'type' ];
|
|
3291
3293
|
let filter = [
|
|
3292
3294
|
|
|
3293
3295
|
{
|
|
@@ -3334,6 +3336,7 @@ export async function getTickets( req, res ) {
|
|
|
3334
3336
|
response.map( ( hit ) => {
|
|
3335
3337
|
const defaultData = {
|
|
3336
3338
|
storeId: hit._source.storeId,
|
|
3339
|
+
createdByEmail: hit?._source?.createdByEmail,
|
|
3337
3340
|
dateString: hit?._source?.dateString,
|
|
3338
3341
|
ticketName: hit?._source?.ticketName,
|
|
3339
3342
|
status: hit?._source?.status?.revicedFootfall,
|
|
@@ -4457,6 +4460,14 @@ async function extractTempIds( document ) {
|
|
|
4457
4460
|
export async function reviewerList( req, res ) {
|
|
4458
4461
|
try {
|
|
4459
4462
|
const inputData = req.query;
|
|
4463
|
+
|
|
4464
|
+
console.log( '🚀 ~ reviewerList ~ inputData.tangotype:', inputData.tangotype );
|
|
4465
|
+
if ( inputData.tangotype!=''&&inputData.tangotype==='internal' ) {
|
|
4466
|
+
const getUserlist = await findUser( { userType: 'tango' }, { userName: 1, email: 1, role: 1 } );
|
|
4467
|
+
return res.sendSuccess( getUserlist || [] );
|
|
4468
|
+
}
|
|
4469
|
+
|
|
4470
|
+
|
|
4460
4471
|
// Build the query for users who have rolespermission with featureName "FootfallDirectory",
|
|
4461
4472
|
// and a module "Reviewer" where isAdd or isEdit is true.
|
|
4462
4473
|
const reviewerRoleQuery = {
|
|
@@ -515,6 +515,7 @@ export const downloadTicketsValid = {
|
|
|
515
515
|
|
|
516
516
|
export const reviewerListSchema = Joi.object().keys( {
|
|
517
517
|
clientId: Joi.string().required(),
|
|
518
|
+
tangotype: Joi.string().optional(),
|
|
518
519
|
type: Joi.string().required().allow( 'approve', 'review' ),
|
|
519
520
|
} );
|
|
520
521
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bulkUpdate, getOpenSearchCount, getOpenSearchData, insertWithId, logger, sendMessageToFIFOQueue, updateOpenSearchData } from 'tango-app-api-middleware';
|
|
1
|
+
import { bulkUpdate, getOpenSearchCount, getOpenSearchData, insertWithId, logger, sendMessageToFIFOQueue, updateOpenSearchData, getOpenSearchById } from 'tango-app-api-middleware';
|
|
2
2
|
import { aggregateCluster } from '../services/cluster.service.js';
|
|
3
3
|
import { findOneRevopDownload } from '../services/revopDownload.service.js';
|
|
4
4
|
import { findOneStore } from '../services/store.service.js';
|
|
@@ -957,13 +957,14 @@ export async function ticketReview( req, res, next ) {
|
|
|
957
957
|
// check the createtion permission from the user permission
|
|
958
958
|
const userInfo = req?.user;
|
|
959
959
|
const ticketsFeature = userInfo?.rolespermission?.some( ( f ) => f.featureName === 'FootfallDirectory' && ( f.modules.find( ( m ) => m.name == 'reviewer' && ( m.isAdd == true || m.isEdit == true ) ) ) );
|
|
960
|
+
logger.info( { ticketsFeature, userInfo } );
|
|
960
961
|
if ( !ticketsFeature ) {
|
|
961
962
|
return res.sendError( 'Forbidden to Reiew this Ticket', 403 );
|
|
962
963
|
}
|
|
963
964
|
|
|
964
965
|
// get store info by the storeId into mongo db
|
|
965
966
|
const getstoreName = await findOneStore( { storeId: inputData.storeId, status: 'active' }, { storeId: 1, storeName: 1, clientId: 1 } );
|
|
966
|
-
|
|
967
|
+
logger.info( { getstoreName } );
|
|
967
968
|
if ( !getstoreName || getstoreName == null ) {
|
|
968
969
|
return res.sendError( 'The store ID is either inActive or not found', 400 );
|
|
969
970
|
}
|
|
@@ -1074,6 +1075,8 @@ export async function ticketReview( req, res, next ) {
|
|
|
1074
1075
|
return res.sendError( 'The Client ID is either not configured or not found', 400 );
|
|
1075
1076
|
}
|
|
1076
1077
|
|
|
1078
|
+
logger.info( { config } );
|
|
1079
|
+
|
|
1077
1080
|
// Get taggingLimitation from config (check both possible paths)
|
|
1078
1081
|
const taggingLimitation = getConfig?.effectiveLimitation?.values;
|
|
1079
1082
|
// Initialize count object from taggingLimitation
|
|
@@ -1148,7 +1151,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1148
1151
|
|
|
1149
1152
|
const revopData = await getOpenSearchData( openSearch.revop, revopQuery );
|
|
1150
1153
|
const buckets = revopData?.body?.aggregations?.type_counts?.buckets || [];
|
|
1151
|
-
|
|
1154
|
+
logger.info( { revopData } );
|
|
1152
1155
|
// Map OpenSearch revopsType values to count object keys
|
|
1153
1156
|
buckets.forEach( ( bucket ) => {
|
|
1154
1157
|
const revopsType = bucket.key;
|
|
@@ -1181,6 +1184,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1181
1184
|
if ( footfallCount - revisedFootfall == 0 ) {
|
|
1182
1185
|
return res.sendError( 'Cannot review a ticket because footfall hasn’t changed', 400 );
|
|
1183
1186
|
}
|
|
1187
|
+
logger.info( { footfallCount, revisedFootfall } );
|
|
1184
1188
|
const taggingData = {
|
|
1185
1189
|
size: 10000,
|
|
1186
1190
|
query: {
|
|
@@ -1213,6 +1217,16 @@ export async function ticketReview( req, res, next ) {
|
|
|
1213
1217
|
query: {
|
|
1214
1218
|
bool: {
|
|
1215
1219
|
must: [
|
|
1220
|
+
{
|
|
1221
|
+
term: {
|
|
1222
|
+
'type.keyword': 'store',
|
|
1223
|
+
},
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
term: {
|
|
1227
|
+
'type.keyword': 'store',
|
|
1228
|
+
},
|
|
1229
|
+
},
|
|
1216
1230
|
{
|
|
1217
1231
|
term: {
|
|
1218
1232
|
'storeId.keyword': inputData.storeId,
|
|
@@ -1233,6 +1247,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1233
1247
|
if ( !ticketData || ticketData?.length == 0 ) {
|
|
1234
1248
|
return res.sendError( 'You don’t have any tagged images right now', 400 );
|
|
1235
1249
|
}
|
|
1250
|
+
logger.info( { ticketData, mappingInfo: ticketData?.[0]?._source?.mappingInfo } );
|
|
1236
1251
|
const record = {
|
|
1237
1252
|
|
|
1238
1253
|
status: 'Reviewer-Closed',
|
|
@@ -1245,7 +1260,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1245
1260
|
// createdByRole: req?.user?.role,
|
|
1246
1261
|
|
|
1247
1262
|
};
|
|
1248
|
-
|
|
1263
|
+
logger.info( { record } );
|
|
1249
1264
|
if ( Array.isArray( record.mappingInfo ) ) {
|
|
1250
1265
|
const temp = record.mappingInfo
|
|
1251
1266
|
.filter( ( item ) => item.type === 'review' )
|
|
@@ -1287,7 +1302,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1287
1302
|
// Retrieve client footfallDirectoryConfigs revision
|
|
1288
1303
|
let isAutoCloseEnable = getConfig?.footfallDirectoryConfigs?.isAutoCloseEnable; ;
|
|
1289
1304
|
let autoCloseAccuracy = getConfig?.footfallDirectoryConfigs?.autoCloseAccuracy;
|
|
1290
|
-
|
|
1305
|
+
logger.info( { isAutoCloseEnable, autoCloseAccuracy } );
|
|
1291
1306
|
|
|
1292
1307
|
const getNumber = autoCloseAccuracy.split( '%' )[0];
|
|
1293
1308
|
let autoCloseAccuracyValue = parseFloat( ( autoCloseAccuracy || getNumber ).replace( '%', '' ) );
|
|
@@ -1366,13 +1381,14 @@ export async function ticketReview( req, res, next ) {
|
|
|
1366
1381
|
createdAt: new Date(),
|
|
1367
1382
|
},
|
|
1368
1383
|
);
|
|
1384
|
+
logger.info( { revisedPercentage } );
|
|
1369
1385
|
} else {
|
|
1370
1386
|
// If ticket is closed, do not proceed with revision mapping
|
|
1371
1387
|
let revisionArray = [];
|
|
1372
1388
|
|
|
1373
1389
|
|
|
1374
1390
|
revisionArray = getConfig?.footfallDirectoryConfigs?.revision || [];
|
|
1375
|
-
|
|
1391
|
+
logger.info( { revisionArray } );
|
|
1376
1392
|
|
|
1377
1393
|
// Default fallbacks
|
|
1378
1394
|
let revisionMapping = null;
|
|
@@ -1405,7 +1421,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1405
1421
|
}
|
|
1406
1422
|
}
|
|
1407
1423
|
}
|
|
1408
|
-
|
|
1424
|
+
logger.info( { record } );
|
|
1409
1425
|
// Insert appropriate mappingInfo blocks
|
|
1410
1426
|
if ( revisionMapping ) {
|
|
1411
1427
|
// If reviewer and checked
|
|
@@ -1422,7 +1438,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1422
1438
|
let checkreview = getConfig.footfallDirectoryConfigs.revision.filter( ( data ) => data.actionType === 'reviewer' && data.isChecked === true );
|
|
1423
1439
|
|
|
1424
1440
|
|
|
1425
|
-
if ( checkreview.length > 0 ) {
|
|
1441
|
+
if ( checkreview.length > 0&&record.status!='Reviewer-Closed' ) {
|
|
1426
1442
|
let userQuery = [
|
|
1427
1443
|
{
|
|
1428
1444
|
$match: {
|
|
@@ -1441,6 +1457,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1441
1457
|
let createdOn = dayjs().format( 'DD MMM YYYY' );
|
|
1442
1458
|
let description = `Created on ${createdOn}`;
|
|
1443
1459
|
|
|
1460
|
+
|
|
1444
1461
|
let Data = {
|
|
1445
1462
|
'title': title,
|
|
1446
1463
|
'body': description,
|
|
@@ -1463,6 +1480,36 @@ export async function ticketReview( req, res, next ) {
|
|
|
1463
1480
|
}
|
|
1464
1481
|
|
|
1465
1482
|
const id = `${inputData.storeId}_${inputData.dateString}_footfall-directory-tagging`;
|
|
1483
|
+
console.log( '-----', record.status );
|
|
1484
|
+
if ( record.status==='Reviewer-Closed' ) {
|
|
1485
|
+
console.log( '🚀 ~ ticketReview ~ id:', id );
|
|
1486
|
+
let Ticket = await getOpenSearchById( openSearch.footfallDirectory, id );
|
|
1487
|
+
console.log( '🚀 ~ ticketReview ~ Ticket:', Ticket.body );
|
|
1488
|
+
if ( Ticket?.body?._source?.type==='store' ) {
|
|
1489
|
+
let findTagging = Ticket?.body?._source?.mappingInfo.filter( ( data ) => data.type==='tagging' );
|
|
1490
|
+
if ( findTagging?.length>0&&findTagging[0].createdByEmail!='' ) {
|
|
1491
|
+
let userData = await findOneUser( { email: findTagging[0]?.createdByEmail } );
|
|
1492
|
+
console.log( '🚀 ~ ticketReview ~ findTagging[0]?.createdByEmail:', findTagging[0]?.createdByEmail );
|
|
1493
|
+
let title = `Received response for the Footfall ticket raised.`;
|
|
1494
|
+
let createdOn = dayjs( Ticket?.body?._source?.dateString ).format( 'DD MMM YYYY' );
|
|
1495
|
+
let description = `Raised on ${createdOn}`;
|
|
1496
|
+
|
|
1497
|
+
let Data = {
|
|
1498
|
+
'title': title,
|
|
1499
|
+
'body': description,
|
|
1500
|
+
'type': 'closed',
|
|
1501
|
+
'date': Ticket?.body?._source?.dateString,
|
|
1502
|
+
'storeId': Ticket?.body?._source?.storeId,
|
|
1503
|
+
'clientId': Ticket?.body?._source?.clientId,
|
|
1504
|
+
'ticketId': Ticket?.body?._source?.ticketId,
|
|
1505
|
+
};
|
|
1506
|
+
if ( userData && userData.fcmToken ) {
|
|
1507
|
+
const fcmToken = userData.fcmToken;
|
|
1508
|
+
await sendPushNotification( title, description, fcmToken, Data );
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1466
1513
|
const insertResult = await updateOpenSearchData( openSearch.footfallDirectory, id, { doc: record } );
|
|
1467
1514
|
|
|
1468
1515
|
if ( insertResult && insertResult.statusCode === 201 || insertResult.statusCode === 200 ) {
|
|
@@ -1552,7 +1599,7 @@ export async function ticketReview( req, res, next ) {
|
|
|
1552
1599
|
} catch ( error ) {
|
|
1553
1600
|
const err = error.message || 'Internal Server Error';
|
|
1554
1601
|
logger.error( { error: err, funtion: 'ticketreview' } );
|
|
1555
|
-
return res.sendError(
|
|
1602
|
+
return res.sendError( error, 500 );
|
|
1556
1603
|
}
|
|
1557
1604
|
}
|
|
1558
1605
|
|
|
@@ -1834,6 +1881,11 @@ export async function ticketApprove( req, res, next ) {
|
|
|
1834
1881
|
query: {
|
|
1835
1882
|
bool: {
|
|
1836
1883
|
must: [
|
|
1884
|
+
{
|
|
1885
|
+
term: {
|
|
1886
|
+
'type.keyword': 'store',
|
|
1887
|
+
},
|
|
1888
|
+
},
|
|
1837
1889
|
{
|
|
1838
1890
|
term: {
|
|
1839
1891
|
'storeId.keyword': inputData.storeId,
|
|
@@ -2136,6 +2188,37 @@ export async function ticketApprove( req, res, next ) {
|
|
|
2136
2188
|
}
|
|
2137
2189
|
|
|
2138
2190
|
const id = `${inputData.storeId}_${inputData.dateString}_footfall-directory-tagging`;
|
|
2191
|
+
console.log( '🚀 ~ ticketReview ~ id:', id );
|
|
2192
|
+
console.log( '🚀 ~ ticketReview ~ id:', id );
|
|
2193
|
+
console.log( '🚀 ~ ticketReview ~ id:', id );
|
|
2194
|
+
if ( record.status==='Approver-Closed' ) {
|
|
2195
|
+
let Ticket = await getOpenSearchById( openSearch.footfallDirectory, id );
|
|
2196
|
+
console.log( '🚀 ~ ticketApprove ~ Ticket:', Ticket?.body );
|
|
2197
|
+
if ( Ticket?.body?._source?.type==='store' ) {
|
|
2198
|
+
let findTagging = Ticket?.body?._source?.mappingInfo.filter( ( data ) => data.type==='tagging' );
|
|
2199
|
+
console.log( '🚀 ~ ticketApprove ~ findTagging[0].createdByEmail:', findTagging[0].createdByEmail );
|
|
2200
|
+
if ( findTagging?.length>0&&findTagging[0].createdByEmail!='' ) {
|
|
2201
|
+
let userData = await findOneUser( { email: findTagging[0]?.createdByEmail } );
|
|
2202
|
+
let title = `Received response for the Footfall ticket raised.`;
|
|
2203
|
+
let createdOn = dayjs( Ticket?.body?._source?.dateString ).format( 'DD MMM YYYY' );
|
|
2204
|
+
let description = `Raised on ${createdOn}`;
|
|
2205
|
+
|
|
2206
|
+
let Data = {
|
|
2207
|
+
'title': title,
|
|
2208
|
+
'body': description,
|
|
2209
|
+
'type': 'closed',
|
|
2210
|
+
'date': Ticket?.body?._source?.dateString,
|
|
2211
|
+
'storeId': Ticket?.body?._source?.storeId,
|
|
2212
|
+
'clientId': Ticket?.body?._source?.clientId,
|
|
2213
|
+
'ticketId': Ticket?.body?._source?.ticketId,
|
|
2214
|
+
};
|
|
2215
|
+
if ( userData && userData.fcmToken ) {
|
|
2216
|
+
const fcmToken = userData.fcmToken;
|
|
2217
|
+
await sendPushNotification( title, description, fcmToken, Data );
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2139
2222
|
const insertResult = await updateOpenSearchData( openSearch.footfallDirectory, id, { doc: record } );
|
|
2140
2223
|
|
|
2141
2224
|
|