diff --git a/client/src/app/shared/models/motions/workflow-state.ts b/client/src/app/shared/models/motions/workflow-state.ts
index 6e39361b8..8c0040acc 100644
--- a/client/src/app/shared/models/motions/workflow-state.ts
+++ b/client/src/app/shared/models/motions/workflow-state.ts
@@ -45,13 +45,15 @@ export class WorkflowState extends Deserializer {
* Also adds the current state.
*/
public getNextStates(workflow: Workflow): WorkflowState[] {
- const nextStates = [];
- workflow.states.forEach(state => {
- if (this.next_states_id.includes(state.id)) {
- nextStates.push(state as WorkflowState);
- }
+ return workflow.states.filter(state => {
+ return this.next_states_id.includes(state.id);
+ });
+ }
+
+ public getPreviousStates(workflow: Workflow): WorkflowState[] {
+ return workflow.states.filter(state => {
+ return state.next_states_id.includes(this.id);
});
- return nextStates;
}
public toString = (): string => {
diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html
index bd7e81b2e..de12ef295 100644
--- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html
+++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html
@@ -223,6 +223,9 @@
0">
+
diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts
index 06993ef19..194a63eae 100644
--- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts
+++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts
@@ -1035,7 +1035,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
* @param id Motion state id
*/
public setState(id: number): void {
- this.repo.setState(this.motion, id);
+ this.repo.setState(this.motion, id).then(null, this.raiseError);
}
/**
diff --git a/client/src/app/site/motions/models/view-motion.ts b/client/src/app/site/motions/models/view-motion.ts
index aed157374..e47febd00 100644
--- a/client/src/app/site/motions/models/view-motion.ts
+++ b/client/src/app/site/motions/models/view-motion.ts
@@ -194,6 +194,10 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
return this.state && this.workflow ? this.state.getNextStates(this.workflow.workflow) : [];
}
+ public get previousStates(): WorkflowState[] {
+ return this.state && this.workflow ? this.state.getPreviousStates(this.workflow.workflow) : [];
+ }
+
public get item(): ViewItem {
return this._item;
}
diff --git a/openslides/motions/models.py b/openslides/motions/models.py
index 1cc1402f9..8cab6f541 100644
--- a/openslides/motions/models.py
+++ b/openslides/motions/models.py
@@ -1176,6 +1176,14 @@ class State(RESTModelMixin, models.Model):
f"{state} can not be next state of {self} because it does not belong to the same workflow."
)
+ def is_next_or_previous_state_id(self, state_id):
+ """ Returns true, if the given state id is a valid next or previous state """
+ next_state_ids = [item.id for item in self.next_states.all()]
+ previous_state_ids = [
+ item.id for item in State.objects.filter(next_states__in=[self.id])
+ ]
+ return state_id in next_state_ids or state_id in previous_state_ids
+
def get_root_rest_element(self):
"""
Returns the workflow to this instance which is the root REST element.
diff --git a/openslides/motions/views.py b/openslides/motions/views.py
index 18c1a7b12..53b3af896 100644
--- a/openslides/motions/views.py
+++ b/openslides/motions/views.py
@@ -552,6 +552,8 @@ class MotionViewSet(ModelViewSet):
Send PUT {'state': } to set and just PUT {} to reset the
state. Only managers can use this view.
+
+ If a state is given, it must be a next or previous state.
"""
# Retrieve motion and state.
motion = self.get_object()
@@ -570,7 +572,7 @@ class MotionViewSet(ModelViewSet):
raise ValidationError(
{"detail": "Invalid data. State must be an integer."}
)
- if state_id not in [item.id for item in motion.state.next_states.all()]:
+ if not motion.state.is_next_or_previous_state_id(state_id):
raise ValidationError(
{"detail": f"You can not set the state to {state_id}."}
)