From 3d645c2993c40693a70d2217582deb36f61f1c14 Mon Sep 17 00:00:00 2001 From: Juan Carlos B Date: Tue, 24 Jan 2023 09:08:31 +0100 Subject: [PATCH] [MIG] pos_margin: Migration to 16.0 --- pos_margin/README.rst | 44 ++++---- pos_margin/__manifest__.py | 20 ++-- pos_margin/i18n/es.po | 85 ++++++++------ pos_margin/i18n/fr.po | 92 --------------- pos_margin/i18n/it.po | 66 ----------- pos_margin/i18n/nl_NL.po | 67 ----------- pos_margin/i18n/pos_margin.pot | 105 ------------------ .../migrations/12.0.2.0.0/pre-migration.py | 18 --- pos_margin/models/__init__.py | 7 +- pos_margin/models/pos_config.py | 2 +- pos_margin/models/pos_order.py | 25 ----- pos_margin/models/pos_order_line.py | 64 ----------- pos_margin/models/res_config_settings.py | 14 +++ pos_margin/readme/CONFIGURE.rst | 4 +- pos_margin/readme/CONTRIBUTORS.rst | 1 + pos_margin/readme/DESCRIPTION.rst | 6 +- pos_margin/readme/HISTORY.rst | 10 ++ pos_margin/readme/USAGE.rst | 17 --- pos_margin/report/__init__.py | 4 + pos_margin/report/pos_order_report.py | 22 +++- pos_margin/static/description/index.html | 18 +-- .../static/description/pos_config_setting.png | Bin 0 -> 60411 bytes .../static/src/js/OrderSummaryMargin.esm.js | 25 +++++ .../static/src/js/OrderSummaryMargin.js | 17 --- pos_margin/static/src/js/OrderWidget.js | 36 ------ pos_margin/static/src/js/models.esm.js | 62 +++++++++++ pos_margin/static/src/js/models.js | 57 ---------- pos_margin/static/src/xml/pos_margin.xml | 22 ++-- pos_margin/tests/__init__.py | 1 - pos_margin/tests/test_module.py | 78 ------------- ...onfig.xml => res_config_settings_view.xml} | 16 +-- pos_margin/views/templates.xml | 22 ---- pos_margin/views/view_pos_order.xml | 24 +--- 33 files changed, 263 insertions(+), 788 deletions(-) delete mode 100644 pos_margin/i18n/fr.po delete mode 100644 pos_margin/i18n/it.po delete mode 100644 pos_margin/i18n/nl_NL.po delete mode 100644 pos_margin/i18n/pos_margin.pot delete mode 100644 pos_margin/migrations/12.0.2.0.0/pre-migration.py delete mode 100644 pos_margin/models/pos_order.py delete mode 100644 pos_margin/models/pos_order_line.py create mode 100644 pos_margin/models/res_config_settings.py create mode 100644 pos_margin/static/description/pos_config_setting.png create mode 100644 pos_margin/static/src/js/OrderSummaryMargin.esm.js delete mode 100644 pos_margin/static/src/js/OrderSummaryMargin.js delete mode 100644 pos_margin/static/src/js/OrderWidget.js create mode 100644 pos_margin/static/src/js/models.esm.js delete mode 100644 pos_margin/static/src/js/models.js delete mode 100644 pos_margin/tests/__init__.py delete mode 100644 pos_margin/tests/test_module.py rename pos_margin/views/{view_pos_config.xml => res_config_settings_view.xml} (52%) delete mode 100644 pos_margin/views/templates.xml diff --git a/pos_margin/README.rst b/pos_margin/README.rst index 2c0075c1d0..6f01ac707d 100644 --- a/pos_margin/README.rst +++ b/pos_margin/README.rst @@ -14,22 +14,18 @@ PoS Order Margin :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github - :target: https://github.com/OCA/pos/tree/14.0/pos_margin + :target: https://github.com/OCA/pos/tree/16.0/pos_margin :alt: OCA/pos .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/pos-14-0/pos-14-0-pos_margin :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/184/14.0 + :target: https://runbot.odoo-community.org/runbot/184/16.0 :alt: Try me on Runbot -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| -This module extends the functionality of point of sale to support margin on -pos orders. - -This gives the profitability by calculating the difference between the Unit -Price and Cost Price. +This module shows margins in PoS frontend during an order creation. **Table of contents** @@ -40,9 +36,9 @@ Configuration ============= * If you want to disable the display of the margin, in the front-office UI, you can - uncheck the check box in the ``pos.config`` form: + uncheck the check box in the ``res.config.settings`` form: -.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_margin/static/description/pos_config_form.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_margin/static/description/pos_config_form.png Usage ===== @@ -52,18 +48,9 @@ Usage * Make an order. Each time a line is added, updated, or deleted, the margin and the margin rate will be updated. -.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_margin/static/description/pos_front_end.png +.. figure:: https://raw.githubusercontent.com/OCA/pos/16.0/pos_margin/static/description/pos_front_end.png :width: 800px -**In the PoS Back Office** - -To use this module, you need to: - -* Go to 'Point Of Sale' / 'Orders' / 'Orders' -* Open an order - -.. figure:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_margin/static/description/pos_order_form.png - :width: 800px Known issues / Roadmap ====================== @@ -74,6 +61,16 @@ for exemple). Changelog ========= +16.0.1.0.0 +~~~~~~~~~~ + +* Migrate to v16.0 +* Remove ``pos.order`` and ``pos.order.line`` funcionality from V14.0. + It's already done by core V16.0. +* Remove tests. +* Create a ``res.config.settings`` field `pos_iface_display_margin` + to display margins in PoS frontend. + 14.0.1.0.0 ~~~~~~~~~~ @@ -95,7 +92,7 @@ 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 smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -114,6 +111,7 @@ Contributors * Wolfgang Pichler * Murtaza Mithaiwala (https://twitter.com/MurtazaMithaiw4) * Dhara Solanki +* Juan Carlos Maintainers ~~~~~~~~~~~ @@ -134,8 +132,8 @@ promote its widespread use. Current `maintainer `__: -|maintainer-legalsylvain| +|maintainer-legalsylvain| -This module is part of the `OCA/pos `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_margin/__manifest__.py b/pos_margin/__manifest__.py index 8b57a8328d..0caee87707 100644 --- a/pos_margin/__manifest__.py +++ b/pos_margin/__manifest__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) +# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "PoS Order Margin", "summary": "Margin on PoS Order", - "version": "14.0.1.0.2", + "version": "16.0.1.0.0", "category": "Point Of Sale", - "author": "GRAP, Odoo Community Association (OCA)", + "author": "GRAP, FactorLibre, Odoo Community Association (OCA)", "maintainers": ["legalsylvain"], "website": "https://github.com/OCA/pos", "license": "AGPL-3", @@ -15,12 +15,16 @@ "point_of_sale", ], "data": [ - "views/templates.xml", - "views/view_pos_config.xml", + "views/res_config_settings_view.xml", "views/view_pos_order.xml", ], - "qweb": [ - "static/src/xml/pos_margin.xml", - ], + "assets": { + "point_of_sale.assets": [ + "pos_margin/static/src/xml/*.xml", + "pos_margin/static/src/js/models.js", + "pos_margin/static/src/js/OrderSummaryMargin.js", + "pos_margin/static/src/css/*.css", + ], + }, "installable": True, } diff --git a/pos_margin/i18n/es.po b/pos_margin/i18n/es.po index b6116868c9..bdc1696137 100644 --- a/pos_margin/i18n/es.po +++ b/pos_margin/i18n/es.po @@ -1,31 +1,45 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * pos_margin +# * pos_margin # -# Translators: -# OCA Transbot , 2017 -# enjolras , 2018 msgid "" msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-03-01 02:01+0000\n" -"PO-Revision-Date: 2018-03-01 02:01+0000\n" -"Last-Translator: enjolras , 2018\n" -"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" -"Language: es\n" +"POT-Creation-Date: 2023-01-22 22:22+0000\n" +"PO-Revision-Date: 2023-01-22 22:22+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: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: \n" #. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line_purchase_price +#: model:ir.model,name:pos_margin.model_res_config_settings +msgid "Config Settings" +msgstr "Opciones de configuración" + +#. module: pos_margin +#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__purchase_price msgid "Cost Price" msgstr "Precio de coste" #. module: pos_margin -#: model:ir.model.fields,help:pos_margin.field_pos_order_margin +#: model:ir.model.fields,field_description:pos_margin.field_pos_config__iface_display_margin +#: model:ir.model.fields,field_description:pos_margin.field_res_config_settings__pos_iface_display_margin +msgid "Diplay Margin" +msgstr "Mostrar margen" + +#. module: pos_margin +#: model:ir.model.fields,help:pos_margin.field_pos_config__iface_display_margin +#: model:ir.model.fields,help:pos_margin.field_res_config_settings__pos_iface_display_margin +#: model_terms:ir.ui.view,arch_db:pos_margin.res_config_settings_view_form_margin_inherit +msgid "Display Margin and Margin Rate in the frontend" +msgstr "Mostrar margen y tasa de margen en el frontend" + +#. module: pos_margin +#: model:ir.model.fields,help:pos_margin.field_pos_order__margin msgid "" "It gives profitability by calculating the difference between the Unit Price " "and the cost price." @@ -34,28 +48,38 @@ msgstr "" "precio de coste." #. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order_line -#, fuzzy -msgid "Lines of Point of Sale Orders" -msgstr "Líneas del punto de venta" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_margin +#: model:ir.model.fields,field_description:pos_margin.field_pos_order__margin +#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__margin msgid "Margin" msgstr "Margen" #. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order_margin_rate -#, fuzzy -msgid "Margin Rate" -msgstr "Margen" +#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__margin_rate +msgid "Margin Rate (%)" +msgstr "Tasa de Margen (%)" #. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order_margin_total -#, fuzzy +#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__margin_total +#: model_terms:ir.ui.view,arch_db:pos_margin.view_pos_order_tree msgid "Margin Total" -msgstr "Margen" +msgstr "Margen total" + +#. module: pos_margin +#. odoo-javascript +#: code:addons/pos_margin/static/src/xml/pos_margin.xml:0 +#, python-format +msgid "Margin:" +msgstr "Margen:" + +#. module: pos_margin +#: model:ir.model,name:pos_margin.model_pos_config +msgid "Point of Sale Configuration" +msgstr "Configuración del TPV" + +#. module: pos_margin +#: model:ir.model,name:pos_margin.model_pos_order_line +msgid "Point of Sale Order Lines" +msgstr "Líneas de Orden de Punto de Venta" #. module: pos_margin #: model:ir.model,name:pos_margin.model_pos_order @@ -64,6 +88,5 @@ msgstr "Pedidos del TPV" #. module: pos_margin #: model:ir.model,name:pos_margin.model_report_pos_order -#, fuzzy -msgid "Point of Sale Orders Statistics" -msgstr "Pedidos del TPV" +msgid "Point of Sale Orders Report" +msgstr "Informe de Órdenes del Punto de Venta" diff --git a/pos_margin/i18n/fr.po b/pos_margin/i18n/fr.po deleted file mode 100644 index 43bbc1e278..0000000000 --- a/pos_margin/i18n/fr.po +++ /dev/null @@ -1,92 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_margin -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-11 14:57+0000\n" -"PO-Revision-Date: 2021-06-11 14:57+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: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__purchase_price -msgid "Cost Price" -msgstr "Prix de revient" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_config__iface_display_margin -msgid "Diplay Margin" -msgstr "Afficher la marge" - -#. module: pos_margin -#: model:ir.model.fields,help:pos_margin.field_pos_config__iface_display_margin -#: model_terms:ir.ui.view,arch_db:pos_margin.view_pos_config_form -msgid "Display Margin and Margin Rate in the frontend" -msgstr "Afficher la marge et le taux de marge sur l'interface tactile" - -#. module: pos_margin -#: model:ir.model.fields,help:pos_margin.field_pos_order__margin -msgid "It gives profitability by calculating the difference between the Unit Price and the cost price." -msgstr "Il donne la rentabilité en calculant la différence entre le prix unitaire et le prix de revient." - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order__margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__margin -msgid "Margin" -msgstr "Marge" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order__margin_percent -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__margin_percent -msgid "Margin (%)" -msgstr "Taux de marque (%)" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__margin_rate -msgid "Margin Rate" -msgstr "Taux de marque" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__margin_total -#: model_terms:ir.ui.view,arch_db:pos_margin.view_pos_order_tree -msgid "Margin Total" -msgstr "Marge Totale" - -#. module: pos_margin -#. openerp-web -#: code:addons/pos_margin/static/src/xml/pos_margin.xml:26 -#, python-format -msgid "Margin:" -msgstr "Marge :" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_config -msgid "Point of Sale Configuration" -msgstr "Paramétrage du point de vente" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order_line -msgid "Point of Sale Order Lines" -msgstr "Lignes des commandes du point de vente" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order -msgid "Point of Sale Orders" -msgstr "Commandes du point de vente" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_report_pos_order -msgid "Point of Sale Orders Report" -msgstr "" - -#. module: pos_margin -#: model_terms:ir.ui.view,arch_db:pos_margin.view_pos_order_tree -msgid "Total" -msgstr "" diff --git a/pos_margin/i18n/it.po b/pos_margin/i18n/it.po deleted file mode 100644 index b000a463f7..0000000000 --- a/pos_margin/i18n/it.po +++ /dev/null @@ -1,66 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_margin -# -# Translators: -# Francesco Fresta , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-03-01 02:01+0000\n" -"PO-Revision-Date: 2023-01-18 11:48+0000\n" -"Last-Translator: Francesco Foresti \n" -"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\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.14.1\n" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line_purchase_price -msgid "Cost Price" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,help:pos_margin.field_pos_order_margin -msgid "" -"It gives profitability by calculating the difference between the Unit Price " -"and the cost price." -msgstr "" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order_line -msgid "Lines of Point of Sale Orders" -msgstr "Righe Ordini del punto vendita" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_margin -msgid "Margin" -msgstr "Margine" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order_margin_rate -#, fuzzy -msgid "Margin Rate" -msgstr "Margine" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order_margin_total -#, fuzzy -msgid "Margin Total" -msgstr "Margine" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order -msgid "Point of Sale Orders" -msgstr "Ordini punto vendita" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_report_pos_order -#, fuzzy -msgid "Point of Sale Orders Statistics" -msgstr "Punto di riordino" diff --git a/pos_margin/i18n/nl_NL.po b/pos_margin/i18n/nl_NL.po deleted file mode 100644 index b560206c61..0000000000 --- a/pos_margin/i18n/nl_NL.po +++ /dev/null @@ -1,67 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_margin -# -# Translators: -# Peter Hageman , 2017 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-30 02:44+0000\n" -"PO-Revision-Date: 2017-05-30 02:44+0000\n" -"Last-Translator: Peter Hageman , 2017\n" -"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/" -"teams/23907/nl_NL/)\n" -"Language: nl_NL\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: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line_purchase_price -msgid "Cost Price" -msgstr "Kostprijs" - -#. module: pos_margin -#: model:ir.model.fields,help:pos_margin.field_pos_order_margin -msgid "" -"It gives profitability by calculating the difference between the Unit Price " -"and the cost price." -msgstr "" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order_line -#, fuzzy -msgid "Lines of Point of Sale Orders" -msgstr "Kassaorders" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_margin -msgid "Margin" -msgstr "Marge" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order_margin_rate -#, fuzzy -msgid "Margin Rate" -msgstr "Marge" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order_margin_total -#, fuzzy -msgid "Margin Total" -msgstr "Marge" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order -msgid "Point of Sale Orders" -msgstr "Kassaorders" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_report_pos_order -#, fuzzy -msgid "Point of Sale Orders Statistics" -msgstr "Kassaorders" diff --git a/pos_margin/i18n/pos_margin.pot b/pos_margin/i18n/pos_margin.pot deleted file mode 100644 index c70a5f6f5f..0000000000 --- a/pos_margin/i18n/pos_margin.pot +++ /dev/null @@ -1,105 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_margin -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.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: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__purchase_price -msgid "Cost Price" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_config__iface_display_margin -msgid "Diplay Margin" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,help:pos_margin.field_pos_config__iface_display_margin -#: model_terms:ir.ui.view,arch_db:pos_margin.view_pos_config_form -msgid "Display Margin and Margin Rate in the frontend" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_config__display_name -#: model:ir.model.fields,field_description:pos_margin.field_pos_order__display_name -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__display_name -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__display_name -msgid "Display Name" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_config__id -#: model:ir.model.fields,field_description:pos_margin.field_pos_order__id -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__id -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__id -msgid "ID" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,help:pos_margin.field_pos_order__margin -msgid "" -"It gives profitability by calculating the difference between the Unit Price " -"and the cost price." -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_config____last_update -#: model:ir.model.fields,field_description:pos_margin.field_pos_order____last_update -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line____last_update -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order____last_update -msgid "Last Modified on" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order__margin -#: model:ir.model.fields,field_description:pos_margin.field_pos_order_line__margin -msgid "Margin" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__margin_rate -msgid "Margin Rate" -msgstr "" - -#. module: pos_margin -#: model:ir.model.fields,field_description:pos_margin.field_report_pos_order__margin_total -#: model_terms:ir.ui.view,arch_db:pos_margin.view_pos_order_tree -msgid "Margin Total" -msgstr "" - -#. module: pos_margin -#. openerp-web -#: code:addons/pos_margin/static/src/xml/pos_margin.xml:0 -#, python-format -msgid "Margin:" -msgstr "" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_config -msgid "Point of Sale Configuration" -msgstr "" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order_line -msgid "Point of Sale Order Lines" -msgstr "" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_pos_order -msgid "Point of Sale Orders" -msgstr "" - -#. module: pos_margin -#: model:ir.model,name:pos_margin.model_report_pos_order -msgid "Point of Sale Orders Report" -msgstr "" diff --git a/pos_margin/migrations/12.0.2.0.0/pre-migration.py b/pos_margin/migrations/12.0.2.0.0/pre-migration.py deleted file mode 100644 index 25bcf902ec..0000000000 --- a/pos_margin/migrations/12.0.2.0.0/pre-migration.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) 2020 - Today: GRAP (http://www.grap.coop) -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - - -def migrate(cr, version): - cr.execute( - """ - ALTER TABLE pos_config - ADD COLUMN iface_display_margin bool; - """ - ) - cr.execute( - """ - UPDATE pos_config - SET iface_display_margin = false; - """ - ) diff --git a/pos_margin/models/__init__.py b/pos_margin/models/__init__.py index 947532d9f5..efaefc2215 100644 --- a/pos_margin/models/__init__.py +++ b/pos_margin/models/__init__.py @@ -1,3 +1,6 @@ +# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from . import pos_config -from . import pos_order -from . import pos_order_line +from . import res_config_settings diff --git a/pos_margin/models/pos_config.py b/pos_margin/models/pos_config.py index dab34d9587..3b7fd635fe 100644 --- a/pos_margin/models/pos_config.py +++ b/pos_margin/models/pos_config.py @@ -1,4 +1,4 @@ -# Copyright (C) 2021 - Today: GRAP (http://www.grap.coop) +# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/pos_margin/models/pos_order.py b/pos_margin/models/pos_order.py deleted file mode 100644 index 6543aa1b83..0000000000 --- a/pos_margin/models/pos_order.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import api, fields, models - - -class PosOrder(models.Model): - _inherit = "pos.order" - - # Columns Section - margin = fields.Float( - "Margin", - compute="_compute_margin", - store=True, - digits="Product Price", - help="It gives profitability by calculating the difference between" - " the Unit Price and the cost price.", - ) - - # Compute Section - @api.depends("lines.margin") - def _compute_margin(self): - for order in self: - order.margin = sum(order.mapped("lines.margin")) diff --git a/pos_margin/models/pos_order_line.py b/pos_margin/models/pos_order_line.py deleted file mode 100644 index addf8fb344..0000000000 --- a/pos_margin/models/pos_order_line.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) -# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import api, fields, models - - -class PosOrderLine(models.Model): - _inherit = "pos.order.line" - - # Columns Section - margin = fields.Float( - "Margin", - compute="_compute_multi_margin", - store=True, - digits="Product Price", - ) - - purchase_price = fields.Float( - "Cost Price", - compute="_compute_multi_margin", - store=True, - digits="Product Price", - ) - - # Compute Section - @api.depends("product_id", "qty", "price_subtotal") - def _compute_multi_margin(self): - for line in self.filtered("product_id"): - purchase_price = self._get_purchase_price(line) - line.purchase_price = purchase_price - if purchase_price: - line.margin = line.price_subtotal - (purchase_price * line.qty) - - @api.model - def _get_purchase_price(self, line): - """Overwrite the method from the module "sale_margin" - (https://github.com/odoo/odoo/blob/14.0/addons/sale_margin/models/sale_order.py#L20)""" - if not line.product_id: - line.purchase_price = 0.0 - line = line.with_company(line.company_id) - product = line.product_id - product_cost = product.standard_price - if not product_cost: - line.purchase_price = 0.0 - fro_cur = product.cost_currency_id - to_cur = line.currency_id or line.order_id.currency_id - if line.product_uom_id and line.product_uom_id != product.uom_id: - product_cost = product.uom_id._compute_price( - product_cost, - line.product_uom, - ) - purchase_price = ( - fro_cur._convert( - from_amount=product_cost, - to_currency=to_cur, - company=line.company_id or self.env.company, - date=line.order_id.date_order or fields.Date.today(), - round=False, - ) - if to_cur and product_cost - else product_cost - ) - return purchase_price diff --git a/pos_margin/models/res_config_settings.py b/pos_margin/models/res_config_settings.py new file mode 100644 index 0000000000..714ddf15ca --- /dev/null +++ b/pos_margin/models/res_config_settings.py @@ -0,0 +1,14 @@ +# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + pos_iface_display_margin = fields.Boolean( + related="pos_config_id.iface_display_margin", + readonly=False, + ) diff --git a/pos_margin/readme/CONFIGURE.rst b/pos_margin/readme/CONFIGURE.rst index 7c161346a4..8c66addc2e 100644 --- a/pos_margin/readme/CONFIGURE.rst +++ b/pos_margin/readme/CONFIGURE.rst @@ -1,4 +1,4 @@ * If you want to disable the display of the margin, in the front-office UI, you can - uncheck the check box in the ``pos.config`` form: + uncheck the check box in the `res.config.settings` shop form: -.. figure:: ../static/description/pos_config_form.png +.. figure:: ../static/description/pos_config_setting.png diff --git a/pos_margin/readme/CONTRIBUTORS.rst b/pos_margin/readme/CONTRIBUTORS.rst index 2e1a052b2d..bfbf8febea 100644 --- a/pos_margin/readme/CONTRIBUTORS.rst +++ b/pos_margin/readme/CONTRIBUTORS.rst @@ -2,3 +2,4 @@ * Wolfgang Pichler * Murtaza Mithaiwala (https://twitter.com/MurtazaMithaiw4) * Dhara Solanki +* Juan Carlos Bonilla diff --git a/pos_margin/readme/DESCRIPTION.rst b/pos_margin/readme/DESCRIPTION.rst index 48bcde4bca..2956e95962 100644 --- a/pos_margin/readme/DESCRIPTION.rst +++ b/pos_margin/readme/DESCRIPTION.rst @@ -1,5 +1 @@ -This module extends the functionality of point of sale to support margin on -pos orders. - -This gives the profitability by calculating the difference between the Unit -Price and Cost Price. +This module shows margins in PoS frontend during an order creation. diff --git a/pos_margin/readme/HISTORY.rst b/pos_margin/readme/HISTORY.rst index df8350ee80..cd4147c08f 100644 --- a/pos_margin/readme/HISTORY.rst +++ b/pos_margin/readme/HISTORY.rst @@ -1,3 +1,13 @@ +16.0.1.0.0 +~~~~~~~~~~ + +* Migrate to V16.0 +* Remove ``pos.order`` and ``pos.order.line`` funcionality from V14.0. + It's already done by V16.0. +* Remove tests. +* Create a ``res.config.settings`` field `pos_iface_display_margin` + to display margins in PoS frontend. + 14.0.1.0.0 ~~~~~~~~~~ diff --git a/pos_margin/readme/USAGE.rst b/pos_margin/readme/USAGE.rst index 72157d36fd..e69de29bb2 100644 --- a/pos_margin/readme/USAGE.rst +++ b/pos_margin/readme/USAGE.rst @@ -1,17 +0,0 @@ -**In the PoS Front Office** - -* Make an order. Each time a line is added, updated, or deleted, the margin and the margin rate - will be updated. - -.. figure:: ../static/description/pos_front_end.png - :width: 800px - -**In the PoS Back Office** - -To use this module, you need to: - -* Go to 'Point Of Sale' / 'Orders' / 'Orders' -* Open an order - -.. figure:: ../static/description/pos_order_form.png - :width: 800px diff --git a/pos_margin/report/__init__.py b/pos_margin/report/__init__.py index 1ddfcaae89..632dab95aa 100644 --- a/pos_margin/report/__init__.py +++ b/pos_margin/report/__init__.py @@ -1 +1,5 @@ +# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from . import pos_order_report diff --git a/pos_margin/report/pos_order_report.py b/pos_margin/report/pos_order_report.py index 4c83eec8c4..2e1706f5cc 100644 --- a/pos_margin/report/pos_order_report.py +++ b/pos_margin/report/pos_order_report.py @@ -1,18 +1,28 @@ +# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from odoo import fields, models class PosOrderReport(models.Model): _inherit = "report.pos.order" - margin_total = fields.Float(string="Margin Total") - margin_rate = fields.Float(string="Margin Rate", group_operator="avg") + margin_rate = fields.Float(string="Margin Rate (%)", group_operator="avg") def _select(self): return ( super(PosOrderReport, self)._select() + """, - SUM(l.margin) as margin_total, - (SUM(l.margin / nullif(l.qty,0)) * 100 / - SUM(nullif(l.purchase_price,0)))::decimal as margin_rate - """ + SUM(l.price_subtotal - l.total_cost / CASE COALESCE(s.currency_rate, 0) + WHEN 0 THEN 1.0 ELSE s.currency_rate END) / NULLIF(SUM(l.price_subtotal), 0) * 100 + AS margin_rate + """ ) + + def _group_by(self): + group_by_append = """, + l.price_subtotal, + l.total_cost + """ + return super(PosOrderReport, self)._group_by() + group_by_append diff --git a/pos_margin/static/description/index.html b/pos_margin/static/description/index.html index d550b3b880..d5696c21e4 100644 --- a/pos_margin/static/description/index.html +++ b/pos_margin/static/description/index.html @@ -367,7 +367,7 @@

