import dayjs from "dayjs"; import { FindPlanSuscripcionsParams, IPlanSuscriptionsAdapter, IPlanSuscription, CreatePlanSuscriptionParams, CancellPlanSuscriptionParams, } from "./PlanSubscriptions.interface"; import { Document, Model, Schema, model } from "mongoose"; export interface IPlanSuscriptionDocument extends Omit, Document {} export enum MP_SUBS_STATUS { PENDING = "pending", AUTHORIZED = "authorized", PAUSED = "paused", CANCELLED = "cancelled", } export class PlanSuscriptionsAdapterMongoose implements IPlanSuscriptionsAdapter { schema: Schema; planSuscriptionList: Model; constructor() { this.schema = new Schema({ userId: { type: Schema.Types.ObjectId, required: true, ref: "User" }, planId: { type: Schema.Types.ObjectId, required: true, ref: "Plan" }, mpPlanId: { type: String, required: false }, startDate: { type: Date, required: true }, endDate: { type: Date, required: true }, isActive: { type: Boolean, required: true, default: true }, autoRenew: { type: Boolean, required: true, default: true }, paymentMethod: { type: String, required: false }, mpPayerId: { type: Number, required: false }, mpPayerEmail: { type: String, required: false }, mpStatus: { type: String, required: false }, mpDateCreated: { type: Date, required: false }, mpInitPoint: { type: String, required: false }, mpPreferenceId: { type: String, required: false }, }); this.planSuscriptionList = model("PlanSuscription", this.schema); } public async find(filters: FindPlanSuscripcionsParams): Promise { return this.planSuscriptionList.find(filters).exec(); } public async delete(data: CancellPlanSuscriptionParams): Promise { await this.planSuscriptionList.deleteOne({ userId: data.sessionUser }).exec(); } public async findOne( filters: FindPlanSuscripcionsParams ): Promise { let subscription = await this.planSuscriptionList .findOne({ userId: filters.sessionUser }) .exec(); if (!subscription) { return null; } const dateNow = dayjs(new Date()); const dateEnd = dayjs(subscription.endDate); try { if (subscription.mpPreferenceId) { if (dateNow.isAfter(dateEnd)) { if (subscription.mpStatus == MP_SUBS_STATUS.CANCELLED) { subscription.mpPreferenceId = ""; subscription.isActive = false; subscription.autoRenew = false; subscription.mpStatus = MP_SUBS_STATUS.CANCELLED; subscription.mpInitPoint = ""; await subscription.save(); return subscription; } // Without subscriptions, we wait for the webhook to update the status. // If it's expired and not updated by webhook, we just cancel it. if (subscription.mpStatus === MP_SUBS_STATUS.PENDING) { subscription.mpPreferenceId = ""; subscription.isActive = false; subscription.autoRenew = false; subscription.mpStatus = MP_SUBS_STATUS.CANCELLED; subscription.mpInitPoint = ""; await subscription.save(); return subscription; } } } } catch (e) { console.log("Ha ocurrido un error al revisar el estado de la suscripcion:", e); } return subscription; } // updateMpStatus was removed as it relied on MercadoPago Subscriptions API. // Payments status updates are now handled by the WebhookController. public async create(data: CreatePlanSuscriptionParams): Promise { return await this.planSuscriptionList.create(data); } }