from __future__ import annotations
from sqlalchemy import func
from sqlalchemy.orm import joinedload
from onegov.core.elements import Link
from onegov.core.security import Public, Private
from onegov.org.forms.political_business import PoliticalBusinessForm
from onegov.org.models import Meeting
from onegov.org.models import MeetingItem
from onegov.org.models import PoliticalBusiness
from onegov.org.models import PoliticalBusinessCollection
from onegov.org.models import PoliticalBusinessParticipationCollection
from onegov.org.models import PoliticalBusinessParticipation
from onegov.org.models.political_business import POLITICAL_BUSINESS_STATUS
from onegov.org.models.political_business import POLITICAL_BUSINESS_TYPE
from onegov.town6 import _
from onegov.town6 import TownApp
from onegov.town6.layout import PoliticalBusinessCollectionLayout
from onegov.town6.layout import PoliticalBusinessLayout
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from onegov.core.types import RenderData
from onegov.town6.request import TownRequest
from webob.response import Response
[docs]
def count_political_businesses_by_type(
request: TownRequest
) -> dict[str, int]:
session = request.session
result = session.query(
PoliticalBusiness.political_business_type,
func.count(PoliticalBusiness.id).label('count')
).group_by(PoliticalBusiness.political_business_type).all()
return dict(result)
[docs]
def count_political_businesses_by_status(
request: TownRequest
) -> dict[str, int]:
session = request.session
result = session.query(
PoliticalBusiness.status,
func.count(PoliticalBusiness.id).label('count')
).group_by(PoliticalBusiness.status).all()
return dict(result)
[docs]
def count_political_businesses_by_year(
request: TownRequest
) -> dict[str, int]:
session = request.session
result = session.query(
func.extract('year', PoliticalBusiness.entry_date).label('year'),
func.count(PoliticalBusiness.id).label('count')
).group_by(func.extract('year', PoliticalBusiness.entry_date)).all()
# convert decimal to string
return {
str(int(year)): count for year, count in result
}
@TownApp.html(
model=PoliticalBusinessCollection,
template='political_businesses.pt',
permission=Public,
)
[docs]
def view_political_businesses(
self: PoliticalBusinessCollection,
request: TownRequest,
layout: PoliticalBusinessCollectionLayout | None = None
) -> RenderData | Response:
count_per_business_type = count_political_businesses_by_type(request)
types = sorted((
Link(
text=request.translate(text) +
f' ({count_per_business_type[type_]})',
active=type_ in self.types,
url=request.link(self.for_filter(type=type_)),
)
for type_, text in POLITICAL_BUSINESS_TYPE.items()
if count_per_business_type.get(type_, 0) > 0
), key=lambda x: (x.text or '').lower())
count_per_status = count_political_businesses_by_status(request)
status = sorted((
Link(
text=request.translate(text) +
f' ({count_per_status[status]})',
active=status in self.status,
url=request.link(self.for_filter(status=status)),
)
for status, text in POLITICAL_BUSINESS_STATUS.items()
if count_per_status.get(status, 0) > 0
), key=lambda x: (x.text or '').lower())
count_per_year = count_political_businesses_by_year(request)
years = (
Link(
text=str(year_int) + f' ({count_per_year[str(year_int)]})',
active=year_int in self.years,
url=request.link(self.for_filter(year=year_int)),
)
for year_int in self.years_for_entries()
if count_per_year.get(str(year_int), 0) > 0
)
return {
# 'add_link': request.link(self, name='new'),
'layout': layout or PoliticalBusinessCollectionLayout(self, request),
'title': _('Political Businesses'),
'businesses': self.batch,
'type_map': POLITICAL_BUSINESS_TYPE,
'status_map': POLITICAL_BUSINESS_STATUS,
'business_types': types,
'business_status': status,
'years': years,
}
@TownApp.form(
model=PoliticalBusinessCollection,
name='new',
template='form.pt',
permission=Private,
form=get_political_business_form_class
)
[docs]
def view_add_political_business(
self: PoliticalBusinessCollection,
request: TownRequest,
form: PoliticalBusinessForm,
) -> RenderData | Response:
layout = PoliticalBusinessCollectionLayout(self, request)
if form.submitted(request):
political_business = self.add(
title=form.title.data,
political_business_type=form.political_business_type.data,
)
form.populate_obj(political_business)
request.success(_('Added a new political business'))
return request.redirect(request.link(political_business))
layout.breadcrumbs.append(Link(_('New'), '#'))
layout.edit_mode = True
return {
'layout': layout,
'title': _('New political business'),
'form': form,
'form_width': 'large',
}
@TownApp.form(
model=PoliticalBusiness,
name='edit',
template='form.pt',
permission=Private,
form=get_political_business_form_class,
pass_model=True
)
[docs]
def edit_political_business(
self: PoliticalBusiness,
request: TownRequest,
form: PoliticalBusinessForm,
) -> RenderData | Response:
layout = PoliticalBusinessLayout(self, request)
if form.submitted(request):
form.populate_obj(self)
request.success(_('Your changes were saved'))
return request.redirect(request.link(self))
layout.breadcrumbs.append(Link(_('Edit'), '#'))
layout.editbar_links = []
layout.edit_mode = True
return {
'layout': layout,
'title': layout.title,
'form': form,
'form_width': 'large',
}
@TownApp.html(
model=PoliticalBusiness,
template='political_business.pt',
permission=Public,
)
[docs]
def view_political_business(
self: PoliticalBusiness,
request: TownRequest,
) -> RenderData | Response:
layout = PoliticalBusinessLayout(self, request)
groups = [self.parliamentary_group] if self.parliamentary_group else []
participations = self.participants
participations.sort(key=lambda x: x.parliamentarian.title)
participations.sort(key=lambda x: x.participant_type or '', reverse=True)
# sort meeting items of this business
items = (
request.session.query(MeetingItem)
.join(Meeting, Meeting.id == MeetingItem.meeting_id)
.filter(MeetingItem.political_business_id == self.id)
.options(joinedload(MeetingItem.meeting))
.order_by(Meeting.start_datetime.desc())
.all()
)
self.meeting_items = items
return {
'layout': layout,
'business': self,
'title': self.title,
'participations': participations,
'type_map': POLITICAL_BUSINESS_TYPE,
'status_map': POLITICAL_BUSINESS_STATUS,
'files': getattr(self, 'files', None),
'political_groups': groups,
}
@TownApp.view(
model=PoliticalBusiness,
request_method='DELETE',
permission=Private,
)
[docs]
def delete_political_business(
self: PoliticalBusiness,
request: TownRequest,
) -> None:
request.assert_valid_csrf_token()
# delete participations first
participations = PoliticalBusinessParticipationCollection(request.session)
participations.query().filter(
PoliticalBusinessParticipation.political_business_id == self.id
).delete(synchronize_session=False)
collection = PoliticalBusinessCollection(request.session)
collection.delete(self)