diff --git a/account_chart_update/README.rst b/account_chart_update/README.rst index a1d133ab..e4e6541b 100644 --- a/account_chart_update/README.rst +++ b/account_chart_update/README.rst @@ -1,11 +1,30 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 - =========================================================== Detect changes and update the Account Chart from a template =========================================================== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! 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%2Faccount--financial--tools-lightgray.png?logo=github + :target: https://github.com/OCA/account-financial-tools/tree/10.0/account_chart_update + :alt: OCA/account-financial-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-financial-tools-10-0/account-financial-tools-10-0-account_chart_update + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/92/10.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + This is a pretty useful tool to update Odoo installations after tax reforms on the official charts of accounts, or to apply fixes performed on the chart template. @@ -19,40 +38,53 @@ The wizard: * It can also update (overwrite) the accounts, taxes, tax codes and fiscal positions that got modified on the template. +**Table of contents** + +.. contents:: + :local: + Usage ===== -The wizard, accesible from *Accounting > Configuration > Settings > Chart of -Accounts > Update chart of accounts*, lets the user select what kind of objects -must be checked/updated, and whether old records must be checked for changes -and updates. +The wizard, accesible from *Accounting > Settings > Update chart of accounts*, +lets the user select what kind of objects must be checked/updated, and whether +old records must be checked for changes and updates. -It will display all the objects to be created / updated with some information -about the detected differences, and allow the user to exclude records -individually. - -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/92/9.0 +It will display all the objects to be created / updated / deactivated with some +information about the detected differences, and allow the user to exclude +records individually. Known issues / Roadmap ====================== -* Add tests. +* Generate and update account reconcile models. +* Generate XML-ID for fiscal position tax and account mapping lines. +* Allow to select independently operations to perform (create, update, + deactivate). +* Detect fiscal positions to deactivate? 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. +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 +~~~~~~~ + +* Tecnativa +* BCIM +* Okia + Contributors ------------- +~~~~~~~~~~~~ * Pedro M. Baeza * Jairo Llopis @@ -60,17 +92,20 @@ Contributors * Sylvain Van Hoof * Nacho Muñoz -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. +This module is part of the `OCA/account-financial-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_chart_update/__manifest__.py b/account_chart_update/__manifest__.py index 35282b52..a9e5d78f 100644 --- a/account_chart_update/__manifest__.py +++ b/account_chart_update/__manifest__.py @@ -1,28 +1,22 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2017 Pedro Manuel Baeza # Copyright 2016 Jairo Llopis # Copyright 2016 Jacques-Etienne Baudoux # Copyright 2016 Sylvain Van Hoof +# Copyright 2015-2018 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': "Detect changes and update the Account Chart from a template", "summary": "Wizard to update a company's account chart from a template", - 'version': "10.0.1.0.2", + 'version': "10.0.2.0.0", 'author': "Tecnativa, " "BCIM, " "Okia, " "Odoo Community Association (OCA)", 'website': "http://odoo-community.org", 'depends': ["account"], - 'category': "Accounting & Finance", - 'contributors': [ - 'Pedro M. Baeza', - 'Jairo Llopis', - 'Jacques-Etienne Baudoux', - 'Sylvain Van Hoof' - 'Nacho Muñoz', - ], + 'development_status': 'Mature', + 'category': "Accounting", 'license': "AGPL-3", "data": [ 'wizard/wizard_chart_update_view.xml', diff --git a/account_chart_update/i18n/es.po b/account_chart_update/i18n/es.po index 741cc032..523559d1 100644 --- a/account_chart_update/i18n/es.po +++ b/account_chart_update/i18n/es.po @@ -1,73 +1,70 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * account_chart_update -# -# Translators: -# OCA Transbot , 2017 +# * account_chart_update +# msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-02-01 03:44+0000\n" -"PO-Revision-Date: 2018-02-01 03:44+0000\n" -"Last-Translator: OCA Transbot , 2017\n" -"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"POT-Creation-Date: 2018-09-21 00:20+0000\n" +"PO-Revision-Date: 2018-09-21 00:20+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: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_code_digits msgid "# of digits" -msgstr "" +msgstr "Nº de dígitos" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid " or " -msgstr "" +msgstr " o " #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_account_id msgid "Account template" -msgstr "" +msgstr "Plantilla de cuenta" #. module: account_chart_update #: model:ir.model,name:account_chart_update.model_wizard_update_charts_accounts_account msgid "Account that needs to be updated (new or updated in the template)." -msgstr "" +msgstr "Cuenta que necesita ser actualizada (nueva o cambiada en la plantilla)." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_update_account_id msgid "Account to update" -msgstr "" +msgstr "Cuenta a actualizar" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_ids #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Accounts" -msgstr "" +msgstr "Cuentas" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_chart_template_id msgid "Chart Template" -msgstr "" +msgstr "Plan contable" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_chart_template_ids msgid "Chart Templates" -msgstr "" +msgstr "Planes contables" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Chart of Accounts" -msgstr "" +msgstr "Plan contable" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Close" -msgstr "" +msgstr "Cerrar" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_company_id @@ -77,23 +74,23 @@ msgstr "Compañía" #. module: account_chart_update #: selection:wizard.update.charts.accounts,state:0 msgid "Configuration" -msgstr "" +msgstr "Configuración" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_continue_on_errors msgid "Continue on errors" -msgstr "" +msgstr "Continuar en errores" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Create/Update" -msgstr "" +msgstr "Crear/Actualizar" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:625 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:613 #, python-format msgid "Created account %s." -msgstr "" +msgstr "Creada cuenta %s." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_create_uid @@ -109,43 +106,41 @@ msgstr "Creado por" #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position_create_date #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_create_date msgid "Created on" -msgstr "Creado en" +msgstr "Creado el" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:708 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:714 #, python-format msgid "Created or updated fiscal position %s." -msgstr "" - -#. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:587 -#, python-format -msgid "Created tax %s." -msgstr "" +msgstr "Creada o actualizada posición fiscal %s." #. module: account_chart_update #: code:addons/account_chart_update/wizard/wizard_chart_update.py:580 #, python-format +msgid "Created tax %s." +msgstr "Creado impuesto %s." + +#. module: account_chart_update +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:575 +#, python-format msgid "Deactivated tax %s." -msgstr "" +msgstr "Deactivado impuesto %s." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_deleted_taxes msgid "Deactivated taxes" -msgstr "" +msgstr "Impuestos desactivados" #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_tax_type_tax_use -msgid "" -"Determines where the tax is selectable. Note : 'None' means a tax can't be " -"used by itself, however it can still be used in a group." -msgstr "" +msgid "Determines where the tax is selectable. Note : 'None' means a tax can't be used by itself, however it can still be used in a group." +msgstr "Determina dónde puede seleccionarse un impuesto. Nota : 'Ninguno' significa que un impuesto no puede ser usado por si mismo; aun así, puede utilizarse en un grupo." #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:453 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:451 #, python-format msgid "Differences in these fields: %s." -msgstr "" +msgstr "Diferencias en estos campos: %s." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_display_name @@ -153,65 +148,60 @@ msgstr "" #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position_display_name #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_display_name msgid "Display Name" -msgstr "Nombre mostrado" +msgstr "Nombre a mostrar" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:629 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:622 #, python-format msgid "Exception creating account %s." -msgstr "" +msgstr "Excepción creando cuenta %s." #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:641 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:644 #, python-format msgid "Exception writing account %s." -msgstr "" +msgstr "Excepción escribiendo cuenta %s." #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_update_account msgid "Existing accounts are updated. Accounts are searched by code." -msgstr "" +msgstr "Las cuentas existentes serán actualizadas. Las cuentas se buscan por código." #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_update_fiscal_position -msgid "" -"Existing fiscal positions are updated. Fiscal positions are searched by " -"name." -msgstr "" +msgid "Existing fiscal positions are updated. Fiscal positions are searched by name." +msgstr "Las posiciones fiscales existentes serán actualizadas. Las posiciones fiscales se buscan por nombre." #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_update_tax msgid "Existing taxes are updated. Taxes are searched by name." -msgstr "" +msgstr "Los impuestos existentes serán actualizados. Los impuestos se buscan por nombre." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position_fiscal_position_id msgid "Fiscal position template" -msgstr "" +msgstr "Plantilla posición fiscal" #. module: account_chart_update #: model:ir.model,name:account_chart_update.model_wizard_update_charts_accounts_fiscal_position -msgid "" -"Fiscal position that needs to be updated (new or updated in the template)." -msgstr "" +msgid "Fiscal position that needs to be updated (new or updated in the template)." +msgstr "Posición fiscal que necesita ser actualizada (nuevo o modificada en la plantilla)" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position_update_fiscal_position_id msgid "Fiscal position to update" -msgstr "" +msgstr "Posición fiscal a actualizar" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position_ids #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Fiscal positions" -msgstr "" +msgstr "Posiciones fiscales" #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_lang -msgid "" -"For records searched by name (taxes, fiscal positions), the template name " -"will be matched against the record name on this language." -msgstr "" +msgid "For records searched by name (taxes, fiscal positions), the template name will be matched against the record name on this language." +msgstr "Para registros buscados por nombre (impuestos, posiciones fiscales), el nombre de la plantilla será casado contra el nombre del registro en este idioma." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_id @@ -223,27 +213,23 @@ msgstr "ID" #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_continue_on_errors -msgid "" -"If set, the wizard will continue to the next step even if there are minor " -"errors." -msgstr "" +msgid "If set, the wizard will continue to the next step even if there are minor errors." +msgstr "Si está establecido, el asistente continuará al siguiente paso aunque haya errores." #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart -msgid "" -"If you leave these options set, the wizard will not just create new records," -" but also update records with changes (i.e. different tax amount)" -msgstr "" +msgid "If you leave these options set, the wizard will not just create new records, but also update records with changes (i.e. different tax amount)" +msgstr "Si deja estas opciones establecidas, el asistente no solo crearé nuevos registros, si no que también actualizará registros con cambios (por ejemplo, diferente importe de impuesto)" #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_chart_template_ids msgid "Includes all chart templates." -msgstr "" +msgstr "Incluye todos los planes contables." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_lang msgid "Language" -msgstr "" +msgstr "Idioma" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts___last_update @@ -251,7 +237,7 @@ msgstr "" #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position___last_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax___last_update msgid "Last Modified on" -msgstr "Última modificación el" +msgstr "Última modificación en" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_write_uid @@ -267,110 +253,125 @@ msgstr "Última actualización por" #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_write_date #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_write_date msgid "Last Updated on" -msgstr "Última actualización en" +msgstr "Última actualización el" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Log" -msgstr "" +msgstr "Registro (Log)" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_log msgid "Messages and Errors" -msgstr "" +msgstr "Mensajes y errores" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:478 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:474 #, python-format msgid "Name or description not found." -msgstr "" +msgstr "Nombre o descripción no encontrada." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_new_accounts msgid "New accounts" -msgstr "" +msgstr "Nuevas cuentas" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_new_fps msgid "New fiscal positions" -msgstr "" +msgstr "Nuevas posiciones fiscales" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_new_taxes msgid "New taxes" -msgstr "" +msgstr "Nuevos impuestos" #. module: account_chart_update #: selection:wizard.update.charts.accounts.account,type:0 #: selection:wizard.update.charts.accounts.fiscal.position,type:0 #: selection:wizard.update.charts.accounts.tax,type:0 msgid "New template" -msgstr "" +msgstr "Nueva plantilla" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Next" -msgstr "" +msgstr "Siguiente" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:524 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:517 #, python-format msgid "No account found with this code." -msgstr "" +msgstr "No se ha encontrado cuenta con este código." #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:557 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:551 #, python-format msgid "No fiscal position found with this name." -msgstr "" +msgstr "No se ha encontrado posición fiscal con este nombre." #. module: account_chart_update #: model:ir.model.fields,help:account_chart_update.field_wizard_update_charts_accounts_code_digits -msgid "" -"No. of digits to use for account code. Make sure it is the same number as " -"existing accounts." -msgstr "" +msgid "No. of digits to use for account code. Make sure it is the same number as existing accounts." +msgstr "Nº de dígitos a usar para el código de cuenta. Asegúrese que es el mismo número que las cuentas existentes." #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Note: Only the changed fields are updated." -msgstr "" +msgstr "Nota: Solo los campos cambiados se actualizan." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_notes #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position_notes #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_notes msgid "Notes" -msgstr "" +msgstr "Notas" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:233 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:246 #, python-format -msgid "" -"One or more errors detected!\n" +msgid "One or more errors detected!\n" +"\n" +"%s" +msgstr "Se ha detectado uno o más errores\n" "\n" "%s" -msgstr "" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Other options" -msgstr "" +msgstr "Otras opciones" + +#. module: account_chart_update +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:667 +#, python-format +msgid "Post-updated tax %s." +msgstr "Impuesto %s post-actualizado." #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Previous" -msgstr "" +msgstr "Anterior" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Records to create/update" -msgstr "" +msgstr "Registros a crear/actualizar" + +#. module: account_chart_update +#: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_rejected_new_account_number +msgid "Rejected new account number" +msgstr "Número de nuevas cuentas rechazadas" + +#. module: account_chart_update +#: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_rejected_updated_account_number +msgid "Rejected updated account number" +msgstr "Número de cuentas a actualizar rechazadas" #. module: account_chart_update #: selection:wizard.update.charts.accounts,state:0 msgid "Select records to update" -msgstr "" +msgstr "Seleccione registros a actualizar" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_state @@ -380,62 +381,60 @@ msgstr "Estado" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Summary of created objects" -msgstr "" +msgstr "Resumen de objetos creados" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Summary of updated objects" -msgstr "" +msgstr "Resumen de objetos actualizados" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_type_tax_use msgid "Tax Scope" -msgstr "" +msgstr "Ámbito del impuesto" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:458 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:456 #, python-format msgid "Tax is disabled." -msgstr "" +msgstr "Impuesto desactivado." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_tax_id msgid "Tax template" -msgstr "" +msgstr "Plantilla de impuesto" #. module: account_chart_update #: model:ir.model,name:account_chart_update.model_wizard_update_charts_accounts_tax msgid "Tax that needs to be updated (new or updated in the template)." -msgstr "" +msgstr "Impuesto que necesita ser actualizado (nuevo o modificado en la plantilla)." #. module: account_chart_update #: selection:wizard.update.charts.accounts.tax,type:0 msgid "Tax to deactivate" -msgstr "" +msgstr "Impuesto a deactivar" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_update_tax_id msgid "Tax to update" -msgstr "" +msgstr "Impuesto a actualizar" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_ids #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Taxes" -msgstr "" +msgstr "Impuestos" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart -msgid "" -"This wizard will update your accounts, taxes and fiscal positions according " -"to the selected chart template" -msgstr "" +msgid "This wizard will update your accounts, taxes and fiscal positions according to the selected chart template" +msgstr "Este asistente actualizará sus cuentas, impuestos y posiciones fiscales de acuerdo con el plan contable seleccionado" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:506 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:501 #, python-format msgid "To deactivate: not in the template" -msgstr "" +msgstr "A deactivar: no está en la plantilla" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_type @@ -447,80 +446,80 @@ msgstr "Tipo" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_update_account msgid "Update accounts" -msgstr "" +msgstr "Actualizar cuentas" #. module: account_chart_update #: model:ir.actions.act_window,name:account_chart_update.action_wizard_update_chart msgid "Update chart of accounts" -msgstr "" +msgstr "Actualizar plan contable" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_account_config_settings msgid "Update chart template" -msgstr "" +msgstr "Actualizar plan contable" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_account_update_chart_wizard_id #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_fiscal_position_update_chart_wizard_id #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_tax_update_chart_wizard_id msgid "Update chart wizard" -msgstr "" +msgstr "Asistente de actualización de plan contable" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_update_fiscal_position msgid "Update fiscal positions" -msgstr "" +msgstr "Actualizar posiciones fiscales" #. module: account_chart_update #: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart msgid "Update records?" -msgstr "" +msgstr "¿Actualizar registros?" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_update_tax msgid "Update taxes" -msgstr "" +msgstr "Actualizar impuestos" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:638 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:635 #, python-format msgid "Updated account %s." -msgstr "" +msgstr "Cuenta %s actualizada." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_updated_accounts msgid "Updated accounts" -msgstr "" +msgstr "Cuentas actualizadas" #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_updated_fps msgid "Updated fiscal positions" -msgstr "" +msgstr "Posiciones fiscales actualizadas" #. module: account_chart_update -#: code:addons/account_chart_update/wizard/wizard_chart_update.py:593 +#: code:addons/account_chart_update/wizard/wizard_chart_update.py:588 #, python-format msgid "Updated tax %s." -msgstr "" +msgstr "Impuesto %s actualizado." #. module: account_chart_update #: model:ir.model.fields,field_description:account_chart_update.field_wizard_update_charts_accounts_updated_taxes msgid "Updated taxes" -msgstr "" +msgstr "Impuestos actualizados" #. module: account_chart_update #: selection:wizard.update.charts.accounts.account,type:0 #: selection:wizard.update.charts.accounts.fiscal.position,type:0 #: selection:wizard.update.charts.accounts.tax,type:0 msgid "Updated template" -msgstr "" +msgstr "Plantilla actualizada" #. module: account_chart_update #: selection:wizard.update.charts.accounts,state:0 msgid "Wizard completed" -msgstr "" +msgstr "Asistente completado" #. module: account_chart_update #: model:ir.model,name:account_chart_update.model_wizard_update_charts_accounts msgid "wizard.update.charts.accounts" -msgstr "" +msgstr "wizard.update.charts.accounts" diff --git a/account_chart_update/readme/CONTRIBUTORS.rst b/account_chart_update/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..f247d64d --- /dev/null +++ b/account_chart_update/readme/CONTRIBUTORS.rst @@ -0,0 +1,6 @@ +* Pedro M. Baeza +* Jairo Llopis +* Jacques-Etienne Baudoux +* Sylvain Van Hoof +* Nacho Muñoz + diff --git a/account_chart_update/readme/DESCRIPTION.rst b/account_chart_update/readme/DESCRIPTION.rst new file mode 100644 index 00000000..16bcfce3 --- /dev/null +++ b/account_chart_update/readme/DESCRIPTION.rst @@ -0,0 +1,12 @@ +This is a pretty useful tool to update Odoo installations after tax reforms +on the official charts of accounts, or to apply fixes performed on the chart +template. + +The wizard: + +* Allows the user to compare a chart and a template showing differences + on accounts, taxes, tax codes and fiscal positions. +* It may create the new account, taxes, tax codes and fiscal positions detected + on the template. +* It can also update (overwrite) the accounts, taxes, tax codes and fiscal + positions that got modified on the template. diff --git a/account_chart_update/readme/ROADMAP.rst b/account_chart_update/readme/ROADMAP.rst new file mode 100644 index 00000000..40b5a6a8 --- /dev/null +++ b/account_chart_update/readme/ROADMAP.rst @@ -0,0 +1,5 @@ +* Generate and update account reconcile models. +* Generate XML-ID for fiscal position tax and account mapping lines. +* Allow to select independently operations to perform (create, update, + deactivate). +* Detect fiscal positions to deactivate? diff --git a/account_chart_update/readme/USAGE.rst b/account_chart_update/readme/USAGE.rst new file mode 100644 index 00000000..011aafa7 --- /dev/null +++ b/account_chart_update/readme/USAGE.rst @@ -0,0 +1,7 @@ +The wizard, accesible from *Accounting > Settings > Update chart of accounts*, +lets the user select what kind of objects must be checked/updated, and whether +old records must be checked for changes and updates. + +It will display all the objects to be created / updated / deactivated with some +information about the detected differences, and allow the user to exclude +records individually. diff --git a/account_chart_update/static/description/index.html b/account_chart_update/static/description/index.html new file mode 100644 index 00000000..c0d18bef --- /dev/null +++ b/account_chart_update/static/description/index.html @@ -0,0 +1,457 @@ + + + + + + +Detect changes and update the Account Chart from a template + + + +
+

