form guarda y estadisticas
This commit is contained in:
@@ -12,7 +12,7 @@ export class CreateTrainingDto {
|
||||
|
||||
@ApiProperty()
|
||||
@IsDateString()
|
||||
visitDate: Date;
|
||||
visitDate: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { IsOptional, IsString, IsNumber, IsDateString } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class TrainingStatisticsFilterDto {
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
startDate?: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
endDate?: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
stateId?: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
municipalityId?: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
parishId?: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
ospType?: string;
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import { UpdateTrainingDto } from './dto/update-training.dto';
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { PaginationDto } from '../../common/dto/pagination.dto';
|
||||
|
||||
import { TrainingStatisticsFilterDto } from './dto/training-statistics-filter.dto';
|
||||
|
||||
@ApiTags('training')
|
||||
@Controller('training')
|
||||
export class TrainingController {
|
||||
@@ -22,6 +24,14 @@ export class TrainingController {
|
||||
};
|
||||
}
|
||||
|
||||
@Get('statistics')
|
||||
@ApiOperation({ summary: 'Get training statistics' })
|
||||
@ApiResponse({ status: 200, description: 'Return training statistics.' })
|
||||
async getStatistics(@Query() filterDto: TrainingStatisticsFilterDto) {
|
||||
const data = await this.trainingService.getStatistics(filterDto);
|
||||
return { message: 'Training statistics fetched successfully', data };
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@ApiOperation({ summary: 'Get a training record by ID' })
|
||||
@ApiResponse({ status: 200, description: 'Return the training record.' })
|
||||
|
||||
@@ -3,9 +3,11 @@ 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 { eq, like, or, and, gte, lte, SQL, sql } from 'drizzle-orm';
|
||||
import { CreateTrainingDto } from './dto/create-training.dto';
|
||||
import { UpdateTrainingDto } from './dto/update-training.dto';
|
||||
import { TrainingStatisticsFilterDto } from './dto/training-statistics-filter.dto';
|
||||
import { states } from 'src/database/index';
|
||||
import { PaginationDto } from '../../common/dto/pagination.dto';
|
||||
|
||||
@Injectable()
|
||||
@@ -14,6 +16,7 @@ export class TrainingService {
|
||||
@Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>,
|
||||
) { }
|
||||
|
||||
|
||||
async findAll(paginationDto?: PaginationDto) {
|
||||
const { page = 1, limit = 10, search = '', sortBy = 'id', sortOrder = 'asc' } = paginationDto || {};
|
||||
|
||||
@@ -63,6 +66,108 @@ export class TrainingService {
|
||||
return { data, meta };
|
||||
}
|
||||
|
||||
async getStatistics(filterDto: TrainingStatisticsFilterDto) {
|
||||
const { startDate, endDate, stateId, municipalityId, parishId, ospType } = filterDto;
|
||||
|
||||
const filters: SQL[] = [];
|
||||
|
||||
if (startDate) {
|
||||
filters.push(gte(trainingSurveys.visitDate, new Date(startDate)));
|
||||
}
|
||||
|
||||
if (endDate) {
|
||||
filters.push(lte(trainingSurveys.visitDate, new Date(endDate)));
|
||||
}
|
||||
|
||||
if (stateId) {
|
||||
filters.push(eq(trainingSurveys.state, stateId));
|
||||
}
|
||||
|
||||
if (municipalityId) {
|
||||
filters.push(eq(trainingSurveys.municipality, municipalityId));
|
||||
}
|
||||
|
||||
if (parishId) {
|
||||
filters.push(eq(trainingSurveys.parish, parishId));
|
||||
}
|
||||
|
||||
if (ospType) {
|
||||
filters.push(eq(trainingSurveys.ospType, ospType));
|
||||
}
|
||||
|
||||
const whereCondition = filters.length > 0 ? and(...filters) : undefined;
|
||||
|
||||
const totalOspsResult = await this.drizzle
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(trainingSurveys)
|
||||
.where(whereCondition);
|
||||
const totalOsps = Number(totalOspsResult[0].count);
|
||||
|
||||
const totalProducersResult = await this.drizzle
|
||||
.select({ sum: sql<number>`sum(${trainingSurveys.producerCount})` })
|
||||
.from(trainingSurveys)
|
||||
.where(whereCondition);
|
||||
const totalProducers = Number(totalProducersResult[0].sum || 0);
|
||||
|
||||
const statusDistribution = await this.drizzle
|
||||
.select({
|
||||
name: trainingSurveys.currentStatus,
|
||||
value: sql<number>`count(*)`
|
||||
})
|
||||
.from(trainingSurveys)
|
||||
.where(whereCondition)
|
||||
.groupBy(trainingSurveys.currentStatus);
|
||||
|
||||
const activityDistribution = await this.drizzle
|
||||
.select({
|
||||
name: trainingSurveys.productiveActivity,
|
||||
value: sql<number>`count(*)`
|
||||
})
|
||||
.from(trainingSurveys)
|
||||
.where(whereCondition)
|
||||
.groupBy(trainingSurveys.productiveActivity);
|
||||
|
||||
const typeDistribution = await this.drizzle
|
||||
.select({
|
||||
name: trainingSurveys.ospType,
|
||||
value: sql<number>`count(*)`
|
||||
})
|
||||
.from(trainingSurveys)
|
||||
.where(whereCondition)
|
||||
.groupBy(trainingSurveys.ospType);
|
||||
|
||||
// New Aggregations
|
||||
const stateDistribution = await this.drizzle
|
||||
.select({
|
||||
name: states.name,
|
||||
value: sql<number>`count(${trainingSurveys.id})`
|
||||
})
|
||||
.from(trainingSurveys)
|
||||
.leftJoin(states, eq(trainingSurveys.state, states.id))
|
||||
.where(whereCondition)
|
||||
.groupBy(states.name);
|
||||
|
||||
const yearDistribution = await this.drizzle
|
||||
.select({
|
||||
name: sql<string>`cast(${trainingSurveys.companyConstitutionYear} as text)`,
|
||||
value: sql<number>`count(*)`
|
||||
})
|
||||
.from(trainingSurveys)
|
||||
.where(whereCondition)
|
||||
.groupBy(trainingSurveys.companyConstitutionYear)
|
||||
.orderBy(trainingSurveys.companyConstitutionYear);
|
||||
|
||||
return {
|
||||
totalOsps,
|
||||
totalProducers,
|
||||
statusDistribution: statusDistribution.map(item => ({ ...item, value: Number(item.value) })),
|
||||
activityDistribution: activityDistribution.map(item => ({ ...item, value: Number(item.value) })),
|
||||
typeDistribution: typeDistribution.map(item => ({ ...item, value: Number(item.value) })),
|
||||
stateDistribution: stateDistribution.map(item => ({ ...item, value: Number(item.value) })),
|
||||
yearDistribution: yearDistribution.map(item => ({ ...item, value: Number(item.value) })),
|
||||
};
|
||||
}
|
||||
|
||||
async findOne(id: number) {
|
||||
const find = await this.drizzle
|
||||
.select()
|
||||
|
||||
Reference in New Issue
Block a user