@goweekdays/core 2.11.12 → 2.11.13
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +64 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -67
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5435,6 +5435,7 @@ var schemaSubscriptionCompute = Joi20.object({
|
|
|
5435
5435
|
seats: Joi20.number().integer().min(1).required(),
|
|
5436
5436
|
plan: Joi20.string().hex().length(24).required(),
|
|
5437
5437
|
promoCode: Joi20.string().optional().allow("", null),
|
|
5438
|
+
nextPromoCode: Joi20.string().optional().allow("", null),
|
|
5438
5439
|
org: Joi20.string().hex().length(24).required()
|
|
5439
5440
|
});
|
|
5440
5441
|
var schemaSubscribe = Joi20.object({
|
|
@@ -5453,6 +5454,7 @@ var schema2 = {
|
|
|
5453
5454
|
};
|
|
5454
5455
|
var schemaSubscription = Joi20.object({
|
|
5455
5456
|
...schema2,
|
|
5457
|
+
billingPeriodStart: Joi20.date().optional().allow("", null),
|
|
5456
5458
|
org: Joi20.string().hex().length(24).required(),
|
|
5457
5459
|
orgName: Joi20.string().optional().allow("", null),
|
|
5458
5460
|
currency: Joi20.string().length(3).required(),
|
|
@@ -5499,9 +5501,11 @@ function modelSubscription(data) {
|
|
|
5499
5501
|
amount: data.amount,
|
|
5500
5502
|
currency: data.currency,
|
|
5501
5503
|
billingCycle: data.billingCycle,
|
|
5502
|
-
promoCode: data.promoCode,
|
|
5504
|
+
promoCode: data.promoCode ?? "",
|
|
5505
|
+
nextPromoCode: data.nextPromoCode ?? "",
|
|
5503
5506
|
status: data.status ?? "active",
|
|
5504
5507
|
retry: data.retry ?? 0,
|
|
5508
|
+
billingPeriodStart: data.billingPeriodStart,
|
|
5505
5509
|
nextBillingDate: data.nextBillingDate,
|
|
5506
5510
|
createdAt: data.createdAt ?? /* @__PURE__ */ new Date(),
|
|
5507
5511
|
updatedAt: data.updatedAt ?? ""
|
|
@@ -5822,7 +5826,9 @@ function useSubscriptionRepo() {
|
|
|
5822
5826
|
paidSeats: Joi21.number().integer().min(0).optional(),
|
|
5823
5827
|
amount: Joi21.number().positive().optional().allow(0),
|
|
5824
5828
|
promoCode: Joi21.string().max(50).optional().allow("", null),
|
|
5829
|
+
nextPromoCode: Joi21.string().max(50).optional().allow("", null),
|
|
5825
5830
|
status: Joi21.string().valid("active", "due", "overdue", "suspended").optional().allow("", null),
|
|
5831
|
+
billingPeriodStart: Joi21.date().optional().allow("", null),
|
|
5826
5832
|
nextBillingDate: Joi21.date().optional().allow("", null)
|
|
5827
5833
|
});
|
|
5828
5834
|
const { error } = validation.validate(options);
|
|
@@ -5958,7 +5964,6 @@ import { BadRequestError as BadRequestError42 } from "@goweekdays/utils";
|
|
|
5958
5964
|
import {
|
|
5959
5965
|
AppError as AppError20,
|
|
5960
5966
|
BadRequestError as BadRequestError41,
|
|
5961
|
-
formatNumber,
|
|
5962
5967
|
InternalServerError as InternalServerError22,
|
|
5963
5968
|
logger as logger23,
|
|
5964
5969
|
useAtlas as useAtlas18
|
|
@@ -5993,6 +5998,16 @@ var schemaSubscriptionTransaction = Joi22.object({
|
|
|
5993
5998
|
"promo-expired",
|
|
5994
5999
|
"promo-updated"
|
|
5995
6000
|
).required(),
|
|
6001
|
+
metadata: Joi22.object({
|
|
6002
|
+
additionalSeats: Joi22.number().integer().min(1).optional(),
|
|
6003
|
+
seats: Joi22.number().integer().min(0).optional(),
|
|
6004
|
+
paidSeats: Joi22.number().integer().min(0).optional(),
|
|
6005
|
+
plan: Joi22.string().hex().length(24).optional(),
|
|
6006
|
+
promoCode: Joi22.string().optional().allow("", null),
|
|
6007
|
+
nextPromoCode: Joi22.string().optional().allow("", null),
|
|
6008
|
+
billingPeriodStart: Joi22.date().optional().allow("", null),
|
|
6009
|
+
nextBillingDate: Joi22.date().optional().allow("", null)
|
|
6010
|
+
}).optional(),
|
|
5996
6011
|
description: Joi22.string().optional().allow("", null),
|
|
5997
6012
|
createdBy: Joi22.string().hex().length(24).required(),
|
|
5998
6013
|
createdByName: Joi22.string().optional().allow("", null)
|
|
@@ -6031,6 +6046,7 @@ function modelSubscriptionTransaction(data) {
|
|
|
6031
6046
|
amount: data.amount,
|
|
6032
6047
|
currency: data.currency,
|
|
6033
6048
|
type: data.type,
|
|
6049
|
+
metadata: data.metadata ?? {},
|
|
6034
6050
|
description: data.description ?? "",
|
|
6035
6051
|
createdBy: data.createdBy,
|
|
6036
6052
|
createdByName: data.createdByName,
|
|
@@ -8583,7 +8599,8 @@ function useSubscriptionService() {
|
|
|
8583
8599
|
if (!membership) {
|
|
8584
8600
|
throw new BadRequestError41("User is not a member of the organization.");
|
|
8585
8601
|
}
|
|
8586
|
-
const
|
|
8602
|
+
const billingPeriodStart = /* @__PURE__ */ new Date();
|
|
8603
|
+
const nextBillingDate = new Date(billingPeriodStart);
|
|
8587
8604
|
nextBillingDate.setDate(nextBillingDate.getDate() + 30);
|
|
8588
8605
|
const { subscriptionAmount, currency } = await computeFee({
|
|
8589
8606
|
seats: value.seats,
|
|
@@ -8608,6 +8625,7 @@ function useSubscriptionService() {
|
|
|
8608
8625
|
amount: subscriptionAmount,
|
|
8609
8626
|
currency,
|
|
8610
8627
|
billingCycle: plan.billingCycle,
|
|
8628
|
+
billingPeriodStart,
|
|
8611
8629
|
nextBillingDate,
|
|
8612
8630
|
promoCode: value.promoCode
|
|
8613
8631
|
},
|
|
@@ -8711,7 +8729,17 @@ function useSubscriptionService() {
|
|
|
8711
8729
|
currency,
|
|
8712
8730
|
subscription: subscription._id?.toString() ?? "",
|
|
8713
8731
|
createdBy: value.user,
|
|
8714
|
-
createdByName: `${userData.firstName} ${userData.lastName}
|
|
8732
|
+
createdByName: `${userData.firstName} ${userData.lastName}`,
|
|
8733
|
+
metadata: {
|
|
8734
|
+
additionalSeats,
|
|
8735
|
+
seats: value.seats,
|
|
8736
|
+
paidSeats,
|
|
8737
|
+
plan: value.plan ?? "",
|
|
8738
|
+
promoCode: subscription.promoCode ?? "",
|
|
8739
|
+
nextPromoCode: subscription.nextPromoCode ?? "",
|
|
8740
|
+
billingPeriodStart: subscription.billingPeriodStart,
|
|
8741
|
+
nextBillingDate: subscription.nextBillingDate
|
|
8742
|
+
}
|
|
8715
8743
|
},
|
|
8716
8744
|
session
|
|
8717
8745
|
);
|
|
@@ -8776,67 +8804,38 @@ function useSubscriptionService() {
|
|
|
8776
8804
|
});
|
|
8777
8805
|
await updateById(
|
|
8778
8806
|
subscription._id?.toString() ?? "",
|
|
8779
|
-
{
|
|
8807
|
+
{ nextPromoCode: value.promoCode ?? "" },
|
|
8780
8808
|
session
|
|
8781
8809
|
);
|
|
8782
8810
|
if (subscription.promoCode) {
|
|
8783
8811
|
await updatePromoUsageStatusByOrgId(value.org, "inactive", session);
|
|
8784
8812
|
}
|
|
8785
|
-
let description = `Promo code updated to ${value.promoCode ?? "none"}. At the time of update, ${formatNumber(subscription.paidSeats, {
|
|
8786
|
-
decimalPlaces: 0
|
|
8787
|
-
})} seat(s) were already included in the subscription.`;
|
|
8788
8813
|
if (promo && promo._id) {
|
|
8789
8814
|
await addPromoUsage(
|
|
8790
8815
|
{
|
|
8791
8816
|
promo: promo._id,
|
|
8792
8817
|
org: value.org,
|
|
8793
|
-
usedBy:
|
|
8818
|
+
usedBy: value.user
|
|
8794
8819
|
},
|
|
8795
8820
|
session
|
|
8796
8821
|
);
|
|
8797
|
-
const additionalDescription = `${promo.seats ? `Seats beyond ${formatNumber(promo.seats, {
|
|
8798
|
-
decimalPlaces: 0
|
|
8799
|
-
})} are charged at the standard rate.` : ""}`;
|
|
8800
|
-
if (promo.type === "flat") {
|
|
8801
|
-
description += ` ${formatNumber(promo.flatRate ?? 0, {
|
|
8802
|
-
currency,
|
|
8803
|
-
useSymbol: true
|
|
8804
|
-
})} ${promo.seats ? `limited to ${formatNumber(promo.seats, {
|
|
8805
|
-
decimalPlaces: 0
|
|
8806
|
-
})} seat(s)` : " for all seats"}. ${additionalDescription}`;
|
|
8807
|
-
}
|
|
8808
|
-
if (promo.type === "fixed") {
|
|
8809
|
-
description += ` ${formatNumber(promo.fixedRate ?? 0, {
|
|
8810
|
-
currency,
|
|
8811
|
-
useSymbol: true
|
|
8812
|
-
})} per seat${promo.seats ? `, limited to ${formatNumber(promo.seats, {
|
|
8813
|
-
decimalPlaces: 0
|
|
8814
|
-
})} seat(s)` : ""}. ${additionalDescription}`;
|
|
8815
|
-
}
|
|
8816
|
-
if (promo.type === "volume") {
|
|
8817
|
-
if (promo.tiers && promo.tiers.length > 0) {
|
|
8818
|
-
const tierDescriptions = promo.tiers.map((tier) => {
|
|
8819
|
-
const maxSeatsDesc = tier.maxSeats === 0 ? "and above" : `to ${formatNumber(tier.maxSeats, { decimalPlaces: 0 })}`;
|
|
8820
|
-
return `${formatNumber(tier.minSeats, {
|
|
8821
|
-
decimalPlaces: 0
|
|
8822
|
-
})} ${maxSeatsDesc} ${formatNumber(tier.rate, {
|
|
8823
|
-
currency,
|
|
8824
|
-
useSymbol: true
|
|
8825
|
-
})} per seat`;
|
|
8826
|
-
}).join(", ");
|
|
8827
|
-
description += ` Volume tiers, ${tierDescriptions}.`;
|
|
8828
|
-
}
|
|
8829
|
-
}
|
|
8830
8822
|
}
|
|
8831
8823
|
await addTransaction(
|
|
8832
8824
|
{
|
|
8833
8825
|
type: "promo-updated",
|
|
8834
|
-
description
|
|
8826
|
+
description: `Promo code ${value.promoCode || "removed"} scheduled to take effect on the next billing cycle.`,
|
|
8835
8827
|
amount: 0,
|
|
8836
|
-
currency,
|
|
8828
|
+
currency: subscription.currency,
|
|
8837
8829
|
subscription: subscription._id?.toString() ?? "",
|
|
8838
8830
|
createdBy: value.user,
|
|
8839
|
-
|
|
8831
|
+
metadata: {
|
|
8832
|
+
seats: subscription.seats,
|
|
8833
|
+
paidSeats: subscription.paidSeats,
|
|
8834
|
+
promoCode: subscription.promoCode,
|
|
8835
|
+
nextPromoCode: value.promoCode ?? "",
|
|
8836
|
+
billingPeriodStart: subscription.billingPeriodStart,
|
|
8837
|
+
nextBillingDate: subscription.nextBillingDate
|
|
8838
|
+
}
|
|
8840
8839
|
},
|
|
8841
8840
|
session
|
|
8842
8841
|
);
|
|
@@ -8996,39 +8995,43 @@ function useSubscriptionService() {
|
|
|
8996
8995
|
}
|
|
8997
8996
|
const ledgerBill = await getByInvoice(invoiceId);
|
|
8998
8997
|
if (!ledgerBill) {
|
|
8999
|
-
throw new BadRequestError41(
|
|
9000
|
-
"Ledger bill not found for the given invoice ID."
|
|
9001
|
-
);
|
|
8998
|
+
throw new BadRequestError41("Ledger bill not found.");
|
|
9002
8999
|
}
|
|
9003
9000
|
const orgId = String(ledgerBill.org);
|
|
9004
|
-
const org = await getOrgById(orgId);
|
|
9005
|
-
if (!org) {
|
|
9006
|
-
throw new BadRequestError41("Organization not found for the ledger bill.");
|
|
9007
|
-
}
|
|
9008
9001
|
const subscription = await getByOrg(orgId);
|
|
9009
9002
|
if (!subscription) {
|
|
9010
|
-
throw new BadRequestError41("Subscription not found
|
|
9003
|
+
throw new BadRequestError41("Subscription not found.");
|
|
9011
9004
|
}
|
|
9012
9005
|
const plan = await getDefaultPlan();
|
|
9013
9006
|
if (!plan) {
|
|
9014
|
-
throw new BadRequestError41("
|
|
9007
|
+
throw new BadRequestError41("Plan not found.");
|
|
9015
9008
|
}
|
|
9016
9009
|
const session = useAtlas18.getClient()?.startSession();
|
|
9017
9010
|
if (!session) {
|
|
9018
|
-
throw new
|
|
9011
|
+
throw new InternalServerError22("Unable to start database session.");
|
|
9019
9012
|
}
|
|
9020
9013
|
try {
|
|
9021
9014
|
session.startTransaction();
|
|
9022
|
-
const
|
|
9023
|
-
const nextBillingDate =
|
|
9015
|
+
const billingPeriodStart = /* @__PURE__ */ new Date();
|
|
9016
|
+
const nextBillingDate = new Date(billingPeriodStart);
|
|
9024
9017
|
nextBillingDate.setMonth(nextBillingDate.getMonth() + 1);
|
|
9018
|
+
const effectivePromoCode = subscription.nextPromoCode || subscription.promoCode;
|
|
9019
|
+
const promo = effectivePromoCode ? await getPromoByCode(effectivePromoCode) : null;
|
|
9020
|
+
const monthlyAmount = computeMonthlyAmount(
|
|
9021
|
+
subscription.seats,
|
|
9022
|
+
plan.price,
|
|
9023
|
+
promo
|
|
9024
|
+
);
|
|
9025
9025
|
await updateById(
|
|
9026
|
-
|
|
9026
|
+
subscription._id?.toString() ?? "",
|
|
9027
9027
|
{
|
|
9028
9028
|
status: "active",
|
|
9029
|
+
billingPeriodStart,
|
|
9029
9030
|
nextBillingDate,
|
|
9030
9031
|
paidSeats: subscription.seats,
|
|
9031
|
-
amount:
|
|
9032
|
+
amount: Math.round(monthlyAmount * 100) / 100,
|
|
9033
|
+
promoCode: effectivePromoCode,
|
|
9034
|
+
nextPromoCode: ""
|
|
9032
9035
|
},
|
|
9033
9036
|
session
|
|
9034
9037
|
);
|
|
@@ -9039,14 +9042,7 @@ function useSubscriptionService() {
|
|
|
9039
9042
|
return "Successfully processed paid invoice.";
|
|
9040
9043
|
} catch (error2) {
|
|
9041
9044
|
await session.abortTransaction();
|
|
9042
|
-
|
|
9043
|
-
level: "error",
|
|
9044
|
-
message: `Failed to process paid invoice ${invoiceId}: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
9045
|
-
});
|
|
9046
|
-
if (error2 instanceof AppError20) {
|
|
9047
|
-
throw error2;
|
|
9048
|
-
}
|
|
9049
|
-
throw new InternalServerError22("Failed to process paid invoice.");
|
|
9045
|
+
throw error2;
|
|
9050
9046
|
} finally {
|
|
9051
9047
|
session.endSession();
|
|
9052
9048
|
}
|
|
@@ -9586,6 +9582,7 @@ function useOrgService() {
|
|
|
9586
9582
|
paidSeats: value.seats,
|
|
9587
9583
|
currency: plan.currency,
|
|
9588
9584
|
billingCycle: plan.billingCycle,
|
|
9585
|
+
billingPeriodStart: currentDate,
|
|
9589
9586
|
nextBillingDate
|
|
9590
9587
|
},
|
|
9591
9588
|
session
|