diff --git a/sale_discount_display_amount/README.rst b/sale_discount_display_amount/README.rst new file mode 100644 index 00000000000..228169b5e9b --- /dev/null +++ b/sale_discount_display_amount/README.rst @@ -0,0 +1,106 @@ +============================ +Sale Discount Display Amount +============================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:3e03252dcc15ca8bc28d294973149c61320c303b7774728774fb0afb77fc8516 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fsale--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/sale-workflow/tree/16.0/sale_discount_display_amount + :alt: OCA/sale-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/sale-workflow-16-0/sale-workflow-16-0-sale_discount_display_amount + :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/sale-workflow&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +In standard Odoo only display the rate of the discount applied, never the +amount. It could be great to be able to tell the customer how much he spares. +This is the goal of this addons, it will show on a sale +order the total without the discount and the value of the discount. +You can choose if you want the discount on the Total with or the Total without TAX. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To configure this module, you need to: + +#. Go to Sales/Settings and check "Allow discounts on sales order lines" +#. Go to Sales/Settings and check or uncheck "Show the Discount with TAX" depending on your needs + +Usage +===== + + +To use this module, you need to: + +#. Go on a sale order +#. Set a discount on a line +#. The value of the discount is dislayed in the total section as well as the total without it. + +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 +~~~~~~~ + +* ACSONE SA/NV + +Contributors +~~~~~~~~~~~~ + +* Cédric Pigeon +* Abraham Anes +* Chafique Delli +* Ruchir Shukla +* Manuel Regidor + +* `Pesol `__: + + * Jonathan Oscategui Taza + +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/sale-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_discount_display_amount/__init__.py b/sale_discount_display_amount/__init__.py new file mode 100644 index 00000000000..77fee9383db --- /dev/null +++ b/sale_discount_display_amount/__init__.py @@ -0,0 +1,3 @@ +from . import models +from .hooks import post_init_hook +from .hooks import pre_init_hook diff --git a/sale_discount_display_amount/__manifest__.py b/sale_discount_display_amount/__manifest__.py new file mode 100644 index 00000000000..241f97dde93 --- /dev/null +++ b/sale_discount_display_amount/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Discount Display Amount", + "summary": """ + This addon intends to display the amount of the discount computed on + sale_order_line and sale_order level""", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/sale-workflow", + "depends": ["sale_management"], + "data": ["views/sale_view.xml", "views/res_config_settings_views.xml"], + "pre_init_hook": "pre_init_hook", + "post_init_hook": "post_init_hook", +} diff --git a/sale_discount_display_amount/hooks.py b/sale_discount_display_amount/hooks.py new file mode 100644 index 00000000000..f6774fc1284 --- /dev/null +++ b/sale_discount_display_amount/hooks.py @@ -0,0 +1,58 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import logging + +from odoo.tools.sql import column_exists, create_column + +_logger = logging.getLogger(__name__) + +COLUMNS = ( + ("sale_order", "price_subtotal_no_discount"), + ("sale_order", "price_total_no_discount"), + ("sale_order", "discount_total"), + ("sale_order", "discount_subtotal"), + ("sale_order_line", "price_subtotal_no_discount"), + ("sale_order_line", "price_total_no_discount"), + ("sale_order_line", "discount_total"), + ("sale_order_line", "discount_subtotal"), +) + + +def pre_init_hook(env): + cr = env.cr # Retrieve the database cursor + for table, column in COLUMNS: + if not column_exists(cr, table, column): + _logger.info("Create discount column %s in database", column) + create_column(cr, table, column, "numeric") + + +def post_init_hook(env): + cr = env.cr # Retrieve the database cursor + _logger.info("Compute discount columns") + + query = """ + update sale_order_line + set + price_subtotal_no_discount = price_subtotal, + price_total_no_discount = price_total + where discount = 0.0 + """ + cr.execute(query) + + query = """ + update sale_order + set + price_subtotal_no_discount = amount_untaxed, + price_total_no_discount = amount_total + """ + cr.execute(query) + + query = """ + select distinct order_id from sale_order_line where discount > 0.0; + """ + + cr.execute(query) + order_ids = cr.fetchall() + + orders = env["sale.order"].search([("id", "in", order_ids)]) + orders.mapped("order_line")._update_discount_display_fields() diff --git a/sale_discount_display_amount/i18n/ca.po b/sale_discount_display_amount/i18n/ca.po new file mode 100644 index 00000000000..c4fba7e21cb --- /dev/null +++ b/sale_discount_display_amount/i18n/ca.po @@ -0,0 +1,48 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-02-23 17:45+0000\n" +"Last-Translator: Daniel Martinez Vila \n" +"Language-Team: none\n" +"Language: ca\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 4.3.2\n" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "Subtotal de descompte" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "Comanda de venda" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línia de comandes de vendes" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Subtotal Without Discount" +msgstr "Subtotal sense descompte" + +#~ msgid "Display Name" +#~ msgstr "Nom Visible" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Darrera modificació el" diff --git a/sale_discount_display_amount/i18n/de.po b/sale_discount_display_amount/i18n/de.po new file mode 100644 index 00000000000..5c1227734c5 --- /dev/null +++ b/sale_discount_display_amount/i18n/de.po @@ -0,0 +1,81 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-22 09:19+0000\n" +"PO-Revision-Date: 2024-02-22 09:19+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,help:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,help:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Check this field to show the Discount with TAX" +msgstr "Aktivieren Sie dieses Feld, um den Rabatt mit Steuern anzuzeigen." + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_company +msgid "Companies" +msgstr "Unternehmen" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "Rabatt-Nettobetrag" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +msgid "Discount total" +msgstr "Rabatt-Bruttobetrag" + +#. module: sale_discount_display_amount +#: model_terms:ir.ui.view,arch_db:sale_discount_display_amount.res_config_settings_view_form +msgid "" +"OFF = Shows the Discount without TAX
ON = Shows the Discount with TAX" +msgstr "" +"OFF = Zeigt den Rabatt ohne Steuer
ON = Zeigt den Rabatt mit Steuer" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "Kundenauftrag" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "Kundenauftragszeile" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_company__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Show the Discount with TAX" +msgstr "Den Rabatt mit Steuer anzeigen" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_subtotal_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_subtotal_no_discount +msgid "Subtotal Without Discount" +msgstr "Nettobetrag ohne Rabatt" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Total Without Discount" +msgstr "Bruttobetrag ohne Rabatt" diff --git a/sale_discount_display_amount/i18n/es.po b/sale_discount_display_amount/i18n/es.po new file mode 100644 index 00000000000..6cb3e0ccf46 --- /dev/null +++ b/sale_discount_display_amount/i18n/es.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2020-07-27 10:19+0000\n" +"Last-Translator: Daniel Martinez Vila \n" +"Language-Team: none\n" +"Language: es\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 3.10\n" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "Descuento total" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "Órdenes de venta" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línea pedido de venta" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Subtotal Without Discount" +msgstr "Total Sin Descuento" diff --git a/sale_discount_display_amount/i18n/es_ES.po b/sale_discount_display_amount/i18n/es_ES.po new file mode 100644 index 00000000000..1b7f8791f4d --- /dev/null +++ b/sale_discount_display_amount/i18n/es_ES.po @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es_ES\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_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Subtotal Without Discount" +msgstr "" diff --git a/sale_discount_display_amount/i18n/fr.po b/sale_discount_display_amount/i18n/fr.po new file mode 100644 index 00000000000..3617857ef51 --- /dev/null +++ b/sale_discount_display_amount/i18n/fr.po @@ -0,0 +1,81 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-22 09:19+0000\n" +"PO-Revision-Date: 2024-02-22 09:19+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,help:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,help:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Check this field to show the Discount with TAX" +msgstr "Cochez ce champ pour afficher la remise avec TAXE" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_company +msgid "Companies" +msgstr "Entreprises" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "Sous-total des remises" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +msgid "Discount total" +msgstr "Total des remises" + +#. module: sale_discount_display_amount +#: model_terms:ir.ui.view,arch_db:sale_discount_display_amount.res_config_settings_view_form +msgid "" +"OFF = Shows the Discount without TAX
ON = Shows the Discount with TAX" +msgstr "" +"OFF = Affiche la remise sans TAXE
ON = Affiche la remise avec TAXE" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "Commande de vente" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_company__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Show the Discount with TAX" +msgstr "Afficher la remise avec la TAXE" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_subtotal_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_subtotal_no_discount +msgid "Subtotal Without Discount" +msgstr "Sous-total sans remise" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Total Without Discount" +msgstr "Total sans remise" diff --git a/sale_discount_display_amount/i18n/it.po b/sale_discount_display_amount/i18n/it.po new file mode 100644 index 00000000000..2c31cd27e36 --- /dev/null +++ b/sale_discount_display_amount/i18n/it.po @@ -0,0 +1,48 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-09-02 18:13+0000\n" +"Last-Translator: Francesco Foresti \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 4.17\n" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "Subtotale sconto" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "Ordine di vendita" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "Riga ordine di vendita" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Subtotal Without Discount" +msgstr "Subtotale senza sconto" + +#~ msgid "Display Name" +#~ msgstr "Nome visualizzato" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" diff --git a/sale_discount_display_amount/i18n/nl.po b/sale_discount_display_amount/i18n/nl.po new file mode 100644 index 00000000000..423a3378a37 --- /dev/null +++ b/sale_discount_display_amount/i18n/nl.po @@ -0,0 +1,81 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-22 09:19+0000\n" +"PO-Revision-Date: 2024-02-22 09:19+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,help:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,help:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Check this field to show the Discount with TAX" +msgstr "Vink dit veld aan om de Korting met BTW weer te geven" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_company +msgid "Companies" +msgstr "Bedrijven" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "Subtotaal Korting" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +msgid "Discount total" +msgstr "Totaal Korting" + +#. module: sale_discount_display_amount +#: model_terms:ir.ui.view,arch_db:sale_discount_display_amount.res_config_settings_view_form +msgid "" +"OFF = Shows the Discount without TAX
ON = Shows the Discount with TAX" +msgstr "" +"OFF = toont de korting zonder BTW
ON = toont de korting met BTW" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "Verkooporder" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "Verkooporderlijn" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_company__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Show the Discount with TAX" +msgstr "Toon de korting met BTW" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_subtotal_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_subtotal_no_discount +msgid "Subtotal Without Discount" +msgstr "Subtotaal zonder korting" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Total Without Discount" +msgstr "Totaal zonder korting" diff --git a/sale_discount_display_amount/i18n/sale_discount_display_amount.pot b/sale_discount_display_amount/i18n/sale_discount_display_amount.pot new file mode 100644 index 00000000000..d547320bec8 --- /dev/null +++ b/sale_discount_display_amount/i18n/sale_discount_display_amount.pot @@ -0,0 +1,79 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-22 09:19+0000\n" +"PO-Revision-Date: 2024-02-22 09:19+0000\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_discount_display_amount +#: model:ir.model.fields,help:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,help:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Check this field to show the Discount with TAX" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_company +msgid "Companies" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_subtotal +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +msgid "Discount total" +msgstr "" + +#. module: sale_discount_display_amount +#: model_terms:ir.ui.view,arch_db:sale_discount_display_amount.res_config_settings_view_form +msgid "" +"OFF = Shows the Discount without TAX
ON = Shows the Discount with TAX" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_company__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_res_config_settings__display_discount_with_tax +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__display_discount_with_tax +msgid "Show the Discount with TAX" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_subtotal_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_subtotal_no_discount +msgid "Subtotal Without Discount" +msgstr "" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Total Without Discount" +msgstr "" diff --git a/sale_discount_display_amount/i18n/zh_CN.po b/sale_discount_display_amount/i18n/zh_CN.po new file mode 100644 index 00000000000..c1d154cac86 --- /dev/null +++ b/sale_discount_display_amount/i18n/zh_CN.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_discount_display_amount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-09-01 09:03+0000\n" +"Last-Translator: 黎伟杰 <674416404@qq.com>\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.8\n" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__discount_total +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__discount_total +msgid "Discount Subtotal" +msgstr "折扣小计" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order +#, fuzzy +msgid "Sales Order" +msgstr "销售订单" + +#. module: sale_discount_display_amount +#: model:ir.model,name:sale_discount_display_amount.model_sale_order_line +msgid "Sales Order Line" +msgstr "销售订单行" + +#. module: sale_discount_display_amount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order__price_total_no_discount +#: model:ir.model.fields,field_description:sale_discount_display_amount.field_sale_order_line__price_total_no_discount +msgid "Subtotal Without Discount" +msgstr "没有折扣的小计" diff --git a/sale_discount_display_amount/models/__init__.py b/sale_discount_display_amount/models/__init__.py new file mode 100644 index 00000000000..a475b71bd4e --- /dev/null +++ b/sale_discount_display_amount/models/__init__.py @@ -0,0 +1,4 @@ +from . import res_company +from . import res_config_settings +from . import sale_order +from . import sale_order_line diff --git a/sale_discount_display_amount/models/res_company.py b/sale_discount_display_amount/models/res_company.py new file mode 100644 index 00000000000..03542ba9eb2 --- /dev/null +++ b/sale_discount_display_amount/models/res_company.py @@ -0,0 +1,7 @@ +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + display_discount_with_tax = fields.Boolean(Name="Show the Discount with TAX") diff --git a/sale_discount_display_amount/models/res_config_settings.py b/sale_discount_display_amount/models/res_config_settings.py new file mode 100644 index 00000000000..7fa58c87351 --- /dev/null +++ b/sale_discount_display_amount/models/res_config_settings.py @@ -0,0 +1,12 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + display_discount_with_tax = fields.Boolean( + Name="Show the Discount with TAX", + help="Check this field to show the Discount with TAX", + related="company_id.display_discount_with_tax", + readonly=False, + ) diff --git a/sale_discount_display_amount/models/sale_order.py b/sale_discount_display_amount/models/sale_order.py new file mode 100644 index 00000000000..1792bb2225a --- /dev/null +++ b/sale_discount_display_amount/models/sale_order.py @@ -0,0 +1,67 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + display_discount_with_tax = fields.Boolean( + name="Show the Discount with TAX", + help="Check this field to show the Discount with TAX", + related="company_id.display_discount_with_tax", + ) + discount_total = fields.Monetary( + compute="_compute_discount_total", + name="Discount total", + currency_field="currency_id", + store=True, + ) + discount_subtotal = fields.Monetary( + compute="_compute_discount_total", + name="Discount Subtotal", + currency_field="currency_id", + store=True, + ) + price_subtotal_no_discount = fields.Monetary( + compute="_compute_discount_total", + name="Subtotal Without Discount", + currency_field="currency_id", + store=True, + ) + price_total_no_discount = fields.Monetary( + compute="_compute_discount_total", + name="Total Without Discount", + currency_field="currency_id", + store=True, + ) + + @api.model + def _get_compute_discount_total_depends(self): + return [ + "order_line.discount_total", + "order_line.discount_subtotal", + "order_line.price_subtotal_no_discount", + "order_line.price_total_no_discount", + ] + + @api.depends(lambda self: self._get_compute_discount_total_depends()) + def _compute_discount_total(self): + for order in self: + discount_total = sum(order.order_line.mapped("discount_total")) + discount_subtotal = sum(order.order_line.mapped("discount_subtotal")) + price_subtotal_no_discount = sum( + order.order_line.mapped("price_subtotal_no_discount") + ) + price_total_no_discount = sum( + order.order_line.mapped("price_total_no_discount") + ) + order.update( + { + "discount_total": discount_total, + "discount_subtotal": discount_subtotal, + "price_subtotal_no_discount": price_subtotal_no_discount, + "price_total_no_discount": price_total_no_discount, + } + ) diff --git a/sale_discount_display_amount/models/sale_order_line.py b/sale_discount_display_amount/models/sale_order_line.py new file mode 100644 index 00000000000..1fbdef520e3 --- /dev/null +++ b/sale_discount_display_amount/models/sale_order_line.py @@ -0,0 +1,75 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + discount_total = fields.Monetary( + compute="_compute_amount", + Name="Discount Subtotal", + store=True, + precompute=True, + ) + discount_subtotal = fields.Monetary( + compute="_compute_amount", + Name="Discount Subtotal", + store=True, + precompute=True, + ) + price_subtotal_no_discount = fields.Monetary( + compute="_compute_amount", + Name="Subtotal Without Discount", + store=True, + precompute=True, + ) + price_total_no_discount = fields.Monetary( + compute="_compute_amount", + Name="Total Without Discount", + store=True, + precompute=True, + ) + + def _update_discount_display_fields(self): + for line in self: + line.price_subtotal_no_discount = 0 + line.price_total_no_discount = 0 + line.discount_total = 0 + if not line.discount: + line.price_subtotal_no_discount = line.price_subtotal + line.price_total_no_discount = line.price_total + continue + price = line.price_unit + 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, + ) + + price_subtotal_no_discount = taxes["total_excluded"] + price_total_no_discount = taxes["total_included"] + discount_total = price_total_no_discount - line.price_total + discount_subtotal = price_subtotal_no_discount - line.price_subtotal + + line.update( + { + "discount_total": discount_total, + "discount_subtotal": discount_subtotal, + "price_subtotal_no_discount": price_subtotal_no_discount, + "price_total_no_discount": price_total_no_discount, + } + ) + + @api.model + def _get_compute_amount_depends(self): + return ["product_uom_qty", "discount", "price_unit", "tax_id"] + + @api.depends(lambda self: self._get_compute_amount_depends()) + def _compute_amount(self): + res = super()._compute_amount() + self._update_discount_display_fields() + return res diff --git a/sale_discount_display_amount/pyproject.toml b/sale_discount_display_amount/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/sale_discount_display_amount/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/sale_discount_display_amount/readme/CONFIGURE.rst b/sale_discount_display_amount/readme/CONFIGURE.rst new file mode 100644 index 00000000000..b305aaac603 --- /dev/null +++ b/sale_discount_display_amount/readme/CONFIGURE.rst @@ -0,0 +1,4 @@ +To configure this module, you need to: + +#. Go to Sales/Settings and check "Allow discounts on sales order lines" +#. Go to Sales/Settings and check or uncheck "Show the Discount with TAX" depending on your needs diff --git a/sale_discount_display_amount/readme/CONTRIBUTORS.rst b/sale_discount_display_amount/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..839fa44b74e --- /dev/null +++ b/sale_discount_display_amount/readme/CONTRIBUTORS.rst @@ -0,0 +1,9 @@ +* Cédric Pigeon +* Abraham Anes +* Chafique Delli +* Ruchir Shukla +* Manuel Regidor + +* `Pesol `__: + + * Jonathan Oscategui Taza diff --git a/sale_discount_display_amount/readme/DESCRIPTION.rst b/sale_discount_display_amount/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..3bbebf6d948 --- /dev/null +++ b/sale_discount_display_amount/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +In standard Odoo only display the rate of the discount applied, never the +amount. It could be great to be able to tell the customer how much he spares. +This is the goal of this addons, it will show on a sale +order the total without the discount and the value of the discount. +You can choose if you want the discount on the Total with or the Total without TAX. diff --git a/sale_discount_display_amount/readme/USAGE.rst b/sale_discount_display_amount/readme/USAGE.rst new file mode 100644 index 00000000000..105f71c2035 --- /dev/null +++ b/sale_discount_display_amount/readme/USAGE.rst @@ -0,0 +1,5 @@ +To use this module, you need to: + +#. Go on a sale order +#. Set a discount on a line +#. The value of the discount is dislayed in the total section as well as the total without it. diff --git a/sale_discount_display_amount/static/description/icon.png b/sale_discount_display_amount/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/sale_discount_display_amount/static/description/icon.png differ diff --git a/sale_discount_display_amount/static/description/index.html b/sale_discount_display_amount/static/description/index.html new file mode 100644 index 00000000000..e74260a0c0a --- /dev/null +++ b/sale_discount_display_amount/static/description/index.html @@ -0,0 +1,533 @@ + + + + + + + Sale Discount Display Amount + + + +
+

