File: /var/www/api-parametros/src/app/parametros/services/parametro.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { CreateParametroDto } from '../dto/create-parametro.dto';
import { UpdateParametroDto } from '../dto/update-parametro.dto';
import { InjectModel } from '@nestjs/mongoose';
import { Parametro } from '../schemas/parametro.schema';
import { Model, Types } from 'mongoose';
import { ResApiInterface } from 'src/shared/interfaces/res-api.interface';
import {
handleMessageError,
handleMessageSucces,
} from '../../../shared/utils/message-handler';
import { handleValidationError } from '../../../shared/utils/error-handler';
@Injectable()
export class ParametroService {
constructor(
@InjectModel(Parametro.name)
private readonly parametroModel: Model<Parametro>,
) {}
async create(
createParametroDto: CreateParametroDto,
): Promise<ResApiInterface<CreateParametroDto>> {
try {
const createdParametro = new this.parametroModel({
...createParametroDto,
idTipoParametro: new Types.ObjectId(createParametroDto.idTipoParametro),
});
const savedParametro = await createdParametro.save();
return handleMessageSucces(savedParametro, 'create');
} catch (error) {
throw handleValidationError(error);
}
}
async findAll(
page: number,
pageSize: number,
): Promise<ResApiInterface<CreateParametroDto[]>> {
try {
const skip = (page - 1) * pageSize;
const totalRecordsPromise = await this.parametroModel.countDocuments({
deletedAt: { $in: null },
});
const parametrosPromise = this.parametroModel
.find(
{ deletedAt: { $in: null } },
'_id codigo nombre padre icon posicion createdAt',
)
.skip(skip)
.limit(pageSize)
.exec();
const [parametros, totalRecords] = await Promise.all([
parametrosPromise,
totalRecordsPromise,
]);
return handleMessageSucces(parametros, 'findAll', totalRecords);
} catch (error) {
throw handleValidationError(error);
}
}
async findOne(id: string): Promise<ResApiInterface<CreateParametroDto>> {
try {
const proyecto = await this.parametroModel
.findById(
id,
'_id codigo nombre padre tipoParametro icon.nombre icon.codigo posicion showMenu',
)
.exec();
if (!proyecto) {
throw new NotFoundException(handleMessageError('notFound'));
}
return handleMessageSucces(proyecto, 'findOne');
} catch (error) {
throw handleValidationError(error);
}
}
async update(
id: string,
updateParametroDto: UpdateParametroDto,
): Promise<ResApiInterface<UpdateParametroDto>> {
try {
const updatedParametro = await this.parametroModel.findByIdAndUpdate(
id,
updateParametroDto,
{ new: true },
);
if (!updatedParametro) {
throw new NotFoundException(handleMessageError('notFound'));
}
return handleMessageSucces(updatedParametro, 'update');
} catch (error) {
throw handleValidationError(error);
}
}
async delete(id: string): Promise<ResApiInterface<CreateParametroDto>> {
try {
const deletedParametro = await this.parametroModel.findByIdAndUpdate(id, {
deletedAt: new Date(),
});
if (!deletedParametro) {
throw new NotFoundException(handleMessageError('notFound'));
}
return handleMessageSucces(deletedParametro, 'delete');
} catch (error) {
throw handleValidationError(error);
}
}
async findByTipoParametro(
idTipoParametro: string,
page: number,
pageSize: number,
): Promise<ResApiInterface<CreateParametroDto[]>> {
try {
const skip = (page - 1) * pageSize;
const totalRecordsPromise = await this.parametroModel.countDocuments({
deletedAt: { $in: null },
idTipoParametro: idTipoParametro,
});
const parametrosPromise = this.parametroModel
.find(
{ deletedAt: { $in: null }, idTipoParametro: idTipoParametro },
'_id codigo nombre padre icon.nombre icon.codigo posicion createdAt',
)
.skip(skip)
.limit(pageSize)
.exec();
const [parametros, totalRecords] = await Promise.all([
parametrosPromise,
totalRecordsPromise,
]);
return handleMessageSucces(parametros, 'findAll', totalRecords);
} catch (error) {
throw handleValidationError(error);
}
}
async findSelectParametrosByTipoParametro(
idTipoParametro: string,
): Promise<ResApiInterface<CreateParametroDto[]>> {
try {
const parametrosPromise = this.parametroModel
.find(
{ deletedAt: { $in: null }, idTipoParametro: idTipoParametro },
'_id codigo nombre icon.codigo posicion showMenu',
)
.sort({ nombre: 1 })
.exec();
const [parametros] = await Promise.all([parametrosPromise]);
return handleMessageSucces(parametros, 'findAll');
} catch (error) {
throw handleValidationError(error);
}
}
async findSelectParametrosByTipoParametroPadre(
idTipoParametro: string,
idPadre: string,
): Promise<ResApiInterface<CreateParametroDto[]>> {
try {
const parametrosPromise = this.parametroModel
.find(
{
deletedAt: null,
idTipoParametro: idTipoParametro,
'padre._id': idPadre,
},
'_id codigo nombre icon.codigo posicion showMenu',
)
.sort({ nombre: 1 })
.exec();
const [parametros] = await Promise.all([parametrosPromise]);
return handleMessageSucces(parametros, 'findAll');
} catch (error) {
throw handleValidationError(error);
}
}
async findParametrosPadreHijosByTipoParametro(
idTipoParametro: string,
): Promise<ResApiInterface<any>> {
try {
const parametrosPadres = await this.parametroModel
.find({ idTipoParametro, deletedAt: null }, '_id nombre')
.exec();
const subCategoriasByCategoria = await Promise.all(
parametrosPadres.map(async (padre) => {
const padreId = padre._id.toString();
const items = await this.parametroModel
.find({ 'padre._id': padreId }, '_id nombre')
.exec();
return { _id: padre._id, nombre: padre.nombre, items };
}),
);
return handleMessageSucces(subCategoriasByCategoria, 'findAll');
} catch (error) {
throw handleValidationError(error);
}
}
async findPadresByTipoParametro(
idTipoParametro: string,
): Promise<ResApiInterface<any>> {
try {
// Paso 1: Obtener los parámetros
const parametros = await this.parametroModel.find(
{ idTipoParametro },
'padre',
);
// Paso 2: Utilizar un Set para almacenar los IDs únicos y un Map para almacenar los objetos
const padresMap = new Map();
parametros.forEach((param: any) => {
if (param.padre) {
const padre = {
nombre: param.padre.nombre,
_id: param.padre._id,
};
padresMap.set(padre._id, padre);
}
});
// Paso 3: Convertir el Map a un array de objetos únicos
const uniqueParents = Array.from(padresMap.values());
uniqueParents.sort((a, b) => a.nombre.localeCompare(b.nombre));
// Paso 4: Devolver los resultados
return handleMessageSucces(uniqueParents, 'findAll');
} catch (error) {
throw handleValidationError(error);
}
}
async findParametrosByPadre(
idPadre: string,
page: number,
pageSize: number,
): Promise<ResApiInterface<CreateParametroDto[]>> {
try {
const skip = (page - 1) * pageSize;
const query = { 'padre._id': idPadre, deletedAt: { $in: null } };
const totalRecordsPromise =
await this.parametroModel.countDocuments(query);
const parametrosPromise = this.parametroModel
.find(query, '_id codigo nombre slug descripcion padre')
.skip(skip)
.limit(pageSize)
.exec();
const [parametros, totalRecords] = await Promise.all([
parametrosPromise,
totalRecordsPromise,
]);
return handleMessageSucces(parametros, 'findAll', totalRecords);
} catch (error) {
throw handleValidationError(error);
}
}
}