tango-app-api-analysis-traffic 3.0.0-alpha.41 → 3.0.0-alpha.42

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.0.0-alpha.41",
3
+ "version": "3.0.0-alpha.42",
4
4
  "description": "Traffic Analysis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,7 +1,8 @@
1
- import { getOpenSearchData, getUTC, insertOpenSearchData, logger, updateOpenSearchData } from 'tango-app-api-middleware';
1
+ import { chunkArray, download, getOpenSearchData, getUTC, insertOpenSearchData, logger, updateOpenSearchData } from 'tango-app-api-middleware';
2
2
  import { aggregateStore } from '../services/stores.service.js';
3
3
  import { findOneNobBilling, updateOneNobBilling } from '../services/nob.service.js';
4
4
  import dayjs from 'dayjs';
5
+ import { findOne } from '../services/clients.services.js';
5
6
 
6
7
  export async function storeList( req, res ) {
7
8
  try {
@@ -103,14 +104,16 @@ export async function addBills( req, res ) {
103
104
  },
104
105
  };
105
106
  let searchData=await getOpenSearchData( openSearch.nob, searchQuery );
106
-
107
+ let nobDateIso =new Date( inputData?.bills[i]?.nobDate );
108
+ nobDateIso.setUTCHours( 0, 0, 0, 0 );
107
109
  let inserData={
108
110
  clientId: req?.user?.clientId,
109
111
  storeId: storeData[0]?.storeId,
110
112
  storeCode: storeData[0]?.storeProfile?.storeCode,
111
113
  storeName: inputData?.bills[i]?.storeName,
112
- nobDate: inputData?.bills[i]?.nobDate,
114
+ nobDate: nobDateIso,
113
115
  nobCount: inputData?.bills[i]?.nobCount,
116
+ dateString: inputData?.bills[i]?.nobDate,
114
117
  nobAmount: 1.0,
115
118
  };
116
119
  const query ={ storeId: storeData[0]?.storeId, nobDate: inputData?.bills[i]?.nobDate };
@@ -138,32 +141,58 @@ export async function addBills( req, res ) {
138
141
  export async function getNobData( req, res ) {
139
142
  try {
140
143
  const inputData = req.body;
144
+ if ( req.user.role !== 'superadmin' && req.user.userType !== 'tango' && ( req?.body?.assignedStores?.length == 0 || !req?.body?.assignedStores ) ) {
145
+ return res.sendError( 'No data found', 204 );
146
+ }
147
+ const dateRange = await getUTC( new Date( inputData.fromDate ), new Date( new Date( inputData.toDate ) ) );
148
+
149
+ let filter = [
150
+ {
151
+ 'terms': {
152
+ 'storeId.keyword': inputData?.storeId,
153
+ },
154
+ },
155
+ {
156
+ range: { nobDate: { gte: dateRange.start,
157
+ lt: dateRange.end } },
158
+ },
159
+ ];
160
+ if ( req.user.role !== 'superadmin' && req.user.userType !== 'tango' ) {
161
+ filter.push(
162
+ req.user.userType !== 'tango',
163
+ );
164
+ }
165
+
166
+ if ( inputData.searchValue && inputData.searchValue!== '' ) {
167
+ const searchValue = escapeSpecialChars( inputData.searchValue );
168
+ logger.info( { searchvalue: inputData.searchValue, searchValue: searchValue } );
169
+ filter.push(
170
+ {
171
+ 'wildcard': {
172
+ 'storeId.keyword': {
173
+ 'value': `${searchValue}*`,
174
+ },
175
+ },
176
+ },
177
+ );
178
+ }
179
+ const getClient = await findOne( { clientId: req.clientId }, { featureConfigs: 1 } );
141
180
  const openSearch = JSON.parse( process.env.OPENSEARCH );
142
- const limit =inputData.limit || 200;
181
+ const limit = inputData.isExport? 10000 : inputData.limit || 200;
143
182
  const skip = inputData.offset? ( inputData.offset - 1 ) * limit : 0;
144
- const dateRange = await getUTC( new Date( inputData.fromDate ), new Date( new Date( inputData.toDate ) ) );
145
183
  const nobQuery={
146
184
  'from': skip,
147
185
  'size': limit,
148
186
  'query': {
149
187
  'bool': {
150
- 'must': [
151
- {
152
- 'terms': {
153
- 'storeId.keyword': inputData.storeId,
154
- },
155
- },
156
- {
157
- range: { nobDate: { gte: dateRange.start,
158
- lt: dateRange.end } },
159
- },
160
- ],
188
+ 'must': filter,
161
189
  },
162
190
  },
163
191
  };
164
192
 
165
193
  const getNobData=await getOpenSearchData( openSearch.nob, nobQuery );
166
- if ( getNobData?.body?.hits?.hits?.length == 0 ) {
194
+ const nobData = getNobData?.body?.hits?.hits;
195
+ if ( !nobData ||nobData?.length == 0 ) {
167
196
  return res.sendError( 'No Data Found', 204 );
168
197
  }
169
198
 
@@ -188,11 +217,80 @@ export async function getNobData( req, res ) {
188
217
  };
189
218
 
190
219
  const getFootfall= await getOpenSearchData( openSearch.footfall, footfallQuery );
191
- logger.info( { getFootfall: getFootfall } );
192
- return res.sendSuccess( { result: getNobData?.body?.hits?.hits, getFootfall: getFootfall?.body?.hits?.hits, count: getNobData?.body?.hits?.total?.value } );
220
+ const footfall = getFootfall?.body?.hits?.hits;
221
+ let result=[];
222
+ nobData.map( ( data ) => {
223
+ let count = 0;
224
+ let temp=[];
225
+
226
+ data._source.isUpdated = data._source.createdAt !== data._source.updatedAt? true : false;
227
+
228
+ footfall.filter( ( item ) => {
229
+ if ( ( data._source.date_string === item._source.dateString ) && ( data._source.store_id === item._source.storeId ) ) {
230
+ count = 1;
231
+ temp =[
232
+ {
233
+ footfallCount: item._source.footfall_count,
234
+ engagersCount: item._source.engagers_count,
235
+ potentialBuyers: item._source.potentialBuyers_count,
236
+ },
237
+ ];
238
+ }
239
+ } );
240
+
241
+ if ( count === 1 ) {
242
+ result.push( {
243
+
244
+ ...data._source,
245
+ footfallCount: temp[0]?.footfallCount || null,
246
+ engagersCount: temp[0]?.engagersCount || null,
247
+ potentialBuyers: temp[0]?.potentialBuyers || null,
248
+
249
+ } );
250
+ } else {
251
+ result.push( {
252
+
253
+ ...data._source,
254
+ footfallCount: null,
255
+ engagersCount: null,
256
+ potentialBuyers: null,
257
+
258
+ } );
259
+ }
260
+ } );
261
+ if ( inputData.isExport ) {
262
+ const chunkedMappingData = await chunkArray( result, 10 );
263
+ const promises = chunkedMappingData.map( async ( chunk ) => {
264
+ const exportData = [];
265
+ chunk.forEach( ( element ) => {
266
+ exportData.push( {
267
+ 'Store Name': element.storeName,
268
+ 'Store Id': element.storeId,
269
+ 'Date': element.nobDate,
270
+ 'Footfall': element.footfallCount,
271
+ 'NoB\'s Count': element.nobCount,
272
+ 'Conversion Rate': `${( element.footfallCount/element.nobCount )*100}%`,
273
+
274
+
275
+ } );
276
+ } );
277
+ return exportData;
278
+ } );
279
+ const mappedArrays = await Promise.all( promises );
280
+ const result1 = mappedArrays.flat();
281
+ await download( result1, res );
282
+ return;
283
+ }
284
+
285
+ return res.sendSuccess( { result: result, count: getNobData?.body?.hits?.total?.value, convertionCalculation: getClient?.featureConfigs?.conversionCalculation } );
193
286
  } catch ( error ) {
194
287
  const err = error.message || 'Internal Server Error';
195
288
  logger.error( { error: error, message: req.body, function: 'nob-getNobData' } );
196
289
  return res.sendError( err, 500 );
197
290
  }
198
291
  }
292
+
293
+
294
+ function escapeSpecialChars( str ) {
295
+ return str.replace( /[-[\]{}()*+?.,\\^$|#]/g, '\\$&' );
296
+ }
@@ -33,10 +33,13 @@ export const storeListValid = {
33
33
  export const getNobDataSchema = joi.object( {
34
34
 
35
35
  storeId: joi.array().items( joi.string().required() ).required(),
36
+ clientId: joi.string().optional(),
36
37
  fromDate: joi.string().required(),
37
38
  toDate: joi.string().required(),
38
39
  limit: joi.number().optional(),
39
40
  offset: joi.number().optional(),
41
+ isExport: joi.boolean().optional(),
42
+ searchValue: joi.string().optional(),
40
43
 
41
44
  } );
42
45
 
@@ -11,6 +11,6 @@ nobRouter.get( '/store-list', isAllowedSessionHandler, accessVerification( { use
11
11
 
12
12
  nobRouter.post( '/add-bills', isAllowedSessionHandler, accessVerification( { userType: [ 'client', 'tango' ] } ), validate( addBillsValid ), addBills );
13
13
 
14
- nobRouter.post( '/get-nob-data', isAllowedSessionHandler, accessVerification( { userType: [ 'client', 'tango' ] } ), validate( getNobDataValid ), getAssinedStore, getNobData );
14
+ nobRouter.post( '/get-nob-data', isAllowedSessionHandler, accessVerification( { userType: [ 'client', 'tango' ] } ), validate( getNobDataValid ), clientValidations, getAssinedStore, getNobData );
15
15
 
16
16
  export default nobRouter;
@@ -1,7 +1,7 @@
1
1
  export async function clientValidations( req, res, next ) {
2
2
  try {
3
- const inputData = req.query;
4
- const clientId = req.user.userType === 'client' ? inputData.clientId :req.user.clientId;
3
+ const inputData = req.method === 'POST' ? req.body : req.query;
4
+ const clientId = req.user.userType === 'tango' ? inputData.clientId :req.user.clientId;
5
5
  if ( !clientId ) {
6
6
  return res.sendError( 'Give valid clientId', 400 );
7
7
  }