How to use name_get condition in odoo 12 - odoo

class ResPartnerInherit(models.Model):
_inherit = 'res.partner'
is_specialist = fields.Boolean(string='Is Specialist')
specialized_in = fields.Many2one('specialization',string='Specialization')
hospital = fields.Char(string='Hospital')
#api.depends('is_specialist')
#api.multi
def name_get(self):
res = []
self.browse(self.ids).read(['name', 'hospital'])
for rec in self:
res.append((rec.id, '%s - %s' % (rec.name, rec.hospital)))
return res
What I'm trying to do here is, using name_get function When selecting a specialist his hospital needs to be shown, so I wanna give condition only for a specialist,there is a boolean field named is_specialist.so I wanna get the condition only when boolean is true

You just need to check is the partner is a specialist when building his name and if yes show also the hospital.
#api.multi
def name_get(self):
res = []
for rec in self:
res.append((rec.id, '%s - %s' % (rec.name, rec.hospital) if rec.is_specialist else rec.name))
return res

Related

ValueError: Expected singleton: daily.attendance.line(123,124,125

#api.model
def create(self, vals):
curr = datetime.now()
new_date = datetime.strftime(curr, '%Y-%m-%d')
cal_obj = self.env['daily.attendance'].search([])
#api.constrains('date')
def _date_test_unique(self):
for rec in self:
if self.search_count([('date', '=', rec.date)]) > 1:
raise ValidationError(_('Current Date Attendance Already Existed!'))
#api.onchange('user_id')
def onchange_department(self):
if self.user_id == True:
emps = self.env['hr.employee'].search([])
emp_attd = []
from datetime import datetime
now = datetime.now() # current date and time
check_in = now.strftime('%Y-%m-%d %H:%M:%S')
check_in_from = now.strftime('%Y-%m-%d 05:30')
check_out = now.strftime('%Y-%m-%d %H:%M:%S')
check_out_from = now.strftime('%Y-%m-%d 14:30')
for emp in emps:
vals = {
'employe_id':emp.id,
'check_in': check_in_from,
'check_out': check_out_from,
'is_present': True
}
emp_attd.append([0, 0, vals])
self.update({
'employee_ids': emp_attd,
})
else:
self.employee_ids = False
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
The error happens when Odoo tries to get employee_ids value from a record set but it expects a record.
for emp in self.employee_ids:
You need to loop over self then access employee_ids field value for each record:
Example:
def attendance_validate(self):
for rec in self:
for emp in rec.employee_ids:
You should move the following code outside the for loop
self.write({'state': 'validate', })
Example:
hr_attendance = self.env['hr.attendance']
for rec in self:
for emp in rec.employee_ids:
if emp.is_present == True:
attd_crete_id = hr_attendance .create({'employee_id': emp.employe_id.id,
'check_in': emp.check_in,
'check_out': emp.check_out,
})
rec.write({
'state': 'validate',
})
...
Probably you need to call write state to validate when the attendance_validate method succeed (at the end)
improvement:
The following expression
if emp.is_present == True:
can be simplified to:
if emp.is_present:
You are using two fields is_present and is_absent, you can simply use is_present and when its value is False (not set) the employee is absent.
You need to remove the second if statement, which is useless
elif emp.is_absent == True:
if emp.is_absent == True:
Avoid raising a validation error in the create method because it will break the workflow, instead you can define a constraint on date field:
#api.constrains('date')
def _date_test_unique(self):
for rec in self:
if self.search_count([('date', '=', rec.date)]) > 1:
raise ValidationError(_('Current Date Attendance Already Existed!'))
Update:
The create method should return the newly created record:
#api.model
def create(self, vals):
res = super(CLASS_NAME, self).create(vals)
# Your code
return res
write a for loop before the if statement
#api.onchange('is_present')
def onchange_attendance(self):
for rec in self:
if rec.is_present:
rec.is_absent = False

Raise UserError only if none fields selected

I added my custom field to res.partner model and when I'm creating partner if branch_id is checked I want to that one of 3 fields should be selected. If some of the fields are not selected then I want to raise UserError.
But now it raises UserError even if I one of the fields is selected.
class ResPartner(models.Model):
_inherit = 'res.partner'
branch_id = fields.Many2one('branch.responsibility','Responsibility by branch')
drawer_id = fields.Many2one(
'furniture.parts.type', string='Drawer Type',
domain=[('type', '=', 'drawer')], )
flexible_id = fields.Many2one(
'furniture.parts.type', string='Flexible Type',
domain=[('type', '=', 'flexible')],)
runner_id = fields.Many2one(
'furniture.parts.type', string='Runner Type',
domain=[('type', '=', 'runner')], )
#api.model
def create(self, vals):
if vals.get('branch_id'):
if not vals['drawer_id'] or not vals['flexible_id'] or not vals['runner_id']:
raise UserError('You need to chose values from notebook raport data')
return super(ResPartner, self).create(vals)
UPDATE.
for write method, I tried this as CZoellner suggested for create but always get True True True for fields_to_check_in_vals
#api.multi
def write(self, vals):
if vals.get('branch_id') or vals.get('drawer_id') or vals.get('flexible_id') or vals.get('runner_id') or
vals.get('group_1_id') or vals.get('group_2_id')or
vals.get('group_3_id'):
fields_to_check = ['drawer_id', 'flexible_id', 'runner_id', 'group_1_id', 'group_2_id', 'group_3_id']
fields_to_check_in_vals = [f in self for f in fields_to_check]
if not any(fields_to_check_in_vals):
raise UserError('If branch is selected then you need to select one of the fields from data raport')
> return super(ResPartner, self).write(vals)
Your logic says, that all 3 fields have to be set. You could use any here:
if vals.get('branch_id'):
fields_to_check = ['drawer_id', 'flexible_id', 'runner_id']
fields_to_check_in_vals = [f in vals for f in fields_to_check]
if not any(fields_to_check_in_vals):
raise UserError()
Edit: the write method is a bit more tricky. Usually it is a multi record method, so a for each loop on self should be implemented. Then you'll need to use either getattr or just (it's suggested in the Odoo doc) treat the recordset like a dict. And then it could be, that the change happens right on the write call. So you have to check both the persisted and the new values:
for record in self:
if vals.get('branch_id'):
fields_to_check = ['drawer_id', 'flexible_id', 'runner_id']
fields_to_check_dict = {f:record[f] for f in fields_to_check}
fields_to_check_dict.update({f:f in vals for f in fields_to_check})
if not any(fields_to_check_dict.values()):
raise UserError()
That's a bit complicated. You could also first call super and just check after that. Raising an exception will rollback all changes, so nothing will happen.
res = super(MyModel, self).write(vals)
for record in self:
if vals.get('branch_id'):
fields_to_check = ['drawer_id', 'flexible_id', 'runner_id']
fields_to_check_in_record = [record[f] for f in fields_to_check]
if not any(fields_to_check_in_record):
raise UserError()
return res

