tango-app-api-audit 1.0.41 → 1.0.43
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/auditMetrics.controllers.js +232 -70
- package/src/controllers/zoneAudit.controller.js +391 -18
- package/src/docs/zoneAudit.docs.js +47 -1
- package/src/dtos/auditMetrics.dtos.js +4 -4
- package/src/dtos/zoneAudit.dtos.js +36 -0
- package/src/routes/zone.routes.js +5 -3
- package/src/validation/zoneAudit.validation.js +45 -0
|
@@ -7,10 +7,10 @@ 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
12
|
import { mapCustomer, mapEmployee, mapJunk, splitB20000, splitE0, splitG20000 } from '../validation/audit.validation.js';
|
|
13
|
-
import { aggregateClient, findClient } from '../service/client.service.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
16
|
import { listQueue } from 'tango-app-api-middleware/src/utils/aws/sqs.js';
|
|
@@ -921,6 +921,10 @@ export async function storeMetrics( req, res ) {
|
|
|
921
921
|
filter.push( { status: { $in: inputData.filterByStatus } } );
|
|
922
922
|
}
|
|
923
923
|
|
|
924
|
+
if ( inputData.filterByType && inputData.filterByType?.length > 0 ) {
|
|
925
|
+
filter.push( { auditType: { $in: inputData.filterByType } } );
|
|
926
|
+
}
|
|
927
|
+
|
|
924
928
|
const query = [
|
|
925
929
|
{
|
|
926
930
|
$match: {
|
|
@@ -958,6 +962,8 @@ export async function storeMetrics( req, res ) {
|
|
|
958
962
|
fileDate: 1,
|
|
959
963
|
storeId: 1,
|
|
960
964
|
storeName: '$store.storeName',
|
|
965
|
+
clientName: '',
|
|
966
|
+
clientId: 1,
|
|
961
967
|
userId: {
|
|
962
968
|
$arrayElemAt: [ '$userId', { $subtract: [ { $size: '$userId' }, 1 ] } ],
|
|
963
969
|
},
|
|
@@ -978,56 +984,56 @@ export async function storeMetrics( req, res ) {
|
|
|
978
984
|
},
|
|
979
985
|
{
|
|
980
986
|
$lookup: {
|
|
981
|
-
from: '
|
|
982
|
-
let: {
|
|
987
|
+
from: 'users',
|
|
988
|
+
let: { userId: '$userId' },
|
|
983
989
|
pipeline: [
|
|
984
990
|
{
|
|
985
991
|
$match: {
|
|
986
992
|
$expr: {
|
|
987
|
-
$eq: [ '$
|
|
993
|
+
$eq: [ '$_id', '$$userId' ],
|
|
988
994
|
},
|
|
989
995
|
},
|
|
990
996
|
},
|
|
991
997
|
{
|
|
992
998
|
$project: {
|
|
993
999
|
_id: 0,
|
|
994
|
-
|
|
1000
|
+
userName: 1,
|
|
1001
|
+
userEmail: '$email',
|
|
995
1002
|
},
|
|
996
1003
|
},
|
|
997
|
-
], as: '
|
|
1004
|
+
], as: 'users',
|
|
998
1005
|
},
|
|
999
1006
|
},
|
|
1000
1007
|
{
|
|
1001
1008
|
$unwind: {
|
|
1002
|
-
path: '$
|
|
1009
|
+
path: '$users',
|
|
1003
1010
|
preserveNullAndEmptyArrays: true,
|
|
1004
1011
|
},
|
|
1005
1012
|
},
|
|
1006
1013
|
{
|
|
1007
1014
|
$lookup: {
|
|
1008
|
-
from: '
|
|
1009
|
-
let: {
|
|
1015
|
+
from: 'clients',
|
|
1016
|
+
let: { clientId: '$clientId' },
|
|
1010
1017
|
pipeline: [
|
|
1011
1018
|
{
|
|
1012
1019
|
$match: {
|
|
1013
1020
|
$expr: {
|
|
1014
|
-
$eq: [ '$
|
|
1021
|
+
$eq: [ '$clientId', '$$clientId' ],
|
|
1015
1022
|
},
|
|
1016
1023
|
},
|
|
1017
1024
|
},
|
|
1018
1025
|
{
|
|
1019
1026
|
$project: {
|
|
1020
1027
|
_id: 0,
|
|
1021
|
-
|
|
1022
|
-
userEmail: '$email',
|
|
1028
|
+
clientName: 1,
|
|
1023
1029
|
},
|
|
1024
1030
|
},
|
|
1025
|
-
], as: '
|
|
1031
|
+
], as: 'client',
|
|
1026
1032
|
},
|
|
1027
1033
|
},
|
|
1028
1034
|
{
|
|
1029
1035
|
$unwind: {
|
|
1030
|
-
path: '$
|
|
1036
|
+
path: '$client',
|
|
1031
1037
|
preserveNullAndEmptyArrays: true,
|
|
1032
1038
|
},
|
|
1033
1039
|
},
|
|
@@ -1039,19 +1045,43 @@ export async function storeMetrics( req, res ) {
|
|
|
1039
1045
|
storeName: '$stores.storeName',
|
|
1040
1046
|
userName: '$users.userName',
|
|
1041
1047
|
userEmail: '$users.userEmail',
|
|
1042
|
-
|
|
1043
1048
|
clientId: 1,
|
|
1049
|
+
clientName: '$client.clientName',
|
|
1044
1050
|
auditType: 1,
|
|
1045
1051
|
beforeCount: 1,
|
|
1046
1052
|
afterCount: { $ifNull: [ '$afterCount', null ] },
|
|
1047
1053
|
accuracy: { $round: [
|
|
1048
1054
|
{ $divide: [
|
|
1049
1055
|
{ $multiply: [ { $ifNull: [ '$afterCount', 0 ] }, '$beforeCount' ] }, 100,
|
|
1050
|
-
] },
|
|
1056
|
+
] }, 1,
|
|
1051
1057
|
],
|
|
1052
1058
|
|
|
1053
1059
|
},
|
|
1054
|
-
timeSpent:
|
|
1060
|
+
timeSpent: {
|
|
1061
|
+
|
|
1062
|
+
$cond: [
|
|
1063
|
+
{ $lt: [ '$timeSpent', 60 ] }, // Case 1: If less than 60 seconds
|
|
1064
|
+
{ $concat: [ { $toString: '$timeSpent' }, ' sec' ] },
|
|
1065
|
+
{
|
|
1066
|
+
$cond: [
|
|
1067
|
+
{ $lt: [ '$timeSpent', 3600 ] }, // Case 2: If less than 60 minutes (3600 seconds)
|
|
1068
|
+
{
|
|
1069
|
+
$concat: [
|
|
1070
|
+
{ $toString: { $round: [ { $divide: [ '$timeSpent', 60 ] }, 1 ] } }, // Convert to minutes
|
|
1071
|
+
' min',
|
|
1072
|
+
],
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
$concat: [
|
|
1076
|
+
{ $toString: { $round: [ { $divide: [ '$timeSpent', 3600 ] }, 1 ] } }, // Convert to hours
|
|
1077
|
+
' hr',
|
|
1078
|
+
],
|
|
1079
|
+
},
|
|
1080
|
+
],
|
|
1081
|
+
},
|
|
1082
|
+
],
|
|
1083
|
+
|
|
1084
|
+
},
|
|
1055
1085
|
status: 1,
|
|
1056
1086
|
},
|
|
1057
1087
|
},
|
|
@@ -1064,10 +1094,24 @@ export async function storeMetrics( req, res ) {
|
|
|
1064
1094
|
$or: [
|
|
1065
1095
|
{ clientId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1066
1096
|
{ clientName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1097
|
+
{ storeId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1098
|
+
{ storeName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1099
|
+
{ userName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1100
|
+
{ status: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1101
|
+
{ auditType: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1067
1102
|
],
|
|
1068
1103
|
},
|
|
1069
1104
|
} );
|
|
1070
1105
|
}
|
|
1106
|
+
|
|
1107
|
+
if ( inputData.sortColumnName ) {
|
|
1108
|
+
const sortBy = inputData.sortBy || -1;
|
|
1109
|
+
query.push( {
|
|
1110
|
+
$sort: { [inputData.sortColumName]: sortBy },
|
|
1111
|
+
},
|
|
1112
|
+
);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1071
1115
|
const count = await aggregateStoreZoneAudit( query );
|
|
1072
1116
|
|
|
1073
1117
|
if ( count.length == 0 ) {
|
|
@@ -1092,6 +1136,7 @@ export async function storeMetrics( req, res ) {
|
|
|
1092
1136
|
'Store Id': element.storeId,
|
|
1093
1137
|
'Store Name': element.storeName,
|
|
1094
1138
|
'Client Id': element.clientId,
|
|
1139
|
+
'Client Name': element.clientName,
|
|
1095
1140
|
'User Name': element.userName,
|
|
1096
1141
|
'User Email': element.userEmail,
|
|
1097
1142
|
'Audit Type': element.auditType,
|
|
@@ -1110,3 +1155,331 @@ export async function storeMetrics( req, res ) {
|
|
|
1110
1155
|
return res.sendError( err, 500 );
|
|
1111
1156
|
}
|
|
1112
1157
|
}
|
|
1158
|
+
|
|
1159
|
+
export async function clientMetrics( req, res ) {
|
|
1160
|
+
try {
|
|
1161
|
+
const inputData = req.body;
|
|
1162
|
+
const limit = inputData.limit || 10;
|
|
1163
|
+
const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
|
|
1164
|
+
const dateRange = await getUTC( new Date( inputData.fromDate ), new Date( inputData.toDate ) );
|
|
1165
|
+
let filter = [
|
|
1166
|
+
{ fileDateISO: { $gte: dateRange.start } },
|
|
1167
|
+
{ fileDateISO: { $lte: dateRange.end } },
|
|
1168
|
+
{ moduleType: { $eq: 'zone' } },
|
|
1169
|
+
|
|
1170
|
+
];
|
|
1171
|
+
if ( inputData?.filterByClient?.length> 0 ) {
|
|
1172
|
+
filter.push(
|
|
1173
|
+
{ clientId: { $in: inputData.filterByClient } },
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
const query = [
|
|
1177
|
+
{
|
|
1178
|
+
$match: {
|
|
1179
|
+
$and: filter,
|
|
1180
|
+
},
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
$project: {
|
|
1184
|
+
fileDate: 1,
|
|
1185
|
+
clientId: 1,
|
|
1186
|
+
clientName: 1,
|
|
1187
|
+
queueName: 1,
|
|
1188
|
+
installedStore: 1,
|
|
1189
|
+
totalFilesCount: 1,
|
|
1190
|
+
notAssignedCount: { $ifNull: [ 0, 0 ] },
|
|
1191
|
+
clientStatus: { $ifNull: [ '', '' ] },
|
|
1192
|
+
},
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
$lookup: {
|
|
1196
|
+
'from': 'storeZoneAudit',
|
|
1197
|
+
'let': { clientId: '$clientId', fileDate: '$fileDate', totalAuditFiles: '$totalAuditFiles' },
|
|
1198
|
+
'pipeline': [
|
|
1199
|
+
|
|
1200
|
+
{
|
|
1201
|
+
$match: {
|
|
1202
|
+
$expr: {
|
|
1203
|
+
$and: [
|
|
1204
|
+
{ $eq: [ '$clientId', '$$clientId' ] },
|
|
1205
|
+
{ $eq: [ '$fileDate', '$$fileDate' ] },
|
|
1206
|
+
],
|
|
1207
|
+
},
|
|
1208
|
+
},
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
$project: {
|
|
1212
|
+
completedStores: { $cond: [ { $eq: [ '$status', 'completed' ] }, 1, 0 ] },
|
|
1213
|
+
notAssignedStores: { $cond: [ { $eq: [ '$status', 'not_assign' ] }, 1, 0 ] },
|
|
1214
|
+
inprogressStores: { $cond: [ { $in: [ '$status', [ 'inprogress', 'drafted', 'assigned' ] ] }, 1, 0 ] },
|
|
1215
|
+
},
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
$group: {
|
|
1219
|
+
_id: { clientId: '$clientId', fileDate: '$fileDate' },
|
|
1220
|
+
completedStores: { $sum: '$completedStores' },
|
|
1221
|
+
inprogressStores: { $sum: '$inprogressStores' },
|
|
1222
|
+
notAssignedStores: { $sum: '$notAssignedStores' },
|
|
1223
|
+
fileCount: { $sum: 1 },
|
|
1224
|
+
},
|
|
1225
|
+
},
|
|
1226
|
+
{
|
|
1227
|
+
$project: {
|
|
1228
|
+
_id: 0,
|
|
1229
|
+
completedStores: 1,
|
|
1230
|
+
inprogressStores: 1,
|
|
1231
|
+
notAssignedStores: 1,
|
|
1232
|
+
fileCount: 1,
|
|
1233
|
+
completionPercentage: { $ifNull: [
|
|
1234
|
+
{
|
|
1235
|
+
$round: [ {
|
|
1236
|
+
$multiply: [
|
|
1237
|
+
100, {
|
|
1238
|
+
$divide: [
|
|
1239
|
+
'$completedStores', '$$totalAuditFiles',
|
|
1240
|
+
],
|
|
1241
|
+
},
|
|
1242
|
+
],
|
|
1243
|
+
}, 1 ],
|
|
1244
|
+
|
|
1245
|
+
},
|
|
1246
|
+
0,
|
|
1247
|
+
],
|
|
1248
|
+
},
|
|
1249
|
+
},
|
|
1250
|
+
},
|
|
1251
|
+
], 'as': 'storeZoneAudit',
|
|
1252
|
+
},
|
|
1253
|
+
},
|
|
1254
|
+
{
|
|
1255
|
+
$unwind: {
|
|
1256
|
+
path: '$storeZoneAudit',
|
|
1257
|
+
preserveNullAndEmptyArrays: true,
|
|
1258
|
+
},
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
$project: {
|
|
1262
|
+
fileDate: 1,
|
|
1263
|
+
clientId: 1,
|
|
1264
|
+
clientName: 1,
|
|
1265
|
+
totalFilesCount: 1,
|
|
1266
|
+
installedStore: 1,
|
|
1267
|
+
fileCount: '$storeZoneAudit.fileCount',
|
|
1268
|
+
notAssignedStores: '$storeZoneAudit.notAssignedStores',
|
|
1269
|
+
inprogressStoresCount: '$storeZoneAudit.inprogressStores',
|
|
1270
|
+
notAssignedCount: 1,
|
|
1271
|
+
clientStatus: { $cond: [ { $eq: [ '$storeZoneAudit.fileCount', 0 ] }, 'not-taken', { $cond: [ { $or: [ { $gt: [ '$notAssignedCount', 0 ] }, { $gt: [ '$storeZoneAudit.notAssignedStores', 0 ] } ] }, 'pending', 'completed' ] } ] },
|
|
1272
|
+
completedStores: '$storeZoneAudit.completedStores',
|
|
1273
|
+
completionPercentage: '$storeZoneAudit.completionPercentage',
|
|
1274
|
+
|
|
1275
|
+
},
|
|
1276
|
+
},
|
|
1277
|
+
];
|
|
1278
|
+
|
|
1279
|
+
if ( inputData.searchValue && inputData.searchValue!== '' ) {
|
|
1280
|
+
query.push( {
|
|
1281
|
+
$match: {
|
|
1282
|
+
$or: [
|
|
1283
|
+
{ clientId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1284
|
+
{ clientName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1285
|
+
],
|
|
1286
|
+
|
|
1287
|
+
},
|
|
1288
|
+
} );
|
|
1289
|
+
}
|
|
1290
|
+
if ( inputData.sortColumnName ) {
|
|
1291
|
+
const sortBy = inputData.sortBy || -1;
|
|
1292
|
+
query.push( {
|
|
1293
|
+
$sort: { [inputData.sortColumName]: sortBy },
|
|
1294
|
+
},
|
|
1295
|
+
);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
const count = await aggregateAuditClientData( query );
|
|
1299
|
+
if ( count.length == 0 ) {
|
|
1300
|
+
return res.sendError( 'No Data Found', 204 );
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
query.push(
|
|
1304
|
+
{ $skip: offset },
|
|
1305
|
+
{ $limit: limit },
|
|
1306
|
+
);
|
|
1307
|
+
if ( inputData.isExport ) {
|
|
1308
|
+
query.push(
|
|
1309
|
+
{
|
|
1310
|
+
$project: {
|
|
1311
|
+
'_id': 0,
|
|
1312
|
+
'File Date': '$fileDate',
|
|
1313
|
+
'Client Name': '$clientName',
|
|
1314
|
+
'Client Id': '$clientId',
|
|
1315
|
+
'Completed Percentage': '$completionPercentage',
|
|
1316
|
+
'Installed Stores': '$installedStore',
|
|
1317
|
+
'Audit Stores': '$totalFilesCount',
|
|
1318
|
+
'Inprogress Stores': '$inprogressStoresCount',
|
|
1319
|
+
'Not Assigned': '$notAssignedCount',
|
|
1320
|
+
'Not Assigned Stores': '$notAssignedStores',
|
|
1321
|
+
'Completed': '$completedStores',
|
|
1322
|
+
'Status': '$clientStatus',
|
|
1323
|
+
},
|
|
1324
|
+
},
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
const result = await aggregateAuditClientData( query );
|
|
1330
|
+
if ( inputData.isExport ) {
|
|
1331
|
+
await download( result, res );
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1334
|
+
return res.sendSuccess( { result: result, count: count.length } );
|
|
1335
|
+
} catch ( error ) {
|
|
1336
|
+
const err = error.error || 'Internal Server Error';
|
|
1337
|
+
logger.info( { error: error, message: req.body, function: 'clientMetrics' } );
|
|
1338
|
+
return res.sendError( err, 500 );
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
export async function reTrigger( req, res ) {
|
|
1343
|
+
try {
|
|
1344
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1345
|
+
const inputData = req.body;
|
|
1346
|
+
const sqs = JSON.parse( process.env.SQS );
|
|
1347
|
+
const query ={
|
|
1348
|
+
storeId: inputData.storeId,
|
|
1349
|
+
fileDate: inputData.fileDate,
|
|
1350
|
+
};
|
|
1351
|
+
const getQueueName = await findOneClient( { clientId: req.audit.clientId }, { 'auditConfigs.zoneQueueName': 1 } );
|
|
1352
|
+
|
|
1353
|
+
if ( !getQueueName || getQueueName?.auditConfigs?.zoneQueueName == '' ) {
|
|
1354
|
+
return res.sendError( 'queueName does not create', 400 );
|
|
1355
|
+
}
|
|
1356
|
+
const queueName = getQueueName?.auditConfigs?.zoneQueueName;
|
|
1357
|
+
logger.info( { queueName: queueName } );
|
|
1358
|
+
switch ( inputData.triggerType ) {
|
|
1359
|
+
case 'queue':
|
|
1360
|
+
const msg = {
|
|
1361
|
+
store_id: inputData.storeId,
|
|
1362
|
+
curr_date: inputData.fileDate,
|
|
1363
|
+
audit_type: inputData.type,
|
|
1364
|
+
total_count: inputData.totalCount,
|
|
1365
|
+
zone_id: inputData.zoneName,
|
|
1366
|
+
};
|
|
1367
|
+
|
|
1368
|
+
const sqsProduceQueue = {
|
|
1369
|
+
QueueUrl: `${sqs.url}${queueName}`,
|
|
1370
|
+
MessageBody: JSON.stringify( msg ),
|
|
1371
|
+
};
|
|
1372
|
+
const sqsQueue = await sendMessageToQueue( sqsProduceQueue.QueueUrl, sqsProduceQueue.MessageBody );
|
|
1373
|
+
if ( sqsQueue?.errorCode ) {
|
|
1374
|
+
const error = sqsQueue?.errorMsg;
|
|
1375
|
+
const code = sqsQueue?.errorCode;
|
|
1376
|
+
return res.sendError( error, code );
|
|
1377
|
+
} else {
|
|
1378
|
+
if ( req.audit.status !== 'completed' ) {
|
|
1379
|
+
const userRecord ={
|
|
1380
|
+
auditStatus: 'skipped',
|
|
1381
|
+
isDraft: false,
|
|
1382
|
+
};
|
|
1383
|
+
const query ={
|
|
1384
|
+
storeId: inputData.storeId,
|
|
1385
|
+
fileDate: inputData.fileDate,
|
|
1386
|
+
zoneName: inputData.zoneName,
|
|
1387
|
+
auditStatus: req.audit.status,
|
|
1388
|
+
|
|
1389
|
+
};
|
|
1390
|
+
await updateOneUserAudit( query, userRecord );
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
const storeRecord ={
|
|
1394
|
+
status: req.audit.status !== 'completed' ? 'skipped': 'not_assign',
|
|
1395
|
+
};
|
|
1396
|
+
|
|
1397
|
+
await updateOneStoreZoneAudit( query, storeRecord );
|
|
1398
|
+
const logData = {
|
|
1399
|
+
userId: req.user._id,
|
|
1400
|
+
userName: req.user.userName,
|
|
1401
|
+
logType: 'zoneAudit',
|
|
1402
|
+
logSubType: 'reTrigger',
|
|
1403
|
+
logData: {
|
|
1404
|
+
beforeCount: inputData.totalCount,
|
|
1405
|
+
afterCount: '',
|
|
1406
|
+
fileDate: inputData.fileDate,
|
|
1407
|
+
auditType: inputData.type,
|
|
1408
|
+
storeId: inputData.storeId,
|
|
1409
|
+
zoneName: inputData.zoneName,
|
|
1410
|
+
queueName: queueName,
|
|
1411
|
+
message: inputData.comments,
|
|
1412
|
+
triggerBy: req.user.userName,
|
|
1413
|
+
triggerId: req.user._id,
|
|
1414
|
+
triggerType: inputData.triggerType,
|
|
1415
|
+
},
|
|
1416
|
+
};
|
|
1417
|
+
await insertOpenSearchData( openSearch.activityLog, logData );
|
|
1418
|
+
}
|
|
1419
|
+
break;
|
|
1420
|
+
case 'user':
|
|
1421
|
+
const assignUser = await findOneUser( { _id: new mongoose.Types.ObjectId( inputData.userId ) } );
|
|
1422
|
+
const assignUserRecord = {
|
|
1423
|
+
storeId: inputData.storeId,
|
|
1424
|
+
clientId: req.audit.clientId,
|
|
1425
|
+
fileDate: inputData.fileDate,
|
|
1426
|
+
zoneName: inputData.zoneName,
|
|
1427
|
+
fileDateISO: dayjs( inputData.fileDate, 'DD-MM-YYYY' ).format(),
|
|
1428
|
+
auditType: inputData.type,
|
|
1429
|
+
moduleType: 'zone',
|
|
1430
|
+
fileCount: inputData.beforeCount,
|
|
1431
|
+
queueName: queueName,
|
|
1432
|
+
userId: inputData.userId,
|
|
1433
|
+
userName: assignUser.userName,
|
|
1434
|
+
};
|
|
1435
|
+
await createAssignAudit( assignUserRecord );
|
|
1436
|
+
|
|
1437
|
+
if ( req.audit.status !== 'completed' ) {
|
|
1438
|
+
const userRecord ={
|
|
1439
|
+
auditStatus: 'skipped',
|
|
1440
|
+
isDraft: false,
|
|
1441
|
+
};
|
|
1442
|
+
const query ={
|
|
1443
|
+
storeId: inputData.storeId,
|
|
1444
|
+
fileDate: inputData.fileDate,
|
|
1445
|
+
zoneName: inputData.zoneName,
|
|
1446
|
+
auditStatus: req.audit.status,
|
|
1447
|
+
|
|
1448
|
+
};
|
|
1449
|
+
await updateOneUserAudit( query, userRecord );
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
const storeRecord ={
|
|
1453
|
+
status: req.audit.status !== 'completed' ? 'skipped': 'assigned',
|
|
1454
|
+
};
|
|
1455
|
+
|
|
1456
|
+
await updateOneStoreZoneAudit( query, storeRecord );
|
|
1457
|
+
const logData = {
|
|
1458
|
+
userId: req.user._id,
|
|
1459
|
+
userName: req.user.userName,
|
|
1460
|
+
logType: 'zoneAudit',
|
|
1461
|
+
logSubType: 'reTrigger',
|
|
1462
|
+
logData: {
|
|
1463
|
+
beforeCount: inputData.totalCount,
|
|
1464
|
+
afterCount: '',
|
|
1465
|
+
fileDate: inputData.fileDate,
|
|
1466
|
+
auditType: inputData.type,
|
|
1467
|
+
storeId: inputData.storeId,
|
|
1468
|
+
zoneName: inputData.zoneName,
|
|
1469
|
+
queueName: queueName,
|
|
1470
|
+
message: inputData.comments,
|
|
1471
|
+
triggerBy: req.user.userName,
|
|
1472
|
+
triggerId: req.user._id,
|
|
1473
|
+
triggerType: inputData.triggerType,
|
|
1474
|
+
},
|
|
1475
|
+
};
|
|
1476
|
+
await insertOpenSearchData( openSearch.activityLog, logData );
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
return res.sendSuccess( { result: 'The File has been Re Trigger Succesfully' } );
|
|
1480
|
+
} catch ( error ) {
|
|
1481
|
+
const err = error.message;
|
|
1482
|
+
logger.error( { error: error, message: req.body } );
|
|
1483
|
+
return res.sendError( err, 500 );
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import j2s from 'joi-to-swagger';
|
|
2
|
-
import { getDraftedDataSchema, getFileSchema, saveDraftSchema, saveSchema, storeMetricsSchema, workSpaceSchema } from '../dtos/zoneAudit.dtos.js';
|
|
2
|
+
import { clientMetricsSchema, getDraftedDataSchema, getFileSchema, reTriggerValidSchema, saveDraftSchema, saveSchema, storeMetricsSchema, workSpaceSchema } from '../dtos/zoneAudit.dtos.js';
|
|
3
3
|
|
|
4
4
|
export const zoneAuditDocs = {
|
|
5
5
|
'/v3/zone-audit/get-file': {
|
|
@@ -179,4 +179,50 @@ 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,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
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
|
+
},
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
'/v3/zone-audit/metrics/re-trigger': {
|
|
206
|
+
post: {
|
|
207
|
+
tags: [ 'Zone Audit Metrics' ],
|
|
208
|
+
description: `Manual re trigger a file`,
|
|
209
|
+
operationId: 'metrics/re-trigger',
|
|
210
|
+
parameters: {},
|
|
211
|
+
requestBody: {
|
|
212
|
+
content: {
|
|
213
|
+
'application/json': {
|
|
214
|
+
schema: j2s( reTriggerValidSchema ).swagger,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
responses: {
|
|
219
|
+
200: { description: 'Successful' },
|
|
220
|
+
401: { description: 'Unauthorized User' },
|
|
221
|
+
422: { description: 'Field Error' },
|
|
222
|
+
500: { description: 'Server Error' },
|
|
223
|
+
204: { description: 'Not Found' },
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
|
|
182
228
|
};
|
|
@@ -45,7 +45,7 @@ export const storeMetricsSchema = joi.object(
|
|
|
45
45
|
filterByClientId: joi.array().required(),
|
|
46
46
|
filterByStoreId: joi.array().optional(),
|
|
47
47
|
filterByStatus: joi.array().optional(),
|
|
48
|
-
|
|
48
|
+
filterByType: joi.array().optional(),
|
|
49
49
|
sortColumnName: joi.string().optional(),
|
|
50
50
|
sortBy: joi.number().optional(),
|
|
51
51
|
limit: joi.number().optional(),
|
|
@@ -62,7 +62,6 @@ export const clientMetricsSchema = joi.object(
|
|
|
62
62
|
{
|
|
63
63
|
fromDate: joi.string().required(),
|
|
64
64
|
toDate: joi.string().required(),
|
|
65
|
-
filterByAuditType: joi.array().optional(),
|
|
66
65
|
searchValue: joi.string().optional().allow( '' ),
|
|
67
66
|
filterByClient: joi.array().required(),
|
|
68
67
|
filterByStatus: joi.array().optional(),
|
|
@@ -130,8 +129,9 @@ export const overViewTableSchema = joi.object(
|
|
|
130
129
|
clientId: joi.array().optional(),
|
|
131
130
|
limit: joi.number().optional(),
|
|
132
131
|
offset: joi.number().optional(),
|
|
133
|
-
searchValue: joi.
|
|
132
|
+
searchValue: joi.string().optional().allow( '' ),
|
|
134
133
|
filterByStatus: joi.array().required(),
|
|
134
|
+
filterByType: joi.array().optional(),
|
|
135
135
|
filterByAuditType: joi.array().required(),
|
|
136
136
|
sortColumnName: joi.string().optional(),
|
|
137
137
|
sortBy: joi.number().optional(),
|
|
@@ -160,7 +160,7 @@ export const reTriggerValidSchema = joi.object(
|
|
|
160
160
|
{
|
|
161
161
|
fileDate: joi.string().required(),
|
|
162
162
|
storeId: joi.string().required(),
|
|
163
|
-
|
|
163
|
+
type: joi.string().optional(),
|
|
164
164
|
triggerType: joi.string().optional(),
|
|
165
165
|
totalCount: joi.number().required(),
|
|
166
166
|
userId: joi.string().optional(),
|
|
@@ -108,3 +108,39 @@ export const storeMetricsValid = {
|
|
|
108
108
|
body: storeMetricsSchema,
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
+
export const clientMetricsSchema = joi.object(
|
|
112
|
+
{
|
|
113
|
+
fromDate: joi.string().required(),
|
|
114
|
+
toDate: joi.string().required(),
|
|
115
|
+
searchValue: joi.string().optional().allow( '' ),
|
|
116
|
+
filterByClient: joi.array().required(),
|
|
117
|
+
filterByStatus: joi.array().optional(),
|
|
118
|
+
sortColumnName: joi.string().optional(),
|
|
119
|
+
sortBy: joi.number().optional(),
|
|
120
|
+
limit: joi.number().optional(),
|
|
121
|
+
offset: joi.number().optional(),
|
|
122
|
+
isExport: joi.boolean().optional(),
|
|
123
|
+
},
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
export const clientMetricsValid = {
|
|
127
|
+
body: clientMetricsSchema,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const reTriggerValidSchema = joi.object(
|
|
131
|
+
{
|
|
132
|
+
fileDate: joi.string().required(),
|
|
133
|
+
storeId: joi.string().required(),
|
|
134
|
+
zoneName: joi.string().required(),
|
|
135
|
+
type: joi.string().optional(),
|
|
136
|
+
triggerType: joi.string().optional(),
|
|
137
|
+
totalCount: joi.number().required(),
|
|
138
|
+
userId: joi.string().optional(),
|
|
139
|
+
comments: joi.string().optional().allow( '' ),
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
export const reTriggerValid = {
|
|
144
|
+
body: reTriggerValidSchema,
|
|
145
|
+
};
|
|
146
|
+
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { getDraftedDataValid, getFileValid, saveDraftValid, saveValid, workSpaceValid } from '../dtos/zoneAudit.dtos.js';
|
|
2
|
+
import { clientMetricsValid, getDraftedDataValid, getFileValid, reTriggerValid, saveDraftValid, saveValid, storeMetricsValid, workSpaceValid } from '../dtos/zoneAudit.dtos.js';
|
|
3
3
|
import { isExistsQueue, validateUserAudit } from '../validation/audit.validation.js';
|
|
4
4
|
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
5
|
-
import { getDraftedData, getZoneAuditFile, save, saveDraft, storeMetrics, workSpace } from '../controllers/zoneAudit.controller.js';
|
|
6
|
-
import {
|
|
5
|
+
import { clientMetrics, getDraftedData, getZoneAuditFile, reTrigger, save, saveDraft, storeMetrics, workSpace } from '../controllers/zoneAudit.controller.js';
|
|
6
|
+
import { isAuditDocumentExist, isAuditInputFolderExist } from '../validation/zoneAudit.validation.js';
|
|
7
7
|
|
|
8
8
|
export const zoneAuditRouter=Router();
|
|
9
9
|
|
|
@@ -17,3 +17,5 @@ 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.post( '/metrics/client-metrics', isAllowedSessionHandler, validate( clientMetricsValid ), clientMetrics );
|
|
21
|
+
zoneAuditRouter.post( '/metrics/re-trigger', isAllowedSessionHandler, validate( reTriggerValid ), isAuditDocumentExist, isAuditInputFolderExist, reTrigger );
|