Merge pull request #3 from grindtildeath/10.0_noviat_asset_management

10.0 noviat asset management
This commit is contained in:
Luc De Meyer
2018-10-01 10:46:48 +02:00
committed by GitHub
44 changed files with 2660 additions and 545 deletions

View File

@@ -27,7 +27,7 @@ addon | version | summary
[account_asset_depr_line_cancel](account_asset_depr_line_cancel/) | 10.0.1.0.0 | Assets Management - Cancel button
[account_asset_disposal](account_asset_disposal/) | 10.0.2.0.0 | Makes asset close account move automatically
[account_balance_line](account_balance_line/) | 10.0.1.0.0 | Display balance totals in move line view
[account_chart_update](account_chart_update/) | 10.0.1.0.1 | Wizard to update a company's account chart from a template
[account_chart_update](account_chart_update/) | 10.0.2.0.1 | Wizard to update a company's account chart from a template
[account_check_deposit](account_check_deposit/) | 10.0.1.0.0 | Manage deposit of checks to the bank
[account_credit_control](account_credit_control/) | 10.0.1.3.4 | Account Credit Control
[account_credit_control_dunning_fees](account_credit_control_dunning_fees/) | 10.0.1.0.0 | Credit control dunning fees

View File

@@ -34,7 +34,7 @@ class AccountAsset(models.Model):
inverse_name='asset_id',
string='Entries', readonly=True, copy=False)
move_line_check = fields.Boolean(
compute='_compute_move_line_check', type='boolean',
compute='_compute_move_line_check',
string='Has accounting entries')
name = fields.Char(
string='Asset Name', size=64, required=True,
@@ -93,7 +93,6 @@ class AccountAsset(models.Model):
date_start = fields.Date(
string='Asset Start Date', readonly=True,
states={'draft': [('readonly', False)]},
default=fields.Datetime.now,
help="You should manually add depreciation lines "
"with the depreciations of previous fiscal years "
"if the Depreciation Start Date is different from the date "
@@ -119,8 +118,8 @@ class AccountAsset(models.Model):
comodel_name='res.partner', string='Partner', readonly=True,
states={'draft': [('readonly', False)]})
method = fields.Selection(
selection=lambda self: self.env['account.asset.profile'].
_selection_method(),
selection=lambda self: self.env[
'account.asset.profile']._selection_method(),
string='Computation Method',
required=True, readonly=True,
states={'draft': [('readonly', False)]}, default='linear',
@@ -138,8 +137,9 @@ class AccountAsset(models.Model):
states={'draft': [('readonly', False)]}, default=5,
help="The number of years needed to depreciate your asset")
method_period = fields.Selection(
selection=lambda self: self.env['account.asset.profile'].
_selection_method_period(), string='Period Length',
selection=lambda self: self.env[
'account.asset.profile']._selection_method_period(),
string='Period Length',
required=True, readonly=True,
states={'draft': [('readonly', False)]}, default='year',
help="Period length for the depreciation accounting entries")
@@ -150,8 +150,9 @@ class AccountAsset(models.Model):
string='Degressive Factor', readonly=True,
states={'draft': [('readonly', False)]}, default=0.3)
method_time = fields.Selection(
selection=lambda self: self.env['account.asset.profile'].
_selection_method_time(), string='Time Method',
selection=lambda self: self.env[
'account.asset.profile']._selection_method_time(),
string='Time Method',
required=True, readonly=True,
states={'draft': [('readonly', False)]}, default='year',
help="Choose the method to use to compute the dates and "
@@ -197,8 +198,7 @@ class AccountAsset(models.Model):
@api.model
def _default_company_id(self):
return self.env[
'res.company']._company_default_get('account.asset')
return self.env['res.company']._company_default_get('account.asset')
@api.multi
def _compute_move_line_check(self):
@@ -221,11 +221,12 @@ class AccountAsset(models.Model):
asset.purchase_value - asset.salvage_value
@api.multi
@api.depends('depreciation_base',
@api.depends('type', 'depreciation_base',
'depreciation_line_ids.type',
'depreciation_line_ids.amount',
'depreciation_line_ids.previous_id',
'depreciation_line_ids.init_entry',
'depreciation_line_ids.move_id')
'depreciation_line_ids.move_check',)
def _compute_depreciation(self):
for asset in self:
if asset.type == 'normal':
@@ -250,7 +251,7 @@ class AccountAsset(models.Model):
return res
@api.multi
@api.constrains('method')
@api.constrains('method', 'method_time')
def _check_method(self):
for asset in self:
if asset.method == 'degr-linear' and asset.method_time != 'year':
@@ -259,7 +260,7 @@ class AccountAsset(models.Model):
"Year."))
@api.multi
@api.constrains('date_start', 'method_end')
@api.constrains('date_start', 'method_end', 'method_time')
def _check_dates(self):
for asset in self:
if asset.method_time == 'end':
@@ -267,7 +268,8 @@ class AccountAsset(models.Model):
raise UserError(
_("The Start Date must precede the Ending Date."))
@api.onchange('purchase_value', 'salvage_value', 'date_start', 'method')
@api.onchange('purchase_value', 'salvage_value', 'date_start', 'method',
'depreciation_line_ids.type')
def _onchange_purchase_salvage_value(self):
if self.method in ['linear-limit', 'degr-limit']:
self.depreciation_base = self.purchase_value or 0.0
@@ -334,9 +336,9 @@ class AccountAsset(models.Model):
if vals.get('method_time'):
if vals['method_time'] != 'year' and not vals.get('prorata'):
vals['prorata'] = True
super(AccountAsset, self).write(vals)
for asset in self:
asset_type = vals.get('type') or asset.type
super(AccountAsset, self).write(vals)
if asset_type == 'view' or \
self._context.get('asset_validate_from_write'):
continue
@@ -479,7 +481,7 @@ class AccountAsset(models.Model):
'|', ('move_check', '=', True), ('init_entry', '=', True)]
posted_lines = line_obj.search(
domain, order='line_date desc')
if (len(posted_lines) > 0):
if posted_lines:
last_line = posted_lines[0]
else:
last_line = line_obj
@@ -521,7 +523,7 @@ class AccountAsset(models.Model):
# check table with posted entries and
# recompute in case of deviation
depreciated_value_posted = depreciated_value = 0.0
if (len(posted_lines) > 0):
if posted_lines:
last_depreciation_date = datetime.strptime(
last_line.line_date, '%Y-%m-%d')
last_date_in_table = table[-1]['lines'][-1]['date']

