Mangocherry
Mangocherry

Reputation: 115

Are there better ways than overwriting a whole function?

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

Answers (1)

joncek
joncek

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

Related Questions