Перейти к содержимому

Модель sale.order.line: строение и логика строк продаж в Odoo

Полный справочник по модели позиций заказа продажи в Odoo для разработчиков и функциональных консультантов
10 марта 2026 г. от
Модель sale.order.line: строение и логика строк продаж в Odoo
Dasolo
| Комментариев пока нет

Введение


В Odoo модели описывают структуру и хранение данных в базе. Любая бизнес‑сущность — от заказа до счета или контакта — представлена моделью, которая задаёт поля, связи и поведение.


Знание моделей критично как для разработчиков, так и для функциональных консультантов: именно они формируют архитектуру данных Odoo. Модель определяет типы полей, отношения между записями и встроенную бизнес‑логику.


Здесь мы подробно разбираем одну из ключевых моделей модуля «Продажи» — sale.order.line. Если вы разрабатываете модули, настраиваете прайс‑листы или интегрируете внешние системы, с ней придётся работать постоянно.

Что такое модель sale.order.line


Модель sale.order.line хранит отдельные позиции в коммерческом предложении или заказе клиента. Каждая запись обычно соответствует одному товару или услуге с количеством, ценой и налогами.


Эта модель принадлежит модулю sale и наследует аналитический миксин для привязки к проектной аналитике и учёту времени. Когда вы добавляете товар в предложение, создаётся запись sale.order.line.


Определение модели находится в модуле продаж, а другие модули расширяют её через наследование моделей Odoo. Например, sale_stock добавляет поля для доставки, а sale_margin — расчёт маржи — при этом ядро остаётся единым и не дублируется.

Ключевые поля модели


Ниже перечислены основные поля sale.order.line, знание которых помогает правильно работать с предложениями и заказами.


1. order_id

Тип: Many2one (sale.order). Обязательное поле. Ссылается на родительский заказ и связывает строку с заказом; при удалении заказа строки обычно удаляются каскадно.


2. sequence

Тип: Integer. Значение по умолчанию 10. Определяет порядок отображения строк в документе — полезно для сортировки секций, заметок и товарных позиций.


3. company_id

Тип: Many2one (res.company). Берётся из order_id. Используется для правил многокомпаний и контроля доступа.


4. currency_id

Тип: Many2one (res.currency). Берётся из заказа. Обеспечивает корректную валюту для всех денежных полей в строке.


5. order_partner_id

Тип: Many2one (res.partner). Клиент, указанный в заказе. Влияет на выбор прайс‑листа и налоговые правила.


6. salesman_id

Тип: Many2one (res.users). Привязка к менеджеру по продажам — важна для комиссии и отчётности.


7. state

Тип: Selection. Берётся из заказа. Статус заказа (черновик, отправлен, подтверждён, выполнен, отменён) определяет, какие поля доступны для редактирования.


8. display_type

Тип: Selection. Значения: line_section или line_note. Позволяет помечать строку как заголовок секции или заметку — такие строки не содержат товарных данных.


9. is_downpayment

Тип: Boolean. Флаг авансовой оплаты; такие строки выставляются отдельным счётом.


10. is_expense

Тип: Boolean. Источник строки — расход или счёт поставщика; используется для учёта затрат по проектам.


11. product_id

Тип: Many2one (product.product). Конкретный продаваемый товар. Для товарных позиций домен ограничивает выбор продажными товарами; обычно обязателен.


12. product_template_id

Тип: Many2one (product.template). Вычисляемое из product_id. Нужен для конфигурации вариантов товара и работы конфигуратора.


13. name

Тип: Text. Описание позиции; формируется из товара и дополнительных атрибутов, включает информацию о варианте при необходимости.


14. product_uom_qty

Тип: Float. Обязательное поле. Количество товара; по умолчанию 1.0; может зависеть от упаковки.


15. product_uom

Тип: Many2one (uom.uom). Единица измерения; по умолчанию берётся из карточки товара; влияет на расчёт цен и количества.


16. tax_id

Тип: Many2many (account.tax). Налоги, применяемые к строке; рассчитываются с учётом товара и фискальной позиции.


17. price_unit

Тип: Float. Обязательно. Цена за единицу в выбранной единице измерения; вычисляется из прайс‑листа или задана вручную.


18. discount

Тип: Float. Процент скидки, применяемый к цене до расчёта налогов.


19. price_subtotal

Тип: Monetary. Сумма по строке до налогов; вычисляется из количества, цены и скидки.


20. price_tax

Тип: Float. Сумма налогов по строке; вычисляется из price_subtotal и tax_id.


21. price_total

Тип: Monetary. Итоговая сумма с учётом налогов — ключевая величина для выставления счёта.


22. product_packaging_id

Тип: Many2one (product.packaging). Дополнительная упаковка (например, коробка на 12 шт.). При заданной упаковке количество может рассчитываться в упаковках.


23. customer_lead

Тип: Float. Время поставки в днях — от подтверждения заказа до отгрузки; используется для расчёта даты доставки.


24. qty_delivered

Тип: Float. Количество отгруженное; обновляется по движениям на складе или вручную; важно для частичного выставления счётов.


25. qty_invoiced

