changeset d80510557e5e in modules/account:default
details: https://hg.tryton.org/modules/account?cmd=changeset&node=d80510557e5e
description:
Add validate_fields to ModelStorage
issue11303
review386191002
diffstat:
account.py | 19 ++++++---
fiscalyear.py | 77 ++++++++++++++++++++++------------------
move.py | 54 +++++++++++++++------------
period.py | 109 +++++++++++++++++++++++++++++++++------------------------
tax.py | 42 ++++++++++++---------
5 files changed, 173 insertions(+), 128 deletions(-)
diffs (400 lines):
diff -r 4f9b64692892 -r d80510557e5e account.py
--- a/account.py Mon Apr 11 22:23:58 2022 +0200
+++ b/account.py Mon Apr 11 23:24:20 2022 +0200
@@ -952,10 +952,10 @@
table_h.drop_column('kind')
@classmethod
- def validate(cls, accounts):
- super(Account, cls).validate(accounts)
- cls.check_second_currency(accounts)
- cls.check_move_domain(accounts)
+ def validate_fields(cls, accounts, field_names):
+ super().validate_fields(accounts, field_names)
+ cls.check_second_currency(accounts, field_names)
+ cls.check_move_domain(accounts, field_names)
@staticmethod
def default_left():
@@ -1159,9 +1159,14 @@
setattr(self, field, getattr(self.parent, field))
@classmethod
- def check_second_currency(cls, accounts):
+ def check_second_currency(cls, accounts, field_names=None):
pool = Pool()
Line = pool.get('account.move.line')
+ if field_names and not (
+ field_names & (
+ {'second_currency', 'type'}
+ | set(cls.deferral.validation_depends))):
+ return
for account in accounts:
if not account.second_currency:
continue
@@ -1190,9 +1195,11 @@
account=account.rec_name))
@classmethod
- def check_move_domain(cls, accounts):
+ def check_move_domain(cls, accounts, field_names=None):
pool = Pool()
Line = pool.get('account.move.line')
+ if field_names and not (field_names & {'closed', 'type'}):
+ return
accounts = [a for a in accounts if a.closed or not a.type]
for sub_accounts in grouped_slice(accounts):
sub_accounts = list(sub_accounts)
diff -r 4f9b64692892 -r d80510557e5e fiscalyear.py
--- a/fiscalyear.py Mon Apr 11 22:23:58 2022 +0200
+++ b/fiscalyear.py Mon Apr 11 23:24:20 2022 +0200
@@ -100,45 +100,54 @@
}.get(self.state)
@classmethod
- def validate(cls, years):
- super(FiscalYear, cls).validate(years)
- for year in years:
- year.check_dates()
- year.check_post_move_sequence()
+ def validate_fields(cls, fiscalyears, field_names):
+ super().validate_fields(fiscalyears, field_names)
+ cls.check_dates(fiscalyears, field_names)
+ cls.check_post_move_sequence(fiscalyears, field_names)
- def check_dates(self):
+ @classmethod
+ def check_dates(cls, fiscalyears, field_names=None):
+ if field_names and not (field_names & {
+ 'start_date', 'end_date', 'company'}):
+ return
transaction = Transaction()
connection = transaction.connection
- self.__class__.lock()
+ cls.lock()
cursor = connection.cursor()
- table = self.__table__()
- cursor.execute(*table.select(table.id,
- where=(((table.start_date <= self.start_date)
- & (table.end_date >= self.start_date))
- | ((table.start_date <= self.end_date)
- & (table.end_date >= self.end_date))
- | ((table.start_date >= self.start_date)
- & (table.end_date <= self.end_date)))
- & (table.company == self.company.id)
- & (table.id != self.id)))
- second_id = cursor.fetchone()
- if second_id:
- second = self.__class__(second_id[0])
- raise FiscalYearDatesError(
- gettext('account.msg_fiscalyear_overlap',
- first=self.rec_name,
- second=second.rec_name))
+ table = cls.__table__()
+ for year in fiscalyears:
+ cursor.execute(*table.select(table.id,
+ where=(((table.start_date <= year.start_date)
+ & (table.end_date >= year.start_date))
+ | ((table.start_date <= year.end_date)
+ & (table.end_date >= year.end_date))
+ | ((table.start_date >= year.start_date)
+ & (table.end_date <= year.end_date)))
+ & (table.company == year.company.id)
+ & (table.id != year.id)))
+ second_id = cursor.fetchone()
+ if second_id:
+ second = cls(second_id[0])
+ raise FiscalYearDatesError(
+ gettext('account.msg_fiscalyear_overlap',
+ first=year.rec_name,
+ second=second.rec_name))
- def check_post_move_sequence(self):
- years = self.search([
- ('post_move_sequence', '=', self.post_move_sequence.id),
- ('id', '!=', self.id),
- ])
- if years:
- raise FiscalYearSequenceError(
- gettext('account.msg_fiscalyear_different_post_move_sequence',
- first=self.rec_name,
- second=years[0].rec_name))
+ @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 write(cls, *args):
diff -r 4f9b64692892 -r d80510557e5e move.py
--- a/move.py Mon Apr 11 22:23:58 2022 +0200
+++ b/move.py Mon Apr 11 23:24:20 2022 +0200
@@ -219,17 +219,20 @@
return [(None, '')] + [(m, get_name(m)) for m in models]
@classmethod
- def validate(cls, moves):
- super(Move, cls).validate(moves)
- for move in moves:
- move.check_date()
+ def validate_fields(cls, moves, field_names):
+ super().validate_fields(moves, field_names)
+ cls.check_date(moves, field_names)
- def check_date(self):
- if (self.date < self.period.start_date
- or self.date > self.period.end_date):
- raise MoveDatesError(
- gettext('account.msg_move_date_outside_period',
- move=self.rec_name))
+ @classmethod
+ def check_date(cls, moves, field_names=None):
+ if field_names and not (field_names & {'date', 'period'}):
+ return
+ for move in moves:
+ if (move.date < move.period.start_date
+ or move.date > move.period.end_date):
+ raise MoveDatesError(
+ gettext('account.msg_move_date_outside_period',
+ move=move.rec_name))
@classmethod
def check_modify(cls, moves):
@@ -1147,22 +1150,25 @@
return list(set(l.id for line in lines for l in line.move.lines))
@classmethod
- def validate(cls, lines):
+ def validate_fields(cls, lines, field_names):
super(Line, cls).validate(lines)
- for line in lines:
- line.check_account()
+ cls.check_account(lines, field_names)
- def check_account(self):
- if not self.account.type or self.account.closed:
- raise AccessError(
- gettext('account.msg_line_closed_account',
- account=self.account.rec_name))
- if bool(self.party) != bool(self.account.party_required):
- error = 'party_set' if self.party else 'party_required'
- raise AccessError(
- gettext('account.msg_line_%s' % error,
- account=self.account.rec_name,
- line=self.rec_name))
+ @classmethod
+ def check_account(cls, lines, field_names=None):
+ if field_names and not (field_names & {'account', 'party'}):
+ return
+ for line in lines:
+ if not line.account.type or line.account.closed:
+ raise AccessError(
+ gettext('account.msg_line_closed_account',
+ account=line.account.rec_name))
+ if bool(line.party) != bool(line.account.party_required):
+ error = 'party_set' if line.party else 'party_required'
+ raise AccessError(
+ gettext('account.msg_line_%s' % error,
+ account=line.account.rec_name,
+ line=line.rec_name))
@classmethod
def check_journal_period_modify(cls, period, journal):
diff -r 4f9b64692892 -r d80510557e5e period.py
--- a/period.py Mon Apr 11 22:23:58 2022 +0200
+++ b/period.py Mon Apr 11 23:24:20 2022 +0200
@@ -103,59 +103,76 @@
}.get(self.state)
@classmethod
- def validate(cls, periods):
- super(Period, cls).validate(periods)
- for period in periods:
- period.check_dates()
- period.check_fiscalyear_dates()
- period.check_post_move_sequence()
+ def validate_fields(cls, periods, field_names):
+ super().validate_fields(periods, field_names)
+ cls.check_dates(periods, field_names)
+ cls.check_fiscalyear_dates(periods, field_names)
+ cls.check_post_move_sequence(periods, field_names)
- def check_dates(self):
- if self.type != 'standard':
- return True
+ @classmethod
+ def check_dates(cls, periods, field_names=None):
+ if field_names and not (
+ field_names & {
+ 'start_date', 'end_date', 'fiscalyear', 'type'}):
+ return
transaction = Transaction()
connection = transaction.connection
- self.__class__.lock()
- table = self.__table__()
+ cls.lock()
+ table = cls.__table__()
cursor = connection.cursor()
- cursor.execute(*table.select(table.id,
- where=(((table.start_date <= self.start_date)
- & (table.end_date >= self.start_date))
- | ((table.start_date <= self.end_date)
- & (table.end_date >= self.end_date))
- | ((table.start_date >= self.start_date)
- & (table.end_date <= self.end_date)))
- & (table.fiscalyear == self.fiscalyear.id)
- & (table.type == 'standard')
- & (table.id != self.id)))
- period_id = cursor.fetchone()
- if period_id:
- overlapping_period = self.__class__(period_id[0])
- raise PeriodDatesError(
- gettext('account.msg_period_overlap',
- first=self.rec_name,
- second=overlapping_period.rec_name))
+ for period in periods:
+ if period.type != 'standard':
+ continue
+ cursor.execute(*table.select(table.id,
+ where=(((table.start_date <= period.start_date)
+ & (table.end_date >= period.start_date))
+ | ((table.start_date <= period.end_date)
+ & (table.end_date >= period.end_date))
+ | ((table.start_date >= period.start_date)
+ & (table.end_date <= period.end_date)))
+ & (table.fiscalyear == period.fiscalyear.id)
+ & (table.type == 'standard')
+ & (table.id != period.id)))
+ period_id = cursor.fetchone()
+ if period_id:
+ overlapping_period = cls(period_id[0])
+ raise PeriodDatesError(
+ gettext('account.msg_period_overlap',
+ first=period.rec_name,
+ second=overlapping_period.rec_name))
- def check_fiscalyear_dates(self):
- if (self.start_date < self.fiscalyear.start_date
- or self.end_date > self.fiscalyear.end_date):
- raise PeriodDatesError(
- gettext('account.msg_period_fiscalyear_dates',
- period=self.rec_name,
- fiscalyear=self.fiscalyear.rec_name))
+ @classmethod
+ def check_fiscalyear_dates(cls, periods, field_names=None):
+ if field_names and not (
+ field_names & {
+ 'start_date', 'end_date', 'fiscalyear'}):
+ return
+ for period in periods:
+ fiscalyear = period.fiscalyear
+ if (period.start_date < fiscalyear.start_date
+ or period.end_date > fiscalyear.end_date):
+ raise PeriodDatesError(
+ gettext('account.msg_period_fiscalyear_dates',
+ period=period.rec_name,
+ fiscalyear=fiscalyear.rec_name))
- def check_post_move_sequence(self):
- if not self.post_move_sequence:
+ @classmethod
+ def check_post_move_sequence(cls, periods, field_names=None):
+ if field_names and not (
+ field_names & {'post_move_sequence', 'fiscalyear'}):
return
- periods = self.search([
- ('post_move_sequence', '=', self.post_move_sequence.id),
- ('fiscalyear', '!=', self.fiscalyear.id),
- ])
- if periods:
- raise PeriodSequenceError(
- gettext('account.msg_period_same_sequence',
- first=self.rec_name,
- second=periods[0].rec_name))
+ 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_id, date=None, exception=True, test_state=True):
diff -r 4f9b64692892 -r d80510557e5e tax.py
--- a/tax.py Mon Apr 11 22:23:58 2022 +0200
+++ b/tax.py Mon Apr 11 23:24:20 2022 +0200
@@ -578,16 +578,19 @@
cls._order.insert(0, ('account', 'ASC'))
@classmethod
- def validate(cls, tax_templates):
- super(TaxTemplate, cls).validate(tax_templates)
- for tax_template in tax_templates:
- tax_template.check_update_unit_price()
+ def validate_fields(cls, tax_templates, field_names):
+ super().validate_fields(tax_templates, field_names)
+ cls.check_update_unit_price(tax_templates, field_names)
- def check_update_unit_price(self):
- if self.update_unit_price and self.parent:
- raise AccessError(
- gettext('account.msg_tax_update_unit_price_with_parent',
- tax=self.rec_name))
+ @classmethod
+ def check_update_unit_price(cls, tax_templates, field_names=None):
+ if field_names and not (field_names & {'update_unit_price', 'parent'}):
+ return
+ for tax in tax_templates:
+ if tax.update_unit_price and tax.parent:
+ raise AccessError(gettext(
+ 'account.msg_tax_update_unit_price_with_parent',
+ tax=tax.rec_name))
@staticmethod
def default_type():
@@ -778,16 +781,19 @@
del _states
@classmethod
- def validate(cls, taxes):
- super(Tax, cls).validate(taxes)
- for tax in taxes:
- tax.check_update_unit_price()
+ def validate_fields(cls, taxes, field_names):
+ super().validate_fields(taxes, field_names)
+ cls.check_update_unit_price(taxes, field_names)
- def check_update_unit_price(self):
- if self.parent and self.update_unit_price:
- raise AccessError(
- gettext('account.msg_tax_update_unit_price_with_parent',
- tax=self.rec_name))
+ @classmethod
+ def check_update_unit_price(cls, taxes, field_names=None):
+ if field_names and not (field_names & {'parent', 'update_unit_price'}):
+ return
+ for tax in taxes:
+ if tax.parent and tax.update_unit_price:
+ raise AccessError(gettext(
+ 'account.msg_tax_update_unit_price_with_parent',
+ tax=tax.rec_name))
@staticmethod
def default_type():