Skip to content

Commit

Permalink
PAS: Add rate sets, settlement runs and changes.
Browse files Browse the repository at this point in the history
TYPE: Feature
LINK: OGC-1503
  • Loading branch information
msom committed Jul 16, 2024
1 parent e22b65d commit 4aa7f49
Show file tree
Hide file tree
Showing 65 changed files with 3,191 additions and 180 deletions.
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ install_requires =
requests
rjsmin
sedate
sentry_sdk
sentry_sdk<2.10.0
sortedcontainers
sqlalchemy<1.4.0
sqlalchemy-utils
Expand Down
2 changes: 1 addition & 1 deletion src/onegov/org/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def is_editor(self) -> bool:

@property
def current_username(self) -> str | None:
return self.identity and self.identity.userid or None
return self.identity .userid if self.identity else None

@cached_property
def current_user(self) -> User | None:
Expand Down
8 changes: 7 additions & 1 deletion src/onegov/pas/collections/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from onegov.pas.collections.attendence import AttendenceCollection
from onegov.pas.collections.change import ChangeCollection
from onegov.pas.collections.commission import CommissionCollection
from onegov.pas.collections.commission_membership import (
CommissionMembershipCollection)
Expand All @@ -10,14 +11,19 @@
from onegov.pas.collections.parliamentary_group import (
ParliamentaryGroupCollection)
from onegov.pas.collections.party import PartyCollection
from onegov.pas.collections.rate_set import RateSetCollection
from onegov.pas.collections.settlement_run import SettlementRunCollection

__all__ = (
'AttendenceCollection',
'ChangeCollection',
'CommissionCollection',
'CommissionMembershipCollection',
'LegislativePeriodCollection',
'ParliamentarianCollection',
'ParliamentarianRoleCollection',
'ParliamentaryGroupCollection',
'PartyCollection'
'PartyCollection',
'RateSetCollection',
'SettlementRunCollection'
)
17 changes: 17 additions & 0 deletions src/onegov/pas/collections/change.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from onegov.core.collection import GenericCollection
from onegov.pas.models import Change
from sqlalchemy import desc

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from sqlalchemy.orm import Query


class ChangeCollection(GenericCollection[Change]):

@property
def model_class(self) -> type[Change]:
return Change

def query(self) -> 'Query[Change]':
return super().query().order_by(desc(Change.last_change))
7 changes: 0 additions & 7 deletions src/onegov/pas/collections/commission_membership.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
from onegov.core.collection import GenericCollection
from onegov.pas.models import CommissionMembership

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from sqlalchemy.orm import Query


class CommissionMembershipCollection(GenericCollection[CommissionMembership]):

@property
def model_class(self) -> type[CommissionMembership]:
return CommissionMembership

def query(self) -> 'Query[CommissionMembership]':
return super().query()
8 changes: 1 addition & 7 deletions src/onegov/pas/collections/legislative_period.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from datetime import date
from onegov.core.collection import GenericCollection
from onegov.pas.models import LegislativePeriod
from sqlalchemy import or_

from typing import TYPE_CHECKING
if TYPE_CHECKING:
Expand Down Expand Up @@ -29,12 +28,7 @@ def query(self) -> 'Query[LegislativePeriod]':

if self.active is not None:
if self.active:
query = query.filter(
or_(
LegislativePeriod.end.is_(None),
LegislativePeriod.end >= date.today()
)
)
query = query.filter(LegislativePeriod.end >= date.today())
else:
query = query.filter(LegislativePeriod.end < date.today())

Expand Down
7 changes: 0 additions & 7 deletions src/onegov/pas/collections/parliamentarian_role.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
from onegov.core.collection import GenericCollection
from onegov.pas.models import ParliamentarianRole

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from sqlalchemy.orm import Query


class ParliamentarianRoleCollection(GenericCollection[ParliamentarianRole]):

@property
def model_class(self) -> type[ParliamentarianRole]:
return ParliamentarianRole

def query(self) -> 'Query[ParliamentarianRole]':
return super().query()
42 changes: 42 additions & 0 deletions src/onegov/pas/collections/rate_set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from datetime import date
from onegov.core.collection import GenericCollection
from onegov.pas.models import RateSet

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from sqlalchemy.orm import Query
from sqlalchemy.orm import Session
from typing_extensions import Self


class RateSetCollection(GenericCollection[RateSet]):

def __init__(
self,
session: 'Session',
active: bool | None = None
):
super().__init__(session)
self.active = active

@property
def model_class(self) -> type[RateSet]:
return RateSet

def query(self) -> 'Query[RateSet]':
query = super().query()

if self.active is not None:
year = date.today().year
if self.active:
query = query.filter(RateSet.year == year)
else:
query = query.filter(RateSet.year != year)

return query.order_by(RateSet.year.desc())

def for_filter(
self,
active: bool | None = None
) -> 'Self':
return self.__class__(self.session, active)
37 changes: 37 additions & 0 deletions src/onegov/pas/collections/settlement_run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from onegov.core.collection import GenericCollection
from onegov.pas.models import SettlementRun

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from sqlalchemy.orm import Query
from sqlalchemy.orm import Session
from typing_extensions import Self


class SettlementRunCollection(GenericCollection[SettlementRun]):

def __init__(
self,
session: 'Session',
active: bool | None = None
):
super().__init__(session)
self.active = active

@property
def model_class(self) -> type[SettlementRun]:
return SettlementRun

def query(self) -> 'Query[SettlementRun]':
query = super().query()

