From c9ce99ed4e3f88346fcb465d39a2cd3070900686 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Fri, 20 Feb 2015 04:16:12 +0100 Subject: [PATCH 01/65] [ADD] l10n_es_account_bank_statement_import_n43: Sustituye a l10n_es_bank_statement para importar extractos bancarios N43 --- .../README.rst | 56 ++++ .../__init__.py | 5 + .../__openerp__.py | 36 +++ .../doc/norma_43_castellano.pdf | Bin 0 -> 161738 bytes .../i18n/en.po | 80 +++++ .../i18n/es.po | 82 +++++ .../i18n/gl.po | 81 +++++ .../models/__init__.py | 5 + .../account_bank_statement_import_n43.py | 299 ++++++++++++++++++ .../static/description/icon.png | Bin 0 -> 7527 bytes .../static/description/icon_src.svg | 194 ++++++++++++ 11 files changed, 838 insertions(+) create mode 100644 l10n_es_account_statement_import_n43/README.rst create mode 100644 l10n_es_account_statement_import_n43/__init__.py create mode 100644 l10n_es_account_statement_import_n43/__openerp__.py create mode 100644 l10n_es_account_statement_import_n43/doc/norma_43_castellano.pdf create mode 100644 l10n_es_account_statement_import_n43/i18n/en.po create mode 100644 l10n_es_account_statement_import_n43/i18n/es.po create mode 100644 l10n_es_account_statement_import_n43/i18n/gl.po create mode 100644 l10n_es_account_statement_import_n43/models/__init__.py create mode 100644 l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py create mode 100644 l10n_es_account_statement_import_n43/static/description/icon.png create mode 100644 l10n_es_account_statement_import_n43/static/description/icon_src.svg diff --git a/l10n_es_account_statement_import_n43/README.rst b/l10n_es_account_statement_import_n43/README.rst new file mode 100644 index 00000000000..bed0f745859 --- /dev/null +++ b/l10n_es_account_statement_import_n43/README.rst @@ -0,0 +1,56 @@ +Extractos bancarios españoles (Norma 43) +======================================== + +Importación y tratamiento de los extractos bancarios españoles que siguen la +norma/cuaderno 43 de la 'Asociación Española de la Banca'. Puede consultarse la +especificación del formato aquí_. + +.. _aquí: http://goo.gl/2zzlmu + +Instalación +=========== + +Para instalar este módulo, es necesario tener disponible el módulo +*account_bank_statement_import* del repositorio +https://github.com/OCA/bank-statement-import + +Configuración +============= + +No es necesaria ninguna configuración especial. + +Uso +=== + +Vaya a Contabilidad > Extractos bancarios > Importar extracto bancario, +seleccione el archivo Norma 43 a importar, el diario en el que registrarlo, +y pulse en 'Importar'. + +Incidencias conocidas / Hoja de ruta +==================================== + +* Reconocimiento de partners para otros bancos distintos del Santander o + CaixaBank. + +Credits +======= + +Contributors +------------ + +* Pedro M. Baeza + +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/l10n_es_account_statement_import_n43/__init__.py b/l10n_es_account_statement_import_n43/__init__.py new file mode 100644 index 00000000000..49d04adebde --- /dev/null +++ b/l10n_es_account_statement_import_n43/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# For copyright and license notices, see __openerp__.py file in root directory +############################################################################## +from . import models diff --git a/l10n_es_account_statement_import_n43/__openerp__.py b/l10n_es_account_statement_import_n43/__openerp__.py new file mode 100644 index 00000000000..5b9c796090e --- /dev/null +++ b/l10n_es_account_statement_import_n43/__openerp__.py @@ -0,0 +1,36 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright(c) 2013-2015 Serv. Tecnol. Avanzados (http://serviciosbaeza.com) +# Pedro M. Baeza +# +# 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': 'Importación de extractos bancarios españoles (Norma 43)', + 'category': 'Accounting & Finance', + 'version': '8.0.4.0.0', + 'license': 'AGPL-3', + 'author': 'Spanish Localization Team,' + 'Serv. Tecnol. Avanzados - Pedro M. Baeza,' + 'Antiun Ingenería S.L.,' + 'Odoo Community Association (OCA)', + "website": "https://github.com/OCA/l10n-spain", + 'depends': [ + 'account_bank_statement_import', + ], + 'data': [], + 'installable': True, +} diff --git a/l10n_es_account_statement_import_n43/doc/norma_43_castellano.pdf b/l10n_es_account_statement_import_n43/doc/norma_43_castellano.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6793e04c3ac71cd69774eec72e9ab4f828cd9c85 GIT binary patch literal 161738 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

