tango-app-api-audit 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -6,8 +6,9 @@ import { auditMetricsDocs } from './src/docs/auditMetrics.docs.js';
6
6
  import { auditDocs } from './src/docs/audit.docs.js';
7
7
  import clientRouter from './src/routes/client.routes.js';
8
8
  import { clientDocs } from './src/docs/client.docs.js';
9
+ import { storeRouter } from './src/routes/store.routes.js';
10
+ import { storeDocs } from './src/docs/store.docs.js';
9
11
 
10
-
11
- export { auditRouter, auditMetricsRouter, auditMetricsDocs, auditDocs, clientRouter, clientDocs };
12
+ export { auditRouter, auditMetricsRouter, auditMetricsDocs, auditDocs, clientRouter, clientDocs, storeRouter, storeDocs };
12
13
 
13
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-audit",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "audit & audit metrics apis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -11,6 +11,7 @@ import { aggregateAuditClientData } from '../service/auditClientData.service.js'
11
11
  import _ from 'lodash';
12
12
  import { createAuditLog, findOneAuditLog } from '../service/auditLog.service.js';
13
13
  import { findOneStore } from '../service/store.service.js';
14
+ import { mapCustomer, mapEmployee, mapJunk, splitB20000, splitE0, splitG20000 } from '../validation/audit.validation.js';
14
15
 
