361 lines
12 KiB
TypeScript
361 lines
12 KiB
TypeScript
import * as moment from 'moment';
|
|
import { ConflictException, Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { FindOptionsWhere, LessThanOrEqual, Like, Repository } from 'typeorm';
|
|
import { Multa } from './entity/multa.entity';
|
|
import { FullInformacionMultaView } from './entity/views/full-informacion-multa.view';
|
|
import { InformacionMultaView } from './entity/views/informacion-multa.view';
|
|
import { Modulo } from '../modulo/entity/modulo.entity';
|
|
import { Operador } from '../operador/entity/operador.entity';
|
|
import { Prestamo } from '../prestamo/entity/prestamo.entity';
|
|
import { Usuario } from '../usuario/entity/usuario.entity';
|
|
import { EquipoService } from '../equipo/equipo.service';
|
|
import { InstitucionInfraccionService } from '../institucion-infraccion/institucion-infraccion.service';
|
|
import { InstitucionUsuarioService } from '../institucion-usuario/institucion-usuario.service';
|
|
import { OperadorService } from '../operador/operador.service';
|
|
import { PrestamoService } from '../prestamo/prestamo.service';
|
|
import { UsuarioService } from '../usuario/usuario.service';
|
|
|
|
@Injectable()
|
|
export class MultaService {
|
|
constructor(
|
|
@InjectRepository(Multa) private repository: Repository<Multa>,
|
|
@InjectRepository(FullInformacionMultaView)
|
|
private fullInformacionMultaView: Repository<FullInformacionMultaView>,
|
|
@InjectRepository(InformacionMultaView)
|
|
private informacionMultaView: Repository<InformacionMultaView>,
|
|
private equipoService: EquipoService,
|
|
private institucionInfraccionService: InstitucionInfraccionService,
|
|
private institucionUsuarioService: InstitucionUsuarioService,
|
|
private operadorService: OperadorService,
|
|
private prestamoService: PrestamoService,
|
|
private usuarioService: UsuarioService,
|
|
) {}
|
|
|
|
async create(
|
|
operadorMulta: Operador,
|
|
modulo: Modulo,
|
|
prestamo: Prestamo,
|
|
descripcion: string,
|
|
retraso?: number,
|
|
id_institucion_infraccion?: number,
|
|
) {
|
|
const institucionInfraccion = id_institucion_infraccion
|
|
? await this.institucionInfraccionService.findById(
|
|
id_institucion_infraccion,
|
|
)
|
|
: // Asigno institucionInfraccion "Sin infracción" por default
|
|
await this.institucionInfraccionService.findSinInfraccion(
|
|
operadorMulta.institucion,
|
|
);
|
|
// Creo registro de multa
|
|
const nuevaMulta = this.repository.create({
|
|
descripcion,
|
|
fecha_inicio: moment().toDate(),
|
|
operadorMulta: id_institucion_infraccion
|
|
? operadorMulta
|
|
: this.operadorService.sistema(),
|
|
prestamo,
|
|
institucionInfraccion,
|
|
});
|
|
const existeMulta = await this.findByPrestamo(prestamo).catch(
|
|
(err) => true,
|
|
);
|
|
const fecha_fin = moment();
|
|
|
|
// Si ya tiene multa es que hubo un error en otra ocasión pero se creo la multa
|
|
// correctamente esa vez
|
|
if (existeMulta) return;
|
|
this.validacionMultaCancelacion(prestamo);
|
|
// Si no se mando un id_institucion_infraccion ni retraso saco error
|
|
if (!id_institucion_infraccion && !retraso)
|
|
throw new ConflictException(
|
|
'No se mandó ningún motivo para multar a este alumno.',
|
|
);
|
|
// Si hay retraso lo agrego a la multa
|
|
if (retraso) {
|
|
nuevaMulta.retraso = true;
|
|
fecha_fin.add(retraso * modulo.institucion.dias_multa_retraso, 'd');
|
|
}
|
|
fecha_fin.add(institucionInfraccion.dias_multa, 'd');
|
|
nuevaMulta.fecha_fin = fecha_fin.toDate();
|
|
// Guardo la información
|
|
return this.repository.save(nuevaMulta).then((_) =>
|
|
// Actualizo multas del usuario
|
|
this.institucionUsuarioService.updateMulta(
|
|
operadorMulta.institucion.id_institucion,
|
|
prestamo.usuario.id_usuario,
|
|
true,
|
|
),
|
|
);
|
|
}
|
|
|
|
async multaExtemporanea(
|
|
operador: Operador,
|
|
id_prestamo: number,
|
|
descripcion: string,
|
|
id_institucion_infraccion: number,
|
|
) {
|
|
const prestamo =
|
|
typeof id_prestamo === 'number'
|
|
? await this.prestamoService.findById(id_prestamo)
|
|
: id_prestamo;
|
|
const institucionInfraccion =
|
|
await this.institucionInfraccionService.findById(
|
|
id_institucion_infraccion,
|
|
);
|
|
const fecha_fin = moment();
|
|
|
|
// Validamos que este prestamo le pertenezca al operador
|
|
if (
|
|
operador.institucion.id_institucion !=
|
|
prestamo.equipo.carrito.modulo.institucion.id_institucion
|
|
)
|
|
throw new ConflictException(
|
|
'Este préstamo no pertenece a esta institución.',
|
|
);
|
|
this.validacionMultaCancelacion(prestamo);
|
|
fecha_fin.add(institucionInfraccion.dias_multa, 'd');
|
|
// Buscamos una multa con este préstamo
|
|
return this.findByPrestamo(prestamo)
|
|
.then((_) =>
|
|
// Creamos y guardamos registro
|
|
this.repository.save(
|
|
this.repository.create({
|
|
descripcion,
|
|
fecha_fin: fecha_fin.toDate(),
|
|
fecha_inicio: moment().toDate(),
|
|
institucionInfraccion,
|
|
operadorMulta: operador,
|
|
prestamo,
|
|
}),
|
|
),
|
|
)
|
|
.then((_) =>
|
|
// Actualizo multas del usuario
|
|
this.institucionUsuarioService.updateMulta(
|
|
operador.institucion.id_institucion,
|
|
prestamo.usuario.id_usuario,
|
|
true,
|
|
),
|
|
);
|
|
}
|
|
|
|
findAllActivasExpiradas() {
|
|
return this.informacionMultaView
|
|
.find({
|
|
where: { activo: 1, fecha_fin: LessThanOrEqual(moment().toDate()) },
|
|
})
|
|
.then((infoMultas) => {
|
|
const multas: Multa[] = [];
|
|
|
|
for (let i = 0; i < infoMultas.length; i++)
|
|
multas.push(
|
|
this.repository.create({
|
|
id_multa: infoMultas[i].id_multa,
|
|
activo: infoMultas[i].activo === 1,
|
|
fecha_fin: infoMultas[i].fecha_fin,
|
|
retraso: infoMultas[i].retraso === 1,
|
|
institucionInfraccion: {
|
|
id_institucion_infraccion:
|
|
infoMultas[i].id_institucion_infraccion,
|
|
infraccion: { id_infraccion: infoMultas[i].id_infraccion },
|
|
institucion: { id_institucion: infoMultas[i].id_institucion },
|
|
},
|
|
operadorMulta: { id_operador: infoMultas[i].id_operador },
|
|
prestamo: {
|
|
id_prestamo: infoMultas[i].id_prestamo,
|
|
usuario: { id_usuario: infoMultas[i].id_usuario },
|
|
},
|
|
}),
|
|
);
|
|
return multas;
|
|
});
|
|
}
|
|
|
|
findAll(
|
|
operador: Operador,
|
|
filtros: {
|
|
pagina: string;
|
|
nombre?: string;
|
|
usuario?: string;
|
|
},
|
|
) {
|
|
const busqueda: FindOptionsWhere<FullInformacionMultaView> = {};
|
|
|
|
if (filtros.nombre) busqueda.nombre = Like(`%${filtros.nombre}%`);
|
|
if (filtros.usuario) busqueda.usuario = Like(`%${filtros.usuario}%`);
|
|
if (operador) busqueda.id_institucion = operador.institucion.id_institucion;
|
|
return this.fullInformacionMultaView
|
|
.findAndCount({
|
|
where: busqueda,
|
|
order: {
|
|
institucion: 'ASC',
|
|
activo: 'DESC',
|
|
fecha_fin: 'ASC',
|
|
id_usuario: 'ASC',
|
|
},
|
|
skip: (parseInt(filtros.pagina) - 1) * 25,
|
|
take: 25,
|
|
})
|
|
.then((infoMultas) => {
|
|
const multas: Multa[] = [];
|
|
|
|
for (let i = 0; i < infoMultas[0].length; i++)
|
|
multas.push(
|
|
this.repository.create(this.fullViewToMulta(infoMultas[0][i])),
|
|
);
|
|
return [multas, infoMultas[1]];
|
|
});
|
|
}
|
|
|
|
findAllByIdEquipo(operador: Operador, id_equipo: number, pagina: number) {
|
|
return this.equipoService.findById(id_equipo).then((equipo) =>
|
|
this.fullInformacionMultaView
|
|
.findAndCount({
|
|
where: {
|
|
id_equipo: equipo.id_equipo,
|
|
id_institucion: operador.institucion.id_institucion,
|
|
},
|
|
skip: (pagina - 1) * 25,
|
|
take: 25,
|
|
})
|
|
.then((infoMultas) => {
|
|
const multas: Multa[] = [];
|
|
|
|
for (let i = 0; i < infoMultas[0].length; i++)
|
|
multas.push(
|
|
this.repository.create(this.fullViewToMulta(infoMultas[0][i])),
|
|
);
|
|
return [multas, infoMultas[1]];
|
|
}),
|
|
);
|
|
}
|
|
|
|
findAllByIdUsuario(operador: Operador, id_usuario: number, pagina: number) {
|
|
return this.usuarioService.findById(id_usuario).then((usuario) =>
|
|
this.fullInformacionMultaView
|
|
.findAndCount({
|
|
where: {
|
|
id_usuario: usuario.id_usuario,
|
|
id_institucion: operador.institucion.id_institucion,
|
|
},
|
|
skip: (pagina - 1) * 25,
|
|
take: 25,
|
|
})
|
|
.then((infoMultas) => {
|
|
const multas: Multa[] = [];
|
|
|
|
for (let i = 0; i < infoMultas[0].length; i++)
|
|
multas.push(
|
|
this.repository.create(this.fullViewToMulta(infoMultas[0][i])),
|
|
);
|
|
return [multas, infoMultas[1]];
|
|
}),
|
|
);
|
|
}
|
|
|
|
findByPrestamo(prestamo: Prestamo) {
|
|
return this.repository
|
|
.findOne({ select: ['id_multa'], where: { prestamo } })
|
|
.then((existeMulta) => {
|
|
if (existeMulta)
|
|
throw new ConflictException(
|
|
'Ya existe una multa asignada a este préstamo.',
|
|
);
|
|
return existeMulta;
|
|
});
|
|
}
|
|
|
|
findMultasActivasByUsuario(usuario: Usuario) {
|
|
return this.repository
|
|
.createQueryBuilder('mu')
|
|
.innerJoin('mu.prestamo', 'p')
|
|
.innerJoin('p.usuario', 'u', 'u.id_usuario = :id_usuario', {
|
|
id_usuario: usuario.id_usuario,
|
|
})
|
|
.innerJoinAndSelect('mu.institucionInfraccion', 'ii')
|
|
.innerJoinAndSelect('ii.institucion', 'i')
|
|
.andWhere('mu.activo = 1')
|
|
.getMany();
|
|
}
|
|
|
|
private fullViewToMulta(infoMulta: FullInformacionMultaView) {
|
|
return this.repository.create({
|
|
id_multa: infoMulta.id_multa,
|
|
activo: infoMulta.activo === 1,
|
|
descripcion: infoMulta.descripcion,
|
|
fecha_fin: infoMulta.fecha_fin,
|
|
fecha_inicio: infoMulta.fecha_inicio,
|
|
retraso: infoMulta.retraso === 1,
|
|
institucionInfraccion: {
|
|
id_institucion_infraccion: infoMulta.id_institucion_infraccion,
|
|
infraccion: {
|
|
id_infraccion: infoMulta.id_infraccion,
|
|
infraccion: infoMulta.infraccion,
|
|
},
|
|
},
|
|
operadorMulta: {
|
|
id_operador: infoMulta.id_operador,
|
|
operador: infoMulta.operador,
|
|
institucion: {
|
|
id_institucion: infoMulta.id_institucion,
|
|
institucion: infoMulta.institucion,
|
|
},
|
|
},
|
|
prestamo: {
|
|
id_prestamo: infoMulta.id_prestamo,
|
|
usuario: {
|
|
id_usuario: infoMulta.id_usuario,
|
|
usuario: infoMulta.usuario,
|
|
nombre: infoMulta.nombre,
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
save(multa: Multa) {
|
|
return this.repository.save(multa);
|
|
}
|
|
|
|
private validacionMultaCancelacion(prestamo: Prestamo) {
|
|
// Validamos que este prestamo no haya sido cancelado poer el usuario u operador
|
|
if (prestamo.cancelado_operador || prestamo.cancelado_usuario)
|
|
throw new ConflictException(
|
|
'No se puede multar a un usuario con un préstamo que fue cancelado.',
|
|
);
|
|
}
|
|
|
|
async quitarMulta(admin: Operador, id_institucion_usuario: number) {
|
|
const institucionUsuario = await this.institucionUsuarioService.findById(
|
|
id_institucion_usuario,
|
|
);
|
|
const multa = await this.repository
|
|
.createQueryBuilder('mu')
|
|
.innerJoinAndSelect('mu.prestamo', 'p')
|
|
.innerJoinAndSelect('p.usuario', 'u')
|
|
.innerJoin(
|
|
'u.instituciones',
|
|
'is',
|
|
'is.id_institucion_usuario = :id_institucion_usuario',
|
|
{ id_institucion_usuario: institucionUsuario.id_institucion_usuario },
|
|
)
|
|
.where('mu.activo = 1')
|
|
.getOne();
|
|
|
|
await this.institucionUsuarioService.updateMulta(
|
|
admin.institucion.id_institucion,
|
|
institucionUsuario.usuario.id_usuario,
|
|
false,
|
|
);
|
|
if (!multa)
|
|
throw new ConflictException(
|
|
'Este usuario no tiene una multa activa en esta institución.',
|
|
);
|
|
multa.activo = false;
|
|
return this.repository
|
|
.save(multa)
|
|
.then((_) => ({ message: 'Se guardaron los cambios correctamente.' }));
|
|
}
|
|
}
|