tango-app-api-report 3.0.3-dev → 3.0.5-dev

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/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
 
2
2
 
3
3
  import { reportRouter } from './src/routes/report.routes.js';
4
+ import { reportDocs } from './src/docs/report.docs.js';
4
5
 
5
- export { reportRouter };
6
+ export { reportRouter, reportDocs };
6
7
 
7
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-report",
3
- "version": "3.0.3-dev",
3
+ "version": "3.0.5-dev",
4
4
  "description": "report",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,8 +1,8 @@
1
- import { reportCreate, reportGet, reportGetSingle, reportUpdate } from '../service/report.service.js';
2
- import { appConfig, insertOpenSearchData, logger, sendMessageToQueue } from 'tango-app-api-middleware';
3
- import { getUserNameEmailById } from '../service/user.service.js';
1
+ import { findOneReport, findReport, reportCreate, reportGet, reportGetSingle, reportUpdate } from '../service/report.service.js';
2
+ import { appConfig, fileUpload, getObject, insertOpenSearchData, listFoldersByPath, logger, sendMessageToQueue } from 'tango-app-api-middleware';
3
+ import { findOneUser, getUserNameEmailById } from '../service/user.service.js';
4
4
  import { updateOneBasePriceModel } from '../service/basePrice.service.js';
5
- import { aggregateClient, findOneClient } from '../service/client.service.js';
5
+ import { aggregateClient } from '../service/client.service.js';
6
6
  // import basePricingModel from 'tango-api-schema/schema/basePricing.model.js';
7
7
 
8
8
 