15
16
  export async function getAuditFile( req, res ) {
16
17
  try {
@@ -881,8 +882,48 @@ export async function getDraftedData( req, res ) {
881
882
 
882
883
  export async function save( req, res ) {
883
884
  try {
885
+ const bucket = JSON.parse( process.env.BUCKET );
884
886
  const inputData = req.body;
885
- return res.sendSuccess( { result: inputData } );
887
+ const params = {
888
+ Key: `${inputData.storeId}/${inputData.fileDate}/${ bucket.masterJsonFile}`,
889
+ };
890
+
891
+ if ( inputData.auditType === 'ReAudit' ) {
892
+ params.Bucket = bucket.auditUploadBucket;
893
+ } else {
894
+ params.Bucket = bucket.masterJson;
895
+ }
896
+ logger.info( { params: params } );
897
+ const fileData = await getJsonFileData( params );
898
+ const masterJsonData = JSON.parse( fileData.toString( 'utf-8' ) );
899
+ logger.info( { masterJsonData: masterJsonData, length: masterJsonData.person_data.length } );
900
+
901
+ const [ G20000, B20000, E0 ] = await Promise.all( [
902
+ splitG20000( masterJsonData.person_data ),
903
+ splitB20000( masterJsonData.person_data ),
904
+ splitE0( masterJsonData.person_data ),
905
+ ] );
906
+
907
+ const [ mappingData ] = await Promise.all( [
908
+ mapEmployee( B20000, inputData.employee ),
909
+ mapJunk( B20000, inputData.junk ),
910
+ mapCustomer( B20000, inputData.customer ),
911
+ ] );
912
+
913
+ const tempData = _.sortBy( [ ...mappingData, ...G20000, ...E0 ], 'index' );
914
+
915
+ const tempObject = { person_data: tempData };
916
+
917
+ const uploadDataParams = {
918
+ Bucket: bucket.auditUploadBucket,
919
+ Key: `${inputData.storeId}/${inputData.fileDate}/${bucket.masterJsonFile}`,
920
+ ContentType: 'application/json',
921
+ Body: JSON.stringify( tempObject ),
922
+ };
923
+ logger.info( { uploadDataParams: uploadDataParams } );
924
+ const mappingUpload = await fileUpload( uploadDataParams );
925
+ logger.info( { mappingUpload: mappingUpload } );
926
+ return res.sendSuccess( { result: mappingUpload } );
886
927
  } catch ( error ) {
887
928
  const err= error.message || 'Internal Server Error';
888
929
  logger.error( { error: error, message: req.body, function: 'save' } );
@@ -2,6 +2,7 @@ import { download, getUTC, logger } from 'tango-app-api-middleware';
2
2
  import { aggregateAuditClientData } from '../service/auditClientData.service.js';
3
3
  import { aggregateUserAudit } from '../service/userAudit.service.js';
4
4
  import mongoose from 'mongoose';
5
+ import dayjs from 'dayjs';
5
6
  // import { listQueue } from 'tango-app-api-middleware/src/utils/aws/sqs.js';
6
7
 
7
8
 
@@ -112,214 +113,213 @@ export async function userAuditHistory( req, res ) {
112
113
  }
113
114
 
114
115
  export async function storeMetrics( req, res ) {
115
- // try {
116
- // const today = moment().subtract( 1, 'days' ).format( 'YYYY-MM-DD' );
117
- // const inputData = req.body;
118
- // const dateRange = await getUTC( new Date( inputData.fromDate ), new Date( inputData.toDate ) );
119
- // const start = dateRange.start;
120
- // const end = dateRange.end;
121
- // const filter = [
122
- // { fileDateISO: { $gte: start } },
123
- // { fileDateISO: { $lte: end } },
124
- // ];
125
- // if ( inputData.filterByClient && inputData.filterByClient?.length > 0 ) {
126
- // filter.push( { clientId: { $in: inputData.filterByClient } } );
127
- // }
128
- // const query = [
129
- // {
130
- // $match: {
131
- // $and: filter,
132
- // },
133
- // },
134
- // {
135
- // $project: {
136
- // fileDate: 1,
137
- // fileDateISO: 1,
138
- // clientName: 1,
139
- // clientId: 1,
140
- // installedStore: 1,
141
- // totalFilesCount: 1,
142
- // queueName: 1,
143
- // },
144
- // },
145
- // {
146
- // $lookup: {
147
- // 'from': 'audit',
148
- // 'let': { 'client_id': '$clientId', 'file_date': '$fileDate', 'total_files_count': '$totalFilesCount' },
149
- // 'pipeline': [
116
+ try {
117
+ const yesterday = dayjs().subtract( 1, 'days' ).format( 'YYYY-MM-DD' );
118
+ const inputData = req.body;
119
+ const dateRange = await getUTC( new Date( inputData.fromDate ), new Date( inputData.toDate ) );
120
+ let filter = [
121
+ { fileDateISO: { $gte: dateRange.start } },
122
+ { fileDateISO: { $lte: dateRange.end } },
123
+ ];
124
+ if ( inputData.filterByClient && inputData.filterByClient?.length > 0 ) {
125
+ filter.push( { clientId: { $in: inputData.filterByClient } } );
126
+ }
127
+ const query = [
128
+ {
129
+ $match: {
130
+ $and: filter,
131
+ },
132
+ },
133
+ {
134
+ $project: {
135
+ fileDate: 1,
136
+ fileDateISO: 1,
137
+ clientName: 1,
138
+ clientId: 1,
139
+ installedStore: 1,
140
+ totalFilesCount: 1,
141
+ queueName: 1,
142
+ },
143
+ },
144
+ {
145
+ $lookup: {
146
+ 'from': 'storeAudit',
147
+ 'let': { 'clientId': '$clientId', 'fileDate': '$fileDate', 'totalFilesCount': '$totalFilesCount' },
148
+ 'pipeline': [
150
149
 
151
- // {
152
- // $match: {
153
- // $expr: {
154
- // $and: [
155
- // { $eq: [ '$clientId', '$$client_id' ] },
156
- // { $eq: [ '$fileDate', '$$file_date' ] },
157
- // ],
158
- // },
159
- // },
160
- // },
161
- // {
162
- // $project: {
163
- // completedStores: { $cond: [ { $eq: [ '$storeStatus', 'completed' ] }, 1, 0 ] },
164
- // assignedStores: { $cond: [ { $or: [ { $in: [ '$auditStatus', [ 'inprogress', 'drafted' ] ] }, { $in: [ '$storeStatus', [ 'skipped' ] ] } ] }, 1, 0 ] },
165
- // },
166
- // },
167
- // {
168
- // $group: {
169
- // _id: { clientId: '$clientId', fileDate: '$fileDate' },
170
- // completedStores: { $sum: '$completedStores' },
171
- // assignedStores: { $sum: '$assignedStores' },
172
- // fileCount: { $sum: 1 },
150
+ {
151
+ $match: {
152
+ $expr: {
153
+ $and: [
154
+ { $eq: [ '$clientId', '$$clientId' ] },
155
+ { $eq: [ '$fileDate', '$$fileDate' ] },
156
+ ],
157
+ },
158
+ },
159
+ },
160
+ {
161
+ $project: {
162
+ completedStores: { $cond: [ { $eq: [ '$status', 'completed' ] }, 1, 0 ] },
163
+ assignedStores: { $cond: [ { $ne: [ '$status', [ 'completed' ] ] }, 1, 0 ] },
164
+ },
165
+ },
166
+ {
167
+ $group: {
168
+ _id: { clientId: '$clientId', fileDate: '$fileDate' },
169
+ completedStores: { $sum: '$completedStores' },
170
+ assignedStores: { $sum: '$assignedStores' },
171
+ fileCount: { $sum: 1 },
173
172
 
174
- // },
175
- // },
176
- // {
177
- // $project: {
178
- // _id: 0,
179
- // fileDateISO: 1,
180
- // completedStores: 1,
181
- // assignedStores: 1,
182
- // completePercentage: {
183
- // $round: [ {
184
- // $multiply: [
185
- // 100, {
186
- // $divide: [
187
- // '$completedStores', '$$total_files_count',
188
- // ],
189
- // },
190
- // ],
191
- // }, 1 ],
173
+ },
174
+ },
175
+ {
176
+ $project: {
177
+ _id: 0,
178
+ fileDateISO: 1,
179
+ completedStores: 1,
180
+ assignedStores: 1,
181
+ completePercentage: {
182
+ $round: [ {
183
+ $multiply: [
184
+ 100, {
185
+ $divide: [
186
+ '$completedStores', '$$totalFilesCount',
187
+ ],
188
+ },
189
+ ],
190
+ }, 1 ],
192
191
 
193
- // },
194
- // fileCount: 1,
195
- // },
192
+ },
193
+ fileCount: 1,
194
+ },
196
195
 
197
- // },
198
- // ], 'as': 'audit',
199
- // },
200
- // },
201
- // {
202
- // $unwind: { path: '$audit', preserveNullAndEmptyArrays: true },
203
- // },
204
- // {
205
- // $project: {
206
- // _id: 0,
207
- // clientId: 1,
208
- // clientName: 1,
209
- // fileDate: 1,
210
- // fileDateISO: 1,
211
- // installedStore: 1,
212
- // totalFilesCount: 1,
213
- // queueName: 1,
214
- // completedStores: { $ifNull: [ '$audit.completedStores', 0 ] },
215
- // assignedStores: { $ifNull: [ '$audit.assignedStores', 0 ] },
216
- // completePercentage: { $ifNull: [ '$audit.completePercentage', 0 ] },
217
- // notAssigned: '',
218
- // status: '',
219
- // fileCount: { $ifNull: [ '$audit.fileCount', 0 ] },
220
- // },
221
- // },
196
+ },
197
+ ], 'as': 'audit',
198
+ },
199
+ },
200
+ {
201
+ $unwind: { path: '$audit', preserveNullAndEmptyArrays: true },
202
+ },
203
+ {
204
+ $project: {
205
+ _id: 0,
206
+ clientId: 1,
207
+ clientName: 1,
208
+ fileDate: 1,
209
+ fileDateISO: 1,
210
+ installedStore: 1,
211
+ totalFilesCount: 1,
212
+ queueName: 1,
213
+ completedStores: { $ifNull: [ '$audit.completedStores', 0 ] },
214
+ assignedStores: { $ifNull: [ '$audit.assignedStores', 0 ] },
215
+ completePercentage: { $ifNull: [ '$audit.completePercentage', 0 ] },
216
+ notAssigned: '',
217
+ status: '',
218
+ fileCount: { $ifNull: [ '$audit.fileCount', 0 ] },
219
+ },
220
+ },
222
221
 
223
- // ];
224
- // query.push( {
225
- // $sort: {
226
- // fileDateISO: -1,
227
- // },
228
- // } );
222
+ ];
223
+ query.push( {
224
+ $sort: {
225
+ fileDateISO: -1,
226
+ },
227
+ } );
229
228
 
230
- // if ( inputData.searchValue && inputData.searchValue !== '' ) {
231
- // query.push( {
232
- // $match: {
233
- // $or: [
234
- // { clientId: { $regex: inputData.searchValue, $options: 'i' } },
235
- // { clientName: { $regex: inputData.searchValue, $options: 'i' } },
236
- // ],
237
- // },
238
- // } );
239
- // }
240
- // const result = await auditFilesCount.aggregate( query );
229
+ if ( inputData.searchValue && inputData.searchValue !== '' ) {
230
+ query.push( {
231
+ $match: {
232
+ $or: [
233
+ { clientId: { $regex: inputData.searchValue, $options: 'i' } },
234
+ { clientName: { $regex: inputData.searchValue, $options: 'i' } },
235
+ ],
236
+ },
237
+ } );
238
+ }
239
+ const result = await aggregateAuditClientData( query );
241
240
 
242
- // if ( result.length == 0 ) {
243
- // return res.sendError( 'No data Found', 204 );
244
- // }
245
- // let count;
246
- // if ( inputData.filterByStatus && inputData.filterByStatus.length > 0 ) {
247
- // let testCount;
248
- // for ( let i = 0; i < result.length; i++ ) {
249
- // const item = result[i];
250
- // if ( inputData.fromDate === inputData.toDate && inputData.fromDate === today ) {
251
- // const temp = await listQueue( item.queueName );
252
- // item.notAssigned = Number( temp );
253
- // } else {
254
- // item.notAssigned = 'No Data';
255
- // }
256
- // item.status = ( item.totalFilesCount === item.completedStores && item.assignedStores === 0 && ( item.notAssigned == 0 || item.notAssigned === 'No Data' ) ) ? 'completed' :
257
- // item.fileCount > 0 ? 'pending' : 'not_taken';
258
- // delete item.fileCount;
259
- // testCount = result.filter( ( i ) => inputData.filterByStatus.includes( i.status ) );
260
- // count = testCount.length;
261
- // }
262
- // if ( !inputData.export ) {
263
- // const skip = ( inputData.offset - 1 ) * inputData.limit;
264
- // testCount = testCount.slice( skip, skip + inputData.limit );
265
- // }
266
- // if ( inputData.export ) {
267
- // const exportdata = [];
268
- // testCount.forEach( ( element ) => {
269
- // exportdata.push( {
270
- // 'File Date': element.fileDate,
271
- // 'Client Name': element.clientName,
272
- // 'Client Id': element.clientId,
273
- // 'Completed Percentage': element.completePercentage + ' %',
274
- // 'Installed Stores': element.installedStore,
275
- // 'Audit Stores': element.totalFilesCount,
276
- // 'Inprogress Stores': element.assignedStores,
277
- // 'Not Assigned': element.notAssigned && element.notAssigned == 'No Data' ? 0 : element.notAssigned,
278
- // 'Completed': element.completedStores,
279
- // 'Status': element.status,
280
- // } );
281
- // } );
282
- // await download( exportdata, res );
283
- // return;
284
- // }
285
- // return res.sendSuccess( { result: testCount, count: count } );
286
- // }
287
- // for ( let i = 0; i < result.length; i++ ) {
288
- // const item = result[i];
289
- // if ( inputData.fromDate === inputData.toDate && inputData.fromDate === today ) {
290
- // const temp = await listQueue( item.queueName );
291
- // item.notAssigned = Number( temp );
292
- // } else {
293
- // item.notAssigned = 'No Data';
294
- // }
295
- // item.status = ( item.totalFilesCount === item.completedStores && item.assignedStores === 0 && ( item.notAssigned == 0 || item.notAssigned === 'No Data' ) ) ? 'completed' :
296
- // item.fileCount > 0 ? 'pending' : 'not_taken';
297
- // delete item.fileCount;
298
- // }
299
- // if ( inputData.export ) {
300
- // const exportdata = [];
301
- // result.forEach( ( element ) => {
302
- // exportdata.push( {
303
- // 'File Date': element.fileDate,
304
- // 'Client Name': element.clientName,
305
- // 'Client Id': element.clientId,
306
- // 'Completed Percentage': element.completePercentage + ' %',
307
- // 'Installed Stores': element.installedStore,
308
- // 'Audit Stores': element.totalFilesCount,
309
- // 'Assigned Stores': element.assignedStores,
310
- // 'Not Assigned': element.notAssigned && element.notAssigned == 'No Data' ? 0 : element.notAssigned,
311
- // 'Completed': element.completedStores,
312
- // 'Status': element.status,
313
- // } );
314
- // } );
315
- // await download( exportdata, res );
316
- // return;
317
- // }
318
- // return res.sendSuccess( { result: result, count: count } );
319
- // } catch ( error ) {
320
- // logger.error( { error: error, data: req.body, function: 'storeMetrics' } );
321
- // return res.sendError( error, 500 );
322
- // }
241
+ if ( result.length == 0 ) {
242
+ return res.sendError( 'No data Found', 204 );
243
+ }
244
+ let count;
245
+ if ( inputData.filterByStatus && inputData.filterByStatus.length > 0 ) {
246
+ let testCount;
247
+ for ( let i = 0; i < result.length; i++ ) {
248
+ const item = result[i];
249
+ if ( inputData.fromDate === inputData.toDate && inputData.fromDate === yesterday ) {
250
+ const temp = await listQueue( item.queueName );
251
+ item.notAssigned = Number( temp );
252
+ } else {
253
+ item.notAssigned = 'No Data';
254
+ }
255
+ item.status = ( item.totalFilesCount === item.completedStores && item.assignedStores === 0 && ( item.notAssigned == 0 || item.notAssigned === 'No Data' ) ) ? 'completed' :
256
+ item.fileCount > 0 ? 'pending' : 'not_taken';
257
+ delete item.fileCount;
258
+ testCount = result.filter( ( i ) => inputData.filterByStatus.includes( i.status ) );
259
+ count = testCount.length;
260
+ }
261
+ if ( !inputData.isExport ) {
262
+ const skip = ( inputData.offset - 1 ) * inputData.limit;
263
+ testCount = testCount.slice( skip, skip + inputData.limit );
264
+ }
265
+ if ( inputData.isExport ) {
266
+ const exportdata = [];
267
+ testCount.forEach( ( element ) => {
268
+ exportdata.push( {
269
+ 'File Date': element.fileDate,
270
+ 'Client Name': element.clientName,
271
+ 'Client Id': element.clientId,
272
+ 'Completed Percentage': element.completePercentage + ' %',
273
+ 'Installed Stores': element.installedStore,
274
+ 'Audit Stores': element.totalFilesCount,
275
+ 'Inprogress Stores': element.assignedStores,
276
+ 'Not Assigned': element.notAssigned && element.notAssigned == 'No Data' ? 0 : element.notAssigned,
277
+ 'Completed': element.completedStores,
278
+ 'Status': element.status,
279
+ } );
280
+ } );
281
+ await download( exportdata, res );
282
+ return;
283
+ }
284
+ return res.sendSuccess( { result: testCount, count: count } );
285
+ }
286
+ for ( let i = 0; i < result.length; i++ ) {
287
+ const item = result[i];
288
+ if ( inputData.fromDate === inputData.toDate && inputData.fromDate === yesterday ) {
289
+ const temp = await listQueue( item.queueName );
290
+ item.notAssigned = Number( temp );
291
+ } else {
292
+ item.notAssigned = 'No Data';
293
+ }
294
+ item.status = ( item.totalFilesCount === item.completedStores && item.assignedStores === 0 && ( item.notAssigned == 0 || item.notAssigned === 'No Data' ) ) ? 'completed' :
295
+ item.fileCount > 0 ? 'pending' : 'not_taken';
296
+ delete item.fileCount;
297
+ }
298
+ if ( inputData.isExport ) {
299
+ const exportdata = [];
300
+ result.forEach( ( element ) => {
301
+ exportdata.push( {
302
+ 'File Date': element.fileDate,
303
+ 'Client Name': element.clientName,
304
+ 'Client Id': element.clientId,
305
+ 'Completed Percentage': element.completePercentage + ' %',
306
+ 'Installed Stores': element.installedStore,
307
+ 'Audit Stores': element.totalFilesCount,
308
+ 'Assigned Stores': element.assignedStores,
309
+ 'Not Assigned': element.notAssigned && element.notAssigned == 'No Data' ? 0 : element.notAssigned,
310
+ 'Completed': element.completedStores,
311
+ 'Status': element.status,
312
+ } );
313
+ } );
314
+ await download( exportdata, res );
315
+ return;
316
+ }
317
+ return res.sendSuccess( { result: result, count: count } );
318
+ } catch ( error ) {
319
+ const err = error.message || 'Internal Server Error';
320
+ logger.error( { error: error, data: req.body, function: 'storeMetrics' } );
321
+ return res.sendError( err, 500 );
322
+ }
323
323
  }
324
324
 
325
325
  export async function clientMetrics( req, res ) {
@@ -22,7 +22,7 @@ export async function clients( req, res ) {
22
22
 
23
23
  const count = await aggregateClient( query );
24
24
  if ( count.length == 0 ) {
25
- return res.sendError( 'No Data Found', 204 );
25
+ return res.sendSuccess( { result: [], count: 0 } );
26
26
  }
27
27
  if ( inputData.limit ) {
28
28
  const offset = inputData.offset ? ( inputData.offset - 1 ) * inputData.limit : 0;
@@ -0,0 +1,77 @@
1
+ import { logger } from 'tango-app-api-middleware';
2
+ import { aggregateAuditClientData } from '../service/auditClientData.service.js';
3
+
4
+ export async function auditStoreList( req, res ) {
5
+ try {
6
+ const inputData = req.query;
7
+ const query =[
8
+ {
9
+ $match: {
10
+ clientId: { $eq: inputData.clientId },
11
+ fileDate: { $eq: inputData.fileDate },
12
+ },
13
+ },
14
+ {
15
+ $project: {
16
+ _id: 0,
17
+ clientName: 1,
18
+ clientId: 1,
19
+ storeList: 1,
20
+ },
21
+ },
22
+ {
23
+ $lookup: {
24
+ from: 'stores',
25
+ let: { storeList: '$storeList' },
26
+ pipeline: [
27
+ {
28
+ $match: {
29
+ $expr: {
30
+ $in: [ '$storeId', '$$storeList' ],
31
+ },
32
+ },
33
+ },
34
+ {
35
+ $project: {
36
+ _id: 1,
37
+ storeId: 1,
38
+ storeName: 1,
39
+ clientId: 1,
40
+ },
41
+ },
42
+ ], as: 'stores',
43
+ },
44
+
45
+ },
46
+ {
47
+ $unwind: { path: '$stores', preserveNullAndEmptyArrays: true },
48
+ },
49
+ {
50
+ $project: {
51
+ storeName: '$stores.storeName',
52
+ storeId: '$stores.storeId',
53
+ clientId: '$clientId',
54
+ },
55
+ },
56
+ ];
57
+
58
+ const count = await aggregateAuditClientData( query );
59
+ if ( count.length == 0 ) {
60
+ return res.sendSuccess( { result: [], count: 0 } );
61
+ }
62
+ if ( inputData.limit ) {
63
+ const offset = inputData.offset ? ( inputData.offset - 1 ) * inputData.limit : 0;
64
+ query.push(
65
+ { $skip: offset },
66
+ { $limit: limit },
67
+ );
68
+ }
69
+ const getAuditClients = await aggregateAuditClientData( query );
70
+
71
+ return res.sendSuccess( { result: getAuditClients, count: count.length } );
72
+ } catch ( error ) {
73
+ const err = error.message || 'Internal Server Error';
74
+ logger.info( { error: error, messgae: req.query, function: 'auditStoreList' } );
75
+ return res.sendError( err, 500 );
76
+ }
77
+ }
@@ -1,5 +1,5 @@
1
1
  import j2s from 'joi-to-swagger';
2
- import { clientMetricsSchema, getAuditImagesSchema, userAuditHistorySchema } from '../dtos/auditMetrics.dtos.js';
2
+ import { clientMetricsSchema, getAuditImagesSchema, storeMetricsSchema, userAuditHistorySchema } from '../dtos/auditMetrics.dtos.js';
3
3
 
4
4
  export const auditMetricsDocs = {
5
5
 
@@ -69,4 +69,26 @@ export const auditMetricsDocs = {
69
69
  },
70
70
  },
71
71
  },
72
+ '/v3/audit-metrics/store-metrics': {
73
+ post: {
74
+ tags: [ 'Audit Metrics' ],
75
+ description: `Get list of store wise details with date range and client Id`,
76
+ operationId: 'store-metrics',
77
+ parameters: {},
78
+ requestBody: {
79
+ content: {
80
+ 'application/json': {
81
+ schema: j2s( storeMetricsSchema ).swagger,
82
+ },
83
+ },
84
+ },
85
+ responses: {
86
+ 200: { description: 'Successful' },
87
+ 401: { description: 'Unauthorized User' },
88
+ 422: { description: 'Field Error' },
89
+ 500: { description: 'Server Error' },
90
+ 204: { description: 'Not Found' },
91
+ },
92
+ },
93
+ },
72
94
  };
@@ -0,0 +1,45 @@
1
+ import j2s from 'joi-to-swagger';
2
+ import { auditStoreSchema } from '../dtos/store.dtos.js';
3
+
4
+ export const storeDocs = {
5
+ '/v3/audit/store/audit-stores': {
6
+ get: {
7
+ tags: [ 'Audit/Store' ],
8
+ description: 'Get client list which is enable for audit',
9
+ operationId: 'clients',
10
+ parameters: [
11
+ {
12
+ in: 'query',
13
+ name: 'clientId',
14
+ scema: j2s( auditStoreSchema ).swagger,
15
+ require: true,
16
+ },
17
+ {
18
+ in: 'query',
19
+ name: 'fileDate',
20
+ scema: j2s( auditStoreSchema ).swagger,
21
+ require: true,
22
+ },
23
+ {
24
+ in: 'query',
25
+ name: 'limit',
26
+ scema: j2s( auditStoreSchema ).swagger,
27
+ require: false,
28
+ },
29
+ {
30
+ in: 'query',
31
+ name: 'offset',
32
+ scema: j2s( auditStoreSchema ).swagger,
33
+ require: false,
34
+ },
35
+ ],
36
+ responses: {
37
+ 200: { description: 'Successful' },
38
+ 401: { description: 'Unauthorized User' },
39
+ 422: { description: 'Field Error' },
40
+ 500: { description: 'Server Error' },
41
+ 204: { description: 'Not Found' },
42
+ },
43
+ },
44
+ },
45
+ };
@@ -54,6 +54,16 @@ export const saveSchema = joi.object(
54
54
  auditId: joi.string().required(),
55
55
  storeId: joi.string().required(),
56
56
  fileDate: joi.string().required(),
57
+ auditType: joi.string().required(),
58
+ fileDate: joi.string().required(),
59
+ beforeCount: joi.number().required(),
60
+ junkCount: joi.number().required(),
61
+ junk: joi.array().required(),
62
+ employeeCount: joi.number().required(),
63
+ employee: joi.array().required(),
64
+ customerCount: joi.number().required(),
65
+ customer: joi.array().required(),
66
+ queueName: joi.string().required(),
57
67
  },
58
68
  );
59
69
 
@@ -40,8 +40,15 @@ export const storeMetricsSchema = joi.object(
40
40
  {
41
41
  fromDate: joi.string().required(),
42
42
  toDate: joi.string().required(),
43
- searchValue: joi.string().optional(),
44
- clientId: joi.array().required(),
43
+ searchValue: joi.string().optional().allow( '' ),
44
+ filterByClientId: joi.array().required(),
45
+ filterByStoreId: joi.array().optional(),
46
+ filterByStatus: joi.array().optional(),
47
+ sortColumnName: joi.string().optional(),
48
+ sortBy: joi.number().optional(),
49
+ limit: joi.number().optional(),
50
+ offset: joi.number().optional(),
51
+ isExport: joi.boolean().optional(),
45
52
  },
46
53
  );
47
54
 
@@ -0,0 +1,15 @@
1
+ import joi from 'joi';
2
+
3
+
4
+ export const auditStoreSchema = joi.object(
5
+ {
6
+ clientId: joi.string().required(),
7
+ fileDate: joi.string().required(),
8
+ limit: joi.number().optional(),
9
+ offset: joi.number().optional(),
10
+ },
11
+ );
12
+
13
+ export const auditStoreValid = {
14
+ query: auditStoreSchema,
15
+ };
@@ -10,4 +10,5 @@ auditMetricsRouter.post( '/get-audit-images', validate( getAuditImagesValid ), g
10
10
  auditMetricsRouter.post( '/user-audit-history', validate( userAuditHistoryValid ), isAllowedSessionHandler, userAuditHistory );
11
11
  auditMetricsRouter.post( '/store-metrics', validate( storeMetricsValid ), isAllowedSessionHandler, storeMetrics );
12
12
  auditMetricsRouter.post( '/client-metrics', validate( clientMetricsValid ), isAllowedSessionHandler, clientMetrics );
13
+
13
14
  export default auditMetricsRouter;
@@ -0,0 +1,10 @@
1
+ import { Router } from 'express';
2
+ import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
3
+ import { auditStoreList } from '../controllers/store.controllers.js';
4
+ import { auditStoreValid } from '../dtos/store.dtos.js';
5
+
6
+ export const storeRouter = Router();
7
+
8
+ storeRouter.get( '/audit-stores', isAllowedSessionHandler, validate( auditStoreValid ), auditStoreList );
9
+
10
+ export default storeRouter;
@@ -55,4 +55,108 @@ export async function isMasterJsonExists( req, res, next ) {
55
55
  }
56
56
  }
57
57
 
58
+ export async function splitG20000( data ) {
59
+ try {
60
+ const dData = data.filter( ( resData ) => resData.temp_ids >= 20000 );
61
+ return dData;
62
+ } catch ( error ) {
63
+ const err = error.message || 'Internal Server Error';
64
+ logger.error( { error: error, message: req.query, function: 'splitG20000' } );
65
+ return res.sendError( err, 500 );
66
+ }
67
+ }
68
+
69
+ export async function splitB20000( data ) {
70
+ try {
71
+ const dData = data.filter(
72
+ ( resData ) => resData.temp_ids < 20000 && resData.temp_ids > 0,
73
+ );
74
+ return dData;
75
+ } catch ( error ) {
76
+ const err = error.message || 'Internal Server Error';
77
+ logger.error( { error: error, message: req.query, function: 'splitB20000' } );
78
+ return res.sendError( err, 500 );
79
+ }
80
+ }
81
+
82
+ export async function splitE0( data ) {
83
+ try {
84
+ const dData = data.filter( ( resData ) => ( resData.temp_ids == 0 ) );
85
+ return dData;
86
+ } catch ( error ) {
87
+ const err = error.message || 'Internal Server Error';
88
+ logger.error( { error: error, message: req.query, function: 'splitE0' } );
89
+ return res.sendError( err, 500 );
90
+ }
91
+ }
92
+
93
+ export async function mapEmployee( sourceMappingData, employeeData ) {
94
+ try {
95
+ employeeData.filter( ( emp ) => {
96
+ sourceMappingData.find( ( map ) => {
97
+ if ( map.temp_ids === emp.img_name ) {
98
+ map.person_status = 'e';
99
+ }
100
+ } );
101
+ } );
102
+
103
+ return sourceMappingData;
104
+ } catch ( error ) {
105
+ logger.error( error );
106
+ return res.sendError( error, 500 );
107
+ }
108
+ }
109
+
110
+ export async function mapJunk( sourceMappingData, junkData ) {
111
+ try {
112
+ junkData.filter( ( emp ) => {
113
+ sourceMappingData.find( ( map ) => {
114
+ if ( map.temp_ids === emp.img_name ) {
115
+ map.person_status = 'j';
116
+ }
117
+ } );
118
+ } );
119
+ return sourceMappingData;
120
+ } catch ( error ) {
121
+ logger.error( error );
122
+ return res.sendError( error, 500 );
123
+ }
124
+ }
125
+
126
+ export async function mapCustomer( sourceMappingData, customerData ) {
127
+ try {
128
+ const filterCustomerData = await filteredCustomerMap( customerData );
129
+ logger.info( { filterCustomerData: filterCustomerData } );
130
+ const chunkedMappingData = await chunkArray( sourceMappingData, 10 );
131
+
132
+ const promises = chunkedMappingData.map( async ( chunk ) => {
133
+ return mapFunction( chunk, filterCustomerData );
134
+ } );
135
+ const mappedArrays = await Promise.all( promises );
136
+ return mappedArrays.flat();
137
+ } catch ( error ) {
138
+ logger.error( { error: error, type: 'mapCustomer' } );
139
+ return error;
140
+ }
141
+ }
142
+
143
+ const filteredCustomerMap = async ( data ) => {
144
+ return data.filter( ( map ) => map.count >= 1 );
145
+ };
146
+
147
+ const mapFunction = async ( chunkData, filterData ) => {
148
+ for ( const data of filterData ) {
149
+ const mappedIds = data.mappedid;
150
+ for ( const mappedId of mappedIds ) {
151
+ chunkData.find( ( item ) => {
152
+ if ( mappedId.img_name === item.temp_ids ) {
153
+ item.temp_ids = data.img_name;
154
+ item.query_status = '';
155
+ }
156
+ } );
157
+ }
158
+ }
159
+ return chunkData;
160
+ };
161
+
58
162