Odoo Help


This community is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.


How to create a field for project sale orders

Yurdik Cervantes Mendoza
on 10/22/15, 10:18 AM 603 views

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

You can only use related fields to browse to another entity just by its ID, not through other fields.

Which could be the way?

Axel Mendoza

--Axel Mendoza--
| 6 7 8
Camaguey, Cuba
--Axel Mendoza--

DevOps - Full stack - Software Architect - Developer - Technology Integrator

I could help you to develop anything and solve complex problems based on technologies, integrations and tricky stuffs mostly in Python with OpenERP/Odoo, Zato, Django and many others frameworks programming languages and technologies.

I offers consulting services to anyone with an unanswered questions or needs for customizations. Think about it, maybe it's better to have an expert to solve your issues and projects than having a full time employee trying to understand what to do an how

Reach me at aekroft@gmail.com

Axel Mendoza
On 10/22/15, 2:46 PM

You just need the relation field if you wanna show the sale orders in the project form, if you wanna show them when clicking on a button, there is no need to do the following

The initial thought could work if you add a many2one field on the sale.order model pointing back to the project.project model 

Option 4:

class project_analytic_account(models.Model):
_name = "account.analytic.account" 
_inherit = 'account.analytic.account'

sale_order_ids = fields.One2many('sale.order', 'project_id', string='Sale orders')

Through inheritance by delegation you could use the new field sale_order_ids in the project.project model and also in views 



Option 3: use a computed field

sale_order_ids = fields.One2many('sale.order', compute='_get_sale_orders', string='Sale orders')

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

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

About This Community

This community is for professionals and enthusiasts of our products and services. Read Guidelines

Question tools

2 follower(s)


Asked: 10/22/15, 10:18 AM
Seen: 603 times
Last updated: 10/22/15, 3:25 PM