from onegov.core.orm import Base
from onegov.core.orm.mixins import TimestampMixin
from onegov.core.orm.types import UUID
from onegov.election_day.models.vote.mixins import DerivedAttributesMixin
from onegov.election_day.models.vote.mixins import DerivedBallotsCountMixin
from sqlalchemy import Boolean
from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import Text
from sqlalchemy.orm import relationship
from uuid import uuid4
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import uuid
from onegov.election_day.models import Ballot
[docs]
class BallotResult(Base, TimestampMixin, DerivedAttributesMixin,
DerivedBallotsCountMixin):
""" The result of a specific ballot. Each ballot may have multiple
results. Those results may be aggregated or not.
"""
[docs]
__tablename__ = 'ballot_results'
#: identifies the result, may be used in the url
[docs]
id: 'Column[uuid.UUID]' = Column(
UUID, # type:ignore[arg-type]
primary_key=True,
default=uuid4
)
#: The entity id (e.g. BFS number).
[docs]
entity_id: 'Column[int]' = Column(Integer, nullable=False)
#: the name of the entity
[docs]
name: 'Column[str]' = Column(Text, nullable=False)
#: the district this entity belongs to
[docs]
district: 'Column[str | None]' = Column(Text, nullable=True)
#: True if the result has been counted and no changes will be made anymore.
#: If the result is definite, all the values below must be specified.
[docs]
counted: 'Column[bool]' = Column(Boolean, nullable=False)
#: number of yeas, in case of variants, the number of yeas for the first
#: option of the tie breaker
[docs]
yeas: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0)
#: number of nays, in case of variants, the number of nays for the first
#: option of the tie breaker (so a yay for the second option)
[docs]
nays: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0)
#: number of empty votes
[docs]
empty: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0)
#: number of invalid votes
[docs]
invalid: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0)
#: number of eligible voters
[docs]
eligible_voters: 'Column[int]' = Column(
Integer,
nullable=False,
default=lambda: 0
)
#: number of expats
[docs]
expats: 'Column[int | None]' = Column(Integer, nullable=True)
#: the id of the ballot this result belongs to
[docs]
ballot_id: 'Column[uuid.UUID]' = Column(
UUID, # type:ignore[arg-type]
ForeignKey('ballots.id', ondelete='CASCADE'),
nullable=False
)
#: the ballot this result belongs to
[docs]
ballot: 'relationship[Ballot]' = relationship(
'Ballot',
back_populates='results'
)