View File

@@ -65,7 +65,7 @@ class AccountAssetLine(models.Model):
help="Set this flag for entries of previous fiscal years "
"for which OpenERP has not generated accounting entries.")
@api.depends('amount', 'previous_id')
@api.depends('amount', 'previous_id', 'type')
@api.multi
def _compute_values(self):
dlines = self

View File

@@ -109,8 +109,7 @@ class AccountAssetProfile(models.Model):
@api.model
def _default_company_id(self):
return self.env[
'res.company']._company_default_get('account.asset')
return self.env['res.company']._company_default_get('account.asset')
@api.model
def _selection_method(self):

View File

@@ -24,8 +24,8 @@ class TestAssetManagement(common.TransactionCase):
super(TestAssetManagement, self).setUp()
self._load('account', 'test', 'account_minimal_test.xml')
self._load('account_asset_management', 'demo',
'account_asset_demo.xml')
self._load('account_asset_management', 'tests',
'account_asset_test_data.xml')
# ENVIRONEMENTS
self.asset_model = self.env['account.asset']

View File

@@ -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,57 +38,74 @@ 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
<https://github.com/OCA/account-financial-tools/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 <https://github.com/OCA/account-financial-tools/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 <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_chart_update%0Aversion:%2010.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Tecnativa
* BCIM
* Okia
Contributors
------------
~~~~~~~~~~~~
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Jairo Llopis <jairo.llopis@tecnativa.com>
* Jacques-Etienne Baudoux <je@bcim.be>
* Sylvain Van Hoof <sylvain@okia.be>
* Nacho Muñoz <nacmuro@gmail.com>
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 <https://github.com/OCA/account-financial-tools/tree/10.0/account_chart_update>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -1,27 +1,22 @@
# -*- coding: utf-8 -*-
# Copyright 2015-2017 Pedro Manuel Baeza <pedro.baeza@tecnativa.com>
# Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
# Copyright 2016 Jacques-Etienne Baudoux <je@bcim.be>
# Copyright 2016 Sylvain Van Hoof <sylvain@okia.be>
# 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.1",
'version': "10.0.2.0.1",
'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'
],
'development_status': 'Mature',
'category': "Accounting",
'license': "AGPL-3",
"data": [
'wizard/wizard_chart_update_view.xml',

View File

@@ -85,7 +85,7 @@ msgid "Create/Update"
msgstr ""
#. 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:616
#, python-format
msgid "Created account %s."
msgstr ""
@@ -107,19 +107,19 @@ msgid "Created on"
msgstr ""
#. 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:717
#, 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
#: code:addons/account_chart_update/wizard/wizard_chart_update.py:583
#, python-format
msgid "Created tax %s."
msgstr ""
#. module: account_chart_update
#: code:addons/account_chart_update/wizard/wizard_chart_update.py:580
#: code:addons/account_chart_update/wizard/wizard_chart_update.py:578
#, python-format
msgid "Deactivated tax %s."
msgstr ""
@@ -149,13 +149,13 @@ msgid "Display Name"
msgstr ""
#. 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:625
#, python-format
msgid "Exception creating account %s."
msgstr ""
#. 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:647
#, python-format
msgid "Exception writing account %s."
msgstr ""
@@ -264,7 +264,7 @@ msgid "Messages and Errors"
msgstr ""
#. 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:477
#, python-format
msgid "Name or description not found."
msgstr ""
@@ -297,13 +297,13 @@ msgid "Next"
msgstr ""
#. 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:520
#, python-format
msgid "No account found with this code."
msgstr ""
#. 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:554
#, python-format
msgid "No fiscal position found with this name."
msgstr ""
@@ -326,7 +326,7 @@ msgid "Notes"
msgstr ""
#. 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"
"\n"
@@ -338,6 +338,12 @@ msgstr ""
msgid "Other options"
msgstr ""
#. module: account_chart_update
#: code:addons/account_chart_update/wizard/wizard_chart_update.py:670
#, python-format
msgid "Post-updated tax %s."
msgstr ""
#. module: account_chart_update
#: model:ir.ui.view,arch_db:account_chart_update.view_update_multi_chart
msgid "Previous"
@@ -348,6 +354,16 @@ msgstr ""
msgid "Records to create/update"
msgstr ""
#. 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 ""
#. 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 ""
#. module: account_chart_update
#: selection:wizard.update.charts.accounts,state:0
msgid "Select records to update"
@@ -411,7 +427,7 @@ msgid "This wizard will update your accounts, taxes and fiscal positions accordi
msgstr ""
#. 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:504
#, python-format
msgid "To deactivate: not in the template"
msgstr ""
@@ -477,7 +493,7 @@ msgid "Updated fiscal positions"
msgstr ""
#. 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:591
#, python-format
msgid "Updated tax %s."
msgstr ""

View File

@@ -1,73 +1,70 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_chart_update
# * account_chart_update
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
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 <transbot@odoo-community.org>, 2017\n"
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n"
"Language: 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"
"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 "<span states=\"init,ready\"> or </span>"
msgstr ""
msgstr "<span states=\"init,ready\"> o </span>"
#. 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,64 +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
@@ -222,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
@@ -250,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
@@ -266,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
@@ -379,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
@@ -446,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"

View File

@@ -0,0 +1,6 @@
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Jairo Llopis <jairo.llopis@tecnativa.com>
* Jacques-Etienne Baudoux <je@bcim.be>
* Sylvain Van Hoof <sylvain@okia.be>
* Nacho Muñoz <nacmuro@gmail.com>

View File

@@ -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.

View File

@@ -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?

View File

@@ -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.

View File

@@ -0,0 +1,457 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Detect changes and update the Account Chart from a template</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="detect-changes-and-update-the-account-chart-from-a-template">
<h1 class="title">Detect changes and update the Account Chart from a template</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Mature" src="https://img.shields.io/badge/maturity-Mature-brightgreen.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/10.0/account_chart_update"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/account-financial-tools-10-0/account-financial-tools-10-0-account_chart_update"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/92/10.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>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.</p>
<p>The wizard:</p>
<ul class="simple">
<li>Allows the user to compare a chart and a template showing differences
on accounts, taxes, tax codes and fiscal positions.</li>
<li>It may create the new account, taxes, tax codes and fiscal positions detected
on the template.</li>
<li>It can also update (overwrite) the accounts, taxes, tax codes and fiscal
positions that got modified on the template.</li>
</ul>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id2">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id1">Usage</a></h1>
<p>The wizard, accesible from <em>Accounting &gt; Settings &gt; Update chart of accounts</em>,
lets the user select what kind of objects must be checked/updated, and whether
old records must be checked for changes and updates.</p>
<p>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.</p>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id2">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Generate and update account reconcile models.</li>
<li>Generate XML-ID for fiscal position tax and account mapping lines.</li>
<li>Allow to select independently operations to perform (create, update,
deactivate).</li>
<li>Detect fiscal positions to deactivate?</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_chart_update%0Aversion:%2010.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id4">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
<li>BCIM</li>
<li>Okia</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<ul class="simple">
<li>Pedro M. Baeza &lt;<a class="reference external" href="mailto:pedro.baeza&#64;tecnativa.com">pedro.baeza&#64;tecnativa.com</a>&gt;</li>
<li>Jairo Llopis &lt;<a class="reference external" href="mailto:jairo.llopis&#64;tecnativa.com">jairo.llopis&#64;tecnativa.com</a>&gt;</li>
<li>Jacques-Etienne Baudoux &lt;<a class="reference external" href="mailto:je&#64;bcim.be">je&#64;bcim.be</a>&gt;</li>
<li>Sylvain Van Hoof &lt;<a class="reference external" href="mailto:sylvain&#64;okia.be">sylvain&#64;okia.be</a>&gt;</li>
<li>Nacho Muñoz &lt;<a class="reference external" href="mailto:nacmuro&#64;gmail.com">nacmuro&#64;gmail.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/10.0/account_chart_update">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -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

View File

@@ -0,0 +1,317 @@
# -*- 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.account_tag_1 = self.env['account.account.tag'].create({
'name': 'Test account tag 1',
})
self.account_tag_2 = self.env['account.account.tag'].create({
'name': 'Test account tag 2',
})
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.account_template.tag_ids = [
(6, 0, [self.account_tag_1.id, self.account_tag_2.id]),
]
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.assertIn(self.account_tag_1, self.account.tag_ids)
self.assertIn(self.account_tag_2, self.account.tag_ids)
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()

