odoov9 override old api onchange - odoo

I want in res.partner model make onchange event on field parent_id. this field already have onchange event by old api, so i changed it`s value on XML to on_change=1 and added .py code
def onchange_parent_id(self):
self.category_id = self.parent_id.category_id
super(res_partner, self).onchange_parent_id(self)
after update, then i open contact form and changing parent_id, everything works as i want, but when i press save error occurrs
TypeError: cannot convert dictionary update sequence element #0 to a sequence
as i understand it occurrs becouse on create other method (_fields_sync) also calls this onchange_parent_id methot by 'old style'.
Maybe someone can advice me how to fix this.
Thanks in advance

It seems that _fields_sync calls onchange_parent_id with context=[partner.id] and this is the raison of the conversion error (api.py line 756).
ODOO LOG:
WARNING ...: partner: res.partner(93,)
api:756:context=[93]
Python test:
>>> from openerp.tools import frozendict
>>> context = [93]
>>> frozendict(context)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot convert dictionary update sequence element #0 to a sequence
You can remove the old onchange event and create a new one (onchange_parent_id_new) without overriding onchange_parent_id method.
Python:
#api.model
#api.onchange('parent_id')
def onchange_parent_id_new(self):
old_res = super(res_partner, self).onchange_parent_id(self.parent_id.id)
if type(old_res) is dict and 'value' in old_res:
for field, value in old_res.get('value').items():
if hasattr(self, field):
setattr(self, field, value)
if self.parent_id:
self.category_id = self.parent_id.category_id
XML:
<record id="view_partner_form_inherit" model="ir.ui.view">
<field name="name">view.partner.form.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="parent_id" position="replace">
<field name="parent_id"/>
</field>
</field>
</record>

Related

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"/>

Save value in Transient model Odoo 10

I added a new field in account.config.settings model. It displays the new field in settings page and can enter the value. But when i reopen the page the value is not there. I know the Transient model won't store values for long.
But rest of the values still there, how can i achieve this?
Below is my code.
*.py
class AccountSettings(models.TransientModel):
_inherit='account.config.settings'
#api.one
def _get_header(self):
header = fields.Char('Header')
*.xml
<record id="view_account_config_settings_inherit" model="ir.ui.view">
<field name="name">view.account.config.settings.inherit.form</field>
<field name="model">account.config.settings</field>
<field name="inherit_id" ref="account.view_account_config_settings"/>
<field name="arch" type="xml">
<xpath expr="//group[#name='accounting']" position="after">
<group string="Reports" name="reports">
<field name="header" class="oe_inline"/>
</group>
</xpath>
</field>
</record>
In account.config.settings Model you can save your value by using this :
class AccountSettings(models.TransientModel):
_inherit='account.config.settings'
header = fields.Char('Header')
#api.multi
def set_header_defaults(self):
return self.env['ir.values'].sudo().set_default(
'account.config.settings', 'header', self.header)
Try this code:
class AccountSettings(models.TransientModel):
_inherit='account.config.settings'
#api.one
def _get_header(self):
header = fields.Char('Header',config_parameter='header.configuration')
you can name the attribute config_parameter anything you want. And it will be used to get the value of header from other models.
example:
test = self.env['ir.config_parameter'].get_param('**header.configuration**', '').strip()
test will return the temporary stored value in account.config.settings.

Warehouse stock restriction not working in edit mode odoo10?

In my custom module I use stock picking type to see the warehouse operations of the user.
class ResUsers(models.Model):
_inherit = 'res.users'
default_picking_type_ids = fields.Many2many(
'stock.picking.type', 'stock_picking_type_users_rel',
'user_id', 'picking_type_id', string='Warehouse Operations')
I added this in user form.
In my sexurity.xml file add
<record id="filter_user_stock_picking_type" model="ir.rule">
<field name="name">Filter Stock Picking Type</field>
<field name="model_id" search="[('model','=','stock.picking.type')]" model="ir.model"/>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
<field name="domain_force">[('id','in', [ s.id for s in user.default_picking_type_ids ])]</field>
</record>
so it is worked in when a user is created and assigns stock operation.
But when changed the stock operation to particular user, it will not affect.
How to resolve this issue??
I think, the problem is the Odoo Cache.
The old values are stored in the Cache for a long time and your change will not take any effect.
You can try it to clear the cache. It helped me to solve the similar problem.
class User(models.Model):
_inherit = 'res.users'
#api.multi
def write(self, vals):
ret = super(User, self).write(vals)
if 'default_picking_type_ids' in vals:
# clear default ir values when default_picking_type_ids changes
self.env['ir.values'].get_defaults_dict.clear_cache(self.env['ir.values'])
return ret

Error while adding custom field using module: ParseError: "arch" while parsing file

I am trying to add a custom field to Odoo 9 res.partner model using module. I have used scoffold command to generate the module files and added following code to models.py and views.xml.
models/models.py
from openerp import models, fields, api
class SeicoPartner(models.Model):
_name = 'res.partner'
_inherit = 'res.partner'
no_of_ac = fields.Integer('No of AC', default=0)
review = fields.Char('Company Review')
views/views.xml
<openerp>
<data>
<record id="res_partner_field_ac" model="ir.ui.view">
<field name="no_of_ac">10</field>
</record>
</data>
</openerp>
Upon installation of this module from Apps screen, I got the following error:
Traceback (most recent call last):
...
File "C:\Program Files (x86)\Odoo 9.0-20160719\server\openerp\addons\base\ir\ir_ui_view.py", line 344, in create
ParseError: "arch" while parsing file:///C:/Program%20Files%20(x86)/Odoo%209.0-20160719/server/openerp/addons/mymodule1/views/views.xml:4, near
<record id="res_partner_field_ac" model="ir.ui.view">
<field name="no_of_ac">10</field>
</record>
From the Settings -> Database Structure -> Fields I can see that res.partner has the no_of_ac field, but the field is not visible while editing any customer details.
That's because you're missing the arch field with describes the type of view (either xml or html), in most cases xml is just fine,
You're also missing the model name, the view name, so odoo doesn't know which model your view belongs to. you also have to specify the existing model form you want to over-ride and the position where you want the new field to be, in this case i used an xpath expression to display the field after the website field in the parent view, it can be anywhere you want it to be.
<openerp>
<data>
<record id="res_partner_field_ac" model="ir.ui.view">
<field name="name">res.partner.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='website']" position="after">
<field name="no_of_ac" />
</xpath>
</field>
</record>
</data>
</openerp>
also you don't need to specify _name if you just want to extend a model and add extra fields to it, so change your model code to this
from openerp import models, fields, api
class SeicoPartner(models.Model):
_inherit = 'res.partner'
no_of_ac = fields.Integer('No of AC', default=0)
review = fields.Char('Company Review')
If you want to add a data record you should use res.partner as model and define the required fields:
<record id="res_partner_field_ac" model="res.partner">
<field name="no_of_ac">10</field>
<field name="name">NEW PARTNER NAME</field>
<!-- define required fields -->
</record>
To define a view, take a look at Odoo views
You are inserting a new record in ir.ui.view data model.
<openerp>
<data>
<record id="res_partner_field_ac" model="ir.ui.view">
<field name="no_of_ac">10</field>
</record>
</data>
</openerp>
But you want to insert data to : res.partner
<openerp>
<data>
<record id="res_partner_field_ac" model="res.partner">
<field name="name">a name here because it's required when the field type != 'contact' </field>
<field name="no_of_ac">10</field>
</record>
</data>
</openerp>
NOTE :you encountered a problem because arch is a requrired field inir.ui.view model.

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.