Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1abf4d4e9c | |||
| c73121f7df | |||
| 1a0af95c4e | |||
| 3ef076111e | |||
| 313bc7e632 | |||
| 29b0f2b3e5 | |||
| a387f11302 | |||
| e336f0bb86 | |||
| 017e6836e9 | |||
| 1155735d9d | |||
| e5f98c9596 | |||
| 24717cf931 | |||
| 02dd974fd6 | |||
| b6e7525dc2 | |||
| bc975bc295 | |||
| cb82dd3354 | |||
| a18fbe441d | |||
| c42c87e080 | |||
| 3bc245e1f7 | |||
| 5c5e7b3f0f | |||
| f50ce6d5f9 | |||
| 7933605cb1 | |||
| 963ec5a765 | |||
| 308f910bee | |||
| 29fdbee734 | |||
| ea14bfc96c | |||
| 9c677fa479 | |||
| 77f685e8d3 | |||
| 757fa541d8 | |||
| 0ee2f86c75 | |||
| 9d8c59d5ca | |||
| 592acee975 | |||
| c33817ace3 | |||
| bcb14ddeba | |||
| 0cf0c54879 | |||
| eb787c21e6 | |||
| 141afc824a | |||
| 617f4fe5bb | |||
| ad7fd3b513 | |||
| 71a24ca189 | |||
| ed5b64afb8 | |||
| c0178301ae | |||
| f70aa0f92e | |||
| 8762b51240 | |||
| c9cd073101 | |||
| 688e13b30c | |||
| 086af154cf | |||
| 400bffa254 | |||
| 61c164225c | |||
| 151d2e8718 | |||
| 62b71060be | |||
| 43abc72a38 | |||
| 04ad4923a5 | |||
| c40c82e7ba | |||
| 050c2b225c | |||
| ccd3781152 | |||
| 6a5d39d122 | |||
| 53c53d62a0 | |||
| 53ba7d45ff | |||
| 0ede1e8372 | |||
| 197b18910d | |||
| cafbce392d | |||
| a6efe25aa3 | |||
| 7b6b29b75f | |||
| 672f3579ac | |||
| 786f56442c | |||
| 90d791347e | |||
| 0aa5180154 | |||
| d6f5f645b8 | |||
| 115265381b | |||
| a851d31d3b | |||
| 29e4b4a7ad | |||
| cadb15a9cf | |||
| 83bbcee4ad | |||
| 8fac3a823a | |||
| b7d22cc07e | |||
| bba0aa12cc | |||
| ff6096f603 | |||
| 53b7d23007 | |||
| 8f68aadd8a | |||
| 9386fbc88d | |||
| 7686e26324 | |||
| 8f575aa662 | |||
| 19303178aa | |||
| 7d3a8ee5ed | |||
| 3aaf9ba0ed | |||
| af28549a04 | |||
| 50487e4859 | |||
| 6c22cfeeba | |||
| bf2367b366 | |||
| 0cb91d8b9e | |||
| 2ed657caf2 | |||
| 016297760f | |||
| 5f7ba5ff69 | |||
| bc4146a07d | |||
| 5567a26ed6 | |||
| 7a260169cc | |||
| 3e67102878 | |||
| 1c40eca428 | |||
| f62a868b97 | |||
| 65e0773337 | |||
| 671f989976 | |||
| 71e5ca35f9 | |||
| 6c0e263bf4 | |||
| aff3a44c09 | |||
| 083cefe84a | |||
| 340c0d59fd | |||
| 1b80de961b | |||
| 995a3a4e5e | |||
| a9b9b39285 | |||
| f25b60eccf | |||
| 0e6d6be3bb | |||
| 324ab9d35a | |||
| a6ee9decec | |||
| 75f55ba918 | |||
| e5a455bbb1 | |||
| 7b8514468f | |||
| 9d9df020db | |||
| 4770e95420 | |||
| c9c0a531f2 | |||
| cea20f387f | |||
| 373b99a57a | |||
| 6a871d8fa1 | |||
| 09e12161bd | |||
| b771ca2e57 | |||
| 4427804865 | |||
| f06decdc43 |
+7
-1
@@ -2,7 +2,8 @@
|
|||||||
/dist
|
/dist
|
||||||
/node_modules
|
/node_modules
|
||||||
/build
|
/build
|
||||||
|
/server/uploads
|
||||||
|
/server
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
@@ -12,6 +13,8 @@ yarn-debug.log*
|
|||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
|
|
||||||
|
/initdb/init.sql
|
||||||
|
/initdb2
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
@@ -19,6 +22,9 @@ lerna-debug.log*
|
|||||||
/coverage
|
/coverage
|
||||||
/.nyc_output
|
/.nyc_output
|
||||||
|
|
||||||
|
# Ignorar credenciales sensibles
|
||||||
|
cred.json
|
||||||
|
|
||||||
# IDEs and editors
|
# IDEs and editors
|
||||||
/.idea
|
/.idea
|
||||||
.project
|
.project
|
||||||
|
|||||||
+11
-26
@@ -1,33 +1,18 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mysql:
|
database:
|
||||||
image: mariadb:latest
|
image: mariadb:latest
|
||||||
container_name: Iris_db
|
container_name: Iris_db
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: root
|
MARIADB_ROOT_PASSWORD: root
|
||||||
MYSQL_DATABASE: Iris
|
MARIADB_DATABASE: Iris_testDB
|
||||||
MYSQL_USER: user_crud
|
MARIADB_USER: root
|
||||||
MYSQL_PASSWORD: root
|
MARIADB_PASSWORD: root
|
||||||
|
ports:
|
||||||
|
- '3306:3306'
|
||||||
volumes:
|
volumes:
|
||||||
- ./mysql:/var/lib/mysql
|
- mariadb_data:/var/lib/mysql
|
||||||
ports:
|
- ./initdb2:/docker-entrypoint-initdb.dP
|
||||||
- "3307:3306"
|
|
||||||
|
|
||||||
nest-app:
|
volumes:
|
||||||
build:
|
mariadb_data:
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
container_name: Iris_app
|
|
||||||
restart: always
|
|
||||||
depends_on:
|
|
||||||
- mysql
|
|
||||||
environment:
|
|
||||||
DATABASE_HOST: mysql
|
|
||||||
DATABASE_PORT: 3306
|
|
||||||
DATABASE_USER: user_crud
|
|
||||||
DATABASE_PASSWORD: root
|
|
||||||
DATABASE_NAME: Iris
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
DB_USERNAME=
|
||||||
|
DB_DATABASE=
|
||||||
|
DB_PASSWORD=
|
||||||
|
DB_PORT=
|
||||||
|
DB_HOST=
|
||||||
|
PORT=
|
||||||
|
JWT=
|
||||||
|
CARPETA=
|
||||||
|
MAIL_URL=
|
||||||
|
MAIL_TOKEN=
|
||||||
|
ESCOLARES=
|
||||||
|
ESCOLARES_PASS=
|
||||||
File diff suppressed because one or more lines are too long
Generated
+924
-1048
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -8,7 +8,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nest build",
|
"build": "nest build",
|
||||||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||||
"start": "nest start",
|
"start": "source ~/.nvm/nvm.sh && nvm use 22.10.0 && npm install && nest start",
|
||||||
"start:dev": "nest start --watch",
|
"start:dev": "nest start --watch",
|
||||||
"start:debug": "nest start --debug --watch",
|
"start:debug": "nest start --debug --watch",
|
||||||
"start:prod": "node dist/main",
|
"start:prod": "node dist/main",
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
"@nestjs/mapped-types": "*",
|
"@nestjs/mapped-types": "*",
|
||||||
"@nestjs/passport": "^11.0.5",
|
"@nestjs/passport": "^11.0.5",
|
||||||
"@nestjs/platform-express": "^11.1.6",
|
"@nestjs/platform-express": "^11.1.6",
|
||||||
|
"@nestjs/schedule": "^6.1.0",
|
||||||
"@nestjs/typeorm": "^11.0.0",
|
"@nestjs/typeorm": "^11.0.0",
|
||||||
"argon2": "^0.44.0",
|
"argon2": "^0.44.0",
|
||||||
"axios": "^1.12.2",
|
"axios": "^1.12.2",
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
"@swc/core": "^1.13.5",
|
"@swc/core": "^1.13.5",
|
||||||
"@types/express": "^5.0.3",
|
"@types/express": "^5.0.3",
|
||||||
"@types/jest": "^30.0.0",
|
"@types/jest": "^30.0.0",
|
||||||
|
"@types/moment": "^2.11.29",
|
||||||
"@types/multer": "^2.0.0",
|
"@types/multer": "^2.0.0",
|
||||||
"@types/node": "^24.5.2",
|
"@types/node": "^24.5.2",
|
||||||
"@types/supertest": "^6.0.3",
|
"@types/supertest": "^6.0.3",
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
|||||||
|
numeroCuenta,nombre,licenciatura,correo,fechaInicio,fechaFin,fechaLiberacion,institucion,dependencia,programa,profesor,clave,status
|
||||||
|
315040357,RAMIREZ AVILA MELANY BETSABE,LIC. EN HISTORIA,424018289@pcpuma.acatlan.unam.mx,29/7/2024,3/12/2025,"",Instituto Nacional De Antropologia E Historia,Museo Nacional De Antropologia,"Investigación, conservación y difusión del patrimonio arqueológico y etnográfico de México","",2024-21/7-1471,Pre-Termino
|
||||||
|
319304899,ASCENCIO DIAZ ENRIQUE,LIC. EN ACTUARIA,424018289@pcpuma.acatlan.unam.mx,27/10/2024,1/12/2025,"",UNAM,FES ACATLAN,Acatlán Contigo,Act. Jorge Carmona Mendoza,2025-12/145-24,Cancelado
|
||||||
|
421039812,ARTEAGA GONZALEZ RUBEN MAURICIO,LIC. EN COMUNICACION,424018289@pcpuma.acatlan.unam.mx,29/12/2024,"","",UNAM,FES ACATLAN,Acatlán Contigo,MTRO. SERGIO ARTEMIO GUILLERMO VALENTÍN,2024-12/20-530,Pre-Termino
|
||||||
|
319302187,PEREZ CENTENO JORGE,LIC. EN CIENCIAS POLITICAS Y ADMON PUB,pcentenojorge15@gmail.com,1/12/2025,8/12/2025,"",UNAM,FES ACATLAN,Acatlán Contigo,Antonio Faustino Torres,2025-12/145-24,Pre-Registro
|
||||||
|
413076379,JIMENEZ GONZALEZ JAZMIN ALEJANDRA,LIC. EN MATEMATICAS APLICADAS Y COMP.,424018289@pcpuma.acatlan.unam.mx,1/12/2025,4/12/2025,"",UNAM,FES ACATLAN,Acatlán Contigo,xxxx,2025-12/145-24,Carta Aceptación Rechazada
|
||||||
|
421162888,DREW IBARRA EDUARDO CARLOS,LIC. ENSEÑANZA DE ESPAÑOL(LENG. EXTRANJ),424018289@pcpuma.acatlan.unam.mx,17/12/2025,11/12/2025,"",UNIVERSIDAD NACIONAL AUTONOMA DE MEXICO,ESCUELA DE EXTENSIÓN EN CHICAGO,Enseñanza de Español como Lengua Extranjera,"",2024-12/226-2509,Pre-Termino
|
||||||
|
419089577,GUTIERREZ GUTIERREZ DIANA ANGELICA,LIC. EN ARQUITECTURA,320154041@pcpuma.acatlan.unam.mx,19/12/2025,18/6/2026,"",UNAM,FES ACATLAN,Titulación por servicio social,LIC. MARCELA MARTÍNEZ RANGEL,2023-12/20-222,Cancelado
|
||||||
|
422116468,CONTRERAS GONZALEZ ANA CRISTINA,LIC. EN ECONOMIA,424018289@pcpuma.acatlan.unam.mx,28/12/2025,"","",Secretaria De Agricultura Y Desarrollo Rural,Liconsa. S.a De C.v.,SERVICIO SOCIAL LICONSA OFICINA CENTRAL,"",2025-192/1-2689,Pre-Registro
|
||||||
|
+20
-15
@@ -14,25 +14,27 @@ import { ServicioModule } from './servicio/servicio.module';
|
|||||||
import { StatusModule } from './status/status.module';
|
import { StatusModule } from './status/status.module';
|
||||||
import { TipoUsuarioModule } from './tipo-usuario/tipo-usuario.module';
|
import { TipoUsuarioModule } from './tipo-usuario/tipo-usuario.module';
|
||||||
import { UsuarioModule } from './usuario/usuario.module';
|
import { UsuarioModule } from './usuario/usuario.module';
|
||||||
|
import { AuthModule } from './auth/auth.module';
|
||||||
|
import { DriveModule } from './drive/drive.module';
|
||||||
|
import { ScheduleModule } from '@nestjs/schedule';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot(
|
ScheduleModule.forRoot(),
|
||||||
{isGlobal: true}
|
ConfigModule.forRoot({ isGlobal: true }),
|
||||||
),
|
|
||||||
|
|
||||||
TypeOrmModule.forRoot({
|
TypeOrmModule.forRoot({
|
||||||
type: 'mysql',
|
type: 'mariadb',
|
||||||
host: process.env.db_host,
|
host: process.env.DB_HOST,
|
||||||
username: process.env.db_username,
|
username: process.env.DB_USERNAME,
|
||||||
database: process.env.db_database,
|
database: process.env.DB_DATABASE,
|
||||||
password: process.env.db_password,
|
password: process.env.DB_PASSWORD,
|
||||||
port: Number(process.env.db_port),
|
port: Number(process.env.DB_PORT),
|
||||||
synchronize: true,
|
synchronize: false, //Lo ponemos en false para no afectar
|
||||||
dropSchema: false, // elimina la base de datos
|
dropSchema: false,
|
||||||
// logging: true, // Habilita los logs para depuración
|
autoLoadEntities: true,
|
||||||
autoLoadEntities: true, // Carga automáticamente las entidades
|
logger: 'advanced-console',
|
||||||
|
logging: 'all',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
CarreraModule,
|
CarreraModule,
|
||||||
@@ -53,12 +55,15 @@ import { UsuarioModule } from './usuario/usuario.module';
|
|||||||
|
|
||||||
StatusModule,
|
StatusModule,
|
||||||
|
|
||||||
|
AuthModule,
|
||||||
|
|
||||||
TipoUsuarioModule,
|
TipoUsuarioModule,
|
||||||
|
|
||||||
UsuarioModule,
|
UsuarioModule,
|
||||||
|
|
||||||
|
DriveModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService],
|
providers: [AppService],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule { }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { AuthService } from './auth.service';
|
|||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private readonly authService: AuthService) {}
|
constructor(private readonly authService: AuthService) { }
|
||||||
|
|
||||||
// ===================== LOGIN =====================
|
// ===================== LOGIN =====================
|
||||||
@Post('login')
|
@Post('login')
|
||||||
@@ -36,4 +36,15 @@ export class AuthController {
|
|||||||
throw new UnauthorizedException(error.message);
|
throw new UnauthorizedException(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===================== ACTUALIZAR CONTRASEÑA ADMIN =====================
|
||||||
|
@Post('update-password')
|
||||||
|
async updatePassword() {
|
||||||
|
try {
|
||||||
|
const newPassword = await this.authService.update_password();
|
||||||
|
return { message: 'Contraseña actualizada correctamente.', contraseña: newPassword };
|
||||||
|
} catch (error) {
|
||||||
|
throw new UnauthorizedException(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-5
@@ -1,18 +1,27 @@
|
|||||||
import { JwtModule } from '@nestjs/jwt';
|
import { JwtModule, JwtService } from '@nestjs/jwt';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { AuthController } from './auth.controller';
|
||||||
|
import { JwtStrategy } from './jwt.strategy';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
ConfigModule.forRoot(),
|
||||||
TypeOrmModule.forFeature([Usuario]),
|
TypeOrmModule.forFeature([Usuario]),
|
||||||
JwtModule.register({
|
JwtModule.registerAsync({
|
||||||
secret: process.env.JWT, // Usa un .env en producción
|
imports: [ConfigModule],
|
||||||
signOptions: { expiresIn: '1h' },
|
useFactory: async (configService: ConfigService) => ({
|
||||||
|
secret: configService.get('JWT') || 'clave_temporal_desarrollo',
|
||||||
|
signOptions: { expiresIn: '1h' },
|
||||||
|
}),
|
||||||
|
inject: [ConfigService],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [AuthService],
|
controllers: [AuthController],
|
||||||
|
providers: [AuthService, JwtStrategy],
|
||||||
exports: [AuthService],
|
exports: [AuthService],
|
||||||
})
|
})
|
||||||
export class AuthModule {}
|
export class AuthModule {}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {
|
|||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { bcrypt } from 'bcrypt';
|
|
||||||
|
|
||||||
import { Carrera } from 'src/carrera/entities/carrera.entity';
|
import { Carrera } from 'src/carrera/entities/carrera.entity';
|
||||||
import { gmail } from 'src/helpers.services/gmail.service';
|
import { gmail } from 'src/helpers.services/gmail.service';
|
||||||
@@ -15,6 +14,7 @@ import { Servicio } from 'src/servicio/entities/servicio.entity';
|
|||||||
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
import { Like, Not, Repository } from 'typeorm';
|
import { Like, Not, Repository } from 'typeorm';
|
||||||
import * as argon2 from 'argon2';
|
import * as argon2 from 'argon2';
|
||||||
|
import * as bcrypt from 'bcrypt';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
@@ -23,7 +23,7 @@ export class AuthService {
|
|||||||
|
|
||||||
@InjectRepository(Usuario)
|
@InjectRepository(Usuario)
|
||||||
private readonly userRepo: Repository<Usuario>,
|
private readonly userRepo: Repository<Usuario>,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async jwtVerificar(token: string) {
|
async jwtVerificar(token: string) {
|
||||||
try {
|
try {
|
||||||
@@ -48,7 +48,7 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async comparar(password, dbPassword) {
|
async comparar(password, dbPassword) {
|
||||||
if (await argon2.verify(password, dbPassword)) {
|
if (await bcrypt.compare(password, dbPassword)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -56,7 +56,8 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async encriptar(password) {
|
async encriptar(password) {
|
||||||
return await argon2.hash(password);
|
const saltRounds = 10;
|
||||||
|
return await bcrypt.hash(password, saltRounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
async generarPassword() {
|
async generarPassword() {
|
||||||
@@ -72,16 +73,49 @@ export class AuthService {
|
|||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async update_password() {
|
||||||
|
let user = await this.userRepo.findOne({ where: { tipoUsuario: { idTipoUsuario: 1 } } })
|
||||||
|
|
||||||
|
if (!user) throw new NotFoundException('No se encontró el usuario administrador.');
|
||||||
|
const newPassword = await this.generarPassword();
|
||||||
|
const hashedPassword = await this.encriptar(newPassword);
|
||||||
|
user.password = hashedPassword;
|
||||||
|
await this.userRepo.save(user);
|
||||||
|
return newPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async login(usuario: string, password: string) {
|
async login(usuario: string, password: string) {
|
||||||
const user = await this.userRepo.findOne({ where: { usuario } });
|
const user = await this.userRepo.findOne({
|
||||||
|
where: { usuario },
|
||||||
|
relations: ['tipoUsuario'],
|
||||||
|
});
|
||||||
|
|
||||||
if (!user) throw new UnauthorizedException('No existe este usuario.');
|
if (!user) throw new UnauthorizedException('No existe este usuario.');
|
||||||
|
|
||||||
const match = await this.comparar(password, user.password);
|
const match = await this.comparar(password, user.password);
|
||||||
if (!match) throw new UnauthorizedException('Credenciales inválidas');
|
if (!match) throw new UnauthorizedException('Credenciales inválidas');
|
||||||
if (!user.activo) throw new Error('Este usuario no esta activo.');
|
|
||||||
const token = this.jwtCreate(
|
if (!user.activo) throw new BadRequestException('Este usuario no esta activo.');
|
||||||
|
|
||||||
|
const token = await this.jwtCreate(
|
||||||
user.idUsuario,
|
user.idUsuario,
|
||||||
user.tipoUsuario.idTipoUsuario,
|
user.tipoUsuario.idTipoUsuario,
|
||||||
);
|
);
|
||||||
return token;
|
|
||||||
|
return {
|
||||||
|
token: token.access_token,
|
||||||
|
Usuario: {
|
||||||
|
idUsuario: user.idUsuario,
|
||||||
|
usuario: user.usuario,
|
||||||
|
nombre: user.nombre || '',
|
||||||
|
TipoUsuario: {
|
||||||
|
idTipoUsuario: user.tipoUsuario.idTipoUsuario,
|
||||||
|
tipoUsuario: user.tipoUsuario.tipoUsuario || '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||||
constructor() {
|
constructor(private configService: ConfigService) {
|
||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
secretOrKey: process.env.JWT_SECRET,
|
secretOrKey: configService.get('JWT') || 'clave_temporal_desarrollo',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(payload: any) {
|
async validate(payload: any) {
|
||||||
// payload contiene los datos del usuario que se pusieron al generar el token
|
return {
|
||||||
// ejemplo: { sub: 123, email: "user@example.com" }
|
userId: payload.Usuario,
|
||||||
return { userId: payload.sub, email: payload.email };
|
tipoUsuario: payload.tipoUsuario,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
import {
|
|
||||||
Controller,
|
|
||||||
Get,
|
|
||||||
Post,
|
|
||||||
Body,
|
|
||||||
Patch,
|
|
||||||
Param,
|
|
||||||
Delete,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { CarreraService } from './carrera.service';
|
|
||||||
import { CreateCarreraDto } from './dto/create-carrera.dto';
|
|
||||||
import { UpdateCarreraDto } from './dto/update-carrera.dto';
|
|
||||||
|
|
||||||
@Controller('carrera')
|
|
||||||
export class CarreraController {
|
|
||||||
constructor(private readonly carreraService: CarreraService) {}
|
|
||||||
|
|
||||||
@Post()
|
|
||||||
create(@Body() createCarreraDto: CreateCarreraDto) {
|
|
||||||
return this.carreraService.create(createCarreraDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get()
|
|
||||||
findAll() {
|
|
||||||
return this.carreraService.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get(':id')
|
|
||||||
findOne(@Param('id') id: string) {
|
|
||||||
return this.carreraService.findOne(+id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Patch(':id')
|
|
||||||
update(@Param('id') id: string, @Body() updateCarreraDto: UpdateCarreraDto) {
|
|
||||||
return this.carreraService.update(+id, updateCarreraDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Delete(':id')
|
|
||||||
remove(@Param('id') id: string) {
|
|
||||||
return this.carreraService.remove(+id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { Carrera } from './entities/carrera.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
controllers: [],
|
imports: [TypeOrmModule.forFeature([Carrera])],
|
||||||
providers: [],
|
exports: [TypeOrmModule],
|
||||||
exports: [],
|
|
||||||
})
|
})
|
||||||
export class CarreraModule {}
|
export class CarreraModule {}
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import { CasoEspecial } from "src/caso-especial/entities/caso-especial.entity";
|
import { CasoEspecial } from 'src/caso-especial/entities/caso-especial.entity';
|
||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { Column, Entity, ManyToMany, OneToMany, PrimaryGeneratedColumn } from "typeorm";
|
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
|
||||||
|
|
||||||
|
|
||||||
@Entity('carrera')
|
@Entity('carrera')
|
||||||
export class Carrera {
|
export class Carrera {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn({ name: 'idCarrera' })
|
||||||
idCarrera:number;
|
idCarrera: number;
|
||||||
|
|
||||||
@Column({type: 'varchar', length: 50, nullable: false})
|
@Column({ type: 'varchar', length: 50 })
|
||||||
carrera:string;
|
carrera: string;
|
||||||
|
|
||||||
@OneToMany(()=>Servicio, (servicio)=>servicio.carrera)
|
@OneToMany(() => CasoEspecial, (casoEspecial) => casoEspecial.carrera)
|
||||||
servicio:Servicio[];
|
casosEspeciales: CasoEspecial[];
|
||||||
|
|
||||||
@OneToMany(()=>CasoEspecial,(casoEspecial)=>casoEspecial.carrera)
|
@OneToMany(() => Servicio, (servicio) => servicio.carrera)
|
||||||
casoEspecial:CasoEspecial[];
|
servicios: Servicio[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
UploadedFile,
|
UploadedFile,
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
Put,
|
Put,
|
||||||
|
Query,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { CasoEspecialService } from './caso-especial.service';
|
import { CasoEspecialService } from './caso-especial.service';
|
||||||
import { CreateCasoEspecialDto } from './dto/create-caso-especial.dto';
|
import { CreateCasoEspecialDto } from './dto/create-caso-especial.dto';
|
||||||
@@ -21,13 +22,18 @@ import { diskStorage } from 'multer';
|
|||||||
import { extname } from 'path';
|
import { extname } from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { FilterCasoEspecialDto } from './dto/filter-caso-especial.dto';
|
import { FilterCasoEspecialDto } from './dto/filter-caso-especial.dto';
|
||||||
|
import { DriveService } from 'src/drive/drive.service';
|
||||||
|
import { plainToInstance } from 'class-transformer';
|
||||||
|
|
||||||
@Controller('caso-especial')
|
@Controller('caso-especial')
|
||||||
export class CasoEspecialController {
|
export class CasoEspecialController {
|
||||||
constructor(private readonly casoEspecialService: CasoEspecialService) {}
|
constructor(private readonly casoEspecialService: CasoEspecialService,
|
||||||
|
private drive: DriveService,
|
||||||
|
|
||||||
|
) { }
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@UseGuards(AuthGuard('jwt')) // reemplaza verificaToken
|
@UseGuards(AuthGuard('jwt'))
|
||||||
@UseInterceptors(
|
@UseInterceptors(
|
||||||
FileInterceptor('archivos', {
|
FileInterceptor('archivos', {
|
||||||
storage: diskStorage({
|
storage: diskStorage({
|
||||||
@@ -41,27 +47,42 @@ export class CasoEspecialController {
|
|||||||
)
|
)
|
||||||
async subirArchivo(
|
async subirArchivo(
|
||||||
@UploadedFile() file: Express.Multer.File,
|
@UploadedFile() file: Express.Multer.File,
|
||||||
@Body('alumno') alumno: CreateCasoEspecialDto,
|
@Body('alumno') alumno: string, // 👈 STRING
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const data = await this.casoEspecialService.create(alumno, file.filename);
|
const alumnoParsed = plainToInstance(
|
||||||
|
CreateCasoEspecialDto,
|
||||||
|
JSON.parse(alumno),
|
||||||
|
);
|
||||||
|
|
||||||
|
return await this.casoEspecialService.create(
|
||||||
|
alumnoParsed,
|
||||||
|
file.filename,
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
if (file?.filename) {
|
||||||
|
fs.unlinkSync(`./server/uploads/${file.filename}`);
|
||||||
|
}
|
||||||
|
throw new BadRequestException(err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Get('carpeta')
|
||||||
|
async carpeta() {
|
||||||
|
try {
|
||||||
|
const data = await this.drive.folder('123456789');
|
||||||
|
console.log(data);
|
||||||
return {
|
return {
|
||||||
statusCode: 201,
|
statusCode: 200,
|
||||||
message: 'Archivo subido con éxito',
|
|
||||||
data,
|
data,
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Si hay error, eliminar archivo subido
|
|
||||||
if (file && file.filename) {
|
|
||||||
fs.unlinkSync(`./server/uploads/${file.filename}`);
|
|
||||||
}
|
|
||||||
throw new BadRequestException(err.message);
|
throw new BadRequestException(err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('servicios_especiales')
|
@Get('servicios_especiales')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
async getServiciosEspeciales(@Body() dtoServEsp: FilterCasoEspecialDto) {
|
async getServiciosEspeciales(@Query() dtoServEsp: FilterCasoEspecialDto) {
|
||||||
try {
|
try {
|
||||||
const data = await this.casoEspecialService.findAllFiltered(dtoServEsp);
|
const data = await this.casoEspecialService.findAllFiltered(dtoServEsp);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ import { DriveService } from 'src/drive/drive.service';
|
|||||||
import { Status } from 'src/status/entities/status.entity';
|
import { Status } from 'src/status/entities/status.entity';
|
||||||
import { FilterCasoEspecialDto } from './dto/filter-caso-especial.dto';
|
import { FilterCasoEspecialDto } from './dto/filter-caso-especial.dto';
|
||||||
import { arch } from 'os';
|
import { arch } from 'os';
|
||||||
|
import { SendMailDto } from 'src/helpers.services/dto/send-email.dto';
|
||||||
|
const {
|
||||||
|
|
||||||
|
terminoValidado
|
||||||
|
} = require('./../helpers.services/msjCorreos');
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CasoEspecialService {
|
export class CasoEspecialService {
|
||||||
@@ -31,7 +37,7 @@ export class CasoEspecialService {
|
|||||||
private validacion: ValidacionService,
|
private validacion: ValidacionService,
|
||||||
private gmail: gmail,
|
private gmail: gmail,
|
||||||
private drive: DriveService,
|
private drive: DriveService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async create(body: CreateCasoEspecialDto, file: string) {
|
async create(body: CreateCasoEspecialDto, file: string) {
|
||||||
const {
|
const {
|
||||||
@@ -51,71 +57,69 @@ export class CasoEspecialService {
|
|||||||
motivo = '',
|
motivo = '',
|
||||||
} = body;
|
} = body;
|
||||||
|
|
||||||
const usuario = await this.usuarioRepository.findOneBy({
|
const usuario = await this.usuarioRepository.findOne({
|
||||||
idUsuario: idUsuario,
|
where: { idUsuario },
|
||||||
|
relations: ['tipoUsuario'],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!usuario)
|
if (!usuario)
|
||||||
throw new NotFoundException('Este alumno no existe en la db.');
|
throw new NotFoundException('Este alumno no existe en la db.');
|
||||||
if (usuario.tipoUsuario.idTipoUsuario !== 3)
|
if (usuario.tipoUsuario.idTipoUsuario !== 3)
|
||||||
throw new BadRequestException('Este usuario no es de tipo Alumno.');
|
throw new BadRequestException('Este usuario no es de tipo Alumno.');
|
||||||
|
|
||||||
const carrera = await this.carreraRepository.findOneBy({
|
const carrera = await this.carreraRepository.findOneBy({ idCarrera });
|
||||||
idCarrera: idCarrera,
|
|
||||||
});
|
|
||||||
if (!carrera)
|
if (!carrera)
|
||||||
throw new NotFoundException('Esta carrera no existe en la db.');
|
throw new NotFoundException('Esta carrera no existe en la db.');
|
||||||
|
|
||||||
const casoExistente = await this.casoEspecialRepository.findOne({
|
const casoExistente = await this.casoEspecialRepository.findOne({
|
||||||
where: { usuario: usuario },
|
where: { usuario: { idUsuario } },
|
||||||
});
|
});
|
||||||
if (casoExistente)
|
if (casoExistente)
|
||||||
throw new BadRequestException('Este alumno ya tiene un Caso Especial.');
|
throw new BadRequestException('Este alumno ya tiene un Caso Especial.');
|
||||||
|
|
||||||
const path = `./server/uploads/${file}`;
|
const path = `./server/uploads/${file}`;
|
||||||
const carpeta = await this.drive.folder(numeroCuenta);
|
const carpeta = await this.drive.folder(numeroCuenta);
|
||||||
if (!carpeta) {
|
if (!carpeta) throw new BadRequestException('No se pudo crear la carpeta en Drive.');
|
||||||
throw new Error('No se pudo crear la carpeta en Drive.');
|
|
||||||
}
|
|
||||||
const archivoZip = await this.drive.uploadFile(
|
const archivoZip = await this.drive.uploadFile(
|
||||||
path,
|
path,
|
||||||
`archivos.zip`,
|
'archivos.zip',
|
||||||
'application/zip',
|
'application/zip',
|
||||||
carpeta,
|
carpeta,
|
||||||
);
|
);
|
||||||
|
if (!archivoZip)
|
||||||
|
throw new BadRequestException('No se pudo subir el archivo a Drive.');
|
||||||
|
|
||||||
const status = await this.statusRepository.findOne({
|
const status = await this.statusRepository.findOneBy({ idStatus });
|
||||||
where: { idStatus: idStatus },
|
if (!status)
|
||||||
});
|
throw new NotFoundException('Este status no existe en la db.');
|
||||||
|
|
||||||
if (!status) throw new NotFoundException('Este status no existe en la db.');
|
|
||||||
if (archivoZip === null)
|
|
||||||
throw new Error('No se pudo subir el archivo a Drive.');
|
|
||||||
|
|
||||||
const nuevoCaso = this.casoEspecialRepository.create({
|
const nuevoCaso = this.casoEspecialRepository.create({
|
||||||
correo: correo,
|
correo,
|
||||||
telefono: telefono,
|
telefono,
|
||||||
institucion: institucion,
|
institucion,
|
||||||
dependencia: dependencia,
|
dependencia,
|
||||||
motivo: motivo,
|
motivo,
|
||||||
direccion: direccion,
|
direccion,
|
||||||
fechaInicio: fechaInicio,
|
fechaInicio,
|
||||||
fechaFin: fechaFin,
|
fechaFin,
|
||||||
fechaNacimiento: fechaNacimiento,
|
fechaNacimiento,
|
||||||
carpeta: carpeta,
|
carpeta,
|
||||||
archivoZip: archivoZip,
|
archivoZip,
|
||||||
usuario: usuario,
|
usuario,
|
||||||
carrera: carrera,
|
carrera,
|
||||||
status: status,
|
status,
|
||||||
creditos: creditos,
|
creditos,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.casoEspecialRepository.save(nuevoCaso);
|
let caso_especial = await this.casoEspecialRepository.save(nuevoCaso);
|
||||||
|
console.log('Nuevo Caso Especial creado:', caso_especial);
|
||||||
return {
|
return {
|
||||||
message: 'Se ha registrado el Caso Especial correctamente.',
|
message: 'Se ha registrado el Caso Especial correctamente.',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async findAllFiltered(dto: FilterCasoEspecialDto) {
|
async findAllFiltered(dto: FilterCasoEspecialDto) {
|
||||||
const { pagina = 1, idStatus, nombre = '', numeroCuenta = '' } = dto;
|
const { pagina = 1, idStatus, nombre = '', numeroCuenta = '' } = dto;
|
||||||
|
|
||||||
@@ -138,11 +142,11 @@ export class CasoEspecialService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nombre) {
|
if (nombre) {
|
||||||
query.andWhere('usuario.nombre ILIKE :nombre', { nombre: `%${nombre}%` });
|
query.andWhere('usuario.nombre LIKE :nombre', { nombre: `%${nombre}%` });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numeroCuenta) {
|
if (numeroCuenta) {
|
||||||
query.andWhere('usuario.usuario ILIKE :numeroCuenta', {
|
query.andWhere('usuario.usuario LIKE :numeroCuenta', {
|
||||||
numeroCuenta: `%${numeroCuenta}%`,
|
numeroCuenta: `%${numeroCuenta}%`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -164,11 +168,11 @@ export class CasoEspecialService {
|
|||||||
|
|
||||||
const caso = await this.casoEspecialRepository.findOne({
|
const caso = await this.casoEspecialRepository.findOne({
|
||||||
where: { idCasoEspecial },
|
where: { idCasoEspecial },
|
||||||
relations: ['usuario'],
|
relations: ['usuario', 'status'],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!caso) {
|
if (!caso) {
|
||||||
throw new Error('No existe este Caso Especial.');
|
throw new BadRequestException('No existe este Caso Especial.');
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (caso.status.idStatus) {
|
switch (caso.status.idStatus) {
|
||||||
@@ -177,11 +181,10 @@ export class CasoEspecialService {
|
|||||||
const correo = terminoValidado(caso.usuario.nombre);
|
const correo = terminoValidado(caso.usuario.nombre);
|
||||||
|
|
||||||
// Actualiza el status según el caso
|
// Actualiza el status según el caso
|
||||||
update = {
|
caso.status.idStatus = caso.status.idStatus === 11 ? 13 : 14;
|
||||||
idStatus: caso.status.idStatus === 11 ? 13 : 14,
|
await this.casoEspecialRepository.save(caso);
|
||||||
};
|
|
||||||
|
|
||||||
let sendcorreo = {
|
let sendMessage: SendMailDto = {
|
||||||
to: caso.correo,
|
to: caso.correo,
|
||||||
|
|
||||||
subject: correo.subject,
|
subject: correo.subject,
|
||||||
@@ -193,18 +196,16 @@ export class CasoEspecialService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Envía correo
|
// Envía correo
|
||||||
await this.gmail.enviarCorreo(sendcorreo);
|
await this.gmail.enviarCorreo(sendMessage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
throw new Error('Este Caso Especial ya se encuentra en Liberación.');
|
throw new BadRequestException('Este Caso Especial ya se encuentra en Liberación.');
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Id status no válido.');
|
throw new BadRequestException('Id status no válido.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza en base de datos
|
|
||||||
await this.casoEspecialRepository.update({ idCasoEspecial }, update);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
message:
|
message:
|
||||||
@@ -223,9 +224,9 @@ export class CasoEspecialService {
|
|||||||
relations: ['usuario', 'carrera', 'status'],
|
relations: ['usuario', 'carrera', 'status'],
|
||||||
});
|
});
|
||||||
if (!casoEspecial) {
|
if (!casoEspecial) {
|
||||||
throw new Error('No existe este Caso Especial.');
|
throw new BadRequestException('No existe este Caso Especial.');
|
||||||
}
|
}
|
||||||
return casoEspecial.createdAt;
|
return casoEspecial;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateCasoEspecial(id: number, dto: UpdateCasoEspecialDto) {
|
async updateCasoEspecial(id: number, dto: UpdateCasoEspecialDto) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Type } from 'class-transformer';
|
||||||
import {
|
import {
|
||||||
IsEmail,
|
IsEmail,
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
@@ -13,19 +14,19 @@ import {
|
|||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateCasoEspecialDto {
|
export class CreateCasoEspecialDto {
|
||||||
|
@Type(() => Number)
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
idUsuario: number;
|
idUsuario: number;
|
||||||
|
|
||||||
@IsNumber()
|
@Type(() => Number)
|
||||||
@IsInt()
|
@IsInt()
|
||||||
idCarrera: number;
|
idCarrera: number;
|
||||||
|
|
||||||
|
@Type(() => Number)
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@Length(1, 11)
|
|
||||||
idStatus: number;
|
idStatus: number;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@Length(9, 9)
|
|
||||||
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
||||||
numeroCuenta: string;
|
numeroCuenta: string;
|
||||||
|
|
||||||
|
|||||||
@@ -14,15 +14,15 @@ export class UpdateCasoEspecialDto {
|
|||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
fechaInicio?: Date;
|
fechaInicio?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
fechaFin?: Date;
|
fechaFin?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
fechaNacimiento?: Date;
|
fechaNacimiento?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@@ -1,63 +1,74 @@
|
|||||||
import { Carrera } from "src/carrera/entities/carrera.entity";
|
import {
|
||||||
import { Status } from "src/status/entities/status.entity";
|
Entity,
|
||||||
import { Usuario } from "src/usuario/entities/usuario.entity";
|
PrimaryGeneratedColumn,
|
||||||
import { Column, Entity, ManyToMany, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
Column,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn,
|
||||||
|
CreateDateColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
import { Carrera } from 'src/carrera/entities/carrera.entity';
|
||||||
|
import { Status } from 'src/status/entities/status.entity';
|
||||||
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
|
|
||||||
@Entity('caso_especial')
|
@Entity('caso_especial')
|
||||||
export class CasoEspecial {
|
export class CasoEspecial {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn({ name: 'idCasoEspecial' })
|
||||||
idCasoEspecial: number;
|
idCasoEspecial: number;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 3 })
|
@Column({ name: 'creditos', type: 'varchar', length: 3, nullable: false })
|
||||||
creditos: string;
|
creditos: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60 })
|
@Column({ name: 'correo', type: 'varchar', length: 60, nullable: false })
|
||||||
correo: string;
|
correo: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 15 })
|
@Column({ name: 'telefono', type: 'varchar', length: 15, nullable: false })
|
||||||
telefono: string;
|
telefono: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 200, nullable: true, default: null })
|
@Column({ name: 'institucion', type: 'varchar', length: 200, nullable: true })
|
||||||
institucion: string | null;
|
institucion?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 200, nullable: true, default: null })
|
@Column({ name: 'dependencia', type: 'varchar', length: 200, nullable: true })
|
||||||
dependencia: string | null;
|
dependencia?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 1, nullable: true, default: null })
|
@Column({ name: 'motivo', type: 'varchar', length: 1, nullable: true })
|
||||||
motivo: string | null;
|
motivo?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 200 })
|
@Column({ name: 'direccion', type: 'varchar', length: 200, nullable: false })
|
||||||
direccion: string;
|
direccion: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamp' })
|
@Column({ name: 'fechaInicio', type: 'date', nullable: false })
|
||||||
fechaInicio: Date;
|
fechaInicio: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamp' })
|
@Column({ name: 'fechaFin', type: 'date', nullable: false })
|
||||||
fechaFin: Date;
|
fechaFin: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamp' })
|
@Column({ name: 'fechaNacimiento', type: 'date', nullable: false })
|
||||||
fechaNacimiento: Date;
|
fechaNacimiento: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60 })
|
@Column({ name: 'carpeta', type: 'varchar', length: 60, nullable: false })
|
||||||
carpeta: string;
|
carpeta: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60 })
|
@Column({ name: 'archivoZip', type: 'varchar', length: 60, nullable: false })
|
||||||
archivoZip: string;
|
archivoZip: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
|
@CreateDateColumn({ name: 'createdAt', type: 'datetime' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP' })
|
@UpdateDateColumn({ name: 'updatedAt', type: 'datetime' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
|
|
||||||
@ManyToOne(()=>Usuario, (usuario)=>usuario.casoEspecial)
|
// ===== Relaciones =====
|
||||||
usuario:Usuario;
|
@ManyToOne(() => Usuario, (usuario) => usuario.casoEspecial) //error en el nombre al llamar caso especial (se cambio)
|
||||||
|
@JoinColumn({ name: 'idUsuario' })
|
||||||
@ManyToOne(()=>Carrera, (carrera)=>carrera.casoEspecial)
|
usuario: Usuario;
|
||||||
carrera:Carrera;
|
|
||||||
|
|
||||||
@ManyToOne(()=>Status, (status)=>status.casoEspecial)
|
|
||||||
status:Status;
|
|
||||||
|
|
||||||
|
@ManyToOne(() => Carrera, (carrera) => carrera.casosEspeciales)
|
||||||
|
@JoinColumn({ name: 'idCarrera' })
|
||||||
|
carrera: Carrera;
|
||||||
|
|
||||||
|
@ManyToOne(() => Status, (status) => status.casoEspecial) //error en el nombre al llamar caso especial (se cambio)
|
||||||
|
@JoinColumn({ name: 'idStatus' })
|
||||||
|
status: Status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +1,124 @@
|
|||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
|
import {
|
||||||
|
Entity,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
OneToMany,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Entity('cuestionario_alumno')
|
@Entity('cuestionario_alumno')
|
||||||
export class CuestionarioAlumno {
|
export class CuestionarioAlumno {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn({ name: 'idCuestionarioAlumno' })
|
||||||
idCuestionarioAlumno: number;
|
idCuestionarioAlumno: number;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 1 })
|
@Column({ name: 'sexo', type: 'varchar', length: 1, nullable: false })
|
||||||
sexo: string;
|
sexo: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 2 })
|
@Column({ name: 'edad', type: 'varchar', length: 2, nullable: false })
|
||||||
edad: string;
|
edad: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100 })
|
@Column({
|
||||||
servicioMedico: string;
|
name: 'servicioMedico',
|
||||||
|
type: 'varchar',
|
||||||
|
length: 100,
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
servicioMedico: string;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p1', type: 'tinyint', width: 1, nullable: false })
|
||||||
p1: boolean;
|
p1: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p2', type: 'tinyint', width: 1, nullable: false })
|
||||||
p2: boolean;
|
p2: boolean;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 150 })
|
@Column({ name: 'p3', type: 'varchar', length: 150, nullable: false })
|
||||||
p3: string;
|
p3: string;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p4', type: 'tinyint', width: 1, nullable: false })
|
||||||
p4: boolean;
|
p4: boolean;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 7 })
|
@Column({ name: 'p5', type: 'varchar', length: 7, nullable: false })
|
||||||
p5: string;
|
p5: string;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p6', type: 'tinyint', width: 1, nullable: false })
|
||||||
p6: boolean;
|
p6: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p7', type: 'tinyint', width: 1, nullable: false })
|
||||||
p7: boolean;
|
p7: boolean;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5 })
|
@Column({ name: 'p8', type: 'varchar', length: 5, nullable: false })
|
||||||
p8: string;
|
p8: string;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p9', type: 'tinyint', width: 1, nullable: false })
|
||||||
p9: boolean;
|
p9: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p10', type: 'tinyint', width: 1, nullable: false })
|
||||||
p10: boolean;
|
p10: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p11', type: 'tinyint', width: 1, nullable: false })
|
||||||
p11: boolean;
|
p11: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p12', type: 'tinyint', width: 1, nullable: false })
|
||||||
p12: boolean;
|
p12: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p13', type: 'tinyint', width: 1, nullable: false })
|
||||||
p13: boolean;
|
p13: boolean;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 7 })
|
@Column({ name: 'p14', type: 'varchar', length: 7, nullable: false })
|
||||||
p14: string;
|
p14: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 7 })
|
@Column({ name: 'p15', type: 'varchar', length: 7, nullable: false })
|
||||||
p15: string;
|
p15: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 2 })
|
@Column({ name: 'p16', type: 'varchar', length: 2, nullable: false })
|
||||||
p16: string;
|
p16: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5 })
|
@Column({ name: 'p17', type: 'varchar', length: 5, nullable: false })
|
||||||
p17: string;
|
p17: string;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p18', type: 'tinyint', width: 1, nullable: false })
|
||||||
p18: boolean;
|
p18: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p19', type: 'tinyint', width: 1, nullable: false })
|
||||||
p19: boolean;
|
p19: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p20', type: 'tinyint', width: 1, nullable: false })
|
||||||
p20: boolean;
|
p20: boolean;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 9 })
|
@Column({ name: 'p21', type: 'varchar', length: 9, nullable: false })
|
||||||
p21: string;
|
p21: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 23 })
|
@Column({ name: 'p22', type: 'varchar', length: 23, nullable: false })
|
||||||
p22: string;
|
p22: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 8 })
|
@Column({ name: 'p23', type: 'varchar', length: 8, nullable: false })
|
||||||
p23: string;
|
p23: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 8 })
|
@Column({ name: 'p24', type: 'varchar', length: 8, nullable: false })
|
||||||
p24: string;
|
p24: string;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p25', type: 'tinyint', width: 1, nullable: false })
|
||||||
p25: boolean;
|
p25: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ name: 'p26', type: 'tinyint', width: 1, nullable: false })
|
||||||
p26: boolean;
|
p26: boolean;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 400 })
|
@Column({ name: 'p27', type: 'varchar', length: 400, nullable: false })
|
||||||
p27: string;
|
p27: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 1 })
|
@Column({ name: 'p28', type: 'varchar', length: 1, nullable: false })
|
||||||
p28: string;
|
p28: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 1 })
|
@Column({ name: 'p29', type: 'varchar', length: 1, nullable: false })
|
||||||
p29: string;
|
p29: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 400 })
|
@Column({ name: 'p30', type: 'varchar', length: 400, nullable: false })
|
||||||
p30: string;
|
p30: string;
|
||||||
|
|
||||||
@OneToMany(()=>Servicio,(servicio)=>servicio.cuestionarioAlumno2)
|
@CreateDateColumn({ name: 'createdAt', type: 'datetime' })
|
||||||
servicio:Servicio[];
|
createdAt: Date;
|
||||||
|
|
||||||
|
@OneToMany(() => Servicio, (servicio) => servicio.cuestionarioAlumno2)
|
||||||
|
servicio: Servicio[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ import {
|
|||||||
Param,
|
Param,
|
||||||
Delete,
|
Delete,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
|
Query,
|
||||||
|
Res,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { CuestionarioAlumno2Service } from './cuestionario-alumno2.service';
|
import { CuestionarioAlumno2Service } from './cuestionario-alumno2.service';
|
||||||
import { CreateCuestionarioAlumno2Dto } from './dto/create-cuestionario-alumno2.dto';
|
import { CreateCuestionarioAlumno2Dto } from './dto/create-cuestionario-alumno2.dto';
|
||||||
|
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
import { findCuestionarioAlumno2Dto } from './dto/find.dto';
|
import { findCuestionarioAlumno2Dto } from './dto/find.dto';
|
||||||
|
import { Response } from 'express';
|
||||||
|
|
||||||
@Controller('cuestionario-alumno2')
|
@Controller('cuestionario-alumno2')
|
||||||
export class CuestionarioAlumno2Controller {
|
export class CuestionarioAlumno2Controller {
|
||||||
@@ -23,13 +26,18 @@ export class CuestionarioAlumno2Controller {
|
|||||||
@Post()
|
@Post()
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
create(@Body() createCuestionarioAlumno2Dto: CreateCuestionarioAlumno2Dto) {
|
create(@Body() createCuestionarioAlumno2Dto: CreateCuestionarioAlumno2Dto) {
|
||||||
|
|
||||||
|
console.log('CreateCuestionarioAlumno2Dto recibido:', createCuestionarioAlumno2Dto);
|
||||||
|
|
||||||
return this.cuestionarioAlumno2Service.create(createCuestionarioAlumno2Dto);
|
return this.cuestionarioAlumno2Service.create(createCuestionarioAlumno2Dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
findAll(@Body() findDto: findCuestionarioAlumno2Dto) {
|
async findAll(@Query() findDto: findCuestionarioAlumno2Dto, @Res() res: Response) {
|
||||||
return this.cuestionarioAlumno2Service.get(findDto.version, findDto.anio);
|
const path = await this.cuestionarioAlumno2Service.get(findDto.version, findDto.anio);
|
||||||
|
|
||||||
|
return res.download(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Get(':id')
|
// @Get(':id')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
import { CreateCuestionarioAlumno2Dto } from './dto/create-cuestionario-alumno2.dto';
|
import { CreateCuestionarioAlumno2Dto } from './dto/create-cuestionario-alumno2.dto';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
@@ -21,7 +21,7 @@ export class CuestionarioAlumno2Service {
|
|||||||
private cuestionarioAlumnoRepository: Repository<CuestionarioAlumno>,
|
private cuestionarioAlumnoRepository: Repository<CuestionarioAlumno>,
|
||||||
private validacionService: ValidacionService,
|
private validacionService: ValidacionService,
|
||||||
private archivoService: ArchivoService,
|
private archivoService: ArchivoService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async create(createCuestionarioAlumno2Dto: CreateCuestionarioAlumno2Dto) {
|
async create(createCuestionarioAlumno2Dto: CreateCuestionarioAlumno2Dto) {
|
||||||
let idServicio = createCuestionarioAlumno2Dto.idServicio;
|
let idServicio = createCuestionarioAlumno2Dto.idServicio;
|
||||||
@@ -32,13 +32,14 @@ export class CuestionarioAlumno2Service {
|
|||||||
|
|
||||||
let servicio = await this.servicioRepository.findOne({
|
let servicio = await this.servicioRepository.findOne({
|
||||||
where: { idServicio },
|
where: { idServicio },
|
||||||
|
relations: ['cuestionarioAlumno2', 'status'],
|
||||||
});
|
});
|
||||||
if (!servicio) {
|
if (!servicio) {
|
||||||
throw new Error('No existe este Servicio Social.');
|
throw new BadRequestException('No existe este Servicio Social.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (servicio.cuestionarioAlumno2.idCuestionarioAlumno2) {
|
if (servicio.cuestionarioAlumno2) {
|
||||||
throw new Error(
|
throw new BadRequestException(
|
||||||
'Este Servicio Social ya cuenta con cuestionario de alumno',
|
'Este Servicio Social ya cuenta con cuestionario de alumno',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -48,7 +49,7 @@ export class CuestionarioAlumno2Service {
|
|||||||
console.log('antes de create ques2');
|
console.log('antes de create ques2');
|
||||||
|
|
||||||
if (messageByStatus.hasOwnProperty(servicio.status.idStatus)) {
|
if (messageByStatus.hasOwnProperty(servicio.status.idStatus)) {
|
||||||
throw new Error(messageByStatus[servicio.status.idStatus]);
|
throw new BadRequestException(messageByStatus[servicio.status.idStatus]);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('datos a registrar en la tabla cuestionarioAlumno2', {
|
console.log('datos a registrar en la tabla cuestionarioAlumno2', {
|
||||||
@@ -66,44 +67,87 @@ export class CuestionarioAlumno2Service {
|
|||||||
{ cuestionarioAlumno2: respuestasRegistradas },
|
{ cuestionarioAlumno2: respuestasRegistradas },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await this.validacionService.validarPreTermino(idServicio)
|
||||||
|
|
||||||
return resX;
|
return resX;
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(version: string, anio: string) {
|
/*
|
||||||
const year = anio;
|
async get(version: string, anio: string) {
|
||||||
const path = `server/uploads/${year}_cuestionario_alumno.csv`;
|
const year = anio;
|
||||||
|
const path = `server/uploads/${year}_cuestionario_alumno.csv`;
|
||||||
|
|
||||||
let data = [];
|
let data = [];
|
||||||
|
|
||||||
|
console.log(year);
|
||||||
|
let temp;
|
||||||
|
|
||||||
|
if (version == 'v1') {
|
||||||
|
temp = await this.cuestionarioAlumnoRepository.find({
|
||||||
|
where: {
|
||||||
|
idCuestionarioAlumno: Not(IsNull()),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version == 'v2') {
|
||||||
|
temp = await this.cuestionarioAlumno2Repository.find({
|
||||||
|
where: {
|
||||||
|
idCuestionarioAlumno2: Not(IsNull()),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!temp) {
|
||||||
|
throw new BadRequestException();
|
||||||
|
}
|
||||||
|
|
||||||
|
data = temp.map((item) => ({ ...item }));
|
||||||
|
|
||||||
|
await this.archivoService.eliminarArchivo(path).catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.archivoService.crearArchivo(path, convertArrayToCSV(data));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
async get(version: string, anio: string): Promise<string> {
|
||||||
|
const path = `server/uploads/${anio}_cuestionario_alumno.csv`;
|
||||||
|
|
||||||
console.log(year);
|
|
||||||
let temp;
|
let temp;
|
||||||
|
|
||||||
if (version == 'v1') {
|
if (version === 'v1') {
|
||||||
temp = this.cuestionarioAlumnoRepository.find({
|
temp = await this.cuestionarioAlumnoRepository.find({
|
||||||
where: {
|
where: {
|
||||||
idCuestionarioAlumno: Not(IsNull()),
|
idCuestionarioAlumno: Not(IsNull()),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version == 'v2') {
|
if (version === 'v2') {
|
||||||
temp = this.cuestionarioAlumno2Repository.find({
|
temp = await this.cuestionarioAlumno2Repository.find({
|
||||||
where: {
|
where: {
|
||||||
idCuestionarioAlumno2: Not(IsNull()),
|
idCuestionarioAlumno2: Not(IsNull()),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!temp) {
|
if (!temp || temp.length === 0) {
|
||||||
throw new Error();
|
throw new BadRequestException('No hay datos para exportar');
|
||||||
}
|
}
|
||||||
|
|
||||||
data = temp.map((item) => ({ ...item }));
|
const data = temp.map((item) => ({ ...item }));
|
||||||
|
|
||||||
await this.archivoService.eliminarArchivo(path).catch((err) => {
|
await this.archivoService.eliminarArchivo(path).catch(() => null);
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.archivoService.crearArchivo(path, convertArrayToCSV(data));
|
// ✅ Creamos el archivo
|
||||||
|
await this.archivoService.crearArchivo(
|
||||||
|
path,
|
||||||
|
convertArrayToCSV(data),
|
||||||
|
);
|
||||||
|
|
||||||
|
// ✅ SOLO regresamos el path
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export class CreateCuestionarioAlumno2Dto {
|
|||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
idServicio:number
|
idServicio: number
|
||||||
|
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@@ -134,6 +134,10 @@ export class CreateCuestionarioAlumno2Dto {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
p12_C_4: string;
|
p12_C_4: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
p12_C_5: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
p12_D_1: string;
|
p12_D_1: string;
|
||||||
|
|||||||
@@ -1,145 +1,143 @@
|
|||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
|
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
@Entity('cuestionario_alumno_2')
|
@Entity('cuestionario_alumno_2')
|
||||||
export class CuestionarioAlumno2 {
|
export class CuestionarioAlumno2 {
|
||||||
|
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
idCuestionarioAlumno2: number;
|
idCuestionarioAlumno2: number;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100, nullable: false })
|
@Column({ type: 'text', nullable: true })
|
||||||
p1: string;
|
p1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p2: string;
|
p2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p4: string;
|
p4: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: true })
|
@Column({ type: 'varchar', length: 500, nullable: true })
|
||||||
p5: string;
|
p5: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p6: string;
|
p6: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p7: string;
|
p7: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: true })
|
@Column({ type: 'varchar', length: 500, nullable: true })
|
||||||
p8: string;
|
p8: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p9: string;
|
p9: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p3_1: string;
|
p3_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p3_2: string;
|
p3_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p3_3: string;
|
p3_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p3_4: string;
|
p3_4: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p10_1: string;
|
p10_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p10_2: string;
|
p10_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p10_3: string;
|
p10_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p11_1: string;
|
p11_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p11_2: string;
|
p11_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p11_3: string;
|
p11_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p11_4: string;
|
p11_4: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_A_1: string;
|
p12_A_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_A_2: string;
|
p12_A_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_A_3: string;
|
p12_A_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_A_4: string;
|
p12_A_4: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_B_1: string;
|
p12_B_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_B_2: string;
|
p12_B_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_B_3: string;
|
p12_B_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_B_4: string;
|
p12_B_4: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_C_1: string;
|
p12_C_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_C_2: string;
|
p12_C_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_C_3: string;
|
p12_C_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p12_C_4: string;
|
p12_C_4: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p12_D_1: string;
|
p12_D_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p12_D_2: string;
|
p12_D_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p12_D_3: string;
|
p12_D_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p12_D_4: string;
|
p12_D_4: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 20, nullable: false })
|
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||||
p12_D_5: string;
|
p12_D_5: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p13: string;
|
p13: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p14: string;
|
p14: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||||
p15: string;
|
p15: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: true })
|
@Column({ type: 'varchar', length: 500, nullable: true })
|
||||||
p16: string;
|
p16: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p17_1: string;
|
p17_1: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p17_2: string;
|
p17_2: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ type: 'varchar', length: 20, nullable: true })
|
||||||
p17_3: string;
|
p17_3: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: true })
|
@Column({ type: 'varchar', length: 500, nullable: true })
|
||||||
p18: string;
|
p18: string;
|
||||||
|
|
||||||
@OneToMany(()=>Servicio,(servicio)=>servicio.cuestionarioAlumno2)
|
@OneToMany(() => Servicio, (servicio) => servicio.cuestionarioAlumno2)
|
||||||
servicio:Servicio[];
|
servicio: Servicio[];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
Entity,
|
||||||
|
OneToMany,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Entity('cuestionario_programa')
|
@Entity('cuestionario_programa')
|
||||||
export class CuestionarioPrograma {
|
export class CuestionarioPrograma {
|
||||||
@@ -30,6 +36,11 @@ export class CuestionarioPrograma {
|
|||||||
@Column({ type: 'varchar', length: 800, nullable: false })
|
@Column({ type: 'varchar', length: 800, nullable: false })
|
||||||
p7: string;
|
p7: string;
|
||||||
|
|
||||||
@OneToMany(()=>Servicio,(servicio)=>servicio.cuestionarioPrograma)
|
@CreateDateColumn({ name: 'createdAt', type: 'datetime' })
|
||||||
servicio:Servicio[];
|
createdAt: Date;
|
||||||
|
|
||||||
|
// faltaba createdAT
|
||||||
|
|
||||||
|
@OneToMany(() => Servicio, (servicio) => servicio.cuestionarioPrograma)
|
||||||
|
servicio: Servicio[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { CuestionarioPrograma2 } from './entities/cuestionario-programa2.entity'
|
|||||||
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { ValidacionService } from 'src/helpers.services/validacion.service';
|
import { ValidacionService } from 'src/helpers.services/validacion.service';
|
||||||
import { ArchivoService } from 'src/helpers.services/archivo.service';
|
import { ArchivoService } from 'src/helpers.services/archivo.service';
|
||||||
|
import { ServicioService } from 'src/servicio/servicio.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { ValidacionService } from 'src/helpers.services/validacion.service';
|
|||||||
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { messageByStatus } from 'src/messageByStatus';
|
import { messageByStatus } from 'src/messageByStatus';
|
||||||
import { convertArrayToCSV } from 'convert-array-to-csv';
|
import { convertArrayToCSV } from 'convert-array-to-csv';
|
||||||
|
import { ServicioService } from 'src/servicio/servicio.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CuestionarioPrograma2Service {
|
export class CuestionarioPrograma2Service {
|
||||||
@@ -21,7 +22,8 @@ export class CuestionarioPrograma2Service {
|
|||||||
private servicioRepository: Repository<Servicio>,
|
private servicioRepository: Repository<Servicio>,
|
||||||
private archivoService: ArchivoService,
|
private archivoService: ArchivoService,
|
||||||
private validacionService: ValidacionService,
|
private validacionService: ValidacionService,
|
||||||
) {}
|
|
||||||
|
) { }
|
||||||
|
|
||||||
async create(cuestionarioPrograma2: CreateCuestionarioPrograma2Dto) {
|
async create(cuestionarioPrograma2: CreateCuestionarioPrograma2Dto) {
|
||||||
let idServicio = cuestionarioPrograma2.idServicio;
|
let idServicio = cuestionarioPrograma2.idServicio;
|
||||||
@@ -31,21 +33,30 @@ export class CuestionarioPrograma2Service {
|
|||||||
|
|
||||||
let servicio = await this.servicioRepository.findOne({
|
let servicio = await this.servicioRepository.findOne({
|
||||||
where: { idServicio },
|
where: { idServicio },
|
||||||
|
relations: ['cuestionarioPrograma2', 'status'],
|
||||||
});
|
});
|
||||||
if (!servicio) {
|
if (!servicio) {
|
||||||
throw new Error('No existe este Servicio Social.');
|
throw new BadRequestException('No existe este Servicio Social.');
|
||||||
}
|
}
|
||||||
if (servicio.cuestionarioPrograma2.idCuestionarioPrograma2) {
|
|
||||||
throw new Error(
|
if (servicio.cuestionarioPrograma2) {
|
||||||
'Este Servicio Social ya cuenta con cuestionario de alumno',
|
throw new BadRequestException(
|
||||||
|
'Este Servicio Social ya cuenta con cuestionario de programa',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Esta validacion esta incorrecta la cambie por la linea de arriva
|
||||||
|
// if (servicio.cuestionarioPrograma2.idCuestionarioPrograma2) {
|
||||||
|
// throw new BadRequestException(
|
||||||
|
// 'Este Servicio Social ya cuenta con cuestionario de alumno',
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
console.log('el servicio social si existe', servicio);
|
console.log('el servicio social si existe', servicio);
|
||||||
|
|
||||||
console.log('antes de create ques2');
|
console.log('antes de create ques2');
|
||||||
if (messageByStatus.hasOwnProperty(servicio.status.idStatus))
|
if (messageByStatus.hasOwnProperty(servicio.status.idStatus))
|
||||||
throw new Error(messageByStatus[servicio.status.idStatus]);
|
throw new BadRequestException(messageByStatus[servicio.status.idStatus]);
|
||||||
|
|
||||||
console.log('despues de registrar cuestionario', cuestionario);
|
console.log('despues de registrar cuestionario', cuestionario);
|
||||||
|
|
||||||
@@ -61,7 +72,7 @@ export class CuestionarioPrograma2Service {
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log(x);
|
console.log(x);
|
||||||
|
await this.validacionService.validarPreTermino(idServicio)
|
||||||
return respuestasRegistradas;
|
return respuestasRegistradas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,142 +1,142 @@
|
|||||||
import {
|
import {
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsNumber,
|
IsNumber,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
Length,
|
Length,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateCuestionarioPrograma2Dto {
|
export class CreateCuestionarioPrograma2Dto {
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
idServicio:number
|
idServicio: number
|
||||||
|
|
||||||
|
|
||||||
// p1, p2, p4, p5, p6
|
// p1, p2, p4, p5, p6
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 100)
|
@Length(1, 500)
|
||||||
p1: string;
|
p1: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 200)
|
||||||
p2: string;
|
p2: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 100)
|
@Length(1, 500)
|
||||||
p4: string;
|
p4: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 5)
|
@Length(1, 200)
|
||||||
p5: string;
|
p5: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@Length(1, 100)
|
@Length(1, 500)
|
||||||
p6?: string;
|
p6?: string;
|
||||||
|
|
||||||
// Sección p3_A
|
// Sección p3_A
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_A_1: string;
|
p3_A_1: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_A_2: string;
|
p3_A_2: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_A_3: string;
|
p3_A_3: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_A_4: string;
|
p3_A_4: string;
|
||||||
|
|
||||||
// Sección p3_B
|
// Sección p3_B
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_B_1: string;
|
p3_B_1: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_B_2: string;
|
p3_B_2: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_B_3: string;
|
p3_B_3: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_B_4: string;
|
p3_B_4: string;
|
||||||
|
|
||||||
// Sección p3_C
|
// Sección p3_C
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_C_1: string;
|
p3_C_1: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_C_2: string;
|
p3_C_2: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_C_3: string;
|
p3_C_3: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_C_4: string;
|
p3_C_4: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_C_5: string;
|
p3_C_5: string;
|
||||||
|
|
||||||
// Sección p3_D
|
// Sección p3_D
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_D_1: string;
|
p3_D_1: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_D_2: string;
|
p3_D_2: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_D_3: string;
|
p3_D_3: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_D_4: string;
|
p3_D_4: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@Length(1, 50)
|
@Length(1, 50)
|
||||||
p3_D_5: string;
|
p3_D_5: string;
|
||||||
|
|
||||||
// Sección p3_E
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@Length(1, 50)
|
|
||||||
p3_E_1: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Elimine esta tabla por que no existe en el cuestionario => Verificar si se ocupa en otro cuestionario ?
|
||||||
|
// Sección p3_E
|
||||||
|
// @IsString()
|
||||||
|
// @IsNotEmpty()
|
||||||
|
// @Length(1, 50)
|
||||||
|
// p3_E_1: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,90 +1,95 @@
|
|||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
Entity,
|
||||||
|
OneToMany,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Entity('cuestionario_programa_2')
|
@Entity('cuestionario_programa_2')
|
||||||
export class CuestionarioPrograma2 {
|
export class CuestionarioPrograma2 {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn({ name: 'idCuestionarioPrograma2' })
|
||||||
idCuestionarioPrograma2: number;
|
idCuestionarioPrograma2: number;
|
||||||
|
|
||||||
// Sección p3_A_*
|
@CreateDateColumn({ name: 'createdAt', type: 'datetime', nullable: true })
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
createdAt?: Date;
|
||||||
p3_A_1: string;
|
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_A_1', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_A_2: string;
|
p3_A_1?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_A_2', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_A_3: string;
|
p3_A_2?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_A_3', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_A_4: string;
|
p3_A_3?: string;
|
||||||
|
|
||||||
// Sección p3_B_*
|
@Column({ name: 'p3_A_4', type: 'varchar', length: 50, nullable: true })
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
p3_A_4?: string;
|
||||||
p3_B_1: string;
|
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_B_1', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_B_2: string;
|
p3_B_1?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_B_2', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_B_3: string;
|
p3_B_2?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_B_3', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_B_4: string;
|
p3_B_3?: string;
|
||||||
|
|
||||||
// Sección p3_C_*
|
@Column({ name: 'p3_B_4', type: 'varchar', length: 50, nullable: true })
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
p3_B_4?: string;
|
||||||
p3_C_1: string;
|
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_C_1', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_C_2: string;
|
p3_C_1?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_C_2', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_C_3: string;
|
p3_C_2?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_C_3', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_C_4: string;
|
p3_C_3?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_C_4', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_C_5: string;
|
p3_C_4?: string;
|
||||||
|
|
||||||
// Sección p3_D_*
|
@Column({ name: 'p3_C_5', type: 'varchar', length: 50, nullable: true })
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
p3_C_5?: string;
|
||||||
p3_D_1: string;
|
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_D_1', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_D_2: string;
|
p3_D_1?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_D_2', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_D_3: string;
|
p3_D_2?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_D_3', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_D_4: string;
|
p3_D_3?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p3_D_4', type: 'varchar', length: 50, nullable: true })
|
||||||
p3_D_5: string;
|
p3_D_4?: string;
|
||||||
|
|
||||||
// Sección p3_E_*
|
@Column({ name: 'p3_D_5', type: 'varchar', length: 50, nullable: true })
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
p3_D_5?: string;
|
||||||
p3_E_1: string;
|
|
||||||
|
|
||||||
// p1, p2, p4, p5, p6
|
@Column({ name: 'p3_E_1', type: 'varchar', length: 50, nullable: true })
|
||||||
@Column({ type: 'varchar', length: 100, nullable: false })
|
p3_E_1?: string;
|
||||||
p1: string;
|
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: false })
|
@Column({ name: 'p1', type: 'varchar', length: 500, nullable: true })
|
||||||
p2: string;
|
p1?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100, nullable: false })
|
@Column({ name: 'p2', type: 'varchar', length: 200, nullable: true })
|
||||||
p4: string;
|
p2?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 5, nullable: false })
|
@Column({ name: 'p4', type: 'varchar', length: 500, nullable: true })
|
||||||
p5: string;
|
p4?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100, nullable: true })
|
@Column({ name: 'p5', type: 'varchar', length: 200, nullable: true })
|
||||||
|
p5?: string;
|
||||||
|
|
||||||
|
@Column({ name: 'p6', type: 'varchar', length: 500, nullable: true })
|
||||||
p6?: string;
|
p6?: string;
|
||||||
|
|
||||||
@OneToMany(()=>Servicio,(servicio)=>servicio.cuestionarioAlumno2)
|
@Column({ name: 'p7', type: 'varchar', length: 200, nullable: true })
|
||||||
servicio:Servicio[];
|
p7?: string;
|
||||||
|
|
||||||
|
@OneToMany(() => Servicio, (servicio) => servicio.cuestionarioAlumno2)
|
||||||
|
servicio: Servicio[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
// src/drive/drive.controller.ts
|
||||||
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Query,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { DriveService } from './drive.service';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
@Controller('drive-test')
|
||||||
|
export class DriveController {
|
||||||
|
constructor(private readonly driveService: DriveService) { }
|
||||||
|
|
||||||
|
// ✅ Listar archivos/carpetas
|
||||||
|
@Get('list')
|
||||||
|
async list(@Query('pageToken') pageToken?: string) {
|
||||||
|
return this.driveService.list(pageToken || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Crear carpeta dentro de CARPETA
|
||||||
|
@Post('mkdir')
|
||||||
|
async createFolder(@Body('name') name: string) {
|
||||||
|
if (!name) {
|
||||||
|
throw new BadRequestException('El nombre es obligatorio');
|
||||||
|
}
|
||||||
|
const folderId = await this.driveService.mkDir(name);
|
||||||
|
return { folderId };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Obtener carpeta (buscar o crear)
|
||||||
|
@Get('folder/:numeroCuenta')
|
||||||
|
async getOrCreateFolder(
|
||||||
|
@Param('numeroCuenta') numeroCuenta: string,
|
||||||
|
) {
|
||||||
|
const folderId = await this.driveService.folder(numeroCuenta);
|
||||||
|
return { folderId };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Subir archivo (archivo dummy para pruebas)
|
||||||
|
@Post('upload')
|
||||||
|
async uploadFile(
|
||||||
|
@Body('parent') parent: string,
|
||||||
|
) {
|
||||||
|
if (!parent) {
|
||||||
|
throw new BadRequestException('Parent es obligatorio');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Archivo temporal para prueba
|
||||||
|
const tempPath = './temp-test.txt';
|
||||||
|
fs.writeFileSync(tempPath, 'Archivo de prueba DriveService');
|
||||||
|
|
||||||
|
const fileId = await this.driveService.uploadFile(
|
||||||
|
tempPath,
|
||||||
|
'test-drive.txt',
|
||||||
|
'text/plain',
|
||||||
|
parent,
|
||||||
|
);
|
||||||
|
|
||||||
|
return { fileId };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Mover archivo (update)
|
||||||
|
@Post('update')
|
||||||
|
async updateFile(
|
||||||
|
@Body('fileId') fileId: string,
|
||||||
|
@Body('addParents') addParents: string,
|
||||||
|
@Body('removeParents') removeParents: string,
|
||||||
|
) {
|
||||||
|
if (!fileId || !addParents || !removeParents) {
|
||||||
|
throw new BadRequestException('Datos incompletos');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.driveService.update(fileId, addParents, removeParents);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Eliminar archivo
|
||||||
|
@Delete('delete/:fileId')
|
||||||
|
async deleteFile(@Param('fileId') fileId: string) {
|
||||||
|
await this.driveService.deleteFile(fileId);
|
||||||
|
return { message: 'Archivo eliminado correctamente' };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
// src/drive/drive.module.ts
|
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { DriveService } from './drive.service';
|
import { DriveService } from './drive.service';
|
||||||
|
import { DriveController } from './drive.controller';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
controllers: [DriveController],
|
||||||
providers: [DriveService],
|
providers: [DriveService],
|
||||||
exports: [DriveService],
|
exports: [DriveService],
|
||||||
})
|
})
|
||||||
export class DriveModule {}
|
export class DriveModule { }
|
||||||
|
|||||||
+76
-55
@@ -1,9 +1,11 @@
|
|||||||
// src/drive/drive.service.ts
|
// src/drive/drive.service.ts
|
||||||
import { Injectable, InternalServerErrorException } from '@nestjs/common';
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
Injectable,
|
||||||
|
InternalServerErrorException,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { google } from 'googleapis';
|
import { google } from 'googleapis';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
|
||||||
import { error } from 'console';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DriveService {
|
export class DriveService {
|
||||||
@@ -11,30 +13,32 @@ export class DriveService {
|
|||||||
|
|
||||||
private loadCredentials() {
|
private loadCredentials() {
|
||||||
try {
|
try {
|
||||||
const credenciales = JSON.parse(
|
const oAuth2Client = new google.auth.OAuth2(
|
||||||
fs.readFileSync(path.resolve('./cred.json'), 'utf8'),
|
process.env.CLIENT_ID,
|
||||||
|
process.env.CLIENT_SECRET,
|
||||||
);
|
);
|
||||||
credenciales.private_key = credenciales.private_key.replace(/\\n/g, '\n');
|
|
||||||
return new google.auth.JWT({
|
oAuth2Client.setCredentials({
|
||||||
email: credenciales.client_email,
|
refresh_token: process.env.REFRESH_TOKEN,
|
||||||
key: credenciales.private_key,
|
});
|
||||||
scopes: ['https://www.googleapis.com/auth/drive'],
|
|
||||||
});
|
return oAuth2Client;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('❌ Error cargando credenciales:', err);
|
throw new InternalServerErrorException(
|
||||||
throw new InternalServerErrorException('Error al cargar credenciales');
|
'Error al cargar credenciales de Google Drive',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async list(pageToken = '') {
|
async list(pageToken = '') {
|
||||||
const authClient = await this.loadCredentials();
|
const authClient = this.loadCredentials();
|
||||||
const drive = google.drive({ version: 'v3', auth: authClient });
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await drive.files.list({
|
const res = await drive.files.list({
|
||||||
corpora: 'user',
|
corpora: 'user',
|
||||||
supportsTeamDrives: true,
|
supportsAllDrives: true,
|
||||||
includeTeamDriveItems: true,
|
includeItemsFromAllDrives: true,
|
||||||
spaces: 'drive',
|
spaces: 'drive',
|
||||||
pageSize: 1000,
|
pageSize: 1000,
|
||||||
pageToken,
|
pageToken,
|
||||||
@@ -50,28 +54,36 @@ export class DriveService {
|
|||||||
|
|
||||||
async deleteFile(fileId: string) {
|
async deleteFile(fileId: string) {
|
||||||
if (fileId === process.env.CARPETA) {
|
if (fileId === process.env.CARPETA) {
|
||||||
throw new Error('No se puede eliminar este archivo/carpeta.');
|
throw new BadRequestException(
|
||||||
|
'No se puede eliminar este archivo/carpeta.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const authClient = await this.loadCredentials();
|
console.log('Eliminando archivo de Drive, ID:', fileId);
|
||||||
|
const authClient = this.loadCredentials();
|
||||||
const drive = google.drive({ version: 'v3', auth: authClient });
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await drive.files.delete({ fileId });
|
return await drive.files.delete({ fileId });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new InternalServerErrorException(
|
console.error('Error al eliminar archivo de Drive:', err.message);
|
||||||
'Error al eliminar archivo: ' + err.message,
|
return 0;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async uploadFile(filePath: string, name: string, mimeType: string, parent: string) {
|
async uploadFile(
|
||||||
const authClient = await this.loadCredentials();
|
filePath: string,
|
||||||
|
name: string,
|
||||||
|
mimeType: string,
|
||||||
|
parent: string,
|
||||||
|
) {
|
||||||
|
const authClient = this.loadCredentials();
|
||||||
const drive = google.drive({ version: 'v3', auth: authClient });
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
||||||
|
|
||||||
const requestBody = {
|
const requestBody = {
|
||||||
name,
|
name,
|
||||||
parents: [parent],
|
parents: [parent],
|
||||||
};
|
};
|
||||||
|
|
||||||
const media = {
|
const media = {
|
||||||
mimeType,
|
mimeType,
|
||||||
body: fs.createReadStream(filePath),
|
body: fs.createReadStream(filePath),
|
||||||
@@ -82,9 +94,12 @@ export class DriveService {
|
|||||||
requestBody,
|
requestBody,
|
||||||
media,
|
media,
|
||||||
fields: 'id',
|
fields: 'id',
|
||||||
|
supportsAllDrives: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.unlinkSync(filePath);
|
fs.unlinkSync(filePath);
|
||||||
return res.data.id;
|
console.log('Archivo subido a Drive, ID:', res.data.id);
|
||||||
|
return res.data.id!;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new InternalServerErrorException(
|
throw new InternalServerErrorException(
|
||||||
'Error al subir archivo: ' + err.message,
|
'Error al subir archivo: ' + err.message,
|
||||||
@@ -93,36 +108,35 @@ export class DriveService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async mkDir(name: string): Promise<string> {
|
async mkDir(name: string): Promise<string> {
|
||||||
const authClient = await this.loadCredentials();
|
if (!name) {
|
||||||
|
throw new BadRequestException('Nombre de carpeta inválido');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!process.env.CARPETA) {
|
||||||
|
throw new InternalServerErrorException('CARPETA no configurada');
|
||||||
|
}
|
||||||
|
|
||||||
|
const authClient = this.loadCredentials();
|
||||||
const drive = google.drive({ version: 'v3', auth: authClient });
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
||||||
|
|
||||||
|
|
||||||
if(!name){
|
|
||||||
throw new Error()
|
|
||||||
}
|
|
||||||
if(!process.env.CARPETA){
|
|
||||||
throw new Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestBody = {
|
const requestBody = {
|
||||||
name,
|
name,
|
||||||
mimeType: 'application/vnd.google-apps.folder',
|
mimeType: 'application/vnd.google-apps.folder',
|
||||||
parents: [process.env.CARPETA],
|
parents: [process.env.CARPETA],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await drive.files.create({
|
const res = await drive.files.create({
|
||||||
requestBody,
|
requestBody,
|
||||||
fields: 'id',
|
fields: 'id',
|
||||||
|
supportsAllDrives: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!res.data.id){
|
if (!res.data.id) {
|
||||||
throw new Error()
|
throw new BadRequestException('No se pudo crear la carpeta');
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.data.id;
|
return res.data.id;
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new InternalServerErrorException(
|
throw new InternalServerErrorException(
|
||||||
'Error al crear carpeta: ' + err.message,
|
'Error al crear carpeta: ' + err.message,
|
||||||
@@ -131,7 +145,7 @@ export class DriveService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(fileId: string, addParents: string, removeParents: string) {
|
async update(fileId: string, addParents: string, removeParents: string) {
|
||||||
const authClient = await this.loadCredentials();
|
const authClient = this.loadCredentials();
|
||||||
const drive = google.drive({ version: 'v3', auth: authClient });
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -139,6 +153,7 @@ export class DriveService {
|
|||||||
fileId,
|
fileId,
|
||||||
addParents,
|
addParents,
|
||||||
removeParents,
|
removeParents,
|
||||||
|
supportsAllDrives: true,
|
||||||
});
|
});
|
||||||
return res.data;
|
return res.data;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -148,24 +163,30 @@ export class DriveService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async folder(numeroCuenta: string) {
|
async folder(numeroCuenta: string): Promise<string> {
|
||||||
let pageToken = '';
|
if (!process.env.CARPETA) {
|
||||||
do {
|
throw new InternalServerErrorException('CARPETA no configurada');
|
||||||
const res = await this.list(pageToken);
|
}
|
||||||
if(!res.files){
|
|
||||||
throw new Error()
|
const authClient = this.loadCredentials();
|
||||||
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
||||||
|
|
||||||
|
const res = await drive.files.list({
|
||||||
|
q: `
|
||||||
|
mimeType='application/vnd.google-apps.folder'
|
||||||
|
and name='${numeroCuenta}'
|
||||||
|
and '${process.env.CARPETA}' in parents
|
||||||
|
and trashed=false
|
||||||
|
`,
|
||||||
|
fields: 'files(id, name)',
|
||||||
|
supportsAllDrives: true,
|
||||||
|
includeItemsFromAllDrives: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.data.files?.length) {
|
||||||
|
return res.data.files[0].id!;
|
||||||
}
|
}
|
||||||
for (const file of res.files) {
|
|
||||||
if (
|
|
||||||
file.name === numeroCuenta &&
|
|
||||||
file.mimeType === 'application/vnd.google-apps.folder'
|
|
||||||
) {
|
|
||||||
return file.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pageToken = res.nextPageToken || '';
|
|
||||||
|
|
||||||
} while (pageToken);
|
|
||||||
return this.mkDir(numeroCuenta);
|
return this.mkDir(numeroCuenta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,19 @@ const preRegistro = (password, nombre) => {
|
|||||||
subject: 'Notificación de Pre-Registro.',
|
subject: 'Notificación de Pre-Registro.',
|
||||||
msj: `Estimado(a) ${nombre}:
|
msj: `Estimado(a) ${nombre}:
|
||||||
|
|
||||||
Te informamos que la dependencia en donde decidiste realizar tu servicio social ya te registró en nuestro sistema de servicio social, por lo que para completar el proceso debes ingresar en un periodo máximo de 10 días hábiles a partir de la recepción de este mensaje, a la página https://iris.acatlan.unam.mx/ con tu número de cuenta y contraseña: ${password}, para llenar un formulario con tus datos.
|
|
||||||
|
Te informamos que la dependencia en donde decidiste realizar tu servicio social
|
||||||
|
ya te registró en nuestro sistema de servicio social, por lo que para completar
|
||||||
|
el proceso deberás:
|
||||||
|
|
||||||
|
|
||||||
|
-Ingresar en un periodo máximo de 10 días hábiles a partir de la recepción de este mensaje,
|
||||||
|
a la página https://iris.acatlan.unam.mx/
|
||||||
|
-Tu usuario será tu número de cuenta
|
||||||
|
-Tu contraseña es: ${password}
|
||||||
|
-Deberás llenar un formulario con tus datos
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
En caso de no realizar dicho registro, tu trámite queda inconcluso y no nos hacemos responsables por las horas de servicio social prestadas en cualquier dependencia.
|
En caso de no realizar dicho registro, tu trámite queda inconcluso y no nos hacemos responsables por las horas de servicio social prestadas en cualquier dependencia.
|
||||||
|
|
||||||
@@ -272,6 +284,7 @@ ${atentamente}
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Quitamos el module para que podamos exportar normal anteriormente module.export
|
||||||
module.exports = {
|
module.exports = {
|
||||||
preRegistro,
|
preRegistro,
|
||||||
preRegistroRechazadoAlumno,
|
preRegistroRechazadoAlumno,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from "@nestjs/common";
|
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||||
import { InjectRepository } from "@nestjs/typeorm";
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from "src/servicio/entities/servicio.entity";
|
||||||
@@ -8,49 +8,49 @@ import validator from "validator";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ValidacionService {
|
export class ValidacionService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(Servicio)
|
@InjectRepository(Servicio)
|
||||||
private servicioRepository:Repository<Servicio>,
|
private servicioRepository: Repository<Servicio>,
|
||||||
){}
|
) { }
|
||||||
|
|
||||||
caracterEspecial(char) {
|
caracterEspecial(char) {
|
||||||
const charset = [' ', '.', ',', ':', ';', '?', '¿', '!', '¡', '(', ')', '"', "'", '-', '_', '/', '#', '%', '\n'];
|
const charset = [' ', '.', ',', ':', ';', '?', '¿', '!', '¡', '(', ')', '"', "'", '-', '_', '/', '#', '%', '\n'];
|
||||||
return charset.includes(char);
|
return charset.includes(char);
|
||||||
}
|
}
|
||||||
|
|
||||||
yaExiste(campo, m) {
|
yaExiste(campo, m) {
|
||||||
throw new Error(`Ya se encuentra en uso ${m ? 'el' : 'la'} ${campo}.`);
|
throw new BadRequestException(`Ya se encuentra en uso ${m ? 'el' : 'la'} ${campo}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
noValido(campo, m, razon) {
|
noValido(campo, m, razon) {
|
||||||
throw new Error(`${m ? 'El' : 'La'} ${campo} no es valid${m ? 'o' : 'a'}, ${razon}.`);
|
throw new BadRequestException(`${m ? 'El' : 'La'} ${campo} no es valid${m ? 'o' : 'a'}, ${razon}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
noHay(variable, campo, m) {
|
noHay(variable, campo, m) {
|
||||||
if (!variable) throw new Error(`No se mando ${m ? 'el' : 'la'} ${campo}.`);
|
if (!variable) throw new BadRequestException(`No se mando ${m ? 'el' : 'la'} ${campo}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
validacionBasicaStr(texto, campo, m, length) {
|
validacionBasicaStr(texto, campo, m, length) {
|
||||||
this.noHay(texto, campo, m);
|
this.noHay(texto, campo, m);
|
||||||
if (typeof texto !== 'string') this.noValido(campo, m, 'no se mando una string');
|
if (typeof texto !== 'string') this.noValido(campo, m, 'no se mando una string');
|
||||||
if (length && texto.length > length) this.noValido(campo, m, 'tiene más caracteres de lo permitido');
|
if (length && texto.length > length) this.noValido(campo, m, 'tiene más caracteres de lo permitido');
|
||||||
return texto;
|
return texto;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarNumeroEntero(numero, campo, m: boolean = true) {
|
validarNumeroEntero(numero, campo, m: boolean = true) {
|
||||||
this.noHay(numero, campo, m);
|
this.noHay(numero, campo, m);
|
||||||
if (typeof numero === 'number') numero = numero.toString();
|
if (typeof numero === 'number') numero = numero.toString();
|
||||||
if (!validator.isNumeric(numero, { no_symbols: true })) this.noValido(campo, m, 'no es un número entero válido');
|
if (!validator.isNumeric(numero, { no_symbols: true })) this.noValido(campo, m, 'no es un número entero válido');
|
||||||
return Number(numero);
|
return Number(numero);
|
||||||
}
|
}
|
||||||
|
|
||||||
validarCorreo(correo: any, length?: any, campo: string = 'correo', m: boolean = true) {
|
validarCorreo(correo: any, length?: any, campo: string = 'correo', m: boolean = true) {
|
||||||
this.validacionBasicaStr(correo, campo, m, length);
|
this.validacionBasicaStr(correo, campo, m, length);
|
||||||
if (!validator.isEmail(correo)) this.noValido(campo, m, 'no es un correo válido');
|
if (!validator.isEmail(correo)) this.noValido(campo, m, 'no es un correo válido');
|
||||||
return correo;
|
return correo;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarTexto(texto, campo, m, length) {
|
validarTexto(texto, campo, m, length) {
|
||||||
this.validacionBasicaStr(texto, campo, m, length);
|
this.validacionBasicaStr(texto, campo, m, length);
|
||||||
for (const char of texto) {
|
for (const char of texto) {
|
||||||
if (!validator.isAlpha(char, 'es-ES') && char !== ' ' && char !== '.') {
|
if (!validator.isAlpha(char, 'es-ES') && char !== ' ' && char !== '.') {
|
||||||
@@ -60,7 +60,7 @@ export class ValidacionService {
|
|||||||
return texto;
|
return texto;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarAlfanumerico(texto, campo, m, length) {
|
validarAlfanumerico(texto, campo, m, length) {
|
||||||
this.validacionBasicaStr(texto, campo, m, length);
|
this.validacionBasicaStr(texto, campo, m, length);
|
||||||
for (const char of texto) {
|
for (const char of texto) {
|
||||||
if (!this.caracterEspecial(char) && !validator.isAlphanumeric(char, 'es-ES')) {
|
if (!this.caracterEspecial(char) && !validator.isAlphanumeric(char, 'es-ES')) {
|
||||||
@@ -70,7 +70,7 @@ export class ValidacionService {
|
|||||||
return texto;
|
return texto;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarNumeroCuenta(numeroCuenta, campo = 'numero de cuenta', m = true) {
|
validarNumeroCuenta(numeroCuenta, campo = 'numero de cuenta', m = true) {
|
||||||
this.validacionBasicaStr(numeroCuenta, campo, m, 9);
|
this.validacionBasicaStr(numeroCuenta, campo, m, 9);
|
||||||
if (!validator.isNumeric(numeroCuenta, { no_symbols: true })) {
|
if (!validator.isNumeric(numeroCuenta, { no_symbols: true })) {
|
||||||
this.noValido(campo, m, 'tiene caracteres que no son números');
|
this.noValido(campo, m, 'tiene caracteres que no son números');
|
||||||
@@ -78,14 +78,14 @@ export class ValidacionService {
|
|||||||
return numeroCuenta;
|
return numeroCuenta;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarFecha(fecha, campo, m) {
|
validarFecha(fecha, campo, m) {
|
||||||
const fechaMoment = moment(fecha);
|
const fechaMoment = moment(fecha);
|
||||||
this.noHay(fecha, campo, m);
|
this.noHay(fecha, campo, m);
|
||||||
if (!fechaMoment.isValid()) this.noValido(campo, m, 'no es una fecha válida');
|
if (!fechaMoment.isValid()) this.noValido(campo, m, 'no es una fecha válida');
|
||||||
return fechaMoment;
|
return fechaMoment;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarNumero(numero, campo, m, length, no_symbols = true, makeNumber = false) {
|
validarNumero(numero, campo, m, length, no_symbols = true, makeNumber = false) {
|
||||||
this.validacionBasicaStr(numero, campo, m, length);
|
this.validacionBasicaStr(numero, campo, m, length);
|
||||||
if (!validator.isNumeric(numero, { no_symbols })) {
|
if (!validator.isNumeric(numero, { no_symbols })) {
|
||||||
this.noValido(campo, m, 'tiene caracteres que no son números');
|
this.noValido(campo, m, 'tiene caracteres que no son números');
|
||||||
@@ -93,32 +93,53 @@ export class ValidacionService {
|
|||||||
return makeNumber ? Number(numero) : numero;
|
return makeNumber ? Number(numero) : numero;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarObjetoVacio(obj) {
|
validarObjetoVacio(obj) {
|
||||||
return Object.keys(obj).length === 0;
|
return Object.keys(obj).length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async validarPreTermino(idServicio) {
|
async validarPreTermino(idServicio: number) {
|
||||||
const res = await this.servicioRepository.findOne({ where: { idServicio } });
|
const res = await this.servicioRepository.findOne({
|
||||||
|
where: { idServicio },
|
||||||
|
relations: [
|
||||||
|
'cuestionarioPrograma',
|
||||||
|
'cuestionarioPrograma2',
|
||||||
|
'cuestionarioAlumno',
|
||||||
|
'cuestionarioAlumno2',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res) return '';
|
||||||
|
|
||||||
|
const tieneCuestionarioPrograma =
|
||||||
|
!!res.cuestionarioPrograma?.idCuestionarioPrograma ||
|
||||||
|
!!res.cuestionarioPrograma2?.idCuestionarioPrograma2;
|
||||||
|
|
||||||
|
const tieneCuestionarioAlumno =
|
||||||
|
!!res.cuestionarioAlumno?.idCuestionarioAlumno ||
|
||||||
|
!!res.cuestionarioAlumno2?.idCuestionarioAlumno2;
|
||||||
|
|
||||||
|
const tieneDocumentos =
|
||||||
|
!!res.cartaTermino && !!res.informeGlobal;
|
||||||
|
|
||||||
|
if (tieneCuestionarioPrograma && tieneCuestionarioAlumno && tieneDocumentos) {
|
||||||
|
await this.servicioRepository.update(idServicio, {
|
||||||
|
status: { idStatus: 5 },
|
||||||
|
});
|
||||||
|
|
||||||
if (
|
|
||||||
(res?.cuestionarioPrograma.idCuestionarioPrograma || res?.cuestionarioPrograma2.idCuestionarioPrograma2) &&
|
|
||||||
(res.cuestionarioAlumno.idCuestionarioAlumno || res.cuestionarioAlumno2.idCuestionarioAlumno2) &&
|
|
||||||
res.cartaTermino &&
|
|
||||||
res.informeGlobal
|
|
||||||
) {
|
|
||||||
await this.servicioRepository.update({ idServicio }, { status: {idStatus:5} });
|
|
||||||
return 'Este Servicio Social pasó a Término, espera a que COESI autorice tu liberación.';
|
return 'Este Servicio Social pasó a Término, espera a que COESI autorice tu liberación.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
validarCuestionarioAlumno2(body) {
|
|
||||||
|
validarCuestionarioAlumno2(body) {
|
||||||
const optionalKeys = ['p5', 'p8', 'p16', 'p18'];
|
const optionalKeys = ['p5', 'p8', 'p16', 'p18'];
|
||||||
if (Array.isArray(body.p1)) body.p1 = body.p1.join(', ');
|
if (Array.isArray(body.p1)) body.p1 = body.p1.join(', ');
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(body)) {
|
for (const [key, value] of Object.entries(body)) {
|
||||||
if (!optionalKeys.includes(key) && (value === null || value === undefined || value === '')) {
|
if (!optionalKeys.includes(key) && (value === null || value === undefined || value === '')) {
|
||||||
throw new Error(`El campo ${key} no puede estar vacío.`);
|
throw new BadRequestException(`El campo ${key} no puede estar vacío.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,20 +157,20 @@ export class ValidacionService {
|
|||||||
|
|
||||||
for (const key of expectedKeys) {
|
for (const key of expectedKeys) {
|
||||||
if (!(key in body)) {
|
if (!(key in body)) {
|
||||||
throw new Error(`Falta la respuesta para la pregunta ${key}.`);
|
throw new BadRequestException(`Falta la respuesta para la pregunta ${key}.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
validarCuestionarioPrograma2(body) {
|
validarCuestionarioPrograma2(body) {
|
||||||
const camposOpcionales = ['p6'];
|
const camposOpcionales = ['p6'];
|
||||||
if (Array.isArray(body.p1)) body.p1 = body.p1.join(', ');
|
if (Array.isArray(body.p1)) body.p1 = body.p1.join(', ');
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(body)) {
|
for (const [key, value] of Object.entries(body)) {
|
||||||
if (!camposOpcionales.includes(key) && (value === null || value === undefined || value === '')) {
|
if (!camposOpcionales.includes(key) && (value === null || value === undefined || value === '')) {
|
||||||
throw new Error(`El campo ${key} no puede estar vacío.`);
|
throw new BadRequestException(`El campo ${key} no puede estar vacío.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +184,7 @@ export class ValidacionService {
|
|||||||
|
|
||||||
for (const key of expectedKeys) {
|
for (const key of expectedKeys) {
|
||||||
if (!(key in body)) {
|
if (!(key in body)) {
|
||||||
throw new Error(`Falta la respuesta para la pregunta ${key}.`);
|
throw new BadRequestException(`Falta la respuesta para la pregunta ${key}.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-2
@@ -1,12 +1,23 @@
|
|||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
import { ValidationPipe } from '@nestjs/common';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
|
|
||||||
|
app.useGlobalPipes(
|
||||||
|
new ValidationPipe({
|
||||||
|
whitelist: true, // elimina propiedades que no existan en el DTO
|
||||||
|
transform: true, // permite que @Type() funcione
|
||||||
|
transformOptions: { enableImplicitConversion: true }, // convierte strings → number/date
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
app.enableCors();
|
app.enableCors();
|
||||||
await app.listen(process.env.PORT ?? 3000);
|
await app.listen(process.env.APP_PORT ?? 3000);
|
||||||
console.log(`Aplicación corriendo en: http://localhost:${process.env.PORT ?? 3000}`);
|
console.log(
|
||||||
|
`Aplicación corriendo en: http://localhost:${process.env.APP_PORT ?? 3000}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { Usuario } from "src/usuario/entities/usuario.entity";
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Entity('programa')
|
@Entity('programa')
|
||||||
export class Programa {
|
export class Programa {
|
||||||
@@ -25,9 +32,10 @@ export class Programa {
|
|||||||
@Column({ type: 'boolean', default: true })
|
@Column({ type: 'boolean', default: true })
|
||||||
activo: boolean;
|
activo: boolean;
|
||||||
|
|
||||||
@ManyToOne(()=>Usuario,(usuario)=>usuario.programa)
|
@ManyToOne(() => Usuario, (usuario) => usuario.programa)
|
||||||
usuario:Usuario;
|
@JoinColumn({ name: 'idUsuario' })
|
||||||
|
usuario: Usuario;
|
||||||
|
|
||||||
@OneToMany(()=>Servicio,(servicio)=>servicio.cuestionarioAlumno2)
|
@OneToMany(() => Servicio, (servicio) => servicio.cuestionarioAlumno2)
|
||||||
servicio:Servicio[];
|
servicio: Servicio[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
UseInterceptors,
|
UseInterceptors,
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
Param,
|
Param,
|
||||||
|
ParseIntPipe,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { FileInterceptor } from '@nestjs/platform-express';
|
import { FileInterceptor } from '@nestjs/platform-express';
|
||||||
import { diskStorage } from 'multer';
|
import { diskStorage } from 'multer';
|
||||||
@@ -70,13 +71,18 @@ export class ProgramaController {
|
|||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
async reasignarProgramas(
|
async reasignarProgramas(
|
||||||
@Body() email: Email,
|
@Body() email: Email,
|
||||||
@Param('idUsuario') idUsuario: number,
|
@Param('idUsuario', ParseIntPipe) idUsuario: number,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
console.log('BODY:', email);
|
||||||
|
console.log('PARAM:', idUsuario);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await this.programaService.reasignarProgramas(
|
const data = await this.programaService.reasignarProgramas(
|
||||||
idUsuario,
|
idUsuario,
|
||||||
email.correo,
|
email.correo,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
message: 'Programas reasignados con éxito',
|
message: 'Programas reasignados con éxito',
|
||||||
|
|||||||
@@ -1,9 +1,27 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ProgramaService } from './programa.service';
|
import { ProgramaService } from './programa.service';
|
||||||
import { ProgramaController } from './programa.controller';
|
import { ProgramaController } from './programa.controller';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { Programa } from './entities/programa.entity';
|
||||||
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
|
import { UsuarioModule } from 'src/usuario/usuario.module';
|
||||||
|
import { ValidacionService } from 'src/helpers.services/validacion.service';
|
||||||
|
import { AuthService } from 'src/auth/auth.service';
|
||||||
|
import { gmail } from 'src/helpers.services/gmail.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
import { JwtService } from '@nestjs/jwt';
|
||||||
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [TypeOrmModule.forFeature([Programa, Servicio]), UsuarioModule],
|
||||||
controllers: [ProgramaController],
|
controllers: [ProgramaController],
|
||||||
providers: [ProgramaService],
|
providers: [
|
||||||
|
ProgramaService,
|
||||||
|
AuthService,
|
||||||
|
ValidacionService,
|
||||||
|
gmail,
|
||||||
|
JwtService,
|
||||||
|
],
|
||||||
|
exports: [TypeOrmModule],
|
||||||
})
|
})
|
||||||
export class ProgramaModule {}
|
export class ProgramaModule {}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Like, Repository } from 'typeorm';
|
||||||
import * as csv from 'csvtojson';
|
import * as csv from 'csvtojson';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@@ -13,6 +13,8 @@ import { ValidacionService } from 'src/helpers.services/validacion.service';
|
|||||||
import { AuthService } from 'src/auth/auth.service';
|
import { AuthService } from 'src/auth/auth.service';
|
||||||
import { gmail } from 'src/helpers.services/gmail.service';
|
import { gmail } from 'src/helpers.services/gmail.service';
|
||||||
import { SendMailDto } from 'src/helpers.services/dto/send-email.dto';
|
import { SendMailDto } from 'src/helpers.services/dto/send-email.dto';
|
||||||
|
const { enviarSec } = require('../helpers.services/msjCorreos');
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProgramaService {
|
export class ProgramaService {
|
||||||
@@ -24,7 +26,7 @@ export class ProgramaService {
|
|||||||
private validacionService: ValidacionService,
|
private validacionService: ValidacionService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private gmail: gmail,
|
private gmail: gmail,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async cargaMasiva(nombreArchivo: string): Promise<{ message: string }> {
|
async cargaMasiva(nombreArchivo: string): Promise<{ message: string }> {
|
||||||
const filePath = path.join('server/uploads', nombreArchivo);
|
const filePath = path.join('server/uploads', nombreArchivo);
|
||||||
@@ -50,12 +52,14 @@ export class ProgramaService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
this.validacionService.validarCorreo(prog.correo);
|
this.validacionService.validarCorreo(prog.correo);
|
||||||
} catch {
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
mensaje += 'Correo inválido. Línea omitida.\n\n';
|
mensaje += 'Correo inválido. Línea omitida.\n\n';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const acatlan = prog.clave.substr(4, 7) === '-12/20-';
|
const acatlan = prog.clave.substr(4, 8) === '-12/145-';
|
||||||
|
console.log("clave:", prog.clave.substr(4, 8))
|
||||||
const activo = Number(prog.clave.substr(0, 4)) === today.year();
|
const activo = Number(prog.clave.substr(0, 4)) === today.year();
|
||||||
|
|
||||||
let responsable = await this.usuarioRepo.findOne({
|
let responsable = await this.usuarioRepo.findOne({
|
||||||
@@ -67,11 +71,18 @@ export class ProgramaService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Agregamos esta linea para verificar los logs
|
||||||
|
console.log("prog:", prog);
|
||||||
|
|
||||||
|
|
||||||
if (!responsable) {
|
if (!responsable) {
|
||||||
const password = await this.authService.encriptar(
|
|
||||||
this.authService.generarPassword(),
|
let contraseña = await this.authService.generarPassword();
|
||||||
);
|
const password = await this.authService.encriptar(contraseña);
|
||||||
const correoInfo = enviarSec(password, prog.correo, prog.nombre);
|
|
||||||
|
|
||||||
|
|
||||||
|
const correoInfo = enviarSec(contraseña, prog.correo, prog.nombre);
|
||||||
|
|
||||||
responsable = await this.usuarioRepo.create({
|
responsable = await this.usuarioRepo.create({
|
||||||
usuario: prog.correo,
|
usuario: prog.correo,
|
||||||
@@ -92,10 +103,6 @@ export class ProgramaService {
|
|||||||
fecha_recibido: new Date(),
|
fecha_recibido: new Date(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!process.env.TOKEN_GMAIL) {
|
|
||||||
throw new Error('No existe el token');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
responsable = await this.usuarioRepo.save(responsable);
|
responsable = await this.usuarioRepo.save(responsable);
|
||||||
|
|
||||||
@@ -167,6 +174,15 @@ export class ProgramaService {
|
|||||||
mensaje += `Error creando programa: ${err.message}\n`;
|
mensaje += `Error creando programa: ${err.message}\n`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
await this.programaRepo.update(
|
||||||
|
{ idPrograma: existente.idPrograma },
|
||||||
|
{ institucion: prog.institucion, programa: prog.programa }
|
||||||
|
)
|
||||||
|
|
||||||
|
await this.usuarioRepo.update(
|
||||||
|
{ idUsuario: responsable.idUsuario },
|
||||||
|
{ nombre: prog.nombre }
|
||||||
|
)
|
||||||
mensaje += `Programa ACATLÁN ya pertenece a ${responsable.usuario}\n`;
|
mensaje += `Programa ACATLÁN ya pertenece a ${responsable.usuario}\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,17 +205,22 @@ export class ProgramaService {
|
|||||||
|
|
||||||
const usuario = await this.usuarioRepo.findOne({
|
const usuario = await this.usuarioRepo.findOne({
|
||||||
where: { idUsuario },
|
where: { idUsuario },
|
||||||
|
relations: ['tipoUsuario'],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('No existe este usuario.');
|
throw new BadRequestException('No existe este usuario.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usuario.tipoUsuario.idTipoUsuario !== 2) {
|
if (usuario.tipoUsuario.idTipoUsuario !== 2) {
|
||||||
throw new Error('No es un usuario de tipo responsable');
|
throw new BadRequestException('No es un usuario de tipo responsable');
|
||||||
}
|
}
|
||||||
return this.programaRepo.find({
|
const year = new Date().getFullYear().toString();
|
||||||
where: { usuario: { idUsuario } },
|
|
||||||
|
return await this.programaRepo.find({
|
||||||
|
where: {
|
||||||
|
usuario: { idUsuario }, clavePrograma: Like(`${year}%`),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,20 +232,23 @@ export class ProgramaService {
|
|||||||
|
|
||||||
const usuario = await this.usuarioRepo.findOne({
|
const usuario = await this.usuarioRepo.findOne({
|
||||||
where: { idUsuario },
|
where: { idUsuario },
|
||||||
|
relations: ['tipoUsuario'], // Se agrego la relacion con tipo de usuario
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('No existe este usuario.');
|
throw new BadRequestException('No existe este usuario.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usuario.tipoUsuario.idTipoUsuario !== 2) {
|
if (usuario.tipoUsuario.idTipoUsuario !== 2) {
|
||||||
throw new Error('No es un usuario de tipo responsable');
|
throw new BadRequestException('No es un usuario de tipo responsable');
|
||||||
}
|
}
|
||||||
|
const year = new Date().getFullYear().toString();
|
||||||
|
|
||||||
return this.programaRepo.find({
|
return await this.programaRepo.find({
|
||||||
where: {
|
where: {
|
||||||
usuario: { idUsuario },
|
usuario: { idUsuario },
|
||||||
activo: true,
|
activo: true,
|
||||||
|
clavePrograma: Like(`${year}%`)
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -240,19 +264,20 @@ export class ProgramaService {
|
|||||||
|
|
||||||
let usuarioNuevo = await this.usuarioRepo.findOne({
|
let usuarioNuevo = await this.usuarioRepo.findOne({
|
||||||
where: { idUsuario: idusuario },
|
where: { idUsuario: idusuario },
|
||||||
|
relations: ["tipoUsuario"],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!usuarioNuevo) throw new Error('No existe este usuario.');
|
if (!usuarioNuevo) throw new BadRequestException('No existe este usuario.');
|
||||||
if (usuarioNuevo.tipoUsuario.idTipoUsuario != 2)
|
if (usuarioNuevo.tipoUsuario.idTipoUsuario != 2)
|
||||||
throw new Error('No es un usuario de tipo responsable');
|
throw new BadRequestException('No es un usuario de tipo responsable');
|
||||||
if (usuarioNuevo.usuario === correoOtroResponsable)
|
if (usuarioNuevo.usuario === correoOtroResponsable)
|
||||||
throw new Error('Son el mismo usuario.');
|
throw new BadRequestException('Son el mismo usuario.');
|
||||||
|
|
||||||
let viejoResponsable = await this.usuarioRepo.findOne({
|
let viejoResponsable = await this.usuarioRepo.findOne({
|
||||||
where: { usuario: otroResponsable },
|
where: { usuario: otroResponsable },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!viejoResponsable) throw new Error('No existe este usuario.');
|
if (!viejoResponsable) throw new BadRequestException('No existe este usuario.');
|
||||||
|
|
||||||
await this.programaRepo.update(
|
await this.programaRepo.update(
|
||||||
{ usuario: viejoResponsable },
|
{ usuario: viejoResponsable },
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ export class CrearServicioDto {
|
|||||||
@IsEmail()
|
@IsEmail()
|
||||||
correo: string;
|
correo: string;
|
||||||
|
|
||||||
@IsDate()
|
@IsDateString()
|
||||||
fechaInicio: Date;
|
fechaInicio: string; // Cambiado a string antes tenia Date
|
||||||
|
|
||||||
@IsDate()
|
@IsDateString()
|
||||||
fechaFin: Date;
|
fechaFin: string; // Cambiado a string antes tenia Date
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class RegistroValidadoDto {
|
|||||||
idServicio: number;
|
idServicio: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
fechaNacimiento?: Date;
|
fechaNacimiento?: string; // Lo pasamos a string antes date
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@@ -19,15 +19,18 @@ export class UpdateServicioDto {
|
|||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString({}, { message: 'fechaInicio debe ser una fecha válida' })
|
@IsDateString({}, { message: 'fechaInicio debe ser una fecha válida' })
|
||||||
fechaInicio?: Date;
|
//@Type(() => Date)
|
||||||
|
fechaInicio?: string; // Lo pasamos a string antes date
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString({}, { message: 'fechaFin debe ser una fecha válida' })
|
@IsDateString({}, { message: 'fechaFin debe ser una fecha válida' })
|
||||||
fechaFin?: Date;
|
//@Type(() => Date)
|
||||||
|
fechaFin?: string; // Lo pasamos a string antes date
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsDateString({}, { message: 'fechaNacimiento debe ser una fecha válida' })
|
@IsDateString({}, { message: 'fechaNacimiento debe ser una fecha válida' })
|
||||||
fechaNacimiento?: Date;
|
//@Type(() => Date)
|
||||||
|
fechaNacimiento?: string; // Lo pasamos a string antes date
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString({ message: 'direccion debe ser texto' })
|
@IsString({ message: 'direccion debe ser texto' })
|
||||||
|
|||||||
@@ -1,88 +1,120 @@
|
|||||||
import { Carrera } from "src/carrera/entities/carrera.entity";
|
import { Carrera } from 'src/carrera/entities/carrera.entity';
|
||||||
import { CuestionarioAlumno } from "src/cuestionario-alumno/entities/cuestionario-alumno.entity";
|
import { CuestionarioAlumno } from 'src/cuestionario-alumno/entities/cuestionario-alumno.entity';
|
||||||
import { CuestionarioAlumno2 } from "src/cuestionario-alumno2/entities/cuestionario-alumno2.entity";
|
import { CuestionarioAlumno2 } from 'src/cuestionario-alumno2/entities/cuestionario-alumno2.entity';
|
||||||
import { CuestionarioPrograma } from "src/cuestionario-programa/entities/cuestionario-programa.entity";
|
import { CuestionarioPrograma } from 'src/cuestionario-programa/entities/cuestionario-programa.entity';
|
||||||
import { CuestionarioPrograma2 } from "src/cuestionario-programa2/entities/cuestionario-programa2.entity";
|
import { CuestionarioPrograma2 } from 'src/cuestionario-programa2/entities/cuestionario-programa2.entity';
|
||||||
import { Programa } from "src/programa/entities/programa.entity";
|
import { Programa } from 'src/programa/entities/programa.entity';
|
||||||
import { Status } from "src/status/entities/status.entity";
|
import { Status } from 'src/status/entities/status.entity';
|
||||||
import { Usuario } from "src/usuario/entities/usuario.entity";
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
Entity,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Entity('servicio')
|
@Entity('servicio')
|
||||||
export class Servicio {
|
export class Servicio {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
idServicio: number;
|
||||||
|
|
||||||
@PrimaryGeneratedColumn()
|
@Column({ type: 'varchar', length: 3 })
|
||||||
idServicio: number;
|
creditos: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 3 })
|
@Column({ type: 'varchar', length: 60 })
|
||||||
creditos: string;
|
correo: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60 })
|
@Column({ type: 'varchar', length: 15, nullable: true, default: null })
|
||||||
correo: string;
|
telefono?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 15, nullable: true, default: null })
|
@Column({ type: 'varchar', length: 200, nullable: true, default: null })
|
||||||
telefono?: string;
|
direccion?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 200, nullable: true, default: null })
|
@Column({ type: 'date' })
|
||||||
direccion?: string;
|
fechaInicio: string; // Cambios a tipo string antes tenia date
|
||||||
|
|
||||||
@Column({ type: 'date' })
|
@Column({ type: 'date' })
|
||||||
fechaInicio: Date;
|
fechaFin: string; // Cambios a tipo string antes tenia date
|
||||||
|
|
||||||
@Column({ type: 'date' })
|
@Column({ type: 'date', nullable: true, default: null })
|
||||||
fechaFin: Date;
|
fechaLiberacion?: string; // Cambios a tipo string antes tenia date
|
||||||
|
|
||||||
@Column({ type: 'date', nullable: true, default: null })
|
@Column({ type: 'date', nullable: true, default: null })
|
||||||
fechaLiberacion?: Date;
|
fechaNacimiento?: string; // Cambios a tipo string antes tenia date
|
||||||
|
|
||||||
@Column({ type: 'date', nullable: true, default: null })
|
@Column({ type: 'varchar', length: 60 })
|
||||||
fechaNacimiento?: Date;
|
carpeta: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60 })
|
@Column({ type: 'varchar', length: 60 })
|
||||||
carpeta: string;
|
cartaAceptacion: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60 })
|
@Column({ type: 'varchar', length: 60, nullable: true, default: null })
|
||||||
cartaAceptacion: string;
|
cartaTermino?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60, nullable: true, default: null })
|
@Column({ type: 'varchar', length: 60, nullable: true, default: null })
|
||||||
cartaTermino?: string;
|
informeGlobal?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 60, nullable: true, default: null })
|
@Column({ type: 'varchar', length: 250, nullable: true, default: null })
|
||||||
informeGlobal?: string;
|
programaInterno?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 250, nullable: true, default: null })
|
@Column({ type: 'varchar', length: 50, nullable: true, default: null })
|
||||||
programaInterno?: string;
|
profesor?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50, nullable: true, default: null })
|
@Column({ type: 'boolean', nullable: true, default: null })
|
||||||
profesor?: string;
|
vistoBuenoAcatlan?: boolean;
|
||||||
|
|
||||||
@Column({ type: 'boolean', nullable: true, default: null })
|
@CreateDateColumn({ name: 'createdAt', type: 'datetime' })
|
||||||
vistoBuenoAcatlan?: boolean;
|
createdAt: Date;
|
||||||
|
|
||||||
@ManyToOne(()=>Usuario,(usuario)=>usuario.servicio)
|
@UpdateDateColumn({ name: 'updatedAt', type: 'datetime' })
|
||||||
usuario:Usuario
|
updatedAt: Date;
|
||||||
|
|
||||||
@ManyToOne(()=>CuestionarioAlumno2,(cuestionarioAlumno2)=>cuestionarioAlumno2.servicio)
|
// faltaba createdAT y updatedAT
|
||||||
cuestionarioAlumno2:CuestionarioAlumno2;
|
|
||||||
|
|
||||||
@ManyToOne(()=>CuestionarioPrograma2,(cuestionarioPrograma2)=>cuestionarioPrograma2.servicio)
|
@ManyToOne(() => Usuario, (usuario) => usuario.servicio)
|
||||||
cuestionarioPrograma2:CuestionarioPrograma2;
|
@JoinColumn({ name: 'idUsuario' })
|
||||||
|
usuario: Usuario;
|
||||||
|
|
||||||
@ManyToOne(()=>CuestionarioPrograma,(cuestionarioPrograma)=>cuestionarioPrograma.servicio)
|
@ManyToOne(
|
||||||
cuestionarioPrograma:CuestionarioPrograma;
|
() => CuestionarioAlumno2,
|
||||||
|
(cuestionarioAlumno2) => cuestionarioAlumno2.servicio,
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: 'idCuestionarioAlumno2' })
|
||||||
|
cuestionarioAlumno2: CuestionarioAlumno2;
|
||||||
|
|
||||||
@ManyToOne(()=>CuestionarioAlumno,(cuestionarioAlumno)=>cuestionarioAlumno.servicio)
|
@ManyToOne(
|
||||||
cuestionarioAlumno:CuestionarioAlumno;
|
() => CuestionarioPrograma2,
|
||||||
|
(cuestionarioPrograma2) => cuestionarioPrograma2.servicio,
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: 'idCuestionarioPrograma2' })
|
||||||
|
cuestionarioPrograma2: CuestionarioPrograma2;
|
||||||
|
|
||||||
@ManyToOne(()=>Status,(status)=>status.servicio)
|
@ManyToOne(
|
||||||
status:Status;
|
() => CuestionarioPrograma,
|
||||||
|
(cuestionarioPrograma) => cuestionarioPrograma.servicio,
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: 'idCuestionarioPrograma' })
|
||||||
|
cuestionarioPrograma: CuestionarioPrograma;
|
||||||
|
|
||||||
@ManyToOne(()=>Programa,(programa)=>programa.servicio)
|
@ManyToOne(
|
||||||
programa:Programa;
|
() => CuestionarioAlumno,
|
||||||
|
(cuestionarioAlumno) => cuestionarioAlumno.servicio,
|
||||||
@ManyToOne(()=>Carrera,(carrera)=>carrera.servicio)
|
)
|
||||||
carrera:Carrera;
|
@JoinColumn({ name: 'idCuestionarioAlumno' })
|
||||||
|
cuestionarioAlumno: CuestionarioAlumno;
|
||||||
|
|
||||||
|
@ManyToOne(() => Status, (status) => status.servicio)
|
||||||
|
@JoinColumn({ name: 'idStatus' })
|
||||||
|
status: Status;
|
||||||
|
|
||||||
|
@ManyToOne(() => Programa, (programa) => programa.servicio)
|
||||||
|
@JoinColumn({ name: 'idPrograma' })
|
||||||
|
programa: Programa;
|
||||||
|
|
||||||
|
@ManyToOne(() => Carrera, (carrera) => carrera.servicios)
|
||||||
|
@JoinColumn({ name: 'idCarrera' })
|
||||||
|
carrera: Carrera;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { diskStorage } from 'multer';
|
||||||
|
import { extname } from 'path';
|
||||||
|
|
||||||
|
export const multerConfig = {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './server/uploads',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
const uniqueName =
|
||||||
|
Date.now() + '-' + Math.round(Math.random() * 1e9);
|
||||||
|
cb(null, uniqueName + extname(file.originalname));
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
@@ -11,6 +11,8 @@ import {
|
|||||||
UseInterceptors,
|
UseInterceptors,
|
||||||
Res,
|
Res,
|
||||||
ParseIntPipe,
|
ParseIntPipe,
|
||||||
|
Param,
|
||||||
|
Req,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import {
|
import {
|
||||||
FileInterceptor,
|
FileInterceptor,
|
||||||
@@ -20,30 +22,85 @@ import { ServicioService } from './servicio.service';
|
|||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
import { CrearServicioDto } from './dto/create-servicio.dto';
|
import { CrearServicioDto } from './dto/create-servicio.dto';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
|
import { ServiciosAdminDto } from './dto/servicios-admin.dto';
|
||||||
|
import { ServiciosResponsableDto } from './dto/servicios-responsable.dto';
|
||||||
|
import { RegistroValidadoDto } from './dto/registro-validado.dto';
|
||||||
|
import { multerConfig } from './multer';
|
||||||
|
import { diskStorage } from 'multer';
|
||||||
|
|
||||||
@Controller('servicio')
|
@Controller('servicio')
|
||||||
export class ServicioController {
|
export class ServicioController {
|
||||||
constructor(private readonly servicioService: ServicioService) {}
|
constructor(private readonly servicioService: ServicioService) { }
|
||||||
|
|
||||||
// ------------------ POST ------------------
|
// ------------------ POST ------------------
|
||||||
|
|
||||||
|
// Garegue un nuevo endpoint para hacer pruebas
|
||||||
|
@Post('test-upload')
|
||||||
|
@UseInterceptors(FileInterceptor('file'))
|
||||||
|
uploadTest(
|
||||||
|
@UploadedFile() file: Express.Multer.File,
|
||||||
|
@Req() req: any,
|
||||||
|
) {
|
||||||
|
console.log('FILE:', file);
|
||||||
|
console.log('FILES REQ:', req.file);
|
||||||
|
console.log('FILES BODY:', req.body);
|
||||||
|
return { ok: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('registro-validado')
|
||||||
|
async registroValidado(
|
||||||
|
@Body() dto: RegistroValidadoDto,
|
||||||
|
): Promise<{ message: string }> {
|
||||||
|
console.log('RegistroValidadoDto recibido:', dto);
|
||||||
|
return this.servicioService.registroValidado(dto);
|
||||||
|
}
|
||||||
|
|
||||||
@Post('nuevo')
|
@Post('nuevo')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
@UseInterceptors(FileInterceptor('cartaAceptacion'))
|
@UseInterceptors(FileInterceptor('cartaAceptacion', {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './server/uploads',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
cb(null, Date.now() + '-' + file.originalname);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
)
|
||||||
async crearServicio(
|
async crearServicio(
|
||||||
@UploadedFile() file: Express.Multer.File,
|
@UploadedFile() file: Express.Multer.File,
|
||||||
@Body('alumno') alumnoJson: string,
|
@Body('alumno') alumnoJson: string,
|
||||||
) {
|
) {
|
||||||
const dto: CrearServicioDto = JSON.parse(alumnoJson);
|
const dto: CrearServicioDto = JSON.parse(alumnoJson);
|
||||||
|
|
||||||
|
console.log('Archivo recibido:', file);
|
||||||
|
|
||||||
return await this.servicioService.registrarNuevoServicio(dto, file);
|
return await this.servicioService.registrarNuevoServicio(dto, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------ GET ------------------
|
// ------------------ GET ------------------
|
||||||
|
|
||||||
|
@Get('todos')
|
||||||
|
//@UseGuards(AuthGuard('jwt'))
|
||||||
|
async obtenerTodosLosServicios() {
|
||||||
|
return this.servicioService.obtenerTodosLosServicios();
|
||||||
|
}
|
||||||
|
|
||||||
@Get('admin')
|
@Get('admin')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
async obtenerAdmin(@Query() query: any) {
|
async obtenerServiciosAdmin(@Query() dto: ServiciosAdminDto) {
|
||||||
return this.servicioService.obtenerDetalleServicio(query.idServicio);
|
return await this.servicioService.obtenerServiciosAdmin(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('servicios_responsable')
|
||||||
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
async obtenerServiciosResponsable(@Query() dto: ServiciosResponsableDto) {
|
||||||
|
return await this.servicioService.obtenerServiciosResponsable(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('admin/:idServicio')
|
||||||
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
async obtenerAdmin(@Param('idServicio') idServicio: number) {
|
||||||
|
return this.servicioService.obtenerDetalleServicio(idServicio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('alumno')
|
@Get('alumno')
|
||||||
@@ -62,10 +119,14 @@ export class ServicioController {
|
|||||||
return res.download(path);
|
return res.download(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Corregi el endpoint tenia llamando a otrea funcion
|
||||||
@Get('reporte')
|
@Get('reporte')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
async generarReporte(@Query() query: any, @Res() res: Response) {
|
async generarReporte(
|
||||||
const path = await this.servicioService.generarGustavoBazPrada(query.year);
|
@Query('inicio') inicio: string,
|
||||||
|
@Query('fin') fin: string,
|
||||||
|
@Res() res: Response) {
|
||||||
|
const path = await this.servicioService.generarReporte(inicio, fin);
|
||||||
return res.download(path);
|
return res.download(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,30 +139,59 @@ export class ServicioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Put('carta_aceptacion')
|
@Put('carta_aceptacion')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
//@UseGuards(AuthGuard('jwt'))
|
||||||
@UseInterceptors(FileInterceptor('cartaAceptacion'))
|
@UseInterceptors(
|
||||||
|
FileInterceptor('cartaAceptacion', {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './server/uploads',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
cb(null, Date.now() + '-' + file.originalname);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
)
|
||||||
async subirCartaAceptacion(
|
async subirCartaAceptacion(
|
||||||
@UploadedFile() file: Express.Multer.File,
|
@UploadedFile() file: Express.Multer.File,
|
||||||
@Body('data') dataJson: string,
|
@Body('data') dataJson: string,
|
||||||
) {
|
) {
|
||||||
const body = JSON.parse(dataJson);
|
const body = JSON.parse(dataJson);
|
||||||
return this.servicioService.cartaTermino(body.idServicio, file);
|
console.log('file:', file)
|
||||||
|
return this.servicioService.cartaTermino(body.idServicio, file.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put('carta_termino')
|
@Put('carta_termino')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
@UseInterceptors(FileInterceptor('cartaTermino'))
|
@UseInterceptors(
|
||||||
|
FileInterceptor('cartaTermino', {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './server/uploads',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
cb(null, Date.now() + '-' + file.originalname);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
)
|
||||||
async subirCartaTermino(
|
async subirCartaTermino(
|
||||||
@UploadedFile() file: Express.Multer.File,
|
@UploadedFile() file: Express.Multer.File,
|
||||||
@Body('data') dataJson: string,
|
@Body('data') dataJson: string,
|
||||||
) {
|
) {
|
||||||
const body = JSON.parse(dataJson);
|
const body = JSON.parse(dataJson);
|
||||||
|
console.log("file", file);
|
||||||
return this.servicioService.subirCartaTermino(body.idServicio, file);
|
return this.servicioService.subirCartaTermino(body.idServicio, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put('informe_global')
|
@Put('informe_global')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
@UseInterceptors(FileInterceptor('informeGlobal'))
|
@UseInterceptors(
|
||||||
|
FileInterceptor('informeGlobal', {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: './server/uploads',
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
cb(null, Date.now() + '-' + file.originalname);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
)
|
||||||
async subirInformeGlobal(
|
async subirInformeGlobal(
|
||||||
@UploadedFile() file: Express.Multer.File,
|
@UploadedFile() file: Express.Multer.File,
|
||||||
@Body('data') dataJson: string,
|
@Body('data') dataJson: string,
|
||||||
@@ -146,13 +236,26 @@ export class ServicioController {
|
|||||||
{ name: 'cartaAceptacion', maxCount: 1 },
|
{ name: 'cartaAceptacion', maxCount: 1 },
|
||||||
{ name: 'cartaTermino', maxCount: 1 },
|
{ name: 'cartaTermino', maxCount: 1 },
|
||||||
{ name: 'informeGlobal', maxCount: 1 },
|
{ name: 'informeGlobal', maxCount: 1 },
|
||||||
]),
|
], multerConfig,),
|
||||||
|
|
||||||
)
|
)
|
||||||
async actualizarServicio(
|
async actualizarServicio(
|
||||||
@UploadedFiles() files: Record<string, Express.Multer.File[]>,
|
@UploadedFiles() files: Record<string, Express.Multer.File[]>,
|
||||||
@Body('data') dataJson: string,
|
@Body('data') dataJson: string,
|
||||||
) {
|
) {
|
||||||
const data = JSON.parse(dataJson);
|
const data = JSON.parse(dataJson);
|
||||||
|
|
||||||
return this.servicioService.update(data, files);
|
return this.servicioService.update(data, files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Put('registro')
|
||||||
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
async registro(@Body() body: { idServicio: number }) {
|
||||||
|
try {
|
||||||
|
return this.servicioService.registro(body.idServicio);
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,24 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||||||
import { Servicio } from './entities/servicio.entity';
|
import { Servicio } from './entities/servicio.entity';
|
||||||
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
import { ArchivoService } from 'src/helpers.services/archivo.service';
|
import { ArchivoService } from 'src/helpers.services/archivo.service';
|
||||||
|
import { UsuarioModule } from 'src/usuario/usuario.module';
|
||||||
|
import { ProgramaModule } from 'src/programa/programa.module';
|
||||||
|
import { Programa } from 'src/programa/entities/programa.entity';
|
||||||
|
import { Carrera } from 'src/carrera/entities/carrera.entity';
|
||||||
|
import { Auth } from 'googleapis';
|
||||||
|
import { AuthService } from 'src/auth/auth.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
import { Status } from 'src/status/entities/status.entity';
|
||||||
|
import { MulterModule } from '@nestjs/platform-express';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([Servicio, Usuario])],
|
imports: [
|
||||||
|
TypeOrmModule.forFeature([Servicio, Usuario, Programa, Carrera, Status]),
|
||||||
|
AuthModule,
|
||||||
|
MulterModule.register({
|
||||||
|
dest: './uploads',
|
||||||
|
}),
|
||||||
|
],
|
||||||
controllers: [ServicioController],
|
controllers: [ServicioController],
|
||||||
providers: [
|
providers: [
|
||||||
ServicioService,
|
ServicioService,
|
||||||
@@ -19,5 +34,6 @@ import { ArchivoService } from 'src/helpers.services/archivo.service';
|
|||||||
gmail,
|
gmail,
|
||||||
ArchivoService,
|
ArchivoService,
|
||||||
],
|
],
|
||||||
|
exports: [TypeOrmModule],
|
||||||
})
|
})
|
||||||
export class ServicioModule {}
|
export class ServicioModule { }
|
||||||
|
|||||||
+396
-181
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,11 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { StatusService } from './status.service';
|
import { StatusService } from './status.service';
|
||||||
import { StatusController } from './status.controller';
|
import { StatusController } from './status.controller';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { Status } from './entities/status.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [TypeOrmModule.forFeature([Status])],
|
||||||
controllers: [StatusController],
|
controllers: [StatusController],
|
||||||
providers: [StatusService],
|
providers: [StatusService],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
import { Usuario } from "src/usuario/entities/usuario.entity";
|
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
|
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
@Entity('tipo_usuario')
|
@Entity('tipo_usuario')
|
||||||
export class TipoUsuario {
|
export class TipoUsuario {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
idTipoUsuario: number;
|
||||||
|
|
||||||
@PrimaryGeneratedColumn()
|
@Column({ type: 'varchar', length: 15 })
|
||||||
idTipoUsuario: number;
|
tipoUsuario: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 15 })
|
|
||||||
tipoUsuario: string;
|
|
||||||
|
|
||||||
@OneToMany(()=>Usuario, (usuario)=>usuario.tipoUsuario)
|
|
||||||
usuario:Usuario;
|
|
||||||
|
|
||||||
|
@OneToMany(() => Usuario, (usuario) => usuario.tipoUsuario)
|
||||||
|
usuario: Usuario;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
|
|
||||||
import { TipoUsuarioService } from './tipo-usuario.service';
|
|
||||||
import { CreateTipoUsuarioDto } from './dto/create-tipo-usuario.dto';
|
|
||||||
import { UpdateTipoUsuarioDto } from './dto/update-tipo-usuario.dto';
|
|
||||||
|
|
||||||
@Controller('tipo-usuario')
|
|
||||||
export class TipoUsuarioController {
|
|
||||||
constructor(private readonly tipoUsuarioService: TipoUsuarioService) {}
|
|
||||||
|
|
||||||
@Post()
|
|
||||||
create(@Body() createTipoUsuarioDto: CreateTipoUsuarioDto) {
|
|
||||||
return this.tipoUsuarioService.create(createTipoUsuarioDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get()
|
|
||||||
findAll() {
|
|
||||||
return this.tipoUsuarioService.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get(':id')
|
|
||||||
findOne(@Param('id') id: string) {
|
|
||||||
return this.tipoUsuarioService.findOne(+id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Patch(':id')
|
|
||||||
update(@Param('id') id: string, @Body() updateTipoUsuarioDto: UpdateTipoUsuarioDto) {
|
|
||||||
return this.tipoUsuarioService.update(+id, updateTipoUsuarioDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Delete(':id')
|
|
||||||
remove(@Param('id') id: string) {
|
|
||||||
return this.tipoUsuarioService.remove(+id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { TipoUsuario } from './entities/tipo-usuario.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [TypeOrmModule.forFeature([TipoUsuario])],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
providers: [],
|
providers: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import {
|
|||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
export class CreateUsuarioDto {
|
export class CreateUsuarioDto {
|
||||||
@IsEmail()
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@MaxLength(100)
|
@MaxLength(100)
|
||||||
usuario: string;
|
usuario: string;
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
import { CasoEspecial } from "src/caso-especial/entities/caso-especial.entity";
|
import { CasoEspecial } from 'src/caso-especial/entities/caso-especial.entity';
|
||||||
import { Programa } from "src/programa/entities/programa.entity";
|
import { Programa } from 'src/programa/entities/programa.entity';
|
||||||
import { Servicio } from "src/servicio/entities/servicio.entity";
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { TipoUsuario } from "src/tipo-usuario/entities/tipo-usuario.entity";
|
import { TipoUsuario } from 'src/tipo-usuario/entities/tipo-usuario.entity';
|
||||||
import { Column, Entity, ManyToMany, ManyToOne, OneToMany, PrimaryGeneratedColumn, Unique } from "typeorm";
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
Unique,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Entity('usuario')
|
@Entity('usuario')
|
||||||
@Unique(['usuario'])
|
@Unique(['usuario'])
|
||||||
export class Usuario {
|
export class Usuario {
|
||||||
|
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
idUsuario: number;
|
idUsuario: number;
|
||||||
|
|
||||||
@@ -23,16 +30,16 @@ export class Usuario {
|
|||||||
@Column({ type: 'boolean', default: true })
|
@Column({ type: 'boolean', default: true })
|
||||||
activo: boolean;
|
activo: boolean;
|
||||||
|
|
||||||
@ManyToOne(()=>TipoUsuario,(tipoUsuario)=>tipoUsuario.usuario)
|
@ManyToOne(() => TipoUsuario, (tipoUsuario) => tipoUsuario.usuario)
|
||||||
tipoUsuario:TipoUsuario;
|
@JoinColumn({ name: 'idTipoUsuario' }) // Talvez faltaba que se llame idTipoUsuario
|
||||||
|
tipoUsuario: TipoUsuario;
|
||||||
|
|
||||||
@OneToMany(()=>CasoEspecial,(casoEspecial)=>casoEspecial.usuario)
|
@OneToMany(() => CasoEspecial, (casoEspecial) => casoEspecial.usuario)
|
||||||
casoEspecial:CasoEspecial[];
|
casoEspecial: CasoEspecial[];
|
||||||
|
|
||||||
@OneToMany(()=>Programa,(programa)=>programa.usuario)
|
@OneToMany(() => Programa, (programa) => programa.usuario)
|
||||||
programa:Programa[];
|
programa: Programa[];
|
||||||
|
|
||||||
@OneToMany(()=>Servicio,(servicio)=>servicio.usuario)
|
|
||||||
servicio:Servicio[];
|
|
||||||
|
|
||||||
|
@OneToMany(() => Servicio, (servicio) => servicio.usuario)
|
||||||
|
servicio: Servicio[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
ParseIntPipe,
|
ParseIntPipe,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
|
UsePipes,
|
||||||
|
ValidationPipe,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { UsuarioService } from './usuario.service';
|
import { UsuarioService } from './usuario.service';
|
||||||
import { CreateUsuarioDto } from './dto/create-usuario.dto';
|
import { CreateUsuarioDto } from './dto/create-usuario.dto';
|
||||||
@@ -16,7 +20,26 @@ import { UpdateUsuarioDto } from './dto/update-usuario.dto';
|
|||||||
|
|
||||||
@Controller('usuario')
|
@Controller('usuario')
|
||||||
export class UsuarioController {
|
export class UsuarioController {
|
||||||
constructor(private readonly usuarioService: UsuarioService) {}
|
constructor(private readonly usuarioService: UsuarioService) { }
|
||||||
|
|
||||||
|
/*Get('todos')
|
||||||
|
//@UseGuards(AuthGuard('jwt'))
|
||||||
|
async obtenerTodosLosServicios() {
|
||||||
|
return this.usuarioService.obtenerTodosLosUsuarios();
|
||||||
|
}*/ //No subir en produccion
|
||||||
|
|
||||||
|
@Post('crearUsuario')
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true }))
|
||||||
|
async create(@Body() createUsuarioDto: CreateUsuarioDto) {
|
||||||
|
try {
|
||||||
|
return await this.usuarioService.create(createUsuarioDto);
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Error al crear usuario',
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Post('escolares/:numeroDeCuenta')
|
@Post('escolares/:numeroDeCuenta')
|
||||||
async escolares(@Param('numeroDeCuenta') numeroDeCuenta: string) {
|
async escolares(@Param('numeroDeCuenta') numeroDeCuenta: string) {
|
||||||
@@ -24,7 +47,7 @@ export class UsuarioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Post('new-password-alumno/:idServicio')
|
@Post('new-password-alumno/:idServicio')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
//@UseGuards(AuthGuard('jwt'))
|
||||||
async newPasswordAlumno(
|
async newPasswordAlumno(
|
||||||
@Param('idServicio', ParseIntPipe) idServicio: number,
|
@Param('idServicio', ParseIntPipe) idServicio: number,
|
||||||
) {
|
) {
|
||||||
@@ -56,7 +79,7 @@ export class UsuarioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Patch('responsable/:idUsuario')
|
@Patch('responsable/:idUsuario')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
//seGuards(AuthGuard('jwt'))
|
||||||
async actualizarResponsable(
|
async actualizarResponsable(
|
||||||
@Param('idUsuario', ParseIntPipe) idUsuario: number,
|
@Param('idUsuario', ParseIntPipe) idUsuario: number,
|
||||||
@Body() updateUsuarioDto: UpdateUsuarioDto,
|
@Body() updateUsuarioDto: UpdateUsuarioDto,
|
||||||
@@ -67,4 +90,12 @@ export class UsuarioController {
|
|||||||
updateUsuarioDto.nombre,
|
updateUsuarioDto.nombre,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('tipos-usuario')
|
||||||
|
async findTiposUsuario() {
|
||||||
|
return await this.usuarioService.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,26 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { UsuarioService } from './usuario.service';
|
import { UsuarioService } from './usuario.service';
|
||||||
import { UsuarioController } from './usuario.controller';
|
import { UsuarioController } from './usuario.controller';
|
||||||
|
import { Usuario } from './entities/usuario.entity';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { CarreraModule } from 'src/carrera/carrera.module';
|
||||||
|
import { ServicioModule } from 'src/servicio/servicio.module';
|
||||||
|
import { gmail } from 'src/helpers.services/gmail.service';
|
||||||
|
import { Auth } from 'googleapis';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
import { TipoUsuario } from 'src/tipo-usuario/entities/tipo-usuario.entity';
|
||||||
|
import { Carrera } from 'src/carrera/entities/carrera.entity';
|
||||||
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [
|
||||||
|
TypeOrmModule.forFeature([Usuario, TipoUsuario, Carrera, Servicio]),
|
||||||
|
CarreraModule,
|
||||||
|
ServicioModule,
|
||||||
|
AuthModule,
|
||||||
|
],
|
||||||
controllers: [UsuarioController],
|
controllers: [UsuarioController],
|
||||||
providers: [UsuarioService],
|
providers: [UsuarioService, gmail],
|
||||||
|
exports: [TypeOrmModule],
|
||||||
})
|
})
|
||||||
export class UsuarioModule {}
|
export class UsuarioModule {}
|
||||||
|
|||||||
+114
-18
@@ -1,5 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
Injectable,
|
Injectable,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
@@ -14,6 +16,8 @@ import { Carrera } from 'src/carrera/entities/carrera.entity';
|
|||||||
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||||
import { gmail } from 'src/helpers.services/gmail.service';
|
import { gmail } from 'src/helpers.services/gmail.service';
|
||||||
import { AuthService } from 'src/auth/auth.service';
|
import { AuthService } from 'src/auth/auth.service';
|
||||||
|
import { TipoUsuario } from 'src/tipo-usuario/entities/tipo-usuario.entity';
|
||||||
|
import * as bcrypt from 'bcrypt';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsuarioService {
|
export class UsuarioService {
|
||||||
@@ -52,24 +56,48 @@ export class UsuarioService {
|
|||||||
private readonly carreraRepo: Repository<Carrera>,
|
private readonly carreraRepo: Repository<Carrera>,
|
||||||
@InjectRepository(Servicio)
|
@InjectRepository(Servicio)
|
||||||
private readonly servicioRepo: Repository<Servicio>,
|
private readonly servicioRepo: Repository<Servicio>,
|
||||||
|
@InjectRepository(TipoUsuario)
|
||||||
|
private readonly tipoUsurioRepo: Repository<TipoUsuario>,
|
||||||
private readonly gmail: gmail,
|
private readonly gmail: gmail,
|
||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async escolares(numeroDeCuenta: string) {
|
async escolares(numeroDeCuenta: string) {
|
||||||
let response;
|
let response;
|
||||||
try {
|
try {
|
||||||
response = await axios.post(
|
if (process.env.MODE == 'pruebas') {
|
||||||
`${process.env.ESCOLARES}${numeroDeCuenta}`,
|
/*
|
||||||
{ password: process.env.ESCOLARES_PASS },
|
Quitamos la promesa ya que muestra un error
|
||||||
|
response = new Promise((res) => {
|
||||||
|
res({
|
||||||
|
data: {
|
||||||
|
nombre: 'nombre',
|
||||||
|
carrconst: 'Carrera',
|
||||||
|
avance: '80',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
{
|
return response = {
|
||||||
headers: {
|
data: {
|
||||||
'Content-Type': 'application/json', // Tipo de contenido
|
nombre: 'nombre',
|
||||||
Authorization: `Bearer ${process.env.API_TOKEN}`, // Header de auth
|
carrconst: 'Carrera',
|
||||||
|
avance: '80',
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
);
|
} else {
|
||||||
|
response = await axios.post(
|
||||||
|
`${process.env.ESCOLARES}${numeroDeCuenta}`,
|
||||||
|
process.env.ESCOLARES_PASS,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new UnauthorizedException(
|
throw new UnauthorizedException(
|
||||||
'No se pudo conectar con el servicio de escolares',
|
'No se pudo conectar con el servicio de escolares',
|
||||||
@@ -81,7 +109,7 @@ export class UsuarioService {
|
|||||||
!response.data.carrconst ||
|
!response.data.carrconst ||
|
||||||
!response.data.avance
|
!response.data.avance
|
||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new BadRequestException(
|
||||||
'El alumno no cumple con los requisitos para realizar el Servicio Social. Si cree que esto es erróneo comunícate al Departamento de Servicio Social y Bolsa de Trabajo.',
|
'El alumno no cumple con los requisitos para realizar el Servicio Social. Si cree que esto es erróneo comunícate al Departamento de Servicio Social y Bolsa de Trabajo.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -99,7 +127,7 @@ export class UsuarioService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (alumno.creditos < this.carreras[alumno.carrera]) {
|
if (alumno.creditos < this.carreras[alumno.carrera]) {
|
||||||
throw new Error('Este alumno no cuenta con los créditos necesarios.');
|
throw new BadRequestException('Este alumno no cuenta con los créditos necesarios.');
|
||||||
}
|
}
|
||||||
while (alumno.nombre.search('') != -1 && alumno.nombre.search('Ã') != -1) {
|
while (alumno.nombre.search('') != -1 && alumno.nombre.search('Ã') != -1) {
|
||||||
alumno.nombre = alumno.nombre.replace('Ã', 'Ñ');
|
alumno.nombre = alumno.nombre.replace('Ã', 'Ñ');
|
||||||
@@ -129,17 +157,17 @@ export class UsuarioService {
|
|||||||
});
|
});
|
||||||
alum = await this.userRepo.save(nuevoUsuario);
|
alum = await this.userRepo.save(nuevoUsuario);
|
||||||
}
|
}
|
||||||
|
console.log("el alumno es:", alumno);
|
||||||
return { ...alumno, idUsuario: alum.idUsuario };
|
return { ...alumno, idUsuario: alum.idUsuario };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newPasswordAlumno(idServicio: number) {
|
async newPasswordAlumno(idServicio: number) {
|
||||||
const password = this.authService.generarPassword();
|
const password = await this.authService.generarPassword();
|
||||||
|
|
||||||
// Buscar el servicio junto con el usuario
|
// Buscar el servicio junto con el usuario
|
||||||
const servicio = await this.servicioRepo.findOne({
|
const servicio = await this.servicioRepo.findOne({
|
||||||
where: { idServicio },
|
where: { idServicio },
|
||||||
relations: ['usuario'], // asegura que traiga la relación
|
relations: ['usuario', 'usuario.tipoUsuario'], // asegura que traiga la relación Le agregue la relacion para traer tipoUsuario
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!servicio) {
|
if (!servicio) {
|
||||||
@@ -153,6 +181,7 @@ export class UsuarioService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Preparar correo
|
// Preparar correo
|
||||||
|
const { preRegistro } = require('../helpers.services/msjCorreos');
|
||||||
let correo = preRegistro(password, usuario.nombre);
|
let correo = preRegistro(password, usuario.nombre);
|
||||||
|
|
||||||
// Enviar correo
|
// Enviar correo
|
||||||
@@ -173,10 +202,10 @@ export class UsuarioService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async newPasswordResponsable(idUsuario: number) {
|
async newPasswordResponsable(idUsuario: number) {
|
||||||
const password = this.authService.generarPassword();
|
const password = await this.authService.generarPassword();
|
||||||
|
|
||||||
// Buscar usuario
|
// Buscar usuario
|
||||||
const usuario = await this.userRepo.findOne({ where: { idUsuario } });
|
const usuario = await this.userRepo.findOne({ where: { idUsuario }, relations: ['tipoUsuario'] });
|
||||||
|
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new NotFoundException('No existe este Usuario.');
|
throw new NotFoundException('No existe este Usuario.');
|
||||||
@@ -186,7 +215,10 @@ export class UsuarioService {
|
|||||||
throw new BadRequestException('Este usuario no es de tipo responsable.');
|
throw new BadRequestException('Este usuario no es de tipo responsable.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Preparar correo
|
// Preparar correo
|
||||||
|
const { enviarSec } = require('../helpers.services/msjCorreos');
|
||||||
|
|
||||||
const correo = enviarSec(password, usuario.usuario, usuario.nombre);
|
const correo = enviarSec(password, usuario.usuario, usuario.nombre);
|
||||||
|
|
||||||
// Enviar correo
|
// Enviar correo
|
||||||
@@ -233,7 +265,10 @@ export class UsuarioService {
|
|||||||
const dataUpdate: Partial<Usuario> = {};
|
const dataUpdate: Partial<Usuario> = {};
|
||||||
|
|
||||||
// Buscar responsable
|
// Buscar responsable
|
||||||
const responsable = await this.userRepo.findOne({ where: { idUsuario } });
|
const responsable = await this.userRepo.findOne({
|
||||||
|
where: { idUsuario },
|
||||||
|
relations: ['tipoUsuario'],
|
||||||
|
});
|
||||||
if (!responsable) {
|
if (!responsable) {
|
||||||
throw new NotFoundException(
|
throw new NotFoundException(
|
||||||
'No existe este responsable en la base de datos.',
|
'No existe este responsable en la base de datos.',
|
||||||
@@ -249,6 +284,7 @@ export class UsuarioService {
|
|||||||
if (correo) {
|
if (correo) {
|
||||||
const yaUsado = await this.userRepo.findOne({
|
const yaUsado = await this.userRepo.findOne({
|
||||||
where: { usuario: correo, idUsuario: Not(idUsuario) },
|
where: { usuario: correo, idUsuario: Not(idUsuario) },
|
||||||
|
relations: ['tipoUsuario'],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (yaUsado) {
|
if (yaUsado) {
|
||||||
@@ -278,4 +314,64 @@ export class UsuarioService {
|
|||||||
'Se actualizó la información de este responsable de programas correctamente.',
|
'Se actualizó la información de este responsable de programas correctamente.',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async create(createUsuarioDto: CreateUsuarioDto) {
|
||||||
|
// Verificar si el usuario ya existe
|
||||||
|
const usuarioExistente = await this.userRepo.findOne({
|
||||||
|
where: { usuario: createUsuarioDto.usuario },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (usuarioExistente) {
|
||||||
|
throw new HttpException('El usuario ya existe', HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar tipo de usuario
|
||||||
|
const tipoUsuario = await this.tipoUsurioRepo.findOne({
|
||||||
|
where: { idTipoUsuario: createUsuarioDto.tipoUsuario },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!tipoUsuario) {
|
||||||
|
throw new HttpException(
|
||||||
|
'Tipo de usuario no válido',
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash password
|
||||||
|
let passwordHash = null;
|
||||||
|
if (createUsuarioDto.password) {
|
||||||
|
const saltRounds = 10;
|
||||||
|
passwordHash = await bcrypt.hash(createUsuarioDto.password, saltRounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crear usuario
|
||||||
|
const usuario = this.userRepo.create({
|
||||||
|
...createUsuarioDto,
|
||||||
|
password: passwordHash,
|
||||||
|
tipoUsuario: tipoUsuario,
|
||||||
|
});
|
||||||
|
|
||||||
|
const usuarioGuardado = await this.userRepo.save(usuario);
|
||||||
|
|
||||||
|
// Eliminar password del response
|
||||||
|
const { password, ...result } = usuarioGuardado;
|
||||||
|
return {
|
||||||
|
message: 'Usuario creado exitosamente',
|
||||||
|
usuario: result,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll() {
|
||||||
|
return await this.tipoUsurioRepo.find()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*c obtenerTodosLosUsuarios() {
|
||||||
|
return await this.userRepo.find({
|
||||||
|
relations: ['tipoUsuario'],
|
||||||
|
take: 10,
|
||||||
|
order: {
|
||||||
|
idUsuario: 'DESC', // Ordenar por el más reciente primero
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}*/ // no subir a produccion
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user