feat: add manual subscription finalization functionality and support for expired plan notifications
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
|
||||
import dayjs from "dayjs";
|
||||
import {
|
||||
FindPlanSuscripcionsParams,
|
||||
IPlanSuscriptionsAdapter,
|
||||
@@ -53,6 +52,11 @@ export class PlanSuscriptionsAdapterMongoose implements IPlanSuscriptionsAdapter
|
||||
lastPaymentPreferenceId: { type: String, required: false },
|
||||
lastPaymentAt: { type: Date, required: false },
|
||||
lastPaymentType: { type: String, required: false, enum: ["new", "extension", "upgrade"] },
|
||||
downgradedFromPlanId: { type: Schema.Types.ObjectId, required: false, ref: "Plan" },
|
||||
downgradedFromPlanName: { type: String, required: false },
|
||||
downgradedFromPlanCode: { type: String, required: false },
|
||||
downgradedAt: { type: Date, required: false },
|
||||
downgradeReason: { type: String, required: false, enum: ["expired"] },
|
||||
});
|
||||
|
||||
this.planSuscriptionList = model<IPlanSuscriptionDocument>("PlanSuscription", this.schema);
|
||||
@@ -89,12 +93,12 @@ export class PlanSuscriptionsAdapterMongoose implements IPlanSuscriptionsAdapter
|
||||
return null;
|
||||
}
|
||||
|
||||
const dateNow = dayjs(new Date());
|
||||
const dateEnd = dayjs(subscription.endDate);
|
||||
const dateNow = new Date();
|
||||
const dateEnd = new Date(subscription.endDate);
|
||||
|
||||
try {
|
||||
if (subscription.mpPreferenceId) {
|
||||
if (dateNow.isAfter(dateEnd)) {
|
||||
if (dateNow > dateEnd) {
|
||||
if (subscription.mpStatus == MP_SUBS_STATUS.CANCELLED) {
|
||||
subscription.mpPreferenceId = "";
|
||||
subscription.isActive = false;
|
||||
|
||||
@@ -36,6 +36,11 @@ export type CreatePlanSuscriptionParams = {
|
||||
lastPaymentPreferenceId?: string;
|
||||
lastPaymentAt?: Date;
|
||||
lastPaymentType?: LastPlanPaymentType;
|
||||
downgradedFromPlanId?: string;
|
||||
downgradedFromPlanName?: string;
|
||||
downgradedFromPlanCode?: string;
|
||||
downgradedAt?: Date;
|
||||
downgradeReason?: DowngradeReason;
|
||||
};
|
||||
|
||||
export type CancellPlanSuscriptionParams = {
|
||||
@@ -65,6 +70,7 @@ export type MPPreApprovalResponse = {
|
||||
|
||||
export type ToFreePlanParams = {
|
||||
sessionUser: string;
|
||||
downgradeReason?: DowngradeReason;
|
||||
};
|
||||
|
||||
export type ToMpParams = {
|
||||
@@ -101,6 +107,7 @@ export type VerifyPendingPlanPaymentResponse = {
|
||||
|
||||
export type LastPlanPaymentStatus = "rejected" | "failed" | "cancelled";
|
||||
export type LastPlanPaymentType = "new" | "extension" | "upgrade";
|
||||
export type DowngradeReason = "expired";
|
||||
|
||||
export interface GetSuscriptionInitPointResponse {
|
||||
init_point: string;
|
||||
@@ -137,6 +144,11 @@ export interface IPlanSuscription {
|
||||
lastPaymentPreferenceId?: string;
|
||||
lastPaymentAt?: Date;
|
||||
lastPaymentType?: LastPlanPaymentType;
|
||||
downgradedFromPlanId?: string;
|
||||
downgradedFromPlanName?: string;
|
||||
downgradedFromPlanCode?: string;
|
||||
downgradedAt?: Date;
|
||||
downgradeReason?: DowngradeReason;
|
||||
}
|
||||
|
||||
export interface ISubscriptionInfo {
|
||||
@@ -155,6 +167,11 @@ export interface ISubscriptionInfo {
|
||||
lastPaymentPreferenceId?: string;
|
||||
lastPaymentAt?: Date;
|
||||
lastPaymentType?: LastPlanPaymentType;
|
||||
downgradedFromPlanId?: string;
|
||||
downgradedFromPlanName?: string;
|
||||
downgradedFromPlanCode?: string;
|
||||
downgradedAt?: Date;
|
||||
downgradeReason?: DowngradeReason;
|
||||
}
|
||||
|
||||
export interface IPlanSuscriptionsAdapter {
|
||||
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
import axios from "axios";
|
||||
import PlansList from "../../Models/Plans/Plans";
|
||||
import dayjs from "dayjs";
|
||||
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
|
||||
import "dayjs/locale/es";
|
||||
import { isNull } from "../../helpers/IsNull";
|
||||
import { PlanFeatures } from "../Plans/Plans.interface";
|
||||
@@ -34,7 +33,6 @@ import { NotificationType } from "../../Models/SystemNotifications/SystemNotific
|
||||
import { calculateProratedUpgradeAmount } from "./PlanSubscriptions.pricing";
|
||||
|
||||
dayjs.locale("es");
|
||||
dayjs.extend(isSameOrAfter);
|
||||
|
||||
const DAY_MS = 24 * 60 * 60 * 1000;
|
||||
|
||||
@@ -195,6 +193,11 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
subscription.autoRenew = false;
|
||||
subscription.mpStatus = "";
|
||||
subscription.mpInitPoint = dashboardUrl || "";
|
||||
subscription.downgradedFromPlanId = undefined;
|
||||
subscription.downgradedFromPlanName = undefined;
|
||||
subscription.downgradedFromPlanCode = undefined;
|
||||
subscription.downgradedAt = undefined;
|
||||
subscription.downgradeReason = undefined;
|
||||
await subscription.save();
|
||||
}
|
||||
} else {
|
||||
@@ -381,6 +384,11 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
currentSubscription.lastPaymentPreferenceId = undefined;
|
||||
currentSubscription.lastPaymentAt = undefined;
|
||||
currentSubscription.lastPaymentType = undefined;
|
||||
currentSubscription.downgradedFromPlanId = undefined;
|
||||
currentSubscription.downgradedFromPlanName = undefined;
|
||||
currentSubscription.downgradedFromPlanCode = undefined;
|
||||
currentSubscription.downgradedAt = undefined;
|
||||
currentSubscription.downgradeReason = undefined;
|
||||
currentSubscription.mpInitPoint = subscriptionData.init_point;
|
||||
await currentSubscription.save();
|
||||
|
||||
@@ -409,6 +417,11 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
currentSubscription.lastPaymentPreferenceId = undefined;
|
||||
currentSubscription.lastPaymentAt = undefined;
|
||||
currentSubscription.lastPaymentType = undefined;
|
||||
currentSubscription.downgradedFromPlanId = undefined;
|
||||
currentSubscription.downgradedFromPlanName = undefined;
|
||||
currentSubscription.downgradedFromPlanCode = undefined;
|
||||
currentSubscription.downgradedAt = undefined;
|
||||
currentSubscription.downgradeReason = undefined;
|
||||
currentSubscription.mpInitPoint = subscriptionData.init_point;
|
||||
await currentSubscription.save();
|
||||
|
||||
@@ -447,6 +460,11 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
lastPaymentPreferenceId: undefined,
|
||||
lastPaymentAt: undefined,
|
||||
lastPaymentType: undefined,
|
||||
downgradedFromPlanId: undefined,
|
||||
downgradedFromPlanName: undefined,
|
||||
downgradedFromPlanCode: undefined,
|
||||
downgradedAt: undefined,
|
||||
downgradeReason: undefined,
|
||||
});
|
||||
|
||||
await NotificationsManager.sendSystemNotification({
|
||||
@@ -493,12 +511,13 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
// We just cancel it locally if not paid, or change to free plan if paid.
|
||||
}
|
||||
|
||||
const dateNow = dayjs(new Date()).endOf("day");
|
||||
const dateEnd = dayjs(subscription.endDate);
|
||||
const dateNow = new Date();
|
||||
const dateEnd = new Date(subscription.endDate);
|
||||
|
||||
if (dateNow.isSameOrAfter(dateEnd)) {
|
||||
if (dateNow > dateEnd) {
|
||||
await this.toFreePlan({
|
||||
sessionUser: data.sessionUser,
|
||||
downgradeReason: "expired",
|
||||
});
|
||||
} else {
|
||||
subscription.mpStatus = MP_SUBS_STATUS.CANCELLED;
|
||||
@@ -573,6 +592,10 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
|
||||
//console.log("guardando el plan gratuito...");
|
||||
//try {
|
||||
const downgradedFromPlan = data.downgradeReason === "expired"
|
||||
? await PlansList.plans.findOne({ _id: String(subscription.planId) })
|
||||
: null;
|
||||
|
||||
console.log("cambiando al free plan:", freePlan.id);
|
||||
subscription.planId = freePlan.id;
|
||||
subscription.mpStatus = "";
|
||||
@@ -593,6 +616,19 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
subscription.pendingPaymentPeriodEndDate = undefined;
|
||||
subscription.startDate = new Date();
|
||||
subscription.endDate = dayjs(new Date()).add(10, "years").toDate();
|
||||
if (data.downgradeReason === "expired" && downgradedFromPlan) {
|
||||
subscription.downgradedFromPlanId = String(downgradedFromPlan.id || downgradedFromPlan._id);
|
||||
subscription.downgradedFromPlanName = downgradedFromPlan.name;
|
||||
subscription.downgradedFromPlanCode = downgradedFromPlan.code;
|
||||
subscription.downgradedAt = new Date();
|
||||
subscription.downgradeReason = "expired";
|
||||
} else {
|
||||
subscription.downgradedFromPlanId = undefined;
|
||||
subscription.downgradedFromPlanName = undefined;
|
||||
subscription.downgradedFromPlanCode = undefined;
|
||||
subscription.downgradedAt = undefined;
|
||||
subscription.downgradeReason = undefined;
|
||||
}
|
||||
|
||||
await subscription.save();
|
||||
// console.log("plan gratuito guardado:", freePlan.id);
|
||||
@@ -621,6 +657,11 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
lastPaymentPreferenceId: subscription.lastPaymentPreferenceId,
|
||||
lastPaymentAt: subscription.lastPaymentAt,
|
||||
lastPaymentType: subscription.lastPaymentType,
|
||||
downgradedFromPlanId: subscription.downgradedFromPlanId,
|
||||
downgradedFromPlanName: subscription.downgradedFromPlanName,
|
||||
downgradedFromPlanCode: subscription.downgradedFromPlanCode,
|
||||
downgradedAt: subscription.downgradedAt,
|
||||
downgradeReason: subscription.downgradeReason,
|
||||
};
|
||||
|
||||
io.to(`user:${String(subscription.userId)}`).emit("suscription_status_updated", susInfo);
|
||||
@@ -637,12 +678,13 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
const dateNow = dayjs(new Date()).endOf("day");
|
||||
const dateEnd = dayjs(subscription.endDate);
|
||||
const dateNow = new Date();
|
||||
const dateEnd = new Date(subscription.endDate);
|
||||
|
||||
if (dateNow.isSameOrAfter(dateEnd) && this.shouldDowngradeExpiredSubscription(subscription)) {
|
||||
if (dateNow > dateEnd && this.shouldDowngradeExpiredSubscription(subscription)) {
|
||||
await this.toFreePlan({
|
||||
sessionUser: data.sessionUser,
|
||||
downgradeReason: "expired",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -658,12 +700,13 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
const dateNow = dayjs(new Date()).endOf("day");
|
||||
const dateEnd = dayjs(subscription.endDate);
|
||||
const dateNow = new Date();
|
||||
const dateEnd = new Date(subscription.endDate);
|
||||
|
||||
if (dateNow.isSameOrAfter(dateEnd) && this.shouldDowngradeExpiredSubscription(subscription)) {
|
||||
if (dateNow > dateEnd && this.shouldDowngradeExpiredSubscription(subscription)) {
|
||||
await this.toFreePlan({
|
||||
sessionUser: data.sessionUser,
|
||||
downgradeReason: "expired",
|
||||
});
|
||||
return this.getSubscriptionByUser(data);
|
||||
}
|
||||
@@ -701,6 +744,11 @@ class PlanSuscriptionsManager implements IPlanSuscriptionsManager {
|
||||
lastPaymentPreferenceId: subscription.lastPaymentPreferenceId,
|
||||
lastPaymentAt: subscription.lastPaymentAt,
|
||||
lastPaymentType: subscription.lastPaymentType,
|
||||
downgradedFromPlanId: subscription.downgradedFromPlanId,
|
||||
downgradedFromPlanName: subscription.downgradedFromPlanName,
|
||||
downgradedFromPlanCode: subscription.downgradedFromPlanCode,
|
||||
downgradedAt: subscription.downgradedAt,
|
||||
downgradeReason: subscription.downgradeReason,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user