tango-app-api-client 3.1.14 → 3.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/controllers/client.controllers.js +668 -85
- package/src/docs/client.docs.js +0 -16
- package/src/dtos/client.dtos.js +22 -0
- package/src/routes/client.routes.js +12 -4
- package/src/service/client.service.js +16 -4
- package/src/service/group.service.js +8 -0
- package/src/service/store.service.js +7 -0
- package/src/service/userAssignedStore.service.js +13 -0
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import { billingDetailsUpdate, brandInfoUpdate, domainDetailsConfigurationUpdate, featureConfigurationUpdate, getClientData, signatoryDetailsUpdate, ticketConfigurationUpdate, documentsUpdate, getUserData, auditConfigurationUpdate, auditConfigurationGet, CsmUsersGet, OpsUsersGet, userConfigurationUpdate, findClient, aggregateClient, createAuditQueue, findOne, insert, update, findOneClient } from '../service/client.service.js';
|
|
2
|
-
import { checkFileExist, fileUpload, signedUrl, chunkArray, download, logger, getOpenSearchData, insertOpenSearchData,
|
|
1
|
+
import { billingDetailsUpdate, brandInfoUpdate, domainDetailsConfigurationUpdate, featureConfigurationUpdate, getClientData, signatoryDetailsUpdate, ticketConfigurationUpdate, documentsUpdate, getUserData, auditConfigurationUpdate, auditConfigurationGet, CsmUsersGet, OpsUsersGet, userConfigurationUpdate, findClient, aggregateClient, createAuditQueue, findOne, insert, update, findOneClient, updateOneClient } from '../service/client.service.js';
|
|
2
|
+
import { checkFileExist, fileUpload, signedUrl, chunkArray, download, logger, getOpenSearchData, insertOpenSearchData, sendEmailWithSES } from 'tango-app-api-middleware';
|
|
3
3
|
import { countDocumentsUser, findOneAndUpdateUser, findOneUser, getUserNameEmailById, updateManyUser } from '../service/user.service.js';
|
|
4
|
-
import { aggregateStore, countDocumentsStore, updateManyStore } from '../service/store.service.js';
|
|
5
|
-
import { aggregateCamera, countDocumentsCamera
|
|
4
|
+
import { aggregateStore, countDocumentsStore, findStore, findOneStore, updateManyStore } from '../service/store.service.js';
|
|
5
|
+
import { aggregateCamera, countDocumentsCamera } from '../service/camera.service.js';
|
|
6
6
|
import _ from 'lodash';
|
|
7
7
|
import { findOneStandaredRole } from '../service/standaredRole.service.js';
|
|
8
|
-
import { aggregateUserAssignedStore } from '../service/userAssignedStore.service.js';
|
|
8
|
+
import { aggregateUserAssignedStore, deleteOneAssignedStore, updateOneUserAssignedStore } from '../service/userAssignedStore.service.js';
|
|
9
9
|
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 } from '../service/group.service.js';
|
|
13
|
+
import { countDocumentsGroup, createGroupModel, findOneGroup } from '../service/group.service.js';
|
|
14
14
|
import { deleteOneAuthentication } from '../service/authentication.service.js';
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
export async function create( req, res ) {
|
|
18
18
|
try {
|
|
19
|
+
const url = JSON.parse( process.env.URL );
|
|
20
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
19
21
|
const inputData = req.body;
|
|
20
22
|
const countQuery = [
|
|
21
23
|
{
|
|
@@ -71,9 +73,33 @@ export async function create( req, res ) {
|
|
|
71
73
|
|
|
72
74
|
const insertClient = await insert( record );
|
|
73
75
|
|
|
76
|
+
const insertedClientRecord = await findOneClient( { clientId: record.clientId }, {} );
|
|
77
|
+
|
|
78
|
+
const defaultGroup = {
|
|
79
|
+
'groupName': 'All stores',
|
|
80
|
+
'description': 'Contains all the onboarded stores',
|
|
81
|
+
'storeList': [],
|
|
82
|
+
'clientId': insertedClientRecord.clientId,
|
|
83
|
+
'isDefault': true,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
await createGroupModel( defaultGroup );
|
|
87
|
+
|
|
88
|
+
const createdGroup = await findOneGroup( { clientId: insertedClientRecord.clientId, isDefault: true }, {} );
|
|
89
|
+
|
|
90
|
+
let oldGroup = {
|
|
91
|
+
'_id': createdGroup._id,
|
|
92
|
+
'client_id': createdGroup.clientId,
|
|
93
|
+
'groupName': createdGroup.groupName,
|
|
94
|
+
'description': createdGroup.description,
|
|
95
|
+
'storeList': createdGroup.storeList,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
await postApi( `${url.oldapidomain}/oldGroupAdd`, [ oldGroup ] );
|
|
100
|
+
|
|
74
101
|
// For old dashboard insert
|
|
75
102
|
|
|
76
|
-
const insertedClientRecord = await findOneClient( { clientId: record.clientId }, {} );
|
|
77
103
|
|
|
78
104
|
const oldBrandInsertData = {
|
|
79
105
|
'_id': insertedClientRecord._id,
|
|
@@ -93,9 +119,7 @@ export async function create( req, res ) {
|
|
|
93
119
|
'birdsEye',
|
|
94
120
|
'tangoZone',
|
|
95
121
|
'tangoTraffic',
|
|
96
|
-
'
|
|
97
|
-
'footFallDirectory',
|
|
98
|
-
'tangoSOP',
|
|
122
|
+
'support',
|
|
99
123
|
],
|
|
100
124
|
'planType': insertedClientRecord.planDetails.subscriptionPeriod,
|
|
101
125
|
'storeCount': insertedClientRecord.planDetails.totalStores,
|
|
@@ -176,9 +200,47 @@ export async function create( req, res ) {
|
|
|
176
200
|
'role': 'storesuperadmin',
|
|
177
201
|
};
|
|
178
202
|
|
|
179
|
-
await postApi( `${
|
|
203
|
+
await postApi( `${url.oldapidomain}/oldBrandAdd`, oldBrandInsertData );
|
|
204
|
+
|
|
205
|
+
await postApi( `${url.oldapidomain}/oldDefaultRoleInsert`, oldDefaultRolesInsertData );
|
|
206
|
+
|
|
207
|
+
const logObj = {
|
|
208
|
+
clientId: insertedClientRecord.clientId,
|
|
209
|
+
userName: req.user?.userName,
|
|
210
|
+
email: req.user?.email,
|
|
211
|
+
date: new Date(),
|
|
212
|
+
logType: 'brandDetails',
|
|
213
|
+
logSubType: 'brandApproval',
|
|
214
|
+
changes: [ insertedClientRecord.clientName ],
|
|
215
|
+
showTo: [],
|
|
216
|
+
eventType: 'approve',
|
|
217
|
+
showTo: [ 'client', 'tango' ],
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
221
|
+
|
|
222
|
+
for ( let index = 0; index < leadRecord?.planDetails?.product?.length; index++ ) {
|
|
223
|
+
const logObj = {
|
|
224
|
+
userName: req.user?.userName,
|
|
225
|
+
email: req.user?.email,
|
|
226
|
+
clientId: insertedClientRecord.clientId,
|
|
227
|
+
clientNotification: false,
|
|
228
|
+
adminNotification: true,
|
|
229
|
+
logSubType: 'startTrial',
|
|
230
|
+
description: 'Subscription - Your 14 Days free trial has been started',
|
|
231
|
+
title: 'Subscription',
|
|
232
|
+
alertCta: [],
|
|
233
|
+
markasRead: false,
|
|
234
|
+
logType: 'subscription',
|
|
235
|
+
showPushNotification: true,
|
|
236
|
+
date: new Date(),
|
|
237
|
+
changes: [ `${convertTitleCase( leadRecord?.planDetails?.product[index] )} trial started` ],
|
|
238
|
+
eventType: '',
|
|
239
|
+
showTo: [ 'client', 'tango' ],
|
|
240
|
+
};
|
|
180
241
|
|
|
181
|
-
|
|
242
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
243
|
+
}
|
|
182
244
|
|
|
183
245
|
|
|
184
246
|
if ( insertClient ) {
|
|
@@ -200,14 +262,23 @@ export async function create( req, res ) {
|
|
|
200
262
|
}
|
|
201
263
|
}
|
|
202
264
|
|
|
265
|
+
function convertTitleCase( data ) {
|
|
266
|
+
let [ firstWord, secondWord ] = data.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
267
|
+
firstWord = firstWord.charAt( 0 ).toUpperCase() + firstWord.slice( 1 );
|
|
268
|
+
data = firstWord + ' ' + secondWord;
|
|
269
|
+
return data;
|
|
270
|
+
}
|
|
271
|
+
|
|
203
272
|
export const sendEmail = ( data ) => {
|
|
204
273
|
try {
|
|
274
|
+
const url = JSON.parse( process.env.URL );
|
|
275
|
+
const ses = JSON.parse( process.env.SES );
|
|
205
276
|
const attachments = null;
|
|
206
277
|
const subject = data.subject;
|
|
207
278
|
const fileContent = readFileSync( join() + data.path, 'utf8' );
|
|
208
279
|
const htmlContent = handlebars.compile( fileContent );
|
|
209
|
-
const html = htmlContent( { url:
|
|
210
|
-
return sendEmailWithSES( data.email, subject, html, attachments,
|
|
280
|
+
const html = htmlContent( { url: url.store, logo: `${url.apiDomain}/logo.png` } );
|
|
281
|
+
return sendEmailWithSES( data.email, subject, html, attachments, ses.adminEmail );
|
|
211
282
|
} catch ( error ) {
|
|
212
283
|
return error;
|
|
213
284
|
}
|
|
@@ -249,6 +320,18 @@ export async function getClients( req, res ) {
|
|
|
249
320
|
$match: {
|
|
250
321
|
userEmail: req?.user?.email,
|
|
251
322
|
assignedType: { $eq: 'client' },
|
|
323
|
+
$expr: {
|
|
324
|
+
$cond: {
|
|
325
|
+
if: {
|
|
326
|
+
$and: [
|
|
327
|
+
{ $eq: [ '$userType', 'tango' ] },
|
|
328
|
+
{ $eq: [ '$tangoUserType', 'csm' ] },
|
|
329
|
+
],
|
|
330
|
+
},
|
|
331
|
+
then: { $eq: [ '$isClientApproved', true ] },
|
|
332
|
+
else: true,
|
|
333
|
+
},
|
|
334
|
+
},
|
|
252
335
|
},
|
|
253
336
|
},
|
|
254
337
|
{
|
|
@@ -302,61 +385,62 @@ export async function getClients( req, res ) {
|
|
|
302
385
|
|
|
303
386
|
export async function clientDetails( req, res ) {
|
|
304
387
|
try {
|
|
388
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
305
389
|
const client = await getClientData( { id: req.params.id } );
|
|
306
390
|
if ( client ) {
|
|
307
|
-
const isLogoExist = await checkFileExist( { Bucket:
|
|
308
|
-
const isGstCertificateExist = await checkFileExist( { Bucket:
|
|
309
|
-
const isAddressCertificateExist = await checkFileExist( { Bucket:
|
|
310
|
-
const isPanCertificateExist = await checkFileExist( { Bucket:
|
|
311
|
-
const isCinCertificateExist = await checkFileExist( { Bucket:
|
|
312
|
-
const isContractCertificateExist = await checkFileExist( { Bucket:
|
|
313
|
-
const isTermsAndConditionsExist = await checkFileExist( { Bucket:
|
|
391
|
+
const isLogoExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
392
|
+
const isGstCertificateExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/documents/${client.document?.gst?.path}` } );
|
|
393
|
+
const isAddressCertificateExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/documents/${client.document?.addressProof?.path}` } );
|
|
394
|
+
const isPanCertificateExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/documents/${client.document?.pan?.path}` } );
|
|
395
|
+
const isCinCertificateExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/documents/${client.document?.cin?.path}` } );
|
|
396
|
+
const isContractCertificateExist = await checkFileExist( { Bucket: bucket.assets, Key: `documents/contract.pdf` } );
|
|
397
|
+
const isTermsAndConditionsExist = await checkFileExist( { Bucket: bucket.assets, Key: `documents/terms&conditions.pdf` } );
|
|
314
398
|
|
|
315
399
|
|
|
316
400
|
if ( isLogoExist ) {
|
|
317
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
401
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
318
402
|
client.profileDetails.logo = signedFilUrl;
|
|
319
403
|
} else {
|
|
320
404
|
client.profileDetails.logo = '';
|
|
321
405
|
}
|
|
322
406
|
|
|
323
407
|
if ( isGstCertificateExist ) {
|
|
324
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
408
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.gst?.path}` } );
|
|
325
409
|
client.document.gst.path = signedFilUrl;
|
|
326
410
|
} else {
|
|
327
411
|
client.document.gst.path = '';
|
|
328
412
|
}
|
|
329
413
|
|
|
330
414
|
if ( isAddressCertificateExist ) {
|
|
331
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
415
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.addressProof?.path}` } );
|
|
332
416
|
client.document.addressProof.path = signedFilUrl;
|
|
333
417
|
} else {
|
|
334
418
|
client.document.addressProof.path = '';
|
|
335
419
|
}
|
|
336
420
|
|
|
337
421
|
if ( isPanCertificateExist ) {
|
|
338
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
422
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.pan?.path}` } );
|
|
339
423
|
client.document.pan.path = signedFilUrl;
|
|
340
424
|
} else {
|
|
341
425
|
client.document.pan.path = '';
|
|
342
426
|
}
|
|
343
427
|
|
|
344
428
|
if ( isCinCertificateExist ) {
|
|
345
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
429
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.cin?.path}` } );
|
|
346
430
|
client.document.cin.path = signedFilUrl;
|
|
347
431
|
} else {
|
|
348
432
|
client.document.cin.path = '';
|
|
349
433
|
}
|
|
350
434
|
|
|
351
435
|
if ( isContractCertificateExist ) {
|
|
352
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
436
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `documents/contract.pdf` } );
|
|
353
437
|
client._doc.document.contract = signedFilUrl;
|
|
354
438
|
} else {
|
|
355
439
|
client._doc.document.contract = '';
|
|
356
440
|
}
|
|
357
441
|
|
|
358
442
|
if ( isTermsAndConditionsExist ) {
|
|
359
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
443
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `documents/terms&conditions.pdf` } );
|
|
360
444
|
client._doc.document.termsAndconditions = signedFilUrl;
|
|
361
445
|
} else {
|
|
362
446
|
client._doc.document.termsAndconditions = '';
|
|
@@ -382,18 +466,30 @@ export async function detailedAllClientCount( req, res ) {
|
|
|
382
466
|
{
|
|
383
467
|
$project: {
|
|
384
468
|
activeClient: { $cond: [ { $eq: [ '$status', 'active' ] }, 1, 0 ] },
|
|
385
|
-
paidClient: {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
469
|
+
paidClient: {
|
|
470
|
+
$cond: [ {
|
|
471
|
+
$and: [
|
|
472
|
+
{ $eq: [ '$status', 'active' ] },
|
|
473
|
+
{ $in: [ '$planDetails.paymentStatus', [ 'paid', 'unbilled', 'due' ] ] },
|
|
474
|
+
],
|
|
475
|
+
}, 1, 0 ],
|
|
476
|
+
},
|
|
477
|
+
trialClient: {
|
|
478
|
+
$cond: [ {
|
|
479
|
+
$and: [
|
|
480
|
+
{ $eq: [ '$status', 'active' ] },
|
|
481
|
+
{ $eq: [ '$planDetails.paymentStatus', 'trial' ] },
|
|
482
|
+
],
|
|
483
|
+
}, 1, 0 ],
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
freeClient: {
|
|
487
|
+
$cond: [ {
|
|
488
|
+
$and: [
|
|
489
|
+
{ $eq: [ '$status', 'active' ] }, { $eq: [ '$planDetails.paymentStatus', 'free' ] },
|
|
490
|
+
],
|
|
491
|
+
}, 1, 0 ],
|
|
492
|
+
},
|
|
397
493
|
holdClient: { $cond: [ { $eq: [ '$status', 'hold' ] }, 1, 0 ] },
|
|
398
494
|
suspendClient: { $cond: [ { $eq: [ '$status', 'suspended' ] }, 1, 0 ] },
|
|
399
495
|
deactiveClient: { $cond: [ { $eq: [ '$status', 'deactive' ] }, 1, 0 ] },
|
|
@@ -413,11 +509,34 @@ export async function detailedAllClientCount( req, res ) {
|
|
|
413
509
|
|
|
414
510
|
},
|
|
415
511
|
},
|
|
512
|
+
{
|
|
513
|
+
$project: {
|
|
514
|
+
_id: 0,
|
|
515
|
+
totalCount: 1,
|
|
516
|
+
activeClient: 1,
|
|
517
|
+
paidClient: 1,
|
|
518
|
+
trialClient: 1,
|
|
519
|
+
freeClient: 1,
|
|
520
|
+
holdClient: 1,
|
|
521
|
+
suspendClient: 1,
|
|
522
|
+
deactiveClient: 1,
|
|
523
|
+
activeStoresCount: { $ifNull: [ 0, 0 ] },
|
|
524
|
+
activeCameraCount: { $ifNull: [ 0, 0 ] },
|
|
525
|
+
},
|
|
526
|
+
},
|
|
416
527
|
];
|
|
417
528
|
const result = await aggregateClient( query );
|
|
418
|
-
|
|
529
|
+
const activeStores = await findStore( { 'status': 'active', 'edge.firstFile': true }, { storeId: 1 } );
|
|
530
|
+
let storesList = [];
|
|
531
|
+
for ( let store of activeStores ) {
|
|
532
|
+
storesList.push( store.storeId );
|
|
533
|
+
}
|
|
534
|
+
const activeCameras = await countDocumentsCamera( { storeId: { $in: storesList }, isUp: true, isActivated: true } );
|
|
535
|
+
if ( result.length == 0 ) {
|
|
419
536
|
return res.sendError( 'No Data Found', 204 );
|
|
420
537
|
}
|
|
538
|
+
result[0].activeStoresCount = activeStores.length;
|
|
539
|
+
result[0].activeCameraCount = activeCameras;
|
|
421
540
|
return res.sendSuccess( { result: result } );
|
|
422
541
|
} catch ( error ) {
|
|
423
542
|
logger.error( { error: error, function: 'detailedAllClientCount' } );
|
|
@@ -433,11 +552,14 @@ function camelCaseToWords( camelCaseString ) {
|
|
|
433
552
|
|
|
434
553
|
export async function updateBrandInfo( req, res ) {
|
|
435
554
|
try {
|
|
555
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
556
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
557
|
+
const url = JSON.parse( process.env.URL );
|
|
436
558
|
let updateKeys = [];
|
|
437
559
|
|
|
438
560
|
if ( req.files?.logo ) {
|
|
439
561
|
const uploadDataParams = {
|
|
440
|
-
Bucket:
|
|
562
|
+
Bucket: bucket.assets,
|
|
441
563
|
Key: `${req.params.id}/logo/`,
|
|
442
564
|
fileName: `brandLogo.${req.files.logo.name.split( '.' )[1]}`,
|
|
443
565
|
ContentType: req.files.logo.mimetype,
|
|
@@ -465,9 +587,12 @@ export async function updateBrandInfo( req, res ) {
|
|
|
465
587
|
logSubType: 'brandInfo',
|
|
466
588
|
changes: updateKeys,
|
|
467
589
|
eventType: 'update',
|
|
590
|
+
showTo: [ 'client', 'tango' ],
|
|
468
591
|
};
|
|
469
592
|
|
|
470
|
-
|
|
593
|
+
if ( updateKeys.length ) {
|
|
594
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
595
|
+
}
|
|
471
596
|
|
|
472
597
|
|
|
473
598
|
const updateAck = await brandInfoUpdate( {
|
|
@@ -492,11 +617,11 @@ export async function updateBrandInfo( req, res ) {
|
|
|
492
617
|
|
|
493
618
|
if ( req.body?.status === 'deactive' ) {
|
|
494
619
|
await updateManyStore( { clientId: req.params?.id }, { status: 'deactive' } );
|
|
495
|
-
await updateManyCamera( { clientId: req.params?.id }, { isUp: false, isActivated: false } );
|
|
620
|
+
// await updateManyCamera( { clientId: req.params?.id }, { isUp: false, isActivated: false } );
|
|
496
621
|
await updateManyUser( { clientId: req.params?.id }, { isActive: false } );
|
|
497
622
|
}
|
|
498
623
|
|
|
499
|
-
const { data } = await getApi( `${
|
|
624
|
+
const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
500
625
|
|
|
501
626
|
switch ( req.body?.status ) {
|
|
502
627
|
case 'active':
|
|
@@ -515,7 +640,7 @@ export async function updateBrandInfo( req, res ) {
|
|
|
515
640
|
data.clientStatus = 'live';
|
|
516
641
|
}
|
|
517
642
|
|
|
518
|
-
await postApi( `${
|
|
643
|
+
await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { clientStatus: data.clientStatus } );
|
|
519
644
|
|
|
520
645
|
if ( updateAck ) {
|
|
521
646
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
@@ -528,11 +653,13 @@ export async function updateBrandInfo( req, res ) {
|
|
|
528
653
|
|
|
529
654
|
export async function updateBillingDetails( req, res ) {
|
|
530
655
|
try {
|
|
656
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
657
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
531
658
|
let updateKeys = [];
|
|
532
659
|
|
|
533
660
|
if ( req.files?.gstCertificate ) {
|
|
534
661
|
const uploadDataParams = {
|
|
535
|
-
Bucket:
|
|
662
|
+
Bucket: bucket.assets,
|
|
536
663
|
Key: `${req.params.id}/documents/`,
|
|
537
664
|
fileName: `gstCertificate.${req.files.gstCertificate.name.split( '.' )[1]}`,
|
|
538
665
|
ContentType: req.files.gstCertificate.mimetype,
|
|
@@ -559,9 +686,13 @@ export async function updateBillingDetails( req, res ) {
|
|
|
559
686
|
logSubType: 'billingDetails',
|
|
560
687
|
changes: updateKeys,
|
|
561
688
|
eventType: 'update',
|
|
689
|
+
showTo: [ 'client', 'tango' ],
|
|
562
690
|
};
|
|
563
691
|
|
|
564
|
-
|
|
692
|
+
if ( updateKeys.length ) {
|
|
693
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
694
|
+
}
|
|
695
|
+
|
|
565
696
|
|
|
566
697
|
const updateAck = await billingDetailsUpdate( {
|
|
567
698
|
clientId: req.params?.id, tradeName: req.body?.tradeName, gstNumber: req.body?.gstNumber,
|
|
@@ -579,6 +710,7 @@ export async function updateBillingDetails( req, res ) {
|
|
|
579
710
|
|
|
580
711
|
export async function updateSignatoryDetails( req, res ) {
|
|
581
712
|
try {
|
|
713
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
582
714
|
let updateKeys = [];
|
|
583
715
|
if ( Object.keys( req.body ).length > 0 ) {
|
|
584
716
|
Object.keys( req.body ).forEach( ( element ) => {
|
|
@@ -597,9 +729,13 @@ export async function updateSignatoryDetails( req, res ) {
|
|
|
597
729
|
logSubType: 'signatoryDetails',
|
|
598
730
|
changes: updateKeys,
|
|
599
731
|
eventType: 'update',
|
|
732
|
+
showTo: [ 'client', 'tango' ],
|
|
600
733
|
};
|
|
601
734
|
|
|
602
|
-
|
|
735
|
+
if ( updateKeys.length ) {
|
|
736
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
737
|
+
}
|
|
738
|
+
|
|
603
739
|
const updateAck = await signatoryDetailsUpdate( {
|
|
604
740
|
clientId: req.params?.id, name: req.body?.name, email: req.body?.email,
|
|
605
741
|
number: req.body?.number, designation: req.body?.designation,
|
|
@@ -615,6 +751,7 @@ export async function updateSignatoryDetails( req, res ) {
|
|
|
615
751
|
|
|
616
752
|
export async function updateTicketConfiguration( req, res ) {
|
|
617
753
|
try {
|
|
754
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
618
755
|
const updateAck = await ticketConfigurationUpdate( {
|
|
619
756
|
clientId: req.params?.id, MinFilesCount: req.body?.MinFilesCount, accuracyPercentage: req.body?.accuracyPercentage, downTimeType: req.body?.downTimeType,
|
|
620
757
|
infraDownTime: req.body?.infraDownTime, installationReAssign: req.body?.installationReAssign, isRcaTicketAssign: req.body?.isRcaTicketAssign,
|
|
@@ -640,8 +777,12 @@ export async function updateTicketConfiguration( req, res ) {
|
|
|
640
777
|
logSubType: 'ticketConfig',
|
|
641
778
|
changes: updateKeys,
|
|
642
779
|
eventType: 'update',
|
|
780
|
+
showTo: [ 'tango' ],
|
|
643
781
|
};
|
|
644
|
-
|
|
782
|
+
|
|
783
|
+
if ( updateKeys.length ) {
|
|
784
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
785
|
+
}
|
|
645
786
|
|
|
646
787
|
if ( updateAck ) {
|
|
647
788
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
@@ -654,11 +795,14 @@ export async function updateTicketConfiguration( req, res ) {
|
|
|
654
795
|
|
|
655
796
|
export async function updateFeatureConfiguration( req, res ) {
|
|
656
797
|
try {
|
|
798
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
799
|
+
const url = JSON.parse( process.env.URL );
|
|
657
800
|
const updateAck = await featureConfigurationUpdate( {
|
|
658
801
|
clientId: req.params?.id, billableCalculation: req.body?.billableCalculation, bouncedLimitCondition: req.body?.bouncedLimitCondition, bouncedLimitValue: req.body?.bouncedLimitValue,
|
|
659
802
|
close: req.body?.close, conversionCalculation: req.body?.conversionCalculation, conversionCondition: req.body?.conversionCondition,
|
|
660
803
|
conversionValue: req.body?.conversionValue, infraAlertCondition: req.body?.infraAlertCondition, infraAlertValue: req.body?.infraAlertValue, isFootfallDirectory: req.body?.isFootfallDirectory,
|
|
661
804
|
isNormalized: req.body?.isNormalized, isPasserByData: req.body?.isPasserByData, missedOpportunityCalculation: req.body?.missedOpportunityCalculation, open: req.body?.open,
|
|
805
|
+
isExcludedArea: req.body?.isExcludedArea,
|
|
662
806
|
} );
|
|
663
807
|
|
|
664
808
|
let updateKeys = [];
|
|
@@ -671,7 +815,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
671
815
|
|
|
672
816
|
const user = await getUserNameEmailById( req.userId );
|
|
673
817
|
|
|
674
|
-
const { data } = await getApi( `${
|
|
818
|
+
const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
675
819
|
|
|
676
820
|
if ( req.body?.open ) {
|
|
677
821
|
data.brandConfigs.storeOpenTime = req.body?.open;
|
|
@@ -713,7 +857,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
713
857
|
data.brandConfigs.missedOpportunityEndTime = data.brandConfigs.missedOpportunityEndTime.replace( /\d+/, req.body?.conversionValue );
|
|
714
858
|
}
|
|
715
859
|
|
|
716
|
-
await postApi( `${
|
|
860
|
+
await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { brandConfigs: data.brandConfigs } );
|
|
717
861
|
|
|
718
862
|
|
|
719
863
|
const logObj = {
|
|
@@ -725,8 +869,11 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
725
869
|
logSubType: 'featureConfig',
|
|
726
870
|
changes: updateKeys,
|
|
727
871
|
eventType: 'update',
|
|
872
|
+
showTo: [ 'client', 'tango' ],
|
|
728
873
|
};
|
|
729
|
-
|
|
874
|
+
if ( updateKeys.length ) {
|
|
875
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
876
|
+
}
|
|
730
877
|
|
|
731
878
|
if ( updateAck ) {
|
|
732
879
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
@@ -739,6 +886,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
739
886
|
|
|
740
887
|
export async function domainDetailsConfiguration( req, res ) {
|
|
741
888
|
try {
|
|
889
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
742
890
|
const updateAck = await domainDetailsConfigurationUpdate( {
|
|
743
891
|
clientId: req.params?.id, domainName: req.body?.domainName, isEnable: req.body?.isEnable,
|
|
744
892
|
} );
|
|
@@ -764,9 +912,13 @@ export async function domainDetailsConfiguration( req, res ) {
|
|
|
764
912
|
logSubType: 'domainDetails',
|
|
765
913
|
changes: updateKeys,
|
|
766
914
|
eventType: 'update',
|
|
915
|
+
showTo: [ 'client', 'tango' ],
|
|
767
916
|
};
|
|
768
917
|
|
|
769
|
-
|
|
918
|
+
if ( updateKeys.length ) {
|
|
919
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
920
|
+
}
|
|
921
|
+
|
|
770
922
|
if ( updateAck ) {
|
|
771
923
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
772
924
|
}
|
|
@@ -792,11 +944,13 @@ export async function userConfiguration( req, res ) {
|
|
|
792
944
|
|
|
793
945
|
export async function updateDocuments( req, res ) {
|
|
794
946
|
try {
|
|
947
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
948
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
795
949
|
let updateKeys = [];
|
|
796
950
|
|
|
797
951
|
if ( req.files?.addressDoc ) {
|
|
798
952
|
const uploadDataParams = {
|
|
799
|
-
Bucket:
|
|
953
|
+
Bucket: bucket.assets,
|
|
800
954
|
Key: `${req.params.id}/documents/`,
|
|
801
955
|
fileName: `addressCertificate.${req.files.addressDoc.name.split( '.' )[1]}`,
|
|
802
956
|
ContentType: req.files.addressDoc.mimetype,
|
|
@@ -809,7 +963,7 @@ export async function updateDocuments( req, res ) {
|
|
|
809
963
|
}
|
|
810
964
|
if ( req.files?.gstDoc ) {
|
|
811
965
|
const uploadDataParams = {
|
|
812
|
-
Bucket:
|
|
966
|
+
Bucket: bucket.assets,
|
|
813
967
|
Key: `${req.params.id}/documents/`,
|
|
814
968
|
fileName: `gstCertificate.${req.files.gstDoc.name.split( '.' )[1]}`,
|
|
815
969
|
ContentType: req.files.gstDoc.mimetype,
|
|
@@ -822,7 +976,7 @@ export async function updateDocuments( req, res ) {
|
|
|
822
976
|
}
|
|
823
977
|
if ( req.files?.panDoc ) {
|
|
824
978
|
const uploadDataParams = {
|
|
825
|
-
Bucket:
|
|
979
|
+
Bucket: bucket.assets,
|
|
826
980
|
Key: `${req.params.id}/documents/`,
|
|
827
981
|
fileName: `panCertificate.${req.files.panDoc.name.split( '.' )[1]}`,
|
|
828
982
|
ContentType: req.files.panDoc.mimetype,
|
|
@@ -835,7 +989,7 @@ export async function updateDocuments( req, res ) {
|
|
|
835
989
|
}
|
|
836
990
|
if ( req.files?.cinDoc ) {
|
|
837
991
|
const uploadDataParams = {
|
|
838
|
-
Bucket:
|
|
992
|
+
Bucket: bucket.assets,
|
|
839
993
|
Key: `${req.params.id}/documents/`,
|
|
840
994
|
fileName: `cinCertificate.${req.files.cinDoc.name.split( '.' )[1]}`,
|
|
841
995
|
ContentType: req.files.cinDoc.mimetype,
|
|
@@ -874,9 +1028,12 @@ export async function updateDocuments( req, res ) {
|
|
|
874
1028
|
logSubType: 'documentUpload',
|
|
875
1029
|
changes: updateKeys,
|
|
876
1030
|
eventType: 'update',
|
|
1031
|
+
showTo: [ 'client', 'tango' ],
|
|
877
1032
|
};
|
|
878
1033
|
|
|
879
|
-
|
|
1034
|
+
if ( updateKeys.length ) {
|
|
1035
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
1036
|
+
}
|
|
880
1037
|
|
|
881
1038
|
if ( updateAck ) {
|
|
882
1039
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
@@ -889,11 +1046,12 @@ export async function updateDocuments( req, res ) {
|
|
|
889
1046
|
|
|
890
1047
|
export async function getAuditConfiguration( req, res ) {
|
|
891
1048
|
try {
|
|
1049
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
892
1050
|
const auditConfig = await auditConfigurationGet( { storeId: req.params?.id } );
|
|
893
1051
|
if ( auditConfig ) {
|
|
894
|
-
const isDocExist = await checkFileExist( { Bucket:
|
|
1052
|
+
const isDocExist = await checkFileExist( { Bucket: bucket.assets, Key: `templates/audit_bulk_update.xlsx` } );
|
|
895
1053
|
if ( isDocExist ) {
|
|
896
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
1054
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `templates/audit_bulk_update.xlsx` } );
|
|
897
1055
|
auditConfig._doc.templateUrl = signedFilUrl;
|
|
898
1056
|
} else {
|
|
899
1057
|
auditConfig._doc.templateUrl = '';
|
|
@@ -911,36 +1069,39 @@ export async function getAuditConfiguration( req, res ) {
|
|
|
911
1069
|
|
|
912
1070
|
export async function auditConfiguration( req, res ) {
|
|
913
1071
|
try {
|
|
1072
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
914
1073
|
for ( let i = 0; i < req.body?.length; i++ ) {
|
|
1074
|
+
const previousStore = await findOneStore( { storeId: req.body[i].storeId }, { auditConfigs: 1, _id: 0 } );
|
|
915
1075
|
await auditConfigurationUpdate( {
|
|
916
1076
|
storeId: req.body[i].storeId,
|
|
917
1077
|
count: req.body[i].count,
|
|
918
1078
|
iteration: req.body[i].iteration,
|
|
919
1079
|
ratio: normalizeNumber( req.body[i].ratio, 0, 100 ),
|
|
920
1080
|
} );
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
const user = await getUserNameEmailById( req.userId );
|
|
924
1081
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1082
|
+
const logObj = {
|
|
1083
|
+
clientId: req.params?.id,
|
|
1084
|
+
userName: req.user?.userName,
|
|
1085
|
+
email: req.user?.email,
|
|
1086
|
+
date: new Date(),
|
|
1087
|
+
logType: 'configuration',
|
|
1088
|
+
logSubType: 'auditConfig',
|
|
1089
|
+
eventType: 'update',
|
|
1090
|
+
showTo: [ 'tango' ],
|
|
1091
|
+
changes: [ `Audit config for store id ${req.body[i].storeId}` ],
|
|
1092
|
+
storeId: req.body[i].storeId,
|
|
1093
|
+
previous: previousStore,
|
|
1094
|
+
current: {
|
|
1095
|
+
storeId: req.body[i].storeId,
|
|
1096
|
+
count: req.body[i].count,
|
|
1097
|
+
iteration: req.body[i].iteration,
|
|
1098
|
+
ratio: normalizeNumber( req.body[i].ratio, 0, 100 ),
|
|
1099
|
+
},
|
|
1100
|
+
};
|
|
938
1101
|
|
|
939
|
-
|
|
940
|
-
logObj.changes = [ `Audit config bulk` ];
|
|
1102
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
941
1103
|
}
|
|
942
1104
|
|
|
943
|
-
await insertOpenSearchData( 'tango-retail-activity-logs', logObj );
|
|
944
1105
|
|
|
945
1106
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
946
1107
|
} catch ( error ) {
|
|
@@ -978,6 +1139,17 @@ export async function clientList( req, res ) {
|
|
|
978
1139
|
$match: {
|
|
979
1140
|
userEmail: { $eq: req?.user?.email },
|
|
980
1141
|
userType: 'tango',
|
|
1142
|
+
$expr: {
|
|
1143
|
+
$cond: {
|
|
1144
|
+
if: {
|
|
1145
|
+
$and: [
|
|
1146
|
+
{ $eq: [ '$tangoUserType', 'csm' ] },
|
|
1147
|
+
],
|
|
1148
|
+
},
|
|
1149
|
+
then: { $eq: [ '$isClientApproved', true ] },
|
|
1150
|
+
else: true,
|
|
1151
|
+
},
|
|
1152
|
+
},
|
|
981
1153
|
|
|
982
1154
|
},
|
|
983
1155
|
}, {
|
|
@@ -990,7 +1162,7 @@ export async function clientList( req, res ) {
|
|
|
990
1162
|
];
|
|
991
1163
|
const clientIdList = await aggregateUserAssignedStore( query );
|
|
992
1164
|
logger.info( { message: clientIdList, value: 'clientIdList' } );
|
|
993
|
-
if ( clientIdList.length ==0 ) {
|
|
1165
|
+
if ( clientIdList.length == 0 ) {
|
|
994
1166
|
return res.sendError( 'No Data Found', 204 );
|
|
995
1167
|
}
|
|
996
1168
|
|
|
@@ -1003,6 +1175,10 @@ export async function clientList( req, res ) {
|
|
|
1003
1175
|
);
|
|
1004
1176
|
}
|
|
1005
1177
|
if ( inputData.filterByPaymentStatus ) {
|
|
1178
|
+
if ( inputData.filterByPaymentStatus.includes( 'paid' ) ) {
|
|
1179
|
+
inputData.filterByPaymentStatus.push( ...[ 'unbilled', 'due' ] );
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1006
1182
|
clientQuery.push(
|
|
1007
1183
|
{
|
|
1008
1184
|
$match: {
|
|
@@ -1253,8 +1429,13 @@ export async function clientList( req, res ) {
|
|
|
1253
1429
|
list.push( {
|
|
1254
1430
|
'client Name': chunk[i]?.clientName,
|
|
1255
1431
|
'client Id': chunk[i]?.clientId,
|
|
1432
|
+
'Installation Stores Count': chunk[i]?.installedStores || 0,
|
|
1433
|
+
'Onboarded Stores Count': chunk[i]?.totalStores,
|
|
1434
|
+
'Store Progress': chunk[i]?.installedStores ? `${( ( chunk[i]?.installedStores / chunk[i]?.totalStores ) * 100 ).toFixed( 0 )}%` : '0%',
|
|
1256
1435
|
'Active Store': chunk[i]?.activeStoreCount || 0,
|
|
1257
1436
|
'Active Camera': chunk[i]?.activeCameraCount && chunk[i]?.activeCameraCount != undefined ? chunk[i]?.activeCameraCount : 0,
|
|
1437
|
+
'Pending Stores': chunk[i]?.pendingStores || 0,
|
|
1438
|
+
'Failed Stores': chunk[i]?.failedStores || 0,
|
|
1258
1439
|
'Payment Status': chunk[i]?.paymentStatus,
|
|
1259
1440
|
'Subs Plan': chunk[i]?.subscriptionType,
|
|
1260
1441
|
'Status': chunk[i]?.status,
|
|
@@ -1273,7 +1454,344 @@ export async function clientList( req, res ) {
|
|
|
1273
1454
|
return res.sendError( 'Internal Server Error', 500 );
|
|
1274
1455
|
}
|
|
1275
1456
|
}
|
|
1457
|
+
export async function clientListV1( req, res ) {
|
|
1458
|
+
try {
|
|
1459
|
+
const inputData = req.body;
|
|
1460
|
+
let clientQuery = [];
|
|
1461
|
+
logger.info( { message: req?.user?.role } );
|
|
1462
|
+
if ( req?.user?.role !== 'superadmin' ) {
|
|
1463
|
+
const query = [
|
|
1464
|
+
{
|
|
1465
|
+
$match: {
|
|
1466
|
+
userEmail: { $eq: req?.user?.email },
|
|
1467
|
+
userType: 'tango',
|
|
1468
|
+
$expr: {
|
|
1469
|
+
$cond: {
|
|
1470
|
+
if: {
|
|
1471
|
+
$and: [
|
|
1472
|
+
{ $eq: [ '$tangoUserType', 'csm' ] },
|
|
1473
|
+
],
|
|
1474
|
+
},
|
|
1475
|
+
then: { $eq: [ '$isClientApproved', true ] },
|
|
1476
|
+
else: true,
|
|
1477
|
+
},
|
|
1478
|
+
},
|
|
1479
|
+
|
|
1480
|
+
},
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
$group: {
|
|
1484
|
+
_id: null,
|
|
1485
|
+
clientList: { $push: '$assignedValue' },
|
|
1486
|
+
},
|
|
1487
|
+
},
|
|
1488
|
+
];
|
|
1489
|
+
const clientIdList = await aggregateUserAssignedStore( query );
|
|
1490
|
+
logger.info( { message: clientIdList, value: 'clientIdList' } );
|
|
1491
|
+
if ( clientIdList.length == 0 ) {
|
|
1492
|
+
return res.sendError( 'No Data Found', 204 );
|
|
1493
|
+
}
|
|
1494
|
+
clientQuery.push(
|
|
1495
|
+
{
|
|
1496
|
+
$match: {
|
|
1497
|
+
clientId: { $in: clientIdList[0].clientList },
|
|
1498
|
+
},
|
|
1499
|
+
},
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1502
|
+
clientQuery.push(
|
|
1503
|
+
{
|
|
1504
|
+
$project: {
|
|
1505
|
+
status: 1,
|
|
1506
|
+
clientName: 1,
|
|
1507
|
+
clientId: 1,
|
|
1508
|
+
subscriptionType: '$planDetails.subscriptionType',
|
|
1509
|
+
PaymentPlan: '$planDetails.paymentStatus',
|
|
1510
|
+
},
|
|
1511
|
+
},
|
|
1512
|
+
);
|
|
1513
|
+
if ( inputData.filterByPaymentStatus ) {
|
|
1514
|
+
if ( inputData.filterByPaymentStatus.includes( 'paid' ) ) {
|
|
1515
|
+
inputData.filterByPaymentStatus.push( ...[ 'unbilled', 'due' ] );
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
clientQuery.push(
|
|
1519
|
+
{
|
|
1520
|
+
$match: {
|
|
1521
|
+
'PaymentPlan': { $in: inputData.filterByPaymentStatus },
|
|
1522
|
+
},
|
|
1523
|
+
},
|
|
1524
|
+
);
|
|
1525
|
+
}
|
|
1526
|
+
if ( inputData.filterBySubscription ) {
|
|
1527
|
+
clientQuery.push(
|
|
1528
|
+
{
|
|
1529
|
+
$match: {
|
|
1530
|
+
'subscriptionType': { $in: inputData.filterBySubscription },
|
|
1531
|
+
},
|
|
1532
|
+
},
|
|
1533
|
+
);
|
|
1534
|
+
}
|
|
1535
|
+
if ( inputData.filterByStatus ) {
|
|
1536
|
+
clientQuery.push(
|
|
1537
|
+
{
|
|
1538
|
+
$match: {
|
|
1539
|
+
status: { $in: inputData.filterByStatus },
|
|
1540
|
+
},
|
|
1541
|
+
},
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1544
|
+
if ( inputData.searchValue && inputData.searchValue != '' ) {
|
|
1545
|
+
clientQuery.push( {
|
|
1546
|
+
$match: {
|
|
1547
|
+
$or: [
|
|
1548
|
+
{ clientId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1549
|
+
{ clientName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1550
|
+
{ subscriptionType: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1551
|
+
{ status: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1552
|
+
],
|
|
1553
|
+
},
|
|
1554
|
+
} );
|
|
1555
|
+
}
|
|
1556
|
+
clientQuery.push( {
|
|
1557
|
+
$lookup: {
|
|
1558
|
+
from: 'stores',
|
|
1559
|
+
let: { clientId: '$clientId' },
|
|
1560
|
+
pipeline: [
|
|
1561
|
+
{
|
|
1562
|
+
$match: {
|
|
1563
|
+
$expr: {
|
|
1564
|
+
$and: [
|
|
1565
|
+
{ $eq: [ '$clientId', '$$clientId' ] },
|
|
1566
|
+
],
|
|
1567
|
+
},
|
|
1568
|
+
},
|
|
1569
|
+
},
|
|
1570
|
+
{
|
|
1571
|
+
$project: {
|
|
1572
|
+
edge: 1,
|
|
1573
|
+
status: 1,
|
|
1574
|
+
clientId: 1,
|
|
1575
|
+
storeId: 1,
|
|
1576
|
+
},
|
|
1577
|
+
},
|
|
1578
|
+
], as: 'stores',
|
|
1579
|
+
},
|
|
1580
|
+
},
|
|
1581
|
+
|
|
1582
|
+
{
|
|
1583
|
+
$unwind: { path: '$stores', preserveNullAndEmptyArrays: true },
|
|
1584
|
+
},
|
|
1585
|
+
{
|
|
1586
|
+
$project: {
|
|
1587
|
+
clientId: 1,
|
|
1588
|
+
status: 1,
|
|
1589
|
+
clientName: 1,
|
|
1590
|
+
subscriptionType: 1,
|
|
1591
|
+
PaymentPlan: 1,
|
|
1592
|
+
installed: {
|
|
1593
|
+
$cond: [ { $or: [ { $eq: [ '$stores.edge.firstFile', true ] } ] }, 1, 0,
|
|
1594
|
+
],
|
|
1595
|
+
},
|
|
1596
|
+
activeStores: {
|
|
1597
|
+
$cond: [ { $and: [ { $eq: [ '$stores.status', 'active' ] } ] }, 1, 0,
|
|
1598
|
+
],
|
|
1599
|
+
},
|
|
1600
|
+
InactiveStores: {
|
|
1601
|
+
$cond: [ { $and: [ { $ne: [ '$stores.status', 'active' ] } ] }, 1, 0,
|
|
1602
|
+
],
|
|
1603
|
+
},
|
|
1604
|
+
},
|
|
1605
|
+
},
|
|
1606
|
+
{
|
|
1607
|
+
$group: {
|
|
1608
|
+
_id: '$clientId',
|
|
1609
|
+
clientId: { $first: '$clientId' },
|
|
1610
|
+
onboardedStores: { $sum: 1 },
|
|
1611
|
+
installedStore: { $sum: '$installed' },
|
|
1612
|
+
activeStores: { $sum: '$activeStores' },
|
|
1613
|
+
InactiveStores: { $sum: '$InactiveStores' },
|
|
1614
|
+
ProcessingStatus: { $first: '$status' },
|
|
1615
|
+
clientName: { $first: '$clientName' },
|
|
1616
|
+
subscriptionPlan: { $first: '$subscriptionType' },
|
|
1617
|
+
PaymentPlan: { $first: '$PaymentPlan' },
|
|
1618
|
+
},
|
|
1619
|
+
},
|
|
1620
|
+
{
|
|
1621
|
+
$lookup: {
|
|
1622
|
+
from: 'tangoTicket',
|
|
1623
|
+
let: { clientId: '$clientId' },
|
|
1624
|
+
pipeline: [
|
|
1625
|
+
{
|
|
1626
|
+
$match: {
|
|
1627
|
+
$expr: {
|
|
1628
|
+
$and: [
|
|
1629
|
+
{ $eq: [ '$issueType', 'installation' ] },
|
|
1630
|
+
{ $eq: [ '$basicDetails.clientId', '$$clientId' ] },
|
|
1631
|
+
],
|
|
1632
|
+
},
|
|
1633
|
+
},
|
|
1634
|
+
|
|
1635
|
+
},
|
|
1636
|
+
{
|
|
1637
|
+
$project: {
|
|
1638
|
+
ticketDetails: 1,
|
|
1639
|
+
status: 1,
|
|
1640
|
+
basicDetails: 1,
|
|
1641
|
+
},
|
|
1642
|
+
},
|
|
1643
|
+
], as: 'ticket',
|
|
1644
|
+
},
|
|
1645
|
+
},
|
|
1646
|
+
{
|
|
1647
|
+
$unwind: { path: '$ticket', preserveNullAndEmptyArrays: true },
|
|
1648
|
+
},
|
|
1649
|
+
{
|
|
1650
|
+
$project: {
|
|
1651
|
+
clientId: 1,
|
|
1652
|
+
ProcessingStatus: 1,
|
|
1653
|
+
onboardedStores: 1,
|
|
1654
|
+
clientName: 1,
|
|
1655
|
+
PaymentPlan: 1,
|
|
1656
|
+
subscriptionPlan: 1,
|
|
1657
|
+
installedStore: 1,
|
|
1658
|
+
activeStores: 1,
|
|
1659
|
+
InactiveStores: 1,
|
|
1660
|
+
installedPending: {
|
|
1661
|
+
$cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] } ] }, 1, 0 ],
|
|
1662
|
+
},
|
|
1663
|
+
installedFailed: {
|
|
1664
|
+
$cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] }, { $eq: [ '$ticket.ticketDetails.issueStatus', 'identified' ] } ] }, 1, 0 ],
|
|
1665
|
+
},
|
|
1666
|
+
},
|
|
1667
|
+
},
|
|
1668
|
+
{
|
|
1669
|
+
$group: {
|
|
1670
|
+
_id: '$clientId',
|
|
1671
|
+
clientId: { $first: '$clientId' },
|
|
1672
|
+
onboardedStores: { $first: '$onboardedStores' },
|
|
1673
|
+
installedStore: { $first: '$installedStore' },
|
|
1674
|
+
activeStores: { $first: '$activeStores' },
|
|
1675
|
+
InactiveStores: { $first: '$InactiveStores' },
|
|
1676
|
+
ProcessingStatus: { $first: '$ProcessingStatus' },
|
|
1677
|
+
clientName: { $first: '$clientName' },
|
|
1678
|
+
subscriptionPlan: { $first: '$subscriptionPlan' },
|
|
1679
|
+
PaymentPlan: { $first: '$PaymentPlan' },
|
|
1680
|
+
installedPending: { $sum: '$installedPending' },
|
|
1681
|
+
installedFailed: { $sum: '$installedFailed' },
|
|
1682
|
+
},
|
|
1683
|
+
},
|
|
1684
|
+
{
|
|
1685
|
+
$project: {
|
|
1686
|
+
clientId: { $toInt: '$clientId' },
|
|
1687
|
+
onboardedStores: 1,
|
|
1688
|
+
installedStore: 1,
|
|
1689
|
+
activeStores: { $max: [
|
|
1690
|
+
{ $subtract: [ '$activeStores', '$installedPending' ] },
|
|
1691
|
+
0,
|
|
1692
|
+
] },
|
|
1693
|
+
InactiveStores: 1,
|
|
1694
|
+
ProcessingStatus: 1,
|
|
1695
|
+
clientName: 1,
|
|
1696
|
+
subscriptionPlan: 1,
|
|
1697
|
+
PaymentPlan: 1,
|
|
1698
|
+
PaymentPlan: {
|
|
1699
|
+
$cond: {
|
|
1700
|
+
if: { $eq: [ '$PaymentPlan', 'unbilled' ] },
|
|
1701
|
+
then: 'paid',
|
|
1702
|
+
else: {
|
|
1703
|
+
$cond: {
|
|
1704
|
+
if: { $eq: [ '$PaymentPlan', 'due' ] },
|
|
1705
|
+
then: 'paid',
|
|
1706
|
+
else: '$PaymentPlan',
|
|
1707
|
+
},
|
|
1708
|
+
},
|
|
1709
|
+
},
|
|
1710
|
+
},
|
|
1711
|
+
installedPending: 1,
|
|
1712
|
+
installedFailed: 1,
|
|
1713
|
+
ProgressBar: {
|
|
1714
|
+
$cond: {
|
|
1715
|
+
if: { $eq: [ '$onboardedStores', 0 ] },
|
|
1716
|
+
then: 0,
|
|
1717
|
+
else: {
|
|
1718
|
+
$round: [
|
|
1719
|
+
{ $multiply: [ { $divide: [ '$installedStore', '$onboardedStores' ] }, 100 ] },
|
|
1720
|
+
0,
|
|
1721
|
+
],
|
|
1722
|
+
},
|
|
1723
|
+
},
|
|
1724
|
+
},
|
|
1725
|
+
},
|
|
1726
|
+
},
|
|
1727
|
+
);
|
|
1276
1728
|
|
|
1729
|
+
const clientCount = await aggregateClient( clientQuery );
|
|
1730
|
+
if ( clientCount.length == 0 ) {
|
|
1731
|
+
return res.sendError( 'No Data Found', 204 );
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
if ( inputData.sortColumName&&inputData.sortColumName!=''&& req.body.sortBy&&req.body.sortBy!='' ) {
|
|
1735
|
+
clientQuery.push( {
|
|
1736
|
+
$sort: { [req.body.sortColumName]: req.body.sortBy },
|
|
1737
|
+
},
|
|
1738
|
+
);
|
|
1739
|
+
} else {
|
|
1740
|
+
clientQuery.push( {
|
|
1741
|
+
$sort: { activeStores: -1 },
|
|
1742
|
+
},
|
|
1743
|
+
);
|
|
1744
|
+
}
|
|
1745
|
+
clientQuery.push( {
|
|
1746
|
+
$project: {
|
|
1747
|
+
clientId: { $toString: '$clientId' },
|
|
1748
|
+
onboardedStores: 1,
|
|
1749
|
+
installedStore: 1,
|
|
1750
|
+
activeStores: 1,
|
|
1751
|
+
InactiveStores: 1,
|
|
1752
|
+
ProcessingStatus: 1,
|
|
1753
|
+
clientName: 1,
|
|
1754
|
+
subscriptionPlan: 1,
|
|
1755
|
+
PaymentPlan: 1,
|
|
1756
|
+
installedPending: 1,
|
|
1757
|
+
installedFailed: 1,
|
|
1758
|
+
ProgressBar: 1,
|
|
1759
|
+
},
|
|
1760
|
+
} );
|
|
1761
|
+
if ( req.body.limit && req.body.offset && !req.body.isExport ) {
|
|
1762
|
+
clientQuery.push(
|
|
1763
|
+
{ $skip: ( req.body.offset - 1 ) * req.body.limit },
|
|
1764
|
+
{ $limit: Number( req.body.limit ) },
|
|
1765
|
+
);
|
|
1766
|
+
}
|
|
1767
|
+
const clientList = await aggregateClient( clientQuery );
|
|
1768
|
+
|
|
1769
|
+
if ( inputData.isExport ) {
|
|
1770
|
+
const exportResult = [];
|
|
1771
|
+
for ( let client of clientList ) {
|
|
1772
|
+
exportResult.push( {
|
|
1773
|
+
'Brand Name': client.clientName,
|
|
1774
|
+
'Brand ID': client.clientId,
|
|
1775
|
+
'Onboarded Stores': client.onboardedStores||0,
|
|
1776
|
+
'Installed Stores': client.installedStore || 0,
|
|
1777
|
+
'Progress Status': client.ProgressBar||0,
|
|
1778
|
+
'Active Stores': client.activeStores || 0,
|
|
1779
|
+
'In-Active Stores': client.InactiveStores || 0,
|
|
1780
|
+
'Pending Configuration': client.installedPending || 0,
|
|
1781
|
+
'Payment Plan': client.PaymentPlan == 'free'?'Lifetime Free':client.PaymentPlan,
|
|
1782
|
+
'Subscription Plan': client.subscriptionPlan,
|
|
1783
|
+
'Processing Status': client.ProcessingStatus=='active'?'Activated':client.ProcessingStatus=='deactive'?'Deactivated':client.ProcessingStatus,
|
|
1784
|
+
} );
|
|
1785
|
+
}
|
|
1786
|
+
await download( exportResult, res );
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1789
|
+
return res.sendSuccess( { result: clientList, count: clientCount.length } );
|
|
1790
|
+
} catch ( error ) {
|
|
1791
|
+
logger.error( { error: error, function: 'clientList' } );
|
|
1792
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1277
1795
|
export async function getOpsUsers( req, res ) {
|
|
1278
1796
|
try {
|
|
1279
1797
|
const users = await OpsUsersGet();
|
|
@@ -1291,6 +1809,7 @@ export async function getOpsUsers( req, res ) {
|
|
|
1291
1809
|
|
|
1292
1810
|
export async function detailedClientCount( req, res ) {
|
|
1293
1811
|
try {
|
|
1812
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
1294
1813
|
const inputData = req.query;
|
|
1295
1814
|
let result = {
|
|
1296
1815
|
clientName: inputData.clientName,
|
|
@@ -1304,10 +1823,10 @@ export async function detailedClientCount( req, res ) {
|
|
|
1304
1823
|
const client = await findOneClient( { clientId: inputData.clientId }, { userId: 1, clientId: 1, profileDetails: 1 } );
|
|
1305
1824
|
const user = await findOneUser( { _id: client.userId }, { userName: 1, email: 1 } );
|
|
1306
1825
|
|
|
1307
|
-
const isLogoExist = await checkFileExist( { Bucket:
|
|
1826
|
+
const isLogoExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
1308
1827
|
|
|
1309
1828
|
if ( isLogoExist ) {
|
|
1310
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
1829
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
1311
1830
|
result['logo'] = signedFilUrl;
|
|
1312
1831
|
} else {
|
|
1313
1832
|
result['logo'] = '';
|
|
@@ -1315,6 +1834,19 @@ export async function detailedClientCount( req, res ) {
|
|
|
1315
1834
|
result['userName'] = user?.userName;
|
|
1316
1835
|
result['email'] = user?.email;
|
|
1317
1836
|
result['profileCompletion'] = 70;
|
|
1837
|
+
let findCsm = await aggregateUserAssignedStore( [
|
|
1838
|
+
{
|
|
1839
|
+
$match: {
|
|
1840
|
+
clientId: inputData.clientId,
|
|
1841
|
+
tangoUserType: 'csm',
|
|
1842
|
+
},
|
|
1843
|
+
},
|
|
1844
|
+
] );
|
|
1845
|
+
|
|
1846
|
+
if ( findCsm&&findCsm.length>0 ) {
|
|
1847
|
+
let finduser = await findOneUser( { email: findCsm[0].userEmail }, { userName: 1, email: 1, countryCode: 1, mobileNumber: 1 } );
|
|
1848
|
+
result['csm'] = finduser;
|
|
1849
|
+
}
|
|
1318
1850
|
|
|
1319
1851
|
return res.sendSuccess( { result: result } );
|
|
1320
1852
|
} catch ( error ) {
|
|
@@ -1325,8 +1857,12 @@ export async function detailedClientCount( req, res ) {
|
|
|
1325
1857
|
|
|
1326
1858
|
export async function getActivityLogs( req, res ) {
|
|
1327
1859
|
try {
|
|
1860
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1328
1861
|
const query = {
|
|
1329
|
-
'_source': [
|
|
1862
|
+
'_source': [
|
|
1863
|
+
'userId', 'userName', 'email', 'date', 'logType', 'logSubType',
|
|
1864
|
+
'changes', 'eventType',
|
|
1865
|
+
],
|
|
1330
1866
|
'query': {
|
|
1331
1867
|
'bool': {
|
|
1332
1868
|
'must': [
|
|
@@ -1340,6 +1876,13 @@ export async function getActivityLogs( req, res ) {
|
|
|
1340
1876
|
},
|
|
1341
1877
|
'from': ( req.body.offset - 1 ) * req.body.limit,
|
|
1342
1878
|
'size': req.body.limit,
|
|
1879
|
+
'sort': [
|
|
1880
|
+
{
|
|
1881
|
+
'date': {
|
|
1882
|
+
'order': 'desc',
|
|
1883
|
+
},
|
|
1884
|
+
},
|
|
1885
|
+
],
|
|
1343
1886
|
};
|
|
1344
1887
|
|
|
1345
1888
|
if ( req.body?.logTypeFilters?.length ) {
|
|
@@ -1363,7 +1906,15 @@ export async function getActivityLogs( req, res ) {
|
|
|
1363
1906
|
} );
|
|
1364
1907
|
}
|
|
1365
1908
|
|
|
1366
|
-
|
|
1909
|
+
query.query.bool.must.push(
|
|
1910
|
+
{
|
|
1911
|
+
'terms': {
|
|
1912
|
+
'showTo.keyword': [ req.user.userType ],
|
|
1913
|
+
},
|
|
1914
|
+
},
|
|
1915
|
+
);
|
|
1916
|
+
|
|
1917
|
+
const logs = await getOpenSearchData( openSearch.activityLog, query );
|
|
1367
1918
|
|
|
1368
1919
|
const hits = logs?.body?.hits?.hits;
|
|
1369
1920
|
const totalDocuments = logs?.body?.hits?.total?.value;
|
|
@@ -1379,6 +1930,7 @@ export async function getActivityLogs( req, res ) {
|
|
|
1379
1930
|
}
|
|
1380
1931
|
}
|
|
1381
1932
|
|
|
1933
|
+
|
|
1382
1934
|
async function postApi( url, data ) {
|
|
1383
1935
|
const requestOptions = {
|
|
1384
1936
|
method: 'POST',
|
|
@@ -1415,3 +1967,34 @@ async function getApi( url ) {
|
|
|
1415
1967
|
}
|
|
1416
1968
|
}
|
|
1417
1969
|
|
|
1970
|
+
|
|
1971
|
+
export async function csmAssignConfirmation( req, res ) {
|
|
1972
|
+
try {
|
|
1973
|
+
const client = await findOneClient( { clientId: req.query.clientId }, { notifyCsmAssign: 1, _id: 0 } );
|
|
1974
|
+
if ( !client ) {
|
|
1975
|
+
res.sendError( 'No data found', 204 );
|
|
1976
|
+
}
|
|
1977
|
+
res.sendSuccess( client );
|
|
1978
|
+
} catch ( error ) {
|
|
1979
|
+
logger.error( { error: error, message: req.params, function: 'csmAssignConfirmation' } );
|
|
1980
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
export async function clientCsmAssignAction( req, res ) {
|
|
1985
|
+
try {
|
|
1986
|
+
await updateOneClient( { clientId: req.query.clientId }, { notifyCsmAssign: false } );
|
|
1987
|
+
if ( req.body.action === 'approve' ) {
|
|
1988
|
+
await updateOneUserAssignedStore( { clientId: req.query.clientId, tangoUserType: 'csm', assignedType: 'client' }, { isClientApproved: true } );
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
if ( req.body.action === 'decline' ) {
|
|
1992
|
+
await deleteOneAssignedStore( { clientId: req.query.clientId, tangoUserType: 'csm', assignedType: 'client' } );
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
res.sendSuccess( 'Updated Succesfully' );
|
|
1996
|
+
} catch ( error ) {
|
|
1997
|
+
logger.error( { error: error, message: req.params, function: 'csmAssignConfirmation' } );
|
|
1998
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
1999
|
+
}
|
|
2000
|
+
}
|