Схемы Что нового

Склад — учёт ТМЦ и оборудования

Склад (/admin/stock/) — универсальный учёт ТМЦ и оборудования провайдера: от закупки до установки у клиента. Каждое перемещение — неизменяемая запись-движение (как финансовые операции: не правим, а сторнируем), поэтому остатки всегда сходятся, а история — доказуема. Модуль интегрирован с нарядами монтажника, карточкой клиента и деньгами: продажа списывает с лицевого счёта, аренда начисляется ежемесячно.

Модуль «Склад» — на сайте продукта
Содержание раздела
Обучающее видео 2:58

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

1920×1080 с озвучкой Скачать

Как устроен модуль

Ядро модели — цепочка держателей. Товар (или конкретная серийная единица) в каждый момент времени находится у одного держателя: на складе, в подотчёте сотрудника или у клиента. Перемещения между держателями фиксируются движениями:

flowchart LR
    P["📦 Закупка
(накладная, поставщик)"] -->|"приход (receipt)"| W["🏬 Склад
остатки · min_stock"] W -->|"выдача (issue)"| S["🧰 Подотчёт сотрудника
монтажник · скан"] S -->|"установка (install)"| C["👤 Клиент
ответхранение · продажа · аренда"] S -->|"возврат (return)"| W C -->|"демонтаж"| W W -->|"акт брака (defect)"| D["🗑 Брак"] S -->|"акт брака"| D style W fill:#e8f5e9,stroke:#43b77a,color:#1b1b1b style C fill:#e7f0fb,stroke:#0d6efd,color:#1b1b1b style D fill:#fdecea,stroke:#dc3545,color:#1b1b1b

Два типа учёта в одной модели:

Остатки — сводная с подсветкой ниже минимума
Остатки — сводная с подсветкой ниже минимума
Как связан с остальной системой. Склад — не изолированный реестр: списание материалов происходит прямо из наряда монтажника (CRM), установленное оборудование видно в карточке клиента, продажа создаёт финансовую операцию, аренда — периодическую услугу, а низкие остатки прилетают в Telegram.
flowchart TB
    ST["📦 Склад
номенклатура · единицы · движения"] CRM["🛠 Наряд монтажа (CRM)
кнопка «Материалы»"] AB["👤 Карточка клиента
вкладка «Оборудование»"] FIN["💰 Финансы
FinanceOperations"] UU["🔁 Услуги клиента
UsersUsluga «Аренда оборудования»"] BW["⚙️ billing_worker
ежемесячные списания"] TG["✈️ Telegram
алерт min_stock"] AUD["🗒 Аудит
каждое движение"] CRM -->|"install (ref: deal#N)"| ST AB -->|"install / демонтаж"| ST ST -->|"продажа: −sale_price"| FIN ST -->|"аренда: услуга rent_price/мес"| UU UU --> BW ST --> TG ST --> AUD style ST fill:#e8f5e9,stroke:#43b77a,stroke-width:2px,color:#1b1b1b

Быстрый старт

  1. Включите модуль «Склад» на /admin/settings/modules/ и тумблер STOCK_ENABLED в настройках (категория «Склад»).
  2. Добавьте кладовщика в группу storekeeper (настройка STOCK_KEEPER_GROUPS); монтажников — в группы из STOCK_HOLDER_GROUPS.
  3. Заведите категории и номенклатуру (/admin/stock/items/) — или посмотрите на демо-данных: manage.py seed_stock_demo (удаление — --clear).
  4. Проведите стартовую инвентаризацию: приход с типом «инвентаризация (correction)» на текущие остатки.
  5. Распечатайте этикетки на серийные единицы и выдайте монтажникам их текущее «железо» в подотчёт.

Движения и статусы единиц

Движение (StockMovement) — append-only запись: тип, позиция, количество, откуда → куда, цена, документ, привязка к наряду (ref_type/ref_id). Ошиблись — нажимаете сторно: создаётся обратная запись, а единица возвращается к держателю-источнику. Серийная единица (StockUnit) дополнительно несёт статус:

stateDiagram-v2
    [*] --> in_stock: приход
    in_stock --> issued: выдача в подотчёт
    issued --> in_stock: возврат
    in_stock --> installed: установка (кладовщик)
    issued --> installed: установка (custody)
    issued --> sold: продажа
    issued --> rented: аренда
    installed --> in_stock: демонтаж
    rented --> in_stock: демонтаж (аренда закрывается)
    issued --> defect: акт брака
    in_stock --> defect: акт брака

В журнале — фильтры по типу движения и по сотруднику (показываются все движения, где он «откуда», «куда» или «кто провёл»); клик по любой фамилии в таблице подставляет её в фильтр. Колонка S/N — единая иконка штрихкода (во всех таблицах модуля): тултип показывает серийник, MAC и штрихкод, клик открывает карточку движения со всеми деталями. Даты — компактно «дд.мм.гг», полная дата в тултипе.

Журнал движений: карточка движения — откуда, куда, наряд, кто провёл
Журнал движений: карточка движения — откуда, куда, наряд, кто провёл

Номенклатура и остатки

Позиция каталога задаёт: категорию, единицу измерения, тип учёта (поштучный/количественный), режим передачи клиенту («Наше у клиента», «Продано клиенту», «В аренде» — можно переопределить при установке), три цены (закупочная, продажи, аренды в месяц) и минимальный остаток min_stock для алертов.

Пресеты номенклатуры: кнопка «Пресеты» на странице номенклатуры добавляет готовый набор позиций с категориями, ценами и порогами остатков — «Интернет-провайдер (ISP)», «Видеонаблюдение», «Домофония». Применение идемпотентно: существующие позиции с теми же названиями не меняются.

Пресеты номенклатуры
Пресеты номенклатуры
Номенклатура — позиции, категории, склады
Номенклатура — позиции, категории, склады

Режимы передачи, значки и цвета

Режим говорит, чьё оборудование у клиента и что с деньгами. Названия одни и те же везде — в номенклатуре, на «Остатках», в наряде и во вкладке клиента, — и у каждого режима свой значок и цвет:

РежимЗначокЧто происходит
Наше у клиентадомик, бирюзовый Оборудование остаётся нашим, у клиента на ответственном хранении. Денег не списывается.
Продано клиентурука с монетой, янтарный Оборудование становится собственностью клиента, с его счёта списывается цена продажи.
В арендестрелки по кругу, фиолетовый Оборудование наше, клиенту ежемесячно начисляется плата за аренду.

Категорию и режим выбирают из списка со значками и цветом: в фильтрах номенклатуры и «Остатков», в окне позиции, при смене категории у нескольких позиций сразу и при установке оборудования клиенту. Под выбором режима написано, что будет с деньгами.

В таблицах категория и режим показаны значком на цветной подложке, название — в подсказке при наведении. На телефоне подсказки нет, поэтому в карточке строки название стоит рядом со значком. Значок и цвет категории задаются в справочнике категорий.

В актах (PDF) режим «Наше у клиента» называется юридически — «Ответственное хранение».

Номенклатура: окно позиции — категория и режим передачи выбором со значками, организация
Номенклатура: окно позиции — категория и режим передачи выбором со значками, организация

Остатки: где лежит запас и сколько он стоит

Страница «Остатки» отвечает на вопрос «что у нас есть» не только штуками, но и деньгами. Над таблицей — полоса распределения: сколько лежит на складе, сколько на руках у монтажников, сколько уже стоит у клиентов и сколько списано в брак. Рядом с количеством — сумма по закупочной цене, чтобы было видно, сколько денег заморожено на складе и в подотчётах.

flowchart LR
    S["Склад
2445 шт · 138 751 ₽"] -->|выдача| P["Подотчёты монтажников
486 шт · 48 815 ₽"] P -->|установка| C["У клиентов
518 шт"] P -->|возврат| S C -->|демонтаж| S P -->|акт брака| D["Брак
7 шт"] S -->|акт брака| D

Таблица сортируется кликом по любому заголовку, фильтруется по складу и категории и выгружается в CSV — ровно тот срез, который на экране. Внизу — строка итогов: сколько позиций попало в выборку и на какую сумму.

Если организаций несколько, у позиции своя колонка «Орг.» с бейджем организации — как в номенклатуре и журнале.

Колонки. Кнопка рядом с выгрузкой открывает настройку колонок: какие показывать, в каком порядке и какой ширины. Настройка хранится в профиле сотрудника и действует на любом компьютере. Такая же кнопка есть в номенклатуре и журнале движений. На телефоне её нет — там строки показываются карточками.

Остатки: колонка «Орг.», значок категории, выбор колонок
Остатки: колонка «Орг.», значок категории, выбор колонок
Остатки: полоса распределения, суммы по закупочной, панель фильтров
Остатки: полоса распределения, суммы по закупочной, панель фильтров

«У клиентов» уменьшается при снятии. Демонтаж, возврат оборудования от клиента и сторно установки вычитают вещь из колонки «У клиентов». Одна вещь числится в одном месте: на складе, в подотчёте или у клиента.

Дефицит и список к закупке

У позиции задаётся минимальный остаток. В номенклатуре рядом с остатком показывается дефицит — сколько не хватает до минимума с учётом того, что уже на руках у монтажников. Кнопка «К закупке» выгружает CSV со списком: что докупить, сколько и на какую сумму по закупочной цене — такой файл можно сразу отдать снабженцу.

Номенклатура: колонка «Дефицит», кнопка «К закупке» и панель действий с отмеченными
Номенклатура: колонка «Дефицит», кнопка «К закупке» и панель действий с отмеченными

Карточка позиции и карточка единицы

Чтобы посмотреть, что происходит с конкретной позицией или с конкретной единицей оборудования, никуда переходить не нужно: обе карточки открываются боковой панелью поверх текущего списка.

Карточка позиции — клик по названию позиции в остатках, номенклатуре, «Я выдал» или в модалке движения. Что показывает:

Карточка единицы — клик по иконке штрихкода (S/N) в любой таблице склада или ссылка из карточки позиции. Показывает, где единица сейчас (склад, сотрудник или клиент), режим передачи, цены, даты — и таймлайн владения: приход → выдача в подотчёт → передача другому сотруднику → установка клиенту → демонтаж или брак. Сторнированные события зачёркнуты.

Карточка позиции: распределение остатка, деньги, дефицит, вкладки
Карточка позиции: распределение остатка, деньги, дефицит, вкладки
Карточка единицы: где она сейчас и таймлайн владения
Карточка единицы: где она сейчас и таймлайн владения

Обе карточки уважают организацию: чужую позицию или единицу открыть нельзя (см. Несколько организаций).

Приход, серийники, этикетки

Приход оформляется накладной: номер документа, склад, позиции. Для серийных позиций серийники сканируются подряд — камерой телефона (на Android — BarcodeDetector, на iPhone — ZXing), USB-сканером или вручную. После проведения — печать этикеток:

На этикетке — штрихкод Code128 (или QR) со значением SU-N и серийник. Code128 кодирует только латиницу и цифры — если значение штрихкода содержит кириллицу, система автоматически строит QR-код (кодирует любой текст, сканируется камерой телефона), чтобы код оставался читаемым. Во всех таблицах модуля при наведении на иконку штрихкода всплывает сканируемая картинка кода — сканер прикладывают прямо к экрану, не отходя к принтеру этикеток.

Приход — накладная и массовое заведение серийников
Приход — накладная и массовое заведение серийников

Приход проводится целиком

Подотчёт сотрудника

Кладовщик выдаёт монтажнику оборудование по скану и расходники количеством. Выбор сотрудника — единый компонент ProfileSelect (аватар, роли, поиск). У монтажника есть свой мобильный экран «Мой подотчёт»: что на руках, возврат на склад, акт брака.

Выдача в подотчёт — скан и единый селектор сотрудника
Выдача в подотчёт — скан и единый селектор сотрудника
Мой подотчёт — мобильный экран монтажника
Мой подотчёт — мобильный экран монтажника

«Я выдал» (/admin/stock/issued/) — зеркальная страница для кладовщика: все выдачи и передачи, которые он провёл, и судьба каждой единицы — в чьём подотчёте сейчас, установлена или в аренде у клиента (ссылка на его вкладку «Оборудование»), возвращена на склад, списана в брак или сторнирована. В профиле сотрудника — блоки «Мой подотчёт» (итог материальной ответственности + акт PDF, даты выдачи) и «Я выдал».

Я выдал — судьба каждой выдачи
Я выдал — судьба каждой выдачи

Передача подотчёт→подотчёт: при включённой настройке сотрудники передают единицы друг другу (например, бригадир — монтажнику) без возврата на склад; движение «Перемещение» в журнале, уведомление получателю, проверка матрицы прав и лимита.

Лимит подотчёта

Лимит — это сколько имущества по закупочной цене может числиться за одним сотрудником. Выдача сверх лимита не проходит, и в сообщении видно, из чего сложилась сумма: что уже на руках, что ждёт подписи и что выдаётся сейчас.

Раздел «Подотчёт»: общий лимит и свой лимит для групп
Раздел «Подотчёт»: общий лимит 100 000 ₽, у монтажников — 60 000 ₽, у главного инженера — без лимита
flowchart TD
    A["Сотруднику выдают вещи"] --> B{"Его группы есть в таблице
«Свой лимит для групп»?"} B -- "нет" --> C["Общий лимит"] B -- "да, одна" --> D["Лимит этой группы"] B -- "да, несколько" --> E["Больший из лимитов"] D --> F{"Лимит = 0?"} E --> F C --> F F -- "да" --> G["Без лимита"] F -- "нет" --> H{"На руках + ждёт подписи
+ выдаётся ≤ лимит?"} H -- "да" --> I["Выдача проходит"] H -- "нет" --> J["Отказ с цифрами"]

Наряд при выдаче. Взять вещи под наряд сам может только монтажник этого наряда. Кладовщик выдаёт под любой наряд своей организации.

«Я выдал»: что стало с выданным

Кладовщику важно не то, что он выдал, а что с этим стало. Страница «Я выдал» показывает каждую выдачу и передачу вместе с текущей судьбой единицы, а сверху — счётчики по судьбам: сколько ещё в подотчёте, сколько уже стоит у клиентов, сколько вернулось, сколько ушло в брак и сколько сторнировано. Клик по счётчику оставляет в списке только эти строки; рядом — фильтры «кому выдал» и период.

«Я выдал»: счётчики по судьбам, фильтры по получателю и периоду
«Я выдал»: счётчики по судьбам, фильтры по получателю и периоду

Передача под две подписи и акт

«Выдал» и «не получал» звучат одинаково уверенно. Поэтому выдача, возврат и сдача брака оформляются передачей: обе стороны расписываются пальцем, каждая — под своей учётной записью, и из этого собирается акт приёма-передачи. Он попадает в реестр документов и в раздел склада «Передачи и акты».

Как именно работает передача, решает настройка «Без обеих подписей не выдавать». Если она выключена, движение проводится сразу, а передача висит «ждёт подписи». Если включена — передача становится черновиком: вещи не двигаются, пока не расписались обе стороны, и проводятся в момент второй подписи. Без подписей за 30 минут черновик отменяется сам, и одну вещь нельзя положить в два черновика сразу.

sequenceDiagram
    participant K as Кладовщик
    participant B as Биллинг
    participant I as Монтажник (свой телефон)
    K->>B: сканирует вещи, выбирает монтажника и наряд
    B-->>K: черновик, вещи ещё на складе
    K->>B: расписывается «выдал»
    B-->>K: на экране QR-код
    I->>B: сканирует QR, входит под своей учёткой
    I->>B: расписывается «получил»
    B->>B: проводит выдачу, собирает акт
    B-->>K: экран кладовщика сам показывает «проведено»
Кладовщик расписался, на экране QR для монтажника
Кладовщик расписался «выдал» — на экране QR: монтажник сканирует его и подписывает у себя. Вещи ещё на складе

Телефон сел. Монтажник расписывается на экране кладовщика и подтверждает, что это он: кодом, который придёт ему в личный Telegram или СМС на номер из профиля, либо своим паролем от биллинга. Пять попыток, код действует 10 минут; в журнале видно, кто подписал, на чьём устройстве и чем подтвердил.

Кто проводит. Выдаёт, принимает возврат и брак только группа «Кладовщик» (настройка «Кто проводит выдачу»). Один человек не может подписать обе стороны: кладовщику выдаёт другой кладовщик, а если он на смене один — выбирает, кто разрешит. Тому приходит ссылка во внутренний чат и Telegram, и его подпись «выдал» и есть разрешение; такой черновик ждёт 4 часа.

Возврат и брак. Монтажник не сдаёт вещи на склад сам: кладовщик сканирует их в руках и принимает. Брак — с причиной и фото, тоже под две подписи. Если монтажник в наряде пытается взять со склада сам, вещи откладываются под наряд, и кладовщик выдаёт их по этому резерву.

Список передач: выдачи, сверка, передачи клиенту и снятие
«Передачи и акты»: выдачи, сверка, передачи клиенту и снятие у клиента — с состоянием подписей и актами

Что подпись проверяет. Росчерк должен быть настоящим, пустое поле не принимается. Перед проведением черновик проверяет, что каждая вещь всё ещё у того, кто её передаёт; иначе он попросит оформить передачу заново. Если за время сверки подотчёт изменился, сверка не подпишется. Подпись клиента в договоре подтверждает только ответственное хранение — продажа и аренда подписываются отдельно. Отменить черновик может кладовщик и тот, кто его оформил.

Сверка подотчёта

Выбор сотрудника для сверки подотчёта
«Сверка подотчёта»: в списке — сотрудники, за которыми что-то числится, с числом единиц

«Передачи и акты» → «Сверка подотчёта»: кладовщик выбирает сотрудника, система показывает всё, что за ним числится. Чего нет на руках — сначала оформляется возвратом, браком или передачей клиенту, затем оба подписывают сверку. Подписанная сверка закрывает старые неподписанные передачи сотрудника. Подотчёт самих кладовщиков сверяет другой кладовщик. Сверку стоит провести перед тем, как включать запрет выдачи без подписей.

Недостача. Пока сверку никто не подписал, кладовщик отмечает строки «нет в наличии»: у единицы — галочкой, у расходника — количеством. Когда оба подпишут, отмеченное списывается с подотчёта движением «Недостача», единица получает статус «Недостача», а в акте сверки видно, что в наличии и что списано; подпись сотрудника подтверждает, что он с недостачей ознакомлен. Вне сверки недостачу одной вещи оформляют в скан-центре — тоже под две подписи. Нашлась — сторно недостачи возвращает вещь в подотчёт.

Клиент расписывается за оборудование

При включённой настройке «Только с подписью клиента» передача клиенту тоже идёт черновиком. «Передать клиенту» в наряде собирает всё взятое под наряд в одну передачу, монтажник подписывает «передал». Клиент расписывается на его телефоне и вводит код из СМС: код приходит на номер из карточки, и в окне номер не меняется. Вещи списываются на клиента при подписи; в акте — номер маской, время отправки и ввода кода. Продажу и аренду система оформляет только после явного подтверждения с суммой.

Если подписывается договор, акт подписывается вместе с ним: та же подпись и тот же код клиента закрывают его сторону акта на оборудование «наше у клиента», а монтажнику остаётся подписать «передал» — кнопка появляется на экране договора.

Подпись клиента: код из СМС и росчерк
Монтажник подписал «передал», расписывается клиент: код приходит на номер из карточки, номер здесь не меняется
Подпись клиента на телефоне монтажника
То же на телефоне монтажника

Демонтаж — тоже с подписью клиента: снятое числится за монтажником, а не сразу на складе, аренда останавливается в момент подписи. На склад вещь потом принимает кладовщик.

Нет связи у клиента. Черновик ждёт сутки — подписать можно, когда связь появится. Если связи нет совсем, монтажник фотографирует бумажный акт с подписью клиента; сторона клиента считается подписанной после того, как акт подтвердит руководитель (не сам монтажник). До этого вещь на ответственности монтажника.

Бумажный акт ждёт подтверждения руководителя
Бумажный акт загружен — сторона клиента будет подписана, когда руководитель посмотрит фото и подтвердит
sequenceDiagram
    participant I as Монтажник
    participant B as Биллинг
    participant R as Руководитель
    I->>B: «передал» и фото бумажного акта с подписью клиента
    B-->>R: ссылка в чат и Telegram
    R->>B: смотрит фото, «Подтвердить бумажный акт»
    B->>B: сторона клиента подписана, оборудование у клиента
    Note over I,R: сам монтажник свой бумажный акт не подтверждает
stateDiagram-v2
    state "На складе" as S
    state "У монтажника" as M
    state "Ждёт подписи клиента" as P
    state "У клиента" as C
    state "Сдаёт на склад" as R
    S --> M: две подписи — кладовщик и монтажник
    M --> P: «Передать клиенту»
    P --> C: подпись клиента и код из СМС
    P --> C: бумажный акт и подтверждение руководителя
    C --> M: демонтаж, клиент расписался
    M --> R: монтажник принёс вещи
    R --> S: кладовщик принял, две подписи

Доска «Подотчёт» и утренняя сводка

Доска подотчёта по сотрудникам
Доска «Подотчёт»: красным — что требует внимания; клик по сотруднику — его подотчёт, значок в колонке «Сверка» — начать сверку

Доска (кнопка на странице «Передачи и акты») показывает по каждому сотруднику: сколько единиц и на какую сумму за ним числится (красным — выше лимита), что лежит без движения дольше 7 дней, какие закрытые наряды с непереданным, сколько передач ждут его подписи и когда была последняя сверка. Сверху — те, у кого непорядок.

Каждое утро в Telegram приходит сводка склада: что висит без движения, у кого превышен лимит, где наряд закрыт, а взятое под него не передано клиенту, какие передачи клиент не подтвердил дольше двух часов и какие бумажные акты ждут руководителя.

Настройка «Выполнено только когда материалы разошлись» не даёт закрыть наряд, пока взятое под него оборудование не у клиента и не сдано. Остаток расходников монтажник оставляет себе явно — это записывается в заметку сделки.

flowchart TD
    A["Монтажник: «Выполнено»"] --> Q{"Оборудование под наряд
ещё у монтажника?"} Q -->|"да"| X["Не закрывается:
передайте клиенту или сдайте"] Q -->|"нет"| R{"Остался расходник?"} R -->|"да"| C["«Остаток остаётся у вас?»"] C -->|"да"| N["Наряд закрыт,
остаток — в заметке сделки"] R -->|"нет"| D["Наряд закрыт"] style X fill:#7f1d1d,stroke:#dc2626,color:#fff style D fill:#43b77a,stroke:#2d9a5f,color:#fff style N fill:#43b77a,stroke:#2d9a5f,color:#fff

Росчерки, фото бумажных актов и акты лежат в закрытом хранилище и открываются только через биллинг: подпись человека — персональные данные.

Журнал движений

Журнал — полная история склада: приход, выдача, передача, установка, возврат, брак и сторно. Фильтры — поиск, сотрудник, тип движения (список со значками и цветом), период и склад, если складов несколько; организация берётся из выбора в шапке системы и показана своей колонкой. Выгрузка в CSV отдаёт тот же отфильтрованный срез. Из карточки движения открываются карточка единицы и карточка позиции.

Записи отмечаются флажками: над отмеченными — копирование серийных номеров, выгрузка и сторно пачкой. Колонки «Серийный №» и «Откуда» прячутся, пока во всей выборке пусты, — освободившееся место получает название позиции. Набор и порядок колонок настраивается кнопкой «Колонки» в конце строки фильтров.

Журнал движений: флажки, организация своей колонкой, кнопка «Колонки»
Журнал движений: флажки, организация своей колонкой, кнопка «Колонки»
Журнал движений: период, организация, склад, тип и выгрузка CSV
Журнал движений: период, организация, склад, тип и выгрузка CSV

Сторно: только с конца

Сторно отменяет движение обратной записью. Чтобы учёт не расходился с тем, где вещь лежит на самом деле, действуют пять правил.

flowchart LR
    R["Приход"] --> I["Выдача
монтажнику"] --> S["Установка
клиенту"] S -. "1. сторно установки" .-> I2["снова у монтажника"] I -. "2. сторно выдачи" .-> R2["снова на складе"] R -. "3. сторно прихода" .-> X["«Возвращено» —
выдать нельзя"]

Сторнировать движение другой организации нельзя: по номеру оно не находится.

Инвентаризация: пересчёт и акт расхождений

Все цифры склада — остатки, дефицит, стоимость запаса — держатся на одном допущении: то, что в базе, лежит на полке. Проверяет это инвентаризация. Раздел Склад → Инвентаризация показывает список актов; кнопка «Начать пересчёт» открывает новый лист по выбранному складу.

Список актов инвентаризации со статусами
Список актов инвентаризации со статусами

Главное правило: пересчёт не правит историю. Разница оформляется отдельными движениями типа «Корректировка (инвентаризация)» со ссылкой на акт: видно, что расхождение было, когда, на сколько и кто его провёл. Приход остаётся таким, каким был.

flowchart LR
    O["Открыли лист
снимок остатков склада"] --> C["Считаем полку
факт по позициям"] O --> S["Сканируем серийники
штрихкод или s/n"] C --> P["Проводим акт"] S --> P P --> M["Движения «Корректировка»
со ссылкой на акт"] P --> L["Ненайденная единица →
статус «Недостача»"] P --> E["Найденная лишняя →
приходуется на склад"]

Лист пересчёта

Лист запоминает учётный остаток на момент открытия — акт показывает ту цифру, от которой считали, даже если склад потом двигали. Сверху — свод: сколько позиций, сколько внесено, сколько излишков и недостач, сколько серийников найдено и во что расхождение обходится по закупочной цене.

Лист пересчёта: свод, ввод факта, скан серийников
Лист пересчёта: свод, ввод факта, скан серийников

Защита от «провёл, не считая». Если по листу не отмечена ни одна серийная единица, при проведении серийники не трогаются вовсе — иначе один клик отправил бы весь склад в недостачу. Если отсканирована меньше половины — подтверждение красное и называет цифры: сколько найдено и сколько уйдёт в недостачу. Непосчитанные позиции (пустой факт) не меняются никогда.

Что происходит при проведении

На один склад одновременно открыт один лист — иначе два человека считали бы одно и то же и оба провели бы расхождение. Лист живёт в границах организации своего склада: чужие позиции в него не попадают.

Если склад работал, пока шёл пересчёт

Закрывать склад на время пересчёта не обязательно. Для каждой строки запоминается время, когда в неё внесли факт, и расхождение считается от учёта на этот момент: остаток при открытии листа плюс все движения до пересчёта строки.

Серийные единицы сверяются с тем, где они числятся в момент проведения:

Что нашлиЧто сделает проведение
Единицы нет на полке, а её выдали, пока шёл пересчётНичего: это не недостача. В акте — запись «без корректировки»
Единицы нет на полке, и она числится на этом складеСтатус «Недостача», списание со склада
Единица на полке, а числится в подотчётеВозврат от этого сотрудника на склад
Единица на полке, а числится у клиентаНичего: в акте — «оформите демонтаж»

Защита «провёл, не считая» смотрит на найденные ожидаемые единицы: если отсканированы только лишние, остальной серийный склад в недостачу не уходит.

Резерв под наряд

Остаток на складе перестал быть ответом на вопрос «можно ли брать»: часть запаса уже обещана конкретным адресам. Резерв — это обещание, а не движение: вещь физически лежит на складе, но считается занятой. Без него монтажник приезжал к клиенту за роутером, который час назад увезли на другой адрес — остаток был, а вещи не было.

Бронь ставится там, где о ней думают, — в наряде, в модалке «Материалы наряда». Клиент для этого не нужен: наряд уже есть, вещь нужна.

Блок «Отложено под наряд» в модалке материалов и кнопка «Забронировать выбранное»
Блок «Отложено под наряд» в модалке материалов и кнопка «Забронировать выбранное»

Общая картина — в разделе Склад → Резервы: что отложено, под какой наряд, к какой дате и кем. Оттуда же бронь снимается.

Список резервов: позиция, наряд, дата, статус
Список резервов: позиция, наряд, дата, статус

Что резерв меняет в работе склада

flowchart LR
    R["Бронь под наряд
позиция или единица"] --> F["Свободно = остаток − резервы"] F -->|"выдача по этому наряду"| C["Резерв закрыт
ушло по назначению"] F -->|"выдача под другой наряд"| X["Отказ
«свободно N, занято M»"] R -->|"наряд отменён"| S["Резерв снят
позиция снова свободна"]

Когда бронь снимается сама

СобытиеЧто происходит с бронью наряда
Вещь выдана или списана на клиента со склада по этому нарядуЗакрывается как «выдана»; частичная выдача уменьшает бронь
Сделку перевели в отказСнимается
Наряд закрыт — кнопкой «Выполнено» или перетаскиванием в канбанеНевыданный остаток снимается
Сделку удалилиСнимается
Срок брони прошёл больше трёх дней назад (настраивается)Снимается раз в сутки, в брони указана причина

Перемещение между складами

Переезд коробки с центрального склада в филиал — одно движение типа «Перемещение», а не списание с одного склада и приход на другой. Пара движений выглядела бы в журнале как потеря в одном месте и находка в другом, хотя это одна и та же вещь.

Модалка перемещения: откуда, куда, позиция или штрихкод
Модалка перемещения: откуда, куда, позиция или штрихкод

Кнопка «Переместить» — в разделе «Остатки». Переместить можно количеством (расходники) или по штрихкоду конкретной единицы. Не даст: на тот же склад, больше, чем лежит, забронированное под наряды и — отдельно — между складами разных организаций: передача имущества между юрлицами оформляется продажей, а не складской проводкой.

Какой склад. Серийная позиция перемещается поштучно, по единицам. Выдаётся единица с того склада, где лежит, и возвращается на склад, с которого её выдали. Расходник выдаётся со склада по умолчанию; если его там не хватает, а есть на другом — с него, а если подходящих складов несколько, система попросит сначала переместить.

Поставщики

Поставщик — отдельный справочник, на который ссылается приход: одна карточка на фирму, вся история закупок и цен в одном месте. Отсюда ответ на вопрос «сколько у них закупили и почём брали в прошлый раз».

Приход: отдельные поля «№ документа» и «Поставщик» с быстрым добавлением
Приход: отдельные поля «№ документа» и «Поставщик» с быстрым добавлением

Материалы в наряде монтажа

На карточке наряда (/admin/crm/montazh/) — строка «Материалы: N». Модалка позволяет прямо с телефона на объекте:

Все списания привязываются к сделке (deal#N) и к учётке клиента. Клиента к моменту выезда может ещё не быть: монтажник берёт материалы под наряд в свой подотчёт, а после договора нажимает «Передать клиенту» — взятое перестаёт числиться за ним и переходит на клиента. Переданное не показывается второй строкой «взято под наряд» и повторно к передаче не предлагается. Настройка STOCK_REQUIRE_MATERIALS_ON_DONE включает жёсткий режим: наряд нельзя закрыть «Выполнено», пока не указаны материалы.

Установка только «своим» клиентам: настройка STOCK_INSTALL_REQUIRE_MONTAGE (по умолчанию выкл.) ограничивает монтажников — установить или демонтировать оборудование клиенту можно, только если у монтажника есть на него наряд в CRM (сделка, где он назначен монтажником и проставлена дата монтажа — то же, что «мой наряд» на /admin/crm/montazh/). Кладовщик, суперпользователь и менеджеры работают без ограничения. Смена статуса единиц по-прежнему возможна только для того, что в своём подотчёте.

Наряды монтажника — строка Материалы на карточке
Наряды монтажника — строка Материалы на карточке
Модалка материалов наряда
Модалка материалов наряда

Частичная установка, закрытие и передача наряда

Бланк «Наряд-заказ»

Вместо бумажного бланка, который монтажники заполняли от руки, бланк печатается из наряда уже заполненным: кнопка «Бланк наряда (PDF)» на карточке в «Нарядах» и в окне материалов наряда. Лист — один A4.

Поле бланкаОткуда
Реквизиты над заголовкоморганизация сделки
Номер наряданомер сделки
Абонент, № договораклиент сделки; если его ещё нет — имя контакта
Адрес, телефонсделка и контакт (оба телефона)
Наряд выдан, дата выполнениямонтажник, дата и окно монтажа
Тариф и комментарийтариф сделки и начало комментария к заявке
Коммутатор, № портаучётная запись клиента
Материалысклад по этому наряду: взятое под наряд и переданное клиенту, с серийными номерами

В материалах две колонки количества: «Со склада» заполнена системой, «Израсходовано» монтажник пишет сам. Ниже — пустые строки для того, что взято не через систему. Перечень работ с квадратиками, технология подключения, дополнительные работы, стоимость и подписи абонента — как на бумажном бланке, для заполнения от руки.

Текст бланка правится в «Документы → Шаблоны», вкладка «Склад», документ «Наряд-заказ» — для каждой организации можно сделать свой вариант (например, с ценами работ). Монтажник без менеджерских прав печатает только свои наряды; каждая печать записывается в журнал действий.

Бланк «Наряд-заказ» с материалами наряда (демо-данные)
Бланк «Наряд-заказ» с материалами наряда (демо-данные)

Оборудование в карточке клиента

Вкладка «Оборудование» (прямая ссылка — /admin/Abonents/<id>/equipment/): всё оборудование со склада у клиента со статусами, история установок со сторно, ручная установка из подотчёта и демонтаж (с вопросом «исправное или брак?»). Режим при установке выбирается из списка со значками; по умолчанию — как указано у позиции. При установке серийной единицы её MAC/серийник автоматически подставляются в учётку клиента (тумблер STOCK_AUTO_FILL_MAC).

Вкладка Оборудование в карточке клиента
Вкладка Оборудование в карточке клиента

Деньги: продажа и аренда

Режим передачи определяет финансовые последствия установки:

flowchart TB
    I["Установка клиенту
(наряд / карточка / API)"] I --> CU["Наше у клиента
(custody)"] I --> SA["Продано клиенту
(sale)"] I --> RE["В аренде
(rent)"] CU --> CU2["Только движение и статус.
Оборудование — собственность оператора"] SA --> SA2["FinanceOperations:
−цена продажи с лицевого счёта
метка [stock:mv:N]"] RE --> RE2["UsersUsluga «Аренда оборудования»
цена/мес · начисления с 1-го числа
следующего месяца (billing_worker)"] SA2 -.->|сторно| SA3["Деньги возвращаются на счёт,
операция помечается «сторно»"] RE2 -.->|"демонтаж / сторно"| RE3["Услуга аренды выключается,
новых начислений нет"] style SA2 fill:#fdecea,stroke:#dc3545,color:#1b1b1b style RE2 fill:#fff3cd,stroke:#fd7e14,color:#1b1b1b style CU2 fill:#e8f5e9,stroke:#43b77a,color:#1b1b1b
Целостность. Складское движение и его финансовая часть выполняются в одной транзакции: если списание с лицевого счёта не удалось — не будет и движения. Продажа без финансовой операции невозможна.

Аналитика

Аналитика склада: период в шапке, показатели карточками, материалы на руках с колонкой S/N
Аналитика склада в 3.7.0

В 3.7.0 период перенесён в шапку страницы, блоки собраны на общих карточках, в таблице «на руках» колонка серийных номеров называется «S/N», пустые ячейки на телефоне скрываются.

Страница /admin/stock/analytics/ (кладовщик, руководитель) отвечает на три вопроса: сколько денег лежит в материалах, у кого они на руках и что ушло клиентам. Период выбирается одним переключателем — «Всё время», месяц, квартал, год или свои даты.

Суммы считаются по закупочной цене позиции; позиции без цены помечены «нет цены». Продажа, по которой сделан возврат, в предупреждения не попадает. На телефоне показатели идут одним столбцом, у графиков нет подписей оси — значения написаны у полос.

Аналитика склада: предупреждения, «Сейчас» с главной цифрой «Вложено в материалы», «За всё время», движения по дням и запас по категориям
Аналитика склада: предупреждения, «Сейчас», «За период» и графики
Аналитика склада: что ушло на подключения, у кого материал на руках, обороты по позициям
Что ушло на подключения, у кого материал на руках, обороты по позициям

Скан-центр: операции с телефона

Страница /admin/stock/scan/ (пункт меню «Скан») — максимум автоматизации в поле: сотрудник наводит камеру телефона на этикетку (код помещается в рамку-видоискатель с бегущей линией; можно ввести S/N вручную), и система сама предлагает действие по статусу единицы и роли сотрудника:

После выдачи или взятия себе в подотчёт в карточке появляется кнопка «Распечатать акт (PDF)» — открывается акт подотчёта получателя (материальная ответственность с подписями); при передаче между сотрудниками кнопку видит кладовщик. Кнопка «Вся история» выдвигает справа сайдбар со всеми событиями единицы по датам: тип операции, откуда → куда, кто провёл, комментарий; сторнированные записи перечёркнуты.

Совместимость: на Android работает нативный BarcodeDetector; на iPhone (WebKit его не поддерживает) автоматически подгружается декодер ZXing — сканирование доступно во всех браузерах. После каждого действия — уведомление и журнал операций на экране; можно сканировать следующий код без перезагрузки. USB-сканер работает как клавиатура (ввод + Enter).

Скан-центр на телефоне — контекстные действия по статусу единицы
Скан-центр на телефоне — контекстные действия по статусу единицы

Сканирование подряд и работа без связи

Сканирование в поле рассчитано на две ситуации: серия кодов подряд и работа без связи.

Что офлайн-режим не делает. Он не решает за сервер: права, организация и остаток проверяются в момент реальной отправки. Поэтому действие, отложенное в очередь, может быть отклонено позже — об этом будет запись в истории с причиной.

Очередь не теряет и не повторяет. Если, пока не было связи, истёк вход в биллинг, действие остаётся в очереди, а в истории появляется «Войдите в биллинг заново». У каждого действия свой номер: если ответ сервера потерялся, повторная отправка выдачу второй раз не проведёт. Новое действие встаёт за ещё не отправленными, поэтому порядок сохраняется. Второе нажатие на кнопку, пока первое не вернулось, не считается.

Документы и интеграция с CRM

Складские операции оформляются печатными документами (PDF, реквизиты организации клиента подставляются автоматически):

Связь с CRM: в карточке сделки (вкладка «Подключение») показываются материалы наряда — количество позиций и себестоимость по закупочной, рядом — PDF-акт. В профиле сотрудника — блоки «Мой подотчёт» (что на руках, итог ответственности, акт) и «Я выдал» (для кладовщика). Из «Остатков» число «У клиентов» открывает список клиентов со ссылками на их вкладку «Оборудование».

Настройки, роли, алерты

Все настройки склада собраны на одной странице — Склад → Настройки. Они разложены по разделам: модуль, роли, подотчёт, подписи, наряды и брони, аналитика, этикетки. Группы сотрудников выбираются из списка, правило «кто кому выдаёт» задаётся строками «группа → группы». Страницу видят кладовщики, менять настройки может только root: от них зависит, кто выдаёт и кто подтверждает. Каждое изменение пишется в журнал, а перед сохранением ответственных настроек система спрашивает подтверждение.

Склад → Настройки: модуль и роли
Склад → Настройки: модуль и роли. Группы выбираются из списка — несуществующую группу сохранить нельзя

Схема данных модуля:

erDiagram
    StockCategory ||--o{ StockItem : "категория"
    StockUom ||--o{ StockItem : "ед. изм."
    StockItem ||--o{ StockUnit : "серийные единицы"
    StockItem ||--o{ StockMovement : "движения"
    StockUnit |o--o{ StockMovement : ""
    StockWarehouse |o--o{ StockMovement : "src/dst склад"
    StockUnit }o--o| Abonents : "у клиента"
    StockMovement }o--o| FinanceOperations : "продажа [stock:mv:N]"
    StockUnit }o--o| UsersUsluga : "аренда [stock:unit:N]"

    StockItem {
        bool is_serialized "S-N или количеством"
        string transfer_mode "custody-sale-rent"
        money purchase_sale_rent "3 цены"
        decimal min_stock "порог алерта"
    }
    StockUnit {
        string serial_mac_barcode "SU-N"
        string status "in_stock-issued-installed-sold-rented-defect"
    }
    StockMovement {
        string mv_type "receipt-issue-install-return-defect-storno"
        string ref "deal-manual + id"
    }
НастройкаDefaultНазначение
STOCK_ENABLEDOFFГлавный тумблер модуля
STOCK_KEEPER_GROUPSstorekeeper, rootКладовщики: приход, выдача, сторно чужих движений, установка прямо со склада
STOCK_HOLDER_GROUPSinstaller, …Кому можно выдавать в подотчёт
STOCK_BARCODE_FORMATcode128Формат этикетки (code128 / qr)
STOCK_LABEL_W_MM / H_MM40 × 14Размер этикетки под ленту принтера
STOCK_AUTO_FILL_MACONПодставлять MAC/серийник в учётку клиента при установке
STOCK_REQUIRE_MATERIALS_ON_DONEOFFЖёсткий режим: наряд не закрывается без материалов
STOCK_ISSUE_RULES—Матрица «кто→кому»: JSON {"группа выдающего": ["группы получателей"]}; пусто — кладовщики выдают всем держателям
STOCK_ALLOW_STAFF_TRANSFEROFFПередача подотчёт→подотчёт между сотрудниками (движение «Перемещение»)
STOCK_MAX_STAFF_COST0Лимит стоимости подотчёта, ₽ по закупочной — выдача сверх лимита блокируется
STOCK_STALE_ISSUED_DAYS0Утренняя сводка склада: единица висит в подотчёте без движения дольше N дней (в ту же сводку — лимит, наряды с непереданным, неподтверждённые клиентом передачи, бумажные акты)
STOCK_HANDOVER_SIGNONСобирать подписи при передаче (выдача, возврат, брак)
STOCK_HANDOVER_REQUIREDOFFБез обеих подписей не выдавать: выдача, возврат и брак — черновиком, вещи двигаются при второй подписи; монтажник сам со склада не берёт и сам не сдаёт
STOCK_OPERATOR_GROUPSКладовщикКто проводит выдачу, приём возврата и брака под подписи (root и суперпользователи — нет)
STOCK_APPROVER_GROUPSroot, Директор, Главный инженерКто, кроме других кладовщиков, разрешает кладовщику взять себе и подтверждает бумажные акты
STOCK_CLIENT_SIGN_REQUIREDOFFПередача клиенту и снятие у клиента — только с подписью клиента (росчерк и код из СМС на номер из карточки)
STOCK_DONE_REQUIRES_HANDEDOFF«Выполнено» в наряде — только когда взятое под наряд оборудование у клиента или сдано
STOCK_ORG_STRICTONЗапрет установки клиенту чужой организации (см. раздел 10а). Выключать только если у вас сознательно общий склад на несколько юрлиц
STOCK_INSTALL_REQUIRE_MONTAGEOFFМонтажник ставит/демонтирует оборудование только клиентам со своим нарядом в CRM (сделка: он монтажник + дата монтажа). Кладовщик/суперюзер/менеджеры — без ограничений
STOCK_STAFF_COST_BY_GROUP—Свой лимит подотчёта для групп, ₽: таблица «группа → лимит». Сотрудник в нескольких группах получает больший лимит, 0 — без лимита, вне таблицы — общий STOCK_MAX_STAFF_COST
STOCK_HIDE_PRICES_FOR_STAFFONЗакупочные цены и суммы склада видят только кладовщики. Цены продажи и аренды остаются видны всем — их называют клиенту
STOCK_DEAL_DELETE_WITH_MATERIALSзапрещатьМожно ли удалить сделку, под которую взяты материалы: запрещать, пока их не вернут, или разрешать
STOCK_RESERVE_EXPIRE_DAYS3Через сколько дней после срока бронь снимается сама. 0 — не снимать
STOCK_CONSUMPTION_MODEушло со складаЧто считать расходом в аналитике: ушло со склада минус возвраты, или выдачи плюс установки (старый счёт — вещь, выданная и затем поставленная, считалась дважды)
STOCK_LOW_STOCK_BASISтолько складС минимумом сравнивается остаток склада или склад вместе с подотчётом. Правило одно для остатков, карточки, аналитики и алерта

Мульти-организация: правила «чьё что» вынесены в отдельный раздел — Несколько организаций.

Алерт остатков: раз в сутки задача stock-min-alert собирает позиции ниже min_stock и отправляет одно сообщение в Telegram-группу оператора со ссылкой на страницу прихода. Та же задача снимает брони с истёкшим сроком.

Аудит: каждое движение пишется в журнал аудита (STOCK_MOVEMENT) — кто, что, куда и когда переместил.

Несколько организаций: чьё что

Если в биллинге заведено больше одной организации, склад ведётся по каждой отдельно: своя номенклатура, свои склады, свои сотрудники, свои деньги. Сотрудник видит и трогает только то, что относится к доступным ему организациям.

ОбъектКому принадлежитЧто из этого следует
Позиция номенклатурыОрганизации (выбирается в модалке позиции)Чужие позиции не видны в списках, поиске, аналитике и журнале
СкладОрганизации (обязательно)Приход и выдача идут в границах организации: склад одного юрлица не подставится под позицию другого
КатегорияОрганизации или общая«Роутеры» и «ONU/Оптика» разумно держать общими — иначе разъедутся отчёты и пресеты
Единица (серийник)Наследует организацию позиции в момент приходаДальше не меняется: история владения не «переезжает», если позицию потом переведут в другую организацию
ДвижениеФиксируется в момент проводкиЖурнал и аналитика фильтруются по организации самого движения, а не по текущему состоянию позиции
СотрудникОрганизациям из профиляВыдать и передать подотчёт можно только сотруднику своей организации
flowchart TB
    subgraph A["Организация «СмИТ»"]
        A1[Склад организации А] --> A2[Позиция: ONU]
        A2 --> A3[Единица SU-56]
        A3 --> A4[Клиент организации А]
    end
    subgraph B["Организация Б"]
        B1[Склад организации Б] --> B2[Позиция: ONU]
        B2 --> B3[Единица SU-77]
        B3 --> B4[Клиент организации Б]
    end
    A3 -. запрещено .-> B4
    B3 -. запрещено .-> A4

Установка клиенту — только внутри своей организации. Оборудование организации А нельзя поставить клиенту организации Б: система ответит «Позиция принадлежит организации А, а клиент — Б». Причина не формальная: себестоимость списывается со склада одной организации, а операция продажи или услуга аренды создаётся у клиента — то есть в другой организации. После такой установки не сходится ни у одной из сторон. Правильный путь — завести позицию в организации клиента. Ограничение снимается настройкой STOCK_ORG_STRICT = 0, если у вас сознательно общий склад на несколько юрлиц.

Где это видно в интерфейсе. Колонка и бейдж «Орг.» в номенклатуре и на остатках; выбор организации в модалке позиции и в справочнике складов; фильтр по организации и выгрузка CSV в журнале движений. Списки организаций в этих селектах приходят с сервера уже отфильтрованными по правам сотрудника — увидеть в выпадающем списке чужую организацию нельзя.

Что проверить при запуске второй организации: завести ей свой склад (иначе приход уедет на склад по умолчанию), завести номенклатуру в её организации, проверить у сотрудников привязку к организациям в профиле — от неё зависит, кому можно выдавать подотчёт.

Чужое по номеру не открывается. Движение, единица, бронь, передача и сделка другой организации не находятся, даже если знать номер: система отвечает «не найдено». Доступ определяется организациями сотрудника из его профиля, а не выбором в шапке. Если модуль «Склад» выключен, раздел закрыт целиком.

Чек-лист запуска

  1. Группа storekeeper + учётка кладовщика в ней.
  2. Категории и номенклатура (типовые позиции ISP: роутеры, ONU, кабель, коннекторы). Для знакомства — manage.py seed_stock_demo, очистка демо — seed_stock_demo --clear.
  3. Стартовая инвентаризация — приход «инвентаризация (correction)» на фактические остатки склада и подотчётов.
  4. Печать этикеток на серийные остатки.
  5. STOCK_ENABLED = ON — с этого момента монтажники видят «Мой подотчёт», в нарядах появляются «Материалы», в карточках клиентов — вкладка «Оборудование».