Source code for feriennet.layout

from functools import cached_property

from onegov.activity import Activity, PeriodCollection, Occasion
from onegov.activity import BookingCollection
from onegov.core.elements import Link, Confirm, Intercooler, Block
from onegov.core.elements import LinkGroup
from onegov.core.utils import linkify, paragraphify
from onegov.feriennet import _
from onegov.feriennet import security
from onegov.feriennet.collections import BillingCollection
from onegov.feriennet.collections import NotificationTemplateCollection
from onegov.feriennet.collections import OccasionAttendeeCollection
from onegov.feriennet.collections import VacationActivityCollection
from onegov.feriennet.const import OWNER_EDITABLE_STATES
from onegov.feriennet.models import InvoiceAction, VacationActivity
from onegov.org.layout import DefaultLayout as BaseLayout
from onegov.pay import PaymentProviderCollection
from onegov.ticket import TicketCollection


from typing import Any, NamedTuple, TYPE_CHECKING
if TYPE_CHECKING:
    from collections.abc import Iterator, Sequence
    from markupsafe import Markup
    from onegov.activity.models import (
        Attendee, Booking, Period, PublicationRequest)
    from onegov.activity.collections import (
        InvoiceCollection, VolunteerCollection)
    from onegov.core.elements import Trait
    from onegov.feriennet.app import FeriennetApp
    from onegov.feriennet.models import NotificationTemplate
    from onegov.feriennet.request import FeriennetRequest
    from onegov.org.models import Organisation
    from onegov.ticket import Ticket
    from onegov.user import User


