Source code for pas.models.settlement_run

from __future__ import annotations

from datetime import date
from onegov.core.orm import Base
from onegov.core.orm.mixins import content_property
from onegov.core.orm.mixins import dict_property
from onegov.core.orm.mixins import ContentMixin
from onegov.core.orm.mixins import TimestampMixin
from onegov.pas.i18n import _
from onegov.search import ORMSearchable
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import Mapped
from uuid import uuid4
from uuid import UUID


from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from sqlalchemy.sql import ColumnElement


[docs] class SettlementRun(Base, ContentMixin, TimestampMixin, ORMSearchable): """ Abrechnungslauf """
[docs] __tablename__ = 'pas_settlements'
[docs] fts_type_title = _('Settlement runs')
[docs] fts_public = False
[docs] fts_title_property = 'name'
[docs] fts_properties = {'name': {'type': 'text', 'weight': 'A'}}
@property
[docs] def title(self) -> str: return self.name
#: Internal ID
[docs] id: Mapped[UUID] = mapped_column( primary_key=True, default=uuid4 )
#: the name
[docs] name: Mapped[str]
#: The start date
[docs] start: Mapped[date]
#: The end date
[docs] end: Mapped[date]
#: Whether this settlement run is closed
[docs] closed: Mapped[bool] = mapped_column(default=False)
#: The description
[docs] description: dict_property[str | None] = content_property()
@hybrid_property
[docs] def active(self) -> bool: return not self.closed
@active.inplace.setter def _active_setter(self, value: bool) -> None: self.closed = not value @active.inplace.expression @classmethod
[docs] def _active_expression(cls) -> ColumnElement[bool]: return ~cls.closed
@classmethod
[docs] def get_run_number_for_year(cls, input_date: date) -> int: """ Computes the run number for a given date within a year. As per customer requirement: No rule mandates 4 payments yearly, but wages must be reported by the 10th. Run breakdown: - Q1: January to March - Q2: April to June - Q3: July to September - Q4: October to November - Q5: December Why 5 runs? The decision to split the fourth quarter ensures that settlement runs are confined to a single calendar year. This avoids situations where a settlement overlaps into two different years, which could cause issues due to differing cost-of-living adjustments (COLA) applicable to each year. Handling settlements across two fiscal years would increase complexity. Thus, we have 5 yearly runs. """ month = input_date.month if 1 <= month <= 3: # January to March return 1 elif 4 <= month <= 6: # April to June return 2 elif 7 <= month <= 9: # July to September return 3 elif 10 <= month <= 11: # October to November return 4 elif month == 12: # December return 5 else: raise ValueError( f'Invalid month: {month}. Date must be within a valid year.' )
[docs] def __repr__(self) -> str: return f'<SettlementRun {self.name} {self.start} {self.end} >'