View File

@@ -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

View File

@@ -6,14 +6,17 @@
# © 2015 Antonio Espinosa <antonioea@tecnativa.com>
# © 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
# © 2016 Jacques-Etienne Baudoux <je@bcim.be>
# 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().decode('utf-8') 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()
@@ -262,7 +274,7 @@ class WizardUpdateChartsAccounts(models.TransientModel):
("type_tax_use", "=", template.type_tax_use)],
limit=1)
result |= single
return result
return result[:1].id
@api.model
@tools.ormcache("code")
@@ -276,7 +288,8 @@ class WizardUpdateChartsAccounts(models.TransientModel):
"""Find an account that matches the template."""
return self.env['account.account'].search(
[('code', 'in', map(self.padded_code, templates.mapped("code"))),
('company_id', '=', self.company_id.id)])
('company_id', '=', self.company_id.id)],
).id
@api.multi
@tools.ormcache("templates")
@@ -284,27 +297,27 @@ class WizardUpdateChartsAccounts(models.TransientModel):
"""Find a real fiscal position from a template."""
return self.env['account.fiscal.position'].search(
[('name', 'in', templates.mapped("name")),
('company_id', '=', self.company_id.id)])
('company_id', '=', self.company_id.id)], limit=1).id
@api.multi
@tools.ormcache("templates", "current_fp_accounts")
def find_fp_account_by_templates(self, templates, current_fp_accounts):
result = []
for tpl in templates:
pos = self.find_fp_by_templates(tpl.position_id)
src = self.find_account_by_templates(tpl.account_src_id)
dest = self.find_account_by_templates(tpl.account_dest_id)
mappings = self.env["account.fiscal.position.account"].search([
("position_id", "=", pos.id),
("account_src_id", "=", src.id),
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)
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, {
'position_id': pos.id,
'account_src_id': src.id,
'account_dest_id': dest.id,
'position_id': pos_id,
'account_src_id': src_id,
'account_dest_id': dest_id,
}))
else:
current_fp_accounts -= existing
@@ -318,20 +331,20 @@ class WizardUpdateChartsAccounts(models.TransientModel):
def find_fp_tax_by_templates(self, templates, current_fp_taxes):
result = []
for tpl in templates:
pos = self.find_fp_by_templates(tpl.position_id)
src = self.find_tax_by_templates(tpl.tax_src_id)
dest = self.find_tax_by_templates(tpl.tax_dest_id)
mappings = self.env["account.fiscal.position.tax"].search([
("position_id", "=", pos.id),
("tax_src_id", "=", src.id),
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)
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 == dest)
if not existing:
# create a new mapping
result.append((0, 0, {
'position_id': pos.id,
'tax_src_id': src.id,
'tax_dest_id': dest.id,
'position_id': pos_id,
'tax_src_id': src_id,
'tax_dest_id': dest_id,
}))
else:
current_fp_taxes -= existing
@@ -341,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
@@ -390,43 +387,46 @@ 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]
# Avoid to cache recordset references
if isinstance(real._fields[key], fields.Many2many):
result[key] = [(6, 0, result[key].ids)]
elif isinstance(real._fields[key], fields.Many2one):
result[key] = result[key].id
except KeyError:
pass
return result
@@ -461,15 +461,14 @@ class WizardUpdateChartsAccounts(models.TransientModel):
@api.multi
def _find_taxes(self):
"""Search for, and load, tax templates to create/update/delete."""
found_taxes = self.env["account.tax"]
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"):
for template in self.chart_template_ids.\
with_context(active_test=False).mapped("tax_template_ids"):
# Check if the template matches a real tax
tax = self.find_tax_by_templates(template)
if not tax:
tax_id = self.find_tax_by_templates(template)
if not tax_id:
# Tax to be created
self.tax_ids.create({
'tax_id': template.id,
@@ -478,9 +477,9 @@ class WizardUpdateChartsAccounts(models.TransientModel):
'notes': _('Name or description not found.'),
})
else:
found_taxes |= tax
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)
if notes:
# Tax to be updated
@@ -488,17 +487,16 @@ class WizardUpdateChartsAccounts(models.TransientModel):
'tax_id': template.id,
'update_chart_wizard_id': self.id,
'type': 'updated',
'update_tax_id': tax.id,
'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),
("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',
@@ -510,12 +508,10 @@ 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 = self.find_account_by_templates(template)
if not account:
account_id = self.find_account_by_templates(template)
if not account_id:
# Account to be created
self.account_ids.create({
'account_id': template.id,
@@ -525,6 +521,7 @@ class WizardUpdateChartsAccounts(models.TransientModel):
})
else:
# Check the account for changes
account = self.env['account.account'].browse(account_id)
notes = self.diff_notes(template, account)
if notes:
# Account to be updated
@@ -532,7 +529,7 @@ class WizardUpdateChartsAccounts(models.TransientModel):
'account_id': template.id,
'update_chart_wizard_id': self.id,
'type': 'updated',
'update_account_id': account.id,
'update_account_id': account_id,
'notes': notes,
})
@@ -547,8 +544,8 @@ class WizardUpdateChartsAccounts(models.TransientModel):
[('chart_template_id', 'in', self.chart_template_ids.ids)])
for template in templates:
# Search for a real fiscal position that matches the template
fp = self.find_fp_by_templates(template)
if not fp:
fp_id = self.find_fp_by_templates(template)
if not fp_id:
# Fiscal position to be created
wiz_fp.create({
'fiscal_position_id': template.id,
@@ -558,6 +555,7 @@ class WizardUpdateChartsAccounts(models.TransientModel):
})
else:
# Check the fiscal position for changes
fp = self.env['account.fiscal.position'].browse(fp_id)
notes = self.diff_notes(template, fp)
if notes:
# Fiscal position template to be updated
@@ -565,7 +563,7 @@ class WizardUpdateChartsAccounts(models.TransientModel):
'fiscal_position_id': template.id,
'update_chart_wizard_id': self.id,
'type': 'updated',
'update_fiscal_position_id': fp.id,
'update_fiscal_position_id': fp_id,
'notes': notes,
})
@@ -577,36 +575,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).ids),
],
'company_id': self.company_id.id,
})
_logger.info(_("Updated tax %s."), "'%s'" % template.name)
@api.multi
def _update_accounts(self):
@@ -616,18 +598,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:
@@ -635,15 +634,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):
@@ -654,10 +659,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
@@ -665,10 +675,8 @@ class WizardUpdateChartsAccounts(models.TransientModel):
for fp_tax in fp_template.tax_ids:
# Create the fp tax mapping
tax_mapping.append({
'tax_src_id': self.find_tax_by_templates(
fp_tax.tax_src_id).id,
'tax_dest_id': self.find_tax_by_templates(
fp_tax.tax_dest_id).id,
'tax_src_id': self.find_tax_by_templates(fp_tax.tax_src_id),
'tax_dest_id': self.find_tax_by_templates(fp_tax.tax_dest_id),
})
# Account mappings
account_mapping = []
@@ -676,11 +684,11 @@ class WizardUpdateChartsAccounts(models.TransientModel):
# Create the fp account mapping
account_mapping.append({
'account_src_id': (
self.find_account_by_templates(
fp_account.account_src_id).id),
self.find_account_by_templates(fp_account.account_src_id)
),
'account_dest_id': (
self.find_account_by_templates(
fp_account.account_dest_id).id),
self.find_account_by_templates(fp_account.account_dest_id)
),
})
return {
'company_id': self.company_id.id,
@@ -697,16 +705,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):

