Merge lp:~acsone-openerp/account-financial-tools/account_partner_required-sbi into lp:~account-core-editors/account-financial-tools/7.0

Proposed by Stéphane Bidoul (Acsone)
Status: Merged
Merged at revision: 188
Proposed branch: lp:~acsone-openerp/account-financial-tools/account_partner_required-sbi
Merge into: lp:~account-core-editors/account-financial-tools/7.0
Diff against target: 382 lines (+351/-0)
6 files modified
account_partner_required/__init__.py (+23/-0)
account_partner_required/__openerp__.py (+46/-0)
account_partner_required/account.py (+96/-0)
account_partner_required/account_view.xml (+35/-0)
account_partner_required/tests/__init__.py (+30/-0)
account_partner_required/tests/test_account_partner_required.py (+121/-0)
To merge this branch: bzr merge lp:~acsone-openerp/account-financial-tools/account_partner_required-sbi
Reviewer Review Type Date Requested Status
Omar (Pexego) code review Approve
Joël Grand-Guillaume @ camptocamp code review, no tests Approve
Lorenzo Battistini (community) code review Approve
Frederic Clementi - Camptocamp Pending
Review via email: mp+216442@code.launchpad.net

Description of the change

New module to control the partner field in account move lines.

In many cases, it is desirable to enforce the presence of the
partner field in account move lines, but not always.

This module provides such a mechanism based on the account user type.

Cfr mailing list discussion for reference.

[1] https://lists.launchpad.net/openerp-community/msg05502.html

To post a comment you must log in.
175. By Stéphane Bidoul (Acsone)

[IMP] add policy column in account type tree view

176. By Stéphane Bidoul (Acsone)

[IMP] local import

177. By Stéphane Bidoul (Acsone)

[IMP] header comments

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Hello Stéphane,

why not using '_constraints' member instead of overriding create and write methods?

Is there any technical reason to avoid YAML tests?

Thanks!

review: Needs Information
Revision history for this message
Stéphane Bidoul (Acsone) (sbi) wrote :

Hello Lorenzo,

About the constraints. This module is heavily inspired by account_analytic_required which used the same technique. I must confess I did not question the approach. Initially account_analytic_required was working mainly on the vals dictionary so it would have been faster than constraints. While working on account_partner_required I identified a bug in account_analytic_required which required a refactoring [1] which possibly rendered the optimization less obvious. Now since there are really two constraints to be checked based on the policy, the current approach is probably still slightly faster.

Would you agree to keep the current approach and postpone a possible performance test / refactoring with constraints to another MP?

Regarding yml vs unittest, it's only a matter of personal taste in this case. I notice the unittest2 framework seems better documented [2]. But hey, at least I have tests, right :)

[1] https://code.launchpad.net/~acsone-openerp/account-analytic/account_analytic_required-test_suite-sbi
[2] https://doc.openerp.com/trunk/server/05_test_framework/

Revision history for this message
Lorenzo Battistini (elbati) wrote :

Ok :-)

review: Approve (code review)
Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote :

Hi Stéphane,

Thanks for the contrib, and as usual, thanks for providing tests :)

LGMT,

Regards,

Joël

review: Approve (code review, no tests)
Revision history for this message
Omar (Pexego) (omar7r) wrote :

LGTM

