How can i use onchange function to change price of account invoice line price_unit - odoo

I would like to use onchange to set account invoice price to a default price set in res.partner. Could anyone give me an example of this ?
Thanks,
Joe

There are lots of examples of onchange in addons.
For example, if you want to change the value of 'name' field and want to set product's name based on selected product:
def onchange_product_id(self, cr, uid, ids, product_id, context=None):
if product_id:
prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
return {'value': {'name': prod.name}}
return {}

Write this in your_invoice_view.xml:
<field name="product_id" on_change="product_id_change(product_id, parent.partner_id, context)"/>
Write onchange in your_invoice.py under "invoice_line" model(class):
def onchange_product_id_change(self, cr, uid, ids, product_id, partner_id context=None):
if product_id and partner_id:
product_brw = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
partner_brw = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
/*write your logic */
return {'value': {'price_unit': your calculated value}}
return {}

Related

Odoo validate invoice from code

I creating an invoice from another model, and want to get validated not draft
But internal number and total are not generated with my code.
invoice_id = self.pool.get('account.invoice').create(cr, uid,{
'partner_id':self.supplier.id,
'name' : 'Faltante mercaderia',
'journal_id': journal_id,
'account_id':account_id,
'type': 'in_refund',
})
self.pool.get('account.invoice.line').create(cr, uid,{
'invoice_id' : invoice_id,
'name' : 'Faltante mercaderia %s: %s' %(self.type,self.number),
'quantity' : self.dif_final,
'price_unit':self.tarifa_dif / 1000,
})
a = self.env['account.invoice'].browse([invoice_id])
a.invoice_validate()
I also try adding a.action_number()
This code should work for you:
inv_obj = self.pool.get('account.invoice')
inv_obj.button_compute(cr, uid, [invoice_id], context=context, set_total=True)
inv_obj.action_date_assign(cr, uid, invoice_id, context=context)
inv_obj.action_move_create(cr, uid, invoice_id, context=context)
inv_obj.action_number(cr, uid, invoice_id, context=context)
inv_obj.invoice_validate(cr, uid, invoice_id, context=context)
You can check by calling all above methods and let me know.
validate button sends a signal to a workflow, you just need to send the same signal:
a.signal_workflow('invoice_open')

Get the value of one selection field

How I affect the value of a field section to a field char.
return { value{'field_char' : field_selection.value !!!}}
If you need to affect it as in onchange event, you just set a parameter to your function with the value you whant of the selection:
<field name="field_selection" onchange="do_change(field_selection)" />
and then, in your function get the parameter, and affect it to your field_char:
def do_change(self, cr, uid, ids, selection_val, context=None):
return {
value{
'field_char' : selection_val
}
}
related to
field1: fields.selection([('a','A')], 'Field1'),
field2: fields.char('Field2'),
just try to
fields2 = fields['a']
only pass key it's return value of key
Override create and write method for that,
def create(self, cr, uid, vals, context={}):
if not vals.get('field_selection',False):
vals.update('field_char') = vals.get('field_selection','')
return super(class_name,self).create(cr, uid, vals, context=context)
def write(self, cr, uid, ids, vals, context={}):
if not vals.get('field_selection',False):
vals.update('field_char') = vals.get('field_selection','')
return super(class_name,self).write(cr, uid, ids, vals, context=context)

openerp override onchange behavior without affecting base

