tango-app-api-analysis-traffic 3.8.7-vms.3 → 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 +2 -2
- package/src/controllers/revop.controller.js +787 -38
- package/src/controllers/tangoTrafficV3.controllers.js +27 -26
- package/src/dtos/revop.dtos.js +13 -2
- package/src/dtos/validation.dtos.js +11 -0
- package/src/routes/revop.routes.js +6 -5
- package/src/routes/traffic.routes.js +3 -1
- package/src/validations/revop.validation.js +229 -111
|
@@ -3129,29 +3129,30 @@ export const managerTrafficDensityExport = async ( req, res ) => {
|
|
|
3129
3129
|
}
|
|
3130
3130
|
};
|
|
3131
3131
|
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
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
|
+
|
package/src/dtos/revop.dtos.js
CHANGED
|
@@ -56,8 +56,8 @@ export const tagTempIdSchema = joi.object( {
|
|
|
56
56
|
|
|
57
57
|
const diff = today.diff( inputDate, 'day' );
|
|
58
58
|
|
|
59
|
-
if ( diff >
|
|
60
|
-
return helpers.message( 'Tagging is not allowed for a period exceeding
|
|
59
|
+
if ( diff > 3 ) {
|
|
60
|
+
return helpers.message( 'Tagging is not allowed for a period exceeding 3 days' );
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
return value;
|
|
@@ -84,6 +84,7 @@ export const tagTempIdSchema = joi.object( {
|
|
|
84
84
|
entryTime: joi.string().required(),
|
|
85
85
|
exitTime: joi.string().required(),
|
|
86
86
|
filePath: joi.string().required(),
|
|
87
|
+
comments: joi.string().optional().allow( '' ),
|
|
87
88
|
|
|
88
89
|
} );
|
|
89
90
|
|
|
@@ -104,3 +105,13 @@ export const getCategorizedImagesValid = {
|
|
|
104
105
|
body: getCategorizedImagesSchema,
|
|
105
106
|
};
|
|
106
107
|
|
|
108
|
+
export const vmsDataMigrationSchema = joi.object( {
|
|
109
|
+
storeId: joi.string().optional(),
|
|
110
|
+
dateString: joi.string().optional(),
|
|
111
|
+
limit: joi.number().optional().default( 100 ),
|
|
112
|
+
} );
|
|
113
|
+
|
|
114
|
+
export const vmsDataMigrationValid = {
|
|
115
|
+
query: vmsDataMigrationSchema,
|
|
116
|
+
};
|
|
117
|
+
|
|
@@ -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,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
21
|
.post( '/tag-tempId', isAllowedSessionHandler, validate( tagTempIdValid ), deleteTaggedDuplicate, mappingConfig, tagTempId )
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
.post( '/get-categorized-images', isAllowedSessionHandler, validate( getCategorizedImagesValid ), getCategorizedImages );
|
|
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,26 +1,100 @@
|
|
|
1
1
|
import { getOpenSearchCount, logger } from 'tango-app-api-middleware';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { findOne } from '../services/clients.services.js';
|
|
2
|
+
import { deleteByQuery, getOpenSearchData } from 'tango-app-api-middleware/src/utils/openSearch.js';
|
|
3
|
+
import { aggregate } from '../services/clients.services.js';
|
|
5
4
|
|
|
6
5
|
export async function getTaggingConfig( req, res, next ) {
|
|
7
6
|
try {
|
|
8
7
|
const inputData= req.query;
|
|
9
8
|
const clientId = inputData.storeId.split( '-' )[0];
|
|
10
|
-
const
|
|
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 );
|
|
11
83
|
|
|
12
84
|
// Convert "taggingLimitation" array (if present) to "config" object with expected key-value pairs
|
|
13
85
|
let config = {};
|
|
14
|
-
if ( getData && Array.isArray( getData
|
|
15
|
-
for ( const item of getData
|
|
86
|
+
if ( getData && getData?.length > 0 && Array.isArray( getData?.[0]?.effectiveLimitation?.values ) ) {
|
|
87
|
+
for ( const item of getData?.[0]?.footfallDirectoryConfigs?.taggingLimitation?.[0]?.values ) {
|
|
16
88
|
if ( item && item.type && typeof item.value !== 'undefined' && item.unit ) {
|
|
17
89
|
config[item.type] = `${item.value}${item.unit}`;
|
|
18
90
|
}
|
|
19
91
|
}
|
|
20
92
|
}
|
|
21
|
-
getData.
|
|
93
|
+
// getData[0].footfallDirectoryConfigs.taggingLimitation = [];
|
|
94
|
+
getData[0].footfallDirectoryConfigs.config = config;
|
|
22
95
|
|
|
23
|
-
|
|
96
|
+
getData[0].footfallDirectoryConfigs.taggingLimitation = getData?.[0]?.effectiveLimitation?.values;
|
|
97
|
+
req.store = getData[0];
|
|
24
98
|
next();
|
|
25
99
|
} catch ( error ) {
|
|
26
100
|
logger.error( { error: error, message: req.body, function: 'traffic-revop-getTaggingConfig' } );
|
|
@@ -65,41 +139,126 @@ export async function getFootfallCount( req, res, next ) {
|
|
|
65
139
|
export async function mappingConfig( req, res, next ) {
|
|
66
140
|
try {
|
|
67
141
|
const inputData = req.body;
|
|
142
|
+
|
|
68
143
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
term: {
|
|
77
|
-
'storeId.keyword': inputData.storeId,
|
|
78
|
-
},
|
|
144
|
+
const footfallQuery ={
|
|
145
|
+
query: {
|
|
146
|
+
bool: {
|
|
147
|
+
must: [
|
|
148
|
+
{
|
|
149
|
+
term: {
|
|
150
|
+
'store_id.keyword': inputData.storeId,
|
|
79
151
|
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
term: {
|
|
155
|
+
'date_string': inputData.dateString,
|
|
84
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',
|
|
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: [
|
|
85
218
|
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
219
|
+
$slice: [
|
|
220
|
+
{
|
|
221
|
+
$sortArray: {
|
|
222
|
+
input: '$matchedLimitation',
|
|
223
|
+
sortBy: { effectiveFrom: -1 },
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
1,
|
|
227
|
+
],
|
|
89
228
|
},
|
|
229
|
+
0,
|
|
90
230
|
],
|
|
91
231
|
},
|
|
92
232
|
},
|
|
93
|
-
}
|
|
233
|
+
},
|
|
94
234
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
235
|
+
{
|
|
236
|
+
$project: {
|
|
237
|
+
config: 1,
|
|
238
|
+
effectiveLimitation: 1,
|
|
239
|
+
footfallDirectoryConfigs: 1,
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
];
|
|
243
|
+
const getConfig = await aggregate( configQuery );
|
|
244
|
+
const taggingLimitation = getConfig?.[0]?.effectiveLimitation?.values;
|
|
245
|
+
|
|
246
|
+
// Find the tagging limitation for the given revopsType
|
|
247
|
+
let matchedLimitation = null;
|
|
248
|
+
if ( Array.isArray( taggingLimitation ) ) {
|
|
249
|
+
matchedLimitation = taggingLimitation.find(
|
|
250
|
+
( l ) => l.type === inputData.revopsType,
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if ( matchedLimitation ) {
|
|
255
|
+
// Determine the limit value
|
|
256
|
+
let limitValue = Number( matchedLimitation.value ) || 0;
|
|
257
|
+
let unit = matchedLimitation.unit;
|
|
258
|
+
|
|
259
|
+
// Assuming getData and/or getOpenSearchCount provides the actual tagged count for revopsType
|
|
260
|
+
// Query OpenSearch for current tagged count for this revopsType
|
|
261
|
+
const taggedCountQuery = {
|
|
103
262
|
query: {
|
|
104
263
|
bool: {
|
|
105
264
|
must: [
|
|
@@ -118,92 +277,51 @@ export async function mappingConfig( req, res, next ) {
|
|
|
118
277
|
'revopsType.keyword': inputData.revopsType,
|
|
119
278
|
},
|
|
120
279
|
},
|
|
280
|
+
{
|
|
281
|
+
term: {
|
|
282
|
+
'isParent': false,
|
|
283
|
+
},
|
|
284
|
+
},
|
|
121
285
|
],
|
|
122
286
|
},
|
|
123
287
|
},
|
|
124
288
|
};
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
289
|
+
const taggedData = await getOpenSearchCount( openSearch.revop, taggedCountQuery );
|
|
290
|
+
const taggedValue = ( taggedData?.body?.count || 0 )+ ( inputData.revopsType == 'duplicate'? inputData?.duplicateImage?.length : 1 );
|
|
291
|
+
// If the unit is %, compare percentage of taggedValue/footfall, otherwise compare taggedValue to limitValue directly
|
|
292
|
+
let isLimitExceeded = false;
|
|
293
|
+
if ( unit === '%' ) {
|
|
294
|
+
// footfall may be undefined, treat as 0 (avoid division by zero)
|
|
295
|
+
const totalFootfall = Number( footfall ) || 0;
|
|
296
|
+
const taggedPercent = totalFootfall > 0 ? ( taggedValue / totalFootfall ) * 100 : 0;
|
|
297
|
+
isLimitExceeded = taggedPercent > limitValue;
|
|
298
|
+
logger.info( {
|
|
299
|
+
limitType: 'PERCENT',
|
|
300
|
+
taggedValue,
|
|
301
|
+
totalFootfall,
|
|
302
|
+
taggedPercent,
|
|
303
|
+
limitValue,
|
|
304
|
+
isLimitExceeded,
|
|
305
|
+
forRevopsType: inputData.revopsType,
|
|
306
|
+
} );
|
|
128
307
|
} else {
|
|
129
|
-
|
|
308
|
+
// Non-percent, treat limitValue as an absolute number
|
|
309
|
+
isLimitExceeded = taggedValue > limitValue;
|
|
310
|
+
logger.info( {
|
|
311
|
+
limitType: 'ABSOLUTE',
|
|
312
|
+
taggedValue,
|
|
313
|
+
limitValue,
|
|
314
|
+
isLimitExceeded,
|
|
315
|
+
forRevopsType: inputData.revopsType,
|
|
316
|
+
} );
|
|
130
317
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
next();
|
|
134
|
-
return;
|
|
135
|
-
} else {
|
|
136
|
-
return res.sendError( 'Forbidden to junk mapping', 500 );
|
|
318
|
+
if ( isLimitExceeded ) {
|
|
319
|
+
return res.sendError( `Limit exceed: Only ${limitValue}${unit || ''} items allowed for ${inputData.revopsType}`, 400 );
|
|
137
320
|
}
|
|
321
|
+
return next();
|
|
138
322
|
} else {
|
|
139
|
-
next();
|
|
323
|
+
return next();
|
|
140
324
|
}
|
|
141
|
-
// else if ( inputData.revopsType == 'duplicate' ) {
|
|
142
|
-
// const getFootfallQuery = {
|
|
143
|
-
// query: {
|
|
144
|
-
// terms: {
|
|
145
|
-
// _id: [ inputData?.dateString ],
|
|
146
|
-
// },
|
|
147
|
-
// },
|
|
148
|
-
// _source: [ 'footfall', 'date_string', 'store_id', 'down_time', 'footfall_count' ],
|
|
149
|
-
// sort: [
|
|
150
|
-
// {
|
|
151
|
-
// date_iso: {
|
|
152
|
-
// order: 'desc',
|
|
153
|
-
// },
|
|
154
|
-
// },
|
|
155
|
-
// ],
|
|
156
|
-
// };
|
|
157
|
-
|
|
158
|
-
// const getFootfall = await getOpenSearchData( openSearch.footfall, getFootfallQuery );
|
|
159
|
-
// const footfall = getFootfall?.body?.hites?.hits?.[0]?._source?.footfall_count;
|
|
160
|
-
// const getQuery = {
|
|
161
|
-
// query: {
|
|
162
|
-
// bool: {
|
|
163
|
-
// must: [
|
|
164
|
-
// {
|
|
165
|
-
// term: {
|
|
166
|
-
// 'storeId.keyword': inputData.storeId,
|
|
167
|
-
// },
|
|
168
|
-
// },
|
|
169
|
-
// {
|
|
170
|
-
// term: {
|
|
171
|
-
// 'dateString': inputData.dateString,
|
|
172
|
-
// },
|
|
173
|
-
// },
|
|
174
|
-
// {
|
|
175
|
-
// term: {
|
|
176
|
-
// 'revopsType.keyword': inputData.revopsType,
|
|
177
|
-
// },
|
|
178
|
-
// },
|
|
179
|
-
// {
|
|
180
|
-
// term: {
|
|
181
|
-
// 'parent.keyword': null,
|
|
182
|
-
// },
|
|
183
|
-
// },
|
|
184
|
-
// ],
|
|
185
|
-
// },
|
|
186
|
-
// },
|
|
187
|
-
// };
|
|
188
|
-
// const getData = await getOpenSearchCount( openSearch.revop, getQuery );
|
|
189
|
-
// logger.info( { getData: getData, footfall: footfall, duplicate: config?.revopTagging?.duplicate } );
|
|
190
|
-
// if ( getData && footfall && config?.revopTagging?.duplicate ) {
|
|
191
|
-
// const data = config?.revopTagging?.duplicate;
|
|
192
|
-
// // Convert "20%" → 0.2 (handle both "20%" and 20)
|
|
193
|
-
// const percentStr = typeof data === 'string' ? data.replace( '%', '' ) : data;
|
|
194
|
-
// logger.info( { percentStr: percentStr } );
|
|
195
|
-
// const percentValue =percentStr / 100;
|
|
196
|
-
|
|
197
|
-
// const result = percentValue * footfall;
|
|
198
|
-
|
|
199
|
-
// logger.info( { result: result, footfall: footfall } );
|
|
200
|
-
// }
|
|
201
|
-
// if ( getData && getData?.body?.count >= Math.round( result ) ) {
|
|
202
|
-
// return res.sendError( `Select up to ${config?.revopTagging?.duplicate} items only`, 400 );
|
|
203
|
-
// } else {
|
|
204
|
-
// next();
|
|
205
|
-
// }
|
|
206
|
-
// }
|
|
207
325
|
} catch ( error ) {
|
|
208
326
|
logger.error( { error: error, message: req.body, function: 'traffic-revop-getTaggingConfig' } );
|
|
209
327
|
next();
|