diff --git a/.pylintrc b/.pylintrc index f3d017a8f..a7aec2a05 100644 --- a/.pylintrc +++ b/.pylintrc @@ -92,20 +92,11 @@ enable=anomalous-backslash-in-string, no-write-in-compute, # messages that do not cause the lint step to fail consider-merging-classes-inherited, - create-user-wo-reset-password, - dangerous-filter-wo-user, deprecated-module, - file-not-used, invalid-commit, - missing-manifest-dependency, - missing-newline-extrafiles, missing-readme, - no-utf8-coding-comment, odoo-addons-relative-import, - old-api7-method-defined, redefined-builtin, - too-complex, - unnecessary-utf8-coding-comment, manifest-external-assets diff --git a/account_invoice_margin/README.rst b/account_invoice_margin/README.rst new file mode 100644 index 000000000..d661eff92 --- /dev/null +++ b/account_invoice_margin/README.rst @@ -0,0 +1,136 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +====================== +Account Invoice Margin +====================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7adca1b38d24a7449a19e13ac1a138558b8e5f6b07663158039a37391142913b + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png + :target: https://odoo-community.org/page/development-status + :alt: Production/Stable +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fmargin--analysis-lightgray.png?logo=github + :target: https://github.com/OCA/margin-analysis/tree/19.0/account_invoice_margin + :alt: OCA/margin-analysis +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/margin-analysis-19-0/margin-analysis-19-0-account_invoice_margin + :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/margin-analysis&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to show sales margin in invoices. + +The new information is available: + +- on the invoice form view + +|image1| + +- and on the invoice tree view + +|image2| + +.. |image1| image:: https://raw.githubusercontent.com/OCA/margin-analysis/19.0/account_invoice_margin/static/description/account_invoice_form.png +.. |image2| image:: https://raw.githubusercontent.com/OCA/margin-analysis/19.0/account_invoice_margin/static/description/account_invoice_tree.png + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +This module also adds a security group. + +1. To activate it go to user and active "Show Invoice Margin" in + security options. + +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 +------- + +* Tecnativa +* GRAP + +Contributors +------------ + +- `Tecnativa `__: + + - Sergio Teruel + +- `GRAP `__: + + - Sylvain LE GAL (https://twitter.com/legalsylvain) + +- `Open Source Integrators `__: + + - Bhavesh Odedra + +- `Avoin.Systems `__: + + - Nedas Žilinskas + +- `Factor Libre `__: + + - Luis J. Salvatierra + +- `Komit `__: + + - Jean-Charles Drubay + +- `Heliconia Solutions Pvt. Ltd. `__ + + - Bhavesh Heliconia + +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. + +.. |maintainer-sergio-teruel| image:: https://github.com/sergio-teruel.png?size=40px + :target: https://github.com/sergio-teruel + :alt: sergio-teruel + +Current `maintainer `__: + +|maintainer-sergio-teruel| + +This module is part of the `OCA/margin-analysis `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_invoice_margin/__init__.py b/account_invoice_margin/__init__.py new file mode 100644 index 000000000..e8310c451 --- /dev/null +++ b/account_invoice_margin/__init__.py @@ -0,0 +1,6 @@ +# © 2017 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from .hooks import pre_init_hook +from . import models +from . import report diff --git a/account_invoice_margin/__manifest__.py b/account_invoice_margin/__manifest__.py new file mode 100644 index 000000000..ed4afaa02 --- /dev/null +++ b/account_invoice_margin/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2017 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Account Invoice Margin", + "summary": "Show margin in invoices", + "version": "19.0.1.0.0", + "category": "Account", + "website": "https://github.com/OCA/margin-analysis", + "author": "Tecnativa, GRAP, Odoo Community Association (OCA)", + "license": "AGPL-3", + "development_status": "Production/Stable", + "maintainers": ["sergio-teruel"], + "application": False, + "installable": True, + "depends": ["account"], + "data": [ + "security/account_invoice_margin_security.xml", + "views/account_invoice_margin_view.xml", + ], + "pre_init_hook": "pre_init_hook", +} diff --git a/account_invoice_margin/hooks.py b/account_invoice_margin/hooks.py new file mode 100644 index 000000000..c1abc6ac2 --- /dev/null +++ b/account_invoice_margin/hooks.py @@ -0,0 +1,57 @@ +import logging + +from odoo.tools.sql import column_exists, create_column + +_logger = logging.getLogger(__name__) + +COLUMNS = ( + ("account_move", "margin"), + ("account_move", "margin_signed"), + ("account_move", "margin_percent"), + ("account_move_line", "margin"), + ("account_move_line", "margin_signed"), + ("account_move_line", "margin_percent"), + ("account_move_line", "purchase_price"), +) + + +def pre_init_hook(env): + cr = env.cr + for table, column in COLUMNS: + if not column_exists(cr, table, column): + _logger.info("Create column %s in database", column) + create_column(cr, table, column, "numeric") + cr.execute( + """ + WITH am AS( + SELECT id FROM account_move WHERE move_type NOT ILIKE 'in_%' + ) + UPDATE account_move_line + SET margin = price_subtotal, margin_signed = price_subtotal, + margin_percent = 100 + FROM am + WHERE am.id = account_move_line.move_id + AND price_subtotal > 0.0; + """ + ) + cr.execute( + """ + WITH aml AS( + SELECT + account_move_line.move_id, + SUM(account_move_line.margin) AS sum_margin, + SUM(account_move_line.margin_signed) AS sum_margin_signed + FROM account_move_line + INNER JOIN account_move + ON account_move.id = account_move_line.move_id + GROUP BY account_move_line.move_id + ) + UPDATE account_move + SET margin = aml.sum_margin, + margin_signed = aml.sum_margin_signed, + margin_percent = aml.sum_margin_signed / amount_untaxed * 100 + FROM aml + WHERE account_move.id = aml.move_id + AND account_move.amount_untaxed > 0.0 + """ + ) diff --git a/account_invoice_margin/i18n/account_invoice_margin.pot b/account_invoice_margin/i18n/account_invoice_margin.pot new file mode 100644 index 000000000..797f87720 --- /dev/null +++ b/account_invoice_margin/i18n/account_invoice_margin.pot @@ -0,0 +1,70 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_invoice_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.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: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__purchase_price +msgid "Cost" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin +msgid "Margin" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_percent +msgid "Margin (%)" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_invoice_report__margin +msgid "Margin Analysis" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_signed +msgid "Margin Signed" +msgstr "" + +#. module: account_invoice_margin +#: model:res.groups,name:account_invoice_margin.group_account_invoice_margin_security +msgid "Show Invoice Margin" +msgstr "" + +#. module: account_invoice_margin +#: model_terms:ir.ui.view,arch_db:account_invoice_margin.view_account_invoice_tree +msgid "Total" +msgstr "" diff --git a/account_invoice_margin/i18n/es.po b/account_invoice_margin/i18n/es.po new file mode 100644 index 000000000..3f15f47cb --- /dev/null +++ b/account_invoice_margin/i18n/es.po @@ -0,0 +1,87 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_invoice_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-12-04 13:11+0000\n" +"PO-Revision-Date: 2023-10-12 13:38+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__purchase_price +msgid "Cost" +msgstr "Coste" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "Estadísticas de facturas" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move +msgid "Journal Entry" +msgstr "Entrada diaria" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move_line +msgid "Journal Item" +msgstr "Apunte Contable" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_invoice_report__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin +msgid "Margin" +msgstr "Margen" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_percent +msgid "Margin (%)" +msgstr "Margen (%)" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_signed +msgid "Margin Signed" +msgstr "Margen firmado" + +#. module: account_invoice_margin +#: model:res.groups,name:account_invoice_margin.group_account_invoice_margin_security +msgid "Show Invoice Margin" +msgstr "Mostrar margen en facturas" + +#. module: account_invoice_margin +#: model_terms:ir.ui.view,arch_db:account_invoice_margin.view_account_invoice_tree +msgid "Total" +msgstr "Total" + +#~ msgid "Journal Entries" +#~ msgstr "Asientos Contables" + +#, fuzzy +#~| msgid "Invoice Line" +#~ msgid "Invoice" +#~ msgstr "Línea factura" + +#~ msgid "Invoice Line" +#~ msgstr "Línea factura" + +#~ msgid "% Margin" +#~ msgstr "% Margen" diff --git a/account_invoice_margin/i18n/fr.po b/account_invoice_margin/i18n/fr.po new file mode 100644 index 000000000..616e94e91 --- /dev/null +++ b/account_invoice_margin/i18n/fr.po @@ -0,0 +1,82 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_invoice_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-12-11 17:47+0000\n" +"PO-Revision-Date: 2023-06-05 18:09+0000\n" +"Last-Translator: \"Sandrine (ACSONE)\" \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: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__purchase_price +msgid "Cost" +msgstr "Coût" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "Statistiques des factures" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move_line +msgid "Journal Item" +msgstr "Ecriture comptable" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_invoice_report__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin +msgid "Margin" +msgstr "Marge" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_percent +msgid "Margin (%)" +msgstr "Marge (%)" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_signed +msgid "Margin Signed" +msgstr "Marge" + +#. module: account_invoice_margin +#: model:res.groups,name:account_invoice_margin.group_account_invoice_margin_security +msgid "Show Invoice Margin" +msgstr "Voir la marge sur les factures" + +#. module: account_invoice_margin +#: model_terms:ir.ui.view,arch_db:account_invoice_margin.view_account_invoice_tree +msgid "Total" +msgstr "Total" + +#~ msgid "Journal Entries" +#~ msgstr "Pièces comptables" + +#~ msgid "Invoice" +#~ msgstr "Facture" + +#~ msgid "Invoice Line" +#~ msgstr "Ligne de facture" diff --git a/account_invoice_margin/i18n/fr_FR.po b/account_invoice_margin/i18n/fr_FR.po new file mode 100644 index 000000000..97825dc2b --- /dev/null +++ b/account_invoice_margin/i18n/fr_FR.po @@ -0,0 +1,72 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_invoice_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-06-05 18:09+0000\n" +"Last-Translator: \"Sandrine (ACSONE)\" \n" +"Language-Team: none\n" +"Language: fr_FR\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: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__purchase_price +msgid "Cost" +msgstr "Coût" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "Statistiques des factures" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move +msgid "Journal Entry" +msgstr "Pièce comptable" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move_line +msgid "Journal Item" +msgstr "Ecriture comptable" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_invoice_report__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin +msgid "Margin" +msgstr "Marge" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_percent +msgid "Margin (%)" +msgstr "Marge (%)" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_signed +msgid "Margin Signed" +msgstr "Marge signée" + +#. module: account_invoice_margin +#: model:res.groups,name:account_invoice_margin.group_account_invoice_margin_security +msgid "Show Invoice Margin" +msgstr "Montrer la marge sur la facture" + +#. module: account_invoice_margin +#: model_terms:ir.ui.view,arch_db:account_invoice_margin.view_account_invoice_tree +msgid "Total" +msgstr "Total" diff --git a/account_invoice_margin/i18n/it.po b/account_invoice_margin/i18n/it.po new file mode 100644 index 000000000..ba6b845ab --- /dev/null +++ b/account_invoice_margin/i18n/it.po @@ -0,0 +1,72 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_invoice_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-02-06 09:36+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 4.17\n" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__purchase_price +msgid "Cost" +msgstr "Costo" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "Statistiche fatture" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move +msgid "Journal Entry" +msgstr "Registrazione contabile" + +#. module: account_invoice_margin +#: model:ir.model,name:account_invoice_margin.model_account_move_line +msgid "Journal Item" +msgstr "Movimento contabile" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_invoice_report__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin +msgid "Margin" +msgstr "Margine" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_percent +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_percent +msgid "Margin (%)" +msgstr "Margine (%)" + +#. module: account_invoice_margin +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_bank_statement_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_move_line__margin_signed +#: model:ir.model.fields,field_description:account_invoice_margin.field_account_payment__margin_signed +msgid "Margin Signed" +msgstr "Margine approvato" + +#. module: account_invoice_margin +#: model:res.groups,name:account_invoice_margin.group_account_invoice_margin_security +msgid "Show Invoice Margin" +msgstr "Mostra margine fattura" + +#. module: account_invoice_margin +#: model_terms:ir.ui.view,arch_db:account_invoice_margin.view_account_invoice_tree +msgid "Total" +msgstr "Totale" diff --git a/account_invoice_margin/models/__init__.py b/account_invoice_margin/models/__init__.py new file mode 100644 index 000000000..06ea9c09e --- /dev/null +++ b/account_invoice_margin/models/__init__.py @@ -0,0 +1,4 @@ +# © 2017 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import account_invoice diff --git a/account_invoice_margin/models/account_invoice.py b/account_invoice_margin/models/account_invoice.py new file mode 100644 index 000000000..d946fe96e --- /dev/null +++ b/account_invoice_margin/models/account_invoice.py @@ -0,0 +1,127 @@ +# Copyright 2017 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class AccountMove(models.Model): + _inherit = "account.move" + + margin = fields.Monetary( + compute="_compute_margin", + store=True, + currency_field="currency_id", + ) + + margin_signed = fields.Monetary( + compute="_compute_margin", + store=True, + currency_field="currency_id", + ) + + margin_percent = fields.Float( + string="Margin (%)", + digits="Product Price", + compute="_compute_margin", + store=True, + ) + + def _get_margin_applicable_lines(self): + self.ensure_one() + return self.invoice_line_ids + + @api.depends( + "invoice_line_ids.margin", + "invoice_line_ids.margin_signed", + "invoice_line_ids.price_subtotal", + ) + def _compute_margin(self): + for invoice in self: + if not invoice.is_invoice(): + continue + margin = 0.0 + margin_signed = 0.0 + price_subtotal = 0.0 + for line in invoice._get_margin_applicable_lines(): + margin += line.margin + margin_signed += line.margin_signed + price_subtotal += line.price_subtotal + invoice.margin = margin + invoice.margin_signed = margin_signed + invoice.margin_percent = ( + price_subtotal and margin_signed / price_subtotal * 100 or 0.0 + ) + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + margin = fields.Float(compute="_compute_margin", digits="Product Price", store=True) + margin_signed = fields.Float( + compute="_compute_margin", + digits="Product Price", + store=True, + ) + margin_percent = fields.Float( + string="Margin (%)", compute="_compute_margin", store=True, readonly=True + ) + purchase_price = fields.Float( + string="Cost", + compute="_compute_purchase_price", + store=True, + readonly=False, + digits="Product Price", + ) + + @api.depends("purchase_price", "price_subtotal") + def _compute_margin(self): + for line in self: + if not line.move_id.is_invoice(): + continue + if line.move_id and line.move_id.is_purchase_document(): + line.update( + {"margin": 0.0, "margin_signed": 0.0, "margin_percent": 0.0} + ) + continue + tmp_margin = line.price_subtotal - (line.purchase_price * line.quantity) + sign = line.move_id.move_type == "out_refund" and -1 or 1 + line.update( + { + "margin": tmp_margin, + "margin_signed": tmp_margin * sign, + "margin_percent": ( + tmp_margin / line.price_subtotal * 100.0 + if line.price_subtotal + else 0.0 + ), + } + ) + + def _get_purchase_price(self): + # Overwrite this function if you don't want to base your + # purchase price on the product standard_price + self.ensure_one() + return self.product_id.standard_price + + @api.depends("product_id", "product_uom_id") + def _compute_purchase_price(self): + for line in self: + if not line.move_id.is_invoice(): + continue + if line.move_id.is_sale_document(): + purchase_price = line._get_purchase_price() + if line.product_uom_id != line.product_id.uom_id: + purchase_price = line.product_id.uom_id._compute_price( + purchase_price, line.product_uom_id + ) + move = line.move_id + company = move.company_id or self.env.company + line.purchase_price = company.currency_id._convert( + purchase_price, + move.currency_id, + company, + move.invoice_date or fields.Date.today(), + round=False, + ) + else: + line.purchase_price = 0.0 diff --git a/account_invoice_margin/pyproject.toml b/account_invoice_margin/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/account_invoice_margin/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/account_invoice_margin/readme/CONTRIBUTORS.md b/account_invoice_margin/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..84702930a --- /dev/null +++ b/account_invoice_margin/readme/CONTRIBUTORS.md @@ -0,0 +1,14 @@ +- [Tecnativa](https://www.tecnativa.com): + - Sergio Teruel +- [GRAP](http://www.grap.coop): + - Sylvain LE GAL () +- [Open Source Integrators](https://www.opensourceintegrators.com): + - Bhavesh Odedra +- [Avoin.Systems](https://www.avoin.systems): + - Nedas Žilinskas +- [Factor Libre](https://factorlibre.com): + - Luis J. Salvatierra +- [Komit](https://komit-consulting.com): + - Jean-Charles Drubay +- [Heliconia Solutions Pvt. Ltd.](https://www.heliconia.io) + - Bhavesh Heliconia diff --git a/account_invoice_margin/readme/DESCRIPTION.md b/account_invoice_margin/readme/DESCRIPTION.md new file mode 100644 index 000000000..cfb62af34 --- /dev/null +++ b/account_invoice_margin/readme/DESCRIPTION.md @@ -0,0 +1,11 @@ +This module allows to show sales margin in invoices. + +The new information is available: + +- on the invoice form view + +![](../static/description/account_invoice_form.png) + +- and on the invoice tree view + +![](../static/description/account_invoice_tree.png) diff --git a/account_invoice_margin/readme/USAGE.md b/account_invoice_margin/readme/USAGE.md new file mode 100644 index 000000000..7482e4fb6 --- /dev/null +++ b/account_invoice_margin/readme/USAGE.md @@ -0,0 +1,4 @@ +This module also adds a security group. + +1. To activate it go to user and active "Show Invoice Margin" in + security options. diff --git a/account_invoice_margin/report/__init__.py b/account_invoice_margin/report/__init__.py new file mode 100644 index 000000000..52e62702b --- /dev/null +++ b/account_invoice_margin/report/__init__.py @@ -0,0 +1 @@ +from . import account_invoice_report diff --git a/account_invoice_margin/report/account_invoice_report.py b/account_invoice_margin/report/account_invoice_report.py new file mode 100644 index 000000000..9a064a699 --- /dev/null +++ b/account_invoice_margin/report/account_invoice_report.py @@ -0,0 +1,14 @@ +# © 2017 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models +from odoo.tools import SQL + + +class AccountInvoiceReport(models.Model): + _inherit = "account.invoice.report" + + margin = fields.Float(readonly=True, string="Margin Analysis") + + def _select(self): + return SQL("%s, line.margin_signed AS margin", super()._select()) diff --git a/account_invoice_margin/security/account_invoice_margin_security.xml b/account_invoice_margin/security/account_invoice_margin_security.xml new file mode 100644 index 000000000..0c173212f --- /dev/null +++ b/account_invoice_margin/security/account_invoice_margin_security.xml @@ -0,0 +1,10 @@ + + + + + Show Invoice Margin + + + + diff --git a/account_invoice_margin/static/description/account_invoice_form.png b/account_invoice_margin/static/description/account_invoice_form.png new file mode 100644 index 000000000..8e580af63 Binary files /dev/null and b/account_invoice_margin/static/description/account_invoice_form.png differ diff --git a/account_invoice_margin/static/description/account_invoice_tree.png b/account_invoice_margin/static/description/account_invoice_tree.png new file mode 100644 index 000000000..4d4f39ef0 Binary files /dev/null and b/account_invoice_margin/static/description/account_invoice_tree.png differ diff --git a/account_invoice_margin/static/description/icon.png b/account_invoice_margin/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/account_invoice_margin/static/description/icon.png differ diff --git a/account_invoice_margin/static/description/index.html b/account_invoice_margin/static/description/index.html new file mode 100644 index 000000000..817c99f5f --- /dev/null +++ b/account_invoice_margin/static/description/index.html @@ -0,0 +1,477 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Account Invoice Margin

