Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 82 additions & 4 deletions src/onegov/org/forms/meeting.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,102 @@
from __future__ import annotations

from wtforms import DateTimeField
from wtforms import StringField
from wtforms.validators import Optional, InputRequired

from onegov.form import Form
from onegov.form.fields import TimezoneDateTimeField, ChosenSelectMultipleField
from onegov.org.forms.fields import HtmlField
from onegov.parliament import _
from wtforms.validators import Optional
from onegov.parliament.models import Meeting, MeetingItem

from typing import TYPE_CHECKING
from collections.abc import Collection
if TYPE_CHECKING:
from collections.abc import Collection


class MeetingForm(Form):
title = StringField(
label=_('Title'),
validators=[InputRequired()],
)

start_datetime = DateTimeField(
start_datetime = TimezoneDateTimeField(
timezone='Europe/Zurich',
label=_('Start'),
validators=[Optional()],
)

end_datetime = TimezoneDateTimeField(
timezone='Europe/Zurich',
label=_('End'),
validators=[Optional()],
)

address = HtmlField(
label=_('Portrait'),
label=_('Address'),
validators=[InputRequired()],
render_kw={'rows': 3}
)

description = HtmlField(
label=_('Description'),
validators=[Optional()],
render_kw={'rows': 5}
)

agenda_items = ChosenSelectMultipleField(
label=_('Agenda Items'),
validators=[Optional()],
choices=[],
)

def on_request(self) -> None:

meetings = (self.request.session.query(MeetingItem)

Check warning on line 56 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L56

Added line #L56 was not covered by tests
.order_by(MeetingItem.number, MeetingItem.title)
.all())

self.agenda_items.choices = [

Check warning on line 60 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L60

Added line #L60 was not covered by tests
(item.id.hex, item.display_name())
for item in meetings
]

def populate_obj(
self,
obj: object,
exclude: Collection[str] | None = None,
include: Collection[str] | None = None
) -> None:
if not isinstance(obj, Meeting):
raise TypeError('Object must be a MeetingItem')

Check warning on line 72 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L71-L72

Added lines #L71 - L72 were not covered by tests

meeting: Meeting = obj

Check warning on line 74 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L74

Added line #L74 was not covered by tests
item: MeetingItem | None
super().populate_obj(obj, exclude=exclude, include=include)

Check warning on line 76 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L76

Added line #L76 was not covered by tests

meeting_item_ids = {item.id.hex for item in meeting.meeting_items}
new_item_ids = set(self.agenda_items.data or [])

Check warning on line 79 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L78-L79

Added lines #L78 - L79 were not covered by tests

items_to_add = new_item_ids - meeting_item_ids
for new_id in items_to_add:
item = (self.request.session.query(MeetingItem)

Check warning on line 83 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L81-L83

Added lines #L81 - L83 were not covered by tests
.filter(MeetingItem.id == new_id).one())
if item is not None:
meeting.meeting_items.append(item)

Check warning on line 86 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L85-L86

Added lines #L85 - L86 were not covered by tests

items_to_remove = meeting_item_ids - new_item_ids
for current_id in items_to_remove:
item = self.request.session.query(MeetingItem).get(current_id)
if item is not None:
meeting.meeting_items.remove(item)

Check warning on line 92 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L88-L92

Added lines #L88 - L92 were not covered by tests

def process_obj(self, obj: MeetingItem) -> None: # type: ignore[override]
if not isinstance(obj, Meeting):
raise TypeError('Object must be a MeetingItem')

Check warning on line 96 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L95-L96

Added lines #L95 - L96 were not covered by tests

super().process_obj(obj)

Check warning on line 98 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L98

Added line #L98 was not covered by tests

self.agenda_items.data = [

Check warning on line 100 in src/onegov/org/forms/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/org/forms/meeting.py#L100

Added line #L100 was not covered by tests
item.id.hex for item in obj.meeting_items
]
10 changes: 8 additions & 2 deletions src/onegov/parliament/collections/meeting.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
from __future__ import annotations

from functools import cached_property

from onegov.core.collection import GenericCollection
from onegov.parliament.models import Meeting
from onegov.town6 import _

from typing import TYPE_CHECKING

from onegov.parliament.models import Meeting

if TYPE_CHECKING:
from uuid import UUID
from sqlalchemy.orm import Query


class MeetingCollection(GenericCollection[Meeting]):

@cached_property
def title(self) -> str:
return _('Meeting')

Check warning on line 20 in src/onegov/parliament/collections/meeting.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/parliament/collections/meeting.py#L20

Added line #L20 was not covered by tests

@property
def model_class(self) -> type[Meeting]:
return Meeting
Expand Down
3 changes: 2 additions & 1 deletion src/onegov/parliament/models/meeting.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def title_text(self) -> str:
ForeignKey('par_political_businesses.id'),
)

