Дополнительная скидка не отображается в строке счета - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть похожие вопросы из моего предыдущего вопроса, связанные с этим, но в другом формате. Как сделать дополнительное поле скидок в строке счета. Кажется, это не отражается после установки модуля настройки. Единственное, что было отражено в строке заказа на продажу, но в счете, это не отражало это.

Это мой account.py

from odoo import api, fields, models
from odoo.addons.base.models import decimal_precision as dp

class AccountInvoice(models.Model):
    _inherit = "account.move"

    def get_taxes_values(self):
        vals = {}
        for line in self.invoice_line_ids:
            vals[line] = {
                'price_unit': line.price_unit,
                'discount': line.discount,
                'add_discount': line.discount,
            }
            price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
            price_unit *= (1 - (line.add_discount or 0.0) / 100.0)
            line.update({
                'price_unit': price_unit,
                'discount': 0.0,
                'add_discount': 0.0,
            })
        tax_grouped = super(AccountInvoice, self).get_taxes_values()
        for line in self.invoice_line_ids:
            line.update(vals[line])
        return tax_grouped


class AccountInvoiceLine(models.Model):
    _inherit = "account.move.line"

    add_discount = fields.Float('Add. Disc. (%)', digits=dp.get_precision('Discount'))

    @api.depends('add_discount')
    def _compute_price(self):
        for line in self:
            prev_price_unit = line.price_unit
            prev_discount = line.discount
            prev_add_discount = line.add_discount
            price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
            price_unit *= (1 - (line.add_discount or 0.0) / 100.0)
            line.update({
                'price_unit': price_unit,
                'discount': 0.0,
                'add_discount': 0.0,
            })
            super(AccountInvoiceLine, line)._compute_price()
            line.update({
                'price_unit': prev_price_unit,
                'discount': prev_discount,
                'add_discount': prev_add_discount,
            })

