tango-app-api-audit 1.0.42 → 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 +2 -2
- package/src/controllers/audit.controllers.js +1 -1
- package/src/controllers/auditMetrics.controllers.js +22 -14
- package/src/controllers/zoneAudit.controller.js +494 -17
- package/src/docs/zoneAudit.docs.js +68 -5
- package/src/dtos/auditMetrics.dtos.js +3 -2
- package/src/dtos/zoneAudit.dtos.js +30 -0
- package/src/routes/zone.routes.js +6 -3
- package/src/validation/audit.validation.js +87 -0
- package/src/validation/zoneAudit.validation.js +45 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-audit",
|
|
3
|
-
"version": "1.0.
|
|
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.
|
|
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
|
-
|
|
213
|
+
res.sendSuccess( {
|
|
214
214
|
result: result,
|
|
215
215
|
storeId: storeDetails?.storeId,
|
|
216
216
|
storeName: storeDetails?.storeName,
|
|
@@ -10,12 +10,13 @@ import { countDocumentsStore } from '../service/store.service.js';
|
|
|
10
10
|
import { findOneClient } from '../service/client.service.js';
|
|
11
11
|
import { getAuditFilterData, getAuditImageData, zipDownloadImage } from '../validation/audit.validation.js';
|
|
12
12
|
import { getReauditImg } from './audit.controllers.js';
|
|
13
|
+
import { aggregateStoreZoneAudit } from '../service/storeZoneAudit.service.js';
|
|
13
14
|
// import { listQueue } from 'tango-app-api-middleware/src/utils/aws/sqs.js';
|
|
14
15
|
|
|
15
16
|
export async function userAuditHistory( req, res ) {
|
|
16
17
|
try {
|
|
17
18
|
const inputData = req.body;
|
|
18
|
-
const userId = inputData.userId
|
|
19
|
+
const userId = inputData.userId? new mongoose.Types.ObjectId( inputData.userId ) : req.user._id;
|
|
19
20
|
const limit = inputData.limit || 10;
|
|
20
21
|
const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
|
|
21
22
|
const dateRange = await getUTC( new Date( inputData.fromDate ), new Date( inputData.toDate ) );
|
|
@@ -1174,12 +1175,15 @@ export async function overViewTable( req, res ) {
|
|
|
1174
1175
|
{ fileDateISO: { $gte: dateRange.start } },
|
|
1175
1176
|
{ fileDateISO: { $lte: dateRange.end } },
|
|
1176
1177
|
{ auditStatus: { $in: inputData.filterByStatus } },
|
|
1177
|
-
{ auditType: { $in: inputData.
|
|
1178
|
+
{ auditType: { $in: inputData.filterByType } },
|
|
1178
1179
|
|
|
1179
1180
|
];
|
|
1180
1181
|
if ( inputData.clientId.length > 0 ) {
|
|
1181
1182
|
filters.push( { clientId: { $in: inputData.clientId } } );
|
|
1182
1183
|
}
|
|
1184
|
+
if ( inputData.filterByAuditType.length > 0 ) {
|
|
1185
|
+
filters.push( { moduleType: { $in: inputData.filterByAuditType } } );
|
|
1186
|
+
}
|
|
1183
1187
|
|
|
1184
1188
|
const query =[
|
|
1185
1189
|
{
|
|
@@ -1198,8 +1202,6 @@ export async function overViewTable( req, res ) {
|
|
|
1198
1202
|
auditType: 1,
|
|
1199
1203
|
auditStatus: 1,
|
|
1200
1204
|
userId: 1,
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
1205
|
},
|
|
1204
1206
|
},
|
|
1205
1207
|
{
|
|
@@ -1237,8 +1239,8 @@ export async function overViewTable( req, res ) {
|
|
|
1237
1239
|
startTime: 1,
|
|
1238
1240
|
auditType: 1,
|
|
1239
1241
|
auditStatus: 1,
|
|
1240
|
-
userName: '$
|
|
1241
|
-
userEmail: '$
|
|
1242
|
+
userName: '$user.userName',
|
|
1243
|
+
userEmail: '$user.userEmail',
|
|
1242
1244
|
|
|
1243
1245
|
},
|
|
1244
1246
|
},
|
|
@@ -1247,8 +1249,12 @@ export async function overViewTable( req, res ) {
|
|
|
1247
1249
|
query.push( {
|
|
1248
1250
|
$match: {
|
|
1249
1251
|
$or: [
|
|
1250
|
-
{
|
|
1251
|
-
{
|
|
1252
|
+
{ storeId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1253
|
+
{ fileDate: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1254
|
+
{ auditType: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1255
|
+
{ auditStatus: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1256
|
+
{ userName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1257
|
+
{ userEmail: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1252
1258
|
],
|
|
1253
1259
|
|
|
1254
1260
|
},
|
|
@@ -1284,12 +1290,13 @@ export async function overViewTable( req, res ) {
|
|
|
1284
1290
|
exportdata.push( {
|
|
1285
1291
|
'Store Id': element.storeId,
|
|
1286
1292
|
'File Date': element.fileDtae,
|
|
1287
|
-
'
|
|
1293
|
+
'Type': element.audittype,
|
|
1288
1294
|
'Before Count': element.beforeCount,
|
|
1289
1295
|
'Start Time': element.startTime,
|
|
1290
1296
|
'User Name': element.userName,
|
|
1291
1297
|
'User Email': element.userEmail,
|
|
1292
1298
|
'Status': element.auditStatus,
|
|
1299
|
+
'Audit Type': element.moduleType,
|
|
1293
1300
|
} );
|
|
1294
1301
|
} );
|
|
1295
1302
|
await download( exportdata, res );
|
|
@@ -1398,7 +1405,7 @@ export async function overAllAuditSummary( req, res ) {
|
|
|
1398
1405
|
},
|
|
1399
1406
|
},
|
|
1400
1407
|
];
|
|
1401
|
-
const storeAudit = await aggregateStoreAudit( storeAuditQuery );
|
|
1408
|
+
const storeAudit = inputData.moduleType == 'zone'?await aggregateStoreZoneAudit( storeAuditQuery ) : await aggregateStoreAudit( storeAuditQuery );
|
|
1402
1409
|
if ( storeAudit.length > 0 ) {
|
|
1403
1410
|
temp.inprogreseStores= storeAudit[0].inprogreseStores;
|
|
1404
1411
|
temp.completedStores = storeAudit[0].completedStores;
|
|
@@ -1440,7 +1447,7 @@ export async function reTrigger( req, res ) {
|
|
|
1440
1447
|
const msg = {
|
|
1441
1448
|
store_id: inputData.storeId,
|
|
1442
1449
|
curr_date: inputData.fileDate,
|
|
1443
|
-
audit_type: inputData.
|
|
1450
|
+
audit_type: inputData.type,
|
|
1444
1451
|
total_count: inputData.totalCount,
|
|
1445
1452
|
};
|
|
1446
1453
|
|
|
@@ -1482,7 +1489,7 @@ export async function reTrigger( req, res ) {
|
|
|
1482
1489
|
beforeCount: inputData.totalCount,
|
|
1483
1490
|
afterCount: '',
|
|
1484
1491
|
fileDate: inputData.fileDate,
|
|
1485
|
-
auditType: inputData.
|
|
1492
|
+
auditType: inputData.type,
|
|
1486
1493
|
storeId: inputData.storeId,
|
|
1487
1494
|
queueName: queueName,
|
|
1488
1495
|
message: inputData.comments,
|
|
@@ -1500,8 +1507,9 @@ export async function reTrigger( req, res ) {
|
|
|
1500
1507
|
storeId: inputData.storeId,
|
|
1501
1508
|
clientId: req.audit.clientId,
|
|
1502
1509
|
fileDate: inputData.fileDate,
|
|
1510
|
+
moduleType: 'traffic',
|
|
1503
1511
|
fileDateISO: dayjs( inputData.fileDate, 'DD-MM-YYYY' ).format(),
|
|
1504
|
-
auditType: inputData.
|
|
1512
|
+
auditType: inputData.type,
|
|
1505
1513
|
fileCount: inputData.beforeCount,
|
|
1506
1514
|
queueName: queueName,
|
|
1507
1515
|
userId: inputData.userId,
|
|
@@ -1537,7 +1545,7 @@ export async function reTrigger( req, res ) {
|
|
|
1537
1545
|
beforeCount: inputData.totalCount,
|
|
1538
1546
|
afterCount: '',
|
|
1539
1547
|
fileDate: inputData.fileDate,
|
|
1540
|
-
auditType: inputData.
|
|
1548
|
+
auditType: inputData.type,
|
|
1541
1549
|
storeId: inputData.storeId,
|
|
1542
1550
|
queueName: queueName,
|
|
1543
1551
|
message: inputData.comments,
|
|
@@ -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';
|
|
@@ -7,13 +7,15 @@ import { findOneUser } from '../service/user.service.js';
|
|
|
7
7
|
import { findOneStore } from '../service/store.service.js';
|
|
8
8
|
import dayjs from 'dayjs';
|
|
9
9
|
import { aggregateUserAudit, findOneUserAudit, updateOneUserAudit } from '../service/userAudit.service.js';
|
|
10
|
-
import { aggregateAssignAudit } from '../service/assignAudit.service.js';
|
|
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';
|
|
13
|
-
import { aggregateClient, findClient } from '../service/client.service.js';
|
|
12
|
+
import { getZoneAuditImageData, mapCustomer, mapEmployee, mapJunk, splitB20000, splitE0, splitG20000, zipDownloadImage } from '../validation/audit.validation.js';
|
|
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
|
-
|
|
92
|
-
|
|
93
|
+
case 'drafted':
|
|
94
|
+
logger.info( 'userDetails drafted', { inputData } );
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
+
};
|
|
141
|
+
|
|
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
|
+
}
|
|
100
166
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// );
|
|
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;
|
|
@@ -1338,3 +1669,149 @@ export async function clientMetrics( req, res ) {
|
|
|
1338
1669
|
return res.sendError( err, 500 );
|
|
1339
1670
|
}
|
|
1340
1671
|
}
|
|
1672
|
+
|
|
1673
|
+
export async function reTrigger( req, res ) {
|
|
1674
|
+
try {
|
|
1675
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1676
|
+
const inputData = req.body;
|
|
1677
|
+
const sqs = JSON.parse( process.env.SQS );
|
|
1678
|
+
const query ={
|
|
1679
|
+
storeId: inputData.storeId,
|
|
1680
|
+
fileDate: inputData.fileDate,
|
|
1681
|
+
};
|
|
1682
|
+
const getQueueName = await findOneClient( { clientId: req.audit.clientId }, { 'auditConfigs': 1 } );
|
|
1683
|
+
logger.info( { queueName: getQueueName.auditConfigs.zoneQueueName } );
|
|
1684
|
+
if ( !getQueueName || getQueueName?.auditConfigs?.zoneQueueName == '' ) {
|
|
1685
|
+
return res.sendError( 'queueName does not create', 400 );
|
|
1686
|
+
}
|
|
1687
|
+
const queueName = getQueueName?.auditConfigs?.zoneQueueName;
|
|
1688
|
+
|
|
1689
|
+
logger.info( { queueName: queueName } );
|
|
1690
|
+
switch ( inputData.triggerType ) {
|
|
1691
|
+
case 'queue':
|
|
1692
|
+
const msg = {
|
|
1693
|
+
store_id: inputData.storeId,
|
|
1694
|
+
curr_date: inputData.fileDate,
|
|
1695
|
+
audit_type: inputData.type,
|
|
1696
|
+
total_count: inputData.totalCount,
|
|
1697
|
+
zone_id: inputData.zoneName,
|
|
1698
|
+
};
|
|
1699
|
+
|
|
1700
|
+
const sqsProduceQueue = {
|
|
1701
|
+
QueueUrl: `${sqs.url}${queueName}`,
|
|
1702
|
+
MessageBody: JSON.stringify( msg ),
|
|
1703
|
+
};
|
|
1704
|
+
const sqsQueue = await sendMessageToQueue( sqsProduceQueue.QueueUrl, sqsProduceQueue.MessageBody );
|
|
1705
|
+
if ( sqsQueue?.errorCode ) {
|
|
1706
|
+
const error = sqsQueue?.errorMsg;
|
|
1707
|
+
const code = sqsQueue?.errorCode;
|
|
1708
|
+
return res.sendError( error, code );
|
|
1709
|
+
} else {
|
|
1710
|
+
if ( req.audit.status !== 'completed' ) {
|
|
1711
|
+
const userRecord ={
|
|
1712
|
+
auditStatus: 'skipped',
|
|
1713
|
+
isDraft: false,
|
|
1714
|
+
};
|
|
1715
|
+
const query ={
|
|
1716
|
+
storeId: inputData.storeId,
|
|
1717
|
+
fileDate: inputData.fileDate,
|
|
1718
|
+
zoneName: inputData.zoneName,
|
|
1719
|
+
auditStatus: req.audit.status,
|
|
1720
|
+
|
|
1721
|
+
};
|
|
1722
|
+
await updateOneUserAudit( query, userRecord );
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
const storeRecord ={
|
|
1726
|
+
status: req.audit.status !== 'completed' ? 'skipped': 'not_assign',
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1729
|
+
await updateOneStoreZoneAudit( query, storeRecord );
|
|
1730
|
+
const logData = {
|
|
1731
|
+
userId: req.user._id,
|
|
1732
|
+
userName: req.user.userName,
|
|
1733
|
+
logType: 'zoneAudit',
|
|
1734
|
+
logSubType: 'reTrigger',
|
|
1735
|
+
logData: {
|
|
1736
|
+
beforeCount: inputData.totalCount,
|
|
1737
|
+
afterCount: '',
|
|
1738
|
+
fileDate: inputData.fileDate,
|
|
1739
|
+
auditType: inputData.type,
|
|
1740
|
+
storeId: inputData.storeId,
|
|
1741
|
+
zoneName: inputData.zoneName,
|
|
1742
|
+
queueName: queueName,
|
|
1743
|
+
message: inputData.comments,
|
|
1744
|
+
triggerBy: req.user.userName,
|
|
1745
|
+
triggerId: req.user._id,
|
|
1746
|
+
triggerType: inputData.triggerType,
|
|
1747
|
+
},
|
|
1748
|
+
};
|
|
1749
|
+
await insertOpenSearchData( openSearch.activityLog, logData );
|
|
1750
|
+
}
|
|
1751
|
+
break;
|
|
1752
|
+
case 'user':
|
|
1753
|
+
const assignUser = await findOneUser( { _id: new mongoose.Types.ObjectId( inputData.userId ) } );
|
|
1754
|
+
const assignUserRecord = {
|
|
1755
|
+
storeId: inputData.storeId,
|
|
1756
|
+
clientId: req.audit.clientId,
|
|
1757
|
+
fileDate: inputData.fileDate,
|
|
1758
|
+
zoneName: inputData.zoneName,
|
|
1759
|
+
fileDateISO: dayjs( inputData.fileDate, 'DD-MM-YYYY' ).format(),
|
|
1760
|
+
auditType: inputData.type,
|
|
1761
|
+
moduleType: 'zone',
|
|
1762
|
+
fileCount: inputData.beforeCount,
|
|
1763
|
+
queueName: queueName,
|
|
1764
|
+
userId: inputData.userId,
|
|
1765
|
+
userName: assignUser.userName,
|
|
1766
|
+
};
|
|
1767
|
+
await createAssignAudit( assignUserRecord );
|
|
1768
|
+
|
|
1769
|
+
if ( req.audit.status !== 'completed' ) {
|
|
1770
|
+
const userRecord ={
|
|
1771
|
+
auditStatus: 'skipped',
|
|
1772
|
+
isDraft: false,
|
|
1773
|
+
};
|
|
1774
|
+
const query ={
|
|
1775
|
+
storeId: inputData.storeId,
|
|
1776
|
+
fileDate: inputData.fileDate,
|
|
1777
|
+
zoneName: inputData.zoneName,
|
|
1778
|
+
auditStatus: req.audit.status,
|
|
1779
|
+
|
|
1780
|
+
};
|
|
1781
|
+
await updateOneUserAudit( query, userRecord );
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
const storeRecord ={
|
|
1785
|
+
status: req.audit.status !== 'completed' ? 'skipped': 'assigned',
|
|
1786
|
+
};
|
|
1787
|
+
|
|
1788
|
+
await updateOneStoreZoneAudit( query, storeRecord );
|
|
1789
|
+
const logData = {
|
|
1790
|
+
userId: req.user._id,
|
|
1791
|
+
userName: req.user.userName,
|
|
1792
|
+
logType: 'zoneAudit',
|
|
1793
|
+
logSubType: 'reTrigger',
|
|
1794
|
+
logData: {
|
|
1795
|
+
beforeCount: inputData.totalCount,
|
|
1796
|
+
afterCount: '',
|
|
1797
|
+
fileDate: inputData.fileDate,
|
|
1798
|
+
auditType: inputData.type,
|
|
1799
|
+
storeId: inputData.storeId,
|
|
1800
|
+
zoneName: inputData.zoneName,
|
|
1801
|
+
queueName: queueName,
|
|
1802
|
+
message: inputData.comments,
|
|
1803
|
+
triggerBy: req.user.userName,
|
|
1804
|
+
triggerId: req.user._id,
|
|
1805
|
+
triggerType: inputData.triggerType,
|
|
1806
|
+
},
|
|
1807
|
+
};
|
|
1808
|
+
await insertOpenSearchData( openSearch.activityLog, logData );
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
return res.sendSuccess( { result: 'The File has been Re Trigger Succesfully' } );
|
|
1812
|
+
} catch ( error ) {
|
|
1813
|
+
const err = error.message;
|
|
1814
|
+
logger.error( { error: error, message: req.body } );
|
|
1815
|
+
return res.sendError( err, 500 );
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import j2s from 'joi-to-swagger';
|
|
2
|
-
import { clientMetricsSchema, getDraftedDataSchema, getFileSchema, 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,16 +179,79 @@ export const zoneAuditDocs = {
|
|
|
179
179
|
},
|
|
180
180
|
},
|
|
181
181
|
|
|
182
|
-
'/v3/zone-audit/metrics/
|
|
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' },
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
'/v3/zone-audit/metrics/re-trigger': {
|
|
183
246
|
post: {
|
|
184
247
|
tags: [ 'Zone Audit Metrics' ],
|
|
185
|
-
description: `
|
|
186
|
-
operationId: 'metrics/
|
|
248
|
+
description: `Manual re trigger a file`,
|
|
249
|
+
operationId: 'metrics/re-trigger',
|
|
187
250
|
parameters: {},
|
|
188
251
|
requestBody: {
|
|
189
252
|
content: {
|
|
190
253
|
'application/json': {
|
|
191
|
-
schema: j2s(
|
|
254
|
+
schema: j2s( reTriggerValidSchema ).swagger,
|
|
192
255
|
},
|
|
193
256
|
},
|
|
194
257
|
},
|
|
@@ -129,8 +129,9 @@ export const overViewTableSchema = joi.object(
|
|
|
129
129
|
clientId: joi.array().optional(),
|
|
130
130
|
limit: joi.number().optional(),
|
|
131
131
|
offset: joi.number().optional(),
|
|
132
|
-
searchValue: joi.
|
|
132
|
+
searchValue: joi.string().optional().allow( '' ),
|
|
133
133
|
filterByStatus: joi.array().required(),
|
|
134
|
+
filterByType: joi.array().optional(),
|
|
134
135
|
filterByAuditType: joi.array().required(),
|
|
135
136
|
sortColumnName: joi.string().optional(),
|
|
136
137
|
sortBy: joi.number().optional(),
|
|
@@ -159,7 +160,7 @@ export const reTriggerValidSchema = joi.object(
|
|
|
159
160
|
{
|
|
160
161
|
fileDate: joi.string().required(),
|
|
161
162
|
storeId: joi.string().required(),
|
|
162
|
-
|
|
163
|
+
type: joi.string().optional(),
|
|
163
164
|
triggerType: joi.string().optional(),
|
|
164
165
|
totalCount: joi.number().required(),
|
|
165
166
|
userId: joi.string().optional(),
|
|
@@ -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(),
|
|
@@ -127,3 +140,20 @@ export const clientMetricsValid = {
|
|
|
127
140
|
body: clientMetricsSchema,
|
|
128
141
|
};
|
|
129
142
|
|
|
143
|
+
export const reTriggerValidSchema = joi.object(
|
|
144
|
+
{
|
|
145
|
+
fileDate: joi.string().required(),
|
|
146
|
+
storeId: joi.string().required(),
|
|
147
|
+
zoneName: joi.string().required(),
|
|
148
|
+
type: joi.string().optional(),
|
|
149
|
+
triggerType: joi.string().optional(),
|
|
150
|
+
totalCount: joi.number().required(),
|
|
151
|
+
userId: joi.string().optional(),
|
|
152
|
+
comments: joi.string().optional().allow( '' ),
|
|
153
|
+
},
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
export const reTriggerValid = {
|
|
157
|
+
body: reTriggerValidSchema,
|
|
158
|
+
};
|
|
159
|
+
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { clientMetricsValid, getDraftedDataValid, getFileValid, saveDraftValid, saveValid,
|
|
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, save, saveDraft, storeMetrics, workSpace } from '../controllers/zoneAudit.controller.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';
|
|
6
7
|
|
|
7
8
|
export const zoneAuditRouter=Router();
|
|
8
9
|
|
|
@@ -16,4 +17,6 @@ zoneAuditRouter.get( '/work-space', isAllowedSessionHandler, validate( workSpace
|
|
|
16
17
|
// metrics
|
|
17
18
|
|
|
18
19
|
zoneAuditRouter.post( '/metrics/store-metrics', isAllowedSessionHandler, validate( storeMetricsValid ), storeMetrics );
|
|
20
|
+
zoneAuditRouter.get( '/metrics/audit-images', isAllowedSessionHandler, validate( zoneAuditImageValid ), isZoneAuditInputFolderExist, zoneAuditImages );
|
|
19
21
|
zoneAuditRouter.post( '/metrics/client-metrics', isAllowedSessionHandler, validate( clientMetricsValid ), clientMetrics );
|
|
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
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { checkFileExist } from 'tango-app-api-middleware';
|
|
2
|
+
import { findOneStoreZoneAudit } from '../service/storeZoneAudit.service.js';
|
|
3
|
+
|
|
4
|
+
export async function isAuditDocumentExist( req, res, next ) {
|
|
5
|
+
try {
|
|
6
|
+
const inputData = req.body;
|
|
7
|
+
const query={
|
|
8
|
+
storeId: inputData.storeId,
|
|
9
|
+
fileDate: inputData.fileDate,
|
|
10
|
+
zoneName: inputData.zoneName,
|
|
11
|
+
};
|
|
12
|
+
const auditInfo = await findOneStoreZoneAudit( query );
|
|
13
|
+
if ( auditInfo ) {
|
|
14
|
+
req.audit = auditInfo;
|
|
15
|
+
return next();
|
|
16
|
+
} else {
|
|
17
|
+
return res.sendError( 'No audited Record', 400 );
|
|
18
|
+
}
|
|
19
|
+
} catch ( error ) {
|
|
20
|
+
const err = error.message || 'Internal Server Error';
|
|
21
|
+
logger.error( { error: error, message: req.body, function: 'isAuditFileExist' } );
|
|
22
|
+
return res.sendError( err, 500 );
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function isAuditInputFolderExist( req, res, next ) {
|
|
27
|
+
try {
|
|
28
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
29
|
+
const inputData = req.method === 'POST' ? req.body : req.query;
|
|
30
|
+
const params={
|
|
31
|
+
Bucket: bucket.auditInput,
|
|
32
|
+
Key: `${inputData.fileDate}/${inputData.storeId}/${inputData.zoneName}`,
|
|
33
|
+
};
|
|
34
|
+
const isExist = await checkFileExist( params );
|
|
35
|
+
if ( isExist ) {
|
|
36
|
+
next();
|
|
37
|
+
} else {
|
|
38
|
+
return res.sendError( `Audit Input folder not available : ${inputData.fileDate}/${inputData.storeId}/${inputData.zoneName}`, 400 );
|
|
39
|
+
}
|
|
40
|
+
} catch ( error ) {
|
|
41
|
+
const err = error.message || 'Internal Server Error';
|
|
42
|
+
logger.error( { error: error, message: req.query, function: 'isAuidtInputFolderExist' } );
|
|
43
|
+
return res.sendError( err, 500 );
|
|
44
|
+
}
|
|
45
|
+
}
|