if self.active is not None:
query = query.filter(SettlementRun.active.is_(self.active))

return query.order_by(SettlementRun.start.desc())

def for_filter(
self,
active: bool | None = None
) -> 'Self':
return self.__class__(self.session, active)
41 changes: 8 additions & 33 deletions src/onegov/pas/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
from onegov.org.elements import LinkGroup
from onegov.pas import _
from onegov.pas.collections import AttendenceCollection
from onegov.pas.collections import CommissionCollection
from onegov.pas.collections import LegislativePeriodCollection
from onegov.pas.collections import ParliamentarianCollection
from onegov.pas.collections import ParliamentaryGroupCollection
from onegov.pas.collections import PartyCollection
from onegov.pas.collections import ChangeCollection
from onegov.user import Auth
from onegov.user import UserCollection

from typing import TYPE_CHECKING
if TYPE_CHECKING:
Expand Down Expand Up @@ -47,37 +42,17 @@ def get_global_tools(request: 'TownRequest') -> 'Iterator[Link | LinkGroup]':
attrs={'class': 'attendences'}
),
Link(
_("Parliamentarians"),
request.class_link(ParliamentarianCollection),
attrs={'class': 'parliamentarians'}
_("Changes"),
request.class_link(ChangeCollection),
attrs={'class': 'changes'}
),
Link(
_("Commissions"),
request.class_link(CommissionCollection),
attrs={'class': 'commissions'}
_("PAS settings"),
request.link(request.app.org, 'pas-settings'),
attrs={'class': 'pas-settings'}
),
Link(
_("Legislative periods"),
request.class_link(LegislativePeriodCollection),
attrs={'class': 'legislative-periods'}
),
Link(
_("Parliamentary groups"),
request.class_link(ParliamentaryGroupCollection),
attrs={'class': 'parliamentary-groups'}
),
Link(
_("Parties"),
request.class_link(PartyCollection),
attrs={'class': 'parties'}
),
Link(
_("Users"),
request.class_link(UserCollection),
attrs={'class': 'user'}
),
Link(
_("Settings"),
_("More settings"),
request.link(request.app.org, 'settings'),
attrs={'class': 'settings'}
),
Expand Down
4 changes: 4 additions & 0 deletions src/onegov/pas/forms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from onegov.pas.forms.parliamentarian_role import ParliamentarianRoleForm
from onegov.pas.forms.parliamentary_group import ParliamentaryGroupForm
from onegov.pas.forms.party import PartyForm
from onegov.pas.forms.rate_set import RateSetForm
from onegov.pas.forms.settlement_run import SettlementRunForm


__all__ = (
Expand All @@ -25,4 +27,6 @@
'ParliamentarianRoleForm',
'ParliamentaryGroupForm',
'PartyForm',
'RateSetForm',
'SettlementRunForm'
)
52 changes: 36 additions & 16 deletions src/onegov/pas/forms/attendence.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from onegov.pas import _
from onegov.pas.collections import CommissionCollection
from onegov.pas.collections import ParliamentarianCollection
from onegov.pas.models import SettlementRun
from onegov.pas.models.attendence import TYPES
from wtforms.fields import DateField
from wtforms.fields import FloatField
Expand All @@ -15,11 +16,37 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Collection
from onegov.core.request import CoreRequest
from onegov.pas.models import Attendence
from typing import Any


class AttendenceForm(Form):
class SettlementRunBoundMixin:

if TYPE_CHECKING:
# forward declaration of required attributes
date: DateField
request: 'CoreRequest'

def ensure_date(self) -> bool:
if self.date.data:
query = self.request.session.query(SettlementRun)
query = query.filter(
SettlementRun.active == True,
SettlementRun.start <= self.date.data,
SettlementRun.end >= self.date.data,
)
if not query.first():
assert isinstance(self.date.errors, list)
self.date.errors.append(
_("No within an active settlement run.")
)
return False

return True


class AttendenceForm(Form, SettlementRunBoundMixin):

date = DateField(
label=_('Date'),
Expand Down Expand Up @@ -50,18 +77,10 @@ class AttendenceForm(Form):
depends_on=('type', '!plenary'),
)

def validate(self) -> bool: # type:ignore[override]
result = super().validate()

if self.type.data != 'plenary' and not self.commission_id.data:
assert isinstance(self.commission_id.errors, list)
self.commission_id.errors.append(
_("Please select a commission.")
)
result = False

def ensure_commission(self) -> bool:
if (
self.type.data != 'plenary'
self.type.data
and self.type.data != 'plenary'
and self.commission_id.data
and self.parliamentarian_id.data
):
Expand All @@ -77,8 +96,9 @@ def validate(self) -> bool: # type:ignore[override]
self.commission_id.errors.append(
_("Parliamentarian is not in this commission.")
)
result = False
return result
return False

return True

def process_obj(self, obj: 'Attendence') -> None: # type:ignore
super().process_obj(obj)
Expand Down Expand Up @@ -129,7 +149,7 @@ def on_request(self) -> None:
]


class AttendenceAddPlenaryForm(Form):
class AttendenceAddPlenaryForm(Form, SettlementRunBoundMixin):

date = DateField(
label=_('Date'),
Expand Down Expand Up @@ -163,7 +183,7 @@ def on_request(self) -> None:
]


class AttendenceAddCommissionForm(Form):
class AttendenceAddCommissionForm(Form, SettlementRunBoundMixin):

date = DateField(
label=_('Date'),
Expand Down
Loading

0 comments on commit 4aa7f49

Please sign in to comment.