From 96bf7be1997a1f53b9334c5bc2e59dad5403dcdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Grand-Guillaume?= Date: Thu, 12 Jul 2012 15:51:36 +0200 Subject: [PATCH 01/75] [MRG] From last customers devs, tests and bugfix. Most improvements are on: - Margin modules - picking dispatch (better warehouse handling)) - grouping PO - Filter on stock delivers from sales (lp:c2c-addons/6.1 rev 28.3.22) --- product_standard_margin/__init__.py | 22 ++++ product_standard_margin/__openerp__.py | 58 ++++++++++ product_standard_margin/product_std_margin.py | 106 ++++++++++++++++++ .../product_std_margin_view.xml | 21 ++++ 4 files changed, 207 insertions(+) create mode 100644 product_standard_margin/__init__.py create mode 100644 product_standard_margin/__openerp__.py create mode 100644 product_standard_margin/product_std_margin.py create mode 100644 product_standard_margin/product_std_margin_view.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py new file mode 100644 index 00000000..4a754ba5 --- /dev/null +++ b/product_standard_margin/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import product_std_margin + diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py new file mode 100644 index 00000000..d42d8ed9 --- /dev/null +++ b/product_standard_margin/__openerp__.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{'name' : 'Markup rate on product and sales', + 'version' : '1.0', + 'author' : 'Camptocamp', + 'maintainer': 'Camptocamp', + 'category': 'Sales Management', + 'complexity': "normal", # easy, normal, expert + 'depends' : ['product_get_cost_field', 'account'], + 'description': """ + Add a field on the product form that compute the standard (or theorical) margin based on the + current values of sale and cost price present in the product form. We take care of taxe included + or excluded. + + It will just compute it as follow : (Sale Price without tax - Cost Price) / Sale Price without tax + + Remember that this module can be used in conjonction with product_cost_incl_bom to have the + cost price computed from the BOM when a product has one. + + WARNING: + + 1) As this module will base his simple computation on sale and cost prices, it suppose + you have them both in the same currency (the price type must of the same currency for both of + them). Remember this is the default OpenERP configuration (price type of all product price + fields are set as the same as the company currency). We don't take care of it cause otherwise + we should have added a dependency on sale module. + + + """, + 'website': 'http://www.camptocamp.com/', + 'init_xml': [], + 'update_xml': ['product_std_margin_view.xml'], + 'demo_xml': [], + 'tests': [], + 'installable': True, + 'auto_install': False, + 'license': 'AGPL-3', + 'application': True} + + diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py new file mode 100644 index 00000000..43759d1f --- /dev/null +++ b/product_standard_margin/product_std_margin.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) +# All Right Reserved +# +# Author : Joel Grand-Guillaume +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields +from osv.orm import Model +import decimal_precision as dp +import logging + +class Product(Model): + _inherit = 'product.product' + + #TODO : compute the margin with default taxes + def _amount_tax_excluded(self, cr, uid, ids, context=None): + """ + Compute the list price total without tax (in case you are in tax included). + This will use the default taxes defined on the product. + :return dict of values: + {INT Product ID: + float price without tax + } + """ + res = {} + if context is None: + context = {} + tax_obj = self.pool.get('account.tax') + cur_obj = self.pool.get('res.currency') + for prod in self.browse(cr, uid, ids): + price = prod.list_price + taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) + res[prod.id] = taxes['total'] + return res + + def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): + """ + Calculate the margin based on product infos. Take care of the cost_field + define in product_get_cost_field. So the margin will be computed based on this + field. + + We don't take care of the product price type currency to remove the dependency on + the sale module. We consider the cost and sale price is in the company currency. + + We take care of the default product taxes, and base our computation on total without + tax. + + :return dict of dict of the form : + {INT Product ID : { + {'margin_absolute': float, + 'margin_relative': float} + }} + """ + logger = logging.getLogger('product_standard_margin') + if context is None: + context = {} + res = {} + if not ids: + return res + for product in ids: + res[product] = {'margin_absolute': 0, 'margin_relative': 0} + for product in self.browse(cursor, user, ids): + cost = product.cost_price + sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] + # sale = product.list_price + res[product.id]['standard_margin'] = sale - cost + if sale == 0: + logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) + res[product.id]['standard_margin_rate'] = 999. + else: + res[product.id]['standard_margin_rate'] = (sale - cost) / sale * 100 + return res + + _columns = { + 'standard_margin' : fields.function(_compute_margin, + method=True, + string='Theorical Margin', + digits_compute=dp.get_precision('Sale Price'), + multi ='margin', + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' + 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), + 'standard_margin_rate' : fields.function(_compute_margin, + method=True, + string='Theorical Margin (%)', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), + } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml new file mode 100644 index 00000000..4ee497e4 --- /dev/null +++ b/product_standard_margin/product_std_margin_view.xml @@ -0,0 +1,21 @@ + + + + + product.markup.view.form + form + product.product + + + + + + + + + + + + + + From 36b42de3f257bc18edf25b7966f171796a35f38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Grand-Guillaume?= Date: Fri, 29 Jun 2012 09:27:40 +0200 Subject: [PATCH 02/75] To ease merging the work with Alex, I already commit part of work: [DOC] Some typo and docstring [IMP] Warning message if no move available for dispatch creation [IMP] Start adding relation between picking and dispatch (lp:c2c-addons/6.1 rev 28.6.4) --- product_standard_margin/__init__.py | 22 ---- product_standard_margin/__openerp__.py | 58 ---------- product_standard_margin/product_std_margin.py | 106 ------------------ .../product_std_margin_view.xml | 21 ---- 4 files changed, 207 deletions(-) delete mode 100644 product_standard_margin/__init__.py delete mode 100644 product_standard_margin/__openerp__.py delete mode 100644 product_standard_margin/product_std_margin.py delete mode 100644 product_standard_margin/product_std_margin_view.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py deleted file mode 100644 index 4a754ba5..00000000 --- a/product_standard_margin/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from . import product_std_margin - diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py deleted file mode 100644 index d42d8ed9..00000000 --- a/product_standard_margin/__openerp__.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -{'name' : 'Markup rate on product and sales', - 'version' : '1.0', - 'author' : 'Camptocamp', - 'maintainer': 'Camptocamp', - 'category': 'Sales Management', - 'complexity': "normal", # easy, normal, expert - 'depends' : ['product_get_cost_field', 'account'], - 'description': """ - Add a field on the product form that compute the standard (or theorical) margin based on the - current values of sale and cost price present in the product form. We take care of taxe included - or excluded. - - It will just compute it as follow : (Sale Price without tax - Cost Price) / Sale Price without tax - - Remember that this module can be used in conjonction with product_cost_incl_bom to have the - cost price computed from the BOM when a product has one. - - WARNING: - - 1) As this module will base his simple computation on sale and cost prices, it suppose - you have them both in the same currency (the price type must of the same currency for both of - them). Remember this is the default OpenERP configuration (price type of all product price - fields are set as the same as the company currency). We don't take care of it cause otherwise - we should have added a dependency on sale module. - - - """, - 'website': 'http://www.camptocamp.com/', - 'init_xml': [], - 'update_xml': ['product_std_margin_view.xml'], - 'demo_xml': [], - 'tests': [], - 'installable': True, - 'auto_install': False, - 'license': 'AGPL-3', - 'application': True} - - diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py deleted file mode 100644 index 43759d1f..00000000 --- a/product_standard_margin/product_std_margin.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) -# All Right Reserved -# -# Author : Joel Grand-Guillaume -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from osv import fields -from osv.orm import Model -import decimal_precision as dp -import logging - -class Product(Model): - _inherit = 'product.product' - - #TODO : compute the margin with default taxes - def _amount_tax_excluded(self, cr, uid, ids, context=None): - """ - Compute the list price total without tax (in case you are in tax included). - This will use the default taxes defined on the product. - :return dict of values: - {INT Product ID: - float price without tax - } - """ - res = {} - if context is None: - context = {} - tax_obj = self.pool.get('account.tax') - cur_obj = self.pool.get('res.currency') - for prod in self.browse(cr, uid, ids): - price = prod.list_price - taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) - res[prod.id] = taxes['total'] - return res - - def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): - """ - Calculate the margin based on product infos. Take care of the cost_field - define in product_get_cost_field. So the margin will be computed based on this - field. - - We don't take care of the product price type currency to remove the dependency on - the sale module. We consider the cost and sale price is in the company currency. - - We take care of the default product taxes, and base our computation on total without - tax. - - :return dict of dict of the form : - {INT Product ID : { - {'margin_absolute': float, - 'margin_relative': float} - }} - """ - logger = logging.getLogger('product_standard_margin') - if context is None: - context = {} - res = {} - if not ids: - return res - for product in ids: - res[product] = {'margin_absolute': 0, 'margin_relative': 0} - for product in self.browse(cursor, user, ids): - cost = product.cost_price - sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] - # sale = product.list_price - res[product.id]['standard_margin'] = sale - cost - if sale == 0: - logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) - res[product.id]['standard_margin_rate'] = 999. - else: - res[product.id]['standard_margin_rate'] = (sale - cost) / sale * 100 - return res - - _columns = { - 'standard_margin' : fields.function(_compute_margin, - method=True, - string='Theorical Margin', - digits_compute=dp.get_precision('Sale Price'), - multi ='margin', - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' - 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), - 'standard_margin_rate' : fields.function(_compute_margin, - method=True, - string='Theorical Margin (%)', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), - } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml deleted file mode 100644 index 4ee497e4..00000000 --- a/product_standard_margin/product_std_margin_view.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - product.markup.view.form - form - product.product - - - - - - - - - - - - - - From d881447cb32fc079b62f7cda07d4bb73bcaa39a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Grand-Guillaume?= Date: Wed, 11 Jul 2012 17:13:42 +0200 Subject: [PATCH 03/75] [IMP] Rebuild the margin modules. This is the first working version that still need strong testing (lp:c2c-addons/6.1 rev 28.6.24) --- product_standard_margin/__init__.py | 22 +++++ product_standard_margin/__openerp__.py | 58 +++++++++++++ product_standard_margin/product_std_margin.py | 84 +++++++++++++++++++ .../product_std_margin_view.xml | 21 +++++ 4 files changed, 185 insertions(+) create mode 100644 product_standard_margin/__init__.py create mode 100644 product_standard_margin/__openerp__.py create mode 100644 product_standard_margin/product_std_margin.py create mode 100644 product_standard_margin/product_std_margin_view.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py new file mode 100644 index 00000000..4a754ba5 --- /dev/null +++ b/product_standard_margin/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import product_std_margin + diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py new file mode 100644 index 00000000..6640d069 --- /dev/null +++ b/product_standard_margin/__openerp__.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{'name' : 'Markup rate on product and sales', + 'version' : '1.0', + 'author' : 'Camptocamp', + 'maintainer': 'Camptocamp', + 'category': 'Sales Management', + 'complexity': "normal", # easy, normal, expert + 'depends' : ['product_get_cost_field',], + 'description': """ + Add a field on the product form that compute the standard (or theorical) margin based on the + current values of sale and cost price present in the product form. + + It will just compute it as follow : (Sale Price - Cost Price) / Sale Price + + Remember that this module can be used in conjonction with product_cost_incl_bom to have the + cost price computed from the BOM when a product has one. + + WARNING: + + 1) As this module will base his simple computation on sale and cost prices, it suppose + you have them both in the same currency (the price type must of the same currency for both of + them). Remember this is the default OpenERP configuration (price type of all product price + fields are set as the same as the company currency). We don't take care of it cause otherwise + we should have added a dependency on sale module. + + 2) For now we consider always the prices values are VAT excluded + + """, + 'website': 'http://www.camptocamp.com/', + 'init_xml': [], + 'update_xml': ['product_std_margin_view.xml'], + 'demo_xml': [], + 'tests': [], + 'installable': True, + 'auto_install': False, + 'license': 'AGPL-3', + 'application': True} + + diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py new file mode 100644 index 00000000..b2ac8c43 --- /dev/null +++ b/product_standard_margin/product_std_margin.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) +# All Right Reserved +# +# Author : Joel Grand-Guillaume +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields +from osv.orm import Model +import decimal_precision as dp +import logging + +class Product(Model): + _inherit = 'product.product' + + def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): + """ + Calculate the margin based on product infos. Take care of the cost_field + define in product_get_cost_field. So the margin will be computed based on this + field. + + We don't take care of the product price type currency to remove the dependency on + the sale module. We consider the cost and sale price is in the company currency. + + We don't take care of the taxes, and base our computation on the hypothesis that + all prices are VAT excluded. + + :return dict of dict of the form : + {INT Product ID : { + {'margin_absolute': float, + 'margin_relative': float} + }} + """ + logger = logging.getLogger('product_standard_margin') + if context is None: + context = {} + res = {} + if not ids: + return res + for product in ids: + res[product] = {'margin_absolute': 0, 'margin_relative': 0} + for product in self.browse(cursor, user, ids): + cost = product.cost_price + sale = product.list_price + res[product.id]['standard_margin'] = sale - cost + if sale == 0: + logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) + res[product.id]['standard_margin_rate'] = 999. + else: + res[product.id]['standard_margin_rate'] = (sale - cost) / sale * 100 + return res + + _columns = { + 'standard_margin' : fields.function(_compute_margin, + method=True, + string='Theorical Margin', + digits_compute=dp.get_precision('Sale Price'), + multi ='margin', + help='Theorical Margin is [ sale price - cost price ] of the product form (not based on historical values).' + 'Prices should be VAT excluded. If no sale price, the margin will be negativ.'), + 'standard_margin_rate' : fields.function(_compute_margin, + method=True, + string='Theorical Margin (%)', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Markup rate is [ Theorical Margin / sale price ] of the product form (not based on historical values).' + 'Prices should be VAT excluded. If no sale price set, will display 999.0'), + } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml new file mode 100644 index 00000000..4ee497e4 --- /dev/null +++ b/product_standard_margin/product_std_margin_view.xml @@ -0,0 +1,21 @@ + + + + + product.markup.view.form + form + product.product + + + + + + + + + + + + + + From 2e1563f53734b392748181a23736fe4841c38af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Grand-Guillaume?= Date: Thu, 12 Jul 2012 09:45:48 +0200 Subject: [PATCH 04/75] [ADD] product_historical_margin_report that override the invoice line analysis to add margin [IMP] Add tax include/exlude support on margin computation [FIX] Little Typo and fixes after tests (lp:c2c-addons/6.1 rev 28.6.25) --- product_standard_margin/__openerp__.py | 8 ++--- product_standard_margin/product_std_margin.py | 36 +++++++++++++++---- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index 6640d069..d42d8ed9 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -24,12 +24,13 @@ 'maintainer': 'Camptocamp', 'category': 'Sales Management', 'complexity': "normal", # easy, normal, expert - 'depends' : ['product_get_cost_field',], + 'depends' : ['product_get_cost_field', 'account'], 'description': """ Add a field on the product form that compute the standard (or theorical) margin based on the - current values of sale and cost price present in the product form. + current values of sale and cost price present in the product form. We take care of taxe included + or excluded. - It will just compute it as follow : (Sale Price - Cost Price) / Sale Price + It will just compute it as follow : (Sale Price without tax - Cost Price) / Sale Price without tax Remember that this module can be used in conjonction with product_cost_incl_bom to have the cost price computed from the BOM when a product has one. @@ -42,7 +43,6 @@ fields are set as the same as the company currency). We don't take care of it cause otherwise we should have added a dependency on sale module. - 2) For now we consider always the prices values are VAT excluded """, 'website': 'http://www.camptocamp.com/', diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index b2ac8c43..43759d1f 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -29,6 +29,27 @@ class Product(Model): _inherit = 'product.product' + #TODO : compute the margin with default taxes + def _amount_tax_excluded(self, cr, uid, ids, context=None): + """ + Compute the list price total without tax (in case you are in tax included). + This will use the default taxes defined on the product. + :return dict of values: + {INT Product ID: + float price without tax + } + """ + res = {} + if context is None: + context = {} + tax_obj = self.pool.get('account.tax') + cur_obj = self.pool.get('res.currency') + for prod in self.browse(cr, uid, ids): + price = prod.list_price + taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) + res[prod.id] = taxes['total'] + return res + def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): """ Calculate the margin based on product infos. Take care of the cost_field @@ -38,8 +59,8 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): We don't take care of the product price type currency to remove the dependency on the sale module. We consider the cost and sale price is in the company currency. - We don't take care of the taxes, and base our computation on the hypothesis that - all prices are VAT excluded. + We take care of the default product taxes, and base our computation on total without + tax. :return dict of dict of the form : {INT Product ID : { @@ -57,7 +78,8 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): res[product] = {'margin_absolute': 0, 'margin_relative': 0} for product in self.browse(cursor, user, ids): cost = product.cost_price - sale = product.list_price + sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] + # sale = product.list_price res[product.id]['standard_margin'] = sale - cost if sale == 0: logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) @@ -72,13 +94,13 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): string='Theorical Margin', digits_compute=dp.get_precision('Sale Price'), multi ='margin', - help='Theorical Margin is [ sale price - cost price ] of the product form (not based on historical values).' - 'Prices should be VAT excluded. If no sale price, the margin will be negativ.'), + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' + 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), 'standard_margin_rate' : fields.function(_compute_margin, method=True, string='Theorical Margin (%)', digits_compute=dp.get_precision('Sale Price'), multi='margin', - help='Markup rate is [ Theorical Margin / sale price ] of the product form (not based on historical values).' - 'Prices should be VAT excluded. If no sale price set, will display 999.0'), + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), } From 45fb74bf8e171fcd445a604fefb51c7736121d48 Mon Sep 17 00:00:00 2001 From: "@" <@> Date: Tue, 15 May 2012 14:42:21 +0200 Subject: [PATCH 05/75] [IMP] product_cost_incl_bom, product_get_cost_field, sale_markup: extracted code to new modules extracted the bits about the computation of product cost with BoM from sale_markup to product_cost_incl_bom (lp:c2c-addons/6.1 rev 40.1.13) --- product_standard_margin/__init__.py | 22 ---- product_standard_margin/__openerp__.py | 58 ---------- product_standard_margin/product_std_margin.py | 106 ------------------ .../product_std_margin_view.xml | 21 ---- 4 files changed, 207 deletions(-) delete mode 100644 product_standard_margin/__init__.py delete mode 100644 product_standard_margin/__openerp__.py delete mode 100644 product_standard_margin/product_std_margin.py delete mode 100644 product_standard_margin/product_std_margin_view.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py deleted file mode 100644 index 4a754ba5..00000000 --- a/product_standard_margin/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from . import product_std_margin - diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py deleted file mode 100644 index d42d8ed9..00000000 --- a/product_standard_margin/__openerp__.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -{'name' : 'Markup rate on product and sales', - 'version' : '1.0', - 'author' : 'Camptocamp', - 'maintainer': 'Camptocamp', - 'category': 'Sales Management', - 'complexity': "normal", # easy, normal, expert - 'depends' : ['product_get_cost_field', 'account'], - 'description': """ - Add a field on the product form that compute the standard (or theorical) margin based on the - current values of sale and cost price present in the product form. We take care of taxe included - or excluded. - - It will just compute it as follow : (Sale Price without tax - Cost Price) / Sale Price without tax - - Remember that this module can be used in conjonction with product_cost_incl_bom to have the - cost price computed from the BOM when a product has one. - - WARNING: - - 1) As this module will base his simple computation on sale and cost prices, it suppose - you have them both in the same currency (the price type must of the same currency for both of - them). Remember this is the default OpenERP configuration (price type of all product price - fields are set as the same as the company currency). We don't take care of it cause otherwise - we should have added a dependency on sale module. - - - """, - 'website': 'http://www.camptocamp.com/', - 'init_xml': [], - 'update_xml': ['product_std_margin_view.xml'], - 'demo_xml': [], - 'tests': [], - 'installable': True, - 'auto_install': False, - 'license': 'AGPL-3', - 'application': True} - - diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py deleted file mode 100644 index 43759d1f..00000000 --- a/product_standard_margin/product_std_margin.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) -# All Right Reserved -# -# Author : Joel Grand-Guillaume -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from osv import fields -from osv.orm import Model -import decimal_precision as dp -import logging - -class Product(Model): - _inherit = 'product.product' - - #TODO : compute the margin with default taxes - def _amount_tax_excluded(self, cr, uid, ids, context=None): - """ - Compute the list price total without tax (in case you are in tax included). - This will use the default taxes defined on the product. - :return dict of values: - {INT Product ID: - float price without tax - } - """ - res = {} - if context is None: - context = {} - tax_obj = self.pool.get('account.tax') - cur_obj = self.pool.get('res.currency') - for prod in self.browse(cr, uid, ids): - price = prod.list_price - taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) - res[prod.id] = taxes['total'] - return res - - def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): - """ - Calculate the margin based on product infos. Take care of the cost_field - define in product_get_cost_field. So the margin will be computed based on this - field. - - We don't take care of the product price type currency to remove the dependency on - the sale module. We consider the cost and sale price is in the company currency. - - We take care of the default product taxes, and base our computation on total without - tax. - - :return dict of dict of the form : - {INT Product ID : { - {'margin_absolute': float, - 'margin_relative': float} - }} - """ - logger = logging.getLogger('product_standard_margin') - if context is None: - context = {} - res = {} - if not ids: - return res - for product in ids: - res[product] = {'margin_absolute': 0, 'margin_relative': 0} - for product in self.browse(cursor, user, ids): - cost = product.cost_price - sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] - # sale = product.list_price - res[product.id]['standard_margin'] = sale - cost - if sale == 0: - logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) - res[product.id]['standard_margin_rate'] = 999. - else: - res[product.id]['standard_margin_rate'] = (sale - cost) / sale * 100 - return res - - _columns = { - 'standard_margin' : fields.function(_compute_margin, - method=True, - string='Theorical Margin', - digits_compute=dp.get_precision('Sale Price'), - multi ='margin', - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' - 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), - 'standard_margin_rate' : fields.function(_compute_margin, - method=True, - string='Theorical Margin (%)', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), - } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml deleted file mode 100644 index 4ee497e4..00000000 --- a/product_standard_margin/product_std_margin_view.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - product.markup.view.form - form - product.product - - - - - - - - - - - - - - From 11d28f6dba5176088c0a4ed9be031f00f04c7f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Grand-Guillaume?= Date: Thu, 12 Jul 2012 15:56:17 +0200 Subject: [PATCH 06/75] [MRG] From trunk branch, tests and bugfix. Most improvements are on: - Margin modules - picking dispatch (better warehouse handling)) - grouping PO - Filter on stock delivers from sales (lp:c2c-addons/6.1 rev 69) --- product_standard_margin/__init__.py | 22 ++++ product_standard_margin/__openerp__.py | 58 ++++++++++ product_standard_margin/product_std_margin.py | 106 ++++++++++++++++++ .../product_std_margin_view.xml | 21 ++++ 4 files changed, 207 insertions(+) create mode 100644 product_standard_margin/__init__.py create mode 100644 product_standard_margin/__openerp__.py create mode 100644 product_standard_margin/product_std_margin.py create mode 100644 product_standard_margin/product_std_margin_view.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py new file mode 100644 index 00000000..4a754ba5 --- /dev/null +++ b/product_standard_margin/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import product_std_margin + diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py new file mode 100644 index 00000000..d42d8ed9 --- /dev/null +++ b/product_standard_margin/__openerp__.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{'name' : 'Markup rate on product and sales', + 'version' : '1.0', + 'author' : 'Camptocamp', + 'maintainer': 'Camptocamp', + 'category': 'Sales Management', + 'complexity': "normal", # easy, normal, expert + 'depends' : ['product_get_cost_field', 'account'], + 'description': """ + Add a field on the product form that compute the standard (or theorical) margin based on the + current values of sale and cost price present in the product form. We take care of taxe included + or excluded. + + It will just compute it as follow : (Sale Price without tax - Cost Price) / Sale Price without tax + + Remember that this module can be used in conjonction with product_cost_incl_bom to have the + cost price computed from the BOM when a product has one. + + WARNING: + + 1) As this module will base his simple computation on sale and cost prices, it suppose + you have them both in the same currency (the price type must of the same currency for both of + them). Remember this is the default OpenERP configuration (price type of all product price + fields are set as the same as the company currency). We don't take care of it cause otherwise + we should have added a dependency on sale module. + + + """, + 'website': 'http://www.camptocamp.com/', + 'init_xml': [], + 'update_xml': ['product_std_margin_view.xml'], + 'demo_xml': [], + 'tests': [], + 'installable': True, + 'auto_install': False, + 'license': 'AGPL-3', + 'application': True} + + diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py new file mode 100644 index 00000000..43759d1f --- /dev/null +++ b/product_standard_margin/product_std_margin.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) +# All Right Reserved +# +# Author : Joel Grand-Guillaume +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import fields +from osv.orm import Model +import decimal_precision as dp +import logging + +class Product(Model): + _inherit = 'product.product' + + #TODO : compute the margin with default taxes + def _amount_tax_excluded(self, cr, uid, ids, context=None): + """ + Compute the list price total without tax (in case you are in tax included). + This will use the default taxes defined on the product. + :return dict of values: + {INT Product ID: + float price without tax + } + """ + res = {} + if context is None: + context = {} + tax_obj = self.pool.get('account.tax') + cur_obj = self.pool.get('res.currency') + for prod in self.browse(cr, uid, ids): + price = prod.list_price + taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) + res[prod.id] = taxes['total'] + return res + + def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): + """ + Calculate the margin based on product infos. Take care of the cost_field + define in product_get_cost_field. So the margin will be computed based on this + field. + + We don't take care of the product price type currency to remove the dependency on + the sale module. We consider the cost and sale price is in the company currency. + + We take care of the default product taxes, and base our computation on total without + tax. + + :return dict of dict of the form : + {INT Product ID : { + {'margin_absolute': float, + 'margin_relative': float} + }} + """ + logger = logging.getLogger('product_standard_margin') + if context is None: + context = {} + res = {} + if not ids: + return res + for product in ids: + res[product] = {'margin_absolute': 0, 'margin_relative': 0} + for product in self.browse(cursor, user, ids): + cost = product.cost_price + sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] + # sale = product.list_price + res[product.id]['standard_margin'] = sale - cost + if sale == 0: + logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) + res[product.id]['standard_margin_rate'] = 999. + else: + res[product.id]['standard_margin_rate'] = (sale - cost) / sale * 100 + return res + + _columns = { + 'standard_margin' : fields.function(_compute_margin, + method=True, + string='Theorical Margin', + digits_compute=dp.get_precision('Sale Price'), + multi ='margin', + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' + 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), + 'standard_margin_rate' : fields.function(_compute_margin, + method=True, + string='Theorical Margin (%)', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), + } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml new file mode 100644 index 00000000..4ee497e4 --- /dev/null +++ b/product_standard_margin/product_std_margin_view.xml @@ -0,0 +1,21 @@ + + + + + product.markup.view.form + form + product.product + + + + + + + + + + + + + + From 917a652754ff88f4f45810e223facf8649c4a567 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Dec 2012 13:39:06 +0100 Subject: [PATCH 07/75] [ADD] translation FR on product_standard_margin and product_historical_margin --- product_standard_margin/i18n/fr.po | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 product_standard_margin/i18n/fr.po diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po new file mode 100644 index 00000000..b1c3d392 --- /dev/null +++ b/product_standard_margin/i18n/fr.po @@ -0,0 +1,52 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-07 14:35+0000\n" +"PO-Revision-Date: 2012-11-07 14:35+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: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "Produit" + +#. module: product_standard_margin +#: field:product.product,standard_margin_rate:0 +msgid "Theorical Margin (%)" +msgstr "Marge Theorique (%)" + +#. module: product_standard_margin +#: help:product.product,standard_margin_rate:0 +msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "Taux de marge théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du formulaire Produit] (ne tient pas compte de la facturation effective). Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le taux sera de 999.0" + +#. module: product_standard_margin +#: constraint:product.product:0 +msgid "Error: Invalid ean code" +msgstr "Erreur : Code EAN invalide" + +#. module: product_standard_margin +#: help:product.product,standard_margin:0 +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgstr "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient pas compte de la facturation effective).Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, la marge sera negative." + +#. module: product_standard_margin +#: view:product.product:0 +msgid "Margin" +msgstr "Marge" + +#. module: product_standard_margin +#: field:product.product,standard_margin:0 +msgid "Theorical Margin" +msgstr "Marge Théorique" + From 29aca3fb03ae0d200eba92500e36840c13defa54 Mon Sep 17 00:00:00 2001 From: "@" <@> Date: Thu, 13 Dec 2012 15:19:45 +0100 Subject: [PATCH 08/75] [FIX] typos --- product_standard_margin/i18n/fr.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po index b1c3d392..1c99776a 100644 --- a/product_standard_margin/i18n/fr.po +++ b/product_standard_margin/i18n/fr.po @@ -23,7 +23,7 @@ msgstr "Produit" #. module: product_standard_margin #: field:product.product,standard_margin_rate:0 msgid "Theorical Margin (%)" -msgstr "Marge Theorique (%)" +msgstr "Marge Théorique (%)" #. module: product_standard_margin #: help:product.product,standard_margin_rate:0 @@ -38,7 +38,7 @@ msgstr "Erreur : Code EAN invalide" #. module: product_standard_margin #: help:product.product,standard_margin:0 msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).Take care of tax include and exclude. If no sale price, the margin will be negativ." -msgstr "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient pas compte de la facturation effective).Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, la marge sera negative." +msgstr "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient pas compte de la facturation effective). Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, la marge sera négative." #. module: product_standard_margin #: view:product.product:0 From 4aaa127e689d210b0bb6a163703549bf5553f25d Mon Sep 17 00:00:00 2001 From: Endian Solutions Date: Sun, 23 Dec 2012 13:12:06 +0100 Subject: [PATCH 09/75] Added Dutch translations to all modules. --- product_standard_margin/i18n/nl.po | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 product_standard_margin/i18n/nl.po diff --git a/product_standard_margin/i18n/nl.po b/product_standard_margin/i18n/nl.po new file mode 100644 index 00000000..2df248f7 --- /dev/null +++ b/product_standard_margin/i18n/nl.po @@ -0,0 +1,67 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-12-23 12:04+0000\n" +"PO-Revision-Date: 2012-12-23 13:09+0100\n" +"Last-Translator: Erwin van der Ploeg | Endian Solutions " +"\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 1.5.4\n" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "Product" + +#. module: product_standard_margin +#: field:product.product,standard_margin_rate:0 +msgid "Theorical Margin (%)" +msgstr "Theoretische marge (%)" + +#. module: product_standard_margin +#: help:product.product,standard_margin_rate:0 +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" +"Theoretische marge (%) is [ Theoretische marge / Verkoopprijs (excl. BTW) ] " +"van het product (niet gebaseerd op historische waardes). Het veld houdt " +"rekening met prijzen incl. en excl. BTW. Indien geen verkooprijs is " +"ingevoerd, wordt 999,0 weergegeven." + +#. module: product_standard_margin +#: constraint:product.product:0 +msgid "Error: Invalid ean code" +msgstr "Fout: ongeldige ean code" + +#. module: product_standard_margin +#: help:product.product,standard_margin:0 +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values).Take care of tax include and exclude. If no " +"sale price, the margin will be negativ." +msgstr "" +"Theoretische marge is [ Verkoopprijs (excl. BTW) - Kostprijs) ] van het " +"product (niet gebaseerd op historische waardes). Het veld houdt rekening met " +"prijzen incl. en excl. BTW. Indien geen verkooprijs is ingevoerd, zal de " +"marge negatief zijn." + +#. module: product_standard_margin +#: view:product.product:0 +msgid "Margin" +msgstr "Marge" + +#. module: product_standard_margin +#: field:product.product,standard_margin:0 +msgid "Theorical Margin" +msgstr "Theorische marge" From 03ee8ca1d0370933d37c0b7aeb81e117b2c75919 Mon Sep 17 00:00:00 2001 From: Endian Solutions Date: Sun, 23 Dec 2012 13:48:18 +0100 Subject: [PATCH 10/75] small fix in translation --- product_standard_margin/i18n/nl.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/product_standard_margin/i18n/nl.po b/product_standard_margin/i18n/nl.po index 2df248f7..554bdeb5 100644 --- a/product_standard_margin/i18n/nl.po +++ b/product_standard_margin/i18n/nl.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-12-23 12:04+0000\n" -"PO-Revision-Date: 2012-12-23 13:09+0100\n" +"PO-Revision-Date: 2012-12-23 13:35+0100\n" "Last-Translator: Erwin van der Ploeg | Endian Solutions " "\n" "Language-Team: \n" @@ -64,4 +64,4 @@ msgstr "Marge" #. module: product_standard_margin #: field:product.product,standard_margin:0 msgid "Theorical Margin" -msgstr "Theorische marge" +msgstr "Theoretische marge" From 362d0e60beeb2a245918be3ccbd7bfea647d58b6 Mon Sep 17 00:00:00 2001 From: Joel Grand-Guillaume Date: Wed, 11 Sep 2013 10:08:22 +0200 Subject: [PATCH 11/75] [MIGR] Mark all module as installable = False unless we migrate them. This will happend in the next coming month. --- product_standard_margin/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index d42d8ed9..5b1f4d40 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -50,7 +50,7 @@ 'update_xml': ['product_std_margin_view.xml'], 'demo_xml': [], 'tests': [], - 'installable': True, + 'installable': False, 'auto_install': False, 'license': 'AGPL-3', 'application': True} From a9de98cb174a443488a31de775d5d680ef5d43bf Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Thu, 10 Oct 2013 14:09:34 +0200 Subject: [PATCH 12/75] [MIG] portage of product_standard_margin --- product_standard_margin/__openerp__.py | 26 ++++++------ product_standard_margin/product_std_margin.py | 41 ++++++++++--------- .../product_std_margin_view.xml | 11 +++-- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index 5b1f4d40..c4b4c871 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -18,39 +18,39 @@ # along with this program. If not, see . # ############################################################################## -{'name' : 'Markup rate on product and sales', - 'version' : '1.0', - 'author' : 'Camptocamp', +{'name': 'Markup rate on product and sales', + 'version': '1.0', + 'author': 'Camptocamp', 'maintainer': 'Camptocamp', 'category': 'Sales Management', 'complexity': "normal", # easy, normal, expert - 'depends' : ['product_get_cost_field', 'account'], + 'depends': ['product_get_cost_field', 'account'], 'description': """ Add a field on the product form that compute the standard (or theorical) margin based on the current values of sale and cost price present in the product form. We take care of taxe included or excluded. - - It will just compute it as follow : (Sale Price without tax - Cost Price) / Sale Price without tax - + + It will just compute it as follow: (Sale Price without tax - Cost Price) / Sale Price without tax + Remember that this module can be used in conjonction with product_cost_incl_bom to have the cost price computed from the BOM when a product has one. - - WARNING: - + + WARNING: + 1) As this module will base his simple computation on sale and cost prices, it suppose you have them both in the same currency (the price type must of the same currency for both of them). Remember this is the default OpenERP configuration (price type of all product price fields are set as the same as the company currency). We don't take care of it cause otherwise we should have added a dependency on sale module. - - + + """, 'website': 'http://www.camptocamp.com/', 'init_xml': [], 'update_xml': ['product_std_margin_view.xml'], 'demo_xml': [], 'tests': [], - 'installable': False, + 'installable': True, 'auto_install': False, 'license': 'AGPL-3', 'application': True} diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index 43759d1f..27ff7211 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -28,7 +28,7 @@ class Product(Model): _inherit = 'product.product' - + #TODO : compute the margin with default taxes def _amount_tax_excluded(self, cr, uid, ids, context=None): """ @@ -49,19 +49,19 @@ def _amount_tax_excluded(self, cr, uid, ids, context=None): taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) res[prod.id] = taxes['total'] return res - + def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): """ Calculate the margin based on product infos. Take care of the cost_field define in product_get_cost_field. So the margin will be computed based on this field. - + We don't take care of the product price type currency to remove the dependency on the sale module. We consider the cost and sale price is in the company currency. - + We take care of the default product taxes, and base our computation on total without tax. - + :return dict of dict of the form : {INT Product ID : { {'margin_absolute': float, @@ -79,7 +79,6 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): for product in self.browse(cursor, user, ids): cost = product.cost_price sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] - # sale = product.list_price res[product.id]['standard_margin'] = sale - cost if sale == 0: logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) @@ -89,18 +88,20 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): return res _columns = { - 'standard_margin' : fields.function(_compute_margin, - method=True, - string='Theorical Margin', - digits_compute=dp.get_precision('Sale Price'), - multi ='margin', - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' - 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), - 'standard_margin_rate' : fields.function(_compute_margin, - method=True, - string='Theorical Margin (%)', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), + 'standard_margin': fields.function( + _compute_margin, + method=True, + string='Theorical Margin', + digits_compute=dp.get_precision('Sale Price'), + multi ='margin', + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' + 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), + 'standard_margin_rate': fields.function( + _compute_margin, + method=True, + string='Theorical Margin (%)', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml index 4ee497e4..5fbd14c2 100644 --- a/product_standard_margin/product_std_margin_view.xml +++ b/product_standard_margin/product_std_margin_view.xml @@ -7,13 +7,12 @@ product.product - - - - - - + + + + + From 81df4ce2426ecb9384db61d68ffeed0d4f806bd3 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Mon, 14 Oct 2013 20:08:34 +0200 Subject: [PATCH 13/75] [FIX] imports --- product_standard_margin/product_std_margin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index 27ff7211..7f39ed31 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -21,12 +21,12 @@ # ############################################################################## -from osv import fields -from osv.orm import Model +from openerp.osv import orm, fields import decimal_precision as dp import logging -class Product(Model): + +class Product(orm.Model): _inherit = 'product.product' #TODO : compute the margin with default taxes From 46098e31af422862a0c5abc595ebd0c559075f0d Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Mon, 14 Oct 2013 20:16:46 +0200 Subject: [PATCH 14/75] [PEP8] --- product_standard_margin/__openerp__.py | 9 ++--- product_standard_margin/product_std_margin.py | 40 ++++++++++--------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index c4b4c871..c901845f 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -32,18 +32,17 @@ It will just compute it as follow: (Sale Price without tax - Cost Price) / Sale Price without tax - Remember that this module can be used in conjonction with product_cost_incl_bom to have the + Remember that this module can be used in conjonction with product_cost_incl_bom to have the cost price computed from the BOM when a product has one. WARNING: 1) As this module will base his simple computation on sale and cost prices, it suppose - you have them both in the same currency (the price type must of the same currency for both of - them). Remember this is the default OpenERP configuration (price type of all product price + you have them both in the same currency (the price type must of the same currency for both of + them). Remember this is the default OpenERP configuration (price type of all product price fields are set as the same as the company currency). We don't take care of it cause otherwise we should have added a dependency on sale module. - """, 'website': 'http://www.camptocamp.com/', 'init_xml': [], @@ -54,5 +53,3 @@ 'auto_install': False, 'license': 'AGPL-3', 'application': True} - - diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index 7f39ed31..fa97b668 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -33,9 +33,9 @@ class Product(orm.Model): def _amount_tax_excluded(self, cr, uid, ids, context=None): """ Compute the list price total without tax (in case you are in tax included). - This will use the default taxes defined on the product. + This will use the default taxes defined on the product. :return dict of values: - {INT Product ID: + {INT Product ID: float price without tax } """ @@ -43,28 +43,27 @@ def _amount_tax_excluded(self, cr, uid, ids, context=None): if context is None: context = {} tax_obj = self.pool.get('account.tax') - cur_obj = self.pool.get('res.currency') for prod in self.browse(cr, uid, ids): price = prod.list_price taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) res[prod.id] = taxes['total'] return res - def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): + def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): """ - Calculate the margin based on product infos. Take care of the cost_field - define in product_get_cost_field. So the margin will be computed based on this + Calculate the margin based on product infos. Take care of the cost_field + define in product_get_cost_field. So the margin will be computed based on this field. We don't take care of the product price type currency to remove the dependency on the sale module. We consider the cost and sale price is in the company currency. - We take care of the default product taxes, and base our computation on total without + We take care of the default product taxes, and base our computation on total without tax. - :return dict of dict of the form : + :return dict of dict of the form : {INT Product ID : { - {'margin_absolute': float, + {'margin_absolute': float, 'margin_relative': float} }} """ @@ -78,7 +77,8 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): res[product] = {'margin_absolute': 0, 'margin_relative': 0} for product in self.browse(cursor, user, ids): cost = product.cost_price - sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] + sale = self._amount_tax_excluded(cursor, user, + [product.id], context=context)[product.id] res[product.id]['standard_margin'] = sale - cost if sale == 0: logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) @@ -90,18 +90,22 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context = None): _columns = { 'standard_margin': fields.function( _compute_margin, - method=True, - string='Theorical Margin', - digits_compute=dp.get_precision('Sale Price'), - multi ='margin', - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).' - 'Take care of tax include and exclude. If no sale price, the margin will be negativ.'), + method=True, + string='Theorical Margin', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' + 'of the product form (not based on historical values). ' + 'Take care of tax include and exclude. If no sale price, ' + 'the margin will be negativ.'), 'standard_margin_rate': fields.function( _compute_margin, method=True, string='Theorical Margin (%)', digits_compute=dp.get_precision('Sale Price'), multi='margin', - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price set, will display 999.0'), + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' + 'of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price ' + 'set, will display 999.0'), } From 3439ff43cae9a7263cedaf727f8ec1a0c9820d82 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Mon, 14 Oct 2013 20:19:31 +0200 Subject: [PATCH 15/75] [IMP] use date in __openerp__.py instead of deprecated update_xml and demo_xml --- product_standard_margin/__openerp__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index c901845f..d5f28959 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -46,8 +46,7 @@ """, 'website': 'http://www.camptocamp.com/', 'init_xml': [], - 'update_xml': ['product_std_margin_view.xml'], - 'demo_xml': [], + 'data': ['product_std_margin_view.xml'], 'tests': [], 'installable': True, 'auto_install': False, From 2d2b0d50f183503849eb4bc85ce1cfc4c7af46a7 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Mon, 14 Oct 2013 20:42:41 +0200 Subject: [PATCH 16/75] [FIX] remove group to show margin fields --- product_standard_margin/product_std_margin_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml index 5fbd14c2..07cfa313 100644 --- a/product_standard_margin/product_std_margin_view.xml +++ b/product_standard_margin/product_std_margin_view.xml @@ -7,8 +7,8 @@ product.product - - + + From 6e3c626e02c53a4f10e9e49633c3bce519266f2a Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Mon, 14 Oct 2013 20:43:38 +0200 Subject: [PATCH 17/75] [ADD] pot file --- .../i18n/product_standard_margin.pot | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 product_standard_margin/i18n/product_standard_margin.pot diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot new file mode 100644 index 00000000..264b76ed --- /dev/null +++ b/product_standard_margin/i18n/product_standard_margin.pot @@ -0,0 +1,44 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-10-14 18:35+0000\n" +"PO-Revision-Date: 2013-10-14 18:35+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: product_standard_margin +#: help:product.product,standard_margin_rate:0 +msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate +#: field:product.product,standard_margin_rate:0 +msgid "Theorical Margin (%)" +msgstr "" + +#. module: product_standard_margin +#: help:product.product,standard_margin:0 +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin +#: field:product.product,standard_margin:0 +msgid "Theorical Margin" +msgstr "" + From 8a543be305773868fd793d9999683372ea7f04c8 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Mon, 14 Oct 2013 20:43:50 +0200 Subject: [PATCH 18/75] [IMP] update fr.po --- product_standard_margin/i18n/fr.po | 47 +++++++++++++++++------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po index 1c99776a..228f7994 100644 --- a/product_standard_margin/i18n/fr.po +++ b/product_standard_margin/i18n/fr.po @@ -1,52 +1,57 @@ # Translation of OpenERP Server. # This file contains the translation of the following modules: -# * product_standard_margin +# * product_standard_margin # msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 6.1\n" +"Project-Id-Version: OpenERP Server 7.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-11-07 14:35+0000\n" +"POT-Creation-Date: 2013-10-14 18:35+0000\n" "PO-Revision-Date: 2012-11-07 14:35+0000\n" "Last-Translator: <>\n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: product_standard_margin +#: help:product.product,standard_margin_rate:0 +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" +"Taux de marge théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " +"formulaire Produit] (ne tient pas compte de la facturation effective). Ce " +"taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " +"taux sera de 999.0" + #. module: product_standard_margin #: model:ir.model,name:product_standard_margin.model_product_product msgid "Product" msgstr "Produit" #. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate #: field:product.product,standard_margin_rate:0 msgid "Theorical Margin (%)" msgstr "Marge Théorique (%)" -#. module: product_standard_margin -#: help:product.product,standard_margin_rate:0 -msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" -msgstr "Taux de marge théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du formulaire Produit] (ne tient pas compte de la facturation effective). Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le taux sera de 999.0" - -#. module: product_standard_margin -#: constraint:product.product:0 -msgid "Error: Invalid ean code" -msgstr "Erreur : Code EAN invalide" - #. module: product_standard_margin #: help:product.product,standard_margin:0 -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values).Take care of tax include and exclude. If no sale price, the margin will be negativ." -msgstr "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient pas compte de la facturation effective). Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, la marge sera négative." - -#. module: product_standard_margin -#: view:product.product:0 -msgid "Margin" -msgstr "Marge" +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." +msgstr "" +"Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient " +"pas compte de la facturation effective). Ce taux tient compte des PV TTC " +"(TVA incluse). Si aucun PV n'a été saisi, la marge sera négative." #. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin #: field:product.product,standard_margin:0 msgid "Theorical Margin" msgstr "Marge Théorique" - From 44dacd44353c5ffe2fb452273ab630bfd2d1f00c Mon Sep 17 00:00:00 2001 From: Joel Grand-Guillaume Date: Wed, 27 Nov 2013 15:03:12 +0100 Subject: [PATCH 19/75] [IMP] Better logger implementation --- product_standard_margin/product_std_margin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index fa97b668..15d38038 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -24,7 +24,7 @@ from openerp.osv import orm, fields import decimal_precision as dp import logging - +_logger = logging.getLogger(__name__) class Product(orm.Model): _inherit = 'product.product' @@ -67,7 +67,7 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): 'margin_relative': float} }} """ - logger = logging.getLogger('product_standard_margin') + if context is None: context = {} res = {} @@ -81,7 +81,7 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): [product.id], context=context)[product.id] res[product.id]['standard_margin'] = sale - cost if sale == 0: - logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) + _logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) res[product.id]['standard_margin_rate'] = 999. else: res[product.id]['standard_margin_rate'] = (sale - cost) / sale * 100 From 89c8e5431b05cc536cb2095c659d42073541daed Mon Sep 17 00:00:00 2001 From: Joel Grand-Guillaume Date: Wed, 27 Nov 2013 16:26:22 +0100 Subject: [PATCH 20/75] [FIX] Context propagation --- product_standard_margin/product_std_margin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index 15d38038..05514893 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -43,7 +43,7 @@ def _amount_tax_excluded(self, cr, uid, ids, context=None): if context is None: context = {} tax_obj = self.pool.get('account.tax') - for prod in self.browse(cr, uid, ids): + for prod in self.browse(cr, uid, ids, context=context): price = prod.list_price taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) res[prod.id] = taxes['total'] @@ -75,7 +75,7 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): return res for product in ids: res[product] = {'margin_absolute': 0, 'margin_relative': 0} - for product in self.browse(cursor, user, ids): + for product in self.browse(cursor, user, ids, context=context): cost = product.cost_price sale = self._amount_tax_excluded(cursor, user, [product.id], context=context)[product.id] From 8f8deb648ff11b23688541d7a84b9cbe44284848 Mon Sep 17 00:00:00 2001 From: Joel Grand-Guillaume Date: Tue, 10 Dec 2013 14:29:31 +0100 Subject: [PATCH 21/75] [IMP] Use read whenever it's possible for performance reasons --- product_standard_margin/product_std_margin.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index 05514893..b2c28cf7 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -75,16 +75,16 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): return res for product in ids: res[product] = {'margin_absolute': 0, 'margin_relative': 0} - for product in self.browse(cursor, user, ids, context=context): - cost = product.cost_price + for product in self.read(cursor, user, ids, ['id','cost_price'], context=context): + cost = product['cost_price'] sale = self._amount_tax_excluded(cursor, user, - [product.id], context=context)[product.id] - res[product.id]['standard_margin'] = sale - cost + [product['id']], context=context)[product['id']] + res[product['id']]['standard_margin'] = sale - cost if sale == 0: - _logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product.id) - res[product.id]['standard_margin_rate'] = 999. + _logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product['id']) + res[product['id']]['standard_margin_rate'] = 999. else: - res[product.id]['standard_margin_rate'] = (sale - cost) / sale * 100 + res[product['id']]['standard_margin_rate'] = (sale - cost) / sale * 100 return res _columns = { From f8a7734baa309eb76fce38cc9df572ff5a10b173 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Wed, 11 Dec 2013 16:30:40 +0100 Subject: [PATCH 22/75] [PEP8] product_standard_margin --- product_standard_margin/product_std_margin.py | 78 ++++++++++--------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index b2c28cf7..7d4c7aad 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -26,18 +26,21 @@ import logging _logger = logging.getLogger(__name__) + class Product(orm.Model): _inherit = 'product.product' #TODO : compute the margin with default taxes def _amount_tax_excluded(self, cr, uid, ids, context=None): - """ - Compute the list price total without tax (in case you are in tax included). + """ Compute the list price total without tax + + (in case you are in tax included). This will use the default taxes defined on the product. :return dict of values: {INT Product ID: float price without tax } + """ res = {} if context is None: @@ -49,25 +52,27 @@ def _amount_tax_excluded(self, cr, uid, ids, context=None): res[prod.id] = taxes['total'] return res - def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): - """ - Calculate the margin based on product infos. Take care of the cost_field - define in product_get_cost_field. So the margin will be computed based on this - field. + def _compute_margin(self, cr, user, ids, field_name, arg, context=None): + """ Calculate the margin based on product infos. + + Take care of the cost_field define in product_get_cost_field. So the + margin will be computed based on this field. - We don't take care of the product price type currency to remove the dependency on - the sale module. We consider the cost and sale price is in the company currency. + We don't take care of the product price type currency to remove the + dependency on the sale module. We consider the cost and sale price is + in the company currency. - We take care of the default product taxes, and base our computation on total without - tax. + We take care of the default product taxes, and base our computation on + total without tax. :return dict of dict of the form : {INT Product ID : { {'margin_absolute': float, 'margin_relative': float} }} + """ - + if context is None: context = {} res = {} @@ -75,13 +80,16 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): return res for product in ids: res[product] = {'margin_absolute': 0, 'margin_relative': 0} - for product in self.read(cursor, user, ids, ['id','cost_price'], context=context): + for product in self.read(cr, user, ids, + ['id', 'cost_price'], context=context): cost = product['cost_price'] - sale = self._amount_tax_excluded(cursor, user, - [product['id']], context=context)[product['id']] + sale = self._amount_tax_excluded(cr, user, + [product['id']], + context=context)[product['id']] res[product['id']]['standard_margin'] = sale - cost if sale == 0: - _logger.debug("Sale price for product ID %d is 0, cannot compute margin rate...", product['id']) + _logger.debug("Sale price for product ID %d is 0, cannot " + "compute margin rate...", product['id']) res[product['id']]['standard_margin_rate'] = 999. else: res[product['id']]['standard_margin_rate'] = (sale - cost) / sale * 100 @@ -89,23 +97,23 @@ def _compute_margin(self, cursor, user, ids, field_name, arg, context=None): _columns = { 'standard_margin': fields.function( - _compute_margin, - method=True, - string='Theorical Margin', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' - 'of the product form (not based on historical values). ' - 'Take care of tax include and exclude. If no sale price, ' - 'the margin will be negativ.'), + _compute_margin, + method=True, + string='Theorical Margin', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' + 'of the product form (not based on historical values). ' + 'Take care of tax include and exclude. If no sale price, ' + 'the margin will be negativ.'), 'standard_margin_rate': fields.function( - _compute_margin, - method=True, - string='Theorical Margin (%)', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' - 'of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price ' - 'set, will display 999.0'), - } + _compute_margin, + method=True, + string='Theorical Margin (%)', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' + 'of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price ' + 'set, will display 999.0'), + } From 58b3bb0c5852c8f0070b2d21dc60eadec1f69b7c Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Wed, 13 Aug 2014 16:09:16 +0200 Subject: [PATCH 23/75] all modules are unported on 8.0 branch --- product_standard_margin/__init__.py | 22 ---- product_standard_margin/__openerp__.py | 54 -------- product_standard_margin/i18n/fr.po | 57 --------- product_standard_margin/i18n/nl.po | 67 ---------- .../i18n/product_standard_margin.pot | 44 ------- product_standard_margin/product_std_margin.py | 119 ------------------ .../product_std_margin_view.xml | 20 --- 7 files changed, 383 deletions(-) delete mode 100644 product_standard_margin/__init__.py delete mode 100644 product_standard_margin/__openerp__.py delete mode 100644 product_standard_margin/i18n/fr.po delete mode 100644 product_standard_margin/i18n/nl.po delete mode 100644 product_standard_margin/i18n/product_standard_margin.pot delete mode 100644 product_standard_margin/product_std_margin.py delete mode 100644 product_standard_margin/product_std_margin_view.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py deleted file mode 100644 index 4a754ba5..00000000 --- a/product_standard_margin/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from . import product_std_margin - diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py deleted file mode 100644 index d5f28959..00000000 --- a/product_standard_margin/__openerp__.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -{'name': 'Markup rate on product and sales', - 'version': '1.0', - 'author': 'Camptocamp', - 'maintainer': 'Camptocamp', - 'category': 'Sales Management', - 'complexity': "normal", # easy, normal, expert - 'depends': ['product_get_cost_field', 'account'], - 'description': """ - Add a field on the product form that compute the standard (or theorical) margin based on the - current values of sale and cost price present in the product form. We take care of taxe included - or excluded. - - It will just compute it as follow: (Sale Price without tax - Cost Price) / Sale Price without tax - - Remember that this module can be used in conjonction with product_cost_incl_bom to have the - cost price computed from the BOM when a product has one. - - WARNING: - - 1) As this module will base his simple computation on sale and cost prices, it suppose - you have them both in the same currency (the price type must of the same currency for both of - them). Remember this is the default OpenERP configuration (price type of all product price - fields are set as the same as the company currency). We don't take care of it cause otherwise - we should have added a dependency on sale module. - - """, - 'website': 'http://www.camptocamp.com/', - 'init_xml': [], - 'data': ['product_std_margin_view.xml'], - 'tests': [], - 'installable': True, - 'auto_install': False, - 'license': 'AGPL-3', - 'application': True} diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po deleted file mode 100644 index 228f7994..00000000 --- a/product_standard_margin/i18n/fr.po +++ /dev/null @@ -1,57 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * product_standard_margin -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-10-14 18:35+0000\n" -"PO-Revision-Date: 2012-11-07 14:35+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: product_standard_margin -#: help:product.product,standard_margin_rate:0 -msgid "" -"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.. " -"If no sale price set, will display 999.0" -msgstr "" -"Taux de marge théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " -"formulaire Produit] (ne tient pas compte de la facturation effective). Ce " -"taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " -"taux sera de 999.0" - -#. module: product_standard_margin -#: model:ir.model,name:product_standard_margin.model_product_product -msgid "Product" -msgstr "Produit" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate -#: field:product.product,standard_margin_rate:0 -msgid "Theorical Margin (%)" -msgstr "Marge Théorique (%)" - -#. module: product_standard_margin -#: help:product.product,standard_margin:0 -msgid "" -"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " -"(not based on historical values). Take care of tax include and exclude. If " -"no sale price, the margin will be negativ." -msgstr "" -"Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient " -"pas compte de la facturation effective). Ce taux tient compte des PV TTC " -"(TVA incluse). Si aucun PV n'a été saisi, la marge sera négative." - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin -#: field:product.product,standard_margin:0 -msgid "Theorical Margin" -msgstr "Marge Théorique" diff --git a/product_standard_margin/i18n/nl.po b/product_standard_margin/i18n/nl.po deleted file mode 100644 index 554bdeb5..00000000 --- a/product_standard_margin/i18n/nl.po +++ /dev/null @@ -1,67 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * product_standard_margin -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 6.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-12-23 12:04+0000\n" -"PO-Revision-Date: 2012-12-23 13:35+0100\n" -"Last-Translator: Erwin van der Ploeg | Endian Solutions " -"\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" -"X-Generator: Poedit 1.5.4\n" - -#. module: product_standard_margin -#: model:ir.model,name:product_standard_margin.model_product_product -msgid "Product" -msgstr "Product" - -#. module: product_standard_margin -#: field:product.product,standard_margin_rate:0 -msgid "Theorical Margin (%)" -msgstr "Theoretische marge (%)" - -#. module: product_standard_margin -#: help:product.product,standard_margin_rate:0 -msgid "" -"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.. " -"If no sale price set, will display 999.0" -msgstr "" -"Theoretische marge (%) is [ Theoretische marge / Verkoopprijs (excl. BTW) ] " -"van het product (niet gebaseerd op historische waardes). Het veld houdt " -"rekening met prijzen incl. en excl. BTW. Indien geen verkooprijs is " -"ingevoerd, wordt 999,0 weergegeven." - -#. module: product_standard_margin -#: constraint:product.product:0 -msgid "Error: Invalid ean code" -msgstr "Fout: ongeldige ean code" - -#. module: product_standard_margin -#: help:product.product,standard_margin:0 -msgid "" -"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " -"(not based on historical values).Take care of tax include and exclude. If no " -"sale price, the margin will be negativ." -msgstr "" -"Theoretische marge is [ Verkoopprijs (excl. BTW) - Kostprijs) ] van het " -"product (niet gebaseerd op historische waardes). Het veld houdt rekening met " -"prijzen incl. en excl. BTW. Indien geen verkooprijs is ingevoerd, zal de " -"marge negatief zijn." - -#. module: product_standard_margin -#: view:product.product:0 -msgid "Margin" -msgstr "Marge" - -#. module: product_standard_margin -#: field:product.product,standard_margin:0 -msgid "Theorical Margin" -msgstr "Theoretische marge" diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot deleted file mode 100644 index 264b76ed..00000000 --- a/product_standard_margin/i18n/product_standard_margin.pot +++ /dev/null @@ -1,44 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * product_standard_margin -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-10-14 18:35+0000\n" -"PO-Revision-Date: 2013-10-14 18:35+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: product_standard_margin -#: help:product.product,standard_margin_rate:0 -msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model,name:product_standard_margin.model_product_product -msgid "Product" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate -#: field:product.product,standard_margin_rate:0 -msgid "Theorical Margin (%)" -msgstr "" - -#. module: product_standard_margin -#: help:product.product,standard_margin:0 -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin -#: field:product.product,standard_margin:0 -msgid "Theorical Margin" -msgstr "" - diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py deleted file mode 100644 index 7d4c7aad..00000000 --- a/product_standard_margin/product_std_margin.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) -# All Right Reserved -# -# Author : Joel Grand-Guillaume -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from openerp.osv import orm, fields -import decimal_precision as dp -import logging -_logger = logging.getLogger(__name__) - - -class Product(orm.Model): - _inherit = 'product.product' - - #TODO : compute the margin with default taxes - def _amount_tax_excluded(self, cr, uid, ids, context=None): - """ Compute the list price total without tax - - (in case you are in tax included). - This will use the default taxes defined on the product. - :return dict of values: - {INT Product ID: - float price without tax - } - - """ - res = {} - if context is None: - context = {} - tax_obj = self.pool.get('account.tax') - for prod in self.browse(cr, uid, ids, context=context): - price = prod.list_price - taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) - res[prod.id] = taxes['total'] - return res - - def _compute_margin(self, cr, user, ids, field_name, arg, context=None): - """ Calculate the margin based on product infos. - - Take care of the cost_field define in product_get_cost_field. So the - margin will be computed based on this field. - - We don't take care of the product price type currency to remove the - dependency on the sale module. We consider the cost and sale price is - in the company currency. - - We take care of the default product taxes, and base our computation on - total without tax. - - :return dict of dict of the form : - {INT Product ID : { - {'margin_absolute': float, - 'margin_relative': float} - }} - - """ - - if context is None: - context = {} - res = {} - if not ids: - return res - for product in ids: - res[product] = {'margin_absolute': 0, 'margin_relative': 0} - for product in self.read(cr, user, ids, - ['id', 'cost_price'], context=context): - cost = product['cost_price'] - sale = self._amount_tax_excluded(cr, user, - [product['id']], - context=context)[product['id']] - res[product['id']]['standard_margin'] = sale - cost - if sale == 0: - _logger.debug("Sale price for product ID %d is 0, cannot " - "compute margin rate...", product['id']) - res[product['id']]['standard_margin_rate'] = 999. - else: - res[product['id']]['standard_margin_rate'] = (sale - cost) / sale * 100 - return res - - _columns = { - 'standard_margin': fields.function( - _compute_margin, - method=True, - string='Theorical Margin', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' - 'of the product form (not based on historical values). ' - 'Take care of tax include and exclude. If no sale price, ' - 'the margin will be negativ.'), - 'standard_margin_rate': fields.function( - _compute_margin, - method=True, - string='Theorical Margin (%)', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' - 'of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price ' - 'set, will display 999.0'), - } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml deleted file mode 100644 index 07cfa313..00000000 --- a/product_standard_margin/product_std_margin_view.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - product.markup.view.form - form - product.product - - - - - - - - - - - - - From 89d5daf7f0756d6b2186a6b7b8a1e3aecc9dd85d Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 24 Jul 2015 09:29:36 +0200 Subject: [PATCH 24/75] [PORT][WIP] move 'product_standard_margin' from unported to regular folder; --- product_standard_margin/__init__.py | 22 ++++ product_standard_margin/__openerp__.py | 54 ++++++++ product_standard_margin/i18n/fr.po | 57 +++++++++ product_standard_margin/i18n/nl.po | 67 ++++++++++ .../i18n/product_standard_margin.pot | 44 +++++++ product_standard_margin/product_std_margin.py | 119 ++++++++++++++++++ .../product_std_margin_view.xml | 20 +++ 7 files changed, 383 insertions(+) create mode 100644 product_standard_margin/__init__.py create mode 100644 product_standard_margin/__openerp__.py create mode 100644 product_standard_margin/i18n/fr.po create mode 100644 product_standard_margin/i18n/nl.po create mode 100644 product_standard_margin/i18n/product_standard_margin.pot create mode 100644 product_standard_margin/product_std_margin.py create mode 100644 product_standard_margin/product_std_margin_view.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py new file mode 100644 index 00000000..4a754ba5 --- /dev/null +++ b/product_standard_margin/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import product_std_margin + diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py new file mode 100644 index 00000000..e9069f0c --- /dev/null +++ b/product_standard_margin/__openerp__.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{'name': 'Markup rate on product and sales', + 'version': '1.0', + 'author': "Camptocamp,Odoo Community Association (OCA)", + 'maintainer': 'Camptocamp', + 'category': 'Sales Management', + 'complexity': "normal", # easy, normal, expert + 'depends': ['product_get_cost_field', 'account'], + 'description': """ + Add a field on the product form that compute the standard (or theorical) margin based on the + current values of sale and cost price present in the product form. We take care of taxe included + or excluded. + + It will just compute it as follow: (Sale Price without tax - Cost Price) / Sale Price without tax + + Remember that this module can be used in conjonction with product_cost_incl_bom to have the + cost price computed from the BOM when a product has one. + + WARNING: + + 1) As this module will base his simple computation on sale and cost prices, it suppose + you have them both in the same currency (the price type must of the same currency for both of + them). Remember this is the default OpenERP configuration (price type of all product price + fields are set as the same as the company currency). We don't take care of it cause otherwise + we should have added a dependency on sale module. + + """, + 'website': 'http://www.camptocamp.com/', + 'init_xml': [], + 'data': ['product_std_margin_view.xml'], + 'tests': [], + 'installable': False, + 'auto_install': False, + 'license': 'AGPL-3', + 'application': True} diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po new file mode 100644 index 00000000..228f7994 --- /dev/null +++ b/product_standard_margin/i18n/fr.po @@ -0,0 +1,57 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-10-14 18:35+0000\n" +"PO-Revision-Date: 2012-11-07 14:35+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: product_standard_margin +#: help:product.product,standard_margin_rate:0 +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" +"Taux de marge théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " +"formulaire Produit] (ne tient pas compte de la facturation effective). Ce " +"taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " +"taux sera de 999.0" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "Produit" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate +#: field:product.product,standard_margin_rate:0 +msgid "Theorical Margin (%)" +msgstr "Marge Théorique (%)" + +#. module: product_standard_margin +#: help:product.product,standard_margin:0 +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." +msgstr "" +"Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient " +"pas compte de la facturation effective). Ce taux tient compte des PV TTC " +"(TVA incluse). Si aucun PV n'a été saisi, la marge sera négative." + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin +#: field:product.product,standard_margin:0 +msgid "Theorical Margin" +msgstr "Marge Théorique" diff --git a/product_standard_margin/i18n/nl.po b/product_standard_margin/i18n/nl.po new file mode 100644 index 00000000..554bdeb5 --- /dev/null +++ b/product_standard_margin/i18n/nl.po @@ -0,0 +1,67 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-12-23 12:04+0000\n" +"PO-Revision-Date: 2012-12-23 13:35+0100\n" +"Last-Translator: Erwin van der Ploeg | Endian Solutions " +"\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 1.5.4\n" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "Product" + +#. module: product_standard_margin +#: field:product.product,standard_margin_rate:0 +msgid "Theorical Margin (%)" +msgstr "Theoretische marge (%)" + +#. module: product_standard_margin +#: help:product.product,standard_margin_rate:0 +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" +"Theoretische marge (%) is [ Theoretische marge / Verkoopprijs (excl. BTW) ] " +"van het product (niet gebaseerd op historische waardes). Het veld houdt " +"rekening met prijzen incl. en excl. BTW. Indien geen verkooprijs is " +"ingevoerd, wordt 999,0 weergegeven." + +#. module: product_standard_margin +#: constraint:product.product:0 +msgid "Error: Invalid ean code" +msgstr "Fout: ongeldige ean code" + +#. module: product_standard_margin +#: help:product.product,standard_margin:0 +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values).Take care of tax include and exclude. If no " +"sale price, the margin will be negativ." +msgstr "" +"Theoretische marge is [ Verkoopprijs (excl. BTW) - Kostprijs) ] van het " +"product (niet gebaseerd op historische waardes). Het veld houdt rekening met " +"prijzen incl. en excl. BTW. Indien geen verkooprijs is ingevoerd, zal de " +"marge negatief zijn." + +#. module: product_standard_margin +#: view:product.product:0 +msgid "Margin" +msgstr "Marge" + +#. module: product_standard_margin +#: field:product.product,standard_margin:0 +msgid "Theorical Margin" +msgstr "Theoretische marge" diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot new file mode 100644 index 00000000..264b76ed --- /dev/null +++ b/product_standard_margin/i18n/product_standard_margin.pot @@ -0,0 +1,44 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-10-14 18:35+0000\n" +"PO-Revision-Date: 2013-10-14 18:35+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: product_standard_margin +#: help:product.product,standard_margin_rate:0 +msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate +#: field:product.product,standard_margin_rate:0 +msgid "Theorical Margin (%)" +msgstr "" + +#. module: product_standard_margin +#: help:product.product,standard_margin:0 +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin +#: field:product.product,standard_margin:0 +msgid "Theorical Margin" +msgstr "" + diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py new file mode 100644 index 00000000..7d4c7aad --- /dev/null +++ b/product_standard_margin/product_std_margin.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) +# All Right Reserved +# +# Author : Joel Grand-Guillaume +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import orm, fields +import decimal_precision as dp +import logging +_logger = logging.getLogger(__name__) + + +class Product(orm.Model): + _inherit = 'product.product' + + #TODO : compute the margin with default taxes + def _amount_tax_excluded(self, cr, uid, ids, context=None): + """ Compute the list price total without tax + + (in case you are in tax included). + This will use the default taxes defined on the product. + :return dict of values: + {INT Product ID: + float price without tax + } + + """ + res = {} + if context is None: + context = {} + tax_obj = self.pool.get('account.tax') + for prod in self.browse(cr, uid, ids, context=context): + price = prod.list_price + taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) + res[prod.id] = taxes['total'] + return res + + def _compute_margin(self, cr, user, ids, field_name, arg, context=None): + """ Calculate the margin based on product infos. + + Take care of the cost_field define in product_get_cost_field. So the + margin will be computed based on this field. + + We don't take care of the product price type currency to remove the + dependency on the sale module. We consider the cost and sale price is + in the company currency. + + We take care of the default product taxes, and base our computation on + total without tax. + + :return dict of dict of the form : + {INT Product ID : { + {'margin_absolute': float, + 'margin_relative': float} + }} + + """ + + if context is None: + context = {} + res = {} + if not ids: + return res + for product in ids: + res[product] = {'margin_absolute': 0, 'margin_relative': 0} + for product in self.read(cr, user, ids, + ['id', 'cost_price'], context=context): + cost = product['cost_price'] + sale = self._amount_tax_excluded(cr, user, + [product['id']], + context=context)[product['id']] + res[product['id']]['standard_margin'] = sale - cost + if sale == 0: + _logger.debug("Sale price for product ID %d is 0, cannot " + "compute margin rate...", product['id']) + res[product['id']]['standard_margin_rate'] = 999. + else: + res[product['id']]['standard_margin_rate'] = (sale - cost) / sale * 100 + return res + + _columns = { + 'standard_margin': fields.function( + _compute_margin, + method=True, + string='Theorical Margin', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' + 'of the product form (not based on historical values). ' + 'Take care of tax include and exclude. If no sale price, ' + 'the margin will be negativ.'), + 'standard_margin_rate': fields.function( + _compute_margin, + method=True, + string='Theorical Margin (%)', + digits_compute=dp.get_precision('Sale Price'), + multi='margin', + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' + 'of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price ' + 'set, will display 999.0'), + } diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/product_std_margin_view.xml new file mode 100644 index 00000000..07cfa313 --- /dev/null +++ b/product_standard_margin/product_std_margin_view.xml @@ -0,0 +1,20 @@ + + + + + product.markup.view.form + form + product.product + + + + + + + + + + + + + From 4c906dc281ecf518490ea6ae8b9cd799fed88a27 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 24 Jul 2015 09:33:14 +0200 Subject: [PATCH 25/75] [PORT][WIP] port somes commit from V7 branches, specially 18bf9614b1c58f39ec8bdbd53cf4363faceaa9c1 that make standard_margin and standard_margin_rate stored fields; --- product_standard_margin/__init__.py | 1 - product_standard_margin/__openerp__.py | 30 +++++----- product_standard_margin/product_std_margin.py | 58 +++++++++++++------ 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py index 4a754ba5..04072607 100644 --- a/product_standard_margin/__init__.py +++ b/product_standard_margin/__init__.py @@ -19,4 +19,3 @@ # ############################################################################## from . import product_std_margin - diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index e9069f0c..0c976ec6 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -24,31 +24,35 @@ 'maintainer': 'Camptocamp', 'category': 'Sales Management', 'complexity': "normal", # easy, normal, expert - 'depends': ['product_get_cost_field', 'account'], + 'depends': ['product_get_cost_field', + 'account'], 'description': """ - Add a field on the product form that compute the standard (or theorical) margin based on the - current values of sale and cost price present in the product form. We take care of taxe included - or excluded. + Add a field on the product form that compute the standard (or theorical) + margin based on the current values of sale and cost price present in the + product form. We take care of taxe included or excluded. - It will just compute it as follow: (Sale Price without tax - Cost Price) / Sale Price without tax + It will just compute it as follow: (Sale Price without tax - Cost Price) / + Sale Price without tax - Remember that this module can be used in conjonction with product_cost_incl_bom to have the - cost price computed from the BOM when a product has one. + Remember that this module can be used in conjonction with + product_cost_incl_bom to have the cost price computed from the BOM when a + product has one. WARNING: - 1) As this module will base his simple computation on sale and cost prices, it suppose - you have them both in the same currency (the price type must of the same currency for both of - them). Remember this is the default OpenERP configuration (price type of all product price - fields are set as the same as the company currency). We don't take care of it cause otherwise - we should have added a dependency on sale module. + 1) As this module will base his simple computation on sale and cost prices, + it suppose you have them both in the same currency (the price type must of + the same currency for both of them). Remember this is the default OpenERP + configuration (price type of all product price fields are set as the same as + the company currency). We don't take care of it cause otherwise we should + have added a dependency on sale module. """, 'website': 'http://www.camptocamp.com/', 'init_xml': [], 'data': ['product_std_margin_view.xml'], 'tests': [], - 'installable': False, + 'installable': True, 'auto_install': False, 'license': 'AGPL-3', 'application': True} diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/product_std_margin.py index 7d4c7aad..408a07dd 100644 --- a/product_standard_margin/product_std_margin.py +++ b/product_standard_margin/product_std_margin.py @@ -27,10 +27,10 @@ _logger = logging.getLogger(__name__) -class Product(orm.Model): +class ProductProduct(orm.Model): _inherit = 'product.product' - #TODO : compute the margin with default taxes + # TODO : compute the margin with default taxes def _amount_tax_excluded(self, cr, uid, ids, context=None): """ Compute the list price total without tax @@ -48,7 +48,11 @@ def _amount_tax_excluded(self, cr, uid, ids, context=None): tax_obj = self.pool.get('account.tax') for prod in self.browse(cr, uid, ids, context=context): price = prod.list_price - taxes = tax_obj.compute_all(cr, uid, prod.taxes_id, price, 1, product=prod.id) + taxes = tax_obj.compute_all(cr, uid, + prod.taxes_id, + price, + 1, + product=prod.id) res[prod.id] = taxes['total'] return res @@ -67,37 +71,56 @@ def _compute_margin(self, cr, user, ids, field_name, arg, context=None): :return dict of dict of the form : {INT Product ID : { - {'margin_absolute': float, - 'margin_relative': float} + {'standard_margin': float, + 'standard_margin_rate': float} }} """ - - if context is None: - context = {} - res = {} - if not ids: - return res - for product in ids: - res[product] = {'margin_absolute': 0, 'margin_relative': 0} + context = context and context or {} + res = {id: {} for id in ids} for product in self.read(cr, user, ids, ['id', 'cost_price'], context=context): cost = product['cost_price'] sale = self._amount_tax_excluded(cr, user, [product['id']], context=context)[product['id']] - res[product['id']]['standard_margin'] = sale - cost + _res = res[product['id']] + _res['standard_margin'] = sale - cost if sale == 0: _logger.debug("Sale price for product ID %d is 0, cannot " - "compute margin rate...", product['id']) - res[product['id']]['standard_margin_rate'] = 999. + "compute margin rate...", + product['id']) + _res['standard_margin_rate'] = 999. else: - res[product['id']]['standard_margin_rate'] = (sale - cost) / sale * 100 + _res['standard_margin_rate'] = (sale - cost) / sale * 100 return res + def _get_product_margin_change_from_tax(self, cr, uid, ids, context=None): + """Find the products to trigger when a Tax changes""" + pt_obj = self.pool['product.template'] + pp_obj = self.pool['product.product'] + pt_ids = pt_obj.search(cr, uid, [ + '|', ('taxes_id', 'in', ids), + ('supplier_taxes_id', 'in', ids)], context=context) + pp_ids = pp_obj.search( + cr, uid, [('product_tmpl_id', 'in', pt_ids)], context=context) + return pp_ids + + _margin_triggers = { + 'product.product': ( + lambda self, cr, uid, ids, context=None: + ids, None, 10), + 'account.tax': ( + _get_product_margin_change_from_tax, [ + 'type', 'price_include', 'amount', + 'include_base_amount', 'child_depend'], + 10), + } + _columns = { 'standard_margin': fields.function( _compute_margin, + store=_margin_triggers, method=True, string='Theorical Margin', digits_compute=dp.get_precision('Sale Price'), @@ -108,6 +131,7 @@ def _compute_margin(self, cr, user, ids, field_name, arg, context=None): 'the margin will be negativ.'), 'standard_margin_rate': fields.function( _compute_margin, + store=_margin_triggers, method=True, string='Theorical Margin (%)', digits_compute=dp.get_precision('Sale Price'), From 5637cc4f7de8999f452066926a29afc6a074867f Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 24 Jul 2015 09:43:25 +0200 Subject: [PATCH 26/75] [PORT][REF] OCA convention; --- product_standard_margin/__init__.py | 2 +- product_standard_margin/__openerp__.py | 4 +++- product_standard_margin/models/__init__.py | 21 +++++++++++++++++++ .../product_product.py} | 0 .../view.xml} | 0 5 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 product_standard_margin/models/__init__.py rename product_standard_margin/{product_std_margin.py => models/product_product.py} (100%) rename product_standard_margin/{product_std_margin_view.xml => views/view.xml} (100%) diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py index 04072607..54f620f4 100644 --- a/product_standard_margin/__init__.py +++ b/product_standard_margin/__init__.py @@ -18,4 +18,4 @@ # along with this program. If not, see . # ############################################################################## -from . import product_std_margin +from . import models diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index 0c976ec6..2f82b357 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -50,7 +50,9 @@ """, 'website': 'http://www.camptocamp.com/', 'init_xml': [], - 'data': ['product_std_margin_view.xml'], + 'data': [ + 'views/view.xml', +], 'tests': [], 'installable': True, 'auto_install': False, diff --git a/product_standard_margin/models/__init__.py b/product_standard_margin/models/__init__.py new file mode 100644 index 00000000..8d4366b6 --- /dev/null +++ b/product_standard_margin/models/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2012 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import product_product diff --git a/product_standard_margin/product_std_margin.py b/product_standard_margin/models/product_product.py similarity index 100% rename from product_standard_margin/product_std_margin.py rename to product_standard_margin/models/product_product.py diff --git a/product_standard_margin/product_std_margin_view.xml b/product_standard_margin/views/view.xml similarity index 100% rename from product_standard_margin/product_std_margin_view.xml rename to product_standard_margin/views/view.xml From 0edd2d1a976485fd4c18dfb65d4bc9b0b88d2b27 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 24 Jul 2015 17:31:00 +0200 Subject: [PATCH 27/75] [REF] V8 api; [FIX] margin precision; [REF] new description in readme file; [ADD] new 'field list_price_vat_excl'; --- product_standard_margin/README.rst | 55 +++++++ product_standard_margin/__init__.py | 1 + product_standard_margin/__openerp__.py | 56 ++----- .../data/decimal_precision.yml | 24 +++ .../models/product_product.py | 153 +++++------------- product_standard_margin/views/view.xml | 31 ++-- 6 files changed, 153 insertions(+), 167 deletions(-) create mode 100644 product_standard_margin/README.rst create mode 100644 product_standard_margin/data/decimal_precision.yml diff --git a/product_standard_margin/README.rst b/product_standard_margin/README.rst new file mode 100644 index 00000000..1c5c9e35 --- /dev/null +++ b/product_standard_margin/README.rst @@ -0,0 +1,55 @@ +Product Margin and Margin Rate +============================== + +Add a field on the product form that compute the standard (or theorical) +margin based on the current values of sale and replenishment cost present in +the product form. We take care of taxe included or excluded. + +It will just compute it as follow: +(Sale Price without tax - Replenishment Cost) / Sale Price without tax + +Remember that this module can be used in conjonction with +product_cost_incl_bom to have the replenishment cost computed from the BOM when +a product has one. + + WARNING: + + 1) As this module will base his simple computation on sale and cost prices, + it suppose you have them both in the same currency (the price type must of + the same currency for both of them). Remember this is the default OpenERP + configuration (price type of all product price fields are set as the same as + the company currency). We don't take care of it cause otherwise we should + have added a dependency on sale module. + +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 +`here `_. + +Credits +======= + +Contributors +------------ + +* Alexandre Fayolle +* Yannick Vaucher +* Joël Grand-Guillaume +* Sylvain Le Gal (https://twitter.com/legalsylvain) + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +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. + +To contribute to this module, please visit http://odoo-community.org. + diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py index 54f620f4..cb1a1975 100644 --- a/product_standard_margin/__init__.py +++ b/product_standard_margin/__init__.py @@ -18,4 +18,5 @@ # along with this program. If not, see . # ############################################################################## + from . import models diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index 2f82b357..5db42015 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -18,43 +18,19 @@ # along with this program. If not, see . # ############################################################################## -{'name': 'Markup rate on product and sales', - 'version': '1.0', - 'author': "Camptocamp,Odoo Community Association (OCA)", - 'maintainer': 'Camptocamp', - 'category': 'Sales Management', - 'complexity': "normal", # easy, normal, expert - 'depends': ['product_get_cost_field', - 'account'], - 'description': """ - Add a field on the product form that compute the standard (or theorical) - margin based on the current values of sale and cost price present in the - product form. We take care of taxe included or excluded. - - It will just compute it as follow: (Sale Price without tax - Cost Price) / - Sale Price without tax - - Remember that this module can be used in conjonction with - product_cost_incl_bom to have the cost price computed from the BOM when a - product has one. - - WARNING: - - 1) As this module will base his simple computation on sale and cost prices, - it suppose you have them both in the same currency (the price type must of - the same currency for both of them). Remember this is the default OpenERP - configuration (price type of all product price fields are set as the same as - the company currency). We don't take care of it cause otherwise we should - have added a dependency on sale module. - - """, - 'website': 'http://www.camptocamp.com/', - 'init_xml': [], - 'data': [ - 'views/view.xml', -], - 'tests': [], - 'installable': True, - 'auto_install': False, - 'license': 'AGPL-3', - 'application': True} +{ + 'name': 'Product Margin and Margin Rate', + 'version': '2.0', + 'author': 'Camptocamp,GRAP,Odoo Community Association (OCA)', + 'category': 'Product', + 'depends': [ + 'product_replenishment_cost', + 'account', + ], + 'website': 'http://www.camptocamp.com/', + 'data': [ + 'data/decimal_precision.yml', + 'views/view.xml', + ], + 'license': 'AGPL-3', +} diff --git a/product_standard_margin/data/decimal_precision.yml b/product_standard_margin/data/decimal_precision.yml new file mode 100644 index 00000000..c96bcc57 --- /dev/null +++ b/product_standard_margin/data/decimal_precision.yml @@ -0,0 +1,24 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2015-Today GRAP (http://www.grap.coop) +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +- !record {model: decimal.precision, id: product_margin_precision}: + name: Product Margin Precision + digits: 2 diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 408a07dd..657e1f87 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -21,123 +21,54 @@ # ############################################################################## -from openerp.osv import orm, fields -import decimal_precision as dp -import logging -_logger = logging.getLogger(__name__) +from openerp import fields, api +from openerp.models import Model +import openerp.addons.decimal_precision as dp -class ProductProduct(orm.Model): +class ProductProduct(Model): _inherit = 'product.product' - # TODO : compute the margin with default taxes - def _amount_tax_excluded(self, cr, uid, ids, context=None): - """ Compute the list price total without tax + @api.multi + @api.depends( + 'product_tmpl_id.list_price', 'replenishment_cost', 'taxes_id.type', + 'taxes_id.price_include', 'taxes_id.amount', + 'taxes_id.include_base_amount', 'taxes_id.child_depend') + def _get_margin(self): + print "_get_margin" + tax_obj = self.pool['account.tax'] + for product in self: + product.list_price_vat_excl = tax_obj.compute_all( + self.env.cr, self.env.uid, product.taxes_id, + product.list_price, 1, product=product.id)['total'] - (in case you are in tax included). - This will use the default taxes defined on the product. - :return dict of values: - {INT Product ID: - float price without tax - } - - """ - res = {} - if context is None: - context = {} - tax_obj = self.pool.get('account.tax') - for prod in self.browse(cr, uid, ids, context=context): - price = prod.list_price - taxes = tax_obj.compute_all(cr, uid, - prod.taxes_id, - price, - 1, - product=prod.id) - res[prod.id] = taxes['total'] - return res - - def _compute_margin(self, cr, user, ids, field_name, arg, context=None): - """ Calculate the margin based on product infos. - - Take care of the cost_field define in product_get_cost_field. So the - margin will be computed based on this field. - - We don't take care of the product price type currency to remove the - dependency on the sale module. We consider the cost and sale price is - in the company currency. - - We take care of the default product taxes, and base our computation on - total without tax. - - :return dict of dict of the form : - {INT Product ID : { - {'standard_margin': float, - 'standard_margin_rate': float} - }} - - """ - context = context and context or {} - res = {id: {} for id in ids} - for product in self.read(cr, user, ids, - ['id', 'cost_price'], context=context): - cost = product['cost_price'] - sale = self._amount_tax_excluded(cr, user, - [product['id']], - context=context)[product['id']] - _res = res[product['id']] - _res['standard_margin'] = sale - cost - if sale == 0: - _logger.debug("Sale price for product ID %d is 0, cannot " - "compute margin rate...", - product['id']) - _res['standard_margin_rate'] = 999. + product.standard_margin =\ + product.list_price_vat_excl - product.replenishment_cost + if product.list_price_vat_excl == 0: + product.standard_margin_rate = 999. else: - _res['standard_margin_rate'] = (sale - cost) / sale * 100 - return res + product.standard_margin_rate = ( + (product.list_price_vat_excl - product.replenishment_cost) / + product.list_price_vat_excl * 100) - def _get_product_margin_change_from_tax(self, cr, uid, ids, context=None): - """Find the products to trigger when a Tax changes""" - pt_obj = self.pool['product.template'] - pp_obj = self.pool['product.product'] - pt_ids = pt_obj.search(cr, uid, [ - '|', ('taxes_id', 'in', ids), - ('supplier_taxes_id', 'in', ids)], context=context) - pp_ids = pp_obj.search( - cr, uid, [('product_tmpl_id', 'in', pt_ids)], context=context) - return pp_ids + # Column Section + list_price_vat_excl = fields.Float( + compute=_get_margin, string='Sale Price VAT Excluded', store=True, + digits_compute=dp.get_precision('Product Price'), + ) - _margin_triggers = { - 'product.product': ( - lambda self, cr, uid, ids, context=None: - ids, None, 10), - 'account.tax': ( - _get_product_margin_change_from_tax, [ - 'type', 'price_include', 'amount', - 'include_base_amount', 'child_depend'], - 10), - } + standard_margin = fields.Float( + compute=_get_margin, string='Theorical Margin', store=True, + digits_compute=dp.get_precision('Product Price'), + help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' + 'of the product form (not based on historical values). ' + 'Take care of tax include and exclude. If no sale price, ' + 'the margin will be negativ.') - _columns = { - 'standard_margin': fields.function( - _compute_margin, - store=_margin_triggers, - method=True, - string='Theorical Margin', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' - 'of the product form (not based on historical values). ' - 'Take care of tax include and exclude. If no sale price, ' - 'the margin will be negativ.'), - 'standard_margin_rate': fields.function( - _compute_margin, - store=_margin_triggers, - method=True, - string='Theorical Margin (%)', - digits_compute=dp.get_precision('Sale Price'), - multi='margin', - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' - 'of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price ' - 'set, will display 999.0'), - } + standard_margin_rate = fields.Float( + compute=_get_margin, string='Theorical Margin (%)', store=True, + digits_compute=dp.get_precision('Product Margin Precision'), + help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' + 'of the product form (not based on historical values).' + 'Take care of tax include and exclude.. If no sale price ' + 'set, will display 999.0') diff --git a/product_standard_margin/views/view.xml b/product_standard_margin/views/view.xml index 07cfa313..eaeba828 100644 --- a/product_standard_margin/views/view.xml +++ b/product_standard_margin/views/view.xml @@ -1,20 +1,19 @@ - - - product.markup.view.form - form - product.product - - - - - - - - - - + + + + product.product + + + + + + + + + + - + From 3a1bbd7b882cba0c634c50bcfbd994df684d57a0 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 17 Aug 2015 12:03:41 +0200 Subject: [PATCH 28/75] [FIX] flake8 + Pylint; --- product_standard_margin/models/product_product.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 657e1f87..01372f8b 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -35,12 +35,11 @@ class ProductProduct(Model): 'taxes_id.price_include', 'taxes_id.amount', 'taxes_id.include_base_amount', 'taxes_id.child_depend') def _get_margin(self): - print "_get_margin" tax_obj = self.pool['account.tax'] for product in self: product.list_price_vat_excl = tax_obj.compute_all( self.env.cr, self.env.uid, product.taxes_id, - product.list_price, 1, product=product.id)['total'] + product.list_price, 1, product=product.id)['total'] product.standard_margin =\ product.list_price_vat_excl - product.replenishment_cost @@ -48,7 +47,8 @@ def _get_margin(self): product.standard_margin_rate = 999. else: product.standard_margin_rate = ( - (product.list_price_vat_excl - product.replenishment_cost) / + (product.list_price_vat_excl + - product.replenishment_cost) / product.list_price_vat_excl * 100) # Column Section From 6645a423ba91ceaee5f556826b20e2c6aa444b1c Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 17 Aug 2015 17:54:27 +0200 Subject: [PATCH 29/75] [REF] use new API; --- product_standard_margin/models/product_product.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 01372f8b..6ddb14d3 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -35,10 +35,8 @@ class ProductProduct(Model): 'taxes_id.price_include', 'taxes_id.amount', 'taxes_id.include_base_amount', 'taxes_id.child_depend') def _get_margin(self): - tax_obj = self.pool['account.tax'] for product in self: - product.list_price_vat_excl = tax_obj.compute_all( - self.env.cr, self.env.uid, product.taxes_id, + product.list_price_vat_excl = product.taxes_id.compute_all( product.list_price, 1, product=product.id)['total'] product.standard_margin =\ From f36859871758dccee14c6dade705a1f51ad86e48 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 17 Aug 2015 17:57:43 +0200 Subject: [PATCH 30/75] [REF] add AGPL logo; --- product_standard_margin/README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/product_standard_margin/README.rst b/product_standard_margin/README.rst index 1c5c9e35..abaf29e0 100644 --- a/product_standard_margin/README.rst +++ b/product_standard_margin/README.rst @@ -1,3 +1,6 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + Product Margin and Margin Rate ============================== From ccafffbf3a3f13765309041482b6e094fcdbf1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 9 Oct 2015 10:01:49 +0200 Subject: [PATCH 31/75] [UPD] prefix versions with 8.0 --- product_standard_margin/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index 5db42015..d523b73f 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -20,7 +20,7 @@ ############################################################################## { 'name': 'Product Margin and Margin Rate', - 'version': '2.0', + 'version': '8.0.2.0.0', 'author': 'Camptocamp,GRAP,Odoo Community Association (OCA)', 'category': 'Product', 'depends': [ From e5e5377dc3585aa9ca364837f971a7d1af79d894 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 14 Oct 2015 03:30:30 +0200 Subject: [PATCH 32/75] [MIG] Make modules uninstallable --- product_standard_margin/__openerp__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__openerp__.py index d523b73f..845100e4 100644 --- a/product_standard_margin/__openerp__.py +++ b/product_standard_margin/__openerp__.py @@ -33,4 +33,5 @@ 'views/view.xml', ], 'license': 'AGPL-3', + 'installable': False, } From 00643602abcfb6a4be139fd368125bc52ffce136 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Thu, 6 Oct 2016 15:56:23 +0200 Subject: [PATCH 33/75] [MIG] Rename manifest files --- product_standard_margin/{__openerp__.py => __manifest__.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename product_standard_margin/{__openerp__.py => __manifest__.py} (100%) diff --git a/product_standard_margin/__openerp__.py b/product_standard_margin/__manifest__.py similarity index 100% rename from product_standard_margin/__openerp__.py rename to product_standard_margin/__manifest__.py From 1a4d9323e31ec6aba3d8857185940234a9868b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul=20=28ACSONE=29?= Date: Fri, 15 Jun 2018 23:32:06 +0200 Subject: [PATCH 34/75] remove obsolete .pot files [ci skip] --- .../i18n/product_standard_margin.pot | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 product_standard_margin/i18n/product_standard_margin.pot diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot deleted file mode 100644 index 264b76ed..00000000 --- a/product_standard_margin/i18n/product_standard_margin.pot +++ /dev/null @@ -1,44 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * product_standard_margin -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-10-14 18:35+0000\n" -"PO-Revision-Date: 2013-10-14 18:35+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: product_standard_margin -#: help:product.product,standard_margin_rate:0 -msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model,name:product_standard_margin.model_product_product -msgid "Product" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate -#: field:product.product,standard_margin_rate:0 -msgid "Theorical Margin (%)" -msgstr "" - -#. module: product_standard_margin -#: help:product.product,standard_margin:0 -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin -#: field:product.product,standard_margin:0 -msgid "Theorical Margin" -msgstr "" - From 0ce74bf33b0eb1e24db83bd9f6708f08e592e4c5 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Tue, 7 Jan 2020 12:36:25 +0100 Subject: [PATCH 35/75] [REF] product_standard_margin: Black python code --- product_standard_margin/__manifest__.py | 24 +++---- .../models/product_product.py | 66 ++++++++++++------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/product_standard_margin/__manifest__.py b/product_standard_margin/__manifest__.py index 845100e4..f1de21b6 100644 --- a/product_standard_margin/__manifest__.py +++ b/product_standard_margin/__manifest__.py @@ -19,19 +19,13 @@ # ############################################################################## { - 'name': 'Product Margin and Margin Rate', - 'version': '8.0.2.0.0', - 'author': 'Camptocamp,GRAP,Odoo Community Association (OCA)', - 'category': 'Product', - 'depends': [ - 'product_replenishment_cost', - 'account', - ], - 'website': 'http://www.camptocamp.com/', - 'data': [ - 'data/decimal_precision.yml', - 'views/view.xml', - ], - 'license': 'AGPL-3', - 'installable': False, + "name": "Product Margin and Margin Rate", + "version": "8.0.2.0.0", + "author": "Camptocamp,GRAP,Odoo Community Association (OCA)", + "category": "Product", + "depends": ["product_replenishment_cost", "account",], + "website": "http://www.camptocamp.com/", + "data": ["data/decimal_precision.yml", "views/view.xml",], + "license": "AGPL-3", + "installable": False, } diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 6ddb14d3..7a6a6f25 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -27,46 +27,62 @@ class ProductProduct(Model): - _inherit = 'product.product' + _inherit = "product.product" @api.multi @api.depends( - 'product_tmpl_id.list_price', 'replenishment_cost', 'taxes_id.type', - 'taxes_id.price_include', 'taxes_id.amount', - 'taxes_id.include_base_amount', 'taxes_id.child_depend') + "product_tmpl_id.list_price", + "replenishment_cost", + "taxes_id.type", + "taxes_id.price_include", + "taxes_id.amount", + "taxes_id.include_base_amount", + "taxes_id.child_depend", + ) def _get_margin(self): for product in self: product.list_price_vat_excl = product.taxes_id.compute_all( - product.list_price, 1, product=product.id)['total'] + product.list_price, 1, product=product.id + )["total"] - product.standard_margin =\ + product.standard_margin = ( product.list_price_vat_excl - product.replenishment_cost + ) if product.list_price_vat_excl == 0: - product.standard_margin_rate = 999. + product.standard_margin_rate = 999.0 else: product.standard_margin_rate = ( - (product.list_price_vat_excl - - product.replenishment_cost) / - product.list_price_vat_excl * 100) + (product.list_price_vat_excl - product.replenishment_cost) + / product.list_price_vat_excl + * 100 + ) # Column Section list_price_vat_excl = fields.Float( - compute=_get_margin, string='Sale Price VAT Excluded', store=True, - digits_compute=dp.get_precision('Product Price'), - ) + compute=_get_margin, + string="Sale Price VAT Excluded", + store=True, + digits_compute=dp.get_precision("Product Price"), + ) standard_margin = fields.Float( - compute=_get_margin, string='Theorical Margin', store=True, - digits_compute=dp.get_precision('Product Price'), - help='Theorical Margin is [ sale price (Wo Tax) - cost price ] ' - 'of the product form (not based on historical values). ' - 'Take care of tax include and exclude. If no sale price, ' - 'the margin will be negativ.') + compute=_get_margin, + string="Theorical Margin", + store=True, + digits_compute=dp.get_precision("Product Price"), + help="Theorical Margin is [ sale price (Wo Tax) - cost price ] " + "of the product form (not based on historical values). " + "Take care of tax include and exclude. If no sale price, " + "the margin will be negativ.", + ) standard_margin_rate = fields.Float( - compute=_get_margin, string='Theorical Margin (%)', store=True, - digits_compute=dp.get_precision('Product Margin Precision'), - help='Markup rate is [ Theorical Margin / sale price (Wo Tax) ] ' - 'of the product form (not based on historical values).' - 'Take care of tax include and exclude.. If no sale price ' - 'set, will display 999.0') + compute=_get_margin, + string="Theorical Margin (%)", + store=True, + digits_compute=dp.get_precision("Product Margin Precision"), + help="Markup rate is [ Theorical Margin / sale price (Wo Tax) ] " + "of the product form (not based on historical values)." + "Take care of tax include and exclude.. If no sale price " + "set, will display 999.0", + ) From dbf5fb0097d1874f5bf720ecc1ad726d9879f54b Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Tue, 7 Jan 2020 12:36:25 +0100 Subject: [PATCH 36/75] [MIG] product_standard_margin: Migration to 12.0 [IMP] compute and display margin fields on template [REF] OCA Convention: readme files, etc. [IMP] Add tests --- product_standard_margin/__init__.py | 21 ---- product_standard_margin/__manifest__.py | 37 +++---- .../data/decimal_precision.yml | 24 ----- product_standard_margin/i18n/fr.po | 64 +++++------ product_standard_margin/models/__init__.py | 21 +--- .../models/product_product.py | 100 +++++++----------- .../models/product_template.py | 67 ++++++++++++ .../readme/CONTRIBUTORS.rst | 4 + .../readme/DESCRIPTION.rst | 17 +++ product_standard_margin/readme/ROADMAP.rst | 7 ++ .../static/description/product_form.png | Bin 0 -> 16078 bytes product_standard_margin/tests/__init__.py | 1 + product_standard_margin/tests/test_module.py | 57 ++++++++++ product_standard_margin/views/view.xml | 19 ---- .../views/view_product_product.xml | 32 ++++++ .../views/view_product_template.xml | 16 +++ 16 files changed, 287 insertions(+), 200 deletions(-) delete mode 100644 product_standard_margin/data/decimal_precision.yml create mode 100644 product_standard_margin/models/product_template.py create mode 100644 product_standard_margin/readme/CONTRIBUTORS.rst create mode 100644 product_standard_margin/readme/DESCRIPTION.rst create mode 100644 product_standard_margin/readme/ROADMAP.rst create mode 100644 product_standard_margin/static/description/product_form.png create mode 100644 product_standard_margin/tests/__init__.py create mode 100644 product_standard_margin/tests/test_module.py delete mode 100644 product_standard_margin/views/view.xml create mode 100644 product_standard_margin/views/view_product_product.xml create mode 100644 product_standard_margin/views/view_product_template.xml diff --git a/product_standard_margin/__init__.py b/product_standard_margin/__init__.py index cb1a1975..0650744f 100644 --- a/product_standard_margin/__init__.py +++ b/product_standard_margin/__init__.py @@ -1,22 +1 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - from . import models diff --git a/product_standard_margin/__manifest__.py b/product_standard_margin/__manifest__.py index f1de21b6..6b59657d 100644 --- a/product_standard_margin/__manifest__.py +++ b/product_standard_margin/__manifest__.py @@ -1,31 +1,18 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# Copyright (C) 2012 - Today: Camptocamp SA +# @author: Joel Grand-Guillaume +# Copyright (C) 2019 - 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": "Product Margin and Margin Rate", - "version": "8.0.2.0.0", + "version": "12.0.1.0.0", "author": "Camptocamp,GRAP,Odoo Community Association (OCA)", "category": "Product", - "depends": ["product_replenishment_cost", "account",], - "website": "http://www.camptocamp.com/", - "data": ["data/decimal_precision.yml", "views/view.xml",], + "depends": ["account"], + "maintainers": ["legalsylvain"], + "website": "https://www.github.com/OCA/margin-analysis", + "data": ["views/view_product_product.xml", "views/view_product_template.xml"], "license": "AGPL-3", - "installable": False, + "installable": True, + "images": ["static/description/product_form.png"], } diff --git a/product_standard_margin/data/decimal_precision.yml b/product_standard_margin/data/decimal_precision.yml deleted file mode 100644 index c96bcc57..00000000 --- a/product_standard_margin/data/decimal_precision.yml +++ /dev/null @@ -1,24 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# Copyright (C) 2015-Today GRAP (http://www.grap.coop) -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -- !record {model: decimal.precision, id: product_margin_precision}: - name: Product Margin Precision - digits: 2 diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po index 228f7994..c9b62192 100644 --- a/product_standard_margin/i18n/fr.po +++ b/product_standard_margin/i18n/fr.po @@ -1,57 +1,59 @@ -# Translation of OpenERP Server. +# Translation of Odoo Server. # This file contains the translation of the following modules: -# * product_standard_margin +# * product_standard_margin # msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-10-14 18:35+0000\n" -"PO-Revision-Date: 2012-11-07 14:35+0000\n" +"POT-Creation-Date: 2020-01-07 14:51+0000\n" +"PO-Revision-Date: 2020-01-07 14:51+0000\n" "Last-Translator: <>\n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" #. module: product_standard_margin -#: help:product.product,standard_margin_rate:0 -msgid "" -"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.. " -"If no sale price set, will display 999.0" -msgstr "" -"Taux de marge théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " -"formulaire Produit] (ne tient pas compte de la facturation effective). Ce " -"taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " -"taux sera de 999.0" +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate +msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "Taux de marque théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du formulaire Produit] (ne tient pas compte de la facturation effective). Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le taux sera de 999.0" #. module: product_standard_margin #: model:ir.model,name:product_standard_margin.model_product_product msgid "Product" -msgstr "Produit" +msgstr "Article" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_template +msgid "Product Template" +msgstr "Modèle d'article" #. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin_rate -#: field:product.product,standard_margin_rate:0 +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl +msgid "Sale Price VAT Excluded" +msgstr "Prix de vente (HT)" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin" +msgstr "Marge Théorique" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate msgid "Theorical Margin (%)" -msgstr "Marge Théorique (%)" +msgstr "Taux de marque Théorique (%)" #. module: product_standard_margin -#: help:product.product,standard_margin:0 -msgid "" -"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " -"(not based on historical values). Take care of tax include and exclude. If " -"no sale price, the margin will be negativ." +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." msgstr "" "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient " "pas compte de la facturation effective). Ce taux tient compte des PV TTC " "(TVA incluse). Si aucun PV n'a été saisi, la marge sera négative." - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product_standard_margin -#: field:product.product,standard_margin:0 -msgid "Theorical Margin" -msgstr "Marge Théorique" diff --git a/product_standard_margin/models/__init__.py b/product_standard_margin/models/__init__.py index 8d4366b6..18b37e85 100644 --- a/product_standard_margin/models/__init__.py +++ b/product_standard_margin/models/__init__.py @@ -1,21 +1,2 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## from . import product_product +from . import product_template diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 7a6a6f25..3e74258f 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -1,75 +1,29 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (c) 2012 Camptocamp SA (http://www.camptocamp.com) -# All Right Reserved -# -# Author : Joel Grand-Guillaume -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# Copyright (C) 2012 - Today: Camptocamp SA +# @author: Joel Grand-Guillaume +# Copyright (C) 2019 - 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 openerp import fields, api -from openerp.models import Model -import openerp.addons.decimal_precision as dp +from odoo import api, fields, models +import odoo.addons.decimal_precision as dp -class ProductProduct(Model): +class ProductProduct(models.Model): _inherit = "product.product" - @api.multi - @api.depends( - "product_tmpl_id.list_price", - "replenishment_cost", - "taxes_id.type", - "taxes_id.price_include", - "taxes_id.amount", - "taxes_id.include_base_amount", - "taxes_id.child_depend", - ) - def _get_margin(self): - for product in self: - product.list_price_vat_excl = product.taxes_id.compute_all( - product.list_price, 1, product=product.id - )["total"] - - product.standard_margin = ( - product.list_price_vat_excl - product.replenishment_cost - ) - if product.list_price_vat_excl == 0: - product.standard_margin_rate = 999.0 - else: - product.standard_margin_rate = ( - (product.list_price_vat_excl - product.replenishment_cost) - / product.list_price_vat_excl - * 100 - ) - # Column Section list_price_vat_excl = fields.Float( - compute=_get_margin, + compute="_compute_margin", string="Sale Price VAT Excluded", store=True, - digits_compute=dp.get_precision("Product Price"), + digits=dp.get_precision("Product Price"), ) standard_margin = fields.Float( - compute=_get_margin, + compute="_compute_margin", string="Theorical Margin", store=True, - digits_compute=dp.get_precision("Product Price"), + digits=dp.get_precision("Product Price"), help="Theorical Margin is [ sale price (Wo Tax) - cost price ] " "of the product form (not based on historical values). " "Take care of tax include and exclude. If no sale price, " @@ -77,12 +31,38 @@ def _get_margin(self): ) standard_margin_rate = fields.Float( - compute=_get_margin, + compute="_compute_margin", string="Theorical Margin (%)", store=True, - digits_compute=dp.get_precision("Product Margin Precision"), + digits=dp.get_precision("Product Price"), help="Markup rate is [ Theorical Margin / sale price (Wo Tax) ] " "of the product form (not based on historical values)." "Take care of tax include and exclude.. If no sale price " "set, will display 999.0", ) + + # Compute Section + @api.depends( + "lst_price", + "product_tmpl_id.list_price", + "standard_price", + "taxes_id.price_include", + "taxes_id.amount", + "taxes_id.include_base_amount", + ) + def _compute_margin(self): + for product in self: + product.list_price_vat_excl = product.taxes_id.compute_all( + product.lst_price, product=product + )["total_excluded"] + product.standard_margin = ( + product.list_price_vat_excl - product.standard_price + ) + if product.list_price_vat_excl == 0: + product.standard_margin_rate = 999.0 + else: + product.standard_margin_rate = ( + (product.list_price_vat_excl - product.standard_price) + / product.list_price_vat_excl + * 100 + ) diff --git a/product_standard_margin/models/product_template.py b/product_standard_margin/models/product_template.py new file mode 100644 index 00000000..19e1f2a1 --- /dev/null +++ b/product_standard_margin/models/product_template.py @@ -0,0 +1,67 @@ +# Copyright (C) 2012 - Today: Camptocamp SA +# @author: Joel Grand-Guillaume +# Copyright (C) 2019 - 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 +import odoo.addons.decimal_precision as dp + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + # Column Section + list_price_vat_excl = fields.Float( + compute="_compute_margin", + string="Sale Price VAT Excluded", + digits=dp.get_precision("Product Price"), + ) + + standard_margin = fields.Float( + compute="_compute_margin", + string="Theorical Margin", + digits=dp.get_precision("Product Price"), + help="Theorical Margin is [ sale price (Wo Tax) - cost price ] " + "of the product form (not based on historical values). " + "Take care of tax include and exclude. If no sale price, " + "the margin will be negativ.", + ) + + standard_margin_rate = fields.Float( + compute="_compute_margin", + string="Theorical Margin (%)", + digits=dp.get_precision("Product Price"), + help="Margin rate is [ Theorical Margin / sale price (Wo Tax) ] " + "of the product form (not based on historical values)." + "Take care of tax include and exclude.. If no sale price " + "set, will display 999.0", + ) + + # Compute Section + @api.depends( + "lst_price", + "standard_price", + "taxes_id.price_include", + "taxes_id.amount", + "taxes_id.include_base_amount", + ) + def _compute_margin(self): + # The code is duplicated from product.product model + # because otherwise, the recomputation is not done correctly + # when the product datas are changed from the template view + for template in self: + template.list_price_vat_excl = template.taxes_id.compute_all( + template.list_price, product=template + )["total_excluded"] + template.standard_margin = ( + template.list_price_vat_excl - template.standard_price + ) + if template.list_price_vat_excl == 0: + template.standard_margin_rate = 999.0 + else: + template.standard_margin_rate = ( + (template.list_price_vat_excl - template.standard_price) + / template.list_price_vat_excl + * 100 + ) diff --git a/product_standard_margin/readme/CONTRIBUTORS.rst b/product_standard_margin/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..1e1d54b1 --- /dev/null +++ b/product_standard_margin/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Alexandre Fayolle +* Yannick Vaucher +* Joël Grand-Guillaume +* Sylvain Le Gal (https://twitter.com/legalsylvain) diff --git a/product_standard_margin/readme/DESCRIPTION.rst b/product_standard_margin/readme/DESCRIPTION.rst new file mode 100644 index 00000000..3698a568 --- /dev/null +++ b/product_standard_margin/readme/DESCRIPTION.rst @@ -0,0 +1,17 @@ +Add a field on the product form that compute the standard (or theorical) +margin based on the current values of sale and standard price present in +the product form. We take care of taxe included or excluded. + +It will just compute it as follow: +(Sale Price without tax - Standard Price) / Sale Price without tax + +.. figure:: ../static/description/product_form.png + +**Note:** + +As this module will base his simple computation on sale and cost prices, +it suppose you have them both in the same currency (the price type must of +the same currency for both of them). Remember this is the default OpenERP +configuration (price type of all product price fields are set as the same as +the company currency). We don't take care of it cause otherwise we should +have added a dependency on sale module. diff --git a/product_standard_margin/readme/ROADMAP.rst b/product_standard_margin/readme/ROADMAP.rst new file mode 100644 index 00000000..c711b0f1 --- /dev/null +++ b/product_standard_margin/readme/ROADMAP.rst @@ -0,0 +1,7 @@ +* This module will not work properly if used in a multicompany context with product + prices depending on the company. + +* It should be great to use the odoo widget ``percentpie`` for the display of the + field ``standard_margin_rate`` but for the time being, the field is not displayed + properly. + Ref of the Odoo Issue: https://github.com/odoo/odoo/issues/42869 diff --git a/product_standard_margin/static/description/product_form.png b/product_standard_margin/static/description/product_form.png new file mode 100644 index 0000000000000000000000000000000000000000..bd8146a0daace0d58b50f73f97b6d48fe41d7b31 GIT binary patch literal 16078 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 literal 0 HcmV?d00001 diff --git a/product_standard_margin/tests/__init__.py b/product_standard_margin/tests/__init__.py new file mode 100644 index 00000000..d9b96c4f --- /dev/null +++ b/product_standard_margin/tests/__init__.py @@ -0,0 +1 @@ +from . import test_module diff --git a/product_standard_margin/tests/test_module.py b/product_standard_margin/tests/test_module.py new file mode 100644 index 00000000..af7d103e --- /dev/null +++ b/product_standard_margin/tests/test_module.py @@ -0,0 +1,57 @@ +# 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). + +from odoo.tests.common import TransactionCase + + +class TestModule(TransactionCase): + + def setUp(self): + super().setUp() + self.ProductProduct = self.env['product.product'] + self.ProductTemplate = self.env['product.template'] + + # Custom Section + def _create_product(self, model, standard_price, sale_price, sale_tax_ids): + if model == 'product': + ModelObj = self.ProductProduct + else: + ModelObj = self.ProductTemplate + return ModelObj.create({ + 'name': 'Demo Product', + 'standard_price': standard_price, + 'lst_price': sale_price, + 'taxes_id': [(6, 0, sale_tax_ids)], + }) + + # Test Section + def test_01_classic_margin(self): + for model in ['product', 'template']: + product = self._create_product(model, 50, 200, []) + self.assertEqual( + product.standard_margin, 150, + "Incorrect Standard Margin") + self.assertEqual( + product.standard_margin_rate, 75.0, + "Incorrect Standard Margin Rate") + + def test_02_margin_without_standard_price(self): + for model in ['product', 'template']: + product = self._create_product(model, 0, 200, []) + self.assertEqual( + product.standard_margin, 200, + "Incorrect Standard Margin (without standard price)") + self.assertEqual( + product.standard_margin_rate, 100.0, + "Incorrect Standard Margin Rate (without standard price)") + + def test_03_margin_without_sale_price(self): + for model in ['product', 'template']: + product = self._create_product(model, 50, 0, []) + self.assertEqual( + product.standard_margin, -50, + "Incorrect Standard Margin (without sale price)") + self.assertEqual( + product.standard_margin_rate, 999.0, + "Incorrect Standard Margin Rate (without sale price)") diff --git a/product_standard_margin/views/view.xml b/product_standard_margin/views/view.xml deleted file mode 100644 index eaeba828..00000000 --- a/product_standard_margin/views/view.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - product.product - - - - - - - - - - - - - diff --git a/product_standard_margin/views/view_product_product.xml b/product_standard_margin/views/view_product_product.xml new file mode 100644 index 00000000..2e1df3e9 --- /dev/null +++ b/product_standard_margin/views/view_product_product.xml @@ -0,0 +1,32 @@ + + + + + product.product + + + + + + + + + + + + + + product.product + + + + + + + + + + + + + diff --git a/product_standard_margin/views/view_product_template.xml b/product_standard_margin/views/view_product_template.xml new file mode 100644 index 00000000..da68bdd0 --- /dev/null +++ b/product_standard_margin/views/view_product_template.xml @@ -0,0 +1,16 @@ + + + + + product.template + + + + + + + + + From 4d4697072c4378521d61247ebbba551a4532a354 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Sun, 19 Jul 2020 08:36:41 +0000 Subject: [PATCH 37/75] [UPD] Update product_standard_margin.pot --- product_standard_margin/i18n/fr.po | 33 +++++++-- product_standard_margin/i18n/nl.po | 72 +++++++++++++------ .../i18n/product_standard_margin.pot | 59 +++++++++++++++ 3 files changed, 136 insertions(+), 28 deletions(-) create mode 100644 product_standard_margin/i18n/product_standard_margin.pot diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po index c9b62192..b168fe40 100644 --- a/product_standard_margin/i18n/fr.po +++ b/product_standard_margin/i18n/fr.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * product_standard_margin +# * product_standard_margin # msgid "" msgstr "" @@ -10,16 +10,36 @@ msgstr "" "PO-Revision-Date: 2020-01-07 14:51+0000\n" "Last-Translator: <>\n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" #. module: product_standard_margin -#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate -msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" -msgstr "Taux de marque théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du formulaire Produit] (ne tient pas compte de la facturation effective). Ce taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le taux sera de 999.0" +msgid "" +"Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" +"Taux de marque théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " +"formulaire Produit] (ne tient pas compte de la facturation effective). Ce " +"taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " +"taux sera de 999.0" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate +#, fuzzy +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" +"Taux de marque théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " +"formulaire Produit] (ne tient pas compte de la facturation effective). Ce " +"taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " +"taux sera de 999.0" #. module: product_standard_margin #: model:ir.model,name:product_standard_margin.model_product_product @@ -52,7 +72,10 @@ msgstr "Taux de marque Théorique (%)" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." msgstr "" "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient " "pas compte de la facturation effective). Ce taux tient compte des PV TTC " diff --git a/product_standard_margin/i18n/nl.po b/product_standard_margin/i18n/nl.po index 554bdeb5..0cc539b5 100644 --- a/product_standard_margin/i18n/nl.po +++ b/product_standard_margin/i18n/nl.po @@ -11,6 +11,7 @@ msgstr "" "Last-Translator: Erwin van der Ploeg | Endian Solutions " "\n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -18,17 +19,20 @@ msgstr "" "X-Generator: Poedit 1.5.4\n" #. module: product_standard_margin -#: model:ir.model,name:product_standard_margin.model_product_product -msgid "Product" -msgstr "Product" - -#. module: product_standard_margin -#: field:product.product,standard_margin_rate:0 -msgid "Theorical Margin (%)" -msgstr "Theoretische marge (%)" +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate +#, fuzzy +msgid "" +"Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" +"Theoretische marge (%) is [ Theoretische marge / Verkoopprijs (excl. BTW) ] " +"van het product (niet gebaseerd op historische waardes). Het veld houdt " +"rekening met prijzen incl. en excl. BTW. Indien geen verkooprijs is " +"ingevoerd, wordt 999,0 weergegeven." #. module: product_standard_margin -#: help:product.product,standard_margin_rate:0 +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate msgid "" "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " "form (not based on historical values).Take care of tax include and exclude.. " @@ -40,28 +44,50 @@ msgstr "" "ingevoerd, wordt 999,0 weergegeven." #. module: product_standard_margin -#: constraint:product.product:0 -msgid "Error: Invalid ean code" -msgstr "Fout: ongeldige ean code" +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "Product" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_template +#, fuzzy +msgid "Product Template" +msgstr "Product" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl +msgid "Sale Price VAT Excluded" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin" +msgstr "Theoretische marge" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate +msgid "Theorical Margin (%)" +msgstr "Theoretische marge (%)" #. module: product_standard_margin -#: help:product.product,standard_margin:0 +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin +#, fuzzy msgid "" "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " -"(not based on historical values).Take care of tax include and exclude. If no " -"sale price, the margin will be negativ." +"(not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." msgstr "" "Theoretische marge is [ Verkoopprijs (excl. BTW) - Kostprijs) ] van het " "product (niet gebaseerd op historische waardes). Het veld houdt rekening met " "prijzen incl. en excl. BTW. Indien geen verkooprijs is ingevoerd, zal de " "marge negatief zijn." -#. module: product_standard_margin -#: view:product.product:0 -msgid "Margin" -msgstr "Marge" +#~ msgid "Error: Invalid ean code" +#~ msgstr "Fout: ongeldige ean code" -#. module: product_standard_margin -#: field:product.product,standard_margin:0 -msgid "Theorical Margin" -msgstr "Theoretische marge" +#~ msgid "Margin" +#~ msgstr "Marge" diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot new file mode 100644 index 00000000..fdd3b605 --- /dev/null +++ b/product_standard_margin/i18n/product_standard_margin.pot @@ -0,0 +1,59 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.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: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate +msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate +msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_template +msgid "Product Template" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl +msgid "Sale Price VAT Excluded" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate +msgid "Theorical Margin (%)" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgstr "" + From 4c54b186d2739b25c2b951f7745928bdc5e97899 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 19 Jul 2020 08:47:38 +0000 Subject: [PATCH 38/75] [UPD] README.rst --- product_standard_margin/README.rst | 108 +++-- .../static/description/index.html | 451 ++++++++++++++++++ 2 files changed, 532 insertions(+), 27 deletions(-) create mode 100644 product_standard_margin/static/description/index.html diff --git a/product_standard_margin/README.rst b/product_standard_margin/README.rst index abaf29e0..67f6efbd 100644 --- a/product_standard_margin/README.rst +++ b/product_standard_margin/README.rst @@ -1,58 +1,112 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :alt: License: AGPL-3 - +============================== Product Margin and Margin Rate ============================== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fmargin--analysis-lightgray.png?logo=github + :target: https://github.com/OCA/margin-analysis/tree/12.0/product_standard_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-12-0/margin-analysis-12-0-product_standard_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/132/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + Add a field on the product form that compute the standard (or theorical) -margin based on the current values of sale and replenishment cost present in +margin based on the current values of sale and standard price present in the product form. We take care of taxe included or excluded. It will just compute it as follow: -(Sale Price without tax - Replenishment Cost) / Sale Price without tax +(Sale Price without tax - Standard Price) / Sale Price without tax + +.. figure:: https://raw.githubusercontent.com/OCA/margin-analysis/12.0/product_standard_margin/static/description/product_form.png + +**Note:** + +As this module will base his simple computation on sale and cost prices, +it suppose you have them both in the same currency (the price type must of +the same currency for both of them). Remember this is the default OpenERP +configuration (price type of all product price fields are set as the same as +the company currency). We don't take care of it cause otherwise we should +have added a dependency on sale module. + +**Table of contents** -Remember that this module can be used in conjonction with -product_cost_incl_bom to have the replenishment cost computed from the BOM when -a product has one. +.. contents:: + :local: - WARNING: +Known issues / Roadmap +====================== - 1) As this module will base his simple computation on sale and cost prices, - it suppose you have them both in the same currency (the price type must of - the same currency for both of them). Remember this is the default OpenERP - configuration (price type of all product price fields are set as the same as - the company currency). We don't take care of it cause otherwise we should - have added a dependency on sale module. +* This module will not work properly if used in a multicompany context with product + prices depending on the company. + +* It should be great to use the odoo widget ``percentpie`` for the display of the + field ``standard_margin_rate`` but for the time being, the field is not displayed + properly. + Ref of the Odoo Issue: https://github.com/odoo/odoo/issues/42869 Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +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 -`here `_. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* Camptocamp +* GRAP + Contributors ------------- +~~~~~~~~~~~~ * Alexandre Fayolle * Yannick Vaucher * Joël Grand-Guillaume * Sylvain Le Gal (https://twitter.com/legalsylvain) -Maintainer ----------- - -.. image:: http://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: http://odoo-community.org +Maintainers +~~~~~~~~~~~ This module is maintained by the OCA. -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. +.. 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-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px + :target: https://github.com/legalsylvain + :alt: legalsylvain + +Current `maintainer `__: + +|maintainer-legalsylvain| -To contribute to this module, please visit http://odoo-community.org. +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/product_standard_margin/static/description/index.html b/product_standard_margin/static/description/index.html new file mode 100644 index 00000000..184d8d25 --- /dev/null +++ b/product_standard_margin/static/description/index.html @@ -0,0 +1,451 @@ + + + + + + +Product Margin and Margin Rate + + + +
+

Product Margin and Margin Rate

+ + +

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

+

Add a field on the product form that compute the standard (or theorical) +margin based on the current values of sale and standard price present in +the product form. We take care of taxe included or excluded.

+

It will just compute it as follow: +(Sale Price without tax - Standard Price) / Sale Price without tax

+
+https://raw.githubusercontent.com/OCA/margin-analysis/12.0/product_standard_margin/static/description/product_form.png +
+

Note:

+

As this module will base his simple computation on sale and cost prices, +it suppose you have them both in the same currency (the price type must of +the same currency for both of them). Remember this is the default OpenERP +configuration (price type of all product price fields are set as the same as +the company currency). We don’t take care of it cause otherwise we should +have added a dependency on sale module.

+

Table of contents

+ +
+

Known issues / Roadmap

+
    +
  • This module will not work properly if used in a multicompany context with product +prices depending on the company.
  • +
  • It should be great to use the odoo widget percentpie for the display of the +field standard_margin_rate but for the time being, the field is not displayed +properly. +Ref of the Odoo Issue: https://github.com/odoo/odoo/issues/42869
  • +
+
+
+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
  • 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:

+

legalsylvain

+

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.

+
+
+
+ + From d164f0a38d66274972f92d27fdd6980cbcd38bb4 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 19 Jul 2020 08:47:39 +0000 Subject: [PATCH 39/75] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 product_standard_margin/static/description/icon.png diff --git a/product_standard_margin/static/description/icon.png b/product_standard_margin/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From ce11d00e2e42c45162c8b9a94cdb4cb4fae3adc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Volksdorf?= Date: Fri, 20 Nov 2020 18:15:00 +0000 Subject: [PATCH 40/75] Added translation using Weblate (German) --- product_standard_margin/i18n/de.po | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 product_standard_margin/i18n/de.po diff --git a/product_standard_margin/i18n/de.po b/product_standard_margin/i18n/de.po new file mode 100644 index 00000000..5fc7044b --- /dev/null +++ b/product_standard_margin/i18n/de.po @@ -0,0 +1,59 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\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: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate +msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate +msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_template +msgid "Product Template" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl +msgid "Sale Price VAT Excluded" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate +msgid "Theorical Margin (%)" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgstr "" From 177744b49ff835b564d9ed7bf7117368a960721e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Volksdorf?= Date: Fri, 20 Nov 2020 18:16:40 +0000 Subject: [PATCH 41/75] Translated using Weblate (German) Currently translated at 100.0% (8 of 8 strings) Translation: margin-analysis-12.0/margin-analysis-12.0-product_standard_margin Translate-URL: https://translation.odoo-community.org/projects/margin-analysis-12-0/margin-analysis-12-0-product_standard_margin/de/ --- product_standard_margin/i18n/de.po | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/product_standard_margin/i18n/de.po b/product_standard_margin/i18n/de.po index 5fc7044b..1386c8ad 100644 --- a/product_standard_margin/i18n/de.po +++ b/product_standard_margin/i18n/de.po @@ -6,54 +6,67 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2020-11-20 18:43+0000\n" +"Last-Translator: André Volksdorf \n" "Language-Team: none\n" "Language: de\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: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" msgstr "" +"Der Margensatz ist [ Theoretische Marge / Verkaufspreis (Ohne Steuern) ] des " +"Produkts (nicht auf historischen Werten basierend), wobei darauf zu achten " +"ist, Steuern ein- und auszuschließen. Wenn kein Verkaufspreis festgelegt " +"wurde, wird 999.0 angezeigt" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" msgstr "" +"Der Aufschlagssatz ist [ Theoretische Marge / Verkaufspreis (Ohne Steuern) ] " +"des Produkts (nicht auf historischen Werten basierend), mit und ohne Steuer. " +"Wenn kein Verkaufspreis festgelegt wurde, wird 999.0 angezeigt" #. module: product_standard_margin #: model:ir.model,name:product_standard_margin.model_product_product msgid "Product" -msgstr "" +msgstr "Produkt" #. module: product_standard_margin #: model:ir.model,name:product_standard_margin.model_product_template msgid "Product Template" -msgstr "" +msgstr "Produktvorlage" #. module: product_standard_margin #: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl #: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl msgid "Sale Price VAT Excluded" -msgstr "" +msgstr "Verkaufspreis ohne Mehrwertsteuer" #. module: product_standard_margin #: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin msgid "Theorical Margin" -msgstr "" +msgstr "Theoretische Marge" #. module: product_standard_margin #: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate #: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate msgid "Theorical Margin (%)" -msgstr "" +msgstr "Theoretische Marge (%)" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." msgstr "" +"Theoretische Gewinnmarge ist [ Verkaufspreis (Ohne Steuern) - Einkaufspreis ]" +" des Produkts (nicht auf historischen Werten basierend). Achten Sie darauf, " +"Steuern ein- und auszuschließen. Wenn kein Verkaufspreis angegeben wird, ist " +"die Marge negativ." From c462e8bc1cd630dba15693e0aa033a0da1a65d8e Mon Sep 17 00:00:00 2001 From: Marcel Savegnago Date: Sun, 14 Mar 2021 21:38:36 +0000 Subject: [PATCH 42/75] Added translation using Weblate (Portuguese (Brazil)) --- product_standard_margin/i18n/pt_BR.po | 59 +++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 product_standard_margin/i18n/pt_BR.po diff --git a/product_standard_margin/i18n/pt_BR.po b/product_standard_margin/i18n/pt_BR.po new file mode 100644 index 00000000..c8a04359 --- /dev/null +++ b/product_standard_margin/i18n/pt_BR.po @@ -0,0 +1,59 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate +msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate +msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_template +msgid "Product Template" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl +msgid "Sale Price VAT Excluded" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate +msgid "Theorical Margin (%)" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgstr "" From f4d713567b0e58c7db16b8c49c7052ef0373ce61 Mon Sep 17 00:00:00 2001 From: alvarorib Date: Mon, 12 Apr 2021 13:56:36 +0000 Subject: [PATCH 43/75] Added translation using Weblate (Portuguese) --- product_standard_margin/i18n/pt.po | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 product_standard_margin/i18n/pt.po diff --git a/product_standard_margin/i18n/pt.po b/product_standard_margin/i18n/pt.po new file mode 100644 index 00000000..5be85e4e --- /dev/null +++ b/product_standard_margin/i18n/pt.po @@ -0,0 +1,59 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt\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: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate +msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate +msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_template +msgid "Product Template" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl +msgid "Sale Price VAT Excluded" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate +msgid "Theorical Margin (%)" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgstr "" From b956b5d4368f4601911049ec02d96b1f5ada1d37 Mon Sep 17 00:00:00 2001 From: Cyril VINH-TUNG Date: Wed, 15 Dec 2021 11:46:34 -1000 Subject: [PATCH 44/75] [IMP] product_standard_margin: black, isort, prettier --- product_standard_margin/__manifest__.py | 2 +- .../models/product_product.py | 1 + .../models/product_template.py | 1 + product_standard_margin/tests/test_module.py | 59 +++++++++++-------- .../views/view_product_product.xml | 19 +++--- .../views/view_product_template.xml | 20 +++++-- 6 files changed, 61 insertions(+), 41 deletions(-) diff --git a/product_standard_margin/__manifest__.py b/product_standard_margin/__manifest__.py index 6b59657d..02c211f6 100644 --- a/product_standard_margin/__manifest__.py +++ b/product_standard_margin/__manifest__.py @@ -10,7 +10,7 @@ "category": "Product", "depends": ["account"], "maintainers": ["legalsylvain"], - "website": "https://www.github.com/OCA/margin-analysis", + "website": "https://github.com/OCA/margin-analysis", "data": ["views/view_product_product.xml", "views/view_product_template.xml"], "license": "AGPL-3", "installable": True, diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 3e74258f..5f3d52af 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -5,6 +5,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import api, fields, models + import odoo.addons.decimal_precision as dp diff --git a/product_standard_margin/models/product_template.py b/product_standard_margin/models/product_template.py index 19e1f2a1..8458feb9 100644 --- a/product_standard_margin/models/product_template.py +++ b/product_standard_margin/models/product_template.py @@ -5,6 +5,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import api, fields, models + import odoo.addons.decimal_precision as dp diff --git a/product_standard_margin/tests/test_module.py b/product_standard_margin/tests/test_module.py index af7d103e..f628568b 100644 --- a/product_standard_margin/tests/test_module.py +++ b/product_standard_margin/tests/test_module.py @@ -6,52 +6,59 @@ class TestModule(TransactionCase): - def setUp(self): super().setUp() - self.ProductProduct = self.env['product.product'] - self.ProductTemplate = self.env['product.template'] + self.ProductProduct = self.env["product.product"] + self.ProductTemplate = self.env["product.template"] # Custom Section def _create_product(self, model, standard_price, sale_price, sale_tax_ids): - if model == 'product': + if model == "product": ModelObj = self.ProductProduct else: ModelObj = self.ProductTemplate - return ModelObj.create({ - 'name': 'Demo Product', - 'standard_price': standard_price, - 'lst_price': sale_price, - 'taxes_id': [(6, 0, sale_tax_ids)], - }) + return ModelObj.create( + { + "name": "Demo Product", + "standard_price": standard_price, + "lst_price": sale_price, + "taxes_id": [(6, 0, sale_tax_ids)], + } + ) # Test Section def test_01_classic_margin(self): - for model in ['product', 'template']: + for model in ["product", "template"]: product = self._create_product(model, 50, 200, []) + self.assertEqual(product.standard_margin, 150, "Incorrect Standard Margin") self.assertEqual( - product.standard_margin, 150, - "Incorrect Standard Margin") - self.assertEqual( - product.standard_margin_rate, 75.0, - "Incorrect Standard Margin Rate") + product.standard_margin_rate, 75.0, "Incorrect Standard Margin Rate" + ) def test_02_margin_without_standard_price(self): - for model in ['product', 'template']: + for model in ["product", "template"]: product = self._create_product(model, 0, 200, []) self.assertEqual( - product.standard_margin, 200, - "Incorrect Standard Margin (without standard price)") + product.standard_margin, + 200, + "Incorrect Standard Margin (without standard price)", + ) self.assertEqual( - product.standard_margin_rate, 100.0, - "Incorrect Standard Margin Rate (without standard price)") + product.standard_margin_rate, + 100.0, + "Incorrect Standard Margin Rate (without standard price)", + ) def test_03_margin_without_sale_price(self): - for model in ['product', 'template']: + for model in ["product", "template"]: product = self._create_product(model, 50, 0, []) self.assertEqual( - product.standard_margin, -50, - "Incorrect Standard Margin (without sale price)") + product.standard_margin, + -50, + "Incorrect Standard Margin (without sale price)", + ) self.assertEqual( - product.standard_margin_rate, 999.0, - "Incorrect Standard Margin Rate (without sale price)") + product.standard_margin_rate, + 999.0, + "Incorrect Standard Margin Rate (without sale price)", + ) diff --git a/product_standard_margin/views/view_product_product.xml b/product_standard_margin/views/view_product_product.xml index 2e1df3e9..6126c826 100644 --- a/product_standard_margin/views/view_product_product.xml +++ b/product_standard_margin/views/view_product_product.xml @@ -1,4 +1,4 @@ - + @@ -6,11 +6,14 @@ - + - - - + + + @@ -20,11 +23,11 @@ - + - - + + diff --git a/product_standard_margin/views/view_product_template.xml b/product_standard_margin/views/view_product_template.xml index da68bdd0..1dba3277 100644 --- a/product_standard_margin/views/view_product_template.xml +++ b/product_standard_margin/views/view_product_template.xml @@ -1,15 +1,23 @@ - + product.template - - - + + + From 0c4c79486fb8eba1a8bd00205bd5e909373f1ebf Mon Sep 17 00:00:00 2001 From: Cyril VINH-TUNG Date: Wed, 15 Dec 2021 12:01:46 -1000 Subject: [PATCH 45/75] [MIG] product_standard_margin: Migration to 14.0 --- product_standard_margin/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product_standard_margin/__manifest__.py b/product_standard_margin/__manifest__.py index 02c211f6..700801dd 100644 --- a/product_standard_margin/__manifest__.py +++ b/product_standard_margin/__manifest__.py @@ -5,7 +5,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Product Margin and Margin Rate", - "version": "12.0.1.0.0", + "version": "14.0.1.0.0", "author": "Camptocamp,GRAP,Odoo Community Association (OCA)", "category": "Product", "depends": ["account"], From a8fd8f16c51904a10cd85f9739df18358242b593 Mon Sep 17 00:00:00 2001 From: Cyril VINH-TUNG Date: Wed, 15 Dec 2021 12:44:37 -1000 Subject: [PATCH 46/75] [IMP] Add margin fields in product tree views --- .../views/view_product_product.xml | 10 ++++++++++ .../views/view_product_template.xml | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/product_standard_margin/views/view_product_product.xml b/product_standard_margin/views/view_product_product.xml index 6126c826..78cea78a 100644 --- a/product_standard_margin/views/view_product_product.xml +++ b/product_standard_margin/views/view_product_product.xml @@ -32,4 +32,14 @@ + + product.product + + + + + + + + diff --git a/product_standard_margin/views/view_product_template.xml b/product_standard_margin/views/view_product_template.xml index 1dba3277..eb3ac742 100644 --- a/product_standard_margin/views/view_product_template.xml +++ b/product_standard_margin/views/view_product_template.xml @@ -21,4 +21,23 @@
+ + product.template + + + + + + + + From 02ab50e1fe4713748a369be1862d673a46952b3c Mon Sep 17 00:00:00 2001 From: Cyril VINH-TUNG Date: Wed, 15 Dec 2021 18:23:55 -1000 Subject: [PATCH 47/75] [IMP] Add percentpie widget for rate field --- product_standard_margin/readme/ROADMAP.rst | 5 ----- product_standard_margin/views/view_product_product.xml | 4 ++-- product_standard_margin/views/view_product_template.xml | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/product_standard_margin/readme/ROADMAP.rst b/product_standard_margin/readme/ROADMAP.rst index c711b0f1..354994f4 100644 --- a/product_standard_margin/readme/ROADMAP.rst +++ b/product_standard_margin/readme/ROADMAP.rst @@ -1,7 +1,2 @@ * This module will not work properly if used in a multicompany context with product prices depending on the company. - -* It should be great to use the odoo widget ``percentpie`` for the display of the - field ``standard_margin_rate`` but for the time being, the field is not displayed - properly. - Ref of the Odoo Issue: https://github.com/odoo/odoo/issues/42869 diff --git a/product_standard_margin/views/view_product_product.xml b/product_standard_margin/views/view_product_product.xml index 78cea78a..7521e805 100644 --- a/product_standard_margin/views/view_product_product.xml +++ b/product_standard_margin/views/view_product_product.xml @@ -13,7 +13,7 @@ position="after" > - + @@ -27,7 +27,7 @@ - + diff --git a/product_standard_margin/views/view_product_template.xml b/product_standard_margin/views/view_product_template.xml index eb3ac742..c2adbfc4 100644 --- a/product_standard_margin/views/view_product_template.xml +++ b/product_standard_margin/views/view_product_template.xml @@ -16,6 +16,7 @@ /> From 29047124ff3ee9ced9e6a584a9c0c8a67e46cd20 Mon Sep 17 00:00:00 2001 From: Cyril VINH-TUNG Date: Thu, 23 Dec 2021 09:52:15 -1000 Subject: [PATCH 48/75] [IMP] Add Markup Rate --- product_standard_margin/i18n/fr.po | 63 ++++++++++++++----- .../i18n/product_standard_margin.pot | 55 ++++++++++++++-- .../models/product_product.py | 18 ++++++ .../models/product_template.py | 17 +++++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 9 ++- .../views/view_product_product.xml | 3 + .../views/view_product_template.xml | 10 +++ 8 files changed, 153 insertions(+), 23 deletions(-) diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po index b168fe40..b3d9c830 100644 --- a/product_standard_margin/i18n/fr.po +++ b/product_standard_margin/i18n/fr.po @@ -4,41 +4,70 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-01-07 14:51+0000\n" -"PO-Revision-Date: 2020-01-07 14:51+0000\n" -"Last-Translator: <>\n" +"POT-Creation-Date: 2021-12-23 19:48+0000\n" +"PO-Revision-Date: 2021-12-23 19:48+0000\n" +"Last-Translator: \n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id +msgid "ID" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.. " -"If no sale price set, will display 999.0" +"form (not based on historical values).Take care of tax include and exclude.." +" If no sale price set, will display 999.0" msgstr "" "Taux de marque théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " "formulaire Produit] (ne tient pas compte de la facturation effective). Ce " "taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " "taux sera de 999.0" +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate +msgid "" +"Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.." +" If no cost price set, will display 999.0" +msgstr "" +"Taux de marge théorique [ (PV unitaire - Coût unitaire ) / Coût unitaire du " +"formulaire Produit] (ne tient pas compte de la facturation effective). Ce " +"taux tient compte des PV TTC (TVA incluse). Si aucun coût n'a été saisi, le " +"taux sera de 999.0" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate -#, fuzzy msgid "" "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.. " -"If no sale price set, will display 999.0" +"form (not based on historical values).Take care of tax include and exclude.." +" If no sale price set, will display 999.0" msgstr "" -"Taux de marque théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " +"Taux de marge théorique [ (PV unitaire - Coût unitaire ) / Coût unitaire du " "formulaire Produit] (ne tient pas compte de la facturation effective). Ce " -"taux tient compte des PV TTC (TVA incluse). Si aucun PV n'a été saisi, le " +"taux tient compte des PV TTC (TVA incluse). Si aucun coût n'a été saisi, le " "taux sera de 999.0" #. module: product_standard_margin @@ -73,10 +102,16 @@ msgstr "Taux de marque Théorique (%)" #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin msgid "" -"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " -"(not based on historical values). Take care of tax include and exclude. If " +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form" +" (not based on historical values). Take care of tax include and exclude. If " "no sale price, the margin will be negativ." msgstr "" "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient " "pas compte de la facturation effective). Ce taux tient compte des PV TTC " "(TVA incluse). Si aucun PV n'a été saisi, la marge sera négative." + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate +msgid "Theorical Markup (%)" +msgstr "Taux de marge Théorique (%)" diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot index fdd3b605..b9358712 100644 --- a/product_standard_margin/i18n/product_standard_margin.pot +++ b/product_standard_margin/i18n/product_standard_margin.pot @@ -1,26 +1,61 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * product_standard_margin +# * product_standard_margin # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: <>\n" +"POT-Creation-Date: 2021-12-23 19:48+0000\n" +"PO-Revision-Date: 2021-12-23 19:48+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: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name +msgid "Display Name" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id +msgid "ID" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update +msgid "Last Modified on" +msgstr "" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate -msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.." +" If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate +msgid "" +"Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.." +" If no cost price set, will display 999.0" msgstr "" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate -msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.." +" If no sale price set, will display 999.0" msgstr "" #. module: product_standard_margin @@ -54,6 +89,14 @@ msgstr "" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form" +" (not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." msgstr "" +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate +msgid "Theorical Markup (%)" +msgstr "" diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 5f3d52af..4da7da4f 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -41,6 +41,16 @@ class ProductProduct(models.Model): "Take care of tax include and exclude.. If no sale price " "set, will display 999.0", ) + standard_markup_rate = fields.Float( + compute="_compute_margin", + string="Theorical Markup (%)", + store=True, + digits=dp.get_precision("Product Price"), + help="Markup rate is [ Theorical Margin / cost price (Wo Tax) ] " + "of the product form (not based on historical values)." + "Take care of tax include and exclude.. If no cost price " + "set, will display 999.0", + ) # Compute Section @api.depends( @@ -67,3 +77,11 @@ def _compute_margin(self): / product.list_price_vat_excl * 100 ) + if product.standard_price == 0: + product.standard_markup_rate = 999.0 + else: + product.standard_markup_rate = ( + (product.list_price_vat_excl - product.standard_price) + / product.standard_price + * 100 + ) diff --git a/product_standard_margin/models/product_template.py b/product_standard_margin/models/product_template.py index 8458feb9..d45ff403 100644 --- a/product_standard_margin/models/product_template.py +++ b/product_standard_margin/models/product_template.py @@ -38,6 +38,15 @@ class ProductTemplate(models.Model): "Take care of tax include and exclude.. If no sale price " "set, will display 999.0", ) + standard_markup_rate = fields.Float( + compute="_compute_margin", + string="Theorical Markup (%)", + digits=dp.get_precision("Product Price"), + help="Markup rate is [ Theorical Margin / cost price (Wo Tax) ] " + "of the product form (not based on historical values)." + "Take care of tax include and exclude.. If no cost price " + "set, will display 999.0", + ) # Compute Section @api.depends( @@ -66,3 +75,11 @@ def _compute_margin(self): / template.list_price_vat_excl * 100 ) + if template.standard_price == 0: + template.standard_markup_rate = 999.0 + else: + template.standard_markup_rate = ( + (template.list_price_vat_excl - template.standard_price) + / template.standard_price + * 100 + ) diff --git a/product_standard_margin/readme/CONTRIBUTORS.rst b/product_standard_margin/readme/CONTRIBUTORS.rst index 1e1d54b1..76e09f2e 100644 --- a/product_standard_margin/readme/CONTRIBUTORS.rst +++ b/product_standard_margin/readme/CONTRIBUTORS.rst @@ -2,3 +2,4 @@ * Yannick Vaucher * Joël Grand-Guillaume * Sylvain Le Gal (https://twitter.com/legalsylvain) +* Cyril Vinh-Tung diff --git a/product_standard_margin/readme/DESCRIPTION.rst b/product_standard_margin/readme/DESCRIPTION.rst index 3698a568..f1db3a83 100644 --- a/product_standard_margin/readme/DESCRIPTION.rst +++ b/product_standard_margin/readme/DESCRIPTION.rst @@ -1,9 +1,12 @@ -Add a field on the product form that compute the standard (or theorical) -margin based on the current values of sale and standard price present in -the product form. We take care of taxe included or excluded. +Add 2 fields on the product form that compute the standard (or theorical) +margin and markup based on the current values of sale and standard price +present in the product form. We take care of taxe included or excluded. It will just compute it as follow: +Margin : (Sale Price without tax - Standard Price) / Sale Price without tax +Markup : +(Sale Price without tax - Standard Price) / Standard Price .. figure:: ../static/description/product_form.png diff --git a/product_standard_margin/views/view_product_product.xml b/product_standard_margin/views/view_product_product.xml index 7521e805..8c7d865c 100644 --- a/product_standard_margin/views/view_product_product.xml +++ b/product_standard_margin/views/view_product_product.xml @@ -14,6 +14,7 @@ > + @@ -28,6 +29,7 @@ + @@ -39,6 +41,7 @@ + diff --git a/product_standard_margin/views/view_product_template.xml b/product_standard_margin/views/view_product_template.xml index c2adbfc4..715e5c41 100644 --- a/product_standard_margin/views/view_product_template.xml +++ b/product_standard_margin/views/view_product_template.xml @@ -19,6 +19,11 @@ widget="percentpie" attrs="{'invisible': [('product_variant_count', '>', 1)]}" /> + @@ -38,6 +43,11 @@ attrs="{'invisible': [('product_variant_count', '>', 1)]}" optional="hide" /> + From 2e26321b88566e52ec1d391b12819daab683ef41 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 16 Feb 2023 13:22:12 +0000 Subject: [PATCH 49/75] [UPD] Update product_standard_margin.pot --- product_standard_margin/i18n/product_standard_margin.pot | 2 -- 1 file changed, 2 deletions(-) diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot index b9358712..0278558b 100644 --- a/product_standard_margin/i18n/product_standard_margin.pot +++ b/product_standard_margin/i18n/product_standard_margin.pot @@ -6,8 +6,6 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-23 19:48+0000\n" -"PO-Revision-Date: 2021-12-23 19:48+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" From ea84c4065085f9c2a6f0db921285c541202d4b8d Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 16 Feb 2023 13:25:27 +0000 Subject: [PATCH 50/75] [UPD] README.rst --- product_standard_margin/README.rst | 27 +++++++++---------- .../static/description/index.html | 24 ++++++++--------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/product_standard_margin/README.rst b/product_standard_margin/README.rst index 67f6efbd..eca4cbee 100644 --- a/product_standard_margin/README.rst +++ b/product_standard_margin/README.rst @@ -14,25 +14,28 @@ Product Margin and Margin Rate :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/12.0/product_standard_margin + :target: https://github.com/OCA/margin-analysis/tree/14.0/product_standard_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-12-0/margin-analysis-12-0-product_standard_margin + :target: https://translation.odoo-community.org/projects/margin-analysis-14-0/margin-analysis-14-0-product_standard_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/132/12.0 + :target: https://runbot.odoo-community.org/runbot/132/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| -Add a field on the product form that compute the standard (or theorical) -margin based on the current values of sale and standard price present in -the product form. We take care of taxe included or excluded. +Add 2 fields on the product form that compute the standard (or theorical) +margin and markup based on the current values of sale and standard price +present in the product form. We take care of taxe included or excluded. It will just compute it as follow: +Margin : (Sale Price without tax - Standard Price) / Sale Price without tax +Markup : +(Sale Price without tax - Standard Price) / Standard Price -.. figure:: https://raw.githubusercontent.com/OCA/margin-analysis/12.0/product_standard_margin/static/description/product_form.png +.. figure:: https://raw.githubusercontent.com/OCA/margin-analysis/14.0/product_standard_margin/static/description/product_form.png **Note:** @@ -54,18 +57,13 @@ Known issues / Roadmap * This module will not work properly if used in a multicompany context with product prices depending on the company. -* It should be great to use the odoo widget ``percentpie`` for the display of the - field ``standard_margin_rate`` but for the time being, the field is not displayed - properly. - Ref of the Odoo Issue: https://github.com/odoo/odoo/issues/42869 - 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. @@ -85,6 +83,7 @@ Contributors * Yannick Vaucher * Joël Grand-Guillaume * Sylvain Le Gal (https://twitter.com/legalsylvain) +* Cyril Vinh-Tung Maintainers ~~~~~~~~~~~ @@ -107,6 +106,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/margin-analysis `_ project on GitHub. +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/product_standard_margin/static/description/index.html b/product_standard_margin/static/description/index.html index 184d8d25..af76cded 100644 --- a/product_standard_margin/static/description/index.html +++ b/product_standard_margin/static/description/index.html @@ -367,14 +367,17 @@

Product Margin and Margin Rate

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

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

-

Add a field on the product form that compute the standard (or theorical) -margin based on the current values of sale and standard price present in -the product form. We take care of taxe included or excluded.

+

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

+

Add 2 fields on the product form that compute the standard (or theorical) +margin and markup based on the current values of sale and standard price +present in the product form. We take care of taxe included or excluded.

It will just compute it as follow: -(Sale Price without tax - Standard Price) / Sale Price without tax

+Margin : +(Sale Price without tax - Standard Price) / Sale Price without tax +Markup : +(Sale Price without tax - Standard Price) / Standard Price

-https://raw.githubusercontent.com/OCA/margin-analysis/12.0/product_standard_margin/static/description/product_form.png +https://raw.githubusercontent.com/OCA/margin-analysis/14.0/product_standard_margin/static/description/product_form.png

Note:

As this module will base his simple computation on sale and cost prices, @@ -401,10 +404,6 @@

Known issues / Roadmap

  • This module will not work properly if used in a multicompany context with product prices depending on the company.
  • -
  • It should be great to use the odoo widget percentpie for the display of the -field standard_margin_rate but for the time being, the field is not displayed -properly. -Ref of the Odoo Issue: https://github.com/odoo/odoo/issues/42869
@@ -412,7 +411,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.

@@ -431,6 +430,7 @@

Contributors

  • Yannick Vaucher <yannick.vaucher@camptocamp.com>
  • Joël Grand-Guillaume <joel.grand-guillaume@camptocamp.com>
  • Sylvain Le Gal (https://twitter.com/legalsylvain)
  • +
  • Cyril Vinh-Tung <cyril@invitu.com>
  • @@ -442,7 +442,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    legalsylvain

    -

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

    +

    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.

    From 9140b8578b4f60ae68e28b52b49816f47091a71e Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 16 Feb 2023 16:44:57 +0000 Subject: [PATCH 51/75] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: margin-analysis-14.0/margin-analysis-14.0-product_standard_margin Translate-URL: https://translation.odoo-community.org/projects/margin-analysis-14-0/margin-analysis-14-0-product_standard_margin/ --- product_standard_margin/i18n/de.po | 58 +++++++++++++++++++++++---- product_standard_margin/i18n/fr.po | 17 ++++---- product_standard_margin/i18n/nl.po | 33 +++++++++++++++ product_standard_margin/i18n/pt.po | 50 +++++++++++++++++++++-- product_standard_margin/i18n/pt_BR.po | 50 +++++++++++++++++++++-- 5 files changed, 184 insertions(+), 24 deletions(-) diff --git a/product_standard_margin/i18n/de.po b/product_standard_margin/i18n/de.po index 1386c8ad..dd31fc92 100644 --- a/product_standard_margin/i18n/de.po +++ b/product_standard_margin/i18n/de.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * product_standard_margin +# * product_standard_margin # msgid "" msgstr "" @@ -16,18 +16,51 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.10\n" +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name +msgid "Display Name" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id +msgid "ID" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update +msgid "Last Modified on" +msgstr "" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate -msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" msgstr "" "Der Margensatz ist [ Theoretische Marge / Verkaufspreis (Ohne Steuern) ] des " "Produkts (nicht auf historischen Werten basierend), wobei darauf zu achten " "ist, Steuern ein- und auszuschließen. Wenn kein Verkaufspreis festgelegt " "wurde, wird 999.0 angezeigt" +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate +msgid "" +"Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no cost price set, will display 999.0" +msgstr "" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate -msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" msgstr "" "Der Aufschlagssatz ist [ Theoretische Marge / Verkaufspreis (Ohne Steuern) ] " "des Produkts (nicht auf historischen Werten basierend), mit und ohne Steuer. " @@ -64,9 +97,18 @@ msgstr "Theoretische Marge (%)" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." +msgstr "" +"Theoretische Gewinnmarge ist [ Verkaufspreis (Ohne Steuern) - " +"Einkaufspreis ] des Produkts (nicht auf historischen Werten basierend). " +"Achten Sie darauf, Steuern ein- und auszuschließen. Wenn kein Verkaufspreis " +"angegeben wird, ist die Marge negativ." + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate +msgid "Theorical Markup (%)" msgstr "" -"Theoretische Gewinnmarge ist [ Verkaufspreis (Ohne Steuern) - Einkaufspreis ]" -" des Produkts (nicht auf historischen Werten basierend). Achten Sie darauf, " -"Steuern ein- und auszuschließen. Wenn kein Verkaufspreis angegeben wird, ist " -"die Marge negativ." diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po index b3d9c830..730ded35 100644 --- a/product_standard_margin/i18n/fr.po +++ b/product_standard_margin/i18n/fr.po @@ -10,6 +10,7 @@ msgstr "" "PO-Revision-Date: 2021-12-23 19:48+0000\n" "Last-Translator: \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" @@ -37,8 +38,8 @@ msgstr "Dernière modification le" #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.." -" If no sale price set, will display 999.0" +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" msgstr "" "Taux de marque théorique [ (PV unitaire - Coût unitaire ) / PV unitaire du " "formulaire Produit] (ne tient pas compte de la facturation effective). Ce " @@ -50,8 +51,8 @@ msgstr "" #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate msgid "" "Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.." -" If no cost price set, will display 999.0" +"form (not based on historical values).Take care of tax include and exclude.. " +"If no cost price set, will display 999.0" msgstr "" "Taux de marge théorique [ (PV unitaire - Coût unitaire ) / Coût unitaire du " "formulaire Produit] (ne tient pas compte de la facturation effective). Ce " @@ -62,8 +63,8 @@ msgstr "" #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate msgid "" "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.." -" If no sale price set, will display 999.0" +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" msgstr "" "Taux de marge théorique [ (PV unitaire - Coût unitaire ) / Coût unitaire du " "formulaire Produit] (ne tient pas compte de la facturation effective). Ce " @@ -102,8 +103,8 @@ msgstr "Taux de marque Théorique (%)" #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin msgid "" -"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form" -" (not based on historical values). Take care of tax include and exclude. If " +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values). Take care of tax include and exclude. If " "no sale price, the margin will be negativ." msgstr "" "Marge théorique [ Vente unitaire HT - coût unitaire ] du produit (ne tient " diff --git a/product_standard_margin/i18n/nl.po b/product_standard_margin/i18n/nl.po index 0cc539b5..a964ef6b 100644 --- a/product_standard_margin/i18n/nl.po +++ b/product_standard_margin/i18n/nl.po @@ -18,6 +18,24 @@ msgstr "" "Plural-Forms: \n" "X-Generator: Poedit 1.5.4\n" +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name +msgid "Display Name" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id +msgid "ID" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update +msgid "Last Modified on" +msgstr "" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate #, fuzzy @@ -31,6 +49,15 @@ msgstr "" "rekening met prijzen incl. en excl. BTW. Indien geen verkooprijs is " "ingevoerd, wordt 999,0 weergegeven." +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate +msgid "" +"Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no cost price set, will display 999.0" +msgstr "" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate msgid "" @@ -86,6 +113,12 @@ msgstr "" "prijzen incl. en excl. BTW. Indien geen verkooprijs is ingevoerd, zal de " "marge negatief zijn." +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate +msgid "Theorical Markup (%)" +msgstr "" + #~ msgid "Error: Invalid ean code" #~ msgstr "Fout: ongeldige ean code" diff --git a/product_standard_margin/i18n/pt.po b/product_standard_margin/i18n/pt.po index 5be85e4e..4495883b 100644 --- a/product_standard_margin/i18n/pt.po +++ b/product_standard_margin/i18n/pt.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * product_standard_margin +# * product_standard_margin # msgid "" msgstr "" @@ -14,14 +14,47 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name +msgid "Display Name" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id +msgid "ID" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update +msgid "Last Modified on" +msgstr "" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate -msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate +msgid "" +"Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no cost price set, will display 999.0" msgstr "" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate -msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" msgstr "" #. module: product_standard_margin @@ -55,5 +88,14 @@ msgstr "" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate +msgid "Theorical Markup (%)" msgstr "" diff --git a/product_standard_margin/i18n/pt_BR.po b/product_standard_margin/i18n/pt_BR.po index c8a04359..d3c442b0 100644 --- a/product_standard_margin/i18n/pt_BR.po +++ b/product_standard_margin/i18n/pt_BR.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * product_standard_margin +# * product_standard_margin # msgid "" msgstr "" @@ -14,14 +14,47 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name +msgid "Display Name" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id +msgid "ID" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update +msgid "Last Modified on" +msgstr "" + #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate -msgid "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate +msgid "" +"Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no cost price set, will display 999.0" msgstr "" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate -msgid "Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product form (not based on historical values).Take care of tax include and exclude.. If no sale price set, will display 999.0" +msgid "" +"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and exclude.. " +"If no sale price set, will display 999.0" msgstr "" #. module: product_standard_margin @@ -55,5 +88,14 @@ msgstr "" #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin -msgid "Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form (not based on historical values). Take care of tax include and exclude. If no sale price, the margin will be negativ." +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product form " +"(not based on historical values). Take care of tax include and exclude. If " +"no sale price, the margin will be negativ." +msgstr "" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate +msgid "Theorical Markup (%)" msgstr "" From 8d98a2186d7c0a8f14be407c68134e405ee8e553 Mon Sep 17 00:00:00 2001 From: Denis Leemann Date: Fri, 17 Feb 2023 13:36:08 +0100 Subject: [PATCH 52/75] [MIG] product_standard_margin: Migration to 15.0 --- product_standard_margin/__manifest__.py | 2 +- product_standard_margin/models/product_product.py | 4 ++-- product_standard_margin/models/product_template.py | 2 +- product_standard_margin/tests/test_module.py | 11 ++++++----- .../views/view_product_product.xml | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/product_standard_margin/__manifest__.py b/product_standard_margin/__manifest__.py index 700801dd..b1930524 100644 --- a/product_standard_margin/__manifest__.py +++ b/product_standard_margin/__manifest__.py @@ -5,7 +5,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Product Margin and Margin Rate", - "version": "14.0.1.0.0", + "version": "15.0.1.0.0", "author": "Camptocamp,GRAP,Odoo Community Association (OCA)", "category": "Product", "depends": ["account"], diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 4da7da4f..43d77b15 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -54,7 +54,7 @@ class ProductProduct(models.Model): # Compute Section @api.depends( - "lst_price", + "list_price", "product_tmpl_id.list_price", "standard_price", "taxes_id.price_include", @@ -64,7 +64,7 @@ class ProductProduct(models.Model): def _compute_margin(self): for product in self: product.list_price_vat_excl = product.taxes_id.compute_all( - product.lst_price, product=product + product.list_price, product=product )["total_excluded"] product.standard_margin = ( product.list_price_vat_excl - product.standard_price diff --git a/product_standard_margin/models/product_template.py b/product_standard_margin/models/product_template.py index d45ff403..f0382201 100644 --- a/product_standard_margin/models/product_template.py +++ b/product_standard_margin/models/product_template.py @@ -50,7 +50,7 @@ class ProductTemplate(models.Model): # Compute Section @api.depends( - "lst_price", + "list_price", "standard_price", "taxes_id.price_include", "taxes_id.amount", diff --git a/product_standard_margin/tests/test_module.py b/product_standard_margin/tests/test_module.py index f628568b..ead2bed8 100644 --- a/product_standard_margin/tests/test_module.py +++ b/product_standard_margin/tests/test_module.py @@ -6,10 +6,11 @@ class TestModule(TransactionCase): - def setUp(self): - super().setUp() - self.ProductProduct = self.env["product.product"] - self.ProductTemplate = self.env["product.template"] + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.ProductProduct = cls.env["product.product"] + cls.ProductTemplate = cls.env["product.template"] # Custom Section def _create_product(self, model, standard_price, sale_price, sale_tax_ids): @@ -21,7 +22,7 @@ def _create_product(self, model, standard_price, sale_price, sale_tax_ids): { "name": "Demo Product", "standard_price": standard_price, - "lst_price": sale_price, + "list_price": sale_price, "taxes_id": [(6, 0, sale_tax_ids)], } ) diff --git a/product_standard_margin/views/view_product_product.xml b/product_standard_margin/views/view_product_product.xml index 8c7d865c..1dd6b899 100644 --- a/product_standard_margin/views/view_product_product.xml +++ b/product_standard_margin/views/view_product_product.xml @@ -5,7 +5,7 @@ product.product - + Date: Mon, 20 Feb 2023 12:16:45 +0000 Subject: [PATCH 53/75] [UPD] Update product_standard_margin.pot --- .../i18n/product_standard_margin.pot | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot index 0278558b..8c0b59d3 100644 --- a/product_standard_margin/i18n/product_standard_margin.pot +++ b/product_standard_margin/i18n/product_standard_margin.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" +"Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -13,24 +13,6 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name -msgid "Display Name" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id -msgid "ID" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update -msgid "Last Modified on" -msgstr "" - #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" From a89a01bc39a03a24ca46fd18fc72edeac1e5fecd Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 20 Feb 2023 12:19:16 +0000 Subject: [PATCH 54/75] [UPD] README.rst --- product_standard_margin/README.rst | 12 ++++++------ .../static/description/index.html | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/product_standard_margin/README.rst b/product_standard_margin/README.rst index eca4cbee..318b2bf6 100644 --- a/product_standard_margin/README.rst +++ b/product_standard_margin/README.rst @@ -14,13 +14,13 @@ Product Margin and Margin Rate :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/14.0/product_standard_margin + :target: https://github.com/OCA/margin-analysis/tree/15.0/product_standard_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-14-0/margin-analysis-14-0-product_standard_margin + :target: https://translation.odoo-community.org/projects/margin-analysis-15-0/margin-analysis-15-0-product_standard_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/132/14.0 + :target: https://runbot.odoo-community.org/runbot/132/15.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -35,7 +35,7 @@ Margin : Markup : (Sale Price without tax - Standard Price) / Standard Price -.. figure:: https://raw.githubusercontent.com/OCA/margin-analysis/14.0/product_standard_margin/static/description/product_form.png +.. figure:: https://raw.githubusercontent.com/OCA/margin-analysis/15.0/product_standard_margin/static/description/product_form.png **Note:** @@ -63,7 +63,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. @@ -106,6 +106,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/margin-analysis `_ project on GitHub. +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/product_standard_margin/static/description/index.html b/product_standard_margin/static/description/index.html index af76cded..18c509a6 100644 --- a/product_standard_margin/static/description/index.html +++ b/product_standard_margin/static/description/index.html @@ -367,7 +367,7 @@

    Product Margin and Margin Rate

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

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

    +

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

    Add 2 fields on the product form that compute the standard (or theorical) margin and markup based on the current values of sale and standard price present in the product form. We take care of taxe included or excluded.

    @@ -377,7 +377,7 @@

    Product Margin and Margin Rate

    Markup : (Sale Price without tax - Standard Price) / Standard Price

    -https://raw.githubusercontent.com/OCA/margin-analysis/14.0/product_standard_margin/static/description/product_form.png +https://raw.githubusercontent.com/OCA/margin-analysis/15.0/product_standard_margin/static/description/product_form.png

    Note:

    As this module will base his simple computation on sale and cost prices, @@ -411,7 +411,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.

    @@ -442,7 +442,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    legalsylvain

    -

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

    +

    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.

    From 40c51e3b120ac8289348ac9857c694853b87ff4d Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 20 Feb 2023 16:07:59 +0000 Subject: [PATCH 55/75] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: margin-analysis-15.0/margin-analysis-15.0-product_standard_margin Translate-URL: https://translation.odoo-community.org/projects/margin-analysis-15-0/margin-analysis-15-0-product_standard_margin/ --- product_standard_margin/i18n/de.po | 18 ------------------ product_standard_margin/i18n/fr.po | 24 ++++++------------------ product_standard_margin/i18n/nl.po | 18 ------------------ product_standard_margin/i18n/pt.po | 18 ------------------ product_standard_margin/i18n/pt_BR.po | 18 ------------------ 5 files changed, 6 insertions(+), 90 deletions(-) diff --git a/product_standard_margin/i18n/de.po b/product_standard_margin/i18n/de.po index dd31fc92..f2fb147f 100644 --- a/product_standard_margin/i18n/de.po +++ b/product_standard_margin/i18n/de.po @@ -16,24 +16,6 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.10\n" -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name -msgid "Display Name" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id -msgid "ID" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update -msgid "Last Modified on" -msgstr "" - #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" diff --git a/product_standard_margin/i18n/fr.po b/product_standard_margin/i18n/fr.po index 730ded35..9072079c 100644 --- a/product_standard_margin/i18n/fr.po +++ b/product_standard_margin/i18n/fr.po @@ -16,24 +16,6 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name -msgid "Display Name" -msgstr "Nom affiché" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id -msgid "ID" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update -msgid "Last Modified on" -msgstr "Dernière modification le" - #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" @@ -116,3 +98,9 @@ msgstr "" #: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate msgid "Theorical Markup (%)" msgstr "Taux de marge Théorique (%)" + +#~ msgid "Display Name" +#~ msgstr "Nom affiché" + +#~ msgid "Last Modified on" +#~ msgstr "Dernière modification le" diff --git a/product_standard_margin/i18n/nl.po b/product_standard_margin/i18n/nl.po index a964ef6b..44f1000a 100644 --- a/product_standard_margin/i18n/nl.po +++ b/product_standard_margin/i18n/nl.po @@ -18,24 +18,6 @@ msgstr "" "Plural-Forms: \n" "X-Generator: Poedit 1.5.4\n" -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name -msgid "Display Name" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id -msgid "ID" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update -msgid "Last Modified on" -msgstr "" - #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate #, fuzzy diff --git a/product_standard_margin/i18n/pt.po b/product_standard_margin/i18n/pt.po index 4495883b..12a51a78 100644 --- a/product_standard_margin/i18n/pt.po +++ b/product_standard_margin/i18n/pt.po @@ -14,24 +14,6 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name -msgid "Display Name" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id -msgid "ID" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update -msgid "Last Modified on" -msgstr "" - #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" diff --git a/product_standard_margin/i18n/pt_BR.po b/product_standard_margin/i18n/pt_BR.po index d3c442b0..a6f8876e 100644 --- a/product_standard_margin/i18n/pt_BR.po +++ b/product_standard_margin/i18n/pt_BR.po @@ -14,24 +14,6 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__display_name -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__display_name -msgid "Display Name" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__id -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__id -msgid "ID" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model.fields,field_description:product_standard_margin.field_product_product____last_update -#: model:ir.model.fields,field_description:product_standard_margin.field_product_template____last_update -msgid "Last Modified on" -msgstr "" - #. module: product_standard_margin #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" From c9d0312f13a5aa6f7a9ecf761db6d10339413209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro?= Date: Mon, 5 Jun 2023 11:32:09 +0200 Subject: [PATCH 56/75] [MIG] product_standard_margin: Migration to 16.0 --- product_standard_margin/__manifest__.py | 2 +- product_standard_margin/i18n/es.po | 91 +++++++++++++++++++ .../models/product_product.py | 12 +-- .../models/product_template.py | 10 +- 4 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 product_standard_margin/i18n/es.po diff --git a/product_standard_margin/__manifest__.py b/product_standard_margin/__manifest__.py index b1930524..0c63670f 100644 --- a/product_standard_margin/__manifest__.py +++ b/product_standard_margin/__manifest__.py @@ -5,7 +5,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Product Margin and Margin Rate", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "author": "Camptocamp,GRAP,Odoo Community Association (OCA)", "category": "Product", "depends": ["account"], diff --git a/product_standard_margin/i18n/es.po b/product_standard_margin/i18n/es.po new file mode 100644 index 00000000..0e1b1ebc --- /dev/null +++ b/product_standard_margin/i18n/es.po @@ -0,0 +1,91 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_standard_margin +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-06-05 09:26+0000\n" +"PO-Revision-Date: 2023-06-05 11:27+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"Language: es\n" +"X-Generator: Poedit 2.0.6\n" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate +msgid "" +"Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and " +"exclude.. If no sale price set, will display 999.0" +msgstr "" +"La tasa de margen es [ Margen teórico / precio de venta (sin impuestos) ] " +"de la ficha del producto (no basado en valores históricos). Tenga cuidado " +"de impuestos incluidos y excluidos. Si no hay precio de venta establecido " +"mostrará 999.0" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_markup_rate +msgid "" +"Markup rate is [ Theorical Margin / cost price (Wo Tax) ] of the product " +"form (not based on historical values).Take care of tax include and " +"exclude.. If no cost price set, will display 999.0" +msgstr "" +"La tasa de Markup es [ Margen teórico / precio de coste (sin impuestos) ] " +"de la ficha del producto (no basado en valores históricos). Tenga cuidado " +"de impuestos incluidos y excluidos. Si no hay precio de coste establecido " +"mostrará 999.0" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_template +msgid "Product" +msgstr "Producto" + +#. module: product_standard_margin +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product Variant" +msgstr "Variante de producto" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__list_price_vat_excl +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__list_price_vat_excl +msgid "Sale Price VAT Excluded" +msgstr "Precio de venta sin impuestos" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin +msgid "Theorical Margin" +msgstr "Margen teórico" + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_margin_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_margin_rate +msgid "Theorical Margin (%)" +msgstr "Margen teórico (%)" + +#. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin +msgid "" +"Theorical Margin is [ sale price (Wo Tax) - cost price ] of the product " +"form (not based on historical values). Take care of tax include and " +"exclude. If no sale price, the margin will be negativ." +msgstr "" +"El margen teórico es [ precio de venta (sin impuestos) - precio de coste ] " +"de la ficha del producto (no basado en valores históricos). Tenga cuidado " +"de impuestos incluidos y excluidos. Si no hay precio de venta el margen " +"será negativo." + +#. module: product_standard_margin +#: model:ir.model.fields,field_description:product_standard_margin.field_product_product__standard_markup_rate +#: model:ir.model.fields,field_description:product_standard_margin.field_product_template__standard_markup_rate +msgid "Theorical Markup (%)" +msgstr "Markup teórico (%)" diff --git a/product_standard_margin/models/product_product.py b/product_standard_margin/models/product_product.py index 43d77b15..1ad77b30 100644 --- a/product_standard_margin/models/product_product.py +++ b/product_standard_margin/models/product_product.py @@ -6,8 +6,6 @@ from odoo import api, fields, models -import odoo.addons.decimal_precision as dp - class ProductProduct(models.Model): _inherit = "product.product" @@ -17,14 +15,14 @@ class ProductProduct(models.Model): compute="_compute_margin", string="Sale Price VAT Excluded", store=True, - digits=dp.get_precision("Product Price"), + digits="Product Price", ) standard_margin = fields.Float( compute="_compute_margin", string="Theorical Margin", store=True, - digits=dp.get_precision("Product Price"), + digits="Product Price", help="Theorical Margin is [ sale price (Wo Tax) - cost price ] " "of the product form (not based on historical values). " "Take care of tax include and exclude. If no sale price, " @@ -35,8 +33,8 @@ class ProductProduct(models.Model): compute="_compute_margin", string="Theorical Margin (%)", store=True, - digits=dp.get_precision("Product Price"), - help="Markup rate is [ Theorical Margin / sale price (Wo Tax) ] " + digits="Product Price", + help="Margin rate is [ Theorical Margin / sale price (Wo Tax) ] " "of the product form (not based on historical values)." "Take care of tax include and exclude.. If no sale price " "set, will display 999.0", @@ -45,7 +43,7 @@ class ProductProduct(models.Model): compute="_compute_margin", string="Theorical Markup (%)", store=True, - digits=dp.get_precision("Product Price"), + digits="Product Price", help="Markup rate is [ Theorical Margin / cost price (Wo Tax) ] " "of the product form (not based on historical values)." "Take care of tax include and exclude.. If no cost price " diff --git a/product_standard_margin/models/product_template.py b/product_standard_margin/models/product_template.py index f0382201..658b1ce3 100644 --- a/product_standard_margin/models/product_template.py +++ b/product_standard_margin/models/product_template.py @@ -6,8 +6,6 @@ from odoo import api, fields, models -import odoo.addons.decimal_precision as dp - class ProductTemplate(models.Model): _inherit = "product.template" @@ -16,13 +14,13 @@ class ProductTemplate(models.Model): list_price_vat_excl = fields.Float( compute="_compute_margin", string="Sale Price VAT Excluded", - digits=dp.get_precision("Product Price"), + digits="Product Price", ) standard_margin = fields.Float( compute="_compute_margin", string="Theorical Margin", - digits=dp.get_precision("Product Price"), + digits="Product Price", help="Theorical Margin is [ sale price (Wo Tax) - cost price ] " "of the product form (not based on historical values). " "Take care of tax include and exclude. If no sale price, " @@ -32,7 +30,7 @@ class ProductTemplate(models.Model): standard_margin_rate = fields.Float( compute="_compute_margin", string="Theorical Margin (%)", - digits=dp.get_precision("Product Price"), + digits="Product Price", help="Margin rate is [ Theorical Margin / sale price (Wo Tax) ] " "of the product form (not based on historical values)." "Take care of tax include and exclude.. If no sale price " @@ -41,7 +39,7 @@ class ProductTemplate(models.Model): standard_markup_rate = fields.Float( compute="_compute_margin", string="Theorical Markup (%)", - digits=dp.get_precision("Product Price"), + digits="Product Price", help="Markup rate is [ Theorical Margin / cost price (Wo Tax) ] " "of the product form (not based on historical values)." "Take care of tax include and exclude.. If no cost price " From 5aed11d98caad77702ae86496c5d542c3dd30b70 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 21 Jun 2023 15:15:23 +0000 Subject: [PATCH 57/75] [UPD] Update product_standard_margin.pot --- .../i18n/product_standard_margin.pot | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/product_standard_margin/i18n/product_standard_margin.pot b/product_standard_margin/i18n/product_standard_margin.pot index 8c0b59d3..25a492dc 100644 --- a/product_standard_margin/i18n/product_standard_margin.pot +++ b/product_standard_margin/i18n/product_standard_margin.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 15.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -14,6 +14,7 @@ msgstr "" "Plural-Forms: \n" #. module: product_standard_margin +#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate #: model:ir.model.fields,help:product_standard_margin.field_product_template__standard_margin_rate msgid "" "Margin rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " @@ -31,21 +32,13 @@ msgid "" msgstr "" #. module: product_standard_margin -#: model:ir.model.fields,help:product_standard_margin.field_product_product__standard_margin_rate -msgid "" -"Markup rate is [ Theorical Margin / sale price (Wo Tax) ] of the product " -"form (not based on historical values).Take care of tax include and exclude.." -" If no sale price set, will display 999.0" -msgstr "" - -#. module: product_standard_margin -#: model:ir.model,name:product_standard_margin.model_product_product +#: model:ir.model,name:product_standard_margin.model_product_template msgid "Product" msgstr "" #. module: product_standard_margin -#: model:ir.model,name:product_standard_margin.model_product_template -msgid "Product Template" +#: model:ir.model,name:product_standard_margin.model_product_product +msgid "Product Variant" msgstr "" #. module: product_standard_margin From 182b68f2d05825040802c73ae50d8b9ed8f43400 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 21 Jun 2023 15:18:28 +0000 Subject: [PATCH 58/75] [UPD] README.rst --- product_standard_margin/README.rst | 12 ++++++------ .../static/description/index.html | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/product_standard_margin/README.rst b/product_standard_margin/README.rst index 318b2bf6..44d3b45e 100644 --- a/product_standard_margin/README.rst +++ b/product_standard_margin/README.rst @@ -14,13 +14,13 @@ Product Margin and Margin Rate :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/15.0/product_standard_margin + :target: https://github.com/OCA/margin-analysis/tree/16.0/product_standard_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-15-0/margin-analysis-15-0-product_standard_margin + :target: https://translation.odoo-community.org/projects/margin-analysis-16-0/margin-analysis-16-0-product_standard_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/132/15.0 + :target: https://runbot.odoo-community.org/runbot/132/16.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -35,7 +35,7 @@ Margin : Markup : (Sale Price without tax - Standard Price) / Standard Price -.. figure:: https://raw.githubusercontent.com/OCA/margin-analysis/15.0/product_standard_margin/static/description/product_form.png +.. figure:: https://raw.githubusercontent.com/OCA/margin-analysis/16.0/product_standard_margin/static/description/product_form.png **Note:** @@ -63,7 +63,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. @@ -106,6 +106,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/margin-analysis `_ project on GitHub. +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/product_standard_margin/static/description/index.html b/product_standard_margin/static/description/index.html index 18c509a6..5f11a215 100644 --- a/product_standard_margin/static/description/index.html +++ b/product_standard_margin/static/description/index.html @@ -367,7 +367,7 @@

    Product Margin and Margin Rate

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

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

    +

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

    Add 2 fields on the product form that compute the standard (or theorical) margin and markup based on the current values of sale and standard price present in the product form. We take care of taxe included or excluded.

    @@ -377,7 +377,7 @@

    Product Margin and Margin Rate

    Markup : (Sale Price without tax - Standard Price) / Standard Price

    -https://raw.githubusercontent.com/OCA/margin-analysis/15.0/product_standard_margin/static/description/product_form.png +https://raw.githubusercontent.com/OCA/margin-analysis/16.0/product_standard_margin/static/description/product_form.png

    Note:

    As this module will base his simple computation on sale and cost prices, @@ -411,7 +411,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.

    @@ -442,7 +442,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    legalsylvain

    -

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

    +

    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.

    From 3c7c5df32214697842dc69d28e5df63f01a74397 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 24 Jul 2023 11:30:04 +0200 Subject: [PATCH 59/75] [FIX] product_standard_margin --- product_standard_margin/views/view_product_product.xml | 8 ++++---- product_standard_margin/views/view_product_template.xml | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/product_standard_margin/views/view_product_product.xml b/product_standard_margin/views/view_product_product.xml index 1dd6b899..6e7fa19b 100644 --- a/product_standard_margin/views/view_product_product.xml +++ b/product_standard_margin/views/view_product_product.xml @@ -13,8 +13,8 @@ position="after" > - - + +
    @@ -28,8 +28,8 @@
    - - + + diff --git a/product_standard_margin/views/view_product_template.xml b/product_standard_margin/views/view_product_template.xml index 715e5c41..e86f6d63 100644 --- a/product_standard_margin/views/view_product_template.xml +++ b/product_standard_margin/views/view_product_template.xml @@ -16,12 +16,10 @@ /> From eda55055a9fc26416e6f0f3a853ce180e5ec5986 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 24 Jul 2023 12:24:25 +0000 Subject: [PATCH 60/75] product_standard_margin 16.0.1.0.1 --- product_standard_margin/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/product_standard_margin/__manifest__.py b/product_standard_margin/__manifest__.py index 0c63670f..53e3d3da 100644 --- a/product_standard_margin/__manifest__.py +++ b/product_standard_margin/__manifest__.py @@ -5,7 +5,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Product Margin and Margin Rate", - "version": "16.0.1.0.0", + "version": "16.0.1.0.1", "author": "Camptocamp,GRAP,Odoo Community Association (OCA)", "category": "Product", "depends": ["account"], From 25b3071996ddadebbb99e05d56ac1e394daa0644 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 3 Sep 2023 14:37:30 +0000 Subject: [PATCH 61/75] [UPD] README.rst --- product_standard_margin/README.rst | 15 ++++--- .../static/description/index.html | 40 ++++++++++--------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/product_standard_margin/README.rst b/product_standard_margin/README.rst index 44d3b45e..826b2b6a 100644 --- a/product_standard_margin/README.rst +++ b/product_standard_margin/README.rst @@ -2,10 +2,13 @@ Product Margin and Margin Rate ============================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:596f5e3407803f321b8176d8a58bd820d13dcab26d4fa2fd4060b458399f0549 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Product Margin and Margin Rate .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/margin-analysis-16-0/margin-analysis-16-0-product_standard_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/132/16.0 - :alt: Try me on Runbot +.. |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=16.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| Add 2 fields on the product form that compute the standard (or theorical) margin and markup based on the current values of sale and standard price @@ -62,7 +65,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 +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. diff --git a/product_standard_margin/static/description/index.html b/product_standard_margin/static/description/index.html index 5f11a215..7d2edc6c 100644 --- a/product_standard_margin/static/description/index.html +++ b/product_standard_margin/static/description/index.html @@ -1,20 +1,20 @@ - + - + Product Margin and Margin Rate