Files
turnosxpress/server/src/Models/Companies/Companies.Adapter.Mongoose.ts
T

376 lines
13 KiB
TypeScript

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<ICompany, "id">, Document {}
export class CompaniesAdapterMongoose implements ICompaniesAdapter {
schema: Schema;
companyList: Model<ICompanyDocument>;
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 },
showPublicScores: { type: Boolean, required: false, default: true },
showPublicOpinions: { type: Boolean, required: false, default: true },
showPublicProfessionals: { type: Boolean, required: false, default: true },
});
this.companyList = model<ICompanyDocument>("Company", this.schema);
}
public async create(company: ICompany): Promise<ICompany> {
const newCompany = await this.companyList.create({
...company,
onboardingStep: company.onboardingStep || 0
});
return newCompany;
}
public async update(data: UpdateCompanyParams): Promise<void> {
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;
}
if (data.showPublicScores !== undefined) {
updateCompany.showPublicScores = data.showPublicScores;
}
if (data.showPublicOpinions !== undefined) {
updateCompany.showPublicOpinions = data.showPublicOpinions;
}
if (data.showPublicProfessionals !== undefined) {
updateCompany.showPublicProfessionals = data.showPublicProfessionals;
}
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<void> {
await this.companyList.deleteOne({ _id: id }).exec();
}
public async find(filters: FindCompaniesParams): Promise<ICompany[]> {
return await this.companyList.find(filters).exec();
}
public async findOne(filters: FindCompaniesParams): Promise<ICompanyDocument | null> {
return await this.companyList.findOne(filters).exec();
}
public async paginate(filters: PaginateCompaniesParams): Promise<PaginateCompaniesResults> {
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<PaginateCompaniesResults> {
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<PaginateCompaniesResults> {
const skip = (data.page - 1) * data.limit;
const searchCriteria: mongoose.FilterQuery<ICompany> = {};
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),
};
}
}