tango-app-api-audit 1.0.43 → 1.0.44

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-audit",
3
- "version": "1.0.43",
3
+ "version": "1.0.44",
4
4
  "description": "audit & audit metrics apis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -24,7 +24,7 @@
24
24
  "mongodb": "^6.7.0",
25
25
  "nodemon": "^3.1.3",
26
26
  "swagger-ui-express": "^5.0.1",
27
- "tango-api-schema": "^2.0.144",
27
+ "tango-api-schema": "^2.0.146",
28
28
  "tango-app-api-middleware": "^3.1.28",
29
29
  "winston": "^3.13.0",
30
30
  "winston-daily-rotate-file": "^5.0.0"
@@ -210,7 +210,7 @@ export async function getAuditFile( req, res ) {
210
210
  address: '$storeProfile.address',
211
211
  };
212
212
  const storeDetails = await findOneStore( storeQuery, storeFields );
213
- return res.sendSuccess( {
213
+ res.sendSuccess( {
214
214
  result: result,
215
215
  storeId: storeDetails?.storeId,
216
216
  storeName: storeDetails?.storeName,
@@ -1,5 +1,5 @@
1
- import { download, fileUpload, getJsonFileData, getUTC, insertOpenSearchData, listFileByPath, sendMessageToQueue, signedUrl, sqsReceive } from 'tango-app-api-middleware';
2
- import { aggregateZoneUserAudit, createZoneUserAudit, findOneZoneUserAudit } from '../service/zoneUserAudit.service.js';
1
+ import { download, fileUpload, getJsonFileData, getUTC, insertOpenSearchData, listFileByPath, listFileWithoutLimit, sendMessageToQueue, signedUrl, sqsReceive } from 'tango-app-api-middleware';
2
+ import { aggregateZoneUserAudit, createZoneUserAudit, findOneZoneUserAudit, updateOneZoneUserAudit } from '../service/zoneUserAudit.service.js';
3
3
  import { logger } from 'tango-app-api-middleware';
4
4
  import { aggregateAssignZoneAudit } from '../service/assignZoneAudit.service.js';
5
5
  import { aggregateStoreZoneAudit, createStoreZoneAudit, findOneStoreZoneAudit, updateOneStoreZoneAudit } from '../service/storeZoneAudit.service.js';
@@ -9,11 +9,13 @@ import dayjs from 'dayjs';
9
9
  import { aggregateUserAudit, findOneUserAudit, updateOneUserAudit } from '../service/userAudit.service.js';
10
10
  import { aggregateAssignAudit, createAssignAudit } from '../service/assignAudit.service.js';
11
11
  import { createAuditLog, findOneAuditLog } from '../service/auditLog.service.js';
12
- import { mapCustomer, mapEmployee, mapJunk, splitB20000, splitE0, splitG20000 } from '../validation/audit.validation.js';
12
+ import { getZoneAuditImageData, mapCustomer, mapEmployee, mapJunk, splitB20000, splitE0, splitG20000, zipDownloadImage } from '../validation/audit.validation.js';
13
13
  import { aggregateClient, findClient, findOneClient } from '../service/client.service.js';
14
14
  import { aggregateAuditClientData } from '../service/auditClientData.service.js';
15
15
  import _ from 'lodash';
16
+ import mongoose from 'mongoose';
16
17
  import { listQueue } from 'tango-app-api-middleware/src/utils/aws/sqs.js';
18
+ import { getReauditImg } from './audit.controllers.js';
17
19
 
18
20
  export async function getZoneAuditFile( req, res ) {
19
21
  try {
@@ -88,21 +90,100 @@ export async function getZoneAuditFile( req, res ) {
88
90
  }
89
91
  break;
90
92
 
91
- // case 'drafted':
92
- // logger.info( 'userDetails drafted', { inputData } );
93
+ case 'drafted':
94
+ logger.info( 'userDetails drafted', { inputData } );
93
95
 
94
- // const log = await findOneAuditLog(
95
- // {
96
- // userId: userDetails[0].userId,
97
- // fileDate: userDetails[0].fileDate,
98
- // storeId: userDetails[0].storeId,
99
- // totalCount: userDetails[0].beforeCount,
96
+ const log = await findOneZoneUserAudit(
97
+ {
98
+ userId: userDetails[0].userId,
99
+ fileDate: userDetails[0].fileDate,
100
+ storeId: userDetails[0].storeId,
101
+ totalCount: userDetails[0].beforeCount,
102
+ moduleType: 'zone',
103
+ zoneName: userDetails[0].zoneName,
104
+ },
105
+ {},
106
+ { createdAt: -1 },
107
+ );
108
+
109
+ if ( !log ) {
110
+ await updateOneZoneUserAudit(
111
+ { _id: userDetails[0]._id },
112
+ { $set: { isDraft: false, auditStatus: 'skipped' } },
113
+ );
114
+ logger.info( 'zone audit update in drafted', {
115
+ _id: userDetails[0]._id,
116
+ isDraft: false,
117
+ auditStatus: 'skipped',
118
+ } );
119
+ return res.sendError( 'User saved data has been deleted', 204 );
120
+ }
121
+ const file = {
122
+ auditId: userDetails[0]._id,
123
+ store_id: userDetails[0].storeId,
124
+ file_date: userDetails[0].fileDate,
125
+ type: userDetails[0].auditType,
126
+ queueName: log.queueName,
127
+ userId: log.userId,
128
+ zoneName: userDetails[0].zoneName,
129
+ };
130
+ const result = {
131
+ junk: log.junk,
132
+ junk_count: log.junkCount,
133
+ employee: log.employee,
134
+ employee_count: log.employeeCount,
135
+ customer: log.customer,
136
+ customer_count: log.customerCount,
137
+ retag_image: log.retagImage,
138
+ retag_count: log.retagCount,
139
+ total_count: log.totalCount,
140
+ };
100
141
 
101
- // },
102
- // {},
103
- // { createdAt: -1 },
104
- // );
142
+ const userdata = await findOneUser( { _id: log.userId } );
143
+
144
+ if (
145
+ !inputData.nextId ||
146
+ inputData.nextId === '' ||
147
+ inputData.nextId == null
148
+ ) {
149
+ const logData = {
150
+ userId: log.userId,
151
+ userName: userdata.name,
152
+ logType: 'auditZone',
153
+ logSubType: 'auditZoneStart',
154
+ logData: {
155
+ file_date: userDetails[0].fileDate,
156
+ auditType: userDetails[0].auditType,
157
+ storeId: userDetails[0].storeId,
158
+ clientName: log.queueName,
159
+ auditId: userDetails[0]._id,
160
+ zoneName: userDetails[0].zoneName,
161
+ },
162
+ };
163
+ logger.info( { logData: logData } );
164
+ await insertOpenSearchData( openSearch.activityLog, logData );
165
+ }
166
+
167
+ const storeQuery = {
168
+ storeId: userDetails[0].storeId,
169
+ };
105
170
 
171
+ const storeFields = {
172
+ storeId: 1,
173
+ storeName: 1,
174
+ address: '$storeProfile.address',
175
+ };
176
+ const storeDetails = await findOneStore( storeQuery, storeFields );
177
+ res.sendSuccess( {
178
+ result: result,
179
+ storeId: storeDetails?.storeId,
180
+ storeName: storeDetails?.storeName,
181
+ address: storeDetails?.address || '',
182
+ count: log.totalCount,
183
+ file: file,
184
+ isDraft: userDetails[0].isDraft,
185
+ } );
186
+ break;
106
187
 
107
188
  default:
108
189
  msg = {
@@ -119,6 +200,104 @@ export async function getZoneAuditFile( req, res ) {
119
200
  * Reaudit pending
120
201
  */
121
202
 
203
+ if ( msg.audit_type === 'ReAudit' ) {
204
+ logger.info( 'Hit in zone user ReAudit', { inputData } );
205
+ let reauditInsert = {};
206
+ const [ filterData, auditImage ] = await Promise.all( [
207
+ getZoneFilterData( msg ),
208
+ getZoneAuditImage( msg ),
209
+ ] );
210
+ if ( filterData.statusCode == 404 || auditImage.statusCode == 404 ) {
211
+ return res.sendError( 'No Data found', 204 );
212
+ }
213
+ const reauditImg = await getReauditImg( filterData, auditImage );
214
+ if ( userDetails.length === 0 ) {
215
+ const [ day, month, year ] = msg.curr_date.split( '-' );
216
+ const temp = `${year}-${month}-${day}`;
217
+ let start = new Date( temp );
218
+ const userTimezoneOffset = start.getTimezoneOffset() * 60000;
219
+ start = new Date( start.getTime() - userTimezoneOffset );
220
+ start.setUTCHours( 0, 0, 0, 0 );
221
+ const record = {
222
+ userId: req.user._id,
223
+ storeId: msg.store_id,
224
+ clientId: msg.store_id.split( '-' )[0],
225
+ auditType: msg.audit_type || 'ReAudit',
226
+ fileDate: msg.curr_date,
227
+ queueName: inputData.queueName,
228
+ beforeCount: reauditImg.length,
229
+ zoneAuditStatus: 'inprogress',
230
+ zoneName: msg.zone_id,
231
+ fileDateISO: start,
232
+ timeSpent: 0,
233
+ startTime: new Date(),
234
+ moduleType: 'zone',
235
+ };
236
+ const storeRecord = {
237
+ userId: req.user._id,
238
+ storeId: msg.store_id,
239
+ clientId: msg.store_id.split( '-' )[0],
240
+ auditType: msg.audit_type || 'ReAudit',
241
+ fileDate: msg.curr_date,
242
+ queueName: inputData.queueName,
243
+ beforeCount: reauditImg.length,
244
+ status: 'inprogress',
245
+ fileDateISO: start,
246
+ timeSpent: 0,
247
+ zoneName: msg.zone_id,
248
+ };
249
+ reauditInsert = await createZoneUserAudit( record );
250
+ await createStoreZoneAudit( storeRecord );
251
+ } else {
252
+ reauditInsert = userDetails[0];
253
+ }
254
+ const userdata = await findOneUser( { _id: req.user._id } );
255
+ if ( inputData.nextId ) {
256
+ const logData = {
257
+ userId: req.user._id,
258
+ userName: userdata.name,
259
+ logType: 'auditZone',
260
+ logSubType: 'auditZoneStart',
261
+ logData: {
262
+ fileDate: msg.curr_date,
263
+ auditType: msg.audit_type,
264
+ storeId: msg.store_id,
265
+ clientName: inputData.queueName,
266
+ auditId: reauditInsert._id,
267
+ zoneName: msg.zone_id,
268
+ },
269
+ };
270
+ await insertOpenSearchData( openSearch.activityLog, logData );
271
+ }
272
+
273
+ const storeQuery = {
274
+ storeId: msg.store_id,
275
+ };
276
+ const storeFields = {
277
+ storeId: 1,
278
+ storeName: 1,
279
+ address: '$storeProfile.address',
280
+ };
281
+ const storeInfo = await findOneStore( storeQuery, storeFields );
282
+ return res.sendSuccess( {
283
+ result: reauditImg,
284
+ count: reauditImg.length,
285
+ storeId: storeInfo?.storeId,
286
+ storeName: storeInfo?.storeName,
287
+ address: storeInfo?.address || '',
288
+ file: {
289
+ store_id: msg.store_id,
290
+ file_date: msg.curr_date,
291
+ type: msg.audit_type || 'ReAudit',
292
+ queueName: inputData.queueName,
293
+ auditId: reauditInsert._id,
294
+ userId: reauditInsert.userId,
295
+ zoneName: msg.zone_id,
296
+ },
297
+ isDraft: reauditInsert.isDraft,
298
+ } );
299
+ }
300
+ // ////////////
122
301
 
123
302
  const storeId = msg.store_id;
124
303
  const fileDate = msg.curr_date;
@@ -233,6 +412,7 @@ export async function getZoneAuditFile( req, res ) {
233
412
  storeId: storeId,
234
413
  clientName: inputData.queueName,
235
414
  auditId: insertData._id,
415
+ zoneName: msg.zone_id,
236
416
  },
237
417
  };
238
418
  await insertOpenSearchData( openSearch.activityLog, logData );
@@ -964,6 +1144,7 @@ export async function storeMetrics( req, res ) {
964
1144
  storeName: '$store.storeName',
965
1145
  clientName: '',
966
1146
  clientId: 1,
1147
+ zoneName: 1,
967
1148
  userId: {
968
1149
  $arrayElemAt: [ '$userId', { $subtract: [ { $size: '$userId' }, 1 ] } ],
969
1150
  },
@@ -1042,6 +1223,7 @@ export async function storeMetrics( req, res ) {
1042
1223
  _id: 0,
1043
1224
  fileDate: 1,
1044
1225
  storeId: 1,
1226
+ zoneName: 1,
1045
1227
  storeName: '$stores.storeName',
1046
1228
  userName: '$users.userName',
1047
1229
  userEmail: '$users.userEmail',
@@ -1099,6 +1281,8 @@ export async function storeMetrics( req, res ) {
1099
1281
  { userName: { $regex: inputData.searchValue, $options: 'i' } },
1100
1282
  { status: { $regex: inputData.searchValue, $options: 'i' } },
1101
1283
  { auditType: { $regex: inputData.searchValue, $options: 'i' } },
1284
+ { zoneName: { $regex: inputData.searchValue, $options: 'i' } },
1285
+
1102
1286
  ],
1103
1287
  },
1104
1288
  } );
@@ -1137,6 +1321,7 @@ export async function storeMetrics( req, res ) {
1137
1321
  'Store Name': element.storeName,
1138
1322
  'Client Id': element.clientId,
1139
1323
  'Client Name': element.clientName,
1324
+ 'Zone Name': element.clientName,
1140
1325
  'User Name': element.userName,
1141
1326
  'User Email': element.userEmail,
1142
1327
  'Audit Type': element.auditType,
@@ -1156,6 +1341,152 @@ export async function storeMetrics( req, res ) {
1156
1341
  }
1157
1342
  }
1158
1343
 
1344
+ export async function zoneAuditImages( req, res ) {
1345
+ try {
1346
+ const inputData = req.query;
1347
+ let auditImageDownload = '';
1348
+ switch ( inputData.imageType ) {
1349
+ case 'BC':
1350
+ const auditImageBC = await getZoneAuditImageData( inputData );
1351
+ if ( auditImageBC?.errorCode ) {
1352
+ const error = auditImageBC?.errorMsg;
1353
+ const code = auditImageBC?.errorCode;
1354
+ return res.sendError( { error: error }, code );
1355
+ }
1356
+
1357
+ if ( inputData.export==true ) {
1358
+ auditImageDownload= await zipDownloadImage( auditImageBC );
1359
+ // Set response headers for the zip file
1360
+ res.set( 'Content-Type', 'application/zip' );
1361
+ res.set( 'Content-Disposition', `attachment; filename=${inputData.storeId}_${inputData.fileDate}_${inputData.imageType}_${inputData.zoneName}.zip` );
1362
+
1363
+ // Send the zip file as the API response
1364
+ return res.send( auditImageDownload );
1365
+ }
1366
+ res.sendSuccess( { result: auditImageBC } );
1367
+
1368
+ break;
1369
+
1370
+ case 'AC':
1371
+
1372
+ const [ filterData, auditImageAC ] = await Promise.all( [ getAuditFilterData( inputData ), getAuditImageData( inputData ) ] );
1373
+
1374
+ if ( filterData?.errorCode || auditImageAC?.errorCode ) {
1375
+ const error = filterData?.errorMsg || auditImageAC.errorMsg;
1376
+ const code = filterData?.errorCode || auditImageAC.errorCode;
1377
+ return res.sendError( { error: error }, code );
1378
+ }
1379
+
1380
+ const reauditImg = await getReauditImg( filterData, auditImageAC );
1381
+
1382
+ logger.info( { filterData: filterData } );
1383
+ logger.info( { auditImageAC: auditImageAC } );
1384
+ logger.info( { reauditImg: reauditImg } );
1385
+ if ( inputData.export==true ) {
1386
+ auditImageDownload= await zipDownloadImage( reauditImg );
1387
+ // Set response headers for the zip file
1388
+ res.set( 'Content-Type', 'application/zip' );
1389
+ res.set( 'Content-Disposition', `attachment; filename=${inputData.storeId}_${inputData.fileDate}_${inputData.imageType}.zip` );
1390
+
1391
+ // Send the zip file as the API response
1392
+ return res.send( auditImageDownload );
1393
+ }
1394
+ res.sendSuccess( { result: reauditImg } );
1395
+ break;
1396
+ default:
1397
+ res.sendError( 'No Data Found', 204 );
1398
+ break;
1399
+ }
1400
+
1401
+
1402
+ // return res.sendSuccess( { result: inputData } );
1403
+ } catch ( error ) {
1404
+ const err = error.message || 'Internal Server Error';
1405
+ logger.info( { error: error, message: req.body, function: 'beforeCountImages' } );
1406
+ return res.sendError( err, 500 );
1407
+ }
1408
+ }
1409
+
1410
+
1411
+ export async function getZoneFilterData( msg ) {
1412
+ try {
1413
+ const bucket = JSON.parse( process.env.BUCKET );
1414
+ const params = {
1415
+ Bucket: `${bucket.auditOutput}`,
1416
+ Key: `${msg.store_id}/${inputData.zoneName}/${msg.curr_date}/${bucketName.masterJsonFile}`,
1417
+ };
1418
+ const mappingFile = await getJsonFileData( params );
1419
+ if ( mappingFile.statusCode ) {
1420
+ return mappingFile;
1421
+ } else {
1422
+ const mappingData = await JSON.parse( mappingFile.toString( 'utf-8' ) );
1423
+ const filterData = await mappingData.person_data.filter(
1424
+ ( item ) =>
1425
+ item.temp_ids < 20000 &&
1426
+ item.temp_ids > 0 &&
1427
+ item.person_status === '',
1428
+ );
1429
+ const finalResult = await filterData.map( ( i ) => {
1430
+ return { ...i, img: i.index.concat( '_', i.temp_ids ) };
1431
+ } );
1432
+ return finalResult;
1433
+ }
1434
+ } catch ( error ) {
1435
+ logger.error( {
1436
+ error: error,
1437
+ type: 'MAPPING JSON getFilterData',
1438
+ function: 'getZoneFilterData',
1439
+ } );
1440
+ return error;
1441
+ }
1442
+ }
1443
+
1444
+ export async function getZoneAuditImage( msg ) {
1445
+ try {
1446
+ const bucket = JSON.parse( process.env.BUCKET );
1447
+ const storeId = msg.store_id;
1448
+ const fileDate = msg.curr_date;
1449
+ const files = [];
1450
+ const fetchData = {};
1451
+ fetchData.Bucket = `${bucket.auditInput}`;
1452
+ fetchData.filePath = `${fileDate}/${storeId}/${msg.zone_id}/`;
1453
+ const folderPath = await listFileWithoutLimit( fetchData );
1454
+ if ( folderPath.statusCode == 404 ) {
1455
+ return folderPath;
1456
+ }
1457
+ const auditImages = folderPath;
1458
+ if ( auditImages && auditImages?.length > 0 ) {
1459
+ for ( let i = 0; i < auditImages.length; i++ ) {
1460
+ const img = auditImages[i].Key.split( '/' );
1461
+ const image = img[2].split( '.' );
1462
+ const indexes = image[0].split( '_' );
1463
+ const params = {
1464
+ file_path: auditImages[i].Key,
1465
+ Bucket: fetchData.Bucket,
1466
+ };
1467
+ const data = await signedUrl( params );
1468
+ const mapimg = {
1469
+ img_path: data,
1470
+ img_name: indexes[1],
1471
+ img_id: image[0],
1472
+ };
1473
+ files.push( {
1474
+ img_path: data,
1475
+ img_name: indexes[1],
1476
+ img_id: image[0],
1477
+ selected: false,
1478
+ dropped: false,
1479
+ count: 1,
1480
+ mappedid: [ mapimg ],
1481
+ } );
1482
+ }
1483
+ return files;
1484
+ }
1485
+ } catch ( error ) {
1486
+ logger.error( { error: error, type: 'AWS BUCKET --getAuditImage' } );
1487
+ return error;
1488
+ }
1489
+ }
1159
1490
  export async function clientMetrics( req, res ) {
1160
1491
  try {
1161
1492
  const inputData = req.body;
@@ -1348,12 +1679,13 @@ export async function reTrigger( req, res ) {
1348
1679
  storeId: inputData.storeId,
1349
1680
  fileDate: inputData.fileDate,
1350
1681
  };
1351
- const getQueueName = await findOneClient( { clientId: req.audit.clientId }, { 'auditConfigs.zoneQueueName': 1 } );
1352
-
1682
+ const getQueueName = await findOneClient( { clientId: req.audit.clientId }, { 'auditConfigs': 1 } );
1683
+ logger.info( { queueName: getQueueName.auditConfigs.zoneQueueName } );
1353
1684
  if ( !getQueueName || getQueueName?.auditConfigs?.zoneQueueName == '' ) {
1354
1685
  return res.sendError( 'queueName does not create', 400 );
1355
1686
  }
1356
1687
  const queueName = getQueueName?.auditConfigs?.zoneQueueName;
1688
+
1357
1689
  logger.info( { queueName: queueName } );
1358
1690
  switch ( inputData.triggerType ) {
1359
1691
  case 'queue':
@@ -1,5 +1,5 @@
1
1
  import j2s from 'joi-to-swagger';
2
- import { clientMetricsSchema, getDraftedDataSchema, getFileSchema, reTriggerValidSchema, saveDraftSchema, saveSchema, storeMetricsSchema, workSpaceSchema } from '../dtos/zoneAudit.dtos.js';
2
+ import { clientMetricsSchema, getDraftedDataSchema, getFileSchema, saveDraftSchema, saveSchema, storeMetricsSchema, workSpaceSchema, zoneAuditImageValidSchema, reTriggerValidSchema } from '../dtos/zoneAudit.dtos.js';
3
3
 
4
4
  export const zoneAuditDocs = {
5
5
  '/v3/zone-audit/get-file': {
@@ -179,26 +179,66 @@ export const zoneAuditDocs = {
179
179
  },
180
180
  },
181
181
 
182
- '/v3/zone-audit/metrics/client-metrics': {
183
- post: {
184
- tags: [ 'Zone Audit Metrics' ],
185
- description: `Get list of client wise details with date range`,
186
- operationId: 'metrics/client-metrics',
187
- parameters: {},
188
- requestBody: {
189
- content: {
190
- 'application/json': {
191
- schema: j2s( clientMetricsSchema ).swagger,
182
+ '/v3/zone-audit/metrics/audit-images': {
183
+ get: {
184
+ 'tags': [ 'Zone Audit Metrics' ],
185
+ 'description': `View and Download audit images`,
186
+ 'operationId': 'zone audit-images',
187
+ 'parameters': [
188
+ {
189
+ in: 'query',
190
+ name: 'fileDate',
191
+ scema: j2s( zoneAuditImageValidSchema ).swagger,
192
+ require: true,
193
+ },
194
+ {
195
+ in: 'query',
196
+ name: 'storeId',
197
+ scema: j2s( zoneAuditImageValidSchema ).swagger,
198
+ require: true,
199
+ },
200
+ {
201
+ in: 'query',
202
+ name: 'imageType',
203
+ scema: j2s( zoneAuditImageValidSchema ).swagger,
204
+ require: true,
205
+ },
206
+ {
207
+ in: 'query',
208
+ name: 'export',
209
+ scema: j2s( zoneAuditImageValidSchema ).swagger,
210
+ require: true,
211
+ },
212
+ {
213
+ in: 'query',
214
+ name: 'zoneName',
215
+ scema: j2s( zoneAuditImageValidSchema ).swagger,
216
+ require: true,
217
+ },
218
+ ],
219
+
220
+ '/v3/zone-audit/metrics/client-metrics': {
221
+ post: {
222
+ tags: [ 'Zone Audit Metrics' ],
223
+ description: `Get list of client wise details with date range`,
224
+ operationId: 'metrics/client-metrics',
225
+ parameters: {},
226
+ requestBody: {
227
+ content: {
228
+ 'application/json': {
229
+ schema: j2s( clientMetricsSchema ).swagger,
230
+ },
231
+ },
232
+ },
233
+ responses: {
234
+ 200: { description: 'Successful' },
235
+ 401: { description: 'Unauthorized User' },
236
+ 422: { description: 'Field Error' },
237
+ 500: { description: 'Server Error' },
238
+ 204: { description: 'Not Found' },
192
239
  },
193
240
  },
194
241
  },
195
- responses: {
196
- 200: { description: 'Successful' },
197
- 401: { description: 'Unauthorized User' },
198
- 422: { description: 'Field Error' },
199
- 500: { description: 'Server Error' },
200
- 204: { description: 'Not Found' },
201
- },
202
242
  },
203
243
  },
204
244
 
@@ -108,6 +108,19 @@ export const storeMetricsValid = {
108
108
  body: storeMetricsSchema,
109
109
  };
110
110
 
111
+ export const zoneAuditImageValidSchema = joi.object(
112
+ {
113
+ fileDate: joi.string().required(),
114
+ storeId: joi.string().required(),
115
+ imageType: joi.string().required(),
116
+ export: joi.boolean().required(),
117
+ zoneName: joi.string().required(),
118
+ },
119
+ );
120
+
121
+ export const zoneAuditImageValid = {
122
+ query: zoneAuditImageValidSchema,
123
+ };
111
124
  export const clientMetricsSchema = joi.object(
112
125
  {
113
126
  fromDate: joi.string().required(),
@@ -1,9 +1,9 @@
1
1
  import { Router } from 'express';
2
- import { clientMetricsValid, getDraftedDataValid, getFileValid, reTriggerValid, saveDraftValid, saveValid, storeMetricsValid, workSpaceValid } from '../dtos/zoneAudit.dtos.js';
3
- import { isExistsQueue, validateUserAudit } from '../validation/audit.validation.js';
2
+ import { clientMetricsValid, getDraftedDataValid, getFileValid, reTriggerValid, saveDraftValid, saveValid, workSpaceValid, zoneAuditImageValid } from '../dtos/zoneAudit.dtos.js';
3
+ import { isAuditDocumentExist, isAuditInputFolderExist, isExistsQueue, isZoneAuditInputFolderExist, validateUserAudit } from '../validation/audit.validation.js';
4
4
  import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
5
- import { clientMetrics, getDraftedData, getZoneAuditFile, reTrigger, save, saveDraft, storeMetrics, workSpace } from '../controllers/zoneAudit.controller.js';
6
- import { isAuditDocumentExist, isAuditInputFolderExist } from '../validation/zoneAudit.validation.js';
5
+ import { clientMetrics, getDraftedData, getZoneAuditFile, reTrigger, save, saveDraft, storeMetrics, workSpace, zoneAuditImages } from '../controllers/zoneAudit.controller.js';
6
+ import { storeMetricsValid } from '../dtos/auditMetrics.dtos.js';
7
7
 
8
8
  export const zoneAuditRouter=Router();
9
9
 
@@ -17,5 +17,6 @@ zoneAuditRouter.get( '/work-space', isAllowedSessionHandler, validate( workSpace
17
17
  // metrics
18
18
 
19
19
  zoneAuditRouter.post( '/metrics/store-metrics', isAllowedSessionHandler, validate( storeMetricsValid ), storeMetrics );
20
+ zoneAuditRouter.get( '/metrics/audit-images', isAllowedSessionHandler, validate( zoneAuditImageValid ), isZoneAuditInputFolderExist, zoneAuditImages );
20
21
  zoneAuditRouter.post( '/metrics/client-metrics', isAllowedSessionHandler, validate( clientMetricsValid ), clientMetrics );
21
22
  zoneAuditRouter.post( '/metrics/re-trigger', isAllowedSessionHandler, validate( reTriggerValid ), isAuditDocumentExist, isAuditInputFolderExist, reTrigger );
@@ -329,3 +329,90 @@ export async function getAuditFilterData( data ) {
329
329
  }
330
330
  }
331
331
 
332
+ // zone
333
+ export async function isZoneAuditInputFolderExist( req, res, next ) {
334
+ try {
335
+ const bucket = JSON.parse( process.env.BUCKET );
336
+ const inputData = req.method === 'POST' ? req.body : req.query;
337
+ const params={
338
+ Bucket: bucket.auditInput,
339
+ Key: `${inputData.fileDate}/${inputData.storeId}/${inputData.zoneName}`,
340
+ };
341
+ const isExist = await checkFileExist( params );
342
+ if ( isExist ) {
343
+ next();
344
+ } else {
345
+ return res.sendError( `Audit Input folder not available : ${inputData.fileDate}/${inputData.storeId}`, 400 );
346
+ }
347
+ } catch ( error ) {
348
+ const err = error.message || 'Internal Server Error';
349
+ logger.error( { error: error, message: req.query, function: 'isAuidtInputFolderExist' } );
350
+ return res.sendError( err, 500 );
351
+ }
352
+ }
353
+
354
+ export async function getZoneAuditImageData( data ) {
355
+ try {
356
+ const bucket = JSON.parse( process.env.BUCKET );
357
+ const storeId = data.storeId;
358
+ const fileDate = data.fileDate;
359
+ const files = [];
360
+ const fetchData = {
361
+ Bucket: `${bucket.auditInput}`,
362
+ filePath: `${fileDate}/${storeId}/${data.zoneName}/`,
363
+ };
364
+
365
+ const folderPath = await listFileWithoutLimit( fetchData );
366
+ if ( folderPath.statusCode == 404 ) {
367
+ return folderPath;
368
+ }
369
+ const auditImages = folderPath;
370
+
371
+ if ( data.export==false ) {
372
+ if ( auditImages && auditImages?.length > 0 ) {
373
+ for ( let i = 0; i < auditImages.length; i++ ) {
374
+ const img = auditImages[i].Key.split( '/' );
375
+ const image = img[3].split( '.' );
376
+ const indexes = image[0].split( '_' );
377
+ const params = {
378
+ file_path: auditImages[i].Key,
379
+ Bucket: fetchData.Bucket,
380
+ };
381
+ const data = await signedUrl( params );
382
+ files.push( {
383
+ imgPath: data,
384
+ imgName: indexes[1],
385
+ imgId: image[0],
386
+ img_name: indexes[1],
387
+ // imgFile: auditImages[i],
388
+ } );
389
+ }
390
+ return files;
391
+ }
392
+ } else {
393
+ if ( auditImages && auditImages?.length > 0 ) {
394
+ for ( let i = 0; i < auditImages.length; i++ ) {
395
+ const img = auditImages[i].Key.split( '/' );
396
+ const image = img[3].split( '.' );
397
+ const indexes = image[0].split( '_' );
398
+ const params = {
399
+ file_path: auditImages[i].Key,
400
+ Bucket: fetchData.Bucket,
401
+ };
402
+ const data = await signedUrl( params );
403
+ files.push( {
404
+ imgPath: data,
405
+ imgName: indexes[1],
406
+ imgId: image[0],
407
+ imgFile: auditImages[i],
408
+ img_name: indexes[1],
409
+ } );
410
+ }
411
+ return files;
412
+ }
413
+ }
414
+ } catch ( error ) {
415
+ logger.error( { error: error, type: 'getAuditImageData' } );
416
+ return error;
417
+ }
418
+ }