Update fields with different number of values

In res.partner model I have a field
property_product_pricelist = fields.Many2many('product.pricelist')
and in sale.order
alternative_pricelist_ids = fields.Many2many(
'product.pricelist')
Partner can have more than one price list so my goal is to add the first pricelist to the pricelist_id field and other pricelists to alternative_pricelist_ids. The things are that how I wrote code is not really good, as you can see I will get an error if there are more than 4 pricelists. So how can I avoid it and write it another way?
#api.multi
#api.onchange('partner_id')
def onchange_partner_id(self):
super(SaleOrder,self).onchange_partner_id()
values = { 'pricelist_id': self.partner_id.property_product_pricelist[0] and self.partner_id.property_product_pricelist.id[0] or False,
'alternative_pricelist_ids': self.partner_id.property_product_pricelist[1] and self.partner_id.property_product_pricelist[2] and self.partner_id.property_product_pricelist[3] or False,
}
self.update(values)
Try this :
#api.multi
#api.onchange('partner_id')
def onchange_partner_id(self):
super(SaleOrder, self).onchange_partner_()
for record in self:
pricelist_id = False
alternative_ids = []
for pricelist in record.partner_id.property_product_pricelist:
if not pricelist_id:
pricelist_id = pricelist.id
else:
alternative_ids.append(pricelist.id)
record.pricelist_id = pricelist_id
record.alternative_pricelist_ids = [(6, 0, alternative_ids)]

How to override create methode in odoo 10

