Show/Hide fields if there is not in list - python

My concept is that I have 5 different access level on Odoo.
I want to check if login user is in list (list is created by an automated action), if yes show the fields else hide them.
My code:
list_of_users= []
if record.user_id.partner_id.id: #level 1 user add on list
list_of_users.append(record.user_id.partner_id.id)
if record.user_id.sale_team_id.user_id.partner_id.id: #level 2 user add on list
list_of_users.append(record.user_id.sale_team_id.user_id.partner_id.id)
if record.user_id.sale_team_id.regional_manager_id.partner_id.id: #level 3 user add on list
list_of_users.append(record.user_id.sale_team_id.regional_manager_id.partner_id.id)
user_ids = record.env['res.users'].search([])
flag = record.env['res.users'].search([('groups_id','ilike','L4')])
for user_ids in flag: #level 4 and 5 users add on list
user_record = record.env['res.users'].browse(user_ids)
list_of_users.append(user_ids.partner_id.id)
record.update({'x_partner_follower_custom': [(6, 0, list_of_users)]})
On view i use attrs="{'invisible': [('x_partner_follower_custom', '=', False)]}" inside on fields i want to show/hide
x_partner_follower_custom: many2many res.partner field
Output Sample:
As you can see im return users back to view, but it seems the attrs is not properly set. Any idea how to fix it?

First of all the field should not be stored and it must be computed every time because it depends on the value of the current logged user, remove store:
#api.depends('x_partner_follower_custom')
def user_exist(self):
for rec in self:
if rec.x_partner_follower_custom and self.env.user.partner_id.id in rec.x_partner_follower_custom.ids:
rec.your_boolean_field_name = True
else:
rec.your_boolean_field_name = False
So the field depends on x_partner_follower_custom and the current logged user it should not be stored.
EDITS
Everything is explained in the Form view and how to make the code works like it was created in the code:
I manage it to find solution, a couple days ago: #Fotic
for record in self:
if record['x_partner_follower_custom'] and self.env.user.partner_id.id in record['x_partner_follower_custom'].ids:
record['x_partner_is_follower_custom'] = True
else:
record['x_partner_is_follower_custom'] = False

Related

Filter Many2one field - Odoo v8

I know I can filter Many2one fields, from python code, or even xml views, with the domain flag, but I have a slightly different scenario right now,
Consider having a model like this:
class MyModel(models.Model):
_name = 'mymodel'
fieldsel = fields.Selection([('sheet', 'Sheet'),('reel','Reel')], string='Printing PPT Type',
track_visibility='onchange', copy=False,
help=" ")
fieldmany = fields.Many2one('text.paper', string="Text Paper")
The text.paper model has another Selection field, which has the same values as fieldsel, however, I cannot use domain since it will filter every text.paper statically.
My issue is, that I need to filter text.paper depending on which option I choose from fieldsel, so, let's say text.paper looks something like this:
class text_paper(models.Model):
_name = 'text.paper'
name = fields.Char(string="Code")
paper_type = fields.Selection([('sheet', 'Sheet'),('reel','Reel')], string="Paper Type")
I need to filter from mymodel the text.paper depending on the fieldsel field, if reel selected, filter text.paper which are reel, and if sheet selected, filter text.paper accordingly.
I hope I've explained myself.
Any ideas?
what you need is dynamic domain for many2one you can achive this by onchange event
class MyModel(models.Model):
_name = 'mymodel'
....
...
#api.onchange('fieldsel ')
def change_domain(self):
"""change the domain of fieldmany whenever the user changes the selected value."""
self.fieldmany = False # may be you want to reset the value when the user changes the selected value
if self.fieldsel : # make sure the user has selected a value
return {'domain': {fieldmany: [('paper_type', '=', self.fieldsel)]}}
else: # remove domain
return {'domain': {fieldmany: []}}

Is it possible to update two different models with single action button in Odoo?

