How to add on_change in default field odoo 8 - odoo

i want to add onchange function in module manufacturing (mrp.production)
in view.xml
<record model="ir.ui.view" id="partner_instructur_form_view">
<field name="name">mrp.production.form.instructur</field>
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_form_view" />
<field name="arch" type="xml">
<xpath expr="//field[#name='location_dest_id']" position="after">
<field name="product_qty" on_change="onchange_hitung_kuota(product_qty, prod_qtys)"/>
<field name="prod_qtys" on_change="onchange_hitung_kuota(product_qty, prod_qtys)"/>
<field name="progres_persen" widget="progressbar"/>
</xpath>
</field>
</record>
in python
class ala_mrp_prod(osv.osv):
_inherit = 'mrp.production'
def onchange_hitung_kuota(self, cr, uid, ids, prod_qtys, product_qty):
kurangi = product_qty - prod_qtys
res = {
'value':{ 'progres_persen': (kurangi * 100) / product_qty}
}
return res
_columns = {
'prod_qtys':fields.integer('Jumlah Total'),
'progres_persen': fields.float('Progres'),
}
_defaults = {
'prod_qtys': 1,
}
ala_mrp_prod()
why product quantity show 2?
so if i input product_quantity 3 , jumlah total 5 progres 40%?
please help

You passed parameters in the wrong order.
product_qty should be the first in onchange_hitung_kuota() method:
def onchange_hitung_kuota(self, cr, uid, ids, product_qty, prod_qtys)

In odoo new api you do not need to modify the xml file. what you have to do is
class mrp_order(models.Model)
_inherit = 'mrp.production'
#api.onchange('product_qty', 'prod_qtys')
def onchange_hitung_kuota(self):
kurangi = product_qty - prod_qtys
self.progres_persen = (kurangi * 100) / self.product_qty
hope this helps!

I think you inverted the two parameters inside the onchange_hitung_kuota function

Related

Odoo. Tree/form display field data

I have some problem with tree/form view in Odoo.
My model have such classes: https://yadi.sk/d/sCLVo3gHtbVEu
class URLList(models.Model):
_name = 'webvisitorcalc.url_list'
url = fields.Char(string="URL", required=True)
url_parametes = fields.Char(string="URL parameters") #пераметры URLб всё что идёт после ?
target_session_id = fields.One2many('webvisitorcalc.session_visitor', 'target_url_ids', string='Target URL')
site_trip_prevouse_id = fields.One2many('webvisitorcalc.site_trip', 'url_prevouse_ids', string='Prevouse URL')
site_trip_current_id = fields.One2many('webvisitorcalc.site_trip', 'url_current_ids', string='Current URL')
remote_sites_id = fields.One2many('webvisitorcalc.remote_sites', 'site_url_ids', string='Remote site page with URL')
remote_sites_target_url_id = fields.One2many('webvisitorcalc.remote_sites', 'target_url_ids', string='URL on remote site page')
#api.multi
def url_exist(self, cr, SUPERUSER_ID, urlForCheck):
_logger.error("Check URL exist in DB ")
result = False
if (self.search_count(cr, SUPERUSER_ID, [('url', '=', urlForCheck)])>0):
result = True
return result
class SiteTrip(models.Model):
_name = 'webvisitorcalc.site_trip'
session_ids = fields.Many2one('webvisitorcalc.session_visitor', string='Session ID', index=True)
url_prevouse_ids = fields.Many2one('webvisitorcalc.url_list', string='Prevouse URL', index=True)
url_current_ids = fields.Many2one('webvisitorcalc.url_list', string='Current URL', index=True)
Template for this model: https://yadi.sk/d/Ob0o65PutbVFA
<record model="ir.actions.act_window" id="site_trip_list_action">
<field name="name">Site trip</field>
<field name="res_model">webvisitorcalc.site_trip</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create the first record for site trip
</p>
</field>
</record>
<record model="ir.actions.act_window" id="url_list_list_action">
<field name="name">URL list</field>
<field name="res_model">webvisitorcalc.url_list</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create the first url
</p>
</field>
</record>
<record model="ir.ui.view" id="site_trip_tree_view">
<field name="name">site_trip.tree</field>
<field name="model">webvisitorcalc.site_trip</field>
<field name="arch" type="xml">
<tree string="URL list tree">
<field name="session_ids"/>
<field name="url_prevouse_ids" string="PrevURL">
</field>
<!--<field name="url_prevouse_ids"/>-->
<field name="url_current_ids"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="url_list_tree_view">
<field name="name">url_list.tree</field>
<field name="model">webvisitorcalc.url_list</field>
<field name="arch" type="xml">
<tree string="URL list tree">
<field name="url"/>
<field name="url_parametes"/>
</tree>
</field>
</record>
<menuitem id="site_trip_menu" name="Site trip" parent="webvisitorcalc_menu"
action="site_trip_list_action"/>
<menuitem id="url_list_menu" name="URL list" parent="webvisitorcalc_menu"
action="url_list_list_action"/>
Screenshots are here:
Tree view for class SiteTrip
http://i.stack.imgur.com/FjRDK.png
Form view for class SiteTrip
http://i.stack.imgur.com/uDbOp.png
Tree view for class URLList
http://i.stack.imgur.com/tXzqL.png
Form view for class URLList
http://i.stack.imgur.com/oVnqg.png
As you see URLList displayed fine. For class SiteTrip present problem. Field is displaying not data from URLList. This is field stored element such webvisitorcalc.url_list.ID (array?). How I can display real data in this field (for example URL: http://some-site.com/page.html)?
URL in URLList must be uniq. SiteTrip must have stored only ID of URLList record.
UPD:
class RemoteSites(models.Model):
_name = 'webvisitorcalc.remote_sites'
site_id = advert_company_id = fields.One2many('webvisitorcalc.site_list', 'remote_sites_ids', string='Site')
site_url_ids = fields.Many2one('webvisitorcalc.url_list', string='URL page ')
target_url_ids = fields.Many2one('webvisitorcalc.url_list', string='URL target page')
You obviously have no name field on your webvisitorcalc.url_list model. Odoo needs this to use it as name in webclient wherever you use this model as e.g. many2one field or in the breadcrumb navigation.
So either you define a name field or you set _name on your class with another field identifier.
You can also (re-)define the method display_name on your model (enough examples in Odoo code) where you can do more cool stuff with the record display name :-)

