I am trying to log the changes on a One2many field using track_visibility='onchange'. But it's not working.
Here is the code:
respartner.py
bank_account_ids = fields.One2many('customer.bank.account','partner_id',
string='Account',track_visibility="onchange")
account.py
_name = 'customer.bank.account'
_description = 'Partner Bank Account Details'
partner_id = fields.Many2one('res.partner',string="Partner")
name = fields.Integer(string="Account Number",required=True,
track_visibility="onchange")
bank_id = fields.Many2one('partner.bank',string="Bank",track_visibility="onchange")
branch_id = fields.Many2one('partner.bank.branch',string="Branch",
track_visibility="onchange")
Yes, No need to touch ORM. Try this
class ParentClass(models.Model):
_name = 'parent.class'
_inherit = ['mail.thread']
child_ids = fields.One2many('child.class', 'relational_field_name_id')
class ChildClass(models.Model):
_name = 'child.class'
_inherit = ['mail.thread']
name = fields.Char(tracking=True) # Note that tracking is true here
relational_field_name_id = fields.Many2one('parent.class')
def write(self, vals):
super().write(vals)
if set(vals) & set(self._get_tracked_fields()):
self._track_changes(self.relational_field_name_id)
def _track_changes(self, field_to_track):
if self.message_ids:
message_id = field_to_track.message_post(body=f'<strong>{ self._description }:</strong> { self.display_name }').id
trackings = self.env['mail.tracking.value'].sudo().search([('mail_message_id', '=', self.message_ids[0].id)])
for tracking in trackings:
tracking.copy({'mail_message_id': message_id})
If you just want to track on relational and not current model then use write instead of copy method
tracking.write({'mail_message_id': message_id})
And for delete and create you can just use message_post inside create and unlink method
self.message_post(body=f'<strong>{ self._description }:</strong> { self.display_name } created/deleted')
Related
I have model structure as
class VendorEvaluationTemplate(models.Model):
_name = 'vendor.evaluation.template'
_description = 'Vendor Evaluation Template'
name = fields.Char(string='Name', required=True)
evaluation_lines = fields.One2many('vendor.evaluation.template.line', 'evaluation_template_id', string='Vendor Evaluation Template Line')
class VendorEvaluationTemplateLine(models.Model):
_name = 'vendor.evaluation.template.line'
_description = 'Details Vendor Evaluation Template'
evaluation_template_id = fields.Many2one('vendor.evaluation.template', string='Evaluation Template', ondelete="cascade")
name = fields.Char(string='Name', required=True)
class VendorEvaluation(models.Model):
_inherit = 'vendor.evaluation'
evaluation_template = fields.Many2one('vendor.evaluation.template', string='Evaluation Template')
Now the requirement is when i select evaluation_template, the related lines name from vendor.evaluation.template.line should display below this field.
Following code will work if you only want to display related lines for information purposes. Ref related fields
evaluation_template_lines = fields.One2many(
related='evaluation_template.evaluation_lines',
string="Vendor Evaluation Template Line"
)
I would like to filter m2o field, but not by default name (_rec_name).
class LecturerWorkday(models.Model):
_name = 'lecturer.workday'
_rec_name = 'lecturer_id'
name = fields.Selection([('sunday','Sunday'),('monday','Monday'),('tuesday','Tuesday'),
('wednesday','Wednesday'),('thursday','Thursday'),('friday','Friday'),('saturday','Saturday'),
], default='sunday',string="Workday", required=True)
lecturer_id = fields.Many2one('school.lecturer', string="Lecturer Name", invisible=True)
class SchoolLecturer(models.Model):
_name = 'school.lecturer'
name = fields.Char(string="Lecturer Name", required=True)
workday_id = fields.Many2one("lecturer.workday", string="Workday ID")
class LecturerTimeoff(models.Model):
_name = "lecturer.timeoff"
lecturer = fields.Many2one('school.lecturer', string="Lecturer Name")
day_m2o = fields.Many2one('lecturer.workday', string="Lecturer Workdays")
reason = fields.Char("Time off Reason")
#api.onchange('lecturer')
def get_lecturer_workday(self):
day_obj = self.env['lecturer.workday'].search([('lecturer_id', '=', self.lecturer.id)]).mapped('name')
day_list = []
for rec in day_obj:
day_list.append(rec)
res = {}
res['domain'] = {'day_m2o': [('name', '=', day_list)]}
return res
print (res)
My question are:
When I choose lecturer name, day_m2o should display the workday of selected lecturer name. I have been trying to compute it as above, but the result is still display lecturer name, instead of workday.
It seems that #api.onchange didn't update the result instantly whenever i clicked the new lecturer name who didn't have workday yet. How to fix this?
Thanks for your help
I have two models:
medical.lab.test.type
This is my class:
class MedicalLabTestType(models.Model):
_name = "medical.lab.test.type"
_description = "Medical Lab Test Types"
name = fields.Char(
'Test',
help='Name of test type, such as X-Ray, Hemogram, Biopsy, etc.',
required=True,
)
code = fields.Char(
'Code',
size=128,
help='Short name or code for test type.',
required=True,
)
description = fields.Text('Description')
Test_Prix = fields.Float(
string='Price of the test',
required=True,
)
Nbr_days = fields.Integer(
string='Number of days to have results',
required=True,
)
and
medical.lab
This is my class:
class MedicalLab(models.Model):
_name = 'medical.lab'
_description = "Medical Labs"
test_type_id = fields.Many2one(
string='Test Type',
comodel_name='medical.lab.test.type',
help='Lab test type.',
)
physician_id = fields.Many2one(
string='Pathologist',
comodel_name='medical.physician',
help='Pathologist that performed the exam.',
)
request_physician_id = fields.Many2one(
string='Requesting Physician',
comodel_name='medical.physician',
help='Physician that requested the exam.',
)
The problem is to show on the view the value of Test_Prix and Nbr_days once I choose a Test
How should i proceed?, should I use an onchange function!!!
to show field of selected m2o on the current view you should use
related field.
in your midecal.lab model add:
# related field should always keep the same type Foalt Float, Char Char
# and it's recommended that you put readonly because if you edit
# the value the value will be edited in the related record when you save
Test_Prix = fields.Float(
retlated='test_type_id.Test_Prix',
readonly=True
)
Nbr_days = fields.Integer(
retlated='test_type_id.Nbr_days',
readonly=True
)
and now you can add this two field to you view like
NB: related field are not stored in database they work as proxy if you
want to create the field in the database use store=True
EDITS :
use onchange not compute field is computed
date_perform = fields.Datetime( string='Date of Results', )
#api.onchange('date_request', 'Nbr_days')
def _compute_date_result(self):
for record in self:
business_days_to_add = record.Nbr_days
current_date = fields.Datetime.from_string(record.date_request)
.....
I've the following model, and the extend to the product_template
class Version(models.Model):
_name='product_cars_application.version'
name = fields.Char()
model_id = fields.Many2one('product_cars_application.model',string="Model")
brand_id = fields.Char(related='model_id.brand_id.name',store=True,readonly=1)
year_id = fields.Char(related='model_id.year_id.name',store=True,readonly=1)
from openerp.osv import osv,fields as Fields
class product_template(osv.osv):
_name = 'product.template'
_inherit = _name
_columns = {
'versions_ids':Fields.many2many('product_cars_application.version',string='Versions')
}
And the following controller which I need to filter products by version_id
#http.route('/pa/get_products/<version_id>', auth='none', type='json',website=True)
def get_products(self,version_id,**kwargs):
#TODO APPEND SECURITY
version_id = int(version_id)
products = http.request.env['product.template'].sudo().search([(version_id,'in','versions_ids')])
I get none products in return while the version_id is in versions_ids.
Do anyone knows what I'm doing wrong?
I need to make the value of comparison of the field a list, maybe becouse the field versions_ids is a many2many
I have solved like this:
#http.route('/pa/get_products/<version_id>', auth='none', type='json',website=True)
def get_products(self,version_id,**kwargs):
#TODO APPEND SECURITY
products = http.request.env['product.template'].sudo().search([('versions_ids','in',[version_id])])
list = []
for p in products:
list.append([p.id, p.name])
return {
'products':list,
}
"return products.ids" is missing inside get_products like:
#http.route('/pa/get_products/<version_id>', auth='none', type='json',website=True)
def get_products(self,version_id,**kwargs):
#TODO APPEND SECURITY
version_id = int(version_id)
products = http.request.env['product.template'].sudo().search([(version_id,'in','versions_ids')])
return products.ids
I have fields for a quick access of the entities related to a project. For example:
class project(models.Model):
_name = "project.project"
_description = "Project"
_inherit = 'project.project'
production_order_ids = fields.One2many('mrp.production', 'project_id', 'Production orders')
purchase_order_ids = fields.One2many('purchase.order', 'project_id', 'Purchase orders')
....
I am trying to create a sale_order_ids in the project.project model. My first try did not work:
sale_order_ids = fields.One2many('sale.order', 'project_id', string='Sale orders')
because because the field sale.order.project_id is of type account.analytic.account.
A project.project object inherits from account.analytic.account. This query should work ok if they would share the same Id, but they do not. So the navigation would be:
"project.project".analytic_account_id" -> sale.order".project_id
And the result would be the corresponding sale.order(s).
Use a computed field:
sale_order_ids = fields.One2many('sale.order', compute='_get_sale_orders', string='Sale orders')
#api.model
def _get_sale_orders(self):
for record in self:
record.sale_order_ids = self.env['sale.order'].search([('project_id', '=', record.analytic_account_id.id)]).ids