Source code for form.models.survey_window

from __future__ import annotations

import sedate

from datetime import date, datetime
from onegov.core.orm import Base
from onegov.core.orm.mixins import TimestampMixin
from onegov.form.models.submission import SurveySubmission
from sqlalchemy import ForeignKey
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped
from sqlalchemy.schema import CheckConstraint
from uuid import uuid4, UUID


from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from onegov.form.models.definition import SurveyDefinition


[docs] class SurveySubmissionWindow(Base, TimestampMixin): """ Defines a submission window during which a survey definition may be used to create submissions. Submissions created thusly are attached to the currently active survey window. """
[docs] __tablename__ = 'submission_windows'
#: the public id of the submission window
[docs] id: Mapped[UUID] = mapped_column( primary_key=True, default=uuid4 )
#: the name of the survey to which this submission window belongs
[docs] name: Mapped[str] = mapped_column(ForeignKey('surveys.name'))
#: the title of the submission window
[docs] title: Mapped[str | None]
#: the survey to which this submission window belongs
[docs] survey: Mapped[SurveyDefinition] = relationship( back_populates='submission_windows' )
#: true if the submission window is enabled
[docs] enabled: Mapped[bool] = mapped_column(default=True)
#: the start date of the window
[docs] start: Mapped[date]
#: the end date of the window
[docs] end: Mapped[date]
#: the timezone of the window
[docs] timezone: Mapped[str] = mapped_column(default='Europe/Zurich')
#: submissions linked to this
[docs] submissions: Mapped[list[SurveySubmission]] = relationship( back_populates='submission_window' )
[docs] __table_args__ = ( # ensures that start <= end CheckConstraint( '"start" <= "end"', name='start_smaller_than_end' ), )
@property
[docs] def localized_start(self) -> datetime: return sedate.align_date_to_day( sedate.standardize_date( sedate.as_datetime(self.start), self.timezone ), self.timezone, 'down' )
@property
[docs] def localized_end(self) -> datetime: return sedate.align_date_to_day( sedate.standardize_date( sedate.as_datetime(self.end), self.timezone ), self.timezone, 'up' )
@property
[docs] def in_the_future(self) -> bool: return sedate.utcnow() <= self.localized_start
@property
[docs] def in_the_past(self) -> bool: return self.localized_end <= sedate.utcnow()
@property
[docs] def in_the_present(self) -> bool: return self.localized_start <= sedate.utcnow() <= self.localized_end
[docs] def accepts_submissions(self) -> bool: if not self.enabled: return False if not self.in_the_present: return False return True