У меня есть похожие вопросы из моего предыдущего вопроса, связанные с этим, но в другом формате. Как сделать дополнительное поле скидок в строке счета. Кажется, это не отражается после установки модуля настройки. Единственное, что было отражено в строке заказа на продажу, но в счете, это не отражало это.
Это мой 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>