+ +

Production/Stable License: AGPL-3 OCA/margin-analysis Translate me on Weblate Try me on Runboat

+

This module allows to show sales margin in invoices.

+

The new information is available:

+
    +
  • on the invoice form view
  • +
+

image1

+
    +
  • and on the invoice tree view
  • +
+

image2

+

Table of contents

+ +
+

Usage

+

This module also adds a security group.

+
    +
  1. To activate it go to user and active “Show Invoice Margin” in +security options.
  2. +
+
+
+

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

+
    +
  • Tecnativa
  • +
  • GRAP
  • +
+
+
+

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.

+

Current maintainer:

+

sergio-teruel

+

This module is part of the OCA/margin-analysis project on GitHub.

+

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

+
+
+
+
+ + diff --git a/account_invoice_margin/tests/__init__.py b/account_invoice_margin/tests/__init__.py new file mode 100644 index 000000000..e36b73435 --- /dev/null +++ b/account_invoice_margin/tests/__init__.py @@ -0,0 +1,4 @@ +# © 2017 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_account_invoice_margin diff --git a/account_invoice_margin/tests/test_account_invoice_margin.py b/account_invoice_margin/tests/test_account_invoice_margin.py new file mode 100644 index 000000000..f996e7713 --- /dev/null +++ b/account_invoice_margin/tests/test_account_invoice_margin.py @@ -0,0 +1,159 @@ +# © 2016 Sergio Teruel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import fields +from odoo.tests import Form, tagged + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon + + +@tagged("post_install", "-at_install") +class TestAccountInvoiceMargin(AccountTestInvoicingCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + # cls.env.user.group_ids |= cls.env.ref( + # "product_cost_security.group_product_edit_cost" + # ) + # cls.env.user.group_ids |= cls.env.ref( + # "product_cost_security.group_product_cost" + # ) + group_edit = cls.env.ref( + "product_cost_security.group_product_edit_cost", raise_if_not_found=False + ) + group_view = cls.env.ref( + "product_cost_security.group_product_cost", raise_if_not_found=False + ) + + if group_edit: + cls.env.user.group_ids |= group_edit + if group_view: + cls.env.user.group_ids |= group_view + + cls.product_a.lst_price = 200 + cls.product_a.standard_price = 100 + cls.invoice = cls.init_invoice( + "out_invoice", + partner=cls.partner_a, + invoice_date=fields.Date.from_string("2017-06-19"), + post=False, + products=cls.product_a, + ) + cls.invoice.invoice_line_ids.quantity = 10 + cls.vendor_bill = cls.init_invoice( + "in_invoice", + partner=cls.partner_a, + invoice_date=fields.Date.from_string("2017-06-19"), + post=False, + products=cls.product_a, + ) + cls.vendor_bill.invoice_line_ids.quantity = 10 + + def test_invoice_margin(self): + self.assertEqual(self.invoice.invoice_line_ids.purchase_price, 100.00) + self.assertEqual(self.invoice.invoice_line_ids.margin, 1000.00) + + self.invoice.invoice_line_ids.with_context( + check_move_validity=False + ).discount = 50 + self.assertEqual(self.invoice.invoice_line_ids.margin, 0.0) + + def test_vendor_bill_margin(self): + self.assertEqual(self.vendor_bill.invoice_line_ids.purchase_price, 0.00) + self.assertEqual(self.vendor_bill.invoice_line_ids.margin, 0.00) + + def test_invoice_margin_uom(self): + inv_line = self.invoice.invoice_line_ids + inv_line.update({"product_uom_id": self.env.ref("uom.product_uom_dozen").id}) + self.assertEqual(inv_line.margin, 12000.00) + + def test_invoice_refund(self): + self.invoice.action_post() + wiz = ( + self.env["account.move.reversal"] + .with_context( + active_model="account.move", + active_ids=self.invoice.ids, + active_id=self.invoice.id, + ) + .create( + { + "reason": "reason test create", + "journal_id": self.invoice.journal_id.id, + } + ) + ) + action = wiz.refund_moves() + new_invoice = self.env["account.move"].browse(action["res_id"]) + self.assertEqual(new_invoice.invoice_line_ids.margin, 1000.00) + self.assertEqual(new_invoice.invoice_line_ids.margin_signed, -1000.00) + + def test_invoice_modify_moves(self): + self.invoice.action_post() + wiz = ( + self.env["account.move.reversal"] + .with_context( + active_model="account.move", + active_ids=self.invoice.ids, + active_id=self.invoice.id, + ) + .create( + { + "reason": "reason test create", + "journal_id": self.invoice.journal_id.id, + } + ) + ) + action = wiz.modify_moves() + new_invoice = self.env["account.move"].browse(action["res_id"]) + self.assertEqual(new_invoice.invoice_line_ids.margin, 1000.00) + self.assertEqual(new_invoice.invoice_line_ids.margin_signed, 1000.00) + + def test_invoice_different_currency(self): + company = self.env.company + currency = self.env["res.currency"].create( + { + "name": "TC1", + "symbol": "T", + "rate_ids": [ + (0, 0, {"company_id": company.id, "name": "2022-01-01", "rate": 2}) + ], + } + ) + company.currency_id.rate_ids.unlink() # avoid odd rates if currency != EUR + move_form = Form( + self.env["account.move"].with_context(default_move_type="out_invoice") + ) + move_form.partner_id = self.partner_a + move_form.currency_id = currency + move_form.invoice_date = "2022-01-01" + with move_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product_a + invoice = move_form.save() + self.assertEqual(invoice.invoice_line_ids.purchase_price, 200) + + def test_invoice_payment_register(self): + invoice = self.invoice.copy() + invoice.action_post() + self.assertEqual(invoice.margin, 1000.0) + self.assertEqual(invoice.margin_signed, 1000.0) + self.assertEqual(invoice.margin_percent, 50.0) + payments = ( + self.env["account.payment.register"] + .with_context( + active_model="account.move", + active_ids=invoice.ids, + ) + .create( + { + "group_payment": False, + } + ) + ._create_payments() + ) + self.assertEqual(1, len(payments)) + self.assertTrue(payments.move_id) + self.assertFalse(payments.move_id.is_invoice()) + self.assertEqual(payments.move_id.amount_total, invoice.amount_total) + self.assertEqual(payments.move_id.margin, 0.0) + self.assertEqual(payments.move_id.margin_signed, 0.0) + self.assertEqual(payments.move_id.margin_percent, 0.0) diff --git a/account_invoice_margin/views/account_invoice_margin_view.xml b/account_invoice_margin/views/account_invoice_margin_view.xml new file mode 100644 index 000000000..b44f65dce --- /dev/null +++ b/account_invoice_margin/views/account_invoice_margin_view.xml @@ -0,0 +1,79 @@ + + + + + account.move + + + + + + + + + + + + + + + + + + + + + + account.move + + + + + + + + +