Reputation: 115
In a recent project I had to add a custom field to a model. A part of the solution to get it to work right was to overwrite an "@api.onchange('')" function. I only had to add two entries to a dicionary but since this was inside a loop I saw no other solution than to copy the whole function and modify it.
The function I had to modify is part of sale.order and was previously modified by website_quote.
This is the function I had to modify:
@api.onchange('template_id')
def onchange_template_id(self):
if not self.template_id:
return
template = self.template_id.with_context(lang=self.partner_id.lang)
order_lines = [(5, 0, 0)]
for line in template.quote_line:
discount = 0
if self.pricelist_id:
price = self.pricelist_id.with_context(uom=line.product_uom_id.id).get_product_price(line.product_id, line.product_uom_qty, False)
if self.pricelist_id.discount_policy == 'without_discount' and line.price_unit:
discount = (line.price_unit - price) / line.price_unit * 100
# negative discounts (= surcharge) are included in the display price
if discount < 0:
discount = 0
else:
price = line.price_unit
else:
price = line.price_unit
data = {
'name': line.name,
'price_unit': price,
'discount': 100 - ((100 - discount) * (100 - line.discount)/100),
'product_uom_qty': line.product_uom_qty,
'product_id': line.product_id.id,
'layout_category_id': line.layout_category_id,
'product_uom': line.product_uom_id.id,
'website_description': line.website_description,
'state': 'draft',
'customer_lead': self._get_customer_lead(line.product_id.product_tmpl_id),
}
if self.pricelist_id:
data.update(self.env['sale.order.line']._get_purchase_price(self.pricelist_id, line.product_id, line.product_uom_id, fields.Date.context_today(self)))
order_lines.append((0, 0, data))
self.order_line = order_lines
self.order_line._compute_tax_id()
option_lines = [(5, 0, 0)]
for option in template.options:
if self.pricelist_id:
price = self.pricelist_id.with_context(uom=option.uom_id.id).get_product_price(option.product_id, 1, False)
else:
price = option.price_unit
data = {
'product_id': option.product_id.id,
'layout_category_id': option.layout_category_id,
'name': option.name,
'quantity': option.quantity,
'uom_id': option.uom_id.id,
'price_unit': price,
'discount': option.discount,
'website_description': option.website_description,
}
option_lines.append((0, 0, data))
self.options = option_lines
if template.number_of_days > 0:
self.validity_date = fields.Date.to_string(datetime.now() + timedelta(template.number_of_days))
self.website_description = template.website_description
self.require_payment = template.require_payment
if template.note:
self.note = template.note
This method is responsible for showing the values of a sale template if you choose a template to create a sale order.
I only had to add the name of my custom fields to the data dictionaries to get the correct result.
But it seems to me, that I attacked this problem with brute force by copying the whole function. Is there no better way to insert my changes in functions like this?
Upvotes: 1
Views: 73
Reputation: 26
Short answer: No, there are not better ways.
Long answer: If you have parts of code that are prone to changes, they should be separated from the rest of the functions body.
So if you'll make a lot of changes in the future try to rewrite that function, so it'll take the data
variabe from the outside.
Upvotes: 1