Adding a field in parent view - odoo

i am having some problems when i try to add a field in the parent view.
The class is:
class VademecumFraccionamiento(models.Model):
_name = 'farmacia.vademecum_fraccionamiento'
_inherits={
'farmacia.vademecum': 'vademecum_id'
}
hijo = fields.Many2one('farmacia.vademecum_fraccionamiento', string="Artículo hijo", index=True)
vademecum_id = fields.Many2one('farmacia.vademecum', string='Artículo Padre', required=True, ondelete='cascade', index=True)
The xml is:
<record model="ir.ui.view" id="farmacia_vademecum_fraccionamiento_form_view">
<field name="name">farmacia_vademecum_fraccionamiento.form</field>
<field name="model">farmacia.vademecum</field>
<field name="inherit_id" ref="farmacia_vademecum.farmacia_vademecum_form_view"/>
<field name="arch" type="xml">
<xpath expr="//page[#string='lalala']" position="after">
<page string="Fracc">
</page>
</xpath>
<xpath expr="//page[#string='Fracc']" position="inside">
<group>
<field name="vademecum_id">
</field>
</group>
</xpath>
</field>
</record>
The error is:
Error details:
The field vademecum_id not exists
I don't know how to solve that.
Thanks in advance

You should refer addons/product/product_view.xml for more help, in which you will get all the answers of your questions related to inheritance.

I would change the code to:
_columns = {
'hijo' : fields.Many2one('farmacia.vademecum_fraccionamiento', string="Artículo hijo", index=True),
'vademecum_id' : fields.Many2one('farmacia.vademecum', string='Artículo Padre', required=True, ondelete='cascade', index=True),
}
This will add the fields to your model

There are two concepts in odoo for field inheritance.
_inherit : can be used in case you want to extend existing model.
Example: adding birth date field in res.partner model
class res_partner(models.Model):
_inherit = 'res.partner'
birth_date = fields.Date('Birthdate')
_inherits : can be used in case you want to adept module field in current model.
Example: Using customer fields in student model,
class Student(models.Model):
_name = 'stundent.student'
_inherits = {'res.partner': partner_id}
partner_id = fields.Many2one('res.partner', 'Partner')
after adding a partner_id field in your model you can use all the fields of partner in xml view of student form & tree.
Hope this helps.

Related

how to use virtual records of one2many field in a many2one field of the same model

In the Sale Order form I added a one2many field named booking_ids which appears within an editable tree view
Within the tree of the order lines, I added a many2one column named booking_id so each orderline have a booking_id.
While in edit mode or create mode of the sale.order how is it possible to show the virtual records added in the booking_ids field within the many2one field which is only showing the records within the database without the virtual ones that are being created.
class SaleOrder(models.Model):
_inherit = 'sale.order'
booking_ids = fields.One2many('sale.booking', 'order_id', string='Bookings')
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
booking_id = fields.Many2one('sale.booking', string="Booking")
class Booking(models.Model):
_name = 'sale.booking'
event_id = fields.Many2one('sale.event', String='Event', required=True,
states={'draft': [('readonly', False)], 'sent': [('readonly', False)]})
name = fields.Char(compute='_get_name')
event_date = fields.Date(string='Event Date')
order_id = fields.Many2one('sale.order', string='Order Reference', ondelete='cascade', index=True, copy=False, readonly=True)
order_line_ids = fields.One2many('sale.order.line', 'booking_id', string='Order Lines')
XML
<xpath expr="//field[#name='payment_term_id']/.." position="after">
<group>
<field name="booking_ids">
<tree editable="bottom">
<field name="event_id"/>
<field name="event_date" string="Date"/>
<field name="order_line_ids" widget="many2many_tags" readonly="1"/>
</tree>
</field>
</group>
</xpath>
<xpath expr="//tree//field[#name='product_id']" position="after">
<field name="order_id" invisible="1"/>
<field name="booking_id" domain="['|', ('order_id', '=', None), ('order_id', '=', order_id)]"/>
</xpath>
<xpath expr="//field[#name='order_line']//field[#name='product_id']/.." position="after">
<field name="order_id" invisible="1"/>
<field name="booking_id" domain="['|', ('order_id', '=', None), ('order_id', '=', order_id)]"/>
</xpath>
thank you
Use a preload in Python code. This will solve your problem.

Why isn't this domain giving me results?