How to update automatically other fields when quantity on hand get increase or decrease odoo?

I need to update automatically this field(qty_available_onhand) either when quantity on hand get increase or decrease below i have mentioned my code.
Current below code working perfectly but only when i fill this field(squ_meter) as i'm entering in this field get multiplied to field(qty_avl) which is qty_avl is nothing but it is actually quantity on hand.
Any answer would be much appreciated
class product_template(osv.osv):
_name = "product.template"
_inherit = "product.template"
_columns = {
'squ_meter':fields.float('Square Meter'),
'qty_available_onhand': fields.float(
'Qty Sqm Available',
compute='_compute_qty_available_onhand',
require = True
),
'qty_avl':fields.related(
'virtual_available',
relation='product.product',
string='Quantity on Hand'
),
}
#api.depends('qty_avl', 'squ_meter')
def _compute_qty_available_onhand(self):
for record in self:
record.qty_available_onhand = record.qty_avl * record.squ_meter
view.xml
<field name="name">product.product.inherited</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="//field[#name='active']" position="after">
<field name="qty_available_onhand"/>
<field name="qty_avl" invisible='1'/>
<field name="squ_meter"/>
</xpath>

How to store default entered value in custom field of quantity on Hand.?

Need to store default value on qty in M.sqr and square meter like quantity on hand showing default entered value.
when i click on update button of quantity on Hand from product inventory page
then it should show me a previous entered value.
class stock_change_product_qty(osv.osv):
_inherit = 'stock.change.product.qty'
_columns = {
'new_quantity' : fields.float('Qty in Boxes'),
'squ_meter': fields.related('product_id','squ_meter', type='float', relation='product.product', string='Square Meter'),
'qty_char': fields.float('Qty in M.sqr', compute='_compute_qty_char'),
}
#api.depends('new_quantity', 'squ_meter')
def _compute_qty_char(self):
for record in self:
record.qty_char = record.new_quantity * record.squ_meter
view.xml
<field name="name">update_product_quantity inherit</field>
<field name="model">stock.change.product.qty</field>
<field name="inherit_id" ref="stock.view_change_product_quantity"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='new_quantity']" position="attributes">
<attribute name="string">Qty in Boxes</attribute>
</xpath>
<xpath expr="//field[#name='new_quantity']" position="replace">
<field name="new_quantity"/>
<field name="squ_meter"/>
<field name="qty_char"/>
</xpath>
</field>
</record>
A solution is to use a function as default value for your field:
odoo V8
from openerp import api, fields, models
class stock_change_product_qty(models.Model):
_inherit = 'stock.change.product.qty'
new_quantity = fields.Float(string='Qty in Boxes', default=1.0),
squ_meter = fields.Float(related='product_id.squ_meter', string='Square Meter', default=1.0),
qty_char = fields.Float('Qty in M.sqr', compute='_compute_qty_char'),
}
#api.one
#api.depends('new_quantity', 'squ_meter')
def _compute_qty_char(self):
for record in self:
record.qty_char = record.new_quantity * record.squ_meter
odoo V7
def _your_function(self, cr, uid, context=None):
your code here
...
...
...
return field_value
_defaults = {
'your_field' : _your_function,
}
#api.onchange
This decorator will trigger the call to the decorated function if any of the fields specified in the decorator is changed in the form:
#api.onchange('fieldx')
def do_stuff(self):
if self.fieldx == x:
self.fieldy = 'toto'
In previous sample self corresponds to the record currently edited on the form. When in on_change context all work is done in the cache. So you can alter RecordSet inside your function without being worried about altering database. That’s the main difference with #api.depends
At function return, differences between the cache and the RecordSet will be returned to the form.

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.

