Merge lp:~acsone-openerp/account-analytic/account_analytic_required-test_suite-sbi into lp:~account-core-editors/account-analytic/7.0

Proposed by Stéphane Bidoul (Acsone) on 2014-04-18
Status: Merged
Merged at revision: 18
Proposed branch: lp:~acsone-openerp/account-analytic/account_analytic_required-test_suite-sbi
Merge into: lp:~account-core-editors/account-analytic/7.0
Diff against target: 369 lines (+249/-31)
6 files modified
account_analytic_required/__init__.py (+1/-1)
account_analytic_required/__openerp__.py (+17/-9)
account_analytic_required/account.py (+59/-20)
account_analytic_required/account_view.xml (+12/-1)
account_analytic_required/tests/__init__.py (+30/-0)
account_analytic_required/tests/test_account_analytic_required.py (+130/-0)
To merge this branch: bzr merge lp:~acsone-openerp/account-analytic/account_analytic_required-test_suite-sbi
Reviewer Review Type Date Requested Status
Guewen Baconnier @ Camptocamp Approve on 2014-04-28
Alexis de Lattre (community) code review and tests 2014-04-18 Approve on 2014-04-18
Pedro Manuel Baeza code review 2014-04-18 Approve on 2014-04-18
Review via email: mp+216451@code.launchpad.net

Description of the change

Add a test suite for account_analytic_required, and fix a small hole in the policy check (when changing analytic account after creating the move line, the policy would not be checked).

To post a comment you must log in.
Pedro Manuel Baeza (pedro.baeza) wrote :

Thanks for the work, Stéphane.

Regards.

review: Approve (code review)
Alexis de Lattre (alexis-via) wrote :

Nice update. Thank you Stefan.

I am pushing to you a branch with pep8 stuff and the additional of the field in the tree view (and not just form view).

review: Approve (code review and tests)
19. By Stéphane Bidoul (Acsone) on 2014-04-19

[MRG] flake8 long lines + add policy in tree view from Alexis de Lattre

20. By Stéphane Bidoul (Acsone) on 2014-04-19

[IMP] comments in test suite + long lines __openerp__.py

Alexis de Lattre (alexis-via) wrote :