tuB}=6jimql=XXDaEI1tIrJF>qTc9 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 X=!%4!6XByyGAF`kVUbpmA;SNE;N3z{ literal 0 HcmV?d00001 diff --git a/l10n_es_account_statement_import_n43/i18n/en.po b/l10n_es_account_statement_import_n43/i18n/en.po new file mode 100644 index 00000000000..68c39352cb3 --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/en.po @@ -0,0 +1,80 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: l10n-spain (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-19 01:41+0000\n" +"PO-Revision-Date: 2015-05-23 08:55+0000\n" +"Last-Translator: Pedro M. Baeza \n" +"Language-Team: English (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/en/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:130 +#, python-format +msgid "" +"Credit amount doesn't match with the defined in the last record of account." +msgstr "Credit amount doesn't match with the defined in the last record of account." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 +#, python-format +msgid "" +"Debit amount doesn't match with the defined in the last record of account." +msgstr "Debit amount doesn't match with the defined in the last record of account." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:120 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:125 +#, python-format +msgid "Error in C43 file" +msgstr "Error in C43 file" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:139 +#, python-format +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "Import Bank Statement" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 +#, python-format +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "Number of credit records doesn't match with the defined in the last record of account." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:116 +#, python-format +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "Number of debit records doesn't match with the defined in the last record of account." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:153 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "Number of records doesn't match with the defined in the last record." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:186 +#, python-format +msgid "Record type %s is not valid." +msgstr "Record type %s is not valid." diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po new file mode 100644 index 00000000000..4d38f136d71 --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -0,0 +1,82 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +# Alejandro Santana , 2015 +# Pedro M. Baeza , 2015 +msgid "" +msgstr "" +"Project-Id-Version: l10n-spain (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-19 01:41+0000\n" +"PO-Revision-Date: 2015-06-25 02:26+0000\n" +"Last-Translator: Alejandro Santana \n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:130 +#, python-format +msgid "" +"Credit amount doesn't match with the defined in the last record of account." +msgstr "El importe del haber no cuadra con el definido en el último registro de la cuenta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 +#, python-format +msgid "" +"Debit amount doesn't match with the defined in the last record of account." +msgstr "La cantidad del debe no cuadra con la definida en el último registro de la cuenta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:120 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:125 +#, python-format +msgid "Error in C43 file" +msgstr "Error en el archivo C43" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:139 +#, python-format +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "El importe final del saldo = (saldo inicial + haber - debe) no cuadra con el definido en el último registro de la cuenta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "Importar extracto bancario" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 +#, python-format +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "El número de registros del haber no cuadra con lo definido en el último registro de la cuenta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:116 +#, python-format +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "El número de registros del debe no cuadra con lo definido en el último registro de la cuenta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:153 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "El número de registros no cuadra con lo definido en el último registro." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:186 +#, python-format +msgid "Record type %s is not valid." +msgstr "El tipo de registro %s no es válido." diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po new file mode 100644 index 00000000000..527070c10d1 --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -0,0 +1,81 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +# Alejandro Santana , 2015 +msgid "" +msgstr "" +"Project-Id-Version: l10n-spain (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-19 01:41+0000\n" +"PO-Revision-Date: 2015-06-25 23:30+0000\n" +"Last-Translator: Alejandro Santana \n" +"Language-Team: Galician (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/gl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: gl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:130 +#, python-format +msgid "" +"Credit amount doesn't match with the defined in the last record of account." +msgstr "O importe do haber non cadra co definido no último rexistro da conta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 +#, python-format +msgid "" +"Debit amount doesn't match with the defined in the last record of account." +msgstr "O importe do debe non cadra co definido no último rexistro da conta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:120 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:125 +#, python-format +msgid "Error in C43 file" +msgstr "Erro no arquivo C43" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:139 +#, python-format +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "O importe final do saldo = (saldo inicial + haber - debe) non cadra co definido no último rexistro da conta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "Importar extracto bancario" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 +#, python-format +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "O número de rexistros do haber non cadra co definido no último rexistro da conta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:116 +#, python-format +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "O número de rexistros do debe non cadra co definido no último rexistro da conta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:153 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "O número de rexistros non cadra co definido no último rexistro." + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:186 +#, python-format +msgid "Record type %s is not valid." +msgstr "O tipo de rexistro %s non é válido." diff --git a/l10n_es_account_statement_import_n43/models/__init__.py b/l10n_es_account_statement_import_n43/models/__init__.py new file mode 100644 index 00000000000..9130d3fbc80 --- /dev/null +++ b/l10n_es_account_statement_import_n43/models/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# For copyright and license notices, see __openerp__.py file in root directory +############################################################################## +from . import account_bank_statement_import_n43 diff --git a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py new file mode 100644 index 00000000000..6e31485a326 --- /dev/null +++ b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py @@ -0,0 +1,299 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# For copyright and license notices, see __openerp__.py file in root directory +############################################################################## +from openerp import models, fields, api, exceptions, _ +from datetime import datetime + +account_concept_mapping = { + '01': '4300%00', + '02': '4100%00', + '03': '4100%00', + '04': '4300%00', + '05': '6800%00', + '06': '4010%00', + '07': '5700%00', + '08': '6800%00', + '09': '2510%00', + '10': '5700%00', + '11': '5700%00', + '12': '5700%00', + '13': '5730%00', + '14': '4300%00', + '15': '6400%00', + '16': '6690%00', + '17': '6690%00', + '98': '5720%00', + '99': '5720%00', +} + + +class AccountBankStatementImport(models.TransientModel): + _inherit = 'account.bank.statement.import' + + def _process_record_11(self, line): + """11 - Registro cabecera de cuenta (obligatorio)""" + st_group = { + 'entidad': line[2:6], + 'oficina': line[6:10], + 'cuenta': line[10:20], + 'fecha_ini': datetime.strptime(line[20:26], '%y%m%d'), + 'fecha_fin': datetime.strptime(line[26:32], '%y%m%d'), + 'divisa': line[47:50], + 'modalidad': line[50:51], # 1, 2 o 3 + 'nombre_propietario': line[51:77], + 'saldo_ini': float("%s.%s" % (line[33:45], line[45:47])), + 'saldo_fin': 0, + 'num_debe': 0, + 'debe': 0, + 'num_haber': 0, + 'haber': 0, + 'lines': [], + } + if line[32:33] == '1': + st_group['saldo_ini'] *= -1 + self.balance_start = st_group['saldo_ini'] + return st_group + + def _process_record_22(self, line): + """22 - Registro principal de movimiento (obligatorio)""" + st_line = { + 'of_origen': line[6:10], + 'fecha_oper': datetime.strptime(line[10:16], '%y%m%d'), + 'fecha_valor': datetime.strptime(line[16:22], '%y%m%d'), + 'concepto_c': line[22:24], + 'concepto_p': line[24:27], + 'importe': (float(line[28:40]) + (float(line[40:42]) / 100)), + 'num_documento': line[41:52], + 'referencia1': line[52:64].strip(), + 'referencia2': line[64:].strip(), + 'conceptos': '', + } + if line[27:28] == '1': + st_line['importe'] *= -1 + return st_line + + def _process_record_23(self, st_line, line): + """23 - Registros complementarios de concepto (opcionales y hasta un + máximo de 5)""" + if not st_line.get('conceptos'): + st_line['conceptos'] = {} + st_line['conceptos'][line[2:4]] = (line[4:39].strip(), + line[39:].strip()) + return st_line + + def _process_record_24(self, st_line, line): + """24 - Registro complementario de información de equivalencia del + importe (opcional y sin valor contable)""" + st_line['divisa_eq'] = line[4:7] + st_line['importe_eq'] = float(line[7:19]) + (float(line[19:21]) / 100) + return st_line + + def _process_record_33(self, st_group, line): + """33 - Registro final de cuenta""" + st_group['num_debe'] += int(line[20:25]) + st_group['debe'] += float("%s.%s" % (line[25:37], line[37:39])) + st_group['num_haber'] += int(line[39:44]) + st_group['haber'] += float("%s.%s" % (line[44:56], line[56:58])) + st_group['saldo_fin'] += float("%s.%s" % (line[59:71], line[71:73])) + if line[58:59] == '1': + st_group['saldo_fin'] *= -1 + self.balance_end = st_group['saldo_fin'] + # Group level checks + debit_count = 0 + debit = 0.0 + credit_count = 0 + credit = 0.0 + for st_line in st_group['lines']: + if st_line['importe'] < 0: + debit_count += 1 + debit -= st_line['importe'] + else: + credit_count += 1 + credit += st_line['importe'] + if st_group['num_debe'] != debit_count: + raise exceptions.Warning( + _("Number of debit records doesn't match with the defined in " + "the last record of account.")) + if st_group['num_haber'] != credit_count: + raise exceptions.Warning( + _('Error in C43 file'), + _("Number of credit records doesn't match with the defined " + "in the last record of account.")) + if abs(st_group['debe'] - debit) > 0.005: + raise exceptions.Warning( + _('Error in C43 file'), + _("Debit amount doesn't match with the defined in the last " + "record of account.")) + if abs(st_group['haber'] - credit) > 0.005: + raise exceptions.Warning( + _("Credit amount doesn't match with the defined in the last " + "record of account.")) + # Note: Only perform this check if the balance is defined on the file + # record, as some banks may leave it empty (zero) on some circumstances + # (like CaixaNova extracts for VISA credit cards). + if st_group['saldo_fin'] and st_group['saldo_ini']: + balance = st_group['saldo_ini'] + credit - debit + if abs(st_group['saldo_fin'] - balance) > 0.005: + raise exceptions.Warning( + _("Final balance amount = (initial balance + credit " + "- debit) doesn't match with the defined in the last " + "record of account.")) + return st_group + + def _process_record_88(self, st_data, line): + """88 - Registro de fin de archivo""" + st_data['num_registros'] = int(line[20:26]) + # File level checks + # Some banks (like Liderbank) are informing this record number + # including the record 88, so checking this with the absolute + # difference allows to bypass the error + if abs(st_data['num_registros'] - st_data['_num_records']) > 1: + raise exceptions.Warning( + _("Number of records doesn't match with the defined in the " + "last record.")) + return st_data + + def _parse(self, data_file): + # st_data will contain data read from the file + st_data = { + '_num_records': 0, # Number of records really counted + 'groups': [], # Info about each of the groups (account groups) + } + for raw_line in data_file.split("\n"): + if not raw_line: + continue + code = raw_line[0:2] + if code == '11': + st_group = self._process_record_11(raw_line) + st_data['groups'].append(st_group) + elif code == '22': + st_line = self._process_record_22(raw_line) + st_group['lines'].append(st_line) + elif code == '23': + self._process_record_23(st_line, raw_line) + elif code == '24': + self._process_record_24(st_line, raw_line) + elif code == '33': + self._process_record_33(st_group, raw_line) + elif code == '88': + self._process_record_88(st_data, raw_line) + elif ord(raw_line[0]) == 26: + # CTRL-Z (^Z), is often used as an end-of-file marker in DOS + continue + else: + raise exceptions.ValidationError( + _('Record type %s is not valid.') % raw_line[0:2]) + # Update the record counter + st_data['_num_records'] += 1 + return st_data['groups'] + + def _check_n43(self, data_file): + data_file = data_file.decode('iso-8859-1') + try: + n43 = self._parse(data_file) + except exceptions.ValidationError: + return False + return n43 + + def _get_ref(self, line): + try: + ref1 = int(line['referencia1']) + except: + ref1 = line['referencia1'] + try: + ref2 = int(line['referencia2']) + except: + ref2 = line['referencia2'] + if not ref1: + return line['referencia2'] or '/' + elif not ref2: + return line['referencia1'] or '/' + else: + return "%s / %s" % (line['referencia1'], line['referencia2']) + + def _get_partner_from_caixabank(self, conceptos): + partner_obj = self.env['res.partner'] + partners = [] + # Try to match from VAT included in concept complementary record #02 + if conceptos.get('02'): + vat = conceptos['02'][0][:2] + conceptos['02'][0][7:] + if vat: + partners = partner_obj.search([('vat', '=', vat)]) + if not partners: + # Try to match from partner name + if conceptos.get('01'): + name = conceptos['01'][0][4:] + conceptos['01'][1] + if name: + partners = partner_obj.search([('name', 'ilike', name)]) + return partners and partners[0].id or False + + def _get_partner_from_santander(self, conceptos): + partner_obj = self.env['res.partner'] + partners = [] + # Try to match from VAT included in concept complementary record #01 + if conceptos.get('01'): + if conceptos['01'][1]: + vat = conceptos['01'][1] + if vat: + partners = partner_obj.search([('vat', 'ilike', vat)]) + if not partners: + # Try to match from partner name + if conceptos.get('01'): + name = conceptos['01'][0] + if name: + partners = partner_obj.search([('name', 'ilike', name)]) + return partners and partners[0].id or False + + def _get_partner(self, line): + if not line.get('conceptos'): + return False + partner_id = self._get_partner_from_caixabank(line['conceptos']) + if partner_id: + return partner_id + partner_id = self._get_partner_from_santander(line['conceptos']) + return partner_id + + def _get_account(self, line): + accounts = [] + if line['concepto_c']: + accounts = self.env['account.account'].search( + [('code', 'like', + account_concept_mapping[line['concepto_c']])]) + return accounts and accounts[0].id or False + + @api.model + def _parse_file(self, data_file): + n43 = self._check_n43(data_file) + if not n43: + return super(AccountBankStatementImport, self)._parse_file( + data_file) + transactions = [] + for group in n43: + for line in group['lines']: + conceptos = [] + for concept_line in line['conceptos']: + conceptos.extend(x.strip() + for x in line['conceptos'][concept_line] + if x.strip()) + vals_line = { + 'date': fields.Date.to_string(line['fecha_valor']), + 'name': ' '.join(conceptos), + 'ref': self._get_ref(line), + 'amount': line['importe'], + 'partner_id': self._get_partner(line), + } + if not vals_line['name']: + vals_line['name'] = vals_line['ref'] + transactions.append(vals_line) + vals_bank_statement = { + 'transactions': transactions, + 'balance_start': n43 and n43[0]['saldo_ini'] or 0.0, + 'balance_end_real': n43 and n43[-1]['saldo_fin'] or 0.0, + } + return 'EUR', False, [vals_bank_statement] + + @api.model + def _get_hide_journal_field(self): + # Show the journal_id field if not coming from a context where is set + return bool(self.env.context.get('journal_id')) diff --git a/l10n_es_account_statement_import_n43/static/description/icon.png b/l10n_es_account_statement_import_n43/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f027ff45ca22aeca44e5a34850a8faebcfedd8 GIT binary patch literal 7527 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 WMYmt%$o)_hPg_GDR;OkY^M3#X@*!{l literal 0 HcmV?d00001 diff --git a/l10n_es_account_statement_import_n43/static/description/icon_src.svg b/l10n_es_account_statement_import_n43/static/description/icon_src.svg new file mode 100644 index 00000000000..8482c25bf56 --- /dev/null +++ b/l10n_es_account_statement_import_n43/static/description/icon_src.svg @@ -0,0 +1,194 @@ + +image/svg+xml08/12/13 1000.00 Delta PC08/15/13 75.46 Walts Drugs03/03/13 379.00 Epic Technologies03/04/13 20.28 YOUR LOCAL SU03/03/13 421.35 SPRINGFIELD WA03/03/13 379.00 Epic Technologies03/04/13 20.28 YOUR LOCAL SUP08/15/13 75.46 Walts Drugs08/12/13 1000.00 Delta PC03/03/13 421.35 SPRINGFIELD WA03/04/13 20.28 YOUR LOCAL SU03/03/13 379.00 Epic Technologies08/12/13 1000.00 De a PC03/03/13 379.00 E Technologies08/15/13 75.46 Walts Drugs03/04/13 20.28 YOUR LOCAL SU03/03/13 379.00 Epic Technologies08/12/13 1000.00 Delta PC08/15/13 75.46 Walts Drugs + + \ No newline at end of file From dceae928f59b58b94b81db6bedeea1e31542b24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santi=20Arg=C3=BCeso?= Date: Mon, 29 Feb 2016 19:43:13 +0100 Subject: [PATCH 02/65] [IMP] l10n_es_account_bank_statement_import_n43. Importar extractos con monedas distintas de euros segun issue #217 y basado en comentario de @fgarciag2001 --- l10n_es_account_statement_import_n43/README.rst | 3 +++ l10n_es_account_statement_import_n43/__openerp__.py | 2 +- .../models/account_bank_statement_import_n43.py | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/l10n_es_account_statement_import_n43/README.rst b/l10n_es_account_statement_import_n43/README.rst index bed0f745859..be89b60e30a 100644 --- a/l10n_es_account_statement_import_n43/README.rst +++ b/l10n_es_account_statement_import_n43/README.rst @@ -31,6 +31,9 @@ Incidencias conocidas / Hoja de ruta * Reconocimiento de partners para otros bancos distintos del Santander o CaixaBank. +* La moneda se extrae del diario con el cual se va a importar o, en su defecto, + de la compañia, no del extracto norma 43 que se importa, para lo cual sería + necesario usar códigos numéricos según la norma ISO 4217. Credits ======= diff --git a/l10n_es_account_statement_import_n43/__openerp__.py b/l10n_es_account_statement_import_n43/__openerp__.py index 5b9c796090e..12bfc042b5d 100644 --- a/l10n_es_account_statement_import_n43/__openerp__.py +++ b/l10n_es_account_statement_import_n43/__openerp__.py @@ -21,7 +21,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '8.0.4.0.0', + 'version': '8.0.4.0.1', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' 'Serv. Tecnol. Avanzados - Pedro M. Baeza,' diff --git a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py index 6e31485a326..adfc3a1cec4 100644 --- a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py @@ -291,7 +291,10 @@ def _parse_file(self, data_file): 'balance_start': n43 and n43[0]['saldo_ini'] or 0.0, 'balance_end_real': n43 and n43[-1]['saldo_fin'] or 0.0, } - return 'EUR', False, [vals_bank_statement] + str_currency = self.journal_id.currency and \ + self.journal_id.currency.name or \ + self.journal_id.company_id.currency_id.name + return str_currency, False, [vals_bank_statement] @api.model def _get_hide_journal_field(self): From edc60d1a81e06d2357f20415d18a5ed10ae72d13 Mon Sep 17 00:00:00 2001 From: Omar Date: Fri, 8 Apr 2016 11:33:55 +0200 Subject: [PATCH 03/65] =?UTF-8?q?[IMP]=20l10n=5Fes=5Faccount=5Fbank=5Fstat?= =?UTF-8?q?ement=5Fimport=5Fn43:=20Se=20a=C3=B1aden=20dos=20comprobaciones?= =?UTF-8?q?=20extra=20para=20obtener=20el=20partner=20extra=C3=ADdas=20del?= =?UTF-8?q?=20n43=20de=20Bankia=20Y=20Sabadell?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.rst | 1 + .../account_bank_statement_import_n43.py | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/l10n_es_account_statement_import_n43/README.rst b/l10n_es_account_statement_import_n43/README.rst index be89b60e30a..5b7674eb8ea 100644 --- a/l10n_es_account_statement_import_n43/README.rst +++ b/l10n_es_account_statement_import_n43/README.rst @@ -42,6 +42,7 @@ Contributors ------------ * Pedro M. Baeza +* Omar Castiñeira Saavedra Maintainer ---------- diff --git a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py index adfc3a1cec4..dbeeb3a3a62 100644 --- a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py @@ -161,7 +161,7 @@ def _parse(self, data_file): 'groups': [], # Info about each of the groups (account groups) } for raw_line in data_file.split("\n"): - if not raw_line: + if not raw_line.strip(): continue code = raw_line[0:2] if code == '11': @@ -245,6 +245,28 @@ def _get_partner_from_santander(self, conceptos): partners = partner_obj.search([('name', 'ilike', name)]) return partners and partners[0].id or False + def _get_partner_from_bankia(self, conceptos): + partner_obj = self.env['res.partner'] + partners = [] + # Try to match from partner name + if conceptos.get('01'): + vat = conceptos['01'][0][:2] + conceptos['01'][0][7:] + if vat: + partners = partner_obj.search([('vat', '=', vat)]) + + return partners and partners[0].id or False + + def _get_partner_from_sabadell(self, conceptos): + partner_obj = self.env['res.partner'] + partners = [] + # Try to match from partner name + if conceptos.get('01'): + name = conceptos['01'][1] + if name: + partners = partner_obj.search([('name', 'ilike', name)]) + + return partners and partners[0].id or False + def _get_partner(self, line): if not line.get('conceptos'): return False @@ -252,6 +274,12 @@ def _get_partner(self, line): if partner_id: return partner_id partner_id = self._get_partner_from_santander(line['conceptos']) + if partner_id: + return partner_id + partner_id = self._get_partner_from_bankia(line['conceptos']) + if partner_id: + return partner_id + partner_id = self._get_partner_from_sabadell(line['conceptos']) return partner_id def _get_account(self, line): From 1120d5ae35922990a57f8f4906f9f0529a11c8b1 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Tue, 31 May 2016 18:52:57 +0200 Subject: [PATCH 04/65] [FIX] l10n_es_account_bank_statement_import_n43: Populate correctly partner_id --- .../__openerp__.py | 29 ++----- .../account_bank_statement_import_n43.py | 83 +++++++++++-------- 2 files changed, 55 insertions(+), 57 deletions(-) diff --git a/l10n_es_account_statement_import_n43/__openerp__.py b/l10n_es_account_statement_import_n43/__openerp__.py index 12bfc042b5d..e4b07a73eba 100644 --- a/l10n_es_account_statement_import_n43/__openerp__.py +++ b/l10n_es_account_statement_import_n43/__openerp__.py @@ -1,30 +1,15 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# Copyright(c) 2013-2015 Serv. Tecnol. Avanzados (http://serviciosbaeza.com) -# Pedro M. Baeza -# -# 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 . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2013-2015 Serv. Tecnol. Avanzados - Pedro M. Baeza +# © 2016 Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '8.0.4.0.1', + 'version': '8.0.4.0.2', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' - 'Serv. Tecnol. Avanzados - Pedro M. Baeza,' + 'Tecnativa,' 'Antiun Ingenería S.L.,' 'Odoo Community Association (OCA)', "website": "https://github.com/OCA/l10n-spain", diff --git a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py index dbeeb3a3a62..de2027aa282 100644 --- a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py @@ -1,7 +1,8 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# For copyright and license notices, see __openerp__.py file in root directory -############################################################################## +# -*- coding: utf-8 -*- +# © 2013-2015 Serv. Tecnol. Avanzados - Pedro M. Baeza +# © 2016 Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from openerp import models, fields, api, exceptions, _ from datetime import datetime @@ -214,73 +215,72 @@ def _get_ref(self, line): def _get_partner_from_caixabank(self, conceptos): partner_obj = self.env['res.partner'] - partners = [] + partner = partner_obj.browse() # Try to match from VAT included in concept complementary record #02 if conceptos.get('02'): vat = conceptos['02'][0][:2] + conceptos['02'][0][7:] if vat: - partners = partner_obj.search([('vat', '=', vat)]) - if not partners: + partner = partner_obj.search([('vat', '=', vat)], limit=1) + if not partner: # Try to match from partner name if conceptos.get('01'): name = conceptos['01'][0][4:] + conceptos['01'][1] if name: - partners = partner_obj.search([('name', 'ilike', name)]) - return partners and partners[0].id or False + partner = partner_obj.search( + [('name', 'ilike', name)], limit=1) + return partner def _get_partner_from_santander(self, conceptos): partner_obj = self.env['res.partner'] - partners = [] + partner = partner_obj.browse() # Try to match from VAT included in concept complementary record #01 if conceptos.get('01'): if conceptos['01'][1]: vat = conceptos['01'][1] if vat: - partners = partner_obj.search([('vat', 'ilike', vat)]) - if not partners: + partner = partner_obj.search( + [('vat', 'ilike', vat)], limit=1) + if not partner: # Try to match from partner name if conceptos.get('01'): name = conceptos['01'][0] if name: - partners = partner_obj.search([('name', 'ilike', name)]) - return partners and partners[0].id or False + partner = partner_obj.search( + [('name', 'ilike', name)], limit=1) + return partner def _get_partner_from_bankia(self, conceptos): partner_obj = self.env['res.partner'] - partners = [] + partner = partner_obj.browse() # Try to match from partner name if conceptos.get('01'): vat = conceptos['01'][0][:2] + conceptos['01'][0][7:] if vat: - partners = partner_obj.search([('vat', '=', vat)]) - - return partners and partners[0].id or False + partner = partner_obj.search([('vat', '=', vat)], limit=1) + return partner def _get_partner_from_sabadell(self, conceptos): partner_obj = self.env['res.partner'] - partners = [] + partner = partner_obj.browse() # Try to match from partner name if conceptos.get('01'): name = conceptos['01'][1] if name: - partners = partner_obj.search([('name', 'ilike', name)]) - - return partners and partners[0].id or False + partner = partner_obj.search( + [('name', 'ilike', name)], limit=1) + return partner def _get_partner(self, line): if not line.get('conceptos'): - return False - partner_id = self._get_partner_from_caixabank(line['conceptos']) - if partner_id: - return partner_id - partner_id = self._get_partner_from_santander(line['conceptos']) - if partner_id: - return partner_id - partner_id = self._get_partner_from_bankia(line['conceptos']) - if partner_id: - return partner_id - partner_id = self._get_partner_from_sabadell(line['conceptos']) - return partner_id + return self.env['res.partner'] + partner = self._get_partner_from_caixabank(line['conceptos']) + if not partner: + partner = self._get_partner_from_santander(line['conceptos']) + if not partner: + partner = self._get_partner_from_bankia(line['conceptos']) + if not partner: + partner = self._get_partner_from_sabadell(line['conceptos']) + return partner def _get_account(self, line): accounts = [] @@ -309,8 +309,11 @@ def _parse_file(self, data_file): 'name': ' '.join(conceptos), 'ref': self._get_ref(line), 'amount': line['importe'], - 'partner_id': self._get_partner(line), + 'note': line, } + c = line['conceptos'] + if c.get('01'): + vals_line['partner_name'] = c['01'][0] + c['01'][1] if not vals_line['name']: vals_line['name'] = vals_line['ref'] transactions.append(vals_line) @@ -328,3 +331,13 @@ def _parse_file(self, data_file): def _get_hide_journal_field(self): # Show the journal_id field if not coming from a context where is set return bool(self.env.context.get('journal_id')) + + def _complete_statement(self, stmt_vals, journal_id, account_number): + """Match partner_id if if hasn't been deducted yet.""" + res = super(AccountBankStatementImport, self)._complete_statement( + stmt_vals, journal_id, account_number) + for line_vals in res['transactions']: + if not line_vals['partner_id']: + line_vals['partner_id'] = self._get_partner( + line_vals['note']).id + return res From 209273e530e73d65f2b4d85e6207e44f6dc55bbc Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 15 Jun 2016 02:01:59 +0200 Subject: [PATCH 05/65] [IMP] l10n_es_account_bank_statement_import_n43: Tests --- .../tests/__init__.py | 4 +++ .../tests/test.n43 | 9 +++++ ...0n_es_account_bank_statement_import_n43.py | 35 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 l10n_es_account_statement_import_n43/tests/__init__.py create mode 100644 l10n_es_account_statement_import_n43/tests/test.n43 create mode 100644 l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py diff --git a/l10n_es_account_statement_import_n43/tests/__init__.py b/l10n_es_account_statement_import_n43/tests/__init__.py new file mode 100644 index 00000000000..3757c4a28f6 --- /dev/null +++ b/l10n_es_account_statement_import_n43/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_l10n_es_account_bank_statement_import_n43 diff --git a/l10n_es_account_statement_import_n43/tests/test.n43 b/l10n_es_account_statement_import_n43/tests/test.n43 new file mode 100644 index 00000000000..bd3420ed932 --- /dev/null +++ b/l10n_es_account_statement_import_n43/tests/test.n43 @@ -0,0 +1,9 @@ +110000000000000000001602011605312000000000000009783TECNATIVA S.L +22 00001605261605260610010000000000000300000000000000000000005540014210128010 +2301COMISI�N +22 0000160512160512040161000000000178300000000000000975737917 +2301TRANSFERENC. A TEST PARTNER +22 0000160516160516040162000000000280290000000000000000000000 +2301TRANSFERENC. TEST PARTNER 2 +3300000000000000000000002000000000178330000100000000028029000000000010196978 +88999999999999999999000008 diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py new file mode 100644 index 00000000000..53dce9261df --- /dev/null +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# © 2016 Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp.tests import common +from openerp.modules.module import get_module_resource + + +class L10nEsAccountBankStatementImportN43(common.TransactionCase): + def setUp(self): + super(L10nEsAccountBankStatementImportN43, self).setUp() + self.partner = self.env['res.partner'].create({'name': 'Test partner'}) + self.journal = self.env['account.journal'].create({ + 'type': 'bank', + 'name': 'Test N43 bank', + 'code': 'BNKN43', + }) + + def test_import_n43(self): + n43_file_path = get_module_resource( + 'l10n_es_account_bank_statement_import_n43', 'tests', 'test.n43') + n43_file = open(n43_file_path, 'rb').read().encode('base64') + import_wizard = self.env['account.bank.statement.import'].create({ + 'data_file': n43_file, + 'journal_id': self.journal.id, + }) + action = import_wizard.import_file() + self.assertTrue(action) + self.assertTrue(action.get('context').get('statement_ids')) + statement = self.env['account.bank.statement'].browse( + action['context']['statement_ids'][0]) + self.assertEqual(len(statement.line_ids), 3) + self.assertAlmostEqual(statement.balance_start, 0, 2) + self.assertAlmostEqual(statement.balance_end, 101.96, 2) + self.assertEqual(statement.line_ids[1].partner_id, self.partner) From 14d7c7e346fe4fdf186d7a694128cdeea5603cc5 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Tue, 28 Jun 2016 12:44:26 +0200 Subject: [PATCH 06/65] [FIX] l10n_es_account_bank_statement_import_n43: Fix 'conceptos' default value --- .../i18n/en.po | 80 ------------------- .../i18n/es.po | 20 ++--- .../i18n/gl.po | 20 ++--- .../account_bank_statement_import_n43.py | 2 +- 4 files changed, 21 insertions(+), 101 deletions(-) delete mode 100644 l10n_es_account_statement_import_n43/i18n/en.po diff --git a/l10n_es_account_statement_import_n43/i18n/en.po b/l10n_es_account_statement_import_n43/i18n/en.po deleted file mode 100644 index 68c39352cb3..00000000000 --- a/l10n_es_account_statement_import_n43/i18n/en.po +++ /dev/null @@ -1,80 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 -# -# Translators: -msgid "" -msgstr "" -"Project-Id-Version: l10n-spain (8.0)\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-19 01:41+0000\n" -"PO-Revision-Date: 2015-05-23 08:55+0000\n" -"Last-Translator: Pedro M. Baeza \n" -"Language-Team: English (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/en/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: en\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:130 -#, python-format -msgid "" -"Credit amount doesn't match with the defined in the last record of account." -msgstr "Credit amount doesn't match with the defined in the last record of account." - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 -#, python-format -msgid "" -"Debit amount doesn't match with the defined in the last record of account." -msgstr "Debit amount doesn't match with the defined in the last record of account." - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:120 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:125 -#, python-format -msgid "Error in C43 file" -msgstr "Error in C43 file" - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:139 -#, python-format -msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." -msgstr "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." - -#. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import -msgid "Import Bank Statement" -msgstr "Import Bank Statement" - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 -#, python-format -msgid "" -"Number of credit records doesn't match with the defined in the last record " -"of account." -msgstr "Number of credit records doesn't match with the defined in the last record of account." - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:116 -#, python-format -msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." -msgstr "Number of debit records doesn't match with the defined in the last record of account." - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:153 -#, python-format -msgid "Number of records doesn't match with the defined in the last record." -msgstr "Number of records doesn't match with the defined in the last record." - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:186 -#, python-format -msgid "Record type %s is not valid." -msgstr "Record type %s is not valid." diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index 4d38f136d71..78fdf02c819 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: l10n-spain (8.0)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-19 01:41+0000\n" +"POT-Creation-Date: 2016-07-01 00:54+0000\n" "PO-Revision-Date: 2015-06-25 02:26+0000\n" "Last-Translator: Alejandro Santana \n" "Language-Team: Spanish (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/es/)\n" @@ -20,28 +20,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:130 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "El importe del haber no cuadra con el definido en el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "La cantidad del debe no cuadra con la definida en el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:120 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 #, python-format msgid "Error in C43 file" msgstr "Error en el archivo C43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:139 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:140 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with" @@ -54,7 +54,7 @@ msgid "Import Bank Statement" msgstr "Importar extracto bancario" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:122 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -62,7 +62,7 @@ msgid "" msgstr "El número de registros del haber no cuadra con lo definido en el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:116 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:117 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of" @@ -70,13 +70,13 @@ msgid "" msgstr "El número de registros del debe no cuadra con lo definido en el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:153 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:154 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "El número de registros no cuadra con lo definido en el último registro." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:186 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:187 #, python-format msgid "Record type %s is not valid." msgstr "El tipo de registro %s no es válido." diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index 527070c10d1..6410804120f 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: l10n-spain (8.0)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-19 01:41+0000\n" +"POT-Creation-Date: 2016-07-01 00:54+0000\n" "PO-Revision-Date: 2015-06-25 23:30+0000\n" "Last-Translator: Alejandro Santana \n" "Language-Team: Galician (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/gl/)\n" @@ -19,28 +19,28 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:130 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "O importe do haber non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "O importe do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:120 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 #, python-format msgid "Error in C43 file" msgstr "Erro no arquivo C43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:139 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:140 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with" @@ -53,7 +53,7 @@ msgid "Import Bank Statement" msgstr "Importar extracto bancario" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:122 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -61,7 +61,7 @@ msgid "" msgstr "O número de rexistros do haber non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:116 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:117 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of" @@ -69,13 +69,13 @@ msgid "" msgstr "O número de rexistros do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:153 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:154 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "O número de rexistros non cadra co definido no último rexistro." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:186 +#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:187 #, python-format msgid "Record type %s is not valid." msgstr "O tipo de rexistro %s non é válido." diff --git a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py index de2027aa282..fbb75366203 100644 --- a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py @@ -68,7 +68,7 @@ def _process_record_22(self, line): 'num_documento': line[41:52], 'referencia1': line[52:64].strip(), 'referencia2': line[64:].strip(), - 'conceptos': '', + 'conceptos': {}, } if line[27:28] == '1': st_line['importe'] *= -1 From e2a960bf25fa992b5ace480f5e038c060760ac6d Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Fri, 4 Nov 2016 14:56:52 +0100 Subject: [PATCH 07/65] [FIX] l10n_es_account_bank_statement_import_n43: Avoid error when having other statement formats --- .../models/account_bank_statement_import_n43.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py index fbb75366203..9e10253737b 100644 --- a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py @@ -337,7 +337,7 @@ def _complete_statement(self, stmt_vals, journal_id, account_number): res = super(AccountBankStatementImport, self)._complete_statement( stmt_vals, journal_id, account_number) for line_vals in res['transactions']: - if not line_vals['partner_id']: + if not line_vals['partner_id'] and line_vals.get('note'): line_vals['partner_id'] = self._get_partner( line_vals['note']).id return res From e6ac6ee1919309f2861fe8df6ba5eab8475e100a Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Tue, 31 May 2016 19:47:19 +0200 Subject: [PATCH 08/65] [MIG] l10n_es_account_bank_statement_import_n43: Migration to 9.0 Improvements ------------ * Counterpart account automatically detected from N43 type (deactivated for now) * Tests --- .../README.rst | 65 ++++++++----- .../__init__.py | 9 +- .../{__openerp__.py => __manifest__.py} | 7 +- .../i18n/es.po | 73 ++++++-------- .../models/__init__.py | 5 - ...0n_es_account_bank_statement_import_n43.py | 5 +- .../wizards/__init__.py | 4 + .../account_bank_statement_import_n43.py | 97 +++++++++---------- .../account_bank_statement_import_view.xml | 12 +++ 9 files changed, 145 insertions(+), 132 deletions(-) rename l10n_es_account_statement_import_n43/{__openerp__.py => __manifest__.py} (84%) delete mode 100644 l10n_es_account_statement_import_n43/models/__init__.py create mode 100644 l10n_es_account_statement_import_n43/wizards/__init__.py rename l10n_es_account_statement_import_n43/{models => wizards}/account_bank_statement_import_n43.py (82%) create mode 100644 l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_view.xml diff --git a/l10n_es_account_statement_import_n43/README.rst b/l10n_es_account_statement_import_n43/README.rst index 5b7674eb8ea..fe2d83a80f2 100644 --- a/l10n_es_account_statement_import_n43/README.rst +++ b/l10n_es_account_statement_import_n43/README.rst @@ -7,49 +7,66 @@ especificación del formato aquí_. .. _aquí: http://goo.gl/2zzlmu -Instalación -=========== - -Para instalar este módulo, es necesario tener disponible el módulo -*account_bank_statement_import* del repositorio -https://github.com/OCA/bank-statement-import - -Configuración -============= - -No es necesaria ninguna configuración especial. - Uso === -Vaya a Contabilidad > Extractos bancarios > Importar extracto bancario, -seleccione el archivo Norma 43 a importar, el diario en el que registrarlo, -y pulse en 'Importar'. +#. Vaya a Contabilidad (Facturación) > Tablero, y escoja "Importar extracto" en + el cuadro que corresponda con el diario de su banco. +#. Seleccione el archivo Norma 43 a importar. +#. Pulse en 'Importar'. +#. Aparecerá el asistente para conciliación inmediatamente después. Incidencias conocidas / Hoja de ruta ==================================== -* Reconocimiento de partners para otros bancos distintos del Santander o - CaixaBank. +* Reconocimiento de partners para otros bancos distintos del Santander, + CaixaBank, Bankia o Sabadell. * La moneda se extrae del diario con el cual se va a importar o, en su defecto, de la compañia, no del extracto norma 43 que se importa, para lo cual sería necesario usar códigos numéricos según la norma ISO 4217. +* Los códigos de operación N43 no se utilizan para asociar una cuenta contable + genérica, ya que Odoo no lo permite. -Credits -======= - -Contributors ------------- +Créditos +======== +Contribuidores +-------------- * Pedro M. Baeza * Omar Castiñeira Saavedra +Financiadores +------------- +La migración de este módulo forma parte de una campaña de migración de la +localización española que ha sido posible gracias a la colaboración económica +de las siguientes empresas (por orden alfabético): + +* `Aizean evolution `_ +* `Aselcis consulting `_ +* `AvanzOSC `_ +* `Diagram software `_ +* `Domatix `_ +* `Eficent `_ +* `FactorLibre `_ +* `Fairhall solutions `_ +* `GAFIC SLP `_ +* `Incaser `_ +* `Ingeos `_ +* `Nubistalia `_ +* `Punt sistemes `_ +* `Praxya `_ +* `Reeng `_ +* `Soluntec `_ +* `Tecnativa `_ +* `Trey `_ +* `Vicent Cubells `_ + Maintainer ---------- .. image:: http://odoo-community.org/logo.png :alt: Odoo Community Association - :target: http://odoo-community.org + :target: https://odoo-community.org This module is maintained by the OCA. @@ -57,4 +74,4 @@ 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. +To contribute to this module, please visit https://odoo-community.org. diff --git a/l10n_es_account_statement_import_n43/__init__.py b/l10n_es_account_statement_import_n43/__init__.py index 49d04adebde..0796ed1dec6 100644 --- a/l10n_es_account_statement_import_n43/__init__.py +++ b/l10n_es_account_statement_import_n43/__init__.py @@ -1,5 +1,4 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# For copyright and license notices, see __openerp__.py file in root directory -############################################################################## -from . import models +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import wizards diff --git a/l10n_es_account_statement_import_n43/__openerp__.py b/l10n_es_account_statement_import_n43/__manifest__.py similarity index 84% rename from l10n_es_account_statement_import_n43/__openerp__.py rename to l10n_es_account_statement_import_n43/__manifest__.py index e4b07a73eba..ae2f3f271a2 100644 --- a/l10n_es_account_statement_import_n43/__openerp__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -6,16 +6,17 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '8.0.4.0.2', + 'version': '9.0.1.0.0', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' 'Tecnativa,' - 'Antiun Ingenería S.L.,' 'Odoo Community Association (OCA)', "website": "https://github.com/OCA/l10n-spain", 'depends': [ 'account_bank_statement_import', ], - 'data': [], + 'data': [ + 'wizards/account_bank_statement_import_view.xml', + ], 'installable': True, } diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index 78fdf02c819..8f29fd666a9 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -1,52 +1,42 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 -# -# Translators: -# Alejandro Santana , 2015 -# Pedro M. Baeza , 2015 +# * l10n_es_account_bank_statement_import_n43 +# msgid "" msgstr "" -"Project-Id-Version: l10n-spain (8.0)\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-07-01 00:54+0000\n" -"PO-Revision-Date: 2015-06-25 02:26+0000\n" -"Last-Translator: Alejandro Santana \n" -"Language-Team: Spanish (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/es/)\n" +"POT-Creation-Date: 2016-12-06 12:14+0000\n" +"PO-Revision-Date: 2016-12-06 12:14+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" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: \n" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:131 -#, python-format -msgid "" -"Credit amount doesn't match with the defined in the last record of account." -msgstr "El importe del haber no cuadra con el definido en el último registro de la cuenta." +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +msgid "AEB norm 43 (.n43)" +msgstr "AEB norma 43 (.n43)" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:127 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:181 #, python-format -msgid "" -"Debit amount doesn't match with the defined in the last record of account." -msgstr "La cantidad del debe no cuadra con la definida en el último registro de la cuenta." +msgid "Credit amount doesn't match with the defined in the last record of account." +msgstr "El importe del haber no csa con lo definido en el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:177 #, python-format -msgid "Error in C43 file" -msgstr "Error en el archivo C43" +msgid "Debit amount doesn't match with the defined in the last record of account." +msgstr "El importe del debe no casa con lo definido en el último registor de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:140 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:190 #, python-format -msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." -msgstr "El importe final del saldo = (saldo inicial + haber - debe) no cuadra con el definido en el último registro de la cuenta." +msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgstr "El saldo final = (saldo inicial + haber - debe) no casa con lo definido en el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import @@ -54,29 +44,26 @@ msgid "Import Bank Statement" msgstr "Importar extracto bancario" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:122 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:173 #, python-format -msgid "" -"Number of credit records doesn't match with the defined in the last record " -"of account." -msgstr "El número de registros del haber no cuadra con lo definido en el último registro de la cuenta." +msgid "Number of credit records doesn't match with the defined in the last record of account." +msgstr "El número de registro del haber no casa con lo definido en el último regisro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:169 #, python-format -msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." -msgstr "El número de registros del debe no cuadra con lo definido en el último registro de la cuenta." +msgid "Number of debit records doesn't match with the defined in the last record of account." +msgstr "El número de registro del debe no casa con lo definido en el último regisro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:154 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:204 #, python-format msgid "Number of records doesn't match with the defined in the last record." -msgstr "El número de registros no cuadra con lo definido en el último registro." +msgstr "El número de registro no casa con lo definido en el último regisro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:187 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:237 #, python-format msgid "Record type %s is not valid." msgstr "El tipo de registro %s no es válido." + diff --git a/l10n_es_account_statement_import_n43/models/__init__.py b/l10n_es_account_statement_import_n43/models/__init__.py deleted file mode 100644 index 9130d3fbc80..00000000000 --- a/l10n_es_account_statement_import_n43/models/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# For copyright and license notices, see __openerp__.py file in root directory -############################################################################## -from . import account_bank_statement_import_n43 diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py index 53dce9261df..ecbabb07872 100644 --- a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -22,9 +22,10 @@ def test_import_n43(self): n43_file = open(n43_file_path, 'rb').read().encode('base64') import_wizard = self.env['account.bank.statement.import'].create({ 'data_file': n43_file, - 'journal_id': self.journal.id, }) - action = import_wizard.import_file() + action = import_wizard.with_context( + journal_id=self.journal.id, + ).import_file() self.assertTrue(action) self.assertTrue(action.get('context').get('statement_ids')) statement = self.env['account.bank.statement'].browse( diff --git a/l10n_es_account_statement_import_n43/wizards/__init__.py b/l10n_es_account_statement_import_n43/wizards/__init__.py new file mode 100644 index 00000000000..6da5ac01574 --- /dev/null +++ b/l10n_es_account_statement_import_n43/wizards/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import account_bank_statement_import_n43 diff --git a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py similarity index 82% rename from l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py rename to l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index 9e10253737b..a2285a9dd5e 100644 --- a/l10n_es_account_statement_import_n43/models/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -6,13 +6,13 @@ from openerp import models, fields, api, exceptions, _ from datetime import datetime -account_concept_mapping = { +account_mapping = { '01': '4300%00', '02': '4100%00', '03': '4100%00', - '04': '4300%00', + '04': '430%00', '05': '6800%00', - '06': '4010%00', + '06': '6260%00', '07': '5700%00', '08': '6800%00', '09': '2510%00', @@ -77,10 +77,8 @@ def _process_record_22(self, line): def _process_record_23(self, st_line, line): """23 - Registros complementarios de concepto (opcionales y hasta un máximo de 5)""" - if not st_line.get('conceptos'): - st_line['conceptos'] = {} - st_line['conceptos'][line[2:4]] = (line[4:39].strip(), - line[39:].strip()) + conceptos = st_line.setdefault('conceptos', {}) + conceptos[line[2:4]] = (line[4:39].strip(), line[39:].strip()) return st_line def _process_record_24(self, st_line, line): @@ -112,31 +110,29 @@ def _process_record_33(self, st_group, line): else: credit_count += 1 credit += st_line['importe'] - if st_group['num_debe'] != debit_count: - raise exceptions.Warning( + if st_group['num_debe'] != debit_count: # pragma: no cover + raise exceptions.UserError( _("Number of debit records doesn't match with the defined in " "the last record of account.")) - if st_group['num_haber'] != credit_count: - raise exceptions.Warning( - _('Error in C43 file'), + if st_group['num_haber'] != credit_count: # pragma: no cover + raise exceptions.UserError( _("Number of credit records doesn't match with the defined " "in the last record of account.")) - if abs(st_group['debe'] - debit) > 0.005: - raise exceptions.Warning( - _('Error in C43 file'), + if abs(st_group['debe'] - debit) > 0.005: # pragma: no cover + raise exceptions.UserError( _("Debit amount doesn't match with the defined in the last " "record of account.")) - if abs(st_group['haber'] - credit) > 0.005: - raise exceptions.Warning( + if abs(st_group['haber'] - credit) > 0.005: # pragma: no cover + raise exceptions.UserError( _("Credit amount doesn't match with the defined in the last " "record of account.")) # Note: Only perform this check if the balance is defined on the file # record, as some banks may leave it empty (zero) on some circumstances # (like CaixaNova extracts for VISA credit cards). - if st_group['saldo_fin'] and st_group['saldo_ini']: + if st_group['saldo_fin'] and st_group['saldo_ini']: # pragma: no cover balance = st_group['saldo_ini'] + credit - debit if abs(st_group['saldo_fin'] - balance) > 0.005: - raise exceptions.Warning( + raise exceptions.UserError( _("Final balance amount = (initial balance + credit " "- debit) doesn't match with the defined in the last " "record of account.")) @@ -149,8 +145,9 @@ def _process_record_88(self, st_data, line): # Some banks (like Liderbank) are informing this record number # including the record 88, so checking this with the absolute # difference allows to bypass the error - if abs(st_data['num_registros'] - st_data['_num_records']) > 1: - raise exceptions.Warning( + if (abs(st_data['num_registros'] - + st_data['_num_records']) > 1): # pragma: no cover + raise exceptions.UserError( _("Number of records doesn't match with the defined in the " "last record.")) return st_data @@ -179,11 +176,11 @@ def _parse(self, data_file): self._process_record_33(st_group, raw_line) elif code == '88': self._process_record_88(st_data, raw_line) - elif ord(raw_line[0]) == 26: + elif ord(raw_line[0]) == 26: # pragma: no cover # CTRL-Z (^Z), is often used as an end-of-file marker in DOS continue - else: - raise exceptions.ValidationError( + else: # pragma: no cover + raise exceptions.UserError( _('Record type %s is not valid.') % raw_line[0:2]) # Update the record counter st_data['_num_records'] += 1 @@ -282,13 +279,14 @@ def _get_partner(self, line): partner = self._get_partner_from_sabadell(line['conceptos']) return partner - def _get_account(self, line): - accounts = [] - if line['concepto_c']: - accounts = self.env['account.account'].search( - [('code', 'like', - account_concept_mapping[line['concepto_c']])]) - return accounts and accounts[0].id or False + def _get_account(self, line, journal): # pragma: no cover + account_obj = self.env['account.account'] + if line['concepto_c'] and account_mapping.get(line['concepto_c']): + return account_obj.search([ + ('code', 'like', account_mapping[line['concepto_c']]), + ('company_id', '=', journal.company_id.id) + ], limit=1) + return account_obj.browse() @api.model def _parse_file(self, data_file): @@ -301,9 +299,9 @@ def _parse_file(self, data_file): for line in group['lines']: conceptos = [] for concept_line in line['conceptos']: - conceptos.extend(x.strip() - for x in line['conceptos'][concept_line] - if x.strip()) + conceptos.extend( + x.strip() for x in line['conceptos'][concept_line] + if x.strip()) vals_line = { 'date': fields.Date.to_string(line['fecha_valor']), 'name': ' '.join(conceptos), @@ -322,22 +320,21 @@ def _parse_file(self, data_file): 'balance_start': n43 and n43[0]['saldo_ini'] or 0.0, 'balance_end_real': n43 and n43[-1]['saldo_fin'] or 0.0, } - str_currency = self.journal_id.currency and \ - self.journal_id.currency.name or \ - self.journal_id.company_id.currency_id.name - return str_currency, False, [vals_bank_statement] - - @api.model - def _get_hide_journal_field(self): - # Show the journal_id field if not coming from a context where is set - return bool(self.env.context.get('journal_id')) + return None, None, [vals_bank_statement] - def _complete_statement(self, stmt_vals, journal_id, account_number): + def _complete_stmts_vals(self, stmts_vals, journal, account_number): """Match partner_id if if hasn't been deducted yet.""" - res = super(AccountBankStatementImport, self)._complete_statement( - stmt_vals, journal_id, account_number) - for line_vals in res['transactions']: - if not line_vals['partner_id'] and line_vals.get('note'): - line_vals['partner_id'] = self._get_partner( - line_vals['note']).id + res = super(AccountBankStatementImport, self)._complete_stmts_vals( + stmts_vals, journal, account_number) + for st_vals in res: + for line_vals in st_vals['transactions']: + if not line_vals.get('partner_id') and line_vals.get('note'): + line_vals['partner_id'] = self._get_partner( + line_vals['note'], + ).id + # This can't be used, as Odoo doesn't present the lines + # that already have a counterpart account as final + # verification, making this very counterintuitive to the user + # line_vals['account_id'] = self._get_account( + # line_vals['raw_data'], journal).id return res diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_view.xml b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_view.xml new file mode 100644 index 00000000000..93e9c903b7c --- /dev/null +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_view.xml @@ -0,0 +1,12 @@ + + + + account.bank.statement.import + + + +
  • AEB norm 43 (.n43)
  • +
    +
    +
    +
    From cced91254e546c849d931c5ac89f7e1d3344b238 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Tue, 6 Dec 2016 16:24:07 +0100 Subject: [PATCH 09/65] [MIG] l10n_es_account_bank_statement_import_n43: Migration to 10.0 --- .../__manifest__.py | 2 +- .../i18n/es.po | 76 ++++++++++++------- .../i18n/gl.po | 50 ++++++------ ...0n_es_account_bank_statement_import_n43.py | 4 +- .../account_bank_statement_import_n43.py | 2 +- 5 files changed, 80 insertions(+), 54 deletions(-) diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index ae2f3f271a2..b68562bc5de 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -6,7 +6,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '9.0.1.0.0', + 'version': '10.0.1.0.0', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' 'Tecnativa,' diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index 8f29fd666a9..b5dc38f78e6 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -1,19 +1,22 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 -# +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +# OCA Transbot , 2017 msgid "" msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" +"Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-12-06 12:14+0000\n" -"PO-Revision-Date: 2016-12-06 12:14+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" +"POT-Creation-Date: 2017-03-18 01:59+0000\n" +"PO-Revision-Date: 2017-03-18 01:59+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view @@ -21,22 +24,32 @@ msgid "AEB norm 43 (.n43)" msgstr "AEB norma 43 (.n43)" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:181 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format -msgid "Credit amount doesn't match with the defined in the last record of account." -msgstr "El importe del haber no csa con lo definido en el último registro de la cuenta." +msgid "" +"Credit amount doesn't match with the defined in the last record of account." +msgstr "" +"El importe del haber no csa con lo definido en el último registro de la " +"cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:177 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format -msgid "Debit amount doesn't match with the defined in the last record of account." -msgstr "El importe del debe no casa con lo definido en el último registor de la cuenta." +msgid "" +"Debit amount doesn't match with the defined in the last record of account." +msgstr "" +"El importe del debe no casa con lo definido en el último registor de la " +"cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:190 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 #, python-format -msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." -msgstr "El saldo final = (saldo inicial + haber - debe) no casa con lo definido en el último registro de la cuenta." +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "" +"El saldo final = (saldo inicial + haber - debe) no casa con lo definido en " +"el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import @@ -44,26 +57,35 @@ msgid "Import Bank Statement" msgstr "Importar extracto bancario" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:173 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 #, python-format -msgid "Number of credit records doesn't match with the defined in the last record of account." -msgstr "El número de registro del haber no casa con lo definido en el último regisro de la cuenta." +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "" +"El número de registro del haber no casa con lo definido en el último regisro" +" de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:169 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 #, python-format -msgid "Number of debit records doesn't match with the defined in the last record of account." -msgstr "El número de registro del debe no casa con lo definido en el último regisro de la cuenta." +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "" +"El número de registro del debe no casa con lo definido en el último regisro " +"de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:204 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 #, python-format msgid "Number of records doesn't match with the defined in the last record." -msgstr "El número de registro no casa con lo definido en el último regisro de la cuenta." +msgstr "" +"El número de registro no casa con lo definido en el último regisro de la " +"cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:237 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 #, python-format msgid "Record type %s is not valid." msgstr "El tipo de registro %s no es válido." - diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index 6410804120f..76191188ba2 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -3,15 +3,15 @@ # * l10n_es_account_bank_statement_import_n43 # # Translators: -# Alejandro Santana , 2015 +# OCA Transbot , 2017 msgid "" msgstr "" -"Project-Id-Version: l10n-spain (8.0)\n" +"Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-07-01 00:54+0000\n" -"PO-Revision-Date: 2015-06-25 23:30+0000\n" -"Last-Translator: Alejandro Santana \n" -"Language-Team: Galician (http://www.transifex.com/oca/OCA-l10n-spain-8-0/language/gl/)\n" +"POT-Creation-Date: 2017-03-18 01:59+0000\n" +"PO-Revision-Date: 2017-03-18 01:59+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" @@ -19,33 +19,33 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:131 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +msgid "AEB norm 43 (.n43)" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "O importe do haber non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:127 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "O importe do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:121 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:126 -#, python-format -msgid "Error in C43 file" -msgstr "Erro no arquivo C43" - -#. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:140 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with" " the defined in the last record of account." -msgstr "O importe final do saldo = (saldo inicial + haber - debe) non cadra co definido no último rexistro da conta." +msgstr "" +"O importe final do saldo = (saldo inicial + haber - debe) non cadra co " +"definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import @@ -53,29 +53,33 @@ msgid "Import Bank Statement" msgstr "Importar extracto bancario" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:122 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." -msgstr "O número de rexistros do haber non cadra co definido no último rexistro da conta." +msgstr "" +"O número de rexistros do haber non cadra co definido no último rexistro da " +"conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of" " account." -msgstr "O número de rexistros do debe non cadra co definido no último rexistro da conta." +msgstr "" +"O número de rexistros do debe non cadra co definido no último rexistro da " +"conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:154 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "O número de rexistros non cadra co definido no último rexistro." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/models/account_bank_statement_import_n43.py:187 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 #, python-format msgid "Record type %s is not valid." msgstr "O tipo de rexistro %s non é válido." diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py index ecbabb07872..1f8c24d4196 100644 --- a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -2,8 +2,8 @@ # © 2016 Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from openerp.tests import common -from openerp.modules.module import get_module_resource +from odoo.tests import common +from odoo.modules.module import get_module_resource class L10nEsAccountBankStatementImportN43(common.TransactionCase): diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index a2285a9dd5e..045442353ab 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -3,7 +3,7 @@ # © 2016 Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from openerp import models, fields, api, exceptions, _ +from odoo import models, fields, api, exceptions, _ from datetime import datetime account_mapping = { From 4fb5e616eb9043cc433778d9ac0c99e7fb993028 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Thu, 13 Apr 2017 19:19:43 +0200 Subject: [PATCH 10/65] [IMP] l10n_es_account_bank_statement_import_n43: Allow to select between 'fecha_valor' and 'fecha_oper'. --- .../__init__.py | 1 + .../__manifest__.py | 3 +- .../i18n/ca.po | 94 ++++++++++++++++ .../i18n/es.po | 85 +++++++------- .../i18n/eu.po | 104 ++++++++++++++++++ .../i18n/gl.po | 73 ++++++------ .../i18n/sl.po | 94 ++++++++++++++++ .../models/__init__.py | 4 + .../models/account_journal.py | 15 +++ .../tests/test.n43 | 2 +- ...0n_es_account_bank_statement_import_n43.py | 37 +++++-- .../views/account_journal_views.xml | 16 +++ .../account_bank_statement_import_n43.py | 5 +- 13 files changed, 446 insertions(+), 87 deletions(-) create mode 100644 l10n_es_account_statement_import_n43/i18n/ca.po create mode 100644 l10n_es_account_statement_import_n43/i18n/eu.po create mode 100644 l10n_es_account_statement_import_n43/i18n/sl.po create mode 100644 l10n_es_account_statement_import_n43/models/__init__.py create mode 100644 l10n_es_account_statement_import_n43/models/account_journal.py create mode 100644 l10n_es_account_statement_import_n43/views/account_journal_views.xml diff --git a/l10n_es_account_statement_import_n43/__init__.py b/l10n_es_account_statement_import_n43/__init__.py index 0796ed1dec6..84830dc8eed 100644 --- a/l10n_es_account_statement_import_n43/__init__.py +++ b/l10n_es_account_statement_import_n43/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from . import models from . import wizards diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index b68562bc5de..08d762b9085 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -6,7 +6,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '10.0.1.0.0', + 'version': '10.0.1.1.0', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' 'Tecnativa,' @@ -16,6 +16,7 @@ 'account_bank_statement_import', ], 'data': [ + 'views/account_journal_views.xml', 'wizards/account_bank_statement_import_view.xml', ], 'installable': True, diff --git a/l10n_es_account_statement_import_n43/i18n/ca.po b/l10n_es_account_statement_import_n43/i18n/ca.po new file mode 100644 index 00000000000..e4b3dac6ea5 --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/ca.po @@ -0,0 +1,94 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-29 15:03+0000\n" +"PO-Revision-Date: 2017-06-29 15:03+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: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +msgid "AEB norm 43 (.n43)" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#, python-format +msgid "Credit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +msgid "Date type for N43 Import" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#, python-format +msgid "Debit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#, python-format +msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_journal +msgid "Journal" +msgstr "Diari" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +msgid "Norm 43 options" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#, python-format +msgid "Number of credit records doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#, python-format +msgid "Number of debit records doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Operation Date" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#, python-format +msgid "Record type %s is not valid." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Value Date" +msgstr "" + diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index b5dc38f78e6..eccf7234845 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -1,22 +1,19 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 -# -# Translators: -# OCA Transbot , 2017 +# * l10n_es_account_bank_statement_import_n43 +# msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-18 01:59+0000\n" -"PO-Revision-Date: 2017-03-18 01:59+0000\n" -"Last-Translator: OCA Transbot , 2017\n" -"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"POT-Creation-Date: 2017-04-13 17:27+0000\n" +"PO-Revision-Date: 2017-04-13 17:27+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" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: \n" #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view @@ -26,66 +23,72 @@ msgstr "AEB norma 43 (.n43)" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format -msgid "" -"Credit amount doesn't match with the defined in the last record of account." -msgstr "" -"El importe del haber no csa con lo definido en el último registro de la " -"cuenta." +msgid "Credit amount doesn't match with the defined in the last record of account." +msgstr "El importe del haber no csa con lo definido en el último registro de la cuenta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +msgid "Date type for N43 Import" +msgstr "Tipo de fecha para importación N43" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format -msgid "" -"Debit amount doesn't match with the defined in the last record of account." -msgstr "" -"El importe del debe no casa con lo definido en el último registor de la " -"cuenta." +msgid "Debit amount doesn't match with the defined in the last record of account." +msgstr "El importe del debe no casa con lo definido en el último registor de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 #, python-format -msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." -msgstr "" -"El saldo final = (saldo inicial + haber - debe) no casa con lo definido en " -"el último registro de la cuenta." +msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgstr "El saldo final = (saldo inicial + haber - debe) no casa con lo definido en el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import msgid "Import Bank Statement" msgstr "Importar extracto bancario" +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_journal +msgid "Journal" +msgstr "Diario" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +msgid "Norm 43 options" +msgstr "Opciones de Norma 43" + #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 #, python-format -msgid "" -"Number of credit records doesn't match with the defined in the last record " -"of account." -msgstr "" -"El número de registro del haber no casa con lo definido en el último regisro" -" de la cuenta." +msgid "Number of credit records doesn't match with the defined in the last record of account." +msgstr "El número de registro del haber no casa con lo definido en el último regisro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 #, python-format -msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." -msgstr "" -"El número de registro del debe no casa con lo definido en el último regisro " -"de la cuenta." +msgid "Number of debit records doesn't match with the defined in the last record of account." +msgstr "El número de registro del debe no casa con lo definido en el último regisro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 #, python-format msgid "Number of records doesn't match with the defined in the last record." -msgstr "" -"El número de registro no casa con lo definido en el último regisro de la " -"cuenta." +msgstr "El número de registro no casa con lo definido en el último regisro de la cuenta." + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Operation Date" +msgstr "Fecha de operación" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 #, python-format msgid "Record type %s is not valid." msgstr "El tipo de registro %s no es válido." + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Value Date" +msgstr "Fecha valor" + diff --git a/l10n_es_account_statement_import_n43/i18n/eu.po b/l10n_es_account_statement_import_n43/i18n/eu.po new file mode 100644 index 00000000000..837c966b3f9 --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/eu.po @@ -0,0 +1,104 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-29 22:48+0000\n" +"PO-Revision-Date: 2017-06-29 22:48+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Basque (https://www.transifex.com/oca/teams/23907/eu/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: eu\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +msgid "AEB norm 43 (.n43)" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#, python-format +msgid "" +"Credit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +msgid "Date type for N43 Import" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#, python-format +msgid "" +"Debit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#, python-format +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_journal +msgid "Journal" +msgstr "Diario" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +msgid "Norm 43 options" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#, python-format +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#, python-format +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Operation Date" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#, python-format +msgid "Record type %s is not valid." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Value Date" +msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index 76191188ba2..ec3e139ba09 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -1,22 +1,19 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 -# -# Translators: -# OCA Transbot , 2017 +# * l10n_es_account_bank_statement_import_n43 +# msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-18 01:59+0000\n" -"PO-Revision-Date: 2017-03-18 01:59+0000\n" -"Last-Translator: OCA Transbot , 2017\n" -"Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" +"POT-Creation-Date: 2017-06-29 15:03+0000\n" +"PO-Revision-Date: 2017-06-29 15:03+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" -"Language: gl\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: \n" #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view @@ -26,51 +23,52 @@ msgstr "" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format -msgid "" -"Credit amount doesn't match with the defined in the last record of account." +msgid "Credit amount doesn't match with the defined in the last record of account." msgstr "O importe do haber non cadra co definido no último rexistro da conta." +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +msgid "Date type for N43 Import" +msgstr "" + #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format -msgid "" -"Debit amount doesn't match with the defined in the last record of account." +msgid "Debit amount doesn't match with the defined in the last record of account." msgstr "O importe do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 #, python-format -msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." -msgstr "" -"O importe final do saldo = (saldo inicial + haber - debe) non cadra co " -"definido no último rexistro da conta." +msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgstr "O importe final do saldo = (saldo inicial + haber - debe) non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import msgid "Import Bank Statement" msgstr "Importar extracto bancario" +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_journal +msgid "Journal" +msgstr "Diario" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +msgid "Norm 43 options" +msgstr "" + #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 #, python-format -msgid "" -"Number of credit records doesn't match with the defined in the last record " -"of account." -msgstr "" -"O número de rexistros do haber non cadra co definido no último rexistro da " -"conta." +msgid "Number of credit records doesn't match with the defined in the last record of account." +msgstr "O número de rexistros do haber non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 #, python-format -msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." -msgstr "" -"O número de rexistros do debe non cadra co definido no último rexistro da " -"conta." +msgid "Number of debit records doesn't match with the defined in the last record of account." +msgstr "O número de rexistros do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 @@ -78,8 +76,19 @@ msgstr "" msgid "Number of records doesn't match with the defined in the last record." msgstr "O número de rexistros non cadra co definido no último rexistro." +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Operation Date" +msgstr "" + #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 #, python-format msgid "Record type %s is not valid." msgstr "O tipo de rexistro %s non é válido." + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Value Date" +msgstr "" + diff --git a/l10n_es_account_statement_import_n43/i18n/sl.po b/l10n_es_account_statement_import_n43/i18n/sl.po new file mode 100644 index 00000000000..9eec24874d8 --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/sl.po @@ -0,0 +1,94 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-29 15:03+0000\n" +"PO-Revision-Date: 2017-06-29 15:03+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: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +msgid "AEB norm 43 (.n43)" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#, python-format +msgid "Credit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +msgid "Date type for N43 Import" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#, python-format +msgid "Debit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#, python-format +msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_journal +msgid "Journal" +msgstr "Dnevnik" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +msgid "Norm 43 options" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#, python-format +msgid "Number of credit records doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#, python-format +msgid "Number of debit records doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Operation Date" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#, python-format +msgid "Record type %s is not valid." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Value Date" +msgstr "" + diff --git a/l10n_es_account_statement_import_n43/models/__init__.py b/l10n_es_account_statement_import_n43/models/__init__.py new file mode 100644 index 00000000000..ba9ebfba7a6 --- /dev/null +++ b/l10n_es_account_statement_import_n43/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import account_journal diff --git a/l10n_es_account_statement_import_n43/models/account_journal.py b/l10n_es_account_statement_import_n43/models/account_journal.py new file mode 100644 index 00000000000..8e827baa6c3 --- /dev/null +++ b/l10n_es_account_statement_import_n43/models/account_journal.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import fields, models + + +class AccountJournal(models.Model): + _inherit = "account.journal" + + n43_date_type = fields.Selection( + string='Date type for N43 Import', + selection=[('fecha_valor', 'Value Date'), + ('fecha_oper', 'Operation Date')], + required=True, default='fecha_valor', + ) diff --git a/l10n_es_account_statement_import_n43/tests/test.n43 b/l10n_es_account_statement_import_n43/tests/test.n43 index bd3420ed932..74d52ff501a 100644 --- a/l10n_es_account_statement_import_n43/tests/test.n43 +++ b/l10n_es_account_statement_import_n43/tests/test.n43 @@ -1,5 +1,5 @@ 110000000000000000001602011605312000000000000009783TECNATIVA S.L -22 00001605261605260610010000000000000300000000000000000000005540014210128010 +22 00001605261605250610010000000000000300000000000000000000005540014210128010 2301COMISI�N 22 0000160512160512040161000000000178300000000000000975737917 2301TRANSFERENC. A TEST PARTNER diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py index 1f8c24d4196..f0a5566bb3a 100644 --- a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -1,36 +1,51 @@ # -*- coding: utf-8 -*- -# © 2016 Pedro M. Baeza +# Copyright 2016-2017 Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo.tests import common from odoo.modules.module import get_module_resource -class L10nEsAccountBankStatementImportN43(common.TransactionCase): - def setUp(self): - super(L10nEsAccountBankStatementImportN43, self).setUp() - self.partner = self.env['res.partner'].create({'name': 'Test partner'}) - self.journal = self.env['account.journal'].create({ +class L10nEsAccountBankStatementImportN43(common.SavepointCase): + @classmethod + def setUpClass(cls): + super(L10nEsAccountBankStatementImportN43, cls).setUpClass() + cls.partner = cls.env['res.partner'].create({'name': 'Test partner'}) + cls.journal = cls.env['account.journal'].create({ 'type': 'bank', 'name': 'Test N43 bank', 'code': 'BNKN43', }) - - def test_import_n43(self): n43_file_path = get_module_resource( 'l10n_es_account_bank_statement_import_n43', 'tests', 'test.n43') n43_file = open(n43_file_path, 'rb').read().encode('base64') - import_wizard = self.env['account.bank.statement.import'].create({ + cls.import_wizard = cls.env['account.bank.statement.import'].create({ 'data_file': n43_file, }) - action = import_wizard.with_context( + + def test_import_n43(self): + action = self.import_wizard.with_context( journal_id=self.journal.id, ).import_file() self.assertTrue(action) self.assertTrue(action.get('context').get('statement_ids')) statement = self.env['account.bank.statement'].browse( - action['context']['statement_ids'][0]) + action['context']['statement_ids'][0], + ) self.assertEqual(len(statement.line_ids), 3) + self.assertEqual(statement.line_ids[2].date, '2016-05-25') self.assertAlmostEqual(statement.balance_start, 0, 2) self.assertAlmostEqual(statement.balance_end, 101.96, 2) self.assertEqual(statement.line_ids[1].partner_id, self.partner) + + def test_import_n43_fecha_oper(self): + self.journal.n43_date_type = 'fecha_oper' + action = self.import_wizard.with_context( + journal_id=self.journal.id, + ).import_file() + self.assertTrue(action) + self.assertTrue(action.get('context').get('statement_ids')) + statement = self.env['account.bank.statement'].browse( + action['context']['statement_ids'][0], + ) + self.assertEqual(statement.line_ids[2].date, '2016-05-26') diff --git a/l10n_es_account_statement_import_n43/views/account_journal_views.xml b/l10n_es_account_statement_import_n43/views/account_journal_views.xml new file mode 100644 index 00000000000..9950985765a --- /dev/null +++ b/l10n_es_account_statement_import_n43/views/account_journal_views.xml @@ -0,0 +1,16 @@ + + + + + account.journal + + + + + + + + + + + diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index 045442353ab..c7bf030ef4b 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -294,6 +294,9 @@ def _parse_file(self, data_file): if not n43: return super(AccountBankStatementImport, self)._parse_file( data_file) + journal = self.env['account.journal'].browse( + self.env.context.get('journal_id', []) + ) transactions = [] for group in n43: for line in group['lines']: @@ -303,7 +306,7 @@ def _parse_file(self, data_file): x.strip() for x in line['conceptos'][concept_line] if x.strip()) vals_line = { - 'date': fields.Date.to_string(line['fecha_valor']), + 'date': fields.Date.to_string(line[journal.n43_date_type]), 'name': ' '.join(conceptos), 'ref': self._get_ref(line), 'amount': line['importe'], From acf7bfd1c8c466cdc9fe4b1524331312417ab76b Mon Sep 17 00:00:00 2001 From: "Roberto Lizana (mi)" Date: Fri, 20 Oct 2017 09:38:34 +0200 Subject: [PATCH 11/65] =?UTF-8?q?[FIX]=20l10n=5Fes=5Faccount=5Fbank=5Fstat?= =?UTF-8?q?ement=5Fimport=5Fn43:=20al=20parsear=20los=20registros=2022,=20?= =?UTF-8?q?n=C2=BA=20documento=20incorrecto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_es_account_statement_import_n43/__manifest__.py | 2 +- .../wizards/account_bank_statement_import_n43.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 08d762b9085..67cd744d5f7 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -6,7 +6,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '10.0.1.1.0', + 'version': '10.0.1.1.1', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' 'Tecnativa,' diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index c7bf030ef4b..f43cbbe7bd6 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -65,7 +65,7 @@ def _process_record_22(self, line): 'concepto_c': line[22:24], 'concepto_p': line[24:27], 'importe': (float(line[28:40]) + (float(line[40:42]) / 100)), - 'num_documento': line[41:52], + 'num_documento': line[42:52], 'referencia1': line[52:64].strip(), 'referencia2': line[64:].strip(), 'conceptos': {}, From 562321d5af96c58c6d8c79eb1559d4092ee15e80 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Thu, 26 Oct 2017 21:32:19 +0200 Subject: [PATCH 12/65] [MIG] l10n_es_account_bank_statement_import_n43: Migration to 11.0 * Metafiles updated * Test adapted to Python 3 * Test coverage improved --- .../README.rst | 38 +++++-------------- .../__init__.py | 1 - .../__manifest__.py | 7 ++-- .../models/account_journal.py | 1 - .../tests/__init__.py | 1 - .../tests/test.n43 | 5 ++- ...0n_es_account_bank_statement_import_n43.py | 6 +-- .../account_bank_statement_import_n43.py | 24 ++++++------ 8 files changed, 29 insertions(+), 54 deletions(-) diff --git a/l10n_es_account_statement_import_n43/README.rst b/l10n_es_account_statement_import_n43/README.rst index fe2d83a80f2..0b48e14a444 100644 --- a/l10n_es_account_statement_import_n43/README.rst +++ b/l10n_es_account_statement_import_n43/README.rst @@ -16,6 +16,10 @@ Uso #. Pulse en 'Importar'. #. Aparecerá el asistente para conciliación inmediatamente después. +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/189/11.0 + Incidencias conocidas / Hoja de ruta ==================================== @@ -32,39 +36,15 @@ Créditos Contribuidores -------------- -* Pedro M. Baeza -* Omar Castiñeira Saavedra - -Financiadores -------------- -La migración de este módulo forma parte de una campaña de migración de la -localización española que ha sido posible gracias a la colaboración económica -de las siguientes empresas (por orden alfabético): - -* `Aizean evolution `_ -* `Aselcis consulting `_ -* `AvanzOSC `_ -* `Diagram software `_ -* `Domatix `_ -* `Eficent `_ -* `FactorLibre `_ -* `Fairhall solutions `_ -* `GAFIC SLP `_ -* `Incaser `_ -* `Ingeos `_ -* `Nubistalia `_ -* `Punt sistemes `_ -* `Praxya `_ -* `Reeng `_ -* `Soluntec `_ -* `Tecnativa `_ -* `Trey `_ -* `Vicent Cubells `_ +* Tecnativa (https://www.tecnativa.com): + * Pedro M. Baeza +* Comunitea (https://www.comunitea.com) + * Omar Castiñeira Saavedra Maintainer ---------- -.. image:: http://odoo-community.org/logo.png +.. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org diff --git a/l10n_es_account_statement_import_n43/__init__.py b/l10n_es_account_statement_import_n43/__init__.py index 84830dc8eed..7588e52c8cc 100644 --- a/l10n_es_account_statement_import_n43/__init__.py +++ b/l10n_es_account_statement_import_n43/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import models diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 67cd744d5f7..8ffe50ce6c6 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -1,12 +1,11 @@ -# -*- coding: utf-8 -*- -# © 2013-2015 Serv. Tecnol. Avanzados - Pedro M. Baeza -# © 2016 Pedro M. Baeza +# Copyright 2016 Comunitea - Omar Castiñeira +# Copyright 2013-2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '10.0.1.1.1', + 'version': '11.0.1.0.0', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' 'Tecnativa,' diff --git a/l10n_es_account_statement_import_n43/models/account_journal.py b/l10n_es_account_statement_import_n43/models/account_journal.py index 8e827baa6c3..5475c68d4d9 100644 --- a/l10n_es_account_statement_import_n43/models/account_journal.py +++ b/l10n_es_account_statement_import_n43/models/account_journal.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp import fields, models diff --git a/l10n_es_account_statement_import_n43/tests/__init__.py b/l10n_es_account_statement_import_n43/tests/__init__.py index 3757c4a28f6..1c9eb25c879 100644 --- a/l10n_es_account_statement_import_n43/tests/__init__.py +++ b/l10n_es_account_statement_import_n43/tests/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import test_l10n_es_account_bank_statement_import_n43 diff --git a/l10n_es_account_statement_import_n43/tests/test.n43 b/l10n_es_account_statement_import_n43/tests/test.n43 index 74d52ff501a..434d859d71f 100644 --- a/l10n_es_account_statement_import_n43/tests/test.n43 +++ b/l10n_es_account_statement_import_n43/tests/test.n43 @@ -1,9 +1,10 @@ 110000000000000000001602011605312000000000000009783TECNATIVA S.L 22 00001605261605250610010000000000000300000000000000000000005540014210128010 -2301COMISI�N +2301COMISI�N 22 0000160512160512040161000000000178300000000000000975737917 2301TRANSFERENC. A TEST PARTNER 22 0000160516160516040162000000000280290000000000000000000000 2301TRANSFERENC. TEST PARTNER 2 -3300000000000000000000002000000000178330000100000000028029000000000010196978 +240197800000000000100 +3300000000000000000000002000000000178330000100000000028029000000000010196978 88999999999999999999000008 diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py index f0a5566bb3a..30c00dd3ed1 100644 --- a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -1,9 +1,9 @@ -# -*- coding: utf-8 -*- -# Copyright 2016-2017 Pedro M. Baeza +# Copyright 2016-2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo.tests import common from odoo.modules.module import get_module_resource +import base64 class L10nEsAccountBankStatementImportN43(common.SavepointCase): @@ -18,7 +18,7 @@ def setUpClass(cls): }) n43_file_path = get_module_resource( 'l10n_es_account_bank_statement_import_n43', 'tests', 'test.n43') - n43_file = open(n43_file_path, 'rb').read().encode('base64') + n43_file = base64.b64encode(open(n43_file_path, 'rb').read()) cls.import_wizard = cls.env['account.bank.statement.import'].create({ 'data_file': n43_file, }) diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index f43cbbe7bd6..30ab1076ffb 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- -# © 2013-2015 Serv. Tecnol. Avanzados - Pedro M. Baeza -# © 2016 Pedro M. Baeza +# Copyright 2013-2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, fields, api, exceptions, _ @@ -51,7 +49,7 @@ def _process_record_11(self, line): 'haber': 0, 'lines': [], } - if line[32:33] == '1': + if line[32:33] == '1': # pragma: no cover st_group['saldo_ini'] *= -1 self.balance_start = st_group['saldo_ini'] return st_group @@ -95,7 +93,7 @@ def _process_record_33(self, st_group, line): st_group['num_haber'] += int(line[39:44]) st_group['haber'] += float("%s.%s" % (line[44:56], line[56:58])) st_group['saldo_fin'] += float("%s.%s" % (line[59:71], line[71:73])) - if line[58:59] == '1': + if line[58:59] == '1': # pragma: no cover st_group['saldo_fin'] *= -1 self.balance_end = st_group['saldo_fin'] # Group level checks @@ -190,31 +188,31 @@ def _check_n43(self, data_file): data_file = data_file.decode('iso-8859-1') try: n43 = self._parse(data_file) - except exceptions.ValidationError: + except exceptions.ValidationError: # pragma: no cover return False return n43 def _get_ref(self, line): try: ref1 = int(line['referencia1']) - except: + except ValueError: # pragma: no cover ref1 = line['referencia1'] try: ref2 = int(line['referencia2']) - except: + except ValueError: ref2 = line['referencia2'] if not ref1: return line['referencia2'] or '/' elif not ref2: return line['referencia1'] or '/' - else: + else: # pragma: no cover return "%s / %s" % (line['referencia1'], line['referencia2']) def _get_partner_from_caixabank(self, conceptos): partner_obj = self.env['res.partner'] partner = partner_obj.browse() # Try to match from VAT included in concept complementary record #02 - if conceptos.get('02'): + if conceptos.get('02'): # pragma: no cover vat = conceptos['02'][0][:2] + conceptos['02'][0][7:] if vat: partner = partner_obj.search([('vat', '=', vat)], limit=1) @@ -268,7 +266,7 @@ def _get_partner_from_sabadell(self, conceptos): return partner def _get_partner(self, line): - if not line.get('conceptos'): + if not line.get('conceptos'): # pragma: no cover return self.env['res.partner'] partner = self._get_partner_from_caixabank(line['conceptos']) if not partner: @@ -291,7 +289,7 @@ def _get_account(self, line, journal): # pragma: no cover @api.model def _parse_file(self, data_file): n43 = self._check_n43(data_file) - if not n43: + if not n43: # pragma: no cover return super(AccountBankStatementImport, self)._parse_file( data_file) journal = self.env['account.journal'].browse( @@ -315,7 +313,7 @@ def _parse_file(self, data_file): c = line['conceptos'] if c.get('01'): vals_line['partner_name'] = c['01'][0] + c['01'][1] - if not vals_line['name']: + if not vals_line['name']: # pragma: no cover vals_line['name'] = vals_line['ref'] transactions.append(vals_line) vals_bank_statement = { From 66c713d86cf8465730ecaec308ba9e2f222727a2 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Thu, 28 Dec 2017 11:15:19 +0100 Subject: [PATCH 13/65] [FIX] l10n_es_account_bank_statement_import_n43: Fix tests due to upstream change --- .../i18n/es.po | 76 ++++++++----- .../i18n/fr.po | 104 ++++++++++++++++++ .../i18n/gl.po | 64 +++++++---- ...0n_es_account_bank_statement_import_n43.py | 6 +- 4 files changed, 196 insertions(+), 54 deletions(-) create mode 100644 l10n_es_account_statement_import_n43/i18n/fr.po diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index eccf7234845..6f6b550a693 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -1,19 +1,22 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 -# +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +# OCA Transbot , 2017 msgid "" msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" +"Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-04-13 17:27+0000\n" -"PO-Revision-Date: 2017-04-13 17:27+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" +"POT-Creation-Date: 2017-12-29 03:40+0000\n" +"PO-Revision-Date: 2017-12-29 03:40+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view @@ -21,10 +24,13 @@ msgid "AEB norm 43 (.n43)" msgstr "AEB norma 43 (.n43)" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 #, python-format -msgid "Credit amount doesn't match with the defined in the last record of account." -msgstr "El importe del haber no csa con lo definido en el último registro de la cuenta." +msgid "" +"Credit amount doesn't match with the defined in the last record of account." +msgstr "" +"El importe del haber no csa con lo definido en el último registro de la " +"cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type @@ -32,16 +38,23 @@ msgid "Date type for N43 Import" msgstr "Tipo de fecha para importación N43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 #, python-format -msgid "Debit amount doesn't match with the defined in the last record of account." -msgstr "El importe del debe no casa con lo definido en el último registor de la cuenta." +msgid "" +"Debit amount doesn't match with the defined in the last record of account." +msgstr "" +"El importe del debe no casa con lo definido en el último registor de la " +"cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format -msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." -msgstr "El saldo final = (saldo inicial + haber - debe) no casa con lo definido en el último registro de la cuenta." +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "" +"El saldo final = (saldo inicial + haber - debe) no casa con lo definido en " +"el último registro de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import @@ -59,22 +72,32 @@ msgid "Norm 43 options" msgstr "Opciones de Norma 43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 #, python-format -msgid "Number of credit records doesn't match with the defined in the last record of account." -msgstr "El número de registro del haber no casa con lo definido en el último regisro de la cuenta." +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "" +"El número de registro del haber no casa con lo definido en el último regisro" +" de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format -msgid "Number of debit records doesn't match with the defined in the last record of account." -msgstr "El número de registro del debe no casa con lo definido en el último regisro de la cuenta." +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "" +"El número de registro del debe no casa con lo definido en el último regisro " +"de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 #, python-format msgid "Number of records doesn't match with the defined in the last record." -msgstr "El número de registro no casa con lo definido en el último regisro de la cuenta." +msgstr "" +"El número de registro no casa con lo definido en el último regisro de la " +"cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: selection:account.journal,n43_date_type:0 @@ -82,7 +105,7 @@ msgid "Operation Date" msgstr "Fecha de operación" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 #, python-format msgid "Record type %s is not valid." msgstr "El tipo de registro %s no es válido." @@ -91,4 +114,3 @@ msgstr "El tipo de registro %s no es válido." #: selection:account.journal,n43_date_type:0 msgid "Value Date" msgstr "Fecha valor" - diff --git a/l10n_es_account_statement_import_n43/i18n/fr.po b/l10n_es_account_statement_import_n43/i18n/fr.po new file mode 100644 index 00000000000..0e5c28ed234 --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/fr.po @@ -0,0 +1,104 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-12-29 03:40+0000\n" +"PO-Revision-Date: 2017-12-29 03:40+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +msgid "AEB norm 43 (.n43)" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#, python-format +msgid "" +"Credit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +msgid "Date type for N43 Import" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#, python-format +msgid "" +"Debit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#, python-format +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_journal +msgid "Journal" +msgstr "Journal" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +msgid "Norm 43 options" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#, python-format +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#, python-format +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Operation Date" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#, python-format +msgid "Record type %s is not valid." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Value Date" +msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index ec3e139ba09..ac3abac1532 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -1,19 +1,22 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 -# +# * l10n_es_account_bank_statement_import_n43 +# +# Translators: +# OCA Transbot , 2017 msgid "" msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" +"Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-29 15:03+0000\n" -"PO-Revision-Date: 2017-06-29 15:03+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" +"POT-Creation-Date: 2017-12-29 03:40+0000\n" +"PO-Revision-Date: 2017-12-29 03:40+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: \n" +"Language: gl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view @@ -21,9 +24,10 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 #, python-format -msgid "Credit amount doesn't match with the defined in the last record of account." +msgid "" +"Credit amount doesn't match with the defined in the last record of account." msgstr "O importe do haber non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 @@ -32,16 +36,21 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 #, python-format -msgid "Debit amount doesn't match with the defined in the last record of account." +msgid "" +"Debit amount doesn't match with the defined in the last record of account." msgstr "O importe do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format -msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." -msgstr "O importe final do saldo = (saldo inicial + haber - debe) non cadra co definido no último rexistro da conta." +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with" +" the defined in the last record of account." +msgstr "" +"O importe final do saldo = (saldo inicial + haber - debe) non cadra co " +"definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import @@ -59,19 +68,27 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 #, python-format -msgid "Number of credit records doesn't match with the defined in the last record of account." -msgstr "O número de rexistros do haber non cadra co definido no último rexistro da conta." +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." +msgstr "" +"O número de rexistros do haber non cadra co definido no último rexistro da " +"conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format -msgid "Number of debit records doesn't match with the defined in the last record of account." -msgstr "O número de rexistros do debe non cadra co definido no último rexistro da conta." +msgid "" +"Number of debit records doesn't match with the defined in the last record of" +" account." +msgstr "" +"O número de rexistros do debe non cadra co definido no último rexistro da " +"conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "O número de rexistros non cadra co definido no último rexistro." @@ -82,7 +99,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 #, python-format msgid "Record type %s is not valid." msgstr "O tipo de rexistro %s non é válido." @@ -91,4 +108,3 @@ msgstr "O tipo de rexistro %s non é válido." #: selection:account.journal,n43_date_type:0 msgid "Value Date" msgstr "" - diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py index 30c00dd3ed1..c96f1836003 100644 --- a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -33,10 +33,10 @@ def test_import_n43(self): action['context']['statement_ids'][0], ) self.assertEqual(len(statement.line_ids), 3) - self.assertEqual(statement.line_ids[2].date, '2016-05-25') + self.assertEqual(statement.line_ids[0].date, '2016-05-25') self.assertAlmostEqual(statement.balance_start, 0, 2) self.assertAlmostEqual(statement.balance_end, 101.96, 2) - self.assertEqual(statement.line_ids[1].partner_id, self.partner) + self.assertEqual(statement.line_ids[2].partner_id, self.partner) def test_import_n43_fecha_oper(self): self.journal.n43_date_type = 'fecha_oper' @@ -48,4 +48,4 @@ def test_import_n43_fecha_oper(self): statement = self.env['account.bank.statement'].browse( action['context']['statement_ids'][0], ) - self.assertEqual(statement.line_ids[2].date, '2016-05-26') + self.assertEqual(statement.line_ids[0].date, '2016-05-26') From 41ced144c43ecfa8c0be853a9ac3d74c08889194 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Fri, 5 Jan 2018 19:45:49 +0100 Subject: [PATCH 14/65] [IMP] l10n_es_account_bank_statement_import_n43: Don't require n43_date_type With this, this is compatible with tests that creates journals before this module is loaded. --- .../__manifest__.py | 2 +- .../i18n/ca.po | 36 +++++--- .../i18n/es.po | 16 ++-- .../i18n/eu.po | 26 +++--- .../i18n/fr.po | 12 +-- .../i18n/gl.po | 12 +-- ...n_es_account_bank_statement_import_n43.pot | 92 +++++++++++++++++++ .../i18n/sl.po | 36 +++++--- .../models/account_journal.py | 4 +- .../account_bank_statement_import_n43.py | 4 +- 10 files changed, 175 insertions(+), 65 deletions(-) create mode 100644 l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 8ffe50ce6c6..41c40eecb88 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '11.0.1.0.0', + 'version': '11.0.1.0.1', 'license': 'AGPL-3', 'author': 'Spanish Localization Team,' 'Tecnativa,' diff --git a/l10n_es_account_statement_import_n43/i18n/ca.po b/l10n_es_account_statement_import_n43/i18n/ca.po index e4b3dac6ea5..357f6601d18 100644 --- a/l10n_es_account_statement_import_n43/i18n/ca.po +++ b/l10n_es_account_statement_import_n43/i18n/ca.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 +# * l10n_es_account_bank_statement_import_n43 # msgid "" msgstr "" @@ -10,6 +10,7 @@ msgstr "" "PO-Revision-Date: 2017-06-29 15:03+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" @@ -21,9 +22,10 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 #, python-format -msgid "Credit amount doesn't match with the defined in the last record of account." +msgid "" +"Credit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 @@ -32,15 +34,18 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 #, python-format -msgid "Debit amount doesn't match with the defined in the last record of account." +msgid "" +"Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format -msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with " +"the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 @@ -59,19 +64,23 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 #, python-format -msgid "Number of credit records doesn't match with the defined in the last record of account." +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format -msgid "Number of debit records doesn't match with the defined in the last record of account." +msgid "" +"Number of debit records doesn't match with the defined in the last record of " +"account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -82,7 +91,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 #, python-format msgid "Record type %s is not valid." msgstr "" @@ -91,4 +100,3 @@ msgstr "" #: selection:account.journal,n43_date_type:0 msgid "Value Date" msgstr "" - diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index 6f6b550a693..46416f4e3a9 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * l10n_es_account_bank_statement_import_n43 -# +# # Translators: # OCA Transbot , 2017 msgid "" @@ -12,10 +12,10 @@ msgstr "" "PO-Revision-Date: 2017-12-29 03:40+0000\n" "Last-Translator: OCA Transbot , 2017\n" "Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 @@ -50,8 +50,8 @@ msgstr "" #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." +"Final balance amount = (initial balance + credit - debit) doesn't match with " +"the defined in the last record of account." msgstr "" "El saldo final = (saldo inicial + haber - debe) no casa con lo definido en " "el último registro de la cuenta." @@ -78,15 +78,15 @@ msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." msgstr "" -"El número de registro del haber no casa con lo definido en el último regisro" -" de la cuenta." +"El número de registro del haber no casa con lo definido en el último regisro " +"de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." +"Number of debit records doesn't match with the defined in the last record of " +"account." msgstr "" "El número de registro del debe no casa con lo definido en el último regisro " "de la cuenta." diff --git a/l10n_es_account_statement_import_n43/i18n/eu.po b/l10n_es_account_statement_import_n43/i18n/eu.po index 837c966b3f9..b916a2467ad 100644 --- a/l10n_es_account_statement_import_n43/i18n/eu.po +++ b/l10n_es_account_statement_import_n43/i18n/eu.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * l10n_es_account_bank_statement_import_n43 -# +# # Translators: # OCA Transbot , 2017 msgid "" @@ -12,10 +12,10 @@ msgstr "" "PO-Revision-Date: 2017-06-29 22:48+0000\n" "Last-Translator: OCA Transbot , 2017\n" "Language-Team: Basque (https://www.transifex.com/oca/teams/23907/eu/)\n" +"Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: eu\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 @@ -24,7 +24,7 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." @@ -36,18 +36,18 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." +"Final balance amount = (initial balance + credit - debit) doesn't match with " +"the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 @@ -66,7 +66,7 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -74,15 +74,15 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." +"Number of debit records doesn't match with the defined in the last record of " +"account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -93,7 +93,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 #, python-format msgid "Record type %s is not valid." msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/fr.po b/l10n_es_account_statement_import_n43/i18n/fr.po index 0e5c28ed234..8a35b6e51a6 100644 --- a/l10n_es_account_statement_import_n43/i18n/fr.po +++ b/l10n_es_account_statement_import_n43/i18n/fr.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * l10n_es_account_bank_statement_import_n43 -# +# # Translators: # OCA Transbot , 2017 msgid "" @@ -12,10 +12,10 @@ msgstr "" "PO-Revision-Date: 2017-12-29 03:40+0000\n" "Last-Translator: OCA Transbot , 2017\n" "Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. module: l10n_es_account_bank_statement_import_n43 @@ -46,8 +46,8 @@ msgstr "" #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." +"Final balance amount = (initial balance + credit - debit) doesn't match with " +"the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 @@ -77,8 +77,8 @@ msgstr "" #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." +"Number of debit records doesn't match with the defined in the last record of " +"account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index ac3abac1532..f679daa5210 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * l10n_es_account_bank_statement_import_n43 -# +# # Translators: # OCA Transbot , 2017 msgid "" @@ -12,10 +12,10 @@ msgstr "" "PO-Revision-Date: 2017-12-29 03:40+0000\n" "Last-Translator: OCA Transbot , 2017\n" "Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" +"Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: gl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 @@ -46,8 +46,8 @@ msgstr "O importe do debe non cadra co definido no último rexistro da conta." #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format msgid "" -"Final balance amount = (initial balance + credit - debit) doesn't match with" -" the defined in the last record of account." +"Final balance amount = (initial balance + credit - debit) doesn't match with " +"the defined in the last record of account." msgstr "" "O importe final do saldo = (saldo inicial + haber - debe) non cadra co " "definido no último rexistro da conta." @@ -81,8 +81,8 @@ msgstr "" #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format msgid "" -"Number of debit records doesn't match with the defined in the last record of" -" account." +"Number of debit records doesn't match with the defined in the last record of " +"account." msgstr "" "O número de rexistros do debe non cadra co definido no último rexistro da " "conta." diff --git a/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot new file mode 100644 index 00000000000..95fe5a5163b --- /dev/null +++ b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot @@ -0,0 +1,92 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_bank_statement_import_n43 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.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: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +msgid "AEB norm 43 (.n43)" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#, python-format +msgid "Credit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +msgid "Date type for N43 Import" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#, python-format +msgid "Debit amount doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#, python-format +msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.model,name:l10n_es_account_bank_statement_import_n43.model_account_journal +msgid "Journal" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +msgid "Norm 43 options" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#, python-format +msgid "Number of credit records doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#, python-format +msgid "Number of debit records doesn't match with the defined in the last record of account." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#, python-format +msgid "Number of records doesn't match with the defined in the last record." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Operation Date" +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#, python-format +msgid "Record type %s is not valid." +msgstr "" + +#. module: l10n_es_account_bank_statement_import_n43 +#: selection:account.journal,n43_date_type:0 +msgid "Value Date" +msgstr "" + diff --git a/l10n_es_account_statement_import_n43/i18n/sl.po b/l10n_es_account_statement_import_n43/i18n/sl.po index 9eec24874d8..5a9fd4f3ea0 100644 --- a/l10n_es_account_statement_import_n43/i18n/sl.po +++ b/l10n_es_account_statement_import_n43/i18n/sl.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_account_bank_statement_import_n43 +# * l10n_es_account_bank_statement_import_n43 # msgid "" msgstr "" @@ -10,6 +10,7 @@ msgstr "" "PO-Revision-Date: 2017-06-29 15:03+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" @@ -21,9 +22,10 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 #, python-format -msgid "Credit amount doesn't match with the defined in the last record of account." +msgid "" +"Credit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 @@ -32,15 +34,18 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 #, python-format -msgid "Debit amount doesn't match with the defined in the last record of account." +msgid "" +"Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:136 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 #, python-format -msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." +msgid "" +"Final balance amount = (initial balance + credit - debit) doesn't match with " +"the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 @@ -59,19 +64,23 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:119 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 #, python-format -msgid "Number of credit records doesn't match with the defined in the last record of account." +msgid "" +"Number of credit records doesn't match with the defined in the last record " +"of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:115 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 #, python-format -msgid "Number of debit records doesn't match with the defined in the last record of account." +msgid "" +"Number of debit records doesn't match with the defined in the last record of " +"account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:151 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -82,7 +91,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:184 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 #, python-format msgid "Record type %s is not valid." msgstr "" @@ -91,4 +100,3 @@ msgstr "" #: selection:account.journal,n43_date_type:0 msgid "Value Date" msgstr "" - diff --git a/l10n_es_account_statement_import_n43/models/account_journal.py b/l10n_es_account_statement_import_n43/models/account_journal.py index 5475c68d4d9..40fcce1b72c 100644 --- a/l10n_es_account_statement_import_n43/models/account_journal.py +++ b/l10n_es_account_statement_import_n43/models/account_journal.py @@ -1,6 +1,6 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from openerp import fields, models +from odoo import fields, models class AccountJournal(models.Model): @@ -10,5 +10,5 @@ class AccountJournal(models.Model): string='Date type for N43 Import', selection=[('fecha_valor', 'Value Date'), ('fecha_oper', 'Operation Date')], - required=True, default='fecha_valor', + default='fecha_valor', ) diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index 30ab1076ffb..5328e8fcbb1 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -304,7 +304,9 @@ def _parse_file(self, data_file): x.strip() for x in line['conceptos'][concept_line] if x.strip()) vals_line = { - 'date': fields.Date.to_string(line[journal.n43_date_type]), + 'date': fields.Date.to_string( + line[journal.n43_date_type or 'fecha_valor'] + ), 'name': ' '.join(conceptos), 'ref': self._get_ref(line), 'amount': line['importe'], From 5348a79dd719360fba896605c9456bd559d13239 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Thu, 4 Oct 2018 08:03:34 +0200 Subject: [PATCH 15/65] [MIG] l10n_es_bank_statement_import_n43: Migration to 12.0 * Standard procedure * Override method for adding the supported format * README by fragments * Tests adapted for new date format and order --- .../README.rst | 97 +++- .../__manifest__.py | 6 +- .../models/account_journal.py | 5 + .../readme/CONTRIBUTORS.rst | 7 + .../readme/DESCRIPTION.rst | 5 + .../readme/ROADMAP.rst | 7 + .../readme/USAGE.rst | 5 + .../static/description/index.html | 455 ++++++++++++++++++ ...0n_es_account_bank_statement_import_n43.py | 18 +- 9 files changed, 578 insertions(+), 27 deletions(-) create mode 100644 l10n_es_account_statement_import_n43/readme/CONTRIBUTORS.rst create mode 100644 l10n_es_account_statement_import_n43/readme/DESCRIPTION.rst create mode 100644 l10n_es_account_statement_import_n43/readme/ROADMAP.rst create mode 100644 l10n_es_account_statement_import_n43/readme/USAGE.rst create mode 100644 l10n_es_account_statement_import_n43/static/description/index.html diff --git a/l10n_es_account_statement_import_n43/README.rst b/l10n_es_account_statement_import_n43/README.rst index 0b48e14a444..e915da67d70 100644 --- a/l10n_es_account_statement_import_n43/README.rst +++ b/l10n_es_account_statement_import_n43/README.rst @@ -1,5 +1,29 @@ -Extractos bancarios españoles (Norma 43) -======================================== +======================================================= +Importación de extractos bancarios españoles (Norma 43) +======================================================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png + :target: https://odoo-community.org/page/development-status + :alt: Mature +.. |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%2Fl10n--spain-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-spain/tree/12.0/l10n_es_account_bank_statement_import_n43 + :alt: OCA/l10n-spain +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-spain-12-0/l10n-spain-12-0-l10n_es_account_bank_statement_import_n43 + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/189/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| Importación y tratamiento de los extractos bancarios españoles que siguen la norma/cuaderno 43 de la 'Asociación Española de la Banca'. Puede consultarse la @@ -7,8 +31,13 @@ especificación del formato aquí_. .. _aquí: http://goo.gl/2zzlmu -Uso -=== +**Table of contents** + +.. contents:: + :local: + +Usage +===== #. Vaya a Contabilidad (Facturación) > Tablero, y escoja "Importar extracto" en el cuadro que corresponda con el diario de su banco. @@ -16,12 +45,8 @@ Uso #. Pulse en 'Importar'. #. Aparecerá el asistente para conciliación inmediatamente después. -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/189/11.0 - -Incidencias conocidas / Hoja de ruta -==================================== +Known issues / Roadmap +====================== * Reconocimiento de partners para otros bancos distintos del Santander, CaixaBank, Bankia o Sabadell. @@ -31,27 +56,57 @@ Incidencias conocidas / Hoja de ruta * Los códigos de operación N43 no se utilizan para asociar una cuenta contable genérica, ya que Odoo no lo permite. -Créditos -======== +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 +~~~~~~~ + +* Spanish Localization Team +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `__: -Contribuidores --------------- -* Tecnativa (https://www.tecnativa.com): * Pedro M. Baeza -* Comunitea (https://www.comunitea.com) + +* `Comunitea `__: + * Omar Castiñeira Saavedra -Maintainer ----------- +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://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 https://odoo-community.org. +.. |maintainer-pedrobaeza| image:: https://github.com/pedrobaeza.png?size=40px + :target: https://github.com/pedrobaeza + :alt: pedrobaeza + +Current `maintainer `__: + +|maintainer-pedrobaeza| + +This module is part of the `OCA/l10n-spain `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 41c40eecb88..4db1e447b91 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -1,12 +1,14 @@ # Copyright 2016 Comunitea - Omar Castiñeira -# Copyright 2013-2017 Tecnativa - Pedro M. Baeza +# Copyright 2013-2018 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '11.0.1.0.1', + 'version': '12.0.1.0.0', 'license': 'AGPL-3', + 'development_status': 'Mature', + 'maintainers': ['pedrobaeza'], 'author': 'Spanish Localization Team,' 'Tecnativa,' 'Odoo Community Association (OCA)', diff --git a/l10n_es_account_statement_import_n43/models/account_journal.py b/l10n_es_account_statement_import_n43/models/account_journal.py index 40fcce1b72c..c759c6a9e4c 100644 --- a/l10n_es_account_statement_import_n43/models/account_journal.py +++ b/l10n_es_account_statement_import_n43/models/account_journal.py @@ -12,3 +12,8 @@ class AccountJournal(models.Model): ('fecha_oper', 'Operation Date')], default='fecha_valor', ) + + def _get_bank_statements_available_import_formats(self): + res = super()._get_bank_statements_available_import_formats() + res.append('N43') + return res diff --git a/l10n_es_account_statement_import_n43/readme/CONTRIBUTORS.rst b/l10n_es_account_statement_import_n43/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..b8950a96dc0 --- /dev/null +++ b/l10n_es_account_statement_import_n43/readme/CONTRIBUTORS.rst @@ -0,0 +1,7 @@ +* `Tecnativa `__: + + * Pedro M. Baeza + +* `Comunitea `__: + + * Omar Castiñeira Saavedra diff --git a/l10n_es_account_statement_import_n43/readme/DESCRIPTION.rst b/l10n_es_account_statement_import_n43/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..adafd2dcb68 --- /dev/null +++ b/l10n_es_account_statement_import_n43/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +Importación y tratamiento de los extractos bancarios españoles que siguen la +norma/cuaderno 43 de la 'Asociación Española de la Banca'. Puede consultarse la +especificación del formato aquí_. + +.. _aquí: http://goo.gl/2zzlmu diff --git a/l10n_es_account_statement_import_n43/readme/ROADMAP.rst b/l10n_es_account_statement_import_n43/readme/ROADMAP.rst new file mode 100644 index 00000000000..7acd84a04e7 --- /dev/null +++ b/l10n_es_account_statement_import_n43/readme/ROADMAP.rst @@ -0,0 +1,7 @@ +* Reconocimiento de partners para otros bancos distintos del Santander, + CaixaBank, Bankia o Sabadell. +* La moneda se extrae del diario con el cual se va a importar o, en su defecto, + de la compañia, no del extracto norma 43 que se importa, para lo cual sería + necesario usar códigos numéricos según la norma ISO 4217. +* Los códigos de operación N43 no se utilizan para asociar una cuenta contable + genérica, ya que Odoo no lo permite. diff --git a/l10n_es_account_statement_import_n43/readme/USAGE.rst b/l10n_es_account_statement_import_n43/readme/USAGE.rst new file mode 100644 index 00000000000..23b00665504 --- /dev/null +++ b/l10n_es_account_statement_import_n43/readme/USAGE.rst @@ -0,0 +1,5 @@ +#. Vaya a Contabilidad (Facturación) > Tablero, y escoja "Importar extracto" en + el cuadro que corresponda con el diario de su banco. +#. Seleccione el archivo Norma 43 a importar. +#. Pulse en 'Importar'. +#. Aparecerá el asistente para conciliación inmediatamente después. diff --git a/l10n_es_account_statement_import_n43/static/description/index.html b/l10n_es_account_statement_import_n43/static/description/index.html new file mode 100644 index 00000000000..046cd83b8c9 --- /dev/null +++ b/l10n_es_account_statement_import_n43/static/description/index.html @@ -0,0 +1,455 @@ + + + + + + +Importación de extractos bancarios españoles (Norma 43) + + + +
    +

    Importación de extractos bancarios españoles (Norma 43)

    + + +

    Mature License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runbot

    +

    Importación y tratamiento de los extractos bancarios españoles que siguen la +norma/cuaderno 43 de la ‘Asociación Española de la Banca’. Puede consultarse la +especificación del formato aquí.

    +

    Table of contents

    + +
    +

    Usage

    +
      +
    1. Vaya a Contabilidad (Facturación) > Tablero, y escoja “Importar extracto” en +el cuadro que corresponda con el diario de su banco.
    2. +
    3. Seleccione el archivo Norma 43 a importar.
    4. +
    5. Pulse en ‘Importar’.
    6. +
    7. Aparecerá el asistente para conciliación inmediatamente después.
    8. +
    +
    +
    +

    Known issues / Roadmap

    +
      +
    • Reconocimiento de partners para otros bancos distintos del Santander, +CaixaBank, Bankia o Sabadell.
    • +
    • La moneda se extrae del diario con el cual se va a importar o, en su defecto, +de la compañia, no del extracto norma 43 que se importa, para lo cual sería +necesario usar códigos numéricos según la norma ISO 4217.
    • +
    • Los códigos de operación N43 no se utilizan para asociar una cuenta contable +genérica, ya que Odoo no lo permite.
    • +
    +
    +
    +

    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

    +
      +
    • Spanish Localization Team
    • +
    • Tecnativa
    • +
    +
    +
    +

    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:

    +

    pedrobaeza

    +

    This module is part of the OCA/l10n-spain project on GitHub.

    +

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

    +
    +
    +
    + + diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py index c96f1836003..fd1d55c0795 100644 --- a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -1,12 +1,16 @@ -# Copyright 2016-2017 Tecnativa - Pedro M. Baeza +# Copyright 2016-2018 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import fields from odoo.tests import common from odoo.modules.module import get_module_resource import base64 class L10nEsAccountBankStatementImportN43(common.SavepointCase): + at_install = False + post_install = True + @classmethod def setUpClass(cls): super(L10nEsAccountBankStatementImportN43, cls).setUpClass() @@ -33,10 +37,13 @@ def test_import_n43(self): action['context']['statement_ids'][0], ) self.assertEqual(len(statement.line_ids), 3) - self.assertEqual(statement.line_ids[0].date, '2016-05-25') + self.assertEqual( + statement.line_ids[2].date, + fields.Date.to_date('2016-05-25'), + ) self.assertAlmostEqual(statement.balance_start, 0, 2) self.assertAlmostEqual(statement.balance_end, 101.96, 2) - self.assertEqual(statement.line_ids[2].partner_id, self.partner) + self.assertEqual(statement.line_ids[0].partner_id, self.partner) def test_import_n43_fecha_oper(self): self.journal.n43_date_type = 'fecha_oper' @@ -48,4 +55,7 @@ def test_import_n43_fecha_oper(self): statement = self.env['account.bank.statement'].browse( action['context']['statement_ids'][0], ) - self.assertEqual(statement.line_ids[0].date, '2016-05-26') + self.assertEqual( + statement.line_ids[2].date, + fields.Date.to_date('2016-05-26'), + ) From f23c711164664aac429285f2e2bc8a2aee42ae3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Pigeon?= Date: Wed, 17 Oct 2018 13:19:20 +0200 Subject: [PATCH 16/65] [FIX] l10n_es_account_bank_statement_import_n43: fix inconsistency between type of exception raised adn type of exception catched --- l10n_es_account_statement_import_n43/__manifest__.py | 2 +- l10n_es_account_statement_import_n43/i18n/ca.po | 6 +++--- l10n_es_account_statement_import_n43/i18n/es.po | 6 +++--- l10n_es_account_statement_import_n43/i18n/eu.po | 6 +++--- l10n_es_account_statement_import_n43/i18n/fr.po | 6 +++--- l10n_es_account_statement_import_n43/i18n/gl.po | 6 +++--- .../i18n/l10n_es_account_bank_statement_import_n43.pot | 8 ++++---- l10n_es_account_statement_import_n43/i18n/sl.po | 6 +++--- .../wizards/account_bank_statement_import_n43.py | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 4db1e447b91..c6d1d08ddbc 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '12.0.1.0.0', + 'version': '12.0.1.0.1', 'license': 'AGPL-3', 'development_status': 'Mature', 'maintainers': ['pedrobaeza'], diff --git a/l10n_es_account_statement_import_n43/i18n/ca.po b/l10n_es_account_statement_import_n43/i18n/ca.po index 357f6601d18..55465b78dbd 100644 --- a/l10n_es_account_statement_import_n43/i18n/ca.po +++ b/l10n_es_account_statement_import_n43/i18n/ca.po @@ -17,7 +17,7 @@ msgstr "" "Plural-Forms: \n" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" msgstr "" @@ -29,7 +29,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" msgstr "" @@ -59,7 +59,7 @@ msgid "Journal" msgstr "Diari" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index 46416f4e3a9..0bb865d40e9 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -19,7 +19,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" msgstr "AEB norma 43 (.n43)" @@ -33,7 +33,7 @@ msgstr "" "cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" msgstr "Tipo de fecha para importación N43" @@ -67,7 +67,7 @@ msgid "Journal" msgstr "Diario" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" msgstr "Opciones de Norma 43" diff --git a/l10n_es_account_statement_import_n43/i18n/eu.po b/l10n_es_account_statement_import_n43/i18n/eu.po index b916a2467ad..4d9c9205d85 100644 --- a/l10n_es_account_statement_import_n43/i18n/eu.po +++ b/l10n_es_account_statement_import_n43/i18n/eu.po @@ -19,7 +19,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" msgstr "" @@ -31,7 +31,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" msgstr "" @@ -61,7 +61,7 @@ msgid "Journal" msgstr "Diario" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/fr.po b/l10n_es_account_statement_import_n43/i18n/fr.po index 8a35b6e51a6..b500c3256a5 100644 --- a/l10n_es_account_statement_import_n43/i18n/fr.po +++ b/l10n_es_account_statement_import_n43/i18n/fr.po @@ -19,7 +19,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" msgstr "" @@ -31,7 +31,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" msgstr "" @@ -61,7 +61,7 @@ msgid "Journal" msgstr "Journal" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index f679daa5210..37abf34fbb2 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -19,7 +19,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" msgstr "" @@ -31,7 +31,7 @@ msgid "" msgstr "O importe do haber non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" msgstr "" @@ -63,7 +63,7 @@ msgid "Journal" msgstr "Diario" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot index 95fe5a5163b..21806b18afd 100644 --- a/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot +++ b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 11.0\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: <>\n" "Language-Team: \n" @@ -14,7 +14,7 @@ msgstr "" "Plural-Forms: \n" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" msgstr "" @@ -25,7 +25,7 @@ msgid "Credit amount doesn't match with the defined in the last record of accoun msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" msgstr "" @@ -52,7 +52,7 @@ msgid "Journal" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/sl.po b/l10n_es_account_statement_import_n43/i18n/sl.po index 5a9fd4f3ea0..636dd7f01d4 100644 --- a/l10n_es_account_statement_import_n43/i18n/sl.po +++ b/l10n_es_account_statement_import_n43/i18n/sl.po @@ -17,7 +17,7 @@ msgstr "" "Plural-Forms: \n" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" msgstr "" @@ -29,7 +29,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal_n43_date_type +#: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" msgstr "" @@ -59,7 +59,7 @@ msgid "Journal" msgstr "Dnevnik" #. module: l10n_es_account_bank_statement_import_n43 -#: model:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 +#: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" msgstr "" diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index 5328e8fcbb1..777c31ffdd5 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -178,7 +178,7 @@ def _parse(self, data_file): # CTRL-Z (^Z), is often used as an end-of-file marker in DOS continue else: # pragma: no cover - raise exceptions.UserError( + raise exceptions.ValidationError( _('Record type %s is not valid.') % raw_line[0:2]) # Update the record counter st_data['_num_records'] += 1 From 01b0a1a0c4fd98859b2c475d061c54e26769b4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20V=C3=A1zquez=20Rodr=C3=ADguez?= Date: Tue, 5 Feb 2019 12:44:44 +0000 Subject: [PATCH 17/65] Translated using Weblate (Galician) Currently translated at 100.0% (14 of 14 strings) Translation: l10n-spain-12.0/l10n-spain-12.0-l10n_es_account_bank_statement_import_n43 Translate-URL: https://translation.odoo-community.org/projects/l10n-spain-12-0/l10n-spain-12-0-l10n_es_account_bank_statement_import_n43/gl/ --- l10n_es_account_statement_import_n43/i18n/gl.po | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index 37abf34fbb2..e1fa484444c 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -9,19 +9,20 @@ msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-12-29 03:40+0000\n" -"PO-Revision-Date: 2017-12-29 03:40+0000\n" -"Last-Translator: OCA Transbot , 2017\n" +"PO-Revision-Date: 2019-02-05 14:50+0000\n" +"Last-Translator: Marta Vázquez Rodríguez \n" "Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.4\n" #. module: l10n_es_account_bank_statement_import_n43 #: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.account_bank_statement_import_view msgid "AEB norm 43 (.n43)" -msgstr "" +msgstr "AEB norma 43 (.n43)" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 @@ -33,7 +34,7 @@ msgstr "O importe do haber non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 #: model:ir.model.fields,field_description:l10n_es_account_bank_statement_import_n43.field_account_journal__n43_date_type msgid "Date type for N43 Import" -msgstr "" +msgstr "Tipo de data para a importación N43" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 @@ -65,7 +66,7 @@ msgstr "Diario" #. module: l10n_es_account_bank_statement_import_n43 #: model_terms:ir.ui.view,arch_db:l10n_es_account_bank_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" -msgstr "" +msgstr "Opcións de Norma 43" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 @@ -96,7 +97,7 @@ msgstr "O número de rexistros non cadra co definido no último rexistro." #. module: l10n_es_account_bank_statement_import_n43 #: selection:account.journal,n43_date_type:0 msgid "Operation Date" -msgstr "" +msgstr "Data de operación" #. module: l10n_es_account_bank_statement_import_n43 #: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 @@ -107,4 +108,4 @@ msgstr "O tipo de rexistro %s non é válido." #. module: l10n_es_account_bank_statement_import_n43 #: selection:account.journal,n43_date_type:0 msgid "Value Date" -msgstr "" +msgstr "Data valor" From ec234f3842af2ed13e707e558f4c0ef51111f0fa Mon Sep 17 00:00:00 2001 From: Jose F Date: Fri, 12 Apr 2019 16:00:00 +0200 Subject: [PATCH 18/65] [FIX] l10n_es_account_bank_statement_import_n43: Change encoding for compatibility with BBVA files (#1056) Some statement files include BOM data (https://es.wikipedia.org/wiki/Marca_de_orden_de_bytes) at the beginning of the file, making them non readable by current parser, as fixed positions are moved in these cases and thus expected data is not matched. As ASCII, which is the encoding used in files according specification, is a subset of UTF-8, there's no danger in using it with the variant 'utf-8-sig' for handling if BOM marker is present or not. --- .../wizards/account_bank_statement_import_n43.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index 777c31ffdd5..510019e70a1 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -185,7 +185,7 @@ def _parse(self, data_file): return st_data['groups'] def _check_n43(self, data_file): - data_file = data_file.decode('iso-8859-1') + data_file = data_file.decode('utf-8-sig') try: n43 = self._parse(data_file) except exceptions.ValidationError: # pragma: no cover From 2463ac6d6e51f8757505a18a0e9b6cb569f16896 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 Apr 2019 14:09:53 +0200 Subject: [PATCH 19/65] [FIX] l10n_es_account_bank_statement_import_n43: decoding import error --- .../__manifest__.py | 7 ++++- .../models/__init__.py | 1 - .../wizards/__init__.py | 1 - .../account_bank_statement_import_n43.py | 31 ++++++++++++++++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index c6d1d08ddbc..2b1a17fd1c1 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '12.0.1.0.1', + 'version': '12.0.1.0.2', 'license': 'AGPL-3', 'development_status': 'Mature', 'maintainers': ['pedrobaeza'], @@ -16,6 +16,11 @@ 'depends': [ 'account_bank_statement_import', ], + 'external_dependencies': { + 'python': [ + 'chardet', + ], + }, 'data': [ 'views/account_journal_views.xml', 'wizards/account_bank_statement_import_view.xml', diff --git a/l10n_es_account_statement_import_n43/models/__init__.py b/l10n_es_account_statement_import_n43/models/__init__.py index ba9ebfba7a6..ec99cd19523 100644 --- a/l10n_es_account_statement_import_n43/models/__init__.py +++ b/l10n_es_account_statement_import_n43/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import account_journal diff --git a/l10n_es_account_statement_import_n43/wizards/__init__.py b/l10n_es_account_statement_import_n43/wizards/__init__.py index 6da5ac01574..510f5952fc4 100644 --- a/l10n_es_account_statement_import_n43/wizards/__init__.py +++ b/l10n_es_account_statement_import_n43/wizards/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import account_bank_statement_import_n43 diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index 510019e70a1..031a970e1e1 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -2,7 +2,18 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, fields, api, exceptions, _ +from odoo.exceptions import ValidationError from datetime import datetime +import logging +_logger = logging.getLogger(__name__) + +try: + import chardet +except ImportError: + _logger.warning( + "chardet library not found, please install it " + "from http://pypi.python.org/pypi/chardet" + ) account_mapping = { '01': '4300%00', @@ -184,8 +195,26 @@ def _parse(self, data_file): st_data['_num_records'] += 1 return st_data['groups'] + @api.model + def _get_common_file_encodings(self): + """Returns a list with commonly used encodings""" + return ['iso-8859-1', 'utf-8-sig'] + def _check_n43(self, data_file): - data_file = data_file.decode('utf-8-sig') + # We'll try to decode with the encoding detected by chardet first + # otherwise, we'll try with another common encodings until success + encodings = self._get_common_file_encodings() + # Try to guess the encoding of the data file + detected_encoding = chardet.detect(data_file).get('encoding', False) + if detected_encoding: + encodings = encodings + [detected_encoding] + while encodings: + try: + data_file = data_file.decode(encodings.pop()) + break + except UnicodeDecodeError: + if not encodings: + return False try: n43 = self._parse(data_file) except exceptions.ValidationError: # pragma: no cover From 83109fb57a9aa3f3bcd8be4069598c061b37766f Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Tue, 23 Apr 2019 19:25:19 +0200 Subject: [PATCH 20/65] [FIX] l10n_es_account_bank_statement_import_n43: Allow to parse on other encodings + flake8 --- l10n_es_account_statement_import_n43/i18n/ca.po | 14 +++++++------- l10n_es_account_statement_import_n43/i18n/es.po | 14 +++++++------- l10n_es_account_statement_import_n43/i18n/eu.po | 14 +++++++------- l10n_es_account_statement_import_n43/i18n/fr.po | 14 +++++++------- l10n_es_account_statement_import_n43/i18n/gl.po | 14 +++++++------- ...l10n_es_account_bank_statement_import_n43.pot | 14 +++++++------- l10n_es_account_statement_import_n43/i18n/sl.po | 14 +++++++------- .../wizards/account_bank_statement_import_n43.py | 16 +++++----------- 8 files changed, 54 insertions(+), 60 deletions(-) diff --git a/l10n_es_account_statement_import_n43/i18n/ca.po b/l10n_es_account_statement_import_n43/i18n/ca.po index 55465b78dbd..4cb9c2a0766 100644 --- a/l10n_es_account_statement_import_n43/i18n/ca.po +++ b/l10n_es_account_statement_import_n43/i18n/ca.po @@ -22,7 +22,7 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:135 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." @@ -34,14 +34,14 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:144 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " @@ -64,7 +64,7 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -72,7 +72,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " @@ -80,7 +80,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:159 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -91,7 +91,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:192 #, python-format msgid "Record type %s is not valid." msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index 0bb865d40e9..5b193f1101d 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -24,7 +24,7 @@ msgid "AEB norm 43 (.n43)" msgstr "AEB norma 43 (.n43)" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:135 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." @@ -38,7 +38,7 @@ msgid "Date type for N43 Import" msgstr "Tipo de fecha para importación N43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." @@ -47,7 +47,7 @@ msgstr "" "cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:144 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " @@ -72,7 +72,7 @@ msgid "Norm 43 options" msgstr "Opciones de Norma 43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -82,7 +82,7 @@ msgstr "" "de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " @@ -92,7 +92,7 @@ msgstr "" "de la cuenta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:159 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -105,7 +105,7 @@ msgid "Operation Date" msgstr "Fecha de operación" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:192 #, python-format msgid "Record type %s is not valid." msgstr "El tipo de registro %s no es válido." diff --git a/l10n_es_account_statement_import_n43/i18n/eu.po b/l10n_es_account_statement_import_n43/i18n/eu.po index 4d9c9205d85..4f560d9a146 100644 --- a/l10n_es_account_statement_import_n43/i18n/eu.po +++ b/l10n_es_account_statement_import_n43/i18n/eu.po @@ -24,7 +24,7 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:135 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." @@ -36,14 +36,14 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:144 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " @@ -66,7 +66,7 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -74,7 +74,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " @@ -82,7 +82,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:159 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -93,7 +93,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:192 #, python-format msgid "Record type %s is not valid." msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/fr.po b/l10n_es_account_statement_import_n43/i18n/fr.po index b500c3256a5..1bb5f2e901a 100644 --- a/l10n_es_account_statement_import_n43/i18n/fr.po +++ b/l10n_es_account_statement_import_n43/i18n/fr.po @@ -24,7 +24,7 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:135 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." @@ -36,14 +36,14 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:144 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " @@ -66,7 +66,7 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -74,7 +74,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " @@ -82,7 +82,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:159 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -93,7 +93,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:192 #, python-format msgid "Record type %s is not valid." msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index e1fa484444c..4721a10e295 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -25,7 +25,7 @@ msgid "AEB norm 43 (.n43)" msgstr "AEB norma 43 (.n43)" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:135 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." @@ -37,14 +37,14 @@ msgid "Date type for N43 Import" msgstr "Tipo de data para a importación N43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "O importe do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:144 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " @@ -69,7 +69,7 @@ msgid "Norm 43 options" msgstr "Opcións de Norma 43" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -79,7 +79,7 @@ msgstr "" "conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " @@ -89,7 +89,7 @@ msgstr "" "conta." #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:159 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "O número de rexistros non cadra co definido no último rexistro." @@ -100,7 +100,7 @@ msgid "Operation Date" msgstr "Data de operación" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:192 #, python-format msgid "Record type %s is not valid." msgstr "O tipo de rexistro %s non é válido." diff --git a/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot index 21806b18afd..4231cd445fd 100644 --- a/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot +++ b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_bank_statement_import_n43.pot @@ -19,7 +19,7 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:135 #, python-format msgid "Credit amount doesn't match with the defined in the last record of account." msgstr "" @@ -30,13 +30,13 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:131 #, python-format msgid "Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:144 #, python-format msgid "Final balance amount = (initial balance + credit - debit) doesn't match with the defined in the last record of account." msgstr "" @@ -57,19 +57,19 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "Number of credit records doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "Number of debit records doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:159 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -80,7 +80,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:192 #, python-format msgid "Record type %s is not valid." msgstr "" diff --git a/l10n_es_account_statement_import_n43/i18n/sl.po b/l10n_es_account_statement_import_n43/i18n/sl.po index 636dd7f01d4..6e0f3ad6863 100644 --- a/l10n_es_account_statement_import_n43/i18n/sl.po +++ b/l10n_es_account_statement_import_n43/i18n/sl.po @@ -22,7 +22,7 @@ msgid "AEB norm 43 (.n43)" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:125 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:135 #, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." @@ -34,14 +34,14 @@ msgid "Date type for N43 Import" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:121 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:131 #, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:134 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:144 #, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " @@ -64,7 +64,7 @@ msgid "Norm 43 options" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:117 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:127 #, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " @@ -72,7 +72,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:113 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:123 #, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " @@ -80,7 +80,7 @@ msgid "" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:149 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:159 #, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -91,7 +91,7 @@ msgid "Operation Date" msgstr "" #. module: l10n_es_account_bank_statement_import_n43 -#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:182 +#: code:addons/l10n_es_account_bank_statement_import_n43/wizards/account_bank_statement_import_n43.py:192 #, python-format msgid "Record type %s is not valid." msgstr "" diff --git a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py index 031a970e1e1..08429221af1 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_bank_statement_import_n43.py @@ -2,7 +2,6 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, fields, api, exceptions, _ -from odoo.exceptions import ValidationError from datetime import datetime import logging _logger = logging.getLogger(__name__) @@ -207,19 +206,14 @@ def _check_n43(self, data_file): # Try to guess the encoding of the data file detected_encoding = chardet.detect(data_file).get('encoding', False) if detected_encoding: - encodings = encodings + [detected_encoding] + encodings += [detected_encoding] while encodings: try: data_file = data_file.decode(encodings.pop()) - break - except UnicodeDecodeError: - if not encodings: - return False - try: - n43 = self._parse(data_file) - except exceptions.ValidationError: # pragma: no cover - return False - return n43 + return self._parse(data_file) + except (UnicodeDecodeError, exceptions.ValidationError): + pass + return False def _get_ref(self, line): try: From dcff2d2b1e4ace1bd6ec132a8ac5fe92ae65343e Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 1 May 2019 16:40:50 +0200 Subject: [PATCH 21/65] [IMP] l10n_es_account_bank_statement_import_n43: Full compatibility in tests with other statement import modules Journal in context should be available since the beginning, as it can be used in default get for example. --- l10n_es_account_statement_import_n43/__manifest__.py | 2 +- .../static/description/index.html | 2 +- ...test_l10n_es_account_bank_statement_import_n43.py | 12 +++++------- .../wizards/account_bank_statement_import_n43.py | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 2b1a17fd1c1..2da3526521a 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Importación de extractos bancarios españoles (Norma 43)', 'category': 'Accounting & Finance', - 'version': '12.0.1.0.2', + 'version': '12.0.1.0.3', 'license': 'AGPL-3', 'development_status': 'Mature', 'maintainers': ['pedrobaeza'], diff --git a/l10n_es_account_statement_import_n43/static/description/index.html b/l10n_es_account_statement_import_n43/static/description/index.html index 046cd83b8c9..88173cd2e54 100644 --- a/l10n_es_account_statement_import_n43/static/description/index.html +++ b/l10n_es_account_statement_import_n43/static/description/index.html @@ -3,7 +3,7 @@ - + Importación de extractos bancarios españoles (Norma 43) -
    -

    Importación de extractos bancarios españoles (Norma 43)

    +
    + + +Odoo Community Association + +
    +

    Importación de extractos bancarios españoles (Norma 43)

    -

    Mature License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runboat

    +

    Mature License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runboat

    Importación y tratamiento de los extractos bancarios españoles que siguen la norma/cuaderno 43 de la ‘Asociación Española de la Banca’. Puede consultarse la especificación del formato @@ -389,7 +394,7 @@

    Importación de extractos bancarios españoles (Norma 43)

    -

    Usage

    +

    Usage

    1. Vaya a Contabilidad (Facturación) > Tablero, y escoja “Importar extracto” en el cuadro que corresponda con el diario de su banco.
    2. @@ -399,7 +404,7 @@

      Usage

    -

    Known issues / Roadmap

    +

    Known issues / Roadmap

    • Reconocimiento de partners para otros bancos distintos del Santander, CaixaBank, Bankia o Sabadell.
    • @@ -411,7 +416,7 @@

      Known issues / Roadmap

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -419,16 +424,16 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Spanish Localization Team
    • Tecnativa
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -462,5 +467,6 @@

    Maintainers

    +
    From cea2c67a5cd7b741290798ea764ca21abfc1e968 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 30 Jun 2025 11:18:38 +0000 Subject: [PATCH 62/65] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: l10n-spain-18.0/l10n-spain-18.0-l10n_es_account_statement_import_n43 Translate-URL: https://translation.odoo-community.org/projects/l10n-spain-18-0/l10n-spain-18-0-l10n_es_account_statement_import_n43/ --- .../i18n/ca.po | 37 +++++++++++++++---- .../i18n/es.po | 7 ---- .../i18n/eu.po | 37 +++++++++++++++---- .../i18n/fr.po | 37 +++++++++++++++---- .../i18n/gl.po | 37 +++++++++++++++---- .../i18n/sl.po | 37 +++++++++++++++---- 6 files changed, 150 insertions(+), 42 deletions(-) diff --git a/l10n_es_account_statement_import_n43/i18n/ca.po b/l10n_es_account_statement_import_n43/i18n/ca.po index b5331543721..4016d7513a6 100644 --- a/l10n_es_account_statement_import_n43/i18n/ca.po +++ b/l10n_es_account_statement_import_n43/i18n/ca.po @@ -22,10 +22,19 @@ msgstr "" msgid "AEB norm 43 (.n43)" msgstr "Norma AEB 43 (.n43)" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__all +msgid "All" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__caixabank +msgid "CaixaBank" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "" @@ -40,7 +49,6 @@ msgstr "Tipus de data per a la importació N43" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" @@ -50,7 +58,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " "the defined in the last record of account." @@ -68,6 +75,11 @@ msgstr "Importa fitxers d'extracte bancari" msgid "Journal" msgstr "Diari" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__none +msgid "None" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model_terms:ir.ui.view,arch_db:l10n_es_account_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" @@ -76,7 +88,6 @@ msgstr "Opcions de la norma 43" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." @@ -87,7 +98,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " "account." @@ -98,7 +108,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" "El nombre de registres no coincideix amb el definit a l'últim registre." @@ -108,13 +117,27 @@ msgstr "" msgid "Operation Date" msgstr "Data d’operació" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_statement_import_n43.field_account_journal__n43_partner_search +msgid "Partner search for N43 import" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Record type %s is not valid." msgstr "El tipus de registre %s no és vàlid." +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__sabadell +msgid "Sabadell" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__santander +msgid "Santander" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_date_type__fecha_valor msgid "Value Date" diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index e2803d21993..38cc8e3910d 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -37,7 +37,6 @@ msgstr "CaixaBank" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "" @@ -52,7 +51,6 @@ msgstr "Tipo de fecha para importación N43" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" @@ -62,7 +60,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " "the defined in the last record of account." @@ -93,7 +90,6 @@ msgstr "Opciones de Norma 43" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." @@ -104,7 +100,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " "account." @@ -115,7 +110,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" "El número de registros no casa con lo definido en el último registro del " @@ -134,7 +128,6 @@ msgstr "Búsqueda de empresa para importación N43" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Record type %s is not valid." msgstr "El tipo de registro %s no es válido." diff --git a/l10n_es_account_statement_import_n43/i18n/eu.po b/l10n_es_account_statement_import_n43/i18n/eu.po index a7c37abeb78..357f7640c1c 100644 --- a/l10n_es_account_statement_import_n43/i18n/eu.po +++ b/l10n_es_account_statement_import_n43/i18n/eu.po @@ -23,10 +23,19 @@ msgstr "" msgid "AEB norm 43 (.n43)" msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__all +msgid "All" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__caixabank +msgid "CaixaBank" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "" @@ -39,7 +48,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" @@ -47,7 +55,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " "the defined in the last record of account." @@ -63,6 +70,11 @@ msgstr "" msgid "Journal" msgstr "Diario" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__none +msgid "None" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model_terms:ir.ui.view,arch_db:l10n_es_account_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" @@ -71,7 +83,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." @@ -80,7 +91,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " "account." @@ -89,7 +99,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -98,13 +107,27 @@ msgstr "" msgid "Operation Date" msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_statement_import_n43.field_account_journal__n43_partner_search +msgid "Partner search for N43 import" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Record type %s is not valid." msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__sabadell +msgid "Sabadell" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__santander +msgid "Santander" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_date_type__fecha_valor msgid "Value Date" diff --git a/l10n_es_account_statement_import_n43/i18n/fr.po b/l10n_es_account_statement_import_n43/i18n/fr.po index f65940ca2a3..26402a848fc 100644 --- a/l10n_es_account_statement_import_n43/i18n/fr.po +++ b/l10n_es_account_statement_import_n43/i18n/fr.po @@ -23,10 +23,19 @@ msgstr "" msgid "AEB norm 43 (.n43)" msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__all +msgid "All" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__caixabank +msgid "CaixaBank" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "" @@ -39,7 +48,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" @@ -47,7 +55,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " "the defined in the last record of account." @@ -63,6 +70,11 @@ msgstr "" msgid "Journal" msgstr "Journal" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__none +msgid "None" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model_terms:ir.ui.view,arch_db:l10n_es_account_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" @@ -71,7 +83,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." @@ -80,7 +91,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " "account." @@ -89,7 +99,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -98,13 +107,27 @@ msgstr "" msgid "Operation Date" msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_statement_import_n43.field_account_journal__n43_partner_search +msgid "Partner search for N43 import" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Record type %s is not valid." msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__sabadell +msgid "Sabadell" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__santander +msgid "Santander" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_date_type__fecha_valor msgid "Value Date" diff --git a/l10n_es_account_statement_import_n43/i18n/gl.po b/l10n_es_account_statement_import_n43/i18n/gl.po index 1c011ac635a..caa4c1af1da 100644 --- a/l10n_es_account_statement_import_n43/i18n/gl.po +++ b/l10n_es_account_statement_import_n43/i18n/gl.po @@ -24,10 +24,19 @@ msgstr "" msgid "AEB norm 43 (.n43)" msgstr "AEB norma 43 (.n43)" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__all +msgid "All" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__caixabank +msgid "CaixaBank" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "O importe do haber non cadra co definido no último rexistro da conta." @@ -40,7 +49,6 @@ msgstr "Tipo de data para a importación N43" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "O importe do debe non cadra co definido no último rexistro da conta." @@ -48,7 +56,6 @@ msgstr "O importe do debe non cadra co definido no último rexistro da conta." #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " "the defined in the last record of account." @@ -67,6 +74,11 @@ msgstr "Importar extracto bancario" msgid "Journal" msgstr "Diario" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__none +msgid "None" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model_terms:ir.ui.view,arch_db:l10n_es_account_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" @@ -75,7 +87,6 @@ msgstr "Opcións de Norma 43" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." @@ -86,7 +97,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " "account." @@ -97,7 +107,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "O número de rexistros non cadra co definido no último rexistro." @@ -106,13 +115,27 @@ msgstr "O número de rexistros non cadra co definido no último rexistro." msgid "Operation Date" msgstr "Data de operación" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_statement_import_n43.field_account_journal__n43_partner_search +msgid "Partner search for N43 import" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Record type %s is not valid." msgstr "O tipo de rexistro %s non é válido." +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__sabadell +msgid "Sabadell" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__santander +msgid "Santander" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_date_type__fecha_valor msgid "Value Date" diff --git a/l10n_es_account_statement_import_n43/i18n/sl.po b/l10n_es_account_statement_import_n43/i18n/sl.po index 29eae42c1fa..574c4e3148a 100644 --- a/l10n_es_account_statement_import_n43/i18n/sl.po +++ b/l10n_es_account_statement_import_n43/i18n/sl.po @@ -21,10 +21,19 @@ msgstr "" msgid "AEB norm 43 (.n43)" msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__all +msgid "All" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__caixabank +msgid "CaixaBank" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Credit amount doesn't match with the defined in the last record of account." msgstr "" @@ -37,7 +46,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" @@ -45,7 +53,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Final balance amount = (initial balance + credit - debit) doesn't match with " "the defined in the last record of account." @@ -61,6 +68,11 @@ msgstr "" msgid "Journal" msgstr "Dnevnik" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__none +msgid "None" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model_terms:ir.ui.view,arch_db:l10n_es_account_statement_import_n43.view_account_journal_form_n43 msgid "Norm 43 options" @@ -69,7 +81,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of credit records doesn't match with the defined in the last record " "of account." @@ -78,7 +89,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "" "Number of debit records doesn't match with the defined in the last record of " "account." @@ -87,7 +97,6 @@ msgstr "" #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Number of records doesn't match with the defined in the last record." msgstr "" @@ -96,13 +105,27 @@ msgstr "" msgid "Operation Date" msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_statement_import_n43.field_account_journal__n43_partner_search +msgid "Partner search for N43 import" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 -#, python-format msgid "Record type %s is not valid." msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__sabadell +msgid "Sabadell" +msgstr "" + +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_partner_search__santander +msgid "Santander" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #: model:ir.model.fields.selection,name:l10n_es_account_statement_import_n43.selection__account_journal__n43_date_type__fecha_valor msgid "Value Date" From 7a33ba028d5b0a7d614ce4f65fc25fea2a4fe704 Mon Sep 17 00:00:00 2001 From: ferran-S73 Date: Tue, 2 Dec 2025 12:17:16 +0100 Subject: [PATCH 63/65] [IMP] l10n_es_account_statement_import_n43: black, isort, prettier --- l10n_es_account_statement_import_n43/__manifest__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 1a64c7b96ad..5ab626e3372 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -9,9 +9,7 @@ "license": "AGPL-3", "development_status": "Mature", "maintainers": ["pedrobaeza"], - "author": "Spanish Localization Team," - "Tecnativa," - "Odoo Community Association (OCA)", + "author": "Spanish Localization Team,Tecnativa,Odoo Community Association (OCA)", "website": "https://github.com/OCA/l10n-spain", "depends": ["account_statement_import_file"], "external_dependencies": {"python": ["chardet"]}, From 22b30e9edbacf2487c2d538deb6a20dda577a382 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Mon, 8 Dec 2025 14:09:35 +0100 Subject: [PATCH 64/65] [IMP] l10n_es_account_statement_import_n43: Add exclude pattern You may be interested in not importing certain statement lines if they come from complicated operations like third party payment providers with several charges/incomes, and you are interested in importing them by other means. This commit includes a new field at journal level for defining an excluding pattern that allows this. TT59339 --- l10n_es_account_statement_import_n43/i18n/es.po | 5 +++++ .../i18n/l10n_es_account_statement_import_n43.pot | 5 +++++ .../models/account_journal.py | 5 +++++ ...t_l10n_es_account_bank_statement_import_n43.py | 8 ++++++++ .../views/account_journal_views.xml | 1 + .../wizards/account_statement_import_n43.py | 15 ++++++++++++++- 6 files changed, 38 insertions(+), 1 deletion(-) diff --git a/l10n_es_account_statement_import_n43/i18n/es.po b/l10n_es_account_statement_import_n43/i18n/es.po index 38cc8e3910d..b91f359e46e 100644 --- a/l10n_es_account_statement_import_n43/i18n/es.po +++ b/l10n_es_account_statement_import_n43/i18n/es.po @@ -57,6 +57,11 @@ msgstr "" "El importe del debe no casa con lo definido en el último registro del " "archivo." +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_statement_import_n43.field_account_journal__n43_exclude_pattern +msgid "Exclude pattern for N43 Import" +msgstr "Patrón de exclusion para importación N43" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 diff --git a/l10n_es_account_statement_import_n43/i18n/l10n_es_account_statement_import_n43.pot b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_statement_import_n43.pot index 2729ec7de6b..d59290a83a1 100644 --- a/l10n_es_account_statement_import_n43/i18n/l10n_es_account_statement_import_n43.pot +++ b/l10n_es_account_statement_import_n43/i18n/l10n_es_account_statement_import_n43.pot @@ -47,6 +47,11 @@ msgid "" "Debit amount doesn't match with the defined in the last record of account." msgstr "" +#. module: l10n_es_account_statement_import_n43 +#: model:ir.model.fields,field_description:l10n_es_account_statement_import_n43.field_account_journal__n43_exclude_pattern +msgid "Exclude pattern for N43 Import" +msgstr "" + #. module: l10n_es_account_statement_import_n43 #. odoo-python #: code:addons/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py:0 diff --git a/l10n_es_account_statement_import_n43/models/account_journal.py b/l10n_es_account_statement_import_n43/models/account_journal.py index 641f8bb38b8..98d2eb32262 100644 --- a/l10n_es_account_statement_import_n43/models/account_journal.py +++ b/l10n_es_account_statement_import_n43/models/account_journal.py @@ -23,6 +23,11 @@ class AccountJournal(models.Model): default="all", required=True, ) + n43_exclude_pattern = fields.Char( + string="Exclude pattern for N43 import", + help="Fill this field if you want to exclude some lines of the N43 according " + "this regexp pattern.", + ) def _get_bank_statements_available_import_formats(self): res = super()._get_bank_statements_available_import_formats() diff --git a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py index ffcac279b0d..3e6829d4c56 100644 --- a/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/tests/test_l10n_es_account_bank_statement_import_n43.py @@ -109,3 +109,11 @@ def test_import_n43_fecha_oper(self): [("statement_id.journal_id", "=", self.journal.id)] ) self.assertEqual(statements[0].date, fields.Date.to_date("2016-05-26")) + + def test_import_n43_excluded_patern(self): + self.journal.n43_exclude_pattern = r".*TEST PARTNER 2.*" + self.import_wizard.import_file_button() + st_lines = self.env["account.bank.statement.line"].search( + [("statement_id.journal_id", "=", self.journal.id)] + ) + self.assertEqual(len(st_lines), 2) diff --git a/l10n_es_account_statement_import_n43/views/account_journal_views.xml b/l10n_es_account_statement_import_n43/views/account_journal_views.xml index 436ed98f0f2..5debc58013d 100644 --- a/l10n_es_account_statement_import_n43/views/account_journal_views.xml +++ b/l10n_es_account_statement_import_n43/views/account_journal_views.xml @@ -8,6 +8,7 @@ + diff --git a/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py index bb582c12318..ef23ef55aa8 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py @@ -3,6 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging +import re from datetime import datetime from odoo import api, exceptions, fields, models @@ -409,9 +410,12 @@ def _get_currency_iso4217(self, iso_currency): return CURRENCY_ISO4217_MAP.get(iso_currency) def _complete_stmts_vals(self, stmts_vals, journal, account_number): - """Match partner_id if if hasn't been deducted yet.""" + """Match partner_id if it hasn't been deducted yet & discard excluded lines.""" res = super()._complete_stmts_vals(stmts_vals, journal, account_number) + pattern = journal.n43_exclude_pattern + pattern = re.compile(pattern) if pattern else False for st_vals in res: + transactions = [] for line_vals in st_vals["transactions"]: if line_vals.get("n43_line"): n43_line = line_vals.pop("n43_line") @@ -422,9 +426,18 @@ def _complete_stmts_vals(self, stmts_vals, journal, account_number): line_vals["date"] = fields.Date.to_string( n43_line.get(journal.n43_date_type or "fecha_valor") ) + if ( + pattern + and not pattern.match(line_vals["payment_ref"]) + or not pattern + ): + transactions.append(line_vals) + else: + transactions.append(line_vals) # This can't be used, as Odoo doesn't present the lines # that already have a counterpart account as final # verification, making this very counter intuitive to the user # line_vals['account_id'] = self._get_n43_account( # line_vals['raw_data'], journal).id + st_vals["transactions"] = transactions return res From 4bf8612e84f44aaa1e6d1f7ae16dff6b88d63c6c Mon Sep 17 00:00:00 2001 From: AlexGarS73 Date: Mon, 9 Feb 2026 11:26:03 +0100 Subject: [PATCH 65/65] [MIG] l10n_es_account_statement_import_n43 --- l10n_es_account_statement_import_n43/README.rst | 10 +++++----- l10n_es_account_statement_import_n43/__manifest__.py | 2 +- .../static/description/index.html | 6 +++--- .../wizards/account_statement_import_n43.py | 2 +- requirements.txt | 2 ++ 5 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 requirements.txt diff --git a/l10n_es_account_statement_import_n43/README.rst b/l10n_es_account_statement_import_n43/README.rst index 01c4add9fca..2da5312cf50 100644 --- a/l10n_es_account_statement_import_n43/README.rst +++ b/l10n_es_account_statement_import_n43/README.rst @@ -21,13 +21,13 @@ Importación de extractos bancarios españoles (Norma 43) :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--spain-lightgray.png?logo=github - :target: https://github.com/OCA/l10n-spain/tree/18.0/l10n_es_account_statement_import_n43 + :target: https://github.com/OCA/l10n-spain/tree/19.0/l10n_es_account_statement_import_n43 :alt: OCA/l10n-spain .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/l10n-spain-18-0/l10n-spain-18-0-l10n_es_account_statement_import_n43 + :target: https://translation.odoo-community.org/projects/l10n-spain-19-0/l10n-spain-19-0-l10n_es_account_statement_import_n43 :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-spain&target_branch=18.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-spain&target_branch=19.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -68,7 +68,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 to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -120,6 +120,6 @@ Current `maintainer `__: |maintainer-pedrobaeza| -This module is part of the `OCA/l10n-spain `_ project on GitHub. +This module is part of the `OCA/l10n-spain `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_es_account_statement_import_n43/__manifest__.py b/l10n_es_account_statement_import_n43/__manifest__.py index 5ab626e3372..9726910c3f9 100644 --- a/l10n_es_account_statement_import_n43/__manifest__.py +++ b/l10n_es_account_statement_import_n43/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Importación de extractos bancarios españoles (Norma 43)", "category": "Accounting & Finance", - "version": "18.0.1.1.0", + "version": "19.0.1.0.0", "license": "AGPL-3", "development_status": "Mature", "maintainers": ["pedrobaeza"], diff --git a/l10n_es_account_statement_import_n43/static/description/index.html b/l10n_es_account_statement_import_n43/static/description/index.html index 55b0036de04..95b5bdc824b 100644 --- a/l10n_es_account_statement_import_n43/static/description/index.html +++ b/l10n_es_account_statement_import_n43/static/description/index.html @@ -374,7 +374,7 @@

    Importación de extractos bancarios españoles (Norma 43)

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:9d0a696765ae928f404d39ae0881812e62cf659ea3bd50a9c823bd86ef3aaeb2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Mature License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runboat

    +

    Mature License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runboat

    Importación y tratamiento de los extractos bancarios españoles que siguen la norma/cuaderno 43 de la ‘Asociación Española de la Banca’. Puede consultarse la especificación del formato @@ -420,7 +420,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 to smash it by providing a detailed and welcomed -feedback.

    +feedback.

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

    @@ -462,7 +462,7 @@

    Maintainers

    promote its widespread use.

    Current maintainer:

    pedrobaeza

    -

    This module is part of the OCA/l10n-spain project on GitHub.

    +

    This module is part of the OCA/l10n-spain project on GitHub.

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

    diff --git a/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py b/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py index ef23ef55aa8..e2d46fbd1a5 100644 --- a/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py +++ b/l10n_es_account_statement_import_n43/wizards/account_statement_import_n43.py @@ -235,7 +235,7 @@ def _parse(self, data_file): continue else: # pragma: no cover raise exceptions.ValidationError( - self.env._("Record type %s is not valid.") % raw_line[0:2] + self.env._("Record type %s is not valid.", raw_line[0:2]) ) # Update the record counter st_data["_num_records"] += 1 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000000..4d812492d28 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +# generated from manifests external_dependencies +chardet