[FIX] typo on statement name
[odoo/odoo.git] / addons / account / account.py
index a4e59da..280d413 100644 (file)
@@ -130,8 +130,45 @@ account_payment_term_line()
 class account_account_type(osv.osv):
     _name = "account.account.type"
     _description = "Account Type"
+
+    def _get_current_report_type(self, cr, uid, ids, name, arg, context=None):
+        obj_data = self.pool.get('ir.model.data')
+        obj_financial_report = self.pool.get('account.financial.report') 
+        res = {}
+        financial_report_ref = {
+            'asset': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_assets0')[1], context=context),
+            'liability': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_liability0')[1], context=context),
+            'income': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_income0')[1], context=context),
+            'expense': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_expense0')[1], context=context),
+        }
+        for record in self.browse(cr, uid, ids, context=context):
+            res[record.id] = 'none'
+            for key, financial_report in financial_report_ref.items():
+                list_ids = [x.id for x in financial_report.account_type_ids]
+                if record.id in list_ids:
+                    res[record.id] = key
+        return res
+
+    def _save_report_type(self, cr, uid, account_type_id, field_name, field_value, arg, context=None):
+        obj_data = self.pool.get('ir.model.data')
+        obj_financial_report = self.pool.get('account.financial.report') 
+        #unlink if it exists somewhere in the financial reports related to BS or PL
+        financial_report_ref = {
+            'asset': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_assets0')[1], context=context),
+            'liability': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_liability0')[1], context=context),
+            'income': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_income0')[1], context=context),
+            'expense': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_expense0')[1], context=context),
+        }
+        for key, financial_report in financial_report_ref.items():
+            list_ids = [x.id for x in financial_report.account_type_ids]
+            if account_type_id in list_ids:
+                obj_financial_report.write(cr, uid, [financial_report.id], {'account_type_ids': [(3, account_type_id)]})
+        #write it in the good place
+        if field_value != 'none':
+            return obj_financial_report.write(cr, uid, [financial_report_ref[field_value].id], {'account_type_ids': [(4, account_type_id)]})
+
     _columns = {
-        'name': fields.char('Account Type', size=64, required=True),
+        'name': fields.char('Account Type', size=64, required=True, translate=True),
         'code': fields.char('Code', size=32, required=True),
         'close_method': fields.selection([('none', 'None'), ('balance', 'Balance'), ('detail', 'Detail'), ('unreconciled', 'Unreconciled')], 'Deferral Method', required=True, help="""Set here the method that will be used to generate the end of year journal entries for all the accounts of this type.
 
@@ -139,19 +176,16 @@ class account_account_type(osv.osv):
  'Balance' will generally be used for cash accounts.
  'Detail' will copy each existing journal item of the previous year, even the reconciled ones.
  'Unreconciled' will copy only the journal items that were unreconciled on the first day of the new fiscal year."""),
-        'sign': fields.selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for  accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.'),
-        'report_type':fields.selection([
-            ('none','/'),
-            ('income','Profit & Loss (Income Accounts)'),
-            ('expense','Profit & Loss (Expense Accounts)'),
-            ('asset','Balance Sheet (Asset Accounts)'),
-            ('liability','Balance Sheet (Liability Accounts)')
-        ],'P&L / BS Category', select=True, readonly=False, help="This field is used to generate legal reports: profit and loss, balance sheet.", required=True),
+        'report_type': fields.function(_get_current_report_type, fnct_inv=_save_report_type, type='selection', string='P&L / BS Category', 
+            selection= [('none','/'),
+                        ('income', _('Profit & Loss (Income account)')),
+                        ('expense', _('Profit & Loss (Expense account)')),
+                        ('asset', _('Balance Sheet (Asset account)')),
+                        ('liability', _('Balance Sheet (Liability account)'))], help="This field is used to generate legal reports: profit and loss, balance sheet.", required=True),
         'note': fields.text('Description'),
     }
     _defaults = {
         'close_method': 'none',
-        'sign': 1,
         'report_type': 'none',
     }
     _order = "code"
@@ -422,6 +456,7 @@ class account_account(osv.osv):
         'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
             help="Account Type is used for information purpose, to generate "
               "country-specific legal reports, and set the rules to close a fiscal year and generate opening entries."),
