Use SQL constraint to enforce unique usage of post move sequence
This commit is contained in:
@@ -21,22 +21,10 @@ class PeriodDatesError(PeriodValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class PeriodSequenceError(PeriodValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class FiscalYearNotFoundError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
class FiscalYearValidationError(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class FiscalYearSequenceError(FiscalYearValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class FiscalYearCloseError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ from sql.operators import Equal, NotEqual
|
||||
|
||||
from trytond.cache import Cache
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import Exclude, ModelSQL, ModelView, Workflow, fields
|
||||
from trytond.model import (
|
||||
Exclude, ModelSQL, ModelView, Unique, Workflow, fields)
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Eval, Id
|
||||
@@ -20,8 +21,7 @@ from trytond.wizard import (
|
||||
Button, StateAction, StateTransition, StateView, Wizard)
|
||||
|
||||
from .exceptions import (
|
||||
FiscalYearCloseError, FiscalYearNotFoundError, FiscalYearReOpenError,
|
||||
FiscalYearSequenceError)
|
||||
FiscalYearCloseError, FiscalYearNotFoundError, FiscalYearReOpenError)
|
||||
|
||||
STATES = {
|
||||
'readonly': Eval('state') != 'open',
|
||||
@@ -79,6 +79,8 @@ class FiscalYear(Workflow, ModelSQL, ModelView):
|
||||
t.end_date), RangeOverlap),
|
||||
(Case((t.state == 'open', t.id), else_=-1), NotEqual)),
|
||||
'account.msg_open_fiscalyear_earlier'),
|
||||
('post_move_sequence_unique', Unique(t, t.post_move_sequence),
|
||||
'account.msg_fiscalyear_post_move_unique'),
|
||||
]
|
||||
cls._order.insert(0, ('start_date', 'DESC'))
|
||||
cls._transitions |= set((
|
||||
@@ -136,25 +138,8 @@ class FiscalYear(Workflow, ModelSQL, ModelView):
|
||||
@classmethod
|
||||
def validate_fields(cls, fiscalyears, field_names):
|
||||
super().validate_fields(fiscalyears, field_names)
|
||||
cls.check_post_move_sequence(fiscalyears, field_names)
|
||||
cls.check_period_dates(fiscalyears, field_names)
|
||||
|
||||
@classmethod
|
||||
def check_post_move_sequence(cls, fiscalyears, field_names=None):
|
||||
if field_names and 'post_move_sequence' not in field_names:
|
||||
return
|
||||
for fiscalyear in fiscalyears:
|
||||
sequence = fiscalyear.post_move_sequence
|
||||
years = cls.search([
|
||||
('post_move_sequence', '=', sequence.id),
|
||||
('id', '!=', fiscalyear.id),
|
||||
], limit=1)
|
||||
if years:
|
||||
raise FiscalYearSequenceError(gettext(
|
||||
'account.msg_fiscalyear_different_post_move_sequence',
|
||||
first=fiscalyear.rec_name,
|
||||
second=years[0].rec_name))
|
||||
|
||||
@classmethod
|
||||
def check_period_dates(cls, fiscalyears, field_names=None):
|
||||
pool = Pool()
|
||||
|
||||
@@ -24,8 +24,8 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<record model="ir.message" id="msg_period_standard_overlap">
|
||||
<field name="text">The dates of standard period of the same fiscal year can not overlap.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_period_same_sequence">
|
||||
<field name="text">You cannot use the same post move sequence for the periods "%(first)s" and "%(second)s" because they are from different fiscal years.</field>
|
||||
<record model="ir.message" id="msg_period_post_move_sequence_unique">
|
||||
<field name="text">A post move sequence can be reused only by periods in the same fiscal year.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_period_fiscalyear_dates">
|
||||
<field name="text">The dates for period "%(period)s" must be between the dates of its fiscal year "%(fiscalyear)s".</field>
|
||||
@@ -69,8 +69,8 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<record model="ir.message" id="msg_open_fiscalyear_earlier">
|
||||
<field name="text">Open fiscal years can not be before closed fiscal years.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_fiscalyear_different_post_move_sequence">
|
||||
<field name="text">The fiscal years "%(first)s" and "%(second)s" cannot have the same post move sequence, you must use different sequences.</field>
|
||||
<record model="ir.message" id="msg_fiscalyear_post_move_sequence_unique">
|
||||
<field name="text">The post move sequence of fiscal years must be unique.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_close_fiscalyear_account_balance_not_zero">
|
||||
<field name="text">To close the fiscal year, the balance of account "%(account)s" must be zero.</field>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from sql.operators import Equal
|
||||
from sql.operators import Equal, NotEqual
|
||||
|
||||
from trytond.cache import Cache
|
||||
from trytond.const import OPERATORS
|
||||
@@ -15,9 +15,7 @@ from trytond.sql.operators import RangeOverlap
|
||||
from trytond.tools import grouped_slice
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
from .exceptions import (
|
||||
ClosePeriodError, PeriodDatesError, PeriodNotFoundError,
|
||||
PeriodSequenceError)
|
||||
from .exceptions import ClosePeriodError, PeriodDatesError, PeriodNotFoundError
|
||||
|
||||
_STATES = {
|
||||
'readonly': Eval('state') != 'open',
|
||||
@@ -70,6 +68,11 @@ class Period(Workflow, ModelSQL, ModelView):
|
||||
(DateRange(t.start_date, t.end_date, '[]'), RangeOverlap),
|
||||
where=t.type == 'standard'),
|
||||
'account.msg_period_standard_overlap'),
|
||||
('post_move_sequence_unique',
|
||||
Exclude(t,
|
||||
(t.post_move_sequence, Equal),
|
||||
(t.fiscalyear, NotEqual)),
|
||||
'account.msg_period_post_move_sequence_unique'),
|
||||
]
|
||||
cls._sql_indexes.add(
|
||||
Index(
|
||||
@@ -135,7 +138,6 @@ class Period(Workflow, ModelSQL, ModelView):
|
||||
super().validate_fields(periods, field_names)
|
||||
cls.check_fiscalyear_dates(periods, field_names)
|
||||
cls.check_move_dates(periods, field_names)
|
||||
cls.check_post_move_sequence(periods, field_names)
|
||||
|
||||
@classmethod
|
||||
def check_fiscalyear_dates(cls, periods, field_names=None):
|
||||
@@ -180,24 +182,6 @@ class Period(Workflow, ModelSQL, ModelView):
|
||||
move=move.rec_name,
|
||||
move_date=lang.strftime(move.date)))
|
||||
|
||||
@classmethod
|
||||
def check_post_move_sequence(cls, periods, field_names=None):
|
||||
if field_names and not (
|
||||
field_names & {'post_move_sequence', 'fiscalyear'}):
|
||||
return
|
||||
for period in periods:
|
||||
if not period.post_move_sequence:
|
||||
continue
|
||||
periods = cls.search([
|
||||
('post_move_sequence', '=', period.post_move_sequence.id),
|
||||
('fiscalyear', '!=', period.fiscalyear.id),
|
||||
])
|
||||
if periods:
|
||||
raise PeriodSequenceError(
|
||||
gettext('account.msg_period_same_sequence',
|
||||
first=period.rec_name,
|
||||
second=periods[0].rec_name))
|
||||
|
||||
@classmethod
|
||||
def find(cls, company, date=None, test_state=True):
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user