Detect changes and update the Account Chart from a template

+ + +

Mature License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runbot

+

This is a pretty useful tool to update Odoo installations after tax reforms +on the official charts of accounts, or to apply fixes performed on the chart +template.

+

The wizard:

+
    +
  • Allows the user to compare a chart and a template showing differences +on accounts, taxes, tax codes and fiscal positions.
  • +
  • It may create the new account, taxes, tax codes and fiscal positions detected +on the template.
  • +
  • It can also update (overwrite) the accounts, taxes, tax codes and fiscal +positions that got modified on the template.
  • +
+

Table of contents

+ +
+

Usage

+

The wizard, accesible from Accounting > Settings > Update chart of accounts, +lets the user select what kind of objects must be checked/updated, and whether +old records must be checked for changes and updates.

+

It will display all the objects to be created / updated / deactivated with some +information about the detected differences, and allow the user to exclude +records individually.

+
+
+

Known issues / Roadmap

+
    +
  • Generate and update account reconcile models.
  • +
  • Generate XML-ID for fiscal position tax and account mapping lines.
  • +
  • Allow to select independently operations to perform (create, update, +deactivate).
  • +
  • Detect fiscal positions to deactivate?
  • +
+
+
+

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

+
    +
  • Tecnativa
  • +
  • BCIM
  • +
  • Okia
  • +
