from onegov.landsgemeinde.models import AgendaItem
from onegov.landsgemeinde.models import Assembly
from onegov.landsgemeinde.models import Votum
from onegov.people import Person
from sqlalchemy import func
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from sqlalchemy.orm import Session
from sqlalchemy.sql import ColumnElement
[docs]
class Suggestion:
""" Provide suggestions based on entries in the directory of persons and
past vota.
"""
def __init__(self, session: 'Session', term: str | None = '') -> None:
@property
[docs]
def votum_expression(
self
) -> 'ColumnElement[str] | ColumnElement[str | None]':
raise NotImplementedError()
@property
[docs]
def person_expressions(
self
) -> tuple['ColumnElement[str] | ColumnElement[str | None]', ...]:
raise NotImplementedError()
[docs]
def query(self) -> list[str]:
result: list[str] = []
if not self.term:
return result
for expression in self.person_expressions:
query = self.session.query(expression)
query = query.filter(
expression.isnot(None),
func.trim(expression) != '',
)
if self.term:
query = query.filter(
expression.ilike(f'%{self.term}%')
)
query = query.order_by(expression)
query = query.limit(self.limit)
result.extend(r[0] for r in query)
result = sorted(set(result))
query = self.session.query(self.votum_expression)
query = query.join(AgendaItem)
query = query.join(Assembly)
query = query.filter(
self.votum_expression.isnot(None),
func.trim(self.votum_expression) != '',
)
if self.term:
query = query.filter(
self.votum_expression.ilike(f'%{self.term}%')
)
query = query.order_by(
Assembly.date.desc(),
self.votum_expression
)
query = query.limit(self.limit)
result.extend(
x for x in dict.fromkeys(r[0] for r in query).keys()
if x not in result
)
return result
[docs]
class PersonNameSuggestion(Suggestion):
@property
[docs]
def votum_expression(self) -> 'ColumnElement[str | None]':
return Votum.person_name
@property
[docs]
def person_expressions(self) -> tuple['ColumnElement[str]']:
return (func.concat(Person.first_name, ' ', Person.last_name),)
[docs]
class PersonFunctionSuggestion(Suggestion):
@property
[docs]
def votum_expression(self) -> 'ColumnElement[str | None]':
return Votum.person_function
@property
[docs]
def person_expressions(self) -> tuple['ColumnElement[str | None]', ...]:
return (Person.function, Person.profession)
[docs]
class PersonPlaceSuggestion(Suggestion):
@property
[docs]
def votum_expression(self) -> 'ColumnElement[str | None]':
return Votum.person_place
@property
[docs]
def person_expressions(self) -> tuple['ColumnElement[str | None]', ...]:
return (Person.postal_code_city, Person.location_code_city)
[docs]
class PersonPoliticalAffiliationSuggestion(Suggestion):
@property
[docs]
def votum_expression(self) -> 'ColumnElement[str | None]':
return Votum.person_political_affiliation
@property
[docs]
def person_expressions(self) -> tuple['ColumnElement[str | None]', ...]:
return (Person.parliamentary_group, Person.political_party)