OK, let's go and merge it in the main branch now :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'account_analytic_required/__init__.py'
--- account_analytic_required/__init__.py 2012-11-21 08:56:48 +0000
+++ account_analytic_required/__init__.py 2014-04-19 10:20:35 +0000
@@ -21,4 +21,4 @@
21##############################################################################21##############################################################################
2222
2323
24import account24from . import account
2525
=== modified file 'account_analytic_required/__openerp__.py'
--- account_analytic_required/__openerp__.py 2013-04-23 14:25:48 +0000
+++ account_analytic_required/__openerp__.py 2014-04-19 10:20:35 +0000
@@ -2,7 +2,7 @@
2##############################################################################2##############################################################################
3#3#
4# Account analytic required module for OpenERP4# Account analytic required module for OpenERP
5# Copyright (C) 2011 Akretion (http://www.akretion.com). All Rights Reserved5# Copyright (C) 2011 Akretion (http://www.akretion.com)
6# @author Alexis de Lattre <alexis.delattre@akretion.com>6# @author Alexis de Lattre <alexis.delattre@akretion.com>
7#7#
8# This program is free software: you can redistribute it and/or modify8# This program is free software: you can redistribute it and/or modify
@@ -22,15 +22,24 @@
2222
2323
24{24{
25 'name': 'Account analytic required',25 'name': 'Account Analytic Required',
26 'version': '0.2',26 'version': '0.2',
27 'category': 'Generic Modules/Accounting',27 'category': 'Analytic Accounting',
28 'license': 'AGPL-3',28 'license': 'AGPL-3',
29 'description': """This module adds an option "analytic policy" on account types. You have the choice between 3 policies : always, never and optional.29 'description': """
3030Account Analytic Required
31For example, if you want to have an analytic account on all your expenses, set the policy to "always" for the account type "expense" ; then, if you try to save an account move line with an account of type "expense" without analytic account, you will get an error message.31=========================
3232
33Module developped by Alexis de Lattre <alexis.delattre@akretion.com> during the Akretion-Camptocamp code sprint of June 2011.33This module adds an option *analytic policy* on account types.
34You have the choice between 3 policies : *always*, *never* and *optional*.
35
36For example, if you want to have an analytic account on all your expenses,
37set the policy to *always* for the account type *expense* ; then, if you
38try to save an account move line with an account of type *expense*
39without analytic account, you will get an error message.
40
41Module developped by Alexis de Lattre <alexis.delattre@akretion.com>
42during the Akretion-Camptocamp code sprint of June 2011.
34""",43""",
35 'author': 'Akretion',44 'author': 'Akretion',
36 'website': 'http://www.akretion.com/',45 'website': 'http://www.akretion.com/',
@@ -39,4 +48,3 @@
39 'installable': True,48 'installable': True,
40 'active': False,49 'active': False,
41}50}
42
4351
=== modified file 'account_analytic_required/account.py'
--- account_analytic_required/account.py 2013-04-23 14:25:48 +0000
+++ account_analytic_required/account.py 2014-04-19 10:20:35 +0000
@@ -2,7 +2,7 @@
2##############################################################################2##############################################################################
3#3#
4# Account analytic required module for OpenERP4# Account analytic required module for OpenERP
5# Copyright (C) 2011 Akretion (http://www.akretion.com). All Rights Reserved5# Copyright (C) 2011 Akretion (http://www.akretion.com)
6# @author Alexis de Lattre <alexis.delattre@akretion.com>6# @author Alexis de Lattre <alexis.delattre@akretion.com>
7# Developped during the Akretion-Camptocamp code sprint of June 20117# Developped during the Akretion-Camptocamp code sprint of June 2011
8#8#
@@ -22,43 +22,82 @@
22##############################################################################22##############################################################################
2323
24from openerp.osv import orm, fields24from openerp.osv import orm, fields
25from tools.translate import _25from openerp.tools.translate import _
2626
2727
28class account_account_type(orm.Model):28class account_account_type(orm.Model):
29 _inherit = "account.account.type"29 _inherit = "account.account.type"
3030
31 _columns = {31 _columns = {
32 'analytic_policy' : fields.selection([32 'analytic_policy': fields.selection([
33 ('optional', 'Optional'),33 ('optional', 'Optional'),
34 ('always', 'Always'),34 ('always', 'Always'),
35 ('never', 'Never')35 ('never', 'Never')
36 ], 'Policy for analytic account', help="Set the policy for analytic accounts : if you select 'Optional', the accountant is free to put an analytic account on an account move line with this type of account ; if you select 'Always', the accountant will get an error message if there is no analytic account ; if you select 'Never', the accountant will get an error message if an analytic account is present."),36 ], 'Policy for analytic account',
37 help="Set the policy for analytic accounts : if you select "
38 "'Optional', the accountant is free to put an analytic account "
39 "on an account move line with this type of account ; if you "
40 "select 'Always', the accountant will get an error message if "
41 "there is no analytic account ; if you select 'Never', the "
42 "accountant will get an error message if an analytic account "
43 "is present."),
37 }44 }
3845
39 _defaults = {46 _defaults = {
40 'analytic_policy': lambda *a: 'optional',47 'analytic_policy': 'optional',
41 }48 }
4249
4350
44class account_move_line(orm.Model):51class account_move_line(orm.Model):
45 _inherit = "account.move.line"52 _inherit = "account.move.line"
4653
47 def check_analytic_required(self, cr, uid, vals, context=None):54 def check_analytic_required(self, cr, uid, ids, vals, context=None):
48 if 'account_id' in vals and (vals.get('debit', 0.0) != 0.0 or vals.get('credit', 0.0) != 0.0):55 if 'account_id' in vals or 'analytic_account_id' in vals or \
49 account = self.pool.get('account.account').browse(cr, uid, vals['account_id'], context=context)56 'debit' in vals or 'credit' in vals:
50 if account.user_type.analytic_policy == 'always' and not vals.get('analytic_account_id', False):57 if isinstance(ids, (int, long)):
51 raise orm.except_orm(_('Error :'), _("Analytic policy is set to 'Always' with account %s '%s' but the analytic account is missing in the account move line with label '%s'." % (account.code, account.name, vals.get('name', False))))58 ids = [ids]
52 elif account.user_type.analytic_policy == 'never' and vals.get('analytic_account_id', False):59 for move_line in self.browse(cr, uid, ids, context):
53 cur_analytic_account = self.pool.get('account.analytic.account').read(cr, uid, vals['analytic_account_id'], ['name', 'code'], context=context)60 if move_line.debit == 0 and move_line.credit == 0:
54 raise orm.except_orm(_('Error :'), _("Analytic policy is set to 'Never' with account %s '%s' but the account move line with label '%s' has an analytic account %s '%s'." % (account.code, account.name, vals.get('name', False), cur_analytic_account['code'], cur_analytic_account['name'])))61 continue
62 analytic_policy = \
63 move_line.account_id.user_type.analytic_policy
64 if analytic_policy == 'always' and \
65 not move_line.analytic_account_id:
66 raise orm.except_orm(
67 _('Error :'),
68 _("Analytic policy is set to 'Always' with account "
69 "%s '%s' but the analytic account is missing in "
70 "the account move line with label '%s'.")
71 % (
72 move_line.account_id.code,
73 move_line.account_id.name,
74 move_line.name))
75 elif analytic_policy == 'never' and \
76 move_line.analytic_account_id:
77 raise orm.except_orm(
78 _('Error :'),
79 _("Analytic policy is set to 'Never' with account %s "
80 "'%s' but the account move line with label '%s' "
81 "has an analytic account %s '%s'.")
82 % (
83 move_line.account_id.code,
84 move_line.account_id.name,
85 move_line.name,
86 move_line.analytic_account_id.code,
87 move_line.analytic_account_id.name))
55 return True88 return True
5689
57 def create(self, cr, uid, vals, context=None, check=True):90 def create(self, cr, uid, vals, context=None, check=True):
58 self.check_analytic_required(cr, uid, vals, context=context)91 line_id = super(account_move_line, self).create(
59 return super(account_move_line, self).create(cr, uid, vals, context=context, check=check)92 cr, uid, vals, context=context, check=check)
6093 self.check_analytic_required(cr, uid, line_id, vals, context=context)
61 def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):94 return line_id
62 self.check_analytic_required(cr, uid, vals, context=context)95
63 return super(account_move_line, self).write(cr, uid, ids, vals, context=context, check=check, update_check=update_check)96 def write(
6497 self, cr, uid, ids, vals, context=None, check=True,
98 update_check=True):
99 res = super(account_move_line, self).write(
100 cr, uid, ids, vals, context=context, check=check,
101 update_check=update_check)
102 self.check_analytic_required(cr, uid, ids, vals, context=context)
103 return res
65104
=== modified file 'account_analytic_required/account_view.xml'
--- account_analytic_required/account_view.xml 2012-11-21 08:56:48 +0000
+++ account_analytic_required/account_view.xml 2014-04-19 10:20:35 +0000
@@ -15,7 +15,18 @@
15 <field name="inherit_id" ref="account.view_account_type_form" />15 <field name="inherit_id" ref="account.view_account_type_form" />
16 <field name="arch" type="xml">16 <field name="arch" type="xml">
17 <field name="code" position="after">17 <field name="code" position="after">
18 <field name="analytic_policy" />18 <field name="analytic_policy" />
19 </field>
20 </field>
21</record>
22
23<record id="view_account_type_tree" model="ir.ui.view">
24 <field name="name">account_analytic_required.account_type_tree</field>
25 <field name="model">account.account.type</field>
26 <field name="inherit_id" ref="account.view_account_type_tree" />
27 <field name="arch" type="xml">
28 <field name="code" position="after">
29 <field name="analytic_policy" />
19 </field>30 </field>
20 </field>31 </field>
21</record>32</record>
2233
=== added directory 'account_analytic_required/tests'
=== added file 'account_analytic_required/tests/__init__.py'
--- account_analytic_required/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ account_analytic_required/tests/__init__.py 2014-04-19 10:20:35 +0000
@@ -0,0 +1,30 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Account analytic required module for OpenERP
5# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved
6# @author Stéphane Bidoul <stephane.bidoul@acsone.eu>
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as
10# published by the Free Software Foundation, either version 3 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22
23from . import test_account_analytic_required
24
25fast_suite = [
26]
27
28checks = [
29 test_account_analytic_required,
30]
031
=== added file 'account_analytic_required/tests/test_account_analytic_required.py'
--- account_analytic_required/tests/test_account_analytic_required.py 1970-01-01 00:00:00 +0000
+++ account_analytic_required/tests/test_account_analytic_required.py 2014-04-19 10:20:35 +0000
@@ -0,0 +1,130 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Account analytic required module for OpenERP
5# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved
6# @author Stéphane Bidoul <stephane.bidoul@acsone.eu>
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as
10# published by the Free Software Foundation, either version 3 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22
23from datetime import datetime
24
25from openerp.tests import common
26from openerp.osv import orm
27
28
29class test_account_analytic_required(common.TransactionCase):
30
31 def setUp(self):
32 super(test_account_analytic_required, self).setUp()
33 self.account_obj = self.registry('account.account')
34 self.account_type_obj = self.registry('account.account.type')
35 self.move_obj = self.registry('account.move')
36 self.move_line_obj = self.registry('account.move.line')
37 self.analytic_account_obj = self.registry('account.analytic.account')
38 self.analytic_account_id = self.analytic_account_obj.create(
39 self.cr, self.uid, {'name': 'test aa', 'type': 'normal'})
40
41 def _create_move(self, with_analytic, amount=100):
42 date = datetime.now()
43 period_id = self.registry('account.period').find(
44 self.cr, self.uid, date,
45 context={'account_period_prefer_normal': True})[0]
46 move_vals = {
47 'journal_id': self.ref('account.sales_journal'),
48 'period_id': period_id,
49 'date': date,
50 }
51 move_id = self.move_obj.create(self.cr, self.uid, move_vals)
52 move_line_id = self.move_line_obj.create(
53 self.cr, self.uid,
54 {'move_id': move_id,
55 'name': '/',
56 'debit': 0,
57 'credit': amount,
58 'account_id': self.ref('account.a_sale'),
59 'analytic_account_id':
60 self.analytic_account_id if with_analytic else False})
61 self.move_line_obj.create(
62 self.cr, self.uid,
63 {'move_id': move_id,
64 'name': '/',
65 'debit': amount,
66 'credit': 0,
67 'account_id': self.ref('account.a_recv')})
68 return move_line_id
69
70 def _set_analytic_policy(self, policy, aref='account.a_sale'):
71 account_type = self.account_obj.browse(self.cr, self.uid,
72 self.ref(aref)).user_type
73 self.account_type_obj.write(self.cr, self.uid, account_type.id,
74 {'analytic_policy': policy})
75
76 def test_optional(self):
77 self._create_move(with_analytic=False)
78 self._create_move(with_analytic=True)
79
80 def test_always_no_analytic(self):
81 self._set_analytic_policy('always')
82 with self.assertRaises(orm.except_orm):
83 self._create_move(with_analytic=False)
84
85 def test_always_no_analytic_0(self):
86 # accept missing analytic account when debit=credit=0
87 self._set_analytic_policy('always')
88 self._create_move(with_analytic=False, amount=0)
89
90 def test_always_with_analytic(self):
91 self._set_analytic_policy('always')
92 self._create_move(with_analytic=True)
93
94 def test_never_no_analytic(self):
95 self._set_analytic_policy('never')
96 self._create_move(with_analytic=False)
97
98 def test_never_with_analytic(self):
99 self._set_analytic_policy('never')
100 with self.assertRaises(orm.except_orm):
101 self._create_move(with_analytic=True)
102
103 def test_never_with_analytic_0(self):
104 # accept analytic when debit=credit=0
105 self._set_analytic_policy('never')
106 self._create_move(with_analytic=True, amount=0)
107
108 def test_always_remove_analytic(self):
109 # remove partner when policy is always
110 self._set_analytic_policy('always')
111 line_id = self._create_move(with_analytic=True)
112 with self.assertRaises(orm.except_orm):
113 self.move_line_obj.write(self.cr, self.uid, line_id,
114 {'analytic_account_id': False})
115
116 def test_change_account(self):
117 self._set_analytic_policy('always', aref='account.a_expense')
118 line_id = self._create_move(with_analytic=False)
119 # change account to a_expense with policy always but missing
120 # analytic_account
121 with self.assertRaises(orm.except_orm):
122 self.move_line_obj.write(
123 self.cr, self.uid, line_id,
124 {'account_id': self.ref('account.a_expense')})
125 # change account to a_expense with policy always
126 # with analytic account -> ok
127 self.move_line_obj.write(
128 self.cr, self.uid, line_id, {
129 'account_id': self.ref('account.a_expense'),
130 'analytic_account_id': self.analytic_account_id})

Subscribers

People subscribed via source and target branches

to status/vote changes: