From 8218a8dc3d53694e887400ff924bc5f9aa025695 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Wed, 31 Dec 2014 23:06:58 +0100 Subject: [PATCH 1/3] currency_rate_date_check: port to v8 --- .../currency_rate_date_check.py | 112 ------------------ .../__init__.py | 4 +- .../__openerp__.py | 12 +- .../company.py | 26 ++-- .../company_view.xml | 7 +- .../currency_rate_date_check.py | 102 ++++++++++++++++ .../i18n/currency_rate_date_check.pot | 0 .../i18n/fr.po | 0 .../i18n/pt_BR.po | 0 .../images/date_check_company_config.jpg | Bin .../images/date_check_error_popup.jpg | Bin .../static/src/img/icon.png | Bin 12 files changed, 122 insertions(+), 141 deletions(-) delete mode 100644 __unported__/currency_rate_date_check/currency_rate_date_check.py rename {__unported__/currency_rate_date_check => currency_rate_date_check}/__init__.py (89%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/__openerp__.py (88%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/company.py (65%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/company_view.xml (72%) create mode 100644 currency_rate_date_check/currency_rate_date_check.py rename {__unported__/currency_rate_date_check => currency_rate_date_check}/i18n/currency_rate_date_check.pot (100%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/i18n/fr.po (100%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/i18n/pt_BR.po (100%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/images/date_check_company_config.jpg (100%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/images/date_check_error_popup.jpg (100%) rename {__unported__/currency_rate_date_check => currency_rate_date_check}/static/src/img/icon.png (100%) diff --git a/__unported__/currency_rate_date_check/currency_rate_date_check.py b/__unported__/currency_rate_date_check/currency_rate_date_check.py deleted file mode 100644 index 73cb041f3..000000000 --- a/__unported__/currency_rate_date_check/currency_rate_date_check.py +++ /dev/null @@ -1,112 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# Currency rate date check module for OpenERP -# Copyright (C) 2012-2013 Akretion (http://www.akretion.com) -# @author Alexis de Lattre -# -# 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 -from datetime import datetime -from openerp.tools.translate import _ - -# Here are some explainations about the design of this module. -# In server/openerp/addons/base/res/res_currency.py : -# compute() -> _get_conversion_rate() -# -> _current_rate() -> _current_rate_computation() -# The date used for the rate is the one in the context -# compute() adds currency_rate_type_from -# and currency_rate_type_to to the context -# _get_conversion_rate() adds currency_rate_type_id to context ; -# its value is currency_rate_type_to ; -# if it doesn't exist it's currency_rate_type_from ; -# if it doesn't exist either it's False -# It already contains raise "No rate found for currency ... at the date ..." -# _current_rate() reads currency_rate_type_id -# from context and uses it in the SQL request -# This is the function used for the definition of -# the field.function 'rate' on res_currency - -# Which one of the 3 functions should we inherit ? Good question... -# It's probably better to inherit the lowest level function, -# i.e. _current_rate_computation() -# Advantage : by inheriting the lowest level function, -# we can be sure that the check -# always apply, even for scenarios where we -# read the field "rate" of the obj currency -# => that's the solution I implement in the code below - - -class res_currency(orm.Model): - _inherit = 'res.currency' - - def _current_rate_computation(self, cr, uid, ids, name, arg, - raise_on_no_rate, context=None): - if context is None: - context = {} - # We only do the check if there is an explicit date in the context and - # there is no specific currency_rate_type_id - if context.get('date') and not context.get('currency_rate_type_id') and\ - not context.get('disable_rate_date_check'): - for currency_id in ids: - # We could get the company from the currency, but it's not a - # 'required' field, so we should probably continue to get it - # from the user, shouldn't we ? - user = self.pool['res.users'].browse(cr, uid, uid, - context=context) - # if it's the company currency, don't do anything - # (there is just one old rate at 1.0) - if user.company_id.currency_id.id == currency_id: - continue - else: - # now we do the real work ! - date = context.get('date', - datetime.today().strftime('%Y-%m-%d')) - date_datetime = datetime.strptime(date, '%Y-%m-%d') - rate_obj = self.pool['res.currency.rate'] - selected_rate = rate_obj.search(cr, uid, [ - ('currency_id', '=', currency_id), - ('name', '<=', date), - ('currency_rate_type_id', '=', None) - ], order='name desc', limit=1, context=context) - if not selected_rate: - continue - - rate_date = rate_obj.read(cr, uid, selected_rate[0], - ['name'], - context=context)['name'] - rate_date_datetime = datetime.strptime(rate_date, - '%Y-%m-%d') - max_delta = user.company_id.currency_rate_max_delta - if (date_datetime - rate_date_datetime).days > max_delta: - currency_name = self.read(cr, uid, - currency_id, - ['name'], - context=context)['name'] - raise orm.except_orm( - _('Error'), - _('You are requesting a rate conversion on %s for ' - 'currency %s but the nearest ' - 'rate before that date is ' - 'dated %s and the maximum currency ' - 'rate time delta for ' - 'your company is %s days') % ( - date, currency_name, rate_date, max_delta) - ) - # Now we call the regular function from the "base" module - return super(res_currency, self)._current_rate_computation( - cr, uid, ids, name, arg, raise_on_no_rate, context=context) diff --git a/__unported__/currency_rate_date_check/__init__.py b/currency_rate_date_check/__init__.py similarity index 89% rename from __unported__/currency_rate_date_check/__init__.py rename to currency_rate_date_check/__init__.py index b050ef08c..749aed522 100644 --- a/__unported__/currency_rate_date_check/__init__.py +++ b/currency_rate_date_check/__init__.py @@ -1,8 +1,8 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# Currency rate date check module for OpenERP -# Copyright (C) 2012-2013 Akretion (http://www.akretion.com). +# Currency rate date check module for Odoo +# Copyright (C) 2012-2014 Akretion (http://www.akretion.com). # @author Alexis de Lattre # # This program is free software: you can redistribute it and/or modify diff --git a/__unported__/currency_rate_date_check/__openerp__.py b/currency_rate_date_check/__openerp__.py similarity index 88% rename from __unported__/currency_rate_date_check/__openerp__.py rename to currency_rate_date_check/__openerp__.py index 87aad9aef..4dd65cce8 100644 --- a/__unported__/currency_rate_date_check/__openerp__.py +++ b/currency_rate_date_check/__openerp__.py @@ -1,8 +1,8 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# Currency rate date check module for OpenERP -# Copyright (C) 2012-2013 Akretion (http://www.akretion.com). +# Currency rate date check module for Odoo +# Copyright (C) 2012-2014 Akretion (http://www.akretion.com). # @author Alexis de Lattre # # This program is free software: you can redistribute it and/or modify @@ -31,10 +31,9 @@ Currency Rate Date Check ======================== -This module adds a check on dates when doing currency conversion in OpenERP. +This module adds a check on dates when doing currency conversion in Odoo. It checks that the currency rate used to make the conversion -is not more than N days away -from the date of the amount to convert. +is not more than N days away from the date of the amount to convert. The maximum number of days of the interval can be configured on the company form. @@ -50,6 +49,5 @@ for any help or question about this module. 'images/date_check_error_popup.jpg', 'images/date_check_company_config.jpg', ], - 'installable': False, - 'active': False, + 'installable': True, } diff --git a/__unported__/currency_rate_date_check/company.py b/currency_rate_date_check/company.py similarity index 65% rename from __unported__/currency_rate_date_check/company.py rename to currency_rate_date_check/company.py index d6881f9d7..d88389668 100644 --- a/__unported__/currency_rate_date_check/company.py +++ b/currency_rate_date_check/company.py @@ -1,8 +1,8 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# Currency rate date check module for OpenERP -# Copyright (C) 2012-2013 Akretion (http://www.akretion.com) +# Currency rate date check module for Odoo +# Copyright (C) 2012-2014 Akretion (http://www.akretion.com) # @author Alexis de Lattre # # This program is free software: you can redistribute it and/or modify @@ -20,25 +20,17 @@ # ############################################################################## -from openerp.osv import orm, fields +from openerp import models, fields -class res_company(orm.Model): +class ResCompany(models.Model): _inherit = 'res.company' - _columns = { - 'currency_rate_max_delta': fields.integer( - 'Max Time Delta in Days for Currency Rates', - help="This is the maximum interval in days between " - "the date associated " - "with the amount to convert and the date " - "of the nearest currency " - "rate available in OpenERP."), - } - - _defaults = { - 'currency_rate_max_delta': 7, - } + currency_rate_max_delta = fields.Integer( + string='Max Time Delta in Days for Currency Rates', default=7, + help="This is the maximum interval in days between " + "the date associated with the amount to convert and the date " + "of the nearest currency rate available in Odoo.") _sql_constraints = [ ('currency_rate_max_delta_positive', diff --git a/__unported__/currency_rate_date_check/company_view.xml b/currency_rate_date_check/company_view.xml similarity index 72% rename from __unported__/currency_rate_date_check/company_view.xml rename to currency_rate_date_check/company_view.xml index ebf326759..6ba5c85df 100644 --- a/__unported__/currency_rate_date_check/company_view.xml +++ b/currency_rate_date_check/company_view.xml @@ -1,7 +1,7 @@ @@ -9,8 +9,9 @@ - - currency.rate.date.check.form + + + currency.rate.date.check.company.form res.company diff --git a/currency_rate_date_check/currency_rate_date_check.py b/currency_rate_date_check/currency_rate_date_check.py new file mode 100644 index 000000000..e0981d989 --- /dev/null +++ b/currency_rate_date_check/currency_rate_date_check.py @@ -0,0 +1,102 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Currency rate date check module for OpenERP +# Copyright (C) 2012-2013 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# +# 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 +from datetime import datetime +from openerp.tools.translate import _ +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, \ + DEFAULT_SERVER_DATETIME_FORMAT + +# Here are some explainations about the design of this module. +# In odoo/openerp/addons/base/res/res_currency.py : +# compute() -> _get_conversion_rate() +# -> _current_rate() -> _get_current_rate() +# The date used for the rate is the one in the context + +# Which one of the 3 functions should we inherit ? Good question... +# It's probably better to inherit the lowest level function, +# i.e. _get_current_rate() +# Advantage : by inheriting the lowest level function, +# we can be sure that the check +# always apply, even for scenarios where we +# read the field "rate" of the obj currency +# => that's the solution I implement in the code below + + +class ResCurrency(orm.Model): + _inherit = 'res.currency' + + def _get_current_rate( + self, cr, uid, ids, raise_on_no_rate=True, context=None): + if context is None: + context = {} + # We don't check if we don't have 'date' in context, which is + # a pb because it means Odoo can do a rate conversion + # on today's date with an old rate, but otherwize it would raise + # too often, for example it would raise entering the + # Currencies menu entry ! + if context.get('date') and not context.get('disable_rate_date_check'): + date = context.get('date') + for currency_id in ids: + # We could get the company from the currency, but it's not a + # 'required' field, so we should probably continue to get it + # from the user, shouldn't we ? + user = self.pool['res.users'].browse(cr, uid, uid, + context=context) + # if it's the company currency, don't do anything + # (there is just one old rate at 1.0) + if user.company_id.currency_id.id == currency_id: + continue + else: + # now we do the real work ! + cr.execute( + 'SELECT rate, name FROM res_currency_rate ' + 'WHERE currency_id = %s ' + 'AND name <= %s ' + 'ORDER BY name desc LIMIT 1', + (currency_id, date)) + if cr.rowcount: + rate_date = cr.fetchone()[1] + rate_date_dt = datetime.strptime( + rate_date, DEFAULT_SERVER_DATETIME_FORMAT) + if len(date) <= 10: + date_dt = datetime.strptime( + date, DEFAULT_SERVER_DATE_FORMAT) + else: + date_dt = datetime.strptime( + date, DEFAULT_SERVER_DATETIME_FORMAT) + max_delta = user.company_id.currency_rate_max_delta + if (date_dt - rate_date_dt).days > max_delta: + currency = self.browse( + cr, uid, currency_id, context=context) + raise orm.except_orm( + _('Error'), + _('You are requesting a rate conversion on %s ' + 'for currency %s but the nearest ' + 'rate before that date is ' + 'dated %s and the maximum currency ' + 'rate time delta for ' + 'your company is %s days') + % (date, currency.name, rate_date, max_delta)) + # Now we call the regular function from the "base" module + return super(ResCurrency, self)._get_current_rate( + cr, uid, ids, raise_on_no_rate=raise_on_no_rate, context=context) diff --git a/__unported__/currency_rate_date_check/i18n/currency_rate_date_check.pot b/currency_rate_date_check/i18n/currency_rate_date_check.pot similarity index 100% rename from __unported__/currency_rate_date_check/i18n/currency_rate_date_check.pot rename to currency_rate_date_check/i18n/currency_rate_date_check.pot diff --git a/__unported__/currency_rate_date_check/i18n/fr.po b/currency_rate_date_check/i18n/fr.po similarity index 100% rename from __unported__/currency_rate_date_check/i18n/fr.po rename to currency_rate_date_check/i18n/fr.po diff --git a/__unported__/currency_rate_date_check/i18n/pt_BR.po b/currency_rate_date_check/i18n/pt_BR.po similarity index 100% rename from __unported__/currency_rate_date_check/i18n/pt_BR.po rename to currency_rate_date_check/i18n/pt_BR.po diff --git a/__unported__/currency_rate_date_check/images/date_check_company_config.jpg b/currency_rate_date_check/images/date_check_company_config.jpg similarity index 100% rename from __unported__/currency_rate_date_check/images/date_check_company_config.jpg rename to currency_rate_date_check/images/date_check_company_config.jpg diff --git a/__unported__/currency_rate_date_check/images/date_check_error_popup.jpg b/currency_rate_date_check/images/date_check_error_popup.jpg similarity index 100% rename from __unported__/currency_rate_date_check/images/date_check_error_popup.jpg rename to currency_rate_date_check/images/date_check_error_popup.jpg diff --git a/__unported__/currency_rate_date_check/static/src/img/icon.png b/currency_rate_date_check/static/src/img/icon.png similarity index 100% rename from __unported__/currency_rate_date_check/static/src/img/icon.png rename to currency_rate_date_check/static/src/img/icon.png From d1be22a150dc062e70fde34274f9d1a9335f59ae Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 8 Jan 2015 21:55:14 +0100 Subject: [PATCH 2/3] Move icon to static/description/ --- .../static/{src/img => description}/icon.png | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename currency_rate_date_check/static/{src/img => description}/icon.png (100%) diff --git a/currency_rate_date_check/static/src/img/icon.png b/currency_rate_date_check/static/description/icon.png similarity index 100% rename from currency_rate_date_check/static/src/img/icon.png rename to currency_rate_date_check/static/description/icon.png From 90c1d9cf7cfd6b4659de90b296b61f755d48067f Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 8 Jan 2015 22:21:06 +0100 Subject: [PATCH 3/3] Use fields.Date.to_string() and .from_string() --- .../currency_rate_date_check.py | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/currency_rate_date_check/currency_rate_date_check.py b/currency_rate_date_check/currency_rate_date_check.py index e0981d989..7e8fe4944 100644 --- a/currency_rate_date_check/currency_rate_date_check.py +++ b/currency_rate_date_check/currency_rate_date_check.py @@ -20,11 +20,8 @@ # ############################################################################## -from openerp.osv import orm -from datetime import datetime -from openerp.tools.translate import _ -from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, \ - DEFAULT_SERVER_DATETIME_FORMAT +from openerp import models, fields, _ +from openerp.exceptions import Warning # Here are some explainations about the design of this module. # In odoo/openerp/addons/base/res/res_currency.py : @@ -42,7 +39,7 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, \ # => that's the solution I implement in the code below -class ResCurrency(orm.Model): +class ResCurrency(models.Model): _inherit = 'res.currency' def _get_current_rate( @@ -76,20 +73,16 @@ class ResCurrency(orm.Model): (currency_id, date)) if cr.rowcount: rate_date = cr.fetchone()[1] - rate_date_dt = datetime.strptime( - rate_date, DEFAULT_SERVER_DATETIME_FORMAT) + rate_date_dt = fields.Date.from_string(rate_date) if len(date) <= 10: - date_dt = datetime.strptime( - date, DEFAULT_SERVER_DATE_FORMAT) + date_dt = fields.Date.from_string(date) else: - date_dt = datetime.strptime( - date, DEFAULT_SERVER_DATETIME_FORMAT) + date_dt = fields.Datetime.from_string(date) max_delta = user.company_id.currency_rate_max_delta if (date_dt - rate_date_dt).days > max_delta: currency = self.browse( cr, uid, currency_id, context=context) - raise orm.except_orm( - _('Error'), + raise Warning( _('You are requesting a rate conversion on %s ' 'for currency %s but the nearest ' 'rate before that date is '