File diff suppressed because it is too large Load Diff

115
account_group/README.rst Normal file
View File

@@ -0,0 +1,115 @@
===================
Groups for accounts
===================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github
:target: https://github.com/OCA/account-financial-tools/tree/10.0/account_group
: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_group
: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 modules brings to version 10 the account group feature from v11.
It also includes a level field for indicating the level depth of the account
group.
**Table of contents**
.. contents::
:local:
Installation
============
If you have already the chart of accounts loaded on your company, you will
need to update it through the module `account_chart_update`. Follow the
instructions on that module for that.
Configuration
=============
To configure account groups, you need to:
#. Be "Account / Adviser" role.
#. Go to *Invoicing/Accounting > Configuration > Accounting > Accounts Groups*.
#. Create or modify existing groups.
For assigning groups to account templates, you have to:
#. Set the group on your account chart module or extension.
#. Or develop/create UI access.
When you have groups on your account templates, you can load a chart template
for a new company, and they will be transferred to created accounts.
Usage
=====
For assigning groups to accounts:
#. Go to *Invoicing > Adviser > Chart of Accounts*.
#. Edit one account and set "Group" field.
Known issues / Roadmap
======================
* This module shouldn't be migrated to v11, as it's a native feature.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/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 <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_group%0Aversion:%2010.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Tecnativa
Contributors
~~~~~~~~~~~~
* `Tecnativa <https://www.tecnativa.com>`__:
* Pedro M. Baeza
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/10.0/account_group>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,4 @@
# coding: utf-8
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models

