2
votes

I would like to ask community to evaluate my solution in OpenERP. I am using Odoo v8.

I have created a popup window with two fields, original_code and replacement_code, and the button with caption "Replace". The popup is launched from parent page "More" button dropdown option.

Use case is that user will type in product code in the field original_code (the field looks like edit textbox) while replacement code field is automatically populated and is read only. Pressing the button "Replace" the button action is triggered that replaces the code in the related tables in database.

I have created new model, new class, and hence new table in database, nk_product_template, that inherits from product_template. The reason I created new table is to have my button action inserts records in this table and not in product_template table. I have added two new char fields to the table, original_code and replacement code. This model is referenced in XML code for popup window.

My button action function is defined in the class nk_product_template and its name is action_replace() which has logic to replace product code. Whenever I click on button "Replace" it always first inserts the record in the table nk_product_template (no code is written for insertion, it's automatic as I understand) and returns id of that record which I use to retrieve original_code and replacement_code values from the table inside button's action_replace() and use those values in the code replacement logic.

I am wondering is this the correct way to solve the use case, and if it is not a correct approach, how would you solve it. My major question is do I need to have new class (hence new model and new table) for each popup window to set and get field values? Your comments are greatly appreciated.

Here is the XML code where the popup window is defined:

<record id="replace_all_in_BOM_form" model="ir.ui.view">
    <field name="name">replace.all.in.BOM.form</field>
    <field name="model">nk.product.template</field>
    <field name="priority" eval="20"/>
    <field name="type">form</field>
    <field name="arch" type="xml">
        <group>
            <field name="original_code" string="Original Code" style="width: 
            10%%" readonly="0" />
            <field name="replacement_code" string="Replacement Code" 
            style="width: 10%%" readonly="1" invisible="0" />
            <field name="default_code" string="Replacement" readonly="1"    
            invisible="1"  />   
            <field name="uom_id" invisible="1"  /> 
            <field name="uom_po_id" invisible="1"   />
            <field name="type" invisible="1"   />   
            <field name="categ_id" invisible="1"   /> 
            <field name="name" invisible="1" />
        </group>
        <button type="object" string="Replace" name="action_replace" />
    </field> 
</record>

My py code is as follows:

class nk_product_template(osv.osv):
    _inherit = 'product.template'
    _name = 'nk.product.template'

    _columns = {
        'replacement_code' : fields.char('Replacement Code', select=True),
        'original_code' : fields.char('Original Code', select=True),
    }
    def default_get(self, cr, uid, fields, context=None):
        # <code to automatically populate replacement_code field>
        # ...   

    def action_replace(self, cr, uid, ids, context=None):
        # <code that replaces product code>
        # ...
1
I would suggest to use another stackexchange site for this kind of question: codereview.stackexchange.comPaco

1 Answers

1
votes

There is no need to inherit from product.template. Just make a one2many field referencing the template you want to change.

Also, it seems like nk.product.template should be a TransientModel and not a normal model. Objects of transient models exist only temporarily and are not indefinitely stored in the database. They are meant for helper functions and wizards - like the one you have.

To use a transient model, instead of inheriting your class from osv.osv, just inherit it from osv.osv_memory. Or even better, instead of using osv which is deprecated, use models.Model for normal models and models.TransientModel for transient models (in place of osv.osv and osv.osv_memory).

The last thing that I would change is the fact that you use the old ORM API. It is much too verbose and hard to read and it is going to be removed from new Odoo versions at some point. It would be much better to use the new Odoo ORM.


The new model could look something like this (obviously I don't know the specifics, so that's just an example):

from openerp import models, fields, api


class ProductCodeWizard(models.TransientModel):
    _name = 'nk.code_wizard'

    template = fields.Many2one(
        'product.template',
        required=True,
        default=lambda self: self.env.context['active_id'],
    )
    replacement_code = fields.Char(string="Replacement Code")
    original_code = fields.Char(
        string="Original Code",
        related='template.default_code',
        readonly=True,
    )

    @api.one
    def action_replace(self):
        self.template.default_code = self.replacement_code

You can read more about the new ORM API here and here. You can also watch presentations here and here.