[FIX] analytic: duplication of analytic lines

When duplicating analytic accounts, child accounts are duplicated as well.
The custom copy method removes the analytic lines but this applies only on the
first copy. As the copy_data method recursively copies child accounts, these
child accounts did not use the custom copy method but the basic copy_data.

Move to copy_data

Fixes #6368, lp:1149676
This commit is contained in:
Christophe Combelles 2015-04-17 17:10:17 +03:00 committed by Martin Trigaux
parent 6af7c636c2
commit 2c37f83435
3 changed files with 67 additions and 2 deletions

View File

@ -157,6 +157,7 @@ for a particular financial year and for preparation of vouchers there is a modul
#'test/account_cash_statement.yml',
'test/test_edi_invoice.yml',
'test/account_report.yml',
'test/analytic_hierarchy.yml',
'test/account_fiscalyear_close.yml', #last test, as it will definitively close the demo fiscalyear
],
'installable': True,

View File

@ -0,0 +1,56 @@
-
We create a simple hierarchy like this
Toplevel view account
├ Real analytic account 1
└ Real analytic account 2
-
!record {model: account.analytic.account, id: analytic_account_view1}:
name: 'Toplevel view account'
type: 'view'
-
!record {model: account.analytic.account, id: analytic_account1}:
name: 'Real analytic account 1'
type: 'normal'
parent_id: analytic_account_view1
-
!record {model: account.analytic.account, id: analytic_account2}:
name: 'Real analytic account 2'
type: 'normal'
parent_id: analytic_account_view1
-
We add analytic lines in real accounts and journal
-
!record {model: account.analytic.journal, id: analytic_journal1}:
name: 'Analytic journal'
-
!record {model: account.analytic.line, id: analytic_line1}:
name: 'Analytic line 1'
account_id: analytic_account1
journal_id: analytic_journal1
general_account_id: account.a_expense
-
!record {model: account.analytic.line, id: analytic_line2}:
name: 'Analytic line 2'
account_id: analytic_account2
journal_id: analytic_journal1
general_account_id: account.a_expense
-
Now we copy the toplevel account
-
!function {model: account.analytic.account, name: copy, id: analytic_account_view1}:
- eval: "ref('analytic_account_view1')"
-
!python {model: account.analytic.account}: |
# the toplevel account has been copied with the (copy) suffix
accounts = self.search(cr, uid, [('name', 'like', '%Toplevel view account%')])
assert len(accounts) == 2, 'The toplevel account has not been copied'
accounts = self.search(cr, uid, [('name', '=', 'Toplevel view account')])
assert len(accounts) == 1, 'The toplevel account copy has a bad name'
# the sub-accounts and sub-accounts have been copied without the (copy) suffix
accounts = self.search(cr, uid, [('name', '=', 'Real analytic account 1')])
assert len(accounts) == 2, 'The sub-account has not been copied'
accounts = self.search(cr, uid, [('name', '=', 'Real analytic account 2')])
assert len(accounts) == 2, 'The sub-account has not been copied'
# the analytic lines should not be duplicated
lines = self.pool.get('account.analytic.line').search(cr, uid, [('name', 'like', '%Analytic line %')])
assert len(lines) == 2, "The analytic lines shouldn't have been copied"

View File

@ -261,13 +261,21 @@ class account_analytic_account(osv.osv):
def name_create(self, cr, uid, name, context=None):
raise osv.except_osv(_('Warning'), _("Quick account creation disallowed."))
def copy_data(self, cr, uid, id, default=None, context=None):
"""executed for all the objects down the hierarchy during copy"""
if not default:
default = {}
default.setdefault('code', False)
default.setdefault('line_ids', [])
return super(account_analytic_account, self).copy_data(cr, uid, id, default, context=context)
def copy(self, cr, uid, id, default=None, context=None):
""" executed only on the toplevel copied object of the hierarchy.
Subobject are actually copied with copy_data"""
if not default:
default = {}
analytic = self.browse(cr, uid, id, context=context)
default.update(
code=False,
line_ids=[],
name=_("%s (copy)") % (analytic['name']))
return super(account_analytic_account, self).copy(cr, uid, id, default, context=context)