@b2y/ecommerce-common 1.2.5 → 1.2.7
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.
|
@@ -33,7 +33,6 @@ const StatusMessageConstants = {
|
|
|
33
33
|
TENANT_SETTINGS_ALREADY_EXISTS: 'Tenant settings already exist for this tenant',
|
|
34
34
|
INVALID_REQUEST: 'Invalid request',
|
|
35
35
|
TENANT_SETTINGS_UPDATE_ERROR: 'Failed to update tenant settings',
|
|
36
|
-
TENANT_SETTINGS_SINGLE_LOGO_ALLOWED: "Only one logo is allowed per tenant.",
|
|
37
36
|
//Location
|
|
38
37
|
STATE_CODE_COUNTRY_CODE_REQUIRE: "State code and country code are required to fetch cities",
|
|
39
38
|
CITIES_NOT_FOUND: "No cities found for given state code",
|
|
@@ -1,352 +1,8 @@
|
|
|
1
1
|
const LocationUtility = require('../utility/LocationUtility');
|
|
2
2
|
const StatusMessage = require('../constants/StatusMessageConstants');
|
|
3
3
|
const AppUtil = require('../utility/AppUtil');
|
|
4
|
-
const SubscriptionStatusEnum = require('../enum/SubscriptionStatusEnum');
|
|
5
|
-
const AppConstants = require('../constants/AppConstants');
|
|
6
4
|
const EntityTypeEnum = require('../enum/EntityTypeEnum');
|
|
7
|
-
const updateTenant = (
|
|
8
|
-
Tenant,
|
|
9
|
-
TenantSubscription,
|
|
10
|
-
SubscriptionPlan,
|
|
11
|
-
UpdatedBy,
|
|
12
|
-
sequelize,
|
|
13
|
-
logger,
|
|
14
|
-
) => {
|
|
15
|
-
return async (req, res) => {
|
|
16
|
-
let transaction;
|
|
17
|
-
try {
|
|
18
|
-
const tenantId =
|
|
19
|
-
req.params && req.params.TenantID
|
|
20
|
-
? req.params.TenantID
|
|
21
|
-
: req.body.TenantID;
|
|
22
|
-
if (!tenantId) {
|
|
23
|
-
logger.warn("TenantID is required for update.");
|
|
24
|
-
return AppUtil.generateResponse(
|
|
25
|
-
400,
|
|
26
|
-
StatusMessage.FAILURE,
|
|
27
|
-
StatusMessage.TENANT_ID_REQUIRED_FIELD,
|
|
28
|
-
null,
|
|
29
|
-
res,
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const existing = await Tenant.findOne({ where: { TenantID: tenantId } });
|
|
34
|
-
if (!existing) {
|
|
35
|
-
logger.warn("Tenant not found with ID:", tenantId);
|
|
36
|
-
return AppUtil.generateResponse(
|
|
37
|
-
404,
|
|
38
|
-
StatusMessage.FAILURE,
|
|
39
|
-
StatusMessage.TENANT_NOT_FOUND,
|
|
40
|
-
null,
|
|
41
|
-
res,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const {
|
|
46
|
-
CompanyName,
|
|
47
|
-
CompanyCode,
|
|
48
|
-
Email,
|
|
49
|
-
PhoneNumber,
|
|
50
|
-
CountryCallingCode,
|
|
51
|
-
GSTNo,
|
|
52
|
-
CustomerPortalDomain,
|
|
53
|
-
AdminPortalDomain,
|
|
54
|
-
AddressLine,
|
|
55
|
-
CityName,
|
|
56
|
-
StateCode,
|
|
57
|
-
CountryCode,
|
|
58
|
-
Zipcode,
|
|
59
|
-
SubscriptionPlanID,
|
|
60
|
-
Status,
|
|
61
|
-
StartDate,
|
|
62
|
-
EndDate,
|
|
63
|
-
AutoRenew,
|
|
64
|
-
IsTrial,
|
|
65
|
-
GraceEndDate,
|
|
66
|
-
TrialEndDate,
|
|
67
|
-
} = req.body;
|
|
68
|
-
|
|
69
|
-
// Validate optional fields when provided
|
|
70
|
-
if (Email && !AppUtil.isValidEmail(Email)) {
|
|
71
|
-
logger.warn("Invalid email format provided for update.");
|
|
72
|
-
return AppUtil.generateResponse(
|
|
73
|
-
400,
|
|
74
|
-
StatusMessage.FAILURE,
|
|
75
|
-
StatusMessage.INVALID_EMAIL_FORMAT,
|
|
76
|
-
null,
|
|
77
|
-
res,
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (PhoneNumber && !AppUtil.isValidPhone(PhoneNumber)) {
|
|
82
|
-
logger.warn("Invalid phone number format provided for update.");
|
|
83
|
-
return AppUtil.generateResponse(
|
|
84
|
-
400,
|
|
85
|
-
StatusMessage.FAILURE,
|
|
86
|
-
StatusMessage.INVALID_PHONE_FORMAT,
|
|
87
|
-
null,
|
|
88
|
-
res,
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (CompanyCode !== undefined) {
|
|
93
|
-
if (
|
|
94
|
-
!Number.isInteger(Number(CompanyCode)) ||
|
|
95
|
-
Number(CompanyCode) <= 0
|
|
96
|
-
) {
|
|
97
|
-
logger.warn("Invalid company code provided for update.");
|
|
98
|
-
return AppUtil.generateResponse(
|
|
99
|
-
400,
|
|
100
|
-
StatusMessage.FAILURE,
|
|
101
|
-
StatusMessage.INVALID_COMPANY_CODE,
|
|
102
|
-
null,
|
|
103
|
-
res,
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Validate country code, state code and city name
|
|
109
|
-
if (CountryCode && StateCode && CityName && CountryCallingCode) {
|
|
110
|
-
const validation = await LocationUtility.validateCountryAndState(
|
|
111
|
-
CountryCode,
|
|
112
|
-
StateCode,
|
|
113
|
-
CityName,
|
|
114
|
-
CountryCallingCode,
|
|
115
|
-
logger,
|
|
116
|
-
);
|
|
117
|
-
if (!validation.isValid) {
|
|
118
|
-
return AppUtil.generateResponse(
|
|
119
|
-
400,
|
|
120
|
-
StatusMessage.FAILURE,
|
|
121
|
-
validation.error,
|
|
122
|
-
null,
|
|
123
|
-
res,
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (Status && !Object.values(SubscriptionStatusEnum).includes(Status)) {
|
|
128
|
-
logger.warn("Invalid Subscription status");
|
|
129
|
-
return AppUtil.generateResponse(
|
|
130
|
-
400,
|
|
131
|
-
StatusMessage.FAILURE,
|
|
132
|
-
StatusMessage.INVALID_SUBSCRIPTION_STATUS,
|
|
133
|
-
null,
|
|
134
|
-
res,
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
AutoRenew !== undefined &&
|
|
140
|
-
typeof AutoRenew !== AppConstants.BOOLEAN
|
|
141
|
-
) {
|
|
142
|
-
logger.warn("AutoRenew must be boolean type");
|
|
143
|
-
return AppUtil.generateResponse(
|
|
144
|
-
400,
|
|
145
|
-
StatusMessage.FAILURE,
|
|
146
|
-
StatusMessage.INVALID_BOOLEAN_TYPE.replace("{field}", "AutoRenew"),
|
|
147
|
-
null,
|
|
148
|
-
res,
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
if (IsTrial !== undefined && typeof IsTrial !== AppConstants.BOOLEAN) {
|
|
152
|
-
logger.warn("IsTrial must be boolean type");
|
|
153
|
-
return AppUtil.generateResponse(
|
|
154
|
-
400,
|
|
155
|
-
StatusMessage.FAILURE,
|
|
156
|
-
StatusMessage.INVALID_BOOLEAN_TYPE.replace("{field}", "IsTrial"),
|
|
157
|
-
null,
|
|
158
|
-
res,
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
transaction = await sequelize.transaction();
|
|
162
|
-
if (SubscriptionPlanID) {
|
|
163
|
-
const subscriptionPlan = await SubscriptionPlan.findOne({
|
|
164
|
-
where: {
|
|
165
|
-
SubscriptionPlanID,
|
|
166
|
-
IsActive: true,
|
|
167
|
-
},
|
|
168
|
-
transaction,
|
|
169
|
-
});
|
|
170
|
-
if (!subscriptionPlan) {
|
|
171
|
-
await transaction.rollback();
|
|
172
|
-
logger.warn("subscription plan not found");
|
|
173
|
-
return AppUtil.generateResponse(
|
|
174
|
-
404,
|
|
175
|
-
StatusMessage.FAILURE,
|
|
176
|
-
StatusMessage.SUBSCRIPTION_PLAN_NOT_FOUND,
|
|
177
|
-
null,
|
|
178
|
-
res,
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
// Build update payload only with provided fields
|
|
183
|
-
const updatePayload = {};
|
|
184
|
-
const fields = {
|
|
185
|
-
CompanyName,
|
|
186
|
-
CompanyCode,
|
|
187
|
-
Email,
|
|
188
|
-
PhoneNumber,
|
|
189
|
-
CountryCode,
|
|
190
|
-
GSTNo,
|
|
191
|
-
CustomerPortalDomain,
|
|
192
|
-
AdminPortalDomain,
|
|
193
|
-
AddressLine,
|
|
194
|
-
CityName,
|
|
195
|
-
StateCode,
|
|
196
|
-
CountryCallingCode,
|
|
197
|
-
Zipcode,
|
|
198
|
-
};
|
|
199
|
-
Object.keys(fields).forEach((k) => {
|
|
200
|
-
if (fields[k] !== undefined)
|
|
201
|
-
updatePayload[k] =
|
|
202
|
-
k === AppConstants.COMPANY_CODE ? Number(fields[k]) : fields[k];
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
updatePayload.UpdatedBy =
|
|
206
|
-
UpdatedBy;
|
|
207
|
-
updatePayload.UpdatedAt = new Date();
|
|
208
|
-
|
|
209
|
-
await existing.update(updatePayload, { transaction });
|
|
210
|
-
|
|
211
|
-
// update subscription
|
|
212
|
-
const updateSubscriptionPayload = {};
|
|
213
|
-
const updateSubscriptionfields = {
|
|
214
|
-
SubscriptionPlanID,
|
|
215
|
-
Status,
|
|
216
|
-
StartDate,
|
|
217
|
-
EndDate,
|
|
218
|
-
GraceEndDate,
|
|
219
|
-
TrialEndDate,
|
|
220
|
-
IsTrial,
|
|
221
|
-
AutoRenew,
|
|
222
|
-
};
|
|
223
|
-
Object.keys(updateSubscriptionfields).forEach((k) => {
|
|
224
|
-
if (updateSubscriptionfields[k] !== undefined)
|
|
225
|
-
updateSubscriptionPayload[k] = updateSubscriptionfields[k];
|
|
226
|
-
});
|
|
227
|
-
if (Object.keys(updateSubscriptionPayload).length !== 0) {
|
|
228
|
-
updateSubscriptionPayload.UpdatedBy = UpdatedBy;
|
|
229
|
-
updateSubscriptionPayload.UpdatedAt = new Date();
|
|
230
5
|
|
|
231
|
-
// find the existing subscription
|
|
232
|
-
const tenantSubscription = await TenantSubscription.findOne({
|
|
233
|
-
where: {
|
|
234
|
-
TenantID: tenantId,
|
|
235
|
-
},
|
|
236
|
-
transaction,
|
|
237
|
-
});
|
|
238
|
-
if (tenantSubscription) {
|
|
239
|
-
await tenantSubscription.update(updateSubscriptionPayload, {
|
|
240
|
-
transaction,
|
|
241
|
-
});
|
|
242
|
-
} else {
|
|
243
|
-
await TenantSubscription.create(
|
|
244
|
-
{
|
|
245
|
-
TenantID: tenantId,
|
|
246
|
-
...updateSubscriptionPayload,
|
|
247
|
-
CreatedBy:UpdatedBy,
|
|
248
|
-
UpdatedBy: UpdatedBy,
|
|
249
|
-
CreatedAt: new Date(),
|
|
250
|
-
UpdatedAt: new Date()
|
|
251
|
-
},
|
|
252
|
-
{ transaction },
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
await transaction.commit();
|
|
257
|
-
|
|
258
|
-
logger.info("Tenant updated successfully with ID:", tenantId);
|
|
259
|
-
return AppUtil.generateResponse(
|
|
260
|
-
200,
|
|
261
|
-
StatusMessage.SUCCESS,
|
|
262
|
-
StatusMessage.TENANT_UPDATED_SUCCESS,
|
|
263
|
-
null,
|
|
264
|
-
res,
|
|
265
|
-
);
|
|
266
|
-
} catch (error) {
|
|
267
|
-
if (transaction) await transaction.rollback();
|
|
268
|
-
|
|
269
|
-
if (error.name === "SequelizeUniqueConstraintError") {
|
|
270
|
-
const detail = error.original?.detail || "";
|
|
271
|
-
if (detail.includes(AppConstants.COMPANY_NAME)) {
|
|
272
|
-
return AppUtil.generateResponse(
|
|
273
|
-
400,
|
|
274
|
-
StatusMessage.FAILURE,
|
|
275
|
-
StatusMessage.COMPANY_NAME_EXISTS,
|
|
276
|
-
null,
|
|
277
|
-
res,
|
|
278
|
-
);
|
|
279
|
-
} else if (detail.includes(AppConstants.COMPANY_CODE)) {
|
|
280
|
-
return AppUtil.generateResponse(
|
|
281
|
-
400,
|
|
282
|
-
StatusMessage.FAILURE,
|
|
283
|
-
StatusMessage.COMPANY_CODE_EXISTS,
|
|
284
|
-
null,
|
|
285
|
-
res,
|
|
286
|
-
);
|
|
287
|
-
} else if (detail.includes(AppConstants.EMAIL)) {
|
|
288
|
-
return AppUtil.generateResponse(
|
|
289
|
-
400,
|
|
290
|
-
StatusMessage.FAILURE,
|
|
291
|
-
StatusMessage.EMAIL_EXISTS,
|
|
292
|
-
null,
|
|
293
|
-
res,
|
|
294
|
-
);
|
|
295
|
-
} else if (detail.includes(AppConstants.PHONE_NUMBER)) {
|
|
296
|
-
return AppUtil.generateResponse(
|
|
297
|
-
400,
|
|
298
|
-
StatusMessage.FAILURE,
|
|
299
|
-
StatusMessage.PHONE_NUMBER_EXISTS,
|
|
300
|
-
null,
|
|
301
|
-
res,
|
|
302
|
-
);
|
|
303
|
-
} else if (detail.includes(AppConstants.CUSTOMER_PORTAL_DOMAIN)) {
|
|
304
|
-
return AppUtil.generateResponse(
|
|
305
|
-
400,
|
|
306
|
-
StatusMessage.FAILURE,
|
|
307
|
-
StatusMessage.CUSTOMER_PORTAL_DOMAIN_EXISTS,
|
|
308
|
-
null,
|
|
309
|
-
res,
|
|
310
|
-
);
|
|
311
|
-
} else if (detail.includes(AppConstants.ADMIN_PORTAL_DOMAIN)) {
|
|
312
|
-
return AppUtil.generateResponse(
|
|
313
|
-
400,
|
|
314
|
-
StatusMessage.FAILURE,
|
|
315
|
-
StatusMessage.ADMIN_PORTAL_DOMAIN_EXISTS,
|
|
316
|
-
null,
|
|
317
|
-
res,
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
return AppUtil.generateResponse(
|
|
321
|
-
400,
|
|
322
|
-
StatusMessage.FAILURE,
|
|
323
|
-
StatusMessage.TENANT_ALREADY_EXISTS,
|
|
324
|
-
null,
|
|
325
|
-
res,
|
|
326
|
-
);
|
|
327
|
-
} else if (error.name === "SequelizeValidationError") {
|
|
328
|
-
const details = error.errors.map((e) => e.message);
|
|
329
|
-
logger.warn(`Validation Error detected: ${details.join("; ")}`);
|
|
330
|
-
return AppUtil.generateResponse(
|
|
331
|
-
400,
|
|
332
|
-
StatusMessage.FAILURE,
|
|
333
|
-
StatusMessage.INVALID_REQUEST,
|
|
334
|
-
null,
|
|
335
|
-
res,
|
|
336
|
-
);
|
|
337
|
-
} else {
|
|
338
|
-
logger.error("Error in UpdateTenant:", error);
|
|
339
|
-
return AppUtil.generateResponse(
|
|
340
|
-
500,
|
|
341
|
-
StatusMessage.FAILURE,
|
|
342
|
-
StatusMessage.TENANT_UPDATE_ERROR,
|
|
343
|
-
null,
|
|
344
|
-
res,
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
};
|
|
350
6
|
|
|
351
7
|
const getTenantById = (
|
|
352
8
|
Tenant,
|
|
@@ -402,7 +58,7 @@ const getTenantById = (
|
|
|
402
58
|
{
|
|
403
59
|
model: SubscriptionPlan,
|
|
404
60
|
as: "SubscriptionPlan",
|
|
405
|
-
attributes: ["SubscriptionPlanID", "PlanName", "PlanCode"],
|
|
61
|
+
attributes: ["SubscriptionPlanID", "PlanName", "PlanCode", "BillingCycle"],
|
|
406
62
|
},
|
|
407
63
|
],
|
|
408
64
|
},
|
|
@@ -462,6 +118,7 @@ const getTenantById = (
|
|
|
462
118
|
TenantLogo: logo,
|
|
463
119
|
SubscriptionPlanID: tenant.CurrentSubscription?.SubscriptionPlan?.SubscriptionPlanID,
|
|
464
120
|
PlanName: tenant.CurrentSubscription?.SubscriptionPlan?.PlanName,
|
|
121
|
+
BillingCycle: tenant.CurrentSubscription?.SubscriptionPlan?.BillingCycle,
|
|
465
122
|
TenantSubscriptionStatus: tenant.CurrentSubscription?.Status,
|
|
466
123
|
StartDate: tenant.CurrentSubscription?.StartDate,
|
|
467
124
|
EndDate: tenant.CurrentSubscription?.EndDate,
|
|
@@ -491,5 +148,5 @@ const getTenantById = (
|
|
|
491
148
|
};
|
|
492
149
|
};
|
|
493
150
|
|
|
494
|
-
module.exports = {
|
|
151
|
+
module.exports = { getTenantById };
|
|
495
152
|
|
package/enum/AccessModeEnum.js
CHANGED
|
@@ -2,7 +2,8 @@ const AccessModeEnum = Object.freeze({
|
|
|
2
2
|
FULL: "Full",
|
|
3
3
|
READ_ONLY: "Read Only",
|
|
4
4
|
BLOCKED: "Blocked",
|
|
5
|
-
PAYMENT_REQUIRED: "Payment Required"
|
|
5
|
+
PAYMENT_REQUIRED: "Payment Required",
|
|
6
|
+
RENEW_SUBSCRIPTION: "Renew Subscription"
|
|
6
7
|
});
|
|
7
8
|
|
|
8
9
|
module.exports = AccessModeEnum;
|
package/package.json
CHANGED
|
@@ -4,25 +4,48 @@ function ResolveAccessMode(subscription) {
|
|
|
4
4
|
const now = new Date();
|
|
5
5
|
|
|
6
6
|
if (!subscription) return AccessModeEnum.BLOCKED;
|
|
7
|
+
const status = subscription.Status;
|
|
8
|
+
// paid endDate
|
|
9
|
+
const endDate = subscription.EndDate
|
|
10
|
+
? new Date(subscription.EndDate)
|
|
11
|
+
: null;
|
|
12
|
+
// paid graceEndDate
|
|
13
|
+
const graceEndDate = subscription.GraceEndDate
|
|
14
|
+
? new Date(subscription.GraceEndDate)
|
|
15
|
+
: null;
|
|
16
|
+
//trialEndDate
|
|
17
|
+
const trialEndDate = subscription.TrialEndDate
|
|
18
|
+
? new Date(subscription.TrialEndDate)
|
|
19
|
+
: null;
|
|
20
|
+
|
|
7
21
|
|
|
8
|
-
if (
|
|
22
|
+
if (status === SubscriptionStatusEnum.SUSPENDED) {
|
|
9
23
|
return AccessModeEnum.BLOCKED;
|
|
10
24
|
}
|
|
25
|
+
if(status === SubscriptionStatusEnum.EXPIRED) {
|
|
26
|
+
return AccessModeEnum.RENEW_SUBSCRIPTION;
|
|
27
|
+
}
|
|
28
|
+
// CANCELLED -> still allow till expiry
|
|
29
|
+
if(status === SubscriptionStatusEnum.CANCELLED) {
|
|
30
|
+
if (endDate && now < endDate) {
|
|
31
|
+
return AccessModeEnum.FULL;
|
|
32
|
+
}
|
|
11
33
|
|
|
34
|
+
if (graceEndDate && now <= graceEndDate) {
|
|
35
|
+
return AccessModeEnum.READ_ONLY;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return AccessModeEnum.RENEW_SUBSCRIPTION;
|
|
39
|
+
}
|
|
12
40
|
if (subscription.Status === SubscriptionStatusEnum.ACTIVE) {
|
|
41
|
+
// trial plan
|
|
13
42
|
if (subscription.IsTrial === true) {
|
|
14
|
-
const trialEndDate = subscription.TrialEndDate
|
|
15
|
-
? new Date(subscription.TrialEndDate)
|
|
16
|
-
: null;
|
|
17
43
|
if (trialEndDate && now < trialEndDate) {
|
|
18
44
|
return AccessModeEnum.FULL;
|
|
19
45
|
}
|
|
20
46
|
return AccessModeEnum.PAYMENT_REQUIRED;
|
|
21
47
|
}
|
|
22
|
-
|
|
23
|
-
const graceEndDate = subscription.GraceEndDate
|
|
24
|
-
? new Date(subscription.GraceEndDate)
|
|
25
|
-
: null;
|
|
48
|
+
// paid plan
|
|
26
49
|
// Still in the paid period
|
|
27
50
|
if (now < endDate) {
|
|
28
51
|
return AccessModeEnum.FULL;
|
|
@@ -32,7 +55,7 @@ function ResolveAccessMode(subscription) {
|
|
|
32
55
|
return AccessModeEnum.READ_ONLY;
|
|
33
56
|
}
|
|
34
57
|
// Past both EndDate and Grace Period
|
|
35
|
-
return AccessModeEnum.
|
|
58
|
+
return AccessModeEnum.RENEW_SUBSCRIPTION;
|
|
36
59
|
}
|
|
37
60
|
return AccessModeEnum.BLOCKED;
|
|
38
61
|
};
|