formulario de capacitacion

This commit is contained in:
2025-12-01 18:23:18 -04:00
parent 6f8a55b8fd
commit efa1726223
25 changed files with 3165 additions and 181 deletions

View File

@@ -0,0 +1,124 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsInt, IsString, IsDateString, IsOptional } from 'class-validator';
export class CreateTrainingDto {
@ApiProperty()
@IsString()
firstname: string;
@ApiProperty()
@IsString()
lastname: string;
@ApiProperty()
@IsDateString()
visitDate: Date;
@ApiProperty()
@IsString()
productiveActivity: string;
@ApiProperty()
@IsString()
financialRequirementDescription: string;
@ApiProperty()
@IsString()
siturCodeCommune: string;
@ApiProperty()
@IsString()
communalCouncil: string;
@ApiProperty()
@IsString()
siturCodeCommunalCouncil: string;
@ApiProperty()
@IsString()
ospName: string;
@ApiProperty()
@IsString()
ospAddress: string;
@ApiProperty()
@IsString()
ospRif: string;
@ApiProperty()
@IsString()
ospType: string;
@ApiProperty()
@IsString()
currentStatus: string;
@ApiProperty()
@IsInt()
companyConstitutionYear: number;
@ApiProperty()
@IsInt()
producerCount: number;
@ApiProperty()
@IsString()
productDescription: string;
@ApiProperty()
@IsString()
installedCapacity: string;
@ApiProperty()
@IsString()
operationalCapacity: string;
@ApiProperty()
@IsString()
ospResponsibleFullname: string;
@ApiProperty()
@IsString()
ospResponsibleCedula: string;
@ApiProperty()
@IsString()
ospResponsibleRif: string;
@ApiProperty()
@IsString()
ospResponsiblePhone: string;
@ApiProperty()
@IsString()
civilState: string;
@ApiProperty()
@IsInt()
familyBurden: number;
@ApiProperty()
@IsInt()
numberOfChildren: number;
@ApiProperty()
@IsString()
generalObservations: string;
@ApiProperty()
@IsString()
photo1: string;
@ApiProperty()
@IsString()
photo2: string;
@ApiProperty()
@IsString()
photo3: string;
@ApiProperty()
@IsString()
paralysisReason: string;
}

View File

@@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/swagger';
import { CreateTrainingDto } from './create-training.dto';
export class UpdateTrainingDto extends PartialType(CreateTrainingDto) { }

View File

@@ -0,0 +1,58 @@
import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';
import { TrainingService } from './training.service';
import { CreateTrainingDto } from './dto/create-training.dto';
import { UpdateTrainingDto } from './dto/update-training.dto';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { PaginationDto } from '../../common/dto/pagination.dto';
@ApiTags('training')
@Controller('training')
export class TrainingController {
constructor(private readonly trainingService: TrainingService) { }
@Get()
@ApiOperation({ summary: 'Get all training records with pagination and filters' })
@ApiResponse({ status: 200, description: 'Return paginated training records.' })
async findAll(@Query() paginationDto: PaginationDto) {
const result = await this.trainingService.findAll(paginationDto);
return {
message: 'Training records fetched successfully',
data: result.data,
meta: result.meta
};
}
@Get(':id')
@ApiOperation({ summary: 'Get a training record by ID' })
@ApiResponse({ status: 200, description: 'Return the training record.' })
@ApiResponse({ status: 404, description: 'Training record not found.' })
async findOne(@Param('id') id: string) {
const data = await this.trainingService.findOne(+id);
return { message: 'Training record fetched successfully', data };
}
@Post()
@ApiOperation({ summary: 'Create a new training record' })
@ApiResponse({ status: 201, description: 'Training record created successfully.' })
async create(@Body() createTrainingDto: CreateTrainingDto) {
const data = await this.trainingService.create(createTrainingDto);
return { message: 'Training record created successfully', data };
}
@Patch(':id')
@ApiOperation({ summary: 'Update a training record' })
@ApiResponse({ status: 200, description: 'Training record updated successfully.' })
@ApiResponse({ status: 404, description: 'Training record not found.' })
async update(@Param('id') id: string, @Body() updateTrainingDto: UpdateTrainingDto) {
const data = await this.trainingService.update(+id, updateTrainingDto);
return { message: 'Training record updated successfully', data };
}
@Delete(':id')
@ApiOperation({ summary: 'Delete a training record' })
@ApiResponse({ status: 200, description: 'Training record deleted successfully.' })
@ApiResponse({ status: 404, description: 'Training record not found.' })
async remove(@Param('id') id: string) {
return await this.trainingService.remove(+id);
}
}