View File

@@ -0,0 +1,22 @@
# coding: utf-8
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Groups for accounts",
"summary": "Use v11 account groups feature",
"version": "10.0.1.0.0",
"category": "Accounting",
"website": "https://github.com/OCA/account-financial-tools",
"author": "Tecnativa,"
"Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": [
"account",
],
"data": [
"security/ir.model.access.csv",
"views/account_account_views.xml",
"views/account_group_views.xml",
],
}

View File

@@ -0,0 +1,130 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_group
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.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: account_group
#: model:ir.model,name:account_group.model_account_account
msgid "Account"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_account_ids
msgid "Accounts"
msgstr ""
#. module: account_group
#: model:ir.ui.view,arch_db:account_group.view_account_group_form
#: model:ir.ui.view,arch_db:account_group.view_account_group_search
#: model:ir.ui.view,arch_db:account_group.view_account_group_tree
msgid "Accounts Group"
msgstr ""
#. module: account_group
#: model:ir.actions.act_window,name:account_group.action_account_group_tree
#: model:ir.ui.menu,name:account_group.account_group_menu
#: model:ir.ui.view,arch_db:account_group.view_account_group_search
msgid "Accounts Groups"
msgstr ""
#. module: account_group
#: model:ir.model.fields,help:account_group.field_account_group_account_ids
msgid "Assigned accounts."
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_code_prefix
msgid "Code prefix"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_create_uid
msgid "Created by"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_create_date
msgid "Created on"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_display_name
msgid "Display Name"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_account_group_id
#: model:ir.model.fields,field_description:account_group.field_account_account_template_group_id
msgid "Group"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_id
msgid "ID"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group___last_update
msgid "Last Modified on"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_write_date
msgid "Last Updated on"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_parent_left
msgid "Left Parent"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_level
msgid "Level"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_name
msgid "Name"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_parent_id
msgid "Parent"
msgstr ""
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_parent_right
msgid "Right Parent"
msgstr ""
#. module: account_group
#: model:ir.model,name:account_group.model_account_chart_template
msgid "Templates for Account Chart"
msgstr ""
#. module: account_group
#: model:ir.model,name:account_group.model_account_account_template
msgid "Templates for Accounts"
msgstr ""
#. module: account_group
#: model:ir.model,name:account_group.model_account_group
msgid "account.group"
msgstr ""