My question is i have defined one function & one action button to update same data in different model.
But I want it to update some fields in two different models.
individual codes are working fine but when i merge them its showing error.
My code is like this.
def function_call(self,cr,uid,ids,vals,context=None):
x = self.pool.get('hotel.booking')
y = self.browse(cr,uid,ids,context=context)
z = {
'name' : y.name,
'mobile':y.mobile,
'email_id':y.email_id
}
return x.create(cr,uid,z,context=context)
objz1 = self.pool.get('room.engage')
currentz1 = self.browse(cr,uid,ids,context=context)
currentz1.status = 'reserved'
new_valsz1 = { #dictionary
'room_num' : currentz1.room_num.room_num,
'room_type':currentz1.room_type,
'status': currentz1.status
}
return objz1.create(cr,uid,new_valsz1,context=context)
Action button is in booking form.. where customer enters name, mobile, email_id, room number details.
In the above code it works only if i remove one segment.
So from this i want to get personal details in one model, room details in another model.
I faced the same problem.
you must have ids for each model to browse records and call create method twice.
(when you write return obj.create(cr, uid, vals, context), you return the id of the new created record.)

Filling Many2many field (odoo 8)

What I've done:
I have a module with
myfield = fields.Many2one('res.partner', string="Graduate", domain=[('is_graduated', '=', True)])
Then I have another class with
_inherit = 'res.partner'
is_graduated = fields.Boolean("Graduated before?", default=False)
graduations = fields.Many2many('my_module.courses', string="Graduation courses")
What I get:
The myfield works good, but the graduations field is empty. If you edit user 1 profile you can add entries to graduation field using Add item, but I need it to be filled automaticaly.
What I expect:
I expect that every record where myfield is set to lets say user 1, will be visible in field graduations when you open user 1 profile. When I create record and set myfield value to lets say user 1, that record must to be visible in user 1 profile in the field graduations. How to achieve that?
user_rel_ids = fields.Many2many(comodel_name='course',
relation='user_course_rel',
column1='user_id',
column2='course_id')
Or
user_rel_id = fields.Many2many('course')
For Filling Data (for add new relation)
user_rel_id = [(4,course_id)]
According to http://odoo4u.blogspot.com/2014/10/orm-methods.html, It says:
A full list of options is in the documentation for the class.
This same thing will apply for one2many
For a many2many and one2many field, a list of tuples is
expected. Here is the list of the tuple that is accepted, with the
corresponding semantics:
(0, 0, { values }) link to a new record that needs to be
created with the given values dictionary
(1, ID, { values }) update the linked record with id = ID (write
values on it)
(2, ID) remove and delete the linked record with id = ID (calls
unlink on ID, that will delete the object completely, and the link to
it as well)
(3, ID) cut the link to the linked record with id = ID (delete the
relationship between the two objects but does not delete the target
object itself)
(4, ID) link to existing record with id = ID (adds a
relationship)
(5) unlink all (like using (3, ID) for all linked records)
(6, 0, [IDs]) replace the list of linked IDs (like using (5)
then (4,ID) for each ID in the list of IDs)
You need to use an onchange method for myfield, then inside it you need to fill the graduations field, something like this:
#api.onchange('myfield'):
def _onchange_myfield(self):
#fill graduations field here...
...
_inherit = 'crm.phonecall'
alarm_ids = fields.Many2many('calendar.alarm',string="Reminders")
set the alarm_ids of calendar.event model in create method of crm phonecall...
alarm_ids = [(6,0,self.alarm_ids.ids)]
_inherit = 'calendar.event'
alarm_ids = fields.Many2many('calendar.alarm',string="Reminders")
You can achieve like these.
For example:
#api.one
#api.depends(
#here you may define your depend field name
)
def _set_graduations(self):
#here comes your logic which will collect ids
#and than return it with self.field_name like
self.graduations = [list_of_ids]
graduations = fields.Many2many('my_module.courses', string='Payments',
compute='_set_graduations')
If you don't want to use #api.depends than you may use #api.multi. For reference you may check out account module with account_invoice.py file.

How to compute a databasefield with the field-id

