[FIX] cinnut

This commit is contained in:
Vincent Renaville
2013-11-07 15:17:47 +01:00
13 changed files with 1353 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
# This module copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>).
#
# 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/>.
#
##############################################################################
from . import model

View File

@@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012 Therp BV (<http://therp.nl>).
# Copyright (C) 2013 Camptocamp SA.
#
# 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/>.
#
##############################################################################
{
"name": "Update tax wizard",
"version": "1.0r43",
"author": "Therp BV/Camptocamp SA",
"category": 'Base',
'complexity': "normal",
"description": """
This module aims at assisting the finance manager with implementing a tax
increase. Currently, only taxes that apply a percentage are covered.
The module creates a new menu item 'Update tax wizard' in the financial
settings menu, under the Taxes submenu. Using the wizard, you can select
the sales and purchase taxes that need to be upgraded and assign a new
percentage.
The selected taxes are in fact duplicated by running the wizard, so that
existing entries in the system are not affected. The new taxes are mapped
automatically in the appropriate fiscal positions. The wizard can replace
default values on accounts and products on demand. Defaults for purchase
and sales taxes can be set at independent times. During the transition,
the old taxes can still be selected manually on invoice lines etc.
After the transition, the old taxes can be made inactive.
This module is compatible with OpenERP 6.0 and 6.1
For Dutch users there is a video on how to use this module:
http://www.youtube.com/watch?v=Hs-NP8rRuIk
""",
'images': ['images/update_tax.png'],
'depends': ['account'],
'data': [
'view/account_tax.xml',
'view/update_tax_config.xml',
'view/select_taxes.xml',
'security/ir.model.access.csv',
],
"license": 'AGPL-3',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@@ -0,0 +1,255 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * trp_update_tax
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-09-20 12:48+0000\n"
"PO-Revision-Date: 2012-09-20 12:48+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: trp_update_tax
#: view:account.update.tax.select_taxes:0
msgid "Add the taxes that need to be replaced here. Any parent or child taxes will be added automatically when you close this window."
msgstr "Selecteer hier de belastingen die vervangen moeten worden. Onder- of bovenliggende belastingen worden automatisch geselecteerd als dit venster wordt gesloten."
#. module: trp_update_tax
#: field:account.update.tax.config.line,target_tax_description:0
msgid "New tax code"
msgstr "Nieuwe belastingcode"
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.config,log:0
msgid "Log"
msgstr "Logbestand"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Confirm"
msgstr "Bevestigen"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Set legacy purchase taxes inactive"
msgstr "Verouderde inkoopbelastingen inactief maken"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Add sale taxes"
msgstr "Verkoopbelastingen toevoegen"
#. module: trp_update_tax
#: model:ir.actions.act_window,name:trp_update_tax.action_update_tax_config
#: model:ir.ui.menu,name:trp_update_tax.menu_update_tax_config
msgid "Update tax wizard"
msgstr "Assistent bijwerken belastingen"
#. module: trp_update_tax
#: field:account.update.tax.config,state:0
#: field:account.update.tax.config.line,state:0
msgid "State"
msgstr "Status"
#. module: trp_update_tax
#: field:account.update.tax.config.line,source_tax_description:0
msgid "Old tax code"
msgstr "Oude belastingcode"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Draft"
msgstr "Concept"
#. module: trp_update_tax
#: field:account.update.tax.config.line,target_tax_id:0
msgid "Target tax"
msgstr "Nieuwe belasting"
#. module: trp_update_tax
#: field:account.update.tax.config,sale_set_defaults:0
msgid "Sales tax defaults have been set"
msgstr "Standaard verkoop belastingen zijn ingesteld"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Replace sales tax defaults"
msgstr "Vervang standaardwaarden verkoopbelasting"
#. module: trp_update_tax
#: view:account.update.tax.select_taxes:0
msgid "Save"
msgstr "Opslaan"
#. module: trp_update_tax
#: field:account.update.tax.config.line,source_tax_name:0
msgid "Old tax name"
msgstr "Oude belastingnaam"
#. module: trp_update_tax
#: field:account.update.tax.config,default_amount:0
msgid "Default new amount"
msgstr "Standaard voor nieuw percentage"
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.config,purchase_line_ids:0
msgid "Purchase taxes"
msgstr "Inkoopbelastingen"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Set legacy sales taxes inactive"
msgstr "Verouderde verkoopbelastingen inactief maken"
#. module: trp_update_tax
#: field:account.update.tax.config,purchase_set_inactive:0
msgid "Purchase taxes have been set to inactive"
msgstr "Inkoopbelastingen zijn inactief gemaakt"
#. module: trp_update_tax
#: model:ir.actions.act_window,help:trp_update_tax.action_update_tax_config
msgid "For every tax increase, you can create a new configuration. Select sales and purchase taxes to adapt. The selected taxes will be duplicated. The old tax names will be prefixed with a 'legacy' tag. Change the new tax names and codes in the window below to reflect the amount change. The new taxes then become available to select manually on sale or purchase order lines. You may also want to change the names of the associated tax codes, or reassign them between the taxes. At specific times during the transition, you can replace the default sales and purchase taxes in the system. Eventually you can hide the obsolete taxes by making them inactive. Until then, you can still select the old taxes manually"
msgstr "Voor elke belastingwijziging kun je een nieuwe configuratie aanmaken. Selecteer de in- en verkoopbelastingen die moeten worden aangepast. De geselecteerde belastingen worden gedupliceerd. De namen van de oorspronkelijke belastingen worden voorzien van een 'legacy' label. Verander in het venster de namen en codes van de nieuwe belastingen om de wijziging weer te geven. De nieuwe belastingen zijn meteen beschikbaar om handmatig te selecteren op de regels van in- en verkooporders. De namen van de bijbehorende belastingcodes moeten wellicht ook gewijzigd worden, of aan andere belastingen gekoppeld worden. Op een bepaald moment in de overgang kun je de standaardbelastingen in het systeem voor in- en verkopen wijzigen. Uiteindelijk kunnen de oude belastingen verborgen worden door deze op inactief te zetten. Tot die tijd kunnen ze nog steeds handmatig worden geselecteerd."
#. module: trp_update_tax
#: model:ir.model,name:trp_update_tax.model_account_update_tax_config_line
msgid "account.update.tax.config.line"
msgstr "account.update.tax.config.line"
#. module: trp_update_tax
#: field:account.update.tax.config.line,amount_old:0
msgid "Old amount"
msgstr "Oud percentage"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Replace purchase tax defaults"
msgstr "Vervang standaardwaarden inkoopbelasting"
#. module: trp_update_tax
#: field:account.update.tax.config.line,purchase_config_id:0
#: field:account.update.tax.config.line,sale_config_id:0
#: field:account.update.tax.select_taxes,config_id:0
msgid "Configuration"
msgstr "Configuratie"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Create tax mappings"
msgstr "Aanmaken belastingomzettingen"
#. module: trp_update_tax
#: field:account.update.tax.config.line,target_tax_name:0
msgid "New tax name"
msgstr "Nieuwe belastingnaam"
#. module: trp_update_tax
#: field:account.update.tax.config,name:0
msgid "Name"
msgstr "Naam"
#. module: trp_update_tax
#: field:account.update.tax.config,purchase_set_defaults:0
msgid "Purchase tax defaults have been set"
msgstr "Standaard inkoopbelastingen zijn ingesteld"
#. module: trp_update_tax
#: model:ir.model,name:trp_update_tax.model_account_update_tax_select_taxes
msgid "account.update.tax.select_taxes"
msgstr "account.update.tax.select_taxes"
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.select_taxes,tax_ids:0
msgid "Taxes"
msgstr "Belastingen"
#. module: trp_update_tax
#: field:account.update.tax.select_taxes,covered_tax_ids:0
msgid "Covered taxes"
msgstr "Covered taxes"
#. module: trp_update_tax
#: help:account.update.tax.config,name:0
msgid "The processed taxes will be marked with this name"
msgstr "De verwerkte belastingen zullen met deze naam gemarkeerd worden"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Purchase updated"
msgstr "Inkoop bijgewerkt"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Sales updated"
msgstr "Verkopen bijgewerkt"
#. module: trp_update_tax
#: field:account.update.tax.config.line,source_tax_id:0
msgid "Source tax"
msgstr "Oorspronkelijke belasting"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Add purchase taxes"
msgstr "Inkoopbelastingen toevoegen"
#. module: trp_update_tax
#: field:account.update.tax.config.line,amount_new:0
msgid "New amount"
msgstr "Nieuw percentage"
#. module: trp_update_tax
#: model:ir.model,name:trp_update_tax.model_account_update_tax_config
msgid "Update taxes"
msgstr "Belastingen bijwerken"
#. module: trp_update_tax
#: model:ir.model,name:trp_update_tax.model_account_update_tax_select_taxes
msgid "Select the taxes to be updated"
msgstr "Selecteer de belastingen die moeten worden bijgewerkt"
#. module: trp_update_tax
#: sql_constraint:account.update.tax.config:0
msgid "Name must be unique."
msgstr "Naam moet uniek zijn"
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.config,sale_line_ids:0
msgid "Sales taxes"
msgstr "Verkoopbelastingen"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Done"
msgstr "Gereed"
#. module: trp_update_tax
#: field:account.update.tax.select_taxes,type_tax_use:0
msgid "Type tax use"
msgstr "Soort gebruik belasting"
#. module: trp_update_tax
#: view:account.update.tax.select_taxes:0
msgid "Cancel"
msgstr "Annuleren"
#. module: trp_update_tax
#: field:account.update.tax.config,sale_set_inactive:0
msgid "Sales taxes have been set to inactive"
msgstr "Verkoopbelastingen zijn inactief gemaakt"
#. module: trp_update_tax
#: help:account.update.tax.config,default_amount:0
msgid "Although it is possible to specify a distinct new amount per tax, you can set the default value here."
msgstr "Hoewel het mogelijk is om per belasting een nieuwe hoogte in te stellen, is het mogelijk om hier de standaardwaarde vast te leggen."

View File

@@ -0,0 +1,216 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * trp_update_tax
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.0.3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-09-19 19:51+0000\n"
"PO-Revision-Date: 2012-09-19 19:51+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.config,log:0
msgid "Log"
msgstr "Log"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Confirm"
msgstr "Confirm"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Set legacy purchase taxes inactive"
msgstr "Set legacy purchase taxes inactive"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Add sale taxes"
msgstr "Add sale taxes"
#. module: trp_update_tax
#: field:account.update.tax.config,state:0
msgid "State"
msgstr "State"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Draft"
msgstr "Draft"
#. module: trp_update_tax
#: field:account.update.tax.config,sale_set_defaults:0
msgid "Sales tax defaults have been set"
msgstr "Sales tax defaults have been set"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Replace sales tax defaults"
msgstr "Replace sales tax defaults"
#. module: trp_update_tax
#: view:account.update.tax.select_taxes:0
msgid "Save"
msgstr "Save"
#. module: trp_update_tax
#: field:account.update.tax.config,default_amount:0
msgid "Default new amount"
msgstr "Default new amount"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Purchase updated"
msgstr "Purchase updated"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Set legacy sales taxes inactive"
msgstr "Set legacy sales taxes inactive"
#. module: trp_update_tax
#: field:account.update.tax.config,purchase_set_inactive:0
msgid "Purchase taxes have been set to inactive"
msgstr "Purchase taxes have been set to inactive"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Replace purchase tax defaults"
msgstr "Replace purchase tax defaults"
#. module: trp_update_tax
#: field:account.update.tax.select_taxes,config_id:0
msgid "Configuration"
msgstr "Configuration"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Create tax mappings"
msgstr "Create tax mappings"
#. module: trp_update_tax
#: field:account.update.tax.config,name:0
msgid "Name"
msgstr "Name"
#. module: trp_update_tax
#: field:account.update.tax.config,purchase_set_defaults:0
msgid "Purchase tax defaults have been set"
msgstr "Purchase tax defaults have been set"
#. module: trp_update_tax
#: code:addons/trp_update_tax/model/update_tax_config.py:102
#: code:addons/trp_update_tax/model/update_tax_config.py:223
#: code:addons/trp_update_tax/model/update_tax_config.py:316
#, python-format
msgid "Can not detect tax use type"
msgstr "Can not detect tax use type"
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.select_taxes,covered_tax_ids:0
#: field:account.update.tax.select_taxes,tax_ids:0
msgid "Taxes"
msgstr "Taxes"
#. module: trp_update_tax
#: help:account.update.tax.config,name:0
msgid "The processed taxes will be marked with this name"
msgstr "The processed taxes will be marked with this name"
#. module: trp_update_tax
#: code:addons/trp_update_tax/model/update_tax_config.py:101
#: code:addons/trp_update_tax/model/update_tax_config.py:151
#: code:addons/trp_update_tax/model/update_tax_config.py:222
#: code:addons/trp_update_tax/model/update_tax_config.py:315
#, python-format
msgid "Error"
msgstr "Error"
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.config,purchase_line_ids:0
msgid "Purchase taxes"
msgstr "Purchase taxes"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Sales updated"
msgstr "Sales updated"
#. module: trp_update_tax
#: model:ir.model,name:trp_update_tax.model_account_update_tax_select_taxes
msgid "account.update.tax.select_taxes"
msgstr "account.update.tax.select_taxes"
#. module: trp_update_tax
#: view:account.update.tax.config:0
msgid "Add purchase taxes"
msgstr "Add purchase taxes"
#. module: trp_update_tax
#: code:addons/trp_update_tax/model/update_tax_config.py:152
#, python-format
msgid "You need to specify the new tax amount"
msgstr "You need to specify the new tax amount"
#. module: trp_update_tax
#: model:ir.actions.act_window,name:trp_update_tax.action_update_tax_config
#: model:ir.ui.menu,name:trp_update_tax.menu_update_tax_config
msgid "Update tax wizard"
msgstr "Update tax wizard"
#. module: trp_update_tax
#: model:ir.model,name:trp_update_tax.model_account_update_tax_config
msgid "Update taxes"
msgstr "Update taxes"
#. module: trp_update_tax
#: sql_constraint:account.update.tax.config:0
msgid "Name must be unique."
msgstr "Name must be unique."
#. module: trp_update_tax
#: view:account.update.tax.config:0
#: field:account.update.tax.config,sale_line_ids:0
msgid "Sales taxes"
msgstr "Sales taxes"
#. module: trp_update_tax
#: selection:account.update.tax.config,state:0
msgid "Done"
msgstr "Done"
#. module: trp_update_tax
#: field:account.update.tax.select_taxes,type_tax_use:0
msgid "Type tax use"
msgstr "Type tax use"
#. module: trp_update_tax
#: view:account.update.tax.select_taxes:0
msgid "Cancel"
msgstr "Cancel"
#. module: trp_update_tax
#: model:ir.model,name:trp_update_tax.model_account_tax
msgid "account.tax"
msgstr "account.tax"
#. module: trp_update_tax
#: field:account.update.tax.config,sale_set_inactive:0
msgid "Sales taxes have been set to inactive"
msgstr "Sales taxes have been set to inactive"
#. module: trp_update_tax
#: help:account.update.tax.config,default_amount:0
msgid "Although it is possible to specify a distinct new amount per tax, you can set the default value here."
msgstr "Although it is possible to specify a distinct new amount per tax, you can set the default value here."

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
# This module copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>).
#
# 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/>.
#
##############################################################################
from . import update_tax_config
from . import select_taxes
from . import account_tax

View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
# This module copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>).
#
# 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/>.
#
##############################################################################
from openerp.osv import orm
class account_tax(orm.Model):
_inherit = 'account.tax'
def name_get(self, cr, uid, ids, context=None):
if not ids:
return []
# unused res = []
if context and context.get('tax_real_name'):
return ((record['id'], record['name']) for record in self.read(
cr, uid, ids, ['name'], context=context))
return super(account_tax, self).name_get(cr, uid, ids, context=context)

View File

@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
# This module copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>).
#
# 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/>.
#
##############################################################################
from openerp.osv import orm, fields
class SelectTaxes(orm.TransientModel):
_name = 'account.update.tax.select_taxes'
_description = 'Select the taxes to be updated'
_rec_name = 'type_tax_use' # wha'evar
def save_taxes(self, cr, uid, ids, context=None):
"""
Create tax lines in the update tax configuration
based on a user selection of taxes.
From these taxes, gather their hierarchically related
other taxes which need to be duplicated to.
From this gathering, ignore any taxes that might
have been added by the user earlier on.
"""
wiz = self.browse(cr, uid, ids[0], context=context)
# unused tax_pool = self.pool.get('account.tax')
line_pool = self.pool.get('account.update.tax.config.line')
def get_root_node(tax):
if tax.parent_id:
return get_root_node(tax.parent_id)
return tax
def add_tree(tax):
result = [tax]
if tax.child_ids:
for child in tax.child_ids:
result += add_tree(child)
return result
covered = [
x.source_tax_id.id for x in
(wiz.config_id.sale_line_ids +
wiz.config_id.purchase_line_ids)
]
taxes = []
for tax in list(set(map(get_root_node, wiz.tax_ids))):
taxes += add_tree(tax)
for tax in filter(lambda x: x.id not in covered, taxes):
line_pool.create(
cr, uid,
{'%s_config_id' % wiz.type_tax_use: wiz.config_id.id,
'source_tax_id': tax.id,
},
context=context)
return {'type': 'ir.actions.act_window_close'}
_columns = {
'type_tax_use': fields.char(
'Type tax use', size=16, readonly=True),
'config_id': fields.many2one(
'account.update.tax.config',
'Configuration', readonly=True),
'tax_ids': fields.many2many(
'account.tax', 'update_tax_select_account_tax_rel',
'tax_select_id', 'tax_id',
string='Taxes'),
'covered_tax_ids': fields.many2many(
'account.tax', 'update_tax_select_covered_taxes_rel',
'tax_select_id', 'tax_id',
string='Covered taxes'),
}

View File

@@ -0,0 +1,476 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2012 Therp BV (<http://therp.nl>).
# This module copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>).
#
# 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/>.
#
##############################################################################
from datetime import datetime
import pickle
from openerp.osv import orm, fields
from openerp.tools.translate import _
class UpdateTaxConfig(orm.Model):
"""
A configuration model to collect taxes to be replaced with
duplicates, but with a different amount. Once the taxes are
collected, the following operations can be carried out by
the user.
1) generate the target taxes
2) Update defaults for sales taxes
3) Update defaults for purchase taxes
4) Set old taxes inactive
"""
_name = 'account.update.tax.config'
_description = 'Update taxes'
_columns = {
'name': fields.char(
'Name', size=64, required=True,
help="The processed taxes will be marked with this name"),
'log': fields.text(
'Log', readonly="1"),
'purchase_line_ids': fields.one2many(
'account.update.tax.config.line',
'purchase_config_id',
'Purchase taxes'),
'sale_line_ids': fields.one2many(
'account.update.tax.config.line',
'sale_config_id',
'Sales taxes'),
'state': fields.selection(
[('draft', 'Draft'),
('confirm', 'Confirm'),
('update_sales', 'Sales updated'),
('update_purchase', 'Purchase updated'),
('done', 'Done'),
], 'State', readonly=True),
'default_amount': fields.float(
'Default new amount', digits=(14, 4),
help=("Although it is possible to specify a distinct new amount "
"per tax, you can set the default value here.")),
'sale_set_defaults': fields.boolean(
'Sales tax defaults have been set',
readonly=True),
'purchase_set_defaults': fields.boolean(
'Purchase tax defaults have been set',
readonly=True),
'sale_set_inactive': fields.boolean(
'Sales taxes have been set to inactive',
readonly=True),
'purchase_set_inactive': fields.boolean(
'Purchase taxes have been set to inactive',
readonly=True),
'duplicate_tax_code': fields.boolean(
'Duplicate Tax code linked'),
}
_defaults = {
'state': 'draft',
}
_sql_constraints = [
('name_uniq', 'unique(name)', 'Name must be unique.'),
]
def add_lines(self, cr, uid, ids, context=None):
"""
Call the wizard that adds configuration lines
"""
if not ids:
return
if isinstance(ids, (int, float)):
ids = [ids]
wizard_obj = self.pool.get('account.update.tax.select_taxes')
config = self.browse(cr, uid, ids[0], context=context)
if not context or not context.get('type_tax_use'):
raise orm.except_orm(
_("Error"),
_("Can not detect tax use type"))
covered_tax_ids = [
x.source_tax_id.id
for x in config['purchase_line_ids'] + config['sale_line_ids']
]
res_id = wizard_obj.create(
cr, uid, {
'config_id': ids[0],
'type_tax_use': context['type_tax_use'],
'covered_tax_ids': [(6, 0, covered_tax_ids)],
}, context=context)
local_context = context.copy()
local_context['active_id'] = res_id
return {
'name': wizard_obj._description,
'view_type': 'form',
'view_mode': 'form',
'res_model': wizard_obj._name,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': res_id,
'nodestroy': True,
}
def confirm(self, cr, uid, ids, context=None):
"""
Set the configuration to confirmed, so that no new
taxes can be added. Create the duplicate taxes,
rename the legacy taxes and recreate the hierarchical
structure. Construct the fiscal position tax mappings.
"""
config = self.browse(cr, uid, ids[0], context=None)
tax_pool = self.pool.get('account.tax')
tax_code_pool = self.pool.get('account.tax.code')
line_pool = self.pool.get('account.update.tax.config.line')
tax_map = {}
log = (config.log or '') + (
"\n*** %s: Confirmed with the following taxes:\n" %
datetime.now().ctime())
for line in config.sale_line_ids + config.purchase_line_ids:
log += " - %s (%s)\n" % (
line.source_tax_id.name,
line.source_tax_id.description
)
# Switch names around, not violating the uniqueness constraint
tax_old_name = line.source_tax_id.name
tax_pool.write(
cr, uid, line.source_tax_id.id,
{'name': '[%s] %s' % (config.name, tax_old_name)},
context=context)
if line.source_tax_id.amount in [1.0, -1.0, 0]:
amount_new = line.source_tax_id.amount
else:
amount_new = config.default_amount or line.source_tax_id.amount
# 6.0 messes up the name change with copy + write, while
# 6.1 throws name uniqueness constraint violation
# So jumping some hoops with rewriting the new name
## We will check if we need to dupliace
cp_base_code_id = False
cp_ref_base_code_id = False
cp_tax_code_id = False
cp_ref_tax_code_id = False
if config.duplicate_tax_code:
if line.source_tax_id.base_code_id:
cp_base_code_id = tax_code_pool.copy(cr, uid,
line.source_tax_id.base_code_id.id)
rename_old = '[%s] %s' % (config.name,
line.source_tax_id.base_code_id.name)
tax_code_pool.write(cr, uid,
line.source_tax_id.base_code_id.id,
{'name': rename_old})
if line.source_tax_id.tax_code_id:
cp_tax_code_id = tax_code_pool.copy(cr, uid,
line.source_tax_id.tax_code_id.id)
rename_old = '[%s] %s' % (config.name,
line.source_tax_id.tax_code_id.name)
tax_code_pool.write(cr, uid,
line.source_tax_id.tax_code_id.id,
{'name': rename_old})
if line.source_tax_id.ref_base_code_id:
cp_ref_base_code_id = tax_code_pool.copy(cr, uid,
line.source_tax_id.ref_base_code_id.id)
rename_old = '[%s] %s' % (config.name,
line.source_tax_id.ref_base_code_id.name)
tax_code_pool.write(cr, uid,
line.source_tax_id.ref_base_code_id.id,
{'name': rename_old})
if line.source_tax_id.ref_tax_code_id:
cp_ref_tax_code_id = tax_code_pool.copy(cr, uid,
line.source_tax_id.ref_tax_code_id.id)
rename_old = '[%s] %s' % (config.name,
line.source_tax_id.ref_tax_code_id.name)
tax_code_pool.write(cr, uid,
line.source_tax_id.ref_tax_code_id.id,
{'name': rename_old})
else:
cp_base_code_id = line.source_tax_id.base_code_id and line.source_tax_id.base_code_id.id or False
cp_ref_base_code_id = line.source_tax_id.ref_base_code_id and line.source_tax_id.ref_base_code_id.id or False
cp_tax_code_id = line.source_tax_id.tax_code_id and line.source_tax_id.tax_code_id.id or False
cp_ref_tax_code_id = line.source_tax_id.ref_tax_code_id and line.source_tax_id.ref_tax_code_id.id or False
target_tax_id = tax_pool.copy(
cr, uid, line.source_tax_id.id,
{'name': '[update, %s] %s' % (config.name, tax_old_name),
'amount': amount_new,
'parent_id': False,
'child_ids': [(6, 0, [])],
}, context=context)
tax_pool.write(
cr, uid, target_tax_id, {'name': tax_old_name,
'base_code_id': cp_base_code_id,
'ref_base_code_id': cp_ref_base_code_id,
'tax_code_id': cp_tax_code_id,
'ref_tax_code_id': cp_ref_tax_code_id
}, context=context
)
tax_map[line.source_tax_id.id] = target_tax_id
line_pool.write(
cr, uid, line.id,
{'target_tax_id': target_tax_id}, context=context)
# Map the parent_id
# First, rebrowse the config
# (as browse_record.refresh() is not available in 6.0)
config = self.browse(cr, uid, ids[0], context=None)
for line in config.sale_line_ids + config.purchase_line_ids:
if line.source_tax_id.parent_id:
tax_pool.write(
cr, uid, line.target_tax_id.id,
{'parent_id': tax_map[line.source_tax_id.parent_id.id]},
context=context)
# Map fiscal positions
fp_tax_pool = self.pool.get('account.fiscal.position.tax')
fp_tax_ids = fp_tax_pool.search(
cr, uid, [('tax_src_id', 'in', tax_map.keys())], context=context)
fp_taxes = fp_tax_pool.browse(cr, uid, fp_tax_ids, context=context)
for fp_tax in fp_taxes:
new_fp_tax_id = fp_tax_pool.copy(
cr, uid, fp_tax.id,
{'tax_src_id': tax_map[fp_tax.tax_src_id.id],
'tax_dest_id': tax_map.get(
fp_tax.tax_dest_id.id, fp_tax.tax_dest_id.id)},
context=context)
new_fp_tax = fp_tax_pool.browse(
cr, uid, new_fp_tax_id, context=context)
log += ("\nCreate new tax mapping on position %s:\n"
"%s (%s)\n"
"=> %s (%s)\n" % (
new_fp_tax.position_id.name,
new_fp_tax.tax_src_id.name,
new_fp_tax.tax_src_id.description,
new_fp_tax.tax_dest_id.name,
new_fp_tax.tax_dest_id.description,
))
self.write(
cr, uid, ids[0],
{'state': 'confirm', 'log': log}, context=context)
return {
'name': self._description,
'view_type': 'form',
'view_mode': 'form',
'res_model': self._name,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'res_id': ids[0],
'nodestroy': True,
}
def set_defaults(self, cr, uid, ids, context=None):
if not context or not context.get('type_tax_use'):
raise orm.except_orm(
_("Error"),
_("Can not detect tax use type"))
local_context = context.copy()
local_context['active_test'] = False
config = self.browse(cr, uid, ids[0], context=None)
tax_lines = config['%s_line_ids' % context['type_tax_use']]
tax_map = dict([(x.source_tax_id.id, x.target_tax_id.id)
for x in tax_lines])
ir_values_pool = self.pool.get('ir.values')
log = (config.log or '') + (
"\n*** %s: Writing default %s taxes:\n" % (
datetime.now().ctime(),
context['type_tax_use']))
def update_defaults(model_name, field_name, column):
log = ''
if column._obj == 'account.tax':
values_ids = ir_values_pool.search(
cr, uid,
[('key', '=', 'default'),
('model', '=', model_name),
('name', '=', field_name)],
context=local_context)
for value in ir_values_pool.browse(
cr, uid, values_ids, context=context):
val = False
write = False
try:
# Currently, value_unpickle from ir_values
# fails as it feeds unicode to pickle.loads()
val = pickle.loads(str(value.value))
except:
continue
if isinstance(val, (int, long)) and val in tax_map:
write = True
new_val = tax_map[val]
elif isinstance(val, list) and val:
new_val = []
for i in val:
if i in tax_map:
write = True
new_val.append(tax_map.get(i, i))
if write:
log += "Default (%s => %s) for %s,%s\n" % (
val, new_val, model_name, field_name)
ir_values_pool.write(
cr, uid, value.id,
{'value_unpickle': new_val}, context=context)
return log
model_pool = self.pool.get('ir.model')
model_ids = model_pool.search(cr, uid, [], context=context)
models = model_pool.read(
cr, uid, model_ids, ['model'], context=context)
pool_models_items = [(x['model'], self.pool.get(
x['model'])) for x in models]
# 6.1: self.pool.models.items():
for model_name, model in pool_models_items:
if model:
for field_name, column in model._columns.items():
log += update_defaults(model_name, field_name, column)
for field_name, field_tuple in model._inherit_fields.iteritems():
if len(field_tuple) >= 3:
column = field_tuple[2]
log += update_defaults(model_name, field_name, column)
log += "\nReplacing %s taxes on accounts and products\n" % (
context['type_tax_use'])
for (model, field) in [
# make this a configurable list of ir_model_fields one day?
('account.account', 'tax_ids'),
('product.product', 'supplier_taxes_id'),
('product.product', 'taxes_id'),
('product.template', 'supplier_taxes_id'),
('product.template', 'taxes_id')]:
pool = self.pool.get(model)
obj_ids = pool.search(
cr, uid, [(field, 'in', tax_map.keys())],
context=local_context)
for obj in pool.read(
cr, uid, obj_ids, [field], context=context):
new_val = []
write = False
for i in obj[field]:
if i in tax_map:
write = True
new_val.append(tax_map.get(i, i))
if write:
pool.write(
cr, uid, obj['id'],
{field: [(6, 0, new_val)]},
context=context)
log += "Value (%s => %s) for %s,%s,%s\n" % (
obj[field], new_val, model, field, obj['id'])
self.write(
cr, uid, ids[0],
{'log': log, '%s_set_defaults' % context['type_tax_use']: True},
context=context)
return {
'name': self._description,
'view_type': 'form',
'view_mode': 'form',
'res_model': self._name,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'res_id': ids[0],
'nodestroy': True,
}
def set_inactive(self, cr, uid, ids, context=None):
if not context or not context.get('type_tax_use'):
raise orm.except_orm(
_("Error"),
_("Can not detect tax use type"))
config = self.browse(cr, uid, ids[0], context=None)
tax_lines = config['%s_line_ids' % context['type_tax_use']]
tax_pool = self.pool.get('account.tax')
tax_ids = tax_pool.search(
cr, uid,
[('id', 'in',
[x.source_tax_id.id for x in tax_lines])],
context=context)
tax_pool.write(
cr, uid, tax_ids, {'active': False}, context=context)
log = (config.log or '') + (
"\n*** %s: Setting %s %s taxes inactive\n" % (
datetime.now().ctime(),
len(tax_ids),
context['type_tax_use']))
self.write(
cr, uid, ids[0],
{'log': log, '%s_set_inactive' % context['type_tax_use']: True},
context=context)
return {
'name': self._description,
'view_type': 'form',
'view_mode': 'form',
'res_model': self._name,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'res_id': ids[0],
'nodestroy': True,
}
class UpdateTaxConfigLine(orm.Model):
_name = 'account.update.tax.config.line'
_description = "Tax update configuration lines"
_rec_name = 'source_tax_id' # Wha'evuh
def _get_config_field(
self, cr, uid, ids, field, args, context=None):
# Retrieve values of the associated config_id
# either sale or purchase
result = dict([(x, False) for x in ids or []])
for x in self.browse(cr, uid, ids, context=context):
config = x['sale_config_id'] or x['purchase_config_id']
if config:
result[x.id] = config[field]
return result
_columns = {
'purchase_config_id': fields.many2one(
'account.update.tax.config',
'Configuration'),
'sale_config_id': fields.many2one(
'account.update.tax.config',
'Configuration'),
'source_tax_id': fields.many2one(
'account.tax', 'Source tax',
required=True),
'source_tax_description': fields.related(
'source_tax_id', 'description',
type='char', size=32,
string="Old tax code"),
'target_tax_id': fields.many2one(
'account.tax', 'Target tax'),
'target_tax_description': fields.related(
'target_tax_id', 'description',
type='char', size=32,
string="New tax code"),
'amount_old': fields.related(
'source_tax_id', 'amount',
type='float', digits=(14, 4),
string='Old amount', readonly=True),
'amount_new': fields.related(
'target_tax_id', 'amount',
type='float', digits=(14, 4),
string='New amount'),
'state': fields.function(
_get_config_field, 'state', method=True,
type='char', size=16, string='State'),
}

View File

@@ -0,0 +1,5 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_config","Read access to the tax update configuration","model_account_update_tax_config","account.group_account_user",1,0,0,0
"access_config_manager","Write access to the tax update configuration","model_account_update_tax_config","account.group_account_manager",1,1,1,1
"access_config_line","Read access to the tax update configuration lines","model_account_update_tax_config_line","account.group_account_user",1,0,0,0
"access_config__line_manager","Write access to the tax update configuration lines","model_account_update_tax_config_line","account.group_account_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_config Read access to the tax update configuration model_account_update_tax_config account.group_account_user 1 0 0 0
3 access_config_manager Write access to the tax update configuration model_account_update_tax_config account.group_account_manager 1 1 1 1
4 access_config_line Read access to the tax update configuration lines model_account_update_tax_config_line account.group_account_user 1 0 0 0
5 access_config__line_manager Write access to the tax update configuration lines model_account_update_tax_config_line account.group_account_manager 1 1 1 1

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="tax_tree_view" model="ir.ui.view">
<field name="name">Tax tree view for the add lines wizard</field>
<field name="model">account.tax</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Taxes">
<field name="name"/>
<field name="description"/>
<field name="amount"/>
</tree>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="update_tax_config_add_lines_form" model="ir.ui.view">
<field name="name">Update tax select taxes form"</field>
<field name="model">account.update.tax.select_taxes</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Taxes">
<label colspan="4" string="Add the taxes that need to be replaced here. Any parent or child taxes will be added automatically when you close this window."/>
<field name="tax_ids" colspan="4" nolabel="1"
domain="['|',('type_tax_use','=','all'),('type_tax_use','=',type_tax_use),('id', 'not in', covered_tax_ids[0][2])]"
context="{'tree_view_ref': 'account_tax_update.tax_tree_view'}"
/>
<newline/>
<button icon="gtk-close"
special="cancel"
string="Cancel"
/>
<button icon="gtk-ok"
name="save_taxes"
string="Save"
type="object"
/>
<newline/>
<group>
<field name="covered_tax_ids" invisible="1"/>
<field name="type_tax_use" invisible="1"/>
<field name="config_id" invisible="1"/>
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="update_tax_config_form" model="ir.ui.view">
<field name="name">Update tax config form"</field>
<field name="model">account.update.tax.config</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Taxes">
<field name="name"
attrs="{'readonly': [('state', '!=', 'draft')]}"
/>
<field name="duplicate_tax_code"
attrs="{'readonly': [('state', '!=', 'draft')]}"
/>
<field name="state"/>
<field name="default_amount"
attrs="{'readonly': [('state', '!=', 'draft')]}"
/>
<notebook colspan="4">
<page string="Taxes">
<group string="Sales taxes" col="4" colspan="4">
<field name="sale_line_ids" height="200"
nolabel="1" colspan="4"
context="{'tax_real_name': 1}"
/>
<button name="add_lines"
type="object"
string="Add sale taxes"
context="{'type_tax_use': 'sale'}"
states="draft"/>
<button name="set_defaults"
string="Replace sales tax defaults"
type="object"
context="{'type_tax_use': 'sale'}"
attrs="{'invisible': ['|', ('state', '!=', 'confirm'), ('sale_set_defaults', '!=', False)]}"
/>
<button name="set_inactive"
string="Set legacy sales taxes inactive"
type="object"
context="{'type_tax_use': 'sale'}"
attrs="{'invisible': ['|', ('state', '!=', 'confirm'), ('sale_set_inactive', '!=', False)]}"
/>
</group>
<group string="Purchase taxes" col="4" colspan="4">
<field name="purchase_line_ids"
nolabel="1" colspan="4" height="200"
context="{'tax_real_name': 1}"
/>
<button name="add_lines"
type="object"
string="Add purchase taxes"
context="{'type_tax_use': 'purchase'}"
states="draft"/>
<button name="set_defaults"
string="Replace purchase tax defaults"
type="object"
context="{'type_tax_use': 'purchase'}"
attrs="{'invisible': ['|', ('state', '!=', 'confirm'), ('purchase_set_defaults', '!=', False)]}"
/>
<button name="set_inactive"
string="Set legacy purchase taxes inactive"
type="object"
attrs="{'invisible': ['|', ('state', '!=', 'confirm'), ('purchase_set_inactive', '!=', False)]}"
context="{'type_tax_use': 'purchase'}"
/>
</group>
<field name="purchase_set_inactive" invisible="1"/>
<field name="sale_set_inactive" invisible="1"/>
<field name="purchase_set_defaults" invisible="1"/>
<field name="sale_set_defaults" invisible="1"/>
</page>
<page string="Log">
<field name="log" colspan="4" nolabel="1"/>
</page>
</notebook>
<button name="confirm"
string="Create tax mappings"
states="draft"
type="object"
help="When you are done configuring the new tax amounts, click here to create the new taxes and a mapping between the new and old taxes"
/>
</form>
</field>
</record>
<record id="update_tax_config_line_tree" model="ir.ui.view">
<field name="name">Update tax config line tree"</field>
<field name="model">account.update.tax.config.line</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Taxes" editable="bottom">
<field name="source_tax_id"/>
<field name="source_tax_description"/>
<field name="amount_old"/>
<field name="target_tax_id" attrs="{'readonly': [('state', '!=', 'confirm')]}" />
<field name="state" invisible='1'/>
<field name="target_tax_description"/>
<field name="amount_new"/>
</tree>
</field>
</record>
<record id="action_update_tax_config"
model="ir.actions.act_window">
<field name="name">Update tax wizard</field>
<field name="res_model">account.update.tax.config</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help">For every tax increase, you can create a new configuration. Select sales and purchase taxes to adapt. The selected taxes will be duplicated. The old tax names will be prefixed with a 'legacy' tag. Change the new tax names and codes in the window below to reflect the amount change. The new taxes then become available to select manually on sale or purchase order lines. You may also want to change the names of the associated tax codes, or reassign them between the taxes. At specific times during the transition, you can replace the default sales and purchase taxes in the system. Eventually you can hide the obsolete taxes by making them inactive. Until then, you can still select the old taxes manually</field>
</record>
<menuitem id="menu_update_tax_config"
parent="account.next_id_27" name="Update tax wizard"
action="action_update_tax_config"
sequence="45"/>
</data>
</openerp>