Это мой discount.py:

 from odoo import models, fields, api
    from functools import partial
    from odoo.tools.misc import formatLang


    class Discount(models.Model):
        _inherit = 'sale.order.line'

        def _compute_amount_undiscounted(self):
            for order in self:
                total = 0.0
                for line in order.order_line:
                    total += line.price_subtotal + line.price_unit * ((line.discount or 0.0) / 100.0) * (
                            (line.add_discount or 0.0) / 100.0) * line.product_uom_qty
                order.amount_undiscounted = total

        def _amount_by_group(self):
            for order in self:
                currency = order.currency_id or order.company_id.currency_id
                fmt = partial(formatLang, self.with_context(lang=order.partner_id.lang).env, currency_obj=currency)
                res = {}
                for line in order.order_line:
                    price_reduce = line.price_unit * (1.0 - line.discount / 100.0) * (1.0 - line.add_discount / 100.0)
                    taxes = line.tax_id.compute_all(price_reduce, quantity=line.product_uom_qty, product=line.product_id,
                                                    partner=order.partner_shipping_id)['taxes']
                    for tax in line.tax_id:
                        group = tax.tax_group_id
                        res.setdefault(group, {'amount': 0.0, 'base': 0.0})
                        for t in taxes:
                            if t['id'] == tax.id or t['id'] in tax.children_tax_ids.ids:
                                res[group]['amount'] += t['amount']
                                res[group]['base'] += t['base']
                res = sorted(res.items(), key=lambda l: l[0].sequence)
                order.amount_by_group = [(
                    l[0].name, l[1]['amount'], l[1]['base'],
                    fmt(l[1]['amount']), fmt(l[1]['base']),
                    len(res),
                ) for l in res]

        @api.depends('product_uom_qty', 'discount', 'add_discount', 'price_unit', 'tax_id')
        def _compute_amount(self):
            """
            Compute the amounts of the SO line.
            """
            for line in self:
                price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) * (1 - (line.add_discount or 0.0) / 100.0)
                taxes = line.tax_id.compute_all(price, line.order_id.currency_id, line.product_uom_qty,
                                                product=line.product_id,
                                                partner=line.order_id.partner_shipping_id)
                line.update({
                    'price_tax': sum(t.get('amount', 0.0) for t in taxes.get('taxes', [])),
                    'price_total': taxes['total_included'],
                    'price_subtotal': taxes['total_excluded'],
                })

        @api.depends('price_unit', 'discount', 'add_discount')
        def _get_price_reduce(self):
            for line in self:
                line.price_reduce = line.price_unit * (1.0 - line.discount / 100.0) * (1.0 - line.add_discount / 100.0)

        def _prepare_invoice_line(self):
            """
            Prepare the dict of values to create the new invoice line for a sales order line.

            :param qty: float quantity to invoice
            """
            self.ensure_one()
            res = {
                'display_type': self.display_type,
                'sequence': self.sequence,
                'name': self.name,
                'product_id': self.product_id.id,
                'product_uom_id': self.product_uom.id,
                'quantity': self.qty_to_invoice,
                'discount': self.discount,
                'add_discount': self.add_discount,
                'price_unit': self.price_unit,
                'tax_ids': [(6, 0, self.tax_id.ids)],
                'analytic_account_id': self.order_id.analytic_account_id.id,
                'analytic_tag_ids': [(6, 0, self.analytic_tag_ids.ids)],
                'sale_line_ids': [(4, self.id)],
            }
            if self.display_type:
                res['account_id'] = False
            return res

        @api.onchange('product_id', 'price_unit', 'product_uom', 'product_uom_qty', 'tax_id')
        def _onchange_discount(self):
            if not (self.product_id and self.product_uom and
                    self.order_id.partner_id and self.order_id.pricelist_id and
                    self.order_id.pricelist_id.discount_policy == 'without_discount' and
                    self.env.user.has_group('product.group_discount_per_so_line')):
                return

            self.discount = 0.0
            self.add_discount = 0.0
            product = self.product_id.with_context(
                lang=self.order_id.partner_id.lang,
                partner=self.order_id.partner_id,
                quantity=self.product_uom_qty,
                date=self.order_id.date_order,
                pricelist=self.order_id.pricelist_id.id,
                uom=self.product_uom.id,
                fiscal_position=self.env.context.get('fiscal_position')
            )

            product_context = dict(self.env.context, partner_id=self.order_id.partner_id.id, date=self.order_id.date_order,
                                   uom=self.product_uom.id)

            price, rule_id = self.order_id.pricelist_id.with_context(product_context).get_product_price_rule(
                self.product_id, self.product_uom_qty or 1.0, self.order_id.partner_id)
            new_list_price, currency = self.with_context(product_context)._get_real_price_currency(product, rule_id,
                                                                                                   self.product_uom_qty,
                                                                                                   self.product_uom,
                                                                                                   self.order_id.pricelist_id.id)

            if new_list_price != 0:
                if self.order_id.pricelist_id.currency_id != currency:
                    # we need new_list_price in the same currency as price, which is in the SO's pricelist's currency
                    new_list_price = currency._convert(
                        new_list_price, self.order_id.pricelist_id.currency_id,
                        self.order_id.company_id or self.env.company, self.order_id.date_order or fields.Date.today())
                discount = (new_list_price - price) / new_list_price * 100
                if (discount > 0 and new_list_price > 0) or (discount < 0 and new_list_price < 0):
                    self.discount = discount

                add_discount = (new_list_price - price) / new_list_price * 100
                if (add_discount > 0 and new_list_price > 0) or (add_discount < 0 and new_list_price < 0):
                    self.add_discount = add_discount

        add_discount = fields.Float(string='Add. Disc (%)', digits='Discount', default=0.0)

Xml:

<odoo>
    <record id="discount_view" model="ir.ui.view">
        <field name="name">Additional Discount</field>
        <field name="model">account.move</field>
        <field name="inherit_id" ref="account.view_move_form"/>
        <field name="arch" type="xml">
            <xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='discount']" position="after">
                <field name="add_discount" string="Add. Disc.%" groups="base.group_no_one" optional="show"/>
            </xpath>
            <xpath expr="//field[@name='invoice_line_ids']/form/sheet/group[1]/field[@name='discount']" position="after">
                <field name="add_discount" string="Add. Disc.%" groups="base.group_no_one" optional="show"/>
            </xpath>
            <xpath expr="//field[@name='line_ids']/tree/field[@name='discount']" position="after">
                <field name="add_discount" invisible="1"/>
            </xpath>
        </field>
    </record>

</odoo>
...