diff --git a/sale_commission_margin_oca/README.rst b/sale_commission_margin_oca/README.rst new file mode 100644 index 000000000..18ac40951 --- /dev/null +++ b/sale_commission_margin_oca/README.rst @@ -0,0 +1,96 @@ +====================== +Sale Commission Margin +====================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:8106e37e1be0140a76412653a94e7c1e14f2817690d3a275bcf62c4958861053 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fcommission-lightgray.png?logo=github + :target: https://github.com/OCA/commission/tree/18.0/sale_commission_margin_oca + :alt: OCA/commission +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/commission-18-0/commission-18-0-sale_commission_margin_oca + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/commission&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionality of sale_margin and sale_commission +to deduct commissions from margin + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +- Go to Sales -> Configuration -> Settings + +- Scroll to pricing settings and check 'Margins' box. + +- Go to Sales -> Orders -> Quotations + +- Create new quotation and set: + + 1. Customer + 2. One order line + +- In the order line created press edit agents button and set an agent. + +- The agent commission amount should be deducted from margin. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Dixmit + +Contributors +------------ + +-Luis Rodríguez luis.rodriguez@dixmit.com +(`www.dixmit.com `__) + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/commission `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_commission_margin_oca/__init__.py b/sale_commission_margin_oca/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/sale_commission_margin_oca/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_commission_margin_oca/__manifest__.py b/sale_commission_margin_oca/__manifest__.py new file mode 100644 index 000000000..7718a6c82 --- /dev/null +++ b/sale_commission_margin_oca/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2025 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Commission Margin", + "summary": """This addons allows commissions to be deducted from the margin.""", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "author": "Dixmit,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/commission", + "depends": [ + "sale_margin", + "sale_commission_oca", + ], + "data": [ + "views/sale_order_view.xml", + ], + "demo": [], +} diff --git a/sale_commission_margin_oca/i18n/it.po b/sale_commission_margin_oca/i18n/it.po new file mode 100644 index 000000000..dac6d090e --- /dev/null +++ b/sale_commission_margin_oca/i18n/it.po @@ -0,0 +1,74 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_commission_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-06-04 10:26+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_move_line__agent_ids +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_mixin__agent_ids +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line__agent_ids +msgid "Agents & commissions" +msgstr "Agenti & provvigioni" + +#. module: sale_commission_margin +#: model:ir.model.fields,help:sale_commission_margin.field_account_move_line__agent_ids +#: model:ir.model.fields,help:sale_commission_margin.field_commission_mixin__agent_ids +#: model:ir.model.fields,help:sale_commission_margin.field_sale_order_line__agent_ids +msgid "Agents/Commissions related to the invoice line." +msgstr "Agenti/provvigioni collegati alla riga fattura." + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_move_line__commission_free +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_mixin__commission_free +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line__commission_free +msgid "Comm. free" +msgstr "Senza provvigione" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_invoice_line_agent__commission_id +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_line_mixin__commission_id +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line_agent__commission_id +msgid "Commission" +msgstr "Provvigione" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_invoice_line_agent__amount +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_line_mixin__amount +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line_agent__amount +msgid "Commission Amount" +msgstr "Importo provvigione" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_commission_mixin +msgid "" +"Mixin model for applying to any object that wants to handle commissions" +msgstr "" +"Modello mixin da applicare a qualsiasi oggetto che voglia gestire le " +"provvigioni" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_commission_line_mixin +msgid "" +"Mixin model for having commission agent lines in any object inheriting from " +"this one" +msgstr "" +"Modello mixin per avere righe di provvigione agente in qualsiasi oggetto che " +"erediti dall'attuale" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_sale_order_line +msgid "Sales Order Line" +msgstr "Riga ordine di vendita" diff --git a/sale_commission_margin_oca/i18n/pt_BR.po b/sale_commission_margin_oca/i18n/pt_BR.po new file mode 100644 index 000000000..fb36a400b --- /dev/null +++ b/sale_commission_margin_oca/i18n/pt_BR.po @@ -0,0 +1,68 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_commission_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_move_line__agent_ids +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_mixin__agent_ids +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line__agent_ids +msgid "Agents & commissions" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,help:sale_commission_margin.field_account_move_line__agent_ids +#: model:ir.model.fields,help:sale_commission_margin.field_commission_mixin__agent_ids +#: model:ir.model.fields,help:sale_commission_margin.field_sale_order_line__agent_ids +msgid "Agents/Commissions related to the invoice line." +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_move_line__commission_free +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_mixin__commission_free +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line__commission_free +msgid "Comm. free" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_invoice_line_agent__commission_id +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_line_mixin__commission_id +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line_agent__commission_id +msgid "Commission" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_invoice_line_agent__amount +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_line_mixin__amount +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line_agent__amount +msgid "Commission Amount" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_commission_mixin +msgid "" +"Mixin model for applying to any object that wants to handle commissions" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_commission_line_mixin +msgid "" +"Mixin model for having commission agent lines in any object inheriting from " +"this one" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_sale_order_line +msgid "Sales Order Line" +msgstr "" diff --git a/sale_commission_margin_oca/i18n/sale_commission_margin.pot b/sale_commission_margin_oca/i18n/sale_commission_margin.pot new file mode 100644 index 000000000..d2b2e6a36 --- /dev/null +++ b/sale_commission_margin_oca/i18n/sale_commission_margin.pot @@ -0,0 +1,67 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_commission_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\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_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_move_line__agent_ids +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_mixin__agent_ids +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line__agent_ids +msgid "Agents & commissions" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,help:sale_commission_margin.field_account_move_line__agent_ids +#: model:ir.model.fields,help:sale_commission_margin.field_commission_mixin__agent_ids +#: model:ir.model.fields,help:sale_commission_margin.field_sale_order_line__agent_ids +msgid "Agents/Commissions related to the invoice line." +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_move_line__commission_free +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_mixin__commission_free +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line__commission_free +msgid "Comm. free" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_invoice_line_agent__commission_id +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_line_mixin__commission_id +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line_agent__commission_id +msgid "Commission" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model.fields,field_description:sale_commission_margin.field_account_invoice_line_agent__amount +#: model:ir.model.fields,field_description:sale_commission_margin.field_commission_line_mixin__amount +#: model:ir.model.fields,field_description:sale_commission_margin.field_sale_order_line_agent__amount +msgid "Commission Amount" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_commission_mixin +msgid "" +"Mixin model for applying to any object that wants to handle commissions" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_commission_line_mixin +msgid "" +"Mixin model for having commission agent lines in any object inheriting from " +"this one" +msgstr "" + +#. module: sale_commission_margin +#: model:ir.model,name:sale_commission_margin.model_sale_order_line +msgid "Sales Order Line" +msgstr "" diff --git a/sale_commission_margin_oca/models/__init__.py b/sale_commission_margin_oca/models/__init__.py new file mode 100644 index 000000000..5cea45f22 --- /dev/null +++ b/sale_commission_margin_oca/models/__init__.py @@ -0,0 +1,2 @@ +from . import commission_mixin +from . import sale_order_line diff --git a/sale_commission_margin_oca/models/commission_mixin.py b/sale_commission_margin_oca/models/commission_mixin.py new file mode 100644 index 000000000..0a6f77296 --- /dev/null +++ b/sale_commission_margin_oca/models/commission_mixin.py @@ -0,0 +1,36 @@ +# Copyright 2025 Dixmit - Luis Rodríguez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class CommissionMixin(models.AbstractModel): + _inherit = "commission.mixin" + + agent_ids = fields.One2many( + compute="_compute_agent_ids", + store=True, + precompute=True, + ) + + commission_free = fields.Boolean( + compute="_compute_commission_free", + store=True, + precompute=True, + ) + + +class CommissionLineMixin(models.AbstractModel): + _inherit = "commission.line.mixin" + + commission_id = fields.Many2one( + compute="_compute_commission_id", + store=True, + precompute=True, + ) + + amount = fields.Monetary( + compute="_compute_amount", + store=True, + precompute=True, + ) diff --git a/sale_commission_margin_oca/models/sale_order_line.py b/sale_commission_margin_oca/models/sale_order_line.py new file mode 100644 index 000000000..5b4caf06c --- /dev/null +++ b/sale_commission_margin_oca/models/sale_order_line.py @@ -0,0 +1,22 @@ +# Copyright 2025 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + @api.depends( + "price_subtotal", "product_uom_qty", "purchase_price", "agent_ids.amount" + ) + def _compute_margin(self): + for line in self: + line.margin = ( + line.price_subtotal + - (line.purchase_price * line.product_uom_qty) + - sum(line.mapped("agent_ids.amount")) + ) + line.margin_percent = ( + line.price_subtotal and line.margin / line.price_subtotal + ) diff --git a/sale_commission_margin_oca/pyproject.toml b/sale_commission_margin_oca/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/sale_commission_margin_oca/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/sale_commission_margin_oca/readme/CONTRIBUTORS.md b/sale_commission_margin_oca/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..94ce05f09 --- /dev/null +++ b/sale_commission_margin_oca/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +-Luis Rodríguez (www.dixmit.com) diff --git a/sale_commission_margin_oca/readme/DESCRIPTION.md b/sale_commission_margin_oca/readme/DESCRIPTION.md new file mode 100644 index 000000000..2be8478e7 --- /dev/null +++ b/sale_commission_margin_oca/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module extends the functionality of sale_margin and sale_commission to deduct commissions from margin diff --git a/sale_commission_margin_oca/readme/USAGE.md b/sale_commission_margin_oca/readme/USAGE.md new file mode 100644 index 000000000..168ff8e02 --- /dev/null +++ b/sale_commission_margin_oca/readme/USAGE.md @@ -0,0 +1,9 @@ +- Go to Sales -> Configuration -> Settings +- Scroll to pricing settings and check 'Margins' box. +- Go to Sales -> Orders -> Quotations +- Create new quotation and set: + 1. Customer + 2. One order line + +- In the order line created press edit agents button and set an agent. +- The agent commission amount should be deducted from margin. diff --git a/sale_commission_margin_oca/static/description/icon.png b/sale_commission_margin_oca/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/sale_commission_margin_oca/static/description/icon.png differ diff --git a/sale_commission_margin_oca/static/description/index.html b/sale_commission_margin_oca/static/description/index.html new file mode 100644 index 000000000..37978ccaa --- /dev/null +++ b/sale_commission_margin_oca/static/description/index.html @@ -0,0 +1,439 @@ + + + + + +Sale Commission Margin + + + +
+

