Введение
В Odoo данные упакованы в модели — это как шкафы для хранения информации в базе. Любая бизнес‑запись — заказ, счёт, контакт — хранится в своей модели, которая определяет, какие полки (поля) и ячейки (связи) для неё есть.
Понимание моделей важно и для консультанта, и для программиста: именно модель задаёт структуру данных, связи между объектами и место, где закрепляют бизнес‑правила. Без этого сложно правильно настраивать процессы и писать расширения.
В этой заметке мы подробно рассмотрим одну из ключевых моделей Odoo — sales.order. Это тот объект, с которым вы неизбежно столкнётесь при настройке продаж, интеграции с внешними системами или разработке модулей.
Что такое модель sales.order
Модель sales.order отвечает за коммерческие предложения и сами заказы — это центральная карточка продажи, пока она не превратилась в отгрузку или счёт. Здесь собираются все данные о сделке до её завершения.
Эта модель используется модулем «Продажи» и служит связующим звеном между CRM, складом и бухгалтерией.
Рабочий цикл прост: менеджер создаёт предложение — появляется запись sales.order в состоянии draft. После подтверждения со стороны клиента запись переводится в состояние sale. Одна и та же модель хранит и черновики, и подтверждённые заказы; поле state фиксирует текущее состояние сделки.
Другие модули дополняют sales.order через наследование: CRM привязывает лид/сделку к заказу, бухгалерия добавляет реквизиты для выставления счёта, склад — даты отгрузки и резервы. Каждый модуль дополняет лишь нужные поля, не копируя базовую структуру.
Ключевые поля модели
Ниже — обзор полей, которые чаще всего встречаются в sales.order. Знание их назначения упрощает настройку процессов и интеграции.
1. name
Тип: Char. Это номер заказа или предложения — служебный идентификатор (например S00042). Обычно генерируется автоматически и отображается на списках и печатных формах.
2. state
Тип: Selection. Статус жизненного цикла заказа. Значения: draft (черновик), sent (отправлено клиенту), sale (подтверждён), done (выполнен/оплачен), cancel (отменён). От значения зависит доступность действий.
3. partner_id
Тип: Many2one (res.partner). Клиент — компания или контакт. Обязательное поле, основа для логики по клиентам и отчётности.
4. partner_invoice_id
Тип: Many2one (res.partner). Адрес / контакт для выставления счёта. По умолчанию берётся из partner_id, меняется при централизованной оплате.
5. partner_shipping_id
Тип: Many2one (res.partner). Адрес доставки. Если не указан, используется partner_id — влияет на создание отгрузочных документов и расчёт доставки.
6. user_id
Тип: Many2one (res.users). Ответственный менеджер. Влияет на комиссии, задачи и отчёты по менеджерам.
7. team_id
Тип: Many2one (crm.team). Команда продаж — нужен для сводных отчётов и распределения квот.
8. date_order
Тип: Datetime. Дата заказа: для черновиков — дата создания, для подтверждённых — дата подтверждения. Используется в отчётах и при сортировке.
9. validity_date
Тип: Date. Дата истечения коммерческого предложения — после неё оффер может стать недействительным.
10. commitment_date
Тип: Datetime. Обещанная дата доставки. При её установке планирование отгрузок ориентируется именно на неё.
11. order_line
Тип: One2many (sale.order.line). Строки заказа — продукты, количество, цена и налоги. Это детальное содержание сделки.
12. amount_untaxed
Тип: Float. Сумма без налогов — вычисляемое поле по строкам заказа. Важно для промежуточных отчётов.
13. amount_tax
Тип: Float. Сумма налогов, рассчитанная по строкам и налоговым правилам.
14. amount_total
Тип: Float. Итоговая сумма с налогами — ключевая величина для выставления счёта и отчётности.
15. currency_id
Тип: Many2one (res.currency). Валюта заказа — чаще наследуется от компании или прайс‑листа. Все денежные поля связаны с ней.
16. pricelist_id
Тип: Many2one (product.pricelist). Прайс‑лист, по которому считаются цены на строки заказа. Может браться из партнёра или устанавливаться вручную.
17. payment_term_id
Тип: Many2one (account.payment.term). Условия оплаты — например, 30 дней или частичный предоплат. Переносится в счёт при создании.
18. fiscal_position_id
Тип: Many2one (account.fiscal.position). Фискальное положение для сопоставления налогов при трансграничных продажах или особых режимах.
19. client_order_ref
Тип: Char. Внутренний референс клиента / номер заказа клиента — полезно, когда у покупателя есть собственный PO.
20. origin
Тип: Char. Источник создания заказа: имя сделки, рекламации или другой документ — важно для прослеживаемости.
21. create_date
Тип: Datetime. Дата и время создания записи — автоматически ведётся системой.
22. write_date
Тип: Datetime. Последнее время обновления записи — также ведётся автоматически.
23. note
Тип: Text. Текст условий, примечания или инструкции — может печататься в документах.
24. require_signature
Тип: Boolean. Если включено, требуется электронная подпись клиента перед подтверждением заказа — важно для интернет‑продаж и портала.
25. require_payment
Тип: Boolean. Если включено, требуется оплата до подтверждения — удобно для предоплаты или депозитов.
26. invoice_status
Тип: Selection. Статус по выставлению счета: no (не выставлен), to invoice (готов к выставлению), invoiced (выписан), upsell (есть дополнительные к выставлению позиции).
27. locked
Тип: Boolean. Блокировка редактирования — ставится при подтверждении или после проводки связанных документов.
28. company_id
Тип: Many2one (res.company). Компания в мультикомпании — влияет на доступность записи и видимость.
29. tag_ids
Тип: Many2many (crm.tag). Теги для категоризации и сегментации — удобны для фильтров и аналитики.
30. signed_by
Тип: Char. Имя подписавшего при требовании подписи — хранится для аудита.
31. signed_on
Тип: Datetime. Время подписи — фиксирует момент подтверждения с подписью.
32. prepayment_percent
Тип: Float. Процент предоплаты при требовании платежа — используется для депозитных заказов.
Как модель используется в бизнес‑процессах
1. Из предложения в заказ
Менеджер создаёт предложение, добавляет строки и цены, отправляет клиенту. После подтверждения запись переводится в состояние sale, и по ней можно сформировать счёт и отгрузочные документы.
2. E‑commerce и клиентский портал
Заказы с сайта автоматически создаются как sales.order. Параметры require_signature и require_payment позволяют требовать онлайн‑оплату или подпись до подтверждения.
3. Из CRM в продажи
При выигрышe сделки из CRM создаётся предложение: origin сохраняет ссылку на сделку, а user_id и team_id позволяют строить отчёты и рассчитывать комиссии.
4. Выставление счетов
Из подтверждённого заказа создаются счета. Строки счёта берутся из строк заказа, условия оплаты и фискальная позиция переносятся, а invoice_status показывает прогресс.
5. Отгрузка и обязательства
commitment_date влияет на планирование отгрузок: при наличии этой даты склад ориентируется на неё. partner_shipping_id указывает фактический адрес доставки.
Как разработчики расширяют модель
Разработчики расширяют sales.order разными способами, но основной инструмент — наследование моделей Odoo.
Наследование модели
Чтобы добавить поля или поведение, создавайте модель с _inherit = 'sale.order'. Так вы сохраняете изменения в отдельном модуле, что упрощает поддержку и обновления.
Добавление полей
В унаследованной модели объявляйте новые поля нужного типа: Char, Many2one, Boolean, Integer, Text, Selection. Для мультикомпаний учитывайте company_dependent поля.
Расширение на Python
Переопределяйте методы вроде action_confirm, create или write, не забывая вызывать super(). Следите за вычисляемыми полями и их зависимостями, чтобы не сломать логику.
Odoo Studio
Odoo Studio позволяет быстро добавить поля и простую логику без кода — удобно для быстрых правок. Для сложных и долгоживущих решений предпочтительнее модульный код.
Рекомендации и лучшие практики
- Используйте корректные статусы и не пропускайте этапы процесса — обход бизнес‑логики приводит к ошибкам в отчётах и обработке документов.
- Указывайте commitment_date, когда есть обещанная дата поставки — это улучшит планирование и уменьшит число аварийных отгрузок.
- Для агрегации по юридическим лицам используйте commercial_partner_id — это важно для кредитного контроля и сводной отчётности.
- При интеграции используйте XML‑RPC или JSON‑RPC API Odoo. Модель sales.order полностью доступна через API — важно корректно маппить внешние идентификаторы.
- Для пользовательских полей применяйте префикс x_ или префикс своего модуля, чтобы избежать конфликтов с будущими версиями Odoo.
Типичные ошибки и подводные камни
- Не пытайтесь править подтверждённые и заблокированные заказы без проверки поля locked — вместо этого создавайте новую ревизию или следуйте установленному workflow.
- Частая ошибка — путаница между partner_id, partner_invoice_id и partner_shipping_id. У каждого своё назначение; если адреса отличаются, задавайте все три поля явно.
- Не переопределяйте action_confirm без вызова super() — это ломает совместимость с другими модулями и усложняет будущие обновления.
- Не делайте новые поля обязательными без дефолтов — при миграции или обновлении существующие записи будут падать валидацией.
- Не забывайте устанавливать pricelist_id, когда валюта или логика ценообразования отличаются от стандартных — иначе цены и счета будут некорректны.
Вывод
Модель sales.order — ключевой элемент модуля «Продажи» в Odoo. Она аккумулирует предложения и подтверждённые заказы; знание её полей и расширений помогает правильно настраивать систему и интегрировать её в бизнес‑процессы.
Для консультанта и для разработчика понимание sales.order экономит время и снижает риск ошибок при настройке, кастомизации и интеграции.
Нужна помощь с внедрением Odoo?
Dasolo помогает компаниям внедрять и оптимизировать Odoo: мы делаем интеграции через API, пишем надёжные модули и проектируем структуры данных, включая модели вроде sales.order.
Если нужна помощь с внедрением, доработками или интеграциями Odoo — мы готовы подключиться и решить задачу. Записаться на демонстрацию чтобы обсудить ваш проект.