diff --git a/CHANGELOG b/CHANGELOG
index e92021e1d5..ea43cf5fa2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,4 @@
+* Prevent creating fiscal year before closed one
* Add automatic reconciliation of suggestions
* Prevent to change the type of journal with posted moves
* Mute reconciled payable/receivable lines
diff --git a/fiscalyear.py b/fiscalyear.py
index 715db956a1..9208e1ce49 100644
--- a/fiscalyear.py
+++ b/fiscalyear.py
@@ -108,7 +108,7 @@ class FiscalYear(Workflow, ModelSQL, ModelView):
@classmethod
def check_dates(cls, fiscalyears, field_names=None):
if field_names and not (field_names & {
- 'start_date', 'end_date', 'company'}):
+ 'start_date', 'end_date', 'state', 'company'}):
return
transaction = Transaction()
connection = transaction.connection
@@ -132,6 +132,20 @@ class FiscalYear(Workflow, ModelSQL, ModelView):
gettext('account.msg_fiscalyear_overlap',
first=year.rec_name,
second=second.rec_name))
+ if year.state == 'open':
+ fiscalyears = cls.search([
+ ('start_date', '>=', year.end_date),
+ ('state', 'in', ['close', 'locked']),
+ ('company', '=', year.company.id),
+ ],
+ limit=1,
+ order=[('start_date', 'ASC')])
+ if fiscalyears:
+ fiscalyear, = fiscalyears
+ raise FiscalYearDatesError(
+ gettext('account.msg_open_fiscalyear_earlier',
+ open=year.rec_name,
+ close=fiscalyear.rec_name))
@classmethod
def check_post_move_sequence(cls, fiscalyears, field_names=None):
@@ -277,7 +291,8 @@ class FiscalYear(Workflow, ModelSQL, ModelView):
Account = pool.get('account.account')
Deferral = pool.get('account.account.deferral')
- # Lock period to be sure no new period will be created in between.
+ # Prevent create new fiscal year or period
+ cls.lock()
Period.lock()
deferrals = []
diff --git a/message.xml b/message.xml
index 28dc059e48..4e29843d4b 100644
--- a/message.xml
+++ b/message.xml
@@ -60,6 +60,9 @@ this repository contains the full copyright notices and license terms. -->
The fiscal years "%(first)s" and "%(second)s" overlap, you must use different dates.
+
+ The open fiscal year "%(open)s" can not be before the close fiscal year "%(closed)s".
+
The fiscal years "%(first)s" and "%(second)s" cannot have the same post move sequence, you must use different sequences.
diff --git a/tests/test_account.py b/tests/test_account.py
index 9037a20710..b649316d63 100644
--- a/tests/test_account.py
+++ b/tests/test_account.py
@@ -18,6 +18,8 @@ from trytond.tests.test_tryton import (
ModuleTestCase, doctest_checker, doctest_teardown, with_transaction)
from trytond.transaction import Transaction
+from ..exceptions import FiscalYearDatesError
+
def create_chart(company, tax=False, chart='account.account_template_root_en'):
pool = Pool()
@@ -274,6 +276,44 @@ class AccountTestCase(
for p1, p2 in zip(
fiscalyear.periods[:-1], fiscalyear.periods[1:])))
+ @with_transaction()
+ def test_open_fiscalyear_before_open(self):
+ "Test create open fiscal year before an open one"
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2022, 1, 1),
+ end_date=datetime.date(2022, 12, 31))
+ fiscalyear.save()
+
+ earlier_fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2021, 1, 1),
+ end_date=datetime.date(2021, 12, 31))
+ earlier_fiscalyear.save()
+
+ @with_transaction()
+ def test_open_fiscalyear_before_close(self):
+ "Test create open fiscal year before a close one"
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2022, 1, 1),
+ end_date=datetime.date(2022, 12, 31))
+ fiscalyear.save()
+ close_fiscalyear(fiscalyear)
+
+ earlier_fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2021, 1, 1),
+ end_date=datetime.date(2021, 12, 31))
+ with self.assertRaises(FiscalYearDatesError):
+ earlier_fiscalyear.save()
+
@with_transaction()
def test_account_debit_credit(self):
'Test account debit/credit'