From ebcede2746d700c1a6b504240107e04b93e5d811 Mon Sep 17 00:00:00 2001 From: Antonio Espinosa Date: Fri, 4 Mar 2016 17:15:53 +0100 Subject: [PATCH] Define SEPA identifiers per payment mode --- account_banking_sepa_direct_debit/README.rst | 4 +- .../__openerp__.py | 5 ++- .../models/__init__.py | 1 + .../models/common.py | 39 +++++++++++++++++ .../models/payment_mode.py | 42 +++++++++++++++++++ .../models/res_company.py | 37 ++-------------- .../views/payment_mode_view.xml | 24 +++++++++++ .../wizard/export_sdd.py | 4 ++ 8 files changed, 119 insertions(+), 37 deletions(-) create mode 100644 account_banking_sepa_direct_debit/models/common.py create mode 100644 account_banking_sepa_direct_debit/models/payment_mode.py create mode 100644 account_banking_sepa_direct_debit/views/payment_mode_view.xml diff --git a/account_banking_sepa_direct_debit/README.rst b/account_banking_sepa_direct_debit/README.rst index ace5ce806..10eb9754d 100644 --- a/account_banking_sepa_direct_debit/README.rst +++ b/account_banking_sepa_direct_debit/README.rst @@ -49,7 +49,7 @@ Known issues / Roadmap ====================== * No known issues - + Bug Tracker =========== @@ -64,13 +64,13 @@ Credits Contributors ------------ -* Firsname Lastname * Alexis de Lattre * Pedro M. Baeza * Stéphane Bidoul * Alexandre Fayolle * Raphaël Valyi * Sandy Carter +* Antonio Espinosa Maintainer diff --git a/account_banking_sepa_direct_debit/__openerp__.py b/account_banking_sepa_direct_debit/__openerp__.py index 268fffe25..c7922127f 100644 --- a/account_banking_sepa_direct_debit/__openerp__.py +++ b/account_banking_sepa_direct_debit/__openerp__.py @@ -1,15 +1,17 @@ # -*- coding: utf-8 -*- # © 2013-2015 Akretion (www.akretion.com) # © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza +# © 2016 Antiun Ingenieria S.L. - Antonio Espinosa # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Account Banking SEPA Direct Debit', 'summary': 'Create SEPA files for Direct Debit', - 'version': '8.0.0.3.0', + 'version': '8.0.0.4.0', 'license': 'AGPL-3', 'author': "Akretion, " "Serv. Tecnol. Avanzados - Pedro M. Baeza, " + "Antiun Ingeniería S.L., " "Odoo Community Association (OCA)", 'website': 'https://github.com/OCA/bank-payment', 'category': 'Banking addons', @@ -21,6 +23,7 @@ 'data': [ 'views/account_banking_mandate_view.xml', 'views/res_company_view.xml', + 'views/payment_mode_view.xml', 'wizard/export_sdd_view.xml', 'data/mandate_expire_cron.xml', 'data/payment_type_sdd.xml', diff --git a/account_banking_sepa_direct_debit/models/__init__.py b/account_banking_sepa_direct_debit/models/__init__.py index ac7674156..93fb91cc8 100644 --- a/account_banking_sepa_direct_debit/models/__init__.py +++ b/account_banking_sepa_direct_debit/models/__init__.py @@ -3,3 +3,4 @@ from . import res_company from . import account_banking_mandate from . import bank_payment_line +from . import payment_mode diff --git a/account_banking_sepa_direct_debit/models/common.py b/account_banking_sepa_direct_debit/models/common.py new file mode 100644 index 000000000..dd507a4db --- /dev/null +++ b/account_banking_sepa_direct_debit/models/common.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# © 2013 Akretion (www.akretion.com) +# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza +# © 2016 Antiun Ingenieria S.L. - Antonio Espinosa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging + +logger = logging.getLogger(__name__) + + +def is_sepa_creditor_identifier_valid(sepa_creditor_identifier): + """Check if SEPA Creditor Identifier is valid + @param sepa_creditor_identifier: SEPA Creditor Identifier as str + or unicode + @return: True if valid, False otherwise + """ + if not isinstance(sepa_creditor_identifier, (str, unicode)): + return False + try: + sci = str(sepa_creditor_identifier).lower() + except: + logger.warning( + "SEPA Creditor ID should contain only ASCII caracters.") + return False + if len(sci) < 9: + return False + before_replacement = sci[7:] + sci[0:2] + '00' + logger.debug( + "SEPA ID check before_replacement = %s" % before_replacement) + after_replacement = '' + for char in before_replacement: + if char.isalpha(): + after_replacement += str(ord(char) - 87) + else: + after_replacement += char + logger.debug( + "SEPA ID check after_replacement = %s" % after_replacement) + return int(sci[2:4]) == (98 - (int(after_replacement) % 97)) diff --git a/account_banking_sepa_direct_debit/models/payment_mode.py b/account_banking_sepa_direct_debit/models/payment_mode.py new file mode 100644 index 000000000..9753ac319 --- /dev/null +++ b/account_banking_sepa_direct_debit/models/payment_mode.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# © 2016 Antiun Ingenieria S.L. - Antonio Espinosa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import models, fields, api, exceptions, _ +from .common import is_sepa_creditor_identifier_valid + + +class PaymentMode(models.Model): + _inherit = 'payment.mode' + + sepa_creditor_identifier = fields.Char( + string='SEPA Creditor Identifier', size=35, + help="Enter the Creditor Identifier that has been attributed to your " + "company to make SEPA Direct Debits. If not defined, " + "SEPA Creditor Identifier from company will be used.\n" + "This identifier is composed of :\n" + "- your country ISO code (2 letters)\n" + "- a 2-digits checkum\n" + "- a 3-letters business code\n" + "- a country-specific identifier") + original_creditor_identifier = fields.Char( + string='Original Creditor Identifier', size=70, + help="If not defined, Original Creditor Identifier from company " + "will be used.") + + def _sepa_type_get(self): + res = super(PaymentMode, self)._sepa_type_get() + if not res: + if self.type.code and self.type.code.startswith('pain.008'): + res = 'sepa_direct_debit' + return res + + @api.one + @api.constrains('sepa_creditor_identifier') + def _check_sepa_creditor_identifier(self): + if self.sepa_creditor_identifier: + if not is_sepa_creditor_identifier_valid( + self.sepa_creditor_identifier): + raise exceptions.Warning( + _('Error'), + _("Invalid SEPA Creditor Identifier.")) diff --git a/account_banking_sepa_direct_debit/models/res_company.py b/account_banking_sepa_direct_debit/models/res_company.py index 9ce040189..8b76a9678 100644 --- a/account_banking_sepa_direct_debit/models/res_company.py +++ b/account_banking_sepa_direct_debit/models/res_company.py @@ -1,12 +1,11 @@ # -*- coding: utf-8 -*- # © 2013 Akretion (www.akretion.com) # © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza +# © 2016 Antiun Ingenieria S.L. - Antonio Espinosa # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from openerp import models, fields, api, exceptions, _ -import logging - -logger = logging.getLogger(__name__) +from .common import is_sepa_creditor_identifier_valid class ResCompany(models.Model): @@ -22,41 +21,11 @@ class ResCompany(models.Model): original_creditor_identifier = fields.Char( string='Original Creditor Identifier', size=70) - def is_sepa_creditor_identifier_valid( - self, sepa_creditor_identifier): - """Check if SEPA Creditor Identifier is valid - @param sepa_creditor_identifier: SEPA Creditor Identifier as str - or unicode - @return: True if valid, False otherwise - """ - if not isinstance(sepa_creditor_identifier, (str, unicode)): - return False - try: - sci = str(sepa_creditor_identifier).lower() - except: - logger.warning( - "SEPA Creditor ID should contain only ASCII caracters.") - return False - if len(sci) < 9: - return False - before_replacement = sci[7:] + sci[0:2] + '00' - logger.debug( - "SEPA ID check before_replacement = %s" % before_replacement) - after_replacement = '' - for char in before_replacement: - if char.isalpha(): - after_replacement += str(ord(char) - 87) - else: - after_replacement += char - logger.debug( - "SEPA ID check after_replacement = %s" % after_replacement) - return int(sci[2:4]) == (98 - (int(after_replacement) % 97)) - @api.one @api.constrains('sepa_creditor_identifier') def _check_sepa_creditor_identifier(self): if self.sepa_creditor_identifier: - if not self.is_sepa_creditor_identifier_valid( + if not is_sepa_creditor_identifier_valid( self.sepa_creditor_identifier): raise exceptions.Warning( _('Error'), diff --git a/account_banking_sepa_direct_debit/views/payment_mode_view.xml b/account_banking_sepa_direct_debit/views/payment_mode_view.xml new file mode 100644 index 000000000..9bba891d6 --- /dev/null +++ b/account_banking_sepa_direct_debit/views/payment_mode_view.xml @@ -0,0 +1,24 @@ + + + + + + + Add SEPA identifiers + payment.mode + + + + + + + + + + + + + diff --git a/account_banking_sepa_direct_debit/wizard/export_sdd.py b/account_banking_sepa_direct_debit/wizard/export_sdd.py index f2be2df00..232bb98a5 100644 --- a/account_banking_sepa_direct_debit/wizard/export_sdd.py +++ b/account_banking_sepa_direct_debit/wizard/export_sdd.py @@ -224,6 +224,8 @@ class BankingExportSddWizard(models.TransientModel): payment_info_2_0, 'CdtrSchmeId') self.generate_creditor_scheme_identification( creditor_scheme_identification_2_27, + 'self.payment_order_ids[0].mode.' + 'sepa_creditor_identifier or' 'self.payment_order_ids[0].company_id.' 'sepa_creditor_identifier', 'SEPA Creditor Identifier', {'self': self}, 'SEPA', gen_args) @@ -325,6 +327,8 @@ class BankingExportSddWizard(models.TransientModel): amendment_info_details_2_51, 'OrgnlCdtrSchmeId') self.generate_creditor_scheme_identification( ori_creditor_scheme_id_2_53, + 'self.payment_order_ids[0].mode.' + 'original_creditor_identifier or' 'self.payment_order_ids[0].company_id.' 'original_creditor_identifier', 'Original Creditor Identifier',