tango-app-api-analysis-traffic 3.8.9 → 3.8.12

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.
@@ -3129,29 +3129,30 @@ export const managerTrafficDensityExport = async ( req, res ) => {
3129
3129
  }
3130
3130
  };
3131
3131
 
3132
- // async function getGeocodedAddress( lat, lng ) {
3133
- // try {
3134
- // const apiKey = 'AIzaSyDlOezgwQO0JviD0aizrCuN1FY9tcWfR3o'; // Use this if you're using dotenv
3135
- // const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${apiKey}`;
3136
-
3137
- // const requestOptions = {
3138
- // method: 'GET',
3139
- // headers: {
3140
- // 'Content-Type': 'application/json',
3141
- // },
3142
- // };
3143
- // const response = await fetch( url, requestOptions );
3144
- // console.log( 'response =>', response );
3145
- // if ( !response.ok ) {
3146
- // throw new Error( `Response status: ${response.status}` );
3147
- // return false;
3148
- // }
3149
- // const json = await response.json();
3150
- // return json;
3151
- // } catch ( error ) {
3152
- // console.log( 'getGeocodedAddress error =>', error );
3153
- // logger.error( { error: error, message: data, function: 'getGeocodedAddress' } );
3154
- // }
3155
- // }
3156
- // let getGEO = await getGeocodedAddress( 12.900260100404893, 80.23384232089138 );
3157
- // console.log( 'getGEO =>', getGEO );
3132
+
3133
+ export const getStoreListv2 = async ( req, res ) => {
3134
+ try {
3135
+ let reqestData = req.body;
3136
+ let getClientData = await getClientConfig( reqestData.clientId );
3137
+ if ( !getClientData ) {
3138
+ return res.sendError( 'Invalid Client Id', 400 );
3139
+ }
3140
+ reqestData.featureConfigs = getClientData.featureConfigs;
3141
+ let LamdaURL = 'https://nmnnlq3ie65bljcvxauhxmsrpa0edhfa.lambda-url.ap-south-1.on.aws/';
3142
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
3143
+ if ( resultData ) {
3144
+ if ( resultData.status_code == '200' ) {
3145
+ return res.sendSuccess( resultData );
3146
+ } else {
3147
+ return res.sendError( 'No Content', 204 );
3148
+ }
3149
+ } else {
3150
+ return res.sendError( 'No Content', 204 );
3151
+ }
3152
+ } catch ( error ) {
3153
+ const err = error.message || 'Internal Server Error';
3154
+ logger.error( { error: error, message: req.body, function: 'getStoreListv2' } );
3155
+ return res.sendError( err, 500 );
3156
+ }
3157
+ };
3158
+
@@ -21,6 +21,19 @@ export const addBillsSchema = joi.object( {
21
21
  'string.empty': 'Please enter a valid NOB Count',
22
22
  'any.required': 'NOB Count is required',
23
23
  } ).allow( null ),
24
+ zonewisenob: joi.array().items(
25
+ joi.object( {
26
+ zoneName: joi.string().required().messages( {
27
+ 'string.empty': 'Zone name is required',
28
+ 'any.required': 'Zone name is required',
29
+ } ),
30
+
31
+ nobCount: joi.number().required().messages( {
32
+ 'number.base': 'Please enter a valid Zone NOB Count',
33
+ 'any.required': 'Zone NOB Count is required',
34
+ } ),
35
+ } ),
36
+ ).optional(),
24
37
  } ),
25
38
  ).required(),
26
39
 
@@ -4,7 +4,8 @@ import dayjs from 'dayjs';
4
4
  export const storeProcessedDataSchema = joi.object( {
5
5
 
6
6
  storeId: joi.string().required(),
7
- dateString: joi.string().required(),
7
+ fromDate: joi.string().required(),
8
+ toDate: joi.string().required(),
8
9
 
9
10
  } );
10
11
 
