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 @@
+ 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}."} )