Odoo conditional readonly field on One2many field disappears - odoo

I've a conditional readonly field in the view of a model. This model is used as a One2many field on it's parent model.
When I edit one of the elements of the One2many field, click another of the elements the value of the field that has the conditional readonly disappears.
In my searches for this problem I've found the next related issue on odoo github.
My problem is quite similar, but the value of the field completely disappears when the readonly condition is False. When the condition is True the value reappears after clicking outside of the element (another element or outside of the form).
Basically, the models are:
One2many class:
class ChildClass(models.Model):
_name = 'child.class'
some_field = fields.Integer()
conditional_field = fields.Boolean()
conditional_readonly_field = fields.Integer()
parent_field = fields.Many2one(
'parent.class'
)
Parent class:
class ParentClass(models.Model):
_name = 'parent.class'
one2many_field = fields.One2many(
'child.class',
'parent_field'
)
View
<odoo>
<data>
<record model="ir.ui.view" id="view_draft_order_form">
<field name="name">parent.class.form</field>
<field name="model">parent.class</field>
<field name="arch" type="xml">
<form>
<field name="one2many_field">
<form>
<field name="some_field"/>
<field name="conditional_readonly_field" attrs="{'readonly': [('conditional_field', '=', True)]}"/>
</form>
</field>
</form>
</field>
</data>
<odoo>
So, the value of the conditional_readonly_field disappears after editing some_field and clicking on another element of the One2many field. The problem is that it may be after the first, second or some number of clicks (I've been trying and it's not consistent).
For the record, when the readonly condition is removed, the problem disappears.
Thanks in advance for any suggestions!

Yes, It will disappear when you give readonly attributes.
For overcome this problem, pass the value in create method as well in the write method. This will solve your problem.

Related

Get the id of the current view in Odoo

Suppose we have a model named 'repertoire' with a field Many2many 'documents_id'
and i have a button in the many2many tree view ,in that button i want to get the id of the 'repertoire' i'm in
is there any solution for this
I found the answer ,we can pass a context to the many2many field ,for example :
<field name="app_ids" string="Apps" context="{'current_instance_id': id}">
<tree editable="false" create="false" delete="true">
<field name="name"/>
<button type="object" name="updating_module" icon="fa-refresh"/>
</tree>
</field>
on my function i can retrieve it :
def updating_module(self):
instance_id = self.env.context.get('current_instance_id')

Odoo write to field not part of the current view

I want to update the field done_date which is part of the project.task form view when pulling a Kanban tile on the stage that is indicated as being the final stage.
My code below works fine if the field is part of the Kanban view but fails to write if the field is only part of the task form view and not part of the Kanban project view.
The done_date field should be written even without being part of the Kanban view.
models.py
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class project_set_end_date(models.Model):
inherit = 'project.task.type'
last_stage = fields.Boolean(string="Final stage")
class project_set_end_date(models.Model):
_inherit = 'project.task'
#api.onchange('stage_id')
def _set_end_date(self):
if self.stage_id.last_stage:
self.date_finished = fields.Datetime.now()
views.py
<odoo>
<data>
<!-- explicit list view definition -->
<record model="ir.ui.view" id="project_set_end_date">
<field name="name">project.task.type.form</field>
<field name="model">project.task.type</field>
<field name="inherit_id" ref="project.task_type_edit"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='fold']" position='after'>
<field name="last_stage"/>
</xpath>
</field>
</record>
</data>
</odoo>
Odoo doesn't write to a field that doesn't exist in the current view. So I suggest adding the field but with the attribute invisible = True to avoid showing it:
<field name="your_field" invisible="True"/>

odoo server error after click on save button

When click on save button gives me odoo server error shown in screenshot
and at backed following error display.
2019-12-14 12:36:25,426 4067 ERROR work_span odoo.sql_db: bad query:
INSERT INTO "survey_page" ("id", "create_uid", "create_date",
"write_uid", "write_date", "create_id_survey", "sequence", "title")
VALUES (nextval('survey_page_id_seq'), 1, (now() at time zone 'UTC'),
1, (now() at time zone 'UTC'), 1, 10, 'test1') RETURNING id ERROR:
null value in column "survey_id" violates not-null constraint DETAIL:
Failing row contains (5, 1, test1, null, 10, null, 1, 2019-12-14
12:36:25.421912, 1, 2019-12-14 12:36:25.421912).
UPDATE
Description: I am trying to display survey title, survey page, survey question in one form for that I have create my custom model. Custom model inherit survey.survey,survey.page,survey.question and also contain two one2many field.
Following is my code:
py file
class SurveyCreate(models.Model):
_name = 'create.survey'
_inherit = ['survey.survey','survey.page','survey.question']
pages_id = fields.One2many('survey.page','create_id_survey','Pages')
questions_survey = fields.One2many('survey.question','create_id_survey','Questions')
survey_id = fields.Many2one('survey.survey', string='Survey',required=False)
page_id = fields.Many2one('survey.page', string='Survey page', required=False)
Xml file
<sheet>
<group>
<field name="title"/>
</group>
<group>
<field name="pages_id" mode="tree">
<tree editable="bottom">
<control>
<create string="Add page"/>
</control>
<field name="title"/>
<field name="questions_id" widget="many2many_tags" context="{'tree_view_ref':'survey_inherit.survey_create_form','default_page_id':active_id}"/>
</tree>
</field>
</group>
<group>
<field name="questions_survey" mode='tree'>
<tree name="questions_tree" editable="bottom">
<control>
<create string="Add Question"/>
</control>
<field name="question"/>
<field name="type"/>
</tree>
</field>
</group>
<group>
<group>
<field name="question"/>
</group>
<group>
<field name="type"/>
</group>
</group>
</sheet>
</form>
as per #Atul suggestion make changes but same error occur
Following screenshot for 1.Form View 2.Error after click on save button
It seems you have created a custom survey action model. and trying to use survey.page as one2many or many2many field on it.
when you add the page and try to save the record it is preventing because in default survey module survey_id field is mandatory. you can have two options to resolve this issue.
inherit the survey.page and Overwrite the field and make it non-required.
survey_id = fields.Many2one('survey.survey', string='Survey', required=False)
Populate the value of survey_id by default (you can use ir.config_parameter)
hope this helps!
Edit: 19th December 2019
You do not need to inherit the create.survey from any model if you do not required to change anything on the default survey mode.
class SurveyCreate(models.Model):
_name = 'create.survey'
_inherit = ['survey.survey','survey.page','survey.question']
Remove the below line from your class.
_inherit = ['survey.survey','survey.page','survey.question']
Instead create a new class for survey.page and overwrite the field like
class SurveyPage(models.Model):
_name = 'survey.page'
survey_id = fields.Many2one('survey.survey', string='Survey', required=False)
Looks like you've created a menu/action for a model which is only used in One2many fields, so the form view of that model is not showing the relation's inverse field (survey_id). In One2many fields there is no need to show this field, because Odoo is doing some black magic for them.
So the best way IMO is to create your own form view for that model. You also have to specify this form view as default on your menu action.