View File

@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { TrainingService } from './training.service';
import { TrainingController } from './training.controller';
@Module({
controllers: [TrainingController],
providers: [TrainingService],
exports: [TrainingService],
})
export class TrainingModule { }

View File

@@ -0,0 +1,118 @@
import { DRIZZLE_PROVIDER } from 'src/database/drizzle-provider';
import { Inject, Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
import * as schema from 'src/database/index';
import { trainingSurveys } from 'src/database/index';
import { eq, like, or, SQL, sql } from 'drizzle-orm';
import { CreateTrainingDto } from './dto/create-training.dto';
import { UpdateTrainingDto } from './dto/update-training.dto';
import { PaginationDto } from '../../common/dto/pagination.dto';
@Injectable()
export class TrainingService {
constructor(
@Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>,
) { }
async findAll(paginationDto?: PaginationDto) {
const { page = 1, limit = 10, search = '', sortBy = 'id', sortOrder = 'asc' } = paginationDto || {};
const offset = (page - 1) * limit;
let searchCondition: SQL<unknown> | undefined;
if (search) {
searchCondition = or(
like(trainingSurveys.firstname, `%${search}%`),
like(trainingSurveys.lastname, `%${search}%`),
like(trainingSurveys.ospName, `%${search}%`),
like(trainingSurveys.ospRif, `%${search}%`)
);
}
const orderBy = sortOrder === 'asc'
? sql`${trainingSurveys[sortBy as keyof typeof trainingSurveys]} asc`
: sql`${trainingSurveys[sortBy as keyof typeof trainingSurveys]} desc`;
const totalCountResult = await this.drizzle
.select({ count: sql<number>`count(*)` })
.from(trainingSurveys)
.where(searchCondition);
const totalCount = Number(totalCountResult[0].count);
const totalPages = Math.ceil(totalCount / limit);
const data = await this.drizzle
.select()
.from(trainingSurveys)
.where(searchCondition)
.orderBy(orderBy)
.limit(limit)
.offset(offset);
const meta = {
page,
limit,
totalCount,
totalPages,
hasNextPage: page < totalPages,
hasPreviousPage: page > 1,
nextPage: page < totalPages ? page + 1 : null,
previousPage: page > 1 ? page - 1 : null,
};
return { data, meta };
}
async findOne(id: number) {
const find = await this.drizzle
.select()
.from(trainingSurveys)
.where(eq(trainingSurveys.id, id));
if (find.length === 0) {
throw new HttpException('Training record not found', HttpStatus.NOT_FOUND);
}
return find[0];
}
async create(createTrainingDto: CreateTrainingDto) {
const [newRecord] = await this.drizzle
.insert(trainingSurveys)
.values({
...createTrainingDto,
visitDate: new Date(createTrainingDto.visitDate),
})
.returning();
return newRecord;
}
async update(id: number, updateTrainingDto: UpdateTrainingDto) {
await this.findOne(id);
const updateData: any = { ...updateTrainingDto };
if (updateTrainingDto.visitDate) {
updateData.visitDate = new Date(updateTrainingDto.visitDate);
}
const [updatedRecord] = await this.drizzle
.update(trainingSurveys)
.set(updateData)
.where(eq(trainingSurveys.id, id))
.returning();
return updatedRecord;
}
async remove(id: number) {
await this.findOne(id);
const [deletedRecord] = await this.drizzle
.delete(trainingSurveys)
.where(eq(trainingSurveys.id, id))
.returning();
return { message: 'Training record deleted successfully', data: deletedRecord };
}
}