import ServiceList from "../Services/Service"; import { FindCompaniesParams, UpdateCompanyParams, ICompaniesAdapter, ICompany, PaginateCompaniesParams, PaginateCompaniesResults, SysAdminPaginateCompaniesParams, } from "./Companies.Interface"; import mongoose, { Document, Model, Schema, model } from "mongoose"; export interface ICompanyDocument extends Omit, Document {} export class CompaniesAdapterMongoose implements ICompaniesAdapter { schema: Schema; companyList: Model; constructor() { this.schema = new Schema({ name: { type: String, required: true, unique: true }, slug: { type: String, required: true, unique: true }, description: { type: String, required: true, default: "" }, categoryId: { type: Number, required: false, default: 50000 }, street: { type: String, required: false }, streetNumber: { type: String, required: false }, builingFloor: { type: String, required: false }, buildingApartament: { type: String, required: false }, block: { type: String, required: false }, city: { type: String, required: false }, state: { type: String, required: false }, country: { type: String, required: false }, zipCode: { type: String, required: false }, latitude: { type: Number, required: false, default: 0 }, longitude: { type: Number, required: false, default: 0 }, phoneCountryCode: { type: String, required: false }, phoneAreaCode: { type: String, required: false }, phoneNumber: { type: String, required: false }, heatMapFraction: { type: Number, required: false }, headerFile: { type: String, required: false }, headerColor: { type: String, required: false }, headerFontColor: { type: String, required: false }, headerFontShadowColor: { type: String, required: false }, iconFile: { type: String, required: false }, logoFile: { type: String, required: false }, wapServerId: { type: Schema.Types.ObjectId, required: false, ref: "WapServer" }, ownerId: { type: Schema.Types.ObjectId, required: true, ref: "User" }, creationDate: { type: Date, required: true, default: Date.now }, published: { type: String, required: false }, automaticNotifications: { type: Boolean, required: false }, appointmentTime: { type: Number, required: false }, cancellationTime: { type: Number, required: false }, appointmentAlert: { type: String, required: false }, templateWapNotifId: { type: Schema.Types.ObjectId, required: false, ref: "Template" }, templateWapAltaId: { type: Schema.Types.ObjectId, required: false, ref: "Template" }, templateWapCancellationId: { type: Schema.Types.ObjectId, required: false, ref: "Template" }, templateEmailNotifId: { type: Schema.Types.ObjectId, required: false, ref: "Template" }, templateEmailAltaId: { type: Schema.Types.ObjectId, required: false, ref: "Template" }, templateEmailCancellationId: { type: Schema.Types.ObjectId, required: false, ref: "Template" }, onboardingStep: { type: Number, required: false, default: 0 }, onboardingCompleted: { type: Boolean, required: false, default: false }, fixedPostIds: { type: Array, required: false }, banned: { type: Boolean, required: false, default: false }, }); this.companyList = model("Company", this.schema); } public async create(company: ICompany): Promise { const newCompany = await this.companyList.create({ ...company, onboardingStep: company.onboardingStep || 0 }); return newCompany; } public async update(data: UpdateCompanyParams): Promise { const updateCompany = await this.companyList.findOne({ _id: data.id }); if (!updateCompany) { throw new Error("Company not found"); } if (data.name) { updateCompany.name = data.name; } if (data.description) { updateCompany.description = data.description; } if (data.categoryId) { updateCompany.categoryId = data.categoryId; } if (data.headerFile) { updateCompany.headerFile = data.headerFile; } if (data.iconFile) { updateCompany.iconFile = data.iconFile; } if (data.logoFile) { updateCompany.logoFile = data.logoFile; } if (data.headerColor) { updateCompany.headerColor = data.headerColor; } if (data.headerFontColor) { updateCompany.headerFontColor = data.headerFontColor; } if (data.headerFontShadowColor) { updateCompany.headerFontShadowColor = data.headerFontShadowColor; } if (data.street) { updateCompany.street = data.street; } if (data.streetNumber) { updateCompany.streetNumber = data.streetNumber; } if (data.builingFloor) { updateCompany.builingFloor = data.builingFloor; } if (data.buildingApartament) { updateCompany.buildingApartament = data.buildingApartament; } if (data.block) { updateCompany.block = data.block; } if (data.city) { updateCompany.city = data.city; } if (data.state) { updateCompany.state = data.state; } if (data.country) { updateCompany.country = data.country; } if (data.zipCode) { updateCompany.zipCode = data.zipCode; } if (data.latitude) { updateCompany.latitude = data.latitude; } if (data.longitude) { updateCompany.longitude = data.longitude; } if (data.phoneCountryCode) { updateCompany.phoneCountryCode = data.phoneCountryCode; } if (data.phoneAreaCode) { updateCompany.phoneAreaCode = data.phoneAreaCode; } if (data.phoneNumber) { updateCompany.phoneNumber = data.phoneNumber; } if (data.heatMapFraction) { updateCompany.heatMapFraction = data.heatMapFraction; } if (data.appointmentTime) { updateCompany.appointmentTime = data.appointmentTime; } if (data.cancellationTime) { updateCompany.cancellationTime = data.cancellationTime; } if (data.wapServerId) { updateCompany.wapServerId = data.wapServerId; } if (data.appointmentAlert) { updateCompany.appointmentAlert = data.appointmentAlert; } if (data.templateWapNotifId) { updateCompany.templateWapNotifId = data.templateWapNotifId; } if (data.templateWapAltaId) { updateCompany.templateWapAltaId = data.templateWapAltaId; } if (data.templateWapCancellationId) { updateCompany.templateWapCancellationId = data.templateWapCancellationId; } if (data.templateEmailNotifId) { updateCompany.templateEmailNotifId = data.templateEmailNotifId; } if (data.templateEmailAltaId) { updateCompany.templateEmailAltaId = data.templateEmailAltaId; } if (data.templateEmailCancellationId) { updateCompany.templateEmailCancellationId = data.templateEmailCancellationId; } if (data.onboardingStep !== undefined) { updateCompany.onboardingStep = data.onboardingStep; } if (data.onboardingCompleted !== undefined) { updateCompany.onboardingCompleted = data.onboardingCompleted; } if (data.banned !== undefined) { updateCompany.banned = data.banned; } updateCompany.save(); //actualizo los campos correspondientes a la localizacion de los servicios de la organizacion. try { const servicesUpdate = await ServiceList.services.find({ companyId: updateCompany.id }); for (const service of servicesUpdate) { if (!service.id) { continue; } await ServiceList.updateService({ id: service.id, companyId: updateCompany.id, latitude: updateCompany.latitude, longitude: updateCompany.longitude, block: updateCompany.block, city: updateCompany.city, state: updateCompany.state, country: updateCompany.country, zipCode: updateCompany.zipCode, sessionUser: data.sessionUser, }); } } catch (error) { console.log( "Ha ocurrido un error al actualizar la localizacion de los servicios de la organizacion." ); } } public async delete(id: string): Promise { await this.companyList.deleteOne({ _id: id }).exec(); } public async find(filters: FindCompaniesParams): Promise { return await this.companyList.find(filters).exec(); } public async findOne(filters: FindCompaniesParams): Promise { return await this.companyList.findOne(filters).exec(); } public async paginate(filters: PaginateCompaniesParams): Promise { const { page, limit, ...findFilters } = filters; //Extract page and limit from filters const count = await this.companyList.countDocuments(findFilters).exec(); const skip = (page - 1) * limit; const results = await this.companyList .find(findFilters) .skip(skip) .limit(filters.limit) .exec(); return { data: results, page: filters.page, pages: Math.ceil(count / filters.limit), }; } public async sysAdminPaginate(filters: SysAdminPaginateCompaniesParams): Promise { const { page, limit, sortBy, sortOrder, name, banned } = filters as any; const query: any = {}; if (name) { query.name = { $regex: name, $options: "i" }; } if (banned !== undefined) { query.banned = banned; } const count = await this.companyList.countDocuments(query).exec(); const skip = (page - 1) * limit; const sortObj: any = {}; if (sortBy) { sortObj[sortBy] = sortOrder === "desc" ? -1 : 1; } const results = await this.companyList .find(query) .sort(sortObj) .skip(skip) .limit(limit) .exec(); return { data: results, page: page, pages: Math.ceil(count / limit), }; } public async paginateFilterAll( data: PaginateCompaniesParams ): Promise { const skip = (data.page - 1) * data.limit; const searchCriteria: mongoose.FilterQuery = {}; if (data.name) { const words = data.name.split(" ").map((word) => new RegExp(word, "i")); searchCriteria.$and = words.map((word) => ({ $or: [{ name: word }, { description: word }], })); } // Realiza la consulta con paginación const results = await this.companyList .find(searchCriteria) .sort({ price: 1 }) // Ordena por precio ascendente .skip(skip) .limit(data.limit) .exec(); // Cuenta el total de documentos que coinciden con los criterios de búsqueda const count = await this.companyList.countDocuments(searchCriteria).exec(); return { data: results, page: data.page, pages: Math.ceil(count / data.limit), }; } }