I have added this to my model:
ref_doc_id = fields.Reference(selection='_referencable_models', string='Reference Document')
#api.model
def _referencable_models(self):
models = self.env['ir.model'].search([('field_id.name', '=', 'message_ids')])
return [(x.model, x.name) for x in models]
And the field to a view:
<field name="ref_doc_id"/>
The field seems to be loaded on frontend but it doesn't show the dropdown. Am I doing something wrong?
Related
I would like to post a message on the chatterbox after I add a new line in my model. I tried putting the tracking=True attribute on the one2many field (that represents my line model) in my main model, but nothing was logged on the chatterbox.
You could do :
model_id = self.env['your.model'].search([('id', '=', 255)])
msg_body = "First Log Note"
model_id.message_post(body=msg_body)
...
msg_body = "Second Log Note"
model_id.message_post(body=msg_body)
Make sure you inherit this mixin ( _inherit = ['mail.thread'] )in your model.
class YourModel(models.Model):
_name = 'your.model'
_inherit = ['mail.thread']
I need applay domain on field product_id in purchase.order.line model, after call onchange method in purchase.order model.
Example:
_inherit = "purchase.order"
custom_id = fields.Many2one('custom.model', string='Custom')
#api.onchange('custom_id')
def change_product(self):
lst = [1,2,3]
return {'domain': {'order_id.product_id': [('id', 'in', lst)]}}
This is original field where I want add my domain
product_id = fields.Many2one('product.product', string='Product',domain=[('purchase_ok', '=', True)], change_default=True, required=True)
I don't get any error but in product_id field show all data from database, not product where id 1,2,3 from above example.
write onchange function for product_id, instead of custom_id and return domain.
#api.onchange('product_id')
def change_product(self):
lst = [1,2,3]
return {'domain': {'product_id': [('id', 'in', lst)]}}
inside the onchange function consider the custom_id.
You have a little problem here: you can't set a domain for child relations IIRC.
What you can do is to create a related field on the child relation (here purchase.order.line and trigger the onchange on that.
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
custom_id = fields.Many2one(
comodel_name='custom.model', string='Custom')
class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"
custom_id = fields.Many2one(
comodel_name="custom.model", related="order_id.custom_id")
#api.onchange('custom_id')
def onchange_custom_id(self):
lst = [1,2,3]
return {'domain': {'product_id': [('id', 'in', lst)]}}
And some more information. Let me presume you have set custom_id on product variants (a) or on product categories (b). Just change the domain of product_id and use the domain operator '=?'. You won't need an onchange method for this solution, but you have to define custom_id in the view (invisible is possible, this is also a must have for the complete first solution)!
(a)
class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"
custom_id = fields.Many2one(
comodel_name="custom.model", related="order_id.custom_id")
product_id = fields.Many2one(
domain="[('purchase_ok', '=', True), ('custom_id', '=?', custom_id)]")
(b)
class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"
custom_id = fields.Many2one(
comodel_name="custom.model", related="order_id.custom_id")
product_id = fields.Many2one(
domain="[('purchase_ok', '=', True), ('categ_id.custom_id', '=?', custom_id)]")
If no custom_id is set the domain will read: product has to be purchasable AND True.
I am trying to reference form_serial_no field of formdownload model in my inherited model(plot.allocate). Instead of the dropdown to show the computed value of form_serial_no which is company_short_code padded with sequence e.g CCK0000006, it's showing "CCK" which is the value of company_short_code excluding the sequence. In actual fact, it's referencing company_short_code of companyname model instead of the computed value of form_serial_no of formdownload model. And in the database, form_serial_no field is showing the right record which is something like these......ABC0000008, CDG0000003 and so on. This is my question, is there any reason why form_serial_no_id Many2one field of plot.allocate model is not picking the value of form_serial_no Char field of formdownload, instead, it's picking the company_short_code Char field of companyname model?
Secondly, how can i change the status field default value of companyname model record to true when a value is picked in form_serial_no_id Many2one field of plot.allocate model?
Kindly help me look into these.
Below are my code snippet
# -*- coding: utf-8 -*-
from openerp import models, fields, api
class CompanyName(models.Model):
_name = 'companyname'
_rec_name = 'company_short_code'
company_name = fields.Char(string="Company Name", required=True)
company_short_code = fields.Char(string="Company short code", required=True)
class FormDownload(models.Model):
_name = 'formdownload'
_rec_name = 'form_serial_no'
name = fields.Many2one('companyname', string="Company Name", ondelete='cascade',
required=True)
form_serial_no = fields.Char(string="Form Serial No", readonly=True)
status = fields.Boolean(string="Status", default=False)
#api.model
def create(self, vals):
serial_no = self.env['ir.sequence'].get('formdownload.form_serial_no')
code = self.env['companyname'].browse(vals['name']).company_short_code
# capitalize company short code values
code = code.upper()
# merge code and serial number
vals['form_serial_no'] = code + serial_no
return super(FormDownload, self).create(vals)
class PlotAllocation(models.Model):
_inherit = 'plot.allocate'
form_serial_no_id = fields.Many2one('formdownload',
domain=[('status', '=', False)],
ondelete='cascade', string="Form Serial No")
#api.model
def create(self, vals):
record = self.env['formdownload'].search([('name', 'like', vals.get('name', False))]).form_serial_no
status = self.env['companyname'].search([('name', 'like', vals.get('name', False))]).status
if vals.get('form_serial_no_id') == record.id:
self.env['companyname'].write({status : True})
return super(PlotAllocation, self).create(vals)
in the view the many2one is always showing the value of the field specified in the Model class by _rec_name :
by default _rec_name = 'name'
so in reality your model is like this :
class FormDownload(models.Model):
_name = 'formdownload'
_rec_name = 'name'
so he will retreive the value of field name name is also a many2one so the value retrieved is the _rec_name of model companyname with is company_short_code:
so i you want to change the value of many2one you have to choice:
if one field is enough than specify the _rec_name = 'form_serial_no'
if you want to combined value like first && last name then override name_get method
#api.multi
def name_get(self):
"""
change the displayed value on m2o
"""
result = []
for record in self:
result.append((record.id, _(" %s %s") % (record.first_name, record.last_name)))
return result
EDITS
in create method is easy just remove all the code in create method and put this two line
rec_id = super(PlotAllocation, self).create(vals)
# create return a record you can acces it's value
rec_id.form_serial_no_id.name.status = True
return rec_id # you need to return the record
I have model contains many to many assign_to_id, I want to modify that field in wizard form through escalte_to method when user trigger escalate button
Model:
class Incident(models.Model):
_name = 'itmangement.incident'
assigned_to_id = fields.Many2one('hr.employee', string="Assigned To",domain="[('department_id', '=', dep_id)]",required=True)
Wizard model
class Escalate(models.TransientModel):
escalated_to = fields.Many2one('hr.employee', string="Escalated To", required=True)
#api.one
def escalate(self):
incident_obj = self.env['itmangement.incident']
record = incident_obj.browse(self._context.get('active_ids'))
record.write({'state': 'escalated'})
class Escalate(models.TransientModel):
escalated_to = fields.Many2one('hr.employee', string="Escalated To", required=True)
#api.one
def escalate(self):
object_id = self.env.context.get('active_id')
for object in self.env['itmangement.incident'].browse(object_id) and self.escalated_to:
object.assigned_to_id = self.escalated_to.id
What are the key roles of active_ids and active_id in development ?
I want to know Advantages and Limitations of that functionality provided by odoo.
In certain case what we can do if I can not get the active_ids in context while opening wizard from other model's list view ?
Here is the action which I used to open my wizard from list view of product.product model.
<act_window name="Calculate Product Price"
res_model="wizard.main"
src_model="product.product"
view_mode="form"
view_type="form"
target="current"
multi="True"
key2="client_action_multi"
id="action_product_price_calculator_ept"
view_id="view_product_calculator_wizard"/>
Here is my python code to get active ids.
#api.model
def default_get(self, fields):
context = self.env.context
res = super(wizard_main, self).default_get(fields)
product_ids = context.get('active_ids',[])
if not product_ids:
return res
#### few more lines will be added here
return res