From c8112c2a15b779e5e22b4c9d55164542b2255530 Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Thu, 7 Aug 2014 12:58:07 +0200 Subject: [PATCH 01/13] [ADD] Add account_invoice_constraint_chronology --- .../__init__.py | 31 ++++ .../__openerp__.py | 60 ++++++++ .../model/__init__.py | 31 ++++ .../model/account.py | 47 +++++++ .../model/account_invoice.py | 69 +++++++++ .../tests/__init__.py | 38 +++++ .../test_account_constraint_chronology.py | 133 ++++++++++++++++++ .../view/account_view.xml | 18 +++ 8 files changed, 427 insertions(+) create mode 100644 account_invoice_constraint_chronology/__init__.py create mode 100644 account_invoice_constraint_chronology/__openerp__.py create mode 100644 account_invoice_constraint_chronology/model/__init__.py create mode 100644 account_invoice_constraint_chronology/model/account.py create mode 100644 account_invoice_constraint_chronology/model/account_invoice.py create mode 100644 account_invoice_constraint_chronology/tests/__init__.py create mode 100644 account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py create mode 100644 account_invoice_constraint_chronology/view/account_view.xml diff --git a/account_invoice_constraint_chronology/__init__.py b/account_invoice_constraint_chronology/__init__.py new file mode 100644 index 000000000..dcf937772 --- /dev/null +++ b/account_invoice_constraint_chronology/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Adrien Peiffer +# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# All Rights Reserved +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs. +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contact a Free Software +# Service Company. +# +# 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 model +from . import tests diff --git a/account_invoice_constraint_chronology/__openerp__.py b/account_invoice_constraint_chronology/__openerp__.py new file mode 100644 index 000000000..a69b5ee06 --- /dev/null +++ b/account_invoice_constraint_chronology/__openerp__.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Adrien Peiffer +# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# All Rights Reserved +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs. +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contact a Free Software +# Service Company. +# +# 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 Invoice Constraint Chronology", + "version": "1.0", + "author": "ACSONE SA/NV", + "maintainer": "ACSONE SA/NV", + "website": "http://www.acsone.eu", + "images": [], + "category": "Accounting", + "depends": [ + "account"], + "description": """ +Account Invoice Constraint Chronology +===================================== + +This module help ensuring the chronology of invoice numbers. + +It prevents the validation of invoices when: +* there are draft invoices with an anterior date +* there are validated invoices with a posterior date + +The check can be activated on a per-journal basis +(for sale and purchase journals). +""", + "data": ["view/account_view.xml"], + "demo": [], + "test": [], + "licence": "AGPL-3", + "installable": True, + "auto_install": False, + "application": True, +} diff --git a/account_invoice_constraint_chronology/model/__init__.py b/account_invoice_constraint_chronology/model/__init__.py new file mode 100644 index 000000000..d01496542 --- /dev/null +++ b/account_invoice_constraint_chronology/model/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Adrien Peiffer +# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# All Rights Reserved +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs. +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contact a Free Software +# Service Company. +# +# 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 account_invoice +from . import account diff --git a/account_invoice_constraint_chronology/model/account.py b/account_invoice_constraint_chronology/model/account.py new file mode 100644 index 000000000..07cc781cd --- /dev/null +++ b/account_invoice_constraint_chronology/model/account.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Adrien Peiffer +# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# All Rights Reserved +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs. +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contact a Free Software +# Service Company. +# +# 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 + + +class account_jounrnal(orm.Model): + _inherit = "account.journal" + _columns = { + 'check_chronology': fields.boolean('Check Chronology'), + } + _defaults = { + 'check_chronology': False, + } + + def on_change_type(self, cr, uid, ids, type_journal, context=None): + value = {} + if type_journal not in ['sale', 'purchase', 'sale_refund', + 'purchase_refund']: + value.update({'check_chronology': False}) + return {'value': value} diff --git a/account_invoice_constraint_chronology/model/account_invoice.py b/account_invoice_constraint_chronology/model/account_invoice.py new file mode 100644 index 000000000..63f9402c8 --- /dev/null +++ b/account_invoice_constraint_chronology/model/account_invoice.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Adrien Peiffer +# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# All Rights Reserved +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs. +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contact a Free Software +# Service Company. +# +# 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 import models, api +from openerp.tools.translate import _ + + +class account_invoice(models.Model): + _inherit = "account.invoice" + + @api.multi + def action_move_create(self): + res = super(account_invoice, self).action_move_create() + for inv in self: + if inv.journal_id.check_chronology: + invoices = \ + self.search([('state', 'not in', + ['open', 'paid', 'cancel', 'proforma']), + ('date_invoice', '!=', False), + ('date_invoice', '<', inv.date_invoice), + ('journal_id', '=', inv.journal_id.id)]) + if len(invoices) > 0: + raise models.except_orm(_('Error !'), + _("Chronology Error!" + " Please confirm older draft" + " invoices before %s and" + " try again.") % + inv.date_invoice) + + if inv.internal_number is False: + invoices = self.search([('state', 'in', ['open', 'paid']), + ('date_invoice', '>', + inv.date_invoice), + ('journal_id', '=', + inv.journal_id.id)]) + if len(invoices) > 0: + raise models.except_orm(_('Error !'), + _("Chronology Error! There" + " exist at least one invoice" + " with a date posterior" + " to %s.") % + inv.date_invoice) + return res diff --git a/account_invoice_constraint_chronology/tests/__init__.py b/account_invoice_constraint_chronology/tests/__init__.py new file mode 100644 index 000000000..cd63538c6 --- /dev/null +++ b/account_invoice_constraint_chronology/tests/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Adrien Peiffer +# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# All Rights Reserved +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs. +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contact a Free Software +# Service Company. +# +# 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_constraint_chronology + +fast_suite = [ + test_account_constraint_chronology, +] + +checks = [ + test_account_constraint_chronology, +] diff --git a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py new file mode 100644 index 000000000..c51c4e6e7 --- /dev/null +++ b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Adrien Peiffer +# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# All Rights Reserved +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs. +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly advised to contact a Free Software +# Service Company. +# +# 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 openerp.tests.common as common +from openerp import workflow +from openerp.osv import orm +from datetime import datetime, timedelta + +DB = common.DB +ADMIN_USER_ID = common.ADMIN_USER_ID + + +def get_simple_product_id(self): + return self.registry('product.product').create(self.cr, + self.uid, + {'name': 'product_test_01', + 'lst_price': 2000.00, + }, context={}) + + +def get_journal_check(self, value): + sale_journal_id = self.ref('account.sales_journal') + journal_id = self.registry('account.journal').copy(self.cr, + self.uid, + sale_journal_id, + {}, + context={}) + self.registry('account.journal').write(self.cr, + self.uid, + [journal_id], + {'check_chronology': value}, + context={}) + return journal_id + + +def get_simple_account_invoice_line_values(self, product_id): + return {'name': 'test', + 'account_id': self.ref('account.a_sale'), + 'price_unit': 2000.00, + 'quantity': 1, + 'product_id': product_id, + } + + +def create_simple_invoice(self, journal_id, date): + partner_id = self.ref('base.res_partner_2') + product_id = get_simple_product_id(self) + return self.env['account.invoice']\ + .create({'partner_id': partner_id, + 'account_id': + self.ref('account.a_recv'), + 'journal_id': + journal_id, + 'date_invoice': date, + 'invoice_line': [(0, 0, {'name': 'test', + 'account_id': + self.ref('account.a_sale'), + 'price_unit': 2000.00, + 'quantity': 1, + 'product_id': product_id, + } + ) + ], + }) + + +class TestAccountConstraintChronology(common.TransactionCase): + + def setUp(self): + super(TestAccountConstraintChronology, self).setUp() + + def test_invoice_draft(self): + journal_id = get_journal_check(self, True) + today = datetime.now() + yesterday = today - timedelta(days=1) + date = yesterday.strftime('%Y-%m-%d') + create_simple_invoice(self, journal_id, date) + date = today.strftime('%Y-%m-%d') + invoice_2 = create_simple_invoice(self, journal_id, date) + self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, + 'account.invoice', invoice_2.id, 'invoice_open', + self.cr) + + def test_invoice_validate(self): + journal_id = get_journal_check(self, True) + today = datetime.now() + tomorrow = today + timedelta(days=1) + date = tomorrow.strftime('%Y-%m-%d') + invoice = create_simple_invoice(self, journal_id, date) + workflow.trg_validate(self.uid, 'account.invoice', invoice.id, + 'invoice_open', self.cr) + date = today.strftime('%Y-%m-%d') + invoice_2 = create_simple_invoice(self, journal_id, date) + self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, + 'account.invoice', invoice_2.id, 'invoice_open', + self.cr) + + def test_invoice_without_date(self): + journal_id = get_journal_check(self, True) + today = datetime.now() + yesterday = today - timedelta(days=1) + date = yesterday.strftime('%Y-%m-%d') + create_simple_invoice(self, journal_id, date) + invoice_2 = create_simple_invoice(self, journal_id, False) + self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, + 'account.invoice', invoice_2.id, 'invoice_open', + self.cr) diff --git a/account_invoice_constraint_chronology/view/account_view.xml b/account_invoice_constraint_chronology/view/account_view.xml new file mode 100644 index 000000000..892ef81b9 --- /dev/null +++ b/account_invoice_constraint_chronology/view/account_view.xml @@ -0,0 +1,18 @@ + + + + + account.journal.form (account_constraint_chronology) + account.journal + + + + + + + on_change_type(type) + + + + + \ No newline at end of file From 726387915cbaf896126110a7831ebc09774ca3a7 Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Thu, 14 Aug 2014 09:52:19 +0200 Subject: [PATCH 02/13] [IMP] Use new API on account_invoice_constraint_chronology for account.py --- .../model/account.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/account_invoice_constraint_chronology/model/account.py b/account_invoice_constraint_chronology/model/account.py index 07cc781cd..5a03f336d 100644 --- a/account_invoice_constraint_chronology/model/account.py +++ b/account_invoice_constraint_chronology/model/account.py @@ -27,19 +27,16 @@ # # -from openerp.osv import orm, fields +from openerp import models, fields, api -class account_jounrnal(orm.Model): - _inherit = "account.journal" - _columns = { - 'check_chronology': fields.boolean('Check Chronology'), - } - _defaults = { - 'check_chronology': False, - } +class account_jounrnal(models.Model): + _inherit = ['account.journal'] - def on_change_type(self, cr, uid, ids, type_journal, context=None): + check_chronology = fields.Boolean(string='Check Chronology', default=False) + + @api.multi + def on_change_type(self, type_journal, context=None): value = {} if type_journal not in ['sale', 'purchase', 'sale_refund', 'purchase_refund']: From 9e2f2c41ea058efc5ab884e7f89e0a00d5c2ffa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Thu, 14 Aug 2014 13:22:55 +0200 Subject: [PATCH 03/13] [IMP] account_inv/account_invoice_constraint_chronology doc spelling --- account_invoice_constraint_chronology/__openerp__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/account_invoice_constraint_chronology/__openerp__.py b/account_invoice_constraint_chronology/__openerp__.py index a69b5ee06..46a44738b 100644 --- a/account_invoice_constraint_chronology/__openerp__.py +++ b/account_invoice_constraint_chronology/__openerp__.py @@ -35,13 +35,12 @@ "website": "http://www.acsone.eu", "images": [], "category": "Accounting", - "depends": [ - "account"], + "depends": ["account"], "description": """ Account Invoice Constraint Chronology ===================================== -This module help ensuring the chronology of invoice numbers. +This module helps ensuring the chronology of invoice numbers. It prevents the validation of invoices when: * there are draft invoices with an anterior date From 2a35a7ecf3982456ba497e965f6c9e046638f70b Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Mon, 18 Aug 2014 11:06:23 +0200 Subject: [PATCH 04/13] [IMP] Exclude proforma2 state for draft invoice check on account_invoice_constraint_chronology --- account_invoice_constraint_chronology/model/account_invoice.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/account_invoice_constraint_chronology/model/account_invoice.py b/account_invoice_constraint_chronology/model/account_invoice.py index 63f9402c8..572bd0f7e 100644 --- a/account_invoice_constraint_chronology/model/account_invoice.py +++ b/account_invoice_constraint_chronology/model/account_invoice.py @@ -41,7 +41,8 @@ class account_invoice(models.Model): if inv.journal_id.check_chronology: invoices = \ self.search([('state', 'not in', - ['open', 'paid', 'cancel', 'proforma']), + ['open', 'paid', 'cancel', 'proforma', + 'proforma2']), ('date_invoice', '!=', False), ('date_invoice', '<', inv.date_invoice), ('journal_id', '=', inv.journal_id.id)]) From 44ca0299b7890c9d6c9096eeb073c0865404482a Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Mon, 18 Aug 2014 11:14:32 +0200 Subject: [PATCH 05/13] [IMP] DEFAULT_SERVER_DATE_FORMAT --- .../tests/test_account_constraint_chronology.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py index c51c4e6e7..bf97d0a81 100644 --- a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py +++ b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py @@ -31,6 +31,7 @@ import openerp.tests.common as common from openerp import workflow from openerp.osv import orm from datetime import datetime, timedelta +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT DB = common.DB ADMIN_USER_ID = common.ADMIN_USER_ID @@ -99,9 +100,9 @@ class TestAccountConstraintChronology(common.TransactionCase): journal_id = get_journal_check(self, True) today = datetime.now() yesterday = today - timedelta(days=1) - date = yesterday.strftime('%Y-%m-%d') + date = yesterday.strftime(DEFAULT_SERVER_DATE_FORMAT) create_simple_invoice(self, journal_id, date) - date = today.strftime('%Y-%m-%d') + date = today.strftime(DEFAULT_SERVER_DATE_FORMAT) invoice_2 = create_simple_invoice(self, journal_id, date) self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', @@ -111,11 +112,11 @@ class TestAccountConstraintChronology(common.TransactionCase): journal_id = get_journal_check(self, True) today = datetime.now() tomorrow = today + timedelta(days=1) - date = tomorrow.strftime('%Y-%m-%d') + date = tomorrow.strftime(DEFAULT_SERVER_DATE_FORMAT) invoice = create_simple_invoice(self, journal_id, date) workflow.trg_validate(self.uid, 'account.invoice', invoice.id, 'invoice_open', self.cr) - date = today.strftime('%Y-%m-%d') + date = today.strftime(DEFAULT_SERVER_DATE_FORMAT) invoice_2 = create_simple_invoice(self, journal_id, date) self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', @@ -125,7 +126,7 @@ class TestAccountConstraintChronology(common.TransactionCase): journal_id = get_journal_check(self, True) today = datetime.now() yesterday = today - timedelta(days=1) - date = yesterday.strftime('%Y-%m-%d') + date = yesterday.strftime(DEFAULT_SERVER_DATE_FORMAT) create_simple_invoice(self, journal_id, date) invoice_2 = create_simple_invoice(self, journal_id, False) self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, From 6b90e76d73b516e51e24a5b661f238397d9ddcaa Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Tue, 19 Aug 2014 17:09:23 +0200 Subject: [PATCH 06/13] [IMP] display formatted date with context timezone in exception popup for account_invoice_constraint_chronology addons --- .../model/account_invoice.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/account_invoice_constraint_chronology/model/account_invoice.py b/account_invoice_constraint_chronology/model/account_invoice.py index 572bd0f7e..b964b13e9 100644 --- a/account_invoice_constraint_chronology/model/account_invoice.py +++ b/account_invoice_constraint_chronology/model/account_invoice.py @@ -27,8 +27,10 @@ # # -from openerp import models, api +from openerp import models, api, fields from openerp.tools.translate import _ +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT +from datetime import datetime class account_invoice(models.Model): @@ -47,12 +49,17 @@ class account_invoice(models.Model): ('date_invoice', '<', inv.date_invoice), ('journal_id', '=', inv.journal_id.id)]) if len(invoices) > 0: + date_invoice_format = datetime\ + .strptime(inv.date_invoice, + DEFAULT_SERVER_DATE_FORMAT) + date_invoice_tz = fields\ + .Date.context_today(self, date_invoice_format) raise models.except_orm(_('Error !'), _("Chronology Error!" " Please confirm older draft" " invoices before %s and" " try again.") % - inv.date_invoice) + date_invoice_tz) if inv.internal_number is False: invoices = self.search([('state', 'in', ['open', 'paid']), @@ -61,10 +68,15 @@ class account_invoice(models.Model): ('journal_id', '=', inv.journal_id.id)]) if len(invoices) > 0: + date_invoice_format = datetime\ + .strptime(inv.date_invoice, + DEFAULT_SERVER_DATE_FORMAT) + date_invoice_tz = fields\ + .Date.context_today(self, date_invoice_format) raise models.except_orm(_('Error !'), _("Chronology Error! There" " exist at least one invoice" " with a date posterior" " to %s.") % - inv.date_invoice) + date_invoice_tz) return res From 5f456b5e6baa0ed73a113364e075eed990531c29 Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Tue, 19 Aug 2014 17:10:52 +0200 Subject: [PATCH 07/13] [ADD] Add context in tests for account_invoice_constraint_chronology addons --- .../tests/test_account_constraint_chronology.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py index bf97d0a81..8c7c4f366 100644 --- a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py +++ b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py @@ -42,7 +42,7 @@ def get_simple_product_id(self): self.uid, {'name': 'product_test_01', 'lst_price': 2000.00, - }, context={}) + }, context=self.context) def get_journal_check(self, value): @@ -50,13 +50,13 @@ def get_journal_check(self, value): journal_id = self.registry('account.journal').copy(self.cr, self.uid, sale_journal_id, - {}, - context={}) + self.context, + context=self.context) self.registry('account.journal').write(self.cr, self.uid, [journal_id], {'check_chronology': value}, - context={}) + context=self.context) return journal_id @@ -95,6 +95,8 @@ class TestAccountConstraintChronology(common.TransactionCase): def setUp(self): super(TestAccountConstraintChronology, self).setUp() + self.context = self.registry("res.users").context_get(self.cr, + self.uid) def test_invoice_draft(self): journal_id = get_journal_check(self, True) From beb35f9df6d769eeb5f85cc963d78a7bc5d418b4 Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Wed, 20 Aug 2014 11:24:05 +0200 Subject: [PATCH 08/13] [IMP] Use exceptions.warning for account_invoice_constraint_chronology addons --- .../model/account_invoice.py | 23 +++++++++---------- .../test_account_constraint_chronology.py | 8 +++---- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/account_invoice_constraint_chronology/model/account_invoice.py b/account_invoice_constraint_chronology/model/account_invoice.py index b964b13e9..63b8e454f 100644 --- a/account_invoice_constraint_chronology/model/account_invoice.py +++ b/account_invoice_constraint_chronology/model/account_invoice.py @@ -31,6 +31,7 @@ from openerp import models, api, fields from openerp.tools.translate import _ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT from datetime import datetime +from openerp import exceptions class account_invoice(models.Model): @@ -54,12 +55,11 @@ class account_invoice(models.Model): DEFAULT_SERVER_DATE_FORMAT) date_invoice_tz = fields\ .Date.context_today(self, date_invoice_format) - raise models.except_orm(_('Error !'), - _("Chronology Error!" - " Please confirm older draft" - " invoices before %s and" - " try again.") % - date_invoice_tz) + raise exceptions.Warning(_("Chronology Error!" + " Please confirm older draft" + " invoices before %s and" + " try again.") % + date_invoice_tz) if inv.internal_number is False: invoices = self.search([('state', 'in', ['open', 'paid']), @@ -73,10 +73,9 @@ class account_invoice(models.Model): DEFAULT_SERVER_DATE_FORMAT) date_invoice_tz = fields\ .Date.context_today(self, date_invoice_format) - raise models.except_orm(_('Error !'), - _("Chronology Error! There" - " exist at least one invoice" - " with a date posterior" - " to %s.") % - date_invoice_tz) + raise exceptions.Warning(_("Chronology Error! There" + " exist at least one" + " invoice with a date" + " posterior to %s.") % + date_invoice_tz) return res diff --git a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py index 8c7c4f366..04cf60091 100644 --- a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py +++ b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py @@ -29,7 +29,7 @@ import openerp.tests.common as common from openerp import workflow -from openerp.osv import orm +from openerp import exceptions from datetime import datetime, timedelta from openerp.tools import DEFAULT_SERVER_DATE_FORMAT @@ -106,7 +106,7 @@ class TestAccountConstraintChronology(common.TransactionCase): create_simple_invoice(self, journal_id, date) date = today.strftime(DEFAULT_SERVER_DATE_FORMAT) invoice_2 = create_simple_invoice(self, journal_id, date) - self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, + self.assertRaises(exceptions.Warning, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', self.cr) @@ -120,7 +120,7 @@ class TestAccountConstraintChronology(common.TransactionCase): 'invoice_open', self.cr) date = today.strftime(DEFAULT_SERVER_DATE_FORMAT) invoice_2 = create_simple_invoice(self, journal_id, date) - self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, + self.assertRaises(exceptions.Warning, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', self.cr) @@ -131,6 +131,6 @@ class TestAccountConstraintChronology(common.TransactionCase): date = yesterday.strftime(DEFAULT_SERVER_DATE_FORMAT) create_simple_invoice(self, journal_id, date) invoice_2 = create_simple_invoice(self, journal_id, False) - self.assertRaises(orm.except_orm, workflow.trg_validate, self.uid, + self.assertRaises(exceptions.Warning, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', self.cr) From 077244ddb20db9b44eac84f2ec8b8c5abaa97896 Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Wed, 20 Aug 2014 11:57:29 +0200 Subject: [PATCH 09/13] [IMP] Remove exclamation mark --- .../model/account_invoice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_invoice_constraint_chronology/model/account_invoice.py b/account_invoice_constraint_chronology/model/account_invoice.py index 63b8e454f..27034925d 100644 --- a/account_invoice_constraint_chronology/model/account_invoice.py +++ b/account_invoice_constraint_chronology/model/account_invoice.py @@ -55,7 +55,7 @@ class account_invoice(models.Model): DEFAULT_SERVER_DATE_FORMAT) date_invoice_tz = fields\ .Date.context_today(self, date_invoice_format) - raise exceptions.Warning(_("Chronology Error!" + raise exceptions.Warning(_("Chronology Error." " Please confirm older draft" " invoices before %s and" " try again.") % @@ -73,7 +73,7 @@ class account_invoice(models.Model): DEFAULT_SERVER_DATE_FORMAT) date_invoice_tz = fields\ .Date.context_today(self, date_invoice_format) - raise exceptions.Warning(_("Chronology Error! There" + raise exceptions.Warning(_("Chronology Error. There" " exist at least one" " invoice with a date" " posterior to %s.") % From ac653fc086beeaf9b1a00238792058e8cb64751a Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Wed, 20 Aug 2014 16:54:57 +0200 Subject: [PATCH 10/13] [ADD] Add .pot file for account_invoice_constraint_chronology --- .../account_invoice_constraint_chronology.pot | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 account_invoice_constraint_chronology/i18n/account_invoice_constraint_chronology.pot diff --git a/account_invoice_constraint_chronology/i18n/account_invoice_constraint_chronology.pot b/account_invoice_constraint_chronology/i18n/account_invoice_constraint_chronology.pot new file mode 100644 index 000000000..c13b71e5f --- /dev/null +++ b/account_invoice_constraint_chronology/i18n/account_invoice_constraint_chronology.pot @@ -0,0 +1,44 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_invoice_constraint_chronology +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0rc1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-08-20 14:51+0000\n" +"PO-Revision-Date: 2014-08-20 14:51+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_invoice_constraint_chronology +#: field:account.journal,check_chronology:0 +msgid "Check Chronology" +msgstr "" + +#. module: account_invoice_constraint_chronology +#: code:addons/account_invoice_constraint_chronology/model/account_invoice.py:58 +#, python-format +msgid "Chronology Error. Please confirm older draft invoices before %s and try again." +msgstr "" + +#. module: account_invoice_constraint_chronology +#: code:addons/account_invoice_constraint_chronology/model/account_invoice.py:76 +#, python-format +msgid "Chronology Error. There exist at least one invoice with a date posterior to %s." +msgstr "" + +#. module: account_invoice_constraint_chronology +#: model:ir.model,name:account_invoice_constraint_chronology.model_account_invoice +msgid "Invoice" +msgstr "" + +#. module: account_invoice_constraint_chronology +#: model:ir.model,name:account_invoice_constraint_chronology.model_account_journal +msgid "Journal" +msgstr "" + From 2b14fc25dbf8ea1e83a958ae72da37e4a1bbac23 Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Fri, 5 Sep 2014 13:22:10 +0200 Subject: [PATCH 11/13] [IMP] Use .env for account_invoice_constraint_chronology tests --- .../test_account_constraint_chronology.py | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py index 04cf60091..70895831e 100644 --- a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py +++ b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py @@ -38,26 +38,17 @@ ADMIN_USER_ID = common.ADMIN_USER_ID def get_simple_product_id(self): - return self.registry('product.product').create(self.cr, - self.uid, - {'name': 'product_test_01', - 'lst_price': 2000.00, - }, context=self.context) + return self.env['product.product'].create({'name': 'product_test_01', + 'lst_price': 2000.00, + }) def get_journal_check(self, value): sale_journal_id = self.ref('account.sales_journal') - journal_id = self.registry('account.journal').copy(self.cr, - self.uid, - sale_journal_id, - self.context, - context=self.context) - self.registry('account.journal').write(self.cr, - self.uid, - [journal_id], - {'check_chronology': value}, - context=self.context) - return journal_id + sale_journal = self.env['account.journal'].browse([sale_journal_id]) + journal = sale_journal.copy() + journal.check_chronology = value + return journal def get_simple_account_invoice_line_values(self, product_id): @@ -71,7 +62,7 @@ def get_simple_account_invoice_line_values(self, product_id): def create_simple_invoice(self, journal_id, date): partner_id = self.ref('base.res_partner_2') - product_id = get_simple_product_id(self) + product = get_simple_product_id(self) return self.env['account.invoice']\ .create({'partner_id': partner_id, 'account_id': @@ -84,7 +75,7 @@ def create_simple_invoice(self, journal_id, date): self.ref('account.a_sale'), 'price_unit': 2000.00, 'quantity': 1, - 'product_id': product_id, + 'product_id': product.id, } ) ], @@ -99,38 +90,38 @@ class TestAccountConstraintChronology(common.TransactionCase): self.uid) def test_invoice_draft(self): - journal_id = get_journal_check(self, True) + journal = get_journal_check(self, True) today = datetime.now() yesterday = today - timedelta(days=1) date = yesterday.strftime(DEFAULT_SERVER_DATE_FORMAT) - create_simple_invoice(self, journal_id, date) + create_simple_invoice(self, journal.id, date) date = today.strftime(DEFAULT_SERVER_DATE_FORMAT) - invoice_2 = create_simple_invoice(self, journal_id, date) + invoice_2 = create_simple_invoice(self, journal.id, date) self.assertRaises(exceptions.Warning, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', self.cr) def test_invoice_validate(self): - journal_id = get_journal_check(self, True) + journal = get_journal_check(self, True) today = datetime.now() tomorrow = today + timedelta(days=1) date = tomorrow.strftime(DEFAULT_SERVER_DATE_FORMAT) - invoice = create_simple_invoice(self, journal_id, date) + invoice = create_simple_invoice(self, journal.id, date) workflow.trg_validate(self.uid, 'account.invoice', invoice.id, 'invoice_open', self.cr) date = today.strftime(DEFAULT_SERVER_DATE_FORMAT) - invoice_2 = create_simple_invoice(self, journal_id, date) + invoice_2 = create_simple_invoice(self, journal.id, date) self.assertRaises(exceptions.Warning, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', self.cr) def test_invoice_without_date(self): - journal_id = get_journal_check(self, True) + journal = get_journal_check(self, True) today = datetime.now() yesterday = today - timedelta(days=1) date = yesterday.strftime(DEFAULT_SERVER_DATE_FORMAT) - create_simple_invoice(self, journal_id, date) - invoice_2 = create_simple_invoice(self, journal_id, False) + create_simple_invoice(self, journal.id, date) + invoice_2 = create_simple_invoice(self, journal.id, False) self.assertRaises(exceptions.Warning, workflow.trg_validate, self.uid, 'account.invoice', invoice_2.id, 'invoice_open', self.cr) From a8f38d3bbe112c89ad9a13e925816538bab8f0da Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Fri, 5 Sep 2014 13:27:13 +0200 Subject: [PATCH 12/13] [IMP] Use onchange decorator, add white space at end of file, correct ypo mistake for account_invoice_constraint_chronology --- .../model/account.py | 16 ++++++++-------- .../view/account_view.xml | 5 +---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/account_invoice_constraint_chronology/model/account.py b/account_invoice_constraint_chronology/model/account.py index 5a03f336d..9a7d36337 100644 --- a/account_invoice_constraint_chronology/model/account.py +++ b/account_invoice_constraint_chronology/model/account.py @@ -30,15 +30,15 @@ from openerp import models, fields, api -class account_jounrnal(models.Model): +class account_journal(models.Model): _inherit = ['account.journal'] check_chronology = fields.Boolean(string='Check Chronology', default=False) - @api.multi - def on_change_type(self, type_journal, context=None): - value = {} - if type_journal not in ['sale', 'purchase', 'sale_refund', - 'purchase_refund']: - value.update({'check_chronology': False}) - return {'value': value} + @api.one + @api.onchange('type') + def on_change_type(self): + if self.type not in ['sale', 'purchase', 'sale_refund', + 'purchase_refund']: + self.check_chronology = False + return True diff --git a/account_invoice_constraint_chronology/view/account_view.xml b/account_invoice_constraint_chronology/view/account_view.xml index 892ef81b9..1fc86dfe7 100644 --- a/account_invoice_constraint_chronology/view/account_view.xml +++ b/account_invoice_constraint_chronology/view/account_view.xml @@ -9,10 +9,7 @@ - - on_change_type(type) - - \ No newline at end of file + From 5cbcfac304d4721dd0b26fc8210f6453cf822beb Mon Sep 17 00:00:00 2001 From: Adrien Peiffer Date: Mon, 15 Sep 2014 10:25:17 +0200 Subject: [PATCH 13/13] [IMP] Improve performance --- .../model/account_invoice.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/account_invoice_constraint_chronology/model/account_invoice.py b/account_invoice_constraint_chronology/model/account_invoice.py index 27034925d..c9ac805f5 100644 --- a/account_invoice_constraint_chronology/model/account_invoice.py +++ b/account_invoice_constraint_chronology/model/account_invoice.py @@ -48,7 +48,8 @@ class account_invoice(models.Model): 'proforma2']), ('date_invoice', '!=', False), ('date_invoice', '<', inv.date_invoice), - ('journal_id', '=', inv.journal_id.id)]) + ('journal_id', '=', inv.journal_id.id)], + limit=1) if len(invoices) > 0: date_invoice_format = datetime\ .strptime(inv.date_invoice, @@ -66,7 +67,8 @@ class account_invoice(models.Model): ('date_invoice', '>', inv.date_invoice), ('journal_id', '=', - inv.journal_id.id)]) + inv.journal_id.id)], + limit=1) if len(invoices) > 0: date_invoice_format = datetime\ .strptime(inv.date_invoice,