156 lines
5.7 KiB
TypeScript
156 lines
5.7 KiB
TypeScript
import { Document, Model, Schema, model } from "mongoose";
|
|
import {
|
|
CreatePlanUsageCycleParams,
|
|
FindPlanUsageCycleParams,
|
|
IPlanUsageCycle,
|
|
IPlanUsageCycleAdapter,
|
|
UpdatePlanUsageCycleParams,
|
|
} from "./PlanUsageCycle.Interface";
|
|
|
|
export interface IPlanUsageCycleDocument extends Omit<IPlanUsageCycle, "id">, Document {}
|
|
|
|
export class PlanUsageCycleAdapterMongoose implements IPlanUsageCycleAdapter {
|
|
schema: Schema;
|
|
planUsageCycleList: Model<IPlanUsageCycleDocument>;
|
|
|
|
constructor() {
|
|
this.schema = new Schema({
|
|
userId: { type: Schema.Types.ObjectId, required: true, ref: "User" },
|
|
subscriptionId: { type: Schema.Types.ObjectId, required: false, ref: "PlanSuscription" },
|
|
planId: { type: Schema.Types.ObjectId, required: true, ref: "Plan" },
|
|
cycleStart: { type: Date, required: true },
|
|
cycleEnd: { type: Date, required: true },
|
|
appointmentsCount: { type: Number, required: true, default: 0 },
|
|
creationDate: { type: Date, required: true, default: Date.now },
|
|
updateDate: { type: Date, required: true, default: Date.now },
|
|
});
|
|
|
|
this.schema.index({ userId: 1, subscriptionId: 1, planId: 1, cycleStart: 1 }, { unique: true });
|
|
|
|
this.planUsageCycleList = model<IPlanUsageCycleDocument>("PlanUsageCycle", this.schema);
|
|
}
|
|
|
|
public async findOne(filters: FindPlanUsageCycleParams): Promise<IPlanUsageCycleDocument | null> {
|
|
return await this.planUsageCycleList.findOne(filters);
|
|
}
|
|
|
|
public async create(data: CreatePlanUsageCycleParams): Promise<IPlanUsageCycleDocument> {
|
|
return await this.planUsageCycleList.create({
|
|
...data,
|
|
appointmentsCount: data.appointmentsCount || 0,
|
|
updateDate: new Date(),
|
|
});
|
|
}
|
|
|
|
public async getOrCreateCurrent(data: UpdatePlanUsageCycleParams): Promise<IPlanUsageCycleDocument> {
|
|
const now = new Date();
|
|
return await this.planUsageCycleList.findOneAndUpdate(
|
|
{
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
},
|
|
{
|
|
$setOnInsert: {
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
cycleEnd: data.cycleEnd,
|
|
appointmentsCount: 0,
|
|
creationDate: now,
|
|
},
|
|
$set: { updateDate: now },
|
|
},
|
|
{ new: true, upsert: true }
|
|
);
|
|
}
|
|
|
|
public async incrementAppointments(
|
|
data: UpdatePlanUsageCycleParams & { quantity: number }
|
|
): Promise<IPlanUsageCycleDocument | null> {
|
|
const now = new Date();
|
|
return await this.planUsageCycleList.findOneAndUpdate(
|
|
{
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
},
|
|
{
|
|
$setOnInsert: {
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
cycleEnd: data.cycleEnd,
|
|
appointmentsCount: 0,
|
|
creationDate: now,
|
|
},
|
|
$inc: { appointmentsCount: data.quantity },
|
|
$set: { updateDate: now },
|
|
},
|
|
{ new: true, upsert: true }
|
|
);
|
|
}
|
|
|
|
public async incrementAppointmentsIfWithinLimit(
|
|
data: UpdatePlanUsageCycleParams & { quantity: number; limit: number }
|
|
): Promise<IPlanUsageCycleDocument | null> {
|
|
const now = new Date();
|
|
return await this.planUsageCycleList.findOneAndUpdate(
|
|
{
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
appointmentsCount: { $lte: data.limit - data.quantity },
|
|
},
|
|
{
|
|
$setOnInsert: {
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
cycleEnd: data.cycleEnd,
|
|
appointmentsCount: 0,
|
|
creationDate: now,
|
|
},
|
|
$inc: { appointmentsCount: data.quantity },
|
|
$set: { updateDate: now },
|
|
},
|
|
{ new: true }
|
|
);
|
|
}
|
|
|
|
public async setAppointmentsCount(
|
|
data: UpdatePlanUsageCycleParams & { appointmentsCount: number }
|
|
): Promise<IPlanUsageCycleDocument | null> {
|
|
const now = new Date();
|
|
return await this.planUsageCycleList.findOneAndUpdate(
|
|
{
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
},
|
|
{
|
|
$setOnInsert: {
|
|
userId: data.userId,
|
|
subscriptionId: data.subscriptionId,
|
|
planId: data.planId,
|
|
cycleStart: data.cycleStart,
|
|
cycleEnd: data.cycleEnd,
|
|
creationDate: now,
|
|
},
|
|
$set: {
|
|
appointmentsCount: Math.max(data.appointmentsCount, 0),
|
|
updateDate: now,
|
|
},
|
|
},
|
|
{ new: true, upsert: true }
|
|
);
|
|
}
|
|
}
|