OpenERP - Show child_ids invoices of a partner

I'd like to show invoices adressed to child partner in the parent partner form view.
I've already a inherited res_partner model as follow :
class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'invoice_ids': fields.one2many('account.invoice', 'partner_id', 'Invoices'),
}
And a view displaying invoices as follow :
<?xml version="1.0"?>
<openerp>
<data>
<!-- Partners inherited form -->
<record id="view_history_partner_info_form" model="ir.ui.view">
<field name="name">res.partner.cap_history.form.inherit</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="model">res.partner</field>
<field name="arch" type="xml">
<page string="Accounting" position="after" version="7.0">
<page string="History" name="cap_history_tab">
<group name="grp_invoice_history" string="Invoices History">
<field name="invoice_ids" colspan="4" nolabel="1">
<tree string="Partner Invoices" create="false" delete="false">
<field name="number" readonly="True"/>
<field name="origin" readonly="True"/>
<field name="name" string="Reference" readonly="True"/>
<field name="date_invoice" readonly="True"/>
<field name="x_category" readonly="True"/>
<field name="state" readonly="True"/>
<field name="payment_term" readonly="True"/>
<field name="amount_total" readonly="True"/>
</tree>
</field>
</group>
</page>
</page>
</field>
</record>
With this code I can see invoices that are directly adressed to a company or a person on their respective form view.
But if an invoice is adressed to person, and none is adressed to the parent company, when I am on the company form view, I won't see the invoice adressed to the child contact.
Is there a way to make visible the contact's invoice in the parent partner form view ?
Thank you for your help !
Cheers
One way to do this is to add a new field, all_invoice_ids, as a function field, and then have the function return both the contents of invoice_ids, plus the contents of any child's invoice_ids.
Something like this (untested):
'all_invoice_ids': fields.function(
_get_invoice_ids,
type='one2many',
obj='account.invoice',
method=True,
string='Invoices',
),
and _get_invoice_ids (which should be defined before columns) like this (also untested):
def _get_invoice_ids(self, cr, uid, ids, field_name, arg, context=None):
res = {}
if isinstance(ids, (int, long)):
ids = [ids] # in case an id was passed in directly
for main_partner in self.browse(cr, uid, ids, context=context):
main_invoices = main_partner.invoice_ids or [] # in case it was False
invoices = [inv.id for inv in main_invoices]
for child_partner in main_partner.child_ids:
child_invoices = child_partner.invoice_ids or []
invoices.extend([inv.id for inv in child_invoices])
# at this point we should have all the invoice ids
# use a set to get rid of duplicates
invoices = list(set(invoices))
# and store in res to be returned
res[main_partner.id] = invoices
return res