From 6cb6f43c2beffaccd871ac93f19e11aeeb92d131 Mon Sep 17 00:00:00 2001 From: qdp-odoo Date: Wed, 19 Aug 2015 15:44:49 +0200 Subject: [PATCH] [REF] base: simplified res.partner.bank and res.bank objects for a greater usability + [IMP] account: bank journals are now the bank accounts of a company --- addons/account/__openerp__.py | 2 +- addons/account/models/__init__.py | 1 - addons/account/models/account.py | 116 +++++--- addons/account/models/account_bank.py | 44 --- .../models/account_journal_dashboard.py | 22 +- addons/account/models/chart_template.py | 41 +-- addons/account/models/company.py | 2 + addons/account/models/res_config.py | 11 +- addons/account/report/inherited_layouts.xml | 22 ++ .../src/less/account_journal_dashboard.less | 4 + .../account/test/account_bank_statement.yml | 7 - addons/account/test/account_minimal_test.xml | 14 + .../tests/test_account_customer_invoice.py | 6 +- addons/account/tests/test_payment.py | 8 +- addons/account/tests/test_reconciliation.py | 10 +- addons/account/views/account_bank_view.xml | 62 ---- .../views/account_journal_dashboard_view.xml | 42 ++- addons/account/views/account_view.xml | 72 ++++- addons/account/views/res_config_view.xml | 2 +- .../account_bank_statement_import/__init__.py | 1 + .../account_bank_statement_import.py | 84 ++---- .../account_bank_statement_import_view.xml | 18 ++ .../account_journal.py | 21 ++ .../demo/partner_bank.xml | 20 +- .../wizard/journal_creation.py | 35 +-- .../wizard/journal_creation.xml | 14 +- addons/base_iban/__openerp__.py | 3 +- addons/base_iban/base_iban.py | 37 ++- addons/base_iban/base_iban_data.xml | 32 -- addons/base_iban/base_iban_view.xml | 6 - addons/base_iban/demo/iban_demo.xml | 15 +- addons/crm/security/ir.model.access.csv | 1 - .../test/hr_payroll_account.yml | 4 +- .../l10n_in_hr_payroll/l10n_in_hr_payroll.py | 2 +- .../test/payment_advice_batch.yml | 4 +- .../views/report_payrolladvice.xml | 4 +- addons/membership/tests/test_membership.py | 4 +- .../models/payment_acquirer.py | 6 +- .../tests/test_purchase_to_invoice.py | 2 +- addons/report/views/layouts.xml | 10 +- addons/sale/security/ir.model.access.csv | 2 - addons/sale/tests/test_sale_to_invoice.py | 3 - .../tests/test_invoicing.py | 2 +- openerp/addons/base/__openerp__.py | 1 + openerp/addons/base/base_demo.xml | 12 +- openerp/addons/base/res/res_bank.py | 281 +++++------------- openerp/addons/base/res/res_bank_demo.xml | 21 ++ openerp/addons/base/res/res_bank_view.xml | 105 +------ openerp/addons/base/res/res_company.py | 37 +-- openerp/addons/base/res/res_company_view.xml | 32 +- openerp/addons/base/res/res_partner_data.xml | 11 - .../addons/base/security/ir.model.access.csv | 4 - openerp/addons/base/tests/__init__.py | 1 + openerp/addons/base/tests/test_expression.py | 52 ++-- .../addons/base/tests/test_osv_expression.yml | 87 +++--- .../base/tests/test_res_partner_bank.py | 70 +++++ 56 files changed, 675 insertions(+), 857 deletions(-) delete mode 100644 addons/account/models/account_bank.py create mode 100644 addons/account/report/inherited_layouts.xml delete mode 100644 addons/account/views/account_bank_view.xml create mode 100644 addons/account_bank_statement_import/account_journal.py delete mode 100644 addons/base_iban/base_iban_data.xml delete mode 100644 addons/base_iban/base_iban_view.xml create mode 100644 openerp/addons/base/res/res_bank_demo.xml create mode 100644 openerp/addons/base/tests/test_res_partner_bank.py diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index b1592ba5bec..f5322dc2a2c 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -41,12 +41,12 @@ You could use this simplified accounting in case you work with an (external) acc 'views/product_view.xml', 'views/account_analytic_view.xml', 'views/company_view.xml', - 'views/account_bank_view.xml', 'views/res_config_view.xml', 'views/account_tip_data.xml', 'views/account.xml', 'views/report_invoice.xml', 'report/account_invoice_report_view.xml', + 'report/inherited_layouts.xml', 'views/account_journal_dashboard_view.xml', ], 'demo': [ diff --git a/addons/account/models/__init__.py b/addons/account/models/__init__.py index a31840bb76e..b4855fb482f 100644 --- a/addons/account/models/__init__.py +++ b/addons/account/models/__init__.py @@ -5,7 +5,6 @@ import account import account_payment import account_invoice import account_bank_statement -import account_bank import account_move import chart_template import account_analytic_line diff --git a/addons/account/models/account.py b/addons/account/models/account.py index f3a1228b58d..95e1f061165 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -6,7 +6,7 @@ import math from openerp.osv import expression from openerp.tools.float_utils import float_round as round from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT -from openerp.exceptions import UserError +from openerp.exceptions import UserError, ValidationError from openerp import api, fields, models, _ @@ -189,7 +189,7 @@ class AccountJournal(models.Model): return self.env.ref('account.account_payment_method_manual_out') name = fields.Char(string='Journal Name', required=True) - code = fields.Char(string='Sequence Prefix', size=5, required=True, help="The journal entries of this journal will be named using this prefix.") + code = fields.Char(string='Short Code', size=5, required=True, help="The journal entries of this journal will be named using this prefix.") type = fields.Selection([ ('sale', 'Sale'), ('purchase', 'Purchase'), @@ -240,6 +240,13 @@ class AccountJournal(models.Model): profit_account_id = fields.Many2one('account.account', string='Profit Account', domain=[('deprecated', '=', False)], help="Used to register a profit when the ending balance of a cash register differs from what the system computes") loss_account_id = fields.Many2one('account.account', string='Loss Account', domain=[('deprecated', '=', False)], help="Used to register a loss when the ending balance of a cash register differs from what the system computes") + # Bank journals fields + bank_account_id = fields.Many2one('res.partner.bank', string="Bank Account", ondelete='restrict') + display_on_footer = fields.Boolean("Show in Invoices Footer", help="Display this bank account on the footer of printed documents like invoices and sales orders.") + bank_statements_source = fields.Selection([('manual', 'Record Manually')], string='Bank Feeds') + bank_acc_number = fields.Char(related='bank_account_id.acc_number') + bank_id = fields.Many2one('res.bank', related='bank_account_id.bank_id') + _sql_constraints = [ ('code_company_uniq', 'unique (code, name, company_id)', 'The code and name of the journal must be unique per company !'), ] @@ -253,6 +260,17 @@ class AccountJournal(models.Model): if self.default_debit_account_id and not self.default_debit_account_id.currency_id.id == self.currency_id.id: raise UserError(_('Configuration error!\nThe currency of the journal should be the same than the default debit account.')) + @api.one + @api.constrains('type', 'bank_account_id') + def _check_bank_account(self): + if self.type == 'bank' and self.bank_account_id: + if self.bank_account_id.company_id != self.company_id: + raise ValidationError(_('The bank account of a bank journal must belong to the same company (%s).') % self.company_id.name) + # A bank account can belong to a customer/supplier, in which case their partner_id is the customer/supplier. + # Or they are part of a bank journal and their partner_id must be the company's partner_id. + if self.bank_account_id.partner_id != self.company_id.partner_id: + raise ValidationError(_('The holder of a journal\'s bank account must be the company (%s).') % self.company_id.name) + @api.onchange('default_debit_account_id') def onchange_debit_account_id(self): if not self.default_credit_account_id: @@ -285,7 +303,14 @@ class AccountJournal(models.Model): if journal.refund_sequence_id: new_prefix = self._get_sequence_prefix(vals['code'], refund=True) journal.refund_sequence_id.write({'prefix': new_prefix}) - return super(AccountJournal, self).write(vals) + result = super(AccountJournal, self).write(vals) + + # Create the bank_account_id if necessary + if 'bank_acc_number' in vals: + for journal in self.filtered(lambda r: r.type == 'bank' and not r.bank_account_id): + journal.set_bank_account(vals.get('bank_acc_number'), vals.get('bank_id')) + + return result @api.model def _get_sequence_prefix(self, code, refund=False): @@ -349,57 +374,55 @@ class AccountJournal(models.Model): 'company_id': company.id, } - @api.model - def _prepare_bank_journal(self, company, line): - ''' - This function prepares the value to use for the creation of a bank journal created through the wizard of - generating COA from templates. - - :param company: company for which the wizard is running - :param line: dictionary containing the values encoded by the user related to his bank account with keys - - acc_name (char): name of the bank account - - account_type (char): kind of liquidity journal to create. Either 'bank' or 'cash' - - currency_id (int): id of the currency related to this account if its different than the company currency (False otherwise) - :return: mapping of field names and values - :rtype: dict - ''' - # we need to loop to find next number for journal code - for num in xrange(1, 100): - # journal_code has a maximal size of 5, hence we can enforce the boundary num < 100 - journal_code = line.get('account_type', 'bank') == 'cash' and 'CSH' or 'BNK' - journal_code += str(num) - journal = self.env['account.journal'].search([('code', '=', journal_code), ('company_id', '=', company.id)], limit=1) - if not journal: - break - else: - raise UserError(_('Cannot generate an unused journal code.')) - - return { - 'name': line['acc_name'], - 'code': journal_code, - 'type': line.get('account_type', 'bank'), - 'company_id': company.id, - 'analytic_journal_id': False, - 'currency_id': line.get('currency_id', False), - 'show_on_dashboard': True, - } - @api.model def create(self, vals): + company_id = vals.get('company_id', self.env.user.company_id.id) if vals.get('type') in ('bank', 'cash'): + # If no code provided, loop to find next available journal code + if not vals.get('code'): + for num in xrange(1, 100): + # journal_code has a maximal size of 5, hence we can enforce the boundary num < 100 + journal_code = (vals['type'] == 'cash' and 'CSH' or 'BNK') + str(num) + journal = self.env['account.journal'].search([('code', '=', journal_code), ('company_id', '=', company_id)], limit=1) + if not journal: + vals['code'] = journal_code + break + else: + raise UserError(_("Cannot generate an unused journal code. Please fill the 'Shortcode' field.")) + + # Create a default debit/credit account if not given default_account = vals.get('default_debit_account_id') or vals.get('default_credit_account_id') if not default_account: - company = self.env['res.company'].browse(vals['company_id']) + company = self.env['res.company'].browse(company_id) account_vals = self._prepare_liquidity_account(vals.get('name'), company, vals.get('currency_id'), vals.get('type')) default_account = self.env['account.account'].create(account_vals) vals['default_debit_account_id'] = default_account.id vals['default_credit_account_id'] = default_account.id + # We just need to create the relevant sequences according to the chosen options if not vals.get('sequence_id'): vals.update({'sequence_id': self.sudo()._create_sequence(vals).id}) if vals.get('refund_sequence') and not vals.get('refund_sequence_id'): vals.update({'refund_sequence_id': self.sudo()._create_sequence(vals, refund=True).id}) - return super(AccountJournal, self).create(vals) + + journal = super(AccountJournal, self).create(vals) + + # Create the bank_account_id if necessary + if journal.type == 'bank' and not journal.bank_account_id and vals.get('bank_acc_number'): + journal.set_bank_account(vals.get('bank_acc_number'), vals.get('bank_id')) + + return journal + + def set_bank_account(self, acc_number, bank_id=None): + """ Create a res.partner.bank and set it as value of the field bank_account_id """ + self.ensure_one() + self.bank_account_id = self.env['res.partner.bank'].create({ + 'acc_number': acc_number, + 'bank_id': bank_id, + 'company_id': self.company_id.id, + 'currency_id': self.currency_id.id, + 'partner_id': self.company_id.partner_id.id, + }).id @api.multi @api.depends('name', 'currency_id', 'company_id', 'company_id.currency_id') @@ -419,6 +442,19 @@ class AccountJournal(models.Model): journal.at_least_one_outbound = bool(len(self.outbound_payment_method_ids)) +class ResPartnerBank(models.Model): + _inherit = "res.partner.bank" + + journal_id = fields.One2many('account.journal', 'bank_account_id', domain=[('type', '=', 'bank')], string='Account Journal', readonly=True, + help="The accounting journal corresponding to this bank account.") + + @api.one + @api.constrains('journal_id') + def _check_journal_id(self): + if len(self.journal_id) > 1: + raise ValidationError(_('A bank account can anly belong to one journal.')) + + #---------------------------------------------------------- # Tax #---------------------------------------------------------- diff --git a/addons/account/models/account_bank.py b/addons/account/models/account_bank.py deleted file mode 100644 index 96b69d81bab..00000000000 --- a/addons/account/models/account_bank.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- - -from openerp import api, fields, models - - -class Bank(models.Model): - _inherit = "res.partner.bank" - - journal_id = fields.Many2one('account.journal', string='Account Journal', - help="This journal will be created automatically for this bank account when you save the record") - - @api.model - def create(self, data): - result = super(Bank, self).create(data) - result.post_write() - return result - - @api.multi - def write(self, data): - result = super(Bank, self).write(data) - self.post_write() - return result - - @api.model - def _prepare_name(self, bank): - "Return the name to use when creating a bank journal" - name = bank.bank_name + ' ' if bank.bank_name else '' - name += bank.acc_number - return name - - @api.multi - def post_write(self): - JournalObj = self.env['account.journal'] - for bank in self: - # Create a journal for the bank account if it belongs to the company. - if bank.company_id and not bank.journal_id: - journal_vals = JournalObj._prepare_bank_journal(bank.company_id, {'acc_name': self._prepare_name(bank), 'currency_id': bank.currency_id.id, 'account_type': 'bank'}) - journal = JournalObj.create(journal_vals) - missing_vals = {'journal_id': journal.id} - if not bank.partner_id: - missing_vals['partner_id'] = bank.company_id.partner_id.id - if not bank.owner_name: - missing_vals['owner_name'] = bank.company_id.partner_id.name - bank.write(missing_vals) diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py index 27e3bc8fb77..d4a8add628b 100644 --- a/addons/account/models/account_journal_dashboard.py +++ b/addons/account/models/account_journal_dashboard.py @@ -187,7 +187,8 @@ class account_journal(models.Model): 'sum_waiting': formatLang(self.env, sum_waiting or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), 'sum_late': formatLang(self.env, sum_late or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), 'currency_id': self.currency_id and self.currency_id.id or self.company_id.currency_id.id, - 'show_import': True if self.type in ['bank', 'cash'] and len(ac_bnk_stmt) == 0 and last_balance == 0 else False, + 'no_statement': bool(self.type in ['bank', 'cash'] and len(ac_bnk_stmt) == 0), + 'bank_statements_source': self.bank_statements_source, 'title': title, } @@ -220,7 +221,7 @@ class account_journal(models.Model): } @api.multi - def create_cash_bank(self): + def create_cash_statement(self): ctx = self._context.copy() ctx.update({'journal_id': self.id, 'default_journal_id': self.id, 'default_journal_type': 'cash'}) return { @@ -337,13 +338,12 @@ class account_journal(models.Model): return action @api.multi - def import_statement(self): - """return action to import bank/cash statements. This button should be called only on journals with type =='bank'""" - model = 'account.bank.statement' - action_name = 'action_account_bank_statement_import' - ir_model_obj = self.pool['ir.model.data'] - model, action_id = ir_model_obj.get_object_reference(self._cr, self._uid, 'account_bank_statement_import', action_name) - action = self.pool[model].read(self._cr, self._uid, action_id, context=self.env.context) - # Note: this drops action['context'], which is a dict stored as a string, which is not easy to update - action.update({'context': (u"{'journal_id': " + str(self.id) + u"}")}) + def create_bank_statement(self): + """return action to create a bank statements. This button should be called only on journals with type =='bank'""" + self.bank_statements_source = 'manual' + action = self.env.ref('account.action_bank_statement_tree').read()[0] + action.update({ + 'views': [[False, 'form']], + 'context': "{'default_journal_id': " + str(self.id) + "}", + }) return action diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py index 12b4433bd70..d9eebe31e1c 100644 --- a/addons/account/models/chart_template.py +++ b/addons/account/models/chart_template.py @@ -751,42 +751,21 @@ class WizardMultiChartsAccounts(models.TransientModel): def _create_bank_journals_from_o2m(self, company, acc_template_ref): ''' This function creates bank journals and its accounts for each line encoded in the field bank_account_ids of the - wizard. + wizard (which is currently only used to create a default bank and cash journal when the CoA is installed). - :param company_id: the id of the company for which the wizard is running. + :param company: 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 ''' self.ensure_one() - # Build a list with all the data to process - journal_data = [] - if self.bank_account_ids: - for acc in self.bank_account_ids: - vals = { - 'acc_name': acc.acc_name, - 'account_type': acc.account_type, - 'currency_id': acc.currency_id.id, - } - journal_data.append(vals) - - for line in journal_data: - if line['account_type'] == 'bank': - #create the bank account that will trigger the journal and account.account creation - res_partner_bank_vals = { - 'acc_number': line['acc_name'], - 'currency_id': line['currency_id'], - 'company_id': company.id, - 'owner_name': company.partner_id.name, - 'partner_id': company.partner_id.id, - 'footer': True - } - self.env['res.partner.bank'].create(res_partner_bank_vals) - else: - #create the cash journal that will trigger the account.account creation - vals_journal = self.env['account.journal']._prepare_bank_journal(company, line) - self.env['account.journal'].create(vals_journal) - return True + # Create the journals that will trigger the account.account creation + for acc in self.bank_account_ids: + self.env['account.journal'].create({ + 'name': acc.acc_name, + 'type': acc.account_type, + 'company_id': company.id, + 'currency_id': acc.currency_id.id, + }) class AccountBankAccountsWizard(models.TransientModel): diff --git a/addons/account/models/company.py b/addons/account/models/company.py index 0b3c0a8d1a9..d329003480b 100644 --- a/addons/account/models/company.py +++ b/addons/account/models/company.py @@ -34,6 +34,8 @@ class ResCompany(models.Model): property_stock_account_input_categ_id = fields.Many2one('account.account', oldname="property_stock_account_input_categ") property_stock_account_output_categ_id = fields.Many2one('account.account', oldname="property_stock_account_output_categ") property_stock_valuation_account_id = fields.Many2one('account.account') + bank_journal_ids = fields.One2many('account.journal', 'company_id', domain=[('type', '=', 'bank')], string='Bank Journals') + @api.multi def compute_fiscalyear_dates(self, date): diff --git a/addons/account/models/res_config.py b/addons/account/models/res_config.py index da44469b2cb..dc19a8dd3ac 100644 --- a/addons/account/models/res_config.py +++ b/addons/account/models/res_config.py @@ -174,14 +174,9 @@ class AccountConfigSettings(models.TransientModel): return True @api.multi - def open_company_form(self): - return { - 'type': 'ir.actions.act_window', - 'name': 'Configure your Company', - 'res_model': 'res.company', - 'res_id': self.company_id.id, - 'view_mode': 'form', - } + def open_bank_accounts(self): + action_rec = self.env['ir.model.data'].xmlid_to_object('account.action_account_bank_journal_form') + return action_rec.read([])[0] @api.multi def set_transfer_account(self): diff --git a/addons/account/report/inherited_layouts.xml b/addons/account/report/inherited_layouts.xml new file mode 100644 index 00000000000..290c1ba3a23 --- /dev/null +++ b/addons/account/report/inherited_layouts.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/addons/account/static/src/less/account_journal_dashboard.less b/addons/account/static/src/less/account_journal_dashboard.less index e0b15be344c..5e86c31d237 100644 --- a/addons/account/static/src/less/account_journal_dashboard.less +++ b/addons/account/static/src/less/account_journal_dashboard.less @@ -6,6 +6,10 @@ min-width: inherit; } + button { + margin-bottom: 5px; + } + .o_kanban_card_settings { padding: 8px; diff --git a/addons/account/test/account_bank_statement.yml b/addons/account/test/account_bank_statement.yml index cadb1f2fcd3..bd668e07a13 100644 --- a/addons/account/test/account_bank_statement.yml +++ b/addons/account/test/account_bank_statement.yml @@ -1,13 +1,6 @@ - !context journal_type: 'bank' -- - We create a new bank with the company as partner in order to be sure to have at least one bank journal -- - !record {model: res.partner.bank, id: test_bank}: - acc_number: BE123456789 - bank_name: BNP Test bank - partner_id: base.main_partner - In order to test Bank Statement feature of account I create a bank statement line and confirm it and check it's move created - diff --git a/addons/account/test/account_minimal_test.xml b/addons/account/test/account_minimal_test.xml index 2d495188db0..9760eb53757 100644 --- a/addons/account/test/account_minimal_test.xml +++ b/addons/account/test/account_minimal_test.xml @@ -237,6 +237,12 @@ + + 987654321 + bank + Bank + + Bank - Test TBNK @@ -244,6 +250,7 @@ + Cash - Test @@ -271,6 +278,12 @@ + + 123456789 + bank + Bank US + + USD Bank - Test TUBK @@ -278,6 +291,7 @@ + diff --git a/addons/account/tests/test_account_customer_invoice.py b/addons/account/tests/test_account_customer_invoice.py index 0b79b47a0d9..565057d733d 100644 --- a/addons/account/tests/test_account_customer_invoice.py +++ b/addons/account/tests/test_account_customer_invoice.py @@ -8,13 +8,11 @@ class TestAccountCustomerInvoice(AccountTestUsers): # I will create bank detail with using manager access rights # because account manager can only create bank details. self.res_partner_bank_0 = self.env['res.partner.bank'].sudo(self.account_manager.id).create(dict( - state='bank', + acc_type='bank', company_id=self.main_company.id, partner_id=self.main_partner.id, acc_number='123456789', - footer=True, - bank=self.main_bank.id, - bank_name=self.main_bank.name, + bank_id=self.main_bank.id, )) # Test with that user which have rights to make Invoicing and payment and who is accountant. diff --git a/addons/account/tests/test_payment.py b/addons/account/tests/test_payment.py index fba65d6f54c..00fcc9d7d3c 100644 --- a/addons/account/tests/test_payment.py +++ b/addons/account/tests/test_payment.py @@ -26,15 +26,11 @@ class TestPayment(AccountingTestCase): self.account_payable = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_payable').id)], limit=1) self.account_revenue = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1) - self.bank_euro = self.env['res.partner.bank'].create({'acc_number': '0123456789', 'bank_name': 'Test Bank', 'company_id': self.env.user.company_id.id}) - self.bank_journal_euro = self.bank_euro.journal_id + self.bank_journal_euro = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'}) self.account_eur = self.bank_journal_euro.default_debit_account_id - self.bank_usd = self.env['res.partner.bank'].create({'acc_number': '0123456789', 'bank_name': 'Test Bank USD', 'company_id': self.env.user.company_id.id}) - self.bank_journal_usd = self.bank_usd.journal_id + self.bank_journal_usd = self.env['account.journal'].create({'name': 'Bank US', 'type': 'bank', 'code': 'BNK68', 'currency_id': self.currency_usd_id}) self.account_usd = self.bank_journal_usd.default_debit_account_id - self.account_usd.write({'currency_id': self.currency_usd_id}) - self.bank_journal_usd.write({'currency_id': self.currency_usd_id}) self.transfer_account = self.env['res.users'].browse(self.env.uid).company_id.transfer_account_id self.diff_income_account = self.env['res.users'].browse(self.env.uid).company_id.income_currency_exchange_account_id diff --git a/addons/account/tests/test_reconciliation.py b/addons/account/tests/test_reconciliation.py index e155923e20a..a11987dae07 100644 --- a/addons/account/tests/test_reconciliation.py +++ b/addons/account/tests/test_reconciliation.py @@ -28,16 +28,12 @@ class TestReconciliation(AccountingTestCase): self.account_rsa = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_payable').id)], limit=1) self.product = self.env.ref("product.product_product_4") - self.bank_euro = self.env['res.partner.bank'].create({'acc_number': 'Reconciliation test', 'bank_name': 'Test Bank', 'company_id': self.env.user.company_id.id}) - self.bank_journal_euro = self.bank_euro.journal_id + self.bank_journal_euro = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'}) self.account_euro = self.bank_journal_euro.default_debit_account_id - self.bank_usd = self.env['res.partner.bank'].create({'acc_number': 'Reconciliation test USD', - 'bank_name': 'Test Bank USD', 'company_id': self.env.user.company_id.id}) - self.bank_journal_usd = self.bank_usd.journal_id + self.bank_journal_usd = self.env['account.journal'].create({'name': 'Bank US', 'type': 'bank', 'code': 'BNK68', 'currency_id': self.currency_usd_id}) self.account_usd = self.bank_journal_usd.default_debit_account_id - self.account_usd.write({'currency_id': self.currency_usd_id}) - self.bank_journal_usd.write({'currency_id': self.currency_usd_id}) + self.diff_income_account = self.env['res.users'].browse(self.env.uid).company_id.income_currency_exchange_account_id self.diff_expense_account = self.env['res.users'].browse(self.env.uid).company_id.expense_currency_exchange_account_id diff --git a/addons/account/views/account_bank_view.xml b/addons/account/views/account_bank_view.xml deleted file mode 100644 index d125251c360..00000000000 --- a/addons/account/views/account_bank_view.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - Partner Bank Accounts - Journal - res.partner.bank - - - - - - - - - - - - - - - Partner Bank Accounts - Add currency on tree - res.partner.bank - - - - - - - - - - - Bank Accounts - res.partner.bank - form - tree,form - - -

- Click to setup a new bank account. -

- Configure your company's bank account and select those that must - appear on the report footer. -

- If you use the accounting application of Odoo, journals and - accounts will be created automatically based on these data. -

-
-
- - -
-
diff --git a/addons/account/views/account_journal_dashboard_view.xml b/addons/account/views/account_journal_dashboard_view.xml index aa4dc1a2187..3d343f7ab84 100644 --- a/addons/account/views/account_journal_dashboard_view.xml +++ b/addons/account/views/account_journal_dashboard_view.xml @@ -71,12 +71,12 @@
New
-
+
@@ -200,12 +200,30 @@ - -
- -
+ +
+ + +
+ +
+
+ +
+ +
+
+
+ +
+ + Reconcile Items + +
+ +
@@ -260,11 +278,7 @@
-
- - -
-
+
diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml index 65d1f101eed..79f7e3d36d4 100644 --- a/addons/account/views/account_view.xml +++ b/addons/account/views/account_view.xml @@ -215,6 +215,7 @@ account.journal.search account.journal + 1 @@ -230,6 +231,7 @@ account.journal.form account.journal + 1
@@ -249,7 +251,7 @@ - + @@ -279,11 +281,79 @@ + + + + + + + + + + + +
+ + + account.bank.journal.tree + account.journal + 10 + + + + + + + + + + + account.bank.journal.form + account.journal + 10 + +
+ + + +
+
+ + + + + + + + +
+
+
+
+ + Bank Accounts + account.journal + tree,form + + [('type', '=', 'bank')] + {'default_type': 'bank', 'default_display_on_footer': True} + +

+ Click to add a bank account. +

+
+
+ + Journals account.journal diff --git a/addons/account/views/res_config_view.xml b/addons/account/views/res_config_view.xml index 6fc3552e650..2160a3a7d02 100644 --- a/addons/account/views/res_config_view.xml +++ b/addons/account/views/res_config_view.xml @@ -164,7 +164,7 @@
- + - - - - - + + + + + - - - - - - - - - @@ -86,7 +68,7 @@ - + diff --git a/openerp/addons/base/res/res_partner_data.xml b/openerp/addons/base/res/res_partner_data.xml index 841a66d316d..607b149c2ed 100644 --- a/openerp/addons/base/res/res_partner_data.xml +++ b/openerp/addons/base/res/res_partner_data.xml @@ -30,17 +30,6 @@ Prof. - - - Normal Bank Account - bank - - - - bank_bic - - - diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv index 1dcfeb81c9c..1357acc31ac 100644 --- a/openerp/addons/base/security/ir.model.access.csv +++ b/openerp/addons/base/security/ir.model.access.csv @@ -63,10 +63,6 @@ "access_res_partner_group_user","res_partner group_user","model_res_partner","group_user",1,0,0,0 "access_res_partner_bank_group_user","res_partner_bank group_user","model_res_partner_bank","group_user",1,0,0,0 "access_res_partner_bank_group_partner_manager","res_partner_bank group_partner_manager","model_res_partner_bank","group_partner_manager",1,1,1,1 -"access_res_partner_bank_type_group_partner_manager","res_partner_bank_type group_partner_manager","model_res_partner_bank_type","group_partner_manager",1,1,1,1 -"access_res_partner_bank_type_group_user","res_partner_bank_type group_user","model_res_partner_bank_type",,1,0,0,0 -"access_res_partner_bank_type_field_group_partner_manager","res_partner_bank_type_field group_partner_manager","model_res_partner_bank_type_field","group_partner_manager",1,1,1,1 -"access_res_partner_bank_type_field_group_user","res_partner_bank_type_field group_user","model_res_partner_bank_type_field",,1,0,0,0 "access_res_partner_category_group_user","res_partner_category group_user","model_res_partner_category","group_user",1,0,0,0 "access_res_partner_category_group_partner_manager","res_partner_category group_partner_manager","model_res_partner_category","group_partner_manager",1,1,1,1 "access_res_partner_title_group_user","res_partner_title group_user","model_res_partner_title","group_partner_manager",1,1,1,1 diff --git a/openerp/addons/base/tests/__init__.py b/openerp/addons/base/tests/__init__.py index 82b79cfc693..d58e4931ec7 100644 --- a/openerp/addons/base/tests/__init__.py +++ b/openerp/addons/base/tests/__init__.py @@ -25,3 +25,4 @@ import test_translate import test_view_validation import test_views import test_xmlrpc +import test_res_partner_bank diff --git a/openerp/addons/base/tests/test_expression.py b/openerp/addons/base/tests/test_expression.py index a3a93971b59..9bf61d61473 100644 --- a/openerp/addons/base/tests/test_expression.py +++ b/openerp/addons/base/tests/test_expression.py @@ -175,8 +175,6 @@ class test_expression(common.TransactionCase): partner_bank_ids_col = partner_obj._columns.get('bank_ids') # one2many on res.partner to res.partner.bank category_id_col = partner_obj._columns.get('category_id') # many2many on res.partner to res.partner.category - # Get the first bank account type to be able to create a res.partner.bank - bank_type = bank_obj._bank_type_get(cr, uid)[0] # Get country/state data country_us_id = registry('res.country').search(cr, uid, [('code', 'like', 'US')])[0] state_ids = registry('res.country.state').search(cr, uid, [('country_id', '=', country_us_id)], limit=2) @@ -187,9 +185,9 @@ class test_expression(common.TransactionCase): p_aa = partner_obj.create(cr, uid, {'name': 'test__AA', 'parent_id': p_a, 'state_id': state_ids[0]}) p_ab = partner_obj.create(cr, uid, {'name': 'test__AB', 'parent_id': p_a, 'state_id': state_ids[1]}) p_ba = partner_obj.create(cr, uid, {'name': 'test__BA', 'parent_id': p_b, 'state_id': state_ids[0]}) - b_aa = bank_obj.create(cr, uid, {'acc_number': '__bank_test_a', 'state': bank_type[0], 'partner_id': p_aa}) - b_ab = bank_obj.create(cr, uid, {'acc_number': '__bank_test_b', 'state': bank_type[0], 'partner_id': p_ab}) - b_ba = bank_obj.create(cr, uid, {'acc_number': '__bank_test_b', 'state': bank_type[0], 'partner_id': p_ba}) + b_aa = bank_obj.create(cr, uid, {'acc_number': '123', 'acc_type': 'bank', 'partner_id': p_aa}) + b_ab = bank_obj.create(cr, uid, {'acc_number': '456', 'acc_type': 'bank', 'partner_id': p_ab}) + b_ba = bank_obj.create(cr, uid, {'acc_number': '789', 'acc_type': 'bank', 'partner_id': p_ba}) # -------------------------------------------------- # Test1: basics about the attribute @@ -203,34 +201,34 @@ class test_expression(common.TransactionCase): # Test2: one2many # -------------------------------------------------- - name_test = 'test_a' + name_test = '12' # Do: one2many without _auto_join self._reinit_mock() - partner_ids = partner_obj.search(cr, uid, [('bank_ids.acc_number', 'like', name_test)]) + partner_ids = partner_obj.search(cr, uid, [('bank_ids.sanitized_acc_number', 'like', name_test)]) # Test result self.assertEqual(set(partner_ids), set([p_aa]), - "_auto_join off: ('bank_ids.acc_number', 'like', '..'): incorrect result") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..'): incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 3, - "_auto_join off: ('bank_ids.acc_number', 'like', '..') should produce 3 queries (1 in res_partner_bank, 2 on res_partner)") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') should produce 3 queries (1 in res_partner_bank, 2 on res_partner)") sql_query = self.query_list[0].get_sql() self.assertIn('res_partner_bank', sql_query[0], - "_auto_join off: ('bank_ids.acc_number', 'like', '..') first query incorrect main table") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect main table") - expected = "%s::text like %s" % (unaccent('"res_partner_bank"."acc_number"'), unaccent('%s')) + expected = "%s::text like %s" % (unaccent('"res_partner_bank"."sanitized_acc_number"'), unaccent('%s')) self.assertIn(expected, sql_query[1], - "_auto_join off: ('bank_ids.acc_number', 'like', '..') first query incorrect where condition") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect where condition") self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]), - "_auto_join off: ('bank_ids.acc_number', 'like', '..') first query incorrect parameter") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect parameter") sql_query = self.query_list[2].get_sql() self.assertIn('res_partner', sql_query[0], - "_auto_join off: ('bank_ids.acc_number', 'like', '..') third query incorrect main table") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect main table") self.assertIn('"res_partner"."id" in (%s)', sql_query[1], - "_auto_join off: ('bank_ids.acc_number', 'like', '..') third query incorrect where condition") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect where condition") self.assertEqual(set([p_aa]), set(sql_query[2]), - "_auto_join off: ('bank_ids.acc_number', 'like', '..') third query incorrect parameter") + "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect parameter") # Do: cascaded one2many without _auto_join self._reinit_mock() @@ -245,27 +243,27 @@ class test_expression(common.TransactionCase): # Do: one2many with _auto_join partner_bank_ids_col._auto_join = True self._reinit_mock() - partner_ids = partner_obj.search(cr, uid, [('bank_ids.acc_number', 'like', 'test_a')]) + partner_ids = partner_obj.search(cr, uid, [('bank_ids.sanitized_acc_number', 'like', '12')]) # Test result self.assertEqual(set(partner_ids), set([p_aa]), - "_auto_join on: ('bank_ids.acc_number', 'like', '..') incorrect result") + "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 1, - "_auto_join on: ('bank_ids.acc_number', 'like', '..') should produce 1 query") + "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') should produce 1 query") sql_query = self.query_list[0].get_sql() self.assertIn('"res_partner"', sql_query[0], - "_auto_join on: ('bank_ids.acc_number', 'like', '..') query incorrect main table") + "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect main table") self.assertIn('"res_partner_bank" as "res_partner__bank_ids"', sql_query[0], - "_auto_join on: ('bank_ids.acc_number', 'like', '..') query incorrect join") + "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect join") - expected = "%s::text like %s" % (unaccent('"res_partner__bank_ids"."acc_number"'), unaccent('%s')) + expected = "%s::text like %s" % (unaccent('"res_partner__bank_ids"."sanitized_acc_number"'), unaccent('%s')) self.assertIn(expected, sql_query[1], - "_auto_join on: ('bank_ids.acc_number', 'like', '..') query incorrect where condition") + "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect where condition") self.assertIn('"res_partner"."id"="res_partner__bank_ids"."partner_id"', sql_query[1], - "_auto_join on: ('bank_ids.acc_number', 'like', '..') query incorrect join condition") + "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect join condition") self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]), - "_auto_join on: ('bank_ids.acc_number', 'like', '..') query incorrect parameter") + "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect parameter") # Do: one2many with _auto_join, test final leaf is an id self._reinit_mock() @@ -426,7 +424,7 @@ class test_expression(common.TransactionCase): partner_child_ids_col._auto_join = True partner_bank_ids_col._auto_join = True partner_child_ids_col._domain = lambda self: ['!', ('name', '=', self._name)] - partner_bank_ids_col._domain = [('acc_number', 'like', 'a')] + partner_bank_ids_col._domain = [('sanitized_acc_number', 'like', '2')] # Do: 2 cascaded one2many with _auto_join, test final leaf is an id self._reinit_mock() partner_ids = partner_obj.search(cr, uid, ['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) @@ -438,7 +436,7 @@ class test_expression(common.TransactionCase): # Test produced queries that domains effectively present sql_query = self.query_list[0].get_sql() - expected = "%s::text like %s" % (unaccent('"res_partner__child_ids__bank_ids"."acc_number"'), unaccent('%s')) + expected = "%s::text like %s" % (unaccent('"res_partner__child_ids__bank_ids"."sanitized_acc_number"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join on one2many with domains incorrect result") # TDE TODO: check first domain has a correct table name diff --git a/openerp/addons/base/tests/test_osv_expression.yml b/openerp/addons/base/tests/test_osv_expression.yml index 3a917528474..813acfd2669 100644 --- a/openerp/addons/base/tests/test_osv_expression.yml +++ b/openerp/addons/base/tests/test_osv_expression.yml @@ -206,7 +206,7 @@ # that don't have OpenERP has a parent company, you expect to find, # among others, the companies that don't have parent company. # - + # existing values be treated similarly if we simply check that some # existing value belongs to them. @@ -367,52 +367,14 @@ Equivalent queries, one2many. - !python {model: res.company }: | - # Search the company via its one2many (the one2many must point back at the company). company = self.browse(cr, uid, ref('ymltest_company3')) - max_currency_id = max(self.pool['res.partner.bank'].search(cr, uid, [])) - bank_ids1 = self.pool['res.partner.bank'].search(cr, uid, [('acc_number', 'not like', 'probably_unexisting_name')]) - bank_ids2 = self.pool['res.partner.bank'].search(cr, uid, [('id', 'not in', [max_currency_id + 1003])]) - bank_ids3 = self.pool['res.partner.bank'].search(cr, uid, [('id', 'not in', [])]) - assert bank_ids1 == bank_ids2 == bank_ids3, 'All 3 results should have be the same: all banks' - default_company = self.browse(cr, uid, 1) - # set manually a bank to the default company. - self.pool['res.partner.bank'].write(cr, uid, bank_ids1, {'company_id': default_company.id}) # one2many towards same model res_1 = self.search(cr, uid, [('child_ids', 'in', [x.id for x in company.child_ids])]) # any company having a child of company3 as child res_2 = self.search(cr, uid, [('child_ids', 'in', [company.child_ids[0].id])]) # any company having the first child of company3 as child - # one2many towards another model - res_3 = self.search(cr, uid, [('bank_ids', 'in', [x.id for x in default_company.bank_ids])]) # companies having a currency of main company - res_4 = self.search(cr, uid, [('bank_ids', 'in', [default_company.bank_ids[0].id])]) # companies having first currency of main company - res_5 = self.search(cr, uid, [('bank_ids', 'in', default_company.bank_ids[0].id)]) # companies having first currency of main company - # res_6 = self.search(cr, uid, [('bank_ids', 'in', [default_company.currency_ids[0].name])]) # TODO - res_7 = self.search(cr, uid, [('bank_ids', '=', default_company.bank_ids[0].acc_number)]) - res_8 = self.search(cr, uid, [('bank_ids', 'like', default_company.bank_ids[0].acc_number)]) - - res_9 = self.search(cr, uid, [('bank_ids', 'like', 'probably_unexisting_name')]) - # self.search(cr, uid, [('bank_ids', 'unexisting_op', 'probably_unexisting_name')]) # TODO expected exception assert res_1 == [ref('ymltest_company3')], "res_1" assert res_2 == [ref('ymltest_company3')], "res_2" - assert res_3 == [1], "res_3" - assert res_4 == [1], "res_4" - assert res_5 == [1], "res_5" - assert res_7 == [1], "res_7" - assert res_8 == [1], "res_8" - assert res_9 == [], "res_9" - # get the companies referenced by some currency (this is normally the main company) using a weird negative domain - res_10 = self.search(cr, uid, [('bank_ids', 'not like', 'probably_unexisting_name')]) - res_11 = self.search(cr, uid, [('bank_ids', 'not in', [max_currency_id + 1])]) - res_12 = self.search(cr, uid, [('bank_ids', '!=', False)]) - res_13 = self.search(cr, uid, [('bank_ids', 'not in', [])]) - res_10.sort() - res_11.sort() - res_12.sort() - res_13.sort() - assert res_10 == res_11 - assert res_10 == res_12 - assert res_10 == res_13 - # try testing real subsets with IN/NOT IN res_partner = self.pool.get('res.partner') res_users = self.pool.get('res.users') @@ -443,6 +405,53 @@ assert res_2 == expected assert res_3 == expected assert res_4 == expected +- + Equivalent queries, one2many. +- + !python {model: res.currency }: | + # Create a currency and a currency rate + res_currency = self.pool['res.currency'] + res_currency_rate = self.pool['res.currency.rate'] + currency = res_currency.create(cr, uid, {'name': 'ZZZ', 'symbol': 'ZZZ', 'rounding': 1.0}) + currency_rate = self.pool['res.currency.rate'].create(cr, uid, {'name': '2010-01-01', 'currency_id': currency, 'rate': 1.0}) + + # Search the currency via its rates one2many (the one2many must point back at the currency). + max_currency_rate_id = max(res_currency_rate.search(cr, uid, [])) + currency_rate1 = res_currency_rate.search(cr, uid, [('name', 'not like', 'probably_unexisting_name')]) + currency_rate2 = res_currency_rate.search(cr, uid, [('id', 'not in', [max_currency_rate_id + 1003])]) + currency_rate3 = res_currency_rate.search(cr, uid, [('id', 'not in', [])]) + assert currency_rate1 == currency_rate2 == currency_rate3, 'All 3 results should be the same : empty' + default_currency = self.browse(cr, uid, 1) + + # one2many towards another model + res_3 = self.search(cr, uid, [('rate_ids', 'in', [x.id for x in default_currency.rate_ids])]) # currencies having a rate of main currency + res_4 = self.search(cr, uid, [('rate_ids', 'in', [default_currency.rate_ids[0].id])]) # currencies having first rate of main currency + res_5 = self.search(cr, uid, [('rate_ids', 'in', default_currency.rate_ids[0].id)]) # currencies having first rate of main currency + # res_6 = self.search(cr, uid, [('rate_ids', 'in', [default_currency.rate_ids[0].name])]) + # res_7 = self.search(cr, uid, [('rate_ids', '=', default_currency.rate_ids[0].name)]) + # res_8 = self.search(cr, uid, [('rate_ids', 'like', default_currency.rate_ids[0].name)]) + + res_9 = self.search(cr, uid, [('rate_ids', 'like', 'probably_unexisting_name')]) + # self.search(cr, uid, [('rate_ids', 'unexisting_op', 'probably_unexisting_name')]) # TODO expected exception + assert res_3 == [1], "res_3" + assert res_4 == [1], "res_4" + assert res_5 == [1], "res_5" + # assert res_7 == [1], "res_7" + # assert res_8 == [1], "res_8" + assert res_9 == [], "res_9" + + # get the currencies referenced by some currency rates using a weird negative domain + res_10 = self.search(cr, uid, [('rate_ids', 'not like', 'probably_unexisting_name')]) + res_11 = self.search(cr, uid, [('rate_ids', 'not in', [max_currency_rate_id + 1])]) + res_12 = self.search(cr, uid, [('rate_ids', '!=', False)]) + res_13 = self.search(cr, uid, [('rate_ids', 'not in', [])]) + res_10.sort() + res_11.sort() + res_12.sort() + res_13.sort() + assert res_10 == res_11, 'res_11' + assert res_10 == res_12, 'res_12' + assert res_10 == res_13, 'res_13' - Unaccent. Create a company with an accent in its name. - diff --git a/openerp/addons/base/tests/test_res_partner_bank.py b/openerp/addons/base/tests/test_res_partner_bank.py new file mode 100644 index 00000000000..40cd9f797bf --- /dev/null +++ b/openerp/addons/base/tests/test_res_partner_bank.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# This file is part of account_bank_statement_import, +# an Odoo module. +# +# Copyright (c) 2015 ACSONE SA/NV () +# +# account_bank_statement_import 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. +# +# account_bank_statement_import 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 account_bank_statement_import_coda. +# If not, see . +# +############################################################################## +from openerp.tests.common import TransactionCase + + +class TestResPartnerBank(TransactionCase): + """Tests acc_number + """ + + def test_sanitized_acc_number(self): + partner_bank_model = self.env['res.partner.bank'] + acc_number = " BE-001 2518823 03 " + vals = partner_bank_model.search([('acc_number', '=', acc_number)]) + self.assertEquals(0, len(vals)) + partner_bank = partner_bank_model.create({ + 'acc_number': acc_number, + 'partner_id': self.ref('base.res_partner_2'), + 'acc_type': 'bank', + }) + vals = partner_bank_model.search([('acc_number', '=', acc_number)]) + self.assertEquals(1, len(vals)) + self.assertEquals(partner_bank, vals[0]) + vals = partner_bank_model.search([('acc_number', 'in', [acc_number])]) + self.assertEquals(1, len(vals)) + self.assertEquals(partner_bank, vals[0]) + + self.assertEqual(partner_bank.acc_number, acc_number) + + # sanitaze the acc_number + sanitized_acc_number = 'BE001251882303' + vals = partner_bank_model.search( + [('acc_number', '=', sanitized_acc_number)]) + self.assertEquals(1, len(vals)) + self.assertEquals(partner_bank, vals[0]) + vals = partner_bank_model.search( + [('acc_number', 'in', [sanitized_acc_number])]) + self.assertEquals(1, len(vals)) + self.assertEquals(partner_bank, vals[0]) + self.assertEqual(partner_bank.sanitized_acc_number, + sanitized_acc_number) + + # search is case insensitive + vals = partner_bank_model.search( + [('acc_number', '=', sanitized_acc_number.lower())]) + self.assertEquals(1, len(vals)) + vals = partner_bank_model.search( + [('acc_number', '=', acc_number.lower())]) + self.assertEquals(1, len(vals))