+
+
+

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.

+

This module is part of the OCA/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/account_chart_update/tests/__init__.py b/account_chart_update/tests/__init__.py new file mode 100644 index 00000000..243c1b0f --- /dev/null +++ b/account_chart_update/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_account_chart_update diff --git a/account_chart_update/tests/test_account_chart_update.py b/account_chart_update/tests/test_account_chart_update.py new file mode 100644 index 00000000..e3b2d026 --- /dev/null +++ b/account_chart_update/tests/test_account_chart_update.py @@ -0,0 +1,306 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields +from odoo.tests import common + + +class TestAccountChartUpdate(common.HttpCase): + at_install = False + post_install = True + + def _create_xml_id(self, record): + return self.env['ir.model.data'].create({ + 'module': 'account_chart_update', + 'name': "%s-%s" % (record._table, record.id), + 'model': record._name, + 'res_id': record.id, + }) + + def _create_account_tmpl(self, name, code, user_type, chart_template): + record = self.env['account.account.template'].create({ + 'name': name, + 'code': code, + 'user_type_id': user_type.id, + 'chart_template_id': chart_template and chart_template.id, + }) + self._create_xml_id(record) + return record + + def _create_tax_tmpl(self, name, chart_template): + record = self.env['account.tax.template'].create({ + 'name': name, + 'amount': 0, + 'chart_template_id': chart_template.id, + 'tax_group_id': self.env.ref('account.tax_group_taxes').id, + }) + self._create_xml_id(record) + return record + + def _create_fp_tmpl(self, name, chart_template): + record = self.env['account.fiscal.position.template'].create({ + 'name': name, + 'chart_template_id': chart_template.id, + }) + self._create_xml_id(record) + return record + + def setUp(self): + super(TestAccountChartUpdate, self).setUp() + # Make sure user is in English + self.env.user.lang = 'en_US' + self.account_type = self.env['account.account.type'].create({ + 'name': 'Test account_chart_update account type', + }) + self.account_template = self._create_account_tmpl( + 'Test', '100000', self.account_type, False, + ) + self.chart_template = self.env['account.chart.template'].create({ + 'name': 'Test account_chart_update chart', + 'currency_id': self.env.ref('base.EUR').id, + 'code_digits': 6, + 'transfer_account_id': self.account_template.id, + }) + self.account_template.chart_template_id = self.chart_template.id + self.account_template_pl = self._create_account_tmpl( + 'Undistributed Profits/Losses', '999999', + self.env.ref("account.data_unaffected_earnings"), + self.chart_template, + ) + self.tax_template = self._create_tax_tmpl( + 'Test tax', self.chart_template, + ) + self.fp_template = self._create_fp_tmpl('Test fp', self.chart_template) + self.fp_template_tax = self.env[ + 'account.fiscal.position.tax.template' + ].create({ + 'tax_src_id': self.tax_template.id, + 'position_id': self.fp_template.id, + }) + self._create_xml_id(self.fp_template_tax) + self.fp_template_account = self.env[ + 'account.fiscal.position.account.template' + ].create({ + 'account_src_id': self.account_template.id, + 'account_dest_id': self.account_template.id, + 'position_id': self.fp_template.id, + }) + self._create_xml_id(self.fp_template_account) + self.tax_group = self.env['account.tax.group'].create({ + 'name': 'Test tax group', + }) + self.company = self.env['res.company'].create({ + 'name': 'Test account_chart_update company', + 'currency_id': self.chart_template.currency_id.id, + }) + # Load chart of template into company + wizard = self.env['wizard.multi.charts.accounts'].create({ + 'company_id': self.company.id, + 'chart_template_id': self.chart_template.id, + 'code_digits': self.chart_template.code_digits, + 'transfer_account_id': self.account_template.id, + 'currency_id': self.chart_template.currency_id.id, + 'bank_account_code_prefix': '572', + 'cash_account_code_prefix': '570', + }) + wizard.onchange_chart_template_id() + wizard.execute() + self.tax = self.env['account.tax'].search([ + ('name', '=', self.tax_template.name), + ('company_id', '=', self.company.id), + ]) + self.account = self.env['account.account'].search([ + ('code', '=', self.account_template.code), + ('company_id', '=', self.company.id), + ]) + self.fp = self.env['account.fiscal.position'].search([ + ('name', '=', self.fp_template.name), + ('company_id', '=', self.company.id), + ]) + # Prepare wizard values + self.wizard_obj = self.env['wizard.update.charts.accounts'] + self.wizard_vals = { + 'company_id': self.company.id, + 'chart_template_id': self.chart_template.id, + 'code_digits': 6, + 'lang': 'en_US' + } + + def test_chart_update(self): + # Test no changes + wizard = self.wizard_obj.create(self.wizard_vals) + wizard.action_find_records() + self.assertEqual(wizard.state, 'ready') + self.assertFalse(wizard.tax_ids) + self.assertFalse(wizard.account_ids) + self.assertFalse(wizard.fiscal_position_ids) + wizard.unlink() + # Add templates + new_tax_tmpl = self._create_tax_tmpl( + 'Test tax 2', self.chart_template, + ) + new_account_tmpl = self._create_account_tmpl( + 'Test account 2', '333333', self.account_type, self.chart_template, + ) + new_fp = self._create_fp_tmpl('Test fp 2', self.chart_template) + fp_template_tax = self.env[ + 'account.fiscal.position.tax.template' + ].create({ + 'tax_src_id': self.tax_template.id, + 'position_id': new_fp.id, + }) + self._create_xml_id(fp_template_tax) + fp_template_account = self.env[ + 'account.fiscal.position.account.template' + ].create({ + 'account_src_id': self.account_template.id, + 'account_dest_id': self.account_template.id, + 'position_id': new_fp.id, + }) + self._create_xml_id(fp_template_account) + # Check that no action is performed if the option is not selected + wizard_vals = self.wizard_vals.copy() + wizard_vals.update({ + 'update_tax': False, + 'update_account': False, + 'update_fiscal_position': False, + }) + wizard = self.wizard_obj.create(wizard_vals) + wizard.action_find_records() + self.assertFalse(wizard.tax_ids) + self.assertFalse(wizard.account_ids) + self.assertFalse(wizard.fiscal_position_ids) + wizard.unlink() + # Now do the real one for detecting additions + wizard = self.wizard_obj.create(self.wizard_vals) + wizard.action_find_records() + self.assertTrue(wizard.tax_ids) + self.assertEqual(wizard.tax_ids.tax_id, new_tax_tmpl) + self.assertEqual(wizard.tax_ids.type, 'new') + self.assertTrue(wizard.account_ids) + self.assertEqual(wizard.account_ids.account_id, new_account_tmpl) + self.assertEqual(wizard.tax_ids.type, 'new') + self.assertTrue(wizard.fiscal_position_ids) + self.assertEqual(wizard.fiscal_position_ids.fiscal_position_id, new_fp) + self.assertEqual(wizard.fiscal_position_ids.type, 'new') + wizard.action_update_records() + self.assertEqual(wizard.state, 'done') + self.assertEqual(wizard.new_taxes, 1) + self.assertEqual(wizard.new_accounts, 1) + self.assertEqual(wizard.new_fps, 1) + self.assertTrue(wizard.log) + new_tax = self.env['account.tax'].search([ + ('name', '=', new_tax_tmpl.name), + ('company_id', '=', self.company.id), + ]) + self.assertTrue(new_tax) + new_account = self.env['account.account'].search([ + ('code', '=', new_account_tmpl.code), + ('company_id', '=', self.company.id), + ]) + self.assertTrue(new_account) + fp = self.env['account.fiscal.position'].search([ + ('name', '=', new_fp.name), + ('company_id', '=', self.company.id), + ]) + self.assertTrue(fp) + self.assertTrue(fp.tax_ids) + self.assertTrue(fp.account_ids) + wizard.unlink() + # Update objects + self.tax_template.description = "Test description" + self.tax_template.tax_group_id = self.tax_group.id + self.tax_template.refund_account_id = new_account_tmpl.id + self.account_template.name = "Other name" + self.fp_template.note = "Test note" + self.fp_template.account_ids.account_dest_id = new_account_tmpl.id + self.fp_template.tax_ids.tax_dest_id = self.tax_template.id + wizard = self.wizard_obj.create(self.wizard_vals) + wizard.action_find_records() + self.assertTrue(wizard.tax_ids) + self.assertEqual(wizard.tax_ids.tax_id, self.tax_template) + self.assertEqual(wizard.tax_ids.type, 'updated') + self.assertTrue(wizard.account_ids) + self.assertEqual(wizard.account_ids.account_id, self.account_template) + self.assertEqual(wizard.account_ids.type, 'updated') + self.assertTrue(wizard.fiscal_position_ids) + self.assertTrue(wizard.fiscal_position_ids.type, 'updated') + self.assertEqual( + wizard.fiscal_position_ids.fiscal_position_id, self.fp_template, + ) + self.assertEqual(wizard.fiscal_position_ids.type, 'updated') + wizard.action_update_records() + self.assertEqual(wizard.updated_taxes, 1) + self.assertEqual(wizard.updated_accounts, 1) + self.assertEqual(wizard.updated_fps, 1) + self.assertEqual(self.tax.description, self.tax_template.description) + self.assertEqual(self.tax.tax_group_id, self.tax_group) + self.assertEqual(self.tax.refund_account_id, new_account) + self.assertEqual(self.account.name, self.account_template.name) + self.assertEqual(self.fp.note, self.fp_template.note) + self.assertEqual(self.fp.account_ids.account_dest_id, new_account) + self.assertEqual(self.fp.tax_ids.tax_dest_id, self.tax) + wizard.unlink() + # Remove objects + new_tax_tmpl.unlink() + wizard = self.wizard_obj.create(self.wizard_vals) + wizard.action_find_records() + self.assertTrue(wizard.tax_ids) + self.assertEqual(wizard.tax_ids.update_tax_id, new_tax) + self.assertEqual(wizard.tax_ids.type, 'deleted') + wizard.action_update_records() + self.assertEqual(wizard.deleted_taxes, 1) + self.assertFalse(new_tax.active) + wizard.unlink() + # Errors on account update + self.account_template.reconcile = True + self.env['account.move'].create({ + 'name': 'Test move', + 'journal_id': self.env['account.journal'].search([ + ('company_id', '=', self.company.id), + ], limit=1).id, + 'date': fields.Date.today(), + 'line_ids': [ + (0, 0, { + 'account_id': self.account.id, + 'name': 'Test move line', + 'debit': 10, + 'credit': 0, + }), + (0, 0, { + 'account_id': self.account.id, + 'name': 'Test move line2', + 'debit': 0, + 'credit': 10, + }), + ] + }) + self.tax_template.description = "Other description" + wizard = self.wizard_obj.create(self.wizard_vals) + wizard.action_find_records() + with self.assertRaises(Exception): + wizard.action_update_records() + # Errors on account update - continuing after that + wizard.continue_on_errors = True + wizard.action_update_records() + self.assertFalse(self.account.reconcile) + self.assertEqual(self.tax.description, self.tax_template.description) + self.assertEqual(wizard.rejected_updated_account_number, 1) + self.assertEqual(wizard.updated_accounts, 0) + wizard.unlink() + # Errors on account_creation + self.account_template.reconcile = False + new_account_tmpl_2 = self._create_account_tmpl( + 'Test account 3', '444444', self.account_type, self.chart_template, + ) + wizard = self.wizard_obj.create(self.wizard_vals) + wizard.action_find_records() + self.assertEqual(wizard.account_ids.type, 'new') + new_account_tmpl_2.code = '333333' # Trick the code for forcing error + with self.assertRaises(Exception): + wizard.action_update_records() + wizard.continue_on_errors = True + wizard.action_update_records() + self.assertEqual(wizard.rejected_new_account_number, 1) + self.assertEqual(wizard.new_accounts, 0) + wizard.unlink() diff --git a/account_chart_update/wizard/__init__.py b/account_chart_update/wizard/__init__.py index 3c52c6a9..3c2acb99 100644 --- a/account_chart_update/wizard/__init__.py +++ b/account_chart_update/wizard/__init__.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -# © 2010 Zikzakmedia S.L. (http://www.zikzakmedia.com) -# © 2010 Pexego Sistemas Informáticos S.L.(http://www.pexego.es) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import wizard_chart_update diff --git a/account_chart_update/wizard/wizard_chart_update.py b/account_chart_update/wizard/wizard_chart_update.py index 2a76d978..bf16b05e 100644 --- a/account_chart_update/wizard/wizard_chart_update.py +++ b/account_chart_update/wizard/wizard_chart_update.py @@ -6,14 +6,17 @@ # © 2015 Antonio Espinosa # © 2016 Jairo Llopis # © 2016 Jacques-Etienne Baudoux +# Copyright 2018 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from openerp import models, fields, api, exceptions, _, tools +from odoo import _, api, exceptions, fields, models, tools +from odoo.tools import config from contextlib import closing from cStringIO import StringIO import logging _logger = logging.getLogger(__name__) +EXCEPTION_TEXT = u"Traceback (most recent call last)" class WizardUpdateChartsAccounts(models.TransientModel): @@ -76,12 +79,14 @@ class WizardUpdateChartsAccounts(models.TransientModel): new_accounts = fields.Integer( string='New accounts', compute="_compute_new_accounts_count") + rejected_new_account_number = fields.Integer() new_fps = fields.Integer( string='New fiscal positions', compute="_compute_new_fps_count") updated_taxes = fields.Integer( string='Updated taxes', compute="_compute_updated_taxes_count") + rejected_updated_account_number = fields.Integer() updated_accounts = fields.Integer( string='Updated accounts', compute="_compute_updated_accounts_count") @@ -115,7 +120,8 @@ class WizardUpdateChartsAccounts(models.TransientModel): @api.depends('account_ids') def _compute_new_accounts_count(self): self.new_accounts = len( - self.account_ids.filtered(lambda x: x.type == 'new')) + self.account_ids.filtered(lambda x: x.type == 'new') + ) - self.rejected_new_account_number @api.multi @api.depends('fiscal_position_ids') @@ -133,7 +139,8 @@ class WizardUpdateChartsAccounts(models.TransientModel): @api.depends('account_ids') def _compute_updated_accounts_count(self): self.updated_accounts = len( - self.account_ids.filtered(lambda x: x.type == 'updated')) + self.account_ids.filtered(lambda x: x.type == 'updated') + ) - self.rejected_updated_account_number @api.multi @api.depends('fiscal_position_ids') @@ -208,30 +215,35 @@ class WizardUpdateChartsAccounts(models.TransientModel): def action_update_records(self): """Action that creates/updates/deletes the selected elements.""" self = self.with_context(lang=self.lang) - + self.rejected_new_account_number = 0 + self.rejected_updated_account_number = 0 with closing(StringIO()) as log_output: handler = logging.StreamHandler(log_output) _logger.addHandler(handler) - # Create or update the records. if self.update_tax: self._update_taxes() + perform_rest = True if self.update_account: self._update_accounts() - if self.update_fiscal_position: + if (EXCEPTION_TEXT in log_output.getvalue() and + not self.continue_on_errors): # Abort early + perform_rest = False + # Clear this cache for avoiding incorrect account hits (as it was + # queried before account creation) + self.find_account_by_templates.clear_cache(self) + if self.update_tax and perform_rest: + self._update_taxes_pending_for_accounts() + if self.update_fiscal_position and perform_rest: self._update_fiscal_positions() - # Store new chart in the company self.company_id.chart_template_id = self.chart_template_id - _logger.removeHandler(handler) self.log = log_output.getvalue() - # Check if errors where detected and wether we should stop. - if self.log and not self.continue_on_errors: + if EXCEPTION_TEXT in self.log and not self.continue_on_errors: raise exceptions.Warning( _("One or more errors detected!\n\n%s") % self.log) - # Store the data and go to the next step. self.state = 'done' return self._reopen() @@ -295,11 +307,11 @@ class WizardUpdateChartsAccounts(models.TransientModel): pos_id = self.find_fp_by_templates(tpl.position_id) src_id = self.find_account_by_templates(tpl.account_src_id) dest_id = self.find_account_by_templates(tpl.account_dest_id) - mappings = self.env["account.fiscal.position.account"].search([ + existing = self.env["account.fiscal.position.account"].search([ ("position_id", "=", pos_id), ("account_src_id", "=", src_id), + ("account_dest_id", "=", dest_id), ]) - existing = mappings.filtered(lambda x: x.account_dest_id == dest) if not existing: # create a new mapping result.append((0, 0, { @@ -322,11 +334,11 @@ class WizardUpdateChartsAccounts(models.TransientModel): pos_id = self.find_fp_by_templates(tpl.position_id) src_id = self.find_tax_by_templates(tpl.tax_src_id) dest_id = self.find_tax_by_templates(tpl.tax_dest_id) - mappings = self.env["account.fiscal.position.tax"].search([ + existing = self.env["account.fiscal.position.tax"].search([ ("position_id", "=", pos_id), ("tax_src_id", "=", src_id), + ("tax_dest_id", "=", dest_id), ]) - existing = mappings.filtered(lambda x: x.tax_dest_id.id == dest_id) if not existing: # create a new mapping result.append((0, 0, { @@ -342,40 +354,24 @@ class WizardUpdateChartsAccounts(models.TransientModel): return result @api.model - @tools.ormcache("template") - def fields_to_ignore(self, template): + @tools.ormcache("name") + def fields_to_ignore(self, template, name): """Get fields that will not be used when checking differences. - :param str template: - The template record. - - :return set: - Fields to ignore in diff. + :param str template: A template record. + :param str name: The name of the template model. + :return set: Fields to ignore in diff. """ - specials = { + specials_mapping = { + "account.tax.template": { + "children_tax_ids", + }, "account.account.template": { "code", }, - "account.tax.template": { - "account_id", - "refund_account_id", - } } - to_include = { - "account.fiscal.position.template": [ - 'tax_ids', - 'account_ids', - ], - } - specials = ({"display_name", "__last_update"} | - specials.get(template._name, set())) - for key, field in template._fields.iteritems(): - if (template._name in to_include and - key in to_include[template._name]): - continue - if ".template" in field.get_description(self.env).get( - "relation", ""): - specials.add(key) + specials = ({"display_name", "__last_update", "company_id"} | + specials_mapping.get(name, set())) return set(models.MAGIC_COLUMNS) | specials @api.model @@ -391,43 +387,44 @@ class WizardUpdateChartsAccounts(models.TransientModel): Fields that are different in both records, and the expected value. """ result = dict() - ignore = self.fields_to_ignore(template) + ignore = self.fields_to_ignore(template, template._name) for key, field in template._fields.iteritems(): if key in ignore: continue - relation = expected = t = None - # Code must be padded to check equality - if key == "code": - expected = self.padded_code(template.code) + expected = t = None # Translate template records to reals for comparison - else: - relation = field.get_description(self.env).get("relation", "") - if relation: - if ".tax.template" in relation: - t = "tax" - elif ".account.template" in relation: - t = "account" - if t: - find = getattr( - self, - "find_%s%s_by_templates" % ( - "fp_" if ".fiscal.position" in relation - else "", - t)) - if ".fiscal.position" in relation: - # Special case - expected = find(template[key], real[key]) - else: - expected = find(template[key]) + relation = field.get_description(self.env).get("relation", "") + if relation: + if ".tax.template" in relation: + t = "tax" + elif ".account.template" in relation: + t = "account" + if t: + find = getattr( + self, + "find_%s%s_by_templates" % ( + "fp_" if ".fiscal.position" in relation + else "", + t)) + if ".fiscal.position" in relation: + # Special case: if something is returned, then + # there's any difference, so it will get non equal + # when comparing, although we get the warning + # "Comparing apples with oranges" + expected = find(template[key], real[key]) + else: + exp_id = find(template[key]) + expected = self.env[relation[:-9]].browse(exp_id) # Register detected differences try: - if not relation: - if expected is not None and expected != real[key]: + if expected is not None: + if expected != [] and expected != real[key]: result[key] = expected - elif template[key] != real[key]: - result[key] = template[key] - elif expected: - result[key] = expected + elif template[key] != real[key]: + result[key] = template[key] + if isinstance(result.get(key, False), models.Model): + # Avoid to cache recordset references + result[key] = result[key].id except KeyError: pass return result @@ -464,12 +461,10 @@ class WizardUpdateChartsAccounts(models.TransientModel): """Search for, and load, tax templates to create/update/delete.""" found_taxes_ids = [] self.tax_ids.unlink() - # Search for changes between template and real tax for template in self.chart_template_ids.mapped("tax_template_ids"): # Check if the template matches a real tax tax_id = self.find_tax_by_templates(template) - if not tax_id: # Tax to be created self.tax_ids.create({ @@ -480,7 +475,6 @@ class WizardUpdateChartsAccounts(models.TransientModel): }) else: found_taxes_ids.append(tax_id) - # Check the tax for changes tax = self.env['account.tax'].browse(tax_id) notes = self.diff_notes(template, tax) @@ -493,14 +487,13 @@ class WizardUpdateChartsAccounts(models.TransientModel): 'update_tax_id': tax_id, 'notes': notes, }) - # search for taxes not in the template and propose them for # deactivation - taxes_to_delete = self.env['account.tax'].search( + taxes_to_deactivate = self.env['account.tax'].search( [('company_id', '=', self.company_id.id), ("id", "not in", found_taxes_ids), ("active", "=", True)]) - for tax in taxes_to_delete: + for tax in taxes_to_deactivate: self.tax_ids.create({ 'update_chart_wizard_id': self.id, 'type': 'deleted', @@ -512,11 +505,9 @@ class WizardUpdateChartsAccounts(models.TransientModel): def _find_accounts(self): """Load account templates to create/update.""" self.account_ids.unlink() - for template in self.chart_template_ids.mapped("account_ids"): # Search for a real account that matches the template account_id = self.find_account_by_templates(template) - if not account_id: # Account to be created self.account_ids.create({ @@ -581,35 +572,20 @@ class WizardUpdateChartsAccounts(models.TransientModel): # Deactivate tax if wiz_tax.type == 'deleted': tax.active = False - _logger.debug(_("Deactivated tax %s."), tax) + _logger.info(_("Deactivated tax %s."), "'%s'" % tax.name) continue - # Create tax if wiz_tax.type == 'new': - tax = template._generate_tax(self.company_id) - tax = tax['tax_template_to_tax'][template.id] - _logger.debug(_("Created tax %s."), template.name) - + template._generate_tax(self.company_id) + _logger.info(_("Created tax %s."), "'%s'" % template.name) # Update tax else: for key, value in self.diff_fields(template, tax).iteritems(): + # We defer update because account might not be created yet + if key in {'account_id', 'refund_account_id'}: + continue tax[key] = value - _logger.debug(_("Updated tax %s."), template.name) - wiz_tax.update_tax_id = tax - - def _create_account_from_template(self, account_template): - return self.env["account.account"].create({ - 'name': account_template.name, - 'currency_id': account_template.currency_id, - 'code': self.padded_code(account_template.code), - 'user_type_id': account_template.user_type_id.id, - 'reconcile': account_template.reconcile, - 'note': account_template.note, - 'tax_ids': [ - (6, 0, [self.find_tax_by_templates(account_template.tax_ids)]), - ], - 'company_id': self.company_id.id, - }) + _logger.info(_("Updated tax %s."), "'%s'" % template.name) @api.multi def _update_accounts(self): @@ -619,18 +595,35 @@ class WizardUpdateChartsAccounts(models.TransientModel): wiz_account.account_id) if wiz_account.type == 'new': # Create the account + tax_template_ref = { + tax.id: self.find_tax_by_templates(tax) for tax in + template.tax_ids + } + vals = self.chart_template_id._get_account_vals( + self.company_id, template, + self.padded_code(template.code), + tax_template_ref, + ) try: with self.env.cr.savepoint(): - account = ( - self._create_account_from_template( - template)) - _logger.debug( + self.chart_template_id.create_record_with_xmlid( + self.company_id, template, 'account.account', vals, + ) + _logger.info( _("Created account %s."), - account.code) - except exceptions.except_orm: - _logger.exception( - _("Exception creating account %s."), - template.code) + "'%s - %s'" % (vals['code'], vals['name']), + ) + except Exception: + self.rejected_new_account_number += 1 + if config['test_enable']: + _logger.info(EXCEPTION_TEXT) + else: # pragma: no cover + _logger.exception( + "ERROR: " + _("Exception creating account %s."), + "'%s - %s'" % (template.code, template.name), + ) + if not self.continue_on_errors: + break else: # Update the account try: @@ -638,15 +631,21 @@ class WizardUpdateChartsAccounts(models.TransientModel): for key, value in (self.diff_fields(template, account) .iteritems()): account[key] = value - _logger.debug(_("Updated account %s."), account) - except exceptions.except_orm: - _logger.exception( - _("Exception writing account %s."), - account) - wiz_account.update_account_id = account - - if self.update_tax: - self._update_taxes_pending_for_accounts() + _logger.info( + _("Updated account %s."), + "'%s - %s'" % (account.code, account.name), + ) + except Exception: + self.rejected_updated_account_number += 1 + if config['test_enable']: + _logger.info(EXCEPTION_TEXT) + else: # pragma: no cover + _logger.exception( + "ERROR: " + _("Exception writing account %s."), + "'%s - %s'" % (account.code, account.name), + ) + if not self.continue_on_errors: + break @api.multi def _update_taxes_pending_for_accounts(self): @@ -657,10 +656,15 @@ class WizardUpdateChartsAccounts(models.TransientModel): for wiz_tax in self.tax_ids: if wiz_tax.type == "deleted" or not wiz_tax.update_tax_id: continue - - for field in ("account_id", "refund_account_id"): - wiz_tax.update_tax_id[field] = ( - self.find_account_by_templates(wiz_tax.tax_id[field])) + template = wiz_tax.tax_id + tax = wiz_tax.update_tax_id + done = False + for key, value in self.diff_fields(template, tax).iteritems(): + if key in {'account_id', 'refund_account_id'}: + tax[key] = value + done = True + if done: + _logger.info(_("Post-updated tax %s."), "'%s'" % tax.name) def _prepare_fp_vals(self, fp_template): # Tax mappings @@ -698,16 +702,17 @@ class WizardUpdateChartsAccounts(models.TransientModel): wiz_fp.fiscal_position_id) if wiz_fp.type == 'new': # Create a new fiscal position - fp = self.env['account.fiscal.position'].create( - self._prepare_fp_vals(template)) + self.chart_template_id.create_record_with_xmlid( + self.company_id, template, 'account.fiscal.position', + self._prepare_fp_vals(template), + ) else: # Update the given fiscal position for key, value in self.diff_fields(template, fp).iteritems(): fp[key] = value - wiz_fp.update_fiscal_position_id = fp - _logger.debug( + _logger.info( _("Created or updated fiscal position %s."), - template.name) + "'%s'" % template.name) class WizardUpdateChartsAccountsTax(models.TransientModel):