@@ -47,24 +48,19 @@ export const tagTempIdSchema = joi.object( {
47
48
  storeId: joi.string().required(),
48
49
  dateString: joi.string().required().custom( ( value, helpers ) => {
49
50
  const inputDate = dayjs( value, 'YYYY-MM-DD', true );
50
- const today = dayjs();
51
51
 
52
52
  if ( !inputDate.isValid() ) {
53
53
  return helpers.error( 'any.invalid' );
54
54
  }
55
-
56
- const diff = today.diff( inputDate, 'day' );
57
-
58
- if ( diff > 4 ) {
59
- return helpers.message( 'Tagging is not allowed for a period exceeding 4 days' );
60
- }
61
-
62
55
  return value;
63
56
  } ), // yyyy-mm-dd
64
57
  tempId: joi.number().required(),
65
58
  revopsType: joi.string().required(),
66
59
  timeRange: joi.string().required(),
67
60
  isChecked: joi.boolean().required().allow( null ),
61
+ mode: joi.string().valid( 'web', 'mobile' ).required().messages( {
62
+ 'any.only': 'type must be one of [mobile,web]',
63
+ } ),
68
64
  duplicateImage: joi.array().items( joi.object(
69
65
  {
70
66
  tempId: joi.number().required(),
@@ -80,6 +76,7 @@ export const tagTempIdSchema = joi.object( {
80
76
  entryTime: joi.string().required(),
81
77
  exitTime: joi.string().required(),
82
78
  filePath: joi.string().required(),
79
+ comments: joi.string().optional().allow( '' ),
83
80
 
84
81
  } );
85
82
 
@@ -100,3 +97,13 @@ export const getCategorizedImagesValid = {
100
97
  body: getCategorizedImagesSchema,
101
98
  };
102
99
 
100
+ export const vmsDataMigrationSchema = joi.object( {
101
+ storeId: joi.string().optional(),
102
+ dateString: joi.string().optional(),
103
+ limit: joi.number().optional().default( 100 ),
104
+ } );
105
+
106
+ export const vmsDataMigrationValid = {
107
+ query: vmsDataMigrationSchema,
108
+ };
109
+
@@ -239,6 +239,17 @@ export const validateCountryHeaderSchemav2 = joi.object( {
239
239
  export const validateCountryHeaderParamsv2 = {
240
240
  body: validateCountryHeaderSchemav2,
241
241
  };
242
+
243
+ export const validateGetStoreListSchemav2 = joi.object( {
244
+ clientId: joi.string().required(),
245
+ storeId: joi.array().items( joi.string().required() ).required(),
246
+ downtime: joi.array().items( joi.string().required() ).optional(),
247
+ fromDate: joi.string().required(),
248
+ toDate: joi.string().required(),
249
+ } );
250
+ export const validateGetStoreList = {
251
+ body: validateGetStoreListSchemav2,
252
+ };
242
253
  export const getMyProductSchema = joi.object( {
243
254
  clientId: joi.string().required(),
244
255
  storeId: joi.array().optional().empty(),
@@ -1,7 +1,7 @@
1
1
  import express from 'express';
2
2
  import { accessVerification, bulkValidate, getAssinedStore, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
3
3
  import { addBillsValid, getNobDataValid, storeListValid } from '../dtos/nob.dtos.js';
4
- import { addBills, getNobData, storeList } from '../controllers/nob.controllers.js';
4
+ import { addBills, getNobData, storeList, zonelist, zonetemplate } from '../controllers/nob.controllers.js';
5
5
  import { clientValidations, fieldValidation, roleVerification } from '../validations/nob.validations.js';
6
6
 
7
7
  const nobRouter=express.Router();
@@ -13,4 +13,8 @@ nobRouter.post( '/add-bills', isAllowedSessionHandler, accessVerification( { use
13
13
 
14
14
  nobRouter.post( '/get-nob-data', isAllowedSessionHandler, accessVerification( { userType: [ 'client', 'tango' ] } ), validate( getNobDataValid ), clientValidations, getAssinedStore, getNobData );
15
15
 
16
+ nobRouter.post( '/zonelist', isAllowedSessionHandler, accessVerification( { userType: [ 'client', 'tango' ] } ), zonelist );
17
+
18
+ nobRouter.post( '/zonetemplate', isAllowedSessionHandler, accessVerification( { userType: [ 'client', 'tango' ] } ), getAssinedStore, zonetemplate );
19
+
16
20
  export default nobRouter;
@@ -1,8 +1,8 @@
1
1
 
2
2
  import express from 'express';
3
- import { storeProcessedData, getconfig, revoptagging, getrevoptagging, revoptaggingcount, footFallImages, tagTempId, getCategorizedImages } 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
- import { footfallImagesValid, getCategorizedImagesValid, storeProcessedDataValid, tagTempIdValid } from '../dtos/revop.dtos.js';
5
+ import { footfallImagesValid, getCategorizedImagesValid, storeProcessedDataValid, tagTempIdValid, vmsDataMigrationValid } from '../dtos/revop.dtos.js';
6
6
  import { deleteTaggedDuplicate, getTaggingConfig, mappingConfig } from '../validations/revop.validation.js';
7
7
 
8
8
  export const revopRouter = express.Router();
@@ -11,15 +11,16 @@ revopRouter
11
11
  .get( '/getconfig', isAllowedSessionHandler, getconfig )
12
12
  .post( '/tagging', isAllowedSessionHandler, revoptagging )
13
13
  .post( '/getrevoptagging', isAllowedSessionHandler, getrevoptagging )
14
+ .post( '/migrate-revop', migrateRevopIndex )
15
+ .post( '/expire-review-status', expireReviewStatus )
14
16
  .post( '/revoptaggingcount', isAllowedSessionHandler, revoptaggingcount )
15
17
 
16
18
  // new enhnacemnet (for footfall directory)
17
19
  .get( '/store-processed-data', isAllowedSessionHandler, validate( storeProcessedDataValid ), storeProcessedData )
18
20
  .get( '/footfall-images', isAllowedSessionHandler, validate( footfallImagesValid ), getTaggingConfig, footFallImages )
19
- .post( '/tag-tempId', isAllowedSessionHandler, validate( tagTempIdValid ), deleteTaggedDuplicate, mappingConfig, tagTempId )
20
-
21
-
22
- .post( '/get-categorized-images', isAllowedSessionHandler, validate( getCategorizedImagesValid ), getCategorizedImages );
21
+ .post( '/tag-tempId', isAllowedSessionHandler, validate( tagTempIdValid ), mappingConfig, deleteTaggedDuplicate, tagTempId )
22
+ .post( '/get-categorized-images', isAllowedSessionHandler, validate( getCategorizedImagesValid ), getCategorizedImages )
23
+ .post( '/vms-data-migration', validate( vmsDataMigrationValid ), vmsDataMigration );
23
24
 
24
25
 
25
26
  export default revopRouter;
@@ -92,6 +92,7 @@ import {
92
92
  funnelV3,
93
93
  getStoreMapDataV3,
94
94
  managerTrafficDensityExport,
95
+ getStoreListv2,
95
96
  } from '../controllers/tangoTrafficV3.controllers.js';
96
97
  analysisTrafficRouter
97
98
  .get( '/welcome', welcome )
@@ -175,5 +176,6 @@ analysisTrafficRouter
175
176
  .post( '/headerCountry_v2', isAllowedSessionHandler, isAllowedClient, validate( validationDtos.validateCountryHeaderParamsv2 ), getAssinedStore, headerCountryV2 )
176
177
  .post( '/checkTodayReportStatus', isAllowedSessionHandler, checkTodayReportStatus )
177
178
  .post( '/headerZoneV2', isAllowedSessionHandler, headerZoneV2 )
178
- .post( '/trafficDensityExport_v2', managerTrafficDensityExport );
179
+ .post( '/trafficDensityExport_v2', managerTrafficDensityExport )
180
+ .post( '/get-store-list-v2', isAllowedSessionHandler, isAllowedClient, validate( validationDtos.validateGetStoreList ), getStoreListv2 );
179
181
  export default analysisTrafficRouter;
@@ -1,6 +1,7 @@
1
1
  import nobBillingModel from 'tango-api-schema/schema/nobBilling.model.js';
2
2
 
3
3
  export async function updateOneNobBilling( query, record ) {
4
+ console.log( '🚀 ~ updateOneNobBilling ~ record:', record );
4
5
  return await nobBillingModel.updateOne( query, { $set: record }, { upsert: true } );
5
6
  }
6
7
 
@@ -0,0 +1,5 @@
1
+ import vmsStoreRequestModel from 'tango-api-schema/schema/vmsStoreRequest.model.js';
2
+
3
+ export async function findOneVmsStoreRequest( query = {} ) {
4
+ return await vmsStoreRequestModel.findOne( query );
5
+ };
@@ -121,6 +121,7 @@ export async function fieldValidation( req, res, next ) {
121
121
  nobDate: nobDateIso,
122
122
  nobCount: inputFilter[i]?.nobCount,
123
123
  dateString: inputFilter[i]?.nobDate,
124
+ zonewisenob: inputFilter[i]?.zonewisenob?inputFilter[i]?.zonewisenob:[],
124
125
  };
125
126
  const query ={ storeId: storeData[0]?.storeId, nobDate: inputFilter[i]?.nobDate };
126
127
 
@@ -1,12 +1,100 @@
1
1
  import { getOpenSearchCount, logger } from 'tango-app-api-middleware';
2
- import { findOneStore } from '../services/stores.service.js';
3
- import { deleteByQuery } from 'tango-app-api-middleware/src/utils/openSearch.js';
2
+ import { deleteByQuery, getOpenSearchData } from 'tango-app-api-middleware/src/utils/openSearch.js';
3
+ import { aggregate } from '../services/clients.services.js';
4
4
 
5
5
  export async function getTaggingConfig( req, res, next ) {
6
6
  try {
7
7
  const inputData= req.query;
8
- const getData = await findOneStore( { storeId: inputData.storeId }, { revopTagging: 1 } );
9
- req.store = getData;
8
+ const clientId = inputData.storeId.split( '-' )[0];
9
+ const configQuery = [
10
+ {
11
+ $match: {
12
+ clientId,
13
+ },
14
+ },
15
+
16
+ // Convert all effectiveFrom to proper Date
17
+ {
18
+ $addFields: {
19
+ taggingLimitationWithDate: {
20
+ $map: {
21
+ input: '$footfallDirectoryConfigs.taggingLimitation',
22
+ as: 'item',
23
+ in: {
24
+ effectiveFrom: { $toDate: '$$item.effectiveFrom' },
25
+ values: '$$item.values',
26
+ },
27
+ },
28
+ },
29
+ },
30
+ },
31
+
32
+ // Filter items <= input date
33
+ {
34
+ $addFields: {
35
+ matchedLimitation: {
36
+ $filter: {
37
+ input: '$taggingLimitationWithDate',
38
+ as: 'item',
39
+ cond: {
40
+ $lte: [
41
+ '$$item.effectiveFrom',
42
+ { $toDate: inputData.dateString },
43
+ ],
44
+ },
45
+ },
46
+ },
47
+ },
48
+ },
49
+
50
+ // Sort DESC and pick ONLY top 1 -> latest effective record
51
+ {
52
+ $addFields: {
53
+ effectiveLimitation: {
54
+ $arrayElemAt: [
55
+ {
56
+ $slice: [
57
+ {
58
+ $sortArray: {
59
+ input: '$matchedLimitation',
60
+ sortBy: { effectiveFrom: -1 },
61
+ },
62
+ },
63
+ 1,
64
+ ],
65
+ },
66
+ 0,
67
+ ],
68
+ },
69
+ },
70
+ },
71
+
72
+ {
73
+ $project: {
74
+ config: 1,
75
+ effectiveLimitation: 1,
76
+ footfallDirectoryConfigs: 1,
77
+ },
78
+ },
79
+ ];
80
+
81
+
82
+ const getData = await aggregate( configQuery );
83
+
84
+ // Convert "taggingLimitation" array (if present) to "config" object with expected key-value pairs
85
+ let config = {};
86
+ if ( getData && getData?.length > 0 && Array.isArray( getData?.[0]?.effectiveLimitation?.values ) ) {
87
+ for ( const item of getData?.[0]?.footfallDirectoryConfigs?.taggingLimitation?.[0]?.values ) {
88
+ if ( item && item.type && typeof item.value !== 'undefined' && item.unit ) {
89
+ config[item.type] = `${item.value}${item.unit}`;
90
+ }
91
+ }
92
+ }
93
+ // getData[0].footfallDirectoryConfigs.taggingLimitation = [];
94
+ getData[0].footfallDirectoryConfigs.config = config;
95
+
96
+ getData[0].footfallDirectoryConfigs.taggingLimitation = getData?.[0]?.effectiveLimitation?.values;
97
+ req.store = getData[0];
10
98
  next();
11
99
  } catch ( error ) {
12
100
  logger.error( { error: error, message: req.body, function: 'traffic-revop-getTaggingConfig' } );
@@ -51,41 +139,127 @@ export async function getFootfallCount( req, res, next ) {
51
139
  export async function mappingConfig( req, res, next ) {
52
140
  try {
53
141
  const inputData = req.body;
142
+
54
143
  const openSearch = JSON.parse( process.env.OPENSEARCH );
55
- const config =await findOneStore( { storeId: inputData.storeId }, { revopTagging: 1 } );
56
- if ( inputData.revopsType == 'employee' ) {
57
- const getQuery = {
58
- query: {
59
- bool: {
60
- must: [
61
- {
62
- term: {
63
- 'storeId.keyword': inputData.storeId,
64
- },
144
+ const footfallQuery ={
145
+ query: {
146
+ bool: {
147
+ must: [
148
+ {
149
+ term: {
150
+ 'store_id.keyword': inputData.storeId,
65
151
  },
66
- {
67
- term: {
68
- 'dateString': inputData.dateString,
69
- },
152
+ },
153
+ {
154
+ term: {
155
+ 'date_string': inputData.dateString,
156
+ },
157
+ },
158
+
159
+ ],
160
+ },
161
+ },
162
+ };
163
+
164
+
165
+ const footfallOutput = await getOpenSearchData( openSearch.footfall, footfallQuery );
166
+ if ( footfallOutput?.body?.hits?.hits?.length === 0 ) {
167
+ return res.sendError( 'No updated footfall for this date', 400 );
168
+ }
169
+ const getFootfallCount = footfallOutput?.body?.hits?.hits;
170
+ const footfall = getFootfallCount?.[0]?._source?.footfall_count;
171
+ const clientId = inputData?.storeId?.split( '-' )[0];
172
+ const configQuery = [
173
+ {
174
+ $match: {
175
+ clientId: clientId,
176
+ },
177
+ },
178
+
179
+ // Convert all effectiveFrom to proper Date
180
+ {
181
+ $addFields: {
182
+ taggingLimitationWithDate: {
183
+ $map: {
184
+ input: '$footfallDirectoryConfigs.taggingLimitation',
185
+ as: 'item',
186
+ in: {
187
+ effectiveFrom: { $toDate: '$$item.effectiveFrom' },
188
+ values: '$$item.values',
70
189
  },
190
+ },
191
+ },
192
+ },
193
+ },
194
+
195
+ // Filter items <= input date
196
+ {
197
+ $addFields: {
198
+ matchedLimitation: {
199
+ $filter: {
200
+ input: '$taggingLimitationWithDate',
201
+ as: 'item',
202
+ cond: {
203
+ $lte: [
204
+ '$$item.effectiveFrom',
205
+ { $toDate: inputData.dateString },
206
+ ],
207
+ },
208
+ },
209
+ },
210
+ },
211
+ },
212
+
213
+ // Sort DESC and pick ONLY top 1 -> latest effective record
214
+ {
215
+ $addFields: {
216
+ effectiveLimitation: {
217
+ $arrayElemAt: [
71
218
  {
72
- term: {
73
- 'revopsType.keyword': inputData.revopsType,
74
- },
219
+ $slice: [
220
+ {
221
+ $sortArray: {
222
+ input: '$matchedLimitation',
223
+ sortBy: { effectiveFrom: -1 },
224
+ },
225
+ },
226
+ 1,
227
+ ],
75
228
  },
229
+ 0,
76
230
  ],
77
231
  },
78
232
  },
79
- };
233
+ },
80
234
 
81
- const getData = await getOpenSearchCount( openSearch.revop, getQuery );
82
- if ( getData && getData?.body?.count >= config?.revopTagging?.employee ) {
83
- return res.sendError( `Select up to ${config?.revopTagging?.employee} items only`, 400 );
84
- } else {
85
- next();
86
- }
87
- } else if ( inputData.revopsType == 'house-keeping' ) {
88
- const getQuery = {
235
+ {
236
+ $project: {
237
+ config: 1,
238
+ effectiveLimitation: 1,
239
+ footfallDirectoryConfigs: 1,
240
+ },
241
+ },
242
+ ];
243
+ const getConfig = await aggregate( configQuery );
244
+ req.client = getConfig[0];
245
+ const taggingLimitation = getConfig?.[0]?.effectiveLimitation?.values;
246
+
247
+ // Find the tagging limitation for the given revopsType
248
+ let matchedLimitation = null;
249
+ if ( Array.isArray( taggingLimitation ) ) {
250
+ matchedLimitation = taggingLimitation.find(
251
+ ( l ) => l.type === inputData.revopsType,
252
+ );
253
+ }
254
+
255
+ if ( matchedLimitation ) {
256
+ // Determine the limit value
257
+ let limitValue = Number( matchedLimitation.value ) || 0;
258
+ let unit = matchedLimitation.unit;
259
+
260
+ // Assuming getData and/or getOpenSearchCount provides the actual tagged count for revopsType
261
+ // Query OpenSearch for current tagged count for this revopsType
262
+ const taggedCountQuery = {
89
263
  query: {
90
264
  bool: {
91
265
  must: [
@@ -104,92 +278,51 @@ export async function mappingConfig( req, res, next ) {
104
278
  'revopsType.keyword': inputData.revopsType,
105
279
  },
106
280
  },
281
+ {
282
+ term: {
283
+ 'isParent': false,
284
+ },
285
+ },
107
286
  ],
108
287
  },
109
288
  },
110
289
  };
111
- const getData = await getOpenSearchCount( openSearch.revop, getQuery );
112
- if ( getData && getData?.body?.count >= config?.revopTagging?.houseKeeping ) {
113
- return res.sendError( `Select up to ${config?.revopTagging?.houseKeeping} items only`, 400 );
290
+ const taggedData = await getOpenSearchCount( openSearch.revop, taggedCountQuery );
291
+ const taggedValue = ( taggedData?.body?.count || 0 )+ ( inputData.revopsType == 'duplicate'? inputData?.duplicateImage?.length : 1 );
292
+ // If the unit is %, compare percentage of taggedValue/footfall, otherwise compare taggedValue to limitValue directly
293
+ let isLimitExceeded = false;
294
+ if ( unit === '%' ) {
295
+ // footfall may be undefined, treat as 0 (avoid division by zero)
296
+ const totalFootfall = Number( footfall ) || 0;
297
+ const taggedPercent = totalFootfall > 0 ? ( taggedValue / totalFootfall ) * 100 : 0;
298
+ isLimitExceeded = taggedPercent > limitValue;
299
+ logger.info( {
300
+ limitType: 'PERCENT',
301
+ taggedValue,
302
+ totalFootfall,
303
+ taggedPercent,
304
+ limitValue,
305
+ isLimitExceeded,
306
+ forRevopsType: inputData.revopsType,
307
+ } );
114
308
  } else {
115
- next();
309
+ // Non-percent, treat limitValue as an absolute number
310
+ isLimitExceeded = taggedValue > limitValue;
311
+ logger.info( {
312
+ limitType: 'ABSOLUTE',
313
+ taggedValue,
314
+ limitValue,
315
+ isLimitExceeded,
316
+ forRevopsType: inputData.revopsType,
317
+ } );
116
318
  }
117
- } else if ( inputData.revopsType === 'junk' ) {
118
- if ( ( req?.user?.userType == 'client' && req?.user?.userType !== 'user ' ) || req?.user?.userType === 'tango' ) {
119
- next();
120
- return;
121
- } else {
122
- return res.sendError( 'Forbidden to junk mapping', 500 );
319
+ if ( isLimitExceeded ) {
320
+ return res.sendError( `Limit exceed: Only ${limitValue}${unit || ''} items allowed for ${inputData.revopsType}`, 400 );
123
321
  }
322
+ return next();
124
323
  } else {
125
- next();
324
+ return next();
126
325
  }
127
- // else if ( inputData.revopsType == 'duplicate' ) {
128
- // const getFootfallQuery = {
129
- // query: {
130
- // terms: {
131
- // _id: [ inputData?.dateString ],
132
- // },
133
- // },
134
- // _source: [ 'footfall', 'date_string', 'store_id', 'down_time', 'footfall_count' ],
135
- // sort: [
136
- // {
137
- // date_iso: {
138
- // order: 'desc',
139
- // },
140
- // },
141
- // ],
142
- // };
143
-
144
- // const getFootfall = await getOpenSearchData( openSearch.footfall, getFootfallQuery );
145
- // const footfall = getFootfall?.body?.hites?.hits?.[0]?._source?.footfall_count;
146
- // const getQuery = {
147
- // query: {
148
- // bool: {
149
- // must: [
150
- // {
151
- // term: {
152
- // 'storeId.keyword': inputData.storeId,
153
- // },
154
- // },
155
- // {
156
- // term: {
157
- // 'dateString': inputData.dateString,
158
- // },
159
- // },
160
- // {
161
- // term: {
162
- // 'revopsType.keyword': inputData.revopsType,
163
- // },
164
- // },
165
- // {
166
- // term: {
167
- // 'parent.keyword': null,
168
- // },
169
- // },
170
- // ],
171
- // },
172
- // },
173
- // };
174
- // const getData = await getOpenSearchCount( openSearch.revop, getQuery );
175
- // logger.info( { getData: getData, footfall: footfall, duplicate: config?.revopTagging?.duplicate } );
176
- // if ( getData && footfall && config?.revopTagging?.duplicate ) {
177
- // const data = config?.revopTagging?.duplicate;
178
- // // Convert "20%" → 0.2 (handle both "20%" and 20)
179
- // const percentStr = typeof data === 'string' ? data.replace( '%', '' ) : data;
180
- // logger.info( { percentStr: percentStr } );
181
- // const percentValue =percentStr / 100;
182
-
183
- // const result = percentValue * footfall;
184
-
185
- // logger.info( { result: result, footfall: footfall } );
186
- // }
187
- // if ( getData && getData?.body?.count >= Math.round( result ) ) {
188
- // return res.sendError( `Select up to ${config?.revopTagging?.duplicate} items only`, 400 );
189
- // } else {
190
- // next();
191
- // }
192
- // }
193
326
  } catch ( error ) {
194
327
  logger.error( { error: error, message: req.body, function: 'traffic-revop-getTaggingConfig' } );
195
328
  next();