Динамический домен для поля Many2one
Коллеги, подскажите, как навесить вычисляемый домен в таком случае:
В Odoo 8 есть сущность «Договор», в которой
1. Указан «Поставщик» — ссылка на сущность «Партнер»
2. Есть поле «Ответственный со стороны поставщика» — ссылка на сущность «Контакт»
«Партнер» и «Контакт» связаны Many2Many
Нужно, чтобы в поле «Ответственный со стороны поставщика», в лукапе показывались только те контакты, которые связаны с указанным поставщиком.
Пробовал писать в модели сущности «Договор»:
Этот метод срабатывает только при создании нового договора или при изменении поля «Поставщик». Как быть в случае, когда форма уже существующего договора открывается на редактирование, но пользователь не трогает поле «Поставщик»?
В Odoo 8 есть сущность «Договор», в которой
1. Указан «Поставщик» — ссылка на сущность «Партнер»
2. Есть поле «Ответственный со стороны поставщика» — ссылка на сущность «Контакт»
«Партнер» и «Контакт» связаны Many2Many
Нужно, чтобы в поле «Ответственный со стороны поставщика», в лукапе показывались только те контакты, которые связаны с указанным поставщиком.
Пробовал писать в модели сущности «Договор»:
@api.onchange('vendor_id')
def onchange_vendor(self):
res = {}
if self.vendor_id:
vendor_contact_ids = self.vendor_id.contact_ids.mapped('id')
res['domain'] = {'vendcontact_id': [('id', 'in', vendor_contact_ids)]}
else:
res['domain'] = {'vendcontact_id': [('id', 'in', [])]
return res
Этот метод срабатывает только при создании нового договора или при изменении поля «Поставщик». Как быть в случае, когда форма уже существующего договора открывается на редактирование, но пользователь не трогает поле «Поставщик»?
9 комментариев
может быть есть событие на открытие окна на редактирование? там и вызови этот код…
Есть fields_view_get(), но внутри него мне так и не удалось добраться до значений полей текущей записи:
Попробуйте переписать в старом стиле:
Вторая ветка моих исследований — это указание в xml формы в качестве домена названия какого-нибудь вычисляемого поля:
Но тут появляется проблема с типом этого поля. В случае, если это one2Many и он заполнен какими-то id контактов, то при нажатии кнопки лукапа появляется ошибка: TypeError: not all arguments converted during string formatting.
Работающий вариант получился только в комбинации: поле типа Char и в нем только один id контакта — тогда домен накладывается успешно.
Если в поле Char пытаться указать несколько id, например «4, 3», то появляется ошибка:
DataError: ОШИБКА: неверное значение для целого числа: «4, 3»
LINE 1: ...t".«active» = true) AND («my_contact».«id» in ('4, 3'))) ...
X
А в самой модели res.partner — переопределить метод search. Который в случаи наличия в контексте ('looluppartner_id')
будет фильтровать вывод search.
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
if context is None: context = {}
res = super(sale_order, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
doc = etree.XML(res['arch'])
nodes = doc.xpath("//field[@name='order_line']/form//field[@name='product_id']")
for node in nodes:
node.set('context', "{'partner_id':parent.partner_id,}")
res['arch'] = etree.tostring(doc)
return res
Если вкратце, то когда я пытался в домен [('id','in', get_vendcontact_ids)] подставить значение поля типа Many2many, то для системы это выглядело вот таким образом: [('id','in', [(6,0,[ID1,ID2,ID3])])], что приводило к ошибке. Чтобы корректно сформировать домен в этом случае нужно писать так: [('id','in', get_vendcontact_ids and get_vendcontact_ids[0][2])]
Для моего случая понадобилось вычисляемое поле Many2many, куда будут записываться нужные id:
Его невидимым нужно вытащить в xml формы:
И вот так должно выглядеть определение поля, где можно выбрать контакт только из отфильтрованного списка:
Уже работает. Для полноты картины еще понадобится на OnChange поля «Поставщик» привесить обновление нашего вычисляемого поля и корректное изменение значения связанного лукапа:
that's all