Контекст
У нас есть специальная модель global.budget, которая управляет глобальным бюджетом проекта. У него есть поле one2many прогноз_бюджет_идс, ссылающееся на другую модель прогноза.бюджет, которая содержит:
- analytic_account_id: аналитический аккаунт;
- budget_amount: запланированную сумму (денежную).
Цель
Когда пользователь открывает мастер распределения аналитики в строке заказа на покупку, в столбце «Аналитическая учетная запись» мы хотим отображать только те аналитические учетные записи, у которых Budget_amount > 0 в связанном глобальном бюджете.
Что мы попробовали
1 – Вычисляемое поле в Purchase.order, чтобы получить разрешенные идентификаторы аналитических учетных записей:
Код: Выделить всё
allowed_analytic_account_ids = fields.Many2many(
'account.analytic.account',
compute='_compute_allowed_analytic_account_ids'
)
@api.depends(
'overall_budget_id',
'overall_budget_id.forecast_budget_ids',
'overall_budget_id.forecast_budget_ids.analytic_account_id',
'overall_budget_id.forecast_budget_ids.budget_amount',
)
def _compute_allowed_analytic_account_ids(self):
for order in self:
if order.overall_budget_id:
lines = order.overall_budget_id.forecast_budget_ids.filtered(
lambda l: l.budget_amount > 0 and l.analytic_account_id
)
order.allowed_analytic_account_ids = lines.mapped('analytic_account_id')
else:
order.allowed_analytic_account_ids = False
- Связанное поле в Purchase.order для предоставления разрешенных идентификаторов на уровне строки:
Код: Выделить всё
allowed_analytic_account_ids = fields.Many2many(
'account.analytic.account',
related='order_id.allowed_analytic_account_ids',
store=False,
)
- Внедрение контекста в представление XML в поле аналитического_распределения:
Код: Выделить всё
{
'allowed_analytic_account_ids': parent.allowed_analytic_account_ids
}
- Переопределение name_search и поиска на account.analytic.account для применения фильтра из контекста:
Код: Выделить всё
@api.model
def search(self, domain, offset=0, limit=None, order=None):
allowed_ids = self.env.context.get('allowed_analytic_account_ids')
if allowed_ids:
domain = [('id', 'in', allowed_ids)] + list(domain)
print("Search domain:", domain)
return super().search(domain, offset=offset, limit=limit, order=order)
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
args = args or []
allowed_ids = self.env.context.get('allowed_analytic_account_ids')
if allowed_ids:
args = [('id', 'in', allowed_ids)] + args
print(args)
return super().name_search(
name=name, args=args, operator=operator, limit=limit
)
Мы проверили, что вычисляемое поле Allow_analytic_account_ids в заказе на покупку заполнено правильно благодаря оболочке odoo — оно содержит ожидаемые идентификаторы аналитических учетных записей (только те, у которых Budget_amount > 0). Таким образом, сторона данных работает нормально.
Однако операторы печати внутри search и name_search никогда не печатаются, когда мы открываем мастер распределения аналитических данных. Это говорит нам о двух вещах:
Виджет вообще не проходит через эти методы Python, ИЛИ
Контекст, который мы установили в представлении XML (allowed_analytic_account_ids), не пересылается на внутренние вызовы RPC, выполняемые виджетом.
Другими словами, идентификаторы вычисляются правильно в заказе на покупку, но, похоже, они никогда не достигают виджетаanalytic_distribution. Таким образом, аналитические учетные записи не фильтруются должным образом.
Вопросы
- Какой метод Python на самом деле вызывает виджет аналитического_распределения в Odoo 18 Enterprise для загрузки аналитических учетных записей в каждом столбце мастера?
- Правильно ли пересылается контекст из поля XML на внутренние вызовы RPC виджета?
- Каков правильный способ внедрения домена? фильтровать аналитические аккаунты внутри этого виджета?
Заранее спасибо.