132
account_group/i18n/es.po Normal file
View File

@@ -0,0 +1,132 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_group
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-09-17 17:46+0000\n"
"PO-Revision-Date: 2018-09-17 17:46+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_group
#: model:ir.model,name:account_group.model_account_account
msgid "Account"
msgstr "Cuenta"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_account_ids
msgid "Accounts"
msgstr "Cuentas"
#. module: account_group
#: model:ir.ui.view,arch_db:account_group.view_account_group_form
#: model:ir.ui.view,arch_db:account_group.view_account_group_search
#: model:ir.ui.view,arch_db:account_group.view_account_group_tree
msgid "Accounts Group"
msgstr "Grupo de cuentas"
#. module: account_group
#: model:ir.actions.act_window,name:account_group.action_account_group_tree
#: model:ir.ui.menu,name:account_group.account_group_menu
#: model:ir.ui.view,arch_db:account_group.view_account_group_search
msgid "Accounts Groups"
msgstr "Grupos de cuentas"
#. module: account_group
#: model:ir.model.fields,help:account_group.field_account_group_account_ids
msgid "Assigned accounts."
msgstr "Cuentas asignadas"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_code_prefix
msgid "Code prefix"
msgstr "Código prefijo"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_create_uid
msgid "Created by"
msgstr "Creado por"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_create_date
msgid "Created on"
msgstr "Creado el"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_display_name
msgid "Display Name"
msgstr "Nombre a mostrar"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_account_group_id
#: model:ir.model.fields,field_description:account_group.field_account_account_template_group_id
msgid "Group"
msgstr "Grupo"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_id
msgid "ID"
msgstr "ID"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group___last_update
msgid "Last Modified on"
msgstr "Última modificación en"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_write_uid
msgid "Last Updated by"
msgstr "Última actualización por"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_write_date
msgid "Last Updated on"
msgstr "Última actualización el"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_parent_left
msgid "Left Parent"
msgstr "Padre izquierdo"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_level
msgid "Level"
msgstr "Nivel"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_name
msgid "Name"
msgstr "Nombre"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_parent_id
msgid "Parent"
msgstr "Padre"
#. module: account_group
#: model:ir.model.fields,field_description:account_group.field_account_group_parent_right
msgid "Right Parent"
msgstr "Padre derecho"
#. module: account_group
#: model:ir.model,name:account_group.model_account_chart_template
msgid "Templates for Account Chart"
msgstr "Plantillas de plan contable"
#. module: account_group
#: model:ir.model,name:account_group.model_account_account_template
msgid "Templates for Accounts"
msgstr "Plantillas de cuentas"
#. module: account_group
#: model:ir.model,name:account_group.model_account_group
msgid "account.group"
msgstr "account.group"

View File

@@ -0,0 +1,7 @@
# coding: utf-8
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import account_account
from . import account_account_template
from . import account_chart_template
from . import account_group

View File

@@ -0,0 +1,30 @@
# coding: utf-8
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class AccountAccount(models.Model):
_inherit = "account.account"
group_id = fields.Many2one(
comodel_name='account.group',
string="Group",
)
@api.onchange('code')
def onchange_code(self):
AccountGroup = self.env['account.group']
group = False
code_prefix = self.code
# find group with longest matching prefix
while code_prefix:
matching_group = AccountGroup.search([
('code_prefix', '=', code_prefix),
], limit=1)
if matching_group:
group = matching_group
break
code_prefix = code_prefix[:-1]
self.group_id = group

