Files
pcpuma_unam_api/src/equipo/equipo.service.ts
T
2022-10-23 21:06:54 -05:00

533 lines
18 KiB
TypeScript

import {
ConflictException,
ForbiddenException,
forwardRef,
Inject,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { FindOptionsWhere, Repository } from 'typeorm';
import { Carrito } from '../carrito/entity/carrito.entity';
import { Equipo } from './entity/equipo.entity';
import { Institucion } from '../institucion/entity/institucion.entity';
import { Marca } from '../marca/entity/marca.entity';
import { Modelo } from '../modelo/entity/modelo.entity';
import { Modulo } from '../modulo/entity/modulo.entity';
import { Operador } from '../operador/entity/operador.entity';
import { Programa } from '../institucion-programa/entity/programa.entity';
import { TipoCarrito } from '../institucion-tipo-carrito/entity/tipo-carrito.entity';
import { TipoEntrada } from '../institucion-tipo-entrada/entity/tipo-entrada.entity';
import { FullInformacionEquipoView } from './entity/views/full-informacion-equipo.view';
import { InformacionEquipoPrestamoView } from './entity/views/informacion-equipo-prestamo.view';
import { InformacionEquipoView } from './entity/views/informacion-equipo.view';
import { CarritoService } from '../carrito/carrito.service';
import { EquipoProgramaService } from '../equipo-programa/equipo-programa.service';
import { EquipoTipoEntradaService } from '../equipo-tipo-entrada/equipo-tipo-entrada.service';
import { InstitucionService } from '../institucion/institucion.service';
import { InstitucionProgramaService } from '../institucion-programa/institucion-programa.service';
import { InstitucionTipoCarritoService } from '../institucion-tipo-carrito/institucion-tipo-carrito.service';
import { InstitucionTipoEntradaService } from '../institucion-tipo-entrada/institucion-tipo-entrada.service';
import { MarcaService } from '../marca/marca.service';
import { ModeloService } from '../modelo/modelo.service';
import { ModuloService } from '../modulo/modulo.service';
import { EquipoMotivoService } from '../equipo-motivo/equipo-motivo.service';
import { StatusService } from '../status/status.service';
@Injectable()
export class EquipoService {
constructor(
@InjectRepository(Equipo) private repository: Repository<Equipo>,
@InjectRepository(FullInformacionEquipoView)
private fullInformacionEquipoView: Repository<FullInformacionEquipoView>,
@InjectRepository(InformacionEquipoPrestamoView)
private informacionEquipoPrestamoView: Repository<InformacionEquipoPrestamoView>,
@InjectRepository(InformacionEquipoView)
private informacionEquipoView: Repository<InformacionEquipoView>,
private carritoService: CarritoService,
@Inject(forwardRef(() => EquipoProgramaService))
private equipoProgramaService: EquipoProgramaService,
@Inject(forwardRef(() => EquipoTipoEntradaService))
private equipoTipoEntradaService: EquipoTipoEntradaService,
private institucionService: InstitucionService,
private institucionProgramaService: InstitucionProgramaService,
private institucionTipoCarritoService: InstitucionTipoCarritoService,
private institucionTipoEntradaService: InstitucionTipoEntradaService,
private marcaService: MarcaService,
private modeloService: ModeloService,
private moduloService: ModuloService,
@Inject(forwardRef(() => EquipoMotivoService))
private equipoMotivoService: EquipoMotivoService,
private statusService: StatusService,
) {}
async create(
carrito: Carrito,
equipo: string,
numero_inventario: string,
numero_serie: string,
marca: Marca,
modelo: Modelo,
) {
const equipoNuevo = await this.repository.save(
this.repository.create({
carrito,
equipo,
marca,
modelo,
numero_inventario,
numero_serie,
status: { id_status: 1 },
}),
);
return this.equipoProgramaService
.createSinPrograma(equipoNuevo)
.then((_) => equipoNuevo);
}
async findAll(
operador: Operador,
filtros: {
pagina: string;
carrito?: string;
equipo?: string;
id_carrito?: string;
id_institucion?: string;
id_marca?: string;
id_modelo?: string;
id_modulo?: string;
id_programa?: string;
id_status?: string;
id_tipo_carrito?: string;
id_tipo_entrada?: string;
},
) {
const carrito = filtros.id_carrito
? await this.carritoService.findById(parseInt(filtros.id_carrito))
: null;
const institucion = filtros.id_institucion
? await this.institucionService.findInfoInstitucionById(
parseInt(filtros.id_institucion),
)
: null;
const marca = filtros.id_marca
? await this.marcaService.findById(parseInt(filtros.id_marca), 'e')
: null;
const modelo = filtros.id_modelo
? await this.modeloService.findById(parseInt(filtros.id_modelo), 'e')
: null;
const modulo = filtros.id_modulo
? await this.moduloService.findInfoModuloById(parseInt(filtros.id_modulo))
: null;
const programa = filtros.id_programa
? await this.institucionProgramaService.findProgramaById(
parseInt(filtros.id_programa),
)
: null;
const tipoCarrito = filtros.id_tipo_carrito
? await this.institucionTipoCarritoService.findTipoCarritoById(
parseInt(filtros.id_tipo_carrito),
)
: null;
const status = filtros.id_status
? await this.statusService.findById(parseInt(filtros.id_status))
: null;
const tipoEntrada = filtros.id_tipo_entrada
? await this.institucionTipoEntradaService.findTipoEntradaById(
parseInt(filtros.id_tipo_entrada),
)
: null;
const query = this.repository
.createQueryBuilder('e')
.innerJoinAndSelect('e.carrito', 'c')
.innerJoinAndSelect('e.marca', 'ma')
.innerJoinAndSelect('e.modelo', 'mo')
.innerJoinAndSelect('e.programas', 'ps')
.innerJoinAndSelect('e.status', 's')
.innerJoinAndSelect('e.tiposEntradas', 'tes')
.innerJoinAndSelect('c.modulo', 'm')
.innerJoinAndSelect('c.tipoCarrito', 'tc')
.innerJoinAndSelect('ps.programa', 'p')
.innerJoinAndSelect('tes.tipoEntrada', 'te')
.innerJoinAndSelect('m.institucion', 'i')
.orderBy('i.institucion')
.addOrderBy('m.modulo')
.addOrderBy('tc.tipo_carrito')
.addOrderBy('c.carrito')
.addOrderBy('e.equipo')
.take(15)
.skip((parseInt(filtros.pagina) - 1) * 15);
if (modulo) {
if (
operador.tipoUsuario.id_tipo_usuario > 2 &&
operador.institucion.id_institucion != modulo.institucion.id_institucion
)
throw new ForbiddenException(
'No puedes acceder a esta información porque este módulo no pertenece a tu institución.',
);
query.andWhere('m.id_modulo = :id_modulo', {
id_modulo: modulo.id_modulo,
});
}
if (carrito) {
if (
operador.tipoUsuario.id_tipo_usuario > 2 &&
operador.institucion.id_institucion !=
carrito.modulo.institucion.id_institucion
)
throw new ForbiddenException(
'No puedes acceder a esta información porque este carrito no pertenece a tu institución.',
);
query.andWhere('c.id_carrito = :id_carrito', {
id_carrito: carrito.id_carrito,
});
}
if (filtros.carrito)
query.andWhere('c.carrito LIKE :carrito', {
carrito: `%${filtros.carrito}%`,
});
if (filtros.equipo)
query.andWhere('e.equipo LIKE :equipo', {
equipo: `%${filtros.equipo}%`,
});
if (institucion)
query.andWhere('m.id_institucion = :id_institucion', {
id_institucion: institucion.id_institucion,
});
if (marca)
query.andWhere('ma.id_marca = :id_marca', {
id_marca: marca.id_marca,
});
if (modelo)
query.andWhere('mo.id_modelo = :id_modelo', {
id_modelo: modelo.id_modelo,
});
if (programa)
query.andWhere('ps.id_programa = :id_programa', {
id_programa: programa.id_programa,
});
if (tipoCarrito)
query.andWhere('tc.id_tipo_carrito = :id_tipo_carrito', {
id_tipo_carrito: tipoCarrito.id_tipo_carrito,
});
if (tipoEntrada)
query.andWhere('tes.id_tipo_entrada = :id_tipo_entrada', {
id_tipo_entrada: tipoEntrada.id_tipo_entrada,
});
if (status)
query.andWhere('s.id_status = :id_status', {
id_status: status.id_status,
});
return query.getManyAndCount();
}
async findEquipo(
id_usuario: number,
modulo: Modulo,
tipoCarrito: TipoCarrito,
programa?: Programa,
tipoEntrada?: TipoEntrada,
) {
const busquedaReseteo: FindOptionsWhere<InformacionEquipoPrestamoView> = {
prestado: 1,
id_modulo: modulo.id_modulo,
id_tipo_carrito: tipoCarrito.id_tipo_carrito,
};
const busqueda: FindOptionsWhere<InformacionEquipoPrestamoView> = {
prestado: 0,
id_modulo: modulo.id_modulo,
id_tipo_carrito: tipoCarrito.id_tipo_carrito,
};
if (programa) {
busqueda.id_programa = programa.id_programa;
busquedaReseteo.id_programa = programa.id_programa;
} else {
busqueda.id_programa = 1;
busquedaReseteo.id_programa = 1;
}
if (tipoEntrada) {
busqueda.id_tipo_entrada = tipoEntrada.id_tipo_entrada;
busquedaReseteo.id_tipo_entrada = tipoEntrada.id_tipo_entrada;
}
return this.informacionEquipoPrestamoView
.findOne({ where: busqueda })
.then((infoEquipo) => {
if (!infoEquipo)
return this.informacionEquipoPrestamoView
.find({ where: busquedaReseteo })
.then(async (infoEquipos) => {
for (let i = 0; i < infoEquipos.length; i++)
await this.repository.save(
this.repository.create({
id_equipo: infoEquipos[i].id_equipo,
prestado: false,
}),
);
return this.informacionEquipoPrestamoView.findOne({
where: busqueda,
});
})
.then((infoEquipo) => {
if (!infoEquipo)
throw new ConflictException(
'No hay un equipo de cómputo que cumpla con las caracteríasticas solicitadas o ya no hay equipos disponibles en este momento. Intenta más tarde o cambia las características.',
);
return infoEquipo;
});
return infoEquipo;
})
.then((infoEquipo) => {
if (infoEquipo.u)
throw new ConflictException(
'Ocurrio un error al tratar de asignarte un equipo de cómputo, intenta de nuevo.',
);
const equipo = this.repository.create({
id_equipo: infoEquipo.id_equipo,
u: id_usuario,
status: { id_status: 2 },
});
return this.repository.save(equipo);
})
.then((equipo) => this.findInfoEquipoById(equipo.id_equipo))
.then((equipo) => {
if (equipo.u != id_usuario)
throw new ConflictException(
'Ocurrio un error al tratar de asignarte un equipo de cómputo, intenta de nuevo.',
);
return equipo;
});
}
findInfoEquipoById(id_equipo: number) {
return this.informacionEquipoView
.findOne({ where: { id_equipo } })
.then((infoEquipo) => {
if (!infoEquipo)
throw new NotFoundException('No existe este id equipo.');
return this.viewToEquipo(infoEquipo);
});
}
findInfoEquipoByNumeroInventario(
institucion: Institucion,
numero_inventario: string,
validarNoExiste = true,
) {
return this.informacionEquipoView
.findOne({
where: {
id_institucion: institucion.id_institucion,
numero_inventario,
},
})
.then((infoEquipo) => {
if (!infoEquipo) {
if (validarNoExiste)
throw new NotFoundException(
'No existe un equipo de cómputo con este número de inventario.',
);
return null;
}
return this.viewToEquipo(infoEquipo);
});
}
async findInfoEquipoByEquipo(
carrito: Carrito,
equipo: string,
validarNoExiste = true,
) {
return this.informacionEquipoView
.findOne({
where: {
id_carrito: carrito.id_carrito,
equipo,
},
})
.then((infoEquipo) => {
if (!infoEquipo) {
if (validarNoExiste)
throw new NotFoundException(
'No existe un equipo de cómputo con este número de inventario.',
);
return null;
}
return this.viewToEquipo(infoEquipo);
});
}
findFullInfoEquipoByNumeroInventario(
id_institucion: number,
numero_inventario: string,
) {
return this.institucionService
.findInfoInstitucionById(id_institucion)
.then((institucion) =>
this.fullInformacionEquipoView.findOne({
where: {
id_institucion: institucion.id_institucion,
numero_inventario,
},
}),
)
.then(async (infoEquipo) => {
if (!infoEquipo)
throw new NotFoundException(
'No existe un equipo de cómputo con este número de inventario.',
);
const programas =
await this.equipoProgramaService.findFullInfoEquipoProgramaAllByIdEquipo(
infoEquipo.id_equipo,
);
const tiposEntradas =
await this.equipoTipoEntradaService.findFullInfoEquipoTipoEntradaAllByIdEquipo(
infoEquipo.id_equipo,
);
return this.repository.create({
id_equipo: infoEquipo.id_equipo,
equipo: infoEquipo.equipo,
numero_inventario: infoEquipo.numero_inventario,
prestado: infoEquipo.prestado,
carrito: {
id_carrito: infoEquipo.id_carrito,
carrito: infoEquipo.carrito,
modulo: {
id_modulo: infoEquipo.id_modulo,
modulo: infoEquipo.modulo,
institucion: {
id_institucion: infoEquipo.id_institucion,
institucion: infoEquipo.institucion,
},
},
tipoCarrito: {
id_tipo_carrito: infoEquipo.id_tipo_carrito,
tipo_carrito: infoEquipo.tipo_carrito,
},
},
marca: {
id_marca: infoEquipo.id_marca,
marca: infoEquipo.marca,
},
modelo: {
id_modelo: infoEquipo.id_modelo,
modelo: infoEquipo.modelo,
},
status: {
id_status: infoEquipo.id_status,
status: infoEquipo.status,
},
programas,
tiposEntradas,
});
});
}
reseteoTotal() {
return this.repository
.createQueryBuilder()
.update()
.set({ prestado: false })
.execute();
}
async update(
operador: Operador,
attrs: Partial<Equipo>,
id_carrito?: number,
id_status?: number,
motivo?: string,
) {
const carrito = id_carrito
? await this.carritoService.findById(id_carrito)
: null;
const status = id_status
? await this.statusService.findById(id_status)
: null;
return this.findInfoEquipoById(attrs.id_equipo)
.then(async (equipo) => {
if (
operador.tipoUsuario.id_tipo_usuario > 2 &&
operador.institucion.id_institucion !=
equipo.carrito.modulo.institucion.id_institucion
)
throw new ForbiddenException(
'No puedes modificar la información este equipo porque no pertenece a tu institución.',
);
if (status) {
if (equipo.status.id_status === 2 || equipo.status.id_status === 3)
throw new ConflictException(
'No se puede cambiar el status de un equipo si esta apartada o en uso.',
);
if (status.id_status === 2 || status.id_status === 3)
throw new ConflictException(
'No se puede cambiar manualmente el status de un equipo a este status.',
);
if (!motivo)
throw new ConflictException(
'No se mandó el motivo para el cambio de status.',
);
}
Object.assign(equipo, attrs);
if (status) {
equipo.status = status;
await this.equipoMotivoService.create(
equipo,
operador,
status,
motivo,
);
}
if (carrito) equipo.carrito = carrito;
return this.repository.save(equipo);
})
.then((_) => ({
message: 'Se guardaron los cambios correctamente.',
}));
}
async updateStatus(equipo: Equipo, operador?: Operador, motivo?: string) {
if (equipo.status.id_status >= 4) {
if (!operador) throw new ConflictException('No se mandó el id operador.');
if (!motivo)
throw new ConflictException(
'No se mandó el motivo para el cambio de status.',
);
await this.equipoMotivoService.create(
equipo,
operador,
equipo.status,
motivo,
);
}
return this.repository.save(equipo);
}
private viewToEquipo(infoEquipo: InformacionEquipoView) {
return this.repository.create({
id_equipo: infoEquipo.id_equipo,
equipo: infoEquipo.equipo,
numero_inventario: infoEquipo.numero_inventario,
prestado: infoEquipo.prestado,
u: infoEquipo.u,
carrito: {
id_carrito: infoEquipo.id_carrito,
carrito: infoEquipo.carrito,
modulo: {
id_modulo: infoEquipo.id_modulo,
institucion: { id_institucion: infoEquipo.id_institucion },
},
tipoCarrito: { id_tipo_carrito: infoEquipo.id_tipo_carrito },
},
status: { id_status: infoEquipo.id_status },
});
}
}