From 3e4b3b1b18d2f189b6268cfd2a59bc55d21d288f Mon Sep 17 00:00:00 2001 From: IO420 Date: Tue, 16 Sep 2025 22:37:25 -0600 Subject: [PATCH] add folder operation and use createQueryRunner --- src/Operations/dto/operations.dto.ts | 18 +++++++ src/Operations/operations.controller.ts | 9 ++++ src/Operations/operations.module.ts | 15 ++++++ src/Operations/operations.services.ts | 54 +++++++++++++++++++ src/alumno/dto/create-student.dto.ts | 5 +- src/alumno/entities/student.entity.ts | 2 +- src/alumno/student.controller.ts | 12 +---- src/alumno/student.service.ts | 21 ++++++-- .../detalle_servicio.service.ts | 25 +++------ .../dto/create-detalle_servicio.dto.ts | 14 ++--- .../dto/detalle_servicio.dto.ts | 9 ---- .../entities/detalle_servicio.entity.ts | 13 +---- src/user/entities/user.entity.ts | 1 - src/user/user.controller.ts | 26 +++++---- src/user/user.service.ts | 2 +- 15 files changed, 150 insertions(+), 76 deletions(-) create mode 100644 src/Operations/dto/operations.dto.ts create mode 100644 src/Operations/operations.controller.ts create mode 100644 src/Operations/operations.module.ts create mode 100644 src/Operations/operations.services.ts delete mode 100644 src/detalle_servicio/dto/detalle_servicio.dto.ts diff --git a/src/Operations/dto/operations.dto.ts b/src/Operations/dto/operations.dto.ts new file mode 100644 index 0000000..2703fa4 --- /dev/null +++ b/src/Operations/dto/operations.dto.ts @@ -0,0 +1,18 @@ +import { IsInt, IsNotEmpty, Min } from "class-validator"; + +export class chargePrintDto { + + @IsInt() + @IsNotEmpty() + @Min(1) + monto:number + + @IsInt() + @Min(1) + @IsNotEmpty() + numero_hojas: number; + + @IsInt() + @IsNotEmpty() + id_cuenta: number; +} diff --git a/src/Operations/operations.controller.ts b/src/Operations/operations.controller.ts new file mode 100644 index 0000000..734f5d8 --- /dev/null +++ b/src/Operations/operations.controller.ts @@ -0,0 +1,9 @@ +import { Controller } from "@nestjs/common"; +import { OperationsService } from "./operations.services"; + +@Controller('operations') +export class OperationsController{ + constructor(private readonly operationsService:OperationsService){} + + +} \ No newline at end of file diff --git a/src/Operations/operations.module.ts b/src/Operations/operations.module.ts new file mode 100644 index 0000000..84e1ba9 --- /dev/null +++ b/src/Operations/operations.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Student } from 'src/alumno/entities/student.entity'; +import { DetalleServicio } from 'src/detalle_servicio/entities/detalle_servicio.entity'; +import { OperationsController } from './operations.controller'; +import { OperationsService } from './operations.services'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Student, DetalleServicio]), // entidades que usarán las transacciones + ], + controllers: [OperationsController], + providers: [OperationsService], +}) +export class OperationsModule {} diff --git a/src/Operations/operations.services.ts b/src/Operations/operations.services.ts new file mode 100644 index 0000000..e609e3d --- /dev/null +++ b/src/Operations/operations.services.ts @@ -0,0 +1,54 @@ +import { BadRequestException, Injectable } from '@nestjs/common'; +import { StudentService } from 'src/alumno/student.service'; +import { DetalleServicioService } from 'src/detalle_servicio/detalle_servicio.service'; +import { DataSource } from 'typeorm'; +import { chargePrintDto } from './dto/operations.dto'; +import { CreateDetalleServicioDto } from 'src/detalle_servicio/dto/create-detalle_servicio.dto'; + +@Injectable() +export class OperationsService { + constructor( + private readonly dataSource: DataSource, + private readonly studentService: StudentService, + private readonly detalleServicioService: DetalleServicioService, + ) {} + + async chargePrint(data: chargePrintDto, userId: number) { + const { monto, id_cuenta } = data; + + const queryRunner = this.dataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + + try { + const credit = await this.studentService.GetCredit(id_cuenta); + + if (credit < monto) { + throw new BadRequestException('Crédito insuficiente'); + } + + const detalleData: CreateDetalleServicioDto = { + ...data, + id_servicio: 1, + id_usuario: userId, + fecha_operacion: new Date(), + }; + + await this.detalleServicioService.Create(detalleData, queryRunner.manager); + + await this.studentService.UpdateCredit( + id_cuenta, + monto, + queryRunner.manager, + ); + + await queryRunner.commitTransaction(); + return { message: 'correct' }; + } catch (error) { + await queryRunner.rollbackTransaction(); + return { message: 'error', error: error.message }; + } finally { + await queryRunner.release(); + } + } +} diff --git a/src/alumno/dto/create-student.dto.ts b/src/alumno/dto/create-student.dto.ts index 130445e..c26edfd 100644 --- a/src/alumno/dto/create-student.dto.ts +++ b/src/alumno/dto/create-student.dto.ts @@ -1,5 +1,5 @@ -import { Type } from 'class-transformer'; -import { IsDate, IsNotEmpty, IsNumber, IsString } from 'class-validator'; + +import { IsEmail, IsNotEmpty, IsNumber, IsString } from 'class-validator'; export class CreateStudentDto { @IsNotEmpty() @@ -17,6 +17,7 @@ export class CreateStudentDto { @IsNumber() id_carrera: number; + @IsEmail() @IsString() correo: string; } diff --git a/src/alumno/entities/student.entity.ts b/src/alumno/entities/student.entity.ts index e50f2d4..1380f9a 100644 --- a/src/alumno/entities/student.entity.ts +++ b/src/alumno/entities/student.entity.ts @@ -26,7 +26,7 @@ export class Student { scale: 2, default: 0.0, }) - credito: string; + credito: number; @Column({ name: 'fecha_actualizacion_credito', diff --git a/src/alumno/student.controller.ts b/src/alumno/student.controller.ts index c93bc87..6b063f2 100644 --- a/src/alumno/student.controller.ts +++ b/src/alumno/student.controller.ts @@ -27,17 +27,7 @@ export class StudentController { } @Get(':id') - findOne(@Param('id') id: string) { + findOne(@Param('id') id: number) { return this.studentService.findOne(+id); } - - @Patch(':id') - update(@Param('id') id: string, @Body() updateStudentDto: UpdateStudentDto) { - return this.studentService.update(+id, updateStudentDto); - } - - @Delete(':id') - remove(@Param('id') id: string) { - return this.studentService.remove(+id); - } } diff --git a/src/alumno/student.service.ts b/src/alumno/student.service.ts index d14dc03..236d15d 100644 --- a/src/alumno/student.service.ts +++ b/src/alumno/student.service.ts @@ -2,7 +2,7 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { CreateStudentDto } from './dto/create-student.dto'; import { UpdateStudentDto } from './dto/update-student.dto'; import { Student } from './entities/student.entity'; -import { Repository } from 'typeorm'; +import { EntityManager, Repository } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; @Injectable() @@ -31,11 +31,22 @@ export class StudentService { return student; } - update(id: number, updateStudentDto: UpdateStudentDto) { - return `This action updates a #${id} student`; + async GetCredit(id_cuenta: number): Promise { + const student = await this.findOne(id_cuenta); + return student.credito; } - remove(id: number) { - return `This action removes a #${id} student`; + async UpdateCredit( + id_cuenta: number, + credit: number, + manager: EntityManager, + ) { + const repo = manager.getRepository(Student); + return await repo + .createQueryBuilder() + .update() + .set({ credito: () => `credito - ${credit}` }) + .where({ id_cuenta }) + .execute(); } } diff --git a/src/detalle_servicio/detalle_servicio.service.ts b/src/detalle_servicio/detalle_servicio.service.ts index 076b150..ea6b477 100644 --- a/src/detalle_servicio/detalle_servicio.service.ts +++ b/src/detalle_servicio/detalle_servicio.service.ts @@ -1,26 +1,13 @@ import { Injectable } from '@nestjs/common'; +import { DetalleServicio } from './entities/detalle_servicio.entity'; +import { EntityManager } from 'typeorm'; import { CreateDetalleServicioDto } from './dto/create-detalle_servicio.dto'; -import { UpdateDetalleServicioDto } from './dto/update-detalle_servicio.dto'; @Injectable() export class DetalleServicioService { - create(createDetalleServicioDto: CreateDetalleServicioDto) { - return 'This action adds a new detalleServicio'; - } - - findAll() { - return `This action returns all detalleServicio`; - } - - findOne(id: number) { - return `This action returns a #${id} detalleServicio`; - } - - update(id: number, updateDetalleServicioDto: UpdateDetalleServicioDto) { - return `This action updates a #${id} detalleServicio`; - } - - remove(id: number) { - return `This action removes a #${id} detalleServicio`; + async Create(data: CreateDetalleServicioDto, manager: EntityManager) { + const repo = manager.getRepository(DetalleServicio); + const details = repo.create(data); + return await repo.save(details); } } diff --git a/src/detalle_servicio/dto/create-detalle_servicio.dto.ts b/src/detalle_servicio/dto/create-detalle_servicio.dto.ts index 7d0c28b..9dc2a64 100644 --- a/src/detalle_servicio/dto/create-detalle_servicio.dto.ts +++ b/src/detalle_servicio/dto/create-detalle_servicio.dto.ts @@ -1,9 +1,15 @@ import { Type } from 'class-transformer'; -import { IsDate, IsInt, IsNotEmpty, IsOptional, Min } from 'class-validator'; +import { IsDate, IsIn, IsInt, IsNotEmpty, IsOptional, Min } from 'class-validator'; export class CreateDetalleServicioDto { + @IsInt() - @Min(0) + @IsNotEmpty() + @Min(1) + monto:number + + @IsInt() + @Min(1) @IsNotEmpty() numero_hojas: number; @@ -23,8 +29,4 @@ export class CreateDetalleServicioDto { @IsInt() @IsNotEmpty() id_usuario: number; - - @IsOptional() - @IsInt() - id_periodo?: number; } diff --git a/src/detalle_servicio/dto/detalle_servicio.dto.ts b/src/detalle_servicio/dto/detalle_servicio.dto.ts deleted file mode 100644 index 5efa1fe..0000000 --- a/src/detalle_servicio/dto/detalle_servicio.dto.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class DetalleServicioDto { - id_detalle_servicio: number; - numero_hojas: number; - fecha_operacion: Date; - id_cuenta: number; - id_servicio: number; - id_usuario: number; - id_periodo: number | null; -} diff --git a/src/detalle_servicio/entities/detalle_servicio.entity.ts b/src/detalle_servicio/entities/detalle_servicio.entity.ts index a9b2b5f..e6691f3 100644 --- a/src/detalle_servicio/entities/detalle_servicio.entity.ts +++ b/src/detalle_servicio/entities/detalle_servicio.entity.ts @@ -15,7 +15,7 @@ export class DetalleServicio { scale: 2, nullable: false, }) - monto: string; + monto: number; @Column({ name: 'numero_hojas', type: 'int', nullable: false, default: 0 }) numero_hojas: number; @@ -39,13 +39,4 @@ export class DetalleServicio { @Column({ name: 'id_perido', type: 'int', default: null }) id_periodo: number; -} - -/* `id_detalle_servicio` int(11) NOT NULL AUTO_INCREMENT, - `monto` decimal(10,2) NOT NULL, - `numero_hojas` int(11) NOT NULL DEFAULT 0, - `fecha_operacion` timestamp NOT NULL DEFAULT current_timestamp(), - `id_cuenta` int(9) unsigned zerofill NOT NULL, - `id_servicio` int(11) NOT NULL, - `id_usuario` int(11) NOT NULL, - `id_periodo` int(11) DEFAULT NULL,*/ +} \ No newline at end of file diff --git a/src/user/entities/user.entity.ts b/src/user/entities/user.entity.ts index bcc0c92..1131977 100644 --- a/src/user/entities/user.entity.ts +++ b/src/user/entities/user.entity.ts @@ -49,7 +49,6 @@ export class Perfil { @Column({ name: 'perfil', type: 'varchar', length: 45, nullable: false }) perfil: string; - // Relación uno a muchos con usuario @OneToMany(() => User, (user) => user.perfil) usuarios: User[]; } \ No newline at end of file diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index 8ea80b9..37bab3d 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -1,4 +1,12 @@ -import { Controller, Get, Post, Body, UseGuards, Request, Res } from '@nestjs/common'; +import { + Controller, + Get, + Post, + Body, + UseGuards, + Request, + Res, +} from '@nestjs/common'; import type { Response } from 'express'; import { UserService } from './user.service'; import { CreateUserDto } from './dto/create-user.dto'; @@ -6,19 +14,17 @@ import { AuthGuard } from '@nestjs/passport'; @Controller('user') export class UserController { - constructor(private readonly userService: UserService) { } - -@Post() -async Login(@Body() data: CreateUserDto, @Res() res: Response) { - return this.userService.Login(data, res); -} + constructor(private readonly userService: UserService) {} + @Post() + async Login(@Body() data: CreateUserDto, @Res() res: Response) { + return this.userService.Login(data, res); + } @UseGuards(AuthGuard('jwt')) @Get('/validate-token') getProfile(@Request() req) { - return req.user; + return req.user; } - } -//IO \ No newline at end of file +//IO diff --git a/src/user/user.service.ts b/src/user/user.service.ts index 8bd2a63..55883b0 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -10,7 +10,7 @@ import { JwtService } from '@nestjs/jwt'; export class UserService { constructor( @InjectRepository(User) - private userRepository: Repository, + private readonly userRepository: Repository, private jwtService: JwtService ) { }