I need to create one2one relation in openerp7. I read many articles about this idea and I could to type the following code
problem is : that openerp7 does not send value from parent view (calculation) to child (container)
this my code
testproject.py:
from osv import fields,osv
class container(osv.osv):
_name='container'
_columns={
'calculation_id': fields.many2one('calculation','Calculation'),
'name': fields.char('Name', size=32),
}
container()
class calculation(osv.osv):
_name='calculation'
_columns={
'container_id': fields.many2one('container','Container'),
'namefull': fields.char('Name Full', size=32),
}
calculation()
xml code:
<?xml version="1.0"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_container_form">
<field name="name">container.form</field>
<field name="model">container</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Container">
<field name="name" select="1"/>
<field name="calculation_id" context="{'default_container_id': active_id}" />
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_container">
<field name="name">Container</field>
<field name="res_model">container</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Container/Container" id="menu_container"/>-->
<menuitem name="Container" id="menu_container_item" parent="menu_container" action="action_container"/>
<record model="ir.ui.view" id="view_calculation_form">
<field name="name">calculation.form</field>
<field name="model">calculation</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Calculation">
<field name="namefull" />
<field name="container_id" />
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_calculation">
<field name="name">Calculation</field>
<field name="res_model">calculation</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Calculation" id="menu_calculation_item" parent="menu_container" action="action_calculation"/>
</data>
</openerp>
You are correct, OpenERP will not move data around for you -- you will need to modify your Python code to do it.
Oh, and you should name your tables with your model as well -- I'll use a fake model name of my_model:
class calculation(osv.Model):
_name = 'my_model.calculation'
_columns = {
'container_id' fields.many2one('my_model.container', 'Container'),
'namefull': fields.char('Name Full', size=32),
}
def create(self, cr, uid, values, context=None):
new_id = super(calculation, self).create(cr, uid, values, context=context)
self.pool.get('my_model.container').create(cr, uid, {'calculation_id':new_id, 'name':values['namefull'])
return new_id
And something similer to write() in case namefull is updated.
Related
I have a parent model (Plant) which sends the active_id (plant_id) in the context as a default:
class Plant(models.Model):
_name = 'db.plant'
_description = 'db.plant'
name = fields.Char("Name", required=True)
...
Plant view with a many2one relation between them:
<odoo>
<data>
<record id="plant_list_view" model="ir.ui.view">
<field name="name">db.plant.view</field>
<field name="model">db.plant</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
...
</tree>
</field>
</record>
<record id="plant_form_view" model="ir.ui.view">
<field name="name">db.form.view</field>
<field name="model">db.plant</field>
<field name="arch" type="xml">
<form>
<sheet>
<group string="Plant">
<field name="name"/>
...
</group>
<group string="Components">
<notebook>
<page string="Data Sources">
<field name="data_source_ids" context="{'default_plant_id': active_id}">
<tree >
<field name="name"/>
...
<!-- <field name="plant_id"/> -->
</tree>
</field>
</page>
</notebook>
</group>
</sheet>
</form>
</field>
</record>
<record id="plant_action" model="ir.actions.act_window">
<field name="name">plant</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">db.plant</field>
<field name="view_mode">tree,form</field>
</record>
</data>
and his child model (Data_source):
class DataSource(models.Model):
_name = 'db.data_source'
_description = 'db.data_source'
name = fields.Char("Name", required=True)
plant_id = fields.Many2one('db.plant', name="Plant", required=True)
data_source view:
<odoo>
<data>
<record id="data_source_list_view" model="ir.ui.view">
<field name="name">db.data_source.view</field>
<field name="model">db.data_source</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
...
</tree>
</field>
</record>
<record id="data_source_form_view" model="ir.ui.view">
<field name="name">db.form.view</field>
<field name="model">db.data_source</field>
<field name="arch" type="xml">
<form>
<group>
<field name="name"/>
...
</group>
<group>
<field name="plant_id" domain="[('id', '=', context.default_plant_id)]" />
</group>
<group>
</group>
</form>
</field>
</record>
<record id="data_source_action" model="ir.actions.act_window">
<field name="name">Data Source</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">db.data_source</field>
<field name="view_mode">tree,form</field>
</record>
</data>
I know that the default_plant_id is received in the child because the plaint_id domain is filtering just my plant_id but I am not able to set it automatically as a default value. I need to click on the list and select my plant_id (which is the only element in the list).
I also tried adding an #api.on_change("plant_id") in the child (data_source) in two ways:
Option 1:
#api.onchange('plant_id')
def onchange_plant_id(self):
if self.plant_id:
context = dict(self._context or {})
return [(0,0,{'plant_id': context.get('default_plant_id')})]
giving me this exception:
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/albertocrespo/tools/odoo/odoo/http.py", line 640, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/Users/albertocrespo/tools/odoo/odoo/http.py", line 316, in _handle_exception
raise exception.with_traceback(None) from new_cause
AttributeError: 'list' object has no attribute 'get'
Option 2 (I am not sure what to send as a response, but the write statement is also not working):
#api.onchange('plant_id')
def onchange_your_many_to_one_field(self):
context = dict(self._context or {})
self.plant_id.write({'id':context.get('default_plant_id')})})
res = {}
return res
I need to auto-select my plant as an option in the data_source view before saving it.
There is no need of onchange method or anything on xml side - context level. You can simply use field plant_id in a relation one2many field data_source_ids.
Try with this:
data_source_ids = fields.One2many("db.data_source", "plant_id")
I'm trying to implement a many2one selection field where you select a project from. If you've selected a project then there's another many2one field where you can select the task from. These task all need to be from the selected project.
Currently I got this (note that I couldn't test it because I kept getting an XML error):
class purchase_order(osv.osv):
_inherit = 'purchase.order'
def get_task(self, cr, uid, ids, project_id, context=None):
task_obj = self.pool.get('project.task')
for task in task_obj.browse(cr, uid, ids, context):
task_ids = task_obj.search(cr, uid, [(task.project_id.id, '=', project_id)])
ids_cus = []
for cus in task_obj.browse(cr, uid, task_ids, context):
if cus.project.id.id not in ids_cus:
ids_cus.append(cus.project_id.id)
self.write(cr, uid, ids, {'state_readonly': 'listed', 'task_ids': [(6, 0, ids_cus)]})
return True
_columns = {
'project_id': fields.many2one('project.project', 'Project'),
'task_id': fields.selection(get_task, 'Select task'),
}
And my XML looks like this:
<record id="purchase_order_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<field name="origin" position="after">
<field name="project_id" on_change="_get_task(project_id)"/>
<field name="task_id" selection="widget"/>
</field>
</field>
</record>
What am I doing wrong with the XML here? And might there be another way?
No need to write method to filter tasks according to project in your case just change few things as follow.
class purchase_order(osv.osv):
_inherit = 'purchase.order'
_columns = {
'project_id': fields.many2one('project.project', 'Project'),
'task_id': fields.many2one('project.task', 'Tasks'),
}
and change your xml,
<record id="purchase_order_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<field name="origin" position="after">
<field name="project_id" />
<field name="task_id" domain="[('project_id','=',project_id.id)]" widget="selection" />
</field>
</field>
</record>
In your existing code you have made small mistake,
selection="widget" is not valid in xml you should write widget="selection"
This solved my problem, I've added a fields.related for chained fields:
_columns = {
'task_id': fields.related('project_id', 'tasks', type='many2one', relation='project.task', store=True,
string='Task')
}
And then adjust my XML (Like #Empiro Technologies said):
<record id="purchase_order_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<field name="origin" position="after">
<field name="project_id"/>
<field name="task_id" domain="[('project_id','=', project_id)]"/>
</field>
</field>
</record>
I have a form with a lot of fields and with two button (Save and Close and Save and New)
when Save and New button is clicked I want those previously entered fields value to be displayed.
Thank You!
OK, my first solution (using context) didn't work out :-( but i tried another way, i dont like it very much, but it could help you out.
following my example .py:
from openerp.osv import orm, fields
class object_one(orm.Model):
_name = "object.one"
_columns = {
'name':fields.char('Name', size=128, required=True),
'many_ids':fields.many2many('object.many',string="Many Objects")
}
class object_many(orm.Model):
_name = "object.many"
_columns = {
'name':fields.char('Name', size=128, required=True),
'sel':fields.selection([('1','One'),
('2','Two'),
('3','Three')],
string="Selection", required=True),
}
def _get_sel(self, cr, uid, context={}):
many_id = self.search(cr, uid, [('create_uid','=',uid)], context=context, order="create_date desc", limit=1)
if many_id:
many = self.browse(cr, uid, many_id[0], context)
return many.sel
return False
_defaults = {
'sel':_get_sel
}
following my example .xml:
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="one_form" model="ir.ui.view">
<field name="name">one form view</field>
<field name="model">object.one</field>
<field name="arch" type="xml">
<form version="7.0" string="">
<group>
<field name="name" />
<field name="many_ids" />
</group>
</form>
</field>
</record>
<record id="one_tree" model="ir.ui.view">
<field name="name">one tree view</field>
<field name="model">object.one</field>
<field name="arch" type="xml">
<tree version="7.0" string="">
<field name="name" />
</tree>
</field>
</record>
<record id="many_form" model="ir.ui.view">
<field name="name">many form view</field>
<field name="model">object.many</field>
<field name="arch" type="xml">
<form version="7.0" string="">
<group>
<field name="name" />
<field name="sel" />
</group>
</form>
</field>
</record>
<record id="many_tree" model="ir.ui.view">
<field name="name">many tree view</field>
<field name="model">object.many</field>
<field name="arch" type="xml">
<tree version="7.0" string="">
<field name="name" />
<field name="sel" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="one_tree_action">
<field name="name">One Objects</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">object.one</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="one_tree" />
</record>
<record model="ir.actions.act_window" id="many_tree_action">
<field name="name">Many Objects</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">object.many</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="many_tree" />
</record>
<menuitem name="Testing Menu" id="testing_menu" />
<menuitem name="Sub Menu" parent="testing_menu" id="sub_menu" />
<menuitem action="one_tree_action" name="One Menu" parent="sub_menu" id="one_menu" />
<menuitem action="many_tree_action" name="Many Menu" parent="sub_menu" id="many_menu" />
</data>
</openerp>
you will see, every many-object created by an user, will have the last selection (sel) get from db. so its more of a workaround for your problem.
hope this will help you.
I am using openerp 6.My form contains one text box and I need to get that value and assign it to a variable so to perform calculations and to return a result to store in a new textbox...
I have give .py file here. This will calculate square of the number
from osv import osv
from osv import fields
class test_base(osv.osv):
_name='test.base'
_columns={
'first':fields.integer('Enter Number here'),
'result':fields.integer('Display calclation result'),
}
def first_change(self, cr, uid, ids,first,context=None):
r=first*first
return {'value':{'result':r}}
test_base()
xml file is given here
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="test_base_form">
<field name="name">test.base.form</field>
<field name="model">test.base</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="best Base">
<field name="first" on_change="first_change(first)"/>
<field name="result"/>
</form>
</field>
</record>
<record model="ir.ui.view" id="test_base_tree">
<field name="name">test.base.tree</field>
<field name="model">test.base</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Test Base">
<field name="first"/>
<field name="result"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_test_seq">
<field name="name">Test Base</field>
<field name="res_model">test.base</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
</record>
<menuitem id="menu_test_base_main" name="Test Base">
</menuitem>
<menuitem id="menu_test_base_sub" parent="menu_test_base_main" name="Square number" action="action_test_seq">
</menuitem>
</data>
</openerp>
with following code I could able to insert/edi trecord without any issue. My form view displays all fields except 'rate' which is selection field. Also tree view shows rate field as undefined. My database holds correct value for rate field. May I know the root cause for this and how to overcome this issue.
.py file is given here
from osv import osv
from osv import fields
class test_base(osv.osv):
_name='test.base'
_columns={
'name':fields.char('Name'),
'email':fields.char('Email'),
'code':fields.integer('Unique ID'),
sal':fields.float('Salary'),
'rate':fields.selection(((10,'10'), (20,'20'),(30,'30')),
'Percentage of Deduction'),
'ded':fields.float('Deduction'),
'bdisplay':fields.float('Button Display'),
}
def on_change_ded_cal(self, cr, uid, ids,rate,context=None):
x=rate*2
return {'value':{'ded':x }}
test_base()
My XML is
<record model="ir.ui.view" id="test_base_form">
<field name="name">test.base.form</field>
<field name="model">test.base</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Test Base">
<field name="name"/>
<field name="email"/>
<field name="code"/>
<field name="sal"/>
<field name="rate" on_change="on_change_ded_cal(rate,sal,ded)"/>
<field name="ded"/>
<field name="bdisplay"/>
<button name="my_button_display" string="Calculate" type="object"/>
<newline />
<newline />
<newline />
<field name="skillid" colspan="4" nolabel="1"/>
</form>
</field>
</record>
<record model="ir.ui.view" id="test_base_tree">
<field name="name">test.base.tree</field>
<field name="model">test.base</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Test Base">
<field name="name"/>
<field name="email"/>
<field name="code"/>
<field name="sal"/>
<field name="ded"/>
<field name="rate"/>
</tree>
</field>
</record>
for your selection field you have to write like this:
you have missed string in selection fields
rate':fields.selection([(10,'10'),
(20,'20'),
(30,'30')],'Rate'),
hope this help