PoS Order Margin

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

This module extends the functionality of point of sale to support margin on pos orders.

This gives the profitability by calculating the difference between the Unit @@ -379,7 +379,7 @@

PoS Order Margin

  • Usage
  • Known issues / Roadmap
  • Changelog
  • @@ -399,7 +399,7 @@

    Configuration

    uncheck the check box in the pos.config form:
    -https://raw.githubusercontent.com/OCA/pos/14.0/pos_margin/static/description/pos_config_form.png +https://raw.githubusercontent.com/OCA/pos/16.0/pos_margin/static/description/pos_config_form.png
    @@ -410,7 +410,7 @@

    Usage

    will be updated.
    -https://raw.githubusercontent.com/OCA/pos/14.0/pos_margin/static/description/pos_front_end.png +https://raw.githubusercontent.com/OCA/pos/16.0/pos_margin/static/description/pos_front_end.png

    In the PoS Back Office

    To use this module, you need to:

    @@ -419,7 +419,7 @@

    Usage

  • Open an order
  • -https://raw.githubusercontent.com/OCA/pos/14.0/pos_margin/static/description/pos_order_form.png +https://raw.githubusercontent.com/OCA/pos/16.0/pos_margin/static/description/pos_order_form.png
    @@ -431,9 +431,9 @@

    Known issues / Roadmap

    Changelog

    -

    14.0.1.0.0

    +

    16.0.1.0.0

      -
    • Migrate to V14.0
    • +
    • Migrate to V16.0
    @@ -452,7 +452,7 @@

    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 smashing it by providing a detailed and welcomed -feedback.

    +feedback.

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

    @@ -481,7 +481,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    legalsylvain

    -

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

    +

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

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

    diff --git a/pos_margin/static/description/pos_config_setting.png b/pos_margin/static/description/pos_config_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..0df117a4e158305d368c7ff29f424917f8103385 GIT binary patch literal 60411 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 O@}Vd_jL;C+R`YDGMJG9~Jv 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 literal 0 HcmV?d00001 diff --git a/pos_margin/static/src/js/OrderSummaryMargin.esm.js b/pos_margin/static/src/js/OrderSummaryMargin.esm.js new file mode 100644 index 0000000000..d425fa36c3 --- /dev/null +++ b/pos_margin/static/src/js/OrderSummaryMargin.esm.js @@ -0,0 +1,25 @@ +/** @odoo-module **/ +// Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) +// @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import PosComponent from "point_of_sale.PosComponent"; +import Registries from "point_of_sale.Registries"; + +export class OrderSummaryMargin extends PosComponent { + getOrderMargin() { + const self = this; + const order = self.env.pos.get_order(); + if (!order.get_orderlines().length) { + return false; + } + const margin = self.env.pos.format_currency(order.get_margin()); + const margin_rate = order.get_margin_rate_str(); + + return {margin, margin_rate}; + } +} + +OrderSummaryMargin.template = "OrderSummaryMargin"; + +Registries.Component.add(OrderSummaryMargin); diff --git a/pos_margin/static/src/js/OrderSummaryMargin.js b/pos_margin/static/src/js/OrderSummaryMargin.js deleted file mode 100644 index ed59e64e10..0000000000 --- a/pos_margin/static/src/js/OrderSummaryMargin.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 - Initos Gmbh -// @author: Dhara Solanki (dhara.solanki@initos.com) -// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -odoo.define("point_of_sale.OrderSummaryMargin", function (require) { - "use strict"; - - const PosComponent = require("point_of_sale.PosComponent"); - const Registries = require("point_of_sale.Registries"); - - class OrderSummaryMargin extends PosComponent {} - OrderSummaryMargin.template = "OrderSummaryMargin"; - - Registries.Component.add(OrderSummaryMargin); - - return OrderSummaryMargin; -}); diff --git a/pos_margin/static/src/js/OrderWidget.js b/pos_margin/static/src/js/OrderWidget.js deleted file mode 100644 index a1dd7f066a..0000000000 --- a/pos_margin/static/src/js/OrderWidget.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2021 - Today: GRAP (http://www.grap.coop) -// @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -odoo.define("pos_margin.OrderWidget", function (require) { - "use strict"; - - var OrderWidget = require("point_of_sale.OrderWidget"); - const Registries = require("point_of_sale.Registries"); - var field_utils = require("web.field_utils"); - - const PosOrderWidget = (OrderWidget) => - class extends OrderWidget { - _updateSummary() { - super._updateSummary(...arguments); - var order = this.env.pos.get_order(); - if (!order.get_orderlines().length) { - return; - } - var value_margin = document.getElementsByClassName("value-margin"); - if (value_margin && value_margin.length) { - value_margin[0].textContent = this.env.pos.format_currency( - order.get_margin() - ); - } - var value_margin_rate = - document.getElementsByClassName("value-margin-rate"); - if (value_margin_rate && value_margin_rate.length) { - value_margin_rate[0].textContent = - field_utils.format.float(order.get_margin_rate()) + "%"; - } - } - }; - Registries.Component.extend(OrderWidget, PosOrderWidget); - return OrderWidget; -}); diff --git a/pos_margin/static/src/js/models.esm.js b/pos_margin/static/src/js/models.esm.js new file mode 100644 index 0000000000..15c059f170 --- /dev/null +++ b/pos_margin/static/src/js/models.esm.js @@ -0,0 +1,62 @@ +/** @odoo-module **/ +// Copyright (C) 2023 - Today: GRAP (http://www.grap.coop) +// @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import {Order, Orderline} from "point_of_sale.models"; +import Registries from "point_of_sale.Registries"; +import field_utils from "web.field_utils"; + +// ///////////////////////////// +// Overload models.Order +// ///////////////////////////// + +const OrderMargin = (Order) => + class extends Order { + get_margin() { + return this.get_orderlines().reduce( + (margin, line) => margin + line.get_margin(), + 0 + ); + } + + get_margin_rate() { + const priceWithoutTax = this.get_total_without_tax(); + return priceWithoutTax ? (this.get_margin() / priceWithoutTax) * 100 : 0; + } + + get_margin_rate_str() { + return field_utils.format.float(this.get_margin_rate()) + "%"; + } + }; + +Registries.Model.extend(Order, OrderMargin); + +// ///////////////////////////// +// Overload models.OrderLine +// ///////////////////////////// +const OrderLineMargin = (Orderline) => + class extends Orderline { + get_purchase_price() { + // Overload the function to use another field that the default standard_price + return this.product.standard_price; + } + + get_margin() { + return ( + this.get_all_prices().priceWithoutTax - + this.quantity * this.get_purchase_price() + ); + } + + get_margin_rate() { + const priceWithoutTax = this.get_all_prices().priceWithoutTax; + return priceWithoutTax ? (this.get_margin() / priceWithoutTax) * 100 : 0; + } + + get_margin_rate_str() { + return field_utils.format.float(this.get_margin_rate()) + "%"; + } + }; + +Registries.Model.extend(Orderline, OrderLineMargin); diff --git a/pos_margin/static/src/js/models.js b/pos_margin/static/src/js/models.js deleted file mode 100644 index 85114155b2..0000000000 --- a/pos_margin/static/src/js/models.js +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2021 - Today: GRAP (http://www.grap.coop) -// @author: Sylvain LE GAL (https://twitter.com/legalsylvain) -// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -odoo.define("pos_margin.models", function (require) { - "use strict"; - - var models = require("point_of_sale.models"); - var field_utils = require("web.field_utils"); - - // ///////////////////////////// - // Overload models.Order - // ///////////////////////////// - var OrderMargin = models.Order.extend({ - get_margin: function () { - return this.get_orderlines().reduce( - (margin, line) => (margin += line.get_margin()), - 0 - ); - }, - - get_margin_rate: function () { - var priceWithoutTax = this.get_total_without_tax(); - return priceWithoutTax ? (this.get_margin() / priceWithoutTax) * 100 : 0; - }, - }); - - models.Order = OrderMargin; - - // ///////////////////////////// - // Overload models.OrderLine - // ///////////////////////////// - var OrderLineMargin = models.Orderline.extend({ - get_purchase_price: function () { - // Overload the function to use another field that the default standard_price - return this.product.standard_price; - }, - - get_margin: function () { - return ( - this.get_all_prices().priceWithoutTax - - this.quantity * this.get_purchase_price() - ); - }, - - get_margin_rate: function () { - var priceWithoutTax = this.get_all_prices().priceWithoutTax; - return priceWithoutTax ? (this.get_margin() / priceWithoutTax) * 100 : 0; - }, - - get_margin_rate_str: function () { - return field_utils.format.float(this.get_margin_rate()) + "%"; - }, - }); - - models.Orderline = OrderLineMargin; -}); diff --git a/pos_margin/static/src/xml/pos_margin.xml b/pos_margin/static/src/xml/pos_margin.xml index ecb8b2bee6..1daae2f344 100644 --- a/pos_margin/static/src/xml/pos_margin.xml +++ b/pos_margin/static/src/xml/pos_margin.xml @@ -1,21 +1,27 @@ -
    -
    -
    - Margin: 0.00 € - (0.00 %) + + +
    +
    + Margin: + + + ( + + ) +
    -
    +
    @@ -32,7 +38,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - () + () diff --git a/pos_margin/tests/__init__.py b/pos_margin/tests/__init__.py deleted file mode 100644 index d9b96c4fa5..0000000000 --- a/pos_margin/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import test_module diff --git a/pos_margin/tests/test_module.py b/pos_margin/tests/test_module.py deleted file mode 100644 index 8b9a06f0c8..0000000000 --- a/pos_margin/tests/test_module.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2019 - Today Sylvain LE GAL (https://twitter.com/legalsylvain) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import fields -from odoo.tests.common import TransactionCase - - -class TestModule(TransactionCase): - def setUp(self): - super(TestModule, self).setUp() - self.PosOrder = self.env["pos.order"] - self.pos_product = self.env.ref("point_of_sale.whiteboard_pen") - self.pricelist = self.env.ref("product.list0") - - # Create a new pos config and open it - self.pos_config = self.env.ref("point_of_sale.pos_config_main").copy() - self.pos_config.open_session_cb() - - def test_margin(self): - self.pos_product.list_price = 1.8 - self.pos_product.standard_price = 0.5 - order = self._create_order() - - self.assertEqual(order.margin, 10 * (1.8 - 0.5), "Bad computation of margin") - - def _create_order(self): - # Create order - account_id = self.env.user.partner_id.property_account_receivable_id.id - order_data = { - "id": "0006-001-0010", - "to_invoice": False, - "data": { - "pricelist_id": self.pricelist.id, - "user_id": 1, - "name": "Order 0006-001-0010", - "partner_id": False, - "amount_paid": 0.9, - "pos_session_id": self.pos_config.current_session_id.id, - "lines": [ - [ - 0, - 0, - { - "product_id": self.pos_product.id, - "price_unit": self.pos_product.list_price, - "qty": 10, - "price_subtotal": 18.0, - "price_subtotal_incl": 18.0, - }, - ] - ], - "statement_ids": [ - [ - 0, - 0, - { - "payment_method_id": self.pos_config.payment_method_ids[ - 0 - ].id, - "amount": 18.0, - "name": fields.Datetime.now(), - "account_id": account_id, - "session_id": self.pos_config.current_session_id.id, - }, - ] - ], - "creation_date": "2018-09-27 15:51:03", - "amount_tax": 0, - "fiscal_position_id": False, - "uid": "00001-001-0001", - "amount_return": 0, - "sequence_number": 1, - "amount_total": 18.0, - }, - } - result = self.PosOrder.create_from_ui([order_data]) - order = self.PosOrder.browse(result[0].get("id")) - return order diff --git a/pos_margin/views/view_pos_config.xml b/pos_margin/views/res_config_settings_view.xml similarity index 52% rename from pos_margin/views/view_pos_config.xml rename to pos_margin/views/res_config_settings_view.xml index 0a76b02b09..e5e72e7123 100644 --- a/pos_margin/views/view_pos_config.xml +++ b/pos_margin/views/res_config_settings_view.xml @@ -1,22 +1,22 @@ - - pos.config - + + res.config.settings + - -
    + +
    - +
    -