396 lines
13 KiB
TypeScript
396 lines
13 KiB
TypeScript
import * as moment from 'moment';
|
|
import { ConflictException, Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import {
|
|
FindManyOptions,
|
|
FindOptionsWhere,
|
|
LessThanOrEqual,
|
|
Like,
|
|
Repository,
|
|
} from 'typeorm';
|
|
import { Modulo } from '../modulo/entity/modulo.entity';
|
|
import { Multa } from './entity/multa.entity';
|
|
import { Operador } from '../operador/entity/operador.entity';
|
|
import { Prestamo } from '../prestamo/entity/prestamo.entity';
|
|
import { Usuario } from '../usuario/entity/usuario.entity';
|
|
import { FullInformacionMultaView } from './entity/views/full-informacion-multa.view';
|
|
import { InformacionMultaView } from './entity/views/informacion-multa.view';
|
|
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,
|
|
semanasCastigo?: number,
|
|
id_institucion_infraccion?: number,
|
|
): Promise<{ message: string }> {
|
|
// Buscamos la infracción, si es que se mandó una, de lo contrario se asigna "Sin infracción" por default
|
|
const institucionInfraccion = id_institucion_infraccion
|
|
? await this.institucionInfraccionService.findById(
|
|
id_institucion_infraccion,
|
|
)
|
|
: await this.institucionInfraccionService.findSinInfraccion(
|
|
operadorMulta.institucion,
|
|
);
|
|
const existeMulta = await this.findByPrestamo(prestamo);
|
|
const fecha_fin = moment();
|
|
|
|
// Si ya existe una multa asignada a este préstamo significa que hubo un problema pero si se multo al usuario. Cortamos la función
|
|
if (existeMulta) return;
|
|
this.validacionMultaCancelacion(prestamo);
|
|
// Si hay semanasCastigo agregamos el tiempo de multa correspondiente a la institución
|
|
if (semanasCastigo)
|
|
fecha_fin.add(
|
|
semanasCastigo * modulo.institucion.dias_multa_retraso,
|
|
'd',
|
|
);
|
|
// Si la institucionInfraccion no es "Sin infracción"
|
|
if (institucionInfraccion.infraccion.id_infraccion != 1)
|
|
// Agregamos el tiempo de multa correspondiente de la infracción enviada
|
|
fecha_fin.add(institucionInfraccion.dias_multa, 'd');
|
|
// Creamos y guardamos un registro
|
|
return this.repository
|
|
.save(
|
|
this.repository.create({
|
|
descripcion,
|
|
fecha_fin: fecha_fin.toDate(),
|
|
fecha_inicio: moment().toDate(),
|
|
retraso: semanasCastigo ? true : false,
|
|
institucionInfraccion,
|
|
operadorMulta: id_institucion_infraccion
|
|
? operadorMulta
|
|
: this.operadorService.sistema(),
|
|
prestamo,
|
|
}),
|
|
)
|
|
.then((_) =>
|
|
// Multamos al usuario en todas las carreras a las que pertenece en esa institución
|
|
this.institucionUsuarioService.updateMulta(
|
|
operadorMulta.institucion,
|
|
prestamo.institucionUsuario.usuario,
|
|
true,
|
|
),
|
|
);
|
|
}
|
|
|
|
findAll(
|
|
operador: Operador,
|
|
filtros: {
|
|
nombre?: string;
|
|
pagina?: string;
|
|
usuario?: string;
|
|
},
|
|
): Promise<FullInformacionMultaView[] | [Multa[], number]> {
|
|
const busqueda: FindOptionsWhere<FullInformacionMultaView> = {
|
|
id_institucion: operador.institucion.id_institucion,
|
|
};
|
|
const options: FindManyOptions<FullInformacionMultaView> = {
|
|
order: {
|
|
institucion: 'ASC',
|
|
activo: 'DESC',
|
|
fecha_fin: 'ASC',
|
|
usuario: 'ASC',
|
|
},
|
|
};
|
|
|
|
if (filtros.nombre) busqueda.nombre = Like(`%${filtros.nombre}%`);
|
|
if (filtros.usuario) busqueda.usuario = Like(`%${filtros.usuario}%`);
|
|
options.where = busqueda;
|
|
if (filtros.pagina) {
|
|
options.skip = (parseInt(filtros.pagina) - 1) * 25;
|
|
options.take = 25;
|
|
return this.fullInformacionMultaView
|
|
.findAndCount(options)
|
|
.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]];
|
|
});
|
|
} else return this.fullInformacionMultaView.find(options);
|
|
}
|
|
|
|
findAllActivasExpiradas(): Promise<Multa[]> {
|
|
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,
|
|
institucionUsuario: {
|
|
usuario: { id_usuario: infoMultas[i].id_usuario },
|
|
},
|
|
},
|
|
}),
|
|
);
|
|
return multas;
|
|
});
|
|
}
|
|
|
|
findAllByIdEquipo(
|
|
operador: Operador,
|
|
id_equipo: number,
|
|
pagina: number,
|
|
): Promise<[Multa[], 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,
|
|
): Promise<[Multa[], 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): Promise<Multa> {
|
|
return this.repository.findOne({
|
|
select: ['id_multa'],
|
|
where: { prestamo },
|
|
});
|
|
}
|
|
|
|
findMultasActivasByUsuario(usuario: Usuario): Promise<Multa[]> {
|
|
return this.repository.find({
|
|
join: {
|
|
alias: 'mu',
|
|
innerJoin: {
|
|
p: 'mu.prestamo',
|
|
iu: 'p.institucionUsuario',
|
|
u: 'iu.usuario',
|
|
},
|
|
innerJoinAndSelect: {
|
|
ii: 'mu.institucionInfraccion',
|
|
i: 'ii.institucion',
|
|
},
|
|
},
|
|
where: { activo: true, prestamo: { institucionUsuario: { usuario } } },
|
|
});
|
|
}
|
|
|
|
private fullViewToMulta(infoMulta: FullInformacionMultaView): Multa {
|
|
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,
|
|
institucionUsuario: {
|
|
usuario: {
|
|
id_usuario: infoMulta.id_usuario,
|
|
usuario: infoMulta.usuario,
|
|
nombre: infoMulta.nombre,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
async multaExtemporanea(
|
|
operador: Operador,
|
|
id_prestamo: number,
|
|
descripcion: string,
|
|
id_institucion_infraccion: number,
|
|
): Promise<{ message: string }> {
|
|
const prestamo = await this.prestamoService.findById(id_prestamo);
|
|
const institucionInfraccion =
|
|
await this.institucionInfraccionService.findById(
|
|
id_institucion_infraccion,
|
|
);
|
|
const fecha_fin = moment();
|
|
|
|
// Validamos que este préstamo 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 tu institución.',
|
|
);
|
|
// Validamos que la infracción enviada no sea "Sin infracción"
|
|
if (institucionInfraccion.infraccion.id_infraccion === 1)
|
|
throw new ConflictException(
|
|
'No se puede asignar esta infracción manualmente.',
|
|
);
|
|
this.validacionMultaCancelacion(prestamo);
|
|
// Agregamos el tiempo de multa correspondiente de la infracción enviada
|
|
fecha_fin.add(institucionInfraccion.dias_multa, 'd');
|
|
return this.findByPrestamo(prestamo)
|
|
.then((existeMulta) => {
|
|
// Validamos que no exista una multa con este préstamo
|
|
if (existeMulta)
|
|
throw new ConflictException(
|
|
'Ya existe una multa asignada a este préstamo.',
|
|
);
|
|
// Creamos y guardamos un registro
|
|
return this.repository.save(
|
|
this.repository.create({
|
|
descripcion,
|
|
fecha_fin: fecha_fin.toDate(),
|
|
fecha_inicio: moment().toDate(),
|
|
institucionInfraccion,
|
|
operadorMulta: operador,
|
|
prestamo,
|
|
}),
|
|
);
|
|
})
|
|
.then((_) =>
|
|
// Multamos al usuario en todas las carreras a las que pertenece en esa institución
|
|
this.institucionUsuarioService.updateMulta(
|
|
operador.institucion,
|
|
prestamo.institucionUsuario.usuario,
|
|
true,
|
|
),
|
|
);
|
|
}
|
|
|
|
async quitarMulta(
|
|
admin: Operador,
|
|
id_institucion_usuario: number,
|
|
): Promise<{ message: string }> {
|
|
const institucionUsuario = await this.institucionUsuarioService.findById(
|
|
id_institucion_usuario,
|
|
);
|
|
const multa = await this.repository
|
|
.createQueryBuilder('mu')
|
|
.innerJoinAndSelect('mu.prestamo', 'p')
|
|
.innerJoin(
|
|
'p.institucionUsuario',
|
|
'iu',
|
|
'iu.id_institucion_usuario = :id_institucion_usuario',
|
|
{ id_institucion_usuario: institucionUsuario.id_institucion_usuario },
|
|
)
|
|
.where('mu.activo = 1')
|
|
.getOne();
|
|
|
|
// Validamos que este institucionUsuario le pertenezca al admin
|
|
if (
|
|
admin.institucion.id_institucion !=
|
|
institucionUsuario.institucionCarrera.institucion.id_institucion
|
|
)
|
|
throw new ConflictException(
|
|
'No puedes modificar la información este usuario porque no pertenece a tu institución.',
|
|
);
|
|
// Quitamos la multa a todas las carreras del usuario en la institución del admin
|
|
return this.institucionUsuarioService
|
|
.updateMulta(admin.institucion, institucionUsuario.usuario, false)
|
|
.then(async (_) => {
|
|
if (multa) {
|
|
multa.activo = false;
|
|
await this.repository.save(multa);
|
|
}
|
|
return { message: 'Se guardaron los cambios correctamente.' };
|
|
});
|
|
}
|
|
|
|
save(multa: Multa): Promise<Multa> {
|
|
return this.repository.save(multa);
|
|
}
|
|
|
|
private validacionMultaCancelacion(prestamo: Prestamo): void {
|
|
// Validamos que este présstamo no haya sido cancelado por 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.',
|
|
);
|
|
}
|
|
}
|