I'm developing an OpenERP 7 module and I need to add a field that logs the user who created each record. How do I retrieve the current user object?
this kind of field is already available in openerp, as create_uid and write_uid.
In OpenERP Python code, functions generally take cr, the database pointer, and uid, the user id, as arguments. If all you need is the id of the current res.users object (for instance, to write into the one2many field), you can use uid as is. If you need to access the object (to see fields, etc.), something like:
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
should work.
Related
How can I restrict the write permissions for a field to a specific group ?
I want to check if a user is in a specific group with id 46. If the user is in this group, he should be allowed to write in this field. If he is not in this group, he should not be allowed to write.
The field is a custom field, editing the domain with the studio app I think I should avoid.
My field:
<field name="customer_codename" placeholder="Codename" attrs="{'invisible':['|',('customer_rank','=', 0),('is_company','=', False)]}"/>
I tried the following, but it did not work:
I created a new field using the studio app. Field type is boolean.
In the advanced properties I wanted to define the compute for the field. In dependencies I gave "user_id" and in the compute field I gave
for record in self:
user_id.has_group('__export__.res_groups_46_eff9dc52')
The boolean field should be set to true if the user is in a certain group.
Not sure if I can give you the best answer there is.
But for me, I'd personally create a Boolean field in the view's associated model, with its default field a lambda function checking if the user belongs to the groups you mentioned.
Assuming groups_id is the name of the user groups in model res.users, we have:
class ResUsers(models.Model):
_inherit = "res.users"
can_write_codename = fields.Boolean(default=lambda self: self.groups_id in ("model_name.group_name"))
Then in your xml file, you can include can_write_codename inside attrs, like this:
<field name="customer_codename" placeholder="Codename" attrs="{'invisible':['|',('customer_rank','=', 0),('is_company','=', False)], 'readonly': [('can_write_codename', '=', 'True')]}"}"/>
I am trying to store the currently logged user into a many2one field using compute method. It's working fine if i define the Mnay2one field without the store="True" parameter. Actually, i need to save it.
Here is the code:
def get_logged_user(self):
for rec in self:
print('inside get_logged_user---------------',rec.env.user.name)
rec.logged_user_id = rec.env.user.id
logged_user_id = fields.Many2one('res.users',string="Logged user",store=True,compute="get_logged_user")
EDIT:
If you only need to control visibility of a field/button inside QWeb view you could archive this without dedicated field. You could use context.get('uid') to get current user like this:
<button ... invisible="context.get('uid') == assigned_user_id">
But if you need to store logged-in user inside a field you could use default instead of compute.
Something like this:
logged_user_id = fields.Many2one('res.users', string="Logged user", default=lambda self: self.env.user)
Note usage of lambda function.
If you really need to use compute field with store=True you need to specify when to compute it. By using api.depends decorator you can trigger it when your_field is changed.
#api.depends('your_field')
def get_logged_user(self):
But I would ask a question why do you need to store logged-in user inside a field? If you could provide more context maybe we could suggest different solution.
.py file:
….
namex=fields.Text()
moifier=fields.Many2one(‘res.users’, string=”Modifier”)
…
When some user modify “namex”, his/her name should be recorded on field “modifier” automatically; what code should I make? I try “onchange/depends”, but failed; maybe modifier could be a “text field/ char field”?
in addition, shall I set "access_rule" to set users just see the records created by the members in his/her own group?
Odoo already has that for you. Every model has those fields, which are automatically created and updated each time you create, or write:
create_date (datetime): when record is created
create_uid (many2one): user who created this record
write_date (datetime): last time record is updated
write_uid (many2one): last user updated this record
Go to Settings > Technical > Database Structure > Models for more details.
While Odoo will keep for you a track of the last user which has modified a record, a modifier per field is not kept. I can see the interest of such a functionality in many cases.
To do that for a particular model one possibility is to redefine the write method of this model. In your .py file you may want to add something like this:
#api.model
def write(self):
if self.namex in values:
values.update({'modifier': uid})
super().write(cr, uid, ids, values, context)
Another way to do that in a more flexible way is to use the #onchange decorator:
#onchange('your_sensible_field_name'):
def set_modifier(self):
self.modifer = self.env.user
You may also want to take a look at the #depends decorator.
can anyone explain the working of create and write orm mehods in openerp ? Actually I'm stuck at this methods,I'm not getting how it works internally and how can I implement it over a simple program.
class dumval(osv.osv):
_name = 'dum_val'
_columns={
'state':fields.selection([('done','confirm'),('cancel','cancelled')],'position',readonly=True),
'name':fields.char('Name',size=40,required=True,states={'done':[('required','False')]}),
'lname':fields.char('Last name',size=40,required=True),
'fname':fields.char('Full name',size=80,readonly=True),
'addr':fields.char('Address',size=40,required=True,help='enter address'),
}
_defaults = {
'state':'done',
}
It would be nice if u could explain using this example..
A couple of comments plus a bit more detail.
As Lukasz answered, convention is to use periods in your model names dum.val. Usually something like my_module.my_model to ensure there are no name collisions (e.g. account.invoice, sale.order)
I am not sure if your conditional "required" in the model will work; this kind of thing is usually done in the view but it would be worth seeing how the field is defined in the SQL schema.
The create method creates new records (SQL Insert). It takes a dict of values, applies any defaults you have specified and then inserts the record and returns the new ID. Note that you can do compound creates, i.e. if you are creating and invoice, you can add the invoice lines into the dictionary and do it all in one create and OpenERP will take care of the related fields for you (ref write method in https://doc.openerp.com/trunk/server/api_models/)
The write method updates existing records (SQL Update). It takes a dict of values and applies to all of the ids you pass. This is an important point, if you pass a list of ids, the values will be written to all ids. If you want to update a single record, pass a list of one entry, if you want to do different updates to the records, you have to do multiple write calls. You can also manage related fields with a write.
It's convention to give _name like dum.val instead of dum_val.
In dumval class you can write a method:
def abc(cr, uid, ids, context=None):
create_dict = {'name':'xxx','lname':'xxx','fname':'xxx','addr':'xyz'}
# create new object and get id
new_id = self.create(cr, uid, write_dict, context=context)
# write on new object
self.write(cr, uid, new_id, {'lname':'yyy'}, context=context)
For more details look: https://www.openerp.com/files/memento/older_versions/OpenERP_Technical_Memento_v0.6.1.pdf
I am trying to create a field from the web gui of OpenERP and field type as reference
1st there is no better docs about reference
2nd what I want is when someone selects the field it should give another option on selection which is not happening (though it is giving some field but 2nd field throws an error)!
It throws an error object does not exist
Reference fields are mainly used for showing different model's records as reference in your record. For example you have created a model such that whenever a sale order, purchase order, delivery order, project etc are created and saved, then a new record with data like user name, date, some notes should be created in your model. So here you add a reference field which link to the original record(sale order, purchase order etc) from which your record is created. You can find this in res.request model in openerp 6
To create an reference field in your class
def _get_selection_list(self, cr, uid, context=None):
##return a list of tuples. tuples containing model name and name of the record
model_pool = self.pool.get('ir.model')
ids = model_pool.search(cr, uid, [('name','not ilike','.')])
res = model_pool.read(cr, uid, ids, ['model', 'name'])
return [(r['model'], r['name']) for r in res] + [('','')]
_columns = {
'ref': fields.reference(Reference', selection=_get_selection_list, size=128)
}