+91 9818211679, +91 9998040067       [email protected]

How To Transfer Data From One Model To Another In Odoo

Odoo ERP envisions transforming the way a company runs its business. Odoo leverages the open-source technology making the business simpler and fully integrated. No matter what industry your company belongs to, Odoo ERP is constantly into revolutionizing your company’s growth and improved revenue.

Odoo Also known as Open ERP was founded by Fabien Pinckaers in 2005. The word Odoo is the acronym of On-Demand Open Object. Odoo is a large collection of business-related applications and modules like CRM, Sales management, E- commerce, Warehouse management, Purchase management, Accounting suit, Manufacturing management, HRMS, etc.. All these basic modules collectively called as Enterprise Resource Planning software.

Odoo has more than 14,000 third party Apps/Plugins available in its app store. Each of them is custom-built for different user needs. Today, Odoo is one of the widely used open-source ERP Solutions in the market.


Data and Model

Odoo is greatly data-driven, and a big part of modules definition is thus the definition of the various records it manages: UI (menus and views), security (access rights and access rules), reports, and plain data are all defined via records.

In Odoo, a model is a class that maps to the data relation (table) and potentially bridge tables (e.g. for many to many relations). It contains the essential fields and behaviors of the data you're storing. Generally, each model maps to a single database table

Data Transfer In Odoo

In this blog, we are going to discuss "How we can Transfer Data from one Model to Another in Odoo".

We can mainly transfer one data from a model to another different model through four ways they are,

- By Using Context

- With the help of ORM Methods

- By Overriding Create Method

- By Overriding Write Method

Let us discuss more deeply,


1) By Using Context

 

The context is a python dictionary and is used to pass certain data to a method. Since nearly all methods have a context parameter you can use the context to pass data through several levels of python methods. You may want to pass some data to a specific page in Odoo, and change the fields based on those data. In those cases, you want to use Context. Context is a data structure passed to the request object that contains hidden values and can be used to change the results of the page.

Context is a frozendict data type in Odoo. That’s why you can change it as you do in a dict data type, for example:-

dict_object.update({ 'test': 'test_value'})

As the Context is frozendict, it won’t take such changes. Odoo provides a way to change values, it’s called ‘with_context’. The syntax is as follows:

self = self.with_context({'test': 'test_value'})

This one should rewrite the context available in the self-object by adding the new key:value pair you have mentioned. There are times, this might not work as expected, and you want a patching technique to update the context. This can be done by changing the data type to dict.

self.env.context = dict(self.env.context)
self.env.context.update({'test': 'test_value})

This would also add the new key: value pair to your context and work as expected. There is almost no security concern here for converting the frozendict as the context will destroy once the page is left soon enough.

you can set a context value in an XML-view and process it in the write() method of the osv object.

context.get('active_id',False)

Returns the value of the key 'active_id'. If the key is not in the context, then it returns the value 'False'.

The value in 'active_id' is passed from the web client and contains the ID of the currently selected record.

Here is an example of how the context is used in the Sale module. File sale_view.xml:

<record id="view_order_form" model="ir.ui.view"> 

         <field name="name">sale.order.form</field>

<field name="model">sale.order</field>

         <field name="arch" type="xml">

  <form string="Sales Order" version="7.0">

                <header>                  <button name="invoice_recreate"states="invoice_except" string="Recreate Invoice"         groups="base.group_user"/>

        <button name="invoice_corrected"states="invoice_except" string="Ignore Exception" groups="base.group_user"/>

                 <button name="action_quotation_send"string="Send by Email" type="object"          states="draft" class="oe_highlight"groups="base.group_user"/> ...

You can see that the button third button (Send by Email) calls method 

action_quotation_send in
sale.py.

Here is the relevant code in sale.py:

def action_quotation_send(self, cr, uid, ids, context=None):

.......

ctx.update({

'default_model': 'sale.order', 'default_res_id': ids[0],
'default_use_template': bool(template_id), 'default_template_id': template_id,
'default_composition_mode': 'comment', 'mark_so_as_sent': True

})

return {

'type': 'ir.actions.act_window', 'view_type': 'form',

'view_mode': 'form',

'res_model': 'mail.compose.message',
'views': [(compose_form_id, 'form')],
'view_id':compose_form_id,

'target':'new',
'context': ctx,
}

The context is updated with the flag mark_so_as_sent set to True. Afterwards, the send-mail window (mail.compose.message) is opened and the modified context is passed.

Then the send_mail() method is overwritten. If the flag mark_so_as_sent has been set in the context, then the new functionality is called. This ensures that the current behavior of send_mail() is not affected. But when the wizard is opened from the Sale Order, the new functionality will be executed.

 Also in sale.py:

class mail_compose_message(osv.Model):

_inherit = 'mail.compose.message'

def send_mail(self, cr, uid, ids, context=None):
context = context or {}
if context.get('default_model') == 'sale.order' and context.get('default_res_id') and context.get('mark_so_as_sent'):

context = dict(context, mail_post_autofollow=True)
wf_service = netsvc.LocalService("workflow")

wf_service.trg_validate(uid,'sale.order', context['default_res_id'], 'quotation_sent', cr)

return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context)

2) With the help of ORM Methods

 So firstly, we can look at how to fetch data from a different model, for fetching data we use ORM search, browse method. And we need to specify the model from which we are going to fetch data. If you want to filter the records based on some conditions you can set the domain so we will get the results based on the conditions.