# FIXME: is this used or covered by meeting_items?
#: list of political businesses, "Traktanden"
political_businesses: RelationshipProperty[PoliticalBusiness] = (
relationship(
Expand All @@ -97,7 +98,7 @@ def title_text(self) -> str:
'MeetingItem',
cascade='all, delete-orphan',
back_populates='meeting',
order_by='desc(MeetingItem.number)'
order_by='asc(MeetingItem.number)'
)

def __repr__(self) -> str:
Expand Down
3 changes: 3 additions & 0 deletions src/onegov/parliament/models/meeting_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,8 @@
back_populates='meeting_items'
)

def display_name(self) -> str:
return f'{self.number} {self.title}' if self.number else self.title

Check warning on line 75 in src/onegov/parliament/models/meeting_item.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/parliament/models/meeting_item.py#L75

Added line #L75 was not covered by tests

def __repr__(self) -> str:
return f'<Meeting Item {self.number} {self.title}>'
38 changes: 35 additions & 3 deletions src/onegov/town6/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,10 @@

class MeetingLayout(DefaultLayout):

@cached_property
def collection(self) -> MeetingCollection:
return MeetingCollection(self.request.session)

Check warning on line 1083 in src/onegov/town6/layout.py

View check run for this annotation

Codecov / codecov/patch

src/onegov/town6/layout.py#L1083

Added line #L1083 was not covered by tests

@cached_property
def title(self) -> str:
return self.model.title
Expand All @@ -1096,20 +1100,48 @@
]

@cached_property
def editbar_links(self) -> list[LinkGroup] | None:
def editbar_links(self) -> list[Link | LinkGroup] | None:
if self.request.is_manager:
return [
LinkGroup(
title=_('Add'),
links=[
Link(
text=_('Meeting'),
text=_('Parliamentarian'),
url=self.request.link(self.model, 'new'),
attrs={'class': 'new-meeting'},
attrs={'class': 'new-parliamentarian'},
),
],
),
Link(
text=_('Edit'),
url=self.request.link(self.model, 'edit'),
attrs={'class': 'edit-meeting'}
),
Link(
text=_('Delete'),
url=self.csrf_protected_url(
self.request.link(self.model)
),
attrs={'class': 'delete-meeting'},
traits=(
Confirm(
_(
'Do you really want to delete this meeting?'
),
_('This cannot be undone.'),
_('Delete meeting'),
_('Cancel')
),
Intercooler(
request_method='DELETE',
redirect_after=self.request.link(
self.collection)
)
)
)
]

return None


Expand Down
63 changes: 51 additions & 12 deletions src/onegov/town6/locale/de_CH/LC_MESSAGES/onegov.town6.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: OneGov Cloud 1.0\n"
"POT-Creation-Date: 2025-07-09 13:44+0200\n"
"POT-Creation-Date: 2025-07-07 15:20+0200\n"
"PO-Revision-Date: 2021-03-03 16:24+0100\n"
"Last-Translator: Lukas Burkhard <lukas.burkhard@seantis.ch>\n"
"Language-Team: German\n"
Expand Down Expand Up @@ -301,18 +301,27 @@ msgstr "Parlamentarierinnen und Parlamentarier"
msgid "Parliamentarian"
msgstr "Parlamentarier:in"

