first commit
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
import Discounts from "../Discounts/Discounts";
|
||||
import {
|
||||
FindServicesParams,
|
||||
IServicesAdapter,
|
||||
IService,
|
||||
CreateServiceParams,
|
||||
UpdateServiceParams,
|
||||
PaginateServicesParams,
|
||||
PaginateServicesResults,
|
||||
SERVICE_PUBLISHED_STATUS,
|
||||
SysAdminPaginateServicesParams,
|
||||
} from "./Service.Interface";
|
||||
import mongoose, { Document, Model, Schema, model } from "mongoose";
|
||||
|
||||
export interface IServiceDocument extends Omit<IService, "id">, Document {}
|
||||
|
||||
export class ServicesAdapterMongoose implements IServicesAdapter {
|
||||
schema: Schema;
|
||||
serviceList: Model<IServiceDocument>;
|
||||
|
||||
constructor() {
|
||||
this.schema = new Schema({
|
||||
companyId: { type: Schema.Types.ObjectId, required: true, ref: "Companie" },
|
||||
discountId: { type: Schema.Types.ObjectId, required: false, ref: "Discount" },
|
||||
categoryId: { type: Number, required: false },
|
||||
name: { type: String, required: true },
|
||||
description: { type: String, required: true },
|
||||
price: { type: Number, required: true, default: 0 },
|
||||
originalPrice: { type: Number, required: false, default: 0 },
|
||||
length: { type: Number, required: true, default: 0 },
|
||||
limit: { type: Number, required: true, default: 0 },
|
||||
image: { type: String, required: false },
|
||||
color: { type: String, required: false },
|
||||
fontColor: { type: String, required: false },
|
||||
fontShadowColor: { 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 },
|
||||
published: { type: String, required: false },
|
||||
banned: { type: Boolean, required: false, default: false },
|
||||
});
|
||||
|
||||
this.serviceList = model<IServiceDocument>("Service", this.schema);
|
||||
}
|
||||
|
||||
public async create(data: CreateServiceParams): Promise<IService> {
|
||||
return await this.serviceList.create(data);
|
||||
}
|
||||
|
||||
public async update(data: UpdateServiceParams): Promise<void> {
|
||||
const updateService = await this.serviceList.findOne({ _id: data.id });
|
||||
|
||||
if (!updateService) {
|
||||
throw new Error("Service not found");
|
||||
}
|
||||
|
||||
if (data.categoryId) updateService.categoryId = data.categoryId;
|
||||
if (data.name) updateService.name = data.name;
|
||||
if (data.description) updateService.description = data.description;
|
||||
if (data.originalPrice) {
|
||||
updateService.originalPrice = data.originalPrice;
|
||||
//Si tiene un descuento aplicado tenemos que actualizar el precio
|
||||
//aplicando el descuento al precio original
|
||||
if (updateService.discountId) {
|
||||
const discount = await Discounts.discounts.discountsList.findOne({
|
||||
_id: String(updateService.discountId),
|
||||
companyId: data.companyId,
|
||||
});
|
||||
|
||||
if (discount) {
|
||||
updateService.price =
|
||||
updateService.originalPrice - updateService.originalPrice * (discount.value / 100);
|
||||
}
|
||||
} else {
|
||||
updateService.price = updateService.originalPrice;
|
||||
}
|
||||
}
|
||||
if (data.length) updateService.length = data.length;
|
||||
if (data.limit) updateService.limit = data.limit;
|
||||
if (data.image) updateService.image = data.image;
|
||||
if (data.color) updateService.color = data.color;
|
||||
if (data.fontColor) updateService.fontColor = data.fontColor;
|
||||
if (data.fontShadowColor) updateService.fontShadowColor = data.fontShadowColor;
|
||||
if (data.block) updateService.block = data.block;
|
||||
if (data.city) updateService.city = data.city;
|
||||
if (data.state) updateService.state = data.state;
|
||||
if (data.country) updateService.country = data.country;
|
||||
if (data.zipCode) updateService.zipCode = data.zipCode;
|
||||
if (data.latitude) updateService.latitude = data.latitude;
|
||||
if (data.longitude) updateService.longitude = data.longitude;
|
||||
if (data.banned !== undefined) updateService.banned = data.banned;
|
||||
|
||||
await updateService.save();
|
||||
}
|
||||
|
||||
public async delete(id: string): Promise<void> {
|
||||
await this.serviceList.findByIdAndDelete(id).exec();
|
||||
}
|
||||
|
||||
public async find(filters: FindServicesParams): Promise<IService[]> {
|
||||
return this.serviceList.find(filters).exec();
|
||||
}
|
||||
|
||||
public async findOne(filters: FindServicesParams): Promise<IServiceDocument | null> {
|
||||
return this.serviceList.findOne(filters).exec();
|
||||
}
|
||||
|
||||
public async paginate(filters: PaginateServicesParams): Promise<PaginateServicesResults> {
|
||||
const { page, limit, ...findFilters } = filters;
|
||||
const count = await this.serviceList.countDocuments(findFilters).exec();
|
||||
const skip = (page - 1) * limit;
|
||||
|
||||
const results = await this.serviceList.find(findFilters).skip(skip).limit(limit).exec();
|
||||
|
||||
return {
|
||||
data: results,
|
||||
page,
|
||||
pages: Math.ceil(count / limit),
|
||||
};
|
||||
}
|
||||
|
||||
// Método para búsqueda con expresiones regulares y paginación
|
||||
public async paginateFiltered(data: PaginateServicesParams): Promise<PaginateServicesResults> {
|
||||
const skip = (data.page - 1) * data.limit;
|
||||
|
||||
// Construye los criterios de búsqueda
|
||||
const searchCriteria: mongoose.FilterQuery<IService> = {};
|
||||
|
||||
// Agrega filtro por query usando expresiones regulares para 'name' y 'description'
|
||||
if (data.query) {
|
||||
const regex = new RegExp(data.query, "i");
|
||||
searchCriteria.$or = [{ name: regex }, { description: regex }];
|
||||
}
|
||||
|
||||
// Filtra por categoryId si está presente
|
||||
if (data.categoryId !== undefined) {
|
||||
searchCriteria.categoryId = data.categoryId;
|
||||
}
|
||||
|
||||
if (data.companyId !== undefined) {
|
||||
searchCriteria.companyId = data.companyId;
|
||||
}
|
||||
|
||||
if (data.serviceId !== undefined) {
|
||||
searchCriteria._id = data.serviceId;
|
||||
}
|
||||
|
||||
// Filtra por rango de precios
|
||||
if (data.priceFrom !== undefined || data.priceTo !== undefined) {
|
||||
searchCriteria.price = {};
|
||||
if (data.priceFrom !== undefined) searchCriteria.price.$gte = data.priceFrom;
|
||||
if (data.priceTo !== undefined) searchCriteria.price.$lte = data.priceTo;
|
||||
}
|
||||
|
||||
// Filtra por rango de longitud
|
||||
if (data.lengthFrom !== undefined || data.lengthTo !== undefined) {
|
||||
searchCriteria.length = {};
|
||||
if (data.lengthFrom !== undefined) searchCriteria.length.$gte = data.lengthFrom;
|
||||
if (data.lengthTo !== undefined) searchCriteria.length.$lte = data.lengthTo;
|
||||
}
|
||||
|
||||
// Filtra por block si está presente
|
||||
if (data.block) {
|
||||
searchCriteria.block = data.block;
|
||||
}
|
||||
|
||||
// Filtra por city si está presente
|
||||
if (data.city) {
|
||||
searchCriteria.city = data.city;
|
||||
}
|
||||
|
||||
// Filtra por state si está presente
|
||||
if (data.state) {
|
||||
searchCriteria.state = data.state;
|
||||
}
|
||||
|
||||
if (data.published !== undefined) {
|
||||
searchCriteria.published = data.published;
|
||||
if (data.published === SERVICE_PUBLISHED_STATUS.PUBLISHED) {
|
||||
searchCriteria.banned = { $ne: true };
|
||||
}
|
||||
}
|
||||
|
||||
// Realiza la consulta con paginación
|
||||
const results = await this.serviceList
|
||||
.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.serviceList.countDocuments(searchCriteria).exec();
|
||||
|
||||
return {
|
||||
data: results,
|
||||
page: data.page,
|
||||
pages: Math.ceil(count / data.limit),
|
||||
};
|
||||
}
|
||||
|
||||
public async sysAdminPaginate(data: SysAdminPaginateServicesParams): Promise<PaginateServicesResults> {
|
||||
const { page, limit, companyId } = data;
|
||||
const query: any = {};
|
||||
if (companyId) {
|
||||
query.companyId = companyId;
|
||||
}
|
||||
|
||||
const count = await this.serviceList.countDocuments(query).exec();
|
||||
const skip = (page - 1) * limit;
|
||||
|
||||
const results = await this.serviceList
|
||||
.find(query)
|
||||
.sort({ name: 1 })
|
||||
.skip(skip)
|
||||
.limit(limit)
|
||||
.exec();
|
||||
|
||||
return {
|
||||
data: results,
|
||||
page: page,
|
||||
pages: Math.ceil(count / limit),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user