View File

@@ -0,0 +1,14 @@
# coding: utf-8
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class AccountAccountTemplate(models.Model):
_inherit = "account.account.template"
group_id = fields.Many2one(
comodel_name='account.group',
string="Group",
)

View File

@@ -0,0 +1,18 @@
# coding: utf-8
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import models
class AccountChartTemplate(models.Model):
_inherit = "account.chart.template"
def _get_account_vals(self, company, account_template, code_acc,
tax_template_ref):
"""Add account group to created accounts."""
res = super(AccountChartTemplate, self)._get_account_vals(
company, account_template, code_acc, tax_template_ref,
)
res['group_id'] = account_template.group_id.id
return res

View File

@@ -0,0 +1,74 @@
# coding: utf-8
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.osv import expression
class AccountGroup(models.Model):
_name = 'account.group'
_parent_store = True
_parent_order = 'name'
_order = 'code_prefix'
parent_id = fields.Many2one(
comodel_name='account.group',
string="Parent",
index=True,
ondelete='cascade',
)
parent_left = fields.Integer(
string='Left Parent',
index=True,
)
parent_right = fields.Integer(
string='Right Parent',
index=True,
)
name = fields.Char(
required=True,
)
code_prefix = fields.Char()
account_ids = fields.One2many(
comodel_name='account.account',
inverse_name='group_id',
string='Accounts',
help="Assigned accounts.",
)
level = fields.Integer(
compute='_compute_level',
store=True,
)
@api.depends('parent_id')
def _compute_level(self):
for group in self:
level = 1
parent = group.parent_id
while parent:
level += 1
parent = parent.parent_id
group.level = level
def name_get(self):
result = []
for group in self:
name = group.name
if group.code_prefix:
name = group.code_prefix + ' ' + name
result.append((group.id, name))
return result
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
if not args:
args = []
criteria_operator = (
['|'] if operator not in expression.NEGATIVE_TERM_OPERATORS
else ['&', '!']
)
domain = criteria_operator + [
('code_prefix', '=ilike', name + '%'), ('name', operator, name)
]
return self.search(domain + args, limit=limit).name_get()

View File

@@ -0,0 +1,13 @@
To configure account groups, you need to:
#. Be "Account / Adviser" role.
#. Go to *Invoicing/Accounting > Configuration > Accounting > Accounts Groups*.
#. Create or modify existing groups.
For assigning groups to account templates, you have to:
#. Set the group on your account chart module or extension.
#. Or develop/create UI access.
When you have groups on your account templates, you can load a chart template
for a new company, and they will be transferred to created accounts.

View File

@@ -0,0 +1,3 @@
* `Tecnativa <https://www.tecnativa.com>`__:
* Pedro M. Baeza

View File

@@ -0,0 +1,4 @@
This modules brings to version 10 the account group feature from v11.
It also includes a level field for indicating the level depth of the account
group.

View File

@@ -0,0 +1,3 @@
If you have already the chart of accounts loaded on your company, you will
need to update it through the module `account_chart_update`. Follow the
instructions on that module for that.

View File

@@ -0,0 +1 @@
* This module shouldn't be migrated to v11, as it's a native feature.

View File

@@ -0,0 +1,4 @@
For assigning groups to accounts:
#. Go to *Invoicing > Adviser > Chart of Accounts*.
#. Edit one account and set "Group" field.

View File

@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_group_manager,account.group,model_account_group,account.group_account_manager,1,1,1,1
access_account_group,account.group,model_account_group,account.group_account_user,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_group_manager account.group model_account_group account.group_account_manager 1 1 1 1
3 access_account_group account.group model_account_group account.group_account_user 1 0 0 0

View File

