Je suis en train de mettre en place un module sur OpenERP 7.0 pour gérer les requêtes. Chaque demande peut (ou non) avoir un propriétaire. Le propriétaire d'une requête appartient à un groupe et à un moment donné, il peut vouloir donner sa demande à un autre utilisateur du même groupe. Ma question va précisément dans cette direction. Avoir à sélectionner un utilisateur de res.users, y a-t-il un moyen de restreindre ses possibilités de recherche aux utilisateurs appartenant au même groupe que lui?Comment restreindre une recherche dans res.user à des utilisateurs appartenant au même groupe que dans OpenERP?
Ajout d'un peu plus d'info:
J'ai 4 groupes mis en place dans OpenERP: Utilisateur, Groupe RH, logistique, et directeur Dans un certain stade de traitement, seuls les utilisateurs appartenant au groupe des ressources humaines (et évidemment le groupe Manager) peut prendre des mesures sur les demandes. Comme je l'ai déjà dit, les utilisateurs du groupe HR font prendre en charge une demande en devenant propriétaires, à ce stade, seul le propriétaire peut apporter des modifications à cette demande. Il peut toutefois devoir donner la propriété de cette demande à un autre utilisateur appartenant au même groupe RH. Pour ce faire, j'ouvre un assistant où il doit sélectionner un utilisateur de res.users. Puisque j'aurais environ 4k utilisateurs, il serait plus agréable de restreindre sa recherche aux utilisateurs avec les mêmes permissions (appartenant également au groupe OpenERP créé dans ce module).
Voici le code python de mon assistant:
from openerp.osv import osv
from openerp.osv import fields
from openerp.tools.translate import _
import netsvc
class give_request(osv.osv_memory):
_name='give.request'
_columns = {
'assign_to': fields.many2one('res.users', 'Assign request to', help='Person who will be responsible for the next action'),
}
def save_info(self, cr, uid, ids, context=None):
if 'active_id' in context:
assign_to=self.browse(cr,uid,ids)[0].assign_to
#import pdb; pdb.set_trace()
self.pool.get('generic.request').write(cr,uid,context['active_id'],{'assign_to' : assign_to.id})
wf_service = netsvc.LocalService('workflow')
wf_service.trg_validate(uid,'generic.request',context['active_id'],'give_request',cr)
return {
'type': 'ir.actions.act_window_close',
}
give_request()
Et la vue XML:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Give request -->
<record id="view_give_request_wizard" model="ir.ui.view">
<field name="name">give_request_wizard.form</field>
<field name="model">give.request</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Select user" version="7.0">
<group >
<separator string="Please select the person you want to set the ownership of the request" colspan="2"/>
<!--<field name="assign_to" string="Assign to" domain="[('groups_id', 'in', [uid.groups_id])]" />-->
<field name="assign_to" string="Assign to" />
<newline/>
</group>
<div style="text-align:right">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-ok" name="save_info" string="Give the request" type="object" />
</div>
</form>
</field>
</record>
<record id="action_give_request" model="ir.actions.act_window">
<field name="name">Give ownership of the request</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">give.request</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_give_request_wizard"/>
<field name="target">new</field>
</record>
<act_window id="action_give_request"
name="Give request"
res_model="give.request"
view_mode="form"
target="new"
/>
</data>
</openerp>
J'ai essayé d'appliquer un filtre de domaine sur mon filtre assign_to <field name="assign_to" string="Assign to" domain="[('groups_id', 'in', [user.groups_id])]" />
(et plus tard avec uid.groups_id
) , mais ça n'a pas marché.
Merci d'avance.
Nouvelle édition, pour adapter mon code aux astuces de nitesh.
Maintenant, le code python de mon assistant ressemble à ceci:
class give_request(osv.osv_memory):
_name='give.request'
def search(self, cr, uid, domain, offset=0, limit=None, order=None, context=None, count=False):
cr.execute("SELECT gid FROM res_groups_users_rel WHERE uid="+str(uid))
group=cr.fetchall()
names = []
#import pdb; pdb.set_trace()
for group_id in group:
cr.execute("SELECT name FROM res_groups WHERE id="+str(group_id[0]))
group_name = cr.fetchall()
names.append(group_name[0][0])
#Now "names" will contain al the group that the user has assigned to
#Check if "Hr Group" is present in that group or not
if 'UC Human Resources' in names:
domain += [('group','=','UC Human Resources')]
return super(give_request, self).search(cr, uid, domain, offset, limit, order, context, count)
_columns = {
#'assign_to': fields.many2one('res.users', 'Assign request to', help='Person who will be responsible for the next action'),
'assign_to': fields.function(search, 'Assign request to', help='Person who will be responsible for the next action', type="integer", obj="res.users", method=True),
}
def save_info(self, cr, uid, ids, context=None):
if 'active_id' in context:
assign_to=self.browse(cr,uid,ids)[0].assign_to
#import pdb; pdb.set_trace()
self.pool.get('generic.request').write(cr,uid,context['active_id'],{'assign_to' : assign_to.id})
wf_service = netsvc.LocalService('workflow')
wf_service.trg_validate(uid,'generic.request',context['active_id'],'give_request',cr)
return {
'type': 'ir.actions.act_window_close',
}
give_request()
Et ne pas apporter de modifications à mon XML, puisque je ne sais pas si cela est nécessaire ou non.
Quoi qu'il en soit, avec le changement que je l'ai fait, maintenant XML est affiché comme celui-ci (avec un « 0 » en face du champ d'un menu déroulant, Wich est pas ce que je pensais, j'espérais obtenir un menu déroulant ici ...) Et une autre chose étrange est que même si j'ai ajouté pdb dans la définition de la fonction de recherche, il ne s'arrête pas lorsque l'assistant se charge (ne devrait-il pas s'arrêter, puisqu'il est appelé par le field.function?) il s'arrête quand je clique sur le bouton save Je devine que la ligne assign_to=self.browse(cr,uid,ids)[0].assign_to
de la fonction save_info l'appelle (?) et puis, quand je fais le débogage, je suppose que j'obtiens une boucle infinie.
Sinon, sans pdb, je reçois la trace suivante (après avoir cliqué sur le bouton Enregistrer):
2014-06-11 14:19:08,063 753 ERROR may_9 openerp.osv.osv: Uncaught exception
Traceback (most recent call last):
File "/opt/openerp/v7/server/openerp/osv/osv.py", line 131, in wrapper
return f(self, dbname, *args, **kwargs)
File "/opt/openerp/v7/server/openerp/osv/osv.py", line 197, in execute
res = self.execute_cr(cr, uid, obj, method, *args, **kw)
File "/opt/openerp/v7/server/openerp/osv/osv.py", line 185, in execute_cr
return getattr(object, method)(cr, uid, *args, **kw)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 3606, in read
result = self._read_flat(cr, user, select, fields, context, load)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 3726, in _read_flat
res2 = self._columns[f].get(cr, self, ids, f, user, context=context, values=res)
File "/opt/openerp/v7/server/openerp/osv/fields.py", line 1133, in get
result = self._fnct(obj, cr, uid, ids, name, self._arg, context)
File "/home/lfc/openerp/v7/addons/processos_uc/wizard/give_req_wiz.py", line 23, in search
return super(give_request, self).search(cr, uid, domain, offset, limit, order, context, count)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 2356, in search
return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 4847, in _search
query = self._where_calc(cr, user, args, context=context)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 4676, in _where_calc
e = expression.expression(cr, user, domain, self, context)
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 642, in __init__
self.parse(cr, uid, context=context)
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 742, in parse
self.stack = [ExtendedLeaf(leaf, self.root_model) for leaf in self.expression]
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 528, in __init__
self.check_leaf()
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 584, in check_leaf
raise ValueError("Invalid leaf %s" % str(self.leaf))
ValueError: Invalid leaf 16
2014-06-11 14:19:08,068 753 ERROR may_9 openerp.netsvc: Invalid leaf 16
Traceback (most recent call last):
File "/opt/openerp/v7/server/openerp/netsvc.py", line 292, in dispatch_rpc
result = ExportService.getService(service_name).dispatch(method, params)
File "/opt/openerp/v7/server/openerp/service/web_services.py", line 626, in dispatch
res = fn(db, uid, *params)
File "/opt/openerp/v7/server/openerp/osv/osv.py", line 188, in execute_kw
return self.execute(db, uid, obj, method, *args, **kw or {})
File "/opt/openerp/v7/server/openerp/osv/osv.py", line 131, in wrapper
return f(self, dbname, *args, **kwargs)
File "/opt/openerp/v7/server/openerp/osv/osv.py", line 197, in execute
res = self.execute_cr(cr, uid, obj, method, *args, **kw)
File "/opt/openerp/v7/server/openerp/osv/osv.py", line 185, in execute_cr
return getattr(object, method)(cr, uid, *args, **kw)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 3606, in read
result = self._read_flat(cr, user, select, fields, context, load)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 3726, in _read_flat
res2 = self._columns[f].get(cr, self, ids, f, user, context=context, values=res)
File "/opt/openerp/v7/server/openerp/osv/fields.py", line 1133, in get
result = self._fnct(obj, cr, uid, ids, name, self._arg, context)
File "/home/lfc/openerp/v7/addons/processos_uc/wizard/give_req_wiz.py", line 23, in search
return super(give_request, self).search(cr, uid, domain, offset, limit, order, context, count)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 2356, in search
return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 4847, in _search
query = self._where_calc(cr, user, args, context=context)
File "/opt/openerp/v7/server/openerp/osv/orm.py", line 4676, in _where_calc
e = expression.expression(cr, user, domain, self, context)
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 642, in __init__
self.parse(cr, uid, context=context)
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 742, in parse
self.stack = [ExtendedLeaf(leaf, self.root_model) for leaf in self.expression]
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 528, in __init__
self.check_leaf()
File "/opt/openerp/v7/server/openerp/osv/expression.py", line 584, in check_leaf
raise ValueError("Invalid leaf %s" % str(self.leaf))
ValueError: Invalid leaf 16
Ne pas être un expert en python et chaque jour qui passe la réalisation pas un expert sur OpenERP soit, je Je ne sais pas ce que je fais mal? N'importe qui? Merci d'avance!
Que voulez-vous dire par groupe? Groupes déjà implémentés dans OpenERP/Odoo ou nouvelle relation avec un nouveau modèle (comme request.usergroup ou autre)? – CZoellner
Je veux dire les groupes OpenERP. J'ai édité ma question pour ajouter une description plus détaillée et un code. –