base con autenticacion, registro, modulo encuestas
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { Roles } from '@/common/decorators';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { CategoryTypesService } from './category-types.service';
|
||||
import { CreateCategoryTypeDto } from './dto/create-category-type.dto';
|
||||
import { UpdateCategoryTypeDto } from './dto/update-category-type.dto';
|
||||
import { CategoryType } from './entities/category-type.entity';
|
||||
|
||||
@ApiTags('Category Types')
|
||||
@Controller('configurations/category-types')
|
||||
export class CategoryTypesController {
|
||||
constructor(private readonly categoryTypesService: CategoryTypesService) {}
|
||||
|
||||
@Get()
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get all category types' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return all category types',
|
||||
type: [CategoryType],
|
||||
})
|
||||
findAll() {
|
||||
return this.categoryTypesService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get a category type by id' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return a category type',
|
||||
type: CategoryType,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Category type not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.categoryTypesService.findOne(id);
|
||||
}
|
||||
|
||||
@Get('group/:group')
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get category types by group' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return category types by group',
|
||||
type: [CategoryType],
|
||||
})
|
||||
findByGroup(@Param('group') group: string) {
|
||||
return this.categoryTypesService.findByGroup(group);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Roles('admin')
|
||||
@ApiOperation({ summary: 'Create a new category type' })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'Category type created',
|
||||
type: CategoryType,
|
||||
})
|
||||
create(@Body() createCategoryTypeDto: CreateCategoryTypeDto) {
|
||||
return this.categoryTypesService.create(createCategoryTypeDto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@Roles('admin')
|
||||
@ApiOperation({ summary: 'Update a category type' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Category type updated',
|
||||
type: CategoryType,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Category type not found' })
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() updateCategoryTypeDto: UpdateCategoryTypeDto,
|
||||
) {
|
||||
return this.categoryTypesService.update(id, updateCategoryTypeDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@Roles('admin')
|
||||
@ApiOperation({ summary: 'Delete a category type' })
|
||||
@ApiResponse({ status: 200, description: 'Category type deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Category type not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.categoryTypesService.remove(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { DrizzleModule } from '@/database/drizzle.module';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { CategoryTypesController } from './category-types.controller';
|
||||
import { CategoryTypesService } from './category-types.service';
|
||||
|
||||
@Module({
|
||||
imports: [DrizzleModule],
|
||||
controllers: [CategoryTypesController],
|
||||
providers: [CategoryTypesService],
|
||||
exports: [CategoryTypesService],
|
||||
})
|
||||
export class CategoryTypesModule {}
|
||||
@@ -0,0 +1,81 @@
|
||||
import { DRIZZLE_PROVIDER } from '@/database/drizzle-provider';
|
||||
import * as schema from '@/database/index';
|
||||
import { categoryType } from '@/database/schema/general';
|
||||
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { CreateCategoryTypeDto } from './dto/create-category-type.dto';
|
||||
import { UpdateCategoryTypeDto } from './dto/update-category-type.dto';
|
||||
import { CategoryType } from './entities/category-type.entity';
|
||||
|
||||
@Injectable()
|
||||
export class CategoryTypesService {
|
||||
constructor(
|
||||
@Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>,
|
||||
) {}
|
||||
|
||||
async findAll(): Promise<CategoryType[]> {
|
||||
return await this.drizzle.select().from(categoryType);
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<CategoryType> {
|
||||
const category = await this.drizzle
|
||||
.select()
|
||||
.from(categoryType)
|
||||
.where(eq(categoryType.id, id));
|
||||
|
||||
if (category.length === 0) {
|
||||
throw new HttpException('Category type not found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
return category[0];
|
||||
}
|
||||
|
||||
async findByGroup(group: string): Promise<CategoryType[]> {
|
||||
return await this.drizzle
|
||||
.select()
|
||||
.from(categoryType)
|
||||
.where(eq(categoryType.group, group));
|
||||
}
|
||||
|
||||
async create(
|
||||
createCategoryTypeDto: CreateCategoryTypeDto,
|
||||
): Promise<CategoryType> {
|
||||
const [category] = await this.drizzle
|
||||
.insert(categoryType)
|
||||
.values({
|
||||
group: createCategoryTypeDto.group,
|
||||
description: createCategoryTypeDto.description,
|
||||
})
|
||||
.returning();
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
async update(
|
||||
id: number,
|
||||
updateCategoryTypeDto: UpdateCategoryTypeDto,
|
||||
): Promise<CategoryType> {
|
||||
// Check if category type exists
|
||||
await this.findOne(id);
|
||||
|
||||
await this.drizzle
|
||||
.update(categoryType)
|
||||
.set({
|
||||
group: updateCategoryTypeDto.group,
|
||||
description: updateCategoryTypeDto.description,
|
||||
})
|
||||
.where(eq(categoryType.id, id));
|
||||
|
||||
return this.findOne(id);
|
||||
}
|
||||
|
||||
async remove(id: number): Promise<{ message: string }> {
|
||||
// Check if category type exists
|
||||
await this.findOne(id);
|
||||
|
||||
await this.drizzle.delete(categoryType).where(eq(categoryType.id, id));
|
||||
|
||||
return { message: 'Category type deleted successfully' };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty, IsNumber, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class CreateCategoryTypeDto {
|
||||
@ApiProperty({
|
||||
description: 'The group of the category type',
|
||||
example: 'PAYROLL_TYPE',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
group: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The description of the category type',
|
||||
example: 'Quincenal',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
description: string;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/swagger';
|
||||
import { CreateCategoryTypeDto } from './create-category-type.dto';
|
||||
|
||||
export class UpdateCategoryTypeDto extends PartialType(CreateCategoryTypeDto) {}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CategoryType {
|
||||
@ApiProperty({
|
||||
description: 'The unique identifier of the category type',
|
||||
example: 1,
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The group of the category type',
|
||||
example: 'PAYROLL_TYPE',
|
||||
})
|
||||
group: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The description of the category type',
|
||||
example: 'Quincenal',
|
||||
})
|
||||
description: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the category type was created',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
created_at?: Date;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the category type was last updated',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
updated_at?: Date | null;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { CategoryTypesModule } from './category-types/category-types.module';
|
||||
import { MunicipalitiesModule } from './municipalities/municipalities.module';
|
||||
import { ParishesModule } from './parishes/parishes.module';
|
||||
import { StatesModule } from './states/states.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
StatesModule,
|
||||
MunicipalitiesModule,
|
||||
ParishesModule,
|
||||
CategoryTypesModule,
|
||||
],
|
||||
})
|
||||
export class ConfigurationsModule {}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
|
||||
|
||||
export class CreateMunicipalityDto {
|
||||
@ApiProperty({
|
||||
description: 'The name of the municipality',
|
||||
example: 'Los Angeles',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The ID of the state this municipality belongs to',
|
||||
example: 1,
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
stateId: number;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/swagger';
|
||||
import { CreateMunicipalityDto } from './create-municipality.dto';
|
||||
|
||||
export class UpdateMunicipalityDto extends PartialType(CreateMunicipalityDto) {}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class Municipality {
|
||||
@ApiProperty({
|
||||
description: 'The unique identifier of the municipality',
|
||||
example: 1,
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The name of the municipality',
|
||||
example: 'Los Angeles',
|
||||
})
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The ID of the state this municipality belongs to',
|
||||
example: 1,
|
||||
})
|
||||
stateId: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The name of the state this municipality belongs to',
|
||||
example: 'California',
|
||||
})
|
||||
stateName?: string | null;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the municipality was created',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
created_at?: Date | null;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the municipality was last updated',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
updated_at?: Date | null;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
import { Roles } from '@/common/decorators';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { CreateMunicipalityDto } from './dto/create-municipality.dto';
|
||||
import { UpdateMunicipalityDto } from './dto/update-municipality.dto';
|
||||
import { Municipality } from './entities/municipality.entity';
|
||||
import { MunicipalitiesService } from './municipalities.service';
|
||||
|
||||
@ApiTags('Municipalities')
|
||||
@Controller('configurations/municipalities')
|
||||
export class MunicipalitiesController {
|
||||
constructor(private readonly municipalitiesService: MunicipalitiesService) {}
|
||||
|
||||
@Get()
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get all municipalities' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return all municipalities',
|
||||
type: [Municipality],
|
||||
})
|
||||
findAll() {
|
||||
return this.municipalitiesService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get a municipality by id' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return a municipality',
|
||||
type: Municipality,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Municipality not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.municipalitiesService.findOne(id);
|
||||
}
|
||||
|
||||
@Get('state/:stateId')
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get municipalities by state id' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return municipalities by state',
|
||||
type: [Municipality],
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'State not found' })
|
||||
findByState(@Param('stateId', ParseIntPipe) stateId: number) {
|
||||
return this.municipalitiesService.findByState(stateId);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Roles('ADMIN')
|
||||
@ApiOperation({ summary: 'Create a new municipality' })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'Municipality created',
|
||||
type: Municipality,
|
||||
})
|
||||
create(@Body() createMunicipalityDto: CreateMunicipalityDto) {
|
||||
return this.municipalitiesService.create(createMunicipalityDto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@Roles('ADMIN')
|
||||
@ApiOperation({ summary: 'Update a municipality' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Municipality updated',
|
||||
type: Municipality,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Municipality not found' })
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() updateMunicipalityDto: UpdateMunicipalityDto,
|
||||
) {
|
||||
return this.municipalitiesService.update(id, updateMunicipalityDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@Roles('ADMIN')
|
||||
@ApiOperation({ summary: 'Delete a municipality' })
|
||||
@ApiResponse({ status: 200, description: 'Municipality deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Municipality not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.municipalitiesService.remove(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { DrizzleModule } from '@/database/drizzle.module';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { StatesModule } from '../states/states.module';
|
||||
import { MunicipalitiesController } from './municipalities.controller';
|
||||
import { MunicipalitiesService } from './municipalities.service';
|
||||
|
||||
@Module({
|
||||
imports: [DrizzleModule, StatesModule],
|
||||
controllers: [MunicipalitiesController],
|
||||
providers: [MunicipalitiesService],
|
||||
exports: [MunicipalitiesService],
|
||||
})
|
||||
export class MunicipalitiesModule {}
|
||||
@@ -0,0 +1,120 @@
|
||||
import { DRIZZLE_PROVIDER } from '@/database/drizzle-provider';
|
||||
import * as schema from '@/database/index';
|
||||
import { municipalities, states } from '@/database/schema/general';
|
||||
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { StatesService } from '../states/states.service';
|
||||
import { CreateMunicipalityDto } from './dto/create-municipality.dto';
|
||||
import { UpdateMunicipalityDto } from './dto/update-municipality.dto';
|
||||
import { Municipality } from './entities/municipality.entity';
|
||||
|
||||
@Injectable()
|
||||
export class MunicipalitiesService {
|
||||
constructor(
|
||||
@Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>,
|
||||
private statesService: StatesService,
|
||||
) {}
|
||||
|
||||
async findAll(): Promise<Municipality[]> {
|
||||
return await this.drizzle
|
||||
.select({
|
||||
id: municipalities.id,
|
||||
name: municipalities.name,
|
||||
stateId: municipalities.stateId,
|
||||
stateName: states.name,
|
||||
created_at: municipalities.created_at,
|
||||
updated_at: municipalities.updated_at,
|
||||
})
|
||||
.from(municipalities)
|
||||
.leftJoin(states, eq(municipalities.stateId, states.id));
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<Municipality> {
|
||||
const municipality = await this.drizzle
|
||||
.select({
|
||||
id: municipalities.id,
|
||||
name: municipalities.name,
|
||||
stateId: municipalities.stateId,
|
||||
stateName: states.name,
|
||||
created_at: municipalities.created_at,
|
||||
updated_at: municipalities.updated_at,
|
||||
})
|
||||
.from(municipalities)
|
||||
.leftJoin(states, eq(municipalities.stateId, states.id))
|
||||
.where(eq(municipalities.id, id));
|
||||
|
||||
if (municipality.length === 0) {
|
||||
throw new HttpException('Municipality not found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
return municipality[0];
|
||||
}
|
||||
|
||||
async findByState(stateId: number): Promise<Municipality[]> {
|
||||
// Verify state exists
|
||||
await this.statesService.findOne(stateId);
|
||||
|
||||
return await this.drizzle
|
||||
.select({
|
||||
id: municipalities.id,
|
||||
name: municipalities.name,
|
||||
stateId: municipalities.stateId,
|
||||
stateName: states.name,
|
||||
created_at: municipalities.created_at,
|
||||
updated_at: municipalities.updated_at,
|
||||
})
|
||||
.from(municipalities)
|
||||
.leftJoin(states, eq(municipalities.stateId, states.id))
|
||||
.where(eq(municipalities.stateId, stateId));
|
||||
}
|
||||
|
||||
async create(
|
||||
createMunicipalityDto: CreateMunicipalityDto,
|
||||
): Promise<Municipality> {
|
||||
// Verify state exists
|
||||
await this.statesService.findOne(createMunicipalityDto.stateId);
|
||||
|
||||
const [municipality] = await this.drizzle
|
||||
.insert(municipalities)
|
||||
.values({
|
||||
name: createMunicipalityDto.name,
|
||||
stateId: createMunicipalityDto.stateId,
|
||||
})
|
||||
.returning();
|
||||
|
||||
return this.findOne(municipality.id);
|
||||
}
|
||||
|
||||
async update(
|
||||
id: number,
|
||||
updateMunicipalityDto: UpdateMunicipalityDto,
|
||||
): Promise<Municipality> {
|
||||
// Check if municipality exists
|
||||
await this.findOne(id);
|
||||
|
||||
// If stateId is provided, verify it exists
|
||||
if (updateMunicipalityDto.stateId) {
|
||||
await this.statesService.findOne(updateMunicipalityDto.stateId);
|
||||
}
|
||||
|
||||
await this.drizzle
|
||||
.update(municipalities)
|
||||
.set({
|
||||
name: updateMunicipalityDto.name,
|
||||
stateId: updateMunicipalityDto.stateId,
|
||||
})
|
||||
.where(eq(municipalities.id, id));
|
||||
|
||||
return this.findOne(id);
|
||||
}
|
||||
|
||||
async remove(id: number): Promise<{ message: string }> {
|
||||
// Check if municipality exists
|
||||
await this.findOne(id);
|
||||
|
||||
await this.drizzle.delete(municipalities).where(eq(municipalities.id, id));
|
||||
|
||||
return { message: 'Municipality deleted successfully' };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
|
||||
|
||||
export class CreateParishDto {
|
||||
@ApiProperty({
|
||||
description: 'The name of the parish',
|
||||
example: 'Downtown',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The ID of the municipality this parish belongs to',
|
||||
example: 1,
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
municipalityId: number;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/swagger';
|
||||
import { CreateParishDto } from './create-parish.dto';
|
||||
|
||||
export class UpdateParishDto extends PartialType(CreateParishDto) {}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class Parish {
|
||||
@ApiProperty({
|
||||
description: 'The unique identifier of the parish',
|
||||
example: 1,
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The name of the parish',
|
||||
example: 'Downtown',
|
||||
})
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The ID of the municipality this parish belongs to',
|
||||
example: 1,
|
||||
})
|
||||
municipalityId: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The name of the municipality this parish belongs to',
|
||||
example: 'Los Angeles',
|
||||
})
|
||||
municipalityName?: string | null;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the parish was created',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
created_at?: Date | null;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the parish was last updated',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
updated_at: Date | null;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import { Roles } from '@/common/decorators';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { CreateParishDto } from './dto/create-parish.dto';
|
||||
import { UpdateParishDto } from './dto/update-parish.dto';
|
||||
import { Parish } from './entities/parish.entity';
|
||||
import { ParishesService } from './parishes.service';
|
||||
|
||||
@ApiTags('Parishes')
|
||||
@Controller('configurations/parishes')
|
||||
export class ParishesController {
|
||||
constructor(private readonly parishesService: ParishesService) {}
|
||||
|
||||
@Get()
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get all parishes' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return all parishes',
|
||||
type: [Parish],
|
||||
})
|
||||
findAll() {
|
||||
return this.parishesService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get a parish by id' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return a parish',
|
||||
type: Parish,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Parish not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.parishesService.findOne(id);
|
||||
}
|
||||
|
||||
@Get('municipality/:municipalityId')
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get parishes by municipality id' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Return parishes by municipality',
|
||||
type: [Parish],
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Municipality not found' })
|
||||
findByMunicipality(
|
||||
@Param('municipalityId', ParseIntPipe) municipalityId: number,
|
||||
) {
|
||||
return this.parishesService.findByMunicipality(municipalityId);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Roles('ADMIN')
|
||||
@ApiOperation({ summary: 'Create a new parish' })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'Parish created',
|
||||
type: Parish,
|
||||
})
|
||||
create(@Body() createParishDto: CreateParishDto) {
|
||||
return this.parishesService.create(createParishDto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@Roles('ADMIN')
|
||||
@ApiOperation({ summary: 'Update a parish' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Parish updated',
|
||||
type: Parish,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Parish not found' })
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() updateParishDto: UpdateParishDto,
|
||||
) {
|
||||
return this.parishesService.update(id, updateParishDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@Roles('ADMIN')
|
||||
@ApiOperation({ summary: 'Delete a parish' })
|
||||
@ApiResponse({ status: 200, description: 'Parish deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Parish not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.parishesService.remove(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { DrizzleModule } from '@/database/drizzle.module';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MunicipalitiesModule } from '../municipalities/municipalities.module';
|
||||
import { ParishesController } from './parishes.controller';
|
||||
import { ParishesService } from './parishes.service';
|
||||
|
||||
@Module({
|
||||
imports: [DrizzleModule, MunicipalitiesModule],
|
||||
controllers: [ParishesController],
|
||||
providers: [ParishesService],
|
||||
exports: [ParishesService],
|
||||
})
|
||||
export class ParishesModule {}
|
||||
@@ -0,0 +1,115 @@
|
||||
import { DRIZZLE_PROVIDER } from '@/database/drizzle-provider';
|
||||
import * as schema from '@/database/index';
|
||||
import { municipalities, parishes } from '@/database/schema/general';
|
||||
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { MunicipalitiesService } from '../municipalities/municipalities.service';
|
||||
import { CreateParishDto } from './dto/create-parish.dto';
|
||||
import { UpdateParishDto } from './dto/update-parish.dto';
|
||||
import { Parish } from './entities/parish.entity';
|
||||
|
||||
@Injectable()
|
||||
export class ParishesService {
|
||||
constructor(
|
||||
@Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>,
|
||||
private municipalitiesService: MunicipalitiesService,
|
||||
) {}
|
||||
|
||||
async findAll(): Promise<Parish[]> {
|
||||
return await this.drizzle
|
||||
.select({
|
||||
id: parishes.id,
|
||||
name: parishes.name,
|
||||
municipalityId: parishes.municipalityId,
|
||||
municipalityName: municipalities.name,
|
||||
created_at: parishes.created_at,
|
||||
updated_at: parishes.updated_at,
|
||||
})
|
||||
.from(parishes)
|
||||
.leftJoin(municipalities, eq(parishes.municipalityId, municipalities.id));
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<Parish> {
|
||||
const parish = await this.drizzle
|
||||
.select({
|
||||
id: parishes.id,
|
||||
name: parishes.name,
|
||||
municipalityId: parishes.municipalityId,
|
||||
municipalityName: municipalities.name,
|
||||
created_at: parishes.created_at,
|
||||
updated_at: parishes.updated_at,
|
||||
})
|
||||
.from(parishes)
|
||||
.leftJoin(municipalities, eq(parishes.municipalityId, municipalities.id))
|
||||
.where(eq(parishes.id, id));
|
||||
|
||||
if (parish.length === 0) {
|
||||
throw new HttpException('Parish not found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
return parish[0];
|
||||
}
|
||||
|
||||
async findByMunicipality(municipalityId: number): Promise<Parish[]> {
|
||||
// Verify municipality exists
|
||||
await this.municipalitiesService.findOne(municipalityId);
|
||||
|
||||
return await this.drizzle
|
||||
.select({
|
||||
id: parishes.id,
|
||||
name: parishes.name,
|
||||
municipalityId: parishes.municipalityId,
|
||||
municipalityName: municipalities.name,
|
||||
created_at: parishes.created_at,
|
||||
updated_at: parishes.updated_at,
|
||||
})
|
||||
.from(parishes)
|
||||
.leftJoin(municipalities, eq(parishes.municipalityId, municipalities.id))
|
||||
.where(eq(parishes.municipalityId, municipalityId));
|
||||
}
|
||||
|
||||
async create(createParishDto: CreateParishDto): Promise<Parish> {
|
||||
// Verify municipality exists
|
||||
await this.municipalitiesService.findOne(createParishDto.municipalityId);
|
||||
|
||||
const [parish] = await this.drizzle
|
||||
.insert(parishes)
|
||||
.values({
|
||||
name: createParishDto.name,
|
||||
municipalityId: createParishDto.municipalityId,
|
||||
})
|
||||
.returning();
|
||||
|
||||
return this.findOne(parish.id);
|
||||
}
|
||||
|
||||
async update(id: number, updateParishDto: UpdateParishDto): Promise<Parish> {
|
||||
// Check if parish exists
|
||||
await this.findOne(id);
|
||||
|
||||
// If municipalityId is provided, verify it exists
|
||||
if (updateParishDto.municipalityId) {
|
||||
await this.municipalitiesService.findOne(updateParishDto.municipalityId);
|
||||
}
|
||||
|
||||
await this.drizzle
|
||||
.update(parishes)
|
||||
.set({
|
||||
name: updateParishDto.name,
|
||||
municipalityId: updateParishDto.municipalityId,
|
||||
})
|
||||
.where(eq(parishes.id, id));
|
||||
|
||||
return this.findOne(id);
|
||||
}
|
||||
|
||||
async remove(id: number): Promise<{ message: string }> {
|
||||
// Check if parish exists
|
||||
await this.findOne(id);
|
||||
|
||||
await this.drizzle.delete(parishes).where(eq(parishes.id, id));
|
||||
|
||||
return { message: 'Parish deleted successfully' };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
export class CreateStateDto {
|
||||
@ApiProperty({
|
||||
description: 'The name of the state',
|
||||
example: 'California',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
name: string;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/swagger';
|
||||
import { CreateStateDto } from './create-state.dto';
|
||||
|
||||
export class UpdateStateDto extends PartialType(CreateStateDto) {}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class State {
|
||||
@ApiProperty({
|
||||
description: 'The unique identifier of the state',
|
||||
example: 1,
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The name of the state',
|
||||
example: 'California',
|
||||
})
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the state was created',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
created_at?: Date | null;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'The date when the state was last updated',
|
||||
example: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
updated_at?: Date | null;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Roles } from '@/common/decorators';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { UpdateStateDto } from './dto//update-state.dto';
|
||||
import { CreateStateDto } from './dto/create-state.dto';
|
||||
import { State } from './entities/state.entity';
|
||||
import { StatesService } from './states.service';
|
||||
|
||||
@ApiTags('States')
|
||||
@Controller('configurations/states')
|
||||
export class StatesController {
|
||||
constructor(private readonly statesService: StatesService) {}
|
||||
|
||||
@Get()
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get all states' })
|
||||
@ApiResponse({ status: 200, description: 'Return all states', type: [State] })
|
||||
findAll() {
|
||||
return this.statesService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@Roles('admin', 'user')
|
||||
@ApiOperation({ summary: 'Get a state by id' })
|
||||
@ApiResponse({ status: 200, description: 'Return a state', type: State })
|
||||
@ApiResponse({ status: 404, description: 'State not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.statesService.findOne(id);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Roles('admin')
|
||||
@ApiOperation({ summary: 'Create a new state' })
|
||||
@ApiResponse({ status: 201, description: 'State created', type: State })
|
||||
create(@Body() createStateDto: CreateStateDto) {
|
||||
return this.statesService.create(createStateDto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@Roles('admin')
|
||||
@ApiOperation({ summary: 'Update a state' })
|
||||
@ApiResponse({ status: 200, description: 'State updated', type: State })
|
||||
@ApiResponse({ status: 404, description: 'State not found' })
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() updateStateDto: UpdateStateDto,
|
||||
) {
|
||||
return this.statesService.update(id, updateStateDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@Roles('admin')
|
||||
@ApiOperation({ summary: 'Delete a state' })
|
||||
@ApiResponse({ status: 200, description: 'State deleted' })
|
||||
@ApiResponse({ status: 404, description: 'State not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.statesService.remove(id);
|
||||
}
|
||||
}
|
||||
12
apps/api/src/features/configurations/states/states.module.ts
Normal file
12
apps/api/src/features/configurations/states/states.module.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { DrizzleModule } from '@/database/drizzle.module';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { StatesController } from './states.controller';
|
||||
import { StatesService } from './states.service';
|
||||
|
||||
@Module({
|
||||
imports: [DrizzleModule],
|
||||
controllers: [StatesController],
|
||||
providers: [StatesService],
|
||||
exports: [StatesService],
|
||||
})
|
||||
export class StatesModule {}
|
||||
@@ -0,0 +1,67 @@
|
||||
import { DRIZZLE_PROVIDER } from '@/database/drizzle-provider';
|
||||
import * as schema from '@/database/index';
|
||||
import { states } from '@/database/schema/general';
|
||||
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { CreateStateDto } from './dto/create-state.dto';
|
||||
import { UpdateStateDto } from './dto/update-state.dto';
|
||||
import { State } from './entities/state.entity';
|
||||
|
||||
@Injectable()
|
||||
export class StatesService {
|
||||
constructor(
|
||||
@Inject(DRIZZLE_PROVIDER) private drizzle: NodePgDatabase<typeof schema>,
|
||||
) {}
|
||||
|
||||
async findAll(): Promise<State[]> {
|
||||
return await this.drizzle.select().from(states);
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<State> {
|
||||
const state = await this.drizzle
|
||||
.select()
|
||||
.from(states)
|
||||
.where(eq(states.id, id));
|
||||
|
||||
if (state.length === 0) {
|
||||
throw new HttpException('State not found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
return state[0];
|
||||
}
|
||||
|
||||
async create(createStateDto: CreateStateDto): Promise<State> {
|
||||
const [state] = await this.drizzle
|
||||
.insert(states)
|
||||
.values({
|
||||
name: createStateDto.name,
|
||||
})
|
||||
.returning();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
async update(id: number, updateStateDto: UpdateStateDto): Promise<State> {
|
||||
// Check if state exists
|
||||
await this.findOne(id);
|
||||
|
||||
await this.drizzle
|
||||
.update(states)
|
||||
.set({
|
||||
name: updateStateDto.name,
|
||||
})
|
||||
.where(eq(states.id, id));
|
||||
|
||||
return this.findOne(id);
|
||||
}
|
||||
|
||||
async remove(id: number): Promise<{ message: string }> {
|
||||
// Check if state exists
|
||||
await this.findOne(id);
|
||||
|
||||
await this.drizzle.delete(states).where(eq(states.id, id));
|
||||
|
||||
return { message: 'State deleted successfully' };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user