Перемещения (Raw, WIP, Finished): Как осветить «слепую зону» производства

Разбираем архитектуру StockTransfer. Почему выдача материалов в цех — это не списание, и как двойная запись спасает ваши миллионы.

На большинстве заводов Склад Сырья (Raw Materials) — это священное место. Там висят камеры, сидит строгий кладовщик, а на дверях замок. Но как только материал выдается мастеру в цех, он попадает в «слепую зону» — Незавершенное производство (WIP - Work in Progress).

В старых учетных системах выдача в цех оформляется как Списание. То есть актив буквально исчезает с баланса компании. Вы не знаете, превратился ли этот металл в станок, лежит ли он под верстаком или уже сдан в металлолом предприимчивым сварщиком.

В ModernERP Pro выдача в цех — это не списание. Это перемещение актива из одного кармана компании в другой.

Топология трех складов

Для наведения порядка мы рекомендуем виртуально или физически разделить завод минимум на три зоны (Склада):

  1. RAW (Сырье): Хранит закупленные материалы.
  2. WIP (Цеховая кладовая): Хранит материалы, находящиеся в работе, и полуфабрикаты. Зона ответственности начальника производства.
  3. Finished Goods (СГ): Склад готовой продукции, ожидающей отгрузки клиенту.

Архитектура документа StockTransfer

Перемещение между этими зонами оформляется сущностью `StockTransfer`. Это не просто бумажка, это сложный финансовый транзакционный механизм.

1. Перемещаем не номенклатуру, а Партии (Batches)

Взгляните на структуру `StockTransferItem` в нашем ядре. Строка перемещения ссылается не просто на товар, она ссылается на конкретную Партию (`Batch`).

Почему это критически важно? Когда лист стали переезжает со Склада Сырья в WIP-кладовую, он забирает с собой свою закупочную цену. Это гарантирует, что алгоритм Cost Roll-up посчитает себестоимость изделия из правильных денег, а не из "среднерыночных" фантазий.

2. Защита от баз данных "с привидениями"

При редактировании перемещений часто возникает проблема: пользователь удалил строку в интерфейсе, а в базе данных она осталась "висеть" как сирота. В сущности `StockTransfer` мы применили жесткое правило ORM:

// Фрагмент из StockTransfer.php
#[ORM\OneToMany(
    targetEntity: StockTransferItem::class,
    mappedBy: 'stockTransfer',
    cascade: ['persist', 'remove'],
    orphanRemoval: true // <--- Уничтожает "зависшие" строки
)]
private $items;

Транзакция в Ledger: Принцип двойной записи

Самое интересное происходит в контроллере `StockTransferController` в момент проведения документа. Когда перемещение получает статус `COMPLETED`, алгоритм генерирует не одну, а две записи в `StockMovement` (наш Ledger).

🛠 Идеальный баланс

Метод createMovement вызывается дважды для каждой строки:

  • Первый вызов: qty < 0 → генерирует StockMovementType::OUT (Расход) со Склада А.
  • Второй вызов: qty > 0 → генерирует StockMovementType::IN (Приход) на Склад Б.

В результате баланс компании (Total Assets) не меняется ни на копейку, но материальная ответственность переходит от Кладовщика к Начальнику цеха.

Защита от конфликтов ("Я отправил!" — "Я не получал!")

Чтобы исключить споры между сотрудниками, `StockTransfer` имеет встроенный State Machine (конечный автомат) статусов:

  • Draft (Черновик): Кладовщик собирает паллету.
  • Sent (Отправлено): Груз уехал. Списано с RAW, но еще не появилось в WIP. Товар "в пути".
  • Completed (Завершено): Мастер цеха принял паллету, пересчитал и нажал кнопку. Только в этот момент товар падает на баланс WIP и появляется в поле зрения сборщиков. Поле `completedBy` навсегда записывает, кто именно принял ответственность.
С прозрачным WIP-складом вы перестаете покупать сырье «на всякий случай». Вы точно знаете, что металл есть, и он лежит у станка ЧПУ.

Транзакция перемещения

Партия: Стальной лист 3мм (Batch #12)

Статус документа:
Draft (Черновик)
Склад RAW
Ответственность: Кладовщик
500
шт. в наличии
В Пути (Sent)
Ответственность: Транзит
0
шт. перемещается
Склад WIP
Ответственность: Мастер цеха
0
шт. в цеху
Системный лог проводок (Ledger)
СистемаИнициализация остатков. RAW: 500 шт.

Чек-лист: 10 дыр в цеху, через которые утекает ваша прибыль

Не готовы к аудиту? Начните с самодиагностики. Мы собрали 10 неочевидных признаков того, что мастера водят вас за нос, а НЗП съедает оборотку предприятия.

  • Как за 5 минут проверить, есть ли на складе неликвиды.
  • 3 неудобных вопроса мастеру, чтобы вскрыть приписки.
  • Тест на «узкое горлышко»: почему склад готовой продукции пуст.
Откроем материал сразу. Без рассылок.