@@ -103,12 +103,17 @@ export async function clientReportList( req, res ) {
103
103
  const query = [
104
104
  {
105
105
  $match: {
106
- 'reportConfigs.report': { $eq: true },
106
+ $and: [
107
+ { 'reportConfigs.report': { $eq: true } },
108
+ { clientId: { $in: inputData.clientId } },
109
+ ],
110
+
107
111
  },
108
112
  },
109
113
  {
110
114
  $project: {
111
115
  clientId: 1,
116
+ tangoId: 1,
112
117
  clientName: 1,
113
118
  daysDifference: 1,
114
119
  datesArray: {
@@ -133,6 +138,7 @@ export async function clientReportList( req, res ) {
133
138
  $project: {
134
139
  clientId: 1,
135
140
  clientName: 1,
141
+ tangoId: 1,
136
142
  fileDate: '$datesArray',
137
143
  },
138
144
  },
@@ -156,18 +162,22 @@ export async function clientReportList( req, res ) {
156
162
  }
157
163
  if ( inputData.sortColumnName ) {
158
164
  const sortBy = inputData.sortBy || -1;
165
+ const sortColumnName =inputData.sortColumnName == 'clientId'? 'tangoId': inputData.sortColumnName;
159
166
  query.push( {
160
- $sort: { [inputData.sortColumnName]: sortBy },
167
+ $sort: { [sortColumnName]: sortBy },
161
168
  } );
162
169
  }
163
170
  const count = await aggregateClient( query );
171
+ if ( count?.length == 0 ) {
172
+ return res.sendError( 'No Data Found', 204 );
173
+ }
164
174
 
165
175
  query.push(
166
176
  { $skip: offset },
167
177
  { $limit: limit },
168
178
  );
169
179
  const result = await aggregateClient( query );
170
- res.sendSuccess( { result: result, count: count.length } );
180
+ res.sendSuccess( { result: result, count: count?.length } );
171
181
  } catch ( error ) {
172
182
  logger.info( { error: error, message: req.body, function: 'clientReportList' } );
173
183
  return res.sendError( 'Internal Server Error', 500 );
@@ -176,17 +186,13 @@ export async function clientReportList( req, res ) {
176
186
 
177
187
  export async function generateReport( req, res ) {
178
188
  try {
179
- const inputdata = req.body;
180
- const getReportName = await findOneClient( { 'clientId': inputdata.clientId, 'reportConfigs.report': true }, { reportName: '$reportConfigs.reportName', clientName: 1 } );
181
- if ( !getReportName ) {
182
- return res.sendError( 'reportName is not there in the client', 204 );
183
- }
189
+ const inputData = req.body;
184
190
  const sqsProduceQueue = {
185
191
  QueueUrl: `${appConfig.cloud.aws.sqs.url}${appConfig.cloud.aws.sqs.generateReport}`,
186
192
  MessageBody: JSON.stringify( {
187
- file_date: inputdata.fileDate,
188
- client_name: getReportName.reportName,
189
- client_id: Number( inputdata.ClientId ),
193
+ file_date: inputData.fileDate,
194
+ client_name: inputData.getReportName?.reportName,
195
+ client_id: Number( inputData.clientId ),
190
196
  message: 'good to trigger',
191
197
  } ),
192
198
  };
@@ -199,10 +205,10 @@ export async function generateReport( req, res ) {
199
205
  logType: 'report',
200
206
  logSubType: 'generateReport',
201
207
  logData: {
202
- clientName: getReportName.clientName,
203
- fileDate: inputdata.fileDate,
204
- reportName: getReportName.reportName,
205
- clientId: inputdata.ClientId,
208
+ clientName: inputData.getReportName?.clientName,
209
+ fileDate: inputData.fileDate,
210
+ reportName: inputData.getReportName?.reportName,
211
+ clientId: inputData.ClientId,
206
212
  sqsMessageId: sqsQueue.MessageId,
207
213
  },
208
214
  };
@@ -210,159 +216,214 @@ export async function generateReport( req, res ) {
210
216
 
211
217
  return res.sendSuccess( { result: 'Report has been Initiated Sucessfully' } );
212
218
  }
213
- } catch ( err ) {
219
+ } catch ( error ) {
220
+ const err = error.code || 'Internal Server Error';
221
+ logger.error( { error: error, message: req.body, function: 'generateReport' } );
214
222
  return res.sendError( err, 500 );
215
223
  }
216
224
  }
217
225
 
218
- export async function sendReport( req, res ) {
226
+ export async function uploadManualReport( req, res ) {
219
227
  try {
220
- // let record = await reportModel.find( { clientId: req.body.clientId } );
221
- // if ( record.length == 0 ) {
222
- // return res.sendError( 'No report Found', 204 );
223
- // }
224
- // let reportname = [];
225
- // let name = [];
226
- // let regionalKey = [];
227
- // let result = [];
228
- // let file = {};
229
- // let sendMailCount = 0;
230
- // let subject = 'Fwd: Tango Eye\'s Customer Intelligence Report - ' + req.body.fileDate;
231
- // let messageBody = `<br>Hi Team,<br><br>&nbsp;Please find attached Tango RetailEye report on customer footfall and shopping patterns for ${req.body.fileDate}.<br><br>&nbsp;Thanks <br>&nbsp;Team Tango`;
232
- // let UserattachmentDetails = [];
233
- // for ( const data of record ) {
234
- // // const email = data.email; // Extract the email property from the current object
235
- // // toemail.push( email );
236
- // const fetchData = {
237
- // Bucket: `${config.r2.bucketName.reportBucket}`,
238
- // Key: `${req.body.fileDate}/${data.reportName}/${req.body.fileDate}_${data.fileName}.${data.fileType}`,
239
- // };
240
- // reportname.push( `${req.body.fileDate}_${data.fileName}` );
241
- // name.push( `${data.fileName}` );
242
- // regionalKey.push( `${req.body.fileDate}_${data.fileName}.${data.fileType}` );
243
- // file = await getFileImg( fetchData );
244
- // if ( file.statusCode == 404 ) {
245
- // logger.info( 'File not available in bucket ' + `${JSON.stringify( file )}` );
246
- // sendMailCount += 1;
247
- // } else {
248
- // data.email.forEach( ( email ) => {
249
- // let UserIndex = UserattachmentDetails.findIndex( ( user ) => user.email == email );
250
- // if ( UserIndex == -1 ) {
251
- // UserattachmentDetails.push( {
252
- // email: email,
253
- // attachments: [
254
- // {
255
- // filename: `${req.body.fileDate}_${data.fileName}.${data.fileType}`,
256
- // content: file.Body,
257
- // contentType: file.ContentType,
258
- // },
259
- // ],
260
- // } );
261
- // } else {
262
- // UserattachmentDetails[UserIndex].attachments.push( {
263
- // filename: `${req.body.fileDate}_${data.fileName}.${data.fileType}`,
264
- // content: file.Body,
265
- // contentType: file.ContentType,
266
- // } );
267
- // }
268
- // } );
269
- // }
270
- // }
271
- // UserattachmentDetails.forEach( async ( userattach ) => {
272
- // await sendEmail( userattach.email, subject, messageBody, userattach.attachments, config.ses.reportEmail ).then( ( response ) => {
273
- // result.push( response );
274
- // } );
275
- // } );
276
- // if ( sendMailCount == record.length ) {
277
- // return res.sendError( 'File not available in bucket', 404 );
278
- // }
279
- // let user = await userModel.findOne( { _id: req.user._id } );
280
-
281
- // const log = {
282
- // userName: user.name,
283
- // Date: new Date(),
284
- // userId: user._id,
285
- // logType: 'report',
286
- // logSubType: 'sendReport',
287
- // logData: {
288
- // fileDate: req.body.fileDate,
289
- // reportName: record[0].reportName,
290
- // clientId: record[0].clientId,
291
- // },
292
- // };
293
- // await activityModel.create( log );
294
- // let client = await clientModel.findOne( { clientId: req.body.clientId } );
228
+ const inputData = req.body;
229
+ const name = inputData.fileName;
230
+ const regex = /^(\d{2}-\d{2}-\d{4})_(.*?)\.([a-zA-Z0-9]+)$/;
231
+ const matches = name.match( regex );
232
+ if ( matches ) {
233
+ const date = matches[1];
234
+ const filenameWithoutExtension = matches[2];
235
+ const extension = matches[3];
236
+ if ( inputData.fileDate !== date ) {
237
+ return res.sendError( 'File Date is Incorrect in the File Name', 400 );
238
+ }
239
+ const query = {
240
+ 'fileName': filenameWithoutExtension,
241
+ 'fileType': extension,
242
+ 'clientId': inputData.clientId,
243
+ };
244
+ const data = await findOneReport( query );
245
+ if ( !data ) {
246
+ return res.sendError( 'Report does not configured', 400 );
247
+ }
248
+ const uploadDataParams = {
249
+ Bucket: appConfig.cloud.aws.bucket.reportBucket,
250
+ Key: `${inputData.fileDate}/${data.reportName}/`,
251
+ fileName: inputData.filename,
252
+ Body: req.files.fileuplaod_data.data,
253
+ };
254
+ const result = await fileUpload( uploadDataParams );
255
+ logger.info( { result: result, value: 'file upload response' } );
256
+ if ( !result ) {
257
+ return res.sendError( 'File Upload Failed', 500 );
258
+ }
259
+ let user = await findOneUser( { _id: req.user._id, isActive: true } );
260
+ if ( !user ) {
261
+ return res.sendError( 'Forbidden', 403 );
262
+ }
263
+ const log = {
264
+ userName: user.userName,
265
+ Date: new Date(),
266
+ userId: req.user._id,
267
+ logType: 'report',
268
+ logSubType: 'uploadReport',
269
+ logData: {
270
+ fileDate: inputData.fileDate,
271
+ reportName: data.reportName,
272
+ clientId: data.clientId,
273
+ },
274
+ };
295
275
 
296
- // const sqsProduceQueue = {
297
- // QueueUrl: `${config.aws.sqs.queue.url}${config.aws.sqs.queueName.sentNotify}`,
298
- // MessageBody: JSON.stringify( {
299
- // file_date: req.body.fileDate,
300
- // client_name: record[0].reportName,
301
- // client_id: Number( client.clientId ),
302
- // file_name: regionalKey,
303
- // report_name: name,
304
- // } ),
305
- // };
306
- // const sqsQueue = await produceQueue( sqsProduceQueue );
307
- // logger.info( 'successfully Pushed to SQS ' + `${JSON.stringify( sqsQueue )}`, 'Send Report' );
276
+ await insertOpenSearchData( 'tango-retail-activity-logs', log );
277
+ return res.sendSuccess( { result: 'uploaded Sucessfully' } );
278
+ } else {
279
+ return res.sendError( 'File Name is Incorrect', 400 );
280
+ }
281
+ } catch ( error ) {
282
+ logger.error( { error: error, message: req.body, function: 'generateReport' } );
283
+ return res.sendError( error, 500 );
284
+ }
285
+ }
308
286
 
309
- return res.sendSuccess( 'Report Send Successfully', 200 );
310
- } catch ( err ) {
311
- console.log( err );
312
- return res.sendError( err, 500 );
287
+ export async function getReportList( req, res ) {
288
+ try {
289
+ const inputData = req.query;
290
+ const fetchData = {
291
+ Bucket: appConfig.cloud.aws.bucket.reportBucket,
292
+ file_path: `${inputData.fileDate}/${inputData.getReportName?.reportName}/`,
293
+ };
294
+ const folderPath = await listFoldersByPath( fetchData );
295
+ logger.info( { folderPath: folderPath, value: 'report list from bucket' } );
296
+ if ( folderPath.length == 0 ) {
297
+ return res.sendError( 'No Reports Found', 204 );
298
+ }
299
+ return res.sendSuccess( { result: folderPath } );
300
+ } catch ( error ) {
301
+ logger.error( { error: error, message: req.query, function: 'getReportList' } );
302
+ return res.sendError( error, 500 );
313
303
  }
314
304
  }
315
305
 
316
- export async function uploadManualReport( req, res ) {
306
+ export async function dowloadReport( req, res ) {
307
+ try {
308
+ const inputData = req.query;
309
+ const params = {
310
+ Bucket: appConfig.cloud.aws.bucket.reportBucket,
311
+ Key: inputData.filePath,
312
+ };
313
+ const fileName = inputData.filePath.split( '/' );
314
+ const getReport = await getObject( params );
315
+ if ( getReport.code ) {
316
+ return res.sendError( getReport, 500 );
317
+ }
318
+ res.setHeader(
319
+ 'Content-disposition',
320
+ `attachment; filename=${fileName[2]}`,
321
+ );
322
+ res.setHeader(
323
+ 'Content-Type',
324
+ `${getReport.ContentType}`,
325
+ );
326
+ res.status( 200 ).send( getReport.Body );
327
+ } catch ( error ) {
328
+ logger.error( { error: error, message: req.query, function: 'dowloadReport' } );
329
+ return res.sendError( error, 500 );
330
+ }
331
+ }
332
+ export async function sendReport( req, res ) {
317
333
  try {
318
334
  const inputData = req.body;
319
- return res.sendSuccess( inputData );
320
- // const name = inputdata.fileName;
321
- // const regex = /^(\d{2}-\d{2}-\d{4})_(.*?)\.([a-zA-Z0-9]+)$/;
322
- // const matches = name.match( regex );
323
- // if ( matches ) {
324
- // const date = matches[1];
325
- // const filenameWithoutExtension = matches[2];
326
- // const extension = matches[3];
327
- // if ( inputdata.fileDate !== date ) {
328
- // return res.sendError( 'file date not match with input file name', 400 );
329
- // }
330
- // const data = await reportModel.findOne( { 'fileName': filenameWithoutExtension, 'fileType': extension, 'clientId': inputdata.clientId } );
331
- // if ( !data ) {
332
- // return res.sendError( 'Something Went wrong', 400 );
333
- // }
334
- // const uploadDataParams = {
335
- // Bucket: config.r2.bucketName.reportBucket,
336
- // Key: `${inputdata.fileDate}/${data.reportName}/`,
337
- // fileName: inputdata.filename,
338
- // Body: req.files.fileuplaod_data.data,
339
- // };
340
- // const result = await fileUpload( uploadDataParams );
341
- // if ( !result ) {
342
- // return res.sendError( 'file upload error', 500 );
343
- // } else {
344
- // let user = await userModel.findOne( { _id: req.user._id } );
335
+ const getReportList = await findReport( { clientId: inputData.clientId } );
336
+ let reportName = [];
337
+ let name = [];
338
+ let regionalKey = [];
339
+ let result = [];
340
+ let file = {};
341
+ let sendMailCount = 0;
342
+ let subject = 'Fwd: Tango Eye\'s Customer Intelligence Report - ' + inputData.fileDate;
343
+ let messageBody = `<br>Hi Team,<br><br>&nbsp;Please find attached Tango RetailEye report on customer footfall and shopping patterns for ${inputData.fileDate}.<br><br>&nbsp;Thanks <br>&nbsp;Team Tango`;
344
+ let UserattachmentDetails = [];
345
+ for ( const data of getReportList ) {
346
+ const fetchData = {
347
+ Bucket: appConfig.cloud.aws.bucket.reportBucket,
348
+ Key: `${inputData.fileDate}/${data.reportName}/${inputData.fileDate}_${data.fileName}.${data.fileType}`,
349
+ };
350
+ reportName.push( `${inputData.fileDate}_${data.fileName}` );
351
+ name.push( `${data.fileName}` );
352
+ regionalKey.push( `${inputData.fileDate}_${data.fileName}.${data.fileType}` );
353
+ file = await getObject( fetchData );
354
+ if ( file.statusCode == 404 ) {
355
+ logger.info( 'File not available in bucket ' + `${JSON.stringify( file )}` );
356
+ sendMailCount += 1;
357
+ } else {
358
+ data.email.forEach( ( email ) => {
359
+ let UserIndex = UserattachmentDetails.findIndex( ( user ) => user.email == email );
360
+ if ( UserIndex == -1 ) {
361
+ UserattachmentDetails.push( {
362
+ email: email,
363
+ attachments: [
364
+ {
365
+ filename: `${inputData.fileDate}_${data.fileName}.${data.fileType}`,
366
+ content: file.Body,
367
+ contentType: file.ContentType,
368
+ },
369
+ ],
370
+ } );
371
+ } else {
372
+ UserattachmentDetails[UserIndex].attachments.push( {
373
+ filename: `${req.body.fileDate}_${data.fileName}.${data.fileType}`,
374
+ content: file.Body,
375
+ contentType: file.ContentType,
376
+ } );
377
+ }
378
+ } );
379
+ }
380
+ }
381
+ UserattachmentDetails.forEach( async ( userattach ) => {
382
+ await sendEmail( userattach.email, subject, messageBody, userattach.attachments, config.ses.reportEmail ).then( ( response ) => {
383
+ result.push( response );
384
+ } );
385
+ } );
386
+ if ( sendMailCount == getReportList.length ) {
387
+ return res.sendError( 'File not available in bucket', 404 );
388
+ }
389
+ let user = await findOneUser( { _id: req.user._id, isActive: true } );
390
+ if ( !user ) {
391
+ return res.sendError( 'Forbiddon to Access', 403 );
392
+ }
393
+ const sqsProduceQueue = {
394
+ QueueUrl: `${appConfig.cloud.aws.sqs.url}${appConfig.cloud.aws.sqs.sendReport}`,
395
+ MessageBody: JSON.stringify( {
396
+ file_date: inputData.fileDate,
397
+ client_name: getReportList[0].reportName,
398
+ client_id: Number( inputData.clientId ),
399
+ file_name: regionalKey,
400
+ report_name: name,
401
+ } ),
402
+ };
403
+ const sqsQueue = await sendMessageToQueue( sqsProduceQueue.QueueUrl, sqsProduceQueue.MessageBody );
404
+ if ( sqsQueue.MessageId ) {
405
+ logger.info( 'successfully Pushed to SQS ' + `${JSON.stringify( sqsQueue )}`, 'Send Report' );
406
+ const log = {
407
+ userName: user.userName,
408
+ Date: new Date(),
409
+ userId: user._id,
410
+ logType: 'report',
411
+ logSubType: 'sendReport',
412
+ logData: {
413
+ fileDate: inputData.fileDate,
414
+ reportName: getReportList[0].reportName,
415
+ clientId: getReportList[0].clientId,
416
+ },
417
+ };
418
+ await insertOpenSearchData( 'tango-retail-activity-logs', log );
419
+ return res.sendSuccess( { result: 'Report has been Sent Successfully' } );
420
+ } else {
421
+ return res.sendError( ' Message does not Sent & Report has been Sent Successfully', 500 );
422
+ }
423
+ } catch ( error ) {
424
+ logger.error( { error: error, message: req.body, function: 'sendReport' } );
345
425
 
346
- // const log = {
347
- // userName: user.name,
348
- // Date: new Date(),
349
- // userId: req.user._id,
350
- // logType: 'report',
351
- // logSubType: 'uploadReport',
352
- // logData: {
353
- // fileDate: inputdata.fileDate,
354
- // reportName: data.reportName,
355
- // clientId: data.clientId,
356
- // },
357
- // };
358
- // await activityModel.create( log );
359
- // }
360
- // res.sendSuccess( 'uploaded Sucessfully', 200 );
361
- // } else {
362
- // }
363
- } catch ( err ) {
364
- console.log( err, 'err' );
365
- return res.sendError( err, 500 );
426
+ return res.sendError( error, 500 );
366
427
  }
367
428
  }
368
429
 
@@ -1,6 +1,6 @@
1
1
  import j2s from 'joi-to-swagger';
2
2
 
3
- import { clientListTableSchema, generateReportSchema } from '../dtos/report.dtos.js';
3
+ import { clientListTableSchema, downloadReportSchema, generateReportSchema, getReportListSchema, sendReportSchema, uploadManualReportSchema } from '../dtos/report.dtos.js';
4
4
 
5
5
  export const reportDocs = {
6
6
 
@@ -51,5 +51,103 @@ export const reportDocs = {
51
51
  },
52
52
  },
53
53
 
54
+ '/v3/report/upload-manual-report': {
55
+ post: {
56
+ tags: [ 'Report' ],
57
+ description: `upload a Report`,
58
+ operationId: 'upload-manual-report',
59
+ parameters: {},
60
+ requestBody: {
61
+ content: {
62
+ 'application/json': {
63
+ schema: j2s( uploadManualReportSchema ).swagger,
64
+ },
65
+ },
66
+ },
67
+ responses: {
68
+ 200: { description: 'Report Uploaded Successfully' },
69
+ 401: { description: 'Unauthorized User' },
70
+ 422: { description: 'Field Error' },
71
+ 500: { description: 'Server Error' },
72
+ 204: { description: 'Not Found' },
73
+ },
74
+ },
75
+ },
76
+
77
+ '/v3/report/get-report-list': {
78
+ get: {
79
+ tags: [ 'Report' ],
80
+ description: 'Get List of Reports',
81
+ operationId: 'get-report-list',
82
+ parameters: [
83
+ {
84
+ in: 'query',
85
+ name: 'fileDate',
86
+ scema: j2s( getReportListSchema ).swagger,
87
+ require: true,
88
+ },
89
+ {
90
+ in: 'query',
91
+ name: 'clientId',
92
+ scema: j2s( getReportListSchema ).swagger,
93
+ require: true,
94
+ },
95
+ ],
96
+ responses: {
97
+ 200: { description: 'Received successfully' },
98
+ 401: { description: 'Unauthorized User' },
99
+ 422: { description: 'Field Error' },
100
+ 500: { description: 'Server Error' },
101
+ 204: { description: 'Not Found' },
102
+ },
103
+ },
104
+ },
105
+
106
+ '/v3/report/download-report': {
107
+ get: {
108
+ tags: [ 'Report' ],
109
+ description: 'Download a Report',
110
+ operationId: 'download-report',
111
+ parameters: [
112
+ {
113
+ in: 'query',
114
+ name: 'filePath',
115
+ scema: j2s( downloadReportSchema ).swagger,
116
+ require: true,
117
+ },
118
+ ],
119
+ responses: {
120
+ 200: { description: 'Report has been Successfully' },
121
+ 401: { description: 'Unauthorized User' },
122
+ 422: { description: 'Field Error' },
123
+ 500: { description: 'Server Error' },
124
+ 204: { description: 'Not Found' },
125
+ },
126
+ },
127
+ },
128
+
129
+ '/v3/report/send-report': {
130
+ post: {
131
+ tags: [ 'Report' ],
132
+ description: `send report a client`,
133
+ operationId: 'send-report',
134
+ parameters: {},
135
+ requestBody: {
136
+ content: {
137
+ 'application/json': {
138
+ schema: j2s( sendReportSchema ).swagger,
139
+ },
140
+ },
141
+ },
142
+ responses: {
143
+ 200: { description: 'Report has been Sent Successfully' },
144
+ 401: { description: 'Unauthorized User' },
145
+ 422: { description: 'Field Error' },
146
+ 500: { description: 'Server Error' },
147
+ 204: { description: 'Not Found' },
148
+ },
149
+ },
150
+ },
151
+
54
152
  };
55
153
 
@@ -60,6 +60,7 @@ export const updateReportValid = {
60
60
  export const clientListTableSchema = joi.object( {
61
61
  fromDate: joi.string().required(),
62
62
  toDate: joi.string().required(),
63
+ clientId: joi.array().required(),
63
64
  limit: joi.number().optional(),
64
65
  offset: joi.number().optional(),
65
66
  searchValue: joi.string().optional(),
@@ -83,24 +84,42 @@ export const generateReportValid = {
83
84
 
84
85
  };
85
86
 
86
- export const sendReportSchema = joi.object( {
87
+ export const uploadManualReportSchema = joi.object( {
87
88
  fileDate: joi.string().required(),
88
89
  clientId: joi.string().required(),
90
+ fileName: joi.string().required(),
89
91
  } );
90
92
 
91
- export const sendReportValid = {
92
- body: sendReportSchema,
93
+ export const uploadManualReportValid = {
94
+ body: uploadManualReportSchema,
95
+ };
96
+
97
+ export const getReportListSchema = joi.object( {
98
+ fileDate: joi.string().required(),
99
+ clientId: joi.string().required(),
100
+ } );
101
+
102
+ export const getReportListValid = {
103
+ query: getReportListSchema,
93
104
 
94
105
  };
95
106
 
96
- export const uploadManualReportSchema = joi.object( {
107
+ export const downloadReportSchema = joi.object( {
108
+ filePath: joi.string().required(),
109
+ } );
110
+
111
+ export const downloadReportValid = {
112
+ query: downloadReportSchema,
113
+
114
+ };
115
+
116
+ export const sendReportSchema = joi.object( {
97
117
  fileDate: joi.string().required(),
98
118
  clientId: joi.string().required(),
99
- fileName: joi.string().required(),
100
119
  } );
101
120
 
102
- export const uploadManualReportValid = {
103
- body: uploadManualReportSchema,
121
+ export const sendReportValid = {
122
+ body: sendReportSchema,
104
123
 
105
124
  };
106
125
 
@@ -1,8 +1,9 @@
1
1
 
2
2
  import express from 'express';
3
3
  import { authorize, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
4
- import { addReportValid, clientListTableValid, generateReportValid, getReportValid, getSingleReportValid, sendReportValid, updateReportValid, uploadManualReportValid } from '../dtos/report.dtos.js';
5
- import { clientReportList, createReport, generateReport, getReport, getSingleReport, sendReport, updateBasePrice, updateReport, uploadManualReport } from '../controllers/report.controllers.js';
4
+ import { addReportValid, clientListTableValid, downloadReportValid, generateReportValid, getReportListValid, getReportValid, getSingleReportValid, sendReportValid, updateReportValid, uploadManualReportValid } from '../dtos/report.dtos.js';
5
+ import { clientReportList, createReport, dowloadReport, generateReport, getReport, getReportList, getSingleReport, sendReport, updateBasePrice, updateReport, uploadManualReport } from '../controllers/report.controllers.js';
6
+ import { isFileExist, isFolderExist, isReportEnable } from '../validations/report.validations.js';
6
7
 
7
8
  export const reportRouter = express.Router();
8
9
 
@@ -20,6 +21,8 @@ reportRouter.put( '/update-report/:id', isAllowedSessionHandler, authorize( { us
20
21
  { featureName: 'settings', name: 'configuration', permissions: [ 'isEdit' ] },
21
22
  ] } ), validate( updateReportValid ), updateReport );
22
23
 
24
+
25
+ // admin report's overview
23
26
  reportRouter.post( '/client-list-table', isAllowedSessionHandler,
24
27
  authorize( { userType: [ 'tango' ], access: [
25
28
  { featureName: 'settings', name: 'configuration', permissions: [ 'isView' ] },
@@ -30,19 +33,31 @@ reportRouter.post( '/generate-report', isAllowedSessionHandler,
30
33
  authorize( { userType: [ 'tango' ], access: [
31
34
  { featureName: 'settings', name: 'configuration', permissions: [ 'isEdit' ] },
32
35
  ] } ),
33
- validate( generateReportValid ), generateReport );
36
+ validate( generateReportValid ), isReportEnable, generateReport );
34
37
 
35
- reportRouter.post( '/send-report', isAllowedSessionHandler,
38
+ reportRouter.post( '/upload-manual-report', isAllowedSessionHandler,
36
39
  authorize( { userType: [ 'tango' ], access: [
37
40
  { featureName: 'settings', name: 'configuration', permissions: [ 'isEdit' ] },
38
41
  ] } ),
39
- validate( sendReportValid ), sendReport );
42
+ validate( uploadManualReportValid ), isReportEnable, uploadManualReport );
40
43
 
41
- reportRouter.post( '/upload-manual-report', isAllowedSessionHandler,
44
+ reportRouter.get( '/get-report-list', isAllowedSessionHandler,
45
+ authorize( { userType: [ 'tango' ], access: [
46
+ { featureName: 'settings', name: 'configuration', permissions: [ 'isView' ] },
47
+ ] } ),
48
+ validate( getReportListValid ), isReportEnable, isFolderExist, getReportList );
49
+
50
+ reportRouter.get( '/download-report', isAllowedSessionHandler,
51
+ authorize( { userType: [ 'tango' ], access: [
52
+ { featureName: 'settings', name: 'configuration', permissions: [ 'isEdit' ] },
53
+ ] } ),
54
+ validate( downloadReportValid ), isFileExist, dowloadReport );
55
+
56
+ reportRouter.post( '/send-report', isAllowedSessionHandler,
42
57
  authorize( { userType: [ 'tango' ], access: [
43
58
  { featureName: 'settings', name: 'configuration', permissions: [ 'isEdit' ] },
44
59
  ] } ),
45
- validate( uploadManualReportValid ), uploadManualReport );
60
+ validate( sendReportValid ), isReportEnable, sendReport );
46
61
 
47
62
  reportRouter.post( '/invoice', updateBasePrice );
48
63
 
@@ -37,3 +37,11 @@ export function reportUpdate( { _id, fileType, email, clientId } ) {
37
37
  },
38
38
  } );
39
39
  }
40
+
41
+ export function findOneReport( query ) {
42
+ return reportModel.findOne( query );
43
+ }
44
+
45
+ export function findReport( query, fields ) {
46
+ return reportModel.find( query, fields );
47
+ }
@@ -3,3 +3,7 @@ import userModel from 'tango-api-schema/schema/user.model.js';
3
3
  export function getUserNameEmailById( objectId ) {
4
4
  return userModel.findOne( { _id: objectId }, { userName: 1, email: 1, _id: 0 } );
5
5
  }
6
+
7
+ export async function findOneUser( query, fields ) {
8
+ return userModel.findOne( query, fields );
9
+ }
@@ -0,0 +1,56 @@
1
+ import { checkFileExist, logger } from 'tango-app-api-middleware';
2
+ import { findOneClient } from '../service/client.service.js';
3
+
4
+
5
+ export async function isReportEnable( req, res, next ) {
6
+ try {
7
+ const inputData = req.method !== 'GET'? req.body: req.query;
8
+ const getReportName = await findOneClient( { 'clientId': inputData.clientId, 'reportConfigs.report': true }, { reportName: '$reportConfigs.reportName', clientName: 1 } );
9
+ if ( !getReportName ) {
10
+ return res.sendError( 'reportName is not there in the client', 204 );
11
+ }
12
+ req.body.reportName = getReportName;
13
+ return next();
14
+ } catch ( error ) {
15
+ logger.error( { error: error, message: req.body, function: 'isReportEnable' } );
16
+ return res.sendError( error, 500 );
17
+ }
18
+ }
19
+
20
+ export async function isFolderExist( req, res, next ) {
21
+ try {
22
+ const inputData = req.query;
23
+ const fetchData = {
24
+ Bucket: appConfig.cloud.aws.bucket.reportBucket,
25
+ Key: `${inputData.fileDate}/${inputData.getReportName?.reportName}/`,
26
+ };
27
+ const isExist = await checkFileExist( fetchData );
28
+ if ( isExist ) {
29
+ return next();
30
+ } else {
31
+ return res.sendError( 'Folder does not Exists', 204 );
32
+ }
33
+ } catch ( error ) {
34
+ logger.error( { error: error, message: req.query, function: 'isFolderExist' } );
35
+ return res.sendError( error, 500 );
36
+ }
37
+ }
38
+
39
+ export async function isFileExist( req, res, next ) {
40
+ try {
41
+ const inputData = req.query;
42
+ const fetchData = {
43
+ Bucket: appConfig.cloud.aws.bucket.reportBucket,
44
+ Key: inputData.Key,
45
+ };
46
+ const isExist = await checkFileExist( fetchData );
47
+ if ( isExist ) {
48
+ return next();
49
+ } else {
50
+ return res.sendError( 'Folder does not Exists', 204 );
51
+ }
52
+ } catch ( error ) {
53
+ logger.error( { error: error, message: req.query, function: 'isFolderExist' } );
54
+ return res.sendError( error, 500 );
55
+ }
56
+ }