From c05e6941b33e6b5a73afc5ef9815dccc36101038 Mon Sep 17 00:00:00 2001 From: aid-orchestrator Date: Sat, 25 Apr 2026 13:53:55 +0000 Subject: [PATCH] feat: add generated code --- backend/prisma/schema.prisma | 241 ++++++++++++++++++ backend/src/app.module.ts | 35 +++ .../category-resource.controller.ts | 54 ++++ .../category-resource.module.ts | 10 + .../category-resource.service.ts | 41 +++ .../dto/create-category-resource.dto.ts | 14 + .../dto/update-category-resource.dto.ts | 4 + .../change-equipment-status.controller.ts | 54 ++++ .../change-equipment-status.module.ts | 10 + .../change-equipment-status.service.ts | 41 +++ .../dto/create-change-equipment-status.dto.ts | 40 +++ .../dto/update-change-equipment-status.dto.ts | 4 + .../confirmation-document.controller.ts | 54 ++++ .../confirmation-document.module.ts | 10 + .../confirmation-document.service.ts | 41 +++ .../dto/create-confirmation-document.dto.ts | 30 +++ .../dto/update-confirmation-document.dto.ts | 4 + .../consumption-registration.controller.ts | 54 ++++ .../consumption-registration.module.ts | 10 + .../consumption-registration.service.ts | 41 +++ .../create-consumption-registration.dto.ts | 31 +++ .../update-consumption-registration.dto.ts | 4 + .../src/employee/dto/create-employee.dto.ts | 42 +++ .../src/employee/dto/update-employee.dto.ts | 4 + backend/src/employee/employee.controller.ts | 54 ++++ backend/src/employee/employee.module.ts | 10 + backend/src/employee/employee.service.ts | 41 +++ .../src/equipment/dto/create-equipment.dto.ts | 78 ++++++ .../src/equipment/dto/update-equipment.dto.ts | 4 + backend/src/equipment/equipment.controller.ts | 54 ++++ backend/src/equipment/equipment.module.ts | 10 + backend/src/equipment/equipment.service.ts | 41 +++ .../dto/create-maintenance-planning.dto.ts | 20 ++ .../dto/update-maintenance-planning.dto.ts | 4 + .../maintenance-planning.controller.ts | 54 ++++ .../maintenance-planning.module.ts | 10 + .../maintenance-planning.service.ts | 41 +++ .../money-needs/dto/create-money-needs.dto.ts | 17 ++ .../money-needs/dto/update-money-needs.dto.ts | 4 + .../src/money-needs/money-needs.controller.ts | 54 ++++ backend/src/money-needs/money-needs.module.ts | 10 + .../src/money-needs/money-needs.service.ts | 41 +++ backend/src/part/dto/create-part.dto.ts | 32 +++ backend/src/part/dto/update-part.dto.ts | 4 + backend/src/part/part.controller.ts | 54 ++++ backend/src/part/part.module.ts | 10 + backend/src/part/part.service.ts | 41 +++ .../price-list/dto/create-price-list.dto.ts | 17 ++ .../price-list/dto/update-price-list.dto.ts | 4 + .../src/price-list/price-list.controller.ts | 54 ++++ backend/src/price-list/price-list.module.ts | 10 + backend/src/price-list/price-list.service.ts | 41 +++ .../dto/create-repair-order.dto.ts | 72 ++++++ .../dto/update-repair-order.dto.ts | 4 + .../repair-order/repair-order.controller.ts | 54 ++++ .../src/repair-order/repair-order.module.ts | 10 + .../src/repair-order/repair-order.service.ts | 41 +++ .../dto/create-resource-needs.dto.ts | 16 ++ .../dto/update-resource-needs.dto.ts | 4 + .../resource-needs.controller.ts | 54 ++++ .../resource-needs/resource-needs.module.ts | 10 + .../resource-needs/resource-needs.service.ts | 74 ++++++ frontend/src/App.tsx | 59 +++++ frontend/src/main.tsx | 15 ++ .../CategoryResourceCreate.tsx | 14 + .../CategoryResourceEdit.tsx | 14 + .../CategoryResourceList.tsx | 12 + .../CategoryResourceShow.tsx | 15 ++ .../src/resources/category-resource/index.ts | 4 + .../ChangeEquipmentStatusCreate.tsx | 24 ++ .../ChangeEquipmentStatusEdit.tsx | 25 ++ .../ChangeEquipmentStatusList.tsx | 17 ++ .../ChangeEquipmentStatusShow.tsx | 18 ++ .../change-equipment-status/index.ts | 4 + .../ConfirmationDocumentCreate.tsx | 17 ++ .../ConfirmationDocumentEdit.tsx | 18 ++ .../ConfirmationDocumentList.tsx | 15 ++ .../ConfirmationDocumentShow.tsx | 18 ++ .../resources/confirmation-document/index.ts | 4 + .../ConsumptionRegistrationCreate.tsx | 15 ++ .../ConsumptionRegistrationEdit.tsx | 16 ++ .../ConsumptionRegistrationList.tsx | 15 ++ .../ConsumptionRegistrationShow.tsx | 16 ++ .../consumption-registration/index.ts | 4 + .../src/resources/employee/EmployeeCreate.tsx | 23 ++ .../src/resources/employee/EmployeeEdit.tsx | 23 ++ .../src/resources/employee/EmployeeList.tsx | 16 ++ .../src/resources/employee/EmployeeShow.tsx | 17 ++ frontend/src/resources/employee/index.ts | 4 + .../resources/equipment/EquipmentCreate.tsx | 42 +++ .../src/resources/equipment/EquipmentEdit.tsx | 43 ++++ .../src/resources/equipment/EquipmentList.tsx | 22 ++ .../src/resources/equipment/EquipmentShow.tsx | 21 ++ frontend/src/resources/equipment/index.ts | 4 + .../MaintenancePlanningCreate.tsx | 22 ++ .../MaintenancePlanningEdit.tsx | 22 ++ .../MaintenancePlanningList.tsx | 13 + .../MaintenancePlanningShow.tsx | 14 + .../resources/maintenance-planning/index.ts | 4 + .../money-needs/MoneyNeedsCreate.tsx | 10 + .../resources/money-needs/MoneyNeedsEdit.tsx | 10 + .../resources/money-needs/MoneyNeedsList.tsx | 12 + .../resources/money-needs/MoneyNeedsShow.tsx | 11 + frontend/src/resources/money-needs/index.ts | 4 + frontend/src/resources/part/PartCreate.tsx | 20 ++ frontend/src/resources/part/PartEdit.tsx | 21 ++ frontend/src/resources/part/PartList.tsx | 15 ++ frontend/src/resources/part/PartShow.tsx | 14 + frontend/src/resources/part/index.ts | 4 + .../repair-order/RepairOrderCreate.tsx | 40 +++ .../repair-order/RepairOrderEdit.tsx | 41 +++ .../repair-order/RepairOrderList.tsx | 23 ++ .../repair-order/RepairOrderShow.tsx | 24 ++ frontend/src/resources/repair-order/index.ts | 4 + .../resource-needs/ResourceNeedsCreate.tsx | 14 + .../resource-needs/ResourceNeedsEdit.tsx | 14 + .../resource-needs/ResourceNeedsList.tsx | 10 + .../resource-needs/ResourceNeedsShow.tsx | 19 ++ .../src/resources/resource-needs/index.ts | 4 + 119 files changed, 2989 insertions(+) create mode 100644 backend/prisma/schema.prisma create mode 100644 backend/src/app.module.ts create mode 100644 backend/src/category-resource/category-resource.controller.ts create mode 100644 backend/src/category-resource/category-resource.module.ts create mode 100644 backend/src/category-resource/category-resource.service.ts create mode 100644 backend/src/category-resource/dto/create-category-resource.dto.ts create mode 100644 backend/src/category-resource/dto/update-category-resource.dto.ts create mode 100644 backend/src/change-equipment-status/change-equipment-status.controller.ts create mode 100644 backend/src/change-equipment-status/change-equipment-status.module.ts create mode 100644 backend/src/change-equipment-status/change-equipment-status.service.ts create mode 100644 backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts create mode 100644 backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts create mode 100644 backend/src/confirmation-document/confirmation-document.controller.ts create mode 100644 backend/src/confirmation-document/confirmation-document.module.ts create mode 100644 backend/src/confirmation-document/confirmation-document.service.ts create mode 100644 backend/src/confirmation-document/dto/create-confirmation-document.dto.ts create mode 100644 backend/src/confirmation-document/dto/update-confirmation-document.dto.ts create mode 100644 backend/src/consumption-registration/consumption-registration.controller.ts create mode 100644 backend/src/consumption-registration/consumption-registration.module.ts create mode 100644 backend/src/consumption-registration/consumption-registration.service.ts create mode 100644 backend/src/consumption-registration/dto/create-consumption-registration.dto.ts create mode 100644 backend/src/consumption-registration/dto/update-consumption-registration.dto.ts create mode 100644 backend/src/employee/dto/create-employee.dto.ts create mode 100644 backend/src/employee/dto/update-employee.dto.ts create mode 100644 backend/src/employee/employee.controller.ts create mode 100644 backend/src/employee/employee.module.ts create mode 100644 backend/src/employee/employee.service.ts create mode 100644 backend/src/equipment/dto/create-equipment.dto.ts create mode 100644 backend/src/equipment/dto/update-equipment.dto.ts create mode 100644 backend/src/equipment/equipment.controller.ts create mode 100644 backend/src/equipment/equipment.module.ts create mode 100644 backend/src/equipment/equipment.service.ts create mode 100644 backend/src/maintenance-planning/dto/create-maintenance-planning.dto.ts create mode 100644 backend/src/maintenance-planning/dto/update-maintenance-planning.dto.ts create mode 100644 backend/src/maintenance-planning/maintenance-planning.controller.ts create mode 100644 backend/src/maintenance-planning/maintenance-planning.module.ts create mode 100644 backend/src/maintenance-planning/maintenance-planning.service.ts create mode 100644 backend/src/money-needs/dto/create-money-needs.dto.ts create mode 100644 backend/src/money-needs/dto/update-money-needs.dto.ts create mode 100644 backend/src/money-needs/money-needs.controller.ts create mode 100644 backend/src/money-needs/money-needs.module.ts create mode 100644 backend/src/money-needs/money-needs.service.ts create mode 100644 backend/src/part/dto/create-part.dto.ts create mode 100644 backend/src/part/dto/update-part.dto.ts create mode 100644 backend/src/part/part.controller.ts create mode 100644 backend/src/part/part.module.ts create mode 100644 backend/src/part/part.service.ts create mode 100644 backend/src/price-list/dto/create-price-list.dto.ts create mode 100644 backend/src/price-list/dto/update-price-list.dto.ts create mode 100644 backend/src/price-list/price-list.controller.ts create mode 100644 backend/src/price-list/price-list.module.ts create mode 100644 backend/src/price-list/price-list.service.ts create mode 100644 backend/src/repair-order/dto/create-repair-order.dto.ts create mode 100644 backend/src/repair-order/dto/update-repair-order.dto.ts create mode 100644 backend/src/repair-order/repair-order.controller.ts create mode 100644 backend/src/repair-order/repair-order.module.ts create mode 100644 backend/src/repair-order/repair-order.service.ts create mode 100644 backend/src/resource-needs/dto/create-resource-needs.dto.ts create mode 100644 backend/src/resource-needs/dto/update-resource-needs.dto.ts create mode 100644 backend/src/resource-needs/resource-needs.controller.ts create mode 100644 backend/src/resource-needs/resource-needs.module.ts create mode 100644 backend/src/resource-needs/resource-needs.service.ts create mode 100644 frontend/src/App.tsx create mode 100644 frontend/src/main.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceCreate.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceEdit.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceList.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceShow.tsx create mode 100644 frontend/src/resources/category-resource/index.ts create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx create mode 100644 frontend/src/resources/change-equipment-status/index.ts create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx create mode 100644 frontend/src/resources/confirmation-document/index.ts create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx create mode 100644 frontend/src/resources/consumption-registration/index.ts create mode 100644 frontend/src/resources/employee/EmployeeCreate.tsx create mode 100644 frontend/src/resources/employee/EmployeeEdit.tsx create mode 100644 frontend/src/resources/employee/EmployeeList.tsx create mode 100644 frontend/src/resources/employee/EmployeeShow.tsx create mode 100644 frontend/src/resources/employee/index.ts create mode 100644 frontend/src/resources/equipment/EquipmentCreate.tsx create mode 100644 frontend/src/resources/equipment/EquipmentEdit.tsx create mode 100644 frontend/src/resources/equipment/EquipmentList.tsx create mode 100644 frontend/src/resources/equipment/EquipmentShow.tsx create mode 100644 frontend/src/resources/equipment/index.ts create mode 100644 frontend/src/resources/maintenance-planning/MaintenancePlanningCreate.tsx create mode 100644 frontend/src/resources/maintenance-planning/MaintenancePlanningEdit.tsx create mode 100644 frontend/src/resources/maintenance-planning/MaintenancePlanningList.tsx create mode 100644 frontend/src/resources/maintenance-planning/MaintenancePlanningShow.tsx create mode 100644 frontend/src/resources/maintenance-planning/index.ts create mode 100644 frontend/src/resources/money-needs/MoneyNeedsCreate.tsx create mode 100644 frontend/src/resources/money-needs/MoneyNeedsEdit.tsx create mode 100644 frontend/src/resources/money-needs/MoneyNeedsList.tsx create mode 100644 frontend/src/resources/money-needs/MoneyNeedsShow.tsx create mode 100644 frontend/src/resources/money-needs/index.ts create mode 100644 frontend/src/resources/part/PartCreate.tsx create mode 100644 frontend/src/resources/part/PartEdit.tsx create mode 100644 frontend/src/resources/part/PartList.tsx create mode 100644 frontend/src/resources/part/PartShow.tsx create mode 100644 frontend/src/resources/part/index.ts create mode 100644 frontend/src/resources/repair-order/RepairOrderCreate.tsx create mode 100644 frontend/src/resources/repair-order/RepairOrderEdit.tsx create mode 100644 frontend/src/resources/repair-order/RepairOrderList.tsx create mode 100644 frontend/src/resources/repair-order/RepairOrderShow.tsx create mode 100644 frontend/src/resources/repair-order/index.ts create mode 100644 frontend/src/resources/resource-needs/ResourceNeedsCreate.tsx create mode 100644 frontend/src/resources/resource-needs/ResourceNeedsEdit.tsx create mode 100644 frontend/src/resources/resource-needs/ResourceNeedsList.tsx create mode 100644 frontend/src/resources/resource-needs/ResourceNeedsShow.tsx create mode 100644 frontend/src/resources/resource-needs/index.ts diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma new file mode 100644 index 0000000..d471d18 --- /dev/null +++ b/backend/prisma/schema.prisma @@ -0,0 +1,241 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +enum EquipmentStatus { + Active + Repair + Reserve + WriteOff +} + +enum laborOperation { + Manual + MachineManual + Machine +} + +enum EnumPeriodicityTO { + Ежедневное + Еженедельное + Ежемесячное + Полугодовое + Годовое +} + +enum Role { + Исполнитель + Подписант + Пользователь +} + +enum CategoryPart { + Расходник + Запчасть + Инструмент + Спецодежда +} + +enum EquipmentType { + Производственное + Энергетическое + Насосное + Компрессорное +} + +enum RepairKind { + TO + TR + TRE + KR + AR + MP +} + +enum RepairOrderStatus { + Draft + Approved + InWork + Done + Cancelled +} + +model Equipment { + id String @id @default(uuid()) + name String + serialNumber String + dateOfInspection DateTime? @db.Date + inventoryNumber String @unique + equipmentType EquipmentType + periodicityTO EnumPeriodicityTO + status EquipmentStatus @default(Active) + commissionedAt DateTime? @db.Date + totalEngineHours Decimal? + engineHoursSinceLastRepair Decimal? + lastRepairAt DateTime? @db.Date + notes String? + workAsPartOf laborOperation? + fuelСonsumed Float? + + // Relations + repairOrders RepairOrder[] + changeEquipmentStatuses ChangeEquipmentStatus[] + consumptionRegistrations ConsumptionRegistration[] + maintenancePlannings MaintenancePlanning[] + + // Indexes + @@index([inventoryNumber]) + @@index([serialNumber]) + @@index([equipmentType]) + @@index([status]) + @@index([dateOfInspection]) +} + +model Employee { + code String @id + fullName String + role Role + position String + price Float? + phoneNumber Float? + + // Self-referential relations for hierarchy + boss Employee? @relation("EmployeeHierarchy", fields: [bossCode], references: [code]) + bossCode String? + subordinates Employee[] @relation("EmployeeHierarchy") + + // Relations to other models + confirmationDocuments ConfirmationDocument[] + resourceNeeds ResourceNeeds[] + categoryResources CategoryResource[] +} + +model Part { + id String @id @default(uuid()) + name String + categories CategoryPart? + price Float? + description String? + serialNumber String? + + // Relations + resourceNeeds ResourceNeeds[] + categoryResources CategoryResource[] +} + +model CategoryResource { + id String @id @default(uuid()) + + // Relations + part Part? @relation(fields: [partId], references: [id]) + partId String? + employee Employee? @relation(fields: [employeeCode], references: [code]) + employeeCode String? +} + +model PriceList { + id String @id @default(uuid()) + costOfWorkingHours Float? + partPrice Float? +} + +model RepairOrder { + id String @id @default(uuid()) + number String @unique + date DateTime @db.Date + equipment Equipment @relation(fields: [equipmentId], references: [id]) + equipmentId String + 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[] + + // Indexes + @@index([date]) + @@index([plannedAt]) + @@index([status]) +} + +model ChangeEquipmentStatus { + id String @id @default(uuid()) + equipment Equipment @relation(fields: [equipmentId], references: [id]) + equipmentId String + newStatus EquipmentStatus + number String? + comment String? + date DateTime @db.Date + responsible String? + document String? // Storing file path or reference + + // Indexes + @@index([date]) + @@index([newStatus]) +} + +model ConfirmationDocument { + id String @id @default(uuid()) + number String? + date DateTime @db.Date + manager Employee @relation(fields: [managerCode], references: [code]) + managerCode String + order RepairOrder @relation(fields: [orderId], references: [id]) + orderId String + confirmed Boolean? + + // Indexes + @@index([date]) + @@index([confirmed]) +} + +model ConsumptionRegistration { + id String @id @default(uuid()) + number String? + date DateTime @db.Date + equipment Equipment @relation(fields: [equipmentId], references: [id]) + equipmentId String + totalEngineHours Decimal? + fuelConsumption Float? + + // Indexes + @@index([date]) +} + +model MaintenancePlanning { + id String @id @default(uuid()) + date DateTime @db.Date + equipment Equipment @relation(fields: [equipmentId], references: [id]) + equipmentId String + repairKind RepairKind + + // Indexes + @@index([date]) + @@index([repairKind]) +} + +model ResourceNeeds { + id String @id @default(uuid()) + + // Many-to-many relations + employees Employee[] + parts Part[] +} + +model MoneyNeeds { + id String @id @default(uuid()) + employees Float? + part Float? +} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts new file mode 100644 index 0000000..297a36f --- /dev/null +++ b/backend/src/app.module.ts @@ -0,0 +1,35 @@ +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'; +import { MaintenancePlanningModule } from './maintenance-planning/maintenance-planning.module'; +import { ResourceNeedsModule } from './resource-needs/resource-needs.module'; +import { MoneyNeedsModule } from './money-needs/money-needs.module'; +import { PriceListModule } from './price-list/price-list.module'; + +@Module({ + imports: [ + AuthModule, + EquipmentModule, + EmployeeModule, + PartModule, + CategoryResourceModule, + RepairOrderModule, + ChangeEquipmentStatusModule, + ConfirmationDocumentModule, + ConsumptionRegistrationModule, + MaintenancePlanningModule, + ResourceNeedsModule, + MoneyNeedsModule, + PriceListModule, + ], + 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..bd0d9b0 --- /dev/null +++ b/backend/src/category-resource/category-resource.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('id') id: string) { + return this.categoryResourceService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateCategoryResourceDto) { + return this.categoryResourceService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateCategoryResourceDto) { + return this.categoryResourceService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + 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..dd23bac --- /dev/null +++ b/backend/src/category-resource/dto/create-category-resource.dto.ts @@ -0,0 +1,14 @@ +import { IsString, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateCategoryResourceDto { + @ApiProperty({ required: false, description: 'Идентификатор ЗИП/ТМЦ' }) + @IsString() + @IsOptional() + partId?: string; + + @ApiProperty({ required: false, description: 'Код сотрудника' }) + @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..960e87d --- /dev/null +++ b/backend/src/change-equipment-status/change-equipment-status.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('id') id: string) { + return this.changeEquipmentStatusService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateChangeEquipmentStatusDto) { + return this.changeEquipmentStatusService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateChangeEquipmentStatusDto) { + return this.changeEquipmentStatusService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + 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..149c1b5 --- /dev/null +++ b/backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts @@ -0,0 +1,40 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional } from 'class-validator'; +import { ApiProperty, ApiParam } from '@nestjs/swagger'; +import { EquipmentStatus } from '@prisma/client'; + +export class CreateChangeEquipmentStatusDto { + @ApiProperty({ description: 'Идентификатор оборудования' }) + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ enum: EquipmentStatus, enumName: 'EquipmentStatus', description: 'Новый статус' }) + @IsEnum(EquipmentStatus) + newStatus: EquipmentStatus; + + @ApiProperty({ required: false, description: 'Номер' }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty({ required: false, description: 'Комментарий' }) + @IsString() + @IsOptional() + comment?: string; + + @ApiProperty({ description: 'Дата изменения статуса' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ required: false, description: 'Ответственный' }) + @IsString() + @IsOptional() + responsible?: string; + + @ApiProperty({ required: false, description: 'Прикрепить документ (путь к файлу)' }) + @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..1f34a14 --- /dev/null +++ b/backend/src/confirmation-document/confirmation-document.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('id') id: string) { + return this.confirmationDocumentService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateConfirmationDocumentDto) { + return this.confirmationDocumentService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateConfirmationDocumentDto) { + return this.confirmationDocumentService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + 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..bd4bc9d --- /dev/null +++ b/backend/src/confirmation-document/dto/create-confirmation-document.dto.ts @@ -0,0 +1,30 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsISO8601, IsOptional, IsBoolean } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateConfirmationDocumentDto { + @ApiProperty({ required: false, description: 'Номер' }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty({ description: 'Дата согласования' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ description: 'Код руководителя' }) + @IsString() + @IsNotEmpty() + managerCode: string; + + @ApiProperty({ description: 'Идентификатор заявки' }) + @IsString() + @IsNotEmpty() + orderId: string; + + @ApiProperty({ required: false, description: 'Согласовано/Не согласовано' }) + @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..9739b22 --- /dev/null +++ b/backend/src/consumption-registration/consumption-registration.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('id') id: string) { + return this.consumptionRegistrationService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateConsumptionRegistrationDto) { + return this.consumptionRegistrationService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateConsumptionRegistrationDto) { + return this.consumptionRegistrationService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + 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..16ec30a --- /dev/null +++ b/backend/src/consumption-registration/dto/create-consumption-registration.dto.ts @@ -0,0 +1,31 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsISO8601, IsOptional, IsDecimal, IsNumber } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateConsumptionRegistrationDto { + @ApiProperty({ required: false, description: 'Номер' }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty({ description: 'Дата регистрации' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ description: 'Идентификатор оборудования' }) + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ required: false, description: 'Наработка' }) + @IsDecimal() + @IsOptional() + totalEngineHours?: string; + + @ApiProperty({ required: false, description: 'Расход топлива' }) + @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..990ac3e --- /dev/null +++ b/backend/src/employee/dto/create-employee.dto.ts @@ -0,0 +1,42 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsOptional, IsNumber } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { Role } from '@prisma/client'; + +export class CreateEmployeeDto { + @ApiProperty({ description: 'Номер сотрудника (Табельный номер)' }) + @IsString() + @IsNotEmpty() + code: string; + + @ApiProperty({ description: 'ФИО сотрудника' }) + @IsString() + @IsNotEmpty() + fullName: string; + + @ApiProperty({ enum: Role, enumName: 'Role', description: 'Роль сотрудника' }) + @IsEnum(Role) + role: Role; + + @ApiProperty({ description: 'Должность сотрудника' }) + @IsString() + @IsNotEmpty() + position: string; + + @ApiProperty({ required: false, description: 'Код руководителя' }) + @IsString() + @IsOptional() + bossCode?: string; + + @ApiProperty({ required: false, description: 'Стоимость часа работы сотрудника' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + price?: number; + + @ApiProperty({ required: false, description: 'Номер телефона' }) + @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..1b6d8cf --- /dev/null +++ b/backend/src/employee/employee.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('code') code: string) { + return this.employeeService.findOne({ code }); + } + + @Post() + create(@Body() dto: CreateEmployeeDto) { + return this.employeeService.create(dto); + } + + @Patch(':code') + update(@Param('code') code: string, @Body() dto: UpdateEmployeeDto) { + return this.employeeService.update({ where: { code }, data: dto }); + } + + @Delete(':code') + 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..051570e --- /dev/null +++ b/backend/src/equipment/dto/create-equipment.dto.ts @@ -0,0 +1,78 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional, IsDecimal, IsNumber, IsBoolean } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { EquipmentStatus, EquipmentType, EnumPeriodicityTO, laborOperation } from '@prisma/client'; + +export class CreateEquipmentDto { + @ApiProperty({ description: 'Название оборудования' }) + @IsString() + @IsNotEmpty() + name: string; + + @ApiProperty({ description: 'Заводской (серийный) номер' }) + @IsString() + @IsNotEmpty() + serialNumber: string; + + @ApiProperty({ description: 'Инвентарный номер' }) + @IsString() + @IsNotEmpty() + inventoryNumber: string; + + @ApiProperty({ enum: EquipmentType, enumName: 'EquipmentType', description: 'Тип оборудования' }) + @IsEnum(EquipmentType) + equipmentType: EquipmentType; + + @ApiProperty({ required: false, description: 'Дата проверки' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + dateOfInspection?: Date; + + @ApiProperty({ enum: EnumPeriodicityTO, enumName: 'EnumPeriodicityTO', description: 'Периодичность ТО' }) + @IsEnum(EnumPeriodicityTO) + periodicityTO: EnumPeriodicityTO; + + @ApiProperty({ enum: EquipmentStatus, enumName: 'EquipmentStatus', description: 'Текущий статус', default: EquipmentStatus.Active }) + @IsEnum(EquipmentStatus) + @IsOptional() + status?: EquipmentStatus; + + @ApiProperty({ required: false, description: 'Год изготовления' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + commissionedAt?: Date; + + @ApiProperty({ required: false, description: 'Общая наработка, моточасов' }) + @IsDecimal() + @IsOptional() + totalEngineHours?: string; + + @ApiProperty({ required: false, description: 'Наработка с последнего ремонта, моточасов' }) + @IsDecimal() + @IsOptional() + engineHoursSinceLastRepair?: string; + + @ApiProperty({ required: false, description: 'Дата последнего ремонта' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + lastRepairAt?: Date; + + @ApiProperty({ required: false, description: 'Примечания' }) + @IsString() + @IsOptional() + notes?: string; + + @ApiProperty({ required: false, enum: laborOperation, enumName: 'laborOperation', description: 'Работы в составе' }) + @IsEnum(laborOperation) + @IsOptional() + workAsPartOf?: laborOperation; + + @ApiProperty({ required: false, description: 'Расход топлива' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + fuelСonsumed?: number; +} \ 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..de90e22 --- /dev/null +++ b/backend/src/equipment/equipment.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('id') id: string) { + return this.equipmentService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateEquipmentDto) { + return this.equipmentService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateEquipmentDto) { + return this.equipmentService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + 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/maintenance-planning/dto/create-maintenance-planning.dto.ts b/backend/src/maintenance-planning/dto/create-maintenance-planning.dto.ts new file mode 100644 index 0000000..95789df --- /dev/null +++ b/backend/src/maintenance-planning/dto/create-maintenance-planning.dto.ts @@ -0,0 +1,20 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601 } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { RepairKind } from '@prisma/client'; + +export class CreateMaintenancePlanningDto { + @ApiProperty({ description: 'Запланированная дата проведения ТО' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ description: 'Идентификатор оборудования' }) + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ enum: RepairKind, enumName: 'RepairKind', description: 'вид ТО/ППР' }) + @IsEnum(RepairKind) + repairKind: RepairKind; +} \ No newline at end of file diff --git a/backend/src/maintenance-planning/dto/update-maintenance-planning.dto.ts b/backend/src/maintenance-planning/dto/update-maintenance-planning.dto.ts new file mode 100644 index 0000000..7678639 --- /dev/null +++ b/backend/src/maintenance-planning/dto/update-maintenance-planning.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateMaintenancePlanningDto } from './create-maintenance-planning.dto'; + +export class UpdateMaintenancePlanningDto extends PartialType(CreateMaintenancePlanningDto) {} \ No newline at end of file diff --git a/backend/src/maintenance-planning/maintenance-planning.controller.ts b/backend/src/maintenance-planning/maintenance-planning.controller.ts new file mode 100644 index 0000000..0d93d27 --- /dev/null +++ b/backend/src/maintenance-planning/maintenance-planning.controller.ts @@ -0,0 +1,54 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { MaintenancePlanningService } from './maintenance-planning.service'; +import { CreateMaintenancePlanningDto } from './dto/create-maintenance-planning.dto'; +import { UpdateMaintenancePlanningDto } from './dto/update-maintenance-planning.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('maintenance-planning') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('maintenance-planning') +export class MaintenancePlanningController { + constructor(private readonly maintenancePlanningService: MaintenancePlanningService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.maintenancePlanningService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.maintenancePlanningService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateMaintenancePlanningDto) { + return this.maintenancePlanningService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateMaintenancePlanningDto) { + return this.maintenancePlanningService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.maintenancePlanningService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/maintenance-planning/maintenance-planning.module.ts b/backend/src/maintenance-planning/maintenance-planning.module.ts new file mode 100644 index 0000000..b343722 --- /dev/null +++ b/backend/src/maintenance-planning/maintenance-planning.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { MaintenancePlanningService } from './maintenance-planning.service'; +import { MaintenancePlanningController } from './maintenance-planning.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [MaintenancePlanningController], + providers: [MaintenancePlanningService, PrismaService], +}) +export class MaintenancePlanningModule {} \ No newline at end of file diff --git a/backend/src/maintenance-planning/maintenance-planning.service.ts b/backend/src/maintenance-planning/maintenance-planning.service.ts new file mode 100644 index 0000000..8d02664 --- /dev/null +++ b/backend/src/maintenance-planning/maintenance-planning.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { MaintenancePlanning, Prisma } from '@prisma/client'; + +@Injectable() +export class MaintenancePlanningService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.MaintenancePlanningWhereInput; + orderBy?: Prisma.MaintenancePlanningOrderByWithRelationInput; + }): Promise<{ data: MaintenancePlanning[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.maintenancePlanning.findMany({ skip, take, where, orderBy }), + this.prisma.maintenancePlanning.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.MaintenancePlanningWhereUniqueInput): Promise { + return this.prisma.maintenancePlanning.findUnique({ where }); + } + + async create(data: Prisma.MaintenancePlanningCreateInput): Promise { + return this.prisma.maintenancePlanning.create({ data }); + } + + async update(params: { + where: Prisma.MaintenancePlanningWhereUniqueInput; + data: Prisma.MaintenancePlanningUpdateInput; + }): Promise { + return this.prisma.maintenancePlanning.update(params); + } + + async remove(where: Prisma.MaintenancePlanningWhereUniqueInput): Promise { + return this.prisma.maintenancePlanning.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/money-needs/dto/create-money-needs.dto.ts b/backend/src/money-needs/dto/create-money-needs.dto.ts new file mode 100644 index 0000000..1109023 --- /dev/null +++ b/backend/src/money-needs/dto/create-money-needs.dto.ts @@ -0,0 +1,17 @@ +import { Type } from 'class-transformer'; +import { IsNumber, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateMoneyNeedsDto { + @ApiProperty({ required: false, description: 'Стоимость часов работы' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + employees?: number; + + @ApiProperty({ required: false, description: 'Стоимость ЗИП/ТМЦ' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + part?: number; +} \ No newline at end of file diff --git a/backend/src/money-needs/dto/update-money-needs.dto.ts b/backend/src/money-needs/dto/update-money-needs.dto.ts new file mode 100644 index 0000000..742f557 --- /dev/null +++ b/backend/src/money-needs/dto/update-money-needs.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateMoneyNeedsDto } from './create-money-needs.dto'; + +export class UpdateMoneyNeedsDto extends PartialType(CreateMoneyNeedsDto) {} \ No newline at end of file diff --git a/backend/src/money-needs/money-needs.controller.ts b/backend/src/money-needs/money-needs.controller.ts new file mode 100644 index 0000000..9223573 --- /dev/null +++ b/backend/src/money-needs/money-needs.controller.ts @@ -0,0 +1,54 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { MoneyNeedsService } from './money-needs.service'; +import { CreateMoneyNeedsDto } from './dto/create-money-needs.dto'; +import { UpdateMoneyNeedsDto } from './dto/update-money-needs.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('money-needs') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('money-needs') +export class MoneyNeedsController { + constructor(private readonly moneyNeedsService: MoneyNeedsService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.moneyNeedsService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.moneyNeedsService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateMoneyNeedsDto) { + return this.moneyNeedsService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateMoneyNeedsDto) { + return this.moneyNeedsService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.moneyNeedsService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/money-needs/money-needs.module.ts b/backend/src/money-needs/money-needs.module.ts new file mode 100644 index 0000000..49a52e2 --- /dev/null +++ b/backend/src/money-needs/money-needs.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { MoneyNeedsService } from './money-needs.service'; +import { MoneyNeedsController } from './money-needs.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [MoneyNeedsController], + providers: [MoneyNeedsService, PrismaService], +}) +export class MoneyNeedsModule {} \ No newline at end of file diff --git a/backend/src/money-needs/money-needs.service.ts b/backend/src/money-needs/money-needs.service.ts new file mode 100644 index 0000000..fd15dff --- /dev/null +++ b/backend/src/money-needs/money-needs.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { MoneyNeeds, Prisma } from '@prisma/client'; + +@Injectable() +export class MoneyNeedsService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.MoneyNeedsWhereInput; + orderBy?: Prisma.MoneyNeedsOrderByWithRelationInput; + }): Promise<{ data: MoneyNeeds[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.moneyNeeds.findMany({ skip, take, where, orderBy }), + this.prisma.moneyNeeds.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.MoneyNeedsWhereUniqueInput): Promise { + return this.prisma.moneyNeeds.findUnique({ where }); + } + + async create(data: Prisma.MoneyNeedsCreateInput): Promise { + return this.prisma.moneyNeeds.create({ data }); + } + + async update(params: { + where: Prisma.MoneyNeedsWhereUniqueInput; + data: Prisma.MoneyNeedsUpdateInput; + }): Promise { + return this.prisma.moneyNeeds.update(params); + } + + async remove(where: Prisma.MoneyNeedsWhereUniqueInput): Promise { + return this.prisma.moneyNeeds.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..7bb37a4 --- /dev/null +++ b/backend/src/part/dto/create-part.dto.ts @@ -0,0 +1,32 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsOptional, IsNumber } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { CategoryPart } from '@prisma/client'; + +export class CreatePartDto { + @ApiProperty({ description: 'Название' }) + @IsString() + @IsNotEmpty() + name: string; + + @ApiProperty({ required: false, enum: CategoryPart, enumName: 'CategoryPart', description: 'Категории' }) + @IsEnum(CategoryPart) + @IsOptional() + categories?: CategoryPart; + + @ApiProperty({ required: false, description: 'Стоимость ЗИП/ТМЦ' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + price?: number; + + @ApiProperty({ required: false, description: 'Описание ЗИП/ТМЦ' }) + @IsString() + @IsOptional() + description?: string; + + @ApiProperty({ required: false, description: 'Серийный номер запасных частей / инструментов / расходников' }) + @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..de9e9af --- /dev/null +++ b/backend/src/part/part.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('id') id: string) { + return this.partService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreatePartDto) { + return this.partService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdatePartDto) { + return this.partService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + 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/price-list/dto/create-price-list.dto.ts b/backend/src/price-list/dto/create-price-list.dto.ts new file mode 100644 index 0000000..0b25692 --- /dev/null +++ b/backend/src/price-list/dto/create-price-list.dto.ts @@ -0,0 +1,17 @@ +import { Type } from 'class-transformer'; +import { IsNumber, IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class CreatePriceListDto { + @ApiProperty({ required: false, description: 'Стоимость часов работы' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + costOfWorkingHours?: number; + + @ApiProperty({ required: false, description: 'Стоимость ЗИП/ТМЦ' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + partPrice?: number; +} \ No newline at end of file diff --git a/backend/src/price-list/dto/update-price-list.dto.ts b/backend/src/price-list/dto/update-price-list.dto.ts new file mode 100644 index 0000000..8c35ba8 --- /dev/null +++ b/backend/src/price-list/dto/update-price-list.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreatePriceListDto } from './create-price-list.dto'; + +export class UpdatePriceListDto extends PartialType(CreatePriceListDto) {} \ No newline at end of file diff --git a/backend/src/price-list/price-list.controller.ts b/backend/src/price-list/price-list.controller.ts new file mode 100644 index 0000000..05dacd1 --- /dev/null +++ b/backend/src/price-list/price-list.controller.ts @@ -0,0 +1,54 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { PriceListService } from './price-list.service'; +import { CreatePriceListDto } from './dto/create-price-list.dto'; +import { UpdatePriceListDto } from './dto/update-price-list.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('price-list') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('price-list') +export class PriceListController { + constructor(private readonly priceListService: PriceListService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.priceListService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.priceListService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreatePriceListDto) { + return this.priceListService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdatePriceListDto) { + return this.priceListService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.priceListService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/price-list/price-list.module.ts b/backend/src/price-list/price-list.module.ts new file mode 100644 index 0000000..a7f9509 --- /dev/null +++ b/backend/src/price-list/price-list.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { PriceListService } from './price-list.service'; +import { PriceListController } from './price-list.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [PriceListController], + providers: [PriceListService, PrismaService], +}) +export class PriceListModule {} \ No newline at end of file diff --git a/backend/src/price-list/price-list.service.ts b/backend/src/price-list/price-list.service.ts new file mode 100644 index 0000000..3f9f484 --- /dev/null +++ b/backend/src/price-list/price-list.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { PriceList, Prisma } from '@prisma/client'; + +@Injectable() +export class PriceListService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.PriceListWhereInput; + orderBy?: Prisma.PriceListOrderByWithRelationInput; + }): Promise<{ data: PriceList[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.priceList.findMany({ skip, take, where, orderBy }), + this.prisma.priceList.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.PriceListWhereUniqueInput): Promise { + return this.prisma.priceList.findUnique({ where }); + } + + async create(data: Prisma.PriceListCreateInput): Promise { + return this.prisma.priceList.create({ data }); + } + + async update(params: { + where: Prisma.PriceListWhereUniqueInput; + data: Prisma.PriceListUpdateInput; + }): Promise { + return this.prisma.priceList.update(params); + } + + async remove(where: Prisma.PriceListWhereUniqueInput): Promise { + return this.prisma.priceList.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..5b77213 --- /dev/null +++ b/backend/src/repair-order/dto/create-repair-order.dto.ts @@ -0,0 +1,72 @@ +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional, IsDecimal, IsBoolean } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; +import { RepairKind, RepairOrderStatus } from '@prisma/client'; + +export class CreateRepairOrderDto { + @ApiProperty({ description: 'Номер заявки' }) + @IsString() + @IsNotEmpty() + number: string; + + @ApiProperty({ description: 'Дата заявки' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ description: 'Идентификатор оборудования' }) + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ enum: RepairKind, enumName: 'RepairKind', description: 'Вид ремонта' }) + @IsEnum(RepairKind) + repairKind: RepairKind; + + @ApiProperty({ enum: RepairOrderStatus, enumName: 'RepairOrderStatus', description: 'Статус заявки', default: RepairOrderStatus.Draft }) + @IsEnum(RepairOrderStatus) + @IsOptional() + status?: RepairOrderStatus; + + @ApiProperty({ description: 'Плановая дата начала' }) + @IsISO8601() + @Type(() => Date) + plannedAt: Date; + + @ApiProperty({ required: false, description: 'Фактическая дата начала' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + startedAt?: Date; + + @ApiProperty({ required: false, description: 'Фактическая дата завершения' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + completedAt?: Date; + + @ApiProperty({ required: false, description: 'Подрядная организация (если внешний ремонт)' }) + @IsString() + @IsOptional() + contractor?: string; + + @ApiProperty({ required: false, description: 'Наработка на момент ремонта, моточасов' }) + @IsDecimal() + @IsOptional() + engineHoursAtRepair?: string; + + @ApiProperty({ required: false, description: 'Описание работ / дефекта' }) + @IsString() + @IsOptional() + description?: string; + + @ApiProperty({ required: false, description: 'Примечания' }) + @IsString() + @IsOptional() + notes?: string; + + @ApiProperty({ required: false, description: 'Согласовано/Не согласовано' }) + @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..a8872f6 --- /dev/null +++ b/backend/src/repair-order/repair-order.controller.ts @@ -0,0 +1,54 @@ +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') + findOne(@Param('id') id: string) { + return this.repairOrderService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateRepairOrderDto) { + return this.repairOrderService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateRepairOrderDto) { + return this.repairOrderService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + 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/backend/src/resource-needs/dto/create-resource-needs.dto.ts b/backend/src/resource-needs/dto/create-resource-needs.dto.ts new file mode 100644 index 0000000..7ade3e8 --- /dev/null +++ b/backend/src/resource-needs/dto/create-resource-needs.dto.ts @@ -0,0 +1,16 @@ +import { IsArray, IsOptional, IsString } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateResourceNeedsDto { + @ApiProperty({ required: false, description: 'Массив кодов сотрудников' }) + @IsArray() + @IsString({ each: true }) + @IsOptional() + employeeCodes?: string[]; + + @ApiProperty({ required: false, description: 'Массив идентификаторов ЗИП/ТМЦ' }) + @IsArray() + @IsString({ each: true }) + @IsOptional() + partIds?: string[]; +} \ No newline at end of file diff --git a/backend/src/resource-needs/dto/update-resource-needs.dto.ts b/backend/src/resource-needs/dto/update-resource-needs.dto.ts new file mode 100644 index 0000000..2e2d915 --- /dev/null +++ b/backend/src/resource-needs/dto/update-resource-needs.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateResourceNeedsDto } from './create-resource-needs.dto'; + +export class UpdateResourceNeedsDto extends PartialType(CreateResourceNeedsDto) {} \ No newline at end of file diff --git a/backend/src/resource-needs/resource-needs.controller.ts b/backend/src/resource-needs/resource-needs.controller.ts new file mode 100644 index 0000000..8e6b3bc --- /dev/null +++ b/backend/src/resource-needs/resource-needs.controller.ts @@ -0,0 +1,54 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiQuery } from '@nestjs/swagger'; +import { ResourceNeedsService } from './resource-needs.service'; +import { CreateResourceNeedsDto } from './dto/create-resource-needs.dto'; +import { UpdateResourceNeedsDto } from './dto/update-resource-needs.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('resource-needs') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('resource-needs') +export class ResourceNeedsController { + constructor(private readonly resourceNeedsService: ResourceNeedsService) {} + + @Get() + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.resourceNeedsService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.resourceNeedsService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateResourceNeedsDto) { + return this.resourceNeedsService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateResourceNeedsDto) { + return this.resourceNeedsService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.resourceNeedsService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/resource-needs/resource-needs.module.ts b/backend/src/resource-needs/resource-needs.module.ts new file mode 100644 index 0000000..54d55e3 --- /dev/null +++ b/backend/src/resource-needs/resource-needs.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ResourceNeedsService } from './resource-needs.service'; +import { ResourceNeedsController } from './resource-needs.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [ResourceNeedsController], + providers: [ResourceNeedsService, PrismaService], +}) +export class ResourceNeedsModule {} \ No newline at end of file diff --git a/backend/src/resource-needs/resource-needs.service.ts b/backend/src/resource-needs/resource-needs.service.ts new file mode 100644 index 0000000..5345b4c --- /dev/null +++ b/backend/src/resource-needs/resource-needs.service.ts @@ -0,0 +1,74 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { ResourceNeeds, Prisma } from '@prisma/client'; + +@Injectable() +export class ResourceNeedsService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.ResourceNeedsWhereInput; + orderBy?: Prisma.ResourceNeedsOrderByWithRelationInput; + }): Promise<{ data: ResourceNeeds[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.resourceNeeds.findMany({ + skip, + take, + where, + orderBy, + include: { + employees: true, + parts: true, + } + }), + this.prisma.resourceNeeds.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.ResourceNeedsWhereUniqueInput): Promise { + return this.prisma.resourceNeeds.findUnique({ + where, + include: { + employees: true, + parts: true, + } + }); + } + + async create(data: Prisma.ResourceNeedsCreateInput): Promise { + return this.prisma.resourceNeeds.create({ + data, + include: { + employees: true, + parts: true, + } + }); + } + + async update(params: { + where: Prisma.ResourceNeedsWhereUniqueInput; + data: Prisma.ResourceNeedsUpdateInput; + }): Promise { + return this.prisma.resourceNeeds.update({ + ...params, + include: { + employees: true, + parts: true, + } + }); + } + + async remove(where: Prisma.ResourceNeedsWhereUniqueInput): Promise { + return this.prisma.resourceNeeds.delete({ + where, + include: { + employees: true, + parts: true, + } + }); + } +} \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx new file mode 100644 index 0000000..a939172 --- /dev/null +++ b/frontend/src/App.tsx @@ -0,0 +1,59 @@ +import { Admin, Resource } from 'react-admin'; +import { dataProvider } from './dataProvider'; +import { authProvider } from './authProvider'; + +// Equipment resources +import { EquipmentList, EquipmentEdit, EquipmentCreate, EquipmentShow } from './resources/equipment'; + +// Employee resources +import { EmployeeList, EmployeeEdit, EmployeeCreate, EmployeeShow } from './resources/employee'; + +// Part resources +import { PartList, PartEdit, PartCreate, PartShow } from './resources/part'; + +// CategoryResource resources +import { CategoryResourceList, CategoryResourceEdit, CategoryResourceCreate, CategoryResourceShow } from './resources/category-resource'; + +// RepairOrder resources +import { RepairOrderList, RepairOrderEdit, RepairOrderCreate, RepairOrderShow } from './resources/repair-order'; + +// ChangeEquipmentStatus resources +import { ChangeEquipmentStatusList, ChangeEquipmentStatusEdit, ChangeEquipmentStatusCreate, ChangeEquipmentStatusShow } from './resources/change-equipment-status'; + +// ConfirmationDocument resources +import { ConfirmationDocumentList, ConfirmationDocumentEdit, ConfirmationDocumentCreate, ConfirmationDocumentShow } from './resources/confirmation-document'; + +// ConsumptionRegistration resources +import { ConsumptionRegistrationList, ConsumptionRegistrationEdit, ConsumptionRegistrationCreate, ConsumptionRegistrationShow } from './resources/consumption-registration'; + +// MaintenancePlanning resources +import { MaintenancePlanningList, MaintenancePlanningEdit, MaintenancePlanningCreate, MaintenancePlanningShow } from './resources/maintenance-planning'; + +// ResourceNeeds resources +import { ResourceNeedsList, ResourceNeedsEdit, ResourceNeedsCreate, ResourceNeedsShow } from './resources/resource-needs'; + +// MoneyNeeds resources +import { MoneyNeedsList, MoneyNeedsEdit, MoneyNeedsCreate, MoneyNeedsShow } from './resources/money-needs'; + +const App = () => ( + + {/* Directories */} + + + + + + {/* Documents */} + + + + + + {/* Reports */} + + + + +); + +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..7a4e4db --- /dev/null +++ b/frontend/src/main.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; +import { initKeycloak } from './authProvider'; + +// Initialize Keycloak before rendering the app +initKeycloak().then(() => { + ReactDOM.createRoot(document.getElementById('root')!).render( + + + + ); +}).catch((error) => { + console.error('Failed to initialize Keycloak:', error); +}); \ 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..ffde200 --- /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..1b99902 --- /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..00ee0c2 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceList.tsx @@ -0,0 +1,12 @@ +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..f4b2f5c --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceShow.tsx @@ -0,0 +1,15 @@ +import { Show, SimpleShowLayout, TextField, ReferenceField } 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..fb6cf95 --- /dev/null +++ b/frontend/src/resources/category-resource/index.ts @@ -0,0 +1,4 @@ +export { CategoryResourceList } from './CategoryResourceList'; +export { CategoryResourceEdit } from './CategoryResourceEdit'; +export { CategoryResourceCreate } from './CategoryResourceCreate'; +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..87340bc --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx @@ -0,0 +1,24 @@ +import { Create, SimpleForm, TextInput, DateInput, SelectInput, ReferenceInput } from 'react-admin'; + +const statusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +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..4ced6d2 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx @@ -0,0 +1,25 @@ +import { Edit, SimpleForm, TextInput, DateInput, SelectInput, ReferenceInput } from 'react-admin'; + +const statusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +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..375695b --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx @@ -0,0 +1,17 @@ +import { List, DataTable, TextField, DateField, EditButton } from 'react-admin'; + +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..d7955a2 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx @@ -0,0 +1,18 @@ +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..06e12bd --- /dev/null +++ b/frontend/src/resources/change-equipment-status/index.ts @@ -0,0 +1,4 @@ +export { ChangeEquipmentStatusList } from './ChangeEquipmentStatusList'; +export { ChangeEquipmentStatusEdit } from './ChangeEquipmentStatusEdit'; +export { ChangeEquipmentStatusCreate } from './ChangeEquipmentStatusCreate'; +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..011bf09 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx @@ -0,0 +1,17 @@ +import { Create, SimpleForm, TextInput, DateInput, BooleanInput, ReferenceInput } 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..f523df4 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx @@ -0,0 +1,18 @@ +import { Edit, SimpleForm, TextInput, DateInput, BooleanInput, ReferenceInput } 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..99172b8 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx @@ -0,0 +1,15 @@ +import { List, DataTable, TextField, DateField, BooleanField, EditButton } 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..1d88376 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx @@ -0,0 +1,18 @@ +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..c9d7a3d --- /dev/null +++ b/frontend/src/resources/confirmation-document/index.ts @@ -0,0 +1,4 @@ +export { ConfirmationDocumentList } from './ConfirmationDocumentList'; +export { ConfirmationDocumentEdit } from './ConfirmationDocumentEdit'; +export { ConfirmationDocumentCreate } from './ConfirmationDocumentCreate'; +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..76baaf4 --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx @@ -0,0 +1,15 @@ +import { Create, SimpleForm, TextInput, DateInput, NumberInput, ReferenceInput } 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..e5ddd47 --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx @@ -0,0 +1,16 @@ +import { Edit, SimpleForm, TextInput, DateInput, NumberInput, ReferenceInput } 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..43378f8 --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx @@ -0,0 +1,15 @@ +import { List, DataTable, TextField, DateField, NumberField, EditButton } 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..6c4046a --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx @@ -0,0 +1,16 @@ +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..8c91522 --- /dev/null +++ b/frontend/src/resources/consumption-registration/index.ts @@ -0,0 +1,4 @@ +export { ConsumptionRegistrationList } from './ConsumptionRegistrationList'; +export { ConsumptionRegistrationEdit } from './ConsumptionRegistrationEdit'; +export { ConsumptionRegistrationCreate } from './ConsumptionRegistrationCreate'; +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..44226bf --- /dev/null +++ b/frontend/src/resources/employee/EmployeeCreate.tsx @@ -0,0 +1,23 @@ +import { Create, SimpleForm, TextInput, SelectInput, NumberInput, ReferenceInput } from 'react-admin'; + +const roleChoices = [ + { id: 'Исполнитель', name: 'Исполнитель' }, + { id: 'Подписант', name: 'Подписант' }, + { id: 'Пользователь', name: 'Пользователь' }, +]; + +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..c3ab727 --- /dev/null +++ b/frontend/src/resources/employee/EmployeeEdit.tsx @@ -0,0 +1,23 @@ +import { Edit, SimpleForm, TextInput, SelectInput, NumberInput, ReferenceInput } from 'react-admin'; + +const roleChoices = [ + { id: 'Исполнитель', name: 'Исполнитель' }, + { id: 'Подписант', name: 'Подписант' }, + { id: 'Пользователь', name: 'Пользователь' }, +]; + +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..81d680f --- /dev/null +++ b/frontend/src/resources/employee/EmployeeList.tsx @@ -0,0 +1,16 @@ +import { List, DataTable, TextField, NumberField, EditButton } from 'react-admin'; + +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..052504b --- /dev/null +++ b/frontend/src/resources/employee/EmployeeShow.tsx @@ -0,0 +1,17 @@ +import { Show, SimpleShowLayout, TextField, NumberField, 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..12954c2 --- /dev/null +++ b/frontend/src/resources/employee/index.ts @@ -0,0 +1,4 @@ +export { EmployeeList } from './EmployeeList'; +export { EmployeeEdit } from './EmployeeEdit'; +export { EmployeeCreate } from './EmployeeCreate'; +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..f01da1b --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentCreate.tsx @@ -0,0 +1,42 @@ +import { Create, SimpleForm, TextInput, DateInput, SelectInput, NumberInput } from 'react-admin'; + +const equipmentTypeChoices = [ + { id: 'Производственное', name: 'Производственное' }, + { id: 'Энергетическое', name: 'Энергетическое' }, + { id: 'Насосное', name: 'Насосное' }, + { id: 'Компрессорное', name: 'Компрессорное' }, +]; + +const periodicityTOChoices = [ + { id: 'Ежедневное', name: 'Ежедневное' }, + { id: 'Еженедельное', name: 'Еженедельное' }, + { id: 'Ежемесячное', name: 'Ежемесячное' }, + { id: 'Полугодовое', name: 'Полугодовое' }, + { id: 'Годовое', name: 'Годовое' }, +]; + +const statusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +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..a6e0ada --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentEdit.tsx @@ -0,0 +1,43 @@ +import { Edit, SimpleForm, TextInput, DateInput, SelectInput, NumberInput } from 'react-admin'; + +const equipmentTypeChoices = [ + { id: 'Производственное', name: 'Производственное' }, + { id: 'Энергетическое', name: 'Энергетическое' }, + { id: 'Насосное', name: 'Насосное' }, + { id: 'Компрессорное', name: 'Компрессорное' }, +]; + +const periodicityTOChoices = [ + { id: 'Ежедневное', name: 'Ежедневное' }, + { id: 'Еженедельное', name: 'Еженедельное' }, + { id: 'Ежемесячное', name: 'Ежемесячное' }, + { id: 'Полугодовое', name: 'Полугодовое' }, + { id: 'Годовое', name: 'Годовое' }, +]; + +const statusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +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..af7f177 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentList.tsx @@ -0,0 +1,22 @@ +import { List, DataTable, TextField, DateField, EditButton } from 'react-admin'; + +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..d373b96 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentShow.tsx @@ -0,0 +1,21 @@ +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..8b4fd08 --- /dev/null +++ b/frontend/src/resources/equipment/index.ts @@ -0,0 +1,4 @@ +export { EquipmentList } from './EquipmentList'; +export { EquipmentEdit } from './EquipmentEdit'; +export { EquipmentCreate } from './EquipmentCreate'; +export { EquipmentShow } from './EquipmentShow'; \ No newline at end of file diff --git a/frontend/src/resources/maintenance-planning/MaintenancePlanningCreate.tsx b/frontend/src/resources/maintenance-planning/MaintenancePlanningCreate.tsx new file mode 100644 index 0000000..b93acdb --- /dev/null +++ b/frontend/src/resources/maintenance-planning/MaintenancePlanningCreate.tsx @@ -0,0 +1,22 @@ +import { Create, SimpleForm, DateInput, SelectInput, ReferenceInput } from 'react-admin'; + +const repairKindChoices = [ + { id: 'TO', name: 'Техническое обслуживание' }, + { id: 'TR', name: 'Текущий ремонт' }, + { id: 'TRE', name: 'Текущий расширенный ремонт' }, + { id: 'KR', name: 'Капитальный ремонт' }, + { id: 'AR', name: 'Аварийный ремонт' }, + { id: 'MP', name: 'Метрологическая поверка' }, +]; + +export const MaintenancePlanningCreate = () => ( + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/maintenance-planning/MaintenancePlanningEdit.tsx b/frontend/src/resources/maintenance-planning/MaintenancePlanningEdit.tsx new file mode 100644 index 0000000..b4512a8 --- /dev/null +++ b/frontend/src/resources/maintenance-planning/MaintenancePlanningEdit.tsx @@ -0,0 +1,22 @@ +import { Edit, SimpleForm, DateInput, SelectInput, ReferenceInput } from 'react-admin'; + +const repairKindChoices = [ + { id: 'TO', name: 'Техническое обслуживание' }, + { id: 'TR', name: 'Текущий ремонт' }, + { id: 'TRE', name: 'Текущий расширенный ремонт' }, + { id: 'KR', name: 'Капитальный ремонт' }, + { id: 'AR', name: 'Аварийный ремонт' }, + { id: 'MP', name: 'Метрологическая поверка' }, +]; + +export const MaintenancePlanningEdit = () => ( + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/maintenance-planning/MaintenancePlanningList.tsx b/frontend/src/resources/maintenance-planning/MaintenancePlanningList.tsx new file mode 100644 index 0000000..7d29f67 --- /dev/null +++ b/frontend/src/resources/maintenance-planning/MaintenancePlanningList.tsx @@ -0,0 +1,13 @@ +import { List, DataTable, TextField, DateField, EditButton } from 'react-admin'; + +export const MaintenancePlanningList = () => ( + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/maintenance-planning/MaintenancePlanningShow.tsx b/frontend/src/resources/maintenance-planning/MaintenancePlanningShow.tsx new file mode 100644 index 0000000..b5c1953 --- /dev/null +++ b/frontend/src/resources/maintenance-planning/MaintenancePlanningShow.tsx @@ -0,0 +1,14 @@ +import { Show, SimpleShowLayout, TextField, DateField, ReferenceField } from 'react-admin'; + +export const MaintenancePlanningShow = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/maintenance-planning/index.ts b/frontend/src/resources/maintenance-planning/index.ts new file mode 100644 index 0000000..f130547 --- /dev/null +++ b/frontend/src/resources/maintenance-planning/index.ts @@ -0,0 +1,4 @@ +export { MaintenancePlanningList } from './MaintenancePlanningList'; +export { MaintenancePlanningEdit } from './MaintenancePlanningEdit'; +export { MaintenancePlanningCreate } from './MaintenancePlanningCreate'; +export { MaintenancePlanningShow } from './MaintenancePlanningShow'; \ No newline at end of file diff --git a/frontend/src/resources/money-needs/MoneyNeedsCreate.tsx b/frontend/src/resources/money-needs/MoneyNeedsCreate.tsx new file mode 100644 index 0000000..03d9beb --- /dev/null +++ b/frontend/src/resources/money-needs/MoneyNeedsCreate.tsx @@ -0,0 +1,10 @@ +import { Create, SimpleForm, NumberInput } from 'react-admin'; + +export const MoneyNeedsCreate = () => ( + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/money-needs/MoneyNeedsEdit.tsx b/frontend/src/resources/money-needs/MoneyNeedsEdit.tsx new file mode 100644 index 0000000..5b6c055 --- /dev/null +++ b/frontend/src/resources/money-needs/MoneyNeedsEdit.tsx @@ -0,0 +1,10 @@ +import { Edit, SimpleForm, NumberInput } from 'react-admin'; + +export const MoneyNeedsEdit = () => ( + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/money-needs/MoneyNeedsList.tsx b/frontend/src/resources/money-needs/MoneyNeedsList.tsx new file mode 100644 index 0000000..eafd710 --- /dev/null +++ b/frontend/src/resources/money-needs/MoneyNeedsList.tsx @@ -0,0 +1,12 @@ +import { List, DataTable, TextField, NumberField, EditButton } from 'react-admin'; + +export const MoneyNeedsList = () => ( + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/money-needs/MoneyNeedsShow.tsx b/frontend/src/resources/money-needs/MoneyNeedsShow.tsx new file mode 100644 index 0000000..d400498 --- /dev/null +++ b/frontend/src/resources/money-needs/MoneyNeedsShow.tsx @@ -0,0 +1,11 @@ +import { Show, SimpleShowLayout, TextField, NumberField } from 'react-admin'; + +export const MoneyNeedsShow = () => ( + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/money-needs/index.ts b/frontend/src/resources/money-needs/index.ts new file mode 100644 index 0000000..cd7da66 --- /dev/null +++ b/frontend/src/resources/money-needs/index.ts @@ -0,0 +1,4 @@ +export { MoneyNeedsList } from './MoneyNeedsList'; +export { MoneyNeedsEdit } from './MoneyNeedsEdit'; +export { MoneyNeedsCreate } from './MoneyNeedsCreate'; +export { MoneyNeedsShow } from './MoneyNeedsShow'; \ 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..b944604 --- /dev/null +++ b/frontend/src/resources/part/PartCreate.tsx @@ -0,0 +1,20 @@ +import { Create, SimpleForm, TextInput, SelectInput, NumberInput } from 'react-admin'; + +const categoryChoices = [ + { id: 'Расходник', name: 'Расходник' }, + { id: 'Запчасть', name: 'Запчасть' }, + { id: 'Инструмент', name: 'Инструмент' }, + { id: 'Спецодежда', name: 'Спецодежда' }, +]; + +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..4e2f87e --- /dev/null +++ b/frontend/src/resources/part/PartEdit.tsx @@ -0,0 +1,21 @@ +import { Edit, SimpleForm, TextInput, SelectInput, NumberInput } from 'react-admin'; + +const categoryChoices = [ + { id: 'Расходник', name: 'Расходник' }, + { id: 'Запчасть', name: 'Запчасть' }, + { id: 'Инструмент', name: 'Инструмент' }, + { id: 'Спецодежда', name: 'Спецодежда' }, +]; + +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..9b92be5 --- /dev/null +++ b/frontend/src/resources/part/PartList.tsx @@ -0,0 +1,15 @@ +import { List, DataTable, TextField, NumberField, EditButton } from 'react-admin'; + +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..63728f9 --- /dev/null +++ b/frontend/src/resources/part/PartShow.tsx @@ -0,0 +1,14 @@ +import { Show, SimpleShowLayout, TextField, NumberField } 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..41165fb --- /dev/null +++ b/frontend/src/resources/part/index.ts @@ -0,0 +1,4 @@ +export { PartList } from './PartList'; +export { PartEdit } from './PartEdit'; +export { PartCreate } from './PartCreate'; +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..671ae46 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderCreate.tsx @@ -0,0 +1,40 @@ +import { Create, SimpleForm, TextInput, DateInput, SelectInput, BooleanInput, ReferenceInput, NumberInput } from 'react-admin'; + +const repairKindChoices = [ + { id: 'TO', name: 'Техническое обслуживание' }, + { id: 'TR', name: 'Текущий ремонт' }, + { id: 'TRE', name: 'Текущий расширенный ремонт' }, + { id: 'KR', name: 'Капитальный ремонт' }, + { id: 'AR', name: 'Аварийный ремонт' }, + { id: 'MP', name: 'Метрологическая поверка' }, +]; + +const statusChoices = [ + { id: 'Draft', name: 'Черновик' }, + { id: 'Approved', name: 'Утверждена' }, + { id: 'InWork', name: 'В работе' }, + { id: 'Done', name: 'Выполнена' }, + { id: 'Cancelled', name: 'Отменена' }, +]; + +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..6f7ef12 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderEdit.tsx @@ -0,0 +1,41 @@ +import { Edit, SimpleForm, TextInput, DateInput, SelectInput, BooleanInput, ReferenceInput, NumberInput } from 'react-admin'; + +const repairKindChoices = [ + { id: 'TO', name: 'Техническое обслуживание' }, + { id: 'TR', name: 'Текущий ремонт' }, + { id: 'TRE', name: 'Текущий расширенный ремонт' }, + { id: 'KR', name: 'Капитальный ремонт' }, + { id: 'AR', name: 'Аварийный ремонт' }, + { id: 'MP', name: 'Метрологическая поверка' }, +]; + +const statusChoices = [ + { id: 'Draft', name: 'Черновик' }, + { id: 'Approved', name: 'Утверждена' }, + { id: 'InWork', name: 'В работе' }, + { id: 'Done', name: 'Выполнена' }, + { id: 'Cancelled', name: 'Отменена' }, +]; + +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..85df8c6 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderList.tsx @@ -0,0 +1,23 @@ +import { List, DataTable, TextField, DateField, BooleanField, EditButton } from 'react-admin'; + +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..5dbf3ec --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderShow.tsx @@ -0,0 +1,24 @@ +import { Show, SimpleShowLayout, TextField, DateField, BooleanField, NumberField, 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..d64ca86 --- /dev/null +++ b/frontend/src/resources/repair-order/index.ts @@ -0,0 +1,4 @@ +export { RepairOrderList } from './RepairOrderList'; +export { RepairOrderEdit } from './RepairOrderEdit'; +export { RepairOrderCreate } from './RepairOrderCreate'; +export { RepairOrderShow } from './RepairOrderShow'; \ No newline at end of file diff --git a/frontend/src/resources/resource-needs/ResourceNeedsCreate.tsx b/frontend/src/resources/resource-needs/ResourceNeedsCreate.tsx new file mode 100644 index 0000000..ef6c9c0 --- /dev/null +++ b/frontend/src/resources/resource-needs/ResourceNeedsCreate.tsx @@ -0,0 +1,14 @@ +import { Create, SimpleForm, ReferenceArrayInput, SelectArrayInput } from 'react-admin'; + +export const ResourceNeedsCreate = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/resource-needs/ResourceNeedsEdit.tsx b/frontend/src/resources/resource-needs/ResourceNeedsEdit.tsx new file mode 100644 index 0000000..ba49b61 --- /dev/null +++ b/frontend/src/resources/resource-needs/ResourceNeedsEdit.tsx @@ -0,0 +1,14 @@ +import { Edit, SimpleForm, ReferenceArrayInput, SelectArrayInput } from 'react-admin'; + +export const ResourceNeedsEdit = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/resource-needs/ResourceNeedsList.tsx b/frontend/src/resources/resource-needs/ResourceNeedsList.tsx new file mode 100644 index 0000000..a6824fa --- /dev/null +++ b/frontend/src/resources/resource-needs/ResourceNeedsList.tsx @@ -0,0 +1,10 @@ +import { List, DataTable, TextField, EditButton } from 'react-admin'; + +export const ResourceNeedsList = () => ( + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/resource-needs/ResourceNeedsShow.tsx b/frontend/src/resources/resource-needs/ResourceNeedsShow.tsx new file mode 100644 index 0000000..8e9c6fb --- /dev/null +++ b/frontend/src/resources/resource-needs/ResourceNeedsShow.tsx @@ -0,0 +1,19 @@ +import { Show, SimpleShowLayout, TextField, ReferenceArrayField, SingleFieldList, ChipField } from 'react-admin'; + +export const ResourceNeedsShow = () => ( + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/resource-needs/index.ts b/frontend/src/resources/resource-needs/index.ts new file mode 100644 index 0000000..b29fab0 --- /dev/null +++ b/frontend/src/resources/resource-needs/index.ts @@ -0,0 +1,4 @@ +export { ResourceNeedsList } from './ResourceNeedsList'; +export { ResourceNeedsEdit } from './ResourceNeedsEdit'; +export { ResourceNeedsCreate } from './ResourceNeedsCreate'; +export { ResourceNeedsShow } from './ResourceNeedsShow'; \ No newline at end of file