msgid "Role (as a party or group member)"
msgstr "Rolle (als Partei- oder Fraktionsmitglied)"

msgid "Edit"
msgstr "Bearbeiten"

msgid "Do you really want to delete this parliamentarian?"
msgstr "Möchten Sie diese:n Parlamentarier:in wirklich löschen?"
msgid "Do you really want to delete this meeting?"
msgstr "Diese Sitzung wirklich löschen?"

msgid "This cannot be undone."
msgstr "Dies kann nicht rückgängig gemacht werden."

msgid "Delete meeting"
msgstr "Sitzung löschen"

msgid "Parliamentarians"
msgstr "Parlamentarierinnen und Parlamentarier"

msgid "Role (as a party or group member)"
msgstr "Rolle (als Partei- oder Fraktionsmitglied)"

msgid "Do you really want to delete this parliamentarian?"
msgstr "Möchten Sie diese:n Parlamentarier:in wirklich löschen?"

msgid "Delete parliamentarian"
msgstr "Parlamentarier:in löschen"

Expand Down Expand Up @@ -2460,33 +2469,63 @@ msgstr "Neue Kommission"
msgid "Your changes were saved"
msgstr "Ihre Änderungen wurden gespeichert"

msgid "The commission has been deleted."
msgstr "Die Kommission wurde gelöscht."

msgid "Sort"
msgstr "Sortieren"

msgid "Added a new meeting."
msgstr "Neue Sitzung hinzugefügt"

msgid "New Meeting"
msgstr "Neue Sitzung"

msgid "Your changes were saved."
msgstr "Ihre Änderungen wurden gespeichert."

msgid "Edit Meeting"
msgstr "Sitzung bearbeiten"

msgid "The meeting has been deleted."
msgstr "Die Sitzung wurde gelöscht."

msgid "Added a new parliamentarian"
msgstr "Parlamentarier:in hinzugefügt"

msgid "New parliamentarian"
msgstr "Neue:r Parlamentarier:in"

msgid "The parliamentarian has been deleted."
msgstr "Der/die Parlamentarier:in wurde gelöscht."

msgid "Added a new role"
msgstr "Neue Rolle hinzugefügt"

msgid "New role"
msgstr "Neue Rolle"

msgid "The parliamentarian role has been deleted."
msgstr "Die Rolle des/der Parlamentarier:in wurde gelöscht."

msgid "Added a new parliamentary group"
msgstr "Fraktion hinzugefügt"

msgid "New parliamentary group"
msgstr "Neue Fraktion"

msgid "The parliamentary group has been deleted."
msgstr "Die Fraktion wurde gelöscht."

msgid "Added a new party"
msgstr "Partei hinzugefügt"

msgid "New party"
msgstr "Neue Partei"

msgid "The party has been deleted."
msgstr "Die Partei wurde gelöscht."

msgid "New Recipient"
msgstr "Neuer Empfänger"

Expand Down Expand Up @@ -2596,6 +2635,12 @@ msgstr "Ratsinformationssystem (RIS)"
msgid "New Note"
msgstr "Neue Notiz"

#~ msgid "The political business has been deleted."
#~ msgstr "Das politische Geschäft wurde gelöscht."

#~ msgid "Agenda Items"
#~ msgstr "Traktanden"

#~ msgid "Parliamentarian is not in this commission."
#~ msgstr "Parlamentarier:in ist nicht in dieser Kommission."

Expand Down Expand Up @@ -2629,12 +2674,6 @@ msgstr "Neue Notiz"
#~ msgid "End must be after start"
#~ msgstr "Ende muss nach dem Start liegen"

#~ msgid "Do you really want to delete this meeting?"
#~ msgstr "Diese Sitzung wirklich löschen?"

#~ msgid "Delete meeting"
#~ msgstr "Sitzung löschen"

#~ msgid "Do you really want to remove this parliamentarian?"
#~ msgstr "Diese:n Parlamentarier:in wirklich entfernen?"

Expand Down
Loading
Loading