diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma new file mode 100644 index 0000000..d7ed6f1 --- /dev/null +++ b/backend/prisma/schema.prisma @@ -0,0 +1,183 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +enum EquipmentType { + // Will be populated based on actual equipment types + UNKNOWN +} + +enum EnumPeriodicityTO { + // Will be populated based on actual periodicity values + UNKNOWN +} + +enum EquipmentStatus { + // Will be populated based on actual status values + UNKNOWN +} + +enum Role { + // Will be populated based on actual role values + UNKNOWN +} + +enum CategoryPart { + // Will be populated based on actual category values + UNKNOWN +} + +enum RepairKind { + // Will be populated based on actual repair kind values + UNKNOWN +} + +enum RepairOrderStatus { + Draft + // Will be populated with other status values + UNKNOWN +} + +model Equipment { + id String @id @default(uuid()) + name String + serialNumber String + inventoryNumber String @unique + equipmentType EquipmentType + dateOfInspection DateTime? @db.Date + periodicityTO EnumPeriodicityTO + location String? + status EquipmentStatus + commissionedAt DateTime? @db.Date + totalEngineHours Decimal? + engineHoursSinceLastRepair Decimal? + lastRepairAt DateTime? @db.Date + notes String? + + // Relations + repairOrders RepairOrder[] + changeEquipmentStatuses ChangeEquipmentStatus[] + consumptionRegistrations ConsumptionRegistration[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Employee { + code String @id + fullName String + role Role + position String + price Float? + phoneNumber Float? + + // Self-referential relation for boss/subordinates + bossCode String? + boss Employee? @relation("EmployeeHierarchy", fields: [bossCode], references: [code]) + subordinates Employee[] @relation("EmployeeHierarchy") + + // Relations + confirmationDocuments ConfirmationDocument[] + categoryResources CategoryResource[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Part { + id String @id @default(uuid()) + name String + categories CategoryPart? + price Float? + description String? + serialNumber String? + + // Relations + categoryResources CategoryResource[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model CategoryResource { + id String @id @default(uuid()) + + // Relations + partId String? + part Part? @relation(fields: [partId], references: [id]) + employeeCode String? + employee Employee? @relation(fields: [employeeCode], references: [code]) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model RepairOrder { + id String @id @default(uuid()) + number String @unique + date DateTime @db.Date + equipmentId String + equipment Equipment @relation(fields: [equipmentId], references: [id]) + repairKind RepairKind + status RepairOrderStatus @default(Draft) + plannedAt DateTime @db.Date + startedAt DateTime? @db.Date + completedAt DateTime? @db.Date + contractor String? + engineHoursAtRepair Decimal? + description String? + notes String? + confirmed Boolean? + + // Relations + confirmationDocuments ConfirmationDocument[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model ChangeEquipmentStatus { + id String @id @default(uuid()) + equipmentId String + equipment Equipment @relation(fields: [equipmentId], references: [id]) + newStatus EquipmentStatus + number String? + comment String? + date DateTime @db.Date + responsible String? + document String? // File path or reference + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model ConfirmationDocument { + id String @id @default(uuid()) + number String? + date DateTime @db.Date + managerCode String? + manager Employee? @relation(fields: [managerCode], references: [code]) + orderId String + order RepairOrder @relation(fields: [orderId], references: [id]) + confirmed Boolean? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model ConsumptionRegistration { + id String @id @default(uuid()) + number String? + date DateTime @db.Date + equipmentId String + equipment Equipment @relation(fields: [equipmentId], references: [id]) + totalEngineHours Decimal? + fuelConsumption Decimal? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts new file mode 100644 index 0000000..59f1e14 --- /dev/null +++ b/backend/src/app.module.ts @@ -0,0 +1,27 @@ +import { Module } from '@nestjs/common'; +import { AuthModule } from './auth/auth.module'; +import { PrismaService } from './prisma/prisma.service'; +import { EquipmentModule } from './equipment/equipment.module'; +import { EmployeeModule } from './employee/employee.module'; +import { PartModule } from './part/part.module'; +import { CategoryResourceModule } from './category-resource/category-resource.module'; +import { RepairOrderModule } from './repair-order/repair-order.module'; +import { ChangeEquipmentStatusModule } from './change-equipment-status/change-equipment-status.module'; +import { ConfirmationDocumentModule } from './confirmation-document/confirmation-document.module'; +import { ConsumptionRegistrationModule } from './consumption-registration/consumption-registration.module'; + +@Module({ + imports: [ + AuthModule, + EquipmentModule, + EmployeeModule, + PartModule, + CategoryResourceModule, + RepairOrderModule, + ChangeEquipmentStatusModule, + ConfirmationDocumentModule, + ConsumptionRegistrationModule, + ], + providers: [PrismaService], +}) +export class AppModule {} \ No newline at end of file diff --git a/backend/src/category-resource/category-resource.controller.ts b/backend/src/category-resource/category-resource.controller.ts new file mode 100644 index 0000000..8076bfa --- /dev/null +++ b/backend/src/category-resource/category-resource.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { CategoryResourceService } from './category-resource.service'; +import { CreateCategoryResourceDto } from './dto/create-category-resource.dto'; +import { UpdateCategoryResourceDto } from './dto/update-category-resource.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('category-resource') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('category-resource') +export class CategoryResourceController { + constructor(private readonly categoryResourceService: CategoryResourceService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.categoryResourceService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + @ApiParam({ name: 'id', type: String }) + findOne(@Param('id') id: string) { + return this.categoryResourceService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateCategoryResourceDto) { + return this.categoryResourceService.create(dto); + } + + @Patch(':id') + @ApiParam({ name: 'id', type: String }) + update(@Param('id') id: string, @Body() dto: UpdateCategoryResourceDto) { + return this.categoryResourceService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + @ApiParam({ name: 'id', type: String }) + remove(@Param('id') id: string) { + return this.categoryResourceService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/category-resource/category-resource.module.ts b/backend/src/category-resource/category-resource.module.ts new file mode 100644 index 0000000..093bd07 --- /dev/null +++ b/backend/src/category-resource/category-resource.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { CategoryResourceService } from './category-resource.service'; +import { CategoryResourceController } from './category-resource.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [CategoryResourceController], + providers: [CategoryResourceService, PrismaService], +}) +export class CategoryResourceModule {} \ No newline at end of file diff --git a/backend/src/category-resource/category-resource.service.ts b/backend/src/category-resource/category-resource.service.ts new file mode 100644 index 0000000..b0460fe --- /dev/null +++ b/backend/src/category-resource/category-resource.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { CategoryResource, Prisma } from '@prisma/client'; + +@Injectable() +export class CategoryResourceService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.CategoryResourceWhereInput; + orderBy?: Prisma.CategoryResourceOrderByWithRelationInput; + }): Promise<{ data: CategoryResource[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.categoryResource.findMany({ skip, take, where, orderBy }), + this.prisma.categoryResource.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.CategoryResourceWhereUniqueInput): Promise { + return this.prisma.categoryResource.findUnique({ where }); + } + + async create(data: Prisma.CategoryResourceCreateInput): Promise { + return this.prisma.categoryResource.create({ data }); + } + + async update(params: { + where: Prisma.CategoryResourceWhereUniqueInput; + data: Prisma.CategoryResourceUpdateInput; + }): Promise { + return this.prisma.categoryResource.update(params); + } + + async remove(where: Prisma.CategoryResourceWhereUniqueInput): Promise { + return this.prisma.categoryResource.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/category-resource/dto/create-category-resource.dto.ts b/backend/src/category-resource/dto/create-category-resource.dto.ts new file mode 100644 index 0000000..abb6f44 --- /dev/null +++ b/backend/src/category-resource/dto/create-category-resource.dto.ts @@ -0,0 +1,14 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsString, IsOptional } from 'class-validator'; + +export class CreateCategoryResourceDto { + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + partId?: string; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + employeeCode?: string; +} \ No newline at end of file diff --git a/backend/src/category-resource/dto/update-category-resource.dto.ts b/backend/src/category-resource/dto/update-category-resource.dto.ts new file mode 100644 index 0000000..fb0d3e0 --- /dev/null +++ b/backend/src/category-resource/dto/update-category-resource.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateCategoryResourceDto } from './create-category-resource.dto'; + +export class UpdateCategoryResourceDto extends PartialType(CreateCategoryResourceDto) {} \ No newline at end of file diff --git a/backend/src/change-equipment-status/change-equipment-status.controller.ts b/backend/src/change-equipment-status/change-equipment-status.controller.ts new file mode 100644 index 0000000..deb97a4 --- /dev/null +++ b/backend/src/change-equipment-status/change-equipment-status.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { ChangeEquipmentStatusService } from './change-equipment-status.service'; +import { CreateChangeEquipmentStatusDto } from './dto/create-change-equipment-status.dto'; +import { UpdateChangeEquipmentStatusDto } from './dto/update-change-equipment-status.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('change-equipment-status') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('change-equipment-status') +export class ChangeEquipmentStatusController { + constructor(private readonly changeEquipmentStatusService: ChangeEquipmentStatusService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.changeEquipmentStatusService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + @ApiParam({ name: 'id', type: String }) + findOne(@Param('id') id: string) { + return this.changeEquipmentStatusService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateChangeEquipmentStatusDto) { + return this.changeEquipmentStatusService.create(dto); + } + + @Patch(':id') + @ApiParam({ name: 'id', type: String }) + update(@Param('id') id: string, @Body() dto: UpdateChangeEquipmentStatusDto) { + return this.changeEquipmentStatusService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + @ApiParam({ name: 'id', type: String }) + remove(@Param('id') id: string) { + return this.changeEquipmentStatusService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/change-equipment-status/change-equipment-status.module.ts b/backend/src/change-equipment-status/change-equipment-status.module.ts new file mode 100644 index 0000000..27bf136 --- /dev/null +++ b/backend/src/change-equipment-status/change-equipment-status.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ChangeEquipmentStatusService } from './change-equipment-status.service'; +import { ChangeEquipmentStatusController } from './change-equipment-status.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [ChangeEquipmentStatusController], + providers: [ChangeEquipmentStatusService, PrismaService], +}) +export class ChangeEquipmentStatusModule {} \ No newline at end of file diff --git a/backend/src/change-equipment-status/change-equipment-status.service.ts b/backend/src/change-equipment-status/change-equipment-status.service.ts new file mode 100644 index 0000000..972f1b2 --- /dev/null +++ b/backend/src/change-equipment-status/change-equipment-status.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { ChangeEquipmentStatus, Prisma } from '@prisma/client'; + +@Injectable() +export class ChangeEquipmentStatusService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.ChangeEquipmentStatusWhereInput; + orderBy?: Prisma.ChangeEquipmentStatusOrderByWithRelationInput; + }): Promise<{ data: ChangeEquipmentStatus[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.changeEquipmentStatus.findMany({ skip, take, where, orderBy }), + this.prisma.changeEquipmentStatus.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.ChangeEquipmentStatusWhereUniqueInput): Promise { + return this.prisma.changeEquipmentStatus.findUnique({ where }); + } + + async create(data: Prisma.ChangeEquipmentStatusCreateInput): Promise { + return this.prisma.changeEquipmentStatus.create({ data }); + } + + async update(params: { + where: Prisma.ChangeEquipmentStatusWhereUniqueInput; + data: Prisma.ChangeEquipmentStatusUpdateInput; + }): Promise { + return this.prisma.changeEquipmentStatus.update(params); + } + + async remove(where: Prisma.ChangeEquipmentStatusWhereUniqueInput): Promise { + return this.prisma.changeEquipmentStatus.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts b/backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts new file mode 100644 index 0000000..b613a06 --- /dev/null +++ b/backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts @@ -0,0 +1,40 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional } from 'class-validator'; +import { EquipmentStatus } from '@prisma/client'; + +export class CreateChangeEquipmentStatusDto { + @ApiProperty() + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ enum: EquipmentStatus, enumName: 'EquipmentStatus' }) + @IsEnum(EquipmentStatus) + newStatus: EquipmentStatus; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + comment?: string; + + @ApiProperty() + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + responsible?: string; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + document?: string; +} \ No newline at end of file diff --git a/backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts b/backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts new file mode 100644 index 0000000..662bc07 --- /dev/null +++ b/backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateChangeEquipmentStatusDto } from './create-change-equipment-status.dto'; + +export class UpdateChangeEquipmentStatusDto extends PartialType(CreateChangeEquipmentStatusDto) {} \ No newline at end of file diff --git a/backend/src/confirmation-document/confirmation-document.controller.ts b/backend/src/confirmation-document/confirmation-document.controller.ts new file mode 100644 index 0000000..d724620 --- /dev/null +++ b/backend/src/confirmation-document/confirmation-document.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { ConfirmationDocumentService } from './confirmation-document.service'; +import { CreateConfirmationDocumentDto } from './dto/create-confirmation-document.dto'; +import { UpdateConfirmationDocumentDto } from './dto/update-confirmation-document.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('confirmation-document') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('confirmation-document') +export class ConfirmationDocumentController { + constructor(private readonly confirmationDocumentService: ConfirmationDocumentService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.confirmationDocumentService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + @ApiParam({ name: 'id', type: String }) + findOne(@Param('id') id: string) { + return this.confirmationDocumentService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateConfirmationDocumentDto) { + return this.confirmationDocumentService.create(dto); + } + + @Patch(':id') + @ApiParam({ name: 'id', type: String }) + update(@Param('id') id: string, @Body() dto: UpdateConfirmationDocumentDto) { + return this.confirmationDocumentService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + @ApiParam({ name: 'id', type: String }) + remove(@Param('id') id: string) { + return this.confirmationDocumentService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/confirmation-document/confirmation-document.module.ts b/backend/src/confirmation-document/confirmation-document.module.ts new file mode 100644 index 0000000..e594c3d --- /dev/null +++ b/backend/src/confirmation-document/confirmation-document.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ConfirmationDocumentService } from './confirmation-document.service'; +import { ConfirmationDocumentController } from './confirmation-document.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [ConfirmationDocumentController], + providers: [ConfirmationDocumentService, PrismaService], +}) +export class ConfirmationDocumentModule {} \ No newline at end of file diff --git a/backend/src/confirmation-document/confirmation-document.service.ts b/backend/src/confirmation-document/confirmation-document.service.ts new file mode 100644 index 0000000..6d4029e --- /dev/null +++ b/backend/src/confirmation-document/confirmation-document.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { ConfirmationDocument, Prisma } from '@prisma/client'; + +@Injectable() +export class ConfirmationDocumentService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.ConfirmationDocumentWhereInput; + orderBy?: Prisma.ConfirmationDocumentOrderByWithRelationInput; + }): Promise<{ data: ConfirmationDocument[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.confirmationDocument.findMany({ skip, take, where, orderBy }), + this.prisma.confirmationDocument.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.ConfirmationDocumentWhereUniqueInput): Promise { + return this.prisma.confirmationDocument.findUnique({ where }); + } + + async create(data: Prisma.ConfirmationDocumentCreateInput): Promise { + return this.prisma.confirmationDocument.create({ data }); + } + + async update(params: { + where: Prisma.ConfirmationDocumentWhereUniqueInput; + data: Prisma.ConfirmationDocumentUpdateInput; + }): Promise { + return this.prisma.confirmationDocument.update(params); + } + + async remove(where: Prisma.ConfirmationDocumentWhereUniqueInput): Promise { + return this.prisma.confirmationDocument.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/confirmation-document/dto/create-confirmation-document.dto.ts b/backend/src/confirmation-document/dto/create-confirmation-document.dto.ts new file mode 100644 index 0000000..ff37f60 --- /dev/null +++ b/backend/src/confirmation-document/dto/create-confirmation-document.dto.ts @@ -0,0 +1,30 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsISO8601, IsOptional, IsBoolean } from 'class-validator'; + +export class CreateConfirmationDocumentDto { + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty() + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + managerCode?: string; + + @ApiProperty() + @IsString() + @IsNotEmpty() + orderId: string; + + @ApiProperty({ required: false }) + @IsBoolean() + @IsOptional() + confirmed?: boolean; +} \ No newline at end of file diff --git a/backend/src/confirmation-document/dto/update-confirmation-document.dto.ts b/backend/src/confirmation-document/dto/update-confirmation-document.dto.ts new file mode 100644 index 0000000..0e9a805 --- /dev/null +++ b/backend/src/confirmation-document/dto/update-confirmation-document.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateConfirmationDocumentDto } from './create-confirmation-document.dto'; + +export class UpdateConfirmationDocumentDto extends PartialType(CreateConfirmationDocumentDto) {} \ No newline at end of file diff --git a/backend/src/consumption-registration/consumption-registration.controller.ts b/backend/src/consumption-registration/consumption-registration.controller.ts new file mode 100644 index 0000000..8ceceef --- /dev/null +++ b/backend/src/consumption-registration/consumption-registration.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { ConsumptionRegistrationService } from './consumption-registration.service'; +import { CreateConsumptionRegistrationDto } from './dto/create-consumption-registration.dto'; +import { UpdateConsumptionRegistrationDto } from './dto/update-consumption-registration.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('consumption-registration') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('consumption-registration') +export class ConsumptionRegistrationController { + constructor(private readonly consumptionRegistrationService: ConsumptionRegistrationService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.consumptionRegistrationService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + @ApiParam({ name: 'id', type: String }) + findOne(@Param('id') id: string) { + return this.consumptionRegistrationService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateConsumptionRegistrationDto) { + return this.consumptionRegistrationService.create(dto); + } + + @Patch(':id') + @ApiParam({ name: 'id', type: String }) + update(@Param('id') id: string, @Body() dto: UpdateConsumptionRegistrationDto) { + return this.consumptionRegistrationService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + @ApiParam({ name: 'id', type: String }) + remove(@Param('id') id: string) { + return this.consumptionRegistrationService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/consumption-registration/consumption-registration.module.ts b/backend/src/consumption-registration/consumption-registration.module.ts new file mode 100644 index 0000000..f2d1d67 --- /dev/null +++ b/backend/src/consumption-registration/consumption-registration.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ConsumptionRegistrationService } from './consumption-registration.service'; +import { ConsumptionRegistrationController } from './consumption-registration.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [ConsumptionRegistrationController], + providers: [ConsumptionRegistrationService, PrismaService], +}) +export class ConsumptionRegistrationModule {} \ No newline at end of file diff --git a/backend/src/consumption-registration/consumption-registration.service.ts b/backend/src/consumption-registration/consumption-registration.service.ts new file mode 100644 index 0000000..f54fa7d --- /dev/null +++ b/backend/src/consumption-registration/consumption-registration.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { ConsumptionRegistration, Prisma } from '@prisma/client'; + +@Injectable() +export class ConsumptionRegistrationService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.ConsumptionRegistrationWhereInput; + orderBy?: Prisma.ConsumptionRegistrationOrderByWithRelationInput; + }): Promise<{ data: ConsumptionRegistration[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.consumptionRegistration.findMany({ skip, take, where, orderBy }), + this.prisma.consumptionRegistration.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.ConsumptionRegistrationWhereUniqueInput): Promise { + return this.prisma.consumptionRegistration.findUnique({ where }); + } + + async create(data: Prisma.ConsumptionRegistrationCreateInput): Promise { + return this.prisma.consumptionRegistration.create({ data }); + } + + async update(params: { + where: Prisma.ConsumptionRegistrationWhereUniqueInput; + data: Prisma.ConsumptionRegistrationUpdateInput; + }): Promise { + return this.prisma.consumptionRegistration.update(params); + } + + async remove(where: Prisma.ConsumptionRegistrationWhereUniqueInput): Promise { + return this.prisma.consumptionRegistration.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/consumption-registration/dto/create-consumption-registration.dto.ts b/backend/src/consumption-registration/dto/create-consumption-registration.dto.ts new file mode 100644 index 0000000..6fa0a58 --- /dev/null +++ b/backend/src/consumption-registration/dto/create-consumption-registration.dto.ts @@ -0,0 +1,32 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsISO8601, IsOptional, IsNumber } from 'class-validator'; + +export class CreateConsumptionRegistrationDto { + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty() + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty() + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + totalEngineHours?: number; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + fuelConsumption?: number; +} \ No newline at end of file diff --git a/backend/src/consumption-registration/dto/update-consumption-registration.dto.ts b/backend/src/consumption-registration/dto/update-consumption-registration.dto.ts new file mode 100644 index 0000000..e03517a --- /dev/null +++ b/backend/src/consumption-registration/dto/update-consumption-registration.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateConsumptionRegistrationDto } from './create-consumption-registration.dto'; + +export class UpdateConsumptionRegistrationDto extends PartialType(CreateConsumptionRegistrationDto) {} \ No newline at end of file diff --git a/backend/src/employee/dto/create-employee.dto.ts b/backend/src/employee/dto/create-employee.dto.ts new file mode 100644 index 0000000..12da577 --- /dev/null +++ b/backend/src/employee/dto/create-employee.dto.ts @@ -0,0 +1,42 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsOptional, IsNumber } from 'class-validator'; +import { Role } from '@prisma/client'; + +export class CreateEmployeeDto { + @ApiProperty() + @IsString() + @IsNotEmpty() + code: string; + + @ApiProperty() + @IsString() + @IsNotEmpty() + fullName: string; + + @ApiProperty({ enum: Role, enumName: 'Role' }) + @IsEnum(Role) + role: Role; + + @ApiProperty() + @IsString() + @IsNotEmpty() + position: string; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + bossCode?: string; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + price?: number; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + phoneNumber?: number; +} \ No newline at end of file diff --git a/backend/src/employee/dto/update-employee.dto.ts b/backend/src/employee/dto/update-employee.dto.ts new file mode 100644 index 0000000..7180917 --- /dev/null +++ b/backend/src/employee/dto/update-employee.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateEmployeeDto } from './create-employee.dto'; + +export class UpdateEmployeeDto extends PartialType(CreateEmployeeDto) {} \ No newline at end of file diff --git a/backend/src/employee/employee.controller.ts b/backend/src/employee/employee.controller.ts new file mode 100644 index 0000000..1e15022 --- /dev/null +++ b/backend/src/employee/employee.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { EmployeeService } from './employee.service'; +import { CreateEmployeeDto } from './dto/create-employee.dto'; +import { UpdateEmployeeDto } from './dto/update-employee.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('employee') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('employee') +export class EmployeeController { + constructor(private readonly employeeService: EmployeeService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.employeeService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':code') + @ApiParam({ name: 'code', type: String }) + findOne(@Param('code') code: string) { + return this.employeeService.findOne({ code }); + } + + @Post() + create(@Body() dto: CreateEmployeeDto) { + return this.employeeService.create(dto); + } + + @Patch(':code') + @ApiParam({ name: 'code', type: String }) + update(@Param('code') code: string, @Body() dto: UpdateEmployeeDto) { + return this.employeeService.update({ where: { code }, data: dto }); + } + + @Delete(':code') + @ApiParam({ name: 'code', type: String }) + remove(@Param('code') code: string) { + return this.employeeService.remove({ code }); + } +} \ No newline at end of file diff --git a/backend/src/employee/employee.module.ts b/backend/src/employee/employee.module.ts new file mode 100644 index 0000000..d5b87d0 --- /dev/null +++ b/backend/src/employee/employee.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { EmployeeService } from './employee.service'; +import { EmployeeController } from './employee.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [EmployeeController], + providers: [EmployeeService, PrismaService], +}) +export class EmployeeModule {} \ No newline at end of file diff --git a/backend/src/employee/employee.service.ts b/backend/src/employee/employee.service.ts new file mode 100644 index 0000000..59b71e3 --- /dev/null +++ b/backend/src/employee/employee.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { Employee, Prisma } from '@prisma/client'; + +@Injectable() +export class EmployeeService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.EmployeeWhereInput; + orderBy?: Prisma.EmployeeOrderByWithRelationInput; + }): Promise<{ data: Employee[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.employee.findMany({ skip, take, where, orderBy }), + this.prisma.employee.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.EmployeeWhereUniqueInput): Promise { + return this.prisma.employee.findUnique({ where }); + } + + async create(data: Prisma.EmployeeCreateInput): Promise { + return this.prisma.employee.create({ data }); + } + + async update(params: { + where: Prisma.EmployeeWhereUniqueInput; + data: Prisma.EmployeeUpdateInput; + }): Promise { + return this.prisma.employee.update(params); + } + + async remove(where: Prisma.EmployeeWhereUniqueInput): Promise { + return this.prisma.employee.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/equipment/dto/create-equipment.dto.ts b/backend/src/equipment/dto/create-equipment.dto.ts new file mode 100644 index 0000000..f8bc5bd --- /dev/null +++ b/backend/src/equipment/dto/create-equipment.dto.ts @@ -0,0 +1,73 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional, IsNumber } from 'class-validator'; +import { EquipmentType, EnumPeriodicityTO, EquipmentStatus } from '@prisma/client'; + +export class CreateEquipmentDto { + @ApiProperty() + @IsString() + @IsNotEmpty() + name: string; + + @ApiProperty() + @IsString() + @IsNotEmpty() + serialNumber: string; + + @ApiProperty() + @IsString() + @IsNotEmpty() + inventoryNumber: string; + + @ApiProperty({ enum: EquipmentType, enumName: 'EquipmentType' }) + @IsEnum(EquipmentType) + equipmentType: EquipmentType; + + @ApiProperty({ required: false }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + dateOfInspection?: Date; + + @ApiProperty({ enum: EnumPeriodicityTO, enumName: 'EnumPeriodicityTO' }) + @IsEnum(EnumPeriodicityTO) + periodicityTO: EnumPeriodicityTO; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + location?: string; + + @ApiProperty({ enum: EquipmentStatus, enumName: 'EquipmentStatus' }) + @IsEnum(EquipmentStatus) + status: EquipmentStatus; + + @ApiProperty({ required: false }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + commissionedAt?: Date; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + totalEngineHours?: number; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + engineHoursSinceLastRepair?: number; + + @ApiProperty({ required: false }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + lastRepairAt?: Date; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + notes?: string; +} \ No newline at end of file diff --git a/backend/src/equipment/dto/update-equipment.dto.ts b/backend/src/equipment/dto/update-equipment.dto.ts new file mode 100644 index 0000000..b6c9a4b --- /dev/null +++ b/backend/src/equipment/dto/update-equipment.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateEquipmentDto } from './create-equipment.dto'; + +export class UpdateEquipmentDto extends PartialType(CreateEquipmentDto) {} \ No newline at end of file diff --git a/backend/src/equipment/equipment.controller.ts b/backend/src/equipment/equipment.controller.ts new file mode 100644 index 0000000..e118b39 --- /dev/null +++ b/backend/src/equipment/equipment.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { EquipmentService } from './equipment.service'; +import { CreateEquipmentDto } from './dto/create-equipment.dto'; +import { UpdateEquipmentDto } from './dto/update-equipment.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('equipment') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('equipment') +export class EquipmentController { + constructor(private readonly equipmentService: EquipmentService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.equipmentService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + @ApiParam({ name: 'id', type: String }) + findOne(@Param('id') id: string) { + return this.equipmentService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateEquipmentDto) { + return this.equipmentService.create(dto); + } + + @Patch(':id') + @ApiParam({ name: 'id', type: String }) + update(@Param('id') id: string, @Body() dto: UpdateEquipmentDto) { + return this.equipmentService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + @ApiParam({ name: 'id', type: String }) + remove(@Param('id') id: string) { + return this.equipmentService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/equipment/equipment.module.ts b/backend/src/equipment/equipment.module.ts new file mode 100644 index 0000000..4b324f7 --- /dev/null +++ b/backend/src/equipment/equipment.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { EquipmentService } from './equipment.service'; +import { EquipmentController } from './equipment.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [EquipmentController], + providers: [EquipmentService, PrismaService], +}) +export class EquipmentModule {} \ No newline at end of file diff --git a/backend/src/equipment/equipment.service.ts b/backend/src/equipment/equipment.service.ts new file mode 100644 index 0000000..26098ec --- /dev/null +++ b/backend/src/equipment/equipment.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { Equipment, Prisma } from '@prisma/client'; + +@Injectable() +export class EquipmentService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.EquipmentWhereInput; + orderBy?: Prisma.EquipmentOrderByWithRelationInput; + }): Promise<{ data: Equipment[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.equipment.findMany({ skip, take, where, orderBy }), + this.prisma.equipment.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.EquipmentWhereUniqueInput): Promise { + return this.prisma.equipment.findUnique({ where }); + } + + async create(data: Prisma.EquipmentCreateInput): Promise { + return this.prisma.equipment.create({ data }); + } + + async update(params: { + where: Prisma.EquipmentWhereUniqueInput; + data: Prisma.EquipmentUpdateInput; + }): Promise { + return this.prisma.equipment.update(params); + } + + async remove(where: Prisma.EquipmentWhereUniqueInput): Promise { + return this.prisma.equipment.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/part/dto/create-part.dto.ts b/backend/src/part/dto/create-part.dto.ts new file mode 100644 index 0000000..d822d38 --- /dev/null +++ b/backend/src/part/dto/create-part.dto.ts @@ -0,0 +1,32 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsOptional, IsNumber } from 'class-validator'; +import { CategoryPart } from '@prisma/client'; + +export class CreatePartDto { + @ApiProperty() + @IsString() + @IsNotEmpty() + name: string; + + @ApiProperty({ enum: CategoryPart, enumName: 'CategoryPart', required: false }) + @IsEnum(CategoryPart) + @IsOptional() + categories?: CategoryPart; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + price?: number; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + description?: string; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + serialNumber?: string; +} \ No newline at end of file diff --git a/backend/src/part/dto/update-part.dto.ts b/backend/src/part/dto/update-part.dto.ts new file mode 100644 index 0000000..bba96fe --- /dev/null +++ b/backend/src/part/dto/update-part.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreatePartDto } from './create-part.dto'; + +export class UpdatePartDto extends PartialType(CreatePartDto) {} \ No newline at end of file diff --git a/backend/src/part/part.controller.ts b/backend/src/part/part.controller.ts new file mode 100644 index 0000000..0349431 --- /dev/null +++ b/backend/src/part/part.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { PartService } from './part.service'; +import { CreatePartDto } from './dto/create-part.dto'; +import { UpdatePartDto } from './dto/update-part.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('part') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('part') +export class PartController { + constructor(private readonly partService: PartService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.partService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + @ApiParam({ name: 'id', type: String }) + findOne(@Param('id') id: string) { + return this.partService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreatePartDto) { + return this.partService.create(dto); + } + + @Patch(':id') + @ApiParam({ name: 'id', type: String }) + update(@Param('id') id: string, @Body() dto: UpdatePartDto) { + return this.partService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + @ApiParam({ name: 'id', type: String }) + remove(@Param('id') id: string) { + return this.partService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/part/part.module.ts b/backend/src/part/part.module.ts new file mode 100644 index 0000000..94f417f --- /dev/null +++ b/backend/src/part/part.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { PartService } from './part.service'; +import { PartController } from './part.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [PartController], + providers: [PartService, PrismaService], +}) +export class PartModule {} \ No newline at end of file diff --git a/backend/src/part/part.service.ts b/backend/src/part/part.service.ts new file mode 100644 index 0000000..7c08f11 --- /dev/null +++ b/backend/src/part/part.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { Part, Prisma } from '@prisma/client'; + +@Injectable() +export class PartService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.PartWhereInput; + orderBy?: Prisma.PartOrderByWithRelationInput; + }): Promise<{ data: Part[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.part.findMany({ skip, take, where, orderBy }), + this.prisma.part.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.PartWhereUniqueInput): Promise { + return this.prisma.part.findUnique({ where }); + } + + async create(data: Prisma.PartCreateInput): Promise { + return this.prisma.part.create({ data }); + } + + async update(params: { + where: Prisma.PartWhereUniqueInput; + data: Prisma.PartUpdateInput; + }): Promise { + return this.prisma.part.update(params); + } + + async remove(where: Prisma.PartWhereUniqueInput): Promise { + return this.prisma.part.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/repair-order/dto/create-repair-order.dto.ts b/backend/src/repair-order/dto/create-repair-order.dto.ts new file mode 100644 index 0000000..2d14ade --- /dev/null +++ b/backend/src/repair-order/dto/create-repair-order.dto.ts @@ -0,0 +1,73 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional, IsBoolean, IsNumber } from 'class-validator'; +import { RepairKind, RepairOrderStatus } from '@prisma/client'; + +export class CreateRepairOrderDto { + @ApiProperty() + @IsString() + @IsNotEmpty() + number: string; + + @ApiProperty() + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty() + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ enum: RepairKind, enumName: 'RepairKind' }) + @IsEnum(RepairKind) + repairKind: RepairKind; + + @ApiProperty({ enum: RepairOrderStatus, enumName: 'RepairOrderStatus', required: false }) + @IsEnum(RepairOrderStatus) + @IsOptional() + status?: RepairOrderStatus; + + @ApiProperty() + @IsISO8601() + @Type(() => Date) + plannedAt: Date; + + @ApiProperty({ required: false }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + startedAt?: Date; + + @ApiProperty({ required: false }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + completedAt?: Date; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + contractor?: string; + + @ApiProperty({ required: false }) + @IsNumber() + @IsOptional() + @Type(() => Number) + engineHoursAtRepair?: number; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + description?: string; + + @ApiProperty({ required: false }) + @IsString() + @IsOptional() + notes?: string; + + @ApiProperty({ required: false }) + @IsBoolean() + @IsOptional() + confirmed?: boolean; +} \ No newline at end of file diff --git a/backend/src/repair-order/dto/update-repair-order.dto.ts b/backend/src/repair-order/dto/update-repair-order.dto.ts new file mode 100644 index 0000000..dc04866 --- /dev/null +++ b/backend/src/repair-order/dto/update-repair-order.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateRepairOrderDto } from './create-repair-order.dto'; + +export class UpdateRepairOrderDto extends PartialType(CreateRepairOrderDto) {} \ No newline at end of file diff --git a/backend/src/repair-order/repair-order.controller.ts b/backend/src/repair-order/repair-order.controller.ts new file mode 100644 index 0000000..ff7791e --- /dev/null +++ b/backend/src/repair-order/repair-order.controller.ts @@ -0,0 +1,57 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { RepairOrderService } from './repair-order.service'; +import { CreateRepairOrderDto } from './dto/create-repair-order.dto'; +import { UpdateRepairOrderDto } from './dto/update-repair-order.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('repair-order') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('repair-order') +export class RepairOrderController { + constructor(private readonly repairOrderService: RepairOrderService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.repairOrderService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + @ApiParam({ name: 'id', type: String }) + findOne(@Param('id') id: string) { + return this.repairOrderService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateRepairOrderDto) { + return this.repairOrderService.create(dto); + } + + @Patch(':id') + @ApiParam({ name: 'id', type: String }) + update(@Param('id') id: string, @Body() dto: UpdateRepairOrderDto) { + return this.repairOrderService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + @ApiParam({ name: 'id', type: String }) + remove(@Param('id') id: string) { + return this.repairOrderService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/repair-order/repair-order.module.ts b/backend/src/repair-order/repair-order.module.ts new file mode 100644 index 0000000..a30fd57 --- /dev/null +++ b/backend/src/repair-order/repair-order.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { RepairOrderService } from './repair-order.service'; +import { RepairOrderController } from './repair-order.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [RepairOrderController], + providers: [RepairOrderService, PrismaService], +}) +export class RepairOrderModule {} \ No newline at end of file diff --git a/backend/src/repair-order/repair-order.service.ts b/backend/src/repair-order/repair-order.service.ts new file mode 100644 index 0000000..493d9ac --- /dev/null +++ b/backend/src/repair-order/repair-order.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { RepairOrder, Prisma } from '@prisma/client'; + +@Injectable() +export class RepairOrderService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.RepairOrderWhereInput; + orderBy?: Prisma.RepairOrderOrderByWithRelationInput; + }): Promise<{ data: RepairOrder[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.repairOrder.findMany({ skip, take, where, orderBy }), + this.prisma.repairOrder.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.RepairOrderWhereUniqueInput): Promise { + return this.prisma.repairOrder.findUnique({ where }); + } + + async create(data: Prisma.RepairOrderCreateInput): Promise { + return this.prisma.repairOrder.create({ data }); + } + + async update(params: { + where: Prisma.RepairOrderWhereUniqueInput; + data: Prisma.RepairOrderUpdateInput; + }): Promise { + return this.prisma.repairOrder.update(params); + } + + async remove(where: Prisma.RepairOrderWhereUniqueInput): Promise { + return this.prisma.repairOrder.delete({ where }); + } +} \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx new file mode 100644 index 0000000..a4f2ce4 --- /dev/null +++ b/frontend/src/App.tsx @@ -0,0 +1,90 @@ +import { Admin, Resource } from 'react-admin'; +import { dataProvider } from './dataProvider'; +import { authProvider } from './authProvider'; + +// Equipment resources +import { EquipmentList, EquipmentCreate, EquipmentEdit, EquipmentShow } from './resources/equipment'; + +// Employee resources +import { EmployeeList, EmployeeCreate, EmployeeEdit, EmployeeShow } from './resources/employee'; + +// Part resources +import { PartList, PartCreate, PartEdit, PartShow } from './resources/part'; + +// CategoryResource resources +import { CategoryResourceList, CategoryResourceCreate, CategoryResourceEdit, CategoryResourceShow } from './resources/category-resource'; + +// RepairOrder resources +import { RepairOrderList, RepairOrderCreate, RepairOrderEdit, RepairOrderShow } from './resources/repair-order'; + +// ChangeEquipmentStatus resources +import { ChangeEquipmentStatusList, ChangeEquipmentStatusCreate, ChangeEquipmentStatusEdit, ChangeEquipmentStatusShow } from './resources/change-equipment-status'; + +// ConfirmationDocument resources +import { ConfirmationDocumentList, ConfirmationDocumentCreate, ConfirmationDocumentEdit, ConfirmationDocumentShow } from './resources/confirmation-document'; + +// ConsumptionRegistration resources +import { ConsumptionRegistrationList, ConsumptionRegistrationCreate, ConsumptionRegistrationEdit, ConsumptionRegistrationShow } from './resources/consumption-registration'; + +const App = () => ( + + + + + + + + + + +); + +export default App; \ No newline at end of file diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx new file mode 100644 index 0000000..c217f97 --- /dev/null +++ b/frontend/src/main.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; +import { initKeycloak } from './authProvider'; + +initKeycloak().then(() => { + ReactDOM.createRoot(document.getElementById('root')!).render( + + + + ); +}); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceCreate.tsx b/frontend/src/resources/category-resource/CategoryResourceCreate.tsx new file mode 100644 index 0000000..a00f591 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceCreate.tsx @@ -0,0 +1,14 @@ +import { Create, SimpleForm, ReferenceInput, SelectInput } from 'react-admin'; + +export const CategoryResourceCreate = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceEdit.tsx b/frontend/src/resources/category-resource/CategoryResourceEdit.tsx new file mode 100644 index 0000000..e751754 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceEdit.tsx @@ -0,0 +1,14 @@ +import { Edit, SimpleForm, ReferenceInput, SelectInput } from 'react-admin'; + +export const CategoryResourceEdit = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceList.tsx b/frontend/src/resources/category-resource/CategoryResourceList.tsx new file mode 100644 index 0000000..258f277 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceList.tsx @@ -0,0 +1,20 @@ +import { List, DataTable, TextField, ReferenceField, EditButton } from 'react-admin'; + +export const CategoryResourceList = () => ( + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceShow.tsx b/frontend/src/resources/category-resource/CategoryResourceShow.tsx new file mode 100644 index 0000000..3c170b2 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceShow.tsx @@ -0,0 +1,17 @@ +import { Show, SimpleShowLayout, TextField, ReferenceField, DateField } from 'react-admin'; + +export const CategoryResourceShow = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/index.ts b/frontend/src/resources/category-resource/index.ts new file mode 100644 index 0000000..d195feb --- /dev/null +++ b/frontend/src/resources/category-resource/index.ts @@ -0,0 +1,4 @@ +export { CategoryResourceList } from './CategoryResourceList'; +export { CategoryResourceCreate } from './CategoryResourceCreate'; +export { CategoryResourceEdit } from './CategoryResourceEdit'; +export { CategoryResourceShow } from './CategoryResourceShow'; \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx new file mode 100644 index 0000000..8bdb813 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx @@ -0,0 +1,26 @@ +import { Create, SimpleForm, TextInput, DateInput, SelectInput, ReferenceInput } from 'react-admin'; +import { EquipmentStatus } from '@prisma/client'; + +const statusChoices = Object.values(EquipmentStatus).map(value => ({ + id: value, + name: value, +})); + +export const ChangeEquipmentStatusCreate = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx new file mode 100644 index 0000000..09d0770 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx @@ -0,0 +1,27 @@ +import { Edit, SimpleForm, TextInput, DateInput, SelectInput, ReferenceInput } from 'react-admin'; +import { EquipmentStatus } from '@prisma/client'; + +const statusChoices = Object.values(EquipmentStatus).map(value => ({ + id: value, + name: value, +})); + +export const ChangeEquipmentStatusEdit = () => ( + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx new file mode 100644 index 0000000..e87b667 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx @@ -0,0 +1,29 @@ +import { List, DataTable, TextField, DateField, EditButton, ReferenceField } from 'react-admin'; +import { EquipmentStatus } from '@prisma/client'; + +const statusChoices = Object.values(EquipmentStatus).map(value => ({ + id: value, + name: value, +})); + +export const ChangeEquipmentStatusList = () => ( + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx new file mode 100644 index 0000000..0e6ff6a --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx @@ -0,0 +1,20 @@ +import { Show, SimpleShowLayout, TextField, DateField, ReferenceField } from 'react-admin'; + +export const ChangeEquipmentStatusShow = () => ( + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/index.ts b/frontend/src/resources/change-equipment-status/index.ts new file mode 100644 index 0000000..1960ad0 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/index.ts @@ -0,0 +1,4 @@ +export { ChangeEquipmentStatusList } from './ChangeEquipmentStatusList'; +export { ChangeEquipmentStatusCreate } from './ChangeEquipmentStatusCreate'; +export { ChangeEquipmentStatusEdit } from './ChangeEquipmentStatusEdit'; +export { ChangeEquipmentStatusShow } from './ChangeEquipmentStatusShow'; \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx new file mode 100644 index 0000000..eac28c5 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx @@ -0,0 +1,17 @@ +import { Create, SimpleForm, TextInput, DateInput, BooleanInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConfirmationDocumentCreate = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx new file mode 100644 index 0000000..ecc41bf --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx @@ -0,0 +1,18 @@ +import { Edit, SimpleForm, TextInput, DateInput, BooleanInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConfirmationDocumentEdit = () => ( + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx new file mode 100644 index 0000000..3231e56 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx @@ -0,0 +1,23 @@ +import { List, DataTable, TextField, DateField, BooleanField, EditButton, ReferenceField } from 'react-admin'; + +export const ConfirmationDocumentList = () => ( + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx new file mode 100644 index 0000000..75fd471 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx @@ -0,0 +1,20 @@ +import { Show, SimpleShowLayout, TextField, DateField, BooleanField, ReferenceField } from 'react-admin'; + +export const ConfirmationDocumentShow = () => ( + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/index.ts b/frontend/src/resources/confirmation-document/index.ts new file mode 100644 index 0000000..8e3f843 --- /dev/null +++ b/frontend/src/resources/confirmation-document/index.ts @@ -0,0 +1,4 @@ +export { ConfirmationDocumentList } from './ConfirmationDocumentList'; +export { ConfirmationDocumentCreate } from './ConfirmationDocumentCreate'; +export { ConfirmationDocumentEdit } from './ConfirmationDocumentEdit'; +export { ConfirmationDocumentShow } from './ConfirmationDocumentShow'; \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx new file mode 100644 index 0000000..7dbbaac --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx @@ -0,0 +1,15 @@ +import { Create, SimpleForm, TextInput, DateInput, NumberInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConsumptionRegistrationCreate = () => ( + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx new file mode 100644 index 0000000..35b6bbb --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx @@ -0,0 +1,16 @@ +import { Edit, SimpleForm, TextInput, DateInput, NumberInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConsumptionRegistrationEdit = () => ( + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx new file mode 100644 index 0000000..d1309c9 --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx @@ -0,0 +1,19 @@ +import { List, DataTable, TextField, DateField, NumberField, EditButton, ReferenceField } from 'react-admin'; + +export const ConsumptionRegistrationList = () => ( + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx new file mode 100644 index 0000000..2f0f0d3 --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx @@ -0,0 +1,18 @@ +import { Show, SimpleShowLayout, TextField, DateField, NumberField, ReferenceField } from 'react-admin'; + +export const ConsumptionRegistrationShow = () => ( + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/index.ts b/frontend/src/resources/consumption-registration/index.ts new file mode 100644 index 0000000..f2d3906 --- /dev/null +++ b/frontend/src/resources/consumption-registration/index.ts @@ -0,0 +1,4 @@ +export { ConsumptionRegistrationList } from './ConsumptionRegistrationList'; +export { ConsumptionRegistrationCreate } from './ConsumptionRegistrationCreate'; +export { ConsumptionRegistrationEdit } from './ConsumptionRegistrationEdit'; +export { ConsumptionRegistrationShow } from './ConsumptionRegistrationShow'; \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeCreate.tsx b/frontend/src/resources/employee/EmployeeCreate.tsx new file mode 100644 index 0000000..b3b1763 --- /dev/null +++ b/frontend/src/resources/employee/EmployeeCreate.tsx @@ -0,0 +1,26 @@ +import { Create, SimpleForm, TextInput, NumberInput, SelectInput, ReferenceInput } from 'react-admin'; +import { Role } from '@prisma/client'; + +const roleChoices = Object.values(Role).map(value => ({ + id: value, + name: value, +})); + +export const EmployeeCreate = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeEdit.tsx b/frontend/src/resources/employee/EmployeeEdit.tsx new file mode 100644 index 0000000..bef6cdf --- /dev/null +++ b/frontend/src/resources/employee/EmployeeEdit.tsx @@ -0,0 +1,26 @@ +import { Edit, SimpleForm, TextInput, NumberInput, SelectInput, ReferenceInput } from 'react-admin'; +import { Role } from '@prisma/client'; + +const roleChoices = Object.values(Role).map(value => ({ + id: value, + name: value, +})); + +export const EmployeeEdit = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeList.tsx b/frontend/src/resources/employee/EmployeeList.tsx new file mode 100644 index 0000000..317b0d3 --- /dev/null +++ b/frontend/src/resources/employee/EmployeeList.tsx @@ -0,0 +1,25 @@ +import { List, DataTable, TextField, NumberField, EditButton } from 'react-admin'; +import { Role } from '@prisma/client'; + +const roleChoices = Object.values(Role).map(value => ({ + id: value, + name: value, +})); + +export const EmployeeList = () => ( + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeShow.tsx b/frontend/src/resources/employee/EmployeeShow.tsx new file mode 100644 index 0000000..e471470 --- /dev/null +++ b/frontend/src/resources/employee/EmployeeShow.tsx @@ -0,0 +1,19 @@ +import { Show, SimpleShowLayout, TextField, NumberField, DateField, ReferenceField } from 'react-admin'; + +export const EmployeeShow = () => ( + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/index.ts b/frontend/src/resources/employee/index.ts new file mode 100644 index 0000000..e93c622 --- /dev/null +++ b/frontend/src/resources/employee/index.ts @@ -0,0 +1,4 @@ +export { EmployeeList } from './EmployeeList'; +export { EmployeeCreate } from './EmployeeCreate'; +export { EmployeeEdit } from './EmployeeEdit'; +export { EmployeeShow } from './EmployeeShow'; \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentCreate.tsx b/frontend/src/resources/equipment/EquipmentCreate.tsx new file mode 100644 index 0000000..e0e47cf --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentCreate.tsx @@ -0,0 +1,46 @@ +import { Create, SimpleForm, TextInput, DateInput, NumberInput, SelectInput } from 'react-admin'; +import { EquipmentType, EnumPeriodicityTO, EquipmentStatus } from '@prisma/client'; + +const equipmentTypeChoices = Object.values(EquipmentType).map(value => ({ + id: value, + name: value, +})); + +const periodicityTOChoices = Object.values(EnumPeriodicityTO).map(value => ({ + id: value, + name: value, +})); + +const statusChoices = Object.values(EquipmentStatus).map(value => ({ + id: value, + name: value, +})); + +export const EquipmentCreate = () => ( + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentEdit.tsx b/frontend/src/resources/equipment/EquipmentEdit.tsx new file mode 100644 index 0000000..6579827 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentEdit.tsx @@ -0,0 +1,47 @@ +import { Edit, SimpleForm, TextInput, DateInput, NumberInput, SelectInput } from 'react-admin'; +import { EquipmentType, EnumPeriodicityTO, EquipmentStatus } from '@prisma/client'; + +const equipmentTypeChoices = Object.values(EquipmentType).map(value => ({ + id: value, + name: value, +})); + +const periodicityTOChoices = Object.values(EnumPeriodicityTO).map(value => ({ + id: value, + name: value, +})); + +const statusChoices = Object.values(EquipmentStatus).map(value => ({ + id: value, + name: value, +})); + +export const EquipmentEdit = () => ( + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentList.tsx b/frontend/src/resources/equipment/EquipmentList.tsx new file mode 100644 index 0000000..06da684 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentList.tsx @@ -0,0 +1,47 @@ +import { List, DataTable, TextField, DateField, NumberField, EditButton } from 'react-admin'; +import { EquipmentType, EnumPeriodicityTO, EquipmentStatus } from '@prisma/client'; + +const equipmentTypeChoices = Object.values(EquipmentType).map(value => ({ + id: value, + name: value, +})); + +const periodicityTOChoices = Object.values(EnumPeriodicityTO).map(value => ({ + id: value, + name: value, +})); + +const statusChoices = Object.values(EquipmentStatus).map(value => ({ + id: value, + name: value, +})); + +export const EquipmentList = () => ( + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentShow.tsx b/frontend/src/resources/equipment/EquipmentShow.tsx new file mode 100644 index 0000000..4cde000 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentShow.tsx @@ -0,0 +1,24 @@ +import { Show, SimpleShowLayout, TextField, DateField, NumberField } from 'react-admin'; + +export const EquipmentShow = () => ( + + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/index.ts b/frontend/src/resources/equipment/index.ts new file mode 100644 index 0000000..a98271f --- /dev/null +++ b/frontend/src/resources/equipment/index.ts @@ -0,0 +1,4 @@ +export { EquipmentList } from './EquipmentList'; +export { EquipmentCreate } from './EquipmentCreate'; +export { EquipmentEdit } from './EquipmentEdit'; +export { EquipmentShow } from './EquipmentShow'; \ No newline at end of file diff --git a/frontend/src/resources/part/PartCreate.tsx b/frontend/src/resources/part/PartCreate.tsx new file mode 100644 index 0000000..b975b27 --- /dev/null +++ b/frontend/src/resources/part/PartCreate.tsx @@ -0,0 +1,22 @@ +import { Create, SimpleForm, TextInput, NumberInput, SelectInput } from 'react-admin'; +import { CategoryPart } from '@prisma/client'; + +const categoryPartChoices = Object.values(CategoryPart).map(value => ({ + id: value, + name: value, +})); + +export const PartCreate = () => ( + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/PartEdit.tsx b/frontend/src/resources/part/PartEdit.tsx new file mode 100644 index 0000000..a03431b --- /dev/null +++ b/frontend/src/resources/part/PartEdit.tsx @@ -0,0 +1,23 @@ +import { Edit, SimpleForm, TextInput, NumberInput, SelectInput } from 'react-admin'; +import { CategoryPart } from '@prisma/client'; + +const categoryPartChoices = Object.values(CategoryPart).map(value => ({ + id: value, + name: value, +})); + +export const PartEdit = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/PartList.tsx b/frontend/src/resources/part/PartList.tsx new file mode 100644 index 0000000..ff37749 --- /dev/null +++ b/frontend/src/resources/part/PartList.tsx @@ -0,0 +1,24 @@ +import { List, DataTable, TextField, NumberField, EditButton } from 'react-admin'; +import { CategoryPart } from '@prisma/client'; + +const categoryPartChoices = Object.values(CategoryPart).map(value => ({ + id: value, + name: value, +})); + +export const PartList = () => ( + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/PartShow.tsx b/frontend/src/resources/part/PartShow.tsx new file mode 100644 index 0000000..f5218bf --- /dev/null +++ b/frontend/src/resources/part/PartShow.tsx @@ -0,0 +1,16 @@ +import { Show, SimpleShowLayout, TextField, NumberField, DateField } from 'react-admin'; + +export const PartShow = () => ( + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/index.ts b/frontend/src/resources/part/index.ts new file mode 100644 index 0000000..45ddc1c --- /dev/null +++ b/frontend/src/resources/part/index.ts @@ -0,0 +1,4 @@ +export { PartList } from './PartList'; +export { PartCreate } from './PartCreate'; +export { PartEdit } from './PartEdit'; +export { PartShow } from './PartShow'; \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderCreate.tsx b/frontend/src/resources/repair-order/RepairOrderCreate.tsx new file mode 100644 index 0000000..090d838 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderCreate.tsx @@ -0,0 +1,40 @@ +import { Create, SimpleForm, TextInput, DateInput, NumberInput, BooleanInput, SelectInput, ReferenceInput } from 'react-admin'; +import { RepairKind, RepairOrderStatus } from '@prisma/client'; + +const repairKindChoices = Object.values(RepairKind).map(value => ({ + id: value, + name: value, +})); + +const statusChoices = Object.values(RepairOrderStatus).map(value => ({ + id: value, + name: value, +})); + +export const RepairOrderCreate = () => ( + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderEdit.tsx b/frontend/src/resources/repair-order/RepairOrderEdit.tsx new file mode 100644 index 0000000..a280a3b --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderEdit.tsx @@ -0,0 +1,41 @@ +import { Edit, SimpleForm, TextInput, DateInput, NumberInput, BooleanInput, SelectInput, ReferenceInput } from 'react-admin'; +import { RepairKind, RepairOrderStatus } from '@prisma/client'; + +const repairKindChoices = Object.values(RepairKind).map(value => ({ + id: value, + name: value, +})); + +const statusChoices = Object.values(RepairOrderStatus).map(value => ({ + id: value, + name: value, +})); + +export const RepairOrderEdit = () => ( + + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderList.tsx b/frontend/src/resources/repair-order/RepairOrderList.tsx new file mode 100644 index 0000000..6213aef --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderList.tsx @@ -0,0 +1,42 @@ +import { List, DataTable, TextField, DateField, NumberField, BooleanField, EditButton, ReferenceField } from 'react-admin'; +import { RepairKind, RepairOrderStatus } from '@prisma/client'; + +const repairKindChoices = Object.values(RepairKind).map(value => ({ + id: value, + name: value, +})); + +const statusChoices = Object.values(RepairOrderStatus).map(value => ({ + id: value, + name: value, +})); + +export const RepairOrderList = () => ( + + + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderShow.tsx b/frontend/src/resources/repair-order/RepairOrderShow.tsx new file mode 100644 index 0000000..1890b16 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderShow.tsx @@ -0,0 +1,26 @@ +import { Show, SimpleShowLayout, TextField, DateField, NumberField, BooleanField, ReferenceField } from 'react-admin'; + +export const RepairOrderShow = () => ( + + + + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/index.ts b/frontend/src/resources/repair-order/index.ts new file mode 100644 index 0000000..1d8fbda --- /dev/null +++ b/frontend/src/resources/repair-order/index.ts @@ -0,0 +1,4 @@ +export { RepairOrderList } from './RepairOrderList'; +export { RepairOrderCreate } from './RepairOrderCreate'; +export { RepairOrderEdit } from './RepairOrderEdit'; +export { RepairOrderShow } from './RepairOrderShow'; \ No newline at end of file