Введение
Поле Float — это стандартный тип в Odoo для хранения чисел с дробной частью. В учётных задачах это те значения, которые не помещаются в целые числа: цены за единицу, вес и объём товаров, проценты скидок и налогов, коэффициенты в спецификациях — всё это обычно хранится именно в полях Float.
На вид это просто числовое поле, но важны детали: как система округляет и хранит значения, как числовые данные участвуют в отчётах и агрегациях, и в каких случаях лучше выбрать другой тип поля.
В этой статье объяснено, какие данные хранит Float, как Odoo с ним взаимодействует, как добавить или настроить такое поле через Studio и код, и где оно практически используется в Sales, Inventory и Accounting.
Что такое поле Float в Odoo
В ORM Odoo значение Float хранится в PostgreSQL как колонка double precision — это примерно до 15 значащих цифр. Для повседневных задач такой запас точности обычно более чем достаточен.
Для пользователя поле Float выглядит как числовое поле ввода. Количество отображаемых знаков после запятой управляется параметром digits, который вы указываете при создании поля. В списках такие значения по умолчанию выравниваются вправо; в сводных таблицах и графиках Float участвует в агрегатах — суммы, средние и т. п.
Пример декларации поля в Python‑модели выглядит примерно так:
from odoo import fields, models
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
custom_margin = fields.Float(
string='Custom Margin',
digits=(5, 2),
default=0.0,
)
Параметр digits — это кортеж: первый элемент — общее число значащих цифр, второй — число знаков после десятичной точки. Например, (5, 2) допускает до пяти значащих цифр с двумя знаками после запятой.
Вместо жёсткого задания digits можно ссылаться на именованную группу точности.
price_premium = fields.Float(
string='Price Premium',
digits='Product Price',
)
В Odoo есть предопределённые группы точности (Decimal Accuracy) — например, Product Price, Product Unit of Measure, Discount и Stock Weight. Если использовать такие группы, администраторы могут менять точность через интерфейс, не правя код.
В Odoo Studio поле Float называется «Decimal Number». При создании через Studio используется дефолтная точность, но её можно изменить в свойствах поля. Это делает добавление дробных полей доступным бизнес‑пользователям без привлечения разработчиков.
Как это поле работает
При добавлении Float‑поля через модуль Odoo автоматически создаёт соответствующую колонку в базе данных при установке или обновлении модуля — отдельно писать SQL‑скрипты не требуется.
Параметр digits одновременно влияет на отображение и на то, как значение округляется при сохранении. Если задать digits=(6, 2) и ввести 3.14159, Odoo сохранит 3.14 — округление проходит на уровне ORM, а не только при показе.
Ключевые атрибуты поля
Ниже — самые важные свойства Float‑поля в Odoo, которые стоит знать и настраивать.
- digits: кортеж вроде (6, 2) или имя группы точности. Управляет и отображением, и тем, как значение хранится.
- required: делает поле обязательным. Учтите, что значение 0.0 проходит проверку обязательности, поэтому иногда это не то поведение, которого ожидают.
- default: значение по умолчанию при создании записи. default=0.0 гарантирует, что поле содержит число, а не False.
- compute: привязка к вычисляемому методу в Python. Подходит для производных полей — маржи, коэффициентов и т. п.
- store: при использовании с compute сохраняет рассчитанное значение в базе, чтобы по нему можно было искать, фильтровать и группировать записи.
- group_operator: определяет способ агрегирования в сводных и графиках: 'sum', 'avg', 'min', 'max' и т. п. По умолчанию Float агрегируются через 'sum'.
- copy: управляет копированием значения при дублировании записи. По умолчанию True.
Отображение в видах
В формах Float рендерится как числовой ввод; разделитель дробной части зависит от локали пользователя. В списках значения по умолчанию выравниваются справа. В поиске по числовым полям доступны сравнения (>, <, = и т. п.).
К полю Float можно применить виджеты. Например, percentage‑виджет умножает внутреннее значение на 100 и добавляет знак %, что удобно для полей, хранящих доли (0–1) или проценты.
Взаимодействие с ORM
При чтении поля ORM возвращает Python float или False, если поле не задано и нет значения по умолчанию. При записи допускаются int, float или False. Округление по digits применяется при сохранении.
Важное правило для разработчиков: не сравнивайте Float с помощью == в Python. Из‑за особенностей вычислений с плавающей точкой видимые равные значения могут оказаться неравными. Для надёжных сравнений используйте float_compare и float_is_zero из odoo.tools.float_utils — они учитывают заданную точность.
Практические бизнес‑сценарии
Поле Float встречается почти во всех модулях Odoo. Ниже — пять реальных примеров применения в бизнес‑процессах.
Продажи: процент скидки в строках заказа
Поле discount на sale.order.line — Float. Когда менеджер вводит 15% скидки, Odoo хранит 15.0 и использует это при расчёте цены за единицу. Значение попадает в печатные предложения и счета, а также участвует в отчётах по марже — корректные скидки важны и для коммуникации с клиентами, и для аналитики прибыльности.
Склад: вес и объём товаров
У товаров есть полевые weight и volume — это Float. Товар с весом 2.5 кг или объёмом 0.003 м3 требует дробной точности; целое число здесь не подойдёт. Эти значения влияют на расчёт стоимости доставки и интеграции с курьерскими сервисами: если вес указан неправильно, тариф от API перевозчика будет неверен.
Бухгалтерия: налоговые ставки
Ставки налогов в account.tax — Float. Стандартная ставка, например 21%, хранится как 21.0; пониженные ставки — 6.0 или 5.5. Бухгалтерский движок Odoo использует эти значения при расчётах по каждому счёту — даже небольшие погрешности округлений при большом количестве документов могут дать расхождения в налоговых отчётах.
Производство: количества в спецификациях
В MRP количество компонентов в BOM — Float. Рецепт может требовать 0.75 л жидкости или 2.5 кг сырья — дробные значения обычны. Если использовать Integer там, где нужны доли, вы получите ошибки в производстве и накопление отклонений.
Закупки: коэффициенты цен и маржи поставщика
В прайс‑листах поставщиков и правилах наценок используются Float‑поля для множителей и коэффициентов. Фактор 1.25 (25% наценки) или 0.85 (15% скидки) — типичные примеры. Эти значения автоматизируют расчёт цен в заказах закупки и помогают закупщикам поддерживать консистентность цен по поставщикам.
Создание и настройка поля Float
Добавить Float‑поле в модель можно тремя основными способами — выбор зависит от того, кто и как управляет системой.
Через Odoo Studio (без кода)
Odoo Studio — встроенный инструмент низкоуровневой кастомизации. Порядок действий для добавления Float поля без программирования:
- Откройте Odoo Studio из меню.
- Перейдите в нужную форму.
- Перетащите поле Decimal Number из палитры на форму.
- Задайте метку, значение по умолчанию и количество десятичных знаков в панели свойств.
- Сохраните и закройте Studio.
Studio создаст поле с префиксом x_studio_ и автоматически добавит его в вид. Базы данных при этом вам трогать не нужно — это самый простой способ расширить формы для бизнес‑пользователей без привлечения разработчиков.
Через Python в кастомном модуле
Для разработчиков Float‑поля объявляются в коде Python — это предпочтительный путь, если кастомизация должна быть версионируемой и переносимой между средами:
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_credit_limit = fields.Float(
string='Credit Limit',
digits=(12, 2),
default=0.0,
help='Maximum outstanding balance allowed for this customer.',
)
После добавления поля не забудьте включить его в XML‑вид, чтобы оно отображалось в интерфейсе. Odoo само создаст колонку в базе при установке/обновлении модуля — это стандартный рабочий процесс для разработок.
Через XML‑RPC API
Если вы автоматизируете конфигурацию удалённо (скрипты развертывания, ноутбуки), поля можно создавать программно через XML‑RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_custom_coefficient',
'field_description': 'Custom Coefficient',
'model_id': model_id,
'ttype': 'float',
'state': 'manual',
}]
)
Параметр state: 'manual' указывает, что поле создано вручную, а не модулем — это корректно для полей, созданных через Studio или API. Точность для таких полей управляется через настройки Decimal Accuracy в техническом меню. Такой подход удобен для автоматизированного создания полей в скриптах развертывания.
Рекомендуемые практики
1. Используйте именованные группы точности
Вместо жесткого digits=(6, 2) ссылаться на группу (например, 'Product Price' или 'Product Unit of Measure') — хорошая практика. Это позволяет менять точность через интерфейс и синхронизировать поведение кастомных полей с нативными полями Odoo.
2. Для сумм и цен используйте Monetary, а не Float
Это главное правило: Monetary‑поле связано с валютой, учитывает правила округления для конкретной валюты и корректно работает в мультивалютной среде. Float для цен и сумм приведёт к проблемам с округлениями и искажению финансовых отчётов.
3. Всегда задавайте значение по умолчанию
Установите default=0.0 для числовых полей, которые должны начинаться с нуля. Иначе поле вернёт False до заполнения, что может вызвать ошибки в вычисляемых полях и методах, ожидающих число.
4. Настройте group_operator для отчётов
Если поле логично суммируется, укажите group_operator='sum'. Для ставок и процентов чаще подходит 'avg'. Правильная агрегатная логика обеспечит адекватные сводные таблицы и графики.
5. Задокументируйте соглашения по процентам
Чётко фиксируйте, хранитесь ли проценты в формате 0–100 (15.0 = 15%) или 0–1 (0.15 = 15%). Смешение этих соглашений в модели приводит к скрытым ошибкам расчётов, которые тяжело отследить.
Типичные ошибки и подводные камни
Использование Float для денежных сумм
Float не хранит информацию о валюте. Число 1500 в поле Float не несёт контекста — это могут быть рубли, евро или доллары. В мультивалютных конфигурациях это приводит к неверным итогам в финансовых отчётах — для денежных значений нужен тип Monetary.
Отсутствие параметра digits
Если не указывать digits, Odoo по умолчанию выдаст точность в 2 знака после запятой. Это может быть неприемлемо для курсов валют или коэффициентов перевода единиц, где нужны 4–6 знаков: невнимательное округление таких коэффициентов приведёт к систематическим ошибкам.
Сравнения Float с == в Python
Проверка равенства через == ненадёжна из‑за особенностей представления чисел с плавающей точкой: 0.1 + 0.2 == 0.3 даст False. Для корректных сравнений используйте float_compare(value1, value2, precision_digits=2) и float_is_zero(value, precision_digits=2) из odoo.tools.float_utils, они учитывают заданную точность.
Применение Float там, где нужен Integer
Если поле всегда содержит целые числа — количество упаковок, номер позиции и т. п. — используйте Integer. Float допустим, но вводит путаницу и позволяет пользователям случайно ввести дробные значения там, где это бессмысленно.
Необработка False в вычисляемых методах
Если поле не имеет default, при отсутствии значения оно вернёт False, а не 0.0. При вычислениях это приведёт к TypeError. Всегда проверяйте на False или задавайте default=0.0, чтобы избежать ошибок при реальных данных.
Заключение
Float — фундаментальный элемент модели данных Odoo. Он отвечает за дробные числа в ценах, количествах, ставках и измерениях и работает корректно, если вы заранее продумали точность и значения по умолчанию.
Ключевые выводы: используйте именованные группы точности для стандартных значений, применяйте Monetary для сумм в валюте, задавайте default=0.0 и документируйте соглашения по процентам. Эти привычки предотвращают большинство проблем с качеством данных.
Добавляйте поля через Studio, пишите их в Python‑модулях или создавайте программно через ORM/API — главное, настроить Float правильно с самого начала, чтобы система оставалась аккуратной и предсказуемой.
Мы в Dasolo помогаем компаниям внедрять и настраивать Odoo по всем направлениям. Если нужна помощь с проектированием модели данных, добавлением кастомных полей или разработкой модуля — наша команда готова взять задачу. Свяжитесь с нами и обсудим ваш Odoo‑проект.