Here we have two sample classes, let us assume both have some fields also.

Class SampleOne(models.Model);   

_name=’sample.one’
       sample_one=fields.Char(string=”name") 

So if I need to get the values of first-class in the second one we need to create a method in the second model, if you want to call the ORM method directly from an object you can use self.env['obj'].method

Class SampleTwo(models.Model)

    _name=’sample.two

    def get_data(self):         fetched_data=self.env.[‘sample.one’].search([])         return fetched_data

Theself.env environment reference allows us to access any other model.

Here we are assigning the searched results to a variable and returning it, we can specify from which model we need to fetch data inside thatself.env.[‘obj.name’] and this function can be called as your wish it can be given as the action of any button also.

So if we need to give some conditions to filter our data you can set the domain inside the search as your wish. Eg.

fetched_data=self.env[‘sample.one’].search([('user_id', '=', self.user_id.id)])

We can also browse records for any model by using browse method like this:

self.env['model.name'].browse(ids)

We can also transfer or create data from the different models to a different destination model. So let us see how to do that,

Class SampleTwo(models.Model);

    _name=’sample.two

   def get_data(self):     fetched_data=self.env.[‘sample.one’].create({ ‘ sample_one’:self.name,})

     return fetched_data

Here inside the create you can specify to which field you are giving value and the corresponding value by ‘field_name’:’value’

We can also write data from one model to another like this,

self.env.[‘object.name’].write({ ‘field_name’:’value’,})

3) By Overriding Create Method

Overriding existing functions in Odoo is quite easy to do. Odoo is built on Python and Python allows you to use super calls, which makes it quite easy to override existing functions. We can Override the create function and change values on a record bypassing the value before storing it in thedatabase.

 First thing is to inherit the model which you are trying to create record or pass value.

 Let us take the model res.partners for example,

from odoo import models, fields, api Class res_partner(models.Model):

    

    _inherit = 'res.partner'

Then,

@api.model     def create(self, values):

"""Override default Odoo create function and extend.""" # Do your custom logic here return super(ResPartner, self).create(values)

You can give values to create like,

record = self.env['your.model'].create({'name': 'Example'})

4) By Overriding Write Method

For Overriding write method also first inherit the model,

from odoo import models, fields, api Class res_partner(models.Model):

    _inherit = 'res.partner'     Then,

    @api.multi

    def write(self, values):     """Override

default Odoo write function and extend.""" # Do your custom logic here

        return super(ResPartner, self).write(values)

For giving values,

record_ids = self.env['your.model'].search([('name', '=','Example')])
for record in record_ids:

    record.write({'some_field': 'some_description})

Hope this blog is helpful to you. If you have any query feel free to ask in the comment section.

Odoo CMS - a big picture
There are no comments for now.

There are no comments for now.


There are no comments for now.