diff --git a/modules/account_statement/message.xml b/modules/account_statement/message.xml
index bab7027298..ddbf8c3607 100644
--- a/modules/account_statement/message.xml
+++ b/modules/account_statement/message.xml
@@ -36,6 +36,13 @@ this repository contains the full copyright notices and license terms. -->
To post statement "%(statement)s" you must create lines for pending %(amount)s of origin "%(origin)s".
+
+ To delete line "%(line)s" you must cancel or reset to draft statement "%(statement)s".
+
+
+ To delete origin "%(origin)s" you must cancel or reset to draft statement "%(statement)s".
+
+
To post the move "%(move)s" you must post the statement "%(statement)s".
diff --git a/modules/account_statement/statement.py b/modules/account_statement/statement.py
index edbfda21e8..72800fb1b8 100644
--- a/modules/account_statement/statement.py
+++ b/modules/account_statement/statement.py
@@ -744,8 +744,9 @@ class Line(origin_mixin(_states), sequence_ordered(), ModelSQL, ModelView):
},
states=_states,
context={'with_payment': False})
- origin = fields.Many2One('account.statement.origin', 'Origin',
- readonly=True,
+ origin = fields.Many2One(
+ 'account.statement.origin', 'Origin', readonly=True,
+ ondelete='RESTRICT',
states={
'invisible': ~Bool(Eval('origin')),
},
@@ -930,6 +931,18 @@ class Line(origin_mixin(_states), sequence_ordered(), ModelSQL, ModelView):
def search_rec_name(cls, name, clause):
return [('statement.rec_name',) + tuple(clause[1:])]
+ @classmethod
+ def delete(cls, lines):
+ for line in lines:
+ if line.statement_state not in {'cancelled', 'draft'}:
+ raise AccessError(
+ gettext(
+ 'account_statement.'
+ 'msg_statement_line_delete_cancel_draft',
+ line=line.rec_name,
+ sale=line.statement.rec_name))
+ super().delete(lines)
+
@classmethod
def copy(cls, lines, default=None):
if default is None:
@@ -1173,6 +1186,18 @@ class Origin(origin_mixin(_states), ModelSQL, ModelView):
group_by=table.id))
return [('id', 'in', query)]
+ @classmethod
+ def delete(cls, origins):
+ for origin in origins:
+ if origin.statement_state not in {'cancelled', 'draft'}:
+ raise AccessError(
+ gettext(
+ 'account_statement.'
+ 'msg_statement_origin_delete_cancel_draft',
+ origin=origin.rec_name,
+ sale=origin.statement.rec_name))
+ super().delete(origins)
+
@classmethod
def copy(cls, origins, default=None):
default = default.copy() if default is not None else {}