Sale Discount Display Amount

+ + +

+ + Beta + + + License: AGPL-3 + + + OCA/sale-workflow + + + Translate me on Weblate + + + Try me on Runboat + +

+

In standard Odoo only display the rate of the discount applied, never the + amount. It could be great to be able to tell the customer how much he spares. + This is the goal of this addons, it will show on a sale + order the total without the discount and the value of the discount. +

+

+ Table of contents +

+
+ +
+
+

+ Configuration +

+

To configure this module, you need to:

+
    +
  1. Go to Sales/Settings and check “Allow discounts on sales order lines”
  2. +
+
+
+

+ Usage +

+

To use this module, you need to:

+
    +
  1. Go on a sale order
  2. +
  3. Set a discount on a line
  4. +
  5. The value of the discount is dislayed in the total section as well as the total without it.
  6. +
+
+
+

+ 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 +

+
    +
  • ACSONE SA/NV
  • +
+
+
+

+ Contributors +

+ +
+
+

+ 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/sale-workflow + + project on GitHub. +

+

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

+
+
+
+ + diff --git a/sale_discount_display_amount/tests/__init__.py b/sale_discount_display_amount/tests/__init__.py new file mode 100644 index 00000000000..b1f57a33cd5 --- /dev/null +++ b/sale_discount_display_amount/tests/__init__.py @@ -0,0 +1 @@ +from . import test_discount_display_amount diff --git a/sale_discount_display_amount/tests/test_discount_display_amount.py b/sale_discount_display_amount/tests/test_discount_display_amount.py new file mode 100644 index 00000000000..88d6f3223d4 --- /dev/null +++ b/sale_discount_display_amount/tests/test_discount_display_amount.py @@ -0,0 +1,42 @@ +# Copyright 2018 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestDiscountDisplay(TransactionCase): + def test_sale_discount_value(self): + product1 = self.env["product.product"].create( + {"name": "Product TEST", "type": "consu"} + ) + customer = self.env["res.partner"].create( + {"name": "Customer TEST", "is_company": False, "email": "test@tes.ttest"} + ) + so = self.env["sale.order"].create({"partner_id": customer.id}) + self.env["sale.order.line"].create( + {"order_id": so.id, "product_id": product1.id, "price_unit": 30.75} + ) + + first_line = so.order_line[0] + first_line.discount = 10 + self.assertAlmostEqual(first_line.price_subtotal_no_discount, 30.75) + self.assertAlmostEqual(first_line.price_total_no_discount, 35.36) + self.assertAlmostEqual(first_line.discount_total, 3.53) + self.assertAlmostEqual(so.price_subtotal_no_discount, 30.75) + self.assertAlmostEqual(so.price_total_no_discount, 35.36) + self.assertAlmostEqual(so.discount_total, 3.53) + self.assertAlmostEqual(so.discount_subtotal, 3.07) + + def test_sale_without_discount_value(self): + product2 = self.env["product.product"].create( + {"name": "Product TEST", "type": "consu"} + ) + customer2 = self.env["res.partner"].create( + {"name": "Customer TEST", "is_company": False, "email": "test@tes.ttest"} + ) + so2 = self.env["sale.order"].create({"partner_id": customer2.id}) + self.env["sale.order.line"].create( + {"order_id": so2.id, "product_id": product2.id, "price_unit": 30.75} + ) + first_line = so2.order_line[0] + self.assertEqual(first_line.price_total_no_discount, first_line.price_total) diff --git a/sale_discount_display_amount/views/res_config_settings_views.xml b/sale_discount_display_amount/views/res_config_settings_views.xml new file mode 100644 index 00000000000..072b208ae6d --- /dev/null +++ b/sale_discount_display_amount/views/res_config_settings_views.xml @@ -0,0 +1,29 @@ + + + + + res.config.settings.view.form.display.discount + res.config.settings + + + + +
+
+ +
+
+
+
+
+
+
+
diff --git a/sale_discount_display_amount/views/sale_view.xml b/sale_discount_display_amount/views/sale_view.xml new file mode 100644 index 00000000000..38146dd8a2f --- /dev/null +++ b/sale_discount_display_amount/views/sale_view.xml @@ -0,0 +1,44 @@ + + + + sale.order + + 99 + + + + + + + + + + + + + + + + + +