From 5500cdb11875191dcd7d11146567849688b7ef36 Mon Sep 17 00:00:00 2001 From: BOHA Date: Fri, 29 May 2026 14:08:00 +0200 Subject: [PATCH] feat(warehouse): add Prisma schema for warehouse module Add 13 warehouse models (sklad_categories, sklad_suppliers, sklad_locations, sklad_items, sklad_batches, sklad_item_locations, sklad_receipts, sklad_receipt_lines, sklad_receipt_attachments, sklad_issues, sklad_issue_lines, sklad_reservations, sklad_inventory_sessions, sklad_inventory_lines) and 4 enums (sklad_receipt_status, sklad_issue_status, sklad_reservation_status, sklad_inventory_status). Add reverse relations to projects and users models with named relations to avoid conflicts with existing relations. Co-Authored-By: Claude Opus 4.8 --- .../migration.sql | 277 ++++++++++++++++++ prisma/schema.prisma | 274 +++++++++++++++++ 2 files changed, 551 insertions(+) create mode 100644 prisma/migrations/20260529000001_add_warehouse_module/migration.sql diff --git a/prisma/migrations/20260529000001_add_warehouse_module/migration.sql b/prisma/migrations/20260529000001_add_warehouse_module/migration.sql new file mode 100644 index 0000000..b494442 --- /dev/null +++ b/prisma/migrations/20260529000001_add_warehouse_module/migration.sql @@ -0,0 +1,277 @@ +-- CreateTable +CREATE TABLE `sklad_categories` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `name` VARCHAR(100) NOT NULL, + `description` TEXT NULL, + `sort_order` INTEGER NOT NULL DEFAULT 0, + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_suppliers` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `ico` VARCHAR(20) NULL, + `dic` VARCHAR(20) NULL, + `contact_person` VARCHAR(255) NULL, + `email` VARCHAR(255) NULL, + `phone` VARCHAR(50) NULL, + `address` TEXT NULL, + `notes` TEXT NULL, + `is_active` BOOLEAN NOT NULL DEFAULT true, + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_locations` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `code` VARCHAR(20) NOT NULL, + `name` VARCHAR(100) NOT NULL, + `description` TEXT NULL, + `is_active` BOOLEAN NOT NULL DEFAULT true, + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + UNIQUE INDEX `sklad_locations_code_key`(`code`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_items` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `item_number` VARCHAR(50) NULL, + `name` VARCHAR(255) NOT NULL, + `description` TEXT NULL, + `category_id` INTEGER NULL, + `unit` VARCHAR(20) NOT NULL, + `min_quantity` DECIMAL(12, 3) NULL, + `is_active` BOOLEAN NOT NULL DEFAULT true, + `notes` TEXT NULL, + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + UNIQUE INDEX `sklad_items_item_number_key`(`item_number`), + INDEX `sklad_items_category_id`(`category_id`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_batches` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `item_id` INTEGER NOT NULL, + `receipt_line_id` INTEGER NOT NULL, + `quantity` DECIMAL(12, 3) NOT NULL, + `original_qty` DECIMAL(12, 3) NOT NULL, + `unit_price` DECIMAL(12, 2) NOT NULL, + `received_at` DATETIME(0) NULL, + `is_consumed` BOOLEAN NOT NULL DEFAULT false, + + UNIQUE INDEX `sklad_batches_receipt_line_id_key`(`receipt_line_id`), + INDEX `sklad_batches_fifo`(`item_id`, `is_consumed`, `received_at`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_item_locations` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `item_id` INTEGER NOT NULL, + `location_id` INTEGER NOT NULL, + `quantity` DECIMAL(12, 3) NOT NULL DEFAULT 0, + + UNIQUE INDEX `sklad_item_locations_unique`(`item_id`, `location_id`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_receipts` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `receipt_number` VARCHAR(50) NULL, + `supplier_id` INTEGER NULL, + `delivery_note_number` VARCHAR(100) NULL, + `delivery_note_date` DATETIME(0) NULL, + `received_by` INTEGER NULL, + `notes` TEXT NULL, + `status` ENUM('DRAFT', 'CONFIRMED', 'CANCELLED') NOT NULL DEFAULT 'DRAFT', + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_receipt_lines` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `receipt_id` INTEGER NOT NULL, + `item_id` INTEGER NOT NULL, + `quantity` DECIMAL(12, 3) NOT NULL, + `unit_price` DECIMAL(12, 2) NOT NULL, + `location_id` INTEGER NULL, + `notes` VARCHAR(255) NULL, + + INDEX `sklad_receipt_lines_receipt_id`(`receipt_id`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_receipt_attachments` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `receipt_id` INTEGER NOT NULL, + `file_name` VARCHAR(255) NOT NULL, + `file_mime` VARCHAR(100) NOT NULL, + `file_size` INTEGER NOT NULL, + `file_path` VARCHAR(500) NOT NULL, + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_issues` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `issue_number` VARCHAR(50) NULL, + `project_id` INTEGER NOT NULL, + `issued_by` INTEGER NULL, + `notes` TEXT NULL, + `status` ENUM('DRAFT', 'CONFIRMED', 'CANCELLED') NOT NULL DEFAULT 'DRAFT', + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_issue_lines` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `issue_id` INTEGER NOT NULL, + `item_id` INTEGER NOT NULL, + `batch_id` INTEGER NOT NULL, + `quantity` DECIMAL(12, 3) NOT NULL, + `location_id` INTEGER NULL, + `reservation_id` INTEGER NULL, + `notes` VARCHAR(255) NULL, + + INDEX `sklad_issue_lines_issue_id`(`issue_id`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_reservations` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `item_id` INTEGER NOT NULL, + `project_id` INTEGER NOT NULL, + `quantity` DECIMAL(12, 3) NOT NULL, + `remaining_qty` DECIMAL(12, 3) NOT NULL, + `reserved_by` INTEGER NULL, + `notes` TEXT NULL, + `status` ENUM('ACTIVE', 'FULFILLED', 'CANCELLED') NOT NULL DEFAULT 'ACTIVE', + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + INDEX `sklad_reservations_item_status`(`item_id`, `status`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_inventory_sessions` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `session_number` VARCHAR(50) NULL, + `notes` TEXT NULL, + `status` ENUM('DRAFT', 'CONFIRMED') NOT NULL DEFAULT 'DRAFT', + `created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `modified_at` DATETIME(0) NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `sklad_inventory_lines` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `session_id` INTEGER NOT NULL, + `item_id` INTEGER NOT NULL, + `location_id` INTEGER NULL, + `system_qty` DECIMAL(12, 3) NOT NULL, + `actual_qty` DECIMAL(12, 3) NOT NULL, + `difference` DECIMAL(12, 3) NOT NULL, + `notes` VARCHAR(255) NULL, + + INDEX `sklad_inventory_lines_session_id`(`session_id`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `sklad_items` ADD CONSTRAINT `sklad_items_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `sklad_categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_batches` ADD CONSTRAINT `sklad_batches_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_batches` ADD CONSTRAINT `sklad_batches_receipt_line_id_fkey` FOREIGN KEY (`receipt_line_id`) REFERENCES `sklad_receipt_lines`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_item_locations` ADD CONSTRAINT `sklad_item_locations_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_item_locations` ADD CONSTRAINT `sklad_item_locations_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_receipts` ADD CONSTRAINT `sklad_receipts_supplier_id_fkey` FOREIGN KEY (`supplier_id`) REFERENCES `sklad_suppliers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_receipts` ADD CONSTRAINT `sklad_receipts_received_by_fkey` FOREIGN KEY (`received_by`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_receipt_id_fkey` FOREIGN KEY (`receipt_id`) REFERENCES `sklad_receipts`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_receipt_attachments` ADD CONSTRAINT `sklad_receipt_attachments_receipt_id_fkey` FOREIGN KEY (`receipt_id`) REFERENCES `sklad_receipts`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_issues` ADD CONSTRAINT `sklad_issues_project_id_fkey` FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_issues` ADD CONSTRAINT `sklad_issues_issued_by_fkey` FOREIGN KEY (`issued_by`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_issue_id_fkey` FOREIGN KEY (`issue_id`) REFERENCES `sklad_issues`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_batch_id_fkey` FOREIGN KEY (`batch_id`) REFERENCES `sklad_batches`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_reservation_id_fkey` FOREIGN KEY (`reservation_id`) REFERENCES `sklad_reservations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_reservations` ADD CONSTRAINT `sklad_reservations_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_reservations` ADD CONSTRAINT `sklad_reservations_project_id_fkey` FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_reservations` ADD CONSTRAINT `sklad_reservations_reserved_by_fkey` FOREIGN KEY (`reserved_by`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_session_id_fkey` FOREIGN KEY (`session_id`) REFERENCES `sklad_inventory_sessions`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1315fef..d672606 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -357,6 +357,8 @@ model projects { modified_at DateTime? @db.DateTime(0) attendance_project_logs attendance_project_logs[] project_notes project_notes[] + sklad_issues sklad_issues[] + sklad_reservations sklad_reservations[] users users? @relation(fields: [responsible_user_id], references: [id], onUpdate: NoAction, map: "fk_projects_responsible_user") customers customers? @relation(fields: [customer_id], references: [id], onUpdate: NoAction, map: "projects_ibfk_1") quotations quotations? @relation(fields: [quotation_id], references: [id], onUpdate: NoAction, map: "projects_ibfk_2") @@ -580,6 +582,9 @@ model users { leave_requests_leave_requests_reviewer_idTousers leave_requests[] @relation("leave_requests_reviewer_idTousers") projects projects[] trips trips[] + sklad_receipts_received sklad_receipts[] @relation("SkladReceivedBy") + sklad_issues_issued sklad_issues[] @relation("SkladIssuedBy") + sklad_reservations sklad_reservations[] @relation("SkladReservedBy") roles roles? @relation(fields: [role_id], references: [id], onUpdate: NoAction, map: "users_ibfk_1") @@index([is_active], map: "idx_users_is_active") @@ -637,3 +642,272 @@ enum attendance_leave_type { holiday unpaid } + +enum sklad_receipt_status { + DRAFT + CONFIRMED + CANCELLED +} + +enum sklad_issue_status { + DRAFT + CONFIRMED + CANCELLED +} + +enum sklad_reservation_status { + ACTIVE + FULFILLED + CANCELLED +} + +enum sklad_inventory_status { + DRAFT + CONFIRMED +} + +model sklad_categories { + id Int @id @default(autoincrement()) + name String @db.VarChar(100) + description String? @db.Text + sort_order Int @default(0) + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + items sklad_items[] + + @@map("sklad_categories") +} + +model sklad_suppliers { + id Int @id @default(autoincrement()) + name String @db.VarChar(255) + ico String? @db.VarChar(20) + dic String? @db.VarChar(20) + contact_person String? @db.VarChar(255) + email String? @db.VarChar(255) + phone String? @db.VarChar(50) + address String? @db.Text + notes String? @db.Text + is_active Boolean @default(true) + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + receipts sklad_receipts[] + + @@map("sklad_suppliers") +} + +model sklad_locations { + id Int @id @default(autoincrement()) + code String @unique @db.VarChar(20) + name String @db.VarChar(100) + description String? @db.Text + is_active Boolean @default(true) + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + items sklad_item_locations[] + receipt_lines sklad_receipt_lines[] + issue_lines sklad_issue_lines[] + inventory_lines sklad_inventory_lines[] + + @@map("sklad_locations") +} + +model sklad_items { + id Int @id @default(autoincrement()) + item_number String? @unique @db.VarChar(50) + name String @db.VarChar(255) + description String? @db.Text + category_id Int? + unit String @db.VarChar(20) + min_quantity Decimal? @db.Decimal(12, 3) + is_active Boolean @default(true) + notes String? @db.Text + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + category sklad_categories? @relation(fields: [category_id], references: [id]) + batches sklad_batches[] + item_locations sklad_item_locations[] + receipt_lines sklad_receipt_lines[] + issue_lines sklad_issue_lines[] + reservations sklad_reservations[] + inventory_lines sklad_inventory_lines[] + + @@index([category_id], map: "sklad_items_category_id") + @@map("sklad_items") +} + +model sklad_batches { + id Int @id @default(autoincrement()) + item_id Int + receipt_line_id Int @unique + quantity Decimal @db.Decimal(12, 3) + original_qty Decimal @db.Decimal(12, 3) + unit_price Decimal @db.Decimal(12, 2) + received_at DateTime? @db.DateTime(0) + is_consumed Boolean @default(false) + + item sklad_items @relation(fields: [item_id], references: [id]) + receipt_line sklad_receipt_lines @relation(fields: [receipt_line_id], references: [id]) + issue_lines sklad_issue_lines[] + + @@index([item_id, is_consumed, received_at], map: "sklad_batches_fifo") + @@map("sklad_batches") +} + +model sklad_item_locations { + id Int @id @default(autoincrement()) + item_id Int + location_id Int + quantity Decimal @default(0) @db.Decimal(12, 3) + + item sklad_items @relation(fields: [item_id], references: [id]) + location sklad_locations @relation(fields: [location_id], references: [id]) + + @@unique([item_id, location_id], map: "sklad_item_locations_unique") + @@map("sklad_item_locations") +} + +model sklad_receipts { + id Int @id @default(autoincrement()) + receipt_number String? @db.VarChar(50) + supplier_id Int? + delivery_note_number String? @db.VarChar(100) + delivery_note_date DateTime? @db.DateTime(0) + received_by Int? + notes String? @db.Text + status sklad_receipt_status @default(DRAFT) + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + supplier sklad_suppliers? @relation(fields: [supplier_id], references: [id]) + received_by_user users? @relation("SkladReceivedBy", fields: [received_by], references: [id]) + lines sklad_receipt_lines[] + attachments sklad_receipt_attachments[] + + @@map("sklad_receipts") +} + +model sklad_receipt_lines { + id Int @id @default(autoincrement()) + receipt_id Int + item_id Int + quantity Decimal @db.Decimal(12, 3) + unit_price Decimal @db.Decimal(12, 2) + location_id Int? + notes String? @db.VarChar(255) + + receipt sklad_receipts @relation(fields: [receipt_id], references: [id]) + item sklad_items @relation(fields: [item_id], references: [id]) + location sklad_locations? @relation(fields: [location_id], references: [id]) + batch sklad_batches? + + @@index([receipt_id], map: "sklad_receipt_lines_receipt_id") + @@map("sklad_receipt_lines") +} + +model sklad_receipt_attachments { + id Int @id @default(autoincrement()) + receipt_id Int + file_name String @db.VarChar(255) + file_mime String @db.VarChar(100) + file_size Int + file_path String @db.VarChar(500) + created_at DateTime? @default(now()) @db.DateTime(0) + + receipt sklad_receipts @relation(fields: [receipt_id], references: [id]) + + @@map("sklad_receipt_attachments") +} + +model sklad_issues { + id Int @id @default(autoincrement()) + issue_number String? @db.VarChar(50) + project_id Int + issued_by Int? + notes String? @db.Text + status sklad_issue_status @default(DRAFT) + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + project projects @relation(fields: [project_id], references: [id]) + issued_by_user users? @relation("SkladIssuedBy", fields: [issued_by], references: [id]) + lines sklad_issue_lines[] + + @@map("sklad_issues") +} + +model sklad_issue_lines { + id Int @id @default(autoincrement()) + issue_id Int + item_id Int + batch_id Int + quantity Decimal @db.Decimal(12, 3) + location_id Int? + reservation_id Int? + notes String? @db.VarChar(255) + + issue sklad_issues @relation(fields: [issue_id], references: [id]) + item sklad_items @relation(fields: [item_id], references: [id]) + batch sklad_batches @relation(fields: [batch_id], references: [id]) + location sklad_locations? @relation(fields: [location_id], references: [id]) + reservation sklad_reservations? @relation(fields: [reservation_id], references: [id]) + + @@index([issue_id], map: "sklad_issue_lines_issue_id") + @@map("sklad_issue_lines") +} + +model sklad_reservations { + id Int @id @default(autoincrement()) + item_id Int + project_id Int + quantity Decimal @db.Decimal(12, 3) + remaining_qty Decimal @db.Decimal(12, 3) + reserved_by Int? + notes String? @db.Text + status sklad_reservation_status @default(ACTIVE) + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + item sklad_items @relation(fields: [item_id], references: [id]) + project projects @relation(fields: [project_id], references: [id]) + reserved_by_user users? @relation("SkladReservedBy", fields: [reserved_by], references: [id]) + issue_lines sklad_issue_lines[] + + @@index([item_id, status], map: "sklad_reservations_item_status") + @@map("sklad_reservations") +} + +model sklad_inventory_sessions { + id Int @id @default(autoincrement()) + session_number String? @db.VarChar(50) + notes String? @db.Text + status sklad_inventory_status @default(DRAFT) + created_at DateTime? @default(now()) @db.DateTime(0) + modified_at DateTime? @db.DateTime(0) + + lines sklad_inventory_lines[] + + @@map("sklad_inventory_sessions") +} + +model sklad_inventory_lines { + id Int @id @default(autoincrement()) + session_id Int + item_id Int + location_id Int? + system_qty Decimal @db.Decimal(12, 3) + actual_qty Decimal @db.Decimal(12, 3) + difference Decimal @db.Decimal(12, 3) + notes String? @db.VarChar(255) + + session sklad_inventory_sessions @relation(fields: [session_id], references: [id]) + item sklad_items @relation(fields: [item_id], references: [id]) + location sklad_locations? @relation(fields: [location_id], references: [id]) + + @@index([session_id], map: "sklad_inventory_lines_session_id") + @@map("sklad_inventory_lines") +}