Merge branch 'develop'
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
services:
|
||||
database:
|
||||
image: mariadb:latest
|
||||
@@ -12,7 +11,7 @@ services:
|
||||
env_file:
|
||||
- ../.env
|
||||
ports:
|
||||
- "${DB_PORT}:3306"
|
||||
- '${DB_PORT}:3306'
|
||||
volumes:
|
||||
- mariadb_data:/var/lib/mysql
|
||||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
|
||||
@@ -37,11 +37,10 @@ export class ExcelController {
|
||||
private readonly movimientoService: MovimientoService,
|
||||
private readonly mailService: MailService,
|
||||
private readonly usuarioService: UsuariosService, // Asegúrate de importar el servicio de correo
|
||||
) { }
|
||||
) {}
|
||||
|
||||
@Post('carga')
|
||||
async cargaUsuario(@Request() req, @Body() usuario: CreateUsuarioDto) {
|
||||
|
||||
if (req.user.origen != 'LOAD' && req.user.origen != 'EXTERNO') {
|
||||
throw new Error('Origen no permitido para carga');
|
||||
}
|
||||
@@ -110,7 +109,11 @@ export class ExcelController {
|
||||
@Post('load')
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
@ExcelDocumentation.loadExcel()
|
||||
async loadExcel(@Request() req, @UploadedFile() file: Express.Multer.File, @Query('function') funcion?: number) {
|
||||
async loadExcel(
|
||||
@Request() req,
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Query('function') funcion?: number,
|
||||
) {
|
||||
const origen = req.user.origen; // ahora sí existe
|
||||
|
||||
if (origen != 'LOAD') {
|
||||
@@ -123,19 +126,12 @@ export class ExcelController {
|
||||
}
|
||||
try {
|
||||
let result;
|
||||
if(funcion==2){
|
||||
result = await this.excelService.loadFile2(
|
||||
file.buffer,
|
||||
req.user.email,
|
||||
);
|
||||
}else{
|
||||
result = await this.excelService.loadFile(
|
||||
file.buffer,
|
||||
req.user.email,
|
||||
);
|
||||
if (funcion == 2) {
|
||||
result = await this.excelService.loadFile2(file.buffer, req.user.email);
|
||||
} else {
|
||||
result = await this.excelService.loadFile(file.buffer, req.user.email);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Actualizar el estado de los movimientos
|
||||
if (!result) {
|
||||
this.mailService.sendMail({
|
||||
@@ -248,12 +244,10 @@ export class ExcelController {
|
||||
'FAILED',
|
||||
'Origen no permitido para descarga',
|
||||
);
|
||||
return res
|
||||
.status(HttpStatus.FORBIDDEN)
|
||||
.json({
|
||||
statusCode: 403,
|
||||
message: 'Origen no permitido para descarga.',
|
||||
});
|
||||
return res.status(HttpStatus.FORBIDDEN).json({
|
||||
statusCode: 403,
|
||||
message: 'Origen no permitido para descarga.',
|
||||
});
|
||||
}
|
||||
} else if (origen == 'CORREO' || origen == 'LOAD') {
|
||||
try {
|
||||
@@ -334,17 +328,16 @@ export class ExcelController {
|
||||
'FAILED',
|
||||
'Origen no permitido para descarga',
|
||||
);
|
||||
return res
|
||||
.status(HttpStatus.FORBIDDEN)
|
||||
.json({
|
||||
statusCode: 403,
|
||||
message: 'Origen no permitido para descarga.',
|
||||
});
|
||||
return res.status(HttpStatus.FORBIDDEN).json({
|
||||
statusCode: 403,
|
||||
message: 'Origen no permitido para descarga.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//Agregarlo en su propio controller
|
||||
@Get('movimientos')
|
||||
@ExcelDocumentation.getMovimientos()
|
||||
async getMovimientos(
|
||||
@Request() req,
|
||||
@Query('page') page: number,
|
||||
@@ -369,18 +362,15 @@ export class ExcelController {
|
||||
return { message: 'Servicios activados correctamente' };
|
||||
}
|
||||
|
||||
@Get('cargaIndividual')
|
||||
async cargarIndividual(@Request() req) {
|
||||
const origen = req.user.origen; // ahora sí existe
|
||||
return this.movimientoService.findAllCargaIndv(origen);
|
||||
}
|
||||
|
||||
@Get('serv_act')
|
||||
async serv(){
|
||||
return await this.excelService.buscaAct()
|
||||
async serv() {
|
||||
return await this.excelService.buscaAct();
|
||||
}
|
||||
|
||||
|
||||
@Post('mov/:id_movimiento')
|
||||
async MOV(@Param('id_movimiento', ParseIntPipe) id_movimiento: number) {
|
||||
return await this.movimientoService.findAllWithRelations(id_movimiento);
|
||||
}
|
||||
// @Delete()
|
||||
// async borrar(){
|
||||
// return await this.excelService.borrarUsers()
|
||||
|
||||
@@ -1,16 +1,55 @@
|
||||
import { applyDecorators } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiConsumes, ApiBody, ApiResponse } from '@nestjs/swagger';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiConsumes,
|
||||
ApiBody,
|
||||
ApiResponse,
|
||||
ApiBearerAuth,
|
||||
ApiQuery,
|
||||
} from '@nestjs/swagger';
|
||||
|
||||
export class ExcelDocumentation {
|
||||
/**
|
||||
* Decorators Swagger para el endpoint POST /excel/verify
|
||||
*/
|
||||
static getMovimientos() {
|
||||
return applyDecorators(
|
||||
ApiBearerAuth(),
|
||||
ApiOperation({
|
||||
summary: 'Obtener movimientos',
|
||||
description:
|
||||
'Obtiene un listado paginado de movimientos según el origen del usuario autenticado.',
|
||||
}),
|
||||
ApiQuery({
|
||||
name: 'page',
|
||||
required: false,
|
||||
type: Number,
|
||||
example: 1,
|
||||
description: 'Número de página',
|
||||
}),
|
||||
ApiQuery({
|
||||
name: 'limit',
|
||||
required: false,
|
||||
type: Number,
|
||||
example: 10,
|
||||
description: 'Cantidad de registros por página',
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 200,
|
||||
description: 'Listado de movimientos obtenido correctamente',
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 401,
|
||||
description: 'No autorizado',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
static verifyExcel() {
|
||||
return applyDecorators(
|
||||
ApiTags('Excel'),
|
||||
ApiOperation({
|
||||
summary: 'Verificar archivo Excel',
|
||||
description: 'Valida duplicados, filas en blanco y formato básico de los datos sin realizar carga en la base.'
|
||||
description:
|
||||
'Valida duplicados, filas en blanco y formato básico de los datos sin realizar carga en la base.',
|
||||
}),
|
||||
ApiConsumes('multipart/form-data'),
|
||||
ApiBody({
|
||||
@@ -20,10 +59,10 @@ export class ExcelDocumentation {
|
||||
file: {
|
||||
type: 'string',
|
||||
format: 'binary',
|
||||
description: 'Archivo Excel (.xlsx) con usuarios a validar'
|
||||
}
|
||||
}
|
||||
}
|
||||
description: 'Archivo Excel (.xlsx) con usuarios a validar',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 200,
|
||||
@@ -35,12 +74,18 @@ export class ExcelDocumentation {
|
||||
errors: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
example: ['Fila 2: cuenta duplicada "42515101".', 'Fila 3: fecha de nacimiento inválida "1988051".']
|
||||
}
|
||||
}
|
||||
}
|
||||
example: [
|
||||
'Fila 2: cuenta duplicada "42515101".',
|
||||
'Fila 3: fecha de nacimiento inválida "1988051".',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 400,
|
||||
description: 'No se recibió archivo o formato inválido.',
|
||||
}),
|
||||
ApiResponse({ status: 400, description: 'No se recibió archivo o formato inválido.' })
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,7 +97,8 @@ export class ExcelDocumentation {
|
||||
ApiTags('Excel'),
|
||||
ApiOperation({
|
||||
summary: 'Cargar archivo Excel',
|
||||
description: 'Valida y persiste los datos en la base de datos. Retorna el número de registros insertados.'
|
||||
description:
|
||||
'Valida y persiste los datos en la base de datos. Retorna el número de registros insertados.',
|
||||
}),
|
||||
ApiConsumes('multipart/form-data'),
|
||||
ApiBody({
|
||||
@@ -62,10 +108,10 @@ export class ExcelDocumentation {
|
||||
file: {
|
||||
type: 'string',
|
||||
format: 'binary',
|
||||
description: 'Archivo Excel (.xlsx) con usuarios a cargar'
|
||||
}
|
||||
}
|
||||
}
|
||||
description: 'Archivo Excel (.xlsx) con usuarios a cargar',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 201,
|
||||
@@ -73,9 +119,9 @@ export class ExcelDocumentation {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
inserted: { type: 'number', example: 3 }
|
||||
}
|
||||
}
|
||||
inserted: { type: 'number', example: 3 },
|
||||
},
|
||||
},
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 400,
|
||||
@@ -86,52 +132,37 @@ export class ExcelDocumentation {
|
||||
errors: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
example: ['Fila 5: rfc contiene caracteres inválidos.']
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
example: ['Fila 5: rfc contiene caracteres inválidos.'],
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static downloadExcel() {
|
||||
return applyDecorators(
|
||||
ApiTags('Excel'),
|
||||
//ApiBearerAuth('bearer'),
|
||||
ApiOperation({
|
||||
summary: 'Descargar usuarios',
|
||||
description: 'Exporta todos los usuarios en un archivo TSV (o CSV) y registra el movimiento.'
|
||||
description:
|
||||
'Exporta todos los usuarios en un archivo TSV (o CSV) y registra el movimiento.',
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 200,
|
||||
description: 'TSV generado correctamente',
|
||||
content: {
|
||||
'text/tab-separated-values': {
|
||||
schema: { type: 'string', example: 'num_cuenta\\tnombre\\t...\\n...' }
|
||||
}
|
||||
}
|
||||
schema: {
|
||||
type: 'string',
|
||||
example: 'num_cuenta\\tnombre\\t...\\n...',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
ApiResponse({ status: 401, description: 'No autorizado' }),
|
||||
ApiResponse({ status: 500, description: 'Error al generar descarga' }),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+89
-137
@@ -34,7 +34,6 @@ export interface UsuarioRow {
|
||||
|
||||
@Injectable()
|
||||
export class ExcelService {
|
||||
|
||||
private readonly logger = new Logger(ExcelService.name);
|
||||
|
||||
constructor(
|
||||
@@ -59,7 +58,7 @@ export class ExcelService {
|
||||
private readonly dataSource: DataSource,
|
||||
|
||||
// … inyecta otros repositorios si los usarás
|
||||
) { }
|
||||
) {}
|
||||
|
||||
/** Lee el buffer del Excel y devuelve un arreglo de filas tipadas */
|
||||
private async parseFile(buffer: Buffer): Promise<UsuarioRow[]> {
|
||||
@@ -278,9 +277,8 @@ export class ExcelService {
|
||||
|
||||
// 🔹 3. Arreglos para inserciones masivas
|
||||
const usuarios: Usuario[] = [];
|
||||
const carrerasUsuario: CarreraUsuario[] = [];
|
||||
const usuariosTipos: UsuarioTipoUsuario[] = [];
|
||||
const serviciosActivos: ServActivos[] = [];
|
||||
|
||||
const usuariosConRow: { usuario: Usuario; row: any }[] = [];
|
||||
|
||||
let contador = 0;
|
||||
|
||||
@@ -345,50 +343,84 @@ export class ExcelService {
|
||||
});
|
||||
|
||||
usuarios.push(usuario);
|
||||
usuariosConRow.push({ usuario, row: r });
|
||||
}
|
||||
|
||||
await queryRunner.manager.save([...mapGenero.values()]);
|
||||
await queryRunner.manager.save([...mapCarreraClave.values()]);
|
||||
await queryRunner.manager.save([...mapTipo.values()]);
|
||||
|
||||
await queryRunner.manager.save(usuarios);
|
||||
|
||||
const carrerasUsuarioFinal: CarreraUsuario[] = [];
|
||||
|
||||
for (const { usuario, row } of usuariosConRow) {
|
||||
const carrera =
|
||||
(row.clave && mapCarreraClave.get(row.clave)) ||
|
||||
(row.nomCarr && mapCarreraNom.get(row.nomCarr));
|
||||
|
||||
if (carrera) {
|
||||
const carreraUsuario = queryRunner.manager.create(CarreraUsuario, {
|
||||
usuario,
|
||||
carrera,
|
||||
});
|
||||
carrerasUsuario.push(carreraUsuario);
|
||||
carrerasUsuarioFinal.push(
|
||||
queryRunner.manager.create(CarreraUsuario, {
|
||||
usuario,
|
||||
carrera,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
usuariosTipos.push(
|
||||
await queryRunner.manager.save(carrerasUsuarioFinal);
|
||||
|
||||
const usuariosTiposFinal: UsuarioTipoUsuario[] = [];
|
||||
|
||||
for (const { usuario, row } of usuariosConRow) {
|
||||
const tipo = mapTipo.get(row.tipo.trim());
|
||||
if (!tipo) continue;
|
||||
|
||||
usuariosTiposFinal.push(
|
||||
queryRunner.manager.create(UsuarioTipoUsuario, {
|
||||
usuario,
|
||||
tipoUsuario: tipo,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// Servicios activos
|
||||
const servData: Partial<ServActivos> = {
|
||||
await queryRunner.manager.save(usuariosTiposFinal);
|
||||
|
||||
const serviciosActivosFinal: ServActivos[] = [];
|
||||
|
||||
for (const { usuario, row } of usuariosConRow) {
|
||||
const serv = queryRunner.manager.create(ServActivos, {
|
||||
usuario,
|
||||
Red: false,
|
||||
AT: false,
|
||||
Correo: false,
|
||||
Prestamos: false,
|
||||
RedStatus: 'Inactivo',
|
||||
ATStatus: 'Inactivo',
|
||||
CorreoStatus: 'Inactivo',
|
||||
PrestamosStatus: 'Inactivo',
|
||||
};
|
||||
});
|
||||
|
||||
switch (r.tipo.trim()) {
|
||||
switch (row.tipo.trim()) {
|
||||
case 'Diplomado':
|
||||
Object.assign(servData, { Correo: true });
|
||||
Object.assign(serv, { Correo: true });
|
||||
conteoTiposCorreo++;
|
||||
break;
|
||||
case 'Extra Largo':
|
||||
Object.assign(servData, { Correo: true, Prestamos: true });
|
||||
Object.assign(serv, { Correo: true, Prestamos: true });
|
||||
conteoTiposCorreo++;
|
||||
conteoTiposSolicita++;
|
||||
break;
|
||||
case 'Servicio Social':
|
||||
Object.assign(servData, { Correo: true, AT: true, Red: true });
|
||||
Object.assign(serv, { Correo: true, AT: true, Red: true });
|
||||
conteoTiposCorreo++;
|
||||
conteoTiposAt++;
|
||||
conteoTiposRed++;
|
||||
break;
|
||||
case 'Idiomas R (UNAM)':
|
||||
case 'Idiomas Sabatino':
|
||||
Object.assign(servData, { Correo: true, Red: true });
|
||||
Object.assign(serv, { Correo: true, Red: true });
|
||||
conteoTiposCorreo++;
|
||||
conteoTiposRed++;
|
||||
break;
|
||||
@@ -399,7 +431,7 @@ export class ExcelService {
|
||||
case 'Ampliación de Conocimiento':
|
||||
case 'Licenciatura':
|
||||
case 'Profesor':
|
||||
Object.assign(servData, {
|
||||
Object.assign(serv, {
|
||||
Correo: true,
|
||||
AT: true,
|
||||
Red: true,
|
||||
@@ -411,79 +443,17 @@ export class ExcelService {
|
||||
conteoTiposSolicita++;
|
||||
break;
|
||||
case 'Trabajadores':
|
||||
Object.assign(servData, { Red: true });
|
||||
Object.assign(serv, { Red: true });
|
||||
conteoTiposRed++;
|
||||
break;
|
||||
}
|
||||
|
||||
serviciosActivos.push(
|
||||
queryRunner.manager.create(ServActivos, servData),
|
||||
);
|
||||
serviciosActivosFinal.push(serv);
|
||||
}
|
||||
|
||||
// 🔹 4. Guardar en batch (orden correcto)
|
||||
await queryRunner.manager.save([...mapGenero.values()]);
|
||||
await queryRunner.manager.save([...mapCarreraClave.values()]);
|
||||
await queryRunner.manager.save([...mapTipo.values()]);
|
||||
|
||||
// 1️⃣ Guardar usuarios primero — asigna IDs
|
||||
await queryRunner.manager.save(usuarios);
|
||||
|
||||
// 2️⃣ Reconstruir relaciones con usuarios ya guardados
|
||||
|
||||
// CarreraUsuario
|
||||
const carrerasUsuarioFinal: CarreraUsuario[] = [];
|
||||
for (const cu of carrerasUsuario) {
|
||||
const usuarioConId = usuarios.find(
|
||||
(u) => u.num_cuenta === cu.usuario.num_cuenta,
|
||||
);
|
||||
if (usuarioConId && cu.carrera) {
|
||||
carrerasUsuarioFinal.push(
|
||||
queryRunner.manager.create(CarreraUsuario, {
|
||||
usuario: usuarioConId,
|
||||
carrera: cu.carrera,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// UsuarioTipoUsuario
|
||||
const usuariosTiposFinal: UsuarioTipoUsuario[] = [];
|
||||
for (const ut of usuariosTipos) {
|
||||
const usuarioConId = usuarios.find(
|
||||
(u) => u.num_cuenta === ut.usuario.num_cuenta,
|
||||
);
|
||||
if (usuarioConId && ut.tipoUsuario) {
|
||||
usuariosTiposFinal.push(
|
||||
queryRunner.manager.create(UsuarioTipoUsuario, {
|
||||
usuario: usuarioConId,
|
||||
tipoUsuario: ut.tipoUsuario,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ServActivos
|
||||
const serviciosActivosFinal: ServActivos[] = [];
|
||||
for (const sa of serviciosActivos) {
|
||||
const usuarioConId = usuarios.find(
|
||||
(u) => u.num_cuenta === sa.usuario.num_cuenta,
|
||||
);
|
||||
if (usuarioConId) {
|
||||
serviciosActivosFinal.push(
|
||||
queryRunner.manager.create(ServActivos, {
|
||||
...sa,
|
||||
usuario: usuarioConId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 3️⃣ Guardar relaciones dependientes en orden
|
||||
await queryRunner.manager.save(carrerasUsuarioFinal);
|
||||
await queryRunner.manager.save(usuariosTiposFinal);
|
||||
await queryRunner.manager.save(serviciosActivosFinal);
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
return {
|
||||
inserted: rows.length - contador,
|
||||
id_movimiento: movimiento.id_mov,
|
||||
@@ -507,9 +477,6 @@ export class ExcelService {
|
||||
const errs = status.errors;
|
||||
const rows = status.rowsGood;
|
||||
|
||||
|
||||
|
||||
|
||||
if (rows.length === 0) {
|
||||
throw new BadRequestException(
|
||||
'No se encontraron filas válidas para cargar. ' + errs,
|
||||
@@ -524,7 +491,7 @@ export class ExcelService {
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
let idsUsuarios: number[] =[]
|
||||
let idsUsuarios: number[] = [];
|
||||
try {
|
||||
const movimiento = await this.movimientoService.logger(
|
||||
queryRunner,
|
||||
@@ -587,12 +554,13 @@ export class ExcelService {
|
||||
const serviciosActivos: ServActivos[] = [];
|
||||
|
||||
let contador = 0;
|
||||
|
||||
|
||||
for (const r of rows) {
|
||||
if (setCuentas.has(r.cuenta) || (r.rfc && setRfcs.has(r.rfc))) {
|
||||
const use= existentes.find( u => u.num_cuenta === r.cuenta || u.rfc === r.rfc)
|
||||
if(use?.id_usuario)
|
||||
idsUsuarios.push(use?.id_usuario)
|
||||
const use = existentes.find(
|
||||
(u) => u.num_cuenta === r.cuenta || u.rfc === r.rfc,
|
||||
);
|
||||
if (use?.id_usuario) idsUsuarios.push(use?.id_usuario);
|
||||
contador++;
|
||||
continue;
|
||||
}
|
||||
@@ -651,7 +619,7 @@ export class ExcelService {
|
||||
});
|
||||
|
||||
usuarios.push(usuario);
|
||||
|
||||
|
||||
if (carrera) {
|
||||
const carreraUsuario = queryRunner.manager.create(CarreraUsuario, {
|
||||
usuario,
|
||||
@@ -734,10 +702,8 @@ export class ExcelService {
|
||||
|
||||
// 1️⃣ Guardar usuarios primero — asigna IDs
|
||||
await queryRunner.manager.save(usuarios);
|
||||
idsUsuarios = usuarios.map(u => u.id_usuario);
|
||||
idsUsuarios.push(
|
||||
...existentes.map(e => e.id_usuario)
|
||||
);
|
||||
idsUsuarios = usuarios.map((u) => u.id_usuario);
|
||||
idsUsuarios.push(...existentes.map((e) => e.id_usuario));
|
||||
// 2️⃣ Reconstruir relaciones con usuarios ya guardados
|
||||
|
||||
// CarreraUsuario
|
||||
@@ -793,11 +759,6 @@ export class ExcelService {
|
||||
await queryRunner.manager.save(usuariosTiposFinal);
|
||||
await queryRunner.manager.save(serviciosActivosFinal);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
inserted: rows.length - contador,
|
||||
id_movimiento: movimiento.id_mov,
|
||||
@@ -812,26 +773,22 @@ export class ExcelService {
|
||||
throw err;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
|
||||
|
||||
await this.servActivosRepo
|
||||
.createQueryBuilder()
|
||||
.update()
|
||||
.set({
|
||||
Red: false,
|
||||
Prestamos: false,
|
||||
AT: false,
|
||||
Correo: false,
|
||||
RedStatus: 'Inactivo',
|
||||
PrestamosStatus: 'Inactivo',
|
||||
ATStatus: 'Inactivo',
|
||||
CorreoStatus: 'Inactivo',
|
||||
})
|
||||
.where('id_usuario NOT IN (:...ids)', { ids: idsUsuarios })
|
||||
.execute();
|
||||
|
||||
|
||||
|
||||
|
||||
.createQueryBuilder()
|
||||
.update()
|
||||
.set({
|
||||
Red: false,
|
||||
Prestamos: false,
|
||||
AT: false,
|
||||
Correo: false,
|
||||
RedStatus: 'Inactivo',
|
||||
PrestamosStatus: 'Inactivo',
|
||||
ATStatus: 'Inactivo',
|
||||
CorreoStatus: 'Inactivo',
|
||||
})
|
||||
.where('id_usuario NOT IN (:...ids)', { ids: idsUsuarios })
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1210,7 +1167,6 @@ export class ExcelService {
|
||||
'Carga de Usuarios',
|
||||
`Se ha realizado una carga de usuarios en el sistema. Nuevos: ${data?.nuevos ?? 0}, Actualizados: ${data?.actualizados ?? 0}`,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
async enviarInforme(
|
||||
@@ -1238,18 +1194,14 @@ export class ExcelService {
|
||||
}
|
||||
}
|
||||
|
||||
async buscaAct() {
|
||||
return await this.servActivosRepo.find({
|
||||
where: [
|
||||
{ AT: true },
|
||||
{ Correo: true },
|
||||
{ Prestamos: true },
|
||||
{ Red: true },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async buscaAct() {
|
||||
return await this.servActivosRepo.find({
|
||||
where: [
|
||||
{ AT: true },
|
||||
{ Correo: true },
|
||||
{ Prestamos: true },
|
||||
{ Red: true },
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export class MovimientoService {
|
||||
private readonly origenRepo: Repository<Origen>,
|
||||
@InjectRepository(Usuario)
|
||||
private readonly usuarioRepo: Repository<Usuario>,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
/** Crea un registro de movimiento */
|
||||
async log(
|
||||
@@ -54,7 +54,7 @@ export class MovimientoService {
|
||||
origenNombre: string,
|
||||
status: string,
|
||||
observaciones?: string,
|
||||
reporte?: string
|
||||
reporte?: string,
|
||||
): Promise<Movimiento> {
|
||||
const origenEntidad = await queryRunner.manager.findOne(Origen, {
|
||||
where: { origen: origenNombre },
|
||||
@@ -76,17 +76,21 @@ export class MovimientoService {
|
||||
return await queryRunner.manager.save(nuevoMov);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** 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 } });
|
||||
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`);
|
||||
}
|
||||
|
||||
console.log('movimiento' + movimiento);
|
||||
movimiento.status = nuevoStatus;
|
||||
movimiento.observaciones = observaciones || movimiento.observaciones; // opcional: actualizar observaciones
|
||||
movimiento.fecha_mov = new Date(); // opcional: actualizar fecha
|
||||
@@ -98,8 +102,12 @@ export class MovimientoService {
|
||||
origen: string,
|
||||
page: number = 1,
|
||||
limit: number = 10,
|
||||
): Promise<{ move: any[]; button: boolean; total?: number; lastPage?: number }> {
|
||||
|
||||
): Promise<{
|
||||
move: any[];
|
||||
button: boolean;
|
||||
total?: number;
|
||||
lastPage?: number;
|
||||
}> {
|
||||
if (origen === 'LOAD') {
|
||||
const [movimientos, total] = await this.movRepo.findAndCount({
|
||||
where: {
|
||||
@@ -136,8 +144,6 @@ export class MovimientoService {
|
||||
SOLICITA: 'Prestamos',
|
||||
} as const;
|
||||
|
||||
|
||||
|
||||
const field = statusFieldMap[origen as keyof typeof statusFieldMap];
|
||||
const origenField = FieldMap[origen as keyof typeof FieldMap];
|
||||
|
||||
@@ -147,7 +153,6 @@ export class MovimientoService {
|
||||
origen: { origen: 'LOAD' },
|
||||
status: 'SUCCESS',
|
||||
reporte: 'CARGA MASIVA DE USUARIOS',
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
@@ -156,23 +161,16 @@ export class MovimientoService {
|
||||
origen: { origen: 'SISTEMA' },
|
||||
status: 'SUCCESS',
|
||||
reporte: 'CARGA MASIVA WEB SERVICE',
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
const mov2 = await this.movRepo.find({
|
||||
where: {
|
||||
|
||||
reporte: 'CARGA INDIVIDUAL DE USUARIOS',
|
||||
status: 'SUCCESS',
|
||||
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
const todosLosMovimientos = [...movimientos, ...mov, ...mov2];
|
||||
return { move: todosLosMovimientos, button: false };
|
||||
}
|
||||
@@ -186,7 +184,7 @@ export class MovimientoService {
|
||||
servActivo: {
|
||||
[origenField]: true,
|
||||
|
||||
[field]: 'Inactivo'
|
||||
[field]: 'Inactivo',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -199,20 +197,19 @@ export class MovimientoService {
|
||||
usuario: {
|
||||
servActivo: {
|
||||
[origenField]: true,
|
||||
[field]: 'Inactivo'
|
||||
[field]: 'Inactivo',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const mov2 = await this.movRepo.find({
|
||||
where: {
|
||||
|
||||
reporte: 'CARGA INDIVIDUAL DE USUARIOS',
|
||||
status: 'SUCCESS',
|
||||
usuario: {
|
||||
servActivo: {
|
||||
[origenField]: true,
|
||||
[field]: 'Inactivo'
|
||||
[field]: 'Inactivo',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -224,7 +221,6 @@ export class MovimientoService {
|
||||
}
|
||||
|
||||
async findAllCargaIndv(origen): Promise<Usuario[]> {
|
||||
|
||||
const statusFieldMap = {
|
||||
AT: 'ATStatus',
|
||||
RED: 'RedStatus',
|
||||
@@ -239,10 +235,6 @@ export class MovimientoService {
|
||||
SOLICITA: 'Prestamos',
|
||||
} as const;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const field = statusFieldMap[origen as keyof typeof statusFieldMap];
|
||||
|
||||
const origenField = FieldMap[origen as keyof typeof FieldMap];
|
||||
@@ -254,7 +246,6 @@ export class MovimientoService {
|
||||
const usuarios = await this.usuarioRepo.find({
|
||||
where: {
|
||||
movimiento: {
|
||||
|
||||
reporte: 'CARGA INDIVIDUAL DE USUARIOS',
|
||||
},
|
||||
|
||||
@@ -262,18 +253,27 @@ export class MovimientoService {
|
||||
[field]: 'Inactivo',
|
||||
[origenField]: true,
|
||||
},
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
return usuarios;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async findAllWithRelations(id: number): Promise<Movimiento[]> {
|
||||
return await this.movRepo.find({
|
||||
where: { id_mov: id },
|
||||
relations: [
|
||||
'usuario',
|
||||
'origen',
|
||||
'usuario.servActivo',
|
||||
'usuario.carreraUsuarios',
|
||||
'usuario.carreraUsuarios.carrera',
|
||||
'usuario.usuarioTipos',
|
||||
'usuario.usuarioTipos.tipoUsuario',
|
||||
],
|
||||
order: {
|
||||
fecha_mov: 'DESC',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user