2018-12-23 11:05:38 +01:00
|
|
|
from typing import Any, Dict
|
2017-08-30 00:07:54 +02:00
|
|
|
|
2019-01-27 13:17:17 +01:00
|
|
|
from ..users.projector import get_user_name
|
|
|
|
from ..utils.projector import (
|
|
|
|
AllData,
|
|
|
|
ProjectorElementException,
|
|
|
|
get_config,
|
|
|
|
register_projector_slide,
|
|
|
|
)
|
2015-06-24 22:11:54 +02:00
|
|
|
|
|
|
|
|
2018-12-23 11:05:38 +01:00
|
|
|
# Important: All functions have to be prune. This means, that thay can only
|
|
|
|
# access the data, that they get as argument and do not have any
|
|
|
|
# side effects. They are called from an async context. So they have
|
|
|
|
# to be fast!
|
2015-06-24 22:11:54 +02:00
|
|
|
|
2016-10-01 20:42:44 +02:00
|
|
|
|
2019-01-19 21:36:30 +01:00
|
|
|
def get_state(
|
|
|
|
all_data: AllData, motion: Dict[str, Any], state_id: int
|
2018-12-23 11:05:38 +01:00
|
|
|
) -> Dict[str, Any]:
|
2019-01-19 21:36:30 +01:00
|
|
|
"""
|
|
|
|
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
|
2019-01-27 13:17:17 +01:00
|
|
|
raise ProjectorElementException(
|
|
|
|
f"motion {motion['id']} can not be on the state with id {state_id}"
|
|
|
|
)
|
2019-01-19 21:36:30 +01:00
|
|
|
|
2019-02-14 16:35:25 +01:00
|
|
|
|
2019-02-03 19:30:07 +01:00
|
|
|
def get_amendment_merge_into_motion(all_data, motion, amendment):
|
|
|
|
"""
|
|
|
|
HINT: This implementation should be consistent to isAccepted() in ViewMotionAmendedParagraph.ts
|
|
|
|
"""
|
|
|
|
if amendment["state_id"] is None:
|
|
|
|
return 0
|
|
|
|
|
2019-02-14 16:35:25 +01:00
|
|
|
state = get_state(all_data, motion, amendment["state_id"])
|
|
|
|
if (
|
|
|
|
state["merge_amendment_into_final"] == -1
|
|
|
|
or state["merge_amendment_into_final"] == 1
|
|
|
|
):
|
2019-02-03 19:30:07 +01:00
|
|
|
return state["merge_amendment_into_final"]
|
|
|
|
|
|
|
|
if amendment["recommendation_id"] is None:
|
|
|
|
return 0
|
2019-02-14 16:35:25 +01:00
|
|
|
recommendation = get_state(all_data, motion, amendment["recommendation_id"])
|
2019-02-03 19:30:07 +01:00
|
|
|
return recommendation["merge_amendment_into_final"]
|
|
|
|
|
2019-02-14 16:35:25 +01:00
|
|
|
|
2019-02-03 19:30:07 +01:00
|
|
|
def get_amendments_for_motion(motion, all_data):
|
|
|
|
amendment_data = []
|
|
|
|
for amendment_id, amendment in all_data["motions/motion"].items():
|
|
|
|
if amendment["parent_id"] == motion["id"]:
|
2019-02-14 16:35:25 +01:00
|
|
|
merge_amendment_into_final = get_amendment_merge_into_motion(
|
|
|
|
all_data, motion, amendment
|
|
|
|
)
|
|
|
|
amendment_data.append(
|
|
|
|
{
|
|
|
|
"id": amendment["id"],
|
|
|
|
"identifier": amendment["identifier"],
|
|
|
|
"title": amendment["title"],
|
|
|
|
"amendment_paragraphs": amendment["amendment_paragraphs"],
|
|
|
|
"merge_amendment_into_final": merge_amendment_into_final,
|
|
|
|
}
|
|
|
|
)
|
2019-02-03 19:30:07 +01:00
|
|
|
return amendment_data
|
|
|
|
|
2019-02-14 16:35:25 +01:00
|
|
|
|
2019-02-03 19:30:07 +01:00
|
|
|
def get_amendment_base_motion(amendment, all_data):
|
|
|
|
try:
|
|
|
|
motion = all_data["motions/motion"][amendment["parent_id"]]
|
|
|
|
except KeyError:
|
|
|
|
motion_id = amendment["parent_id"]
|
|
|
|
raise ProjectorElementException(f"motion with id {motion_id} does not exist")
|
|
|
|
|
|
|
|
return {
|
|
|
|
"identifier": motion["identifier"],
|
|
|
|
"title": motion["title"],
|
|
|
|
"text": motion["text"],
|
|
|
|
}
|
|
|
|
|
2019-02-14 16:35:25 +01:00
|
|
|
|
2019-02-03 19:30:07 +01:00
|
|
|
def get_amendment_base_statute(amendment, all_data):
|
|
|
|
try:
|
2019-02-14 16:35:25 +01:00
|
|
|
statute = all_data["motions/statute-paragraph"][
|
|
|
|
amendment["statute_paragraph_id"]
|
|
|
|
]
|
2019-02-03 19:30:07 +01:00
|
|
|
except KeyError:
|
|
|
|
statute_id = amendment["statute_paragraph_id"]
|
|
|
|
raise ProjectorElementException(f"statute with id {statute_id} does not exist")
|
|
|
|
|
2019-02-14 16:35:25 +01:00
|
|
|
return {"title": statute["title"], "text": statute["text"]}
|
|
|
|
|
2019-01-19 21:36:30 +01:00
|
|
|
|
2019-01-27 13:17:17 +01:00
|
|
|
def motion_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
2016-10-01 20:42:44 +02:00
|
|
|
"""
|
2018-12-23 11:05:38 +01:00
|
|
|
Motion slide.
|
2019-01-19 21:36:30 +01:00
|
|
|
|
|
|
|
The returned dict can contain the following fields:
|
|
|
|
* identifier
|
|
|
|
* title
|
|
|
|
* text
|
|
|
|
* amendment_paragraphs
|
|
|
|
* is_child
|
|
|
|
* show_meta_box
|
|
|
|
* reason
|
|
|
|
* modified_final_version
|
|
|
|
* recommendation
|
|
|
|
* recommendation_extension
|
2019-01-26 20:37:49 +01:00
|
|
|
* recommender
|
|
|
|
* change_recommendations
|
2019-01-19 21:36:30 +01:00
|
|
|
* submitter
|
2016-10-01 20:42:44 +02:00
|
|
|
"""
|
2019-02-14 16:35:25 +01:00
|
|
|
mode = element.get("mode", get_config(all_data, "motions_recommendation_text_mode"))
|
2019-01-19 21:36:30 +01:00
|
|
|
motion_id = element.get("id")
|
2019-01-06 16:22:33 +01:00
|
|
|
|
2019-01-19 21:36:30 +01:00
|
|
|
if motion_id is None:
|
2019-02-15 12:01:16 +01:00
|
|
|
raise ProjectorElementException("id is required for motion slide")
|
2016-10-01 20:42:44 +02:00
|
|
|
|
2019-01-19 21:36:30 +01:00
|
|
|
try:
|
|
|
|
motion = all_data["motions/motion"][motion_id]
|
|
|
|
except KeyError:
|
2019-01-27 13:17:17 +01:00
|
|
|
raise ProjectorElementException(f"motion with id {motion_id} does not exist")
|
2019-01-19 21:36:30 +01:00
|
|
|
|
|
|
|
show_meta_box = not get_config(all_data, "motions_disable_sidebox_on_projector")
|
2019-02-03 19:30:07 +01:00
|
|
|
line_length = get_config(all_data, "motions_line_length")
|
|
|
|
line_numbering_mode = get_config(all_data, "motions_default_line_numbering")
|
|
|
|
motions_preamble = get_config(all_data, "motions_preamble")
|
|
|
|
|
|
|
|
if motion["statute_paragraph_id"]:
|
2019-02-14 16:35:25 +01:00
|
|
|
change_recommendations = [] # type: ignore
|
|
|
|
amendments = [] # type: ignore
|
2019-02-03 19:30:07 +01:00
|
|
|
base_motion = None
|
|
|
|
base_statute = get_amendment_base_statute(motion, all_data)
|
|
|
|
elif bool(motion["parent_id"]) and motion["amendment_paragraphs"]:
|
|
|
|
change_recommendations = []
|
|
|
|
amendments = []
|
|
|
|
base_motion = get_amendment_base_motion(motion, all_data)
|
|
|
|
base_statute = None
|
|
|
|
else:
|
2019-02-14 16:35:25 +01:00
|
|
|
change_recommendations = list(
|
|
|
|
filter(
|
|
|
|
lambda reco: reco["internal"] is False, motion["change_recommendations"]
|
|
|
|
)
|
|
|
|
)
|
2019-02-03 19:30:07 +01:00
|
|
|
amendments = get_amendments_for_motion(motion, all_data)
|
|
|
|
base_motion = None
|
|
|
|
base_statute = None
|
2019-01-19 21:36:30 +01:00
|
|
|
|
|
|
|
return_value = {
|
|
|
|
"identifier": motion["identifier"],
|
|
|
|
"title": motion["title"],
|
2019-02-03 19:30:07 +01:00
|
|
|
"preamble": motions_preamble,
|
2019-01-19 21:36:30 +01:00
|
|
|
"text": motion["text"],
|
|
|
|
"amendment_paragraphs": motion["amendment_paragraphs"],
|
2019-02-03 19:30:07 +01:00
|
|
|
"base_motion": base_motion,
|
|
|
|
"base_statute": base_statute,
|
2019-01-19 21:36:30 +01:00
|
|
|
"is_child": bool(motion["parent_id"]),
|
|
|
|
"show_meta_box": show_meta_box,
|
2019-02-03 19:30:07 +01:00
|
|
|
"change_recommendations": change_recommendations,
|
|
|
|
"amendments": amendments,
|
|
|
|
"line_length": line_length,
|
|
|
|
"line_numbering_mode": line_numbering_mode,
|
2019-01-19 21:36:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if not get_config(all_data, "motions_disable_reason_on_projector"):
|
|
|
|
return_value["reason"] = motion["reason"]
|
2019-01-27 13:17:17 +01:00
|
|
|
|
2019-01-19 21:36:30 +01:00
|
|
|
if mode == "final":
|
|
|
|
return_value["modified_final_version"] = motion["modified_final_version"]
|
|
|
|
|
|
|
|
if show_meta_box:
|
|
|
|
if (
|
|
|
|
not get_config(all_data, "motions_disable_recommendation_on_projector")
|
|
|
|
and motion["recommendation_id"]
|
|
|
|
):
|
2019-01-27 13:17:17 +01:00
|
|
|
recommendation_state = get_state(
|
|
|
|
all_data, motion, motion["recommendation_id"]
|
|
|
|
)
|
|
|
|
return_value["recommendation"] = recommendation_state[
|
|
|
|
"recommendation_label"
|
2019-01-19 21:36:30 +01:00
|
|
|
]
|
2019-01-27 13:17:17 +01:00
|
|
|
if recommendation_state["show_recommendation_extension_field"]:
|
|
|
|
return_value["recommendation_extension"] = motion[
|
|
|
|
"recommendation_extension"
|
|
|
|
]
|
|
|
|
|
2019-01-26 20:37:49 +01:00
|
|
|
return_value["recommender"] = get_config(
|
|
|
|
all_data, "motions_recommendations_by"
|
|
|
|
)
|
2019-01-19 21:36:30 +01:00
|
|
|
|
|
|
|
return_value["submitter"] = [
|
2019-01-27 13:17:17 +01:00
|
|
|
get_user_name(all_data, submitter["user_id"])
|
|
|
|
for submitter in sorted(
|
|
|
|
motion["submitters"], key=lambda submitter: submitter["weight"]
|
|
|
|
)
|
2019-01-19 21:36:30 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
return return_value
|
|
|
|
|
|
|
|
|
2019-01-27 13:17:17 +01:00
|
|
|
def motion_block_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
2018-12-23 11:05:38 +01:00
|
|
|
"""
|
2019-02-21 12:34:13 +01:00
|
|
|
Motion block slide.
|
2018-12-23 11:05:38 +01:00
|
|
|
"""
|
2019-02-21 12:34:13 +01:00
|
|
|
motion_block_id = element.get("id")
|
|
|
|
|
|
|
|
if motion_block_id is None:
|
|
|
|
raise ProjectorElementException("id is required for motion block slide")
|
|
|
|
|
|
|
|
try:
|
|
|
|
motion_block = all_data["motions/motion-block"][motion_block_id]
|
|
|
|
except KeyError:
|
|
|
|
raise ProjectorElementException(
|
|
|
|
f"motion block with id {motion_block_id} does not exist"
|
|
|
|
)
|
|
|
|
|
|
|
|
motions = []
|
|
|
|
for motion in all_data["motions/motion"].values():
|
|
|
|
if motion["motion_block_id"] == motion_block_id:
|
|
|
|
motion_object = {
|
|
|
|
"title": motion["title"],
|
|
|
|
"identifier": motion["identifier"],
|
|
|
|
}
|
|
|
|
|
|
|
|
recommendation_id = motion["recommendation_id"]
|
|
|
|
if recommendation_id is not None:
|
|
|
|
recommendation = get_state(
|
|
|
|
all_data, motion, motion["recommendation_id"]
|
|
|
|
)
|
|
|
|
motion_object["recommendation"] = {
|
|
|
|
"name": recommendation["name"],
|
|
|
|
"css_class": recommendation["css_class"],
|
|
|
|
}
|
|
|
|
if recommendation["show_recommendation_extension_field"]:
|
|
|
|
motion_object["recommendation_extension"] = motion[
|
|
|
|
"recommendation_extension"
|
|
|
|
]
|
|
|
|
|
|
|
|
motions.append(motion_object)
|
|
|
|
|
|
|
|
return {"title": motion_block["title"], "motions": motions}
|
2017-08-30 00:07:54 +02:00
|
|
|
|
|
|
|
|
2019-01-27 13:17:17 +01:00
|
|
|
def register_projector_slides() -> None:
|
|
|
|
register_projector_slide("motions/motion", motion_slide)
|
|
|
|
register_projector_slide("motions/motion-block", motion_block_slide)
|