Se agregaron funciones y cambios en los dto
This commit is contained in:
Generated
+66
-10
@@ -18,6 +18,7 @@
|
||||
"@nestjs/passport": "^11.0.5",
|
||||
"@nestjs/platform-express": "^11.1.6",
|
||||
"@nestjs/typeorm": "^11.0.0",
|
||||
"argon2": "^0.44.0",
|
||||
"axios": "^1.12.2",
|
||||
"bcrypt": "^6.0.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
@@ -794,6 +795,12 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@epic-web/invariant": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
|
||||
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
|
||||
@@ -2576,12 +2583,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/jwt": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.0.tgz",
|
||||
"integrity": "sha512-v7YRsW3Xi8HNTsO+jeHSEEqelX37TVWgwt+BcxtkG/OfXJEOs6GZdbdza200d6KqId1pJQZ6UPj1F0M6E+mxaA==",
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.1.tgz",
|
||||
"integrity": "sha512-HXSsc7SAnCnjA98TsZqrE7trGtHDnYXWp4Ffy6LwSmck1QvbGYdMzBquXofX5l6tIRpeY4Qidl2Ti2CVG77Pdw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/jsonwebtoken": "9.0.7",
|
||||
"@types/jsonwebtoken": "9.0.10",
|
||||
"jsonwebtoken": "9.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -2774,6 +2781,15 @@
|
||||
"@noble/hashes": "^1.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@phc/format": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz",
|
||||
"integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@@ -3410,11 +3426,12 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/jsonwebtoken": {
|
||||
"version": "9.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz",
|
||||
"integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==",
|
||||
"version": "9.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz",
|
||||
"integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/ms": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
@@ -3432,6 +3449,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
|
||||
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/multer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.0.0.tgz",
|
||||
@@ -5167,6 +5190,22 @@
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argon2": {
|
||||
"version": "0.44.0",
|
||||
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.44.0.tgz",
|
||||
"integrity": "sha512-zHPGN3S55sihSQo0dBbK0A5qpi2R31z7HZDZnry3ifOyj8bZZnpZND2gpmhnRGO1V/d555RwBqIK5W4Mrmv3ig==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@phc/format": "^1.0.0",
|
||||
"cross-env": "^10.0.0",
|
||||
"node-addon-api": "^8.5.0",
|
||||
"node-gyp-build": "^4.8.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@@ -6165,6 +6204,23 @@
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@epic-web/invariant": "^1.0.0",
|
||||
"cross-spawn": "^7.0.6"
|
||||
},
|
||||
"bin": {
|
||||
"cross-env": "dist/bin/cross-env.js",
|
||||
"cross-env-shell": "dist/bin/cross-env-shell.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
@@ -9928,9 +9984,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "8.3.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz",
|
||||
"integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==",
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz",
|
||||
"integrity": "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18 || ^20 || >= 21"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"@nestjs/passport": "^11.0.5",
|
||||
"@nestjs/platform-express": "^11.1.6",
|
||||
"@nestjs/typeorm": "^11.0.0",
|
||||
"argon2": "^0.44.0",
|
||||
"axios": "^1.12.2",
|
||||
"bcrypt": "^6.0.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
|
||||
@@ -14,6 +14,7 @@ import { gmail } from 'src/helpers.services/gmail.service';
|
||||
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||
import { Like, Not, Repository } from 'typeorm';
|
||||
import * as argon2 from 'argon2';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
@@ -80,15 +81,15 @@ export class AuthService {
|
||||
}
|
||||
|
||||
async comparar(password, dbPassword) {
|
||||
if (!bcrypt.compareSync(password, dbPassword)) {
|
||||
return false;
|
||||
} else {
|
||||
if (await argon2.verify(password, dbPassword)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async encriptar(password) {
|
||||
return bcrypt.hashSync(password, Number(process.env.SALT_ROUNDS));
|
||||
return await argon2.hash(password);
|
||||
}
|
||||
|
||||
async generarPassword() {
|
||||
@@ -107,7 +108,7 @@ export class AuthService {
|
||||
async login(usuario: string, password: string) {
|
||||
const user = await this.userRepo.findOne({ where: { usuario } });
|
||||
if (!user) throw new UnauthorizedException('No existe este usuario.');
|
||||
const match = await bcrypt.compare(password, user.password);
|
||||
const match = await this.comparar(password, user.password);
|
||||
if (!match) throw new UnauthorizedException('Credenciales inválidas');
|
||||
if (!user.activo) throw new Error('Este usuario no esta activo.');
|
||||
const token = this.jwtCreate(
|
||||
|
||||
@@ -1,73 +1,72 @@
|
||||
import {
|
||||
IsEmail,
|
||||
IsNotEmpty,
|
||||
IsNumberString,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Length,
|
||||
IsDateString,
|
||||
IsNumber,
|
||||
IsIn,
|
||||
IsInt,
|
||||
Matches,
|
||||
} from 'class-validator';
|
||||
|
||||
export class CreateCasoEspecialDto {
|
||||
@IsNumber()
|
||||
|
||||
idUsuario: number;
|
||||
|
||||
@IsNumber()
|
||||
@IsInt()
|
||||
idCarrera: number;
|
||||
|
||||
@IsNumber()
|
||||
@Length(1, 11)
|
||||
idStatus: number;
|
||||
|
||||
@IsString()
|
||||
@Length(9, 9)
|
||||
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
||||
numeroCuenta: string;
|
||||
|
||||
@IsEmail()
|
||||
correo: string;
|
||||
|
||||
@IsString()
|
||||
@Length(1, 3)
|
||||
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
||||
creditos : string;
|
||||
|
||||
@IsString()
|
||||
@Length(1, 15)
|
||||
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
||||
telefono: string;
|
||||
|
||||
@IsDateString()
|
||||
fechaInicio: Date;
|
||||
|
||||
@IsDateString()
|
||||
fechaFin: Date;
|
||||
|
||||
@IsDateString()
|
||||
fechaNacimiento: Date;
|
||||
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
direccion: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
institucion?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
dependencia?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Length(1, 1)
|
||||
motivo?: string;
|
||||
}
|
||||
IsEmail,
|
||||
IsNotEmpty,
|
||||
IsNumberString,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Length,
|
||||
IsDateString,
|
||||
IsNumber,
|
||||
IsIn,
|
||||
IsInt,
|
||||
Matches,
|
||||
} from 'class-validator';
|
||||
|
||||
export class CreateCasoEspecialDto {
|
||||
@IsNumber()
|
||||
idUsuario: number;
|
||||
|
||||
@IsNumber()
|
||||
@IsInt()
|
||||
idCarrera: number;
|
||||
|
||||
@IsNumber()
|
||||
@Length(1, 11)
|
||||
idStatus: number;
|
||||
|
||||
@IsString()
|
||||
@Length(9, 9)
|
||||
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
||||
numeroCuenta: string;
|
||||
|
||||
@IsEmail()
|
||||
correo: string;
|
||||
|
||||
@IsString()
|
||||
@Length(1, 3)
|
||||
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
||||
creditos: string;
|
||||
|
||||
@IsString()
|
||||
@Length(1, 15)
|
||||
@Matches(/^\d+$/, { message: 'solo puede contener números' })
|
||||
telefono: string;
|
||||
|
||||
@IsDateString()
|
||||
fechaInicio: Date;
|
||||
|
||||
@IsDateString()
|
||||
fechaFin: Date;
|
||||
|
||||
@IsDateString()
|
||||
fechaNacimiento: Date;
|
||||
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
direccion: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
institucion?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
dependencia?: string;
|
||||
|
||||
@IsOptional() // Permite que no se envíe
|
||||
@IsString() // Debe ser string si se envía
|
||||
@Length(1, 1)
|
||||
motivo?: string;
|
||||
}
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
import {
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsEmail,
|
||||
Length,
|
||||
IsDateString,
|
||||
IsNumber,
|
||||
} from 'class-validator';
|
||||
|
||||
export class UpdateCasoEspecialDto {
|
||||
@IsOptional()
|
||||
@IsEmail()
|
||||
correo?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
fechaInicio?: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
fechaFin?: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
fechaNacimiento?: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
direccion?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 15)
|
||||
telefono?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
institucion?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
dependencia?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
motivo?: number;
|
||||
}
|
||||
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsEmail,
|
||||
Length,
|
||||
IsDateString,
|
||||
IsNumber,
|
||||
} from 'class-validator';
|
||||
|
||||
export class UpdateCasoEspecialDto {
|
||||
@IsOptional()
|
||||
@IsEmail()
|
||||
correo?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
fechaInicio?: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
fechaFin?: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
fechaNacimiento?: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
direccion?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 15)
|
||||
telefono?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
institucion?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Length(1, 200)
|
||||
dependencia?: string;
|
||||
|
||||
@IsOptional() // Permite que no se envíe
|
||||
@IsString() // Debe ser string si se envía
|
||||
@Length(1, 1)
|
||||
motivo?: string;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { CuestionarioAlumno2 } from './entities/cuestionario-alumno2.entity';
|
||||
import { messageByStatus } from 'src/messageByStatus';
|
||||
import { ArchivoService } from 'src/helpers.services/archivo.service';
|
||||
import { ValidacionService } from 'src/helpers.services/validacion.service';
|
||||
const { convertArrayToCSV } = require('convert-array-to-csv');
|
||||
import { convertArrayToCSV } from 'convert-array-to-csv';
|
||||
|
||||
@Injectable()
|
||||
export class CuestionarioAlumno2Service {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ArchivoService } from 'src/helpers.services/archivo.service';
|
||||
import { ValidacionService } from 'src/helpers.services/validacion.service';
|
||||
import { Servicio } from 'src/servicio/entities/servicio.entity';
|
||||
import { messageByStatus } from 'src/messageByStatus';
|
||||
const { convertArrayToCSV } = require('convert-array-to-csv');
|
||||
import { convertArrayToCSV } from 'convert-array-to-csv';
|
||||
|
||||
@Injectable()
|
||||
export class CuestionarioPrograma2Service {
|
||||
|
||||
@@ -1,27 +1,46 @@
|
||||
import { IsString, IsEmail, IsDate, IsOptional } from 'class-validator';
|
||||
import {
|
||||
IsString,
|
||||
IsArray,
|
||||
IsOptional,
|
||||
IsISO8601,
|
||||
ValidateNested,
|
||||
} from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
|
||||
export class SendCorreoDto {
|
||||
@IsEmail()
|
||||
class AdjuntoDto {
|
||||
@IsString()
|
||||
filename: string;
|
||||
|
||||
@IsString()
|
||||
content: string;
|
||||
|
||||
@IsString()
|
||||
encoding: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
cid?: string;
|
||||
}
|
||||
|
||||
export class SendMailDto {
|
||||
@IsString()
|
||||
to: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
subject?: string;
|
||||
subject: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
text?: string;
|
||||
text: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
html?: string;
|
||||
html: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
fileName?: string;
|
||||
@IsISO8601()
|
||||
fecha_recibido: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
filePath?: string;
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => AdjuntoDto)
|
||||
adjuntos?: AdjuntoDto[];
|
||||
}
|
||||
|
||||
@@ -1,93 +1,34 @@
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import * as nodemailer from 'nodemailer';
|
||||
import { SendCorreoDto } from './dto/send-email.dto';
|
||||
|
||||
|
||||
|
||||
|
||||
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
|
||||
import axios from 'axios';
|
||||
import { SendMailDto } from './dto/send-email.dto';
|
||||
|
||||
@Injectable()
|
||||
export class gmail {
|
||||
private readonly baseUrl = process.env.MAIL_URL;
|
||||
private readonly token = process.env.MAIL_TOKEN; // idealmente: process.env.MAIL_TOKEN
|
||||
|
||||
async sendMail(sendEmail: SendCorreoDto) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
|
||||
|
||||
service: 'gmail',
|
||||
auth: {
|
||||
type: 'OAuth2',
|
||||
user: process.env.EMAIL_USER, // tu correo de Gmail
|
||||
clientId: process.env.CLIENT_ID, // tu Client ID de OAuth2
|
||||
clientSecret: process.env.CLIENT_SECRET, // tu Client Secret de OAuth2
|
||||
refreshToken: process.env.REFRESH_TOKEN, // tu Refresh Token de OAuth2
|
||||
//accessToken: sistem.accessToken, // opcional
|
||||
},
|
||||
pool: true,
|
||||
maxConnections: 1,
|
||||
maxMessages: 100,
|
||||
rateDelta: 2000,
|
||||
rateLimit: 1
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const mailOptions = {
|
||||
from: process.env.EMAIL_USER, // tu correo de Gmail
|
||||
to: sendEmail.to,
|
||||
subject: sendEmail.subject,
|
||||
text: sendEmail.text,
|
||||
html: sendEmail.html,
|
||||
|
||||
attachments: [
|
||||
{
|
||||
filename: '',
|
||||
path: '', // ruta local
|
||||
async enviarCorreo(data: SendMailDto): Promise<any> {
|
||||
try {
|
||||
if (!this.baseUrl || !this.token) {
|
||||
throw new HttpException(
|
||||
'Configuración de correo no encontrada',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
const response = await axios.post(this.baseUrl, data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
accept: '*/*',
|
||||
token: this.token,
|
||||
},
|
||||
{
|
||||
filename: '',
|
||||
path: '', // adjuntar desde URL
|
||||
},
|
||||
{
|
||||
filename: '',
|
||||
content: '', // adjunto generado en memoria
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
console.log(mailOptions);
|
||||
|
||||
|
||||
|
||||
|
||||
let resMail = await transporter.sendMail(mailOptions);
|
||||
if (!resMail) throw new Error("")
|
||||
|
||||
|
||||
const statusTexto = resMail.accepted.length > 0 ? "Enviado" : "Fallido";
|
||||
|
||||
|
||||
|
||||
if (!resMail) {
|
||||
throw new Error("fallo")
|
||||
}
|
||||
|
||||
|
||||
return (statusTexto);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
throw new HttpException(
|
||||
error.response?.data || 'Error al enviar correo',
|
||||
error.response?.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,119 @@
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
|
||||
import {
|
||||
Controller,
|
||||
Post,
|
||||
Put,
|
||||
Get,
|
||||
Body,
|
||||
Query,
|
||||
UploadedFile,
|
||||
UseGuards,
|
||||
UseInterceptors,
|
||||
BadRequestException,
|
||||
Param,
|
||||
} from '@nestjs/common';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { diskStorage } from 'multer';
|
||||
import { extname } from 'path';
|
||||
import * as fs from 'fs';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
import { ProgramaService } from './programa.service';
|
||||
import { CreateProgramaDto } from './dto/create-programa.dto';
|
||||
import { UpdateProgramaDto } from './dto/update-programa.dto';
|
||||
import { IsEmail, isEmail } from 'class-validator';
|
||||
|
||||
class Email {
|
||||
@IsEmail()
|
||||
correo: string;
|
||||
}
|
||||
|
||||
@Controller('programa')
|
||||
export class ProgramaController {
|
||||
constructor(private readonly programaService: ProgramaService) {}
|
||||
|
||||
@Post()
|
||||
create(@Body() createProgramaDto: CreateProgramaDto) {
|
||||
return this.programaService.create(createProgramaDto);
|
||||
// ==================== POST /carga_masiva ====================
|
||||
@Post('carga_masiva')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
@UseInterceptors(
|
||||
FileInterceptor('csv', {
|
||||
storage: diskStorage({
|
||||
destination: './server/uploads',
|
||||
filename: (req, file, cb) => {
|
||||
const uniqueName = `${Date.now()}${extname(file.originalname)}`;
|
||||
cb(null, uniqueName);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
)
|
||||
async cargaMasiva(@UploadedFile() file: Express.Multer.File) {
|
||||
if (!file) {
|
||||
throw new BadRequestException(
|
||||
'No se envio un archivo csv para la carga masiva.',
|
||||
);
|
||||
}
|
||||
try {
|
||||
const data = await this.programaService.cargaMasiva(file.filename);
|
||||
return {
|
||||
statusCode: 201,
|
||||
message: 'Carga masiva realizada con éxito',
|
||||
data,
|
||||
};
|
||||
} catch (err) {
|
||||
// Eliminar archivo si ocurre error
|
||||
if (file && file.filename) {
|
||||
fs.unlinkSync(`./server/uploads/${file.filename}`);
|
||||
}
|
||||
throw new BadRequestException(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.programaService.findAll();
|
||||
// ==================== PUT /reasignar_programas ====================
|
||||
@Put('reasignar_programas/:idUsuario')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async reasignarProgramas(
|
||||
@Body() email: Email,
|
||||
@Param('idUsuario') idUsuario: number,
|
||||
) {
|
||||
try {
|
||||
const data = await this.programaService.reasignarProgramas(
|
||||
idUsuario,
|
||||
email.correo,
|
||||
);
|
||||
return {
|
||||
statusCode: 200,
|
||||
message: 'Programas reasignados con éxito',
|
||||
data,
|
||||
};
|
||||
} catch (err) {
|
||||
throw new BadRequestException(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.programaService.findOne(+id);
|
||||
// ==================== GET /programas_admin ====================
|
||||
@Get('programas_admin/:idUsuario')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async programasAdmin(@Param('idUsuario') query: number) {
|
||||
try {
|
||||
const data = await this.programaService.programasAdmin(query);
|
||||
return {
|
||||
statusCode: 200,
|
||||
data,
|
||||
};
|
||||
} catch (err) {
|
||||
throw new BadRequestException(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
update(@Param('id') id: string, @Body() updateProgramaDto: UpdateProgramaDto) {
|
||||
return this.programaService.update(+id, updateProgramaDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
remove(@Param('id') id: string) {
|
||||
return this.programaService.remove(+id);
|
||||
// ==================== GET /programas_responsable ====================
|
||||
@Get('programas_responsable/:idUsuario')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async programasResponsable(@Param(`idUsuario`) idUsuario: number) {
|
||||
try {
|
||||
const data = await this.programaService.programasResponsable(idUsuario);
|
||||
return {
|
||||
statusCode: 200,
|
||||
data,
|
||||
};
|
||||
} catch (err) {
|
||||
throw new BadRequestException(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,9 +179,9 @@ export class ProgramaService {
|
||||
};
|
||||
}
|
||||
|
||||
async programasAdmin(body: { idUsuario: number }) {
|
||||
async programasAdmin(idUser: number) {
|
||||
const idUsuario = this.validacionService.validarNumeroEntero(
|
||||
body.idUsuario,
|
||||
idUser,
|
||||
'id usuario',
|
||||
);
|
||||
|
||||
@@ -201,9 +201,9 @@ export class ProgramaService {
|
||||
});
|
||||
}
|
||||
|
||||
async programasResponsable(body: { idUsuario: number }) {
|
||||
async programasResponsable(idUser: number) {
|
||||
const idUsuario = this.validacionService.validarNumeroEntero(
|
||||
body.idUsuario,
|
||||
idUser,
|
||||
'id usuario',
|
||||
);
|
||||
|
||||
|
||||
@@ -1 +1,42 @@
|
||||
export class CreateServicioDto {}
|
||||
import {
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsDateString,
|
||||
IsEmail,
|
||||
IsDate,
|
||||
} from 'class-validator';
|
||||
|
||||
export class CrearServicioDto {
|
||||
@IsNumber()
|
||||
idUsuario: number;
|
||||
|
||||
@IsNumber()
|
||||
idPrograma: number;
|
||||
|
||||
@IsNumber()
|
||||
idCarrera: number;
|
||||
|
||||
@IsString()
|
||||
numeroCuenta: string;
|
||||
|
||||
@IsNumber()
|
||||
creditos: number;
|
||||
|
||||
@IsEmail()
|
||||
correo: string;
|
||||
|
||||
@IsDate()
|
||||
fechaInicio: Date;
|
||||
|
||||
@IsDate()
|
||||
fechaFin: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
programaInterno?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
profesor?: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import {
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
MaxLength,
|
||||
} from 'class-validator';
|
||||
|
||||
export class RegistroValidadoDto {
|
||||
@IsNumber()
|
||||
@IsNotEmpty()
|
||||
idServicio: number;
|
||||
|
||||
@IsOptional()
|
||||
fechaNacimiento?: Date;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(15)
|
||||
telefono?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(200)
|
||||
direccion?: string;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { IsOptional, IsNumber, IsString } from 'class-validator';
|
||||
|
||||
export class ServiciosAdminDto {
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
pagina?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
idStatus?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
nombre?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
numeroCuenta?: string;
|
||||
}
|
||||
@@ -1,9 +1,23 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ServicioService } from './servicio.service';
|
||||
import { ServicioController } from './servicio.controller';
|
||||
import { DriveService } from 'src/drive/drive.service';
|
||||
import { ValidacionService } from 'src/helpers.services/validacion.service';
|
||||
import { gmail } from 'src/helpers.services/gmail.service';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Servicio } from './entities/servicio.entity';
|
||||
import { Usuario } from 'src/usuario/entities/usuario.entity';
|
||||
import { ArchivoService } from 'src/helpers.services/archivo.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Servicio, Usuario])],
|
||||
controllers: [ServicioController],
|
||||
providers: [ServicioService],
|
||||
providers: [
|
||||
ServicioService,
|
||||
DriveService,
|
||||
ValidacionService,
|
||||
gmail,
|
||||
ArchivoService,
|
||||
],
|
||||
})
|
||||
export class ServicioModule {}
|
||||
|
||||
+1003
-31
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user