Skip to content

Commit

Permalink
[IMP] account_global_discount: add fixed discount support
Browse files Browse the repository at this point in the history
  • Loading branch information
primes2h committed Feb 12, 2024
1 parent 3c60994 commit f9aee31
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 15 deletions.
5 changes: 4 additions & 1 deletion account_global_discount/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Account Global Discount
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4999219d4f99b734512a691ec20ccfe819f85c7d08d92a5d894d051d5f0a5fd5
!! source digest: sha256:67f29e2f1d4c9dd6ef7dfaa58d84e53a86abb545b581d5e7c5c042a37190552b
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down Expand Up @@ -114,6 +114,9 @@ Contributors
* `TAKOBI <https://takobi.online>`_:

* Simone Rubino <[email protected]>
* `Pordenone Linux User Group APS <https://www.pnlug.it>`_:

* Sergio Zanchetta

Maintainers
~~~~~~~~~~~
Expand Down
56 changes: 46 additions & 10 deletions account_global_discount/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Copyright 2020-2021 Tecnativa - Pedro M. Baeza
# Copyright 2021 Tecnativa - Víctor Martínez
# Copyright 2022 Simone Rubino - TAKOBI
# Copyright 2024 Sergio Zanchetta - PNLUG APS
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, exceptions, fields, models
from odoo.fields import first
Expand Down Expand Up @@ -41,7 +42,15 @@ class AccountMove(models.Model):
("total", "Total"),
],
string="Discount Base",
compute="_compute_global_discount_base",
compute="_compute_global_discount_selection",
)
global_discount_type = fields.Selection(
selection=[
("percentage", "Percentage"),
("fixed", "Fixed"),
],
string="Discount Type",
compute="_compute_global_discount_selection",
)
amount_global_discount = fields.Monetary(
string="Total Global Discounts",
Expand Down Expand Up @@ -74,12 +83,13 @@ class AccountMove(models.Model):
)

@api.depends("global_discount_ids")
def _compute_global_discount_base(self):
def _compute_global_discount_selection(self):
for invoice in self:
# Only check first because sanity checks
# assure all global discounts in same invoice have same base
first_global_discount = first(invoice.global_discount_ids)
invoice.global_discount_base = first_global_discount.discount_base
invoice.global_discount_type = first_global_discount.discount_type