So I'm making this localization kind of module for Lebanon and am currently doing the location bit.
The intended functionality is to have the choices of governate, district and region restrict the choices the user can make by filtering out the irrelevant options.
Here are the models:
# -*- coding: utf-8 -*-
from odoo import models, fields, api
# Base model
class LebaneseLocation(models.Model):
_inherit = "res.partner"
governate_id = fields.Many2one("lebanon.governate", "Governate")
district_id = fields.Many2one("lebanon.district", "District")
region_id = fields.Many2one("lebanon.region", "Region")
# Child models with the necessary relations
class Governate(models.Model):
_name = "lebanon.governate"
name = fields.Char()
child_districts = fields.One2many("lebanon.district", "parent_governate",
"Child Districts")
class District(models.Model):
_name = "lebanon.district"
name = fields.Char()
parent_governate = fields.Many2one("lebanon.governate", "Parent Governate")
child_regions = fields.One2many("lebanon.region", "parent_district",
"Child Regions")
class Region(models.Model):
_name = "lebanon.region"
name = fields.Char()
parent_district = fields.Many2one("lebanon.district", "Parent District")
and the view file:
<?xml version="1.0"?>
<odoo>
<record id="view_res_partner_extended_location" model="ir.ui.view">
<field name="name">Contacts Custom</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="category_id" position="after">
<field name="governate_id" domain="[('child_districts','=?','district_id'),('child_districts.child_regions','=?','region_id')]"/>
<field name="district_id"/>
<field name="region_id"/>
</field>
</field>
</record>
</odoo>
And all the data was inputed via two data files, one makes the records without relations and the other updates the same records with relations.
I was testing things out with the Governate domain and it just kept returning nothing.
Is there some way to check what exactly these parameters i'm evaluating are returning? That would help a lot with debugging.
Edit: Here's a screenshot from Studio's menu for the domain, in case that's at all relevant for debugging (I avoid Studio like a plague usually)
Domain Image
I solved my issue by forgoing the XML approach and setting the domains using the onchange api call:
#api.onchange('governate_id', 'district_id', 'region_id')
def update_domains(self):
governate = self.governate_id.name
district = self.district_id.name
region = self.region_id.name
result = {}
result['domain']={
'governate_id':[('child_districts.name','=?', governate),
('child_districts.child_regions.name', '=?', region)],
'district_id':[('parent_governate.name', '=?', governate),
('child_regions.name', '=?', region)],
'region_id':[('parent_district.name', '=?', district),
('parent_district.parent_governate.name', '=?', governate)]
}
return result

Access inherited field of a model from a view

I'm working on OpenERP7, trying to access a related field located in a parent model of said related model. If someone at this point understand something, you're way smarter than I am, so i will just put the example of what i'm trying to achieve :
My model :
class trench(osv.osv):
_name = 'trench'
_inherit = 'common'
_columns = {
'trench_lines': fields.one2many('trench.line', 'trench_id', 'Trench Lines'),
'trench_depth': fields.one2many('trench.depth', 'trench_id', 'Trench Depth'),
}
trench()
class trench_common(osv.osv):
_name = 'trench.common'
def compute_vals(self, cr, uid, ids, field_name, arg, context):
...
def on_change_values(self, cr, uid, ids, context=None):
...
_columns = {
'trench_id': fields.many2one('trench', 'Trench', ondelete='cascade', required=True),
'length' : fields.function(compute_vals, type='float', string="Length", method=True, store=True),
}
trench_common()
class trench_line(trench_common):
_name = 'trench.line'
_inherit = 'trench.common'
trench_line()
class trench_dig_common(trench_common):
_name = 'trench.dig.common'
_inherit = 'trench.common'
_columns = {
'length' : fields.float('Length', digits=(6,3)),
'height' : fields.float('Height', digits=(6,3)),
'total_m3' : fields.float('Total m3', digits=(6,3)),
'observation' : fields.text('Observation'),
}
trench_dig_common()
class trench_depth(trench_dig_common):
_name = 'trench.depth'
_inherit = 'trench.common'
trench_depth()
My view :
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="trench_form" model="ir.ui.view">
<field name="name">trench.form</field>
<field name="model">trench</field>
<field name="inherit_id" ref="common_form" />
<field name="arch" type="xml">
<group string="Worksite" position="after">
<separator string="Progress" />
<field name="trench_lines">
<tree editable="bottom">
<field name="length"/>
</tree>
</field>
<separator string="Cumulate Length" />
<field name="total_length"/>
<separator string="Trench Particularity" />
<notebook>
<page string="Surdepth">
<field name="trench_depth">
<tree editable="bottom">
<field name="height"/>
</tree>
</field>
</page>
</notebook>
</group>
</field>
</record>
</data>
</openerp>
My error :
except_orm: ('View error', u"Can't find field 'height' in the following view parts composing the view of object model 'qhse.trench':\n * trench.form\n\nEither you wrongly customized this view, or some modules bringing those views are not compatible with your current data model")
2015-05-21 07:56:28,631 13918 ERROR ahak_production openerp.tools.convert: Parse error in trench_view.xml:4:
So, i'm figuring i can't access a field of a model with so many layers, but is there a way to achieve this, and if so, how? I'm trying to make something DRY, but always end up duplicating code with OpenERP.
Thanks for reading.
You need to define your last class as below.
class trench_depth(trench_dig_common):
_name = 'trench.depth'
_inherit = 'trench.dig.common'
trench_depth()
Then after you can access all fields which are available inside "trehch.dig.common" model.

