From 2dc90a4ac890a2ee74815e516e60b2750a078f1c Mon Sep 17 00:00:00 2001 From: IO420 <320154041@pcpuma.acatlan.unam.mx> Date: Mon, 20 Oct 2025 12:14:16 -0600 Subject: [PATCH] added new files abono-ticket, kiosco, pago-kiosco, transaccion, and others EP --- .env.example | 14 ++++ package-lock.json | 35 +++++++++ package.json | 2 + .../abono-ticket.controller.spec.ts | 20 +++++ src/abono-ticket/abono-ticket.controller.ts | 34 +++++++++ src/abono-ticket/abono-ticket.module.ts | 12 +++ src/abono-ticket/abono-ticket.service.spec.ts | 18 +++++ src/abono-ticket/abono-ticket.service.ts | 35 +++++++++ .../dto/create-abono-ticket.dto.ts | 1 + .../dto/update-abono-ticket.dto.ts | 4 + .../entities/abono-ticket.entity.ts | 29 +++++++ src/app.module.ts | 13 +++- src/kiosco/dto/create-kiosco.dto.ts | 1 + src/kiosco/dto/update-kiosco.dto.ts | 4 + src/kiosco/entities/kiosco.entity.ts | 40 ++++++++++ src/kiosco/kiosco.controller.spec.ts | 20 +++++ src/kiosco/kiosco.controller.ts | 34 +++++++++ src/kiosco/kiosco.module.ts | 9 +++ src/kiosco/kiosco.service.spec.ts | 18 +++++ src/kiosco/kiosco.service.ts | 26 +++++++ src/main.ts | 5 ++ src/pago-kiosco/dto/create-pago-kiosco.dto.ts | 1 + src/pago-kiosco/dto/update-pago-kiosco.dto.ts | 4 + .../entities/pago-kiosco.entity.ts | 76 +++++++++++++++++++ .../pago-kiosco.controller.spec.ts | 20 +++++ src/pago-kiosco/pago-kiosco.controller.ts | 22 ++++++ src/pago-kiosco/pago-kiosco.module.ts | 12 +++ src/pago-kiosco/pago-kiosco.service.spec.ts | 18 +++++ src/pago-kiosco/pago-kiosco.service.ts | 20 +++++ src/persona/entities/persona.entity.ts | 6 +- src/persona/jwt.guard.ts | 2 +- src/persona/persona.controller.ts | 12 ++- src/persona/persona.service.ts | 25 ++++-- src/transaccion/dto/create-transaccion.dto.ts | 19 +++++ .../entities/transaccion.entity.ts | 58 ++++++++++++++ .../transaccion.controller.spec.ts | 20 +++++ src/transaccion/transaccion.controller.ts | 26 +++++++ src/transaccion/transaccion.module.ts | 12 +++ src/transaccion/transaccion.service.spec.ts | 18 +++++ src/transaccion/transaccion.service.ts | 24 ++++++ 40 files changed, 757 insertions(+), 12 deletions(-) create mode 100644 .env.example create mode 100644 src/abono-ticket/abono-ticket.controller.spec.ts create mode 100644 src/abono-ticket/abono-ticket.controller.ts create mode 100644 src/abono-ticket/abono-ticket.module.ts create mode 100644 src/abono-ticket/abono-ticket.service.spec.ts create mode 100644 src/abono-ticket/abono-ticket.service.ts create mode 100644 src/abono-ticket/dto/create-abono-ticket.dto.ts create mode 100644 src/abono-ticket/dto/update-abono-ticket.dto.ts create mode 100644 src/abono-ticket/entities/abono-ticket.entity.ts create mode 100644 src/kiosco/dto/create-kiosco.dto.ts create mode 100644 src/kiosco/dto/update-kiosco.dto.ts create mode 100644 src/kiosco/entities/kiosco.entity.ts create mode 100644 src/kiosco/kiosco.controller.spec.ts create mode 100644 src/kiosco/kiosco.controller.ts create mode 100644 src/kiosco/kiosco.module.ts create mode 100644 src/kiosco/kiosco.service.spec.ts create mode 100644 src/kiosco/kiosco.service.ts create mode 100644 src/pago-kiosco/dto/create-pago-kiosco.dto.ts create mode 100644 src/pago-kiosco/dto/update-pago-kiosco.dto.ts create mode 100644 src/pago-kiosco/entities/pago-kiosco.entity.ts create mode 100644 src/pago-kiosco/pago-kiosco.controller.spec.ts create mode 100644 src/pago-kiosco/pago-kiosco.controller.ts create mode 100644 src/pago-kiosco/pago-kiosco.module.ts create mode 100644 src/pago-kiosco/pago-kiosco.service.spec.ts create mode 100644 src/pago-kiosco/pago-kiosco.service.ts create mode 100644 src/transaccion/dto/create-transaccion.dto.ts create mode 100644 src/transaccion/entities/transaccion.entity.ts create mode 100644 src/transaccion/transaccion.controller.spec.ts create mode 100644 src/transaccion/transaccion.controller.ts create mode 100644 src/transaccion/transaccion.module.ts create mode 100644 src/transaccion/transaccion.service.spec.ts create mode 100644 src/transaccion/transaccion.service.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..3f89f60 --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +GOOGLE_CLIENT_ID=164998630411-i53dmn6cjibjv7o2llq32fn2hb1cdcnm.apps.googleusercontent.com +GOOGLE_CLIENT_SECRET=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 +GOOGLE_CALLBACK_URL=http://localhost:3000/persona/google/callback +FRONTEND_URL=http://localhost:3000 +JWT_SECRET=supersecreto +JWT_EXPIRES_IN=3600s + +DB_HOST = '132.248.180.82' +DB_USER = 'usr_kiosco' +DB_PASS = '4o-QEux.GL' +DB_NAME = 'Betelgeuse_kiosco_test' <== Nombre de la base de datos +DB_PORT = '3306' <== Puerto de la base de datos + +PORT = 3001 <== Puerto de despliege de la aplicacion web \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1180aad..43844f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,8 @@ "@nestjs/platform-express": "^11.0.1", "@nestjs/typeorm": "^11.0.0", "bcrypt": "^6.0.0", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.2", "jsonwebtoken": "^9.0.2", "mysql2": "^3.15.2", "passport": "^0.7.0", @@ -2961,6 +2963,11 @@ "@types/superagent": "^8.1.0" } }, + "node_modules/@types/validator": { + "version": "13.15.3", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.3.tgz", + "integrity": "sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==" + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -4377,6 +4384,21 @@ "integrity": "sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==", "dev": true }, + "node_modules/class-transformer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" + }, + "node_modules/class-validator": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.2.tgz", + "integrity": "sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==", + "dependencies": { + "@types/validator": "^13.11.8", + "libphonenumber-js": "^1.11.1", + "validator": "^13.9.0" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -7204,6 +7226,11 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.12.24", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.24.tgz", + "integrity": "sha512-l5IlyL9AONj4voSd7q9xkuQOL4u8Ty44puTic7J88CmdXkxfGsRfoVLXHCxppwehgpb/Chdb80FFehHqjN3ItQ==" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -10073,6 +10100,14 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.15.15", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", + "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index e86e9b8..8cbd479 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,8 @@ "@nestjs/platform-express": "^11.0.1", "@nestjs/typeorm": "^11.0.0", "bcrypt": "^6.0.0", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.2", "jsonwebtoken": "^9.0.2", "mysql2": "^3.15.2", "passport": "^0.7.0", diff --git a/src/abono-ticket/abono-ticket.controller.spec.ts b/src/abono-ticket/abono-ticket.controller.spec.ts new file mode 100644 index 0000000..0bedfe9 --- /dev/null +++ b/src/abono-ticket/abono-ticket.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AbonoTicketController } from './abono-ticket.controller'; +import { AbonoTicketService } from './abono-ticket.service'; + +describe('AbonoTicketController', () => { + let controller: AbonoTicketController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AbonoTicketController], + providers: [AbonoTicketService], + }).compile(); + + controller = module.get(AbonoTicketController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/abono-ticket/abono-ticket.controller.ts b/src/abono-ticket/abono-ticket.controller.ts new file mode 100644 index 0000000..284e561 --- /dev/null +++ b/src/abono-ticket/abono-ticket.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { AbonoTicketService } from './abono-ticket.service'; +import { CreateAbonoTicketDto } from './dto/create-abono-ticket.dto'; +import { UpdateAbonoTicketDto } from './dto/update-abono-ticket.dto'; + +@Controller('abono-ticket') +export class AbonoTicketController { + constructor(private readonly abonoTicketService: AbonoTicketService) {} + + @Post() + create(@Body() createAbonoTicketDto: CreateAbonoTicketDto) { + return this.abonoTicketService.create(createAbonoTicketDto); + } + + @Get() + findAll() { + return this.abonoTicketService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.abonoTicketService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateAbonoTicketDto: UpdateAbonoTicketDto) { + return this.abonoTicketService.update(+id, updateAbonoTicketDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.abonoTicketService.remove(+id); + } +} diff --git a/src/abono-ticket/abono-ticket.module.ts b/src/abono-ticket/abono-ticket.module.ts new file mode 100644 index 0000000..9e79685 --- /dev/null +++ b/src/abono-ticket/abono-ticket.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { AbonoTicketService } from './abono-ticket.service'; +import { AbonoTicketController } from './abono-ticket.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AbonoTicket } from './entities/abono-ticket.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([AbonoTicket])], + controllers: [AbonoTicketController], + providers: [AbonoTicketService], +}) +export class AbonoTicketModule {} diff --git a/src/abono-ticket/abono-ticket.service.spec.ts b/src/abono-ticket/abono-ticket.service.spec.ts new file mode 100644 index 0000000..f0859ff --- /dev/null +++ b/src/abono-ticket/abono-ticket.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AbonoTicketService } from './abono-ticket.service'; + +describe('AbonoTicketService', () => { + let service: AbonoTicketService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AbonoTicketService], + }).compile(); + + service = module.get(AbonoTicketService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/abono-ticket/abono-ticket.service.ts b/src/abono-ticket/abono-ticket.service.ts new file mode 100644 index 0000000..b20fa62 --- /dev/null +++ b/src/abono-ticket/abono-ticket.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@nestjs/common'; +import { CreateAbonoTicketDto } from './dto/create-abono-ticket.dto'; +import { UpdateAbonoTicketDto } from './dto/update-abono-ticket.dto'; +import { AbonoTicket } from './entities/abono-ticket.entity'; +import { Repository } from 'typeorm'; +import { InjectRepository } from '@nestjs/typeorm'; + +@Injectable() +export class AbonoTicketService { + constructor( + @InjectRepository(AbonoTicket) + private readonly abonoTicketRepository: Repository, + ) {} + async create(createAbonoTicketDto: CreateAbonoTicketDto) { + const create = this.abonoTicketRepository.create(createAbonoTicketDto); + await this.abonoTicketRepository.save(create); + return 'success'; + } + + findAll() { + return `This action returns all abonoTicket`; + } + + findOne(id: number) { + return `This action returns a #${id} abonoTicket`; + } + + update(id: number, updateAbonoTicketDto: UpdateAbonoTicketDto) { + return `This action updates a #${id} abonoTicket`; + } + + remove(id: number) { + return `This action removes a #${id} abonoTicket`; + } +} diff --git a/src/abono-ticket/dto/create-abono-ticket.dto.ts b/src/abono-ticket/dto/create-abono-ticket.dto.ts new file mode 100644 index 0000000..3bfa292 --- /dev/null +++ b/src/abono-ticket/dto/create-abono-ticket.dto.ts @@ -0,0 +1 @@ +export class CreateAbonoTicketDto {} diff --git a/src/abono-ticket/dto/update-abono-ticket.dto.ts b/src/abono-ticket/dto/update-abono-ticket.dto.ts new file mode 100644 index 0000000..410037d --- /dev/null +++ b/src/abono-ticket/dto/update-abono-ticket.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateAbonoTicketDto } from './create-abono-ticket.dto'; + +export class UpdateAbonoTicketDto extends PartialType(CreateAbonoTicketDto) {} diff --git a/src/abono-ticket/entities/abono-ticket.entity.ts b/src/abono-ticket/entities/abono-ticket.entity.ts new file mode 100644 index 0000000..7334358 --- /dev/null +++ b/src/abono-ticket/entities/abono-ticket.entity.ts @@ -0,0 +1,29 @@ +import { + Entity, + PrimaryGeneratedColumn, + Column, + ManyToOne, + JoinColumn, +} from 'typeorm'; +import { Transaccion } from 'src/transaccion/entities/transaccion.entity'; // ajusta la ruta según tu estructura + +@Entity('AbonoTicket') +export class AbonoTicket { + @PrimaryGeneratedColumn({ name: 'idTicket', type: 'int' }) + idTicket: number; + + @ManyToOne(() => Transaccion, (transaccion) => transaccion.abonos, { + onDelete: 'CASCADE', + }) + @JoinColumn({ name: 'idTransaccion' }) + transaccion: Transaccion; + + @Column({ type: 'varchar', length: 100 }) + folio: string; + + @Column({ type: 'int' }) + monto: number; + + @Column({ type: 'datetime' }) + fecha: Date; +} diff --git a/src/app.module.ts b/src/app.module.ts index 484a71d..2b190fa 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,6 +4,10 @@ import { AppService } from './app.service'; import { PersonaModule } from './persona/persona.module'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ConfigModule, ConfigService } from '@nestjs/config'; +import { TransaccionModule } from './transaccion/transaccion.module'; +import { AbonoTicketModule } from './abono-ticket/abono-ticket.module'; +import { PagoKioscoModule } from './pago-kiosco/pago-kiosco.module'; +import { KioscoModule } from './kiosco/kiosco.module'; @Module({ imports: [ @@ -15,18 +19,21 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; imports: [ConfigModule], inject: [ConfigService], useFactory: async (config: ConfigService) => ({ - type: 'mysql', // ejemplo, ajusta a tu BD + type: 'mariadb', host: config.get('DB_HOST'), port: config.get('DB_PORT'), username: config.get('DB_USER'), password: config.get('DB_PASS'), database: config.get('DB_NAME'), entities: [__dirname + '/**/*.entity{.ts,.js}'], - synchronize: true, + synchronize: false, }), }), - PersonaModule, + TransaccionModule, + AbonoTicketModule, + PagoKioscoModule, + KioscoModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/kiosco/dto/create-kiosco.dto.ts b/src/kiosco/dto/create-kiosco.dto.ts new file mode 100644 index 0000000..27416e0 --- /dev/null +++ b/src/kiosco/dto/create-kiosco.dto.ts @@ -0,0 +1 @@ +export class CreateKioscoDto {} diff --git a/src/kiosco/dto/update-kiosco.dto.ts b/src/kiosco/dto/update-kiosco.dto.ts new file mode 100644 index 0000000..bddb9bf --- /dev/null +++ b/src/kiosco/dto/update-kiosco.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateKioscoDto } from './create-kiosco.dto'; + +export class UpdateKioscoDto extends PartialType(CreateKioscoDto) {} diff --git a/src/kiosco/entities/kiosco.entity.ts b/src/kiosco/entities/kiosco.entity.ts new file mode 100644 index 0000000..8afe3b4 --- /dev/null +++ b/src/kiosco/entities/kiosco.entity.ts @@ -0,0 +1,40 @@ +import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; + +@Entity() +export class Kiosco { + @PrimaryGeneratedColumn({ type: 'int' }) + idKiosco: number; + + @Column({ type: 'varchar', length: 100 }) + responsable: string; + + @Column({ type: 'varchar', length: 100 }) + lugar: string; + + @Column({ type: 'varchar', length: 20 }) + token: string; + + @Column({ type: 'tinyint', width: 1, default: 0 }) + useToken: boolean; + + @Column({ type: 'datetime', nullable: true }) + dateToken: Date; + + @Column({ type: 'int' }) + saldo: number; + + @Column({ type: 'varchar', length: 20 }) + status: string; + + @Column({ type: 'varchar', length: 100 }) + usuario: string; + + @Column({ type: 'varchar', length: 250 }) + password: string; + + @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + fechaCreado: Date; + + @Column({ type: 'tinyint', width: 1, default: 0 }) + activado: boolean; +} diff --git a/src/kiosco/kiosco.controller.spec.ts b/src/kiosco/kiosco.controller.spec.ts new file mode 100644 index 0000000..210bd3a --- /dev/null +++ b/src/kiosco/kiosco.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { KioscoController } from './kiosco.controller'; +import { KioscoService } from './kiosco.service'; + +describe('KioscoController', () => { + let controller: KioscoController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [KioscoController], + providers: [KioscoService], + }).compile(); + + controller = module.get(KioscoController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/kiosco/kiosco.controller.ts b/src/kiosco/kiosco.controller.ts new file mode 100644 index 0000000..c86a469 --- /dev/null +++ b/src/kiosco/kiosco.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { KioscoService } from './kiosco.service'; +import { CreateKioscoDto } from './dto/create-kiosco.dto'; +import { UpdateKioscoDto } from './dto/update-kiosco.dto'; + +@Controller('kiosco') +export class KioscoController { + constructor(private readonly kioscoService: KioscoService) {} + + @Post() + create(@Body() createKioscoDto: CreateKioscoDto) { + return this.kioscoService.create(createKioscoDto); + } + + @Get() + findAll() { + return this.kioscoService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.kioscoService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateKioscoDto: UpdateKioscoDto) { + return this.kioscoService.update(+id, updateKioscoDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.kioscoService.remove(+id); + } +} diff --git a/src/kiosco/kiosco.module.ts b/src/kiosco/kiosco.module.ts new file mode 100644 index 0000000..9b615a3 --- /dev/null +++ b/src/kiosco/kiosco.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { KioscoService } from './kiosco.service'; +import { KioscoController } from './kiosco.controller'; + +@Module({ + controllers: [KioscoController], + providers: [KioscoService], +}) +export class KioscoModule {} diff --git a/src/kiosco/kiosco.service.spec.ts b/src/kiosco/kiosco.service.spec.ts new file mode 100644 index 0000000..c663445 --- /dev/null +++ b/src/kiosco/kiosco.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { KioscoService } from './kiosco.service'; + +describe('KioscoService', () => { + let service: KioscoService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [KioscoService], + }).compile(); + + service = module.get(KioscoService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/kiosco/kiosco.service.ts b/src/kiosco/kiosco.service.ts new file mode 100644 index 0000000..c75afd4 --- /dev/null +++ b/src/kiosco/kiosco.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@nestjs/common'; +import { CreateKioscoDto } from './dto/create-kiosco.dto'; +import { UpdateKioscoDto } from './dto/update-kiosco.dto'; + +@Injectable() +export class KioscoService { + create(createKioscoDto: CreateKioscoDto) { + return 'This action adds a new kiosco'; + } + + findAll() { + return `This action returns all kiosco`; + } + + findOne(id: number) { + return `This action returns a #${id} kiosco`; + } + + update(id: number, updateKioscoDto: UpdateKioscoDto) { + return `This action updates a #${id} kiosco`; + } + + remove(id: number) { + return `This action removes a #${id} kiosco`; + } +} diff --git a/src/main.ts b/src/main.ts index f76bc8d..0e19a92 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,13 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; +import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); + app.enableCors({}); + app.useGlobalPipes(new ValidationPipe()); await app.listen(process.env.PORT ?? 3000); + + console.log(`successfully connected at the port ${process.env.PORT}`); } bootstrap(); diff --git a/src/pago-kiosco/dto/create-pago-kiosco.dto.ts b/src/pago-kiosco/dto/create-pago-kiosco.dto.ts new file mode 100644 index 0000000..a25ce20 --- /dev/null +++ b/src/pago-kiosco/dto/create-pago-kiosco.dto.ts @@ -0,0 +1 @@ +export class CreatePagoKioscoDto {} diff --git a/src/pago-kiosco/dto/update-pago-kiosco.dto.ts b/src/pago-kiosco/dto/update-pago-kiosco.dto.ts new file mode 100644 index 0000000..fedbaa3 --- /dev/null +++ b/src/pago-kiosco/dto/update-pago-kiosco.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreatePagoKioscoDto } from './create-pago-kiosco.dto'; + +export class UpdatePagoKioscoDto extends PartialType(CreatePagoKioscoDto) {} diff --git a/src/pago-kiosco/entities/pago-kiosco.entity.ts b/src/pago-kiosco/entities/pago-kiosco.entity.ts new file mode 100644 index 0000000..2bab3e0 --- /dev/null +++ b/src/pago-kiosco/entities/pago-kiosco.entity.ts @@ -0,0 +1,76 @@ +import { + Entity, + PrimaryGeneratedColumn, + Column, + ManyToOne, + JoinColumn, + OneToMany, +} from 'typeorm'; +import { Transaccion } from 'src/transaccion/entities/transaccion.entity'; // ajusta la ruta +import { Kiosco } from 'src/kiosco/entities/kiosco.entity'; + +@Entity() +export class PagoPatronato { + @PrimaryGeneratedColumn({ type: 'int' }) + idPagoPatronato: number; + + @Column({ type: 'varchar', length: 30 }) + numeroTicket: string; + + @Column({ type: 'varchar', length: 30 }) + folio: string; + + @Column({ type: 'varchar', length: 50 }) + importeLetra: string; + + @Column({ type: 'varchar', length: 30 }) + fechaPago: string; + + @Column({ type: 'datetime', nullable: true }) + fechaEnvio: Date; + + @OneToMany(() => PagoKiosco, (pagokiosco) => pagokiosco.pagoPatronato) + pagoKiosco: PagoKiosco[]; +} + +@Entity('PagoKiosco') +export class PagoKiosco { + @PrimaryGeneratedColumn({ name: 'idPagoKiosco', type: 'int' }) + idPagoKiosco: number; + + @ManyToOne(() => Transaccion, (transacccion) => transacccion.pagoKiosco, { + onDelete: 'CASCADE', + }) + @JoinColumn({ name: 'idTransaccion' }) + transaccion: Transaccion; + + @Column({ type: 'int' }) + monto: number; + + @Column({ type: 'datetime' }) + fecha: Date; + + @Column({ type: 'tinyint', width: 1, default: 0 }) + patronatoCompletado: boolean; + + @Column({ type: 'tinyint', width: 1, default: 0 }) + pagoPatronatoCreado: boolean; + + @Column({ type: 'tinyint', width: 1, default: 0 }) + ticketCreado: boolean; + + @Column({ type: 'tinyint', width: 1, default: 0 }) + ticketEnviado: boolean; + + @ManyToOne(() => PagoPatronato, (pago) => pago.pagoKiosco, { + onDelete: 'CASCADE', + }) + @JoinColumn({ name: 'idPagoPatronato' }) + pagoPatronato: PagoPatronato; + + @ManyToOne(() => Kiosco, (kiosco) => kiosco.idKiosco, { + onDelete: 'CASCADE', + }) + @JoinColumn({ name: 'idKiosco' }) + kiosco: Kiosco; +} diff --git a/src/pago-kiosco/pago-kiosco.controller.spec.ts b/src/pago-kiosco/pago-kiosco.controller.spec.ts new file mode 100644 index 0000000..23e9d7e --- /dev/null +++ b/src/pago-kiosco/pago-kiosco.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PagoKioscoController } from './pago-kiosco.controller'; +import { PagoKioscoService } from './pago-kiosco.service'; + +describe('PagoKioscoController', () => { + let controller: PagoKioscoController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [PagoKioscoController], + providers: [PagoKioscoService], + }).compile(); + + controller = module.get(PagoKioscoController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/pago-kiosco/pago-kiosco.controller.ts b/src/pago-kiosco/pago-kiosco.controller.ts new file mode 100644 index 0000000..c606c12 --- /dev/null +++ b/src/pago-kiosco/pago-kiosco.controller.ts @@ -0,0 +1,22 @@ +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Delete, +} from '@nestjs/common'; +import { PagoKioscoService } from './pago-kiosco.service'; +import { CreatePagoKioscoDto } from './dto/create-pago-kiosco.dto'; +import { UpdatePagoKioscoDto } from './dto/update-pago-kiosco.dto'; + +@Controller('pago-kiosco') +export class PagoKioscoController { + constructor(private readonly pagoKioscoService: PagoKioscoService) {} + + @Post() + create(@Body() createPagoKioscoDto: CreatePagoKioscoDto) { + return this.pagoKioscoService.create(createPagoKioscoDto); + } +} diff --git a/src/pago-kiosco/pago-kiosco.module.ts b/src/pago-kiosco/pago-kiosco.module.ts new file mode 100644 index 0000000..4b18170 --- /dev/null +++ b/src/pago-kiosco/pago-kiosco.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { PagoKioscoService } from './pago-kiosco.service'; +import { PagoKioscoController } from './pago-kiosco.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { PagoKiosco } from './entities/pago-kiosco.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([PagoKiosco])], + controllers: [PagoKioscoController], + providers: [PagoKioscoService], +}) +export class PagoKioscoModule {} diff --git a/src/pago-kiosco/pago-kiosco.service.spec.ts b/src/pago-kiosco/pago-kiosco.service.spec.ts new file mode 100644 index 0000000..d64b5f1 --- /dev/null +++ b/src/pago-kiosco/pago-kiosco.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PagoKioscoService } from './pago-kiosco.service'; + +describe('PagoKioscoService', () => { + let service: PagoKioscoService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PagoKioscoService], + }).compile(); + + service = module.get(PagoKioscoService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/pago-kiosco/pago-kiosco.service.ts b/src/pago-kiosco/pago-kiosco.service.ts new file mode 100644 index 0000000..8bcca7d --- /dev/null +++ b/src/pago-kiosco/pago-kiosco.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@nestjs/common'; +import { CreatePagoKioscoDto } from './dto/create-pago-kiosco.dto'; +import { UpdatePagoKioscoDto } from './dto/update-pago-kiosco.dto'; +import { InjectRepository } from '@nestjs/typeorm'; +import { PagoKiosco } from './entities/pago-kiosco.entity'; +import { Repository } from 'typeorm'; + +@Injectable() +export class PagoKioscoService { + constructor( + @InjectRepository(PagoKiosco) + private readonly pagoKioscoRepository: Repository, + ) {} + + async create(createPagoKiosco: CreatePagoKioscoDto) { + const create = this.pagoKioscoRepository.create(createPagoKiosco); + await this.pagoKioscoRepository.save(create); + return { statusCode: 200, message: 'success' }; + } +} diff --git a/src/persona/entities/persona.entity.ts b/src/persona/entities/persona.entity.ts index f53d275..2ebe7b3 100644 --- a/src/persona/entities/persona.entity.ts +++ b/src/persona/entities/persona.entity.ts @@ -1,4 +1,5 @@ -import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Transaccion } from 'src/transaccion/entities/transaccion.entity'; +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; @Entity({ name: 'persona' }) export class Persona { @@ -52,4 +53,7 @@ export class Persona { @Column({ type: 'boolean', default: false }) primerLogin: boolean; + + @OneToMany(() => Transaccion, (transaccion) => transaccion.persona) + transacciones: Transaccion[]; } diff --git a/src/persona/jwt.guard.ts b/src/persona/jwt.guard.ts index 1ca9664..c568c52 100644 --- a/src/persona/jwt.guard.ts +++ b/src/persona/jwt.guard.ts @@ -9,7 +9,7 @@ import { AuthGuard } from '@nestjs/passport'; export class JwtAuthGuard extends AuthGuard('jwt') { handleRequest(err: any, user: any, info: any, context: ExecutionContext) { if (err || !user) { - throw new ForbiddenException('Acceso denegado: token inválido o ausente'); + throw new ForbiddenException('Access denied: token inválido o ausente'); } return user; } diff --git a/src/persona/persona.controller.ts b/src/persona/persona.controller.ts index 2c294ee..4ad2ee0 100644 --- a/src/persona/persona.controller.ts +++ b/src/persona/persona.controller.ts @@ -20,13 +20,12 @@ export class PersonaController { @Get('google/callback') @UseGuards(GoogleAuthGuard) async googleCallback(@Req() req, @Res() res: Response) { - const persona = req.user; // Ya viene desde GoogleStrategy.validate() + const persona = req.user; if (!persona) { return res.redirect(`${process.env.FRONTEND_URL}?error=oauth_failed`); } - // Generar JWT con los datos de la persona const jwt = await this.personaService.generateJwt(persona); return res.redirect( @@ -58,4 +57,13 @@ export class PersonaController { }, }; } + + @UseGuards(JwtAuthGuard) + @Get('saldo') + async saldo(@Req() req) { + const idPersona = req.user.idPersona; + + return this.personaService.saldo(idPersona); + } } +//IO diff --git a/src/persona/persona.service.ts b/src/persona/persona.service.ts index 5ef92e8..7341930 100644 --- a/src/persona/persona.service.ts +++ b/src/persona/persona.service.ts @@ -18,9 +18,9 @@ export class PersonaService { return this.personaRepository.find(); } - async findByEmail(email: string): Promise { + async findByEmail(correo: string): Promise { const user = await this.personaRepository.findOne({ - where: { correo: email }, + where: { correo }, }); console.log('service', user); return user; @@ -87,8 +87,23 @@ export class PersonaService { return persona; } - saldo(idPersona) { - this.personaRepository.findOne({ where: { idPersona } }); - return; + async saldo(idPersona: number) { + const persona = await this.personaRepository.findOne({ + where: { idPersona }, + select: { cantidadCuenta: true }, + }); + + return persona?.cantidadCuenta; + } + + async updateSaldo(idPersona: number, monto: number) { + const persona = await this.findById(idPersona); + + const nuevoSaldo = (persona.cantidadCuenta || 0) + monto; + await this.personaRepository.update(idPersona, { + cantidadCuenta: nuevoSaldo, + }); + return { statusCode: 200, message: `tu saldo es ${nuevoSaldo}` }; } } +//IO diff --git a/src/transaccion/dto/create-transaccion.dto.ts b/src/transaccion/dto/create-transaccion.dto.ts new file mode 100644 index 0000000..5c31627 --- /dev/null +++ b/src/transaccion/dto/create-transaccion.dto.ts @@ -0,0 +1,19 @@ +import { IsInt, IsNotEmpty, IsDateString, IsNumber } from 'class-validator'; + +export class CreateTransaccionDto { + @IsInt() + @IsNotEmpty() + idNombreTransaccion: number; + + @IsInt() + @IsNotEmpty() + idPersona: number; + + @IsDateString() + @IsNotEmpty() + fecha: string; + + @IsNumber() + @IsNotEmpty() + tipoTransaccion: number; +} diff --git a/src/transaccion/entities/transaccion.entity.ts b/src/transaccion/entities/transaccion.entity.ts new file mode 100644 index 0000000..7404b56 --- /dev/null +++ b/src/transaccion/entities/transaccion.entity.ts @@ -0,0 +1,58 @@ +import { + Entity, + PrimaryGeneratedColumn, + Column, + ManyToOne, + JoinColumn, + OneToMany, +} from 'typeorm'; +import { Persona } from 'src/persona/entities/persona.entity'; // ajusta la ruta según tu estructura +import { AbonoTicket } from 'src/abono-ticket/entities/abono-ticket.entity'; +import { PagoKiosco } from 'src/pago-kiosco/entities/pago-kiosco.entity'; + +@Entity('NombreTransaccion') +export class NombreTransaccion { + @PrimaryGeneratedColumn() + idNombreTransaccion: number; + + @Column({ type: 'varchar', length: '50' }) + nombreTransaccion: string; + + @OneToMany(() => Transaccion, (transaccion) => transaccion.nombreTransaccion) + transacciones: Transaccion[]; +} + +@Entity('Transaccion') +export class Transaccion { + @PrimaryGeneratedColumn({ name: 'idTransaccion', type: 'int' }) + idTransaccion: number; + + @ManyToOne( + () => NombreTransaccion, + (nombreTransaccion) => nombreTransaccion.transacciones, + ) + @JoinColumn({ name: 'idNombreTransaccion' }) + nombreTransaccion: NombreTransaccion; + + @ManyToOne(() => Persona, (people) => people.transacciones) + @JoinColumn({ name: 'idPersona' }) + persona: Persona; + + @Column({ type: 'datetime' }) + fecha: Date; + + @Column({ type: 'float' }) + saldoDespuesTransaccion: number; + + @Column({ + type: 'enum', + enum: ['deposito', 'retiro', 'transferencia', 'ajuste'], + }) + tipoTransaccion: number; + + @OneToMany(() => AbonoTicket, (abono) => abono.idTicket) + abonos: AbonoTicket[]; + + @OneToMany(() => PagoKiosco, (pago) => pago.kiosco) + pagoKiosco: PagoKiosco[]; +} diff --git a/src/transaccion/transaccion.controller.spec.ts b/src/transaccion/transaccion.controller.spec.ts new file mode 100644 index 0000000..ff9f593 --- /dev/null +++ b/src/transaccion/transaccion.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { TransaccionController } from './transaccion.controller'; +import { TransaccionService } from './transaccion.service'; + +describe('TransaccionController', () => { + let controller: TransaccionController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [TransaccionController], + providers: [TransaccionService], + }).compile(); + + controller = module.get(TransaccionController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/transaccion/transaccion.controller.ts b/src/transaccion/transaccion.controller.ts new file mode 100644 index 0000000..3edc0da --- /dev/null +++ b/src/transaccion/transaccion.controller.ts @@ -0,0 +1,26 @@ +import { Controller, Get, Post, Body } from '@nestjs/common'; +import { TransaccionService } from './transaccion.service'; +import { CreateTransaccionDto } from './dto/create-transaccion.dto'; + +@Controller('transaccion') +export class TransaccionController { + constructor(private readonly transaccionService: TransaccionService) {} + + @Get() + all() { + return this.transaccionService.all(); + } + + @Post('abonoKiosco') + abonoKiosco(@Body() createTransaccionDto: CreateTransaccionDto) { + const { ...rest } = createTransaccionDto; + + const data = { + ...rest, + fecha: new Date().toString(), + tipoTransaccion: 2, + }; + return this.transaccionService.create(data); + } +} +//IO diff --git a/src/transaccion/transaccion.module.ts b/src/transaccion/transaccion.module.ts new file mode 100644 index 0000000..bca7b7a --- /dev/null +++ b/src/transaccion/transaccion.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { TransaccionService } from './transaccion.service'; +import { TransaccionController } from './transaccion.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Transaccion } from './entities/transaccion.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Transaccion])], + controllers: [TransaccionController], + providers: [TransaccionService], +}) +export class TransaccionModule {} diff --git a/src/transaccion/transaccion.service.spec.ts b/src/transaccion/transaccion.service.spec.ts new file mode 100644 index 0000000..39e311a --- /dev/null +++ b/src/transaccion/transaccion.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { TransaccionService } from './transaccion.service'; + +describe('TransaccionService', () => { + let service: TransaccionService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [TransaccionService], + }).compile(); + + service = module.get(TransaccionService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/transaccion/transaccion.service.ts b/src/transaccion/transaccion.service.ts new file mode 100644 index 0000000..2438fc4 --- /dev/null +++ b/src/transaccion/transaccion.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@nestjs/common'; +import { CreateTransaccionDto } from './dto/create-transaccion.dto'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Transaccion } from './entities/transaccion.entity'; +import { Repository } from 'typeorm'; + +@Injectable() +export class TransaccionService { + constructor( + @InjectRepository(Transaccion) + private readonly transaccionRepository: Repository, + ) {} + + async all() { + return await this.transaccionRepository.find(); + } + + async create(createTransaccion: CreateTransaccionDto) { + const create = this.transaccionRepository.create(createTransaccion); + await this.transaccionRepository.save(create); + return 'success'; + } +} +//IO