review: Approve (code review)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'account_partner_required'
=== added file 'account_partner_required/__init__.py'
--- account_partner_required/__init__.py 1970-01-01 00:00:00 +0000
+++ account_partner_required/__init__.py 2014-04-19 10:33:22 +0000
@@ -0,0 +1,23 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Account partner required module for OpenERP
5# Copyright (C) 2014 Acsone (http://acsone.eu).
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 account
024
=== added file 'account_partner_required/__openerp__.py'
--- account_partner_required/__openerp__.py 1970-01-01 00:00:00 +0000
+++ account_partner_required/__openerp__.py 2014-04-19 10:33:22 +0000
@@ -0,0 +1,46 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Account partner required module for OpenERP
5# Copyright (C) 2014 Acsone (http://acsone.eu).
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
23{
24 'name': 'Account partner required',
25 'version': '0.1',
26 'category': 'Generic Modules/Accounting',
27 'license': 'AGPL-3',
28 'description': """This module adds an option "partner policy"
29on account types.
30
31You have the choice between 3 policies : optional (the default),
32always (require a partner), and never (forbid a partner).
33
34This module is useful to enforce a partner on account move lines on
35customer and supplier accounts.
36
37Module developed by Stéphane Bidoul <stephane.bidoul@acsone.eu>,
38inspired by Alexis de Lattre <alexis.delattre@akretion.com>'s
39account_analytic_required module.
40""",
41 'author': 'ACSONE SA/NV',
42 'website': 'http://acsone.eu/',
43 'depends': ['account'],
44 'data': ['account_view.xml'],
45 'installable': True,
46}
047
=== added file 'account_partner_required/account.py'
--- account_partner_required/account.py 1970-01-01 00:00:00 +0000
+++ account_partner_required/account.py 2014-04-19 10:33:22 +0000
@@ -0,0 +1,96 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Account partner required module for OpenERP
5# Copyright (C) 2014 Acsone (http://acsone.eu).
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 openerp.osv import orm, fields
24from openerp.tools.translate import _
25
26
27class account_account_type(orm.Model):
28 _inherit = "account.account.type"
29
30 _columns = {
31 'partner_policy': fields.selection([
32 ('optional', 'Optional'),
33 ('always', 'Always'),
34 ('never', 'Never')
35 ], 'Policy for partner field',
36 help="Set the policy for the partner field : if you select "
37 "'Optional', the accountant is free to put a partner "
38 "on an account move line with this type of account ; "
39 "if you select 'Always', the accountant will get an error "
40 "message if there is no partner ; if you select 'Never', "
41 "the accountant will get an error message if a partner "
42 "is present."),
43 }
44
45 _defaults = {
46 'partner_policy': 'optional',
47 }
48
49
50class account_move_line(orm.Model):
51 _inherit = "account.move.line"
52
53 def check_partner_required(self, cr, uid, ids, vals, context=None):
54 if 'account_id' in vals or 'partner_id' in vals or \
55 'debit' in vals or 'credit' in vals:
56 if isinstance(ids, (int, long)):
57 ids = [ids]
58 for move_line in self.browse(cr, uid, ids, context):
59 if move_line.debit == 0 and move_line.credit == 0:
60 continue
61 policy = move_line.account_id.user_type.partner_policy
62 if policy == 'always' and not move_line.partner_id:
63 raise orm.except_orm(_('Error :'),
64 _("Partner policy is set to 'Always' "
65 "with account %s '%s' but the "
66 "partner is missing in the account "
67 "move line with label '%s'." %
68 (move_line.account_id.code,
69 move_line.account_id.name,
70 move_line.name)))
71 elif policy == 'never' and move_line.partner_id:
72 raise orm.except_orm(_('Error :'),
73 _("Partner policy is set to 'Never' "
74 "with account %s '%s' but the "
75 "account move line with label '%s' "
76 "has a partner '%s'." %
77 (move_line.account_id.code,
78 move_line.account_id.name,
79 move_line.name,
80 move_line.partner_id.name)))
81
82 def create(self, cr, uid, vals, context=None, check=True):
83 line_id = super(account_move_line, self).create(cr, uid, vals,
84 context=context,
85 check=check)
86 self.check_partner_required(cr, uid, line_id, vals, context=context)
87 return line_id
88
89 def write(self, cr, uid, ids, vals, context=None, check=True,
90 update_check=True):
91 res = super(account_move_line, self).write(cr, uid, ids, vals,
92 context=context,
93 check=check,
94 update_check=update_check)
95 self.check_partner_required(cr, uid, ids, vals, context=context)
96 return res
097
=== added file 'account_partner_required/account_view.xml'
--- account_partner_required/account_view.xml 1970-01-01 00:00:00 +0000
+++ account_partner_required/account_view.xml 2014-04-19 10:33:22 +0000
@@ -0,0 +1,35 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3 Account partner required module for OpenERP
4 Copyright (C) 2014 Acsone (http://acsone.eu).
5 @author Stéphane Bidoul <stephane.bidoul@acsone.eu>
6 The licence is in the file __openerp__.py
7-->
8
9<openerp>
10<data>
11
12<record id="account_partner_required_account_type_form" model="ir.ui.view">
13 <field name="name">account_partner_required.account_type_form</field>
14 <field name="model">account.account.type</field>
15 <field name="inherit_id" ref="account.view_account_type_form" />
16 <field name="arch" type="xml">
17 <field name="code" position="after">
18 <field name="partner_policy" />
19 </field>
20 </field>
21</record>
22
23<record id="view_account_type_tree" model="ir.ui.view">
24 <field name="name">account_partner_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="partner_policy" />
30 </field>
31 </field>
32</record>
33
34</data>
35</openerp>
036
=== added directory 'account_partner_required/tests'
=== added file 'account_partner_required/tests/__init__.py'
--- account_partner_required/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ account_partner_required/tests/__init__.py 2014-04-19 10:33:22 +0000
@@ -0,0 +1,30 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Account partner required module for OpenERP
5# Copyright (C) 2014 Acsone (http://acsone.eu).
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_partner_required
24
25fast_suite = [
26]
27
28checks = [
29 test_account_partner_required,
30]
031
=== added file 'account_partner_required/tests/test_account_partner_required.py'
--- account_partner_required/tests/test_account_partner_required.py 1970-01-01 00:00:00 +0000
+++ account_partner_required/tests/test_account_partner_required.py 2014-04-19 10:33:22 +0000
@@ -0,0 +1,121 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# Account partner required module for OpenERP
5# Copyright (C) 2014 Acsone (http://acsone.eu).
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_partner_required(common.TransactionCase):
30
31 def setUp(self):
32 super(test_account_partner_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
38 def _create_move(self, with_partner, amount=100):
39 date = datetime.now()
40 period_id = self.registry('account.period').find(
41 self.cr, self.uid, date,
42 context={'account_period_prefer_normal': True})[0]
43 move_vals = {
44 'journal_id': self.ref('account.sales_journal'),
45 'period_id': period_id,
46 'date': date,
47 }
48 move_id = self.move_obj.create(self.cr, self.uid, move_vals)
49 self.move_line_obj.create(self.cr, self.uid,
50 {'move_id': move_id,
51 'name': '/',
52 'debit': 0,
53 'credit': amount,
54 'account_id': self.ref('account.a_sale')})
55 move_line_id = self.move_line_obj.create(
56 self.cr, self.uid,
57 {'move_id': move_id,
58 'name': '/',
59 'debit': amount,
60 'credit': 0,
61 'account_id': self.ref('account.a_recv'),
62 'partner_id': self.ref('base.res_partner_1') if with_partner else False})
63 return move_line_id
64
65 def _set_partner_policy(self, policy, aref='account.a_recv'):
66 account_type = self.account_obj.browse(self.cr, self.uid,
67 self.ref(aref)).user_type
68 self.account_type_obj.write(self.cr, self.uid, account_type.id,
69 {'partner_policy': policy})
70
71 def test_optional(self):
72 self._create_move(with_partner=False)
73 self._create_move(with_partner=True)
74
75 def test_always_no_partner(self):
76 self._set_partner_policy('always')
77 with self.assertRaises(orm.except_orm):
78 self._create_move(with_partner=False)
79
80 def test_always_no_partner_0(self):
81 # accept missing partner when debit=credit=0
82 self._set_partner_policy('always')
83 self._create_move(with_partner=False, amount=0)
84
85 def test_always_with_partner(self):
86 self._set_partner_policy('always')
87 self._create_move(with_partner=True)
88
89 def test_never_no_partner(self):
90 self._set_partner_policy('never')
91 self._create_move(with_partner=False)
92
93 def test_never_with_partner(self):
94 self._set_partner_policy('never')
95 with self.assertRaises(orm.except_orm):
96 self._create_move(with_partner=True)
97
98 def test_never_with_partner_0(self):
99 # accept partner when debit=credit=0
100 self._set_partner_policy('never')
101 self._create_move(with_partner=True, amount=0)
102
103 def test_always_remove_partner(self):
104 # remove partner when policy is always
105 self._set_partner_policy('always')
106 line_id = self._create_move(with_partner=True)
107 with self.assertRaises(orm.except_orm):
108 self.move_line_obj.write(self.cr, self.uid, line_id,
109 {'partner_id': False})
110
111 def test_change_account(self):
112 self._set_partner_policy('always', aref='account.a_pay')
113 line_id = self._create_move(with_partner=False)
114 # change account to a_pay with policy always but missing partner
115 with self.assertRaises(orm.except_orm):
116 self.move_line_obj.write(self.cr, self.uid, line_id,
117 {'account_id': self.ref('account.a_pay')})
118 # change account to a_pay with policy always with partner -> ok
119 self.move_line_obj.write(self.cr, self.uid, line_id,
120 {'account_id': self.ref('account.a_pay'),
121 'partner_id': self.ref('base.res_partner_1')})

Subscribers

People subscribed via source and target branches