Master-detail relation, variable scope, passing variables, etc in openerp

I'm writing a warehouse management module and I came to the inventory step.
I need to make an inventory every now and then for each warehouse separately and each inventory operation will be kept in the database as a master-detail relation,
ie:
one record for the basic data such as id, date, warehouse_id etc. and
this will be recorded in a table created by (inventory) object.
many records will keep the details of the operation (one record for each material) recording the material id, inventory id, balance, etc. and this will be recorded in the table (inventory_lines).
During the data entry, when the user selects a material, I need to check its current balance and display it in the balance field. In order to do this, I'll need to know the warehouse id because every warehouse shall have separate inventories.
I have many materials stored in many warehouses.
For example: I can have a quantity of 5 pens in warehouse A and 10 pens in warehouse B and 6 pens in warehouse C.
First, I select the warehouse (A or B or C) --- let's say warehouse B
Then I select the material (Pen or notebook or whatever) --- let's say Pen
Now, I want to search the database to find the balance of (Pen) in (Warehouse B)
I can write something like this:
select balance from inventory_lines where material_id=mmmmmm and warehouse_id=wwwwww
So, I need to get the material id (mmmmm) and the warehouse id (wwwww)
And that will be done with each material I choose.
The warehouse id is in the column: inventory_id in the object: inventory
'warehouse_id' : fields.many2one('makhazen.warehouse', 'Warehouse Name',required=True),
The material id is in the column: material_id of the object inventory_line as in the picture in the question
'material_id' : fields.many2one('makhazen.material' ,'Material Name'),
I faced the following problem:
I could use the (on_change) method in the form view on the material_id field and could trigger a method to search for the balance in the database but I needed the warehouse_id which I couldn't get.
The questions are:
- How are this master-detail relationship is handled in openerp? how values are passed between the master table and the details table?
- How can we extend the scope of the warehouse_id so that it can be seen from any method in the module?
- I could change the values of the fields by calling a method and returning the desired values in a dictionary, but how to do the opposite (read them)?
It's very critical matter to me.
Firstly, you don't need the warehouse_id field in the wh_inventory_line class. You can always access it trough the the parent object:
inventory_line = self.pool.get('wh.inventory.line').browse(cr, uid, line_id)
wharehouse_id = inventory_line.inventory_id.warehouse_id.id
Secondly, in your case you can just pass the warehouse_id value as parameter to your onchange method. Something like this:
<field name="material_id"
on_change="onchange_material_id(material_id, warehouse_id)"/>
or, if you follow my first advice and remove the warehouse_id from wh_inventory_line:
<field name="material_id"
on_change="onchange_material_id(material_id, parent.warehouse_id)"/>
EDIT
After testing on OpenERP 6.0 I found some errors in your code. I'm just wondering how did you manage to run it.
First, you missed a quote (\') on the warehouse_id column definition of your wh.inventory model:
_columns = {
'date': fields.datetime('Date'),
'warehouse_id': fields.many2one('wh.warehouse', 'Warehouse Name, required=True),
Second, the fields.char() field definition takes at least size parameter additionally to the supplied Field Name. Again, you missed a quote on the following line:
'notes': fields.char('Notes),
Not an error but something you should consider too - you tagged your question with the openerp-7 tag. In OpenERP v7 inheriting from osv.osv is deprecated. Inherit from osv.Model instead.
If I insist on your errors it's because the solution I proposed to you is working fine on my side. So there must be some little error somewhere that prevents your code for doing what is expected.
Here is my test code. You can try it:
wh.py
# -*- encoding: utf-8 -*-
import netsvc
import pooler
from osv import fields, osv
class wh_warehouse(osv.osv):
_name = 'wh.warehouse'
_columns = {
'name': fields.char('Name', 128),
}
wh_warehouse()
class wh_material(osv.osv):
_name = 'wh.material'
_columns = {
'name': fields.char('Name', 128),
}
wh_material()
class wh_inventory(osv.osv):
_name = 'wh.inventory'
_columns = {
'date': fields.datetime('Date'),
'warehouse_id': fields.many2one('wh.warehouse', 'Warehouse Name', required=True),
'inventory_line_ids': fields.one2many('wh.inventory.line', 'inventory_id', 'Inventory'),
'notes': fields.char('Notes', 512),
'balance_track': fields.boolean('Balance Track'),
}
wh_inventory()
class wh_inventory_line(osv.osv):
_name = 'wh.inventory.line'
_columns = {
'inventory_id': fields.many2one('wh.inventory', 'Inventory'),
'material_id': fields.many2one('wh.material', 'Material'),
'balance': fields.float('Balance'),
'previous_balance': fields.float('Previous Balance'),
'notes': fields.char('Notes', 512),
}
def onchange_material_id(self, cr, uid, ids, material_id, warehouse_id):
return = {'value': {
'notes': 'Selected material {0} and warehouse {1}'.format(material_id, warehouse_id), }
}
wh_inventory_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
wh_view.xml
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_wh_inventory_form" model="ir.ui.view">
<field name="name">wh.inventory.form</field>
<field name="model">wh.inventory</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Warehouse Inventory">
<field name="date"/>
<field name="warehouse_id" widget="selection"/>
<field name="notes"/>
<field name="balance_track"/>
<field colspan="4" name="inventory_line_ids" widget="one2many_list">
<tree string="Details" editable="bottom">
<field name="material_id" widget="selection"
on_change="onchange_material_id(material_id, parent.warehouse_id)"/>
<field name="balance"/>
<field name="previous_balance"/>
<field name="notes"/>
</tree>
</field>
</form>
</field>
</record>
<record id="view_wh_inventory_tree" model="ir.ui.view">
<field name="name">wh.inventory.tree</field>
<field name="model">wh.inventory</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Warehouse Inventory">
<field name="date"/>
<field name="warehouse_id" widget="selection"/>
<field name="notes"/>
<field name="balance_track"/>
</tree>
</field>
</record>
<record id="action_wh_inventory_form" model="ir.actions.act_window">
<field name="name">Warehouse Inventory</field>
<field name="res_model">wh.inventory</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_wh_inventory_tree"/>
</record>
<menuitem
action="action_wh_inventory_form"
id="menu_wh_inventory_form"
parent="account.menu_finance"
/>
<!-- Sample data -->
<record id="warehouse_1" model="wh.warehouse">
<field name="name">Warehouse 1</field>
</record>
<record id="warehouse_2" model="wh.warehouse">
<field name="name">Warehouse 2</field>
</record>
<record id="warehouse_3" model="wh.warehouse">
<field name="name">Warehouse 3</field>
</record>
<record id="material_1" model="wh.material">
<field name="name">Material 1</field>
</record>
<record id="material_2" model="wh.material">
<field name="name">Material 2</field>
</record>
<record id="material_3" model="wh.material">
<field name="name">Material 3</field>
</record>
</data>
</openerp>

Can we add Date range in Group by search filters in Openerp 7.0?

In OpenERP 7 Is it possible to add From and To date in "Group By Filter" ?.. if possible please give me steps how to add in group by filter date range
import time
import netsvc
from osv import fields, osv
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, float_compare
class sale_order(osv.osv):
_inherit = "sale.order"
_columns = {
'order_date_from':fields.function(lambda *a,**k:{}, method=True, type='date',string="Order date from"),
'order_date_to':fields.function(lambda *a,**k:{}, method=True, type='date',string="Order date to"),
}
sale_order()
Here I've given the ex for 'Order Date' in Sale Order module. Try the codes. Hope it will solve ur problem.
<record id="sale_order_period_filter" model="ir.ui.view">
<field name="name">sale.order.period.filter</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="order_date_from" filter_domain="[('date_order','>=',self)]" widget="calendar"/>
<field name="order_date_to" filter_domain="[('date_order','<=',self)]" widget="calendar"/>
</field>
</field>
</record>
You can define group by filter in xml.
<filter string="Month" name="groupbymonth" icon="terp-personal" domain="[]" context="{'group_by':'visitdate'}" />
Domain looks like,
domain="[('visitdate', '>=', time.strftime('%%Y-%%m-%%d 00:00:00')),('visitdate', '<=', time.strftime('%%Y-%%m-%%d 23:59:59'))]"
You need to add domain like given above into the group by filter,
this is the example, you need to change it to your requirement.
I hope this helps you.