Введение
Если вы хоть раз открывали заказ продажи, задачу проекта или производственный ордер в Odoo, вы уже встречались с полем «Дата». Сроки завершения, даты доставки, даты оплаты счетов, даты начала контрактов — почти вся критичная по времени информация в системе хранится именно в таких полях.
Для конечного пользователя поле «Дата» кажется простым: клик — календарь — выбор нужного дня. Но под этой простотой скрывается важная логика: отличие от полей с временем, правила хранения в базе и нюансы при автоматизациях. Понимание этих деталей помогает избежать неожиданных сдвигов дат и ошибок в рабочих процессах при внедрении Odoo.
Эта статья расскажет, что именно хранит поле «Дата» в Odoo, как его правильно использовать в бизнес-процессах и какие настройки помогают сделать систему надёжной и предсказуемой.
Что представляет собой поле «Дата» в Odoo
В модели данных Odoo поле типа fields.Date хранит только календарную дату — год, месяц, день — без указания времени суток. Запись вроде «2026-03-06» сохраняется как чистая дата, без часов и минут.
В PostgreSQL, на котором работает Odoo, такое поле соответствуют типу столбца DATE. Это отличается от поля даты-времени, которое мапится в TIMESTAMP и содержит точную отметку времени с секундами.
В интерфейсе поле отображается как текстовое поле с выпадающим календарём: пользователь может ввести дату вручную или выбрать её через пикер. В списках даты показываются в локальном формате пользователя и выровнены в соответствии с привычной для него ориентацией.
Ниже — пример того, как создают такое поле в кастомном модуле на Python:
from odoo import fields, models
class ProjectTask(models.Model):
_inherit = 'project.task'
x_deadline_confirmed = fields.Date(
string='Confirmed Deadline',
help='The officially confirmed deadline agreed with the customer.',
)
Если добавлять поле через Odoo Studio, оно будет отображаться как Date и автоматически получит префикс x_studio_. При создании через Python или API вы задаёте техническое имя сами — это удобно для версионирования и контроля кода.
Как работает это поле
Дата против Даты-времени: в чём разница
Главное, что нужно помнить о поле «Дата» — в нём нет времени. Никаких часов, минут или конвертаций по часовым поясам: только календарный день.
Поле DateTime, наоборот, хранит полный временной штамп в UTC, и Odoo при отображении переводит его в локальное время пользователя. Именно это поведение вызывает типичные жалобы «моя дата сместилась на день» — такие проблемы почти всегда связаны с DateTime, а не с чистой датой.
С полем Date то, что вы записали, увидят все пользователи одинаково. Запись 2026-03-15 останется 2026-03-15 вне зависимости от местоположения сотрудника.
Ключевые атрибуты поля
Ниже — набор свойств поля Date, которые чаще всего настраивают разработчики и консультанты в Odoo:
- required: делает поле обязательным в интерфейсе и на уровне модели.
- default: задаёт значение по умолчанию, например
fields.Date.todayставит текущую дату при создании записи. - index: создаёт индекс в базе для ускорения фильтрации и поиска по этому полю.
- compute: указывает метод Python для вычисления значения поля динамически.
- store: в комбинации с
computeсохраняет вычисленное значение в базе данных. - readonly: делает поле только для чтения, чтобы пользователи не могли менять значение вручную.
- copy: управляет поведением при дублировании записи. По умолчанию
True, можно отключить.
Как поле отображается в представлениях
В форме поле Date выглядит как текстовый инпут с календарём, в списках — как отформатированный текст. В поиске доступны готовые фильтры по диапазонам («на этой неделе», «в этом месяце», «в этом квартале») и стандартные операторы сравнения: до, после, равно и т.д.
Формат показа зависит от языковых настроек пользователя: американцы увидят MM/DD/YYYY, европейцы — DD/MM/YYYY. Но в базе дата всегда хранится в ISO-формате YYYY-MM-DD, независимо от отображения на экране.
Взаимодействие с ORM Odoo
При чтении через ORM поле Date возвращается как объект Python datetime.date, либо False, если поле пустое. При записи можно передать объект datetime.date или строку в формате «YYYY-MM-DD». Через XML-RPC даты передаются строками.
Сложных преобразований между представлением и хранением тут нет: фреймворк автоматически управляет форматами и сохранением, поэтому с Date работать удобно и предсказуемо.
Сценарии использования в бизнесе
Где поле «Дата» приносит реальную пользу в бизнесе
CRM: даты начала и окончания контрактов
В отделах продаж важно отслеживать, когда контракт начинается и заканчивается. Поля Date в карточках лидов или в отдельной модели контракта помогают понимать периоды действия соглашений и планировать продления.
Добавив автоматические триггеры на приближение даты окончания, можно отправлять клиенту напоминания или переводить контракт в статус «на продление» — это снижает риск пропуска пролонгаций и увеличивает удержание клиентов.
Продажи: желаемые даты доставки
Клиенты часто указывают конкретную дату доставки в заказе. Поле «Requested Delivery Date» на заказе продажи даёт операционной команде чёткую цель для планирования отгрузок.
Использование Date вместо DateTime упрощает коммуникацию между отделами и исключает проблемы с часовыми поясами: склад и отдел продаж видят один и тот же календарный день без смещений.
Склад: сроки годности партий
В пищевой, фармацевтической и химической отраслях контроль сроков годности по партиям критичен. В Odoo партии (stock.lot) обычно снабжают полями Date для хранения дат истечения срока и «лучше до».
Эти даты формируют правила отбора FEFO (первым истекает срок — первым отгружается) и запускают автоматические оповещения при приближении к истечению срока, помогая сохранять качество и соответствовать регуляторным требованиям.
Бухгалтерия: даты платежей по счетам
Даты оплаты в счётах — это Date поля. От них зависят напоминания об оплате, классификация просрочек и расчёт ageing-отчётов по дебиторам и кредиторам.
Правильность этих дат критична для денежного потока: ошибочная дата из-за неправильно выбранного типа поля может нарушить автоматическую рассылку напоминаний и учёт просрочек.
HR: даты приёма, контрактов и сертификаций
HR-подсистемы активно используют Date для дат приёма на работу, окончания испытательного срока, начала и конца контрактов, а также сроков действия сертификатов и медосмотров. Эти даты запускают уведомления, расчёты и интеграции с оплатой труда.
Чистые и корректные данные по датам сотрудников — основа надёжных HR-процессов. Ошибки в датах ломают автоматизацию и создают ручные сверки в будущем.
Как добавить и настроить поле «Дата»
Существует три основных подхода к добавлению Date-поля в модель Odoo — выбор зависит от уровня доступа к коду и способа управления системой.
Через Odoo Studio (без кода)
Odoo Studio — самый быстрый способ добавить Date-поле без программирования. Подходит бизнес-пользователям и консультантам, которые хотят быстро расширить стандартные формы:
- Откройте Odoo Studio из главного меню.
- Перейдите на форму, в которую хотите добавить поле.
- Перетащите поле Date из боковой панели на форму.
- Задайте подпись, обязательность и значение по умолчанию при необходимости.
- Сохраните и закройте Studio.
Studio создаёт поле с префиксом x_studio_ и сразу добавляет его в форму — никаких миграций базы данных вручную делать не нужно.
Через Python в кастомном модуле
Для разработчиков и при необходимости версионирования правок поле добавляют в файлы модели на Python. Такой подход обязателен при развертывании в нескольких средах и для поддержки через систему контроля версий:
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_customer_requested_date = fields.Date(
string='Customer Requested Date',
index=True,
copy=False,
help='Delivery date requested by the customer at time of order.',
)
После добавления поля его нужно включить в XML-представления, чтобы оно отображалось в интерфейсе. При установке или обновлении модуля Odoo создаст соответствующий столбец в базе автоматически.
Через XML-RPC API
Если вы создаёте поля программно в рамках CI/CD или удалённых скриптов, это можно сделать через XML-RPC API Odoo:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_customer_requested_date',
'field_description': 'Customer Requested Date',
'model_id': model_id,
'ttype': 'date',
'state': 'manual',
}]
)
Для поля «Дата» значение ttype — 'date'. Для DateTime это было бы 'datetime'. Установка state в 'manual' отмечает поле как созданное вручную, а не модулем — полезно для удалённых конфигураций и автоматизации.
Рекомендации по использованию
Рекомендация 1: выбирайте Date, когда важен только день
Если вам нужен лишь календарный день — дедлайн, дата начала контракта или день рождения — используйте fields.Date. Выбор DateTime там, где не нужен час, добавляет сложности с часовыми поясами и может привести к смещению даты на один день у пользователей в других зонах.
Рекомендация 2: задавайте осмысленные значения по умолчанию
Для полей вроде «Ожидаемая дата доставки» удобнее ставить дефолт на сегодня или сегодня плюс несколько дней. В Python используйте default=fields.Date.today (без скобок), чтобы значение вычислялось при создании записи, а не фиксировалось на уровне класса.
Рекомендация 3: индексируйте поля, которые фильтруете часто
Если пользователи регулярно ищут записи по дате (просроченные счета, предстоящие продления, истекающие сертификаты), включите index=True. На больших объёмах данных индекс значительно ускорит фильтры и отчёты и стоит практически ничего на этапе внедрения.
Рекомендация 4: выключайте копирование для неподходящих дат
Поля вроде «Дата начала контракта» или «Срок годности» не должны переноситься при дублировании записи. Поставьте copy=False, чтобы избежать тихих ошибок, когда при клонировании остаются устаревшие даты.
Рекомендация 5: добавляйте проверки для пар дат «начало—конец»
Если в модели есть пара «Дата начала» и «Дата окончания», обязательно добавьте проверку через @api.constrains, чтобы конец не был раньше начала. Это простая мера, которая предотвращает целый класс проблем с расчётом длительностей и корректностью отчётов.
Распространённые ошибки
Типичная путаница между Date и DateTime
Самая частая ошибка — использовать DateTime там, где достаточно Date. DateTime сохраняет отметку в UTC и переводит при показе; Date сохраняет только день без конвертаций. Из-за этого дата, введённая в зоне UTC+2 как 15 марта, может у пользователя в UTC-5 отображаться как 14 марта — путаница, которую легко избежать выбором правильного типа поля.
Всегда выбирайте самый простой тип поля, соответствующий реальной бизнес-логике.
Неучёт часового пояса сервера в планировщиках
При настройке планируемых действий и отчётов, которые опираются на «сегодня», помните, что fields.Date.today() берёт дату сервера (UTC). В большинстве случаев это приемлемо, но для распределённых команд с сильно разными часовыми поясами возможны несоответствия на один день — тестируйте автоматизации из разных зон, если это критично.
Отсутствие валидации для диапазонов дат
Часто видишь, как в модели есть поля «Дата начала» и «Дата окончания», но никакой проверки, чтобы конец не был раньше начала. Это позволяет неверным данным проникать в систему и ломать вычисления длительностей и отчёты. Всегда добавляйте @api.constrains для таких пар полей.
Забытые индексы для часто используемых дат
Поля, по которым строят «просроченные» списки или «ближайшие дедлайны», часто используются в запросах с условиями «дата меньше сегодня». Без индекса такие запросы приводят к полному сканированию таблицы, что на больших моделях (счета, задачи, перемещения) ощутимо замедляет систему.
Хранение дат в Char-полях
Иногда команды сохраняют даты в текстовых полях, чтобы сохранить нужный формат или избежать пикера. Это ломает сортировку, фильтрацию, арифметику по датам и отчёты. Всегда используйте fields.Date — база и Odoo сами корректно локализуют и формируют представление даты.
Часто задаваемые вопросы
Чем отличается поле Date от DateTime в Odoo?
Date хранит только календарную дату (год, месяц, день) без времени. DateTime содержит полный временной штамп с часами и секундами, сохраняется в UTC и при показе переводится в локальное время пользователя. Используйте Date, когда время суток не важно; DateTime — когда нужно знать точный момент события.
Как задать сегодняшнюю дату по умолчанию?
В Python указывайте default=fields.Date.today без скобок — это callable, который вычисляется при создании записи. В Odoo Studio можно выбрать «Today» в параметрах поля как значение по умолчанию.
Можно ли вычислять Date поле на основе других полей?
Да. Определите поле с compute='_compute_my_date' и напишите метод с декоратором @api.depends(), перечислив поля, влияющие на вычисление. Для арифметики по датам используйте datetime.date и timedelta. Если нужен поиск или группировка по вычисляемому значению, добавьте store=True.
Как отфильтровать записи по диапазону дат в домене Odoo?
В домене используйте стандартные операторы сравнения. Например, чтобы найти записи за март 2026:
[
('x_date_field', '>=', '2026-03-01'),
('x_date_field', '<=', '2026-03-31')
]
Строки дат в доменах всегда должны быть в ISO-формате YYYY-MM-DD.
Можно ли сделать поле «Дата» обязательным только при определённых условиях?
Нативно Odoo не поддерживает «условную обязательность» на уровне модели без кода. В представлениях через attrs можно визуально пометить поле как требуемое, но полная серверная проверка требует Python-валидации с @api.constrains. Для простых случаев Odoo Studio предлагает условную видимость и правила, которые часто решают задачу без программирования.
Заключение
Поле «Дата» — один из самых практичных типов в Odoo. Оно просто по природе, но при этом формирует базу для важных бизнес-логик: напоминаний, проверки просрочек и отчётности по времени.
Главные выводы: выбирайте Date вместо DateTime, когда важен только календарный день; используйте дефолты и индексы, чтобы улучшить удобство и производительность; всегда добавляйте валидацию для пар дат, определяющих диапазон.
Чистая и продуманная модель данных в Odoo начинается с мелочей — например, с правильного выбора типа поля. Принятые с самого старта решения делают внедрение надёжным, а поддержку — проще. Поле «Дата» — базовый, но критически важный элемент такой модели.
Мы в Dasolo помогаем компаниям настраивать, дорабатывать и оптимизировать Odoo во всех направлениях. Нужна помощь с проектированием модели данных, созданием кастомных полей и процессов или разработкой модуля с нуля — наши специалисты готовы подключиться. Свяжитесь с нами и обсудим ваш проект по Odoo.