Sale Commission Margin

+ + +

Beta License: AGPL-3 OCA/commission Translate me on Weblate Try me on Runboat

+

This module extends the functionality of sale_margin and sale_commission +to deduct commissions from margin

+

Table of contents

+ +
+

Usage

+
    +
  • Go to Sales -> Configuration -> Settings
  • +
  • Scroll to pricing settings and check ‘Margins’ box.
  • +
  • Go to Sales -> Orders -> Quotations
  • +
  • Create new quotation and set:
      +
    1. Customer
    2. +
    3. One order line
    4. +
    +
  • +
  • In the order line created press edit agents button and set an agent.
  • +
  • The agent commission amount should be deducted from margin.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Dixmit
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/commission project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/sale_commission_margin_oca/tests/__init__.py b/sale_commission_margin_oca/tests/__init__.py new file mode 100644 index 000000000..6f699d0d8 --- /dev/null +++ b/sale_commission_margin_oca/tests/__init__.py @@ -0,0 +1 @@ +from . import test_sale_order diff --git a/sale_commission_margin_oca/tests/test_sale_order.py b/sale_commission_margin_oca/tests/test_sale_order.py new file mode 100644 index 000000000..0fa86c679 --- /dev/null +++ b/sale_commission_margin_oca/tests/test_sale_order.py @@ -0,0 +1,80 @@ +# Copyright 2025 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestSaleOrder(TransactionCase): + def setUp(self): + super().setUp() + + self.product = self.env["product.product"].create( + { + "name": "Product", + "type": "consu", + "list_price": 100, + "standard_price": 50, + } + ) + + self.commission = self.env["commission"].create( + { + "name": "10% Commission", + "commission_type": "fixed", + "amount_base_type": "gross_amount", + "invoice_state": "open", + "fix_qty": 10, + } + ) + + self.agent = self.env["res.partner"].create( + { + "name": "Agent", + "agent": True, + "agent_type": "agent", + "commission_id": self.commission.id, + "settlement": "monthly", + } + ) + + def test_sale_order_with_commission(self): + """ + Data: + Price: 100 + Cost: 50 + Commission: 10% + + Result: + Sale Order Total: 100 + Sale Order Commission: 10 + Sale Order Margin: 40""" + + sale_order = self.env["sale.order"].create( + { + "partner_id": self.env.ref("base.res_partner_2").id, + "order_line": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_qty": 1, + "price_unit": 100, + }, + ) + ], + } + ) + sale_agent = self.env["sale.order.line.agent"].create( + { + "object_id": sale_order.order_line[0].id, + "commission_id": self.commission.id, + "agent_id": self.agent.id, + } + ) + sale_order.order_line[0].agent_ids = [(4, sale_agent.id)] + + self.assertEqual(sale_order.amount_untaxed, 100.0) + self.assertEqual(sale_order.commission_total, 10.0) + self.assertEqual(sale_order.margin, 40.0) + self.assertEqual(sale_order.margin_percent, 0.4) diff --git a/sale_commission_margin_oca/views/sale_order_view.xml b/sale_commission_margin_oca/views/sale_order_view.xml new file mode 100644 index 000000000..f508184a3 --- /dev/null +++ b/sale_commission_margin_oca/views/sale_order_view.xml @@ -0,0 +1,14 @@ + + + + sale.order.margin.view.form + sale.order + 99 + + + + + + + +