How to make Many2One invisible when the form is called via 'add an item' in the parent view?

I would like to make a many2one field invisible when called by 'add an item' in the One2many view, for exemple :
parent view :
Name = 'this is One2many field'
value 1 =
value 2 : add an item
child view :
Parent Name = 'this is Many2one field'
value 1 = ....
and when i click on 'add an item' i'd like to get the folowing view :
child view :
value 1 = ...
I tried setting attrs="{'invisible':[('parent_id', '!=', False)]}" in the child view but this is always true because the parent fields are not created yet. Any idea ?
There is very simple way to achieve this by defining inline form view for that one2many field.
Here is an example for your reference.
<field name="one2many_field_name">
<tree>
<field name="field1" />
<field name="field2" />
<field name="field3" />
</tree>
<form>
<field name="field1" invisible="1" />
<field name="field2" />
<field name="field3" />
</form>
</field>
While you click on "Add an item" it will render form view which is defined inline and if there is no inline view defined then it will take form view which you have created externally.
So, that way you can define inline view for many2many / one2many fields, in that manner you can define behavior of any fields directly.
You can achieve it by setting context in one2many field in parent form view.
I will explain you by example.
placement_line is the parent view one2many field. In that set the context like below code.
<field name="placement_line" context="{'one2many':True}" />
Here, student_id is the manyone child form view field. See the below code.
<field name="student_id" invisible="context.get('one2many')"/>
By settings like above code in your parent form and child form you can invisible child field(many2one) when child form open from 'add an item' in the One2many view.

New State in Openerp7

... In openerp7
I want my new state to show up in sale module ... But it is not appearing
Pls have a look at code below
In sale.py module I added state like:
class Sale_order(osv.Model):
_inherit = 'sale.order'
_columns = {
'state': fields.selection([
('draft', 'Draft Quotation'),
('my_new_state', 'My New State'),
('sent', 'Quotation Sent'),
('cancel', 'Cancelled'),
('waiting_date', 'Waiting Schedule'),
('progress', 'Sales Order'),
('manual', 'Sale to Invoice'),
('invoice_except', 'Invoice Exception'),
('done', 'Done'),
], 'Status', readonly=True, track_visibility='onchange',
help="Gives the status of the quotation or sales order. \nThe exception status is automatically set when a cancel operation occurs in the processing of a document linked to the sales order. \nThe 'Waiting Schedule' status is set when the invoice is confirmed but waiting for the scheduler to run on the order date.", select=True),
}
And in sale_view.xml, I added this piece of code..
<openerp>
<data>
<!-- Inherit the sale order model's form view and customize -->
<record id="sale_form_view" model="ir.ui.view">
<field name="name">sale.order.form.inherit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<!-- Statusbar widget should also contain the new status -->
<field name="state" position="replace">
<field name="state" widget="statusbar" statusbar_visible="draft,my_new_state,sent,invoiced,done" statusbar_colors='{"invoice_except":"red","waiting_date":"blue"}'/>
</field>
</field>
</record>
</data>
But.... My new state is not appearing between draft quotation and quotation sent
Please guide
Why is this so
Thanks
First thing I would check is to make sure you are replacing the proper field in your view (if there are several instances of a field named "state" in the view you inherit, the wrong occurence could be replaced). Check the view by opening the 'Modify FormView' item in the developper tools/view.
If it is the wrong occurence you are replacing, you main need to change your view definition by using an xpath expression.
Second thing I would check, is make sure the sequence of your inherited view is smaller that the original view you are trying to replace/modify. You can check in 'Manage Views' item in the developper tools/view.
Third thing I would try is to rename your class from 'Sale_order' to 'sale_order' just to match the name of the original class your are trying to override.
Hope this helps.