import { CalculateMetricsParams, DeleteMetricsByCompany, IMetricsManager, MetricsParams, } from "./Metrics.Interface"; import { IMetricsDocument, MetricsAdapterMongoose } from "./Metrics.Adapter.Mongoose"; import PlansList from "../../Models/Plans/Plans"; import PlanSubscriptionsList from "../../Models/PlanSubscriptions/PlanSubscriptons"; import CompaniesList from "../Companies/Companies"; import EmployeesList from "../Employees/Employee"; import ServiceList from "../Services/Service"; import AppointmentList from "../Appointments/Appointments"; import ClientsList from "../Clients/Clients"; import RepeatsList from "../Repeats/Repeats"; import { isNull } from "../../helpers/IsNull"; import PlanUsageCycleList from "../PlanUsageCycle/PlanUsageCycle"; class MetricsManager implements IMetricsManager { metrics: MetricsAdapterMongoose; constructor() { this.metrics = new MetricsAdapterMongoose(); } public async calculateMetrics(data: CalculateMetricsParams): Promise { //TODO: calcular las metricas... const metrics = await this.getMetrics(data.userId); const organizations = await CompaniesList.companies.find({ ownerId: data.userId, }); let employeesLength = 0; let servicesLength = 0; let appointmentsLength = 0; let clientsLength = 0; let repeatsLength = 0; for (const org of organizations) { const employees = await EmployeesList.employees.find({ companyId: String(org.id), }); employeesLength += employees.length; const services = await ServiceList.services.find({ companyId: String(org.id), }); servicesLength += services.length; //TODO: Revisar si el parametro del mes esta bien o necesita incrementar en uno. //ya que no recuerdo si empieza en 0 o en 1. appointmentsLength += await AppointmentList.countAppointmentsByMonth({ year: metrics.year, month: metrics.month, companyId: String(org.id), }); const clients = await ClientsList.clients.find({ companyId: String(org.id), }); clientsLength += clients.length; const repeats = await RepeatsList.repeats.find({ companyId: String(org.id), }); repeatsLength += repeats.length; } metrics.organizationsCount = organizations.length; metrics.employeesCount = employeesLength; metrics.servicesCount = servicesLength; metrics.appointmentsCount = appointmentsLength; metrics.clientsCount = clientsLength; metrics.repeatsCount = repeatsLength; await metrics.save(); } public async deleteMetricsByCompany(data: DeleteMetricsByCompany): Promise { const companyCheck = await CompaniesList.companies.findOne({ _id: data.companyId }); if (!companyCheck) { throw new Error("La compañia no existe"); } await this.metrics.reset(String(companyCheck.ownerId)); //await this.metrics.metricsList.deleteMany({ userId: String(companyCheck.ownerId) }); } public async reset(userId: string): Promise { await this.metrics.reset(userId); } public async getMetrics(userId: string): Promise { return await this.metrics.getMetrics(userId); } public async canAddOrganization(userId: string): Promise { const subscription = await PlanSubscriptionsList.findOne({ sessionUser: userId, }); if (!subscription) { return false; } const plan = await PlansList.plans.findOne({ _id: subscription.planId, }); if (!plan) { return false; } if (plan.limitOrganizations < 0) { return true; } const metrics = await this.getMetrics(userId); if (metrics.organizationsCount >= plan.limitOrganizations) { return false; } return true; } public async canAddService(userId: string): Promise { const subscription = await PlanSubscriptionsList.findOne({ sessionUser: userId, }); if (!subscription) { return false; } const plan = await PlansList.plans.findOne({ _id: subscription.planId, }); if (!plan) { return false; } if (plan.limitServices < 0) { return true; } const metrics = await this.getMetrics(userId); if (metrics.servicesCount >= plan.limitServices) { return false; } return true; } public async canAddEmployee(userId: string): Promise { const subscription = await PlanSubscriptionsList.findOne({ sessionUser: userId, }); if (!subscription) { return false; } const plan = await PlansList.plans.findOne({ _id: subscription.planId, }); if (!plan) { return false; } if (plan.limitEmployees < 0) { return true; } const metrics = await this.getMetrics(userId); if (metrics.employeesCount >= plan.limitEmployees) { return false; } return true; } public async canAddClient(userId: string): Promise { const subscription = await PlanSubscriptionsList.findOne({ sessionUser: userId, }); if (!subscription) { return false; } const plan = await PlansList.plans.findOne({ _id: subscription.planId, }); if (!plan) { return false; } if (plan.limitClients < 0) { return true; } const metrics = await this.getMetrics(userId); if (metrics.clientsCount >= plan.limitClients) { return false; } return true; } public async canAddRepeat(userId: string): Promise { const subscription = await PlanSubscriptionsList.findOne({ sessionUser: userId, }); if (!subscription) { return false; } const plan = await PlansList.plans.findOne({ _id: subscription.planId, }); if (!plan) { return false; } if (plan.limitRepeats < 0) { return true; } const metrics = await this.getMetrics(userId); if (isNull(metrics.repeatsCount, 0) >= plan.limitRepeats) { return false; } return true; } public async canAddAppointment(userId: string): Promise { const subscription = await PlanSubscriptionsList.findOne({ sessionUser: userId, }); if (!subscription) { return false; } const plan = await PlansList.plans.findOne({ _id: subscription.planId, }); if (!plan) { return false; } if (plan.limitAppointments < 0) { return true; } const appointmentsCount = await PlanUsageCycleList.getAppointmentsCount({ userId }); if (appointmentsCount >= plan.limitAppointments) { return false; } return true; } public async addAppointment(data: MetricsParams): Promise { if (data.userId) { await PlanUsageCycleList.addAppointment({ userId: data.userId, quantity: data.quantity, }); } await this.metrics.addAppointment(data); } public async reserveAppointment(data: MetricsParams): Promise { if (!data.userId) { return false; } const subscription = await PlanSubscriptionsList.findOne({ sessionUser: data.userId, }); if (!subscription) { return false; } const plan = await PlansList.plans.findOne({ _id: subscription.planId, }); if (!plan) { return false; } if (plan.limitAppointments < 0) { await PlanUsageCycleList.addAppointment({ userId: data.userId, quantity: data.quantity, }); return true; } return await PlanUsageCycleList.reserveAppointment({ userId: data.userId, quantity: data.quantity, limit: plan.limitAppointments, }); } public async releaseAppointment(data: MetricsParams): Promise { if (data.userId) { await PlanUsageCycleList.releaseAppointment({ userId: data.userId, quantity: data.quantity, }); } } public async addClient(data: MetricsParams): Promise { await this.metrics.addClient(data); } public async addRepeat(data: MetricsParams): Promise { await this.metrics.addRepeat(data); } public async addEmployee(data: MetricsParams): Promise { await this.metrics.addEmployee(data); } public async addOrganization(data: MetricsParams): Promise { await this.metrics.addOrganization(data); } public async addService(data: MetricsParams): Promise { await this.metrics.addService(data); } } const MetricsList = new MetricsManager(); export default MetricsList;