@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/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -866,8 +866,10 @@ type TSubscription = {
|
|
|
866
866
|
currency: string;
|
|
867
867
|
billingCycle: "monthly" | "yearly";
|
|
868
868
|
promoCode?: string;
|
|
869
|
+
nextPromoCode?: string;
|
|
869
870
|
retry?: number;
|
|
870
871
|
status?: string;
|
|
872
|
+
billingPeriodStart: Date | string;
|
|
871
873
|
nextBillingDate: Date | string;
|
|
872
874
|
createdAt?: Date | string;
|
|
873
875
|
updatedAt?: Date | string;
|
|
@@ -904,7 +906,9 @@ declare function useSubscriptionRepo(): {
|
|
|
904
906
|
paidSeats?: number;
|
|
905
907
|
amount?: number;
|
|
906
908
|
promoCode?: string;
|
|
909
|
+
nextPromoCode?: string;
|
|
907
910
|
status?: string;
|
|
911
|
+
billingPeriodStart?: Date;
|
|
908
912
|
nextBillingDate?: Date;
|
|
909
913
|
}, session?: ClientSession) => Promise<string>;
|
|
910
914
|
getByStatus: (status?: string, limit?: number, retry?: number) => Promise<TSubscription[]>;
|
|
@@ -949,12 +953,23 @@ declare function useSubscriptionService(): {
|
|
|
949
953
|
processPaidInvoice: (invoiceId: string) => Promise<string>;
|
|
950
954
|
};
|
|
951
955
|
|
|
956
|
+
type TSubscriptionTransactionMetadata = {
|
|
957
|
+
additionalSeats?: number;
|
|
958
|
+
seats?: number;
|
|
959
|
+
paidSeats?: number;
|
|
960
|
+
plan?: string;
|
|
961
|
+
promoCode?: string;
|
|
962
|
+
nextPromoCode?: string;
|
|
963
|
+
billingPeriodStart?: Date | string;
|
|
964
|
+
nextBillingDate?: Date | string;
|
|
965
|
+
};
|
|
952
966
|
type TSubscriptionTransaction = {
|
|
953
967
|
_id?: ObjectId;
|
|
954
968
|
subscription: string | ObjectId;
|
|
955
969
|
amount: number;
|
|
956
970
|
currency: string;
|
|
957
971
|
type: "initiate" | "add-seat" | "remove-seat" | "renewal" | "promo-applied" | "promo-removed" | "promo-expired" | "promo-updated";
|
|
972
|
+
metadata?: TSubscriptionTransactionMetadata;
|
|
958
973
|
description?: string;
|
|
959
974
|
createdBy: string | ObjectId;
|
|
960
975
|
createdByName?: string;
|
package/dist/index.js
CHANGED
|
@@ -5486,6 +5486,7 @@ var schemaSubscriptionCompute = import_joi20.default.object({
|
|
|
5486
5486
|
seats: import_joi20.default.number().integer().min(1).required(),
|
|
5487
5487
|
plan: import_joi20.default.string().hex().length(24).required(),
|
|
5488
5488
|
promoCode: import_joi20.default.string().optional().allow("", null),
|
|
5489
|
+
nextPromoCode: import_joi20.default.string().optional().allow("", null),
|
|
5489
5490
|
org: import_joi20.default.string().hex().length(24).required()
|
|
5490
5491
|
});
|
|
5491
5492
|
var schemaSubscribe = import_joi20.default.object({
|
|
@@ -5504,6 +5505,7 @@ var schema2 = {
|
|
|
5504
5505
|
};
|
|
5505
5506
|
var schemaSubscription = import_joi20.default.object({
|
|
5506
5507
|
...schema2,
|
|
5508
|
+
billingPeriodStart: import_joi20.default.date().optional().allow("", null),
|
|
5507
5509
|
org: import_joi20.default.string().hex().length(24).required(),
|
|
5508
5510
|
orgName: import_joi20.default.string().optional().allow("", null),
|
|
5509
5511
|
currency: import_joi20.default.string().length(3).required(),
|
|
@@ -5550,9 +5552,11 @@ function modelSubscription(data) {
|
|
|
5550
5552
|
amount: data.amount,
|
|
5551
5553
|
currency: data.currency,
|
|
5552
5554
|
billingCycle: data.billingCycle,
|
|
5553
|
-
promoCode: data.promoCode,
|
|
5555
|
+
promoCode: data.promoCode ?? "",
|
|
5556
|
+
nextPromoCode: data.nextPromoCode ?? "",
|
|
5554
5557
|
status: data.status ?? "active",
|
|
5555
5558
|
retry: data.retry ?? 0,
|
|
5559
|
+
billingPeriodStart: data.billingPeriodStart,
|
|
5556
5560
|
nextBillingDate: data.nextBillingDate,
|
|
5557
5561
|
createdAt: data.createdAt ?? /* @__PURE__ */ new Date(),
|
|
5558
5562
|
updatedAt: data.updatedAt ?? ""
|
|
@@ -5864,7 +5868,9 @@ function useSubscriptionRepo() {
|
|
|
5864
5868
|
paidSeats: import_joi21.default.number().integer().min(0).optional(),
|
|
5865
5869
|
amount: import_joi21.default.number().positive().optional().allow(0),
|
|
5866
5870
|
promoCode: import_joi21.default.string().max(50).optional().allow("", null),
|
|
5871
|
+
nextPromoCode: import_joi21.default.string().max(50).optional().allow("", null),
|
|
5867
5872
|
status: import_joi21.default.string().valid("active", "due", "overdue", "suspended").optional().allow("", null),
|
|
5873
|
+
billingPeriodStart: import_joi21.default.date().optional().allow("", null),
|
|
5868
5874
|
nextBillingDate: import_joi21.default.date().optional().allow("", null)
|
|
5869
5875
|
});
|
|
5870
5876
|
const { error } = validation.validate(options);
|
|
@@ -6020,6 +6026,16 @@ var schemaSubscriptionTransaction = import_joi22.default.object({
|
|
|
6020
6026
|
"promo-expired",
|
|
6021
6027
|
"promo-updated"
|
|
6022
6028
|
).required(),
|
|
6029
|
+
metadata: import_joi22.default.object({
|
|
6030
|
+
additionalSeats: import_joi22.default.number().integer().min(1).optional(),
|
|
6031
|
+
seats: import_joi22.default.number().integer().min(0).optional(),
|
|
6032
|
+
paidSeats: import_joi22.default.number().integer().min(0).optional(),
|
|
6033
|
+
plan: import_joi22.default.string().hex().length(24).optional(),
|
|
6034
|
+
promoCode: import_joi22.default.string().optional().allow("", null),
|
|
6035
|
+
nextPromoCode: import_joi22.default.string().optional().allow("", null),
|
|
6036
|
+
billingPeriodStart: import_joi22.default.date().optional().allow("", null),
|
|
6037
|
+
nextBillingDate: import_joi22.default.date().optional().allow("", null)
|
|
6038
|
+
}).optional(),
|
|
6023
6039
|
description: import_joi22.default.string().optional().allow("", null),
|
|
6024
6040
|
createdBy: import_joi22.default.string().hex().length(24).required(),
|
|
6025
6041
|
createdByName: import_joi22.default.string().optional().allow("", null)
|
|
@@ -6058,6 +6074,7 @@ function modelSubscriptionTransaction(data) {
|
|
|
6058
6074
|
amount: data.amount,
|
|
6059
6075
|
currency: data.currency,
|
|
6060
6076
|
type: data.type,
|
|
6077
|
+
metadata: data.metadata ?? {},
|
|
6061
6078
|
description: data.description ?? "",
|
|
6062
6079
|
createdBy: data.createdBy,
|
|
6063
6080
|
createdByName: data.createdByName,
|
|
@@ -8563,7 +8580,8 @@ function useSubscriptionService() {
|
|
|
8563
8580
|
if (!membership) {
|
|
8564
8581
|
throw new import_utils44.BadRequestError("User is not a member of the organization.");
|
|
8565
8582
|
}
|
|
8566
|
-
const
|
|
8583
|
+
const billingPeriodStart = /* @__PURE__ */ new Date();
|
|
8584
|
+
const nextBillingDate = new Date(billingPeriodStart);
|
|
8567
8585
|
nextBillingDate.setDate(nextBillingDate.getDate() + 30);
|
|
8568
8586
|
const { subscriptionAmount, currency } = await computeFee({
|
|
8569
8587
|
seats: value.seats,
|
|
@@ -8588,6 +8606,7 @@ function useSubscriptionService() {
|
|
|
8588
8606
|
amount: subscriptionAmount,
|
|
8589
8607
|
currency,
|
|
8590
8608
|
billingCycle: plan.billingCycle,
|
|
8609
|
+
billingPeriodStart,
|
|
8591
8610
|
nextBillingDate,
|
|
8592
8611
|
promoCode: value.promoCode
|
|
8593
8612
|
},
|
|
@@ -8691,7 +8710,17 @@ function useSubscriptionService() {
|
|
|
8691
8710
|
currency,
|
|
8692
8711
|
subscription: subscription._id?.toString() ?? "",
|
|
8693
8712
|
createdBy: value.user,
|
|
8694
|
-
createdByName: `${userData.firstName} ${userData.lastName}
|
|
8713
|
+
createdByName: `${userData.firstName} ${userData.lastName}`,
|
|
8714
|
+
metadata: {
|
|
8715
|
+
additionalSeats,
|
|
8716
|
+
seats: value.seats,
|
|
8717
|
+
paidSeats,
|
|
8718
|
+
plan: value.plan ?? "",
|
|
8719
|
+
promoCode: subscription.promoCode ?? "",
|
|
8720
|
+
nextPromoCode: subscription.nextPromoCode ?? "",
|
|
8721
|
+
billingPeriodStart: subscription.billingPeriodStart,
|
|
8722
|
+
nextBillingDate: subscription.nextBillingDate
|
|
8723
|
+
}
|
|
8695
8724
|
},
|
|
8696
8725
|
session
|
|
8697
8726
|
);
|
|
@@ -8756,67 +8785,38 @@ function useSubscriptionService() {
|
|
|
8756
8785
|
});
|
|
8757
8786
|
await updateById(
|
|
8758
8787
|
subscription._id?.toString() ?? "",
|
|
8759
|
-
{
|
|
8788
|
+
{ nextPromoCode: value.promoCode ?? "" },
|
|
8760
8789
|
session
|
|
8761
8790
|
);
|
|
8762
8791
|
if (subscription.promoCode) {
|
|
8763
8792
|
await updatePromoUsageStatusByOrgId(value.org, "inactive", session);
|
|
8764
8793
|
}
|
|
8765
|
-
let description = `Promo code updated to ${value.promoCode ?? "none"}. At the time of update, ${(0, import_utils44.formatNumber)(subscription.paidSeats, {
|
|
8766
|
-
decimalPlaces: 0
|
|
8767
|
-
})} seat(s) were already included in the subscription.`;
|
|
8768
8794
|
if (promo && promo._id) {
|
|
8769
8795
|
await addPromoUsage(
|
|
8770
8796
|
{
|
|
8771
8797
|
promo: promo._id,
|
|
8772
8798
|
org: value.org,
|
|
8773
|
-
usedBy:
|
|
8799
|
+
usedBy: value.user
|
|
8774
8800
|
},
|
|
8775
8801
|
session
|
|
8776
8802
|
);
|
|
8777
|
-
const additionalDescription = `${promo.seats ? `Seats beyond ${(0, import_utils44.formatNumber)(promo.seats, {
|
|
8778
|
-
decimalPlaces: 0
|
|
8779
|
-
})} are charged at the standard rate.` : ""}`;
|
|
8780
|
-
if (promo.type === "flat") {
|
|
8781
|
-
description += ` ${(0, import_utils44.formatNumber)(promo.flatRate ?? 0, {
|
|
8782
|
-
currency,
|
|
8783
|
-
useSymbol: true
|
|
8784
|
-
})} ${promo.seats ? `limited to ${(0, import_utils44.formatNumber)(promo.seats, {
|
|
8785
|
-
decimalPlaces: 0
|
|
8786
|
-
})} seat(s)` : " for all seats"}. ${additionalDescription}`;
|
|
8787
|
-
}
|
|
8788
|
-
if (promo.type === "fixed") {
|
|
8789
|
-
description += ` ${(0, import_utils44.formatNumber)(promo.fixedRate ?? 0, {
|
|
8790
|
-
currency,
|
|
8791
|
-
useSymbol: true
|
|
8792
|
-
})} per seat${promo.seats ? `, limited to ${(0, import_utils44.formatNumber)(promo.seats, {
|
|
8793
|
-
decimalPlaces: 0
|
|
8794
|
-
})} seat(s)` : ""}. ${additionalDescription}`;
|
|
8795
|
-
}
|
|
8796
|
-
if (promo.type === "volume") {
|
|
8797
|
-
if (promo.tiers && promo.tiers.length > 0) {
|
|
8798
|
-
const tierDescriptions = promo.tiers.map((tier) => {
|
|
8799
|
-
const maxSeatsDesc = tier.maxSeats === 0 ? "and above" : `to ${(0, import_utils44.formatNumber)(tier.maxSeats, { decimalPlaces: 0 })}`;
|
|
8800
|
-
return `${(0, import_utils44.formatNumber)(tier.minSeats, {
|
|
8801
|
-
decimalPlaces: 0
|
|
8802
|
-
})} ${maxSeatsDesc} ${(0, import_utils44.formatNumber)(tier.rate, {
|
|
8803
|
-
currency,
|
|
8804
|
-
useSymbol: true
|
|
8805
|
-
})} per seat`;
|
|
8806
|
-
}).join(", ");
|
|
8807
|
-
description += ` Volume tiers, ${tierDescriptions}.`;
|
|
8808
|
-
}
|
|
8809
|
-
}
|
|
8810
8803
|
}
|
|
8811
8804
|
await addTransaction(
|
|
8812
8805
|
{
|
|
8813
8806
|
type: "promo-updated",
|
|
8814
|
-
description
|
|
8807
|
+
description: `Promo code ${value.promoCode || "removed"} scheduled to take effect on the next billing cycle.`,
|
|
8815
8808
|
amount: 0,
|
|
8816
|
-
currency,
|
|
8809
|
+
currency: subscription.currency,
|
|
8817
8810
|
subscription: subscription._id?.toString() ?? "",
|
|
8818
8811
|
createdBy: value.user,
|
|
8819
|
-
|
|
8812
|
+
metadata: {
|
|
8813
|
+
seats: subscription.seats,
|
|
8814
|
+
paidSeats: subscription.paidSeats,
|
|
8815
|
+
promoCode: subscription.promoCode,
|
|
8816
|
+
nextPromoCode: value.promoCode ?? "",
|
|
8817
|
+
billingPeriodStart: subscription.billingPeriodStart,
|
|
8818
|
+
nextBillingDate: subscription.nextBillingDate
|
|
8819
|
+
}
|
|
8820
8820
|
},
|
|
8821
8821
|
session
|
|
8822
8822
|
);
|
|
@@ -8976,39 +8976,43 @@ function useSubscriptionService() {
|
|
|
8976
8976
|
}
|
|
8977
8977
|
const ledgerBill = await getByInvoice(invoiceId);
|
|
8978
8978
|
if (!ledgerBill) {
|
|
8979
|
-
throw new import_utils44.BadRequestError(
|
|
8980
|
-
"Ledger bill not found for the given invoice ID."
|
|
8981
|
-
);
|
|
8979
|
+
throw new import_utils44.BadRequestError("Ledger bill not found.");
|
|
8982
8980
|
}
|
|
8983
8981
|
const orgId = String(ledgerBill.org);
|
|
8984
|
-
const org = await getOrgById(orgId);
|
|
8985
|
-
if (!org) {
|
|
8986
|
-
throw new import_utils44.BadRequestError("Organization not found for the ledger bill.");
|
|
8987
|
-
}
|
|
8988
8982
|
const subscription = await getByOrg(orgId);
|
|
8989
8983
|
if (!subscription) {
|
|
8990
|
-
throw new import_utils44.BadRequestError("Subscription not found
|
|
8984
|
+
throw new import_utils44.BadRequestError("Subscription not found.");
|
|
8991
8985
|
}
|
|
8992
8986
|
const plan = await getDefaultPlan();
|
|
8993
8987
|
if (!plan) {
|
|
8994
|
-
throw new import_utils44.BadRequestError("
|
|
8988
|
+
throw new import_utils44.BadRequestError("Plan not found.");
|
|
8995
8989
|
}
|
|
8996
8990
|
const session = import_utils44.useAtlas.getClient()?.startSession();
|
|
8997
8991
|
if (!session) {
|
|
8998
|
-
throw new
|
|
8992
|
+
throw new import_utils44.InternalServerError("Unable to start database session.");
|
|
8999
8993
|
}
|
|
9000
8994
|
try {
|
|
9001
8995
|
session.startTransaction();
|
|
9002
|
-
const
|
|
9003
|
-
const nextBillingDate =
|
|
8996
|
+
const billingPeriodStart = /* @__PURE__ */ new Date();
|
|
8997
|
+
const nextBillingDate = new Date(billingPeriodStart);
|
|
9004
8998
|
nextBillingDate.setMonth(nextBillingDate.getMonth() + 1);
|
|
8999
|
+
const effectivePromoCode = subscription.nextPromoCode || subscription.promoCode;
|
|
9000
|
+
const promo = effectivePromoCode ? await getPromoByCode(effectivePromoCode) : null;
|
|
9001
|
+
const monthlyAmount = computeMonthlyAmount(
|
|
9002
|
+
subscription.seats,
|
|
9003
|
+
plan.price,
|
|
9004
|
+
promo
|
|
9005
|
+
);
|
|
9005
9006
|
await updateById(
|
|
9006
|
-
|
|
9007
|
+
subscription._id?.toString() ?? "",
|
|
9007
9008
|
{
|
|
9008
9009
|
status: "active",
|
|
9010
|
+
billingPeriodStart,
|
|
9009
9011
|
nextBillingDate,
|
|
9010
9012
|
paidSeats: subscription.seats,
|
|
9011
|
-
amount:
|
|
9013
|
+
amount: Math.round(monthlyAmount * 100) / 100,
|
|
9014
|
+
promoCode: effectivePromoCode,
|
|
9015
|
+
nextPromoCode: ""
|
|
9012
9016
|
},
|
|
9013
9017
|
session
|
|
9014
9018
|
);
|
|
@@ -9019,14 +9023,7 @@ function useSubscriptionService() {
|
|
|
9019
9023
|
return "Successfully processed paid invoice.";
|
|
9020
9024
|
} catch (error2) {
|
|
9021
9025
|
await session.abortTransaction();
|
|
9022
|
-
|
|
9023
|
-
level: "error",
|
|
9024
|
-
message: `Failed to process paid invoice ${invoiceId}: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
9025
|
-
});
|
|
9026
|
-
if (error2 instanceof import_utils44.AppError) {
|
|
9027
|
-
throw error2;
|
|
9028
|
-
}
|
|
9029
|
-
throw new import_utils44.InternalServerError("Failed to process paid invoice.");
|
|
9026
|
+
throw error2;
|
|
9030
9027
|
} finally {
|
|
9031
9028
|
session.endSession();
|
|
9032
9029
|
}
|
|
@@ -9562,6 +9559,7 @@ function useOrgService() {
|
|
|
9562
9559
|
paidSeats: value.seats,
|
|
9563
9560
|
currency: plan.currency,
|
|
9564
9561
|
billingCycle: plan.billingCycle,
|
|
9562
|
+
billingPeriodStart: currentDate,
|
|
9565
9563
|
nextBillingDate
|
|
9566
9564
|
},
|
|
9567
9565
|
session
|