Odoo - Скрыть кнопку для конкретного пользователя
Я использую odoo 10 enterpeise. Я хочу показывать кнопки определенным пользователям, а не группам, потому что в группе будет много пользователей, и я хочу показывать только кнопку ниже, у которой есть previlige, чтобы отклонить/одобрить объект.
Вот кнопка
<xpath expr="//sheet" position="before">
<header>
<button name="update_approve" attrs="{'invisible':[('first_approve', '=', uid)]}" string="Approve" type="object" class="oe_highlight"/>
<button name="update_reject" attrs="{'invisible':[('second_approve', '=', uid)]}" string="Reject" type="object" class="btn-danger"/>
</header>
</xpath>
Я попытался сделать это с помощью uid
, но uid не доступен в xml
first_approve
и second_approve
- это поля в моей модели, на основе которых я хочу показывать кнопку только пользователям, которые назначены в first_approve/second_approve
Ответы
Ответ 1
Я не пробовал это, надеюсь, он работает.
Одна из вещей, которые я знаю, чтобы использовать поле в attrs, поле должно быть задано в форме.
Я не знаю, как получить значение идентификатора пользователя в форме. но если нет коротких
например, uid
или user
, вы можете работать над этим, просто создайте поле m2o для res.users
сделайте это поле полем вычисления с помощью store = False.
# by default store = False this means the value of this field
# is always computed.
current_user = fields.Many2one('res.users', compute='_get_current_user')
@api.depends()
def _get_current_user(self):
for rec in self:
rec.current_user = self.env.user
# i think this work too so you don't have to loop
self.update({'current_user' : self.env.user.id})
и вы можете использовать это поле в своей форме.
<xpath expr="//sheet" position="before">
<header>
<!-- fin a good place for the field if i make the header look ugly -->
<!-- make invisible -->
<field name="current_user" invisible="1"/>
<!-- hope it work like this -->
<button name="update_approve" attrs="{'invisible':[('first_approve', '=', current_user)]}" string="Approve" type="object" class="oe_highlight"/>
<button name="update_reject" attrs="{'invisible':[('second_approve', '=', current_user)]}" string="Reject" type="object" class="btn-danger"/>
</header>
</xpath>
извините за мой английский.
Ответ 2
Я понял, что у вас есть фиксированный список пользователей, которые смогут утвердить и другой фиксированный список пользователей, которые смогут отклонить. Несмотря на то, что я несколько пользователей, я бы создал две группы и использовал атрибут groups
на ваших кнопках, но если вы даже не хотите создавать для них пару групп, вы можете сделать это:
from openerp import models, api
import json
from lxml import etree
FIRST_APPROVE = [] # Fill this list with the IDs of the users who can update approve
SECOND_APPROVE = [] # Fill this list with the IDs of the users who can update reject
class YourClass(models.Model):
_inherit = 'your.class'
def update_json_data(self, json_data=False, update_data={}):
''' It updates JSON data. It gets JSON data, converts it to a Python
dictionary, updates this, and converts the dictionary to JSON data
again. '''
dict_data = json.loads(json_data) if json_data else {}
dict_data.update(update_data)
return json.dumps(dict_data, ensure_ascii=False)
def set_modifiers(self, element=False, modifiers_upd={}):
''' It updates the JSON modifiers with the specified data to indicate
if a XML tag is readonly or invisible or not. '''
if element is not False: # Do not write only if element:
modifiers = element.get('modifiers') or {}
modifiers_json = self.update_json_data(
modifiers, modifiers_upd)
element.set('modifiers', modifiers_json)
@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False,
submenu=False):
res = super(YourClass, self).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
doc = etree.XML(res['arch'])
if view_type == 'form':
if self.env.uid in FIRST_APPROVE:
upd_approve_btn_search = doc.xpath("//button[@name='update_approve']")
upd_approve_btn = upd_approve_btn_search[0] \
if upd_approve_btn_search else False
if upd_approve_btn:
self.set_modifiers(upd_approve_btn, {'invisible': False, })
if self.env.uid in SECOND_APPROVE:
upd_reject_btn_search = doc.xpath("//button[@name='update_reject']")
upd_reject_btn = upd_reject_btn_search[0] \
if upd_reject_btn_search else False
if upd_reject_btn:
self.set_modifiers(upd_reject_btn, {'invisible': False, })
res['arch'] = etree.tostring(doc)
return res
FIRST APPROVE
и SECOND_APPROVE
будет const, в котором вы должны ввести фиксированную IDS пользователей, которые могут выполнить соответствующее действие (например: FIRST APPROVE = [2, 7, 9]
).
YourClass
должен быть классом, в котором вы объявили методы ваших кнопок (тот, в котором вы объявили update_approve
и update_reject
).
ВАЖНО: с помощью этого кода ваши кнопки должны быть всегда невидимыми (напишите invisible="1"
в вашем представлении XML), потому что после загрузки кода XML fields_view_get
перезапишет значение invisible
, чтобы установить 0.
Это необычный способ управлять вашей целью, но, к сожалению, я думаю, что это самый простой, если вы не хотите создавать группы. Надеюсь, это поможет вам и другим пользователям!