How to create a field for project sale orders - odoo

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

Related

Get and display many2one line ids record

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"
)

How to get value on one field based on two different fields

So Im creating a hotel management module . I have the option to filter rooms based on bed_type and tag. Tag contains different facilities like AC, TV etc. So an user will come and select a bed_type and the facilities he wants and in the third field it should show the rooms that have the given configuration if not available an error messages should come. SO i created a onchange function to do this , but i dint know how to include the tags in it. Im doing it on odoo v14. m
This is the model for the room
from odoo import api, fields, models, _
class HotelRoom(models.Model):
_name = 'hotel.room'
_description = 'hotel room'
_rec_name = 'room_number'
room_number = fields.Char('Room Number', required=True)
room_rent = fields.Monetary('Room Rent')
tag = fields.Many2many('hotel.tags', string='Facilities')
dormitory_count = fields.Integer('Dormitory count')
bed_type = fields.Selection([
('single', 'Single'),
('double', 'Double'),
('dormitory', 'Dormitory')
], required=True, default='other')
This is the model for the reception
class HotelAccommodation(models.Model):
_name = 'accommodation.room'
_description = 'Reception'
bed_type = fields.Selection([
('single', 'Single'),
('double', 'Double'),
('dormitory', 'Dormitory')
], required=True, string= 'Bed type')
state = fields.Selection([
('draft','Draft'),
('check-in','Check-In'),
('check-out', "Check-Out"),
('cancel','Cancel'),
], required=True, default='draft', tracking=True)
tag = fields.Many2many('hotel.tags', string='Facilities')
room_id = fields.Many2one('hotel.room', string='Room')
Using this I can filter the rooms based on the bed_type but I need to have the tags as well.I tried giving it inside the domain but its not working .
#api.onchange('bed_type')
def filter_room(self):
for rec in self:
return {'domain': {'room_id': [('bed_type', '=', rec.bed_type)]}}
You need also to add the tag field to the domain and to the onchange decorator, so the method will be called when the tag field is modified.
The method is invoked on a pseudo-record that contains the values present in the form, you do not need to loop over self.
Try the following example:
#api.onchange('bed_type', 'tag')
def filter_room(self):
return {'domain': {'room_id': [('bed_type', '=', self.bed_type), ('tag', 'in', self.tag.ids)]}}
You can use _compute fields with the store option = True
take a look https://www.odoo.com/documentation/14.0/reference/orm.html#computed-fields

How to track One2many field in Odoo12?

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')

odoo how to show the values of my two fields once I do a select

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)
.....

How to filter a many2many field in odoo8?

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