Source code for org.pdf.my_reservations

from __future__ import annotations

from copy import deepcopy
from datetime import date
from io import BytesIO

from itertools import groupby
from markupsafe import Markup
from onegov.org import _
from onegov.org.layout import DefaultLayout
from onegov.org.pdf.core import OrgPdf
from onegov.reservation import Resource
from pdfdocument.document import MarkupParagraph
from reportlab.lib.enums import TA_RIGHT
from reportlab.platypus import PageBreak


from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from datetime import datetime
    from onegov.org.request import OrgRequest
    from onegov.org.utils import MyReservationEventInfo


[docs] class MyReservationsPdf(OrgPdf):
[docs] def add_reservations( self, infos: list[MyReservationEventInfo], start: datetime, end: datetime, request: OrgRequest ) -> None: """ Adds reservations to the story. """ layout = DefaultLayout(None, request) self.h1(_('My Reservations')) self.h2( f"{layout.format_date(start, 'date_long')} - " f"{layout.format_date(end, 'date_long')}" ) if not infos: self.p_markup(_('No data available')) return current_year: int | None = None current_month: str | None = None for dt, group in groupby(infos, key=lambda info: info.start.date()): if current_year: self.spacer() with self.keep_together(): month = layout.format_date(dt, 'month_long') if current_year != dt.year or current_month != month: current_year = dt.year current_month = month self.h2(f'{current_month} {current_year}') day_style = deepcopy(self.style.bold) day_style.alignment = TA_RIGHT event_data = sorted( (info.event_time, info.event_title) for info in group ) self.table([ [ MarkupParagraph( layout.format_date(dt, 'date'), style=deepcopy(self.style.bold) ), MarkupParagraph( layout.format_date(dt, 'weekday_long'), style=deepcopy(self.style.bold) ) ], *( [ MarkupParagraph(event_time), MarkupParagraph(Markup('<br/>').join( Markup('<b>{}</b>').format(line) if idx == 0 else line for idx, line in enumerate( event_title.splitlines() ) if line != event_time )) ] for event_time, event_title in event_data ) ], [.2, .8], ratios=True, first_bold=False)
[docs] def resource_infos(self, resources: list[Resource]) -> None: first = True for resource in resources: confirmation_text = getattr(resource, 'confirmation_text', None) if not confirmation_text: continue self.story.append(PageBreak()) if first: first = False self.h1('Appendix') else: self.spacer() self.h2(resource.title) self.mini_html(confirmation_text)
@classmethod
[docs] def from_reservations( cls, request: OrgRequest, infos: list[MyReservationEventInfo], start: datetime, end: datetime, ) -> BytesIO: """ Creates a PDF representation of the reservations. """ layout = DefaultLayout(None, request) result = BytesIO() pdf = cls( result, title=f"{request.translate(_('My Reservations'))} " f"{layout.format_date(start, 'date')} - " f"{layout.format_date(end, 'date')}", created=f'{date.today():%d.%m.%Y}', link_color='#00538c', underline_links=True, author=request.host_url, translations=request.app.translations, locale=request.locale, ) pdf.init_a4_portrait( page_fn=pdf.page_fn, page_fn_later=pdf.page_fn_later ) pdf.add_reservations(infos, start, end, request) resource_ids = {info.resource_id for info in infos} resources = ( request.app.libres_resources.query() .filter(Resource.id.in_(resource_ids)) .order_by(Resource.title.asc()) .all() ) pdf.resource_infos(resources) pdf.generate() result.seek(0) return result