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 make 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. They can be the same thing from the business perspective but the domains expressions treat them as different entities. I don't want to theorize whether the ORM should map the entities equivalences or if the reference should b to project.project. Right now I look for a way to need a solution to easily navigate from the project to its sale orders.
So the navigation would be:
"project.project".analytic_account_id" -> sale.order".project_id
And the result would be the corresponding sale.order(s).
Option 1: specify domains
sale_order_ids = fields.One2many('account.invoice', 'project_id',
domain = [('analytic_account_id','=',self._fields_id)],
string = 'Sale Orders')
...trying to look for reference to the inverse column values. I got the error:
NameError: name 'self' is not defined
it seems that this kind of static domains can have reference to the browsing fields and constants but not to dynamic values or the inverse column (the corresponding column from the comodel). So I did try with a dynamic domain using a function:
sale_order_ids = fields.One2many('account.invoice', 'project_id',
domain = lambda self: [('analytic_account_id','=',self._fields_id)],
string = 'Sale Orders')
and I got:
'project.project' object has no attribute '_fields_id'" while parsing /opt/odoo_v8/addons/my_project/project_view.xml:4
Then I look into the code (v8 - http://bit.ly/1GjYLEl), to see which is the parameter passed to the domain functions:
# retrieve the records in the comodel
comodel = obj.pool[self._obj].browse(cr, user, [], context)
inverse = self._fields_id
domain = self._domain(obj) if callable(self._domain) else self._domain
domain = domain + [(inverse, 'in', ids)]
records = comodel.search(domain, limit=self._limit)
So the parameter is the project.project object not the field as I though. There we can see that it seems to be no way to refer to the comodel nor the inverse field (project_id) inside the domain function.
The inverse field is added always after calling the domain function:
domain = domain + [(inverse, 'in', ids)]
Option 2: use relation field
The relation field would allow me follow a browse path. My try was:
sale_order_ids = fields.One2many('sale.order', 'project_id', related='analytic_account_id' string='Sale orders')
and then I got:
Warning: Type of related field project.project.sale_order_ids is inconsistent
with project.project.analytic_account_id
It says "warning" but it crashs the updating process.I think it is telling me
Which could be the way?You can only use related fields to browse to another entity just by its ID, not through other fields.