tango-app-api-payment-subscription 3.0.53-dev → 3.0.55-dev
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/paymentSubscription.controllers.js +311 -73
- package/src/services/assignedStore.service.js +5 -0
- package/src/services/camera.service.js +28 -0
- package/src/services/clientPayment.services.js +4 -0
- package/src/utils/validations/client.validation.js +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-payment-subscription",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.55-dev",
|
|
4
4
|
"description": "paymentSubscription",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"mongodb": "^6.4.0",
|
|
26
26
|
"nodemon": "^3.1.0",
|
|
27
27
|
"swagger-ui-express": "^5.0.0",
|
|
28
|
-
"tango-api-schema": "^2.0.
|
|
29
|
-
"tango-app-api-middleware": "^1.
|
|
28
|
+
"tango-api-schema": "^2.0.108",
|
|
29
|
+
"tango-app-api-middleware": "^3.1.12",
|
|
30
30
|
"winston": "^3.12.0",
|
|
31
31
|
"winston-daily-rotate-file": "^5.0.0"
|
|
32
32
|
},
|
|
@@ -9,6 +9,7 @@ import * as clientRequestService from '../services/clientRequest.service.js';
|
|
|
9
9
|
import * as invoiceService from '../services/invoice.service.js';
|
|
10
10
|
import * as userService from '../services/user.service.js';
|
|
11
11
|
import * as dailyPriceService from '../services/dailyPrice.service.js';
|
|
12
|
+
import * as cameraService from '../services/camera.service.js';
|
|
12
13
|
import dayjs from 'dayjs';
|
|
13
14
|
import Handlebars from 'handlebars';
|
|
14
15
|
import fs from 'fs';
|
|
@@ -398,6 +399,7 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
398
399
|
try {
|
|
399
400
|
let requestBody = req.body;
|
|
400
401
|
let subscriptionCount = 0;
|
|
402
|
+
let getClientCount = await paymentService.getClientCount( { status: 'active' } );
|
|
401
403
|
if ( !requestBody?.products?.length ) {
|
|
402
404
|
return res.sendError( 'product is required', 400 );
|
|
403
405
|
}
|
|
@@ -420,18 +422,27 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
420
422
|
};
|
|
421
423
|
let productExists = await clientRequestService.findOne( { clientId: requestBody.clientId, name: item.name, category: 'Trial', status: 'pending' } );
|
|
422
424
|
if ( !productExists ) {
|
|
423
|
-
await clientRequestService.insert( params );
|
|
425
|
+
let data =await clientRequestService.insert( params );
|
|
424
426
|
const logObj = {
|
|
425
|
-
clientId:
|
|
427
|
+
clientId: requestBody.clientId,
|
|
426
428
|
userName: req.user?.userName,
|
|
427
429
|
email: req.user?.email,
|
|
430
|
+
showNotificationTo: 'tango',
|
|
431
|
+
// clientNotification: false,
|
|
432
|
+
// adminNotification: false,
|
|
433
|
+
// tangoNotification: true,
|
|
428
434
|
date: new Date(),
|
|
429
435
|
logType: 'subscription',
|
|
430
436
|
logSubType: 'trialRequest',
|
|
431
|
-
|
|
437
|
+
title: 'Subscription',
|
|
438
|
+
description: `${requestBody?.client?.clientName} has requested for ${item.name} trial for 14 days, kindly make the necessary actions immediately for them to watch the insights.`,
|
|
439
|
+
alertCta: [ { buttonName: 'Approve', redirectionUrl: 'trialApproved', product: item.name, name: convertTitleCase( item.name ), clientId: requestBody.clientId, id: data._id }, { buttonName: 'Cancel', redirectionUrl: 'cancel' } ],
|
|
440
|
+
markasRead: false,
|
|
441
|
+
showPushNotification: true,
|
|
442
|
+
changes: [ `${convertTitleCase( item.name )} trial Request` ],
|
|
432
443
|
eventType: 'create',
|
|
433
|
-
timestamp: new Date(),
|
|
434
444
|
showTo: [ 'client', 'tango' ],
|
|
445
|
+
csmDetails: requestBody?.csm || [],
|
|
435
446
|
};
|
|
436
447
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
437
448
|
}
|
|
@@ -447,10 +458,13 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
447
458
|
userName: req.user?.userName,
|
|
448
459
|
email: req.user?.email,
|
|
449
460
|
clientId: requestBody.clientId,
|
|
450
|
-
clientNotification: false,
|
|
451
|
-
adminNotification: true,
|
|
461
|
+
// clientNotification: false,
|
|
462
|
+
// adminNotification: true,
|
|
463
|
+
// tangoNotification: false,
|
|
464
|
+
showNotificationTo: 'superadmin',
|
|
452
465
|
title: 'Subscription',
|
|
453
466
|
description: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
|
|
467
|
+
tangoDescription: `${requestBody?.client?.clientName} has been sucessfully Subscribed to TangoEye Suite !! We are now onboarded ${getClientCount} succesfull brands.`,
|
|
454
468
|
alertCta: [],
|
|
455
469
|
markasRead: false,
|
|
456
470
|
logType: 'subscription',
|
|
@@ -460,6 +474,7 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
460
474
|
eventType: '',
|
|
461
475
|
date: new Date(),
|
|
462
476
|
showTo: [ 'client', 'tango' ],
|
|
477
|
+
csmDetails: requestBody?.csm || [],
|
|
463
478
|
};
|
|
464
479
|
insertOpenSearchData( appConfig.opensearch.activityLog, productObj );
|
|
465
480
|
} else {
|
|
@@ -469,10 +484,13 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
469
484
|
userName: req.user?.userName,
|
|
470
485
|
email: req.user?.email,
|
|
471
486
|
clientId: requestBody.clientId,
|
|
472
|
-
clientNotification: false,
|
|
473
|
-
adminNotification: true,
|
|
487
|
+
// clientNotification: false,
|
|
488
|
+
// adminNotification: true,
|
|
489
|
+
// tangoNotification: false,
|
|
490
|
+
showNotificationTo: 'superadmin',
|
|
474
491
|
title: 'Subscription',
|
|
475
492
|
description: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
|
|
493
|
+
tangoDescription: `${requestBody?.client?.clientName} has been sucessfully Subscribed to TangoEye Suite !! We are now onboarded ${getClientCount} succesfull brands.`,
|
|
476
494
|
alertCta: [],
|
|
477
495
|
markasRead: false,
|
|
478
496
|
logType: 'subscription',
|
|
@@ -482,8 +500,13 @@ export const updateSubscription = async ( req, res ) => {
|
|
|
482
500
|
eventType: '',
|
|
483
501
|
date: new Date(),
|
|
484
502
|
showTo: [ 'client', 'tango' ],
|
|
503
|
+
csmDetails: requestBody?.csm || [],
|
|
485
504
|
};
|
|
486
505
|
insertOpenSearchData( appConfig.opensearch.activityLog, productObj );
|
|
506
|
+
// productObj.adminNotification = false;
|
|
507
|
+
// productObj.tangoNotification = true;
|
|
508
|
+
productObj.showNotificationTo = 'tango',
|
|
509
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, productObj );
|
|
487
510
|
}
|
|
488
511
|
subscriptionCount = subscriptionCount + 1;
|
|
489
512
|
}
|
|
@@ -661,9 +684,20 @@ export const unsubscribeProduct = async ( req, res ) => {
|
|
|
661
684
|
date: new Date(),
|
|
662
685
|
logType: 'subscription',
|
|
663
686
|
logSubType: 'unsubscribedRequest',
|
|
687
|
+
showNotificationTo: 'tango',
|
|
688
|
+
// clientNotification: false,
|
|
689
|
+
// adminNotification: false,
|
|
690
|
+
// tangoNotification: true,
|
|
691
|
+
date: new Date(),
|
|
664
692
|
changes: [ `${req.body.clientId} Unsubscribed Request ` ],
|
|
665
693
|
eventType: 'create',
|
|
666
694
|
showTo: [ 'client', 'tango' ],
|
|
695
|
+
title: 'Unsubscription Request',
|
|
696
|
+
description: `${req.body?.client?.clientName} has unsubscribed due to ${req.body.reason} `,
|
|
697
|
+
alertCta: [ { buttonName: 'View', redirectionUrl: 'manage/settings/payment-subscription' } ],
|
|
698
|
+
markasRead: false,
|
|
699
|
+
showPushNotification: true,
|
|
700
|
+
csmDetails: requestBody?.csm || [],
|
|
667
701
|
};
|
|
668
702
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
669
703
|
|
|
@@ -699,6 +733,17 @@ export const trialExtendRequest = async ( req, res ) => {
|
|
|
699
733
|
changes: [ `${convertTitleCase( req.body.product )} trial Extend Request` ],
|
|
700
734
|
eventType: 'create',
|
|
701
735
|
showTo: [ 'client', 'tango' ],
|
|
736
|
+
// clientNotification: false,
|
|
737
|
+
// adminNotification: false,
|
|
738
|
+
// tangoNotification: true,
|
|
739
|
+
showNotificationTo: 'tango',
|
|
740
|
+
date: new Date(),
|
|
741
|
+
title: 'Subscription',
|
|
742
|
+
description: `${req.body?.client?.clientName} has requested for trial extention, kindly make the necessary action immediately.`,
|
|
743
|
+
alertCta: [ { buttonName: 'View', redirectionUrl: 'manage/settings/payment-subscription' } ],
|
|
744
|
+
markasRead: false,
|
|
745
|
+
showPushNotification: true,
|
|
746
|
+
csmDetails: req.body?.csm || [],
|
|
702
747
|
};
|
|
703
748
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
704
749
|
|
|
@@ -724,18 +769,28 @@ export const trialRequest = async ( req, res ) => {
|
|
|
724
769
|
category: 'Trial',
|
|
725
770
|
status: 'pending',
|
|
726
771
|
};
|
|
727
|
-
await clientRequestService.insert( params );
|
|
772
|
+
let data = await clientRequestService.insert( params );
|
|
728
773
|
|
|
729
774
|
const logObj = {
|
|
730
775
|
clientId: req.body.clientId,
|
|
731
776
|
userName: req.user?.userName,
|
|
732
777
|
email: req.user?.email,
|
|
778
|
+
// clientNotification: false,
|
|
779
|
+
// adminNotification: false,
|
|
780
|
+
// tangoNotification: true,
|
|
781
|
+
showNotificationTo: 'tango',
|
|
733
782
|
date: new Date(),
|
|
734
783
|
logType: 'subscription',
|
|
735
784
|
logSubType: 'trialRequest',
|
|
785
|
+
title: 'Subscription',
|
|
786
|
+
description: `${req.body?.client?.clientName} has requested for ${req.body.product} trial for 14 days, kindly make the necessary actions immediately for them to watch the insights.`,
|
|
787
|
+
alertCta: [ { buttonName: 'Approve', redirectionUrl: 'trialApproved', product: req.body.product, name: convertTitleCase( req.body.product ), clientId: client.clientId, id: data._id }, { buttonName: 'Cancel', redirectionUrl: 'cancel' } ],
|
|
788
|
+
markasRead: false,
|
|
789
|
+
showPushNotification: true,
|
|
736
790
|
changes: [ `${convertTitleCase( req.body.product )} trial Request` ],
|
|
737
791
|
eventType: 'create',
|
|
738
792
|
showTo: [ 'client', 'tango' ],
|
|
793
|
+
csmDetails: requestBody?.csm || [],
|
|
739
794
|
};
|
|
740
795
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
741
796
|
|
|
@@ -911,8 +966,10 @@ export const trialApproval = async ( req, res ) => {
|
|
|
911
966
|
userName: req.user?.userName,
|
|
912
967
|
email: req.user?.email,
|
|
913
968
|
clientId: requestData.clientId,
|
|
914
|
-
clientNotification: false,
|
|
915
|
-
adminNotification: true,
|
|
969
|
+
// clientNotification: false,
|
|
970
|
+
// adminNotification: true,
|
|
971
|
+
// tangoNotification: false,
|
|
972
|
+
showNotificationTo: 'superadmin',
|
|
916
973
|
logSubType: 'startTrial',
|
|
917
974
|
description: 'Subscription - Your 14 Days free trial has been started',
|
|
918
975
|
// category: 'Brand Activity Log',
|
|
@@ -926,6 +983,7 @@ export const trialApproval = async ( req, res ) => {
|
|
|
926
983
|
changes: [ `${convertTitleCase( requestData.name )} trial started` ],
|
|
927
984
|
eventType: '',
|
|
928
985
|
showTo: [ 'client', 'tango' ],
|
|
986
|
+
csmDetails: req.body?.csm || [],
|
|
929
987
|
};
|
|
930
988
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
931
989
|
let clientProducts = await paymentService.findOne( { clientId: requestData.clientId }, { planDetails: 1 } );
|
|
@@ -1075,8 +1133,10 @@ export const trialExtendRequestApproval = async ( req, res ) => {
|
|
|
1075
1133
|
userName: req.user?.userName,
|
|
1076
1134
|
email: req.user?.email,
|
|
1077
1135
|
clientId: req.body.clientId,
|
|
1078
|
-
clientNotification: false,
|
|
1079
|
-
adminNotification: true,
|
|
1136
|
+
// clientNotification: false,
|
|
1137
|
+
// adminNotification: true,
|
|
1138
|
+
// tangoNotification: false,
|
|
1139
|
+
showNotificationTo: 'superadmin',
|
|
1080
1140
|
logSubType: 'trialExtended',
|
|
1081
1141
|
description: `Your Trial has been extended for ${req.body.days} days, explore the service with no extra charge and keep unlocking better insights`,
|
|
1082
1142
|
// category: 'Brand Activity Log',
|
|
@@ -1090,6 +1150,7 @@ export const trialExtendRequestApproval = async ( req, res ) => {
|
|
|
1090
1150
|
changes: [ `${firstWord + ' ' + secondWord} trial Extended` ],
|
|
1091
1151
|
eventType: '',
|
|
1092
1152
|
showTo: [ 'client', 'tango' ],
|
|
1153
|
+
csmDetails: req?.body?.csm || [],
|
|
1093
1154
|
};
|
|
1094
1155
|
insertOpenSearchData( appConfig.opensearch.activityLog, notifyObj );
|
|
1095
1156
|
// const logObj = {
|
|
@@ -1132,6 +1193,7 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1132
1193
|
}
|
|
1133
1194
|
} );
|
|
1134
1195
|
let clientInfo = await paymentService.findOne( { clientId: req.body.clientId }, { clientId: 1, planDetails: 1 } );
|
|
1196
|
+
let getClientCount = await paymentService.getClientCount( { status: 'active' } );
|
|
1135
1197
|
if ( !clientInfo ) {
|
|
1136
1198
|
return res.sendError( 'no data found', 204 );
|
|
1137
1199
|
}
|
|
@@ -1162,8 +1224,10 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1162
1224
|
userName: req.user?.userName,
|
|
1163
1225
|
email: req.user?.email,
|
|
1164
1226
|
clientId: clientInfo.clientId,
|
|
1165
|
-
clientNotification: false,
|
|
1166
|
-
adminNotification: true,
|
|
1227
|
+
// clientNotification: false,
|
|
1228
|
+
// adminNotification: true,
|
|
1229
|
+
// tangoNotification: false,
|
|
1230
|
+
showNotificationTo: 'superadmin',
|
|
1167
1231
|
logSubType: 'startTrial',
|
|
1168
1232
|
description: 'Subscription - Your 14 Days free trial has been started',
|
|
1169
1233
|
// category: 'Brand Activity Log',
|
|
@@ -1178,8 +1242,11 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1178
1242
|
eventType: '',
|
|
1179
1243
|
timestamp: new Date(),
|
|
1180
1244
|
showTo: [ 'client', 'tango' ],
|
|
1245
|
+
csmDetails: req.body?.csm || [],
|
|
1181
1246
|
};
|
|
1182
1247
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1248
|
+
logObj.showNotificationTo = 'tango';
|
|
1249
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1183
1250
|
product.push( {
|
|
1184
1251
|
productName: item.name,
|
|
1185
1252
|
trialStartDate: new Date(),
|
|
@@ -1195,10 +1262,13 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1195
1262
|
userName: req.user?.userName,
|
|
1196
1263
|
email: req.user?.email,
|
|
1197
1264
|
clientId: clientInfo.clientId,
|
|
1198
|
-
clientNotification: false,
|
|
1199
|
-
adminNotification: true,
|
|
1265
|
+
// clientNotification: false,
|
|
1266
|
+
// adminNotification: true,
|
|
1267
|
+
// tangoNotification: true,
|
|
1268
|
+
showNotificationTo: 'superadmin',
|
|
1200
1269
|
logSubType: 'productSubscribed',
|
|
1201
1270
|
description: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
|
|
1271
|
+
tangoDescription: `${clientInfo?.clientName} has been sucessfully Subscribed to TangoEye Suite !! We are now onboarded ${getClientCount} succesfull brands.`,
|
|
1202
1272
|
// category: 'Brand Activity Log',
|
|
1203
1273
|
// features: 'Subscription',
|
|
1204
1274
|
title: 'Subscription',
|
|
@@ -1210,8 +1280,11 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1210
1280
|
changes: [ `${convertTitleCase( item.name )} prodcut Subscribed` ],
|
|
1211
1281
|
eventType: '',
|
|
1212
1282
|
showTo: [ 'client', 'tango' ],
|
|
1283
|
+
csmDetails: req.body?.csm || [],
|
|
1213
1284
|
};
|
|
1214
1285
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1286
|
+
logObj.showNotificationTo = 'tango';
|
|
1287
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1215
1288
|
product.push( {
|
|
1216
1289
|
productName: item.name,
|
|
1217
1290
|
subscribedDate: new Date(),
|
|
@@ -1228,10 +1301,13 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1228
1301
|
userName: req.user?.userName,
|
|
1229
1302
|
email: req.user?.email,
|
|
1230
1303
|
clientId: clientInfo.clientId,
|
|
1231
|
-
clientNotification: false,
|
|
1232
|
-
adminNotification: true,
|
|
1304
|
+
// clientNotification: false,
|
|
1305
|
+
// adminNotification: true,
|
|
1306
|
+
// tangoNotification: false,
|
|
1307
|
+
showNotificationTo: 'superadmin',
|
|
1233
1308
|
logSubType: 'productSubscribed',
|
|
1234
1309
|
description: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
|
|
1310
|
+
tangoDescription: `${clientInfo?.clientName} has been sucessfully Subscribed to TangoEye Suite !! We are now onboarded ${getClientCount} succesfull brands.`,
|
|
1235
1311
|
// category: 'Brand Activity Log',
|
|
1236
1312
|
// features: 'Subscription',
|
|
1237
1313
|
title: 'Subscription',
|
|
@@ -1243,8 +1319,11 @@ export const productSubscribe = async ( req, res ) => {
|
|
|
1243
1319
|
changes: [ `${convertTitleCase( item.name )} prodcut Subscribed` ],
|
|
1244
1320
|
eventType: '',
|
|
1245
1321
|
showTo: [ 'client', 'tango' ],
|
|
1322
|
+
csmDetails: req.body?.csm || [],
|
|
1246
1323
|
};
|
|
1247
1324
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1325
|
+
logObj.showNotificationTo = 'tango';
|
|
1326
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1248
1327
|
product[productIndex].subscribedDate = new Date();
|
|
1249
1328
|
product[productIndex].status = 'live';
|
|
1250
1329
|
subscriptionCount = subscriptionCount + 1;
|
|
@@ -1610,7 +1689,8 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1610
1689
|
} );
|
|
1611
1690
|
}
|
|
1612
1691
|
} );
|
|
1613
|
-
let clientInfo = await paymentService.findOne( { clientId: req.body.clientId }, { 'planDetails.product': 1 } );
|
|
1692
|
+
let clientInfo = await paymentService.findOne( { clientId: req.body.clientId }, { 'planDetails.product': 1, 'clientName': 1 } );
|
|
1693
|
+
let getClientCount = await paymentService.getClientCount( { status: 'active' } );
|
|
1614
1694
|
let productList = clientInfo.planDetails.product.map( ( product ) => product.productName );
|
|
1615
1695
|
let clientProduct = [];
|
|
1616
1696
|
let storeProduct = [];
|
|
@@ -1678,8 +1758,10 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1678
1758
|
userName: req.user?.userName,
|
|
1679
1759
|
email: req.user?.email,
|
|
1680
1760
|
clientId: req.body.clientId,
|
|
1681
|
-
clientNotification: false,
|
|
1682
|
-
adminNotification: true,
|
|
1761
|
+
// clientNotification: false,
|
|
1762
|
+
// adminNotification: true,
|
|
1763
|
+
// tangoNotification: false,
|
|
1764
|
+
showNotificationTo: 'superadmin',
|
|
1683
1765
|
logSubType: 'startTrial',
|
|
1684
1766
|
description: 'Subscription - Your 14 Days free trial has been started',
|
|
1685
1767
|
title: 'Start Trial',
|
|
@@ -1691,6 +1773,7 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1691
1773
|
changes: [ `${convertTitleCase( item.name )} trial started` ],
|
|
1692
1774
|
eventType: '',
|
|
1693
1775
|
showTo: [ 'client', 'tango' ],
|
|
1776
|
+
csmDetails: req.body?.csm || [],
|
|
1694
1777
|
|
|
1695
1778
|
};
|
|
1696
1779
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
@@ -1706,10 +1789,13 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1706
1789
|
userName: req.user?.userName,
|
|
1707
1790
|
email: req.user?.email,
|
|
1708
1791
|
clientId: req.body.clientId,
|
|
1709
|
-
clientNotification: false,
|
|
1710
|
-
adminNotification: true,
|
|
1792
|
+
// clientNotification: false,
|
|
1793
|
+
// adminNotification: true,
|
|
1794
|
+
// tangoNotification: false,
|
|
1795
|
+
showNotificationTo: 'superadmin',
|
|
1711
1796
|
logSubType: 'productSubscription',
|
|
1712
1797
|
description: 'Your subscription is now active! Get ready to maximize your instore sales potential with the Tangoeye suite',
|
|
1798
|
+
tangoDescription: `${clientInfo?.clientName} has been sucessfully Subscribed to TangoEye Suite !! We are now onboarded ${getClientCount} succesfull brands.`,
|
|
1713
1799
|
title: 'Subscription',
|
|
1714
1800
|
alertCta: [],
|
|
1715
1801
|
markasRead: false,
|
|
@@ -1719,8 +1805,12 @@ export const addStoreProduct = async ( req, res ) => {
|
|
|
1719
1805
|
changes: [ `${convertTitleCase( item.name )} product subscribed` ],
|
|
1720
1806
|
eventType: '',
|
|
1721
1807
|
showTo: [ 'client', 'tango' ],
|
|
1808
|
+
csmDetails: req.body?.csm || [],
|
|
1722
1809
|
};
|
|
1723
1810
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1811
|
+
logObj.showNotificationTo = 'tango';
|
|
1812
|
+
// logObj.tangoNotification = true;
|
|
1813
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
1724
1814
|
}
|
|
1725
1815
|
}
|
|
1726
1816
|
}
|
|
@@ -2435,6 +2525,7 @@ export const getRemindClients = async ( req, res ) => {
|
|
|
2435
2525
|
let date = dayjs().startOf( 'day' );
|
|
2436
2526
|
let leftDays = endDate.diff( date, 'day' );
|
|
2437
2527
|
let userDetails = await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2528
|
+
let csmDetails = await find( { clientId: client.clientId } );
|
|
2438
2529
|
if ( userDetails ) {
|
|
2439
2530
|
if ( leftDays == 3 ) {
|
|
2440
2531
|
let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
@@ -2446,9 +2537,9 @@ export const getRemindClients = async ( req, res ) => {
|
|
|
2446
2537
|
};
|
|
2447
2538
|
let logObj = {
|
|
2448
2539
|
clientId: client.clientId,
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2540
|
+
showNotificationTo: 'superadmin',
|
|
2541
|
+
description: 'Your Free trial is about to expire in 3 days. Please make sure to subscribe to the products',
|
|
2542
|
+
tangoDescription: `${client.clientName} Free trial is about to expire in 3 days. Please make sure to make the necessary actions`,
|
|
2452
2543
|
logSubType: 'trialReminder',
|
|
2453
2544
|
title: 'Subscription',
|
|
2454
2545
|
alertCta: [ { buttonName: 'Subscribe now', redirectionUrl: 'subscribed', product: item.productName, name: data.product, clientId: client.clientId }, { buttonName: 'Remind me later', redirectionUrl: 'remind' } ],
|
|
@@ -2461,8 +2552,12 @@ export const getRemindClients = async ( req, res ) => {
|
|
|
2461
2552
|
changes: [ `${data.product} trial is going to expired.` ],
|
|
2462
2553
|
eventType: '',
|
|
2463
2554
|
showTo: [ 'client', 'tango' ],
|
|
2555
|
+
csmDetails: csmDetails.map( ( item ) => item.userEmail ),
|
|
2464
2556
|
};
|
|
2465
2557
|
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
2558
|
+
logObj.showNotificationTo = 'tango';
|
|
2559
|
+
logObj.alertCta = [];
|
|
2560
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
2466
2561
|
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialReminderEmail.hbs', 'utf8' );
|
|
2467
2562
|
const template = Handlebars.compile( templateHtml );
|
|
2468
2563
|
const html = template( { data: data } );
|
|
@@ -2560,6 +2655,7 @@ export const getExpiredClients = async ( req, res ) => {
|
|
|
2560
2655
|
let date = dayjs().startOf( 'day' );
|
|
2561
2656
|
let leftDays = endDate.diff( date, 'day' );
|
|
2562
2657
|
let userDetails = await userService.findOne( { clientId: client.clientId, role: 'superadmin' } );
|
|
2658
|
+
let csmDetails = await find( { clientId: client.clientId } );
|
|
2563
2659
|
if ( userDetails ) {
|
|
2564
2660
|
if ( leftDays == -1 ) {
|
|
2565
2661
|
let [ firstWord, secondWord ] = item.productName.replace( /([a-z])([A-Z])/g, '$1 $2' ).split( ' ' );
|
|
@@ -2569,6 +2665,32 @@ export const getExpiredClients = async ( req, res ) => {
|
|
|
2569
2665
|
product: firstWord + ' ' + secondWord,
|
|
2570
2666
|
domain: appConfig.url.domain,
|
|
2571
2667
|
};
|
|
2668
|
+
let logObj = {
|
|
2669
|
+
clientId: client.clientId,
|
|
2670
|
+
// clientNotification: false,
|
|
2671
|
+
// adminNotification: true,
|
|
2672
|
+
// tangoNotification: false,
|
|
2673
|
+
showNotificationTo: 'superadmin',
|
|
2674
|
+
description: 'Subscribe Now to Continue Access Your trial period has ended. Subscribe to keep accessing advanced analytics and insights!',
|
|
2675
|
+
tangoDescription: `Plan Expired for ${client.clientName} on ${dayjs( item?.trialEndDate, 'DD-MM-YYYY' )}, please take necessary actions inorder to proceed with the next steps`,
|
|
2676
|
+
logSubType: 'trialExpired',
|
|
2677
|
+
title: 'Trial Expired',
|
|
2678
|
+
alertCta: [ { buttonName: 'Subscribe now', redirectionUrl: 'subscribed', product: item.productName, name: data.product, clientId: client.clientId }, { buttonName: 'Remind me later', redirectionUrl: 'remind' } ],
|
|
2679
|
+
markasRead: false,
|
|
2680
|
+
logType: 'subscription',
|
|
2681
|
+
showPushNotification: true,
|
|
2682
|
+
date: new Date(),
|
|
2683
|
+
userName: userDetails?.userName,
|
|
2684
|
+
email: userDetails?.email,
|
|
2685
|
+
changes: [ `${data.product} trial is going to expired.` ],
|
|
2686
|
+
eventType: '',
|
|
2687
|
+
showTo: [ 'client', 'tango' ],
|
|
2688
|
+
csmDetails: csmDetails.map( ( item ) => item.userEmail ),
|
|
2689
|
+
};
|
|
2690
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
2691
|
+
logObj.showNotificationTo = 'tango';
|
|
2692
|
+
logObj.alertCta = [];
|
|
2693
|
+
insertOpenSearchData( appConfig.opensearch.activityLog, logObj );
|
|
2572
2694
|
const templateHtml = fs.readFileSync( path.resolve( path.dirname( '' ) ) + '/src/hbs/trialExpiredEmail.hbs', 'utf8' );
|
|
2573
2695
|
const template = Handlebars.compile( templateHtml );
|
|
2574
2696
|
const html = template( { data: data } );
|
|
@@ -2819,7 +2941,7 @@ export const invoiceCreate = async ( req, res ) => {
|
|
|
2819
2941
|
}
|
|
2820
2942
|
};
|
|
2821
2943
|
|
|
2822
|
-
export const
|
|
2944
|
+
export const dailyPricingInsertOld = async ( req, res ) => {
|
|
2823
2945
|
try {
|
|
2824
2946
|
let requestData = req.body;
|
|
2825
2947
|
let clientlist = await paymentService.find( { 'status': 'active' } );
|
|
@@ -2899,6 +3021,138 @@ export const dailyPricingInsert = async ( req, res ) => {
|
|
|
2899
3021
|
}
|
|
2900
3022
|
};
|
|
2901
3023
|
|
|
3024
|
+
export const dailyPricingInsert = async ( req, res ) => {
|
|
3025
|
+
try {
|
|
3026
|
+
let requestData = req.body;
|
|
3027
|
+
let clientlist;
|
|
3028
|
+
let requestClient = [];
|
|
3029
|
+
if ( !requestData?.clientId || !requestData?.clientId?.length ) {
|
|
3030
|
+
clientlist = await paymentService.find( { 'status': 'active' } );
|
|
3031
|
+
for ( let client of clientlist ) {
|
|
3032
|
+
requestClient.push( client.clientId );
|
|
3033
|
+
}
|
|
3034
|
+
} else {
|
|
3035
|
+
requestClient.push( ...requestData.clientId );
|
|
3036
|
+
}
|
|
3037
|
+
|
|
3038
|
+
if ( requestData.clientId && requestClient.length > 0 ) {
|
|
3039
|
+
for ( let clientIndex = 0; clientIndex < requestClient.length; clientIndex++ ) {
|
|
3040
|
+
let getClient = await paymentService.findOne( { clientId: requestClient[clientIndex] } );
|
|
3041
|
+
if ( getClient ) {
|
|
3042
|
+
let getBaseprice = await basePriceService.findOne( { clientId: requestClient[clientIndex] } );
|
|
3043
|
+
let getStore = await storeService.find( { clientId: requestClient[clientIndex] } );
|
|
3044
|
+
if ( getStore.length ) {
|
|
3045
|
+
let storeList = [];
|
|
3046
|
+
for ( let storeIndex = 0; storeIndex < getStore.length; storeIndex++ ) {
|
|
3047
|
+
let productList = [];
|
|
3048
|
+
if ( getBaseprice ) {
|
|
3049
|
+
let priceDetails = getClient.priceType == 'standard' ? getBaseprice.standard : getBaseprice.step;
|
|
3050
|
+
for ( let storeProductIndex = 0; storeProductIndex < getStore[storeIndex].product.length; storeProductIndex++ ) {
|
|
3051
|
+
let productDetails;
|
|
3052
|
+
if ( getClient.priceType == 'standard' ) {
|
|
3053
|
+
productDetails = priceDetails.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3054
|
+
} else {
|
|
3055
|
+
productDetails = priceDetails.find( ( item ) => {
|
|
3056
|
+
let range = item.storeRange.split( '-' );
|
|
3057
|
+
if ( parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) ) {
|
|
3058
|
+
return ( item.productName == getStore[storeIndex].product[storeProductIndex] && parseInt( range[0] ) <= ( storeIndex + 1 ) && parseInt( range[1] ) >= ( storeIndex + 1 ) );
|
|
3059
|
+
}
|
|
3060
|
+
} );
|
|
3061
|
+
if ( !productDetails ) {
|
|
3062
|
+
let stepProductDetails = priceDetails.filter( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3063
|
+
productDetails = stepProductDetails[stepProductDetails.length - 1];
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
let productStatus = getClient.planDetails.product.find( ( item ) => item.productName == getStore[storeIndex].product[storeProductIndex] );
|
|
3067
|
+
if ( productDetails ) {
|
|
3068
|
+
let newObject = {
|
|
3069
|
+
productName: productDetails.productName,
|
|
3070
|
+
status: productStatus ? productStatus.status : '',
|
|
3071
|
+
price: productStatus ? [ 'trial', 'free' ].includes( productStatus.status ) ? 0 : productDetails.negotiatePrice : 0,
|
|
3072
|
+
featureStoreCount: storeIndex + 1,
|
|
3073
|
+
basePrice: productDetails.negotiatePrice,
|
|
3074
|
+
...( getClient.priceType == 'step' ? { storeRange: productDetails.storeRange } : { storeRange: 'standard' } ),
|
|
3075
|
+
};
|
|
3076
|
+
productList.push( newObject );
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
|
|
3080
|
+
await axios.get( `${appConfig.url.oldapidomain}/processedDayData/getDailyData?clientId=${requestClient[clientIndex]}&storeId=${getStore[storeIndex].storeId}&date=${requestData.date}`, { headers: { Authorization: 'Bearer d47433f8-9a33-47c7-ba43-1a0fbac28f66' } } ).then( async ( response ) => {
|
|
3081
|
+
let processedFileDate = response.data?.data?.firstFileDate || null;
|
|
3082
|
+
let query = [
|
|
3083
|
+
{
|
|
3084
|
+
$match: {
|
|
3085
|
+
clientId: requestClient[clientIndex],
|
|
3086
|
+
},
|
|
3087
|
+
},
|
|
3088
|
+
{ $unwind: '$stores' },
|
|
3089
|
+
{
|
|
3090
|
+
$match: {
|
|
3091
|
+
'stores.storeId': getStore[storeIndex].storeId,
|
|
3092
|
+
},
|
|
3093
|
+
},
|
|
3094
|
+
{
|
|
3095
|
+
$project: {
|
|
3096
|
+
'stores.daysDifference': 1,
|
|
3097
|
+
},
|
|
3098
|
+
},
|
|
3099
|
+
{
|
|
3100
|
+
$sort: {
|
|
3101
|
+
_id: -1,
|
|
3102
|
+
},
|
|
3103
|
+
},
|
|
3104
|
+
{ $limit: 1 },
|
|
3105
|
+
];
|
|
3106
|
+
let dailyData = await dailyPriceService.aggregate( query );
|
|
3107
|
+
let cameraDetails = await cameraService.find( { storeId: getStore[storeIndex].storeId, clientId: requestClient[clientIndex], isActivated: true, isUp: true }, { streamName: 1 } );
|
|
3108
|
+
storeList.push(
|
|
3109
|
+
{
|
|
3110
|
+
storeId: getStore[storeIndex].storeId,
|
|
3111
|
+
store: getStore[storeIndex]._id,
|
|
3112
|
+
storeName: getStore[storeIndex].storeName,
|
|
3113
|
+
active: getStore[storeIndex]?.status == 'active' ? true : false,
|
|
3114
|
+
deployedStatus: getStore[storeIndex]?.edge?.firstFile || false,
|
|
3115
|
+
edgefirstFileDate: getStore[storeIndex]?.edge?.firstFileDate || null,
|
|
3116
|
+
date: new Date( requestData.date ),
|
|
3117
|
+
processfirstFileDate: processedFileDate?.date_iso || null,
|
|
3118
|
+
daysDifference: getStore[storeIndex]?.status == 'active' ? ( dailyData.length && dailyData[0]?.stores?.daysDifference ) ? ( dailyData[0]?.stores?.daysDifference + 1 ) : 1 : dailyData[0]?.stores?.daysDifference ? dailyData[0]?.stores?.daysDifference : 0,
|
|
3119
|
+
products: productList,
|
|
3120
|
+
camera: cameraDetails.map( ( item ) => item.streamName ),
|
|
3121
|
+
cameraCount: cameraDetails.length,
|
|
3122
|
+
},
|
|
3123
|
+
);
|
|
3124
|
+
if ( storeIndex == getStore.length - 1 ) {
|
|
3125
|
+
let params = {
|
|
3126
|
+
clientId: requestClient[clientIndex],
|
|
3127
|
+
stores: storeList,
|
|
3128
|
+
dateISO: new Date( requestData.date ),
|
|
3129
|
+
accountType: getClient?.planDetails?.subscriptionType,
|
|
3130
|
+
active: getClient?.status == 'active' ? true : false,
|
|
3131
|
+
activeStores: getStore?.length,
|
|
3132
|
+
brandName: getClient?.clientName,
|
|
3133
|
+
proRate: getClient?.paymentInvoice?.proRate,
|
|
3134
|
+
dateString: dayjs( requestData.date, 'YYYY-MM-DD' ).format( 'YYYY-MM-DD' ),
|
|
3135
|
+
};
|
|
3136
|
+
await dailyPriceService.create( params );
|
|
3137
|
+
}
|
|
3138
|
+
} ).catch( ( error ) => {
|
|
3139
|
+
logger.error( { error: error, function: 'old processedDayData' } );
|
|
3140
|
+
} );
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
if ( clientIndex == requestClient.length - 1 ) {
|
|
3146
|
+
return res.sendSuccess( 'Price Details Inserted Successfully' );
|
|
3147
|
+
}
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
} catch ( e ) {
|
|
3151
|
+
logger.error( { error: e, function: 'invoiceCreate' } );
|
|
3152
|
+
return res.sendError( e, 500 );
|
|
3153
|
+
}
|
|
3154
|
+
};
|
|
3155
|
+
|
|
2902
3156
|
export const invoiceGenerate = async ( req, res ) => {
|
|
2903
3157
|
try {
|
|
2904
3158
|
// let requestData = req.body;
|
|
@@ -3145,54 +3399,38 @@ export const clientNotificationList = async ( req, res ) => {
|
|
|
3145
3399
|
let end = new Date();
|
|
3146
3400
|
end = new Date( end.getTime() - userTimezoneOffset );
|
|
3147
3401
|
end.setUTCHours( 23, 59, 59, 59 );
|
|
3148
|
-
let query
|
|
3149
|
-
|
|
3150
|
-
query
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
{
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3402
|
+
let query = {
|
|
3403
|
+
from: from,
|
|
3404
|
+
size: req.query.limit,
|
|
3405
|
+
query: {
|
|
3406
|
+
bool: {
|
|
3407
|
+
must: [
|
|
3408
|
+
...( req.user.userType === 'tango' ?
|
|
3409
|
+
[
|
|
3410
|
+
{ exists: { field: 'csmDetails' } },
|
|
3411
|
+
{ terms: { 'csmDetails.keyword': [ req.user.email ] } },
|
|
3412
|
+
] :
|
|
3413
|
+
[ { match: { clientId: req.user.clientId } } ] ),
|
|
3414
|
+
...( req.user.userType === 'tango' ?
|
|
3415
|
+
[ { match: { showNotificationTo: 'tango' } } ] :
|
|
3416
|
+
// req.user.role === 'client' && req.user.userType === 'client' ?
|
|
3417
|
+
[ { match: { showNotificationTo: req.user.role } } ]
|
|
3418
|
+
// { match: { showNotificationTo: req.user.role } },
|
|
3419
|
+
),
|
|
3420
|
+
{ match: { markasRead: false } },
|
|
3421
|
+
{ range: { date: { gte: start, lte: end } } },
|
|
3422
|
+
],
|
|
3163
3423
|
},
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
},
|
|
3170
|
-
],
|
|
3171
|
-
_source: [ 'title', 'alertCta', 'clientId', 'markasRead', 'showPushNotification', 'date', 'description' ],
|
|
3172
|
-
};
|
|
3173
|
-
} else {
|
|
3174
|
-
query = {
|
|
3175
|
-
query: {
|
|
3176
|
-
bool: {
|
|
3177
|
-
must: [
|
|
3178
|
-
{ match: { clientId: req.user.clientId } },
|
|
3179
|
-
// { match: { type: 'notification' } },
|
|
3180
|
-
{ match: { clientNotification: true } },
|
|
3181
|
-
{ match: { markasRead: false } },
|
|
3182
|
-
{ range: { date: { gte: start, lte: end } } },
|
|
3183
|
-
],
|
|
3424
|
+
},
|
|
3425
|
+
sort: [
|
|
3426
|
+
{
|
|
3427
|
+
date: {
|
|
3428
|
+
order: 'desc',
|
|
3184
3429
|
},
|
|
3185
3430
|
},
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
order: 'desc',
|
|
3190
|
-
},
|
|
3191
|
-
},
|
|
3192
|
-
],
|
|
3193
|
-
_source: [ 'title', 'alertCta', 'clientId', 'markasRead', 'showPushNotification', 'date', 'description' ],
|
|
3194
|
-
};
|
|
3195
|
-
}
|
|
3431
|
+
],
|
|
3432
|
+
// _source: [ 'title', 'alertCta', 'clientId', 'markasRead', 'showPushNotification', 'date', 'description' ],
|
|
3433
|
+
};
|
|
3196
3434
|
let result = await getOpenSearchData( appConfig.opensearch.activityLog, query );
|
|
3197
3435
|
if ( !result || !result.body.hits.hits.length ) {
|
|
3198
3436
|
return res.sendError( 'no data found', 204 );
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import model from 'tango-api-schema';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const aggregate = ( query = {} ) => {
|
|
5
|
+
return model.cameraModel.aggregate( query );
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export const find = ( query = {}, record = {} ) => {
|
|
10
|
+
return model.cameraModel.find( query, record );
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export const findOne = ( query = {}, record = {} ) => {
|
|
15
|
+
return model.cameraModel.findOne( query, record );
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export const create = ( record ) => {
|
|
20
|
+
return model.cameraModel.create( record );
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
export const updateOne = ( query, record ) => {
|
|
25
|
+
return model.cameraModel.updateOne( query, { $set: record } );
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as clientPayment from '../../services/clientPayment.services.js';
|
|
2
2
|
import { logger } from 'tango-app-api-middleware';
|
|
3
|
-
|
|
3
|
+
import { find } from '../../services/assignedStore.service.js';
|
|
4
4
|
|
|
5
5
|
export const validateClient = async ( req, res, next ) => {
|
|
6
6
|
try {
|
|
@@ -18,6 +18,10 @@ export const validateClient = async ( req, res, next ) => {
|
|
|
18
18
|
if ( !clientDetails ) {
|
|
19
19
|
return res.sendError( 'no data found', 204 );
|
|
20
20
|
}
|
|
21
|
+
let csmDetails = await find( { clientId: data } );
|
|
22
|
+
if ( csmDetails.length ) {
|
|
23
|
+
req.body.csm = csmDetails.map( ( item ) => item.userEmail );
|
|
24
|
+
}
|
|
21
25
|
req.body.client = clientDetails;
|
|
22
26
|
next();
|
|
23
27
|
} catch ( e ) {
|