@@ -0,0 +1,464 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Groups for accounts</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="groups-for-accounts">
<h1 class="title">Groups for accounts</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/10.0/account_group"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/account-financial-tools-10-0/account-financial-tools-10-0-account_group"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/92/10.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This modules brings to version 10 the account group feature from v11.</p>
<p>It also includes a level field for indicating the level depth of the account
group.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#installation" id="id1">Installation</a></li>
<li><a class="reference internal" href="#configuration" id="id2">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id3">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id4">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id5">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id6">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id7">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id8">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id9">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="installation">
<h1><a class="toc-backref" href="#id1">Installation</a></h1>
<p>If you have already the chart of accounts loaded on your company, you will
need to update it through the module <cite>account_chart_update</cite>. Follow the
instructions on that module for that.</p>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id2">Configuration</a></h1>
<p>To configure account groups, you need to:</p>
<ol class="arabic simple">
<li>Be “Account / Adviser” role.</li>
<li>Go to <em>Invoicing/Accounting &gt; Configuration &gt; Accounting &gt; Accounts Groups</em>.</li>
<li>Create or modify existing groups.</li>
</ol>
<p>For assigning groups to account templates, you have to:</p>
<ol class="arabic simple">
<li>Set the group on your account chart module or extension.</li>
<li>Or develop/create UI access.</li>
</ol>
<p>When you have groups on your account templates, you can load a chart template
for a new company, and they will be transferred to created accounts.</p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id3">Usage</a></h1>
<p>For assigning groups to accounts:</p>
<ol class="arabic simple">
<li>Go to <em>Invoicing &gt; Adviser &gt; Chart of Accounts</em>.</li>
<li>Edit one account and set “Group” field.</li>
</ol>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id4">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>This module shouldnt be migrated to v11, as its a native feature.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id5">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_group%0Aversion:%2010.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id6">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id7">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id8">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Pedro M. Baeza</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id9">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/10.0/account_group">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,13 @@
<odoo>
<record id="view_account_form" model="ir.ui.view">
<field name="model">account.account</field>
<field name="inherit_id" ref="account.view_account_form"/>
<field name="arch" type="xml">
<field name="tag_ids" position="after">
<field name="group_id"/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,66 @@
<odoo>
<record id="view_account_group_form" model="ir.ui.view">
<field name="name">account.group.form</field>
<field name="model">account.group</field>
<field name="arch" type="xml">
<form string="Accounts Group">
<group>
<field name="name"/>
<field name="code_prefix"/>
<field name="parent_id"/>
<field name="level"/>
</group>
<group>
<group id="links">
<label for="account_ids"/>
<field name="account_ids"
widget="many2many"
nolabel="1"
options="{'no_create_edit': True}"
/>
</group>
</group>
</form>
</field>
</record>
<record id="view_account_group_search" model="ir.ui.view">
<field name="name">account.group.search</field>
<field name="model">account.group</field>
<field name="arch" type="xml">
<search string="Accounts Groups">
<field name="name"
filter_domain="['|', ('code_prefix', '=like', str(self) + '%'), ('name', 'ilike', self)]"
string="Accounts Group"/>
</search>
</field>
</record>
<record id="view_account_group_tree" model="ir.ui.view">
<field name="name">account.group.tree</field>
<field name="model">account.group</field>
<field name="arch" type="xml">
<tree string="Accounts Group">
<field name="code_prefix"/>
<field name="name"/>
<field name="level"/>
</tree>
</field>
</record>
<record id="action_account_group_tree" model="ir.actions.act_window">
<field name="name">Accounts Groups</field>
<field name="res_model">account.group</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_account_group_search"/>
</record>
<menuitem id="account_group_menu"
action="action_account_group_tree"
sequence="50"
parent="account.account_account_menu"
/>
</odoo>

View File

@@ -10,11 +10,12 @@ class TestAccountLockDateUpdate(TransactionCase):
def setUp(self):
super(TestAccountLockDateUpdate, self).setUp()
self.UpdateLockDateUpdateObj = self.env['account.update.lock_date']
self.company = self.env.ref('base.main_company')
self.demo_user = self.env.ref('base.user_demo')
self.adviser_group = self.env.ref('account.group_account_manager')
self.UpdateLockDateUpdateObj = self.env[
'account.update.lock_date'
].sudo(self.demo_user)
def create_account_lock_date_update(self):
return self.UpdateLockDateUpdateObj.create({
@@ -27,23 +28,21 @@ class TestAccountLockDateUpdate(TransactionCase):
'period_lock_date': '2000-01-01',
'fiscalyear_lock_date': '2000-01-01',
})
self.demo_user.write({
'groups_id': [(3, self.adviser_group.id)],
})
with self.assertRaises(UserError):
wizard.sudo(self.demo_user.id).execute()
def test_02_update_with_access(self):
wizard = self.create_account_lock_date_update()
wizard.write({
'period_lock_date': '2000-01-01',
'period_lock_date': '2000-02-01',
'fiscalyear_lock_date': '2000-01-01',
})
self.demo_user.write({
'groups_id': [(4, self.adviser_group.id)],
})
wizard.sudo(self.demo_user.id).execute()
self.assertEqual(self.company.period_lock_date, '2000-02-01')
self.assertEqual(self.company.fiscalyear_lock_date, '2000-01-01')

View File

@@ -126,7 +126,7 @@ msgid "Reversal Date"
msgstr ""
#. module: account_reversal
#: model:ir.model.fields,field_description:account_reversal.field_account_move_reversal_id_4066
#: model:ir.model.fields,field_description:account_reversal.field_account_move_reversal_id_4084
msgid "Reversal Entry"
msgstr ""

View File

@@ -119,5 +119,5 @@ class AccountMove(models.Model):
moves._post_validate()
moves.post()
if reconcile:
orig.move_reverse_reconcile()
self.move_reverse_reconcile()
return moves

View File

@@ -71,7 +71,7 @@ msgstr ""
#. module: account_tag_category
#: model:ir.model.fields,field_description:account_tag_category.field_account_account_tag_category_color
#: model:ir.model.fields,field_description:account_tag_category.field_account_account_tag_category_color_4085
#: model:ir.model.fields,field_description:account_tag_category.field_account_account_tag_category_color_4103
msgid "Color Index"
msgstr ""