[MERGE] merged with main addons trunk
authorQuentin (OpenERP) <qdp-launchpad@openerp.com>
Fri, 9 Dec 2011 08:19:05 +0000 (09:19 +0100)
committerQuentin (OpenERP) <qdp-launchpad@openerp.com>
Fri, 9 Dec 2011 08:19:05 +0000 (09:19 +0100)
bzr revid: qdp-launchpad@openerp.com-20111209081905-pq3nm1un3hgiavvz

1  2 
addons/account/__openerp__.py
addons/account/account.py
addons/account/account_view.xml

Simple merge
@@@ -3059,420 -2874,264 +3061,420 @@@ class wizard_multi_charts_accounts(osv.
                  res['fields'][field]['domain'] = [('id','in',unconfigured_cmp)]
                  res['fields'][field]['selection'] = [('', '')]
                  if unconfigured_cmp:
 -                    cmp_select = [(line.id, line.name) for line in self.pool.get('res.company').browse(cr, uid, 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 execute(self, cr, uid, ids, context=None):
 -        obj_multi = self.browse(cr, uid, ids[0])
 -        obj_acc = self.pool.get('account.account')
 -        obj_acc_tax = self.pool.get('account.tax')
 +    def check_created_journals(self, cr, uid, vals_journal, company_id, context=None):
 +        """
 +        This method used for checking journals already created or not. If not then create new journal.
 +        """
          obj_journal = self.pool.get('account.journal')
 -        obj_acc_template = self.pool.get('account.account.template')
 -        obj_fiscal_position_template = self.pool.get('account.fiscal.position.template')
 -        obj_fiscal_position = self.pool.get('account.fiscal.position')
 +        rec_list = obj_journal.search(cr, uid, [('name','=', vals_journal['name']),('company_id', '=', company_id)], context=context)
 +        if not rec_list:
 +            obj_journal.create(cr, uid, vals_journal, context=context)
 +        return True
 +
 +    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.
 +        """
 +        journal_data = self._prepare_all_journals(cr, uid, chart_template_id, acc_template_ref, company_id, context=context)
 +        for vals_journal in journal_data:
 +            self.check_created_journals(cr, uid, vals_journal, company_id, context=context)
 +        return True
 +
 +    def _prepare_all_journals(self, cr, uid, chart_template_id, acc_template_ref, company_id, context=None):
 +        def _get_analytic_journal(journal_type):
 +            # Get the analytic journal
 +            analytic_journal_ids = []
 +            if journal_type in ('sale', 'sale_refund'):
 +                analytical_journal_ids = analytic_journal_obj.search(cr, uid, [('type','=','sale')], context=context)
 +            elif journal_type in ('purchase', 'purchase_refund'):
 +                analytical_journal_ids = analytic_journal_obj.search(cr, uid, [('type','=','purchase')], context=context)
 +            elif journal_type == 'general':
 +                analytical_journal_ids = analytic_journal_obj.search(cr, uid, [('type', '=', 'situation')], context=context)
 +            return analytic_journal_ids and analytic_journal_ids[0] or False
 +
 +        def _get_default_account(journal_type, type='debit'):
 +            # Get the default accounts
 +            default_account = False
 +            if journal_type in ('sale', 'sale_refund'):
 +                default_account = acc_template_ref.get(template.property_account_income_categ.id)
 +            elif journal_type in ('purchase', 'purchase_refund'):
 +                default_account = acc_template_ref.get(template.property_account_expense_categ.id)
 +            elif journal_type == 'situation':
 +                if type == 'debit':
 +                    default_account = acc_template_ref.get(template.property_account_expense_opening.id)
 +                else:
 +                    default_account = acc_template_ref.get(template.property_account_income_opening.id)
 +            return default_account
 +
 +        def _get_view_id(journal_type):
 +            # Get the journal views
 +            if journal_type in ('general', 'situation'):
 +                data = obj_data.get_object_reference(cr, uid, 'account', 'account_journal_view')
 +            elif journal_type in ('sale_refund', 'purchase_refund'):
 +                data = obj_data.get_object_reference(cr, uid, 'account', 'account_sp_refund_journal_view') 
 +            else:
 +                data = obj_data.get_object_reference(cr, uid, 'account', 'account_sp_journal_view')
 +            return data and data[1] or False
 +
 +        journal_names = {
 +            'sale': _('Sales Journal'),
 +            'purchase': _('Purchase Journal'),
 +            'sale_refund': _('Sales Refund Journal'),
 +            'purchase_refund': _('Purchase Refund Journal'),
 +            'general': _('Miscellaneous Journal'),
 +            'situation': _('Opening Entries Journal'),
 +        }
 +        journal_codes = {
 +            'sale': _('SAJ'),
 +            'purchase': _('EXJ'),
 +            'sale_refund': _('SCNJ'),
 +            'purchase_refund': _('ECNJ'),
 +            'general': _('MISC'),
 +            'situation': _('OPEJ'),
 +        }
 +
          obj_data = self.pool.get('ir.model.data')
          analytic_journal_obj = self.pool.get('account.analytic.journal')
 -        obj_tax_code = self.pool.get('account.tax.code')
 -        obj_tax_code_template = self.pool.get('account.tax.code.template')
 -        ir_values_obj = self.pool.get('ir.values')
 -        # Creating Account
 -        obj_acc_root = obj_multi.chart_template_id.account_root_id
 -        tax_code_root_id = obj_multi.chart_template_id.tax_code_root_id.id
 -        company_id = obj_multi.company_id.id
 -
 -        #new code
 -        acc_template_ref = {}
 -        tax_template_ref = {}
 -        tax_code_template_ref = {}
 -        todo_dict = {}
 +        template = self.pool.get('account.chart.template').browse(cr, uid, chart_template_id, context=context)
  
 -        #create all the tax code
 -        children_tax_code_template = obj_tax_code_template.search(cr, uid, [('parent_id','child_of',[tax_code_root_id])], order='id')
 -        children_tax_code_template.sort()
 -        for tax_code_template in obj_tax_code_template.browse(cr, uid, children_tax_code_template, context=context):
 +        journal_data = []
 +        for journal_type in ['sale', 'purchase', 'sale_refund', 'purchase_refund', 'general', 'situation']:
              vals = {
 -                'name': (tax_code_root_id == tax_code_template.id) and obj_multi.company_id.name or tax_code_template.name,
 -                'code': tax_code_template.code,
 -                'info': tax_code_template.info,
 -                'parent_id': tax_code_template.parent_id and ((tax_code_template.parent_id.id in tax_code_template_ref) and tax_code_template_ref[tax_code_template.parent_id.id]) or False,
 +                'type': journal_type,
 +                'name': journal_names[journal_type],
 +                'code': journal_codes[journal_type],
                  'company_id': company_id,
 -                'sign': tax_code_template.sign,
 +                'centralisation': journal_type == 'situation',
 +                'view_id': _get_view_id(journal_type),
 +                'analytic_journal_id': _get_analytic_journal(journal_type),
 +                'default_credit_account_id': _get_default_account(journal_type, 'credit'),
 +                'default_debit_account_id': _get_default_account(journal_type, 'debit'),
              }
 -            new_tax_code = obj_tax_code.create(cr, uid, vals)
 -            #recording the new tax code to do the mapping
 -            tax_code_template_ref[tax_code_template.id] = new_tax_code
 +            journal_data.append(vals)
 +        return journal_data
  
 -        #create all the tax
 -        tax_template_to_tax = {}
 -        for tax in obj_multi.chart_template_id.tax_template_ids:
 -            #create it
 -            vals_tax = {
 -                'name':tax.name,
 -                'sequence': tax.sequence,
 -                'amount':tax.amount,
 -                'type':tax.type,
 -                'applicable_type': tax.applicable_type,
 -                'domain':tax.domain,
 -                'parent_id': tax.parent_id and ((tax.parent_id.id in tax_template_ref) and tax_template_ref[tax.parent_id.id]) or False,
 -                'child_depend': tax.child_depend,
 -                'python_compute': tax.python_compute,
 -                'python_compute_inv': tax.python_compute_inv,
 -                'python_applicable': tax.python_applicable,
 -                'base_code_id': tax.base_code_id and ((tax.base_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.base_code_id.id]) or False,
 -                'tax_code_id': tax.tax_code_id and ((tax.tax_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.tax_code_id.id]) or False,
 -                'base_sign': tax.base_sign,
 -                'tax_sign': tax.tax_sign,
 -                'ref_base_code_id': tax.ref_base_code_id and ((tax.ref_base_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.ref_base_code_id.id]) or False,
 -                'ref_tax_code_id': tax.ref_tax_code_id and ((tax.ref_tax_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.ref_tax_code_id.id]) or False,
 -                'ref_base_sign': tax.ref_base_sign,
 -                'ref_tax_sign': tax.ref_tax_sign,
 -                'include_base_amount': tax.include_base_amount,
 -                'description':tax.description,
 -                'company_id': company_id,
 -                'type_tax_use': tax.type_tax_use,
 -                'price_include': tax.price_include
 -            }
 -            new_tax = obj_acc_tax.create(cr, uid, vals_tax)
 -            tax_template_to_tax[tax.id] = new_tax
 -            #as the accounts have not been created yet, we have to wait before filling these fields
 -            todo_dict[new_tax] = {
 -                'account_collected_id': tax.account_collected_id and tax.account_collected_id.id or False,
 -                'account_paid_id': tax.account_paid_id and tax.account_paid_id.id or False,
 -            }
 -            tax_template_ref[tax.id] = new_tax
 -        #deactivate the parent_store functionnality on account_account for rapidity purpose
 -        ctx = context and context.copy() or {}
 -        ctx['defer_parent_store_computation'] = True
 +    def generate_properties(self, cr, uid, chart_template_id, acc_template_ref, company_id, context=None):
 +        """
 +        This method used for creating properties.
  
 -        children_acc_template = obj_acc_template.search(cr, uid, [('parent_id','child_of',[obj_acc_root.id]),('nocreate','!=',True)])
 -        children_acc_template.sort()
 -        for account_template in obj_acc_template.browse(cr, uid, children_acc_template, context=context):
 -            tax_ids = []
 -            for tax in account_template.tax_ids:
 -                tax_ids.append(tax_template_ref[tax.id])
 -            #create the account_account
 +        :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')
 +        todo_list = [
 +            ('property_account_receivable','res.partner','account.account'),
 +            ('property_account_payable','res.partner','account.account'),
 +            ('property_account_expense_categ','product.category','account.account'),
 +            ('property_account_income_categ','product.category','account.account'),
 +            ('property_account_expense','product.template','account.account'),
 +            ('property_account_income','product.template','account.account'),
 +            ('property_reserve_and_surplus_account','res.company','account.account')
 +        ]
 +        template = self.pool.get('account.chart.template').browse(cr, uid, chart_template_id, context=context)
 +        for record in todo_list:
 +            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
  
 -            dig = obj_multi.code_digits
 -            code_main = account_template.code and len(account_template.code) or 0
 -            code_acc = account_template.code or ''
 -            if code_main>0 and code_main<=dig and account_template.type != 'view':
 -                code_acc=str(code_acc) + (str('0'*(dig-code_main)))
 -            vals={
 -                'name': (obj_acc_root.id == account_template.id) and obj_multi.company_id.name or account_template.name,
 -                'currency_id': account_template.currency_id and account_template.currency_id.id or False,
 -                'code': code_acc,
 -                '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.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,
 -            }
 -            new_account = obj_acc.create(cr, uid, vals, context=ctx)
 -            acc_template_ref[account_template.id] = new_account
 +    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.
 +
 +        :param template_id: id of the chart template to load
 +        :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,
 +            * 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)
 +        if template.parent_id:
 +            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)
 +            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)
 +        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={}, tax_code_ref={}, context=None):
 +        '''
 +        This function generates all the objects from the templates
 +
 +        :param template_id: id of the chart template to load
 +        :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,
 +            * 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')
 +        obj_acc_tax = self.pool.get('account.tax')
 +        obj_tax_temp = self.pool.get('account.tax.template')
 +        obj_acc_template = self.pool.get('account.account.template')
 +        obj_fiscal_position_template = self.pool.get('account.fiscal.position.template')
  
 +        # create all the tax code.
 +        tax_code_ref.update(obj_tax_code_template.generate_tax_code(cr, uid, template.tax_code_root_id.id, company_id, context=context))
  
 -        #reactivate the parent_store functionnality on account_account
 -        obj_acc._parent_store_compute(cr)
 +        # 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_ref, company_id, context=context)
 +        taxes_ref.update(generated_tax_res['tax_template_to_tax'])
  
 -        for key,value in todo_dict.items():
 +        # Generating Accounts from templates.
 +        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
 +        for key,value in generated_tax_res['account_dict'].items():
              if value['account_collected_id'] or value['account_paid_id']:
                  obj_acc_tax.write(cr, uid, [key], {
 -                    'account_collected_id': acc_template_ref.get(value['account_collected_id'], False),
 -                    'account_paid_id': acc_template_ref.get(value['account_paid_id'], False),
 +                    'account_collected_id': account_ref.get(value['account_collected_id'], False),
 +                    'account_paid_id': account_ref.get(value['account_paid_id'], False),
                  })
  
 -        # Creating Journals
 -        data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_sp_journal_view')])
 -        data = obj_data.browse(cr, uid, data_id[0], context=context)
 -        view_id = data.res_id
 -
 -        #Sales Journal
 -        analytical_sale_ids = analytic_journal_obj.search(cr,uid,[('type','=','sale')])
 -        analytical_journal_sale = analytical_sale_ids and analytical_sale_ids[0] or False
 +        # Create Journals
 +        self.generate_journals(cr, uid, template_id, account_ref, company_id, context=context)
  
 -        vals_journal = {
 -            'name': _('Sales Journal'),
 -            'type': 'sale',
 -            'code': _('SAJ'),
 -            'view_id': view_id,
 -            'company_id': company_id,
 -            'analytic_journal_id': analytical_journal_sale,
 -        }
 +        # generate properties function
 +        self.generate_properties(cr, uid, template_id, account_ref, company_id, context=context)
  
 -        if obj_multi.chart_template_id.property_account_receivable:
 -            vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
 -            vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
 +        # 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)
  
 -        obj_journal.create(cr,uid,vals_journal)
 +        return account_ref, taxes_ref, tax_code_ref
  
 -        # Purchase Journal
 -        analytical_purchase_ids = analytic_journal_obj.search(cr,uid,[('type','=','purchase')])
 -        analytical_journal_purchase = analytical_purchase_ids and analytical_purchase_ids[0] or False
 -
 -        vals_journal = {
 -            'name': _('Purchase Journal'),
 -            'type': 'purchase',
 -            'code': _('EXJ'),
 -            'view_id': view_id,
 -            'company_id':  company_id,
 -            'analytic_journal_id': analytical_journal_purchase,
 -        }
 +    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.
  
 -        if obj_multi.chart_template_id.property_account_payable:
 -            vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
 -            vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
 -        obj_journal.create(cr,uid,vals_journal)
 -
 -        # Creating Journals Sales Refund and Purchase Refund
 -        data_id = obj_data.search(cr, uid, [('model', '=', 'account.journal.view'), ('name', '=', 'account_sp_refund_journal_view')], context=context)
 -        data = obj_data.browse(cr, uid, data_id[0], context=context)
 -        view_id = data.res_id
 -
 -        #Sales Refund Journal
 -        vals_journal = {
 -            'name': _('Sales Refund Journal'),
 -            'type': 'sale_refund',
 -            'code': _('SCNJ'),
 -            'view_id': view_id,
 -            'analytic_journal_id': analytical_journal_sale,
 -            'company_id': company_id
 -        }
 +        :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
 +        :return: True
 +        '''
 +        obj_tax_code_template = self.pool.get('account.tax.code.template')
 +        obj_tax_temp = self.pool.get('account.tax.template')
 +        chart_template = obj_wizard.chart_template_id
 +        vals = {}
 +        # create tax templates and tax code templates from purchase_tax_rate and sale_tax_rate fields
 +        if not chart_template.complete_tax_set:
 +            tax_data = {
 +                'sale': obj_wizard.sale_tax_rate,
 +                'purchase': obj_wizard.purchase_tax_rate,
 +            }
  
 -        if obj_multi.chart_template_id.property_account_receivable:
 -            vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
 -            vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
 +            for tax_type, value in tax_data.items():
 +                # don't consider cases where entered value in rates are lower than 0
 +                if value >= 0.0:
 +                    #create the tax code templates for base and tax
 +                    base_code_vals = {
 +                        'name': (tax_type == 'sale' and _('Taxable Sales at %s') or _('Taxable Purchases at %s')) % value,
 +                        'code': (tax_type == 'sale' and _('BASE-S-%s') or _('BASE-P-%s')) %value,
 +                        'parent_id': chart_template.tax_code_root_id.id,
 +                        'company_id': company_id,
 +                    }
 +                    new_base_code_id = obj_tax_code_template.create(cr, uid, base_code_vals, context=context)
 +                    tax_code_vals = {
 +                        'name': (tax_type == 'sale' and _('Tax Received at %s') or _('Tax Paid at %s')) % value,
 +                        'code': (tax_type == 'sale' and _('TAX-S-%s') or _('TAX-P-%s')) %value,
 +                        'parent_id': chart_template.tax_code_root_id.id,
 +                        'company_id': company_id,
 +                    }
 +                    new_tax_code_id = obj_tax_code_template.create(cr, uid, tax_code_vals, context=context)
 +                    #create the tax
 +                    tax_template_id = obj_tax_temp.create(cr, uid, {
 +                                            'name': _('Tax %s%%') % value,
 +                                            'amount': value/100,
 +                                            'base_code_id': new_base_code_id,
 +                                            'tax_code_id': new_tax_code_id,
 +                                            '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,
 +                    }, context=context)
 +                    #record this new tax_template as default for this chart template
 +                    field_name = tax_type == 'sale' and 'sale_tax' or 'purchase_tax'
 +                    vals[field_name] = tax_template_id
 +        self.write(cr, uid, obj_wizard.id, vals, context=context)
 +        return True
  
 -        obj_journal.create(cr, uid, vals_journal, context=context)
 +    def execute(self, cr, uid, ids, context=None):
 +        '''
 +        This function is called at the confirmation of the wizard to generate the COA from the templates. It will read
 +        all the provided information to create the accounts, the banks, the journals, the taxes, the tax codes, the
 +        accounting properties... accordingly for the chosen company.
 +        '''
 +        ir_values_obj = self.pool.get('ir.values')
 +        obj_wizard = self.browse(cr, uid, ids[0])
 +        company_id = obj_wizard.company_id.id
 +        # If the floats for sale/purchase rates have been filled, create templates from them
 +        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, 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:
 +                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)
 +        return True
  
 -        # Purchase Refund Journal
 -        vals_journal = {
 -            'name': _('Purchase Refund Journal'),
 -            'type': 'purchase_refund',
 -            'code': _('ECNJ'),
 -            'view_id': view_id,
 -            'analytic_journal_id': analytical_journal_purchase,
 -            'company_id': company_id
 +    def _prepare_bank_journal(self, cr, uid, line, current_num, default_account_id, company_id, context=None):
 +        '''
 +        This function prepares the value to use for the creation of a bank journal created through the wizard of 
 +        generating COA from templates.
 +
 +        :param line: dictionary containing the values encoded by the user related to his bank account
 +        :param current_num: integer corresponding to a counter of the already created bank journals through this wizard.
 +        :param default_account_id: id of the default debit.credit account created before for this journal.
 +        :param company_id: id of the company for which the wizard is running
 +        :return: mapping of field names and values
 +        :rtype: dict
 +        '''
 +        obj_data = self.pool.get('ir.model.data')
 +        # Get the id of journal views
 +        tmp = obj_data.get_object_reference(cr, uid, 'account', 'account_journal_bank_view_multi')
 +        view_id_cur = tmp and tmp[1] or False
 +        tmp = obj_data.get_object_reference(cr, uid, 'account', 'account_journal_bank_view')
 +        view_id_cash = tmp and tmp[1] or False
 +        vals = {
 +                'name': line['acc_name'],
 +                'code': _('BNK') + str(current_num),
 +                '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,
          }
 +        if line['currency_id']:
 +            vals['view_id'] = view_id_cur
 +            vals['currency'] = line['currency_id']
 +        else:
 +            vals['view_id'] = view_id_cash
 +        return vals
 +
 +    def _prepare_bank_account(self, cr, uid, line, new_code, acc_template_ref, ref_acc_bank, company_id, context=None):
 +        '''
 +        This function prepares the value to use for the creation of the default debit and credit accounts of a
 +        bank journal created through the wizard of generating COA from templates.
 +
 +        :param line: dictionary containing the values encoded by the user related to his bank account
 +        :param new_code: integer corresponding to the next available number to use as account code
 +        :param acc_template_ref: the dictionary containing the mapping between the ids of account templates and the ids
 +            of the accounts that have been generated from them.
 +        :param ref_acc_bank: browse record of the account template set as root of all bank accounts for the chosen
 +            template
 +        :param company_id: id of the company for which the wizard is running
 +        :return: mapping of field names and values
 +        :rtype: dict
 +        '''
 +        obj_data = self.pool.get('ir.model.data')
  
 -        if obj_multi.chart_template_id.property_account_payable:
 -            vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
 -            vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
 -
 -        obj_journal.create(cr, uid, vals_journal, context=context)
 -
 -        # Miscellaneous Journal
 -        data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_view')])
 -        data = obj_data.browse(cr, uid, data_id[0], context=context)
 -        view_id = data.res_id
 -
 -        analytical_miscellaneous_ids = analytic_journal_obj.search(cr, uid, [('type', '=', 'situation')], context=context)
 -        analytical_journal_miscellaneous = analytical_miscellaneous_ids and analytical_miscellaneous_ids[0] or False
 -
 -        vals_journal = {
 -            'name': _('Miscellaneous Journal'),
 -            'type': 'general',
 -            'code': _('MISC'),
 -            'view_id': view_id,
 -            'analytic_journal_id': analytical_journal_miscellaneous,
 -            'company_id': company_id
 +        # Get the id of the user types fr-or cash and bank
 +        tmp = obj_data.get_object_reference(cr, uid, 'account', 'data_account_type_cash')
 +        cash_type = tmp and tmp[1] or False
 +        tmp = obj_data.get_object_reference(cr, uid, 'account', 'data_account_type_bank')
 +        bank_type = tmp and tmp[1] or False
 +        return {
 +                'name': line['acc_name'],
 +                'currency_id': line['currency_id'],
 +                'code': new_code,
 +                'type': 'liquidity',
 +                'user_type': line['account_type'] == 'cash' and cash_type or bank_type,
 +                'parent_id': acc_template_ref[ref_acc_bank.id] or False,
 +                'company_id': company_id,
          }
  
 -        obj_journal.create(cr, uid, vals_journal, context=context)
 -
 -        # Opening Entries Journal
 -        if obj_multi.chart_template_id.property_account_income_opening and obj_multi.chart_template_id.property_account_expense_opening:
 -            vals_journal = {
 -                'name': _('Opening Entries Journal'),
 -                'type': 'situation',
 -                'code': _('OPEJ'),
 -                'view_id': view_id,
 -                'company_id': company_id,
 -                'centralisation': True,
 -                'default_credit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_income_opening.id],
 -                'default_debit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_expense_opening.id]
 +    def _create_bank_journals_from_o2m(self, cr, uid, obj_wizard, company_id, acc_template_ref, context=None):
 +        '''
 +        This function creates bank journals and its accounts for each line encoded in the field bank_accounts_id of the
 +        wizard.
 +
 +        :param obj_wizard: the current wizard that generates the COA from the templates.
 +        :param company_id: the id of the company for which the wizard is running.
 +        :param acc_template_ref: the dictionary containing the mapping between the ids of account templates and the ids
 +            of the accounts that have been generated from them.
 +        :return: True
 +        '''
 +        obj_acc = self.pool.get('account.account')
 +        obj_journal = self.pool.get('account.journal')
 +        code_digits = obj_wizard.code_digits
 +
 +        # Build a list with all the data to process
 +        journal_data = []
 +        if obj_wizard.bank_accounts_id:
 +            for acc in obj_wizard.bank_accounts_id:
 +                vals = {
 +                    'acc_name': acc.acc_name,
 +                    'account_type': acc.account_type,
 +                    'currency_id': acc.currency_id.id,
                  }
 -            obj_journal.create(cr, uid, vals_journal, context=context)
 -
 -        # Bank Journals
 -        data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
 -        data = obj_data.browse(cr, uid, data_id[0], context=context)
 -        view_id_cash = data.res_id
 -
 -        data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view_multi')])
 -        data = obj_data.browse(cr, uid, data_id[0], context=context)
 -        view_id_cur = data.res_id
 -        ref_acc_bank = obj_multi.chart_template_id.bank_account_view_id
 +                journal_data.append(vals)
 +        ref_acc_bank = obj_wizard.chart_template_id.bank_account_view_id
 +        if journal_data and not ref_acc_bank.code:
 +            raise osv.except_osv(_('Configuration Error !'), _('The bank account defined on the selected chart of accounts hasn\'t a code.'))
  
          current_num = 1
 -        valid = True
 -        for line in obj_multi.bank_accounts_id:
 -            #create the account_account for this bank journal
 -            tmp = line.acc_name
 -            dig = obj_multi.code_digits
 -            if not ref_acc_bank.code:
 -                raise osv.except_osv(_('Configuration Error !'), _('The bank account defined on the selected chart of accounts hasn\'t a code.'))
 +        for line in journal_data:
 +            # Seek the next available number for the account code
              while True:
 -                new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num)
 +                new_code = str(ref_acc_bank.code.ljust(code_digits-len(str(current_num)), '0')) + str(current_num)
                  ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', company_id)])
                  if not ids:
                      break
Simple merge