From 95cae7104b1a4999eb6db92d0cfc166a9f45f940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 18 Apr 2014 14:53:38 +0200 Subject: [PATCH 1/5] [ADD] account_partner_required --- account_partner_required/__init__.py | 23 ++++ account_partner_required/__openerp__.py | 46 +++++++ account_partner_required/account.py | 96 ++++++++++++++ account_partner_required/account_view.xml | 24 ++++ account_partner_required/tests/__init__.py | 30 +++++ .../tests/test_account_partner_required.py | 120 ++++++++++++++++++ 6 files changed, 339 insertions(+) create mode 100644 account_partner_required/__init__.py create mode 100644 account_partner_required/__openerp__.py create mode 100644 account_partner_required/account.py create mode 100644 account_partner_required/account_view.xml create mode 100644 account_partner_required/tests/__init__.py create mode 100644 account_partner_required/tests/test_account_partner_required.py diff --git a/account_partner_required/__init__.py b/account_partner_required/__init__.py new file mode 100644 index 000000000..22c8fe294 --- /dev/null +++ b/account_partner_required/__init__.py @@ -0,0 +1,23 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Account partner required module for OpenERP +# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# @author Stéphane Bidoul +# +# This program 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. +# +# This program 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 this program. If not, see . +# +############################################################################## + +import account diff --git a/account_partner_required/__openerp__.py b/account_partner_required/__openerp__.py new file mode 100644 index 000000000..ed9f82592 --- /dev/null +++ b/account_partner_required/__openerp__.py @@ -0,0 +1,46 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Account partner required module for OpenERP +# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# @author Stéphane Bidoul +# +# This program 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. +# +# This program 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 this program. If not, see . +# +############################################################################## + +{ + 'name': 'Account partner required', + 'version': '0.1', + 'category': 'Generic Modules/Accounting', + 'license': 'AGPL-3', + 'description': """This module adds an option "partner policy" +on account types. + +You have the choice between 3 policies : optional (the default), +always (require a partner), and never (forbid a partner). + +This module is useful to enforce a partner on account move lines on +customer and supplier accounts. + +Module developed by Stéphane Bidoul , +inspired by Alexis de Lattre 's +account_analytic_required module. +""", + 'author': 'ACSONE SA/NV', + 'website': 'http://acsone.eu/', + 'depends': ['account'], + 'data': ['account_view.xml'], + 'installable': True, +} diff --git a/account_partner_required/account.py b/account_partner_required/account.py new file mode 100644 index 000000000..5c7053b31 --- /dev/null +++ b/account_partner_required/account.py @@ -0,0 +1,96 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Account partner required module for OpenERP +# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# @author Stéphane Bidoul +# +# This program 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. +# +# This program 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 this program. If not, see . +# +############################################################################## + +from openerp.osv import orm, fields +from openerp.tools.translate import _ + + +class account_account_type(orm.Model): + _inherit = "account.account.type" + + _columns = { + 'partner_policy': fields.selection([ + ('optional', 'Optional'), + ('always', 'Always'), + ('never', 'Never') + ], 'Policy for partner field', + help="Set the policy for the partner field : if you select " + "'Optional', the accountant is free to put a partner " + "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 partner ; if you select 'Never', " + "the accountant will get an error message if a partner " + "is present."), + } + + _defaults = { + 'partner_policy': 'optional', + } + + +class account_move_line(orm.Model): + _inherit = "account.move.line" + + def check_partner_required(self, cr, uid, ids, vals, context=None): + if 'account_id' in vals or 'partner_id' in vals or \ + 'debit' in vals or 'credit' in vals: + if isinstance(ids, (int, long)): + ids = [ids] + for move_line in self.browse(cr, uid, ids, context): + if move_line.debit == 0 and move_line.credit == 0: + continue + policy = move_line.account_id.user_type.partner_policy + if policy == 'always' and not move_line.partner_id: + raise orm.except_orm(_('Error :'), + _("Partner policy is set to 'Always' " + "with account %s '%s' but the " + "partner is missing in the account " + "move line with label '%s'." % + (move_line.account_id.code, + move_line.account_id.name, + move_line.name))) + elif policy == 'never' and move_line.partner_id: + raise orm.except_orm(_('Error :'), + _("Partner policy is set to 'Never' " + "with account %s '%s' but the " + "account move line with label '%s' " + "has a partner '%s'." % + (move_line.account_id.code, + move_line.account_id.name, + move_line.name, + move_line.partner_id.name))) + + def create(self, cr, uid, vals, context=None, check=True): + line_id = super(account_move_line, self).create(cr, uid, vals, + context=context, + check=check) + self.check_partner_required(cr, uid, line_id, vals, context=context) + return line_id + + def write(self, cr, uid, ids, vals, context=None, check=True, + update_check=True): + res = super(account_move_line, self).write(cr, uid, ids, vals, + context=context, + check=check, + update_check=update_check) + self.check_partner_required(cr, uid, ids, vals, context=context) + return res diff --git a/account_partner_required/account_view.xml b/account_partner_required/account_view.xml new file mode 100644 index 000000000..3f94ad52c --- /dev/null +++ b/account_partner_required/account_view.xml @@ -0,0 +1,24 @@ + + + + + + + + account_partner_required.account_type_form + account.account.type + + + + + + + + + + diff --git a/account_partner_required/tests/__init__.py b/account_partner_required/tests/__init__.py new file mode 100644 index 000000000..7b4043fc2 --- /dev/null +++ b/account_partner_required/tests/__init__.py @@ -0,0 +1,30 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Account partner required module for OpenERP +# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# @author Stéphane Bidoul +# +# This program 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. +# +# This program 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 this program. If not, see . +# +############################################################################## + +from . import test_account_partner_required + +fast_suite = [ +] + +checks = [ + test_account_partner_required, +] diff --git a/account_partner_required/tests/test_account_partner_required.py b/account_partner_required/tests/test_account_partner_required.py new file mode 100644 index 000000000..79af6ed0c --- /dev/null +++ b/account_partner_required/tests/test_account_partner_required.py @@ -0,0 +1,120 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Account partner required module for OpenERP +# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# @author Stéphane Bidoul +# +# This program 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. +# +# This program 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 this program. If not, see . +# +############################################################################## + +from datetime import datetime + +from openerp.tests import common +from openerp.osv import orm + + +class test_account_partner_required(common.TransactionCase): + + def setUp(self): + super(test_account_partner_required, self).setUp() + self.account_obj = self.registry('account.account') + self.account_type_obj = self.registry('account.account.type') + self.move_obj = self.registry('account.move') + self.move_line_obj = self.registry('account.move.line') + + def _create_move(self, with_partner, amount=100): + date = datetime.now() + period_id = self.registry('account.period').find(self.cr, self.uid, date, context={'account_period_prefer_normal': True})[0] + move_vals = { + 'journal_id': self.ref('account.sales_journal'), + 'period_id': period_id, + 'date': date, + } + move_id = self.move_obj.create(self.cr, self.uid, move_vals) + self.move_line_obj.create(self.cr, self.uid, + {'move_id': move_id, + 'name': '/', + 'debit': 0, + 'credit': amount, + 'account_id': self.ref('account.a_sale'), + }) + move_line_id = self.move_line_obj.create(self.cr, self.uid, + {'move_id': move_id, + 'name': '/', + 'debit': amount, + 'credit': 0, + 'account_id': self.ref('account.a_recv'), + 'partner_id': self.ref('base.res_partner_1') if with_partner else False, + }) + return move_line_id + + def _set_partner_policy(self, policy, aref='account.a_recv'): + account_type = self.account_obj.browse(self.cr, self.uid, + self.ref(aref)).user_type + self.account_type_obj.write(self.cr, self.uid, account_type.id, + {'partner_policy': policy}) + + def test_optional(self): + self._create_move(with_partner=False) + self._create_move(with_partner=True) + + def test_always_no_partner(self): + self._set_partner_policy('always') + with self.assertRaises(orm.except_orm): + self._create_move(with_partner=False) + + def test_always_no_partner_0(self): + # accept missing partner when debit=credit=0 + self._set_partner_policy('always') + self._create_move(with_partner=False, amount=0) + + def test_always_with_partner(self): + self._set_partner_policy('always') + self._create_move(with_partner=True) + + def test_never_no_partner(self): + self._set_partner_policy('never') + self._create_move(with_partner=False) + + def test_never_with_partner(self): + self._set_partner_policy('never') + with self.assertRaises(orm.except_orm): + self._create_move(with_partner=True) + + def test_never_with_partner_0(self): + # accept partner when debit=credit=0 + self._set_partner_policy('never') + self._create_move(with_partner=True, amount=0) + + def test_always_remove_partner(self): + # remove partner when policy is always + self._set_partner_policy('always') + line_id = self._create_move(with_partner=True) + with self.assertRaises(orm.except_orm): + self.move_line_obj.write(self.cr, self.uid, line_id, + {'partner_id': False}) + + def test_change_account(self): + self._set_partner_policy('always', aref='account.a_pay') + line_id = self._create_move(with_partner=False) + # change account to a_pay with policy always but missing partner + with self.assertRaises(orm.except_orm): + self.move_line_obj.write(self.cr, self.uid, line_id, + {'account_id': self.ref('account.a_pay')}) + # change account to a_pay with policy always with partner -> ok + self.move_line_obj.write(self.cr, self.uid, line_id, + {'account_id': self.ref('account.a_pay'), + 'partner_id': self.ref('base.res_partner_1')}) From 605549395a3d43b365ac201710ceb94fcd9e0802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 18 Apr 2014 15:03:11 +0200 Subject: [PATCH 2/5] flake8 --- account_partner_required/account.py | 16 ++++----- .../tests/test_account_partner_required.py | 35 ++++++++++--------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/account_partner_required/account.py b/account_partner_required/account.py index 5c7053b31..3f5d4b59c 100644 --- a/account_partner_required/account.py +++ b/account_partner_required/account.py @@ -29,9 +29,9 @@ class account_account_type(orm.Model): _columns = { 'partner_policy': fields.selection([ - ('optional', 'Optional'), - ('always', 'Always'), - ('never', 'Never') + ('optional', 'Optional'), + ('always', 'Always'), + ('never', 'Never') ], 'Policy for partner field', help="Set the policy for the partner field : if you select " "'Optional', the accountant is free to put a partner " @@ -81,16 +81,16 @@ class account_move_line(orm.Model): def create(self, cr, uid, vals, context=None, check=True): line_id = super(account_move_line, self).create(cr, uid, vals, - context=context, - check=check) + context=context, + check=check) self.check_partner_required(cr, uid, line_id, vals, context=context) return line_id def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True): res = super(account_move_line, self).write(cr, uid, ids, vals, - context=context, - check=check, - update_check=update_check) + context=context, + check=check, + update_check=update_check) self.check_partner_required(cr, uid, ids, vals, context=context) return res diff --git a/account_partner_required/tests/test_account_partner_required.py b/account_partner_required/tests/test_account_partner_required.py index 79af6ed0c..4a286a204 100644 --- a/account_partner_required/tests/test_account_partner_required.py +++ b/account_partner_required/tests/test_account_partner_required.py @@ -37,7 +37,9 @@ class test_account_partner_required(common.TransactionCase): def _create_move(self, with_partner, amount=100): date = datetime.now() - period_id = self.registry('account.period').find(self.cr, self.uid, date, context={'account_period_prefer_normal': True})[0] + period_id = self.registry('account.period').find( + self.cr, self.uid, date, + context={'account_period_prefer_normal': True})[0] move_vals = { 'journal_id': self.ref('account.sales_journal'), 'period_id': period_id, @@ -45,27 +47,26 @@ class test_account_partner_required(common.TransactionCase): } move_id = self.move_obj.create(self.cr, self.uid, move_vals) self.move_line_obj.create(self.cr, self.uid, - {'move_id': move_id, - 'name': '/', - 'debit': 0, - 'credit': amount, - 'account_id': self.ref('account.a_sale'), - }) - move_line_id = self.move_line_obj.create(self.cr, self.uid, - {'move_id': move_id, - 'name': '/', - 'debit': amount, - 'credit': 0, - 'account_id': self.ref('account.a_recv'), - 'partner_id': self.ref('base.res_partner_1') if with_partner else False, - }) + {'move_id': move_id, + 'name': '/', + 'debit': 0, + 'credit': amount, + 'account_id': self.ref('account.a_sale')}) + move_line_id = self.move_line_obj.create( + self.cr, self.uid, + {'move_id': move_id, + 'name': '/', + 'debit': amount, + 'credit': 0, + 'account_id': self.ref('account.a_recv'), + 'partner_id': self.ref('base.res_partner_1') if with_partner else False}) return move_line_id def _set_partner_policy(self, policy, aref='account.a_recv'): account_type = self.account_obj.browse(self.cr, self.uid, - self.ref(aref)).user_type + self.ref(aref)).user_type self.account_type_obj.write(self.cr, self.uid, account_type.id, - {'partner_policy': policy}) + {'partner_policy': policy}) def test_optional(self): self._create_move(with_partner=False) From ae5d9333e0b37c75745c9a8c141857749820c22d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sat, 19 Apr 2014 12:32:37 +0200 Subject: [PATCH 3/5] [IMP] add policy column in account type tree view --- account_partner_required/account_view.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/account_partner_required/account_view.xml b/account_partner_required/account_view.xml index 3f94ad52c..85d1c453c 100644 --- a/account_partner_required/account_view.xml +++ b/account_partner_required/account_view.xml @@ -1,7 +1,7 @@ @@ -20,5 +20,16 @@ + + account_partner_required.account_type_tree + account.account.type + + + + + + + + From 8cd5539c3f06c69126c8e14bbe75be6ef6e21285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sat, 19 Apr 2014 12:32:54 +0200 Subject: [PATCH 4/5] [IMP] local import --- account_partner_required/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_partner_required/__init__.py b/account_partner_required/__init__.py index 22c8fe294..5cb889309 100644 --- a/account_partner_required/__init__.py +++ b/account_partner_required/__init__.py @@ -2,7 +2,7 @@ ############################################################################## # # Account partner required module for OpenERP -# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# Copyright (C) 2014 Acsone (http://acsone.eu). # @author Stéphane Bidoul # # This program is free software: you can redistribute it and/or modify @@ -20,4 +20,4 @@ # ############################################################################## -import account +from . import account From 670e1f2b4185b9a5247dec7c843a9db76c4f3306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sat, 19 Apr 2014 12:33:10 +0200 Subject: [PATCH 5/5] [IMP] header comments --- account_partner_required/__openerp__.py | 2 +- account_partner_required/account.py | 2 +- account_partner_required/tests/__init__.py | 2 +- account_partner_required/tests/test_account_partner_required.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/account_partner_required/__openerp__.py b/account_partner_required/__openerp__.py index ed9f82592..961c36f39 100644 --- a/account_partner_required/__openerp__.py +++ b/account_partner_required/__openerp__.py @@ -2,7 +2,7 @@ ############################################################################## # # Account partner required module for OpenERP -# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# Copyright (C) 2014 Acsone (http://acsone.eu). # @author Stéphane Bidoul # # This program is free software: you can redistribute it and/or modify diff --git a/account_partner_required/account.py b/account_partner_required/account.py index 3f5d4b59c..58c1d24ff 100644 --- a/account_partner_required/account.py +++ b/account_partner_required/account.py @@ -2,7 +2,7 @@ ############################################################################## # # Account partner required module for OpenERP -# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# Copyright (C) 2014 Acsone (http://acsone.eu). # @author Stéphane Bidoul # # This program is free software: you can redistribute it and/or modify diff --git a/account_partner_required/tests/__init__.py b/account_partner_required/tests/__init__.py index 7b4043fc2..0654dbcb8 100644 --- a/account_partner_required/tests/__init__.py +++ b/account_partner_required/tests/__init__.py @@ -2,7 +2,7 @@ ############################################################################## # # Account partner required module for OpenERP -# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# Copyright (C) 2014 Acsone (http://acsone.eu). # @author Stéphane Bidoul # # This program is free software: you can redistribute it and/or modify diff --git a/account_partner_required/tests/test_account_partner_required.py b/account_partner_required/tests/test_account_partner_required.py index 4a286a204..824df11bb 100644 --- a/account_partner_required/tests/test_account_partner_required.py +++ b/account_partner_required/tests/test_account_partner_required.py @@ -2,7 +2,7 @@ ############################################################################## # # Account partner required module for OpenERP -# Copyright (C) 2014 Acsone (http://acsone.eu). All Rights Reserved +# Copyright (C) 2014 Acsone (http://acsone.eu). # @author Stéphane Bidoul # # This program is free software: you can redistribute it and/or modify