tango-app-api-client 3.4.3-beta.4 → 3.6.0
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/.eslintrc.cjs +1 -1
- package/build.js +25 -0
- package/package.json +46 -43
- package/src/controllers/client.controllers.js +1116 -342
- package/src/docs/client.docs.js +2 -10
- package/src/dtos/client.dtos.js +48 -2
- package/src/hbs/approved-client.hbs +170 -170
- package/src/routes/client.routes.js +16 -2
- package/src/service/auditConfig.service.js +13 -0
- package/src/service/client.service.js +6 -0
- package/src/service/revopConfig.service.js +16 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { billingDetailsUpdate, brandInfoUpdate, domainDetailsConfigurationUpdate, featureConfigurationUpdate, getClientData, signatoryDetailsUpdate, ticketConfigurationUpdate, documentsUpdate, getUserData, CsmUsersGet, OpsUsersGet, userConfigurationUpdate, findClient, aggregateClient, createAuditQueue, findOne, insert, update, findOneClient, updateOneClient } from '../service/client.service.js';
|
|
2
|
-
import { checkFileExist,
|
|
2
|
+
import { checkFileExist, signedUrl, chunkArray, download, logger, getOpenSearchData, insertOpenSearchData, sendEmailWithSES, createCustomer, createVirtualAccount, getUuid, fileRestrictedUpload, getXsscheck } from 'tango-app-api-middleware';
|
|
3
3
|
import { countDocumentsUser, findOneAndUpdateUser, findOneUser, getUserNameEmailById, updateManyUser } from '../service/user.service.js';
|
|
4
4
|
import { aggregateStore, countDocumentsStore, findStore, updateManyStore } from '../service/store.service.js';
|
|
5
5
|
import { aggregateCamera, countDocumentsCamera } from '../service/camera.service.js';
|
|
@@ -10,16 +10,18 @@ import { aggregateTickets } from '../service/tangoticket.service.js';
|
|
|
10
10
|
import { join } from 'path';
|
|
11
11
|
import { readFileSync } from 'fs';
|
|
12
12
|
import handlebars from 'handlebars';
|
|
13
|
-
import { countDocumentsGroup, createGroupModel
|
|
13
|
+
import { countDocumentsGroup, createGroupModel } from '../service/group.service.js';
|
|
14
14
|
// import { deleteOneAuthentication } from '../service/authentication.service.js';
|
|
15
15
|
import { createBilling } from '../service/billing.service.js';
|
|
16
16
|
import { createPaymentAccount } from '../service/paymentAccount.service.js';
|
|
17
17
|
import { countDocumentsClusters, createclusterModel } from '../service/cluster.service.js';
|
|
18
18
|
import { countDocumentsTeams } from '../service/teams.service.js';
|
|
19
|
+
import { createauditConfig, updateauditConfig, aggregateAuditconfig } from '../service/auditConfig.service.js';
|
|
20
|
+
import { findOnerevopConfig, createrevopConfig, updaterevopConfig } from '../service/revopConfig.service.js';
|
|
19
21
|
|
|
20
22
|
export async function create( req, res ) {
|
|
21
23
|
try {
|
|
22
|
-
const url = JSON.parse( process.env.URL );
|
|
24
|
+
// const url = JSON.parse( process.env.URL );
|
|
23
25
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
24
26
|
const inputData = req.body;
|
|
25
27
|
const countQuery = [
|
|
@@ -37,7 +39,6 @@ export async function create( req, res ) {
|
|
|
37
39
|
];
|
|
38
40
|
const ID = await aggregateClient( countQuery );
|
|
39
41
|
const count = ID[0]?.tangoId || 0;
|
|
40
|
-
logger.info( { count: count } );
|
|
41
42
|
const query = { clientName: inputData.clientName };
|
|
42
43
|
const leadRecord = await findOne( query );
|
|
43
44
|
const tangoId = count + 1;
|
|
@@ -71,14 +72,19 @@ export async function create( req, res ) {
|
|
|
71
72
|
'planDetails.product': product,
|
|
72
73
|
'profileDetails.website': leadRecord?.websiteUrl,
|
|
73
74
|
'reportConfigs.reportName': generatedName,
|
|
74
|
-
'auditConfigs.queueName': generatedName,
|
|
75
75
|
'auditConfigs.zoneQueueName': `${generatedName}-zone`,
|
|
76
76
|
'auditConfigs.trafficQueueName': `${generatedName}-traffic`,
|
|
77
|
+
'auditConfigs.trackQueueName': `${generatedName}-track`,
|
|
77
78
|
'auditConfigs.traxQueueName.unattendedCustomer': `${generatedName}-unattendedCustomer`,
|
|
78
79
|
'auditConfigs.traxQueueName.leftInMiddle': `${generatedName}-leftInMiddle`,
|
|
79
80
|
'auditConfigs.traxQueueName.uniformDetection': `${generatedName}-uniformDetection`,
|
|
80
81
|
'auditConfigs.traxQueueName.mobileDetection': `${generatedName}-mobileDetection`,
|
|
81
82
|
'auditConfigs.traxQueueName.cameraAngleChange': `${generatedName}-cameraAngleChange`,
|
|
83
|
+
'auditConfigs.traxQueueName.hygiene': `${generatedName}-hygiene`,
|
|
84
|
+
'clientApi.apiKey': await getUuid(),
|
|
85
|
+
'clientApi.status': true,
|
|
86
|
+
'clientApi.allowedIps': [ '*' ],
|
|
87
|
+
|
|
82
88
|
};
|
|
83
89
|
|
|
84
90
|
record.featureConfigs = {};
|
|
@@ -94,7 +100,7 @@ export async function create( req, res ) {
|
|
|
94
100
|
record.featureConfigs.isNewZone = true;
|
|
95
101
|
}
|
|
96
102
|
if ( data.productName === 'tangoTrax' ) {
|
|
97
|
-
record.featureConfigs.
|
|
103
|
+
record.featureConfigs.isTrax = true;
|
|
98
104
|
}
|
|
99
105
|
}
|
|
100
106
|
}
|
|
@@ -140,7 +146,23 @@ export async function create( req, res ) {
|
|
|
140
146
|
'isDefaults': true,
|
|
141
147
|
};
|
|
142
148
|
|
|
143
|
-
await createclusterModel( defaultcluster );
|
|
149
|
+
const cluster = await createclusterModel( defaultcluster );
|
|
150
|
+
|
|
151
|
+
const logClusterObj = {
|
|
152
|
+
clientId: insertedClientRecord.clientId,
|
|
153
|
+
userName: req.user?.userName,
|
|
154
|
+
userId: req?.user?._id,
|
|
155
|
+
email: req.user?.email,
|
|
156
|
+
clusterId: cluster._id,
|
|
157
|
+
date: new Date(),
|
|
158
|
+
logType: 'cluster',
|
|
159
|
+
logSubType: 'clusterCreated',
|
|
160
|
+
changes: [ 'All stores' ],
|
|
161
|
+
eventType: 'create',
|
|
162
|
+
showTo: [ 'client', 'tango' ],
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
await insertOpenSearchData( openSearch.activityLog, logClusterObj );
|
|
144
166
|
|
|
145
167
|
|
|
146
168
|
const defaultGroup = {
|
|
@@ -160,128 +182,122 @@ export async function create( req, res ) {
|
|
|
160
182
|
|
|
161
183
|
await createBilling( primaryBillingGroup );
|
|
162
184
|
|
|
163
|
-
const createdGroup = await findOneGroup( { clientId: insertedClientRecord.clientId, isDefault: true }, {} );
|
|
164
|
-
|
|
165
|
-
let oldGroup = {
|
|
166
|
-
'_id': createdGroup._id,
|
|
167
|
-
'client_id': createdGroup.clientId,
|
|
168
|
-
'groupName': createdGroup.groupName,
|
|
169
|
-
'description': createdGroup.description,
|
|
170
|
-
'storeList': createdGroup.storeList,
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
await postApi( `${url.oldapidomain}/oldGroupAdd`, [ oldGroup ] );
|
|
175
|
-
|
|
176
185
|
// For old dashboard insert
|
|
186
|
+
// const createdGroup = await findOneGroup( { clientId: insertedClientRecord.clientId, isDefault: true }, {} );
|
|
187
|
+
// let oldGroup = {
|
|
188
|
+
// '_id': createdGroup._id,
|
|
189
|
+
// 'client_id': createdGroup.clientId,
|
|
190
|
+
// 'groupName': createdGroup.groupName,
|
|
191
|
+
// 'description': createdGroup.description,
|
|
192
|
+
// 'storeList': createdGroup.storeList,
|
|
193
|
+
// };
|
|
194
|
+
// await postApi( `${url.oldapidomain}/oldGroupAdd`, [ oldGroup ] );
|
|
195
|
+
|
|
196
|
+
// const oldBrandInsertData = {
|
|
197
|
+
// '_id': insertedClientRecord._id,
|
|
198
|
+
// 'brandName': insertedClientRecord.clientName,
|
|
199
|
+
// 'brandIndex': insertedClientRecord.tangoId,
|
|
200
|
+
// 'client_id': insertedClientRecord.clientId,
|
|
201
|
+
// 'phone': user.mobileNumber,
|
|
202
|
+
// 'email': user.email,
|
|
203
|
+
// 'dialCode': user.countryCode,
|
|
204
|
+
// 'name': user.userName,
|
|
205
|
+
// 'cameraCount': insertedClientRecord.planDetails.totalCamera,
|
|
206
|
+
// 'apiKey': insertedClientRecord.clientApi.apiKey,
|
|
207
|
+
// 'clientStatus': insertedClientRecord.status,
|
|
208
|
+
// 'client_type': insertedClientRecord.planDetails.paymentStatus,
|
|
209
|
+
// 'activeMenu': [
|
|
210
|
+
// 'reports',
|
|
211
|
+
// 'birdsEye',
|
|
212
|
+
// 'tangoZone',
|
|
213
|
+
// 'tangoTraffic',
|
|
214
|
+
// 'support',
|
|
215
|
+
// ],
|
|
216
|
+
// 'planType': insertedClientRecord.planDetails.subscriptionPeriod,
|
|
217
|
+
// 'storeCount': insertedClientRecord.planDetails.totalStores,
|
|
218
|
+
// 'squareFeet': insertedClientRecord.planDetails.storeSize,
|
|
219
|
+
// 'subscription': insertedClientRecord.planDetails.subscriptionType,
|
|
220
|
+
// 'subscription_status': true,
|
|
221
|
+
// 'subscribed_features': {
|
|
222
|
+
// 'tango_traffic': false,
|
|
223
|
+
// 'tango_zone': false,
|
|
224
|
+
// 'tango_revop': false,
|
|
225
|
+
// 'tango_storeops': false,
|
|
226
|
+
// 'controlroom': false,
|
|
227
|
+
// 'live_data': false,
|
|
228
|
+
// 'normalization_features': false,
|
|
229
|
+
// 'actual_features': false,
|
|
230
|
+
// },
|
|
231
|
+
// 'store_added_status': true,
|
|
232
|
+
// 'terms_conditions': true,
|
|
233
|
+
// 'otp_verified': true,
|
|
234
|
+
// 'price': 6510,
|
|
235
|
+
// 'currency_type': 'rupees',
|
|
236
|
+
// 'domains': [],
|
|
237
|
+
// 'store_radius_config': 500,
|
|
238
|
+
// };
|
|
239
|
+
|
|
240
|
+
// insertedClientRecord.planDetails.product.forEach( ( element ) => {
|
|
241
|
+
// if ( element.productName === 'tangoTraffic' ) {
|
|
242
|
+
// oldBrandInsertData.subscribed_features.tango_traffic = true;
|
|
243
|
+
// }
|
|
244
|
+
// if ( element.productName === 'tangoZone' ) {
|
|
245
|
+
// oldBrandInsertData.subscribed_features.tango_zone = true;
|
|
246
|
+
// }
|
|
247
|
+
// if ( element.productName === 'prioritySupport' ) {
|
|
248
|
+
// oldBrandInsertData.subscribed_features.tango_storeops = true;
|
|
249
|
+
// }
|
|
250
|
+
// } );
|
|
251
|
+
|
|
252
|
+
// switch ( insertedClientRecord.status ) {
|
|
253
|
+
// case 'active':
|
|
254
|
+
// oldBrandInsertData.clientStatus = 'live';
|
|
255
|
+
// break;
|
|
256
|
+
// case 'hold':
|
|
257
|
+
// oldBrandInsertData.clientStatus = 'hold';
|
|
258
|
+
// break;
|
|
259
|
+
// case 'suspended':
|
|
260
|
+
// oldBrandInsertData.clientStatus = 'suspended';
|
|
261
|
+
// break;
|
|
262
|
+
// case 'deactive':
|
|
263
|
+
// oldBrandInsertData.clientStatus = 'deactivated';
|
|
264
|
+
// break;
|
|
265
|
+
// default:
|
|
266
|
+
// oldBrandInsertData.clientStatus = 'live';
|
|
267
|
+
// }
|
|
268
|
+
|
|
269
|
+
// switch ( insertedClientRecord.planDetails.paymentStatus ) {
|
|
270
|
+
// case 'free':
|
|
271
|
+
// oldBrandInsertData.client_type = 'free';
|
|
272
|
+
// break;
|
|
273
|
+
// case 'trial':
|
|
274
|
+
// oldBrandInsertData.client_type = 'trial';
|
|
275
|
+
// break;
|
|
276
|
+
// case 'paid':
|
|
277
|
+
// oldBrandInsertData.client_type = 'paid';
|
|
278
|
+
// break;
|
|
279
|
+
// default:
|
|
280
|
+
// oldBrandInsertData.client_type = 'trial';
|
|
281
|
+
// }
|
|
282
|
+
// await postApi( `${url.oldapidomain}/oldBrandAdd`, oldBrandInsertData );
|
|
283
|
+
|
|
284
|
+
// const oldDefaultRolesInsertData = {
|
|
285
|
+
// '_id': user._id,
|
|
286
|
+
// 'client_id': insertedClientRecord.clientId,
|
|
287
|
+
// 'brandId': insertedClientRecord._id,
|
|
288
|
+
// 'name': user.userName,
|
|
289
|
+
// 'email': user.email,
|
|
290
|
+
// 'phone': user.mobileNumber,
|
|
291
|
+
// 'password': user.password,
|
|
292
|
+
// 'role': 'storesuperadmin',
|
|
293
|
+
// };
|
|
294
|
+
// await postApi( `${url.oldapidomain}/oldDefaultRoleInsert`, oldDefaultRolesInsertData );
|
|
177
295
|
|
|
178
296
|
|
|
179
|
-
const oldBrandInsertData = {
|
|
180
|
-
'_id': insertedClientRecord._id,
|
|
181
|
-
'brandName': insertedClientRecord.clientName,
|
|
182
|
-
'brandIndex': insertedClientRecord.tangoId,
|
|
183
|
-
'client_id': insertedClientRecord.clientId,
|
|
184
|
-
'phone': user.mobileNumber,
|
|
185
|
-
'email': user.email,
|
|
186
|
-
'dialCode': user.countryCode,
|
|
187
|
-
'name': user.userName,
|
|
188
|
-
'cameraCount': insertedClientRecord.planDetails.totalCamera,
|
|
189
|
-
'apiKey': insertedClientRecord.clientApi.apiKey,
|
|
190
|
-
'clientStatus': insertedClientRecord.status,
|
|
191
|
-
'client_type': insertedClientRecord.planDetails.paymentStatus,
|
|
192
|
-
'activeMenu': [
|
|
193
|
-
'reports',
|
|
194
|
-
'birdsEye',
|
|
195
|
-
'tangoZone',
|
|
196
|
-
'tangoTraffic',
|
|
197
|
-
'support',
|
|
198
|
-
],
|
|
199
|
-
'planType': insertedClientRecord.planDetails.subscriptionPeriod,
|
|
200
|
-
'storeCount': insertedClientRecord.planDetails.totalStores,
|
|
201
|
-
'squareFeet': insertedClientRecord.planDetails.storeSize,
|
|
202
|
-
'subscription': insertedClientRecord.planDetails.subscriptionType,
|
|
203
|
-
'subscription_status': true,
|
|
204
|
-
'subscribed_features': {
|
|
205
|
-
'tango_traffic': false,
|
|
206
|
-
'tango_zone': false,
|
|
207
|
-
'tango_revop': false,
|
|
208
|
-
'tango_storeops': false,
|
|
209
|
-
'controlroom': false,
|
|
210
|
-
'live_data': false,
|
|
211
|
-
'normalization_features': false,
|
|
212
|
-
'actual_features': false,
|
|
213
|
-
},
|
|
214
|
-
'store_added_status': true,
|
|
215
|
-
'terms_conditions': true,
|
|
216
|
-
'otp_verified': true,
|
|
217
|
-
'price': 6510,
|
|
218
|
-
'currency_type': 'rupees',
|
|
219
|
-
'domains': [],
|
|
220
|
-
'store_radius_config': 500,
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
insertedClientRecord.planDetails.product.forEach( ( element ) => {
|
|
224
|
-
if ( element.productName === 'tangoTraffic' ) {
|
|
225
|
-
oldBrandInsertData.subscribed_features.tango_traffic = true;
|
|
226
|
-
}
|
|
227
|
-
if ( element.productName === 'tangoZone' ) {
|
|
228
|
-
oldBrandInsertData.subscribed_features.tango_zone = true;
|
|
229
|
-
}
|
|
230
|
-
if ( element.productName === 'prioritySupport' ) {
|
|
231
|
-
oldBrandInsertData.subscribed_features.tango_storeops = true;
|
|
232
|
-
}
|
|
233
|
-
} );
|
|
234
|
-
|
|
235
|
-
switch ( insertedClientRecord.status ) {
|
|
236
|
-
case 'active':
|
|
237
|
-
oldBrandInsertData.clientStatus = 'live';
|
|
238
|
-
break;
|
|
239
|
-
case 'hold':
|
|
240
|
-
oldBrandInsertData.clientStatus = 'hold';
|
|
241
|
-
break;
|
|
242
|
-
case 'suspended':
|
|
243
|
-
oldBrandInsertData.clientStatus = 'suspended';
|
|
244
|
-
break;
|
|
245
|
-
case 'deactive':
|
|
246
|
-
oldBrandInsertData.clientStatus = 'deactivated';
|
|
247
|
-
break;
|
|
248
|
-
default:
|
|
249
|
-
oldBrandInsertData.clientStatus = 'live';
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
switch ( insertedClientRecord.planDetails.paymentStatus ) {
|
|
253
|
-
case 'free':
|
|
254
|
-
oldBrandInsertData.client_type = 'free';
|
|
255
|
-
break;
|
|
256
|
-
case 'trial':
|
|
257
|
-
oldBrandInsertData.client_type = 'trial';
|
|
258
|
-
break;
|
|
259
|
-
case 'paid':
|
|
260
|
-
oldBrandInsertData.client_type = 'paid';
|
|
261
|
-
break;
|
|
262
|
-
default:
|
|
263
|
-
oldBrandInsertData.client_type = 'trial';
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const oldDefaultRolesInsertData = {
|
|
268
|
-
'_id': user._id,
|
|
269
|
-
'client_id': insertedClientRecord.clientId,
|
|
270
|
-
'brandId': insertedClientRecord._id,
|
|
271
|
-
'name': user.userName,
|
|
272
|
-
'email': user.email,
|
|
273
|
-
'phone': user.mobileNumber,
|
|
274
|
-
'password': user.password,
|
|
275
|
-
'role': 'storesuperadmin',
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
await postApi( `${url.oldapidomain}/oldBrandAdd`, oldBrandInsertData );
|
|
279
|
-
|
|
280
|
-
await postApi( `${url.oldapidomain}/oldDefaultRoleInsert`, oldDefaultRolesInsertData );
|
|
281
|
-
|
|
282
297
|
const logObj = {
|
|
283
298
|
clientId: insertedClientRecord.clientId,
|
|
284
299
|
userName: req.user?.userName,
|
|
300
|
+
userId: req?.user?._id,
|
|
285
301
|
email: req.user?.email,
|
|
286
302
|
date: new Date(),
|
|
287
303
|
logType: 'brandDetails',
|
|
@@ -330,15 +346,15 @@ export async function create( req, res ) {
|
|
|
330
346
|
// await deleteOneAuthentication( { user: user?._id, type: 'retail' } );
|
|
331
347
|
await findOneAndUpdateUser( userQuery, userRecord );
|
|
332
348
|
await Promise.all( [
|
|
333
|
-
createAuditQueue( generatedName ),
|
|
334
349
|
createAuditQueue( `${generatedName}-zone` ),
|
|
335
350
|
createAuditQueue( `${generatedName}-traffic` ),
|
|
351
|
+
createAuditQueue( `${generatedName}-track` ),
|
|
336
352
|
createAuditQueue( `${generatedName}-unattendedCustomer` ),
|
|
337
353
|
createAuditQueue( `${generatedName}-leftInMiddle` ),
|
|
338
354
|
createAuditQueue( `${generatedName}-uniformDetection` ),
|
|
339
355
|
createAuditQueue( `${generatedName}-mobileDetection` ),
|
|
340
356
|
createAuditQueue( `${generatedName}-cameraAngleChange` ),
|
|
341
|
-
|
|
357
|
+
createAuditQueue( `${generatedName}-hygiene` ) ] );
|
|
342
358
|
return res.sendSuccess( { result: { clientId: String( tangoId ) } } );
|
|
343
359
|
}
|
|
344
360
|
} catch ( error ) {
|
|
@@ -395,7 +411,7 @@ export async function changeStatus( req, res, next ) {
|
|
|
395
411
|
|
|
396
412
|
export async function getClients( req, res ) {
|
|
397
413
|
try {
|
|
398
|
-
const field = { clientName: 1, clientId: 1 };
|
|
414
|
+
const field = { clientName: 1, clientId: 1, traxDateRange: '$featureConfigs.traxDateRange', trafficDateRange: '$featureConfigs.trafficDateRange' };
|
|
399
415
|
let result = [];
|
|
400
416
|
if ( req?.user?.role === 'superadmin' ) {
|
|
401
417
|
result = await findClient( {}, field );
|
|
@@ -405,18 +421,6 @@ export async function getClients( req, res ) {
|
|
|
405
421
|
$match: {
|
|
406
422
|
userEmail: req?.user?.email,
|
|
407
423
|
assignedType: { $eq: 'client' },
|
|
408
|
-
// $expr: {
|
|
409
|
-
// $cond: {
|
|
410
|
-
// if: {
|
|
411
|
-
// $and: [
|
|
412
|
-
// { $eq: [ '$userType', 'tango' ] },
|
|
413
|
-
// { $eq: [ '$tangoUserType', 'csm' ] },
|
|
414
|
-
// ],
|
|
415
|
-
// },
|
|
416
|
-
// then: { $eq: [ '$isClientApproved', true ] },
|
|
417
|
-
// else: true,
|
|
418
|
-
// },
|
|
419
|
-
// },
|
|
420
424
|
},
|
|
421
425
|
},
|
|
422
426
|
{
|
|
@@ -450,9 +454,9 @@ export async function getClients( req, res ) {
|
|
|
450
454
|
},
|
|
451
455
|
{
|
|
452
456
|
$project: {
|
|
453
|
-
_id: 0,
|
|
454
457
|
clientId: 1,
|
|
455
458
|
clientName: 1,
|
|
459
|
+
traxDateRange: '$featureConfigs.traxDateRange',
|
|
456
460
|
},
|
|
457
461
|
},
|
|
458
462
|
];
|
|
@@ -471,6 +475,7 @@ export async function getClients( req, res ) {
|
|
|
471
475
|
export async function clientDetails( req, res ) {
|
|
472
476
|
try {
|
|
473
477
|
const bucket = JSON.parse( process.env.BUCKET );
|
|
478
|
+
const url=JSON.parse( process.env.URL );
|
|
474
479
|
const client = await getClientData( { id: req.params.id } );
|
|
475
480
|
if ( client ) {
|
|
476
481
|
const isLogoExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
@@ -483,49 +488,48 @@ export async function clientDetails( req, res ) {
|
|
|
483
488
|
|
|
484
489
|
|
|
485
490
|
if ( isLogoExist ) {
|
|
486
|
-
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
491
|
+
const signedFilUrl = `${url.assests}/${client.clientId}/logo/${client.profileDetails?.logo}`; // await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
487
492
|
client.profileDetails.logo = signedFilUrl;
|
|
488
493
|
} else {
|
|
489
494
|
client.profileDetails.logo = '';
|
|
490
495
|
}
|
|
491
496
|
|
|
492
497
|
if ( isGstCertificateExist ) {
|
|
493
|
-
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.gst?.path}` } );
|
|
498
|
+
const signedFilUrl = `${url.assests}/${client.clientId}/documents/${client.document?.gst?.path}`;// await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.gst?.path}` } );
|
|
494
499
|
client.document.gst.path = signedFilUrl;
|
|
495
500
|
} else {
|
|
496
501
|
client.document.gst.path = '';
|
|
497
502
|
}
|
|
498
503
|
|
|
499
504
|
if ( isAddressCertificateExist ) {
|
|
500
|
-
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.addressProof?.path}` } );
|
|
505
|
+
const signedFilUrl = `${url.assests}/${client.clientId}/documents/${client.document?.addressProof?.path}`;// await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.addressProof?.path}` } );
|
|
501
506
|
client.document.addressProof.path = signedFilUrl;
|
|
502
507
|
} else {
|
|
503
508
|
client.document.addressProof.path = '';
|
|
504
509
|
}
|
|
505
|
-
|
|
506
510
|
if ( isPanCertificateExist ) {
|
|
507
|
-
const signedFilUrl
|
|
511
|
+
const signedFilUrl =`${url.assests}/${client.clientId}/documents/${client.document?.pan?.path}`;// await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.pan?.path}` } );
|
|
508
512
|
client.document.pan.path = signedFilUrl;
|
|
509
513
|
} else {
|
|
510
514
|
client.document.pan.path = '';
|
|
511
515
|
}
|
|
512
516
|
|
|
513
517
|
if ( isCinCertificateExist ) {
|
|
514
|
-
const signedFilUrl
|
|
518
|
+
const signedFilUrl =`${url.assests}/${client.clientId}/documents/${client.document?.cin?.path}`;// await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.cin?.path}` } );
|
|
515
519
|
client.document.cin.path = signedFilUrl;
|
|
516
520
|
} else {
|
|
517
521
|
client.document.cin.path = '';
|
|
518
522
|
}
|
|
519
523
|
|
|
520
524
|
if ( isContractCertificateExist ) {
|
|
521
|
-
const signedFilUrl
|
|
525
|
+
const signedFilUrl =`${url.assests}/documents/contract.pdf`;// await signedUrl( { Bucket: bucket.assets, file_path: `documents/contract.pdf` } );
|
|
522
526
|
client._doc.document.contract = signedFilUrl;
|
|
523
527
|
} else {
|
|
524
528
|
client._doc.document.contract = '';
|
|
525
529
|
}
|
|
526
530
|
|
|
527
531
|
if ( isTermsAndConditionsExist ) {
|
|
528
|
-
const signedFilUrl
|
|
532
|
+
const signedFilUrl =`${url.assests}/documents/terms&conditions.pdf`;// await signedUrl( { Bucket: bucket.assets, file_path: `documents/terms&conditions.pdf` } );
|
|
529
533
|
client._doc.document.termsAndconditions = signedFilUrl;
|
|
530
534
|
} else {
|
|
531
535
|
client._doc.document.termsAndconditions = '';
|
|
@@ -672,7 +676,7 @@ export async function detailedAllClientCount( req, res ) {
|
|
|
672
676
|
if ( result.length == 0 ) {
|
|
673
677
|
return res.sendError( 'No Data Found', 204 );
|
|
674
678
|
}
|
|
675
|
-
result[0].activeStoresCount = activeStores.length>0?Math.abs( activeStores.length - yettoInstallCount.length ):0;
|
|
679
|
+
result[0].activeStoresCount = activeStores.length > 0 ? Math.abs( activeStores.length - yettoInstallCount.length ) : 0;
|
|
676
680
|
result[0].activeCameraCount = activeCameras;
|
|
677
681
|
return res.sendSuccess( { result: result } );
|
|
678
682
|
} catch ( error ) {
|
|
@@ -691,9 +695,8 @@ export async function updateBrandInfo( req, res ) {
|
|
|
691
695
|
try {
|
|
692
696
|
const bucket = JSON.parse( process.env.BUCKET );
|
|
693
697
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
694
|
-
const url = JSON.parse( process.env.URL );
|
|
698
|
+
// const url = JSON.parse( process.env.URL );
|
|
695
699
|
let updateKeys = [];
|
|
696
|
-
|
|
697
700
|
if ( req.files?.logo ) {
|
|
698
701
|
const uploadDataParams = {
|
|
699
702
|
Bucket: bucket.assets,
|
|
@@ -702,8 +705,12 @@ export async function updateBrandInfo( req, res ) {
|
|
|
702
705
|
ContentType: req.files.logo.mimetype,
|
|
703
706
|
body: req.files.logo.data,
|
|
704
707
|
};
|
|
705
|
-
updateKeys.push( 'Logo' );
|
|
706
|
-
await
|
|
708
|
+
updateKeys.push( 'Brand Logo' );
|
|
709
|
+
let uploadStatus= await fileRestrictedUpload( uploadDataParams );
|
|
710
|
+
|
|
711
|
+
if ( uploadStatus==false ) {
|
|
712
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
713
|
+
}
|
|
707
714
|
}
|
|
708
715
|
|
|
709
716
|
if ( Object.keys( req.body ).length > 0 ) {
|
|
@@ -712,32 +719,93 @@ export async function updateBrandInfo( req, res ) {
|
|
|
712
719
|
} );
|
|
713
720
|
}
|
|
714
721
|
|
|
715
|
-
|
|
722
|
+
// Get updated client information before the update operation (fetch selected fields only)
|
|
723
|
+
const getPreCientInfo = await findOneClient(
|
|
724
|
+
{ clientId: req.params.id }, // Filter by clientId
|
|
725
|
+
{
|
|
726
|
+
'_id': 0,
|
|
727
|
+
'profileDetails.registeredCompanyName': 1,
|
|
728
|
+
'profileDetails.industry': 1,
|
|
729
|
+
'profileDetails.clientType': 1,
|
|
730
|
+
'profileDetails.registeredAddress': 1,
|
|
731
|
+
'profileDetails.headQuarters': 1,
|
|
732
|
+
'profileDetails.website': 1,
|
|
733
|
+
'status': 1,
|
|
734
|
+
'averageTransactionValue': 1,
|
|
735
|
+
},
|
|
736
|
+
);
|
|
737
|
+
|
|
716
738
|
|
|
739
|
+
const updateAck = await brandInfoUpdate( {
|
|
740
|
+
clientId: req.params?.id, registeredCompanyName: req.body?.registeredCompanyName, industry: req.body?.industry,
|
|
741
|
+
clientType: req.body?.clientType, registeredAddress: req.body?.registeredAddress, headQuarters: req.body?.headQuarters,
|
|
742
|
+
website: req.body?.website, status: req.body?.status, logo: req.files?.logo ? `brandLogo.${req.files.logo.name.split( '.' )[1]}` : undefined, averageTransactionValue: req.body?.averageTransactionValue,
|
|
743
|
+
} );
|
|
744
|
+
|
|
745
|
+
// Get updated client information after the update operation (fetch selected fields only)
|
|
746
|
+
const getPosCientInfo = await findOneClient(
|
|
747
|
+
{ clientId: req.params.id }, // Filter by clientId
|
|
748
|
+
{
|
|
749
|
+
'_id': 0,
|
|
750
|
+
'profileDetails.registeredCompanyName': 1,
|
|
751
|
+
'profileDetails.industry': 1,
|
|
752
|
+
'profileDetails.clientType': 1,
|
|
753
|
+
'profileDetails.registeredAddress': 1,
|
|
754
|
+
'profileDetails.headQuarters': 1,
|
|
755
|
+
'profileDetails.website': 1,
|
|
756
|
+
'status': 1,
|
|
757
|
+
'averageTransactionValue': 1,
|
|
758
|
+
},
|
|
759
|
+
);
|
|
760
|
+
// Map and rename keys from previous client info for UI display and logging
|
|
761
|
+
const oldData = {
|
|
762
|
+
RegisteredCompanyName: getPreCientInfo?.profileDetails?.registeredCompanyName,
|
|
763
|
+
IndustryType: getPreCientInfo?.profileDetails?.industry,
|
|
764
|
+
FirmType: getPreCientInfo?.profileDetails?.clientType,
|
|
765
|
+
RegisteredAddress: getPreCientInfo?.profileDetails?.registeredAddress,
|
|
766
|
+
HeadQuarters: getPreCientInfo?.profileDetails?.headQuarters,
|
|
767
|
+
CompanyWebsite: getPreCientInfo?.profileDetails?.website,
|
|
768
|
+
ProcessingStatus: getPreCientInfo?.status,
|
|
769
|
+
AverageTransactionValue: getPreCientInfo?.averageTransactionValue,
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
// Map and rename keys from current client info for UI display and logging
|
|
773
|
+
const newData = {
|
|
774
|
+
RegisteredCompanyName: getPosCientInfo?.profileDetails?.registeredCompanyName,
|
|
775
|
+
IndustryType: getPosCientInfo?.profileDetails?.industry,
|
|
776
|
+
FirmType: getPosCientInfo?.profileDetails?.clientType,
|
|
777
|
+
RegisteredAddress: getPosCientInfo?.profileDetails?.registeredAddress,
|
|
778
|
+
HeadQuarters: getPosCientInfo?.profileDetails?.headQuarters,
|
|
779
|
+
CompanyWebsite: getPosCientInfo?.profileDetails?.website,
|
|
780
|
+
ProcessingStatus: getPosCientInfo?.status,
|
|
781
|
+
AverageTransactionValue: getPosCientInfo?.averageTransactionValue,
|
|
782
|
+
|
|
783
|
+
};
|
|
717
784
|
|
|
785
|
+
// Prepare activity log object with all relevant details for OpenSearch logging
|
|
718
786
|
const logObj = {
|
|
719
|
-
clientId: req.params?.id,
|
|
720
|
-
userName: user?.userName,
|
|
721
|
-
email: user?.email,
|
|
722
|
-
date: new Date(),
|
|
723
|
-
logType: 'brandDetails',
|
|
724
|
-
logSubType: 'brandInfo',
|
|
725
|
-
changes: updateKeys,
|
|
726
|
-
eventType: 'update',
|
|
727
|
-
showTo: [ 'client', 'tango' ],
|
|
787
|
+
clientId: req.params?.id, // ID of the client whose data was updated
|
|
788
|
+
userName: req?.user?.userName, // Name of the user performing the update
|
|
789
|
+
email: req?.user?.email, // Email of the user performing the update
|
|
790
|
+
date: new Date(), // Timestamp of the update event
|
|
791
|
+
logType: 'brandDetails', // Type of log (e.g., related to brand details)
|
|
792
|
+
logSubType: 'brandInfo', // Subtype for more specific categorization
|
|
793
|
+
changes: updateKeys, // List of fields that were updated.these will shown in the UI as part of activity log
|
|
794
|
+
eventType: 'update', // Type of event (update operation)
|
|
795
|
+
showTo: [ 'client', 'tango' ], // Visibility of the log (who can see this log)
|
|
796
|
+
previous: getPreCientInfo, // Previous (old) client information before update based on DB keys (for internal reference and comparison).
|
|
797
|
+
current: getPosCientInfo, // Current (new) client information after update based on DB keys (for internal reference and comparison).
|
|
798
|
+
oldData: oldData, // Previous (old) client information before update (used for showing detailed changes in the UI).
|
|
799
|
+
newData: newData, // Current (new) client information after update (used for showing detailed changes in the UI).
|
|
728
800
|
};
|
|
801
|
+
logger.info( { logObj: logObj, updateKeys: updateKeys, length: updateKeys?.length } );
|
|
729
802
|
|
|
803
|
+
// Insert activity log into OpenSearch if there are fields that were updated
|
|
730
804
|
if ( updateKeys.length ) {
|
|
731
|
-
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
805
|
+
await insertOpenSearchData( openSearch.activityLog, logObj ); // Insert activity log
|
|
732
806
|
}
|
|
733
807
|
|
|
734
808
|
|
|
735
|
-
const updateAck = await brandInfoUpdate( {
|
|
736
|
-
clientId: req.params?.id, registeredCompanyName: req.body?.registeredCompanyName, industry: req.body?.industry,
|
|
737
|
-
clientType: req.body?.clientType, registeredAddress: req.body?.registeredAddress, headQuarters: req.body?.headQuarters,
|
|
738
|
-
website: req.body?.website, status: req.body?.status, logo: req.files?.logo ? `brandLogo.${req.files.logo.name.split( '.' )[1]}` : undefined, averageTransactionValue: req.body?.averageTransactionValue,
|
|
739
|
-
} );
|
|
740
|
-
|
|
741
809
|
if ( req.body?.status === 'active' ) {
|
|
742
810
|
await updateManyStore( { clientId: req.params?.id }, { status: 'active' } );
|
|
743
811
|
await updateManyUser( { clientId: req.params?.id }, { isActive: true } );
|
|
@@ -754,33 +822,30 @@ export async function updateBrandInfo( req, res ) {
|
|
|
754
822
|
|
|
755
823
|
if ( req.body?.status === 'deactive' ) {
|
|
756
824
|
await updateManyStore( { clientId: req.params?.id }, { status: 'deactive' } );
|
|
757
|
-
// await updateManyCamera( { clientId: req.params?.id }, { isUp: false, isActivated: false } );
|
|
758
825
|
await updateManyUser( { clientId: req.params?.id }, { isActive: false } );
|
|
759
826
|
}
|
|
760
827
|
|
|
761
|
-
const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { clientStatus: data.clientStatus } );
|
|
828
|
+
// const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
829
|
+
// switch ( req.body?.status ) {
|
|
830
|
+
// case 'active':
|
|
831
|
+
// data.clientStatus = 'live';
|
|
832
|
+
// break;
|
|
833
|
+
// case 'hold':
|
|
834
|
+
// data.clientStatus = 'hold';
|
|
835
|
+
// break;
|
|
836
|
+
// case 'suspended':
|
|
837
|
+
// data.clientStatus = 'suspended';
|
|
838
|
+
// break;
|
|
839
|
+
// case 'deactive':
|
|
840
|
+
// data.clientStatus = 'deactivated';
|
|
841
|
+
// break;
|
|
842
|
+
// default:
|
|
843
|
+
// data.clientStatus = 'live';
|
|
844
|
+
// }
|
|
845
|
+
// await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { clientStatus: data.clientStatus } );
|
|
781
846
|
|
|
782
847
|
if ( updateAck ) {
|
|
783
|
-
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
848
|
+
return res.sendSuccess( { result: 'Updated Successfully' } );
|
|
784
849
|
}
|
|
785
850
|
} catch ( error ) {
|
|
786
851
|
logger.error( { error: error, message: req.params, function: 'updateBrandInfo' } );
|
|
@@ -803,7 +868,11 @@ export async function updateBillingDetails( req, res ) {
|
|
|
803
868
|
body: req.files.gstCertificate.data,
|
|
804
869
|
};
|
|
805
870
|
updateKeys.push( 'GST certificate' );
|
|
806
|
-
await
|
|
871
|
+
let uploadStatus= await fileRestrictedUpload( uploadDataParams );
|
|
872
|
+
|
|
873
|
+
if ( uploadStatus==false ) {
|
|
874
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
875
|
+
}
|
|
807
876
|
}
|
|
808
877
|
|
|
809
878
|
if ( Object.keys( req.body ).length > 0 ) {
|
|
@@ -889,6 +958,25 @@ export async function updateSignatoryDetails( req, res ) {
|
|
|
889
958
|
export async function updateTicketConfiguration( req, res ) {
|
|
890
959
|
try {
|
|
891
960
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
961
|
+
const fields = {
|
|
962
|
+
'ticketConfigs.downTimeType': 1,
|
|
963
|
+
'ticketConfigs.installationReAssign': 1,
|
|
964
|
+
'ticketConfigs.infraDownTime': 1,
|
|
965
|
+
'ticketConfigs.MinFilesCount': 1,
|
|
966
|
+
'ticketConfigs.rcaTicketAssign': 1,
|
|
967
|
+
'ticketConfigs.refreshAlert': 1,
|
|
968
|
+
'ticketConfigs.statusCheckAlert': 1,
|
|
969
|
+
'ticketConfigs.accuracyPercentage': 1,
|
|
970
|
+
'ticketConfigs.reTrain': 1,
|
|
971
|
+
};
|
|
972
|
+
|
|
973
|
+
// Get updated client ticket configuration before the update operation (fetch selected fields only)
|
|
974
|
+
let findClient = await findOneClient(
|
|
975
|
+
{ clientId: req.params?.id }, // Filter by clientId
|
|
976
|
+
fields,
|
|
977
|
+
);
|
|
978
|
+
|
|
979
|
+
// update the requested values in Mongo DB
|
|
892
980
|
const updateAck = await ticketConfigurationUpdate( {
|
|
893
981
|
clientId: req.params?.id, MinFilesCount: req.body?.MinFilesCount, accuracyPercentage: req.body?.accuracyPercentage, downTimeType: req.body?.downTimeType,
|
|
894
982
|
infraDownTime: req.body?.infraDownTime, installationReAssign: req.body?.installationReAssign, isRcaTicketAssign: req.body?.isRcaTicketAssign,
|
|
@@ -896,44 +984,85 @@ export async function updateTicketConfiguration( req, res ) {
|
|
|
896
984
|
refreshAlert: req.body?.refreshAlert, sendToAdmin: req.body?.sendToAdmin, sendToUser: req.body?.sendToUser, statusCheckAlert: req.body?.statusCheckAlert,
|
|
897
985
|
} );
|
|
898
986
|
|
|
899
|
-
let updateKeys = [];
|
|
987
|
+
let updateKeys = []; // List of updated field names in readable format
|
|
988
|
+
|
|
989
|
+
// Check if request body has any fields to update
|
|
900
990
|
if ( Object.keys( req.body ).length > 0 ) {
|
|
901
991
|
Object.keys( req.body ).forEach( ( element ) => {
|
|
902
|
-
updateKeys.push( camelCaseToWords( element ) );
|
|
992
|
+
updateKeys.push( camelCaseToWords( element ) ); // Convert camelCase field name to readable format and add to updateKeys
|
|
903
993
|
} );
|
|
904
994
|
}
|
|
905
995
|
|
|
906
|
-
const user = await getUserNameEmailById( req.userId );
|
|
907
996
|
|
|
997
|
+
// Get updated client ticket configuration after the update operation (fetch selected fields only)
|
|
998
|
+
let updatedClient = await findOneClient( { clientId: req.params?.id }, fields );
|
|
999
|
+
|
|
1000
|
+
// Map and rename keys from previous client info for UI display and logging
|
|
1001
|
+
const oldData = {
|
|
1002
|
+
InfraDowntimeType: findClient?.ticketConfigs?.downTimeType == 0 ? 'Single Camera' : 'All Cameras',
|
|
1003
|
+
AutoReAssignInstallation: findClient?.ticketConfigs?.installationReAssign,
|
|
1004
|
+
InfraDowntime: findClient?.ticketConfigs?.infraDownTime,
|
|
1005
|
+
InfraFiles: findClient?.ticketConfigs?.MinFilesCount,
|
|
1006
|
+
RcaTicket: findClient?.ticketConfigs?.rcaTicketAssign,
|
|
1007
|
+
RefreshTicketAlert: findClient?.ticketConfigs?.refreshAlert,
|
|
1008
|
+
StatusCheckAlert: findClient?.ticketConfigs?.statusCheckAlert,
|
|
1009
|
+
DataMismatchAccuracyPercentage: findClient?.ticketConfigs?.accuracyPercentage,
|
|
1010
|
+
DataMismatchReTraining: findClient?.ticketConfigs?.reTrain,
|
|
1011
|
+
};
|
|
1012
|
+
|
|
1013
|
+
// Map and rename keys from current client info for UI display and logging
|
|
1014
|
+
const newData = {
|
|
1015
|
+
InfraDowntimeType: updatedClient?.ticketConfigs?.downTimeType == 0 ? 'Single Camera' : 'All Cameras',
|
|
1016
|
+
AutoReAssignInstallation: updatedClient?.ticketConfigs?.installationReAssign,
|
|
1017
|
+
InfraDowntime: updatedClient?.ticketConfigs?.infraDownTime,
|
|
1018
|
+
InfraFiles: updatedClient?.ticketConfigs?.MinFilesCount,
|
|
1019
|
+
RcaTicket: updatedClient?.ticketConfigs?.rcaTicketAssign,
|
|
1020
|
+
RefreshTicketAlert: updatedClient?.ticketConfigs?.refreshAlert,
|
|
1021
|
+
StatusCheckAlert: updatedClient?.ticketConfigs?.statusCheckAlert,
|
|
1022
|
+
DataMismatchAccuracyPercentage: updatedClient?.ticketConfigs?.accuracyPercentage,
|
|
1023
|
+
DataMismatchReTraining: updatedClient?.ticketConfigs?.reTrain,
|
|
1024
|
+
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
// Prepare activity log object with all relevant details for OpenSearch logging
|
|
908
1028
|
const logObj = {
|
|
909
|
-
clientId: req.params?.id,
|
|
910
|
-
userName: user
|
|
911
|
-
email: user
|
|
912
|
-
date: new Date(),
|
|
913
|
-
logType: 'configuration',
|
|
914
|
-
logSubType: 'ticketConfig',
|
|
915
|
-
changes: updateKeys,
|
|
916
|
-
eventType: 'update',
|
|
917
|
-
showTo: [ 'tango' ],
|
|
1029
|
+
clientId: req.params?.id, // ID of the client whose data was updated
|
|
1030
|
+
userName: req?.user?.userName, // Name of the user performing the update
|
|
1031
|
+
email: req?.user?.email, // Email of the user performing the update
|
|
1032
|
+
date: new Date(), // Timestamp of the update event
|
|
1033
|
+
logType: 'configuration', // Type of log (e.g., related to brand details)
|
|
1034
|
+
logSubType: 'ticketConfig', // Subtype for more specific categorization
|
|
1035
|
+
changes: updateKeys, // List of fields that were updated.these will shown in the UI as part of activity log
|
|
1036
|
+
eventType: 'update', // Type of event (update operation)
|
|
1037
|
+
showTo: [ 'tango' ], // Visibility of the log (who can see this log)
|
|
1038
|
+
current: updatedClient.ticketConfigs, // Previous (old) client information before update based on DB keys (for internal reference and comparison).
|
|
1039
|
+
previous: findClient.ticketConfigs, // Current (new) client information after update based on DB keys (for internal reference and comparison).
|
|
1040
|
+
oldData: oldData, // Previous (old) client information before update (used for showing detailed changes in the UI).
|
|
1041
|
+
newData: newData, // Current (new) client information after update (used for showing detailed changes in the UI).
|
|
918
1042
|
};
|
|
919
1043
|
|
|
1044
|
+
// Insert activity log into OpenSearch if there are fields that were updated
|
|
920
1045
|
if ( updateKeys.length ) {
|
|
921
|
-
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
1046
|
+
await insertOpenSearchData( openSearch.activityLog, logObj ); // Insert activity log
|
|
922
1047
|
}
|
|
923
1048
|
|
|
924
1049
|
if ( updateAck ) {
|
|
925
1050
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
926
1051
|
}
|
|
927
1052
|
} catch ( error ) {
|
|
1053
|
+
const err = error.message || 'Internal Server Error';
|
|
928
1054
|
logger.error( { error: error, message: req.params, function: 'updateTicketConfiguration' } );
|
|
929
|
-
return res.sendError(
|
|
1055
|
+
return res.sendError( err, 500 );
|
|
930
1056
|
}
|
|
931
1057
|
}
|
|
932
1058
|
|
|
933
1059
|
export async function updateFeatureConfiguration( req, res ) {
|
|
934
1060
|
try {
|
|
935
1061
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
936
|
-
const url = JSON.parse( process.env.URL );
|
|
1062
|
+
// const url = JSON.parse( process.env.URL );
|
|
1063
|
+
|
|
1064
|
+
// Get updated client Feature configuration before the update operation (fetch selected fields only)
|
|
1065
|
+
const previousData = await findOneClient( { clientId: req.params?.id }, { featureConfigs: 1 } );
|
|
937
1066
|
const inputData = req.body;
|
|
938
1067
|
if ( inputData?.bouncedLimitValue ) {
|
|
939
1068
|
inputData.missedOpportunityFromValue = inputData?.bouncedLimitValue;
|
|
@@ -944,74 +1073,156 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
944
1073
|
}
|
|
945
1074
|
const updateAck = await featureConfigurationUpdate( { clientId: req.params?.id }, inputData );
|
|
946
1075
|
|
|
947
|
-
|
|
1076
|
+
// Get updated client Feature configuration after the update operation (fetch selected fields only)
|
|
1077
|
+
const postData = await findOneClient( { clientId: req.params?.id }, { featureConfigs: 1 } );
|
|
1078
|
+
let updateKeys = []; // List of updated field names in readable format
|
|
948
1079
|
|
|
1080
|
+
// Check if request body has any fields to update
|
|
949
1081
|
if ( Object.keys( inputData ).length > 0 ) {
|
|
950
1082
|
Object.keys( inputData ).forEach( ( element ) => {
|
|
951
|
-
|
|
1083
|
+
element === 'billableCalculation' ? 'potentialCalculation' : element; // Replace 'billableCalculation' with 'potentialCalculation' if present
|
|
1084
|
+
updateKeys.push( camelCaseToWords( element ) ); // Convert camelCase field name to readable format and add to updateKeys
|
|
952
1085
|
} );
|
|
953
1086
|
}
|
|
954
1087
|
|
|
955
1088
|
const user = req.user;
|
|
956
1089
|
|
|
957
|
-
const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
if ( inputData?.
|
|
968
|
-
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1090
|
+
// const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
1091
|
+
// if ( inputData?.open ) {
|
|
1092
|
+
// data.brandConfigs.storeOpenTime = inputData?.open;
|
|
1093
|
+
// }
|
|
1094
|
+
// if ( inputData?.close ) {
|
|
1095
|
+
// data.brandConfigs.storeCloseTime = inputData?.open;
|
|
1096
|
+
// }
|
|
1097
|
+
// if ( inputData?.missedOpportunityCalculation ) {
|
|
1098
|
+
// data.brandConfigs.missedOpportunityCalculate = inputData?.missedOpportunityCalculation;
|
|
1099
|
+
// }
|
|
1100
|
+
// if ( inputData?.conversionCalculation ) {
|
|
1101
|
+
// data.brandConfigs.conversionCalculate = inputData?.conversionCalculation;
|
|
1102
|
+
// }
|
|
1103
|
+
// if ( inputData?.billableCalculation ) {
|
|
1104
|
+
// data.brandConfigs.billableCalculate = inputData?.billableCalculation;
|
|
1105
|
+
// }
|
|
1106
|
+
// if ( inputData?.bouncedLimitCondition ) {
|
|
1107
|
+
// data.brandConfigs.bouncedConfigTime = data.brandConfigs.bouncedConfigTime.replace( /^.+(?=\d)/, inputData?.bouncedLimitCondition );
|
|
1108
|
+
// data.brandConfigs.missedOpportunityEndTime = data.brandConfigs.missedOpportunityEndTime.replace( /^.+(?=\d)/, inputData?.bouncedLimitCondition );
|
|
1109
|
+
// }
|
|
1110
|
+
// if ( inputData?.bouncedLimitValue ) {
|
|
1111
|
+
// data.brandConfigs.bouncedConfigTime = data.brandConfigs.bouncedConfigTime.replace( /\d+/, inputData?.bouncedLimitValue );
|
|
1112
|
+
// data.brandConfigs.missedOpportunityStartTime = data.brandConfigs.missedOpportunityStartTime.replace( /\d+/, inputData?.bouncedLimitValue );
|
|
1113
|
+
// }
|
|
1114
|
+
// if ( inputData?.conversionCondition ) {
|
|
1115
|
+
// data.brandConfigs.conversionConfigTime = data.brandConfigs.conversionConfigTime.replace( /^.+(?=\d)/, inputData?.conversionCondition );
|
|
1116
|
+
// data.brandConfigs.missedOpportunityStartTime = data.brandConfigs.missedOpportunityStartTime.replace( /^.+(?=\d)/, inputData?.conversionCondition );
|
|
1117
|
+
// }
|
|
1118
|
+
// if ( inputData?.conversionValue ) {
|
|
1119
|
+
// data.brandConfigs.conversionConfigTime = data.brandConfigs.conversionConfigTime.replace( /\d+/, inputData?.conversionValue );
|
|
1120
|
+
// data.brandConfigs.missedOpportunityEndTime = data.brandConfigs.missedOpportunityEndTime.replace( /\d+/, inputData?.conversionValue );
|
|
1121
|
+
// }
|
|
1122
|
+
// await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { brandConfigs: data.brandConfigs } );
|
|
1123
|
+
|
|
1124
|
+
const keysArray = [
|
|
1125
|
+
'isExcludedArea', 'isPasserByData', 'isNormalized', 'isbillingDisabled', 'isCameraDisabled', 'isFootfallDirectory', 'isNOB', 'isNewTraffic', 'isTrax', 'isNewZone', 'isNewReports', 'isNewDashboard', 'streamBy', 'isFootfallView', 'isAIManager', 'isAIManagerAccessControl', 'isCameraEdit' ];
|
|
1126
|
+
// Map and rename keys from previous client info for UI display and logging
|
|
1127
|
+
const oldData = {
|
|
1128
|
+
StoreOpenTime: previousData?.featureConfigs?.open,
|
|
1129
|
+
StoreCloseTime: previousData?.featureConfigs?.close,
|
|
1130
|
+
ConversionCalculations: previousData?.featureConfigs?.conversionCalculation == 'footfall-count' ? 'Footfall Count' : postData?.featureConfigs?.conversionCalculation == 'engagers-count' ? 'Engagers Count' : 'Potential Entities',
|
|
1131
|
+
MissedOpportunityCalculation: previousData?.featureConfigs?.missedOpportunityCalculation == 'engagers-conversion' ? 'Engagers - Conversion' : 'Potential Entities - Conversion',
|
|
1132
|
+
PotentialCalculations: previousData?.featureConfigs?.billableCalculation == 'footfall-count' ? 'Footfall Count' : 'Engagers Count',
|
|
1133
|
+
ConversionCondition: previousData?.featureConfigs?.conversion.condition,
|
|
1134
|
+
ConversionValue: previousData?.featureConfigs?.conversion.value,
|
|
1135
|
+
MissedOpportunityFromCondition: previousData?.featureConfigs?.missedOpportunityFrom?.condition,
|
|
1136
|
+
MissedOpportunityToCondition: previousData?.featureConfigs?.missedOpportunityTo?.condition,
|
|
1137
|
+
MissedOpportunityFromValue: previousData?.featureConfigs?.missedOpportunityFrom?.value,
|
|
1138
|
+
MissedOpportunityToValue: previousData?.featureConfigs?.missedOpportunityTo?.value,
|
|
1139
|
+
BouncedLimitCondition: previousData?.featureConfigs?.bouncedLimit?.condition,
|
|
1140
|
+
BouncedLimitValue: previousData?.featureConfigs?.bouncedLimit?.value,
|
|
1141
|
+
InfraAlertValue: previousData?.featureConfigs?.infraAlert?.value,
|
|
1142
|
+
InfraAlertCondition: previousData?.featureConfigs?.infraAlert?.condition,
|
|
1143
|
+
ExcludedArea: previousData?.featureConfigs?.isExcludedArea == true ? 'Enabled' : 'Disabled',
|
|
1144
|
+
PasserBydata: previousData?.featureConfigs?.isPasserByData == true ? 'Enabled' : 'Disabled',
|
|
1145
|
+
NormalizedDataDuringDowntime: previousData?.featureConfigs?.isNormalized == true ? 'Enabled' : 'Disabled',
|
|
1146
|
+
Billing: previousData?.featureConfigs?.isbillingDisabled == true ? 'Enabled' : 'Disabled',
|
|
1147
|
+
CameraBlurring: previousData?.featureConfigs?.isCameraDisabled == true ? 'Enabled' : 'Disabled',
|
|
1148
|
+
FootfallDirectory: previousData?.featureConfigs?.isFootfallDirectory == true ? 'Enabled' : 'Disabled',
|
|
1149
|
+
NOBStatus: previousData?.featureConfigs?.isNOB == true ? 'Enabled' : 'Disabled',
|
|
1150
|
+
EnableAnalyze: previousData?.featureConfigs?.isNewDashboard == true ? 'Enabled' : 'Disabled',
|
|
1151
|
+
Traffic: previousData?.featureConfigs?.isNewTraffic == true ? 'Enabled' : 'Disabled',
|
|
1152
|
+
Zone: previousData?.featureConfigs?.isNewZone == true ? 'Enabled' : 'Disabled',
|
|
1153
|
+
Zonev2: previousData?.featureConfigs?.isNewZoneV2 == true ? 'Enabled' : 'Disabled',
|
|
1154
|
+
Reports: previousData?.featureConfigs?.isNewReports == true ? 'Enabled' : 'Disabled',
|
|
1155
|
+
Trax: previousData?.featureConfigs?.isTrax == true ? 'Enabled' : 'Disabled',
|
|
1156
|
+
Revops: previousData?.featureConfigs?.isRevops == true ? 'Enabled' : 'Disabled',
|
|
1157
|
+
StreamType: previousData?.featureConfigs?.streamBy == 'Edge' ? 'Edge App' : 'RTSP',
|
|
1158
|
+
FootfallDirectoryOnlyAudit: previousData?.featureConfigs?.isFootfallDirectoryAudit == true ? 'Enabled' : 'Disabled',
|
|
1159
|
+
FootfallDirectoryOnlyFew: previousData?.featureConfigs?.isFootfallDirectoryLimit == true ? 'Enabled' : 'Disabled',
|
|
1160
|
+
FootfallView: previousData?.featureConfigs?.isFootfallView == true ? 'Enabled' : 'Disabled',
|
|
1161
|
+
AIManager: previousData?.featureConfigs?.isAIManager == true ? 'Enabled' : 'Disabled',
|
|
1162
|
+
AIManagerAccessControl: previousData?.featureConfigs?.isAIManagerAccessControl == true ? 'Enabled' : 'Disabled',
|
|
1163
|
+
CameraEdit: previousData?.featureConfigs?.isCameraEdit == true ? 'Enabled' : 'Disabled',
|
|
1164
|
+
};
|
|
1000
1165
|
|
|
1166
|
+
// Map and rename keys from current client info for UI display and logging
|
|
1167
|
+
const newData = {
|
|
1168
|
+
StoreOpenTime: postData?.featureConfigs?.open,
|
|
1169
|
+
StoreCloseTime: postData?.featureConfigs?.close,
|
|
1170
|
+
ConversionCalculations: postData?.featureConfigs?.conversionCalculation == 'footfall-count' ? 'Footfall Count' : postData?.featureConfigs?.conversionCalculation == 'engagers-count' ? 'Engagers Count' : 'Potential Entities',
|
|
1171
|
+
MissedOpportunityCalculation: postData?.featureConfigs?.missedOpportunityCalculation == 'engagers-conversion' ? 'Engagers - Conversion' : 'Potential Entities - Conversion',
|
|
1172
|
+
PotentialCalculations: postData?.featureConfigs?.billableCalculation == 'footfall-count' ? 'Footfall Count' : 'Engagers Count',
|
|
1173
|
+
ConversionCondition: postData?.featureConfigs?.conversion.condition,
|
|
1174
|
+
ConversionValue: postData?.featureConfigs?.conversion.value,
|
|
1175
|
+
MissedOpportunityFromCondition: postData?.featureConfigs?.missedOpportunityFrom?.condition,
|
|
1176
|
+
MissedOpportunityToCondition: postData?.featureConfigs?.missedOpportunityTo?.condition,
|
|
1177
|
+
MissedOpportunityFromValue: postData?.featureConfigs?.missedOpportunityFrom?.value,
|
|
1178
|
+
MissedOpportunityToValue: postData?.featureConfigs?.missedOpportunityTo?.value,
|
|
1179
|
+
BouncedLimitCondition: postData?.featureConfigs?.bouncedLimit?.condition,
|
|
1180
|
+
BouncedLimitValue: postData?.featureConfigs?.bouncedLimit?.value,
|
|
1181
|
+
InfraAlertValue: postData?.featureConfigs?.infraAlert?.value,
|
|
1182
|
+
InfraAlertCondition: postData?.featureConfigs?.infraAlert?.condition,
|
|
1183
|
+
ExcludedArea: postData?.featureConfigs?.isExcludedArea == true ? 'Enabled' : 'Disabled',
|
|
1184
|
+
PasserBydata: postData?.featureConfigs?.isPasserByData == true ? 'Enabled' : 'Disabled',
|
|
1185
|
+
NormalizedDataDuringDowntime: postData?.featureConfigs?.isNormalized == true ? 'Enabled' : 'Disabled',
|
|
1186
|
+
Billing: postData?.featureConfigs?.isbillingDisabled == true ? 'Enabled' : 'Disabled',
|
|
1187
|
+
CameraBlurring: postData?.featureConfigs?.isCameraDisabled == true ? 'Enabled' : 'Disabled',
|
|
1188
|
+
FootfallDirectory: postData?.featureConfigs?.isFootfallDirectory == true ? 'Enabled' : 'Disabled',
|
|
1189
|
+
NOBStatus: postData?.featureConfigs?.isNOB == true ? 'Enabled' : 'Disabled',
|
|
1190
|
+
EnableAnalyze: postData?.featureConfigs?.isNewDashboard == true ? 'Enabled' : 'Disabled',
|
|
1191
|
+
Traffic: postData?.featureConfigs?.isNewTraffic == true ? 'Enabled' : 'Disabled',
|
|
1192
|
+
Zone: postData?.featureConfigs?.isNewZone == true ? 'Enabled' : 'Disabled',
|
|
1193
|
+
Zonev2: postData?.featureConfigs?.isNewZoneV2 == true ? 'Enabled' : 'Disabled',
|
|
1194
|
+
Reports: postData?.featureConfigs?.isNewReports == true ? 'Enabled' : 'Disabled',
|
|
1195
|
+
Trax: postData?.featureConfigs?.isTrax == true ? 'Enabled' : 'Disabled',
|
|
1196
|
+
Revops: postData?.featureConfigs?.isRevops == true ? 'Enabled' : 'Disabled',
|
|
1197
|
+
StreamType: postData?.featureConfigs?.streamBy == 'Edge' ? 'Edge App' : 'RTSP',
|
|
1198
|
+
FootfallDirectoryOnlyAudit: postData?.featureConfigs?.isFootfallDirectoryAudit == true ? 'Enabled' : 'Disabled',
|
|
1199
|
+
FootfallDirectoryOnlyFew: postData?.featureConfigs?.isFootfallDirectoryLimit == true ? 'Enabled' : 'Disabled',
|
|
1200
|
+
FootfallView: previousData?.featureConfigs?.isFootfallView == true ? 'Enabled' : 'Disabled',
|
|
1201
|
+
AIManager: previousData?.featureConfigs?.isAIManager == true ? 'Enabled' : 'Disabled',
|
|
1202
|
+
AIManagerAccessControl: previousData?.featureConfigs?.isAIManagerAccessControl == true ? 'Enabled' : 'Disabled',
|
|
1203
|
+
CameraEdit: previousData?.featureConfigs?.isCameraEdit == true ? 'Enabled' : 'Disabled',
|
|
1204
|
+
};
|
|
1001
1205
|
|
|
1206
|
+
// Prepare activity log object with all relevant details for OpenSearch logging
|
|
1002
1207
|
const logObj = {
|
|
1003
|
-
clientId: req.params?.id,
|
|
1004
|
-
userName: user?.userName,
|
|
1005
|
-
email: user?.email,
|
|
1006
|
-
date: new Date(),
|
|
1007
|
-
logType: 'configuration',
|
|
1008
|
-
logSubType: 'featureConfig',
|
|
1009
|
-
changes: updateKeys,
|
|
1010
|
-
eventType: 'update',
|
|
1011
|
-
showTo: [ 'client', 'tango' ],
|
|
1208
|
+
clientId: req.params?.id, // ID of the client whose data was updated
|
|
1209
|
+
userName: user?.userName, // Name of the user performing the update
|
|
1210
|
+
email: user?.email, // Email of the user performing the update
|
|
1211
|
+
date: new Date(), // Timestamp of the update event
|
|
1212
|
+
logType: 'configuration', // Type of log (e.g., related to brand details)
|
|
1213
|
+
logSubType: Object.keys( inputData ).some( ( key ) => keysArray.includes( key ) ) ? 'dashboardConfig' : 'featureConfig', // Subtype for more specific categorization
|
|
1214
|
+
changes: updateKeys, // List of fields that were updated.these will shown in the UI as part of activity log
|
|
1215
|
+
eventType: 'update', // Type of event (update operation)
|
|
1216
|
+
showTo: [ 'client', 'tango' ], // Visibility of the log (who can see this log)
|
|
1217
|
+
previous: previousData.featureConfigs, // Previous (old) client information before update based on DB keys (for internal reference and comparison).
|
|
1218
|
+
current: postData.featureConfigs, // Current (new) client information after update based on DB keys (for internal reference and comparison).
|
|
1219
|
+
oldData: oldData, // Previous (old) client information before update (used for showing detailed changes in the UI).
|
|
1220
|
+
newData: newData, // Current (new) client information after update (used for showing detailed changes in the UI).
|
|
1012
1221
|
};
|
|
1222
|
+
|
|
1223
|
+
// Insert activity log into OpenSearch if there are fields that were updated
|
|
1013
1224
|
if ( updateKeys.length ) {
|
|
1014
|
-
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
1225
|
+
await insertOpenSearchData( openSearch.activityLog, logObj ); // Insert activity log
|
|
1015
1226
|
}
|
|
1016
1227
|
|
|
1017
1228
|
if ( updateAck ) {
|
|
@@ -1027,6 +1238,18 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
1027
1238
|
export async function domainDetailsConfiguration( req, res ) {
|
|
1028
1239
|
try {
|
|
1029
1240
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1241
|
+
|
|
1242
|
+
// Get updated client domain configuration before the update operation (fetch selected fields only)
|
|
1243
|
+
const getPreData = await findOneClient(
|
|
1244
|
+
{ clientId: req.params?.id }, // filter by clientId
|
|
1245
|
+
{
|
|
1246
|
+
'domainConfig.ssoLogin.domainName': 1,
|
|
1247
|
+
'domainConfig.ssoLogin.isEnable': 1,
|
|
1248
|
+
'domainConfig.ipWhitelisting.enableWhitelisting': 1,
|
|
1249
|
+
'domainConfig.ipWhitelisting.allowedIps': 1,
|
|
1250
|
+
'domainConfig.enableOtp': 1,
|
|
1251
|
+
},
|
|
1252
|
+
);
|
|
1030
1253
|
const updateAck = await domainDetailsConfigurationUpdate( {
|
|
1031
1254
|
clientId: req.params?.id, domainName: req.body?.domainName, isEnable: req.body?.isEnable,
|
|
1032
1255
|
enableWhitelisting: req.body?.enableWhitelisting, allowedIps: req.body?.allowedIps, enableOtp: req.body?.enableOtp,
|
|
@@ -1034,30 +1257,66 @@ export async function domainDetailsConfiguration( req, res ) {
|
|
|
1034
1257
|
|
|
1035
1258
|
let updateKeys = [];
|
|
1036
1259
|
|
|
1037
|
-
|
|
1260
|
+
// Check if request body has any fields to update
|
|
1038
1261
|
if ( Object.keys( req.body ).length > 0 ) {
|
|
1039
1262
|
Object.keys( req.body ).forEach( ( element ) => {
|
|
1040
1263
|
updateKeys.push( camelCaseToWords( element ) );
|
|
1041
1264
|
} );
|
|
1042
1265
|
}
|
|
1043
1266
|
|
|
1044
|
-
|
|
1267
|
+
// Get updated client domain configuration after the update operation (fetch selected fields only)
|
|
1268
|
+
const getPostData = await findOneClient(
|
|
1269
|
+
{ clientId: req.params?.id }, // Filter by clientId
|
|
1270
|
+
{
|
|
1271
|
+
'domainConfig.ssoLogin.domainName': 1,
|
|
1272
|
+
'domainConfig.ssoLogin.isEnable': 1,
|
|
1273
|
+
'domainConfig.ipWhitelisting.enableWhitelisting': 1,
|
|
1274
|
+
'domainConfig.ipWhitelisting.allowedIps': 1,
|
|
1275
|
+
'domainConfig.enableOtp': 1,
|
|
1276
|
+
},
|
|
1277
|
+
);
|
|
1278
|
+
|
|
1045
1279
|
|
|
1280
|
+
// Map and rename keys from previous client info for UI display and logging
|
|
1281
|
+
const oldData = {
|
|
1282
|
+
DomainName: getPreData?.domainConfig?.ssoLogin?.domainName?.join( ', ' ),
|
|
1283
|
+
IsEnable: getPreData?.domainConfig?.ssoLogin?.isEnable == true ? 'Enable' : 'Disable',
|
|
1284
|
+
IPWhitelist: getPreData?.domainConfig?.ipWhitelisting?.enableWhitelisting == true ? 'Enable' : 'Disable',
|
|
1285
|
+
WhitelistedIps: getPreData?.domainConfig?.ipWhitelisting?.allowedIps?.join( ', ' ),
|
|
1286
|
+
TwoFactorAuthentication: getPreData?.domainConfig?.enableOtp == true ? 'Enable' : 'Disable',
|
|
1287
|
+
|
|
1288
|
+
};
|
|
1046
1289
|
|
|
1290
|
+
// Map and rename keys from current client info for UI display and logging
|
|
1291
|
+
const newData = {
|
|
1292
|
+
DomainName: getPostData?.domainConfig?.ssoLogin?.domainName?.join( ', ' ),
|
|
1293
|
+
IsEnable: getPostData?.domainConfig?.ssoLogin?.isEnable == true ? 'Enable' : 'Disable',
|
|
1294
|
+
IPWhitelist: getPostData?.domainConfig?.ipWhitelisting?.enableWhitelisting == true ? 'Enable' : 'Disable',
|
|
1295
|
+
WhitelistedIps: getPostData?.domainConfig?.ipWhitelisting?.allowedIps?.join( ', ' ),
|
|
1296
|
+
TwoFactorAuthentication: getPostData?.domainConfig?.enableOtp == true ? 'Enable' : 'Disable',
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
logger.info( { getPreData: getPreData, getPostData: getPostData, newData: newData, oldData: oldData } );
|
|
1300
|
+
// Prepare activity log object with all relevant details for OpenSearch logging
|
|
1047
1301
|
const logObj = {
|
|
1048
|
-
clientId: req.params?.id,
|
|
1049
|
-
userName: user?.userName,
|
|
1050
|
-
email: user?.email,
|
|
1051
|
-
date: new Date(),
|
|
1052
|
-
logType: 'configuration',
|
|
1053
|
-
logSubType: 'domainDetails',
|
|
1054
|
-
changes: updateKeys,
|
|
1055
|
-
eventType: 'update',
|
|
1056
|
-
showTo: [ 'client', 'tango' ],
|
|
1302
|
+
clientId: req.params?.id, // ID of the client whose data was updated
|
|
1303
|
+
userName: req?.user?.userName, // Name of the user performing the update
|
|
1304
|
+
email: req?.user?.email, // Email of the user performing the update
|
|
1305
|
+
date: new Date(), // Timestamp of the update event
|
|
1306
|
+
logType: 'configuration', // Type of log (e.g., related to brand details)
|
|
1307
|
+
logSubType: 'domainDetails', // Subtype for more specific categorization
|
|
1308
|
+
changes: updateKeys, // List of fields that were updated.these will shown in the UI as part of activity log
|
|
1309
|
+
eventType: 'update', // Type of event (update operation)
|
|
1310
|
+
showTo: [ 'client', 'tango' ], // Visibility of the log (who can see this log)
|
|
1311
|
+
previous: getPreData, // Previous (old) client information before update based on DB keys (for internal reference and comparison).
|
|
1312
|
+
current: getPostData, // Current (new) client information after update based on DB keys (for internal reference and comparison).
|
|
1313
|
+
oldData: oldData, // Previous (old) client information before update (used for showing detailed changes in the UI).
|
|
1314
|
+
newData: newData, // Current (new) client information after update (used for showing detailed changes in the UI).
|
|
1057
1315
|
};
|
|
1058
1316
|
|
|
1317
|
+
// Insert activity log into OpenSearch if there are fields that were updated
|
|
1059
1318
|
if ( updateKeys.length ) {
|
|
1060
|
-
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
1319
|
+
await insertOpenSearchData( openSearch.activityLog, logObj ); // Insert activity log
|
|
1061
1320
|
}
|
|
1062
1321
|
|
|
1063
1322
|
if ( updateAck ) {
|
|
@@ -1099,8 +1358,17 @@ export async function updateDocuments( req, res ) {
|
|
|
1099
1358
|
};
|
|
1100
1359
|
|
|
1101
1360
|
updateKeys.push( 'Address certificate' );
|
|
1361
|
+
let xssCheckData=await getXsscheck( uploadDataParams.body );
|
|
1362
|
+
|
|
1363
|
+
if ( xssCheckData==true ) {
|
|
1364
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
1365
|
+
}
|
|
1102
1366
|
|
|
1103
|
-
await
|
|
1367
|
+
let uploadStatus= await fileRestrictedUpload( uploadDataParams );
|
|
1368
|
+
|
|
1369
|
+
if ( uploadStatus==false ) {
|
|
1370
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
1371
|
+
}
|
|
1104
1372
|
}
|
|
1105
1373
|
if ( req.files?.gstDoc ) {
|
|
1106
1374
|
const uploadDataParams = {
|
|
@@ -1113,7 +1381,17 @@ export async function updateDocuments( req, res ) {
|
|
|
1113
1381
|
|
|
1114
1382
|
updateKeys.push( 'GST certificate' );
|
|
1115
1383
|
|
|
1116
|
-
await
|
|
1384
|
+
let xssCheckData=await getXsscheck( uploadDataParams.body );
|
|
1385
|
+
|
|
1386
|
+
if ( xssCheckData==true ) {
|
|
1387
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
let uploadStatus= await fileRestrictedUpload( uploadDataParams );
|
|
1391
|
+
|
|
1392
|
+
if ( uploadStatus==false ) {
|
|
1393
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
1394
|
+
}
|
|
1117
1395
|
}
|
|
1118
1396
|
if ( req.files?.panDoc ) {
|
|
1119
1397
|
const uploadDataParams = {
|
|
@@ -1126,7 +1404,17 @@ export async function updateDocuments( req, res ) {
|
|
|
1126
1404
|
|
|
1127
1405
|
updateKeys.push( 'PAN certificate' );
|
|
1128
1406
|
|
|
1129
|
-
await
|
|
1407
|
+
let xssCheckData=await getXsscheck( uploadDataParams.body );
|
|
1408
|
+
|
|
1409
|
+
if ( xssCheckData==true ) {
|
|
1410
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
let uploadStatus= await fileRestrictedUpload( uploadDataParams );
|
|
1414
|
+
|
|
1415
|
+
if ( uploadStatus==false ) {
|
|
1416
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
1417
|
+
}
|
|
1130
1418
|
}
|
|
1131
1419
|
if ( req.files?.cinDoc ) {
|
|
1132
1420
|
const uploadDataParams = {
|
|
@@ -1139,7 +1427,11 @@ export async function updateDocuments( req, res ) {
|
|
|
1139
1427
|
|
|
1140
1428
|
updateKeys.push( 'CIN certificate' );
|
|
1141
1429
|
|
|
1142
|
-
await
|
|
1430
|
+
let uploadStatus= await fileRestrictedUpload( uploadDataParams );
|
|
1431
|
+
|
|
1432
|
+
if ( uploadStatus==false ) {
|
|
1433
|
+
return res.sendError( 'Unsupported Media Type', 415 );
|
|
1434
|
+
}
|
|
1143
1435
|
}
|
|
1144
1436
|
|
|
1145
1437
|
const updateAck = await documentsUpdate( {
|
|
@@ -1159,7 +1451,6 @@ export async function updateDocuments( req, res ) {
|
|
|
1159
1451
|
|
|
1160
1452
|
const user = await getUserNameEmailById( req.userId );
|
|
1161
1453
|
|
|
1162
|
-
|
|
1163
1454
|
const logObj = {
|
|
1164
1455
|
clientId: req.params?.id,
|
|
1165
1456
|
userName: user?.userName,
|
|
@@ -1221,14 +1512,31 @@ export async function auditConfiguration( req, res ) {
|
|
|
1221
1512
|
auditConfigs: 1, _id: 0,
|
|
1222
1513
|
};
|
|
1223
1514
|
const previousClient = await findOneClient( query, fields );
|
|
1515
|
+
previousClient.auditConfigs.ratio = previousClient?.auditConfigs?.ratio ? ( previousClient.auditConfigs.ratio ) * 100 : null;
|
|
1224
1516
|
const record = {
|
|
1225
1517
|
'auditConfigs.count': inputData.count,
|
|
1226
1518
|
'auditConfigs.audit': inputData.audit,
|
|
1227
1519
|
'auditConfigs.ratio': Number( normalizeNumber( inputData.ratio, 0, 100 ) ),
|
|
1228
1520
|
};
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1521
|
+
await updateOneClient( query, record );
|
|
1522
|
+
|
|
1523
|
+
// Map and rename keys from previous client info for UI display and logging
|
|
1524
|
+
const oldData = {
|
|
1525
|
+
AuditStatus: previousClient?.auditConfigs?.audit == true ? 'Enable' : 'Disable',
|
|
1526
|
+
MappingPercentage: previousClient?.auditConfigs?.ratio,
|
|
1527
|
+
AuditCount: previousClient?.auditConfigs?.count,
|
|
1528
|
+
};
|
|
1529
|
+
|
|
1530
|
+
const currentClient = await findOneClient( query, fields );
|
|
1531
|
+
currentClient.auditConfigs.ratio = currentClient?.auditConfigs?.ratio ? ( currentClient.auditConfigs.ratio ) * 100 : null;
|
|
1532
|
+
|
|
1533
|
+
// Map and rename keys from current client info for UI display and logging
|
|
1534
|
+
const newData = {
|
|
1535
|
+
AuditStatus: currentClient?.auditConfigs?.audit == true ? 'Enable' : 'Disable',
|
|
1536
|
+
MappingPercentage: currentClient?.auditConfigs?.ratio,
|
|
1537
|
+
AuditCount: currentClient?.auditConfigs?.count,
|
|
1538
|
+
|
|
1539
|
+
};
|
|
1232
1540
|
const logObj = {
|
|
1233
1541
|
clientId: req.params?.id,
|
|
1234
1542
|
userName: req.user?.userName,
|
|
@@ -1239,13 +1547,10 @@ export async function auditConfiguration( req, res ) {
|
|
|
1239
1547
|
eventType: 'update',
|
|
1240
1548
|
showTo: [ 'tango' ],
|
|
1241
1549
|
changes: [ `Audit config for client id ${req.params?.id}` ],
|
|
1242
|
-
previous: previousClient,
|
|
1243
|
-
current:
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
audit: inputData.audit,
|
|
1247
|
-
ratio: normalizeNumber( inputData.ratio, 0, 100 ),
|
|
1248
|
-
},
|
|
1550
|
+
previous: previousClient.auditConfigs,
|
|
1551
|
+
current: currentClient.auditConfigs,
|
|
1552
|
+
oldData: oldData,
|
|
1553
|
+
newData: newData,
|
|
1249
1554
|
};
|
|
1250
1555
|
|
|
1251
1556
|
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
@@ -1288,17 +1593,6 @@ export async function clientList( req, res ) {
|
|
|
1288
1593
|
$match: {
|
|
1289
1594
|
userEmail: { $eq: req?.user?.email },
|
|
1290
1595
|
userType: 'tango',
|
|
1291
|
-
// $expr: {
|
|
1292
|
-
// $cond: {
|
|
1293
|
-
// if: {
|
|
1294
|
-
// $and: [
|
|
1295
|
-
// { $eq: [ '$tangoUserType', 'csm' ] },
|
|
1296
|
-
// ],
|
|
1297
|
-
// },
|
|
1298
|
-
// then: { $eq: [ '$isClientApproved', true ] },
|
|
1299
|
-
// else: true,
|
|
1300
|
-
// },
|
|
1301
|
-
// },
|
|
1302
1596
|
|
|
1303
1597
|
},
|
|
1304
1598
|
}, {
|
|
@@ -1614,17 +1908,6 @@ export async function clientListV1( req, res ) {
|
|
|
1614
1908
|
$match: {
|
|
1615
1909
|
userEmail: { $eq: req?.user?.email },
|
|
1616
1910
|
userType: 'tango',
|
|
1617
|
-
// $expr: {
|
|
1618
|
-
// $cond: {
|
|
1619
|
-
// if: {
|
|
1620
|
-
// $and: [
|
|
1621
|
-
// { $eq: [ '$tangoUserType', 'csm' ] },
|
|
1622
|
-
// ],
|
|
1623
|
-
// },
|
|
1624
|
-
// then: { $eq: [ '$isClientApproved', true ] },
|
|
1625
|
-
// else: true,
|
|
1626
|
-
// },
|
|
1627
|
-
// },
|
|
1628
1911
|
|
|
1629
1912
|
},
|
|
1630
1913
|
},
|
|
@@ -2020,13 +2303,41 @@ export async function detailedClientCount( req, res ) {
|
|
|
2020
2303
|
}
|
|
2021
2304
|
}
|
|
2022
2305
|
|
|
2023
|
-
export async function
|
|
2306
|
+
export async function getActivityLogs1( req, res ) {
|
|
2024
2307
|
try {
|
|
2308
|
+
const inputData = req.body;
|
|
2025
2309
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
2310
|
+
const clientQuery = [
|
|
2311
|
+
{
|
|
2312
|
+
$match: {
|
|
2313
|
+
$and: [
|
|
2314
|
+
{
|
|
2315
|
+
clientId: { $in: [ inputData?.clientId ] },
|
|
2316
|
+
},
|
|
2317
|
+
],
|
|
2318
|
+
},
|
|
2319
|
+
},
|
|
2320
|
+
{
|
|
2321
|
+
$group: {
|
|
2322
|
+
_id: null,
|
|
2323
|
+
clientName: { $push: '$clientName' },
|
|
2324
|
+
},
|
|
2325
|
+
},
|
|
2326
|
+
{
|
|
2327
|
+
$project: {
|
|
2328
|
+
_id: 0,
|
|
2329
|
+
clientName: 1,
|
|
2330
|
+
},
|
|
2331
|
+
},
|
|
2332
|
+
];
|
|
2333
|
+
const getClientName = await aggregateClient( clientQuery );
|
|
2334
|
+
if ( getClientName?.length == 0 || getClientName[0]?.clientName?.length === 0 ) {
|
|
2335
|
+
return res.sendError( 'No Data Found', 204 );
|
|
2336
|
+
}
|
|
2026
2337
|
const query = {
|
|
2027
2338
|
'_source': [
|
|
2028
2339
|
'userId', 'userName', 'email', 'date', 'logType', 'logSubType',
|
|
2029
|
-
'changes', 'eventType',
|
|
2340
|
+
'changes', 'eventType', 'previous', 'current', 'oldData', 'newData',
|
|
2030
2341
|
],
|
|
2031
2342
|
'query': {
|
|
2032
2343
|
'bool': {
|
|
@@ -2083,9 +2394,32 @@ export async function getActivityLogs( req, res ) {
|
|
|
2083
2394
|
|
|
2084
2395
|
const hits = logs?.body?.hits?.hits;
|
|
2085
2396
|
const totalDocuments = logs?.body?.hits?.total?.value;
|
|
2397
|
+
|
|
2398
|
+
let temp = [];
|
|
2086
2399
|
if ( totalDocuments ) {
|
|
2087
|
-
|
|
2088
|
-
|
|
2400
|
+
hits.map( ( hit, i ) => {
|
|
2401
|
+
let respo = {};
|
|
2402
|
+
hit._source.logSubType = hit._source.logSubType === 'documentUpload' ? 'documentsUpload' : hit._source.logSubType === 'domainDetails' ? 'securityFeatures' : hit?._source?.logSubType;
|
|
2403
|
+
if ( ( ( hit?._source?.eventType ).match( /update/ ) || ( hit?._source?.eventType ).match( /edit/ ) ) && hit?._source?.previous ) {
|
|
2404
|
+
const previous = hit?._source?.logType == 'cameras' ? hit?._source?.oldData : hit?._source?.previous;
|
|
2405
|
+
const current = hit?._source?.logType == 'cameras' ? hit?._source?.newData : hit?._source?.current;
|
|
2406
|
+
const logType = hit?._source?.logType;
|
|
2407
|
+
const logSubType = hit?._source?.logSubType;
|
|
2408
|
+
if ( previous && current && hit?._source?.logType == 'cameras' ) {
|
|
2409
|
+
respo = findDifferences( previous, current );
|
|
2410
|
+
} else {
|
|
2411
|
+
respo = findDifferences1( previous, current, logType, logSubType );
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
hit._source.updatedValue = respo;
|
|
2415
|
+
temp.push( hit?._source );
|
|
2416
|
+
hit._source.changes = logSubType === 'ticketConfig' ? Object.keys( respo ).map( ( item ) => item ) : hit._source.changes;
|
|
2417
|
+
} else {
|
|
2418
|
+
temp.push( hit?._source );
|
|
2419
|
+
}
|
|
2420
|
+
},
|
|
2421
|
+
);
|
|
2422
|
+
res.sendSuccess( { data: temp, count: totalDocuments } );
|
|
2089
2423
|
} else {
|
|
2090
2424
|
res.sendError( 'No data found', 204 );
|
|
2091
2425
|
}
|
|
@@ -2096,42 +2430,334 @@ export async function getActivityLogs( req, res ) {
|
|
|
2096
2430
|
}
|
|
2097
2431
|
|
|
2098
2432
|
|
|
2099
|
-
|
|
2100
|
-
const
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2433
|
+
function findDifferences1( previous, current, logType, logSubType, path = '' ) {
|
|
2434
|
+
const dbKeys = JSON.parse( process.env.DB_KEYS );
|
|
2435
|
+
const ignoredKeys = new Set( [
|
|
2436
|
+
'_id', 'updatedAt', 'createdAt', 'password', 'clientId',
|
|
2437
|
+
'storeId', 'refreshToken', 'employeeId', 'fcmToken', 'permission', 'updateFeatureConfig',
|
|
2438
|
+
] );
|
|
2439
|
+
const documents = dbKeys.DOCUMENTS;
|
|
2440
|
+
// Get correct key mapping based on logType
|
|
2441
|
+
const keyMapping = logType == 'stores' ? documents.stores : logType == 'users' ? documents.users : logSubType == 'reportConfig' ? documents.reports : logType == 'brandInfo' ? documents.client : documents.client;
|
|
2442
|
+
|
|
2443
|
+
|
|
2444
|
+
let differences = {};
|
|
2445
|
+
|
|
2446
|
+
for ( const key in current ) {
|
|
2447
|
+
if ( !Object.prototype.hasOwnProperty.call( current, key ) || ignoredKeys.has( key ) ) continue;
|
|
2448
|
+
|
|
2449
|
+
const prevValue = previous[key];
|
|
2450
|
+
const currValue = current[key];
|
|
2451
|
+
|
|
2452
|
+
if ( typeof prevValue === 'object' && typeof currValue === 'object' && prevValue !== null && currValue !== null ) {
|
|
2453
|
+
if ( logSubType !== 'userUpdated' ) {
|
|
2454
|
+
if ( key == 'spocDetails' ) {
|
|
2455
|
+
if ( _.isEqual( prevValue, currValue ) ) {
|
|
2456
|
+
continue;
|
|
2457
|
+
} else {
|
|
2458
|
+
let result = compareArrayObjects( prevValue, currValue );
|
|
2459
|
+
differences = { ...differences, ...result };
|
|
2460
|
+
}
|
|
2461
|
+
} else if ( Array.isArray( prevValue ) && prevValue.every( ( item ) => typeof item === 'string' ) || Array.isArray( currValue ) && currValue.every( ( item ) => typeof item === 'string' ) ) {
|
|
2462
|
+
JSON.stringify( prevValue ) !== JSON.stringify( currValue ) ?
|
|
2463
|
+
differences[`${path}${key}`] = { previous: prevValue.length > 0 ? prevValue.join( ',' ) : null, current: currValue.length > 0 ? currValue.join( ',' ) : null } : null;
|
|
2464
|
+
|
|
2465
|
+
// differences[`${path}${key}`] = { previous: removed.length> 0 ? prevValue.join( ',' ): prevValue.join( ', ' ) :, current: added.length > 0? addedUsers.join( ', ' ) : currValue.join( ',' ) } : null;
|
|
2466
|
+
} else {
|
|
2467
|
+
const nestedDiffs = findDifferences1( prevValue, currValue, logType, logSubType, `${path}${key}.` );
|
|
2468
|
+
Object.assign( differences, nestedDiffs );
|
|
2469
|
+
}
|
|
2470
|
+
} else {
|
|
2471
|
+
const nestedDiffs = findDifferences1( prevValue, currValue, logType, logSubType, `${path}${key}.` );
|
|
2472
|
+
Object.assign( differences, nestedDiffs );
|
|
2473
|
+
}
|
|
2474
|
+
} else if ( prevValue !== currValue ) {
|
|
2475
|
+
if (
|
|
2476
|
+
( prevValue === '' && currValue === '' ) ||
|
|
2477
|
+
( Array.isArray( prevValue ) && Array.isArray( currValue ) && prevValue.length === 0 && currValue.length === 0 )
|
|
2478
|
+
) {
|
|
2479
|
+
continue;
|
|
2480
|
+
}
|
|
2481
|
+
differences[`${path}${key}`] = { previous: prevValue, current: currValue };
|
|
2482
|
+
}
|
|
2114
2483
|
}
|
|
2484
|
+
|
|
2485
|
+
// **Transform & Filter Differences**
|
|
2486
|
+
let updatedDifferences = {};
|
|
2487
|
+
Object.keys( differences ).forEach( ( key ) => {
|
|
2488
|
+
let newKey = key.replace( /spocDetails\.\d+\./, 'spocDetails.' ).replace( /WhitelistedIps\.\d+/, 'Whitelisted Ips' );
|
|
2489
|
+
let diff = differences[key];
|
|
2490
|
+
if ( newKey.toLowerCase().includes( 'isactive' ) ) {
|
|
2491
|
+
diff = {
|
|
2492
|
+
previous: diff.previous ? 'Active' : 'Deactive',
|
|
2493
|
+
current: diff.current ? 'Active' : 'Deactive',
|
|
2494
|
+
};
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
const userFriendlyKey = getUserFriendlyKey( newKey, keyMapping );
|
|
2498
|
+
if ( userFriendlyKey ) {
|
|
2499
|
+
newKey = userFriendlyKey;
|
|
2500
|
+
}
|
|
2501
|
+
const binaryKeys = [ 'Two Factor Authentication', 'Mat Enabled', 'Audit Status', 'Infra Email Alert', 'Ip Whitelist', 'Excluded Area', 'Passer-by data', 'Normalized data during downtime', 'Billing', 'Camera Blurring', 'Footfall Directory', 'Footfall Directory Audit', 'Footfall Directory Limit', 'NOB Status', 'Traffic', 'Trax', 'Zone V1', 'Zone V2', 'Reports', 'Analyze' ];
|
|
2502
|
+
if ( binaryKeys.includes( newKey ) ) {
|
|
2503
|
+
diff.previous = ( diff.previous == true || diff.previous == 'Enabled' ) ? 'Enabled' : 'Disabled';
|
|
2504
|
+
diff.current = ( diff.current == true || diff.current == 'Enabled' ) ? 'Enabled' : 'Disabled';
|
|
2505
|
+
}
|
|
2506
|
+
if ( newKey === 'Server Type' ) {
|
|
2507
|
+
diff.previous = ( diff.previous == true || diff.previous == 'Server' ) ? 'Server' : 'Serverless';
|
|
2508
|
+
diff.current = ( diff.current == true || diff.current == 'Server' ) ? 'Server' : 'Serverless';
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
if ( newKey === 'Stream Type' ) {
|
|
2512
|
+
diff.previous = ( diff.previous == 'Edge' || diff.previous == 'Edge App' ) ? 'Edge App' : 'RTSP';
|
|
2513
|
+
diff.current = ( diff.current == 'Edge' || diff.current == 'Edge App' ) ? 'Edge App' : 'RTSP';
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
// **Transform Roles Permission Keys**
|
|
2517
|
+
const rolesPermissionMatch = newKey.match( /rolespermission\.(\d+)\.modules\.(\d+)\.(isAdd|isEdit)/ );
|
|
2518
|
+
if ( rolesPermissionMatch ) {
|
|
2519
|
+
const [ , roleIndex, moduleIndex, action ] = rolesPermissionMatch;
|
|
2520
|
+
const role = previous.rolespermission?.[roleIndex];
|
|
2521
|
+
const module = role?.modules?.[moduleIndex];
|
|
2522
|
+
|
|
2523
|
+
if ( module ) {
|
|
2524
|
+
newKey = `User's ${module.name} Module ${action === 'isAdd' ? 'Add' : 'Edit'}`;
|
|
2525
|
+
diff.previous = diff.previous ? 'Enabled' : 'Disabled';
|
|
2526
|
+
diff.current = diff.current ? 'Enabled' : 'Disabled';
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
if ( !newKey || ( diff.previous === '' && !diff.current ) ) return;
|
|
2531
|
+
|
|
2532
|
+
if (
|
|
2533
|
+
( diff.previous === '' || diff.previous === null || ( Array.isArray( diff.previous ) && diff.previous.length === 0 ) ) &&
|
|
2534
|
+
diff.current === undefined
|
|
2535
|
+
) {
|
|
2536
|
+
return;
|
|
2537
|
+
}
|
|
2538
|
+
if (
|
|
2539
|
+
( diff.current === '' || diff.current === null || ( Array.isArray( diff.current ) && diff.current.length === 0 ) ) &&
|
|
2540
|
+
diff.previous === undefined
|
|
2541
|
+
) {
|
|
2542
|
+
return;
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
updatedDifferences[newKey] = diff;
|
|
2546
|
+
} );
|
|
2547
|
+
|
|
2548
|
+
return updatedDifferences;
|
|
2115
2549
|
}
|
|
2116
2550
|
|
|
2117
|
-
async function getApi( url ) {
|
|
2118
|
-
const requestOptions = {
|
|
2119
|
-
method: 'GET',
|
|
2120
|
-
headers: {
|
|
2121
|
-
'Content-Type': 'application/json',
|
|
2122
|
-
'Authorization': 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66',
|
|
2123
|
-
},
|
|
2124
|
-
};
|
|
2125
2551
|
|
|
2552
|
+
function getUserFriendlyKey( keyPath, mapping ) {
|
|
2553
|
+
const keys = keyPath.split( '.' ); // Split the key path (e.g., storeProfile.pincode → ['storeProfile', 'pincode'])
|
|
2554
|
+
let value = mapping;
|
|
2555
|
+
|
|
2556
|
+
for ( const key of keys ) {
|
|
2557
|
+
if ( value && typeof value === 'object' && key in value ) {
|
|
2558
|
+
value = value[key]; // Traverse down the object
|
|
2559
|
+
} else {
|
|
2560
|
+
return null; // Return original if not found
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2564
|
+
return typeof value === 'string' ? value : keyPath; // Return mapped value or original key
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
export async function getActivityLogs( req, res ) {
|
|
2126
2568
|
try {
|
|
2127
|
-
const
|
|
2128
|
-
const
|
|
2129
|
-
|
|
2569
|
+
const inputData = req.body;
|
|
2570
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
2571
|
+
const clientQuery = [
|
|
2572
|
+
{
|
|
2573
|
+
$match: {
|
|
2574
|
+
$and: [
|
|
2575
|
+
{
|
|
2576
|
+
clientId: { $eq: inputData.clientId },
|
|
2577
|
+
},
|
|
2578
|
+
],
|
|
2579
|
+
},
|
|
2580
|
+
},
|
|
2581
|
+
{
|
|
2582
|
+
$group: {
|
|
2583
|
+
_id: null,
|
|
2584
|
+
clientName: { $push: '$clientName' },
|
|
2585
|
+
},
|
|
2586
|
+
},
|
|
2587
|
+
{
|
|
2588
|
+
$project: {
|
|
2589
|
+
_id: 0,
|
|
2590
|
+
clientName: 1,
|
|
2591
|
+
},
|
|
2592
|
+
},
|
|
2593
|
+
];
|
|
2594
|
+
const getClientName = await aggregateClient( clientQuery );
|
|
2595
|
+
if ( getClientName?.length == 0 || getClientName[0]?.clientName?.length === 0 ) {
|
|
2596
|
+
return res.sendError( 'No Data Found', 204 );
|
|
2597
|
+
}
|
|
2598
|
+
const query = {
|
|
2599
|
+
'_source': [
|
|
2600
|
+
'userId', 'userName', 'email', 'date', 'logType', 'logSubType',
|
|
2601
|
+
'changes', 'eventType', 'previous', 'current', 'oldData', 'newData',
|
|
2602
|
+
],
|
|
2603
|
+
'query': {
|
|
2604
|
+
'bool': {
|
|
2605
|
+
'must': [
|
|
2606
|
+
{
|
|
2607
|
+
'terms': {
|
|
2608
|
+
'clientId.keyword': [ inputData.clientId ],
|
|
2609
|
+
},
|
|
2610
|
+
},
|
|
2611
|
+
|
|
2612
|
+
],
|
|
2613
|
+
'should': [
|
|
2614
|
+
{
|
|
2615
|
+
'terms': {
|
|
2616
|
+
'clientName.keyword': getClientName[0].clientName, // Add clientName condition
|
|
2617
|
+
},
|
|
2618
|
+
},
|
|
2619
|
+
],
|
|
2620
|
+
},
|
|
2621
|
+
},
|
|
2622
|
+
'from': ( req.body.offset - 1 ) * req.body.limit,
|
|
2623
|
+
'size': req.body.limit,
|
|
2624
|
+
'sort': [
|
|
2625
|
+
{
|
|
2626
|
+
'date': {
|
|
2627
|
+
'order': 'desc',
|
|
2628
|
+
},
|
|
2629
|
+
},
|
|
2630
|
+
],
|
|
2631
|
+
};
|
|
2632
|
+
|
|
2633
|
+
if ( req.body?.logTypeFilters?.length ) {
|
|
2634
|
+
query.query.bool.must.push(
|
|
2635
|
+
{
|
|
2636
|
+
'terms': {
|
|
2637
|
+
'logType.keyword': req.body.logTypeFilters,
|
|
2638
|
+
},
|
|
2639
|
+
},
|
|
2640
|
+
);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
if ( req.body?.startDate || req.body?.endDate ) {
|
|
2644
|
+
query.query.bool.must.push( {
|
|
2645
|
+
'range': {
|
|
2646
|
+
'date': {
|
|
2647
|
+
'gte': req.body?.startDate ? req.body.startDate : '',
|
|
2648
|
+
'lte': req.body?.endDate ? req.body.endDate : '',
|
|
2649
|
+
},
|
|
2650
|
+
},
|
|
2651
|
+
} );
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
query.query.bool.must.push(
|
|
2655
|
+
{
|
|
2656
|
+
'terms': {
|
|
2657
|
+
'showTo.keyword': [ req.user.userType ],
|
|
2658
|
+
},
|
|
2659
|
+
},
|
|
2660
|
+
);
|
|
2661
|
+
|
|
2662
|
+
const logs = await getOpenSearchData( openSearch.activityLog, query );
|
|
2663
|
+
|
|
2664
|
+
const hits = logs?.body?.hits?.hits;
|
|
2665
|
+
const totalDocuments = logs?.body?.hits?.total?.value;
|
|
2666
|
+
|
|
2667
|
+
let temp = [];
|
|
2668
|
+
if ( totalDocuments ) {
|
|
2669
|
+
hits.map( ( hit, i ) => {
|
|
2670
|
+
let respo = {};
|
|
2671
|
+
hit._source.logSubType = hit._source.logSubType === 'documentUpload' ? 'documentsUpload' : hit._source.logSubType === 'domainDetails' ? 'securityFeatures' : hit?._source?.logSubType;
|
|
2672
|
+
if ( ( ( hit?._source?.eventType ).match( /update/ ) || ( hit?._source?.eventType ).match( /edit/ ) ) && hit?._source?.previous ) {
|
|
2673
|
+
const previous = hit?._source?.oldData;
|
|
2674
|
+
const current = hit?._source?.newData;
|
|
2675
|
+
if ( previous && current ) {
|
|
2676
|
+
respo = findDifferences( previous, current );
|
|
2677
|
+
}
|
|
2678
|
+
hit._source.updatedValue = respo;
|
|
2679
|
+
temp.push( hit?._source );
|
|
2680
|
+
// hit._source.changes =logSubType === 'ticketConfig'? Object.keys( respo ).map( ( item ) => item ) : hit._source.changes;
|
|
2681
|
+
} else {
|
|
2682
|
+
temp.push( hit?._source );
|
|
2683
|
+
}
|
|
2684
|
+
},
|
|
2685
|
+
);
|
|
2686
|
+
res.sendSuccess( { data: temp, count: totalDocuments } );
|
|
2687
|
+
} else {
|
|
2688
|
+
res.sendError( 'No data found', 204 );
|
|
2689
|
+
}
|
|
2130
2690
|
} catch ( error ) {
|
|
2131
|
-
logger.error( { error: error, message:
|
|
2691
|
+
logger.error( { error: error, message: req.body, function: 'getActivityLogs' } );
|
|
2692
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
2132
2693
|
}
|
|
2133
2694
|
}
|
|
2134
2695
|
|
|
2696
|
+
function findDifferences( oldData, newData ) {
|
|
2697
|
+
logger.info( { oldData: oldData, newData: newData } );
|
|
2698
|
+
const allKeys = new Set( [ ...Object.keys( oldData ), ...Object.keys( newData ) ] );
|
|
2699
|
+
const diff = {};
|
|
2700
|
+
|
|
2701
|
+
allKeys.forEach( ( key ) => {
|
|
2702
|
+
const previous = key in oldData ? oldData[key] : null;
|
|
2703
|
+
const current = key in newData ? newData[key] : null;
|
|
2704
|
+
|
|
2705
|
+
// Only include fields that are added or updated (where previous !== current)
|
|
2706
|
+
if ( previous !== current ) {
|
|
2707
|
+
diff[splitCamelCase( key )] = {
|
|
2708
|
+
previous,
|
|
2709
|
+
current,
|
|
2710
|
+
};
|
|
2711
|
+
}
|
|
2712
|
+
} );
|
|
2713
|
+
|
|
2714
|
+
return diff;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
function splitCamelCase( text ) {
|
|
2718
|
+
return text.replace( /([a-z])([A-Z])/g, '$1 $2' ) // Add space between camelCase words
|
|
2719
|
+
.replace( /([a-zA-Z])(\d+)/g, '$1 $2' ) // Add space between letters and numbers
|
|
2720
|
+
.replace( /(\d+)([a-zA-Z])/g, '$1 $2' )
|
|
2721
|
+
.trim()
|
|
2722
|
+
.replace( /^./, ( match ) => match.toUpperCase() ); // Capitalize the first letter
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
// async function postApi( url, data ) {
|
|
2726
|
+
// const requestOptions = {
|
|
2727
|
+
// method: 'POST',
|
|
2728
|
+
// headers: {
|
|
2729
|
+
// 'Content-Type': 'application/json',
|
|
2730
|
+
// 'Authorization': 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66',
|
|
2731
|
+
// },
|
|
2732
|
+
// body: JSON.stringify( data ),
|
|
2733
|
+
// };
|
|
2734
|
+
|
|
2735
|
+
// try {
|
|
2736
|
+
// const response = await fetch( url, requestOptions );
|
|
2737
|
+
// await response.json();
|
|
2738
|
+
// } catch ( error ) {
|
|
2739
|
+
// logger.error( { error: error, message: data, function: 'postApi' } );
|
|
2740
|
+
// }
|
|
2741
|
+
// }
|
|
2742
|
+
|
|
2743
|
+
// async function getApi( url ) {
|
|
2744
|
+
// const requestOptions = {
|
|
2745
|
+
// method: 'GET',
|
|
2746
|
+
// headers: {
|
|
2747
|
+
// 'Content-Type': 'application/json',
|
|
2748
|
+
// 'Authorization': 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66',
|
|
2749
|
+
// },
|
|
2750
|
+
// };
|
|
2751
|
+
|
|
2752
|
+
// try {
|
|
2753
|
+
// const response = await fetch( url, requestOptions );
|
|
2754
|
+
// const responseData = await response.json();
|
|
2755
|
+
// return responseData;
|
|
2756
|
+
// } catch ( error ) {
|
|
2757
|
+
// logger.error( { error: error, message: 'Error in GET request', function: 'getApi' } );
|
|
2758
|
+
// }
|
|
2759
|
+
// }
|
|
2760
|
+
|
|
2135
2761
|
|
|
2136
2762
|
export async function csmAssignConfirmation( req, res ) {
|
|
2137
2763
|
try {
|
|
@@ -2163,3 +2789,151 @@ export async function clientCsmAssignAction( req, res ) {
|
|
|
2163
2789
|
return res.sendError( 'Internal Server Error', 500 );
|
|
2164
2790
|
}
|
|
2165
2791
|
}
|
|
2792
|
+
|
|
2793
|
+
function compareArrayObjects( prevArray, currArray ) {
|
|
2794
|
+
let changes = {};
|
|
2795
|
+
// logger.info( { prevArray: prevArray, currArray: currArray } );
|
|
2796
|
+
// Find the longest array length to avoid index mismatch
|
|
2797
|
+
let maxLength = Math.max( prevArray.length, currArray.length );
|
|
2798
|
+
|
|
2799
|
+
for ( let i = 0; i < maxLength; i++ ) {
|
|
2800
|
+
let prevObj = prevArray[i] || {}; // Default to empty object if missing
|
|
2801
|
+
let currObj = currArray[i] || {};
|
|
2802
|
+
let diff = {};
|
|
2803
|
+
|
|
2804
|
+
Object.keys( { ...prevObj, ...currObj } ).forEach( ( key ) => {
|
|
2805
|
+
if ( prevObj[key] !== currObj[key] && key !== '_id' ) {
|
|
2806
|
+
const key1 = key == 'contact' ? 'Contact Number' : key == 'email' ? 'Email ID' : key == 'name' ? 'Name' : key == 'designation' ? 'Designation' : key;
|
|
2807
|
+
const name = i == 0 ? 'Primary Spoc' : `Alternate Spoc ${i + 1}`;
|
|
2808
|
+
diff[`${name} ${key1}`] = {
|
|
2809
|
+
previous: prevObj[key] || 'null',
|
|
2810
|
+
current: currObj[key] || 'null',
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
} );
|
|
2814
|
+
|
|
2815
|
+
if ( Object.keys( diff ).length > 0 ) {
|
|
2816
|
+
// changes.push( { index: i, changes: diff } );
|
|
2817
|
+
changes = { ...changes, ...diff };
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
return changes;
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
|
|
2825
|
+
export async function createAuditConfig( req, res ) {
|
|
2826
|
+
try {
|
|
2827
|
+
await createauditConfig( req.body );
|
|
2828
|
+
return res.sendSuccess( 'created Sucessfully' );
|
|
2829
|
+
} catch ( error ) {
|
|
2830
|
+
logger.error( { error: error, message: req.body, function: 'createAuditConfig' } );
|
|
2831
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
export async function updateAuditConfig( req, res ) {
|
|
2835
|
+
try {
|
|
2836
|
+
await updateauditConfig( { _id: req.params.id }, req.body );
|
|
2837
|
+
return res.sendSuccess( 'updated Sucessfully' );
|
|
2838
|
+
} catch ( error ) {
|
|
2839
|
+
logger.error( { error: error, message: req.body, function: 'createAuditConfig' } );
|
|
2840
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
export async function AuditConfiglist( req, res ) {
|
|
2844
|
+
try {
|
|
2845
|
+
let Query = [ {
|
|
2846
|
+
$match: {
|
|
2847
|
+
'$and': [
|
|
2848
|
+
{ 'clientId': { $in: req.body.clientId } },
|
|
2849
|
+
],
|
|
2850
|
+
},
|
|
2851
|
+
} ];
|
|
2852
|
+
if ( req.body.searchValue && req.body.searchValue !== '' ) {
|
|
2853
|
+
const searchCondition = {
|
|
2854
|
+
$match: {
|
|
2855
|
+
$or: [
|
|
2856
|
+
{ AuditName: { $regex: req.body.searchValue, $options: 'i' } },
|
|
2857
|
+
{ keyWord: { $regex: req.body.searchValue, $options: 'i' } },
|
|
2858
|
+
],
|
|
2859
|
+
},
|
|
2860
|
+
};
|
|
2861
|
+
|
|
2862
|
+
Query.push( searchCondition );
|
|
2863
|
+
}
|
|
2864
|
+
if ( req.body.sortColumName && req.body.sortColumName !== '' && req.body.sortBy ) {
|
|
2865
|
+
const sortOption = { $sort: { [req.body.sortColumName]: req.body.sortBy } };
|
|
2866
|
+
Query.push( sortOption );
|
|
2867
|
+
} else {
|
|
2868
|
+
const sortOption = { $sort: { 'AuditName': -1 } };
|
|
2869
|
+
Query.push( sortOption );
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2872
|
+
let count = await aggregateAuditconfig( Query );
|
|
2873
|
+
|
|
2874
|
+
if ( req.body.limit && req.body.offset && !req.body.export ) {
|
|
2875
|
+
const skipValue = ( req.body.offset - 1 ) * req.body.limit;
|
|
2876
|
+
const limitValue = Number( req.body.limit );
|
|
2877
|
+
|
|
2878
|
+
const pagination = [
|
|
2879
|
+
{ $skip: skipValue },
|
|
2880
|
+
{ $limit: limitValue },
|
|
2881
|
+
];
|
|
2882
|
+
|
|
2883
|
+
Query.push( ...pagination );
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
let result = await aggregateAuditconfig( Query );
|
|
2887
|
+
|
|
2888
|
+
if ( req.body.export && result.length > 0 ) {
|
|
2889
|
+
const exportdata = result.map( ( element ) => {
|
|
2890
|
+
return {
|
|
2891
|
+
'Audit Name': element.AuditName,
|
|
2892
|
+
'Keyword': element.keyWord,
|
|
2893
|
+
'File Type': element.fileType,
|
|
2894
|
+
'Response Type': element.responseType,
|
|
2895
|
+
'Status': element.status,
|
|
2896
|
+
};
|
|
2897
|
+
} );
|
|
2898
|
+
await download( exportdata, res );
|
|
2899
|
+
return;
|
|
2900
|
+
}
|
|
2901
|
+
return res.sendSuccess( { result: result, totalCount: count.length } );
|
|
2902
|
+
} catch ( error ) {
|
|
2903
|
+
logger.error( { error: error, message: req.body, function: 'createAuditConfig' } );
|
|
2904
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2908
|
+
|
|
2909
|
+
export async function revopconfig( req, res ) {
|
|
2910
|
+
try {
|
|
2911
|
+
let result = await findOnerevopConfig( { clientId: req.body.clientId } );
|
|
2912
|
+
|
|
2913
|
+
if ( result===null ) {
|
|
2914
|
+
await createrevopConfig( req.body );
|
|
2915
|
+
return res.sendSuccess( 'revopconfig created Sucessfully' );
|
|
2916
|
+
} else {
|
|
2917
|
+
await updaterevopConfig( { clientId: req.body.clientId }, req.body );
|
|
2918
|
+
return res.sendSuccess( 'revopconfig updated Sucessfully' );
|
|
2919
|
+
}
|
|
2920
|
+
} catch ( error ) {
|
|
2921
|
+
logger.error( { error: error, message: req.body, function: 'revopconfig' } );
|
|
2922
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
export async function getrevopconfig( req, res ) {
|
|
2927
|
+
try {
|
|
2928
|
+
let result = await findOnerevopConfig( { clientId: req.query.clientId } );
|
|
2929
|
+
if ( result===null ) {
|
|
2930
|
+
return res.sendError( 'no data found', 204 );
|
|
2931
|
+
}
|
|
2932
|
+
return res.sendSuccess( result );
|
|
2933
|
+
} catch ( error ) {
|
|
2934
|
+
logger.error( { error: error, message: req.query, function: 'revopconfig' } );
|
|
2935
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
|
|
2939
|
+
|