Модуль управления запчастями добавляет полнофункциональную систему для:
ВАЖНО: Каталог запчастей является общим для всех лет. Одна запчасть (по артикулу) существует во всех годах, но количества рассчитываются только для текущего выбранного года.
Доступ: Меню → Запчасти → вкладка "Каталог"
Функции:
Вычисляемые поля:
Кликабельные ячейки: Клик по ячейке с количеством открывает вкладку "Заказы деталей" с автоматическим фильтром по:
ВАЖНО: Заказы разделены по годам. Каждый заказ принадлежит конкретному году.
Доступ: Меню → Запчасти → вкладка "Заказы деталей"
Функции:
Статусы заказа:
История списаний:
Доступ: Меню → Запчасти → вкладка "Контроль наличия"
Две таблицы:
Критический недостаток (красные строки):
Ниже минимального остатка (желтые строки):
Автоматическое списание: При добавлении детали в рекламацию система:
Чекбокс "С док.":
Доступ: Меню → Запчасти → (отдельный раздел, только для admin)
Функции:
КРИТИЧНО ВАЖНО:
spare_parts НЕ имеет поле yearSparePart НЕ использует YearScopespare_part_orders имеет поле yearSparePartOrder использует YearScopequantity_without_docs, quantity_with_docs) в модели SparePartyear()Пример:
// Запчасть "BOLT-001" существует одна
$sparePart = SparePart::where('article', 'BOLT-001')->first();
// Год 2024: есть заказ на 100 шт
session(['year' => 2024]);
echo $sparePart->total_quantity; // 100
// Год 2025: есть заказ на 50 шт
session(['year' => 2025]);
echo $sparePart->total_quantity; // 50
// Год 2026: нет заказов
session(['year' => 2026]);
echo $sparePart->total_quantity; // 0
spare_parts - каталог запчастей (БЕЗ year)spare_part_orders - заказы деталей (С year)spare_part_order_shipments - история списаний (БЕЗ year, привязана к заказу)pricing_codes - справочник расценокreclamation_spare_part - pivot таблица запчасти-рекламацииspare_part_orders_view - представление для заказов с join'амиExportSparePartsJob)/templates/SpareParts.xlsx| ID | Артикул | Где используется | Кол-во без док | Кол-во с док | Кол-во общее | Примечание | Цена закупки | Цена для заказчика | Цена экспертизы | № по ТСН | Шифр расценки | Минимальный остаток |
Расположение: /public/images/spare_parts/
Формат имени: {article}.jpg
Пример: TEST-001.jpg
Загрузка:
SparePartInventoryService - логика автосписания и контроляExport/ExportSparePartsService - экспорт в ExcelExport/ExportSparePartsJob - фоновая задача экспортаStoreSparePartRequest - валидация запчастиStoreSparePartOrderRequest - валидация заказаShipSparePartOrderRequest - валидация отгрузкиStoreReclamationDetailsRequest - обновлён для поддержки with_documentsSparePartController - каталогSparePartOrderController - заказыSparePartInventoryController - контроль наличияPricingCodeController - справочник расценокReclamationController - обновлён для интеграции// Каталог
GET /spare-parts
POST /spare-parts (admin)
GET /spare-parts/create (admin)
GET /spare-parts/{id}
PUT /spare-parts/{id} (admin)
DELETE /spare-parts/{id} (admin)
POST /spare-parts/export (admin)
POST /spare-parts/{id}/upload-image (admin)
// Заказы
GET /spare-part-orders
POST /spare-part-orders (admin, manager)
GET /spare-part-orders/create (admin, manager)
GET /spare-part-orders/{id}
PUT /spare-part-orders/{id} (admin, manager)
DELETE /spare-part-orders/{id} (admin)
POST /spare-part-orders/{id}/ship (admin, manager)
POST /spare-part-orders/{id}/set-in-stock (admin, manager)
// Контроль
GET /spare-part-inventory
// Справочник
GET /pricing-codes (admin)
POST /pricing-codes (admin)
PUT /pricing-codes/{id} (admin)
DELETE /pricing-codes/{id} (admin)
// API
GET /api/pricing-codes/{code}
docker exec dkr-app-1 php artisan tinker
// Создать запчасть
$sp = SparePart::create([
'article' => 'TEST-001',
'used_in_maf' => 'Качели',
'customer_price' => 150.00,
'min_stock' => 10
]);
// Создать заказ
$order = SparePartOrder::create([
'spare_part_id' => $sp->id,
'source_text' => 'Поставщик А',
'status' => 'in_stock',
'ordered_quantity' => 100,
'with_documents' => true,
'user_id' => 1
]);
// Проверить количество
echo $sp->quantity_with_docs; // 100
$service = new SparePartInventoryService();
$service->deductForReclamation('TEST-001', 10, true, $reclamationId);
// Проверить
$sp->refresh();
echo $sp->quantity_with_docs; // 90