+        'financial_report_ids': fields.many2many('account.financial.report', 'account_account_financial_report', 'account_id', 'report_line_id', 'Financial Reports'),
         'parent_id': fields.many2one('account.account', 'Parent', ondelete='cascade', domain=[('type','=','view')]),
         'child_parent_ids': fields.one2many('account.account','parent_id','Children'),
         'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
@@ -760,7 +795,6 @@ class account_journal(osv.osv):
 
         seq = {
             'name': vals['name'],
-            'company_id': vals['company_id'],
             'implementation':'no_gap',
             'prefix': prefix + "/%(year)s/",
             'padding': 4,
@@ -772,7 +806,9 @@ class account_journal(osv.osv):
 
     def create(self, cr, uid, vals, context=None):
         if not 'sequence_id' in vals or not vals['sequence_id']:
-            vals.update({'sequence_id': self.create_sequence(cr, uid, vals, context)})
+            # if we have the right to create a journal, we should be able to
+            # create it's sequence.
+            vals.update({'sequence_id': self.create_sequence(cr, 1, vals, context)})
         return super(account_journal, self).create(cr, uid, vals, context)
 
     def name_get(self, cr, user, ids, context=None):
@@ -790,9 +826,11 @@ class account_journal(osv.osv):
         result = self.browse(cr, user, ids, context=context)
         res = []
         for rs in result:
-            name = rs.name
             if rs.currency:
-                name = "%s (%s)" % (rs.name, rs.currency.name)
+                currency = rs.currency
+            else:
+                currency = rs.company_id.currency_id
+            name = "%s (%s)" % (rs.name, currency.name)
             res += [(rs.id, name)]
         return res
 
@@ -1224,7 +1262,7 @@ class account_move(osv.osv):
         'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
         'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
         'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'State', required=True, readonly=True,
-            help='All manually created new journal entry are usually in the state \'Unposted\', but you can set the option to skip that state on the related journal. In that case, they will be behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' state.'),
+            help='All manually created new journal entries are usually in the state \'Unposted\', but you can set the option to skip that state on the related journal. In that case, they will be behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' state.'),
         'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
         'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
         'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
@@ -2421,6 +2459,7 @@ class account_account_template(osv.osv):
         'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
             help="These types are defined according to your country. The type contains more information "\
             "about the account and its specificities."),
+        'financial_report_ids': fields.many2many('account.financial.report', 'account_template_financial_report', 'account_template_id', 'report_line_id', 'Financial Reports'),
         'reconcile': fields.boolean('Allow Reconciliation', help="Check this option if you want the user to reconcile entries in this account."),
         'shortcut': fields.char('Shortcut', size=12),
         'note': fields.text('Note'),
@@ -2428,7 +2467,7 @@ class account_account_template(osv.osv):
         'child_parent_ids':fields.one2many('account.account.template', 'parent_id', 'Children'),
         'tax_ids': fields.many2many('account.tax.template', 'account_account_template_tax_rel', 'account_id', 'tax_id', 'Default Taxes'),
         'nocreate': fields.boolean('Optional create', help="If checked, the new chart of accounts will not contain this by default."),