Model:
db.define_table('orders',
Field('customer_id', db.customer)
Field('order_id', 'string')
)
I want to get a special order_id like XY-150012 where XY is part of the customer name, 15 is the year and 12 the id the actual record-id of orders. I tried in the model:
db.orders.order_id.compute = lambda r: "%s-%s00%s" % (db.customer(r['customer_id']).short, str(request.now.year)[2:], r['id'])
The id is never recognized, the computation ends up as None. If I remove r['id'] from the compute-line it works.
EDIT:
After adding an extra field field('running_number', 'integer') to the model I can access this fields content.
Is there a easy way to set this fields default=db.orders.id?
SOLUTION:
With Anthony´s Input, and reading about recursive selects I came up with this solution:
db.define_table('orders',
Field('customer_id', db.customer),
Field('order_id', 'string', default = None))
def get_order_id(id, short):
y = str(request.now.year)[2:]
return '%s-%s00%s' % (short, y, id)
def set_id_after_insert(fields,id):
fields.update(id=id)
def set_order_id_after_update(s,f):
row = s.select().first()
if row['order_id'] == None:
s.update_naive(order_id=get_order_id(row['id'], row['customer_id'].short)
else:
return
db.orders._after_insert.append(lambda f,id: set_id_after_insert(f,id))
db.orders._after_update.append(lambda s,f: set_order_id_after_update(s,f))
The problem is that the record ID is not known until after the record has been inserted in the database, as the id field is an auto-incrementing integer field whose value is generated by the database, not by web2py.
One option would be to define an _after_insert callback that updates the order_id field after the insert:
def order_after_insert(fields, id):
fields.update(id=id)
db(db.order.id == id).update(order_id=db.order.order_id.compute(fields))
db.order._after_insert.append(order_after_insert)
You might also want to create an _after_update callback, but in that case, be sure to use the update_naive argument in both callbacks when defining the Set (see above link for details).
Depending on how the order_id is used, another option might be a virtual field.

Query Django models

I am trying to create a query using django models. I have 4 models. The functionality is to display all a person's facebook friends that are not already friends and do not have a friend request waiting.
CustomUserFriends
id,
from_customuser_id,
to_customuser_id,
FacebookProfile
id,
facebook_id,
custom_user_id
CustomUser
id,
name,
FriendRequests
id,
requester (user_id of the person requesting),
requestee (user_id of the person requested),
Now I have a list of facebook ids as a variable example
facebook_ids = [12123,45433,455664,44445]
Essentially the query im trying to create through django models is select all customusers that have a facebook id in the facebookprofile table but do not have the relationship of being a friend with the user already or have a pending friend request.
A friend is defined as having 2 records in the CustomUserFriends table, example
a friend relationship is
CustomUsers
id
1
2
CustomUserFriends
id from_custom_user_id to_custom_user_id
1 1 2
2 2 1
So, I wasn't entirely sure what you were trying to accomplish here. It was a toss up between getting all non-friends for a particular user or having a particular user and trying to find all of his friends who weren't friends with each other. I decided I'd do both and let you decide which one you wanted.
First, there are two functions. One is the main function we'll be using, the other is just for displaying the info.
def get_non_friends_for_user(u, friend_ids_filter=[]):
# Search the friends lists
friend_ids = list(CustomUserFriends.objects.filter(
from_customuser_id=u.pk).values_list('to_customuser_id', flat=True))
friend_ids += list(CustomUserFriends.objects.filter(
to_customuser_id=u.pk).values_list('from_customuser_id', flat=True))
# Search the requests lists
friend_ids += list(FriendRequests.objects.filter(
requester=u.pk).values_list('requestee', flat=True))
friend_ids += list(FriendRequests.objects.filter(
requestee=u.pk).values_list('requester', flat=True))
non_friends = CustomUser.objects.exclude(id__in=friend_ids)
if friend_ids_filter:
non_friends = non_friends.filter(id__in=friend_ids_filter)
return non_friends
def display_user_info(cu, non_friends):
print
print cuf.name
for non_friend in non_friends:
print '\t', non_friend.name
Now, to get all people who are not friends of a particular user we just use that function
# Get all non-friends for custom_user
# Note that custom_user should be defined before as a CustomUsers object
non_friends = get_non_friends_for_user(custom_user)
display_user_info(custom_user, non_friends)
To get the list of a user's friends that aren't friends with another of the user's friends, we can do this:
# Again, custom_user must already be defined as a CustomUsers object
custom_user_non_friends = {}
custom_user_friends = CustomUserFriends.objects.filter(
from_customuser_id=custom_user.pk)
friend_ids = list(custom_user_friends.values_list('to_customuser_id', flat=True))
for cuf in custom_user_friends:
cu = cuf.to_customuser_id
# Add the queryset to the dictionary
custom_user_non_friends[cu] = get_non_friends_for_user(cu, friend_ids)
for cu, non_friends in custom_user_non_friends.items():
display_user_info(cu, non_friends)
And that should do it. I haven't tested any of this and it's all pretty much coming off the top of my head, so there may be some bugs. If it doesn't work for you or it's not what you were looking for, just post a comment and I'll see what I can do.

Categories

Resources