tango-app-api-infra 3.8.1-beta.2 → 3.8.1-beta.4

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.8.1-beta.2",
3
+ "version": "3.8.1-beta.4",
4
4
  "description": "infra",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -174,120 +174,182 @@ export async function ticketSummary( req, res ) {
174
174
 
175
175
  export async function ticketList( req, res ) {
176
176
  try {
177
- // let count = 0;
178
- // const array =[
179
- // { A: '3c88e8eb6d499a26d37ca075c390bd2d', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/101' },
180
- // { A: 'c3dd981f485ccd25221c7da704f35d24', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/101' },
181
- // { A: 'ee887e5546ab0e96ca0adbf8c2453c8d', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/1001' },
182
- // { A: 'a59ddeb30d158602d6c672994af2f79a', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/1001' },
183
- // { A: '1f3318280025f5456262b0322b806940', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/201' },
184
- // { A: '925a70751a0988793057148b20158186', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/201',
185
- // }, { A: 'd6d4ab301c322212fb612a7d9661b6be', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/301',
186
- // }, { A: 'cb09aeedfa5ade043922634eb1c35e46', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/301',
187
- // }, { A: '58f81e33f66ef7af15424c1dc44e7de1', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/401',
188
- // }, { A: '7ac8f73f02347d29f6f2bff3c52275f5', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/401',
189
- // }, { A: '9599acd19a48eb28957ad18e40a0a5b1', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/401',
190
- // }, { A: '36584a3ce215a5fbd1c0e6535201020c', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/501',
191
- // }, { A: 'cb7e91870e0a72d4eb691e2618aa5979', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/501',
192
- // }, { A: 'cd072627e6924df745cba004616ec3c9', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/601',
193
- // }, { A: 'a5891519a50f68a9d73a774539fe8496', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/601',
194
- // }, { A: '2008517125b03b1b9a66348e6d017523', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/701',
195
- // }, { A: '79fc93551b59f9ed07eab48d190ba7f4', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/701',
196
- // }, { A: '89365abcfc8dc663b26471d81a7f68eb', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/801',
197
- // }, { A: 'e9fb3b989a245994bd48b97287aad096', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/801',
198
- // }, { A: '4493fb6dc07611bab03630b154ca2483', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/801',
199
- // }, { A: 'e31caf56bb86f6e12377db006ac61756', B: 'rtsp://admin:Bli$$%40145@192.168.29.86/streaming/channels/901',
200
- // }, { A: 'fe66c637bc8da296485494e371f67b99', B: 'rtsp://admin:Bli$$%40145@192.168.29.58/streaming/channels/901' },
201
- // ];
202
-
203
- // for ( const item of array ) {
204
- // const a = await updateOneCamera( { streamName: item.A, clientId: '370' }, { RTSP: item.B } );
205
- // count++;
206
- // logger.info( { aaa: a, count: count } );
207
- // }
208
-
209
- // process.exit();
210
177
  const openSearch = JSON.parse( process.env.OPENSEARCH );
211
178
  const inputData = req.query;
212
179
  const limit = inputData.limit || 10;
213
- const skip= inputData.offset == 0? 0:( inputData.offset - 1 ) *limit || 0;
180
+ const offset= inputData.offset == 0? 0:( inputData.offset - 1 ) *limit || 0;
181
+ const order = inputData?.sortOrder || -1;
182
+
214
183
  inputData.clientId = inputData.clientId.split( ',' ); // convert strig to array
215
- logger.info( { inputData: inputData, limit: limit, skip: skip } );
216
- const getCount= {
217
- query: {
218
- bool: {
219
- filter: [
220
- { terms: { 'clientId.keyword': Array.isArray( inputData.clientId ) ?
221
- inputData.clientId :
222
- inputData.clientId } },
223
- {
224
- range: {
225
- dateString: {
226
- gte: inputData.fromDate,
227
- lte: inputData.toDate,
228
- format: 'yyyy-MM-dd',
229
- },
230
- },
231
- },
232
- ],
184
+
185
+
186
+ let filter= [
187
+ {
188
+ 'range': {
189
+ 'dateString': {
190
+ 'gte': inputData.fromDate,
191
+ 'lte': inputData.toDate,
192
+ 'format': 'yyyy-MM-dd',
193
+ },
233
194
  },
234
195
  },
235
- };
236
-
237
- const geteDataCount = await getOpenSearchCount( openSearch.footfallDirectory, getCount );
238
- if ( !geteDataCount || geteDataCount?.body?.count == 0 ) {
239
- return res.sendError( 'No data found', 204 );
240
- }
241
- const getQuery = {
242
- size: limit,
243
- from: skip,
244
- query: {
245
- bool: {
246
- filter: [
247
- { terms: { 'clientId.keyword': Array.isArray( inputData.clientId ) ?
196
+ { terms: { 'clientId.keyword': Array.isArray( inputData.clientId ) ?
248
197
  inputData.clientId :
249
198
  inputData.clientId } },
250
- {
251
- range: {
252
- dateString: {
253
- gte: inputData.fromDate,
254
- lte: inputData.toDate,
255
- format: 'yyyy-MM-dd',
256
- },
199
+ ];
200
+
201
+ let search ={
202
+ 'must': filter,
203
+ };
204
+
205
+ if ( inputData.searchValue && inputData.searchValue !== '' ) {
206
+ search ={
207
+ 'must': filter,
208
+ 'should': [
209
+ {
210
+ 'wildcard': {
211
+ 'storeName.keyword': {
212
+ 'value': `*${inputData.searchValue}*`,
257
213
  },
258
214
  },
259
- ],
260
- },
215
+ },
216
+ {
217
+ 'wildcard': {
218
+ 'storeId.keyword': {
219
+ 'value': `*${inputData.searchValue}*`,
220
+ },
221
+ },
222
+ },
223
+ {
224
+ 'wildcard': {
225
+ 'ticketId.keyword': {
226
+ 'value': `*${inputData.searchValue}*`,
227
+ },
228
+ },
229
+ },
230
+ {
231
+ 'wildcard': {
232
+ 'status.keyword': {
233
+ 'value': `*${inputData.searchValue}*`,
234
+ },
235
+ },
236
+ },
237
+
238
+ ],
239
+ 'minimum_should_match': 1,
240
+ };
241
+ }
242
+
243
+ let searchQuery={
244
+ '_source': [
245
+ 'storeName',
246
+ 'storeId',
247
+ 'ticketId',
248
+ 'createdAt',
249
+ 'footfallCount',
250
+ 'duplicateCount',
251
+ 'employeeCount',
252
+ 'houseKeepingCount',
253
+ 'status',
254
+ 'dateString',
255
+ ],
256
+ 'from': offset,
257
+ 'size': limit,
258
+ 'query': {
259
+ 'bool': search,
261
260
  },
262
- _source: [ 'storeName', 'storeId', 'ticketId', 'createdAt', 'footfallCount', 'duplicateCount', 'employeeCount', 'houseKeepingCount', 'status', 'dateString' ],
261
+ 'sort': [
262
+ { dateString: { order: 'desc' } },
263
+ ],
263
264
  };
264
265
 
265
- const getData = await getOpenSearchData( openSearch.footfallDirectory, getQuery );
266
- const response = getData?.body?.hits?.hits;
267
- logger.info( { response: response, body: getData?.body, getData: getData, geteDataCount: geteDataCount } );
266
+ if ( inputData.sortBy && inputData.sortBy !== '' ) {
267
+ let sortByValue = '';
268
268
 
269
+ if ( [ 'storeName', 'storeId', 'ticketId', 'status' ].includes( inputData?.sortBy ) ) {
270
+ sortByValue = `${inputData.sortBy}.keyword`;
271
+ } else {
272
+ sortByValue = inputData.sortBy;
273
+ }
269
274
 
270
- if ( inputData.isExport=== true ) {
271
- const temp = [];
272
- for ( const item of response ) {
273
- temp.push( {
274
- 'Store Name': item.storeName,
275
- 'Store ID': item.storeId,
276
- 'Ticket ID': item.ticketId,
277
- 'Ticket raised on': dayjs( item.createdAt ).format( 'dd MMM, yyyy' ),
278
- 'Total Footfalls': item.footfallCount,
279
- 'Duplicates': item.duplicateCount,
280
- 'Employee/Staff': item.employeeCount,
281
- 'HouseKeeping': item.houseKeepingCount,
282
- 'Revised Footfalls': item.footfallCount-( item.duplicateCount+item.employeeCount+item.houseKeepingCount ),
283
- 'Status': item.status,
275
+
276
+ searchQuery={
277
+ '_source': [
278
+ 'storeName',
279
+ 'storeId',
280
+ 'ticketId',
281
+ 'createdAt',
282
+ 'footfallCount',
283
+ 'duplicateCount',
284
+ 'employeeCount',
285
+ 'houseKeepingCount',
286
+ 'status',
287
+ 'dateString',
288
+ ],
289
+ 'from': offset,
290
+ 'size': limit,
291
+ 'query': {
292
+ 'bool': search,
293
+ },
294
+ 'sort': [
295
+ { [sortByValue]: { order: order === -1 ?'desc':'asc' } },
296
+ ],
297
+ };
298
+ }
299
+
300
+ if ( inputData.isExport==true ) {
301
+ searchQuery={
302
+ '_source': [
303
+ 'storeName',
304
+ 'storeId',
305
+ 'ticketId',
306
+ 'createdAt',
307
+ 'footfallCount',
308
+ 'duplicateCount',
309
+ 'employeeCount',
310
+ 'houseKeepingCount',
311
+ 'status',
312
+ 'dateString',
313
+ ],
314
+ 'from': 0,
315
+ 'size': 10000,
316
+ 'query': {
317
+ 'bool': search,
318
+ },
319
+ 'sort': [
320
+ { 'storeName.keyword': { order: 'desc' } },
321
+ ],
322
+ };
323
+ }
324
+ const getData = await getOpenSearchData( openSearch.footfallDirectory, searchQuery );
325
+ const count = getData?.body?.hits?.total?.value;
326
+ if ( !count || count == 0 ) {
327
+ return res.sendError( 'No data found', 204 );
328
+ }
329
+ const searchValue = getData?.body?.hits?.hits;
330
+ if ( !searchValue || searchValue?.length == 0 ) {
331
+ return res.sendError( 'No data found', 204 );
332
+ }
333
+
334
+ if ( inputData.isExport==true ) {
335
+ const exportData = [];
336
+ for ( const item of searchValue ) {
337
+ exportData.push( {
338
+ 'Store Name': item._source.storeName || '--',
339
+ 'Store ID': item._source.storeId,
340
+ 'Ticket ID': item._source.ticketId,
341
+ 'Ticket raised on': dayjs( item._source.createdAt ).format( 'DD MMM, YYYY' ),
342
+ 'Total Footfalls': item._source.footfallCount,
343
+ 'Duplicates': item._source.duplicateCount,
344
+ 'Employee/Staff': item._source.employeeCount,
345
+ 'HouseKeeping': item._source.houseKeepingCount,
346
+ 'Revised Footfalls': item._source.footfallCount-( item._source.duplicateCount+item._source.employeeCount+item._source.houseKeepingCount ),
347
+ 'Status': item._source.status,
284
348
  } );
285
349
  }
286
- await download( temp, res );
287
- return;
350
+ return await download( exportData, res );
288
351
  }
289
-
290
- return res.sendSuccess( { result: response, count: geteDataCount?.body?.count } );
352
+ return res.sendSuccess( { result: searchValue, count: count } );
291
353
  } catch ( error ) {
292
354
  const err = error.message || 'Internal Server Error';
293
355
  logger.error( { error: error, messgage: req.query } );
@@ -467,17 +529,15 @@ export async function getTaggedStores( req, res ) {
467
529
  try {
468
530
  const openSearch = JSON.parse( process.env.OPENSEARCH );
469
531
  const inputData = req.query;
470
- const limit = inputData.limit || 10;
471
- const skip= inputData.offset == 0? 0:( inputData.offset - 1 ) *limit || 0;
472
- inputData.storeId = inputData.storeId.split( ',' ); // convert strig to array
473
- logger.info( { inputData: inputData, limit: limit, skip: skip } );
474
- const getCount= {
532
+ logger.info( { inputData: inputData } );
533
+ const getCount = {
534
+ size: 0,
475
535
  query: {
476
536
  bool: {
477
537
  filter: [
478
- { terms: { 'storeId.keyword': Array.isArray( inputData.storeId ) ?
479
- inputData.storeId :
480
- inputData.storeId } },
538
+ {
539
+ term: { 'clientId.keyword': inputData.clientId },
540
+ },
481
541
  {
482
542
  range: {
483
543
  dateString: {
@@ -487,65 +547,51 @@ export async function getTaggedStores( req, res ) {
487
547
  },
488
548
  },
489
549
  },
490
- ],
491
- },
492
- },
493
- };
494
550
 
495
- const geteDataCount = await getOpenSearchCount( openSearch.footfallDirectory, getCount );
496
- if ( !geteDataCount || geteDataCount?.body?.count == 0 ) {
497
- return res.sendError( 'No data found', 204 );
498
- }
499
- const getQuery = {
500
- size: limit,
501
- from: skip,
502
- query: {
503
- bool: {
504
- filter: [
505
- { terms: { 'storeId.keyword': Array.isArray( inputData.storeId ) ?
506
- inputData.storeId :
507
- inputData.storeId } },
508
551
  {
509
- range: {
510
- dateString: {
511
- gte: inputData.fromDate,
512
- lte: inputData.toDate,
513
- format: 'yyyy-MM-dd',
514
- },
552
+ exists: {
553
+ field: 'storeId',
554
+ },
555
+ },
556
+ {
557
+ exists: {
558
+ field: 'storeName',
515
559
  },
516
560
  },
517
561
  ],
518
562
  },
519
563
  },
520
- // _source: [ 'storeName', 'storeId', 'ticketId', 'createdAt', 'footfallCount', 'duplicateCount', 'employeeCount', 'houseKeepingCount', 'status', 'dateString' ],
564
+ aggs: {
565
+ unique_stores: {
566
+ composite: {
567
+ size: 1000,
568
+ sources: [
569
+ {
570
+ storeId: {
571
+ terms: { field: 'storeId.keyword' },
572
+ },
573
+ },
574
+ {
575
+ storeName: {
576
+ terms: { field: 'storeName.keyword' },
577
+ },
578
+ },
579
+ ],
580
+ },
581
+ },
582
+ },
521
583
  };
584
+ let temp = [];
522
585
 
523
- const getData = await getOpenSearchData( openSearch.footfallDirectory, getQuery );
524
- const response = getData?.body?.hits?.hits;
525
- logger.info( { response: response, body: getData?.body, getData: getData, geteDataCount: geteDataCount } );
526
-
527
-
528
- if ( inputData.isExport=== true ) {
529
- const temp = [];
530
- for ( const item of response ) {
531
- temp.push( {
532
- 'Store Name': item.storeName,
533
- 'Store ID': item.storeId,
534
- 'Ticket ID': item.ticketId,
535
- 'Ticket raised on': dayjs( item.createdAt ).format( 'dd MMM, yyyy' ),
536
- 'Total Footfalls': item.footfallCount,
537
- 'Duplicates': item.duplicateCount,
538
- 'Employee/Staff': item.employeeCount,
539
- 'HouseKeeping': item.houseKeepingCount,
540
- 'Revised Footfalls': item.footfallCount-( item.duplicateCount+item.employeeCount+item.houseKeepingCount ),
541
- 'Status': item.status,
542
- } );
543
- }
544
- await download( temp, res );
545
- return;
586
+ const geteDataCount = await getOpenSearchData( openSearch.footfallDirectory, getCount );
587
+ if ( !geteDataCount && geteDataCount?.body?.aggregations?.unique_stores?.buckets?.length > 0 ) {
588
+ return res.sendError( 'No data found', 204 );
546
589
  }
547
590
 
548
- return res.sendSuccess( { result: response, count: geteDataCount?.body?.count } );
591
+ const response = geteDataCount?.body?.aggregations?.unique_stores?.buckets;
592
+ logger.info( { response: response } );
593
+ response?.map( ( item ) => temp.push( { storeId: item.key.storeId, storeName: item.key.storeName } ) );
594
+ return res.sendSuccess( { result: temp, count: response?.length } );
549
595
  } catch ( error ) {
550
596
  const err = error.message || 'Internal Server Error';
551
597
  logger.error( { error: error, messgage: req.query } );
@@ -1,5 +1,5 @@
1
1
  import j2s from 'joi-to-swagger';
2
- import { createTicketSchema, getTicketsSchema, ticketListSchema, ticketSummarySchema, updateStatusQuerySchema, updateStatusSchemea } from '../dtos/footfallDirectory.dtos.js';
2
+ import { createTicketSchema, getTaggedStoresSchema, getTicketsSchema, ticketListSchema, ticketSummarySchema, updateStatusQuerySchema, updateStatusSchemea } from '../dtos/footfallDirectory.dtos.js';
3
3
 
4
4
  export const footfallDirectoryDocs = {
5
5
 
@@ -59,7 +59,6 @@ export const footfallDirectoryDocs = {
59
59
  },
60
60
  },
61
61
  },
62
-
63
62
  '/v3/footfall-directory-tagging/ticket-list': {
64
63
  get: {
65
64
  tags: [ 'Footfall Directory Ticket' ],
@@ -86,7 +85,7 @@ export const footfallDirectoryDocs = {
86
85
  },
87
86
  {
88
87
  in: 'query',
89
- name: 'searchvalue',
88
+ name: 'searchValue',
90
89
  scema: j2s( ticketListSchema ).swagger,
91
90
  required: false,
92
91
  },
@@ -108,6 +107,12 @@ export const footfallDirectoryDocs = {
108
107
  scema: j2s( ticketListSchema ).swagger,
109
108
  required: false,
110
109
  },
110
+ {
111
+ in: 'query',
112
+ name: 'sortBy',
113
+ scema: j2s( ticketListSchema ).swagger,
114
+ required: false,
115
+ },
111
116
  ],
112
117
  responses: {
113
118
  200: { description: 'Successful' },
@@ -149,6 +154,18 @@ export const footfallDirectoryDocs = {
149
154
  scema: j2s( getTicketsSchema ).swagger,
150
155
  required: false,
151
156
  },
157
+ {
158
+ in: 'query',
159
+ name: 'status',
160
+ scema: j2s( getTicketsSchema ).swagger,
161
+ required: false,
162
+ },
163
+ {
164
+ in: 'query',
165
+ name: 'action',
166
+ scema: j2s( getTicketsSchema ).swagger,
167
+ required: false,
168
+ },
152
169
  {
153
170
  in: 'query',
154
171
  name: 'limit',
@@ -201,4 +218,40 @@ export const footfallDirectoryDocs = {
201
218
  },
202
219
  },
203
220
  },
221
+
222
+ '/v3/footfall-directory-tagging/get-tagged-stores': {
223
+ get: {
224
+ tags: [ 'Footfall Directory Ticket' ],
225
+ description: 'To get list of tagged stores',
226
+ operationId: 'get-tagged-stores',
227
+ parameters: [
228
+ {
229
+ in: 'query',
230
+ name: 'clientId',
231
+ scema: j2s( getTaggedStoresSchema ).swagger,
232
+ required: true,
233
+ },
234
+ {
235
+ in: 'query',
236
+ name: 'fromDate',
237
+ scema: j2s( getTaggedStoresSchema ).swagger,
238
+ required: true,
239
+ },
240
+ {
241
+ in: 'query',
242
+ name: 'toDate',
243
+ scema: j2s( getTaggedStoresSchema ).swagger,
244
+ required: true,
245
+ },
246
+ ],
247
+ responses: {
248
+ 200: { description: 'Successful' },
249
+ 401: { description: 'Unauthorized User' },
250
+ 422: { description: 'Field Error' },
251
+ 500: { description: 'Server Error' },
252
+ 204: { description: 'Not Found' },
253
+ },
254
+ },
255
+ },
256
+
204
257
  };
@@ -125,6 +125,7 @@ export const ticketListSchema = Joi.object().keys( {
125
125
  limit: Joi.number().optional(),
126
126
  offset: Joi.number().optional(),
127
127
  isExport: Joi.boolean().optional(),
128
+ sortBy: Joi.string().optional().allow( '' ),
128
129
  fromDate: Joi.string()
129
130
  .pattern( /^\d{4}-\d{2}-\d{2}$/, 'YYYY-MM-DD format' )
130
131
  .required()