-        'chart_template_id': fields.many2one('account.chart.template', 'Chart Template'),
+        'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', help="This optional field allow you to link an account template to a specific chart template that may differ from the one its root parent belongs to. This allow you to define chart templates that extend another and complete it with few new accounts (You don't need to define the whole structure that is common to both several times)."),
     }
 
     _defaults = {
@@ -2465,30 +2504,31 @@ class account_account_template(osv.osv):
             res.append((record['id'],name ))
         return res
 
-    def generate_account(self, cr, uid, template_id, tax_template_ref, code_digits, company_id, context=None):
+    def generate_account(self, cr, uid, chart_template_id, tax_template_ref, acc_template_ref, code_digits, company_id, context=None):
         """
         This method for generating accounts from templates.
-        @param cr: A database cursor.
-        @param uid: ID of the user currently logged in.
-        @param account_root_id: Root account id getting from current template.
-        @param tax_template_ref: Taxes templates reference for write taxes_id in account_account.
-        @param code_digits: Digit getting from wizard.multi.charts.accounts.,this is use for account code.
-        @param company_id: company_id selected from wizard.multi.charts.accounts.
-        @return : return acc_template_ref for reference purpose.
+
+        :param chart_template_id: id of the chart template chosen in the wizard
+        :param tax_template_ref: Taxes templates reference for write taxes_id in account_account.
+        :paramacc_template_ref: dictionary with the mappping between the account templates and the real accounts.
+        :param code_digits: number of digits got from wizard.multi.charts.accounts, this is use for account code.
+        :param company_id: company_id selected from wizard.multi.charts.accounts.
+        :returns: return acc_template_ref for reference purpose.
+        :rtype: dict
         """
         if context is None:
             context = {}
         obj_acc = self.pool.get('account.account')
         company_name = self.pool.get('res.company').browse(cr, uid, company_id, context=context).name
-        template = self.pool.get('account.chart.template').browse(cr, uid, template_id, context=context)
-        acc_template_ref = {}
+        template = self.pool.get('account.chart.template').browse(cr, uid, chart_template_id, context=context)
         #deactivate the parent_store functionnality on account_account for rapidity purpose
         ctx = context.copy()
         ctx.update({'defer_parent_store_computation': True})
-        #import pdb;pdb.set_trace()
-        #TODO: this is where the program currently fail as the search doesn't return the template id 16 (bank view id of demo chart C)
-        children_acc_template = self.search(cr, uid, [('parent_id','child_of', [template.account_root_id.id]),'|', ('chart_template_id','=', [template_id]),('chart_template_id','=', False), ('nocreate','!=',True)], order='id')
+        children_acc_template = self.search(cr, uid, ['|', ('chart_template_id','=', [chart_template_id]),'&',('parent_id','child_of', [template.account_root_id.id]),('chart_template_id','=', False), ('nocreate','!=',True)], order='id')
         for account_template in self.browse(cr, uid, children_acc_template, context=context):
+            # skip the root of COA if it's not the main one
+            if (template.account_root_id.id == account_template.id) and template.parent_id:
+                continue
             tax_ids = []
             for tax in account_template.tax_ids:
                 tax_ids.append(tax_template_ref[tax.id])
@@ -2506,6 +2546,7 @@ class account_account_template(osv.osv):
                 'reconcile': account_template.reconcile,
                 'shortcut': account_template.shortcut,
                 'note': account_template.note,
+                'financial_report_ids': account_template.financial_report_ids and [(6,0,[x.id for x in account_template.financial_report_ids])] or False,
                 'parent_id': account_template.parent_id and ((account_template.parent_id.id in acc_template_ref) and acc_template_ref[account_template.parent_id.id]) or False,
                 'tax_ids': [(6,0,tax_ids)],
                 'company_id': company_id,
@@ -2621,7 +2662,7 @@ class account_tax_code_template(osv.osv):
                 'sign': tax_code_template.sign,
             }
             #check if this tax code already exists
-            rec_list = obj_tax_code.search(cr, uid, [('name', '=', vals['name']),('company_id', '=', vals['company_id'])], context=context)
+            rec_list = obj_tax_code.search(cr, uid, [('name', '=', vals['name']),('code', '=', vals['code']),('company_id', '=', vals['company_id'])], context=context)
             if not rec_list:
                 #if not yet, create it
                 new_tax_code = obj_tax_code.create(cr, uid, vals)
@@ -2718,7 +2759,6 @@ class account_tax_template(osv.osv):
         'description': fields.char('Internal Name', size=32),
         'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Use In', required=True,),
         'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
-        'installable': fields.boolean('Should be Installed', help="Set this to False if you do not want to create real tax object from this template.")
     }
 
     def name_get(self, cr, uid, ids, context=None):
@@ -2750,24 +2790,22 @@ class account_tax_template(osv.osv):
         'include_base_amount': False,
         'type_tax_use': 'all',
         'price_include': 0,
-        'installable': True
     }
     _order = 'sequence'
 
-    def generate_tax(self, cr, uid, tax_templates, tax_code_template_ref, company_id, context=None):
+    def _generate_tax(self, cr, uid, tax_templates, tax_code_template_ref, company_id, context=None):
         """
         This method generate taxes from templates.
-        @param cr: A database cursor.
-        @param uid: ID of the user currently logged in.
-        @param tax_templates: Tax templates.
-        @param tax_code_template_ref: Taxcode templates reference.
-        @param company_id: if tax generated from account multi wizard at that time company_id is wizard company_id field
-        or logged user company_id.
-        @param Return: 
-        {'tax_template_to_tax': New generated taxes ids, 
-         'account_dict': Used this reference value for Account Tax, 
-        }
-        """#TODO: improve this docstring
+
+        :param tax_templates: list of browse record of the tax templates to process
+        :param tax_code_template_ref: Taxcode templates reference.
+        :param company_id: id of the company the wizard is running for
+        :returns:
+            {
+            'tax_template_to_tax': mapping between tax template and the newly generated taxes corresponding,
+            'account_dict': dictionary containing a to-do list with all the accounts to assign on new taxes
+            }
+        """
         if context is None:
             context = {}
         res = {}
@@ -2828,13 +2866,13 @@ class account_fiscal_position_template(osv.osv):
 
     def generate_fiscal_position(self, cr, uid, chart_temp_id, tax_template_ref, acc_template_ref, company_id, context=None):
         """
