tango-app-api-analysis-traffic 3.8.7-vms.30 → 3.8.7-vms.31

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-analysis-traffic",
3
- "version": "3.8.7-vms.30",
3
+ "version": "3.8.7-vms.31",
4
4
  "description": "Traffic Analysis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,7 +1,7 @@
1
1
  import { logger, insertOpenSearchData, getOpenSearchData, updateOpenSearchData } from 'tango-app-api-middleware';
2
2
  import { findOnerevopConfig } from '../services/revopConfig.service.js';
3
3
  import * as clientService from '../services/clients.services.js';
4
- import { bulkUpdate, insertWithId, upsertWithScript } from 'tango-app-api-middleware/src/utils/openSearch.js';
4
+ import { bulkUpdate, insertWithId, searchOpenSearchData, scrollResponse, upsertWithScript } from 'tango-app-api-middleware/src/utils/openSearch.js';
5
5
  import { findOneVmsStoreRequest } from '../services/vmsStoreRequest.service.js';
6
6
  // import dayjs from 'dayjs';
7
7
  // Lamda Service Call //
@@ -240,6 +240,114 @@ export async function migrateRevopIndex( req, res ) {
240
240
  return res.sendError( { error: error }, 500 );
241
241
  }
242
242
  }
243
+
244
+ export async function expireReviewStatus( req, res ) {
245
+ try {
246
+ const {
247
+ thresholdDate = '2025-12-20',
248
+ batchSize = 500,
249
+ storeId,
250
+ dateString,
251
+ } = req.body;
252
+ logger.info( { inputData: req.body, msg: '........1' } );
253
+ const cutoffDate = new Date( thresholdDate );
254
+ if ( Number.isNaN( cutoffDate.getTime() ) ) {
255
+ return res.sendError( 'Invalid thresholdDate', 400 );
256
+ }
257
+
258
+
259
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
260
+ const query = {
261
+ size: batchSize,
262
+ query: {
263
+ bool: {
264
+ must: [
265
+ { term: { 'ticketName.keyword': 'footfall-directory' } },
266
+ { term: { 'type.keyword': 'store' } },
267
+ ],
268
+ must_not: [
269
+ { terms: { 'status.keyword': [ 'Closed' ] } },
270
+ ],
271
+ },
272
+ },
273
+ };
274
+
275
+
276
+ if ( storeId ) {
277
+ query.query.bool.must.push( { term: { 'storeId.keyword': storeId } } );
278
+ }
279
+
280
+
281
+ if ( dateString ) {
282
+ query.query.bool.must.push( {
283
+ terms: {
284
+ dateString: Array.isArray( dateString ) ? dateString : `${dateString}`.split( ',' ),
285
+ },
286
+ } );
287
+ }
288
+
289
+
290
+ let totalUpdated = 0;
291
+ let scrollId = null;
292
+
293
+ let firstResponse = await searchOpenSearchData( openSearch.footfallDirectory, query );
294
+ let hitsBatch = firstResponse?.body?.hits?.hits || [];
295
+ logger.info( { hitsBatch } );
296
+ scrollId = firstResponse?.body?._scroll_id;
297
+
298
+ while ( hitsBatch.length > 0 ) {
299
+ const bulkBody = [];
300
+
301
+ for ( const hit of hitsBatch ) {
302
+ const src = hit._source || {};
303
+ const mappingInfo = Array.isArray( src.mappingInfo ) ? src.mappingInfo : [];
304
+ let changed = false;
305
+ const updatedMapping = mappingInfo.map( ( item ) => {
306
+ if ( item?.type === 'review'&& item?.type !== 'Closed' && item?.dueDate ) {
307
+ const due = new Date( item.dueDate );
308
+ logger.info( { due, msg: '..........1', cutoffDate } );
309
+ if ( !Number.isNaN( due.getTime() ) && due < cutoffDate ) {
310
+ changed = true;
311
+ return { ...item, status: 'Expired' };
312
+ }
313
+ }
314
+ return item;
315
+ } );
316
+
317
+
318
+ if ( changed ) {
319
+ const doc = {
320
+ mappingInfo: updatedMapping,
321
+ status: 'Expired',
322
+ };
323
+
324
+ bulkBody.push(
325
+ { update: { _index: openSearch.footfallDirectory, _id: hit._id } },
326
+ { doc: doc, doc_as_upsert: true },
327
+ );
328
+ }
329
+ }
330
+
331
+ if ( bulkBody.length > 0 ) {
332
+ const bulkRes = await bulkUpdate( bulkBody );
333
+ if ( bulkRes?.errors ) {
334
+ logger.error( { message: 'Bulk expire errors', items: bulkRes.items } );
335
+ }
336
+ totalUpdated += bulkBody.length / 2;
337
+ }
338
+ logger.info( { totalUpdated, msg: '........9' } );
339
+ if ( !scrollId ) break;
340
+ const nextRes = await scrollResponse( scrollId );
341
+ hitsBatch = nextRes?.body?.hits?.hits || [];
342
+ scrollId = nextRes?.body?._scroll_id;
343
+ }
344
+
345
+ return res.sendSuccess( { message: 'Expired review status updated', updated: totalUpdated } );
346
+ } catch ( error ) {
347
+ logger.error( { error: error, message: req.body, function: 'expireReviewStatus' } );
348
+ return res.sendError( { error: error }, 500 );
349
+ }
350
+ }
243
351
  export async function revoptaggingcount( req, res ) {
244
352
  try {
245
353
  const openSearch = JSON.parse( process.env.OPENSEARCH );
@@ -651,7 +759,7 @@ export async function footFallImages( req, res ) {
651
759
  actionType: type,
652
760
  footfall: footfallValue,
653
761
  revicedFootfall: mapping.revicedFootfall ?? 0,
654
- revicedPerc: mapping.reviced ?? '--',
762
+ revicedPerc: mapping.revicedPerc ?? '--',
655
763
  count: countObj,
656
764
  createdAt: mapping.createdAt ?? '',
657
765
  createdByEmail: mapping.createdByEmail ?? '',
@@ -666,7 +774,7 @@ export async function footFallImages( req, res ) {
666
774
  actionType: type,
667
775
  footfall: footfallValue,
668
776
  revicedFootfall: mapping.revicedFootfall ?? 0,
669
- revicedPerc: mapping.reviced ?? '--',
777
+ revicedPerc: mapping.revicedPerc ?? '--',
670
778
  count: countObj,
671
779
  createdAt: mapping.createdAt ?? '',
672
780
  createdByEmail: mapping.createdByEmail ?? '',
@@ -1,6 +1,6 @@
1
1
 
2
2
  import express from 'express';
3
- import { storeProcessedData, getconfig, revoptagging, getrevoptagging, revoptaggingcount, footFallImages, tagTempId, getCategorizedImages, vmsDataMigration, migrateRevopIndex } from '../controllers/revop.controller.js';
3
+ import { storeProcessedData, getconfig, revoptagging, getrevoptagging, revoptaggingcount, footFallImages, tagTempId, getCategorizedImages, vmsDataMigration, migrateRevopIndex, expireReviewStatus } from '../controllers/revop.controller.js';
4
4
  import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
5
5
  import { footfallImagesValid, getCategorizedImagesValid, storeProcessedDataValid, tagTempIdValid, vmsDataMigrationValid } from '../dtos/revop.dtos.js';
6
6
  import { deleteTaggedDuplicate, getTaggingConfig, mappingConfig } from '../validations/revop.validation.js';
@@ -12,6 +12,7 @@ revopRouter
12
12
  .post( '/tagging', isAllowedSessionHandler, revoptagging )
13
13
  .post( '/getrevoptagging', isAllowedSessionHandler, getrevoptagging )
14
14
  .post( '/migrate-revop', migrateRevopIndex )
15
+ .post( '/expire-review-status', expireReviewStatus )
15
16
  .post( '/revoptaggingcount', isAllowedSessionHandler, revoptaggingcount )
16
17
 
17
18
  // new enhnacemnet (for footfall directory)