Se agredó la entidad servActivos, se agregaron funciones para activacion de dervicio
This commit is contained in:
+1
-1
@@ -41,7 +41,7 @@ import { UsuariosModule } from './usuarios/usuarios.module';
|
||||
logger: 'advanced-console',
|
||||
retryAttempts: 5,
|
||||
retryDelay: 2000,
|
||||
dropSchema: true, // solo para desarrollo
|
||||
dropSchema: false, // solo para desarrollo
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -77,7 +77,7 @@ export class AuthDocumentation {
|
||||
properties: {
|
||||
email: { type: 'string', format: 'email', example: 'nuevo@dominio.com' },
|
||||
password: { type: 'string', example: 'Password123' },
|
||||
origen: { type: 'string', example: 'redes', description: 'Origen del usuario' }
|
||||
origen: { type: 'string', example: 'RED', description: 'Origen del usuario' }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ export class AuthDocumentation {
|
||||
id_usuario: { type: 'number', example: 1 },
|
||||
correo: { type: 'string', example: 'nuevo@dominio.com' },
|
||||
|
||||
origen: { type: 'string', example: 'redes' }
|
||||
origen: { type: 'string', example: 'RED' }
|
||||
|
||||
|
||||
}
|
||||
|
||||
+57
-32
@@ -1,4 +1,5 @@
|
||||
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn, PrimaryColumn } from 'typeorm';
|
||||
import { ServActivos } from 'src/usuarios/entities/servActivos.entitie';
|
||||
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn, PrimaryColumn, OneToOne } from 'typeorm';
|
||||
|
||||
@Entity({ name: 'origen' })
|
||||
export class Origen {
|
||||
@@ -42,6 +43,44 @@ export class Carrera {
|
||||
carreraUsuarios: CarreraUsuario[];
|
||||
}
|
||||
|
||||
@Entity({ name: 'movimiento' })
|
||||
export class Movimiento {
|
||||
@PrimaryGeneratedColumn({ name: 'id_mov', type: 'int' })
|
||||
id_mov: number;
|
||||
|
||||
@Column({ name: 'fecha_mov', type: 'datetime' })
|
||||
fecha_mov: Date;
|
||||
|
||||
@Column({ type: 'varchar', length: 100 })
|
||||
status: string;
|
||||
|
||||
@Column({
|
||||
type: 'varchar',
|
||||
length: 200,
|
||||
nullable: true, // permite NULL
|
||||
})
|
||||
observaciones?: string;
|
||||
|
||||
@Column({ type: 'bit' })
|
||||
flag: boolean;
|
||||
|
||||
@Column({
|
||||
type: 'varchar',
|
||||
length: 200,
|
||||
nullable: true, // permite NULL
|
||||
})
|
||||
reporte?: string;
|
||||
|
||||
@OneToMany(() => Usuario, usuario => usuario.movimiento)
|
||||
usuario: Usuario[];
|
||||
|
||||
|
||||
@ManyToOne(() => Origen, origen => origen.movimientos)
|
||||
@JoinColumn({ name: 'id_origen' })
|
||||
origen: Origen;
|
||||
}
|
||||
|
||||
|
||||
@Entity({ name: 'usuario' })
|
||||
export class Usuario {
|
||||
@PrimaryGeneratedColumn({ name: 'id_usuario', type: 'int' })
|
||||
@@ -89,7 +128,17 @@ export class Usuario {
|
||||
|
||||
@OneToMany(() => UsuarioTipoUsuario, utu => utu.usuario)
|
||||
usuarioTipos: UsuarioTipoUsuario[];
|
||||
|
||||
@ManyToOne(() => Movimiento, movimiento => movimiento.usuario)
|
||||
@JoinColumn({ name: 'id_movimiento' })
|
||||
movimiento: Movimiento;
|
||||
|
||||
@OneToOne(() => ServActivos, (servActivo) => servActivo.usuario,)
|
||||
servActivo: ServActivos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Entity({ name: 'carrera_usuario' })
|
||||
export class CarreraUsuario {
|
||||
@PrimaryGeneratedColumn({ name: 'id_carrera_usuario', type: 'int' })
|
||||
@@ -152,6 +201,12 @@ export class TipoUsuario {
|
||||
usuariosTipos: UsuarioTipoUsuario[];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Entity({ name: 'usuario_tipo_usuario' })
|
||||
export class UsuarioTipoUsuario {
|
||||
@PrimaryGeneratedColumn({ name: 'id_user_tipo_usuario', type: 'int' })
|
||||
@@ -166,36 +221,6 @@ export class UsuarioTipoUsuario {
|
||||
usuario: Usuario;
|
||||
}
|
||||
|
||||
@Entity({ name: 'movimiento' })
|
||||
export class Movimiento {
|
||||
@PrimaryGeneratedColumn({ name: 'id_mov', type: 'int' })
|
||||
id_mov: number;
|
||||
|
||||
@Column({ name: 'fecha_mov', type: 'datetime' })
|
||||
fecha_mov: Date;
|
||||
export { ServActivos };
|
||||
|
||||
@Column({ type: 'varchar', length: 100 })
|
||||
status: string;
|
||||
|
||||
@Column({
|
||||
type: 'varchar',
|
||||
length: 200,
|
||||
nullable: true, // permite NULL
|
||||
})
|
||||
observaciones?: string;
|
||||
|
||||
@Column({ type: 'bit' })
|
||||
flag: boolean;
|
||||
|
||||
@Column({
|
||||
type: 'varchar',
|
||||
length: 200,
|
||||
nullable: true, // permite NULL
|
||||
})
|
||||
reporte?: string;
|
||||
|
||||
|
||||
@ManyToOne(() => Origen, origen => origen.movimientos)
|
||||
@JoinColumn({ name: 'id_origen' })
|
||||
origen: Origen;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// src/excel/excel.controller.ts
|
||||
import { Controller, Post, Get, UseGuards, Request, Res, UploadedFile, UseInterceptors, HttpStatus } from '@nestjs/common';
|
||||
import { Controller, Post, Get, UseGuards, Request, Res, UploadedFile, UseInterceptors, HttpStatus, Param, ParseIntPipe } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
@@ -22,7 +22,8 @@ export class ExcelController {
|
||||
@ExcelDocumentation.verifyExcel()
|
||||
async verifyExcel(@UploadedFile() file: Express.Multer.File, @Request() req) {
|
||||
const userId: number = req.user.userId; // ahora sí existe
|
||||
const errors = await this.excelService.validateFile(file.buffer);
|
||||
const status = await this.excelService.validateFile(file.buffer);
|
||||
const errors = status.errors;
|
||||
await this.movimientoService.log(
|
||||
|
||||
'VERIFY',
|
||||
@@ -47,14 +48,17 @@ export class ExcelController {
|
||||
}
|
||||
try {
|
||||
const result = await this.excelService.loadFile(file.buffer);
|
||||
await this.movimientoService.log(
|
||||
|
||||
'LOAD',
|
||||
//Actualizar el estado de los movimientos
|
||||
if (!result) {
|
||||
throw new Error('No se pudo procesar el archivo.');
|
||||
}
|
||||
await this.movimientoService.updateStatus(
|
||||
result.id_movimiento,
|
||||
'SUCCESS',
|
||||
undefined,
|
||||
`inserted=${result.inserted}`
|
||||
);
|
||||
return result;
|
||||
return result
|
||||
|
||||
} catch (err) {
|
||||
await this.movimientoService.log(
|
||||
|
||||
@@ -189,4 +193,28 @@ export class ExcelController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Agregarlo en su propio controller
|
||||
@Get('movimientos')
|
||||
async getMovimientos() {
|
||||
const movimientos = await this.movimientoService.findAll();
|
||||
return movimientos;
|
||||
}
|
||||
|
||||
@Post('activar-servicios/:id_movimiento')
|
||||
async activarServicios(
|
||||
@Param('id_movimiento', ParseIntPipe) id_movimiento: number,
|
||||
@Request() req,
|
||||
): Promise<{ message: string }> {
|
||||
const origen = req.user.origen;
|
||||
|
||||
if (!origen) {
|
||||
throw new Error('No se encontró origen en el JWT');
|
||||
}
|
||||
|
||||
await this.excelService.activarServicios(id_movimiento, origen);
|
||||
|
||||
return { message: 'Servicios activados correctamente' };
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import { ExcelController } from './excel.controller';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Usuario, Genero, Carrera, CarreraUsuario, UsuarioTipoUsuario, TipoUsuario } from '../entities/entities';
|
||||
import { MovimientoModule } from 'src/movimiento/movimiento.module';
|
||||
import { ServActivos } from 'src/usuarios/entities/servActivos.entitie';
|
||||
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Usuario, Genero, Carrera, CarreraUsuario, UsuarioTipoUsuario, TipoUsuario]),
|
||||
TypeOrmModule.forFeature([Usuario, Genero, Carrera, CarreraUsuario, UsuarioTipoUsuario, TipoUsuario, ServActivos]),
|
||||
MovimientoModule
|
||||
],
|
||||
providers: [ExcelService],
|
||||
|
||||
+154
-15
@@ -6,6 +6,8 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { CarreraUsuario, TipoUsuario, Usuario, UsuarioTipoUsuario } from '../entities/entities';
|
||||
import { Genero } from '../entities/entities';
|
||||
import { Carrera } from '../entities/entities';
|
||||
import { MovimientoService } from 'src/movimiento/movimiento.service';
|
||||
import { ServActivos } from 'src/usuarios/entities/servActivos.entitie';
|
||||
|
||||
export interface UsuarioRow {
|
||||
cuenta: string;
|
||||
@@ -40,6 +42,10 @@ export class ExcelService {
|
||||
private readonly usuarioTipoUsuarioRepo: Repository<UsuarioTipoUsuario>,
|
||||
@InjectRepository(TipoUsuario)
|
||||
private readonly tipoUsuarioRepo: Repository<TipoUsuario>,
|
||||
@InjectRepository(ServActivos)
|
||||
private readonly servActivosRepo: Repository<ServActivos>,
|
||||
private readonly movimientoService: MovimientoService,
|
||||
|
||||
// … inyecta otros repositorios si los usarás
|
||||
) { }
|
||||
|
||||
@@ -101,23 +107,35 @@ export class ExcelService {
|
||||
validateRows(rows: UsuarioRow[]) {
|
||||
const errors: string[] = [];
|
||||
const seen = new Set<string>();
|
||||
const rowsGood: UsuarioRow[] = [];
|
||||
let flagError: boolean = false;
|
||||
|
||||
rows.forEach((r, i) => {
|
||||
const rowNum = i + 2; // por el encabezado
|
||||
|
||||
// Campos que no pueden quedar vacíos
|
||||
['cuenta', 'nombreCompleto'].forEach(field => {
|
||||
['cuenta', 'nombreCompleto', 'tipo'].forEach(field => {
|
||||
const raw = (r as any)[field];
|
||||
const str = raw != null ? raw.toString().trim() : '';
|
||||
if (!str) {
|
||||
errors.push(`Fila ${rowNum}: campo "${field}" está vacío.`);
|
||||
flagError = true;
|
||||
}
|
||||
});
|
||||
|
||||
// El número de cuenta debe ser de nueve dígitos para los alumnos
|
||||
if (r.cuenta && !/^\d{9}$/.test(r.cuenta.toString().trim()) && r.tipo.trim() === 'Licenciatura') {
|
||||
errors.push(`Fila ${rowNum}: cuenta "${r.cuenta}" debe tener 9 dígitos.`);
|
||||
flagError = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Duplicados de "cuenta"
|
||||
const cuentaStr = r.cuenta != null ? r.cuenta.toString().trim() : '';
|
||||
if (seen.has(cuentaStr)) {
|
||||
errors.push(`Fila ${rowNum}: cuenta duplicada "${cuentaStr}".`);
|
||||
flagError = true;
|
||||
} else {
|
||||
seen.add(cuentaStr);
|
||||
}
|
||||
@@ -128,6 +146,7 @@ export class ExcelService {
|
||||
const genStr = r.gen != null ? r.gen.toString().trim() : '';
|
||||
if (genStr && !/^[0-9]{4}$/.test(genStr)) {
|
||||
errors.push(`Fila ${rowNum}: generación inválida "${genStr}".`);
|
||||
flagError = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -135,16 +154,29 @@ export class ExcelService {
|
||||
const fechaStr = r.fechnac != null ? r.fechnac.toString().trim() : '';
|
||||
if (!/^[0-9]{8}$/.test(fechaStr)) {
|
||||
errors.push(`Fila ${rowNum}: fecha de nacimiento inválida "${fechaStr}".`);
|
||||
flagError = true;
|
||||
}
|
||||
|
||||
// RFC alfanumérico
|
||||
const rfcStr = r.rfc != null ? r.rfc.toString().trim() : '';
|
||||
if (rfcStr && !/^[A-Z0-9]+$/.test(rfcStr)) {
|
||||
errors.push(`Fila ${rowNum}: RFC contiene caracteres no válidos.`);
|
||||
flagError = true;
|
||||
}
|
||||
|
||||
if (!flagError) {
|
||||
rowsGood.push(r)
|
||||
} else {
|
||||
flagError = false; // reset para la siguiente fila
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
return errors;
|
||||
console.log(rowsGood);
|
||||
|
||||
return { errors, rowsGood };
|
||||
}
|
||||
|
||||
|
||||
@@ -153,21 +185,42 @@ export class ExcelService {
|
||||
*/
|
||||
async validateFile(buffer: Buffer) {
|
||||
const rows = await this.parseFile(buffer);
|
||||
const errs = this.validateRows(rows);
|
||||
return errs;
|
||||
const status = this.validateRows(rows);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida y luego persiste usuarios y relaciones básicas
|
||||
*/
|
||||
async loadFile(buffer: Buffer) {
|
||||
const rows = await this.parseFile(buffer);
|
||||
const errs = this.validateRows(rows);
|
||||
if (errs.length) {
|
||||
throw new BadRequestException({ errors: errs });
|
||||
}
|
||||
const file = await this.parseFile(buffer);
|
||||
const status = this.validateRows(file);
|
||||
const errs = status.errors;
|
||||
const rows = status.rowsGood;
|
||||
|
||||
const movimiento = await this.movimientoService.log(
|
||||
|
||||
'LOAD',
|
||||
'LOADING',
|
||||
undefined
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for (const r of rows) {
|
||||
//0.1
|
||||
const userExists = await this.usuarioRepo.findOne({
|
||||
where: { num_cuenta: r.cuenta },
|
||||
});
|
||||
|
||||
if (userExists) {
|
||||
errs.push(`Cuenta ${r.cuenta} ya existe, se omite.`);
|
||||
continue; // si ya existe, no lo insertamos
|
||||
}
|
||||
|
||||
|
||||
// 1) Género (crea o reutiliza)
|
||||
let genero = await this.generoRepo.findOne({ where: { genero: r.sexo } });
|
||||
if (!genero) {
|
||||
@@ -200,6 +253,8 @@ export class ExcelService {
|
||||
const generacion = /^[0-9]{4}$/.test(r.gen?.toString().trim())
|
||||
? parseInt(r.gen.toString().trim(), 10)
|
||||
: null;
|
||||
|
||||
|
||||
// 3) Usuario
|
||||
const usuario = this.usuarioRepo.create({
|
||||
num_cuenta: r.cuenta,
|
||||
@@ -210,9 +265,10 @@ export class ExcelService {
|
||||
fecha_nacimiento: r.fechnac,
|
||||
generacion: generacion,
|
||||
genero,
|
||||
movimiento: { id_mov: movimiento.id_mov }, // Relación con movimiento
|
||||
|
||||
});
|
||||
await this.usuarioRepo.save(usuario);
|
||||
const user = await this.usuarioRepo.save(usuario);
|
||||
|
||||
|
||||
|
||||
@@ -231,14 +287,50 @@ export class ExcelService {
|
||||
});
|
||||
await this.usuarioTipoUsuarioRepo.save(usuarioTipo);
|
||||
|
||||
// 6) ServActivos (si es necesario)
|
||||
switch (r.tipo.trim()) {
|
||||
|
||||
|
||||
case 'Licenciatura':
|
||||
case 'Profesor':
|
||||
const servActivos = this.servActivosRepo.create({
|
||||
|
||||
Red: true,
|
||||
AT: true,
|
||||
Correo: true,
|
||||
Prestamos: true,
|
||||
usuario: user,
|
||||
RedStatus: 'Inactivo',
|
||||
ATStatus: 'Inactivo',
|
||||
CorreoStatus: 'Inactivo',
|
||||
PrestamosStatus: 'Inactivo',
|
||||
});
|
||||
await this.servActivosRepo.save(servActivos);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case 'Trabajadores':
|
||||
const servActivosTrabajadores = this.servActivosRepo.create({
|
||||
Red: true,
|
||||
usuario: user,
|
||||
RedStatus: 'Inactivo',
|
||||
|
||||
});
|
||||
await this.servActivosRepo.save(servActivosTrabajadores);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return { inserted: rows.length };
|
||||
return { inserted: rows.length, id_movimiento: movimiento.id_mov, errors: errs };
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// async generateCsv(): Promise<string> {
|
||||
// const users = await this.usuarioRepo.find({
|
||||
// relations: ['genero', 'carreraUsuarios'], // si quieres más info
|
||||
@@ -293,6 +385,9 @@ export class ExcelService {
|
||||
tipo_usuario: In(tipos),
|
||||
},
|
||||
},
|
||||
servActivo: {
|
||||
CorreoStatus: 'Inactivo', // solo los que no tienen servicio activo
|
||||
}
|
||||
},
|
||||
relations: [
|
||||
'genero',
|
||||
@@ -355,6 +450,9 @@ export class ExcelService {
|
||||
tipo_usuario: In(tipos),
|
||||
},
|
||||
},
|
||||
servActivo: {
|
||||
PrestamosStatus: 'Inactivo', // solo los que no tienen servicio activo
|
||||
}
|
||||
},
|
||||
relations: [
|
||||
'genero',
|
||||
@@ -433,6 +531,9 @@ export class ExcelService {
|
||||
tipo_usuario: In(tipos),
|
||||
},
|
||||
},
|
||||
servActivo: {
|
||||
RedStatus: 'Inactivo',
|
||||
}
|
||||
},
|
||||
relations: [
|
||||
'genero',
|
||||
@@ -483,6 +584,9 @@ export class ExcelService {
|
||||
tipo_usuario: In(tipos),
|
||||
},
|
||||
},
|
||||
servActivo: {
|
||||
ATStatus: 'Inactivo',
|
||||
},
|
||||
},
|
||||
relations: [
|
||||
'genero',
|
||||
@@ -523,17 +627,52 @@ export class ExcelService {
|
||||
|
||||
|
||||
|
||||
//Funcion que se le debe hacer su propio módulo
|
||||
async activarServicios(id_movimiento: number, origen: string): Promise<void> {
|
||||
if (!['AT', 'SOLICITA', 'CORREO', 'RED'].includes(origen)) {
|
||||
throw new BadRequestException(`Origen ${origen} no válido`);
|
||||
}
|
||||
|
||||
const usuarios = await this.usuarioRepo.find({
|
||||
where: { movimiento: { id_mov: id_movimiento } },
|
||||
});
|
||||
|
||||
if (!usuarios || usuarios.length === 0) {
|
||||
throw new BadRequestException('No se encontró el usuario asociado al movimiento');
|
||||
}
|
||||
|
||||
for (const usuario of usuarios) {
|
||||
const servActivos = await this.servActivosRepo.findOne({
|
||||
where: { usuario: { id_usuario: usuario.id_usuario } },
|
||||
});
|
||||
|
||||
if (!servActivos) {
|
||||
throw new BadRequestException(
|
||||
`No se encontraron servicios activos para el usuario con ID ${usuario.id_usuario}`,
|
||||
);
|
||||
}
|
||||
|
||||
const timestamp = 'Activo ' + new Date().toISOString();
|
||||
|
||||
if (origen === 'AT' && servActivos.AT) {
|
||||
servActivos.ATStatus = timestamp;
|
||||
} else if (origen === 'RED' && servActivos.Red) {
|
||||
servActivos.RedStatus = timestamp;
|
||||
} else if (origen === 'CORREO' && servActivos.Correo) {
|
||||
servActivos.CorreoStatus = timestamp;
|
||||
} else if (origen === 'SOLICITA' && servActivos.Prestamos) {
|
||||
servActivos.PrestamosStatus = timestamp;
|
||||
} else {
|
||||
throw new BadRequestException(
|
||||
`Origen ${origen} no válido o servicio no activo para el usuario con ID ${usuario.id_usuario}`,
|
||||
);
|
||||
}
|
||||
|
||||
await this.servActivosRepo.save(servActivos);
|
||||
console.log(`Servicio ${servActivos}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,19 +20,50 @@ export class MovimientoService {
|
||||
observaciones?: string,
|
||||
reporte?: string,
|
||||
flag = false,
|
||||
) {
|
||||
): Promise<Movimiento> {
|
||||
// 1) Obtén el origen o falla si no existe
|
||||
const origin = await this.origenRepo.findOne({ where: { origen } });
|
||||
if (!origin) throw new Error(`Origen desconocido: ${origen}`);
|
||||
|
||||
// 2) Inserta directamente usando los campos de FK
|
||||
await this.movRepo.insert({
|
||||
// 2) Crea el objeto movimiento
|
||||
const movimiento = this.movRepo.create({
|
||||
fecha_mov: new Date(),
|
||||
status,
|
||||
observaciones, // aquí usas el valor que vino como parámetro
|
||||
reporte, // idem
|
||||
observaciones,
|
||||
reporte,
|
||||
flag,
|
||||
origen: { id_origen: origin.id_origen },
|
||||
});
|
||||
|
||||
// 3) Guarda y devuelve el ID
|
||||
const saved = await this.movRepo.save(movimiento);
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
/** Actualiza el status de un movimiento existente */
|
||||
async updateStatus(id_movimiento: number, nuevoStatus: string, observaciones?: string): Promise<void> {
|
||||
const movimiento = await this.movRepo.findOne({ where: { id_mov: id_movimiento } });
|
||||
|
||||
if (!movimiento) {
|
||||
throw new Error(`Movimiento con ID ${id_movimiento} no encontrado`);
|
||||
}
|
||||
|
||||
movimiento.status = nuevoStatus;
|
||||
movimiento.observaciones = observaciones || movimiento.observaciones; // opcional: actualizar observaciones
|
||||
movimiento.fecha_mov = new Date(); // opcional: actualizar fecha
|
||||
|
||||
await this.movRepo.save(movimiento);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Movimiento[]> {
|
||||
return await this.movRepo.find({ where: { origen: { origen: 'LOAD' } } });
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Usuario } from "src/entities/entities";
|
||||
import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from "typeorm";
|
||||
|
||||
@Entity({ name: 'servActivos' })
|
||||
export class ServActivos {
|
||||
@PrimaryGeneratedColumn({ name: 'id_servActivos' })
|
||||
id_servActivos: number;
|
||||
|
||||
@OneToOne(() => Usuario, (usuario) => usuario.servActivo, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id_usuario' })
|
||||
usuario: Usuario;
|
||||
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
Red: boolean;
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
Prestamos: boolean;
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
AT: boolean;
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
Correo: boolean;
|
||||
|
||||
@Column({ type: 'varchar', length: 40, nullable: true })
|
||||
RedStatus: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 40, nullable: true })
|
||||
PrestamosStatus: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 40, nullable: true })
|
||||
ATStatus: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 40, nullable: true })
|
||||
CorreoStatus: string;
|
||||
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@ export class UsuariosController {
|
||||
|
||||
@Get(':noCuenta')
|
||||
findOne(@Param('noCuenta') noCuenta: string) {
|
||||
return this.usuariosService.findOne(noCuenta);
|
||||
return this.usuariosService.findOneStatus(noCuenta);
|
||||
}
|
||||
// @UseGuards(AuthGuard('jwt'))
|
||||
// @ApiBearerAuth('bearer')
|
||||
|
||||
@@ -4,13 +4,16 @@ import { UsuariosController } from './usuarios.controller';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Carrera, CarreraUsuario, Genero, Usuario } from 'src/entities/entities';
|
||||
import { MovimientoModule } from 'src/movimiento/movimiento.module';
|
||||
import { ServActivos } from './entities/servActivos.entitie';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Usuario, Genero, Carrera, CarreraUsuario]),
|
||||
TypeOrmModule.forFeature([Usuario, Genero, Carrera, CarreraUsuario, ServActivos]),
|
||||
MovimientoModule
|
||||
|
||||
],
|
||||
controllers: [UsuariosController],
|
||||
providers: [UsuariosService],
|
||||
exports: [TypeOrmModule.forFeature([ServActivos])],
|
||||
})
|
||||
export class UsuariosModule { }
|
||||
|
||||
@@ -4,6 +4,7 @@ import { UpdateUsuarioDto } from './dto/update-usuario.dto';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { CarreraUsuario, Usuario } from 'src/entities/entities';
|
||||
import { Repository } from 'typeorm';
|
||||
import { ServActivos } from './entities/servActivos.entitie';
|
||||
|
||||
@Injectable()
|
||||
export class UsuariosService {
|
||||
@@ -12,47 +13,82 @@ export class UsuariosService {
|
||||
private readonly usuarioRepository: Repository<Usuario>,
|
||||
@InjectRepository(CarreraUsuario)
|
||||
private readonly carreraUsuarioRepository: Repository<CarreraUsuario>,
|
||||
@InjectRepository(ServActivos)
|
||||
private readonly servActivosRepository: Repository<ServActivos>,
|
||||
) { }
|
||||
|
||||
altaIndividual(createUsuarioDto: CreateUsuarioDto) {
|
||||
return 'This action adds a new usuario';
|
||||
}
|
||||
|
||||
async findOne(noCuenta: string) {
|
||||
async findOneStatus(noCuenta: string) {
|
||||
const usuario = await this.usuarioRepository.findOne({
|
||||
relations: [
|
||||
'genero',
|
||||
'carreraUsuarios',
|
||||
'carreraUsuarios.carrera',
|
||||
],
|
||||
where: { num_cuenta: noCuenta },
|
||||
|
||||
select: ['id_usuario'],
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!usuario) {
|
||||
throw new NotFoundException('Usuario no encontrado');
|
||||
}
|
||||
|
||||
const servActivo = await this.servActivosRepository.findOne({
|
||||
where: { usuario: { id_usuario: usuario.id_usuario } },
|
||||
|
||||
});
|
||||
if (!servActivo) {
|
||||
throw new NotFoundException('Servicios no encontrados para el usuario');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Transformar a formato plano
|
||||
const resultadoPlano = {
|
||||
num_cuenta: usuario.num_cuenta,
|
||||
nombre: usuario.nombre,
|
||||
a_paterno: usuario.a_paterno,
|
||||
a_materno: usuario.a_materno,
|
||||
fecha_nacimiento: usuario.fecha_nacimiento,
|
||||
generacion: usuario.generacion,
|
||||
genero: usuario.genero?.genero ?? '',
|
||||
carreras: (usuario.carreraUsuarios ?? [])
|
||||
.map(cu => cu.carrera?.carrera)
|
||||
.filter(Boolean)
|
||||
.join(', '), // todas las carreras como string plano
|
||||
};
|
||||
let resultadoPlano = {};
|
||||
|
||||
if (servActivo.AT) {
|
||||
resultadoPlano = {
|
||||
AT: servActivo.ATStatus
|
||||
}
|
||||
}
|
||||
if (servActivo.Red) {
|
||||
resultadoPlano = {
|
||||
...resultadoPlano,
|
||||
Red: servActivo.RedStatus
|
||||
}
|
||||
}
|
||||
if (servActivo.Prestamos) {
|
||||
resultadoPlano = {
|
||||
...resultadoPlano,
|
||||
Prestamos: servActivo.PrestamosStatus
|
||||
}
|
||||
}
|
||||
if (servActivo.Correo) {
|
||||
resultadoPlano = {
|
||||
...resultadoPlano,
|
||||
Correo: servActivo.CorreoStatus
|
||||
}
|
||||
}
|
||||
|
||||
// Si no hay servicios activos, retornar un objeto vacío
|
||||
if (Object.keys(resultadoPlano).length === 0) {
|
||||
resultadoPlano = {
|
||||
Servicios: 'No hay servicios activos para este usuario'
|
||||
};
|
||||
}
|
||||
console.log('Resultado plano:', resultadoPlano);
|
||||
|
||||
return [resultadoPlano]; // importante: frontend espera array
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
update(id: number, updateUsuarioDto: UpdateUsuarioDto) {
|
||||
return `This action updates a #${id} usuario`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user