-        This method generate Fiscal Position , Fiscal Position Accounts and Fiscal Position Taxes from templates.
-        @param cr: A database cursor.
-        @param uid: ID of the user currently logged in.
-        @param chart_temp_id: Chart Template Id.
-        @param taxes_ids: Taxes templates reference for generating account.fiscal.position.tax.
-        @param acc_template_ref: Account templates reference for generating account.fiscal.position.account.
-        @param company_id: company_id selected from wizard.multi.charts.accounts.
+        This method generate Fiscal Position, Fiscal Position Accounts and Fiscal Position Taxes from templates.
+
+        :param chart_temp_id: Chart Template Id.
+        :param taxes_ids: Taxes templates reference for generating account.fiscal.position.tax.
+        :param acc_template_ref: Account templates reference for generating account.fiscal.position.account.
+        :param company_id: company_id selected from wizard.multi.charts.accounts.
+        :returns: True
         """
         if context is None:
             context = {}
@@ -2856,7 +2894,7 @@ class account_fiscal_position_template(osv.osv):
                     'account_dest_id': acc_template_ref[acc.account_dest_id.id],
                     'position_id': new_fp
                 })
-        return {}
+        return True
 
 account_fiscal_position_template()
 
@@ -2911,6 +2949,7 @@ class account_financial_report(osv.osv):
         return res
 
     def _get_balance(self, cr, uid, ids, name, args, context=None):
+        account_obj = self.pool.get('account.account')
         res = {}
         res_all = {}
         for report in self.browse(cr, uid, ids, context=context):
@@ -2921,6 +2960,12 @@ class account_financial_report(osv.osv):
                 # it's the sum of balance of the linked accounts
                 for a in report.account_ids:
                     balance += a.balance
+            elif report.type == 'account_type':
+                # it's the sum of balance of the leaf accounts with such an account type
+                report_types = [x.id for x in report.account_type_ids]
+                account_ids = account_obj.search(cr, uid, [('user_type','in', report_types), ('type','!=','view')], context=context)
+                for a in account_obj.browse(cr, uid, account_ids, context=context):
+                    balance += a.balance
             elif report.type == 'account_report' and report.account_report_id:
                 # it's the amount of the linked report
                 res2 = self._get_balance(cr, uid, [report.account_report_id.id], 'balance', False, context=context)
@@ -2943,7 +2988,6 @@ class account_financial_report(osv.osv):
         'parent_id': fields.many2one('account.financial.report', 'Parent'),
         'children_ids':  fields.one2many('account.financial.report', 'parent_id', 'Account Report'),
         'sequence': fields.integer('Sequence'),
-        'note': fields.text('Notes'),
         'balance': fields.function(_get_balance, 'Balance'),
         'level': fields.function(_get_level, string='Level', store=True, type='integer'),
         'type': fields.selection([
@@ -2953,13 +2997,20 @@ class account_financial_report(osv.osv):
             ('account_report','Report Value'),
             ],'Type'),
         'account_ids': fields.many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts'),
-        'display_detail': fields.boolean('Display details', help='Display every account with its balance instead of the sum.'),
+        'display_detail': fields.selection([
+            ('no_detail','No detail'),
+            ('detail_flat','Display children flat'),
+            ('detail_with_hierarchy','Display children with hierarchy')
+            ], 'Display details'),
         'account_report_id':  fields.many2one('account.financial.report', 'Report Value'),
         'account_type_ids': fields.many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types'),
+        'sign': fields.selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.'),
     }
 
     _defaults = {
         'type': 'sum',
+        'display_detail': 'detail_flat',
+        'sign': 1,
     }
 
 account_financial_report()
@@ -2990,7 +3041,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
         'bank_accounts_id': fields.one2many('account.bank.accounts.wizard', 'bank_account_id', 'Cash and Banks', required=True),
         'code_digits':fields.integer('# of Digits', required=True, help="No. of Digits to use for account code"),
         'seq_journal':fields.boolean('Separated Journal Sequences', help="Check this box if you want to use a different sequence for each created journal. Otherwise, all will use the same sequence."),
-        "sale_tax": fields.many2one("account.tax.template", "Default Sales Tax"),
+        "sale_tax": fields.many2one("account.tax.template", "Default Sale Tax"),
         "purchase_tax": fields.many2one("account.tax.template", "Default Purchase Tax"),
         'sale_tax_rate': fields.float('Sales Tax(%)'),
         'purchase_tax_rate': fields.float('Purchase Tax(%)'),
@@ -3006,9 +3057,9 @@ class wizard_multi_charts_accounts(osv.osv_memory):
             if data.complete_tax_set:
             # default tax is given by the lowest sequence. For same sequence we will take the latest created as it will be the case for tax created while isntalling the generic chart of account
                 sale_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id"
-                                              , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all')), ('installable', '=', True)], order="sequence, id desc")
+                                              , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all'))], order="sequence, id desc")
                 purchase_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id"
-                                              , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all')), ('installable', '=', True)], order="sequence, id desc")
+                                              , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all'))], order="sequence, id desc")
                 res['value'].update({'sale_tax': sale_tax_ids and sale_tax_ids[0] or False, 'purchase_tax': purchase_tax_ids and purchase_tax_ids[0] or False})
 
             if data.code_digits:
@@ -3035,11 +3086,11 @@ class wizard_multi_charts_accounts(osv.osv_memory):
                 res.update({'chart_template_id': ids[0]})
             if 'sale_tax' in fields:
                 sale_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id"
-                                              , "=", ids[0]), ('type_tax_use', 'in', ('sale','all')), ('installable', '=', True)], order="sequence")
+                                              , "=", ids[0]), ('type_tax_use', 'in', ('sale','all'))], order="sequence")
                 res.update({'sale_tax': sale_tax_ids and sale_tax_ids[0] or False})
             if 'purchase_tax' in fields:
                 purchase_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id"
-                                          , "=", ids[0]), ('type_tax_use', 'in', ('purchase','all')), ('installable', '=', True)], order="sequence")
+                                          , "=", ids[0]), ('type_tax_use', 'in', ('purchase','all'))], order="sequence")
                 res.update({'purchase_tax': purchase_tax_ids and purchase_tax_ids[0] or False})
         return res
 
@@ -3049,7 +3100,6 @@ class wizard_multi_charts_accounts(osv.osv_memory):
         acc_template_obj = self.pool.get('account.chart.template')
         company_obj = self.pool.get('res.company')
 
-        template_ids = acc_template_obj.search(cr, uid, [('visible', '=', True)], context=context)
         company_ids = company_obj.search(cr, uid, [], context=context)
         #display in the widget selection of companies, only the companies that haven't been configured yet (but don't care about the demo chart of accounts)
         cr.execute("SELECT company_id FROM account_account WHERE active = 't' AND account_account.parent_id IS NULL AND name != %s", ("Chart For Automated Tests",))
@@ -3062,11 +3112,6 @@ class wizard_multi_charts_accounts(osv.osv_memory):
                 if unconfigured_cmp:
                     cmp_select = [(line.id, line.name) for line in company_obj.browse(cr, uid, unconfigured_cmp)]
                     res['fields'][field]['selection'] = cmp_select
-            if field == 'chart_template_id':
-                res['fields'][field]['selection'] = [('', '')]
-                if template_ids:
-                    template_select = [(template.id, template.name) for template in acc_template_obj.browse(cr, uid, template_ids)]
-                    res['fields'][field]['selection'] = template_select
         return res
 
     def check_created_journals(self, cr, uid, vals_journal, company_id, context=None):
@@ -3081,12 +3126,12 @@ class wizard_multi_charts_accounts(osv.osv_memory):
 
     def generate_journals(self, cr, uid, chart_template_id, acc_template_ref, company_id, context=None):
         """