I have inherited from purchase.order.line. I have added a bunch of related fields. They are all related to fields in product.product via product_id in order_line.
What I want to achieve is that when a user selects or changes a product in the purchase order line form, the related fields should get refreshed/updated/populated with values of the selected product.
I have written the onchange method for this but I'm not sure how to invoke it from the inherited view? The product_id field was already there in the (parent) order_line view and it already has an onchange defined. How do I get the system to use my onchange as well?
I don't want to disturb the onchange_productid method that is already there in purchase.order.line. So either before my onchange or after it, it should continue with its standard functioning.
Thanks
EDIT: latest version (getting errors when any of the related many2one or selection fields has a value).
class purchase_order_line_custom(osv.osv):
_name = 'purchase.order.line'
_inherit = 'purchase.order.line'
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit, context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'qualified_name':product.qualified_name,
'product_type' : product.product_type or None,
'product_subtype' : product.product_subtype,
'count_id':product.count_id or None
})
return values
_columns={
'product_type': fields.related('product_id','product_type',type='selection', string='Product Type', selection=[('X','X'),('Y','Y'),('Z','Z')]),
'product_subtype': fields.related('product_id','product_subtype',type='char', size=64, string='Sub-Type'),
'qualified_name': fields.related('product_id','qualified_name',type='char', size=64, string='Qualified Name'),
'count_id': fields.related('product_id','count_id',type='many2one',relation='product.mycount',string='Count')
}
purchase_order_line_custom()
you need to overide the onchange function(you can use super() ) for the field 'product_id' and update the result.
for example
def onchange_product(self,cr,uid,ids,product_id,context=None):
values = super(<your_class_name>,self).onchange_product(cr, uid,ids,product_id,context=context)
# values will be a dictionary containing 'value' as a key.
# You need to add all the newly added related fields and other fields to the values['value'].
# if 'aaa' is the newly added field, then values['value'].update({'aaa':<value for aaa>})
# then return values
return values
modify you onchange to the following
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,
partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit, context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'product_type' : product.product_type,
'product_subtype' : product.product_subtype,
'qualified_name' : product.qualified_name,
'count_id' : product.count_id
})
return values
First let's understand why fields.related is used?
fields.related field that points to some data inside another field of the current record.
That means, fields which are related will be filled automatically when you will select the value of other field.
Example:
_columns = {
'product_id': fields.many2one('product.product', 'Product'),
'product_name': fields.related('product_id', 'name', type='char', string='Product Name'),
}
In this example product_name will be filled automatically when you will select the product_id. You don't have to write onchange for that.
You can find many examples for fields.related.

OpenERP fields.related crashing

Followup question from openerp override onchange behavior without affecting base
15244031
The following code does get fired but I get server error 500 when any of the related fields has a value.
When I look at the log, it says JSON serialization issue.
TypeError: browse_record(product.mycount, 1) is not JSON serializable
Please suggest a solution.
class purchase_order_line_custom(osv.osv):
_name = 'purchase.order.line'
_inherit = 'purchase.order.line'
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, context=None):
values = super(purchase_order_line_custom, self).onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order, fiscal_position_id, date_planned,name, price_unit, context=context)
if product_id:
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
values['value'].update({
'qualified_name':product.qualified_name,
'product_type' : product.product_type or None,
'product_subtype' : product.product_subtype,
'count_id':product.count_id or None
})
return values
_columns={
'product_type': fields.related('product_id','product_type',type='selection', string='Product Type', selection=[('X','X'),('Y','Y'),('Z','Z')]),
'product_subtype': fields.related('product_id','product_subtype',type='char', size=64, string='Sub-Type'),
'qualified_name': fields.related('product_id','qualified_name',type='char', size=64, string='Qualified Name'),
'count_id': fields.related('product_id','count_id',type='many2one',relation='product.mycount',string='Count')
}
purchase_order_line_custom()
in the line 'count_id':product.count_id or None, I think count_id is a many2one field in product.you are trying to pass object to the count_id field in product.order.line, you need to pass product.count_id.id to get the id.

Confirm a sale quotation into a sale order with some quantities set to 0

In my custom sale quotation report I want to show some products with a 0 quantity and therefore have created sale order lines for some products with their quantities set to 0. It works fine and shows in the sale quotation report.
But when I confirm that same sale quotation into a sale order OpenERP throws the following message:
"Data Insufficient !
Please check the quantity in procurement order(s), it should not be 0 or less!"
How can I confirm an order with some quantities set to 0?
First you have to inherit the Procurement and then override the action_confirm method in your custom module.
In procurement.py, find "def action_confirm()" on line: 320. Copy and past the whole method and remove those lines which raise the exception.
Hope this will solve your problem.
Thank You.
class procurement_order(osv.osv):
_inherit = 'procurement.order'
def action_confirm(self, cr, uid, ids, context=None):
move_obj = self.pool.get('stock.move')
for procurement in self.browse(cr, uid, ids, context=context):
#if procurement.product_qty <= 0.00:
#raise osv.except_osv(_('Data Insufficient !'),_('Please check the quantity in procurement order(s), it should not be 0 or less!'))
if procurement.product_id.type in ('product', 'consu'):
if not procurement.move_id:
source = procurement.location_id.id
if procurement.procure_method == 'make_to_order':
source = procurement.product_id.product_tmpl_id.property_stock_procurement.id
id = move_obj.create(cr, uid, {
'name': procurement.name,
'location_id': source,
'location_dest_id': procurement.location_id.id,
'product_id': procurement.product_id.id,
'product_qty': procurement.product_qty,
'product_uom': procurement.product_uom.id,
'date_expected': procurement.date_planned,
'state': 'draft',
'company_id': procurement.company_id.id,
'auto_validate': True,
})
move_obj.action_confirm(cr, uid, [id], context=context)
self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move': 1})
self.write(cr, uid, ids, {'state': 'confirmed', 'message': ''})
return True