tango-app-api-client 3.1.15 → 3.1.17
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-client",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.17",
|
|
4
4
|
"description": "client",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"mongodb": "^6.3.0",
|
|
26
26
|
"nodemon": "^3.0.3",
|
|
27
27
|
"swagger-ui-express": "^5.0.0",
|
|
28
|
-
"tango-api-schema": "^2.0.
|
|
29
|
-
"tango-app-api-middleware": "^3.1.
|
|
28
|
+
"tango-api-schema": "^2.0.113",
|
|
29
|
+
"tango-app-api-middleware": "^3.1.19",
|
|
30
30
|
"winston": "^3.11.0",
|
|
31
31
|
"winston-daily-rotate-file": "^5.0.0"
|
|
32
32
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
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,
|
|
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, findOneStore, 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
8
|
import { aggregateUserAssignedStore, deleteOneAssignedStore, updateOneUserAssignedStore } from '../service/userAssignedStore.service.js';
|
|
@@ -10,12 +10,14 @@ 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,9 @@ export async function create( req, res ) {
|
|
|
176
200
|
'role': 'storesuperadmin',
|
|
177
201
|
};
|
|
178
202
|
|
|
179
|
-
await postApi( `${
|
|
203
|
+
await postApi( `${url.oldapidomain}/oldBrandAdd`, oldBrandInsertData );
|
|
180
204
|
|
|
181
|
-
await postApi( `${
|
|
205
|
+
await postApi( `${url.oldapidomain}/oldDefaultRoleInsert`, oldDefaultRolesInsertData );
|
|
182
206
|
|
|
183
207
|
const logObj = {
|
|
184
208
|
clientId: insertedClientRecord.clientId,
|
|
@@ -193,7 +217,7 @@ export async function create( req, res ) {
|
|
|
193
217
|
showTo: [ 'client', 'tango' ],
|
|
194
218
|
};
|
|
195
219
|
|
|
196
|
-
await insertOpenSearchData(
|
|
220
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
197
221
|
|
|
198
222
|
for ( let index = 0; index < leadRecord?.planDetails?.product?.length; index++ ) {
|
|
199
223
|
const logObj = {
|
|
@@ -215,7 +239,7 @@ export async function create( req, res ) {
|
|
|
215
239
|
showTo: [ 'client', 'tango' ],
|
|
216
240
|
};
|
|
217
241
|
|
|
218
|
-
await insertOpenSearchData(
|
|
242
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
219
243
|
}
|
|
220
244
|
|
|
221
245
|
|
|
@@ -247,12 +271,14 @@ function convertTitleCase( data ) {
|
|
|
247
271
|
|
|
248
272
|
export const sendEmail = ( data ) => {
|
|
249
273
|
try {
|
|
274
|
+
const url = JSON.parse( process.env.URL );
|
|
275
|
+
const ses = JSON.parse( process.env.SES );
|
|
250
276
|
const attachments = null;
|
|
251
277
|
const subject = data.subject;
|
|
252
278
|
const fileContent = readFileSync( join() + data.path, 'utf8' );
|
|
253
279
|
const htmlContent = handlebars.compile( fileContent );
|
|
254
|
-
const html = htmlContent( { url:
|
|
255
|
-
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 );
|
|
256
282
|
} catch ( error ) {
|
|
257
283
|
return error;
|
|
258
284
|
}
|
|
@@ -296,10 +322,12 @@ export async function getClients( req, res ) {
|
|
|
296
322
|
assignedType: { $eq: 'client' },
|
|
297
323
|
$expr: {
|
|
298
324
|
$cond: {
|
|
299
|
-
if: {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
325
|
+
if: {
|
|
326
|
+
$and: [
|
|
327
|
+
{ $eq: [ '$userType', 'tango' ] },
|
|
328
|
+
{ $eq: [ '$tangoUserType', 'csm' ] },
|
|
329
|
+
],
|
|
330
|
+
},
|
|
303
331
|
then: { $eq: [ '$isClientApproved', true ] },
|
|
304
332
|
else: true,
|
|
305
333
|
},
|
|
@@ -357,61 +385,62 @@ export async function getClients( req, res ) {
|
|
|
357
385
|
|
|
358
386
|
export async function clientDetails( req, res ) {
|
|
359
387
|
try {
|
|
388
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
360
389
|
const client = await getClientData( { id: req.params.id } );
|
|
361
390
|
if ( client ) {
|
|
362
|
-
const isLogoExist = await checkFileExist( { Bucket:
|
|
363
|
-
const isGstCertificateExist = await checkFileExist( { Bucket:
|
|
364
|
-
const isAddressCertificateExist = await checkFileExist( { Bucket:
|
|
365
|
-
const isPanCertificateExist = await checkFileExist( { Bucket:
|
|
366
|
-
const isCinCertificateExist = await checkFileExist( { Bucket:
|
|
367
|
-
const isContractCertificateExist = await checkFileExist( { Bucket:
|
|
368
|
-
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` } );
|
|
369
398
|
|
|
370
399
|
|
|
371
400
|
if ( isLogoExist ) {
|
|
372
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
401
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
373
402
|
client.profileDetails.logo = signedFilUrl;
|
|
374
403
|
} else {
|
|
375
404
|
client.profileDetails.logo = '';
|
|
376
405
|
}
|
|
377
406
|
|
|
378
407
|
if ( isGstCertificateExist ) {
|
|
379
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
408
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.gst?.path}` } );
|
|
380
409
|
client.document.gst.path = signedFilUrl;
|
|
381
410
|
} else {
|
|
382
411
|
client.document.gst.path = '';
|
|
383
412
|
}
|
|
384
413
|
|
|
385
414
|
if ( isAddressCertificateExist ) {
|
|
386
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
415
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.addressProof?.path}` } );
|
|
387
416
|
client.document.addressProof.path = signedFilUrl;
|
|
388
417
|
} else {
|
|
389
418
|
client.document.addressProof.path = '';
|
|
390
419
|
}
|
|
391
420
|
|
|
392
421
|
if ( isPanCertificateExist ) {
|
|
393
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
422
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.pan?.path}` } );
|
|
394
423
|
client.document.pan.path = signedFilUrl;
|
|
395
424
|
} else {
|
|
396
425
|
client.document.pan.path = '';
|
|
397
426
|
}
|
|
398
427
|
|
|
399
428
|
if ( isCinCertificateExist ) {
|
|
400
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
429
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/documents/${client.document?.cin?.path}` } );
|
|
401
430
|
client.document.cin.path = signedFilUrl;
|
|
402
431
|
} else {
|
|
403
432
|
client.document.cin.path = '';
|
|
404
433
|
}
|
|
405
434
|
|
|
406
435
|
if ( isContractCertificateExist ) {
|
|
407
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
436
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `documents/contract.pdf` } );
|
|
408
437
|
client._doc.document.contract = signedFilUrl;
|
|
409
438
|
} else {
|
|
410
439
|
client._doc.document.contract = '';
|
|
411
440
|
}
|
|
412
441
|
|
|
413
442
|
if ( isTermsAndConditionsExist ) {
|
|
414
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
443
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `documents/terms&conditions.pdf` } );
|
|
415
444
|
client._doc.document.termsAndconditions = signedFilUrl;
|
|
416
445
|
} else {
|
|
417
446
|
client._doc.document.termsAndconditions = '';
|
|
@@ -437,18 +466,30 @@ export async function detailedAllClientCount( req, res ) {
|
|
|
437
466
|
{
|
|
438
467
|
$project: {
|
|
439
468
|
activeClient: { $cond: [ { $eq: [ '$status', 'active' ] }, 1, 0 ] },
|
|
440
|
-
paidClient: {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
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
|
+
},
|
|
452
493
|
holdClient: { $cond: [ { $eq: [ '$status', 'hold' ] }, 1, 0 ] },
|
|
453
494
|
suspendClient: { $cond: [ { $eq: [ '$status', 'suspended' ] }, 1, 0 ] },
|
|
454
495
|
deactiveClient: { $cond: [ { $eq: [ '$status', 'deactive' ] }, 1, 0 ] },
|
|
@@ -485,12 +526,27 @@ export async function detailedAllClientCount( req, res ) {
|
|
|
485
526
|
},
|
|
486
527
|
];
|
|
487
528
|
const result = await aggregateClient( query );
|
|
488
|
-
const activeStores = await
|
|
489
|
-
|
|
529
|
+
const activeStores = await findStore( { 'status': 'active' }, { storeId: 1 } );
|
|
530
|
+
let yettoInstallCount = await aggregateTickets( [
|
|
531
|
+
{
|
|
532
|
+
$match: {
|
|
533
|
+
$and: [
|
|
534
|
+
{ issueType: 'installation' },
|
|
535
|
+
{ 'status': { $ne: 'closed' } },
|
|
536
|
+
],
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
] );
|
|
540
|
+
|
|
541
|
+
let storesList = [];
|
|
542
|
+
for ( let store of activeStores ) {
|
|
543
|
+
storesList.push( store.storeId );
|
|
544
|
+
}
|
|
545
|
+
const activeCameras = await countDocumentsCamera( { storeId: { $in: storesList }, isUp: true, isActivated: true } );
|
|
490
546
|
if ( result.length == 0 ) {
|
|
491
547
|
return res.sendError( 'No Data Found', 204 );
|
|
492
548
|
}
|
|
493
|
-
result[0].activeStoresCount = activeStores;
|
|
549
|
+
result[0].activeStoresCount = activeStores.length-yettoInstallCount.length;
|
|
494
550
|
result[0].activeCameraCount = activeCameras;
|
|
495
551
|
return res.sendSuccess( { result: result } );
|
|
496
552
|
} catch ( error ) {
|
|
@@ -507,11 +563,14 @@ function camelCaseToWords( camelCaseString ) {
|
|
|
507
563
|
|
|
508
564
|
export async function updateBrandInfo( req, res ) {
|
|
509
565
|
try {
|
|
566
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
567
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
568
|
+
const url = JSON.parse( process.env.URL );
|
|
510
569
|
let updateKeys = [];
|
|
511
570
|
|
|
512
571
|
if ( req.files?.logo ) {
|
|
513
572
|
const uploadDataParams = {
|
|
514
|
-
Bucket:
|
|
573
|
+
Bucket: bucket.assets,
|
|
515
574
|
Key: `${req.params.id}/logo/`,
|
|
516
575
|
fileName: `brandLogo.${req.files.logo.name.split( '.' )[1]}`,
|
|
517
576
|
ContentType: req.files.logo.mimetype,
|
|
@@ -543,7 +602,7 @@ export async function updateBrandInfo( req, res ) {
|
|
|
543
602
|
};
|
|
544
603
|
|
|
545
604
|
if ( updateKeys.length ) {
|
|
546
|
-
await insertOpenSearchData(
|
|
605
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
547
606
|
}
|
|
548
607
|
|
|
549
608
|
|
|
@@ -569,11 +628,11 @@ export async function updateBrandInfo( req, res ) {
|
|
|
569
628
|
|
|
570
629
|
if ( req.body?.status === 'deactive' ) {
|
|
571
630
|
await updateManyStore( { clientId: req.params?.id }, { status: 'deactive' } );
|
|
572
|
-
await updateManyCamera( { clientId: req.params?.id }, { isUp: false, isActivated: false } );
|
|
631
|
+
// await updateManyCamera( { clientId: req.params?.id }, { isUp: false, isActivated: false } );
|
|
573
632
|
await updateManyUser( { clientId: req.params?.id }, { isActive: false } );
|
|
574
633
|
}
|
|
575
634
|
|
|
576
|
-
const { data } = await getApi( `${
|
|
635
|
+
const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
577
636
|
|
|
578
637
|
switch ( req.body?.status ) {
|
|
579
638
|
case 'active':
|
|
@@ -592,7 +651,7 @@ export async function updateBrandInfo( req, res ) {
|
|
|
592
651
|
data.clientStatus = 'live';
|
|
593
652
|
}
|
|
594
653
|
|
|
595
|
-
await postApi( `${
|
|
654
|
+
await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { clientStatus: data.clientStatus } );
|
|
596
655
|
|
|
597
656
|
if ( updateAck ) {
|
|
598
657
|
res.sendSuccess( { result: 'Updated Successfully' } );
|
|
@@ -605,11 +664,13 @@ export async function updateBrandInfo( req, res ) {
|
|
|
605
664
|
|
|
606
665
|
export async function updateBillingDetails( req, res ) {
|
|
607
666
|
try {
|
|
667
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
668
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
608
669
|
let updateKeys = [];
|
|
609
670
|
|
|
610
671
|
if ( req.files?.gstCertificate ) {
|
|
611
672
|
const uploadDataParams = {
|
|
612
|
-
Bucket:
|
|
673
|
+
Bucket: bucket.assets,
|
|
613
674
|
Key: `${req.params.id}/documents/`,
|
|
614
675
|
fileName: `gstCertificate.${req.files.gstCertificate.name.split( '.' )[1]}`,
|
|
615
676
|
ContentType: req.files.gstCertificate.mimetype,
|
|
@@ -640,7 +701,7 @@ export async function updateBillingDetails( req, res ) {
|
|
|
640
701
|
};
|
|
641
702
|
|
|
642
703
|
if ( updateKeys.length ) {
|
|
643
|
-
await insertOpenSearchData(
|
|
704
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
644
705
|
}
|
|
645
706
|
|
|
646
707
|
|
|
@@ -660,6 +721,7 @@ export async function updateBillingDetails( req, res ) {
|
|
|
660
721
|
|
|
661
722
|
export async function updateSignatoryDetails( req, res ) {
|
|
662
723
|
try {
|
|
724
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
663
725
|
let updateKeys = [];
|
|
664
726
|
if ( Object.keys( req.body ).length > 0 ) {
|
|
665
727
|
Object.keys( req.body ).forEach( ( element ) => {
|
|
@@ -682,7 +744,7 @@ export async function updateSignatoryDetails( req, res ) {
|
|
|
682
744
|
};
|
|
683
745
|
|
|
684
746
|
if ( updateKeys.length ) {
|
|
685
|
-
await insertOpenSearchData(
|
|
747
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
686
748
|
}
|
|
687
749
|
|
|
688
750
|
const updateAck = await signatoryDetailsUpdate( {
|
|
@@ -700,6 +762,7 @@ export async function updateSignatoryDetails( req, res ) {
|
|
|
700
762
|
|
|
701
763
|
export async function updateTicketConfiguration( req, res ) {
|
|
702
764
|
try {
|
|
765
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
703
766
|
const updateAck = await ticketConfigurationUpdate( {
|
|
704
767
|
clientId: req.params?.id, MinFilesCount: req.body?.MinFilesCount, accuracyPercentage: req.body?.accuracyPercentage, downTimeType: req.body?.downTimeType,
|
|
705
768
|
infraDownTime: req.body?.infraDownTime, installationReAssign: req.body?.installationReAssign, isRcaTicketAssign: req.body?.isRcaTicketAssign,
|
|
@@ -729,7 +792,7 @@ export async function updateTicketConfiguration( req, res ) {
|
|
|
729
792
|
};
|
|
730
793
|
|
|
731
794
|
if ( updateKeys.length ) {
|
|
732
|
-
await insertOpenSearchData(
|
|
795
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
733
796
|
}
|
|
734
797
|
|
|
735
798
|
if ( updateAck ) {
|
|
@@ -743,11 +806,14 @@ export async function updateTicketConfiguration( req, res ) {
|
|
|
743
806
|
|
|
744
807
|
export async function updateFeatureConfiguration( req, res ) {
|
|
745
808
|
try {
|
|
809
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
810
|
+
const url = JSON.parse( process.env.URL );
|
|
746
811
|
const updateAck = await featureConfigurationUpdate( {
|
|
747
812
|
clientId: req.params?.id, billableCalculation: req.body?.billableCalculation, bouncedLimitCondition: req.body?.bouncedLimitCondition, bouncedLimitValue: req.body?.bouncedLimitValue,
|
|
748
813
|
close: req.body?.close, conversionCalculation: req.body?.conversionCalculation, conversionCondition: req.body?.conversionCondition,
|
|
749
814
|
conversionValue: req.body?.conversionValue, infraAlertCondition: req.body?.infraAlertCondition, infraAlertValue: req.body?.infraAlertValue, isFootfallDirectory: req.body?.isFootfallDirectory,
|
|
750
815
|
isNormalized: req.body?.isNormalized, isPasserByData: req.body?.isPasserByData, missedOpportunityCalculation: req.body?.missedOpportunityCalculation, open: req.body?.open,
|
|
816
|
+
isExcludedArea: req.body?.isExcludedArea,
|
|
751
817
|
} );
|
|
752
818
|
|
|
753
819
|
let updateKeys = [];
|
|
@@ -760,7 +826,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
760
826
|
|
|
761
827
|
const user = await getUserNameEmailById( req.userId );
|
|
762
828
|
|
|
763
|
-
const { data } = await getApi( `${
|
|
829
|
+
const { data } = await getApi( `${url.oldapidomain}/oldBrandGet/${req.params?.id}` );
|
|
764
830
|
|
|
765
831
|
if ( req.body?.open ) {
|
|
766
832
|
data.brandConfigs.storeOpenTime = req.body?.open;
|
|
@@ -802,7 +868,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
802
868
|
data.brandConfigs.missedOpportunityEndTime = data.brandConfigs.missedOpportunityEndTime.replace( /\d+/, req.body?.conversionValue );
|
|
803
869
|
}
|
|
804
870
|
|
|
805
|
-
await postApi( `${
|
|
871
|
+
await postApi( `${url.oldapidomain}/oldBrandUpdate/${data?._id}`, { brandConfigs: data.brandConfigs } );
|
|
806
872
|
|
|
807
873
|
|
|
808
874
|
const logObj = {
|
|
@@ -817,7 +883,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
817
883
|
showTo: [ 'client', 'tango' ],
|
|
818
884
|
};
|
|
819
885
|
if ( updateKeys.length ) {
|
|
820
|
-
await insertOpenSearchData(
|
|
886
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
821
887
|
}
|
|
822
888
|
|
|
823
889
|
if ( updateAck ) {
|
|
@@ -831,6 +897,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
831
897
|
|
|
832
898
|
export async function domainDetailsConfiguration( req, res ) {
|
|
833
899
|
try {
|
|
900
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
834
901
|
const updateAck = await domainDetailsConfigurationUpdate( {
|
|
835
902
|
clientId: req.params?.id, domainName: req.body?.domainName, isEnable: req.body?.isEnable,
|
|
836
903
|
} );
|
|
@@ -860,7 +927,7 @@ export async function domainDetailsConfiguration( req, res ) {
|
|
|
860
927
|
};
|
|
861
928
|
|
|
862
929
|
if ( updateKeys.length ) {
|
|
863
|
-
await insertOpenSearchData(
|
|
930
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
864
931
|
}
|
|
865
932
|
|
|
866
933
|
if ( updateAck ) {
|
|
@@ -888,11 +955,13 @@ export async function userConfiguration( req, res ) {
|
|
|
888
955
|
|
|
889
956
|
export async function updateDocuments( req, res ) {
|
|
890
957
|
try {
|
|
958
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
959
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
891
960
|
let updateKeys = [];
|
|
892
961
|
|
|
893
962
|
if ( req.files?.addressDoc ) {
|
|
894
963
|
const uploadDataParams = {
|
|
895
|
-
Bucket:
|
|
964
|
+
Bucket: bucket.assets,
|
|
896
965
|
Key: `${req.params.id}/documents/`,
|
|
897
966
|
fileName: `addressCertificate.${req.files.addressDoc.name.split( '.' )[1]}`,
|
|
898
967
|
ContentType: req.files.addressDoc.mimetype,
|
|
@@ -905,7 +974,7 @@ export async function updateDocuments( req, res ) {
|
|
|
905
974
|
}
|
|
906
975
|
if ( req.files?.gstDoc ) {
|
|
907
976
|
const uploadDataParams = {
|
|
908
|
-
Bucket:
|
|
977
|
+
Bucket: bucket.assets,
|
|
909
978
|
Key: `${req.params.id}/documents/`,
|
|
910
979
|
fileName: `gstCertificate.${req.files.gstDoc.name.split( '.' )[1]}`,
|
|
911
980
|
ContentType: req.files.gstDoc.mimetype,
|
|
@@ -918,7 +987,7 @@ export async function updateDocuments( req, res ) {
|
|
|
918
987
|
}
|
|
919
988
|
if ( req.files?.panDoc ) {
|
|
920
989
|
const uploadDataParams = {
|
|
921
|
-
Bucket:
|
|
990
|
+
Bucket: bucket.assets,
|
|
922
991
|
Key: `${req.params.id}/documents/`,
|
|
923
992
|
fileName: `panCertificate.${req.files.panDoc.name.split( '.' )[1]}`,
|
|
924
993
|
ContentType: req.files.panDoc.mimetype,
|
|
@@ -931,7 +1000,7 @@ export async function updateDocuments( req, res ) {
|
|
|
931
1000
|
}
|
|
932
1001
|
if ( req.files?.cinDoc ) {
|
|
933
1002
|
const uploadDataParams = {
|
|
934
|
-
Bucket:
|
|
1003
|
+
Bucket: bucket.assets,
|
|
935
1004
|
Key: `${req.params.id}/documents/`,
|
|
936
1005
|
fileName: `cinCertificate.${req.files.cinDoc.name.split( '.' )[1]}`,
|
|
937
1006
|
ContentType: req.files.cinDoc.mimetype,
|
|
@@ -974,7 +1043,7 @@ export async function updateDocuments( req, res ) {
|
|
|
974
1043
|
};
|
|
975
1044
|
|
|
976
1045
|
if ( updateKeys.length ) {
|
|
977
|
-
await insertOpenSearchData(
|
|
1046
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
978
1047
|
}
|
|
979
1048
|
|
|
980
1049
|
if ( updateAck ) {
|
|
@@ -988,11 +1057,12 @@ export async function updateDocuments( req, res ) {
|
|
|
988
1057
|
|
|
989
1058
|
export async function getAuditConfiguration( req, res ) {
|
|
990
1059
|
try {
|
|
1060
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
991
1061
|
const auditConfig = await auditConfigurationGet( { storeId: req.params?.id } );
|
|
992
1062
|
if ( auditConfig ) {
|
|
993
|
-
const isDocExist = await checkFileExist( { Bucket:
|
|
1063
|
+
const isDocExist = await checkFileExist( { Bucket: bucket.assets, Key: `templates/audit_bulk_update.xlsx` } );
|
|
994
1064
|
if ( isDocExist ) {
|
|
995
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
1065
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `templates/audit_bulk_update.xlsx` } );
|
|
996
1066
|
auditConfig._doc.templateUrl = signedFilUrl;
|
|
997
1067
|
} else {
|
|
998
1068
|
auditConfig._doc.templateUrl = '';
|
|
@@ -1010,6 +1080,7 @@ export async function getAuditConfiguration( req, res ) {
|
|
|
1010
1080
|
|
|
1011
1081
|
export async function auditConfiguration( req, res ) {
|
|
1012
1082
|
try {
|
|
1083
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1013
1084
|
for ( let i = 0; i < req.body?.length; i++ ) {
|
|
1014
1085
|
const previousStore = await findOneStore( { storeId: req.body[i].storeId }, { auditConfigs: 1, _id: 0 } );
|
|
1015
1086
|
await auditConfigurationUpdate( {
|
|
@@ -1039,7 +1110,7 @@ export async function auditConfiguration( req, res ) {
|
|
|
1039
1110
|
},
|
|
1040
1111
|
};
|
|
1041
1112
|
|
|
1042
|
-
await insertOpenSearchData(
|
|
1113
|
+
await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
1043
1114
|
}
|
|
1044
1115
|
|
|
1045
1116
|
|
|
@@ -1081,9 +1152,11 @@ export async function clientList( req, res ) {
|
|
|
1081
1152
|
userType: 'tango',
|
|
1082
1153
|
$expr: {
|
|
1083
1154
|
$cond: {
|
|
1084
|
-
if: {
|
|
1085
|
-
|
|
1086
|
-
|
|
1155
|
+
if: {
|
|
1156
|
+
$and: [
|
|
1157
|
+
{ $eq: [ '$tangoUserType', 'csm' ] },
|
|
1158
|
+
],
|
|
1159
|
+
},
|
|
1087
1160
|
then: { $eq: [ '$isClientApproved', true ] },
|
|
1088
1161
|
else: true,
|
|
1089
1162
|
},
|
|
@@ -1100,7 +1173,7 @@ export async function clientList( req, res ) {
|
|
|
1100
1173
|
];
|
|
1101
1174
|
const clientIdList = await aggregateUserAssignedStore( query );
|
|
1102
1175
|
logger.info( { message: clientIdList, value: 'clientIdList' } );
|
|
1103
|
-
if ( clientIdList.length ==0 ) {
|
|
1176
|
+
if ( clientIdList.length == 0 ) {
|
|
1104
1177
|
return res.sendError( 'No Data Found', 204 );
|
|
1105
1178
|
}
|
|
1106
1179
|
|
|
@@ -1369,7 +1442,7 @@ export async function clientList( req, res ) {
|
|
|
1369
1442
|
'client Id': chunk[i]?.clientId,
|
|
1370
1443
|
'Installation Stores Count': chunk[i]?.installedStores || 0,
|
|
1371
1444
|
'Onboarded Stores Count': chunk[i]?.totalStores,
|
|
1372
|
-
'Store Progress': chunk[i]?.installedStores? `${
|
|
1445
|
+
'Store Progress': chunk[i]?.installedStores ? `${( ( chunk[i]?.installedStores / chunk[i]?.totalStores ) * 100 ).toFixed( 0 )}%` : '0%',
|
|
1373
1446
|
'Active Store': chunk[i]?.activeStoreCount || 0,
|
|
1374
1447
|
'Active Camera': chunk[i]?.activeCameraCount && chunk[i]?.activeCameraCount != undefined ? chunk[i]?.activeCameraCount : 0,
|
|
1375
1448
|
'Pending Stores': chunk[i]?.pendingStores || 0,
|
|
@@ -1392,7 +1465,356 @@ export async function clientList( req, res ) {
|
|
|
1392
1465
|
return res.sendError( 'Internal Server Error', 500 );
|
|
1393
1466
|
}
|
|
1394
1467
|
}
|
|
1468
|
+
export async function clientListV1( req, res ) {
|
|
1469
|
+
try {
|
|
1470
|
+
const inputData = req.body;
|
|
1471
|
+
let clientQuery = [];
|
|
1472
|
+
logger.info( { message: req?.user?.role } );
|
|
1473
|
+
if ( req?.user?.role !== 'superadmin' ) {
|
|
1474
|
+
const query = [
|
|
1475
|
+
{
|
|
1476
|
+
$match: {
|
|
1477
|
+
userEmail: { $eq: req?.user?.email },
|
|
1478
|
+
userType: 'tango',
|
|
1479
|
+
$expr: {
|
|
1480
|
+
$cond: {
|
|
1481
|
+
if: {
|
|
1482
|
+
$and: [
|
|
1483
|
+
{ $eq: [ '$tangoUserType', 'csm' ] },
|
|
1484
|
+
],
|
|
1485
|
+
},
|
|
1486
|
+
then: { $eq: [ '$isClientApproved', true ] },
|
|
1487
|
+
else: true,
|
|
1488
|
+
},
|
|
1489
|
+
},
|
|
1490
|
+
|
|
1491
|
+
},
|
|
1492
|
+
},
|
|
1493
|
+
{
|
|
1494
|
+
$group: {
|
|
1495
|
+
_id: null,
|
|
1496
|
+
clientList: { $push: '$assignedValue' },
|
|
1497
|
+
},
|
|
1498
|
+
},
|
|
1499
|
+
];
|
|
1500
|
+
const clientIdList = await aggregateUserAssignedStore( query );
|
|
1501
|
+
logger.info( { message: clientIdList, value: 'clientIdList' } );
|
|
1502
|
+
if ( clientIdList.length == 0 ) {
|
|
1503
|
+
return res.sendError( 'No Data Found', 204 );
|
|
1504
|
+
}
|
|
1505
|
+
clientQuery.push(
|
|
1506
|
+
{
|
|
1507
|
+
$match: {
|
|
1508
|
+
clientId: { $in: clientIdList[0].clientList },
|
|
1509
|
+
},
|
|
1510
|
+
},
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1513
|
+
clientQuery.push(
|
|
1514
|
+
{
|
|
1515
|
+
$project: {
|
|
1516
|
+
status: 1,
|
|
1517
|
+
clientName: 1,
|
|
1518
|
+
clientId: 1,
|
|
1519
|
+
subscriptionType: '$planDetails.subscriptionType',
|
|
1520
|
+
PaymentPlan: '$planDetails.paymentStatus',
|
|
1521
|
+
},
|
|
1522
|
+
},
|
|
1523
|
+
);
|
|
1524
|
+
if ( inputData.filterByPaymentStatus ) {
|
|
1525
|
+
if ( inputData.filterByPaymentStatus.includes( 'paid' ) ) {
|
|
1526
|
+
inputData.filterByPaymentStatus.push( ...[ 'unbilled', 'due' ] );
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
clientQuery.push(
|
|
1530
|
+
{
|
|
1531
|
+
$match: {
|
|
1532
|
+
'PaymentPlan': { $in: inputData.filterByPaymentStatus },
|
|
1533
|
+
},
|
|
1534
|
+
},
|
|
1535
|
+
);
|
|
1536
|
+
}
|
|
1537
|
+
if ( inputData.filterBySubscription ) {
|
|
1538
|
+
clientQuery.push(
|
|
1539
|
+
{
|
|
1540
|
+
$match: {
|
|
1541
|
+
'subscriptionType': { $in: inputData.filterBySubscription },
|
|
1542
|
+
},
|
|
1543
|
+
},
|
|
1544
|
+
);
|
|
1545
|
+
}
|
|
1546
|
+
if ( inputData.filterByStatus ) {
|
|
1547
|
+
clientQuery.push(
|
|
1548
|
+
{
|
|
1549
|
+
$match: {
|
|
1550
|
+
status: { $in: inputData.filterByStatus },
|
|
1551
|
+
},
|
|
1552
|
+
},
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
if ( inputData.searchValue && inputData.searchValue != '' ) {
|
|
1556
|
+
clientQuery.push( {
|
|
1557
|
+
$match: {
|
|
1558
|
+
$or: [
|
|
1559
|
+
{ clientId: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1560
|
+
{ clientName: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1561
|
+
{ subscriptionType: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1562
|
+
{ status: { $regex: inputData.searchValue, $options: 'i' } },
|
|
1563
|
+
],
|
|
1564
|
+
},
|
|
1565
|
+
} );
|
|
1566
|
+
}
|
|
1567
|
+
clientQuery.push( {
|
|
1568
|
+
$lookup: {
|
|
1569
|
+
from: 'stores',
|
|
1570
|
+
let: { clientId: '$clientId' },
|
|
1571
|
+
pipeline: [
|
|
1572
|
+
{
|
|
1573
|
+
$match: {
|
|
1574
|
+
$expr: {
|
|
1575
|
+
$and: [
|
|
1576
|
+
{ $eq: [ '$clientId', '$$clientId' ] },
|
|
1577
|
+
],
|
|
1578
|
+
},
|
|
1579
|
+
},
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
$project: {
|
|
1583
|
+
edge: 1,
|
|
1584
|
+
status: 1,
|
|
1585
|
+
clientId: 1,
|
|
1586
|
+
storeId: 1,
|
|
1587
|
+
},
|
|
1588
|
+
},
|
|
1589
|
+
], as: 'stores',
|
|
1590
|
+
},
|
|
1591
|
+
},
|
|
1592
|
+
|
|
1593
|
+
{
|
|
1594
|
+
$unwind: { path: '$stores', preserveNullAndEmptyArrays: true },
|
|
1595
|
+
},
|
|
1596
|
+
{
|
|
1597
|
+
$project: {
|
|
1598
|
+
clientId: 1,
|
|
1599
|
+
status: 1,
|
|
1600
|
+
clientName: 1,
|
|
1601
|
+
subscriptionType: 1,
|
|
1602
|
+
PaymentPlan: 1,
|
|
1603
|
+
installed: {
|
|
1604
|
+
$cond: [ { $or: [ { $eq: [ '$stores.edge.firstFile', true ] } ] }, 1, 0,
|
|
1605
|
+
],
|
|
1606
|
+
},
|
|
1607
|
+
activeStores: {
|
|
1608
|
+
$cond: [ { $and: [ { $eq: [ '$stores.status', 'active' ] } ] }, 1, 0,
|
|
1609
|
+
],
|
|
1610
|
+
},
|
|
1611
|
+
InactiveStores: {
|
|
1612
|
+
$cond: [ { $and: [ { $ne: [ '$stores.status', 'active' ] } ] }, 1, 0,
|
|
1613
|
+
],
|
|
1614
|
+
},
|
|
1615
|
+
},
|
|
1616
|
+
},
|
|
1617
|
+
{
|
|
1618
|
+
$group: {
|
|
1619
|
+
_id: '$clientId',
|
|
1620
|
+
clientId: { $first: '$clientId' },
|
|
1621
|
+
onboardedStores: { $sum: 1 },
|
|
1622
|
+
installedStore: { $sum: '$installed' },
|
|
1623
|
+
activeStores: { $sum: '$activeStores' },
|
|
1624
|
+
InactiveStores: { $sum: '$InactiveStores' },
|
|
1625
|
+
ProcessingStatus: { $first: '$status' },
|
|
1626
|
+
clientName: { $first: '$clientName' },
|
|
1627
|
+
subscriptionPlan: { $first: '$subscriptionType' },
|
|
1628
|
+
PaymentPlan: { $first: '$PaymentPlan' },
|
|
1629
|
+
},
|
|
1630
|
+
},
|
|
1631
|
+
{
|
|
1632
|
+
$lookup: {
|
|
1633
|
+
from: 'tangoTicket',
|
|
1634
|
+
let: { clientId: '$clientId' },
|
|
1635
|
+
pipeline: [
|
|
1636
|
+
{
|
|
1637
|
+
$match: {
|
|
1638
|
+
$expr: {
|
|
1639
|
+
$and: [
|
|
1640
|
+
{ $eq: [ '$issueType', 'installation' ] },
|
|
1641
|
+
{ $eq: [ '$basicDetails.clientId', '$$clientId' ] },
|
|
1642
|
+
],
|
|
1643
|
+
},
|
|
1644
|
+
},
|
|
1395
1645
|
|
|
1646
|
+
},
|
|
1647
|
+
{
|
|
1648
|
+
$project: {
|
|
1649
|
+
ticketDetails: 1,
|
|
1650
|
+
status: 1,
|
|
1651
|
+
basicDetails: 1,
|
|
1652
|
+
},
|
|
1653
|
+
},
|
|
1654
|
+
], as: 'ticket',
|
|
1655
|
+
},
|
|
1656
|
+
},
|
|
1657
|
+
{
|
|
1658
|
+
$unwind: { path: '$ticket', preserveNullAndEmptyArrays: true },
|
|
1659
|
+
},
|
|
1660
|
+
{
|
|
1661
|
+
$project: {
|
|
1662
|
+
clientId: 1,
|
|
1663
|
+
ProcessingStatus: 1,
|
|
1664
|
+
onboardedStores: 1,
|
|
1665
|
+
clientName: 1,
|
|
1666
|
+
PaymentPlan: 1,
|
|
1667
|
+
subscriptionPlan: 1,
|
|
1668
|
+
installedStore: 1,
|
|
1669
|
+
activeStores: 1,
|
|
1670
|
+
InactiveStores: 1,
|
|
1671
|
+
installedPending: {
|
|
1672
|
+
$cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] } ] }, 1, 0 ],
|
|
1673
|
+
},
|
|
1674
|
+
installedFailed: {
|
|
1675
|
+
$cond: [ { $and: [ { $ne: [ '$ticket.status', 'closed' ] }, { $eq: [ '$ticket.ticketDetails.issueStatus', 'identified' ] } ] }, 1, 0 ],
|
|
1676
|
+
},
|
|
1677
|
+
},
|
|
1678
|
+
},
|
|
1679
|
+
{
|
|
1680
|
+
$group: {
|
|
1681
|
+
_id: '$clientId',
|
|
1682
|
+
clientId: { $first: '$clientId' },
|
|
1683
|
+
onboardedStores: { $first: '$onboardedStores' },
|
|
1684
|
+
installedStore: { $first: '$installedStore' },
|
|
1685
|
+
activeStores: { $first: '$activeStores' },
|
|
1686
|
+
InactiveStores: { $first: '$InactiveStores' },
|
|
1687
|
+
ProcessingStatus: { $first: '$ProcessingStatus' },
|
|
1688
|
+
clientName: { $first: '$clientName' },
|
|
1689
|
+
subscriptionPlan: { $first: '$subscriptionPlan' },
|
|
1690
|
+
PaymentPlan: { $first: '$PaymentPlan' },
|
|
1691
|
+
installedPending: { $sum: '$installedPending' },
|
|
1692
|
+
installedFailed: { $sum: '$installedFailed' },
|
|
1693
|
+
},
|
|
1694
|
+
},
|
|
1695
|
+
{
|
|
1696
|
+
$project: {
|
|
1697
|
+
clientId: { $toInt: '$clientId' },
|
|
1698
|
+
onboardedStores: 1,
|
|
1699
|
+
installedStore: 1,
|
|
1700
|
+
activeStores: { $max: [
|
|
1701
|
+
{ $subtract: [ '$activeStores', '$installedPending' ] },
|
|
1702
|
+
0,
|
|
1703
|
+
] },
|
|
1704
|
+
InactiveStores: 1,
|
|
1705
|
+
ProcessingStatus: 1,
|
|
1706
|
+
clientName: 1,
|
|
1707
|
+
subscriptionPlan: 1,
|
|
1708
|
+
PaymentPlan: 1,
|
|
1709
|
+
PaymentPlan: {
|
|
1710
|
+
$cond: {
|
|
1711
|
+
if: { $eq: [ '$PaymentPlan', 'unbilled' ] },
|
|
1712
|
+
then: 'paid',
|
|
1713
|
+
else: {
|
|
1714
|
+
$cond: {
|
|
1715
|
+
if: { $eq: [ '$PaymentPlan', 'due' ] },
|
|
1716
|
+
then: 'paid',
|
|
1717
|
+
else: '$PaymentPlan',
|
|
1718
|
+
},
|
|
1719
|
+
},
|
|
1720
|
+
},
|
|
1721
|
+
},
|
|
1722
|
+
installedPending: 1,
|
|
1723
|
+
installedFailed: 1,
|
|
1724
|
+
ProgressBar: {
|
|
1725
|
+
$cond: {
|
|
1726
|
+
if: { $eq: [ '$onboardedStores', 0 ] },
|
|
1727
|
+
then: 0,
|
|
1728
|
+
else: {
|
|
1729
|
+
$round: [
|
|
1730
|
+
{ $multiply: [ { $divide: [ '$installedStore', '$onboardedStores' ] }, 100 ] },
|
|
1731
|
+
0,
|
|
1732
|
+
],
|
|
1733
|
+
},
|
|
1734
|
+
},
|
|
1735
|
+
},
|
|
1736
|
+
},
|
|
1737
|
+
},
|
|
1738
|
+
);
|
|
1739
|
+
|
|
1740
|
+
const clientCount = await aggregateClient( clientQuery );
|
|
1741
|
+
if ( clientCount.length == 0 ) {
|
|
1742
|
+
return res.sendError( 'No Data Found', 204 );
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
if ( inputData.sortColumName&&inputData.sortColumName!=''&& req.body.sortBy&&req.body.sortBy!='' ) {
|
|
1746
|
+
if ( inputData.sortColumName==='clientName' ) {
|
|
1747
|
+
clientQuery.push(
|
|
1748
|
+
{
|
|
1749
|
+
$project: {
|
|
1750
|
+
clientId: 1,
|
|
1751
|
+
onboardedStores: 1,
|
|
1752
|
+
installedStore: 1,
|
|
1753
|
+
activeStores: 1,
|
|
1754
|
+
InactiveStores: 1,
|
|
1755
|
+
ProcessingStatus: 1,
|
|
1756
|
+
clientName: 1,
|
|
1757
|
+
subscriptionPlan: 1,
|
|
1758
|
+
PaymentPlan: 1,
|
|
1759
|
+
PaymentPlan: 1,
|
|
1760
|
+
installedPending: 1,
|
|
1761
|
+
installedFailed: 1,
|
|
1762
|
+
ProgressBar: 1,
|
|
1763
|
+
sortField: {
|
|
1764
|
+
'$toLower': `$${req.body.sortColumName}`,
|
|
1765
|
+
},
|
|
1766
|
+
},
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
$sort: { sortField: req.body.sortBy },
|
|
1770
|
+
},
|
|
1771
|
+
);
|
|
1772
|
+
} else {
|
|
1773
|
+
clientQuery.push( {
|
|
1774
|
+
$sort: { [req.body.sortColumName]: req.body.sortBy },
|
|
1775
|
+
} );
|
|
1776
|
+
}
|
|
1777
|
+
} else {
|
|
1778
|
+
clientQuery.push( {
|
|
1779
|
+
$sort: { activeStores: -1 },
|
|
1780
|
+
},
|
|
1781
|
+
);
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
if ( req.body.limit && req.body.offset && !req.body.isExport ) {
|
|
1785
|
+
clientQuery.push(
|
|
1786
|
+
{ $skip: ( req.body.offset - 1 ) * req.body.limit },
|
|
1787
|
+
{ $limit: Number( req.body.limit ) },
|
|
1788
|
+
);
|
|
1789
|
+
}
|
|
1790
|
+
const clientList = await aggregateClient( clientQuery );
|
|
1791
|
+
|
|
1792
|
+
if ( inputData.isExport ) {
|
|
1793
|
+
const exportResult = [];
|
|
1794
|
+
for ( let client of clientList ) {
|
|
1795
|
+
exportResult.push( {
|
|
1796
|
+
'Brand Name': client.clientName,
|
|
1797
|
+
'Brand ID': client.clientId,
|
|
1798
|
+
'Onboarded Stores': client.onboardedStores||0,
|
|
1799
|
+
'Installed Stores': client.installedStore || 0,
|
|
1800
|
+
'Progress Status': client.ProgressBar||0,
|
|
1801
|
+
'Active Stores': client.activeStores || 0,
|
|
1802
|
+
'In-Active Stores': client.InactiveStores || 0,
|
|
1803
|
+
'Pending Configuration': client.installedPending || 0,
|
|
1804
|
+
'Payment Plan': client.PaymentPlan == 'free'?'Lifetime Free':client.PaymentPlan,
|
|
1805
|
+
'Subscription Plan': client.subscriptionPlan,
|
|
1806
|
+
'Processing Status': client.ProcessingStatus=='active'?'Activated':client.ProcessingStatus=='deactive'?'Deactivated':client.ProcessingStatus,
|
|
1807
|
+
} );
|
|
1808
|
+
}
|
|
1809
|
+
await download( exportResult, res );
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
return res.sendSuccess( { result: clientList, count: clientCount.length } );
|
|
1813
|
+
} catch ( error ) {
|
|
1814
|
+
logger.error( { error: error, function: 'clientList' } );
|
|
1815
|
+
return res.sendError( 'Internal Server Error', 500 );
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1396
1818
|
export async function getOpsUsers( req, res ) {
|
|
1397
1819
|
try {
|
|
1398
1820
|
const users = await OpsUsersGet();
|
|
@@ -1410,6 +1832,7 @@ export async function getOpsUsers( req, res ) {
|
|
|
1410
1832
|
|
|
1411
1833
|
export async function detailedClientCount( req, res ) {
|
|
1412
1834
|
try {
|
|
1835
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
1413
1836
|
const inputData = req.query;
|
|
1414
1837
|
let result = {
|
|
1415
1838
|
clientName: inputData.clientName,
|
|
@@ -1423,10 +1846,10 @@ export async function detailedClientCount( req, res ) {
|
|
|
1423
1846
|
const client = await findOneClient( { clientId: inputData.clientId }, { userId: 1, clientId: 1, profileDetails: 1 } );
|
|
1424
1847
|
const user = await findOneUser( { _id: client.userId }, { userName: 1, email: 1 } );
|
|
1425
1848
|
|
|
1426
|
-
const isLogoExist = await checkFileExist( { Bucket:
|
|
1849
|
+
const isLogoExist = await checkFileExist( { Bucket: bucket.assets, Key: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
1427
1850
|
|
|
1428
1851
|
if ( isLogoExist ) {
|
|
1429
|
-
const signedFilUrl = await signedUrl( { Bucket:
|
|
1852
|
+
const signedFilUrl = await signedUrl( { Bucket: bucket.assets, file_path: `${client.clientId}/logo/${client.profileDetails?.logo}` } );
|
|
1430
1853
|
result['logo'] = signedFilUrl;
|
|
1431
1854
|
} else {
|
|
1432
1855
|
result['logo'] = '';
|
|
@@ -1434,6 +1857,19 @@ export async function detailedClientCount( req, res ) {
|
|
|
1434
1857
|
result['userName'] = user?.userName;
|
|
1435
1858
|
result['email'] = user?.email;
|
|
1436
1859
|
result['profileCompletion'] = 70;
|
|
1860
|
+
let findCsm = await aggregateUserAssignedStore( [
|
|
1861
|
+
{
|
|
1862
|
+
$match: {
|
|
1863
|
+
clientId: inputData.clientId,
|
|
1864
|
+
tangoUserType: 'csm',
|
|
1865
|
+
},
|
|
1866
|
+
},
|
|
1867
|
+
] );
|
|
1868
|
+
|
|
1869
|
+
if ( findCsm&&findCsm.length>0 ) {
|
|
1870
|
+
let finduser = await findOneUser( { email: findCsm[0].userEmail }, { userName: 1, email: 1, countryCode: 1, mobileNumber: 1 } );
|
|
1871
|
+
result['csm'] = finduser;
|
|
1872
|
+
}
|
|
1437
1873
|
|
|
1438
1874
|
return res.sendSuccess( { result: result } );
|
|
1439
1875
|
} catch ( error ) {
|
|
@@ -1444,6 +1880,7 @@ export async function detailedClientCount( req, res ) {
|
|
|
1444
1880
|
|
|
1445
1881
|
export async function getActivityLogs( req, res ) {
|
|
1446
1882
|
try {
|
|
1883
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1447
1884
|
const query = {
|
|
1448
1885
|
'_source': [
|
|
1449
1886
|
'userId', 'userName', 'email', 'date', 'logType', 'logSubType',
|
|
@@ -1500,7 +1937,7 @@ export async function getActivityLogs( req, res ) {
|
|
|
1500
1937
|
},
|
|
1501
1938
|
);
|
|
1502
1939
|
|
|
1503
|
-
const logs = await getOpenSearchData(
|
|
1940
|
+
const logs = await getOpenSearchData( openSearch.activityLog, query );
|
|
1504
1941
|
|
|
1505
1942
|
const hits = logs?.body?.hits?.hits;
|
|
1506
1943
|
const totalDocuments = logs?.body?.hits?.total?.value;
|
package/src/dtos/client.dtos.js
CHANGED
|
@@ -108,6 +108,7 @@ export const featureConfigurationSchemaBody = joi.object(
|
|
|
108
108
|
isNormalized: joi.boolean().optional(),
|
|
109
109
|
isPasserByData: joi.boolean().optional(),
|
|
110
110
|
isFootfallDirectory: joi.boolean().optional(),
|
|
111
|
+
isExcludedArea: joi.boolean().optional(),
|
|
111
112
|
},
|
|
112
113
|
);
|
|
113
114
|
|
|
@@ -5,7 +5,7 @@ import { auditConfiguration, changeStatus, clientCsmAssignAction, clientDetails,
|
|
|
5
5
|
import { authorize, isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
6
6
|
import { clientListValid, detailedClientCountValid } from '../dtos/client.dtos.js';
|
|
7
7
|
import { isclientIdExists, isclientNameExists } from '../validations/client.validations.js';
|
|
8
|
-
import { detailedAllClientCount, detailedClientCount, clientList } from '../controllers/client.controllers.js';
|
|
8
|
+
import { detailedAllClientCount, detailedClientCount, clientList, clientListV1 } from '../controllers/client.controllers.js';
|
|
9
9
|
|
|
10
10
|
export const clientRouter = express.Router();
|
|
11
11
|
|
|
@@ -83,7 +83,9 @@ clientRouter.get( '/detailed-all-client-count', isAllowedSessionHandler,
|
|
|
83
83
|
clientRouter.post( '/client-list', isAllowedSessionHandler,
|
|
84
84
|
authorize( { userType: [ 'tango' ], access: [ { featureName: 'manage', name: 'brands', permissions: [ 'isView' ] } ] } ),
|
|
85
85
|
validate( clientListValid ), clientList );
|
|
86
|
-
|
|
86
|
+
clientRouter.post( '/client-list_v1', isAllowedSessionHandler,
|
|
87
|
+
authorize( { userType: [ 'tango' ], access: [ { featureName: 'manage', name: 'brands', permissions: [ 'isView' ] } ] } ),
|
|
88
|
+
validate( clientListValid ), clientListV1 );
|
|
87
89
|
clientRouter.get( '/detailed-client-count', isAllowedSessionHandler,
|
|
88
90
|
authorize( { userType: [ 'tango', 'client' ] } ),
|
|
89
91
|
validate( detailedClientCountValid ), isclientIdExists, detailedClientCount );
|
|
@@ -2,7 +2,7 @@ import clientModel from 'tango-api-schema/schema/client.model.js';
|
|
|
2
2
|
import leadModel from 'tango-api-schema/schema/lead.model.js';
|
|
3
3
|
import storeModel from 'tango-api-schema/schema/store.model.js';
|
|
4
4
|
import userModel from 'tango-api-schema/schema/user.model.js';
|
|
5
|
-
import { createQueue, getQueueUrl,
|
|
5
|
+
import { createQueue, getQueueUrl, logger } from 'tango-app-api-middleware';
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
export function update( query, record ) {
|
|
@@ -27,10 +27,11 @@ export function findClient( query, field ) {
|
|
|
27
27
|
|
|
28
28
|
export async function createAuditQueue( queueName ) {
|
|
29
29
|
try {
|
|
30
|
-
const
|
|
30
|
+
const sqs = JSON.parse( process.env.SQS );
|
|
31
|
+
const isExist = await getQueueUrl( `${queueName}${sqs.queueType}` );
|
|
31
32
|
logger.info( { message: isExist, function: 'createAuditQueue-isExist' } );
|
|
32
33
|
if ( isExist.statusCode ) {
|
|
33
|
-
const addQueue = await createQueue( `${queueName}${
|
|
34
|
+
const addQueue = await createQueue( `${queueName}${sqs.queueType}` );
|
|
34
35
|
logger.info( { message: addQueue.QueueUrl, function: 'addQueue.QueueUrl' } );
|
|
35
36
|
if ( addQueue.QueueUrl ) {
|
|
36
37
|
logger.info(
|
|
@@ -131,7 +132,7 @@ export function featureConfigurationUpdate( {
|
|
|
131
132
|
clientId, billableCalculation, bouncedLimitCondition, bouncedLimitValue,
|
|
132
133
|
close, conversionCalculation, conversionCondition,
|
|
133
134
|
conversionValue, infraAlertCondition, infraAlertValue, isFootfallDirectory,
|
|
134
|
-
isNormalized, isPasserByData, missedOpportunityCalculation, open,
|
|
135
|
+
isNormalized, isPasserByData, missedOpportunityCalculation, open, isExcludedArea,
|
|
135
136
|
} ) {
|
|
136
137
|
return clientModel.updateOne( { clientId: clientId },
|
|
137
138
|
{
|
|
@@ -150,6 +151,8 @@ export function featureConfigurationUpdate( {
|
|
|
150
151
|
'featureConfigs.isNormalized': isNormalized,
|
|
151
152
|
'featureConfigs.isPasserByData': isPasserByData,
|
|
152
153
|
'featureConfigs.isFootfallDirectory': isFootfallDirectory,
|
|
154
|
+
'featureConfigs.isExcludedArea': isExcludedArea,
|
|
155
|
+
'featureConfigs.updateFeatureConfig': false,
|
|
153
156
|
},
|
|
154
157
|
} );
|
|
155
158
|
}
|
|
@@ -3,3 +3,11 @@ import groupModel from 'tango-api-schema/schema/group.model.js';
|
|
|
3
3
|
export function countDocumentsGroup( query ) {
|
|
4
4
|
return groupModel.countDocuments( query );
|
|
5
5
|
}
|
|
6
|
+
|
|
7
|
+
export async function createGroupModel( query ={}, field={} ) {
|
|
8
|
+
return await groupModel.create( query, field );
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export async function findOneGroup( query ={}, field={} ) {
|
|
12
|
+
return await groupModel.findOne( query, field );
|
|
13
|
+
};
|
|
@@ -3,6 +3,9 @@ import storeModel from 'tango-api-schema/schema/store.model.js';
|
|
|
3
3
|
export function countDocumentsStore( query ) {
|
|
4
4
|
return storeModel.countDocuments( query );
|
|
5
5
|
}
|
|
6
|
+
export function findStore( query ) {
|
|
7
|
+
return storeModel.find( query );
|
|
8
|
+
}
|
|
6
9
|
|
|
7
10
|
export function aggregateStore( query ) {
|
|
8
11
|
return storeModel.aggregate( query );
|