Тип: Float. Уже выставленное количество; вычисляется по строкам счёта.


26. qty_to_invoice

Тип: Float. Оставшееся к выставлению количество; рассчитывается по qty_delivered и qty_invoiced.


27. invoice_status

Тип: Selection. Значения: upselling, invoiced, to invoice, no — показывает текущее состояние по выставлению счётов для строки.


28. invoice_lines

Тип: Many2many (account.move.line). Связь со строками счётов, созданными из этой позиции — нужна для прозрачности и трассировки.


29. create_date

Тип: Datetime. Дата создания записи; управляется системой автоматически.


30. write_date

Тип: Datetime. Дата последнего изменения; полезна для аудита и синхронизаций.

Где эта модель применяется в бизнес-процессах


1. Коммерческое предложение и заказ

При создании предложения менеджер добавляет товары — каждая позиция превращается в sale.order.line и отображает количество, цену, скидку и сумму. Заказ подтверждается, когда клиент согласен с условиями.


2. Прайс‑листы и скидки

Прайс‑листы применяются на уровне строки: price_unit и discount часто вычисляются по правилам прайс‑листа. Там же обрабатываются скидки по объёму и индивидуальные условия для клиентов.


3. Доставка и выставление счетов

При отгрузке обновляется qty_delivered. Выставление счётов может происходить по факту отгрузки или по всему заказу целиком; поле invoice_status подсказывает, что ещё нужно выставить.


4. Проекты и услуги

Для сервисных продуктов строки связываются с задачами проекта и табелями; наследование analytic.mixin даёт возможность учитывать затраты по проекту.


5. Интернет‑магазин и портал

Когда клиент делает заказ на сайте, позиции корзины превращаются в sale.order.line. Конфигуратор товаров работает через product_template_id и набор пользовательских атрибутов.

Как разработчики расширяют модель


Разработчики расширяют sale.order.line разными способами, главным образом через механизмы наследования моделей Odoo.


Наследование модели

Пропишите _inherit = 'sale.order.line' в своём модуле, чтобы добавить поля, переопределить методы или задать ограничения. Такой подход сохраняет расширения вынесенными в отдельный модуль и упрощает будущие обновления.


Добавление полей

В дочерней модели объявляйте новые поля подходящего типа: Char, Many2one, Boolean, Integer, Text, Selection. Для многокомпанейных сценариев продумывайте company_dependent поля.


Расширения на Python

Переопределяйте вычисляемые методы, например _compute_price_unit или _compute_price_subtotal, либо подключайте логику в create/write. Всегда оборачивайте вызов базовой реализации через super() и внимательно следите за зависимостями вычислений.


Odoo Studio

Studio позволяет добавлять поля без кода — удобно для быстрых правок. Но для сложной логики и поддержки при обновлениях надёжнее писать полноценный модуль.

Рекомендации по использованию


  • Используйте display_type для разделов и заметок — так отчёты не засоряются «пустыми» товарными строками.
  • При интеграции через API создавайте строки в контексте заказа: используйте поле order_line_ids на sale.order с корректными командами Odoo для создания/обновления.
  • Уважайте SQL‑ограничения: товарная строка должна иметь product_id и product_uom, а для секции/заметки обязательно указывать display_type.
  • Для кастомной логики ценообразования сначала пробуйте прайс‑листы. Переопределяйте вычисления только если правила прайс‑листов не покрывают требуемый сценарий.
  • Для пользовательских полей придерживайтесь префикса x_ или добавляйте префикс модуля, чтобы минимизировать риск конфликтов с будущими версиями Odoo.

Распространённые ошибки


  • Создание строк без order_id. Это обязательное поле — всегда создавайте строки в контексте заказа, иначе валидаторы и бизнес‑логика сломаются.
  • Путаница между product_id и product_template_id. Для реальной товарной позиции используйте product_id; product_template_id удобен в потоках конфигурации при выборе варианта.
  • Изменение price_unit или discount после выставления счёта. Если qty_invoiced > 0, изменение цен может привести к несоответствиям между заказом и уже выставленными счетами.
  • Переопределение ключевых методов без вызова super(). Это часто ломает сторонние модули и осложняет обновления.
  • Забыть установить display_type для секции или заметки. Тогда строка будет валидироваться как товарная и приведёт к ошибке.

Вывод


Модель sale.order.line — ядро модуля продаж в Odoo: она хранит каждую позицию в предложениях и заказах. Понимание её полей и способов расширения облегчит настройку, кастомизацию и интеграцию системы.


Будь вы функциональным консультантом, формализующим процессы, или разработчиком, пишущим модули, глубокое понимание sale.order.line сэкономит время и уменьшит количество ошибок.

Нужна помощь с внедрением Odoo?


Компания Dasolo помогает внедрять, настраивать и оптимизировать Odoo. Мы специализируемся на интеграциях через API и разработке модулей, и имеем богатый опыт работы с архитектурой данных Odoo и моделями, такими как sale.order.line.


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

Модель sale.order.line: строение и логика строк продаж в Odoo
Dasolo 10 марта 2026 г.
Поделиться этой записью
Войти оставить комментарий