Merge pull request #4152 from ostcar/new_projector_iv_motion_slide

New projector IV
This commit is contained in:
Finn Stutzenstein 2019-01-24 11:28:53 +01:00 committed by GitHub
commit 1b3c0b4cee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 304 additions and 18 deletions

View File

@ -507,9 +507,11 @@ class Motion(RESTModelMixin, models.Model):
"""
if self.recommendation is not None:
self.set_state(self.recommendation)
if (self.recommendation_extension is not None
if (
self.recommendation_extension is not None
and self.state.show_state_extension_field
and self.recommendation.show_recommendation_extension_field):
and self.recommendation.show_recommendation_extension_field
):
self.state_extension = self.recommendation_extension
"""

View File

@ -1,6 +1,6 @@
from typing import Any, Dict
from ..utils.projector import register_projector_element
from ..utils.projector import AllData, get_config, get_user, register_projector_element
# Important: All functions have to be prune. This means, that thay can only
@ -9,18 +9,105 @@ from ..utils.projector import register_projector_element
# to be fast!
def motion(
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
def get_state(
all_data: AllData, motion: Dict[str, Any], state_id: int
) -> Dict[str, Any]:
"""
Returns a state element from one motion.
Returns an error if the state_id does not exist for the workflow in the motion.
"""
states = all_data["motions/workflow"][motion["workflow_id"]]["states"]
for state in states:
if state["id"] == state_id:
return state
return {"error": f"motion {motion['id']} can not have to id {state_id}"}
def motion_slide(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
"""
Motion slide.
The returned dict can contain the following fields:
* identifier
* title
* text
* amendment_paragraphs
* is_child
* show_meta_box
* reason
* modified_final_version
* state
* state_extension
* recommendation
* recommendation_extension
* submitter
* poll
"""
return {"error": "TODO", "some_key": "another_value"}
mode = element.get("mode")
motion_id = element.get("id")
if motion_id is None:
return {"error": "id is required for motion slide"}
try:
motion = all_data["motions/motion"][motion_id]
except KeyError:
return {"error": f"motion with id {motion_id} does not exist"}
show_meta_box = not get_config(all_data, "motions_disable_sidebox_on_projector")
return_value = {
"identifier": motion["identifier"],
"title": motion["title"],
"text": motion["text"],
"amendment_paragraphs": motion["amendment_paragraphs"],
"is_child": bool(motion["parent_id"]),
"show_meta_box": show_meta_box,
}
if not get_config(all_data, "motions_disable_reason_on_projector"):
return_value["reason"] = motion["reason"]
if mode == "final":
return_value["modified_final_version"] = motion["modified_final_version"]
if show_meta_box:
state = get_state(all_data, motion, motion["state_id"])
if state.get("error"):
return state
return_value["state"] = state["name"]
return_value["state_extension"] = motion["state_extension"]
if (
not get_config(all_data, "motions_disable_recommendation_on_projector")
and motion["recommendation_id"]
):
return_value["recommendation"] = all_data[
"motions/motion-change-recommendation"
][motion["recommendation_id"]]["text"]
return_value["recommendation_extension"] = motion[
"recommendation_extension"
]
return_value["submitter"] = [
get_user(all_data, submitter["user_id"])
for submitter in motion["submitters"]
]
for poll in motion["polls"][::-1]:
if poll["has_votes"]:
return_value["poll"] = {
"yes": poll["yes"],
"no": poll["no"],
"abstain": poll["abstain"],
}
break
return return_value
def motion_block(
element: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
def motion_block(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
"""
Motion slide.
"""
@ -28,5 +115,5 @@ def motion_block(
def register_projector_elements() -> None:
register_projector_element("motions/motion", motion)
register_projector_element("motions/motion", motion_slide)
register_projector_element("motions/motion-block", motion_block)

View File

@ -92,3 +92,15 @@ def get_config(all_data: AllData, key: str) -> Any:
return all_data[config.get_collection_string()][config.get_key_to_id()[key]][
"value"
]
def get_user(all_data: AllData, user_id: int) -> Dict[str, Any]:
"""
Returns the value of a user to show his name.
"""
user = all_data["users/user"][user_id]
return {
"title": user["title"],
"first_name": user["first_name"],
"last_name": user["last_name"],
}

View File

@ -6,7 +6,7 @@ from django.test.utils import CaptureQueriesContext
from openslides.core.config import config
from openslides.core.models import Projector
from openslides.users.models import User
from openslides.utils.projector import get_config, register_projector_element
from openslides.utils.projector import AllData, get_config, register_projector_element
class TConfig:
@ -90,18 +90,14 @@ class TProjector:
return elements
def slide1(
config: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
def slide1(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
"""
Slide that shows the general_event_name.
"""
return {"name": "slide1", "event_name": get_config(all_data, "general_event_name")}
def slide2(
config: Dict[str, Any], all_data: Dict[str, Dict[int, Dict[str, Any]]]
) -> Dict[str, Any]:
def slide2(element: Dict[str, Any], all_data: AllData) -> Dict[str, Any]:
return {"name": "slide2"}
@ -121,3 +117,19 @@ def count_queries(func, *args, **kwargs) -> int:
print(f"{len(context)} queries executed\nCaptured queries were:\n{queries}")
return len(context)
def all_data_config() -> AllData:
return {
TConfig().get_collection_string(): {
element["id"]: element for element in TConfig().get_elements()
}
}
def all_data_users() -> AllData:
return {
TUser().get_collection_string(): {
element["id"]: element for element in TUser().get_elements()
}
}

View File

@ -0,0 +1,173 @@
from typing import Any, Dict
import pytest
from openslides.motions import projector
from ...integration.helpers import all_data_config, all_data_users
@pytest.fixture
def all_data():
return_value = all_data_config()
return_value.update(all_data_users())
return_value["motions/motion"] = {
1: {
"id": 1,
"identifier": "4",
"title": "12345",
"text": "motion text",
"amendment_paragraphs": None,
"modified_final_version": "",
"reason": "",
"parent_id": None,
"category_id": None,
"comments": [],
"motion_block_id": None,
"origin": "",
"submitters": [{"id": 4, "user_id": 1, "motion_id": 1, "weight": 1}],
"supporters_id": [],
"state_id": 1,
"state_extension": None,
"state_required_permission_to_see": "",
"statute_paragraph_id": None,
"workflow_id": 1,
"recommendation_id": None,
"recommendation_extension": None,
"tags_id": [],
"attachments_id": [],
"polls": [
{
"id": 1,
"motion_id": 4,
"yes": "10.000000",
"no": "-1.000000",
"abstain": "20.000000",
"votesvalid": "11.000000",
"votesinvalid": "2.000000",
"votescast": "30.000000",
"has_votes": True,
}
],
"agenda_item_id": 4,
"log_messages": [
{
"message_list": "['Vote updated']",
"person_id": 1,
"time": "2019-01-19T22:15:53.291123+01:00",
"message": "Jan. 19, 2019, 10:15 p.m. Vote updated by Administrator",
},
{
"message_list": "['Vote created']",
"person_id": 1,
"time": "2019-01-19T22:15:37.446262+01:00",
"message": "Jan. 19, 2019, 10:15 p.m. Vote created by Administrator",
},
{
"message_list": "['Motion created']",
"person_id": 1,
"time": "2019-01-19T18:37:34.833749+01:00",
"message": "Jan. 19, 2019, 6:37 p.m. Motion created by Administrator",
},
],
"sort_parent_id": None,
"weight": 10000,
"created": "2019-01-19T18:37:34.741336+01:00",
"last_modified": "2019-01-19T18:37:34.741368+01:00",
}
}
return_value["motions/workflow"] = {
1: {
"id": 1,
"name": "Simple Workflow",
"states": [
{
"id": 1,
"name": "submitted",
"recommendation_label": None,
"css_class": "primary",
"required_permission_to_see": "",
"allow_support": True,
"allow_create_poll": True,
"allow_submitter_edit": True,
"dont_set_identifier": False,
"show_state_extension_field": False,
"merge_amendment_into_final": 0,
"show_recommendation_extension_field": False,
"next_states_id": [2, 3, 4],
"workflow_id": 1,
},
{
"id": 2,
"name": "accepted",
"recommendation_label": "Acceptance",
"css_class": "success",
"required_permission_to_see": "",
"allow_support": False,
"allow_create_poll": False,
"allow_submitter_edit": False,
"dont_set_identifier": False,
"show_state_extension_field": False,
"merge_amendment_into_final": 1,
"show_recommendation_extension_field": False,
"next_states_id": [],
"workflow_id": 1,
},
{
"id": 3,
"name": "rejected",
"recommendation_label": "Rejection",
"css_class": "danger",
"required_permission_to_see": "",
"allow_support": False,
"allow_create_poll": False,
"allow_submitter_edit": False,
"dont_set_identifier": False,
"show_state_extension_field": False,
"merge_amendment_into_final": -1,
"show_recommendation_extension_field": False,
"next_states_id": [],
"workflow_id": 1,
},
{
"id": 4,
"name": "not decided",
"recommendation_label": "No decision",
"css_class": "default",
"required_permission_to_see": "",
"allow_support": False,
"allow_create_poll": False,
"allow_submitter_edit": False,
"dont_set_identifier": False,
"show_state_extension_field": False,
"merge_amendment_into_final": -1,
"show_recommendation_extension_field": False,
"next_states_id": [],
"workflow_id": 1,
},
],
"first_state_id": 1,
}
}
return_value["motions/motion-change-recommendation"] = {}
return return_value
def test_motion_slide(all_data):
element: Dict[str, Any] = {"id": 1}
data = projector.motion_slide(element, all_data)
assert data == {
"identifier": "4",
"title": "12345",
"text": "motion text",
"amendment_paragraphs": None,
"is_child": False,
"show_meta_box": True,
"reason": "",
"state": "submitted",
"state_extension": None,
"submitter": [{"first_name": "", "last_name": "Administrator", "title": ""}],
"poll": {"yes": "10.000000", "no": "-1.000000", "abstain": "20.000000"},
}