1
votes

I'm developing on Odoo 10.

I created a dynamic form view which search and display a product from its barcode, but I've got a problem.

Since the view has no initial record to display it is opened in edit mode, and that's ok, because I want to type the 'barcode' field.
But, after the product is displayed, when I exit from that view the 'can_be_discarded' function is fired, opening the confirm dialog.

Have I to create a new view type inheriting from FormView or is there a way to workaround this problem?


The view is a classic form view, with nothing special.
Here's the server code instead.

class ProductFromBarcode(models.TransientModel):
    _name = 'levelprime_product_general_status.product_from_barcode'
    _inherits = { 'product.product': 'product_id' }

    product_id      = fields.Many2one(
                            comodel_name='product.product',
                            store=False)
    product_barcode = fields.Integer(help='Insert the barcode to search '
                                          'the correspondent product',
                                     store=False)

    @api.onchange('product_barcode')
    def on_barcode_changed(self):
        if self.product_barcode != 0:
            self.product_id = self.get_product_from_barcode(self.product_barcode)

    @api.model
    def get_product_from_barcode(self, barcode):
        r = self.env['product.product'].search([('barcode', '=', barcode)])
        if r:
            return r
3

3 Answers

1
votes

Ok, I think I'm in the right way, there are some rendering problem to solve, but the main behavior is what I was searching for.

I created a new type of view which inherit from the 'FormView' one and override the 'can_be_discarded' method to not execute controls about the data changes.


JS

odoo.define('levelprime_product_general_status.readonly_formview', function(require) {
    'use strict'

    var core = require('web.core')
    var FormView = require('web.FormView')

    var ReadOnly_FormView = FormView.extend({
        init: function() {
            this._super.apply(this, arguments)
        },
        start: function() {
            this._super.apply(this, arguments)
        },
        can_be_discarded: function() {
            return $.Deferred().resolve()
        }
    })

    core.view_registry.add('readonly_form', ReadOnly_FormView)

    return ReadOnly_FormView
})

PY

class ViewExtension(models.Model):
    _inherit = 'ir.ui.view'

    type = fields.Selection(selection_add=[
        ('readonly_form', 'ReadOnly Form Version')])

Then you can simply use the tag in the xml.

0
votes

You have used _inherits = { 'product.product': 'product_id' } in your wizard.

When using _inherits you will do a kind of polymorphic model in the database way.

For example product.product inherits product.template or res.users inherits res.partner.

This mean we create a model that gets the know how of a Model but adds aditional data/columns in a new database table. So when you create a user, all partner data is stored in res_partner table (and a partner is created) and all user related info is stored in res_users table.

In your code when wizard (levelprime_product_general_status.product_from_barcode) record will create then all product.product/product.template fields are required,due to that reason you are getting this type of error.

You can check difference between _inherit & _inherits from following link.

https://www.odoo.com/forum/how-to/developers-13/the-different-openerp-model-inheritance-mechanisms-what-s-the-difference-between-them-and-when-should-they-be-used-46

You need to follow following code.

class ProductFromBarcode(models.TransientModel):
    _name = 'levelprime_product_general_status.product_from_barcode'

    product_id= fields.Many2one(comodel_name='product.product',string="Product")
    product_barcode = fields.Char(help='Insert the barcode to search '
                                          'the correspondent product',
                                     "Barcode")

    @api.onchange('product_barcode')
    def on_barcode_changed(self):
        if self.product_barcode:
            self.product_id = self.get_product_from_barcode(self.product_barcode)

    @api.model
    def get_product_from_barcode(self,barcode):
        r = self.env['product.product'].search([('barcode', '=', barcode)])
        if r:
            return r
        else:
            return False

In above code just create wizard & add two fields. This may help you.

0
votes

from what you are saying you are using inherits to show the information of the product selected by the barcode remove it and use related field: add the fields that you are showing on the form view to you model

name = fields.Char(related='product_id.name', readonly=True)

Now you can use name on your view it's like compute field or proxy. you can make them readonly if you want to display them.