-        This method used for creating journals.
-        @param cr: A database cursor.
-        @param uid: ID of the user currently logged in.
-        @param chart_temp_id: Chart Template Id.
-        @param acc_template_ref: Account templates reference.
-        @param company_id: company_id selected from wizard.multi.charts.accounts.
+        This method is used for creating journals.
+
+        :param chart_temp_id: Chart Template Id.
+        :param acc_template_ref: Account templates reference.
+        :param company_id: company_id selected from wizard.multi.charts.accounts.
+        :returns: True
         """
         journal_data = self._prepare_all_journals(cr, uid, chart_template_id, acc_template_ref, company_id, context=context)
         for vals_journal in journal_data:
@@ -3169,11 +3214,11 @@ class wizard_multi_charts_accounts(osv.osv_memory):
     def generate_properties(self, cr, uid, chart_template_id, acc_template_ref, company_id, context=None):
         """
         This method used for creating properties.
-        @param cr: A database cursor.
-        @param uid: ID of the user currently logged in.
-        @param chart_temp_id: Chart Template Id.
-        @param acc_template_ref: Account templates reference.
-        @param company_id: company_id selected from wizard.multi.charts.accounts.
+
+        :param chart_template_id: id of the current chart template for which we need to create properties
+        :param acc_template_ref: Mapping between ids of account templates and real accounts created from them
+        :param company_id: company_id selected from wizard.multi.charts.accounts.
+        :returns: True
         """
         property_obj = self.pool.get('ir.property')
         field_obj = self.pool.get('ir.model.fields')
@@ -3186,28 +3231,28 @@ class wizard_multi_charts_accounts(osv.osv_memory):
             ('property_account_income','product.template','account.account'),
             ('property_reserve_and_surplus_account','res.company','account.account')
         ]
-        template_id = self.pool.get('account.chart.template').browse(cr, uid, chart_template_id, context=context)
+        template = self.pool.get('account.chart.template').browse(cr, uid, chart_template_id, context=context)
         for record in todo_list:
-            rec_list = []
-            rec_list = property_obj.search(cr, uid, [('name','=', record[0]),('company_id', '=', company_id)], context=context)
-            account = getattr(template_id, record[0])
-            field = field_obj.search(cr, uid, [('name', '=', record[0]),('model', '=', record[1]),('relation', '=', record[2])], context=context)
-            vals = {
-                'name': record[0],
-                'company_id': company_id,
-                'fields_id': field[0],
-                'value': account and 'account.account,' + str(acc_template_ref[account.id]) or False,
-            }
-
-            if rec_list:
-                #the property exist: modify it
-                property_obj.write(cr, uid, rec_list, vals, context=context)
-            else:
-                #create the property
-                property_obj.create(cr, uid, vals, context=context)
+            account = getattr(template, record[0])
+            value = account and 'account.account,' + str(acc_template_ref[account.id]) or False
+            if value:
+                field = field_obj.search(cr, uid, [('name', '=', record[0]),('model', '=', record[1]),('relation', '=', record[2])], context=context)
+                vals = {
+                    'name': record[0],
+                    'company_id': company_id,
+                    'fields_id': field[0],
+                    'value': value,
+                }
+                property_ids = property_obj.search(cr, uid, [('name','=', record[0]),('company_id', '=', company_id)], context=context)
+                if property_ids:
+                    #the property exist: modify it
+                    property_obj.write(cr, uid, property_ids, vals, context=context)
+                else:
+                    #create the property
+                    property_obj.create(cr, uid, vals, context=context)
         return True
 
-    def _install_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, acc_ref={}, taxes_ref={}, context=None):
+    def _install_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, acc_ref={}, taxes_ref={}, tax_code_ref={}, context=None):
         '''
         This function recursively loads the template objects and create the real objects from them.
 
@@ -3215,24 +3260,29 @@ class wizard_multi_charts_accounts(osv.osv_memory):
         :param company_id: id of the company the wizard is running for
         :param code_digits: integer that depicts the number of digits the accounts code should have in the COA
         :param obj_wizard: the current wizard for generating the COA from the templates
-        :returns: return a tuple with a dictionary containing the mapping between the account template ids and the ids
-            of the real accounts that have been generated from them, as first item, and a similar dictionary for mapping
-            between tax templates and taxes
-        :rtype: tuple(dict, dict)
+        :param acc_ref: Mapping between ids of account templates and real accounts created from them
+        :param taxes_ref: Mapping between ids of tax templates and real taxes created from them
+        :param tax_code_ref: Mapping between ids of tax code templates and real tax codes created from them
+        :returns: return a tuple with a dictionary containing
+            * the mapping between the account template ids and the ids of the real accounts that have been generated
+              from them, as first item,
+            * a similar dictionary for mapping the tax templates and taxes, as second item,
+            * a last identical containing the mapping of tax code templates and tax codes
+        :rtype: tuple(dict, dict, dict)
         '''
-        #import pdb;pdb.set_trace()
         template = self.pool.get('account.chart.template').browse(cr, uid, template_id, context=context)
         if template.parent_id:
-            tmp1, tmp2 = self._install_template(cr, uid, template.parent_id.id, company_id, code_digits=code_digits, acc_ref=acc_ref, taxes_ref=taxes_ref, context=context)
+            tmp1, tmp2, tmp3 = self._install_template(cr, uid, template.parent_id.id, company_id, code_digits=code_digits, acc_ref=acc_ref, taxes_ref=taxes_ref, tax_code_ref=tax_code_ref, context=context)
             acc_ref.update(tmp1)
             taxes_ref.update(tmp2)
-        #import pdb;pdb.set_trace()
-        tmp1, tmp2 = self._load_template(cr, uid, template_id, company_id, code_digits=code_digits, obj_wizard=obj_wizard, account_ref=acc_ref, taxes_ref=taxes_ref, context=context)
+            tax_code_ref.update(tmp3)
+        tmp1, tmp2, tmp3 = self._load_template(cr, uid, template_id, company_id, code_digits=code_digits, obj_wizard=obj_wizard, account_ref=acc_ref, taxes_ref=taxes_ref, tax_code_ref=tax_code_ref, context=context)
         acc_ref.update(tmp1)
         taxes_ref.update(tmp2)
-        return acc_ref, taxes_ref
+        tax_code_ref.update(tmp3)
+        return acc_ref, taxes_ref, tax_code_ref
 
-    def _load_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, account_ref={}, taxes_ref={}, context=None):
+    def _load_template(self, cr, uid, template_id, company_id, code_digits=None, obj_wizard=None, account_ref={}, taxes_ref={}, tax_code_ref={}, context=None):
         '''
         This function generates all the objects from the templates
 
@@ -3240,10 +3290,15 @@ class wizard_multi_charts_accounts(osv.osv_memory):
         :param company_id: id of the company the wizard is running for
         :param code_digits: integer that depicts the number of digits the accounts code should have in the COA
         :param obj_wizard: the current wizard for generating the COA from the templates
-        :returns: return a tuple with a dictionary containing the mapping between the account template ids and the ids
-            of the real accounts that have been generated from them, as first item, and a similar dictionary for mapping
-            between tax templates and taxes
-        :rtype: tuple(dict, dict)
+        :param acc_ref: Mapping between ids of account templates and real accounts created from them
+        :param taxes_ref: Mapping between ids of tax templates and real taxes created from them
+        :param tax_code_ref: Mapping between ids of tax code templates and real tax codes created from them
+        :returns: return a tuple with a dictionary containing
+            * the mapping between the account template ids and the ids of the real accounts that have been generated
+              from them, as first item,
+            * a similar dictionary for mapping the tax templates and taxes, as second item,
+            * a last identical containing the mapping of tax code templates and tax codes
+        :rtype: tuple(dict, dict, dict)
         '''
         template = self.pool.get('account.chart.template').browse(cr, uid, template_id, context=context)
         obj_tax_code_template = self.pool.get('account.tax.code.template')
@@ -3253,15 +3308,15 @@ class wizard_multi_charts_accounts(osv.osv_memory):
         obj_fiscal_position_template = self.pool.get('account.fiscal.position.template')
 
         # create all the tax code.
-        tax_code_template_ref = obj_tax_code_template.generate_tax_code(cr, uid, template.tax_code_root_id.id, company_id, context=context)
+        tax_code_ref.update(obj_tax_code_template.generate_tax_code(cr, uid, template.tax_code_root_id.id, company_id, context=context))
 
         # Generate taxes from templates.
-        tax_templates = [x for x in template.tax_template_ids if x.installable]
-        generated_tax_res = obj_tax_temp.generate_tax(cr, uid, tax_templates, tax_code_template_ref, company_id, context=context)
+        tax_templates = [x for x in template.tax_template_ids]
+        generated_tax_res = obj_tax_temp._generate_tax(cr, uid, tax_templates, tax_code_ref, company_id, context=context)
         taxes_ref.update(generated_tax_res['tax_template_to_tax'])
 
         # Generating Accounts from templates.
-        account_template_ref = obj_acc_template.generate_account(cr, uid, template_id, taxes_ref, code_digits, company_id, context=context)
+        account_template_ref = obj_acc_template.generate_account(cr, uid, template_id, taxes_ref, account_ref, code_digits, company_id, context=context)
         account_ref.update(account_template_ref)
 
         # writing account values on tax after creation of accounts
@@ -3273,7 +3328,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
                 })
 
         # Create Journals
-        self.generate_journals(cr, uid, template_id, account_ref, company_id, context)
+        self.generate_journals(cr, uid, template_id, account_ref, company_id, context=context)
 
         # generate properties function
         self.generate_properties(cr, uid, template_id, account_ref, company_id, context=context)
@@ -3281,13 +3336,14 @@ class wizard_multi_charts_accounts(osv.osv_memory):
         # Generate Fiscal Position , Fiscal Position Accounts and Fiscal Position Taxes from templates
         obj_fiscal_position_template.generate_fiscal_position(cr, uid, template_id, taxes_ref, account_ref, company_id, context=context)
 
-        return account_ref, taxes_ref
+        return account_ref, taxes_ref, tax_code_ref
 
     def _create_tax_templates_from_rates(self, cr, uid, obj_wizard, company_id, context=None):
         '''
         This function checks if the chosen chart template is configured as containing a full set of taxes, and if
         it's not the case, it creates the templates for account.tax.code and for account.account.tax objects accordingly
-        to the provided sale/purchase rates.
+        to the provided sale/purchase rates. Then it saves the new tax templates as default taxes to use for this chart
+        template.
 
         :param obj_wizard: browse record of wizard to generate COA from templates
         :param company_id: id of the company for wich the wizard is running
@@ -3331,7 +3387,6 @@ class wizard_multi_charts_accounts(osv.osv_memory):
                                             'ref_base_code_id': new_base_code_id,
                                             'ref_tax_code_id': new_tax_code_id,
                                             'type_tax_use': tax_type,
-                                            'installable': True,
                                             'type': 'percent',
                                             'sequence': 0,
                                             'chart_template_id': chart_template.id or False,
@@ -3355,19 +3410,18 @@ class wizard_multi_charts_accounts(osv.osv_memory):
         self._create_tax_templates_from_rates(cr, uid, obj_wizard, company_id, context=context)
 
         # Install all the templates objects and generate the real objects
-        acc_template_ref, taxes_ref = self._install_template(cr, uid, obj_wizard.chart_template_id.id, company_id, code_digits=obj_wizard.code_digits, obj_wizard=obj_wizard, context=context)
+        acc_template_ref, taxes_ref, tax_code_ref = self._install_template(cr, uid, obj_wizard.chart_template_id.id, company_id, code_digits=obj_wizard.code_digits, obj_wizard=obj_wizard, context=context)
 
         # write values of default taxes for product
         if obj_wizard.sale_tax and taxes_ref:
             ir_values_obj.set(cr, uid, key='default', key2=False, name="taxes_id", company=company_id,
                                 models =[('product.product',False)], value=[taxes_ref[obj_wizard.sale_tax.id]])
-        if obj_wizard.purchase_tax and taxes_ref['taxes_id']:
+        if obj_wizard.purchase_tax and taxes_ref:
                 ir_values_obj.set(cr, uid, key='default', key2=False, name="supplier_taxes_id", company=company_id,
                                 models =[('product.product',False)], value=[taxes_ref[obj_wizard.purchase_tax.id]])
 
         # Create Bank journals
         self._create_bank_journals_from_o2m(cr, uid, obj_wizard, company_id, acc_template_ref, context=context)
-        #import pdb;pdb.set_trace()
         return True
 
     def _prepare_bank_journal(self, cr, uid, line, current_num, default_account_id, company_id, context=None):
@@ -3394,7 +3448,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
                 'type': line['account_type'] == 'cash' and 'cash' or 'bank',
                 'company_id': company_id,
                 'analytic_journal_id': False,
-                'currency_id': False,
+                'currency': False,
                 'default_credit_account_id': default_account_id,
                 'default_debit_account_id': default_account_id,
         }