i want to use same create method in odoo 10 as below means i want to convert below code in odoo 10, below code is working well for odoo 8
def create(self, cr, uid, vals, context=None):
phase_obj = self.pool.get('hr_evaluation.plan.phase')
survey_id = phase_obj.read(cr, uid, vals.get('phase_id'), fields=['survey_id'], context=context)['survey_id'][0]
if vals.get('user_id'):
user_obj = self.pool.get('res.users')
partner_id = user_obj.read(cr, uid, vals.get('user_id'), fields=['partner_id'], context=context)['partner_id'][0]
else:
partner_id = None
user_input_obj = self.pool.get('survey.user_input')
if not vals.get('deadline'):
vals['deadline'] = (datetime.now() + timedelta(days=28)).strftime(DF)
ret = user_input_obj.create(cr, uid, {'survey_id': survey_id,
'deadline': vals.get('deadline'),
'type': 'link',
'partner_id': partner_id}, context=context)
vals['request_id'] = ret
return super(hr_evaluation_interview, self).create(cr, uid, vals, context=context)
i am trying below code:
def create(self, vals):
survey_id = self.env['hr_evaluation.plan.phase'].read(vals.get('phase_id'),fields=['survey_id'])['survey_id'][0]
if vals.get('user_id'):
partner_id = self.env['res.users'].read(vals.get('user_id'), fields=['partner_id'])['partner_id'][0]
else:
partner_id = None
if not vals.get('deadline'):
vals['deadline'] = (datetime.now() + timedelta(days=28)).strftime(DF)
ret = self.env['survey.user_input'].create({'survey_id': survey_id,
'deadline': vals.get('deadline'),
'type': 'link',
'partner_id': partner_id})
vals['request_id'] = ret
return super(hr_evaluation_interview, self).create(vals)
but it is giving me error like TypeError: read() got multiple values for keyword argument 'fields' so please guide me how can i remove this error?
read method accept fields as argument and you give it two arguments.
read([fields])
Reads the requested fields for the records in self, low-level/RPC method. In Python code, prefer browse().
Parameters
fields -- list of field names to return (default is all fields)
Returns
a list of dictionaries mapping field names to their values, with one dictionary per record
Raises
AccessError -- if user has no read rights on some of the given records
Instead of calling read method it's better to call browse() method, you can read Browse() vs read() performance in Odoo 8
Your code should be:
def create(self, vals):
survey_id = self.env['hr_evaluation.plan.phase'].browse(vals.get('phase_id'))
if vals.get('user_id'):
partner_id = self.env['res.users'].browse(vals.get('user_id'))
else:
partner_id = None
if not vals.get('deadline'):
vals['deadline'] = (datetime.now() + timedelta(days=28)).strftime(DF)
ret = self.env['survey.user_input'].create({'survey_id': survey_id.id,
'deadline': vals.get('deadline'),
'type': 'link',
'partner_id': partner_id.id})
vals['request_id'] = ret.id
return super(hr_evaluation_interview, self).create(vals)

TypeError: generate_purchase_order() takes exactly 1 argument (5 given)

I am trying to convert openerp 7 code to odoo8. In V7 browse() method had several parameters like self,cr,uid,ids,context but in V8 I think none of these is needed.In my custom module I am trying to create a purchase order based on the information obtained from mrp.I have done a custom calculation for how many Kgs of paper needed for 10000 quantities of books to be manufactured.After calculation this info should go to purchase invoice.Products will be obtained from bill of materials,quantity from no of kgs of paper needed and unit price from product cost attribute.I am unable to solve this error "method takes exactly 1 argument (5 given)"
mrp.py,
from openerp import models
class mrp_production(models.Model):
_inherit = 'mrp.production'
def generate_purchase_order(self,supplier_id,warehouse_id):
purchase_obj = self.env['purchase.order']
purchase_line_obj = self.env['purchase.order.line']
warehouse_obj = self.env['stock.warehouse']
warehouse = warehouse_obj.browse(warehouse_id)
if not warehouse:
return False
if isinstance(warehouse, list):
warehouse = warehouse[0]
for order in self:
vals = {}
vals = purchase_obj.onchange_partner_id()
vals['origin'] = order.name
vals['partner_id'] = supplier_id
vals['warehouse_id'] = warehouse_id
vals['location_id'] = warehouse.lot_stock_id.id
vals['date_order'] = order.date_planned
purchase_id = purchase_obj.create(vals)
for line in self.bom_id.bom_line_ids:
if not line.product_id:
continue
line_vals = purchase_line_obj.onchange_product_id(line.product_id.id,
line.product_uom_qty, line.product_uom.id, supplier_id,
date_planned=line.date_planned)['value']
line_vals['name'] = line.name
line_vals['product_id'] = line.product_id.id
if not line_vals.get('price_unit', False):
line_vals['price_unit'] = line.product_id.list_price
line_vals['product_uom'] = line.product_uom.id
line_vals['product_uom_qty'] = 181.13
line_vals['order_id'] = purchase_id
purchase_line_obj.create(line_vals)
return True
generate_purchase_order.py,
from openerp import models,fields,api
class generate_purchase_order(models.Model):
_name = 'mrp_to_purchase_order.generate_purchase_order'
_description = 'Generate Purchase Order'
partner_id = fields.Many2one('res.partner', 'Supplier', required=True, domain="[('supplier','=',True)]")
warehouse_id = fields.Many2one('stock.warehouse', 'Warehouse', required=True)
#api.multi
def onchange_partner_id(self,partner_id):
return {}
def generate_purchase_order(self):
for wizard in self:
#mrp_order_ids = [context['active_id']]
mrp_obj = self.env['mrp.production']
mrp_obj.generate_purchase_order(wizard.partner_id.id, wizard.warehouse_id.id)
return { 'type': 'ir.actions.act_window_close'}
If you are calling the generate_purchase_order method from some other method in your model, then use the decorator #api.multi for that method.
Also in your generate_purchase_order method, replace
for order in self.browse():
by
for order in self:
EDIT
#api.multi
def generate_purchase_order(self):
for wizard in self:
#mrp_order_ids = [context['active_id']]
mrp_obj = self.env['mrp.production']
# Get the mrp record
mrp_rec = code to get mrp record
mrp_rec.generate_purchase_order(wizard.partner_id.id, wizard.warehouse_id.id)
return { 'type': 'ir.actions.act_window_close'}