Unknown field 'state' in domain when editing attribute - odoo

Using Odoo 10 (fetched from GitHub commit 7413b26, branch 10.0), installing a module which I'm porting over from Odoo 8.
This module forces the purchase.order.line form to show up upon clicking a line in purchase.order by removing the editable attribute from the tree, but when saving changes done in that form Odoo raises:
Error: Unknown field state in domain [["state","in",["purchase","to approve","done","cancel"]]]
purchase_order_error.xml:
<record id="purchase_order_line_tree" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="priority" eval="33"/>
<field name="type">form</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page/field[#name='order_line']/tree" position="attributes">
<attribute name="editable"/>
</xpath>
</field>
</record>
The __manifest__.py is:
{'name': "purchase_order_error",'depends': ['base', 'product', 'purchase'],'data': ['purchase_order_error.xml',],'installable':True}
and __init__.py is just the usual from . import purchase_order_error.
Here are some more observations:
The field state can have the following Selection values: [draft], [sent], [to approve], [purchase], [done], [cancel]; [draft] and [sent] do not appear in the error.
An Odoo user reported same problem on the Odoo GitHub bug tracker, without any solution as the time of writing.
Is there a workaround ?

You should add
<record id="purchase_order_line_tree" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="priority" eval="33"/>
<field name="type">form</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page/field[#name='order_line']/tree" position="attributes">
<attribute name="editable">top</attribute>
</xpath>
</field>
</record>
In your case it's going to open form view to allow you to create
records, because you have not given the value of editable attribute.
So in form view of purchase order line there might be no field defined "state". According to rule if fields are used anywhere in attrs, domains then it must be defined on view, it doesn't matter you can define it invisible.
So just add this field in Purchase order line form view or follow the first solution for editable="top"
<field name="state" invisible="1" />

The problem is when saving the record from the form view
the state field is not defined. you don't get this error
in the tree view because the field is there:
<page string="Products">
<field name="order_line" attrs="{'readonly': [('state', 'in', ('done', 'cancel'))]}">
<tree string="Purchase Order Lines" editable="bottom">
<field name="currency_id" invisible="1"/>
<field name="state" invisible="1"/>
.....
....
..
so you need to add it to the embedded form too:
<record id="xxx_purchase_order_form_list_details" model="ir.ui.view">
<field name="name">xxx_purchase_order_form_list_details</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='order_line']/tree" position="attributes">
<attribute name="editable"/>
</xpath>
<xpath expr="//field[#name='order_line']//form//field[#name='product_id']" position="before">
<field name="state" invisible="1"/>
</xpath>
</field>
</record>

Related

Add field in wizard view inside inherited module

I have a wizard with a m2m field that displays library.book tree.
In parent module view:
<field name='model'>library.return.wizard</field>
<field name='arch' type='xml'>
<form string="Return books">
<sheet>
<group>
<field name='book_ids'>
<tree>
<field name="name"/>
<field name="state"/>
<!--How to add date_return field here?-->
<!--<field name="date_return"/>-->
</tree>
</field>
</group>
</sheet>
</form>
</field>
Another module model inherits library.book and adds a field date_return.
class LibraryBook(models.Model):
_inherit = 'library.book'
date_return = fields.Date('Date to return')
I tried to add a date_return field to the wizard view like this, in the child module view:
<field name='model'>library.return.wizard</field>
<field name='arch' type='xml'>
<field name='book_ids' position="inside">
<tree>
<xpath expr="field[#name='state']" position="after">
<field name="date_return" />
</xpath>
</tree>
</field>
</field>
It doesn't work. What is the right way to address it in the view?
Again, I have a module that inherits m2m field model, and add a field there, but I can't get the field.
UPDATE 22 Jun:
inherit_id definitely helped. Parent record is <record id='library_return_wizard_form' model='ir.ui.view'> so my child view uses <field name="inherit_id" ref="my_library.library_return_wizard_form"/>.
When i only use an element locator, the only column rendered in the tree widget is state.
<record id='library_return_wizard_form_add' model='ir.ui.view'>
<field name='name'>library.return.wizard.form.view.add</field>
<field name='model'>library.return.wizard</field>
<field name="inherit_id" ref="my_library.library_return_wizard_form"/>
<field name='arch' type='xml'>
<field name='book_ids' position="inside">
<tree>
<field name="state" position="after">
<field name="date_return"/>
</field>
</tree>
</field>
</field>
</record>
If I try to go with xpath, there is a js frontend error.
<record id='library_return_wizard_form_add' model='ir.ui.view'>
<field name='name'>library.return.wizard.form.view.add</field>
<field name='model'>library.return.wizard</field>
<field name="inherit_id" ref="my_library.library_return_wizard_form"/>
<field name='arch' type='xml'>
<field name='book_ids' position="inside">
<tree>
<xpath expr="//field[#name='book_ids']/tree/field[#name='state']" position="after">
<field name="date_return" />
</xpath>
</tree>
</field>
</field>
</record>
Maybe, just maybe the field is not being found with this xpath, but I doubt it.
Full error:
TypeError: Cannot read property 'type' of undefined
at Class._renderBodyCell (http://localhost:8069/web/static/src/js/views/list/list_renderer.js:317:55)
at http://localhost:8069/web/static/src/js/views/list/list_renderer.js:593:25
at Function._.map._.collect (http://localhost:8069/web/static/lib/underscore/underscore.js:164:24)
at Class._renderRow [as _super] (http://localhost:8069/web/static/src/js/views/list/list_renderer.js:592:24)
at Class._renderRow (http://localhost:8069/web/static/src/js/views/list/list_editable_renderer.js:566:32)
at Class._renderRow (http://localhost:8069/web/static/src/js/core/class.js:123:38)
at Function._.map._.collect (http://localhost:8069/web/static/lib/underscore/underscore.js:164:24)
at Class._renderRows (http://localhost:8069/web/static/src/js/views/list/list_renderer.js:614:18)
at Class._renderRows (http://localhost:8069/web/static/src/js/views/list/list_editable_renderer.js:588:26)
at Class._renderRows (http://localhost:8069/web/static/src/js/core/class.js:123:38)
In list_renderer.js file xpath node has all it's attributes except expr undefined.
FINAL EDIT:
I should have removed also these few elements which I didn't notice after staring at this one file for too long. Locator or xpath should have been put right into arch.
<field name='book_ids' position="inside">
<tree>
You should use the inherit_id field to specify the parent view of the current view, it is unset by default.
You are trying to locate the field named book_ids and add a tree to it which has an XPath expression to locate the state field. The correct way is to locate the state field and use the position attribute to specify how the matched node should be altered.
<record id="view_library_return_wizard_form" model="ir.ui.view">
<field name="name">library.return.wizard.form.inherit</field>
<field name="model">library.return.wizard</field>
<field name="inherit_id" ref="MODULE_NAME.FORM_VIEW_ID"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='book_ids']/tree/field[#name='state']" position="after">
<field name="date_return"/>
</xpath>
</field>
</record>
When using an element locator, Odoo will try to find the first element matching. You can use the field locator to simplify the syntax (if there is only one state field or you need to locate the first one).
<record id="view_library_return_wizard_form" model="ir.ui.view">
<field name="name">library.return.wizard.form.inherit</field>
<field name="model">library.return.wizard</field>
<field name="inherit_id" ref="MODULE_NAME.FORM_VIEW_ID"/>
<field name="arch" type="xml">
<field name="state" position="after">
<field name="date_return"/>
</field>
</field>
</record>
EDIT::
Inheritance specs are comprised of an element locator, to match the inherited element in the parent view, and children element that will be used to modify the inherited element.
You have just to include one of the following expressions in the view arch
xpath:
<xpath expr="//field[#name='book_ids']/tree/field[#name='state']" position="after">
<field name="date_return"/>
</xpath>
field:
<field name="state" position="after">
<field name="date_return"/>
</field>

hide button Edit , Create on odoo xml

I want to hide the edit and create button on the form view for a specific user I use this code but the button not showing at all
i just want to hide buttons just for only group
<record model="ir.ui.view" id="edit_button_message_">
<field name="name">edit.button.message.1</field>
<field name="model">person.message</field>
<field name="inherit_id" ref="view_parent_message_form"/>
<field name="groups_id" eval="[(6,0,[ref('person_access')])]"/>
<field name="arch" type="xml">
<xpath expr="/form[#string='form_view_string']" position="attributes">
<attribute name="create">false</attribute>
<attribute name="edit">false</attribute>
</xpath>
</field>
</record>
and i use this
<form string="form_view_string" edit="false" create="false" >
nothing happened , I use odoo v8
You better create a security access for that group to allow just read to that model, preventing the create, write and unlink actions and those buttons should disappear.
You could create it in xml as it will be only one, like:
<record id="person_message_access" model="ir.model.access">
<field name="name">edit.button.message.access</field>
<field name="model_id" ref="person.message"/>
<field name="group_id" ref="person_access"/>
<field name="perm_read" eval="1"/>
<field name="perm_create" eval="0"/>
<field name="perm_write" eval="0"/>
<field name="perm_unlink" eval="0"/>
</record>
or you could set it into a field ir.model.access.csv with content like:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
person_message_access,edit.button.message.access,model_person_message,person_access,1,0,0,0

Odoo. How to create a view to extended model

I am very new in odoo and i really need your help.
I've extended res.partner :
class extendedPartner(models.Model):
_name = 'extended.partner'
_inherit = 'res.partner'
auto = fields.One2Many('partner.car', 'auto_name', 'Car', required=False)
class partnerCar(models.Model):
_name = 'partner.car'
auto_model = fields.Char('Model auto', size=20, required=True)
release = fields.Integer('Year of release', required=True)
auto_name = fields.Many2One('extended.partner', 'Car Name', required=True)
But I don't know how to write xml so that I could see all partner's cars and information about them
<record model="ir.ui.view" id="view_partner_form">
<field name="name">res.partner.form.inherit</field>
<field name="model">extended.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<notebook position="inside">
<page string="Cars">
<!-- what should I write here? -->
</page>
</notebook>
</field>
</record>
Could you please help me? Thank you in advance.
UPD:
Is it right solution?
<record model="ir.ui.view" id="view_partner_form">
<field name="name">res.partner.form.inherit</field>
<field name="model">extended.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="auto">
<tree>
<field name="auto_name"/>
<field name="auto_model"/>
<field name="release"/>
</tree>
</field>
</field>
</record>
You are almost there, since you inherit from another view and you injecting your view into the view you inherit from, you need to give your new view a "hook" in the parent view which it can use to attach its contents. So you use an xpath expression, and then you insert your field.
When you insert a relational field you can create so called embedded views. Here you have defined a tree view for your field. That means whenever your field will be rendered as a tree that is the tree that will be used, in your case the form.
You could also create a <form> after <tree> to be shown when clicked.
<record model="ir.ui.view" id="view_partner_form">
<field name="name">res.partner.form.inherit</field>
<field name="model">extended.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="insert_x_path_xpression here" position="after, before etc"
<field name="auto">
<tree>
<field name="auto_name"/>
<field name="auto_model"/>
<field name="release"/>
</tree>
</field>
</xpath>
</field>
</record>

readonly in invoice lines based on a value in line

I have a field 'uneditable' in 'account.invoice.line'.
I want to disable editing the line record if uneditable is true but creating enw line should be allowed.
my view code is as follows
<record model="ir.ui.view" id="invoice_supplier_form_ext">
<field name="name">account.invoice.supplier.form</field>
<field name="model">account.invoice</field>
<field name='inherit_id' ref='account.invoice_supplier_form'/>
<field name="type">form</field>
<field name="arch" type="xml">
<data>
<field name="product_id" position="before">
<field name="uneditable" invisible="1"/>
</field>
<field name="quantity" position="attributes">
<attribute name="attrs">{'readonly': [('uneditable','=', True)]}</attribute>
</field>
</data>
</field>
</record>
Please suggest me what i am doing wrong. I am getting error with this code in view and does not make the line readonly.
Actually your view is wrong. You have defined the fields 'quantity' and 'uneditable' in account.invoice.line and you are adding then in the invoice view. Please check the invoice_supplier_form view and add the fields correctly in the view.
<record model="ir.ui.view" id="invoice_line_form_ext">
<field name="name">account.invoice.line.form</field>
<field name="model">account.invoice.line</field>
<field name='inherit_id' ref='account.view_invoice_line_form'/>
<field name="type">form</field>
<field name="arch" type="xml">
<data>
<field name="product_id" position="before">
<field name="uneditable" invisible="1"/>
</field>
<field name="quantity" position="attributes">
<attribute name="attrs">{'readonly': [('uneditable','=', True)]}</attribute>
</field>
</data>
</field>
</record>

How to add a field into an inherited view's tab/page?

How can I inherited a view to add a field into the "Sessions" tab ?
e.g :
<record model="ir.ui.view" id="partner_sessions_form_view">
<field name="name">partner.sessions.name</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[#string='Notes']" position="after">
<page string="Sessions">
<field name="session_ids" nolabel="1" colspan="4"/>
</page>
</xpath>
</field>
</record>
This adds a page, but how would I add a field in the page Sessions ?
If you want to add a field to page 'Sessions' that you have created above, then you should provide
<record model="ir.ui.view" id="partner_sessions_form_view_again_inherited">
<field name="name">partner.sessions.name.inherited</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="partner_sessions_form_view" />
<field name="arch" type="xml">
<xpath expr="//field[#name='session_ids']" position="before">
<field name="new_field1" nolabel="1" colspan="4"/>
</xpath>
</field>
</record>
if you want to add add a field to the session_ids tree or form view, then
<xpath expr="//field[#name='session_ids']/tree/field[#name='already_existing_field']" position="after">
<field name="new_field1" />
</xpath>
You need to find that field in side you page Session
like this (but that page has to be their in view):
<xpath expr="//page[#string='Sessions']/field[#name='some_field'] position="after">
<field name="session_ids" nolabel="1" colspan="4"/>
</xpath>
Thanks
This is covered pretty well in the documentation. The simplest case is to just add your new field after an existing one. In this example, you're placing the relation_ids field after the lang field.
<record model="ir.ui.view" id="view_partner_form4">
<field name="name">res.partner.form.inherit4</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="lang" position="after">
<field name="relation_ids"/>
</field>
</field>
</record>
If that field appears in more than one place, you'll have to use an XPath element. For example, if the lang field appears in a subview's tree view and its form view.