Введение
В Odoo структура данных задаётся моделями — это схемы, в которых хранятся записи бизнеса. Всё: заказы, счета, перемещения запасов — живёт в моделях, а не в разрозненных таблицах.
Понимание моделей важно и для консультанта, и для разработчика. Именно модели задают поля, связи и логику, на которых строится вся система Odoo — от валидации до отчётности и прав доступа.
В этой заметке мы подробно разберём одну из ключевых моделей склада — stock.move. Если вы настраиваете склад, пишете интеграции или дописываете модули для логистики, с ней придётся работать постоянно.
Что такое модель stock.move
Модель stock.move описывает одну единицу перемещения товара: откуда он ушёл и куда пришёл. Каждое реальное действие — снятие с полки, перемещение между складами, отгрузка клиенту — фиксируется записью stock.move.
Модель используется модулем Склад (Inventory). Продажи, закупки, производство и интернет-магазин генерируют записи stock.move при операциях с товаром. Подтверждение доставки, приёмка от поставщика или завершение производства всегда создаёт или изменяет такие записи.
Определение модели находится в модуле stock; другие модули дополняют её через наследование Odoo. Модуль продаж добавляет связь sale_line_id, закупки — purchase_line_id, производство — production_id. Так бизнес-логики интегрируются без копирования ядра.
Ключевые поля модели
Ниже — основные поля модели stock.move, которые полезно знать, чтобы корректно работать с движениями запасов.
1. name
Тип: Char. Краткое название или описание перемещения. Часто собирается из названия товара и количества и отображается в списках и печатных документах как читаемый идентификатор.
2. product_id
Тип: Many2one (product.product). Ссылка на товар, который перемещается. Поле обязательно — без него перемещение бессмысленно. По нему Odoo считает остатки и применяет правила складирования.
3. product_uom
Тип: Many2one (uom.uom). Единица измерения количества. Обязательное поле; обычно совпадает с основной единицей товара. Odoo контролирует, чтобы количество задавалось в этой единице.
4. product_uom_qty
Тип: Float. Запланированное количество в выбранной единице — потребность или заявка на перемещение. Фактически выполненное количество хранится в quantity_done.
5. quantity
Тип: Float. Отображаемое или вычисляемое поле для количества. В интерфейсе служит удобным представлением — иногда это тот же показ, что и product_uom_qty, иногда конвертированное значение.
6. location_id
Тип: Many2one (stock.location). Место-источник — откуда берут товар. Обязательное поле: для исходящих операций это склад, для входящих — местоположение поставщика или производство.
7. location_dest_id
Тип: Many2one (stock.location). Место-получатель — куда идёт товар. Обязательное поле: для входящих — склад, для исходящих — местоположение клиента или утилизации.
8. picking_id
Тип: Many2one (stock.picking). Документ-перемещение, который объединяет несколько moves (например, накладная, приёмка или внутренний перенос). Группировка упрощает операции и печать документов.
9. picking_type_id
Тип: Many2one (stock.picking.type). Тип операции: отгрузка, приёмка или внутренний перенос. От него зависят стандартные местоположения и рабочий процесс.
10. state
Тип: Selection. Текущий статус перемещения: draft, waiting, confirmed, assigned, done, cancelled. Draft — черновик, assigned — зарезервировано, done — завершено.
11. date
Тип: Datetime. Планируемая дата операции. Используется в планировании и приоритезации перемещений в расписании склада.
12. date_deadline
Тип: Datetime. Крайний срок выполнения — например, обещанная дата доставки клиенту. Применяют при расчёте срочности задач.
13. origin
Тип: Char. Ссылка на исходный документ — номер заказа, закупки или производства. Помогает быстро найти, откуда пришло требование на перемещение.
14. move_dest_id
Тип: Many2one (stock.move). Ссылка на последующее перемещение в цепочке. Если выход производства должен дальше отгружаться, здесь ставится связь для последовательности операций.
15. move_orig_ids
Тип: One2many (stock.move). Обратная связь — список предыдущих перемещений, которые подпитывают текущее. Полезно для прослеживаемости и аудита цепочек.
16. move_line_ids
Тип: One2many (stock.move.line). Детализация перемещения: партии, серийные номера, конкретные места хранения. Резервирование и обработка товаров работают с move lines.
17. partner_id
Тип: Many2one (res.partner). Контрагент для операции: клиент при отгрузке или поставщик при приёмке. Используется для адресов и отчётности.
18. company_id
Тип: Many2one (res.company). При мультикомпаний указывает принадлежность записи к конкретной компании. Влияет на видимость и межфирменные правила.
19. quantity_done
Тип: Float. Фактически обработанное количество. При приёмке или отборе пользователь обновляет это поле; перемещение считается завершённым, когда quantity_done равен product_uom_qty.
20. reserved_availability
Тип: Float. Зарезервированное количество для этого перемещения. Поле показывает, сколько товара зафиксировано под заявку после назначения (assigned).
21. create_date
Тип: Datetime. Дата и время создания записи — ведётся автоматически Odoo. Полезно для отчётов и аудита.
22. write_date
Тип: Datetime. Дата последнего изменения записи — также поддерживается системой. Помогает понять, когда данные обновлялись в последний раз.
23. sequence
Тип: Integer. Порядок отображения перемещений внутри одной накладной. Меньшее значение показывает выше в списке.
24. priority
Тип: Selection. Уровень срочности — обычно 0 (нормально) или 1 (срочно). Влияет на планирование и отдачу заданий кладовщикам.
25. description_picking
Тип: Char. Текст примечания для перемещения, видимый на документах. Удобно для инструкций по хранению или обработке товара.
26. reference
Тип: Char. Внутренний код или ссылка — можно использовать для интеграций или собственных учётных номеров.
27. group_id
Тип: Many2one (procurement.group). Группа закупок/потребностей, объединяющая связанные перемещения от одного источника (например, по одному заказу). Помогает в планировании и цепочках.
28. procure_method
Тип: Selection. Стратегия снабжения: make_to_stock или make_to_order. Определяет, брать ли товар со склада или запускать закупку/производство.
29. sale_line_id
Тип: Many2one (sale.order.line). Поле добавляется модулем продаж и связывает перемещение со строкой заказа — удобно для учёта и аналитики.
30. purchase_line_id
Тип: Many2one (purchase.order.line). Поле от модуля закупок — привязка перемещения к строке закупки при приёмке от поставщика.
31. production_id
Тип: Many2one (mrp.production). Поле от модуля производства — связывает перемещение с производственным ордером для списания сырья и прихода готовой продукции.
32. active
Тип: Boolean. Флаг «активности» для мягкого удаления. При False запись архивируется и скрывается из стандартных представлений, но не удаляется из базы.
Как модель используется в бизнес-процессах
1. Отгрузка клиенту
После подтверждения заказа продаж система создаёт stock.move для каждой строки: location_id — склад, location_dest_id — местоположение клиента. Все перемещения собираются в picking (накладная). При сборке и отгрузке кладовщик фиксирует quantity_done — и статус перемещения переходит в done.
2. Приёмка от поставщика
При подтверждении заказа закупки создаются входящие stock.move: источник — местоположение поставщика, приём — склад. Перемещения группируются в receipt; при фактическом поступлении пользователь подтверждает приём и заполняет quantity_done.
3. Внутренние перемещения
Переносы между складами или зонами также оформляются как stock.move, где location_id — отправитель, location_dest_id — получатель. Такие перемещения используются для пополнения, балансировки остатков и работы с несколькими складами.
4. Производство
Производственные ордера формируют два типа перемещений: исходящий для списания сырья и входящий для прихода готовой продукции. production_id связывает эти перемещения с ордером; с помощью move_dest_id выход производства можно привязать к дальнейшей отгрузке.
5. Возвраты и списание
Возврат клиента оформляется как обратное перемещение, списание уходит в специальное «scrap» местоположение. Одна и та же модель stock.move поддерживает все сценарии; picking_type_id задаёт конкретный поток и логику.
Как разработчики расширяют модель
Разработчики расширяют stock.move несколькими способами; основная механика — наследование моделей Odoo.
Наследование моделей
Объявляйте _inherit = 'stock.move' в своём модуле, чтобы добавить поля, переопределить методы или ввести ограничения. Наследование позволяет держать изменения в отдельном модуле, что упрощает обновления системы.
Добавление полей
В своём наследнике определяйте поля нужных типов: Char, Many2one, Boolean, Integer, Text, Selection. Для мультикомпаний продумывайте company-dependent поля. Частые расширения для перемещений — собственные номера партий, ссылки на перевозчиков или дополнительные атрибуты лота.
Расширение на Python
Переопределяйте методы вроде _action_done, _action_assign или _action_cancel, вызывая super(), чтобы дописать логику. Будьте внимательны: неверная правка может сломать учёт остатков и цепочки перемещений.
Odoo Studio
Odoo Studio позволяет добавить поля без кода — быстро и удобно для простых улучшений формы перемещения. Для сложной логики лучше делать полноценный модуль, чтобы изменения были воспроизводимы и управляемы в версиях.
Рекомендации по использованию
- Всегда задавайте корректные location_id и location_dest_id. Неправильные местоположения приводят к ошибочным остаткам и потерям штук в учёте.
- Используйте picking_id для группировки связанных перемещений. Не создавайте разрозненные move, если они логически принадлежат одной транспортной операции.
- При интеграции через API работайте через XML-RPC или JSON-RPC — модель stock.move полностью доступна. Внешние идентификаторы мапьте аккуратно, чтобы не потерять связи.
- Для пользовательских полей применяйте префикс x_ или префикс модуля, чтобы избежать конфликтов с будущими полями стандартного Odoo.
- Проставляйте move_dest_id и move_orig_ids для прослеживаемости. При создании цепочек программно не забудьте связать исходящие и последующие перемещения.
- Берите в расчёт разницу между quantity_done и product_uom_qty — возможны частичные отгрузки и приёмки, и система это поддерживает.
Частые ошибки
- Создание перемещений с некорректными типами локаций. Источник и получатель должны быть совместимы — например, нельзя одновременно указывать два клиентских лока.
- Изменение product_uom_qty после создания move lines. Это часто приводит к рассинхронам остатков; если нужно — отмените перемещение и создайте заново.
- Забыть заполнить origin. Без ссылки на исходный документ теряется трассируемость и сложнее разбирать операции в отчётах.
- Переопределить _action_done без вызова super(). Это рискует нарушить логику списания и взаимодействие с другими модулями.
- Создавать moves напрямую, минуя workflow (например, не через stock.picking). Обход пикача ломает резервирование и назначение запасов.
- Игнорировать move_dest_id при разделении или слиянии перемещений. В результате цепочки могут остаться без связи и потерять смысл в процессе исполнения.
Заключение
Модель stock.move — это сердце учёта движения товаров в Odoo. Она фиксирует каждое перемещение, привязывая количество, локации и контекст. Чем лучше вы понимаете её поля и расширения, тем проще настраивать систему и избегать ошибок.
Независимо от роли — консультант по складским процессам или разработчик модулей — хорошее знание stock.move экономит время и снижает риск ошибок при внедрении и поддержке системы.
Нужна помощь с внедрением Odoo?
Dasolo помогает компаниям внедрять, настраивать и оптимизировать Odoo. Мы специализируемся на интеграциях через API и разработке модулей, глубоко работая с модельной архитектурой Odoo и такими моделями, как stock.move.
Если вам нужна помощь с внедрением Odoo, разработкой кастомных модулей или интеграциями — свяжитесь с нами, мы поможем. Запланируйте демонстрацию чтобы обсудить ваш проект.