diff --git a/sale_margin_tax/README.rst b/sale_margin_tax/README.rst
index 14974dcf..8a6d738c 100644
--- a/sale_margin_tax/README.rst
+++ b/sale_margin_tax/README.rst
@@ -7,7 +7,7 @@ Sale Margin Tax
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:416d0b79eaaa0c0f1e1a0e5a318854e8c96763da78689885a682a6dab2556725
+ !! source digest: sha256:c643555de95864a024f53fe400bc41b671c13907fe80729c92c7365c5de15f28
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
diff --git a/sale_margin_tax/__manifest__.py b/sale_margin_tax/__manifest__.py
index 57a51572..59a3a696 100644
--- a/sale_margin_tax/__manifest__.py
+++ b/sale_margin_tax/__manifest__.py
@@ -14,6 +14,7 @@
"data": [
"views/tax.xml",
"data/account_tax.xml",
+ "data/product.xml",
"reports/report_invoice_document.xml",
],
}
diff --git a/sale_margin_tax/data/account_tax.xml b/sale_margin_tax/data/account_tax.xml
index e23a357b..cd88696a 100644
--- a/sale_margin_tax/data/account_tax.xml
+++ b/sale_margin_tax/data/account_tax.xml
@@ -2,6 +2,14 @@
[Margin Tax]
+
+
+ Margin 0%
+ margin
+ Margin Tax
+ 0
+
+
Margin 21%
@@ -10,5 +18,6 @@
21
+
diff --git a/sale_margin_tax/data/product.xml b/sale_margin_tax/data/product.xml
new file mode 100644
index 00000000..6200532d
--- /dev/null
+++ b/sale_margin_tax/data/product.xml
@@ -0,0 +1,7 @@
+
+
+
+ Margin on secondhand sales
+ service
+
+
diff --git a/sale_margin_tax/i18n/sale_margin_tax.pot b/sale_margin_tax/i18n/sale_margin_tax.pot
new file mode 100644
index 00000000..af40a222
--- /dev/null
+++ b/sale_margin_tax/i18n/sale_margin_tax.pot
@@ -0,0 +1,140 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * sale_margin_tax
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 16.0+e\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,help:sale_margin_tax.field_account_tax__amount_type
+msgid ""
+"\n"
+" - Group of Taxes: The tax is a set of sub taxes.\n"
+" - Fixed: The tax amount stays the same whatever the price.\n"
+" - Percentage of Price: The tax amount is a % of the price:\n"
+" e.g 100 * (1 + 10%) = 110 (not price included)\n"
+" e.g 110 / (1 + 10%) = 100 (price included)\n"
+" - Percentage of Price Tax Included: The tax amount is a division of the price:\n"
+" e.g 180 / (1 - 10%) = 200 (not price included)\n"
+" e.g 200 * (1 - 10%) = 180 (price included)\n"
+" "
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_bank_statement_line__has_margin_taxes
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_move__has_margin_taxes
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_move_line__has_margin_taxes
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_payment__has_margin_taxes
+#: model:ir.model.fields,field_description:sale_margin_tax.field_sale_order__has_margin_taxes
+msgid "Has Margin Taxes"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model,name:sale_margin_tax.model_account_move
+msgid "Journal Entry"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model,name:sale_margin_tax.model_account_move_line
+msgid "Journal Item"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:account.tax,name:sale_margin_tax.tax_margin
+msgid "Margin 21%"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:account.tax,margin_mention:sale_margin_tax.tax_margin
+msgid "Margin EN mention"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:account.tax,margin_description_template:sale_margin_tax.tax_margin
+msgid "Margin Tax"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:account.tax,margin_name_template:sale_margin_tax.tax_margin
+msgid "Margin: {}%"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_tax__margin_mention
+msgid "Mention on invoice"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model,name:sale_margin_tax.model_sale_order
+msgid "Sales Order"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model,name:sale_margin_tax.model_sale_order_line
+msgid "Sales Order Line"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_move_line__price_subtotal_report
+msgid "Subtotal (Report)"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model,name:sale_margin_tax.model_account_tax
+msgid "Tax"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_tax__amount_type
+msgid "Tax Computation"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields.selection,name:sale_margin_tax.selection__account_tax__amount_type__margin
+msgid "Tax on margin"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_tax__margin_description_template
+msgid "Template used for the generated tax description"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,field_description:sale_margin_tax.field_account_tax__margin_name_template
+msgid "Template used for the generated tax names"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,help:sale_margin_tax.field_account_tax__margin_mention
+msgid "This mention will be automatically added to the invoice."
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,help:sale_margin_tax.field_account_tax__margin_description_template
+msgid "This name can accept the rate as parameter, e.g. use 'Margin: {:.2f}%'"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:ir.model.fields,help:sale_margin_tax.field_account_tax__margin_name_template
+msgid "This name must accept the rate as parameter, e.g. use 'Margin: {}%'"
+msgstr ""
+
+#. module: sale_margin_tax
+#. odoo-python
+#: code:addons/sale_margin_tax/models/account_tax.py:0
+#, python-format
+msgid "Untaxed Amount"
+msgstr ""
+
+#. module: sale_margin_tax
+#: model:account.tax.group,name:sale_margin_tax.tax_group_margin
+msgid "[Margin Tax]"
+msgstr ""
diff --git a/sale_margin_tax/models/__init__.py b/sale_margin_tax/models/__init__.py
index c81d98b2..f340edec 100644
--- a/sale_margin_tax/models/__init__.py
+++ b/sale_margin_tax/models/__init__.py
@@ -1,3 +1,4 @@
+from . import margin_mixin
from . import account_tax
from . import sale_order_line
from . import sale_order
diff --git a/sale_margin_tax/models/account_move.py b/sale_margin_tax/models/account_move.py
index bc8247a1..982d1558 100644
--- a/sale_margin_tax/models/account_move.py
+++ b/sale_margin_tax/models/account_move.py
@@ -2,27 +2,24 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo import api, fields, models
+from odoo import fields, models
class AccountMove(models.Model):
- _inherit = "account.move"
-
- has_margin_taxes = fields.Boolean(compute="_compute_has_margin_taxes")
-
- @api.depends("line_ids.tax_ids")
- def _compute_has_margin_taxes(self):
- for move in self:
- move.has_margin_taxes = any(move.mapped("line_ids.has_margin_taxes"))
-
- def _get_margin_taxes(self):
- filter_tax = lambda t: t.amount_type == "margin" # noqa: E731
- return self.line_ids.tax_ids.filtered(filter_tax)
-
- def _get_margin_mention(self):
- margin_tax = self._get_margin_taxes()[0]
- margin_tax = margin_tax.with_context(lang=self.partner_id.lang)
- return margin_tax.margin_mention
+ _name = "account.move"
+ _inherit = ["account.move", "margin.mixin"]
+
+ invoice_report_line_ids = fields.One2many(
+ "account.move.line",
+ "move_id",
+ string="Invoice Report lines",
+ copy=False,
+ readonly=True,
+ domain=[
+ ("display_type", "in", ("product", "line_section", "line_note")),
+ ("is_margin_line", "=", False),
+ ],
+ )
def action_post(self):
res = super().action_post()
diff --git a/sale_margin_tax/models/account_move_line.py b/sale_margin_tax/models/account_move_line.py
index 8383e435..6a2d1940 100644
--- a/sale_margin_tax/models/account_move_line.py
+++ b/sale_margin_tax/models/account_move_line.py
@@ -6,23 +6,35 @@
class AccountMoveLine(models.Model):
- _inherit = "account.move.line"
+ _name = "account.move.line"
+ _inherit = ["account.move.line", "margin.line.mixin"]
- has_margin_taxes = fields.Boolean(compute="_compute_has_margin_taxes")
price_subtotal_report = fields.Monetary(
string="Subtotal (Report)",
compute="_compute_price_subtotal_report",
currency_field="currency_id",
)
-
- @api.depends("tax_ids")
- def _compute_has_margin_taxes(self):
- mg = self.env.ref("sale_margin_tax.tax_group_margin")
- for line in self:
- line.has_margin_taxes = mg in line.mapped("tax_ids.tax_group_id")
+ price_unit_report = fields.Monetary(
+ string="Price Unit (Report)",
+ compute="_compute_price_subtotal_report",
+ currency_field="currency_id",
+ )
+ is_margin_line = fields.Boolean(
+ help="True if this line is a margin line.",
+ default=False,
+ )
+ margin_line_id = fields.Many2one(
+ "account.move.line",
+ help="The margin line for this line.",
+ )
@api.depends("price_subtotal", "price_total", "has_margin_taxes")
def _compute_price_subtotal_report(self):
for line in self:
- price = line.price_total if line.has_margin_taxes else line.price_subtotal
+ price = line.price_subtotal
+ price_unit = line.price_unit
+ if line.has_margin_taxes:
+ price = line.price_total + line.margin_line_id.price_total
+ price_unit = price_unit + line.margin_line_id.price_unit
line.price_subtotal_report = price
+ line.price_unit_report = price_unit
diff --git a/sale_margin_tax/models/account_tax.py b/sale_margin_tax/models/account_tax.py
index e6c8080e..de023e7a 100644
--- a/sale_margin_tax/models/account_tax.py
+++ b/sale_margin_tax/models/account_tax.py
@@ -33,6 +33,10 @@ class AccountTax(models.Model):
_inherit = "account.tax"
+ is_margin_tax = fields.Boolean(
+ compute="_compute_is_margin_tax",
+ help="True if this tax is a margin tax.",
+ )
amount_type = fields.Selection(
selection_add=[("margin", "Tax on margin")], ondelete={"margin": "cascade"}
)
@@ -55,6 +59,16 @@ class AccountTax(models.Model):
default="Margin: {:.2f}%",
help="This name can accept the rate as parameter, e.g. use 'Margin: {:.2f}%'",
)
+ margin_base_tax_id = fields.Many2one(
+ "account.tax",
+ string="Base Tax",
+ help="The tax to be applied on the base amount of the margin tax.",
+ )
+
+ def _compute_is_margin_tax(self):
+ margin_group = self.env.ref("sale_margin_tax.tax_group_margin")
+ for tax in self:
+ tax.is_margin_tax = tax.tax_group_id == margin_group
def _get_or_create_margin_tax(self, base_amount, margin):
"""On non margin tax, simply return the tax;
diff --git a/sale_margin_tax/models/margin_mixin.py b/sale_margin_tax/models/margin_mixin.py
new file mode 100644
index 00000000..08733c6b
--- /dev/null
+++ b/sale_margin_tax/models/margin_mixin.py
@@ -0,0 +1,68 @@
+# Copyright 2023 len-foss/Financial Way
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+
+from odoo import api, fields, models
+
+
+class MarginLineMixin(models.AbstractModel):
+ _name = "margin.line.mixin"
+ _description = "Margin Line Mixin"
+
+ has_margin_taxes = fields.Boolean(compute="_compute_has_margin_taxes")
+
+ @api.model
+ def _get_tax_field(self):
+ return "tax_id" if self._name == "sale.order.line" else "tax_ids"
+
+ @api.model
+ def _get_margin_depends(self):
+ tax_field = self._get_tax_field()
+ return [tax_field + ".is_margin_tax"]
+
+ def _get_line_taxes(self):
+ tax_field = self._get_tax_field()
+ return self[tax_field]
+
+ def _get_margin_taxes(self):
+ taxes = self._get_line_taxes()
+ return taxes.filtered("is_margin_tax")
+
+ @api.depends(lambda self: self._get_margin_depends())
+ def _compute_has_margin_taxes(self):
+ for line in self:
+ line.has_margin_taxes = line._get_margin_taxes()
+
+
+class MarginMixin(models.AbstractModel):
+ _name = "margin.mixin"
+ _description = "Margin Mixin"
+
+ has_margin_taxes = fields.Boolean(compute="_compute_has_margin_taxes")
+
+ @api.model
+ def _get_margin_depends(self):
+ line_field = self._get_lines_field()
+ return [line_field + ".has_margin_taxes"]
+
+ def _get_lines_field(self):
+ return "order_line" if self._name == "sale.order" else "line_ids"
+
+ def _get_lines(self):
+ line_field = self._get_lines_field()
+ return self[line_field]
+
+ @api.depends(lambda self: self._get_margin_depends())
+ def _compute_has_margin_taxes(self):
+ for record in self:
+ lines = record._get_lines()
+ record.has_margin_taxes = any(lines.mapped("has_margin_taxes"))
+
+ def _get_margin_taxes(self):
+ lines = self._get_lines()
+ return lines._get_margin_taxes()
+
+ def _get_margin_mention(self):
+ margin_tax = self._get_margin_taxes()[0]
+ margin_tax = margin_tax.with_context(lang=self.partner_id.lang)
+ return margin_tax.margin_mention
diff --git a/sale_margin_tax/models/sale_order.py b/sale_margin_tax/models/sale_order.py
index 3a9f1f10..78ba2279 100644
--- a/sale_margin_tax/models/sale_order.py
+++ b/sale_margin_tax/models/sale_order.py
@@ -1,27 +1,12 @@
# Copyright 2023 len-foss/Financial Way
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo import api, fields, models
+from odoo import models
class SaleOrder(models.Model):
- _inherit = "sale.order"
-
- has_margin_taxes = fields.Boolean(compute="_compute_has_margin_taxes")
-
- @api.depends("order_line.tax_id")
- def _compute_has_margin_taxes(self):
- for order in self:
- order.has_margin_taxes = order._get_margin_taxes()
-
- def _get_margin_taxes(self):
- filter_tax = lambda t: t.amount_type == "margin" # noqa: E731
- return self.order_line.tax_id.filtered(filter_tax)
-
- def _get_margin_mention(self):
- margin_tax = self._get_margin_taxes()[0]
- margin_tax = margin_tax.with_context(lang=self.partner_id.lang)
- return margin_tax.margin_mention
+ _name = "sale.order"
+ _inherit = ["sale.order", "margin.mixin"]
def action_confirm(self):
res = super().action_confirm()
@@ -32,3 +17,15 @@ def action_confirm(self):
if msg not in note:
order.note = note + "\n" + msg
return res
+
+ def _create_invoices(self, grouped=False, final=False):
+ res = super()._create_invoices(grouped=grouped, final=final)
+ for invoice in res:
+ if self.has_margin_taxes:
+ for line in self.order_line.filtered("has_margin_taxes"):
+ invoice_line = line.invoice_lines # will crash in many cases...
+ vals_line = line._prepare_invoice_margin_base_line()
+ vals_line["move_id"] = invoice.id
+ vals_line["margin_line_id"] = invoice_line.id
+ self.env["account.move.line"].create(vals_line)
+ return res
diff --git a/sale_margin_tax/models/sale_order_line.py b/sale_margin_tax/models/sale_order_line.py
index b6d92526..1d95db9a 100644
--- a/sale_margin_tax/models/sale_order_line.py
+++ b/sale_margin_tax/models/sale_order_line.py
@@ -7,7 +7,8 @@
class SaleOrderLine(models.Model):
- _inherit = "sale.order.line"
+ _name = "sale.order.line"
+ _inherit = ["sale.order.line", "margin.line.mixin"]
def _get_taxes(self):
"""Override to get the purchase price from lot, purchase order, etc.
@@ -21,14 +22,38 @@ def _get_purchase_price(self):
"""
return self.product_id.standard_price * self.product_uom_qty
+ def _get_margin(self):
+ purchase_price = self._get_purchase_price()
+ return max(self.price_subtotal - purchase_price, 0)
+
+ def _get_margin_base_price(self):
+ base_price = self.price_subtotal
+ margin = self._get_margin()
+ return base_price - margin
+
def _prepare_invoice_line(self, **optional_values):
vals = super()._prepare_invoice_line(**optional_values)
taxes = self._get_taxes()
if "margin" in taxes.mapped("amount_type"):
- purchase_price = self._get_purchase_price()
- taxes = taxes._apply_margin_taxes(self.price_subtotal, purchase_price)
- if taxes:
- vals["tax_ids"] = [(6, 0, taxes.ids)]
- else:
- vals.pop("tax_ids", False)
+ vals["is_margin_line"] = True
+ qty = self.product_uom_qty
+ product = self.env.ref("sale_margin_tax.product_margin")
+ vals["product_id"] = product.id
+ margin = self._get_margin()
+ taxes = taxes._apply_margin_taxes(margin, 0)
+ vals["price_unit"] = margin / qty
+ vals["tax_ids"] = [(6, 0, taxes.ids)] if taxes else [(5, 0, 0)]
+ return vals
+
+ def _prepare_invoice_margin_base_line(self, **optional_values):
+ vals = super()._prepare_invoice_line(**optional_values)
+ taxes = self._get_taxes()
+ tax_null = taxes.margin_base_tax_id
+ qty = self.product_uom_qty
+ base_values = {
+ "price_unit": self._get_margin_base_price() / qty,
+ "quantity": qty,
+ "tax_ids": [(6, 0, tax_null.ids)],
+ }
+ vals.update(base_values)
return vals
diff --git a/sale_margin_tax/reports/report_invoice_document.xml b/sale_margin_tax/reports/report_invoice_document.xml
index 775ea23e..2d11703a 100644
--- a/sale_margin_tax/reports/report_invoice_document.xml
+++ b/sale_margin_tax/reports/report_invoice_document.xml
@@ -5,8 +5,14 @@
+
+
+
line.price_subtotal_report
+
+
+
+
diff --git a/sale_margin_tax/static/description/index.html b/sale_margin_tax/static/description/index.html
index 05c84f5a..f769da07 100644
--- a/sale_margin_tax/static/description/index.html
+++ b/sale_margin_tax/static/description/index.html
@@ -367,7 +367,7 @@
Sale Margin Tax
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:416d0b79eaaa0c0f1e1a0e5a318854e8c96763da78689885a682a6dab2556725
+!! source digest: sha256:c643555de95864a024f53fe400bc41b671c13907fe80729c92c7365c5de15f28
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
![Try me on Runboat](https://img.shields.io/badge/runboat-Try%20me-875A7B.png)
This module takes a simple approach to the Belgian margin tax.
diff --git a/sale_margin_tax/tests/common.py b/sale_margin_tax/tests/common.py
index 53605da3..2f7c4619 100644
--- a/sale_margin_tax/tests/common.py
+++ b/sale_margin_tax/tests/common.py
@@ -16,7 +16,17 @@ def setUpClass(cls):
vals_product_2 = {"name": "P2", "standard_price": 5}
cls.product_2 = cls.env["product.product"].create(vals_product_2)
- vals_tax = {"name": "Margin Tax", "amount": 21.0, "amount_type": "margin"}
+ margin_group = cls.env.ref("sale_margin_tax.tax_group_margin")
+
+ vals_tax_null = {"name": "M0", "amount": 0, "amount_type": "margin"}
+ cls.tax_null = cls.env["account.tax"].create(vals_tax_null)
+ vals_tax = {
+ "name": "Margin Tax",
+ "amount": 21.0,
+ "amount_type": "margin",
+ "margin_base_tax_id": cls.tax_null.id,
+ "tax_group_id": margin_group.id,
+ }
cls.tax_margin = cls.env["account.tax"].create(vals_tax)
vals_tax_other = {"name": "Other Tax", "amount": 21.0, "amount_type": "percent"}
@@ -26,13 +36,20 @@ def setUpClass(cls):
cls.tag_vat = cls.env["account.account.tag"].create(vals_tag_vat)
vals_tag_base = {"name": "Base", "applicability": "taxes"}
cls.tag_base = cls.env["account.account.tag"].create(vals_tag_base)
- cls.tags = cls.tag_base + cls.tag_vat
+ vals_tag_margin = {"name": "Margin", "applicability": "taxes"}
+ cls.tag_margin = cls.env["account.account.tag"].create(vals_tag_margin)
+ cls.tags = cls.tag_base + cls.tag_vat + cls.tag_margin
lines = cls.tax_margin.invoice_repartition_line_ids
- line_base = lines.filtered(lambda l: l.repartition_type == "base")
- line_margin = lines.filtered(lambda l: l.repartition_type == "tax")
+ line_margin = lines.filtered(lambda l: l.repartition_type == "base")
+ line_tax = lines.filtered(lambda l: l.repartition_type == "tax")
+ line_margin.tag_ids = [(6, 0, cls.tag_margin.ids)]
+ line_tax.tag_ids = [(6, 0, cls.tag_vat.ids)]
+
+ # the repartition line for the base is on the null tax
+ rls = cls.tax_null.invoice_repartition_line_ids
+ line_base = rls.filtered(lambda l: l.repartition_type == "base")
line_base.tag_ids = [(6, 0, cls.tag_base.ids)]
- line_margin.tag_ids = [(6, 0, cls.tag_vat.ids)]
vals_sale = {
"partner_id": cls.partner.id,
@@ -71,4 +88,3 @@ def setUpClass(cls):
langs = cls.env["res.lang"].with_context(active_test=False)
cls.lang = langs.search([("code", "=", "fr_BE")])
cls.lang.active = True
- # cls.env["ir.translation"].load_module_terms(["base"], [cls.lang.code])
diff --git a/sale_margin_tax/tests/test_tax.py b/sale_margin_tax/tests/test_tax.py
index 348ba1e2..91e6b53e 100644
--- a/sale_margin_tax/tests/test_tax.py
+++ b/sale_margin_tax/tests/test_tax.py
@@ -55,6 +55,33 @@ def test_mixed_taxes(self):
self.assertEqual(invoice.amount_total, 136)
self.assertTrue("marg" in invoice.narration)
+ def test_negative_margin(self):
+ # given:
+ self.sale.order_line[1].unlink()
+ # margin is -2 since we buy it for 10
+ self.sale.order_line[0].price_unit = 8
+
+ # when
+ self.sale.action_confirm()
+
+ # then: tax is properly applied for the first line
+ self.assertEqual(self.sale.amount_tax, 0)
+ # total: 4 * 8 = 32
+ self.assertEqual(self.sale.amount_total, 4 * 8)
+ # margin is negative but the mention should be there anyway
+ self.assertTrue("marg" in self.sale.note)
+
+ # when
+ invoice = self.sale._create_invoices()
+
+ # then: invoice values are coherent with it
+ self.assertAlmostEqual(invoice.amount_tax, 0)
+ self.assertEqual(invoice.amount_total, 32)
+ self.assertTrue("marg" in invoice.narration)
+ # the margin line is 0
+ margin_line = invoice.invoice_line_ids.filtered("is_margin_line")
+ self.assertEqual(margin_line.balance, 0)
+
def test_no_margin_tax(self):
"""Sell one product with normal tax; nothing fancy should happen."""
# given
diff --git a/sale_margin_tax/views/tax.xml b/sale_margin_tax/views/tax.xml
index 4b63eaa8..e76d9eba 100644
--- a/sale_margin_tax/views/tax.xml
+++ b/sale_margin_tax/views/tax.xml
@@ -30,6 +30,10 @@
name="margin_description_template"
attrs="{'invisible':[('amount_type','!=', 'margin')]}"
/>
+