1332 lines
59 KiB
Python
1332 lines
59 KiB
Python
# -*- coding: utf-8 -*-
|
|
##############################################################################
|
|
#
|
|
# Copyright (c) 2010 Zikzakmedia S.L. (http://www.zikzakmedia.com)
|
|
# Copyright (c) 2010 Pexego Sistemas Informáticos S.L. (http://www.pexego.es)
|
|
# @authors: Jordi Esteve (Zikzakmedia), Borja López Soilán (Pexego)
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
##############################################################################
|
|
"""
|
|
Account Chart Update Wizard
|
|
"""
|
|
|
|
from openerp.osv import fields, orm
|
|
from openerp.tools.translate import _
|
|
import logging
|
|
|
|
|
|
def _reopen(self, res_id, model):
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'view_mode': 'form',
|
|
'view_type': 'form',
|
|
'res_id': res_id,
|
|
'res_model': self._name,
|
|
'target': 'new',
|
|
# save original model in context, because selecting the list of available
|
|
# templates requires a model in context
|
|
'context': {
|
|
'default_model': model,
|
|
},
|
|
}
|
|
|
|
|
|
class WizardLog:
|
|
"""
|
|
*******************************************************************
|
|
Small helper class to store the messages and errors on the wizard.
|
|
*******************************************************************
|
|
"""
|
|
def __init__(self):
|
|
self.messages = []
|
|
self.errors = []
|
|
|
|
"""
|
|
Adds a message to the log.
|
|
"""
|
|
def add(self, message, is_error=False):
|
|
logger = logging.getLogger("account_chart_update")
|
|
if is_error:
|
|
logger.warning(u"Log line: %s" % message)
|
|
self.errors.append(message)
|
|
else:
|
|
logger.debug(u"Log line: %s" % message)
|
|
self.messages.append(message)
|
|
|
|
"""
|
|
Returns whether errors where logged.
|
|
"""
|
|
def has_errors(self):
|
|
return self.errors
|
|
|
|
def __call__(self):
|
|
return "".join(self.messages)
|
|
|
|
def __str__(self):
|
|
return "".join(self.messages)
|
|
|
|
def get_errors_str(self):
|
|
return "".join(self.errors)
|
|
|
|
|
|
class wizard_update_charts_accounts(orm.TransientModel):
|
|
_name = 'wizard.update.charts.accounts'
|
|
|
|
"""
|
|
Gets the available languages for the selection.
|
|
"""
|
|
def _get_lang_selection_options(self, cr, uid, context={}):
|
|
obj = self.pool.get('res.lang')
|
|
ids = obj.search(cr, uid, [], context=context)
|
|
res = obj.read(cr, uid, ids, ['code', 'name'], context)
|
|
return [(r['code'], r['name']) for r in res] + [('', '')]
|
|
|
|
_columns = {
|
|
'state': fields.selection([
|
|
('init', 'Step 1'),
|
|
('ready', 'Step 2'),
|
|
('done', 'Wizard completed')
|
|
], 'Status', readonly=True),
|
|
'company_id': fields.many2one('res.company', 'Company', required=True, ondelete='set null'),
|
|
'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True, ondelete='set null'),
|
|
'code_digits': fields.integer('# of Digits', required=True, help="No. of Digits to use for account code. Make sure it is the same number as existing accounts."),
|
|
'lang': fields.selection(_get_lang_selection_options, 'Language', size=5, help="For records searched by name (taxes, tax codes, fiscal positions), the template name will be matched against the record name on this language."),
|
|
'update_tax_code': fields.boolean('Update tax codes', help="Existing tax codes are updated. Tax codes are searched by name."),
|
|
'update_tax': fields.boolean('Update taxes', help="Existing taxes are updated. Taxes are searched by name."),
|
|
'update_account': fields.boolean('Update accounts', help="Existing accounts are updated. Accounts are searched by code."),
|
|
'update_fiscal_position': fields.boolean('Update fiscal positions', help="Existing fiscal positions are updated. Fiscal positions are searched by name."),
|
|
'update_children_accounts_parent': fields.boolean("Update children accounts parent",
|
|
help="Update the parent of accounts that seem (based on the code) to be children of the newly created ones. If you had an account 430 with a child 4300000, and a 4300 account is created, the 4300000 parent will be set to 4300."),
|
|
'continue_on_errors': fields.boolean("Continue on errors", help="If set, the wizard will continue to the next step even if there are minor errors (for example the parent account of a new account couldn't be set)."),
|
|
'tax_code_ids': fields.one2many('wizard.update.charts.accounts.tax.code', 'update_chart_wizard_id', 'Tax codes', ondelete='cascade'),
|
|
'tax_ids': fields.one2many('wizard.update.charts.accounts.tax', 'update_chart_wizard_id', 'Taxes', ondelete='cascade'),
|
|
'account_ids': fields.one2many('wizard.update.charts.accounts.account', 'update_chart_wizard_id', 'Accounts', ondelete='cascade'),
|
|
'fiscal_position_ids': fields.one2many('wizard.update.charts.accounts.fiscal.position', 'update_chart_wizard_id', 'Fiscal positions', ondelete='cascade'),
|
|
'new_tax_codes': fields.integer('New tax codes', readonly=True),
|
|
'new_taxes': fields.integer('New taxes', readonly=True),
|
|
'new_accounts': fields.integer('New accounts', readonly=True),
|
|
'new_fps': fields.integer('New fiscal positions', readonly=True),
|
|
'updated_tax_codes': fields.integer('Updated tax codes', readonly=True),
|
|
'updated_taxes': fields.integer('Updated taxes', readonly=True),
|
|
'updated_accounts': fields.integer('Updated accounts', readonly=True),
|
|
'updated_fps': fields.integer('Updated fiscal positions', readonly=True),
|
|
'log': fields.text('Messages and Errors', readonly=True)
|
|
}
|
|
|
|
def name_search(self, cr, user, name,
|
|
args=None, operator='ilike', context=None, limit=80):
|
|
if not name:
|
|
name = '%'
|
|
if not args:
|
|
args = []
|
|
if not context:
|
|
context = {}
|
|
args = args[:]
|
|
ids = []
|
|
ids = self.search(
|
|
cr, user, [('company_id', operator, name)] + args, limit=limit)
|
|
return self.name_get(cr, user, ids, context=context)
|
|
|
|
"""
|
|
Use the company name and template as name.
|
|
"""
|
|
def name_get(self, cr, uid, ids, context=None):
|
|
if context is None:
|
|
context = {}
|
|
if not len(ids):
|
|
return []
|
|
records = self.browse(cr, uid, ids, context)
|
|
res = []
|
|
for record in records:
|
|
res.append((record.id, record.company_id.name +
|
|
' - ' + record.chart_template_id.name))
|
|
return res
|
|
|
|
"""
|
|
Returns the default chart template.
|
|
"""
|
|
def _get_chart(self, cr, uid, context=None):
|
|
if context is None:
|
|
context = {}
|
|
ids = self.pool.get(
|
|
'account.chart.template').search(cr, uid, [], context=context)
|
|
if ids:
|
|
return ids[0]
|
|
return False
|
|
|
|
"""
|
|
Returns the default code size for the accounts.
|
|
To figure out the number of digits of the accounts it look at the
|
|
code size of the default receivable account of the company
|
|
(or user's company if any company is given).
|
|
"""
|
|
def _get_code_digits(self, cr, uid, context=None, company_id=None):
|
|
if context is None:
|
|
context = {}
|
|
property_obj = self.pool.get('ir.property')
|
|
account_obj = self.pool.get('account.account')
|
|
if not company_id:
|
|
user = self.pool.get('res.users').browse(cr, uid, uid, context)
|
|
company_id = user.company_id.id
|
|
property_ids = property_obj.search(cr, uid, [
|
|
('name', '=', 'property_account_receivable'),
|
|
('company_id', '=', company_id),
|
|
('res_id', '=', False),
|
|
('value_reference', '!=', False)
|
|
])
|
|
if not property_ids:
|
|
# Try to get a generic (no-company) property
|
|
property_ids = property_obj.search(cr, uid, [
|
|
('name', '=', 'property_account_receivable'),
|
|
('res_id', '=', False),
|
|
('value_reference', '!=', False)
|
|
])
|
|
number_digits = 6
|
|
if property_ids:
|
|
prop = property_obj.browse(
|
|
cr, uid, property_ids[0], context=context)
|
|
account_id = prop.value_reference.id
|
|
if account_id:
|
|
code = account_obj.read(
|
|
cr, uid, account_id, ['code'], context)['code']
|
|
number_digits = len(code)
|
|
return number_digits
|
|
|
|
_defaults = {
|
|
'state': 'init',
|
|
'company_id': lambda self, cr, uid, context: self.pool.get('res.users').browse(cr, uid, [uid], context)[0].company_id.id,
|
|
'chart_template_id': _get_chart,
|
|
'update_tax_code': True,
|
|
'update_tax': True,
|
|
'update_account': True,
|
|
'update_fiscal_position': True,
|
|
'update_children_accounts_parent': True,
|
|
'continue_on_errors': False,
|
|
'lang': lambda self, cr, uid, context: context and context.get('lang') or None,
|
|
}
|
|
|
|
"""
|
|
Update the code size when the company changes
|
|
"""
|
|
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
|
|
res = {
|
|
'value': {
|
|
'code_digits': self._get_code_digits(cr, uid, context=context, company_id=company_id),
|
|
}
|
|
}
|
|
return res
|
|
|
|
"""
|
|
Initial action that sets the initial state.
|
|
"""
|
|
def action_init(self, cr, uid, ids, context=None):
|
|
if context is None:
|
|
context = {}
|
|
wizard = self.browse(cr, uid, ids[0], context=context)
|
|
self.write(cr, uid, ids, {'state': 'init'}, context)
|
|
return _reopen(self, wizard.id, 'wizard.update.chart.accounts')
|
|
|
|
##########################################################################
|
|
# Helper methods
|
|
##########################################################################
|
|
"""
|
|
Adds a tax template -> tax id to the mapping.
|
|
"""
|
|
def _map_tax_template(self, cr, uid, wizard, tax_template_mapping, tax_template, context=None):
|
|
if tax_template and not tax_template_mapping.get(tax_template.id):
|
|
taxes = self.pool.get('account.tax')
|
|
tax_ids = taxes.search(cr, uid, [
|
|
('name', '=', tax_template.name),
|
|
('company_id', '=', wizard.company_id.id)
|
|
], context=context)
|
|
if tax_ids:
|
|
tax_template_mapping[tax_template.id] = tax_ids[0]
|
|
|
|
"""
|
|
Adds a tax code template -> tax code id to the mapping.
|
|
"""
|
|
def _map_tax_code_template(self, cr, uid, wizard, tax_code_template_mapping, tax_code_template, context=None):
|
|
if tax_code_template and not tax_code_template_mapping.get(tax_code_template.id):
|
|
tax_codes = self.pool.get('account.tax.code')
|
|
root_tax_code_id = wizard.chart_template_id.tax_code_root_id.id
|
|
tax_code_name = (tax_code_template.id == root_tax_code_id) and wizard.company_id.name or tax_code_template.name
|
|
tax_code_ids = tax_codes.search(cr, uid, [
|
|
('name', '=', tax_code_name),
|
|
('company_id', '=', wizard.company_id.id)
|
|
])
|
|
if not tax_code_ids:
|
|
# if we could not match no tax code template name,
|
|
# try to match on tax code template code, if any
|
|
tax_code_code = tax_code_template.code
|
|
if tax_code_code:
|
|
tax_code_ids = tax_codes.search(cr, uid, [
|
|
('code', '=', tax_code_code),
|
|
('company_id', '=', wizard.company_id.id)
|
|
])
|
|
if tax_code_ids:
|
|
tax_code_template_mapping[
|
|
tax_code_template.id] = tax_code_ids[0]
|
|
|
|
"""
|
|
Adds an account template -> account id to the mapping
|
|
"""
|
|
def _map_account_template(self, cr, uid, wizard, account_template_mapping, account_template, context=None):
|
|
if account_template and not account_template_mapping.get(account_template.id):
|
|
accounts = self.pool.get('account.account')
|
|
code = account_template.code or ''
|
|
if account_template.type != 'view':
|
|
if len(code) > 0 and len(code) <= wizard.code_digits:
|
|
code = '%s%s' % (
|
|
code, '0' * (wizard.code_digits - len(code)))
|
|
account_ids = accounts.search(cr, uid, [
|
|
('code', '=', code),
|
|
('company_id', '=', wizard.company_id.id)
|
|
], context=context)
|
|
if account_ids:
|
|
account_template_mapping[account_template.id] = account_ids[0]
|
|
"""
|
|
Adds a fiscal position template -> fiscal position id to the mapping.
|
|
"""
|
|
def _map_fp_template(self, cr, uid, wizard, fp_template_mapping, fp_template, context=None):
|
|
if fp_template and not fp_template_mapping.get(fp_template.id):
|
|
fiscalpositions = self.pool.get('account.fiscal.position')
|
|
fp_ids = fiscalpositions.search(cr, uid, [
|
|
('name', '=', fp_template.name),
|
|
('company_id', '=', wizard.company_id.id)
|
|
], context=context)
|
|
if fp_ids:
|
|
fp_template_mapping[fp_template.id] = fp_ids[0]
|
|
|
|
"""
|
|
Search for, and load, tax code templates to create/update.
|
|
"""
|
|
def _find_tax_codes(self, cr, uid, wizard, context=None):
|
|
new_tax_codes = 0
|
|
updated_tax_codes = 0
|
|
tax_code_template_mapping = {}
|
|
|
|
taxes_codes_templates = self.pool.get('account.tax.code.template')
|
|
taxcodes = self.pool.get('account.tax.code')
|
|
wiz_taxcodes = self.pool.get('wizard.update.charts.accounts.tax.code')
|
|
|
|
# Remove previous tax codes
|
|
wiz_taxcodes.unlink(
|
|
cr, uid, wiz_taxcodes.search(cr, uid, []))
|
|
|
|
#
|
|
# Search for new / updated tax codes
|
|
#
|
|
root_tax_code_id = wizard.chart_template_id.tax_code_root_id.id
|
|
children_tax_code_template = taxes_codes_templates.search(cr, uid, [(
|
|
'parent_id', 'child_of', [root_tax_code_id])], order='id')
|
|
for tax_code_template in taxes_codes_templates.browse(cr, uid, children_tax_code_template):
|
|
# Ensure the tax code template is on the map (search for the mapped
|
|
# tax code id).
|
|
self._map_tax_code_template(cr, uid, wizard, tax_code_template_mapping, tax_code_template, context)
|
|
|
|
tax_code_id = tax_code_template_mapping.get(tax_code_template.id)
|
|
if not tax_code_id:
|
|
new_tax_codes += 1
|
|
wiz_taxcodes.create(cr, uid, {
|
|
'tax_code_id': tax_code_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'new',
|
|
}, context)
|
|
elif wizard.update_tax_code:
|
|
#
|
|
# Check the tax code for changes.
|
|
#
|
|
modified = False
|
|
notes = ""
|
|
tax_code = taxcodes.browse(
|
|
cr, uid, tax_code_id, context=context)
|
|
|
|
if tax_code.code != tax_code_template.code:
|
|
notes += _("The code field is different.\n")
|
|
modified = True
|
|
if tax_code.info != tax_code_template.info:
|
|
notes += _("The info field is different.\n")
|
|
modified = True
|
|
if tax_code.sign != tax_code_template.sign:
|
|
notes += _("The sign field is different.\n")
|
|
modified = True
|
|
|
|
# TODO: We could check other account fields for changes...
|
|
|
|
if modified:
|
|
#
|
|
# Tax code to update.
|
|
#
|
|
updated_tax_codes += 1
|
|
wiz_taxcodes.create(cr, uid, {
|
|
'tax_code_id': tax_code_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'updated',
|
|
'update_tax_code_id': tax_code_id,
|
|
'notes': notes,
|
|
}, context)
|
|
|
|
return {
|
|
'new': new_tax_codes,
|
|
'updated': updated_tax_codes,
|
|
'mapping': tax_code_template_mapping
|
|
}
|
|
|
|
def _find_taxes(self, cr, uid, wizard, context=None):
|
|
new_taxes = 0
|
|
updated_taxes = 0
|
|
tax_template_mapping = {}
|
|
|
|
taxes = self.pool.get('account.tax')
|
|
wiz_taxes = self.pool.get('wizard.update.charts.accounts.tax')
|
|
|
|
delay_wiz_tax = []
|
|
# Remove previous taxes
|
|
wiz_taxes.unlink(cr, uid, wiz_taxes.search(cr, uid, []))
|
|
|
|
#
|
|
# Search for new / updated taxes
|
|
#
|
|
for tax_template in wizard.chart_template_id.tax_template_ids:
|
|
# Ensure the tax template is on the map (search for the mapped tax
|
|
# id).
|
|
self._map_tax_template(
|
|
cr, uid, wizard, tax_template_mapping, tax_template, context)
|
|
|
|
tax_id = tax_template_mapping.get(tax_template.id)
|
|
if not tax_id:
|
|
new_taxes += 1
|
|
vals_wiz = {
|
|
'tax_id': tax_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'new',
|
|
}
|
|
if not tax_template.parent_id:
|
|
wiz_taxes.create(cr, uid, vals_wiz, context)
|
|
else:
|
|
delay_wiz_tax.append(vals_wiz)
|
|
elif wizard.update_tax:
|
|
#
|
|
# Check the tax for changes.
|
|
#
|
|
modified = False
|
|
notes = ""
|
|
tax = taxes.browse(cr, uid, tax_id, context=context)
|
|
if tax.sequence != tax_template.sequence:
|
|
notes += _("The sequence field is different.\n")
|
|
modified = True
|
|
if tax.amount != tax_template.amount:
|
|
notes += _("The amount field is different.\n")
|
|
modified = True
|
|
if tax.type != tax_template.type:
|
|
notes += _("The type field is different.\n")
|
|
modified = True
|
|
if tax.applicable_type != tax_template.applicable_type:
|
|
notes += _("The applicable type field is different.\n")
|
|
modified = True
|
|
if tax.domain != tax_template.domain:
|
|
notes += _("The domain field is different.\n")
|
|
modified = True
|
|
if tax.child_depend != tax_template.child_depend:
|
|
notes += _("The child depend field is different.\n")
|
|
modified = True
|
|
if tax.python_compute != tax_template.python_compute:
|
|
notes += _("The python compute field is different.\n")
|
|
modified = True
|
|
# if tax.tax_group != tax_template.tax_group:
|
|
# notes += _("The tax group field is different.\n")
|
|
# modified = True
|
|
if tax.base_sign != tax_template.base_sign:
|
|
notes += _("The base sign field is different.\n")
|
|
modified = True
|
|
if tax.tax_sign != tax_template.tax_sign:
|
|
notes += _("The tax sign field is different.\n")
|
|
modified = True
|
|
if tax.include_base_amount != tax_template.include_base_amount:
|
|
notes += _("The include base amount field is different.\n")
|
|
modified = True
|
|
if tax.type_tax_use != tax_template.type_tax_use:
|
|
notes += _("The type tax use field is different.\n")
|
|
modified = True
|
|
# TODO: We could check other tax fields for changes...
|
|
|
|
if modified:
|
|
#
|
|
# Tax code to update.
|
|
#
|
|
updated_taxes += 1
|
|
wiz_taxes.create(cr, uid, {
|
|
'tax_id': tax_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'updated',
|
|
'update_tax_id': tax_id,
|
|
'notes': notes,
|
|
}, context)
|
|
|
|
for delay_vals_wiz in delay_wiz_tax:
|
|
wiz_taxes.create(cr, uid, delay_vals_wiz, context)
|
|
|
|
return {'new': new_taxes, 'updated': updated_taxes, 'mapping': tax_template_mapping}
|
|
|
|
"""
|
|
Search for, and load, account templates to create/update.
|
|
"""
|
|
def _find_accounts(self, cr, uid, wizard, context=None):
|
|
new_accounts = 0
|
|
updated_accounts = 0
|
|
account_template_mapping = {}
|
|
|
|
accounts = self.pool.get('account.account')
|
|
accounts_template = self.pool.get('account.account.template')
|
|
wiz_accounts = self.pool.get(
|
|
'wizard.update.charts.accounts.account')
|
|
|
|
# Remove previous accounts
|
|
wiz_accounts.unlink(
|
|
cr, uid, wiz_accounts.search(cr, uid, []))
|
|
|
|
#
|
|
# Search for new / updated accounts
|
|
#
|
|
root_account_id = wizard.chart_template_id.account_root_id.id
|
|
children_acc_template = accounts_template.search(cr, uid, [(
|
|
'parent_id', 'child_of', [root_account_id])], context=context)
|
|
children_acc_template.sort()
|
|
for account_template in accounts_template.browse(cr, uid, children_acc_template, context=context):
|
|
# Ensure the account template is on the map (search for the mapped
|
|
# account id).
|
|
self._map_account_template(cr, uid, wizard, account_template_mapping, account_template, context)
|
|
|
|
account_id = account_template_mapping.get(account_template.id)
|
|
if not account_id:
|
|
new_accounts += 1
|
|
wiz_accounts.create(cr, uid, {
|
|
'account_id': account_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'new',
|
|
}, context)
|
|
elif wizard.update_account:
|
|
#
|
|
# Check the account for changes.
|
|
#
|
|
modified = False
|
|
notes = ""
|
|
account = accounts.browse(
|
|
cr, uid, account_id, context=context)
|
|
|
|
if account.name != account_template.name and account.name != wizard.company_id.name:
|
|
notes += _("The name is different.\n")
|
|
modified = True
|
|
if account.type != account_template.type:
|
|
notes += _("The type is different.\n")
|
|
modified = True
|
|
if account.user_type != account_template.user_type:
|
|
notes += _("The user type is different.\n")
|
|
modified = True
|
|
if account.reconcile != account_template.reconcile:
|
|
notes += _("The reconcile is different.\n")
|
|
modified = True
|
|
|
|
# TODO: We could check other account fields for changes...
|
|
|
|
if modified:
|
|
#
|
|
# Account to update.
|
|
#
|
|
updated_accounts += 1
|
|
wiz_accounts.create(cr, uid, {
|
|
'account_id': account_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'updated',
|
|
'update_account_id': account_id,
|
|
'notes': notes,
|
|
}, context)
|
|
|
|
return {'new': new_accounts, 'updated': updated_accounts, 'mapping': account_template_mapping}
|
|
|
|
"""
|
|
Search for, and load, fiscal position templates to create/update.
|
|
"""
|
|
def _find_fiscal_positions(self, cr, uid, wizard, context=None):
|
|
new_fps = 0
|
|
updated_fps = 0
|
|
fp_template_mapping = {}
|
|
|
|
fiscalpostitions_template = self.pool.get('account.fiscal.position.template')
|
|
fiscalpositions = self.pool.get('account.fiscal.position')
|
|
wiz_fiscalpositions = self.pool.get(
|
|
'wizard.update.charts.accounts.fiscal.position')
|
|
|
|
# Remove previous fiscal positions
|
|
wiz_fiscalpositions.unlink(cr, uid, wiz_fiscalpositions.search(cr, uid, []))
|
|
|
|
#
|
|
# Search for new / updated fiscal positions
|
|
#
|
|
fp_template_ids = fiscalpostitions_template.search(cr, uid, [('chart_template_id', '=', wizard.chart_template_id.id)], context=context)
|
|
for fp_template in fiscalpostitions_template.browse(cr, uid, fp_template_ids, context=context):
|
|
# Ensure the fiscal position template is on the map (search for the
|
|
# mapped fiscal position id).
|
|
self._map_fp_template(
|
|
cr, uid, wizard, fp_template_mapping, fp_template, context)
|
|
|
|
fp_id = fp_template_mapping.get(fp_template.id)
|
|
if not fp_id:
|
|
#
|
|
# New fiscal position template.
|
|
#
|
|
new_fps += 1
|
|
wiz_fiscalpositions.create(cr, uid, {
|
|
'fiscal_position_id': fp_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'new',
|
|
}, context)
|
|
elif wizard.update_fiscal_position:
|
|
#
|
|
# Check the fiscal position for changes.
|
|
#
|
|
modified = False
|
|
notes = ""
|
|
fp = fiscalpositions.browse(cr, uid, fp_id, context=context)
|
|
|
|
#
|
|
# Check fiscal position taxes for changes.
|
|
#
|
|
if fp_template.tax_ids and fp.tax_ids:
|
|
for fp_tax_template in fp_template.tax_ids:
|
|
found = False
|
|
for fp_tax in fp.tax_ids:
|
|
if fp_tax.tax_src_id.name == fp_tax_template.tax_src_id.name:
|
|
if fp_tax_template.tax_dest_id and fp_tax.tax_dest_id:
|
|
if fp_tax.tax_dest_id.name == fp_tax_template.tax_dest_id.name:
|
|
found = True
|
|
break
|
|
elif not fp_tax_template.tax_dest_id and not fp_tax.tax_dest_id:
|
|
found = True
|
|
break
|
|
if not found:
|
|
if fp_tax_template.tax_dest_id:
|
|
notes += _("Tax mapping not found on the fiscal position instance: %s -> %s.\n") % (fp_tax_template.tax_src_id.name, fp_tax_template.tax_dest_id.name)
|
|
else:
|
|
notes += _("Tax mapping not found on the fiscal position instance: %s -> None.\n") % fp_tax_template.tax_src_id.name
|
|
modified = True
|
|
elif fp_template.tax_ids and not fp.tax_ids:
|
|
notes += _("The template has taxes the fiscal position instance does not.\n")
|
|
modified = True
|
|
|
|
#
|
|
# Check fiscal position accounts for changes.
|
|
#
|
|
if fp_template.account_ids and fp.account_ids:
|
|
for fp_account_template in fp_template.account_ids:
|
|
found = False
|
|
for fp_account in fp.account_ids:
|
|
if fp_account.account_src_id.name == fp_account_template.account_src_id.name:
|
|
if fp_account.account_dest_id.name == fp_account_template.account_dest_id.name:
|
|
found = True
|
|
break
|
|
if not found:
|
|
notes += _("Account mapping not found on the fiscal position instance: %s -> %s.\n") % (fp_account_template.account_src_id.name, fp_account_template.account_dest_id.name)
|
|
modified = True
|
|
elif fp_template.account_ids and not fp.account_ids:
|
|
notes += _("The template has accounts the fiscal position instance does not.\n")
|
|
modified = True
|
|
|
|
if modified:
|
|
#
|
|
# Fiscal position template to update.
|
|
#
|
|
updated_fps += 1
|
|
wiz_fiscalpositions.create(cr, uid, {
|
|
'fiscal_position_id': fp_template.id,
|
|
'update_chart_wizard_id': wizard.id,
|
|
'type': 'updated',
|
|
'update_fiscal_position_id': fp_id,
|
|
'notes': notes,
|
|
}, context)
|
|
|
|
return {'new': new_fps, 'updated': updated_fps, 'mapping': fp_template_mapping}
|
|
|
|
"""
|
|
Searchs for records to update/create and shows them
|
|
"""
|
|
def action_find_records(self, cr, uid, ids, context=None):
|
|
if context is None:
|
|
context = {}
|
|
wizard = self.browse(cr, uid, ids[0], context=context)
|
|
|
|
if wizard.lang:
|
|
context['lang'] = wizard.lang
|
|
elif context.get('lang'):
|
|
del context['lang']
|
|
|
|
#
|
|
# Search for, and load, the records to create/update.
|
|
#
|
|
tax_codes_res = self._find_tax_codes(cr, uid, wizard, context=context)
|
|
taxes_res = self._find_taxes(cr, uid, wizard, context=context)
|
|
accounts_res = self._find_accounts(cr, uid, wizard, context=context)
|
|
fps_res = self._find_fiscal_positions(cr, uid, wizard, context=context)
|
|
|
|
#
|
|
# Write the results, and go to the next step.
|
|
#
|
|
self.write(cr, uid, [wizard.id], {
|
|
'state': 'ready',
|
|
'new_tax_codes': tax_codes_res.get('new', 0),
|
|
'new_taxes': taxes_res.get('new', 0),
|
|
'new_accounts': accounts_res.get('new', 0),
|
|
'new_fps': fps_res.get('new', 0),
|
|
'updated_tax_codes': tax_codes_res.get('updated', 0),
|
|
'updated_taxes': taxes_res.get('updated', 0),
|
|
'updated_accounts': accounts_res.get('updated', 0),
|
|
'updated_fps': fps_res.get('updated', 0),
|
|
}, context)
|
|
|
|
return _reopen(self, wizard.id, 'wizard.update.chart.accounts')
|
|
"""
|
|
Search for, and load, tax code templates to create/update.
|
|
"""
|
|
def _update_tax_codes(self, cr, uid, wizard, log, context=None):
|
|
taxcodes = self.pool.get('account.tax.code')
|
|
root_tax_code_id = wizard.chart_template_id.tax_code_root_id.id
|
|
new_tax_codes = 0
|
|
updated_tax_codes = 0
|
|
tax_code_template_mapping = {}
|
|
|
|
for wiz_tax_code in wizard.tax_code_ids:
|
|
tax_code_template = wiz_tax_code.tax_code_id
|
|
tax_code_name = (root_tax_code_id == tax_code_template.id) and wizard.company_id.name or tax_code_template.name
|
|
|
|
# Ensure the parent tax code template is on the map.
|
|
self._map_tax_code_template(cr, uid, wizard, tax_code_template_mapping, tax_code_template.parent_id, context)
|
|
|
|
#
|
|
# Values
|
|
#
|
|
vals = {
|
|
'name': tax_code_name,
|
|
'code': tax_code_template.code,
|
|
'info': tax_code_template.info,
|
|
'parent_id': tax_code_template.parent_id and tax_code_template_mapping.get(tax_code_template.parent_id.id),
|
|
'company_id': wizard.company_id.id,
|
|
'sign': tax_code_template.sign,
|
|
}
|
|
|
|
tax_code_id = None
|
|
modified = False
|
|
|
|
if wiz_tax_code.type == 'new':
|
|
#
|
|
# Create the tax code
|
|
#
|
|
tax_code_id = taxcodes.create(cr, uid, vals)
|
|
log.add(_("Created tax code %s.\n") % tax_code_name)
|
|
new_tax_codes += 1
|
|
modified = True
|
|
elif wizard.update_tax_code and wiz_tax_code.update_tax_code_id:
|
|
#
|
|
# Update the tax code
|
|
#
|
|
tax_code_id = wiz_tax_code.update_tax_code_id.id
|
|
taxcodes.write(cr, uid, [tax_code_id], vals)
|
|
log.add(_("Updated tax code %s.\n") % tax_code_name)
|
|
updated_tax_codes += 1
|
|
modified = True
|
|
else:
|
|
tax_code_id = wiz_tax_code.update_tax_code_id and wiz_tax_code.update_tax_code_id.id
|
|
modified = False
|
|
|
|
# Store the tax codes on the map
|
|
tax_code_template_mapping[tax_code_template.id] = tax_code_id
|
|
|
|
if modified:
|
|
#
|
|
# Detect errors
|
|
#
|
|
if tax_code_template.parent_id and not tax_code_template_mapping.get(tax_code_template.parent_id.id):
|
|
log.add(_("Tax code %s: The parent tax code %s can not be set.\n") % (tax_code_name, tax_code_template.parent_id.name), True)
|
|
|
|
return {
|
|
'new': new_tax_codes,
|
|
'updated': updated_tax_codes,
|
|
'mapping': tax_code_template_mapping
|
|
}
|
|
|
|
"""
|
|
Search for, and load, tax templates to create/update.
|
|
"""
|
|
def _update_taxes(self, cr, uid, wizard, log, tax_code_template_mapping, context=None):
|
|
taxes = self.pool.get('account.tax')
|
|
|
|
new_taxes = 0
|
|
updated_taxes = 0
|
|
tax_template_mapping = {}
|
|
taxes_pending_for_accounts = {}
|
|
|
|
for wiz_tax in wizard.tax_ids:
|
|
tax_template = wiz_tax.tax_id
|
|
|
|
# Ensure the parent tax template is on the map.
|
|
self._map_tax_template(cr, uid, wizard, tax_template_mapping,
|
|
tax_template.parent_id, context)
|
|
|
|
#
|
|
# Ensure the referenced tax codes are on the map.
|
|
#
|
|
tax_code_templates_to_find = [
|
|
tax_template.base_code_id,
|
|
tax_template.tax_code_id,
|
|
tax_template.ref_base_code_id,
|
|
tax_template.ref_tax_code_id
|
|
]
|
|
for tax_code_template in [tmpl for tmpl in tax_code_templates_to_find if tmpl]:
|
|
self._map_tax_code_template(cr, uid, wizard, tax_code_template_mapping, tax_code_template)
|
|
|
|
#
|
|
# Values
|
|
#
|
|
vals_tax = {
|
|
'name': tax_template.name,
|
|
'sequence': tax_template.sequence,
|
|
'amount': tax_template.amount,
|
|
'type': tax_template.type,
|
|
'applicable_type': tax_template.applicable_type,
|
|
'domain': tax_template.domain,
|
|
'parent_id': tax_template.parent_id and tax_template_mapping.get(tax_template.parent_id.id),
|
|
'child_depend': tax_template.child_depend,
|
|
'python_compute': tax_template.python_compute,
|
|
'python_compute_inv': tax_template.python_compute_inv,
|
|
'python_applicable': tax_template.python_applicable,
|
|
#'tax_group': tax_template.tax_group,
|
|
'base_code_id': tax_template.base_code_id and tax_code_template_mapping.get(tax_template.base_code_id.id),
|
|
'tax_code_id': tax_template.tax_code_id and tax_code_template_mapping.get(tax_template.tax_code_id.id),
|
|
'base_sign': tax_template.base_sign,
|
|
'tax_sign': tax_template.tax_sign,
|
|
'ref_base_code_id': tax_template.ref_base_code_id and tax_code_template_mapping.get(tax_template.ref_base_code_id.id),
|
|
'ref_tax_code_id': tax_template.ref_tax_code_id and tax_code_template_mapping.get(tax_template.ref_tax_code_id.id),
|
|
'ref_base_sign': tax_template.ref_base_sign,
|
|
'ref_tax_sign': tax_template.ref_tax_sign,
|
|
'include_base_amount': tax_template.include_base_amount,
|
|
'description': tax_template.description,
|
|
'company_id': wizard.company_id.id,
|
|
'type_tax_use': tax_template.type_tax_use
|
|
}
|
|
|
|
tax_id = None
|
|
modified = False
|
|
|
|
if wiz_tax.type == 'new':
|
|
#
|
|
# Create a new tax.
|
|
#
|
|
tax_id = taxes.create(cr, uid, vals_tax)
|
|
log.add(_("Created tax %s.\n") % tax_template.name)
|
|
new_taxes += 1
|
|
modified = True
|
|
elif wizard.update_tax and wiz_tax.update_tax_id:
|
|
#
|
|
# Update a tax.
|
|
#
|
|
tax_id = wiz_tax.update_tax_id.id
|
|
taxes.write(cr, uid, [tax_id], vals_tax)
|
|
log.add(_("Updated tax %s.\n") % tax_template.name)
|
|
updated_taxes += 1
|
|
modified = True
|
|
else:
|
|
tax_id = wiz_tax.update_tax_id and wiz_tax.update_tax_id.id
|
|
|
|
# Update the tax template map
|
|
tax_template_mapping[tax_template.id] = tax_id
|
|
|
|
if modified:
|
|
#
|
|
# Add to the dict of taxes waiting for accounts.
|
|
#
|
|
taxes_pending_for_accounts[tax_id] = {
|
|
'account_collected_id': tax_template.account_collected_id and tax_template.account_collected_id.id or False,
|
|
'account_paid_id': tax_template.account_paid_id and tax_template.account_paid_id.id or False,
|
|
}
|
|
|
|
#
|
|
# Detect errors
|
|
#
|
|
if tax_template.parent_id and not tax_template_mapping.get(tax_template.parent_id.id):
|
|
log.add(_("Tax %s: The parent tax %s can not be set.\n") % (tax_template.name, tax_template.parent_id.name), True)
|
|
if tax_template.base_code_id and not tax_code_template_mapping.get(tax_template.base_code_id.id):
|
|
log.add(_("Tax %s: The tax code for the base %s can not be set.\n") % (tax_template.name, tax_template.base_code_id.name), True)
|
|
if tax_template.tax_code_id and not tax_code_template_mapping.get(tax_template.tax_code_id.id):
|
|
log.add(_("Tax %s: The tax code for the tax %s can not be set.\n") % (tax_template.name, tax_template.tax_code_id.name), True)
|
|
if tax_template.ref_base_code_id and not tax_code_template_mapping.get(tax_template.ref_base_code_id.id):
|
|
log.add(_("Tax %s: The tax code for the base refund %s can not be set.\n") % (tax_template.name, tax_template.ref_base_code_id.name), True)
|
|
if tax_template.ref_tax_code_id and not tax_code_template_mapping.get(tax_template.ref_tax_code_id.id):
|
|
log.add(_("Tax %s: The tax code for the tax refund %s can not be set.\n") % (tax_template.name, tax_template.ref_tax_code_id.name), True)
|
|
|
|
return {
|
|
'new': new_taxes,
|
|
'updated': updated_taxes,
|
|
'mapping': tax_template_mapping,
|
|
'pending': taxes_pending_for_accounts
|
|
}
|
|
|
|
"""
|
|
Updates the parent_id of accounts that seem to be children of the
|
|
given account (accounts that start with the same code and are brothers
|
|
of the first account).
|
|
"""
|
|
def _update_children_accounts_parent(self, cr, uid, wizard, log, parent_account_id, context=None):
|
|
account_account = self.pool.get('account.account')
|
|
parent_account = account_account.browse(
|
|
cr, uid, parent_account_id, context=context)
|
|
|
|
if not parent_account.parent_id or not parent_account.code:
|
|
return False
|
|
|
|
children_ids = account_account.search(cr, uid, [
|
|
('company_id', '=',
|
|
parent_account.company_id and parent_account.company_id.id),
|
|
('parent_id', '=', parent_account.parent_id.id),
|
|
('code', '=like', "%s%%" % parent_account.code),
|
|
('id', '!=', parent_account.id),
|
|
], context=context)
|
|
|
|
if children_ids:
|
|
try:
|
|
account_account.write(cr, uid, children_ids, {'parent_id': parent_account.id}, context=context)
|
|
except orm.except_orm, ex:
|
|
log.add(_("Exception setting the parent of account %s children: %s - %s.\n") % (parent_account.code, ex.name, ex.value), True)
|
|
|
|
return True
|
|
|
|
"""
|
|
Search for, and load, account templates to create/update.
|
|
"""
|
|
def _update_accounts(self, cr, uid, wizard, log, tax_template_mapping, context=None):
|
|
accounts = self.pool.get('account.account')
|
|
root_account_id = wizard.chart_template_id.account_root_id.id
|
|
|
|
# Disable the parent_store computing on account_account during the batch
|
|
# processing, we will force _parent_store_compute afterwards.
|
|
self.pool._init = True
|
|
new_accounts = 0
|
|
updated_accounts = 0
|
|
account_template_mapping = {}
|
|
|
|
for wiz_account in wizard.account_ids:
|
|
account_template = wiz_account.account_id
|
|
|
|
# Ensure the parent account template is on the map.
|
|
self._map_account_template(cr, uid, wizard, account_template_mapping, account_template.parent_id, context)
|
|
|
|
#
|
|
# Ensure the related tax templates are on the map.
|
|
#
|
|
for tax_template in account_template.tax_ids:
|
|
self._map_tax_template(cr, uid, wizard, tax_template_mapping,
|
|
tax_template, context)
|
|
|
|
# Get the tax ids
|
|
tax_ids = [tax_template_mapping[tax_template.id] for tax_template in account_template.tax_ids if tax_template_mapping[tax_template.id]]
|
|
|
|
#
|
|
# Calculate the account code (we need to add zeros to non-view
|
|
# account codes)
|
|
#
|
|
code = account_template.code or ''
|
|
if account_template.type != 'view':
|
|
if len(code) > 0 and len(code) <= wizard.code_digits:
|
|
code = '%s%s' % (
|
|
code, '0' * (wizard.code_digits - len(code)))
|
|
|
|
#
|
|
# Values
|
|
#
|
|
vals = {
|
|
'name': (root_account_id == account_template.id) and wizard.company_id.name or account_template.name,
|
|
#'sign': account_template.sign,
|
|
'currency_id': account_template.currency_id and account_template.currency_id.id or False,
|
|
'code': code,
|
|
'type': account_template.type,
|
|
'user_type': account_template.user_type and account_template.user_type.id or False,
|
|
'reconcile': account_template.reconcile,
|
|
'shortcut': account_template.shortcut,
|
|
'note': account_template.note,
|
|
'parent_id': account_template.parent_id and account_template_mapping.get(account_template.parent_id.id) or False,
|
|
'tax_ids': [(6, 0, tax_ids)],
|
|
'company_id': wizard.company_id.id,
|
|
}
|
|
|
|
account_id = None
|
|
modified = False
|
|
|
|
if wiz_account.type == 'new':
|
|
#
|
|
# Create the account
|
|
#
|
|
try:
|
|
account_id = accounts.create(cr, uid, vals)
|
|
log.add(_("Created account %s.\n") % code)
|
|
new_accounts += 1
|
|
modified = True
|
|
except orm.except_orm, ex:
|
|
log.add(_("Exception creating account %s: %s - %s.\n")
|
|
% (code, ex.name, ex.value), True)
|
|
elif wizard.update_account and wiz_account.update_account_id:
|
|
#
|
|
# Update the account
|
|
#
|
|
account_id = wiz_account.update_account_id.id
|
|
try:
|
|
accounts.write(cr, uid, [account_id], vals)
|
|
log.add(_("Updated account %s.\n") % code)
|
|
updated_accounts += 1
|
|
modified = True
|
|
except orm.except_orm, ex:
|
|
log.add(_("Exception writing account %s: %s - %s.\n")
|
|
% (code, ex.name, ex.value), True)
|
|
else:
|
|
account_id = wiz_account.update_account_id and wiz_account.update_account_id.id
|
|
|
|
# Store the account on the map
|
|
account_template_mapping[account_template.id] = account_id
|
|
|
|
if modified:
|
|
#
|
|
# Detect errors
|
|
#
|
|
if account_template.parent_id and not account_template_mapping.get(account_template.parent_id.id):
|
|
log.add(_("Account %s: The parent account %s can not be set.\n") % (code, account_template.parent_id.code), True)
|
|
|
|
#
|
|
# Set this account as the parent of the accounts that seem to
|
|
# be its children (brothers starting with the same code).
|
|
#
|
|
if wizard.update_children_accounts_parent:
|
|
self._update_children_accounts_parent(
|
|
cr, uid, wizard, log, account_id, context=context)
|
|
|
|
#
|
|
# Reenable the parent_store computing on account_account
|
|
# and force the recomputation.
|
|
#
|
|
self.pool._init = False
|
|
self.pool.get('account.account')._parent_store_compute(cr)
|
|
|
|
return {
|
|
'new': new_accounts,
|
|
'updated': updated_accounts,
|
|
'mapping': account_template_mapping
|
|
}
|
|
|
|
"""
|
|
Updates the taxes (created or updated on previous steps) to set
|
|
the references to the accounts (the taxes where created/updated first,
|
|
when the referenced accounts where still not available).
|
|
"""
|
|
def _update_taxes_pending_for_accounts(self, cr, uid, wizard, log, taxes_pending_for_accounts, account_template_mapping, context=None):
|
|
taxes = self.pool.get('account.tax')
|
|
accounts_template = self.pool.get('account.account.template')
|
|
|
|
for key, value in taxes_pending_for_accounts.items():
|
|
#
|
|
# Ensure the related account templates are on the map.
|
|
#
|
|
if value['account_collected_id']:
|
|
account_template = accounts_template.browse(
|
|
cr, uid, value['account_collected_id'], context=context)
|
|
self._map_account_template(cr, uid, wizard, account_template_mapping, account_template, context)
|
|
if value['account_paid_id']:
|
|
account_template = accounts_template.browse(
|
|
cr, uid, value['account_paid_id'], context=context)
|
|
self._map_account_template(cr, uid, wizard, account_template_mapping, account_template, context)
|
|
|
|
if value['account_collected_id'] or value['account_paid_id']:
|
|
if account_template_mapping.get(value['account_collected_id']) and account_template_mapping.get(value['account_paid_id']):
|
|
vals = {
|
|
'account_collected_id': account_template_mapping[value['account_collected_id']],
|
|
'account_paid_id': account_template_mapping[value['account_paid_id']],
|
|
}
|
|
taxes.write(cr, uid, [key], vals)
|
|
else:
|
|
tax = taxes.browse(cr, uid, key)
|
|
if not account_template_mapping.get(value['account_collected_id']):
|
|
log.add(_("Tax %s: The collected account can not be set.\n") % (tax.name), True)
|
|
if not account_template_mapping.get(value['account_paid_id']):
|
|
log.add(_("Tax %s: The paid account can not be set.\n")
|
|
% (tax.name), True)
|
|
|
|
"""
|
|
Search for, and load, fiscal position templates to create/update.
|
|
"""
|
|
def _update_fiscal_positions(self, cr, uid, wizard, log, tax_template_mapping, account_template_mapping, context=None):
|
|
fiscalpositions = self.pool.get('account.fiscal.position')
|
|
fiscalpositions_taxes = self.pool.get('account.fiscal.position.tax')
|
|
fiscalpositions_account = self.pool.get('account.fiscal.position.account')
|
|
|
|
new_fps = 0
|
|
updated_fps = 0
|
|
|
|
for wiz_fp in wizard.fiscal_position_ids:
|
|
fp_template = wiz_fp.fiscal_position_id
|
|
fp_id = None
|
|
modified = False
|
|
if wiz_fp.type == 'new':
|
|
#
|
|
# Create a new fiscal position
|
|
#
|
|
vals_fp = {
|
|
'company_id': wizard.company_id.id,
|
|
'name': fp_template.name,
|
|
}
|
|
fp_id = fiscalpositions.create(cr, uid, vals_fp)
|
|
new_fps += 1
|
|
modified = True
|
|
elif wizard.update_fiscal_position and wiz_fp.update_fiscal_position_id:
|
|
#
|
|
# Update the given fiscal position (remove the tax and account
|
|
# mappings, that will be regenerated later)
|
|
#
|
|
fp_id = wiz_fp.update_fiscal_position_id.id
|
|
updated_fps += 1
|
|
modified = True
|
|
# Remove the tax mappings
|
|
fp_tax_ids = fiscalpositions_taxes.search(
|
|
cr, uid, [('position_id', '=', fp_id)])
|
|
fiscalpositions_taxes.unlink(cr, uid, fp_tax_ids)
|
|
# Remove the account mappings
|
|
fp_account_ids = fiscalpositions_account.search(
|
|
cr, uid, [('position_id', '=', fp_id)])
|
|
fiscalpositions_account.unlink(cr, uid, fp_account_ids)
|
|
else:
|
|
fp_id = wiz_fp.update_fiscal_position_id and wiz_fp.update_fiscal_position_id.id
|
|
|
|
if modified:
|
|
#
|
|
# (Re)create the tax mappings
|
|
#
|
|
for fp_tax in fp_template.tax_ids:
|
|
#
|
|
# Ensure the related tax templates are on the map.
|
|
#
|
|
self._map_tax_template(cr, uid, wizard, tax_template_mapping, fp_tax.tax_src_id, context)
|
|
if fp_tax.tax_dest_id:
|
|
self._map_tax_template(cr, uid, wizard, tax_template_mapping, fp_tax.tax_dest_id, context)
|
|
|
|
#
|
|
# Create the fp tax mapping
|
|
#
|
|
vals_tax = {
|
|
'tax_src_id': tax_template_mapping.get(fp_tax.tax_src_id.id),
|
|
'tax_dest_id': fp_tax.tax_dest_id and tax_template_mapping.get(fp_tax.tax_dest_id.id),
|
|
'position_id': fp_id,
|
|
}
|
|
fiscalpositions_taxes.create(cr, uid, vals_tax)
|
|
|
|
#
|
|
# Check for errors
|
|
#
|
|
if not tax_template_mapping.get(fp_tax.tax_src_id.id):
|
|
log.add(_("Fiscal position %s: The source tax %s can not be set.\n") % (fp_template.name, fp_tax.tax_src_id.code), True)
|
|
if fp_tax.tax_dest_id and not tax_template_mapping.get(fp_tax.tax_dest_id.id):
|
|
log.add(_("Fiscal position %s: The destination tax %s can not be set.\n") % (fp_template.name, fp_tax.tax_dest_id.name), True)
|
|
#
|
|
# (Re)create the account mappings
|
|
#
|
|
for fp_account in fp_template.account_ids:
|
|
#
|
|
# Ensure the related account templates are on the map.
|
|
#
|
|
self._map_account_template(cr, uid, wizard, account_template_mapping, fp_account.account_src_id, context)
|
|
if fp_account.account_dest_id:
|
|
self._map_account_template(cr, uid, wizard, account_template_mapping, fp_account.account_dest_id, context)
|
|
|
|
#
|
|
# Create the fp account mapping
|
|
#
|
|
vals_account = {
|
|
'account_src_id': account_template_mapping.get(fp_account.account_src_id.id),
|
|
'account_dest_id': fp_account.account_dest_id and account_template_mapping.get(fp_account.account_dest_id.id),
|
|
'position_id': fp_id,
|
|
}
|
|
fiscalpositions_account.create(cr, uid, vals_account)
|
|
|
|
#
|
|
# Check for errors
|
|
#
|
|
if not account_template_mapping.get(fp_account.account_src_id.id):
|
|
log.add(_("Fiscal position %s: The source account %s can not be set.\n") % (fp_template.name, fp_account.account_src_id.code), True)
|
|
if fp_account.account_dest_id and not account_template_mapping.get(fp_account.account_dest_id.id):
|
|
log.add(_("Fiscal position %s: The destination account %s can not be set.\n") % (fp_template.name, fp_account.account_dest_id.code), True)
|
|
|
|
log.add(_("Created or updated fiscal position %s.\n")
|
|
% fp_template.name)
|
|
return {'new': new_fps, 'updated': updated_fps}
|
|
|
|
"""
|
|
Action that creates/updates the selected elements.
|
|
"""
|
|
def action_update_records(self, cr, uid, ids, context=None):
|
|
if context is None:
|
|
context = {}
|
|
wizard = self.browse(cr, uid, ids[0], context=context)
|
|
|
|
if wizard.lang:
|
|
context['lang'] = wizard.lang
|
|
elif context.get('lang'):
|
|
del context['lang']
|
|
|
|
log = WizardLog()
|
|
|
|
#
|
|
# Create or update the records.
|
|
#
|
|
tax_codes_res = self._update_tax_codes(
|
|
cr, uid, wizard, log, context=context)
|
|
taxes_res = self._update_taxes(
|
|
cr, uid, wizard, log, tax_codes_res['mapping'], context=context)
|
|
accounts_res = self._update_accounts(
|
|
cr, uid, wizard, log, taxes_res['mapping'], context=context)
|
|
self._update_taxes_pending_for_accounts(cr, uid, wizard, log, taxes_res['pending'], accounts_res['mapping'], context=context)
|
|
fps_res = self._update_fiscal_positions(cr, uid, wizard, log, taxes_res['mapping'], accounts_res['mapping'], context=context)
|
|
|
|
#
|
|
# Check if errors where detected and wether we should stop.
|
|
#
|
|
if log.has_errors() and not wizard.continue_on_errors:
|
|
raise orm.except_orm(_('Error'), _(
|
|
"One or more errors detected!\n\n%s") % log.get_errors_str())
|
|
|
|
#
|
|
# Store the data and go to the next step.
|
|
#
|
|
self.write(cr, uid, [wizard.id], {
|
|
'state': 'done',
|
|
'new_tax_codes': tax_codes_res.get('new', 0),
|
|
'new_taxes': taxes_res.get('new', 0),
|
|
'new_accounts': accounts_res .get('new', 0),
|
|
'new_fps': fps_res.get('new', 0),
|
|
'updated_tax_codes': tax_codes_res.get('updated', 0),
|
|
'updated_taxes': taxes_res.get('updated', 0),
|
|
'updated_accounts': accounts_res.get('updated', 0),
|
|
'updated_fps': fps_res.get('updated', 0),
|
|
'log': log(),
|
|
}, context)
|
|
|
|
return _reopen(self, wizard.id, 'wizard.update.chart.accounts')
|
|
|
|
wizard_update_charts_accounts()
|
|
|
|
|
|
class wizard_update_charts_accounts_tax_code(orm.TransientModel):
|
|
"""
|
|
******************************************************************
|
|
Tax code that needs to be updated (new or updated in the template).
|
|
******************************************************************
|
|
"""
|
|
_name = 'wizard.update.charts.accounts.tax.code'
|
|
_columns = {
|
|
'tax_code_id': fields.many2one('account.tax.code.template', 'Tax code template', required=True, ondelete='set null'),
|
|
'update_chart_wizard_id': fields.many2one('wizard.update.charts.accounts', 'Update chart wizard', required=True, ondelete='cascade'),
|
|
'type': fields.selection([
|
|
('new', 'New template'),
|
|
('updated', 'Updated template'),
|
|
], 'Type'),
|
|
'update_tax_code_id': fields.many2one('account.tax.code', 'Tax code to update', required=False, ondelete='set null'),
|
|
'notes': fields.text('Notes'),
|
|
}
|
|
_defaults = {
|
|
}
|
|
|
|
wizard_update_charts_accounts_tax_code()
|
|
|
|
|
|
class wizard_update_charts_accounts_tax(orm.TransientModel):
|
|
"""
|
|
**************************************************************
|
|
Tax that needs to be updated (new or updated in the template).
|
|
**************************************************************
|
|
"""
|
|
_name = 'wizard.update.charts.accounts.tax'
|
|
_columns = {
|
|
'tax_id': fields.many2one('account.tax.template', 'Tax template', required=True, ondelete='set null'),
|
|
'update_chart_wizard_id': fields.many2one('wizard.update.charts.accounts', 'Update chart wizard', required=True, ondelete='cascade'),
|
|
'type': fields.selection([
|
|
('new', 'New template'),
|
|
('updated', 'Updated template'),
|
|
], 'Type'),
|
|
'update_tax_id': fields.many2one('account.tax', 'Tax to update', required=False, ondelete='set null'),
|
|
'notes': fields.text('Notes'),
|
|
}
|
|
|
|
_defaults = {
|
|
}
|
|
|
|
wizard_update_charts_accounts_tax()
|
|
|
|
|
|
class wizard_update_charts_accounts_account(orm.TransientModel):
|
|
"""
|
|
******************************************************************
|
|
Account that needs to be updated (new or updated in the template).
|
|
*******************************************************************
|
|
"""
|
|
_name = 'wizard.update.charts.accounts.account'
|
|
# The chart of accounts can have a lot of accounts, so we need an higher
|
|
# limit for the objects in memory to let the wizard create all the items
|
|
# at once.
|
|
_max_count = 4096
|
|
_columns = {
|
|
'account_id': fields.many2one('account.account.template', 'Account template', required=True, ondelete='set null'),
|
|
'update_chart_wizard_id': fields.many2one('wizard.update.charts.accounts', 'Update chart wizard', required=True, ondelete='cascade'),
|
|
'type': fields.selection([
|
|
('new', 'New template'),
|
|
('updated', 'Updated template'),
|
|
], 'Type'),
|
|
'update_account_id': fields.many2one('account.account', 'Account to update', required=False, ondelete='set null'),
|
|
'notes': fields.text('Notes'),
|
|
}
|
|
|
|
_defaults = {
|
|
}
|
|
|
|
wizard_update_charts_accounts_account()
|
|
|
|
|
|
class wizard_update_charts_accounts_fiscal_position(orm.TransientModel):
|
|
"""
|
|
**************************************************************************
|
|
Fiscal position that needs to be updated (new or updated in the template).
|
|
**************************************************************************
|
|
"""
|
|
_name = 'wizard.update.charts.accounts.fiscal.position'
|
|
_columns = {
|
|
'fiscal_position_id': fields.many2one('account.fiscal.position.template', 'Fiscal position template', required=True, ondelete='set null'),
|
|
'update_chart_wizard_id': fields.many2one('wizard.update.charts.accounts', 'Update chart wizard', required=True, ondelete='cascade'),
|
|
'type': fields.selection([
|
|
('new', 'New template'),
|
|
('updated', 'Updated template'),
|
|
], 'Type'),
|
|
'update_fiscal_position_id': fields.many2one('account.fiscal.position', 'Fiscal position to update', required=False, ondelete='set null'),
|
|
'notes': fields.text('Notes'),
|
|
}
|
|
_defaults = {
|
|
}
|
|
|
|
|
|
wizard_update_charts_accounts_fiscal_position()
|
|
|
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|