[docs] class DefaultLayout(BaseLayout):
[docs] app: 'FeriennetApp'
[docs] request: 'FeriennetRequest'
@property
[docs] def is_owner(self) -> bool: if not self.request.current_username: return False return security.is_owner(self.request.current_username, self.model)
@property
[docs] def is_editable(self) -> bool: if self.request.is_admin: return True if not self.request.is_organiser: return False if isinstance(self.model, Activity): return self.model.state in OWNER_EDITABLE_STATES if isinstance(self.model, Occasion): return self.model.activity.state in OWNER_EDITABLE_STATES return True
[docs] def linkify(self, text: str | None) -> 'Markup': # type:ignore[override] return linkify(text)
[docs] def paragraphify(self, text: str) -> 'Markup': return paragraphify(text)
[docs] class VacationActivityCollectionLayout(DefaultLayout):
[docs] model: VacationActivityCollection
if TYPE_CHECKING: def __init__( self, model: VacationActivityCollection, request: 'FeriennetRequest' ) -> None: ... @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link(_('Activities'), self.request.class_link( VacationActivityCollection)), ]
@property @property @cached_property
[docs] class BookingCollectionLayout(DefaultLayout):
[docs] model: BookingCollection
def __init__( self, model: BookingCollection, request: 'FeriennetRequest', user: 'User | None' = None ) -> None: super().__init__(model, request) if user is None: user = request.current_user assert user is not None
[docs] self.user = user
@cached_property
[docs] def title(self) -> str: wishlist_phase = (self.app.active_period and self.app.active_period.wishlist_phase) if self.user.username == self.request.current_username: return wishlist_phase and _('Wishlist') or _('Bookings') elif wishlist_phase: return _('Wishlist of ${user}', mapping={ 'user': self.user.title }) else: return _('Bookings of ${user}', mapping={ 'user': self.user.title })
@cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link(self.title, self.request.link(self.model)) ]
[docs] class GroupInviteLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: wishlist_phase = (self.app.active_period and self.app.active_period.wishlist_phase) if self.request.is_logged_in: return [ Link(_('Homepage'), self.homepage_url), Link( wishlist_phase and _('Wishlist') or _('Bookings'), self.request.class_link(BookingCollection) ), Link(_('Group'), '#') ] else: return [ Link(_('Homepage'), self.homepage_url), Link(_('Group'), '#') ]
[docs] class VacationActivityFormLayout(DefaultLayout):
[docs] model: VacationActivity | VacationActivityCollection
def __init__( self, model: VacationActivity | VacationActivityCollection, request: 'FeriennetRequest', title: str ) -> None: super().__init__(model, request) self.include_editor()
[docs] self.title = title
@cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), # FIXME: This breadcrumb seems wrong for VacationActivity Link(_('Activities'), self.request.link(self.model)), Link(self.title, '#') ]
@cached_property
[docs] class OccasionFormLayout(DefaultLayout):
[docs] model: Activity
def __init__( self, model: Activity, request: 'FeriennetRequest', title: str ) -> None: assert isinstance(model, Activity) super().__init__(model, request)
[docs] self.title = title
@cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link(_('Activities'), self.request.class_link( VacationActivityCollection)), Link(self.model.title, self.request.link(self.model)), Link(self.title, '#') ]
@cached_property
[docs] class VacationActivityLayout(DefaultLayout):
[docs] model: VacationActivity
if TYPE_CHECKING: def __init__( self, model: VacationActivity, request: 'FeriennetRequest' ) -> None: ... @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link(_('Activities'), self.request.class_link( VacationActivityCollection)), Link(self.model.title, self.request.link(self.model)) ]
@cached_property
[docs] def latest_request(self) -> 'PublicationRequest | None': return self.model.latest_request
@cached_property
[docs] def ticket(self) -> 'Ticket | None': if self.latest_request: tickets = TicketCollection(self.request.session) return tickets.by_handler_id(self.latest_request.id.hex) return None
@cached_property
[docs] def attendees(self) -> OccasionAttendeeCollection | None: if self.request.app.default_period: return OccasionAttendeeCollection( self.request.session, self.request.app.default_period, self.model ) return None
@cached_property
[docs] class PeriodCollectionLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link(_('Manage Periods'), '#') ]
@cached_property
[docs] class PeriodFormLayout(DefaultLayout):
[docs] model: 'Period | PeriodCollection'
def __init__( self, model: 'Period | PeriodCollection', request: 'FeriennetRequest', title: str ) -> None: super().__init__(model, request)
[docs] self.title = title
@cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link( _('Manage Periods'), self.request.class_link(PeriodCollection) ), Link(self.title, '#') ]
@cached_property
[docs] class MatchCollectionLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link(_('Matches'), '#') ]
[docs] class BillingCollectionLayout(DefaultLayout):
[docs] model: BillingCollection
if TYPE_CHECKING: def __init__( self, model: BillingCollection, request: 'FeriennetRequest' ) -> None: ...
[docs] class FamilyRow(NamedTuple):
[docs] text: str
[docs] item: str
[docs] count: int # type:ignore[assignment]
[docs] has_online_payments: bool
@property
[docs] def families(self) -> 'Iterator[FamilyRow]': yield from self.app.session().execute(""" SELECT text || ' (' || replace(avg(unit * quantity)::money::text, '$', '') || ' CHF)' AS text , MIN(id::text) AS item, COUNT(*) AS count, family IN ( SELECT DISTINCT(family) FROM invoice_items WHERE source IS NOT NULL and source != 'xml' ) AS has_online_payments FROM invoice_items WHERE family IS NOT NULL GROUP BY family, text ORDER BY text """)
@property @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link(_('Billing'), '#') ]
@cached_property
[docs] class OnlinePaymentsLayout(DefaultLayout): def __init__( self, model: Any, request: 'FeriennetRequest', title: str ) -> None:
[docs] self.title = title
super().__init__(model, request) @cached_property @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link( _('Billing'), self.request.class_link(BillingCollection) ), Link(self.title, '#') ]
[docs] class BillingCollectionImportLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link(_('Billing'), self.request.link(self.model)), Link(_('Import Bank Statement'), '#') ]
[docs] class BillingCollectionManualBookingLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link(_('Billing'), self.request.link(self.model)), Link(_('Manual Booking'), '#') ]
[docs] class BillingCollectionPaymentWithDateLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link(_('Billing'), self.request.link(self.model)), Link(_('Payment with date'), '#') ]
[docs] class InvoiceLayout(DefaultLayout): def __init__( self, model: Any, request: 'FeriennetRequest', title: str ) -> None: super().__init__(model, request)
[docs] self.title = title
@cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link(self.title, '#') ]
[docs] class DonationLayout(DefaultLayout): def __init__( self, model: 'InvoiceCollection', request: 'FeriennetRequest', title: str ) -> None: super().__init__(model, request)
[docs] self.title = title
@cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link(_('Invoices'), self.request.link(self.model)), Link(_('Donation'), self.title) ]
[docs] class OccasionAttendeeLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link( self.model.activity.title, self.request.link(self.model.activity) ), Link(_('Attendees'), '#') ]
[docs] class NotificationTemplateCollectionLayout(DefaultLayout):
[docs] model: NotificationTemplateCollection
def __init__( self, model: NotificationTemplateCollection, request: 'FeriennetRequest', subtitle: str | None = None ) -> None: super().__init__(model, request)
[docs] self.subtitle = subtitle
self.include_editor() @cached_property
[docs] def breadcrumbs(self) -> list[Link]: links = [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link( _('Notification Templates'), self.request.class_link(NotificationTemplateCollection) ) ] if self.subtitle: links.append(Link(self.subtitle, '#')) return links
@cached_property
[docs] class NotificationTemplateLayout(DefaultLayout):
[docs] model: 'NotificationTemplate'
def __init__( self, model: 'NotificationTemplate', request: 'FeriennetRequest', subtitle: str | None = None ) -> None: super().__init__(model, request)
[docs] self.subtitle = subtitle
self.include_editor() @cached_property
[docs] def breadcrumbs(self) -> list[Link]: links = [ Link(_('Homepage'), self.homepage_url), Link( _('Activities'), self.request.class_link(VacationActivityCollection) ), Link( _('Notification Templates'), self.request.class_link(NotificationTemplateCollection) ), Link( self.model.subject, self.request.link(self.model) ) ] if self.subtitle: links.append(Link(self.subtitle, '#')) return links
[docs] class VolunteerLayout(DefaultLayout):
[docs] model: 'VolunteerCollection'
if TYPE_CHECKING: def __init__( self, model: 'VolunteerCollection', request: 'FeriennetRequest' ) -> None: ... @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link(_('Volunteers'), self.request.link(self.model)) ]
[docs] class VolunteerFormLayout(DefaultLayout): @cached_property
[docs] def breadcrumbs(self) -> list[Link]: return [ Link(_('Homepage'), self.homepage_url), Link( _('Join as a Volunteer'), self.request.class_link( VacationActivityCollection, name='volunteer' ) ), Link( _('Register as Volunteer'), '#' ) ]
[docs] class HomepageLayout(DefaultLayout):
[docs] model: 'Organisation'
if TYPE_CHECKING: def __init__( self, model: 'Organisation', request: 'FeriennetRequest' ) -> None: ... @property