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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-infra",
3
- "version": "3.9.5-vms.90",
3
+ "version": "3.9.5-vms.91",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -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.type === 'tagging' )?.createdAt,
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.dueDate && f.type !== 'finalRevisoon' );
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( err, 500 );
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