from functools import cached_property
from onegov.activity import Activity, ActivityCollection, Occasion
from onegov.activity import PublicationRequestCollection
from onegov.activity.models import DAYS
from onegov.core.templates import render_macro
from onegov.feriennet import _
from onegov.core.elements import Link, Confirm, Intercooler
from onegov.org.models.extensions import CoordinatesExtension
from onegov.org.models.ticket import OrgTicketMixin
from onegov.search import SearchableContent
from onegov.ticket import handlers, Handler, Ticket
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Iterator, Sequence
from markupsafe import Markup
from onegov.activity.models import PublicationRequest
from onegov.feriennet.request import FeriennetRequest
[docs]
class VacationActivity(Activity, CoordinatesExtension, SearchableContent):
[docs]
__mapper_args__ = {'polymorphic_identity': 'vacation'}
[docs]
es_type_name = 'vacation'
[docs]
es_properties = {
'title': {'type': 'localized'},
'lead': {'type': 'localized'},
'text': {'type': 'localized_html'},
'organiser': {'type': 'text'}
}
@property
[docs]
def es_public(self) -> bool:
return self.state == 'accepted'
@property
[docs]
def es_skip(self) -> bool:
return self.state == 'preview'
@property
[docs]
def organiser(self) -> list[str]:
organiser: list[str] = [
self.user.username,
# FIXME: For now we assume this is always set, if it
# is sometimes not set, then perhaps we should
# only append it when it is set.
self.user.realname # type:ignore[list-item]
]
userprofile_keys = (
'organisation',
'address',
'zip_code',
'place',
'email',
'phone',
'emergency',
'website',
'bank_account',
'bank_beneficiary',
)
for key in userprofile_keys:
if not self.user.data:
continue
if value := self.user.data.get(key):
organiser.append(value)
return organiser
[docs]
class ActivityTicket(OrgTicketMixin, Ticket):
[docs]
__mapper_args__ = {'polymorphic_identity': 'FER'} # type:ignore
[docs]
es_type_name = 'activity_tickets'
[docs]
def reference_group(
self,
request: 'FeriennetRequest' # type:ignore[override]
) -> str:
return self.handler.title
@handlers.registered_handler('FER')
[docs]
class VacationActivityHandler(Handler):
[docs]
handler_title = _('Activities')
[docs]
code_title = _('Activities')
@cached_property
[docs]
def collection(self) -> PublicationRequestCollection:
return PublicationRequestCollection(self.session)
@cached_property
[docs]
def activity(self) -> Activity | None:
if self.publication_request is None:
return None
return self.publication_request.activity
@cached_property
[docs]
def publication_request(self) -> 'PublicationRequest | None':
return self.collection.by_id(self.id)
@property
[docs]
def deleted(self) -> bool:
return self.publication_request is None
@property
[docs]
def email(self) -> str:
return self.activity.username if self.activity else ''
@property
[docs]
def title(self) -> str:
return self.activity.title if self.activity else ''
@property
[docs]
def subtitle(self) -> str | None:
if self.publication_request is None:
return None
return self.publication_request.period.title
@property
[docs]
def group(self) -> str:
return _('Activity')
@property
[docs]
def extra_data(self) -> 'Sequence[str]':
return ()
@property
[docs]
def undecided(self) -> bool:
if self.deleted:
return False
assert self.activity is not None
return self.activity.state == 'proposed'
@cached_property
[docs]
def ticket_deletable(self) -> bool:
if super().ticket_deletable:
if self.activity is not None:
return self.activity.state != 'archived'
return True
return False
[docs]
def get_summary(
self,
request: 'FeriennetRequest' # type:ignore[override]
) -> 'Markup':
assert self.publication_request is not None
assert self.activity is not None
from onegov.feriennet.layout import DefaultLayout
layout = DefaultLayout(self.activity, request)
ac = ActivityCollection(request.session)
activities = ac.by_username(self.activity.username)
return render_macro(
layout.macros['activity_ticket_summary'], request, {
'activity': self.activity,
'layout': layout,
'show_ticket_panel': False,
'ticket': self.ticket,
'is_first': activities.count() == 1,
'period': self.publication_request.period
}
)
[docs]
def get_period_bound_links(
self,
request: 'FeriennetRequest'
) -> 'Iterator[Link]':
if self.activity is None:
return
if self.activity.state in ('proposed', 'archived'):
yield Link(
text=_('Publish'),
url=request.link(self.activity, name='accept'),
attrs={'class': 'accept-activity'},
traits=(
Confirm(
_('Do you really want to publish this activity?'),
_('This cannot be undone.'),
_('Publish Activity'),
_('Cancel')
),
Intercooler(
request_method='POST',
redirect_after=request.url
)
)
)
if self.activity.state == 'accepted':
yield Link(
text=_('Archive'),
url=request.link(self.activity, name='archive'),
attrs={'class': 'archive-activity'},
traits=(
Confirm(
_('Do you really want to archive this activity?'),
_(
'This cannot be undone. '
'The activity will be made private as a result.'
),
_('Archive Activity'),
_('Cancel')
),
Intercooler(
request_method='POST',
redirect_after=request.url
)
)
)
[docs]
def get_links( # type:ignore[override]
self,
request: 'FeriennetRequest' # type:ignore[override]
) -> list[Link]:
links = list(self.get_period_bound_links(request))
links.append(Link(
text=_('Show activity'),
url=request.return_here(request.link(self.activity)),
attrs={'class': 'show-activity'}
))
return links