def _recompute_tax_lines(
self, recompute_tax_base_amount=False, tax_rep_lines_to_recompute=None
Expand Down Expand Up @@ -121,9 +131,10 @@ def _update_tax_lines_for_global_discount(self):
amount = tax_line.balance
for discount in self.global_discount_ids:
base = discount._get_global_discount_vals(base)["base_discounted"]
amount = discount._get_global_discount_vals(amount)[
"base_discounted"
]
if discount.discount_type == "percentage":
amount = discount._get_global_discount_vals(amount)[
"base_discounted"
]
tax_line.tax_base_amount = round_curr(base)
tax_line.debit = amount > 0.0 and amount or 0.0
tax_line.credit = amount < 0.0 and -amount or 0.0
Expand All @@ -141,7 +152,9 @@ def _prepare_global_discount_vals(self, global_discount, base, tax_ids=None):
"name": global_discount.display_name,
"invoice_id": self.id,
"global_discount_id": global_discount.id,
"discount_type": global_discount.discount_type,
"discount": global_discount.discount,
"discount_fixed": global_discount.discount_fixed,
"base": base,
"base_discounted": discount["base_discounted"],
"account_id": global_discount.account_id.id,
Expand Down Expand Up @@ -234,7 +247,9 @@ def _recompute_global_discount_lines(self):
in_draft_mode = self != self._origin
model = "account.move.line"
create_method = in_draft_mode and self.env[model].new or self.env[model].create
for discount in self.invoice_global_discount_ids.filtered("discount"):
for discount in self.invoice_global_discount_ids.filtered(
lambda x: x.discount or x.discount_fixed
):
sign = -1 if self.move_type in {"in_invoice", "out_refund"} else 1
disc_amount = sign * discount.discount_amount
create_method(
Expand Down Expand Up @@ -355,6 +370,7 @@ def create(self, vals_list):
def _check_balanced(self):
"""Add the check of proper taxes for global discounts."""
super()._check_balanced()

test_condition = not config["test_enable"] or self.env.context.get(
"test_account_global_discount"
)
Expand Down Expand Up @@ -417,7 +433,20 @@ class AccountInvoiceGlobalDiscount(models.Model):
comodel_name="global.discount",
string="Global Discount",
)
discount = fields.Float(string="Discount (number)")
discount_type = fields.Selection(
selection=[
("percentage", "Percentage"),
("fixed", "Fixed"),
],
string="Discount Type",
)
discount = fields.Float(
string="Discount (number)",
)
discount_fixed = fields.Float(
string="Discount (number)",
currency_field="currency_id",
)
discount_display = fields.Char(
compute="_compute_discount_display",
string="Discount",
Expand All @@ -426,7 +455,7 @@ class AccountInvoiceGlobalDiscount(models.Model):
base_discounted = fields.Float(string="Base after discount", digits="Product Price")
currency_id = fields.Many2one(related="invoice_id.currency_id", readonly=True)
discount_amount = fields.Monetary(
string="Discounted Amount",
string="Discount Amount",
compute="_compute_discount_amount",
currency_field="currency_id",
compute_sudo=True,
Expand All @@ -446,9 +475,16 @@ class AccountInvoiceGlobalDiscount(models.Model):

def _compute_discount_display(self):
"""Given a discount type, we need to render a different symbol"""

for one in self:
precision = self.env["decimal.precision"].precision_get("Discount")
one.discount_display = "{0:.{1}f}%".format(one.discount * -1, precision)
if one.discount_type == "percentage":
precision = self.env["decimal.precision"].precision_get("Discount")
one.discount_display = "{0:.{1}f}%".format(one.discount * -1, precision)
elif one.discount_type == "fixed":
precision = self.env["decimal.precision"].precision_get("Product Price")
one.discount_display = "{0:.{1}f}".format(
one.discount_fixed * -1, precision
)

@api.depends("base", "base_discounted")
def _compute_discount_amount(self):
Expand Down
3 changes: 3 additions & 0 deletions account_global_discount/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
* `TAKOBI <https://takobi.online>`_:

* Simone Rubino <[email protected]>
* `Pordenone Linux User Group APS <https://www.pnlug.it>`_:

* Sergio Zanchetta
6 changes: 5 additions & 1 deletion account_global_discount/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ <h1 class="title">Account Global Discount</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4999219d4f99b734512a691ec20ccfe819f85c7d08d92a5d894d051d5f0a5fd5
!! source digest: sha256:67f29e2f1d4c9dd6ef7dfaa58d84e53a86abb545b581d5e7c5c042a37190552b
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-invoicing/tree/14.0/account_global_discount"><img alt="OCA/account-invoicing" src="https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-invoicing-14-0/account-invoicing-14-0-account_global_discount"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-invoicing&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Apply global discounts to invoices</p>
Expand Down Expand Up @@ -466,6 +466,10 @@ <h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<li>Simone Rubino &lt;<a class="reference external" href="mailto:sir&#64;takobi.online">sir&#64;takobi.online</a>&gt;</li>
</ul>
</li>
<li><a class="reference external" href="https://www.pnlug.it">Pordenone Linux User Group APS</a>:<ul>
<li>Sergio Zanchetta</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down
49 changes: 49 additions & 0 deletions account_global_discount/tests/test_global_discount.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ def setUpClass(cls):
"account_id": cls.account.id,
}
)
cls.global_discount_fixed_total = cls.global_discount_obj.create(
{
"name": "Test Total Fixed Discount",
"discount_scope": "sale",
"discount_base": "total",
"discount_type": "fixed",
"discount_fixed": 20,
"account_id": cls.account.id,
}
)
cls.partner_2.supplier_global_discount_ids = cls.global_discount_2
cls.tax = cls.env["account.tax"].create(
{
Expand Down Expand Up @@ -427,3 +437,42 @@ def test_discount_total(self):
self.assertAlmostEqual(self.invoice.amount_tax, 30.0)
self.assertAlmostEqual(self.invoice.amount_global_discount, -115.0)
self.assertAlmostEqual(self.invoice.amount_total, 115.0)

def test_global_invoice_total_mixed_discount(self):
"""Add both global fixed and percentage discount on total to the invoice"""
# Pre-condition: check starting amounts and the discount base
self.assertAlmostEqual(self.invoice.amount_untaxed, 200.0)
self.assertAlmostEqual(self.invoice.amount_tax, 30.0)
self.assertAlmostEqual(self.invoice.amount_global_discount, 0)
self.assertAlmostEqual(self.invoice.amount_total, 230)
self.assertEqual(self.global_discount_total.discount_base, "total")

# Act: set the fixed global total discount
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.clear()
invoice_form.global_discount_ids.add(self.global_discount_fixed_total)
precision = self.env["decimal.precision"].precision_get("Product Price")

# Assert: fixed discount is applied to the total
# and taxes remain the same:
# 230 - 20 (fixed disc.) = 210
self.assertEqual(
self.invoice.invoice_global_discount_ids.discount_display,
"-20.{}".format("0" * precision),
)
self.assertAlmostEqual(self.invoice.amount_untaxed, 200.0)
self.assertAlmostEqual(self.invoice.amount_tax, 30.0)
self.assertAlmostEqual(self.invoice.amount_global_discount, -20.0)
self.assertAlmostEqual(self.invoice.amount_total, 210.0)

# Act: set the next global total discount
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_total)

# Assert: percentage discount is applied to previous discounted total,
# and taxes remain the same:
# 210 - 50% (percentage disc.) = 105
self.assertAlmostEqual(self.invoice.amount_untaxed, 200.0)
self.assertAlmostEqual(self.invoice.amount_tax, 30.0)
self.assertAlmostEqual(self.invoice.amount_global_discount, -125.0)
self.assertAlmostEqual(self.invoice.amount_total, 105.0)
3 changes: 3 additions & 0 deletions account_global_discount/views/account_invoice_views.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2019 Tecnativa - David Vidal
Copyright 2022 Simone Rubino - TAKOBI
Copyright 2024 Sergio Zanchetta - PNLUG APS
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_move_form" model="ir.ui.view">
Expand Down Expand Up @@ -77,7 +78,9 @@
<field name="name" />
<field name="currency_id" invisible="1" />
<field name="global_discount_id" invisible="1" />
<field name="discount_type" invisible="1" />
<field name="discount" invisible="1" />
<field name="discount_fixed" invisible="1" />
<field
name="base"
widget="monetary"
Expand Down
17 changes: 14 additions & 3 deletions account_global_discount/views/report_account_invoice.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 Simone Rubino - TAKOBI
Copyright 2024 Sergio Zanchetta - PNLUG APS
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<template id="report_invoice_document" inherit_id="account.report_invoice_document">
Expand Down Expand Up @@ -49,9 +50,19 @@
</tr>
<tr>
<td><strong>Global Discounts</strong><br />
<t
t-esc="'→'.join(['{:.2f}%'.format(x.discount) for x in o.global_discount_ids])"
/></td>
<t t-foreach="o.global_discount_ids" t-as="global_discount_id">
<t t-if="global_discount_id.discount_type == 'percentage'">
<t
t-esc="'→'.join(['{:.2f}%'.format(global_discount_id.discount)])"
/>
</t>
<t t-else="global_discount_id.discount_type == 'fixed'">
<t
t-esc="'→'.join(['{:.2f}'.format(global_discount_id.discount_fixed)])"
/>
</t>
</t>
</td>
<td class="text-right">
<span
t-field="o.amount_global_discount"
Expand Down
2 changes: 2 additions & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# https://github.com/OCA/server-backend/pull/267
git+https://github.com/OCA/server-backend@refs/pull/267/head#subdirectory=setup/base_global_discount

0 comments on commit f9aee31

Please sign in to comment.