tango-app-api-report 3.0.3-dev → 3.0.4-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/package.json +1 -1
- package/src/controllers/report.controllers.js +220 -159
- package/src/docs/report.docs.js +99 -1
- package/src/dtos/report.dtos.js +26 -7
- package/src/routes/report.routes.js +22 -7
- package/src/service/report.service.js +8 -0
- package/src/service/user.service.js +4 -0
- package/src/validations/report.validations.js +56 -0
package/package.json
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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: { [
|
|
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
|
|
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
|
|
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:
|
|
188
|
-
client_name: getReportName
|
|
189
|
-
client_id: Number(
|
|
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
|
|
203
|
-
fileDate:
|
|
204
|
-
reportName: getReportName
|
|
205
|
-
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 (
|
|
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
|
|
226
|
+
export async function uploadManualReport( req, res ) {
|
|
219
227
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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> Please find attached Tango RetailEye report on customer footfall and shopping patterns for ${inputData.fileDate}.<br><br> Thanks <br> 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
|
-
|
|
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
|
|
package/src/docs/report.docs.js
CHANGED
|
@@ -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
|
|
package/src/dtos/report.dtos.js
CHANGED
|
@@ -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
|
|
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
|
|
92
|
-
body:
|
|
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
|
|
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
|
|
103
|
-
body:
|
|
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( '/
|
|
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(
|
|
42
|
+
validate( uploadManualReportValid ), isReportEnable, uploadManualReport );
|
|
40
43
|
|
|
41
|
-
reportRouter.
|
|
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(
|
|
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
|
+
}
|