Source code for landsgemeinde.models.suggestion

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:
[docs] self.session = session
[docs] self.term = term
[docs] self.limit = 5
@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)