From cda5bc8b9c35acc82755f4b0ff10a208301f9fc9 Mon Sep 17 00:00:00 2001 From: gilles Date: Mon, 13 Mar 2017 14:18:36 +0100 Subject: [PATCH] [MIG] account_invoice_constraint_chronology --- .../README.rst | 58 +++++++ .../__init__.py | 29 ---- .../__manifest__.py | 59 ++------ .../model/__init__.py | 29 ---- .../model/account.py | 31 +--- .../model/account_invoice.py | 72 +++------ .../tests/__init__.py | 29 ---- .../test_account_constraint_chronology.py | 142 ++++++++---------- .../view/account_view.xml | 8 +- 9 files changed, 158 insertions(+), 299 deletions(-) create mode 100644 account_invoice_constraint_chronology/README.rst diff --git a/account_invoice_constraint_chronology/README.rst b/account_invoice_constraint_chronology/README.rst new file mode 100644 index 00000000..7ff9af8e --- /dev/null +++ b/account_invoice_constraint_chronology/README.rst @@ -0,0 +1,58 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +===================================== +Account Invoice Constraint Chronology +===================================== + +This module helps 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 + +Configuration +============= + +To configure this module, go to the menu *Accounting > Configuration > Journals > Journals* and activate the option *Check Chronology* on the relevant journals. After the installation of the module, this option will be active on *sale* and *sale refund* journals. + +Usage +===== + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/92/8.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Contributors +------------ + +* Adrien Peiffer (`Acsone SA/NV `_) +* Gilles Gilles + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/account_invoice_constraint_chronology/__init__.py b/account_invoice_constraint_chronology/__init__.py index dcf93777..d6af3144 100644 --- a/account_invoice_constraint_chronology/__init__.py +++ b/account_invoice_constraint_chronology/__init__.py @@ -1,31 +1,2 @@ -# -*- 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/__manifest__.py b/account_invoice_constraint_chronology/__manifest__.py index c6d31163..2a334a8a 100644 --- a/account_invoice_constraint_chronology/__manifest__.py +++ b/account_invoice_constraint_chronology/__manifest__.py @@ -1,60 +1,23 @@ # -*- 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 . -# -# - +# Copyright 2015-2017 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Account Invoice Constraint Chronology", - "version": "8.0.1.0.0", + "version": "10.0.1.0.0", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "maintainer": "ACSONE SA/NV", "website": "http://www.acsone.eu", "license": "AGPL-3", - "images": [], "category": "Accounting", "depends": ["account"], "description": """ -Account Invoice Constraint Chronology -===================================== - -This module helps 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). -""", + Account Invoice Constraint Chronology + This module helps 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 + """, + "test": ["../account/test/account_minimal_test.xml"], "data": ["view/account_view.xml"], - "demo": [], - "test": [], - "licence": "AGPL-3", - 'installable': False, - "auto_install": False, - "application": True, + 'installable': True, } diff --git a/account_invoice_constraint_chronology/model/__init__.py b/account_invoice_constraint_chronology/model/__init__.py index d0149654..97b1db6f 100644 --- a/account_invoice_constraint_chronology/model/__init__.py +++ b/account_invoice_constraint_chronology/model/__init__.py @@ -1,31 +1,2 @@ -# -*- 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 index 9a7d3633..3cf04a46 100644 --- a/account_invoice_constraint_chronology/model/account.py +++ b/account_invoice_constraint_chronology/model/account.py @@ -1,33 +1,8 @@ # -*- 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 . -# -# +# Copyright 2015-2017 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp import models, fields, api +from odoo import models, fields, api class account_journal(models.Model): diff --git a/account_invoice_constraint_chronology/model/account_invoice.py b/account_invoice_constraint_chronology/model/account_invoice.py index c9ac805f..4dd19daf 100644 --- a/account_invoice_constraint_chronology/model/account_invoice.py +++ b/account_invoice_constraint_chronology/model/account_invoice.py @@ -1,42 +1,16 @@ # -*- 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 . -# -# +# Copyright 2015-2017 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -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 +from odoo import models, api, fields, _ +from odoo.exceptions import UserError class account_invoice(models.Model): _inherit = "account.invoice" + already_validated = fields.Boolean(readonly=True, copy=False) + @api.multi def action_move_create(self): res = super(account_invoice, self).action_move_create() @@ -51,33 +25,31 @@ class account_invoice(models.Model): ('journal_id', '=', inv.journal_id.id)], limit=1) if len(invoices) > 0: - date_invoice_format = datetime\ - .strptime(inv.date_invoice, - DEFAULT_SERVER_DATE_FORMAT) + date_invoice_format = fields.Date.\ + from_string(inv.date_invoice) date_invoice_tz = fields\ .Date.context_today(self, date_invoice_format) - raise exceptions.Warning(_("Chronology Error." - " Please confirm older draft" - " invoices before %s and" - " try again.") % - date_invoice_tz) - - if inv.internal_number is False: + raise UserError(_("Chronology Error. " + "Please confirm older draft " + "invoices before %s and try again.") + % date_invoice_tz) + if not inv.already_validated: invoices = self.search([('state', 'in', ['open', 'paid']), ('date_invoice', '>', inv.date_invoice), ('journal_id', '=', inv.journal_id.id)], limit=1) + if len(invoices) > 0: - date_invoice_format = datetime\ - .strptime(inv.date_invoice, - DEFAULT_SERVER_DATE_FORMAT) + date_invoice_format = fields.Date.\ + from_string(inv.date_invoice) date_invoice_tz = fields\ .Date.context_today(self, date_invoice_format) - raise exceptions.Warning(_("Chronology Error. There" - " exist at least one" - " invoice with a date" - " posterior to %s.") % - date_invoice_tz) + raise UserError(_("Chronology Error. " + "There exist at least one invoice " + "with a date posterior to %s.") % + date_invoice_tz) + if not inv.already_validated: + inv.already_validated = True return res diff --git a/account_invoice_constraint_chronology/tests/__init__.py b/account_invoice_constraint_chronology/tests/__init__.py index 3dd2ee2c..1f3c5398 100644 --- a/account_invoice_constraint_chronology/tests/__init__.py +++ b/account_invoice_constraint_chronology/tests/__init__.py @@ -1,30 +1 @@ -# -*- 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 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 df5a2ed7..1781f696 100644 --- a/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py +++ b/account_invoice_constraint_chronology/tests/test_account_constraint_chronology.py @@ -1,90 +1,62 @@ # -*- 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 . -# -# +# Copyright 2015-2017 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import openerp.tests.common as common -from openerp import workflow -from openerp import exceptions +import odoo.tests.common as common +from odoo.exceptions import UserError from datetime import datetime, timedelta -from openerp.tools import DEFAULT_SERVER_DATE_FORMAT - - -def get_simple_product_id(self): - return self.env['product.product'].create({'name': 'product_test_01', - 'lst_price': 2000.00, - }) +from odoo.tools import DEFAULT_SERVER_DATE_FORMAT def get_journal_check(self, value): - sale_journal_id = self.ref('account.sales_journal') - sale_journal = self.env['account.journal'].browse([sale_journal_id]) - journal = sale_journal.copy() + sale_journal_obj = self.AccountJournal.env['account.journal'].\ + search([('type', '=', 'sale')], limit=1) + journal = sale_journal_obj.copy() journal.check_chronology = value return journal -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 = 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, - } - ) - ], - }) + invoice_account = self.env['account.account'].\ + search([('user_type_id', '=', + self.env.ref( + 'account.data_account_type_receivable' + ).id)], limit=1).id + invoice_line_account = self.env['account.account'].\ + search([('user_type_id', '=', + self.env.ref( + 'account.data_account_type_expenses' + ).id)], limit=1).id + analytic_account = self.env['account.analytic.account'].\ + create({'name': 'test account'}) + + invoice = self.env['account.invoice'].create( + {'partner_id': self.env.ref('base.res_partner_2').id, + 'account_id': invoice_account, + 'type': 'in_invoice', + 'journal_id': journal_id, + 'date_invoice': date, + 'state': 'draft', + }) + # invoice.write({'internal_number': invoice.number}) + self.env['account.invoice.line'].create( + {'product_id': self.env.ref('product.product_product_4').id, + 'quantity': 1.0, + 'price_unit': 100.0, + 'invoice_id': invoice.id, + 'name': 'product that cost 100', + 'account_id': invoice_line_account, + 'account_analytic_id': analytic_account.id, + }) + return invoice class TestAccountConstraintChronology(common.TransactionCase): def setUp(self): super(TestAccountConstraintChronology, self).setUp() - self.context = self.registry("res.users").context_get(self.cr, - self.uid) + self.AccountJournal = self.env['account.journal'] + self.Account = self.env['account.account'] def test_invoice_draft(self): journal = get_journal_check(self, True) @@ -94,23 +66,26 @@ 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(exceptions.Warning, workflow.trg_validate, self.uid, - 'account.invoice', invoice_2.id, 'invoice_open', - self.cr) + self.assertTrue((invoice_2.state == 'draft'), + "Initial invoice state is not Draft") + with self.assertRaises(UserError): + invoice_2.action_invoice_open() def test_invoice_validate(self): 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) - workflow.trg_validate(self.uid, 'account.invoice', invoice.id, - 'invoice_open', self.cr) + date_tomorrow = tomorrow.strftime(DEFAULT_SERVER_DATE_FORMAT) + invoice_1 = create_simple_invoice(self, journal.id, date_tomorrow) + self.assertTrue((invoice_1.state == 'draft'), + "Initial invoice state is not Draft") + invoice_1.action_invoice_open() date = today.strftime(DEFAULT_SERVER_DATE_FORMAT) 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) + self.assertTrue((invoice_2.state == 'draft'), + "Initial invoice state is not Draft") + with self.assertRaises(UserError): + invoice_2.action_invoice_open() def test_invoice_without_date(self): journal = get_journal_check(self, True) @@ -119,6 +94,7 @@ 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(exceptions.Warning, workflow.trg_validate, self.uid, - 'account.invoice', invoice_2.id, 'invoice_open', - self.cr) + self.assertTrue((invoice_2.state == 'draft'), + "Initial invoice state is not Draft") + with self.assertRaises(UserError): + invoice_2.action_invoice_open() diff --git a/account_invoice_constraint_chronology/view/account_view.xml b/account_invoice_constraint_chronology/view/account_view.xml index 1fc86dfe..95baf1ee 100644 --- a/account_invoice_constraint_chronology/view/account_view.xml +++ b/account_invoice_constraint_chronology/view/account_view.xml @@ -1,15 +1,17 @@ - + + account.journal.form (account_constraint_chronology) account.journal - + - +