diff --git a/CHANGELOG b/CHANGELOG index bcc290f06d..abbd3b59f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Handle errors in move template expression * Rename split lines into reschedule lines * Add optional credit type on account * Always require a date to compute taxes diff --git a/exceptions.py b/exceptions.py index a573d01495..1742ee2f59 100644 --- a/exceptions.py +++ b/exceptions.py @@ -73,6 +73,10 @@ class MoveDatesError(ValidationError): pass +class MoveTemplateExpressionError(UserError): + pass + + class CancelWarning(UserWarning): pass diff --git a/message.xml b/message.xml index 9c690e5921..da6c47bc71 100644 --- a/message.xml +++ b/message.xml @@ -133,6 +133,14 @@ this repository contains the full copyright notices and license terms. --> Use the current period to cancel the move? + + Failed to evaluate expression "%(expression)s" from template "%(template)s" with error: +"%(error)s" + + + The value "%(value)s" of "%(expression)s" from template "%(template)s" is not a number. + + You cannot modify any reconciliation. diff --git a/move_template.py b/move_template.py index 2861b470b4..2333400ce2 100644 --- a/move_template.py +++ b/move_template.py @@ -3,8 +3,9 @@ from decimal import Decimal from xml.sax.saxutils import quoteattr -from simpleeval import simple_eval +from simpleeval import InvalidExpression, simple_eval +from trytond.i18n import gettext from trytond.model import ( DeactivableMixin, ModelSQL, ModelView, fields, sequence_ordered) from trytond.pool import Pool @@ -14,6 +15,8 @@ from trytond.transaction import Transaction from trytond.wizard import ( Button, StateAction, StateTransition, StateView, Wizard) +from .exceptions import MoveTemplateExpressionError + class MoveTemplate(DeactivableMixin, ModelSQL, ModelView): 'Account Move Template' @@ -202,8 +205,23 @@ class MoveLineTemplate(ModelSQL, ModelView): Keyword = pool.get('account.move.template.keyword') line = Line() - amount = simple_eval(decistmt(self.amount), - functions={'Decimal': Decimal}, names=values) + try: + amount = simple_eval(decistmt(self.amount), + functions={'Decimal': Decimal}, names=values) + except InvalidExpression as e: + raise MoveTemplateExpressionError( + gettext('account.msg_move_template_invalid_expression', + expression=values, + template=self.move.rec_name, + error=e)) from e + + if not isinstance(amount, Decimal): + raise MoveTemplateExpressionError( + gettext('account.msg_move_template_expession_not_number', + value=amount, + expression=self.move.name, + template=self.move.rec_name)) + amount = self.move.company.currency.round(amount) if self.operation == 'debit': line.debit = amount @@ -213,8 +231,15 @@ class MoveLineTemplate(ModelSQL, ModelView): if self.party: line.party = values.get(self.party) if self.description: - line.description = self.description.format( - **dict(Keyword.format_values(self.move, values))) + try: + line.description = self.description.format( + **dict(Keyword.format_values(self.move, values))) + except KeyError as e: + raise MoveTemplateExpressionError( + gettext('account.msg_move_template_invalid_expression', + expression=values, + template=self.move.name, + error=e)) from e line.tax_lines = [t.get_line(values) for t in self.taxes] return line @@ -258,8 +283,21 @@ class TaxLineTemplate(ModelSQL, ModelView): TaxLine = pool.get('account.tax.line') line = TaxLine() - amount = simple_eval(decistmt(self.amount), - functions={'Decimal': Decimal}, names=values) + try: + amount = simple_eval(decistmt(self.amount), + functions={'Decimal': Decimal}, names=values) + except InvalidExpression as e: + raise MoveTemplateExpressionError( + gettext('account.msg_template_invalid_expression', + expression=values, + template=self.line.rec_name, + error=e)) from e + + if not isinstance(amount, Decimal): + raise MoveTemplateExpressionError( + gettext('account.msg_not_number', + result=amount, + expression=self.move.rec_name)) amount = self.line.move.company.currency.round(amount) line.amount = amount line.type = self.type