feat(reports): include workspace thumbnail in pdf exports
This commit is contained in:
@@ -418,7 +418,11 @@ def _scope_payload(filters: ReportFilters) -> dict:
|
||||
}
|
||||
|
||||
return {
|
||||
"workspace": {"id": str(filters.workspace.id), "name": filters.workspace.name},
|
||||
"workspace": {
|
||||
"id": str(filters.workspace.id),
|
||||
"name": filters.workspace.name,
|
||||
"thumbnail_path": filters.workspace.thumbnail.path if getattr(filters.workspace, "thumbnail", None) else None,
|
||||
},
|
||||
"period": filters.period,
|
||||
"from_date": filters.from_date.isoformat(),
|
||||
"to_date": filters.to_date.isoformat(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from openpyxl import Workbook
|
||||
@@ -12,6 +13,7 @@ from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
|
||||
from reportlab.lib.units import mm
|
||||
from reportlab.pdfbase import pdfmetrics
|
||||
from reportlab.pdfbase.ttfonts import TTFont
|
||||
from reportlab.platypus import Image as RLImage
|
||||
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer, Table, TableStyle
|
||||
|
||||
from apps.reports.services.export_i18n import ExportLocale, safe_sheet_title, user_label
|
||||
@@ -229,6 +231,11 @@ def _paragraph(text: str, style: ParagraphStyle, locale: ExportLocale) -> Paragr
|
||||
return Paragraph(locale.shape(text), style)
|
||||
|
||||
|
||||
def _workspace_initial(name: str) -> str:
|
||||
stripped = (name or "").strip()
|
||||
return stripped[0].upper() if stripped else "W"
|
||||
|
||||
|
||||
def _styled_table(data: list[list[str]], *, locale: ExportLocale, column_widths: list[float]) -> Table:
|
||||
shaped_data = [
|
||||
[locale.shape(cell) if cell is not None else "" for cell in row]
|
||||
@@ -318,10 +325,35 @@ def build_pdf_report(*, report_data: dict, locale: ExportLocale) -> bytes:
|
||||
|
||||
scope = report_data["scope"]
|
||||
summary = report_data["summary"]
|
||||
story = [
|
||||
_paragraph(f"{locale.t('report_title')} - {scope['workspace']['name']}", title_style, locale),
|
||||
Spacer(1, 6 * mm),
|
||||
workspace_name = scope["workspace"]["name"]
|
||||
workspace_thumbnail_path = scope["workspace"].get("thumbnail_path")
|
||||
title_text = f"{locale.t('report_title')} - {workspace_name}"
|
||||
|
||||
title_cell = _paragraph(title_text, title_style, locale)
|
||||
badge_cell = _paragraph(_workspace_initial(workspace_name), title_style, locale)
|
||||
if workspace_thumbnail_path and os.path.exists(workspace_thumbnail_path):
|
||||
try:
|
||||
badge_cell = RLImage(workspace_thumbnail_path, width=14 * mm, height=14 * mm)
|
||||
except Exception: # noqa: BLE001
|
||||
badge_cell = _paragraph(_workspace_initial(workspace_name), title_style, locale)
|
||||
|
||||
header_row = [badge_cell, title_cell] if locale.is_rtl else [title_cell, badge_cell]
|
||||
header_col_widths = [doc.width * 0.08, doc.width * 0.92] if locale.is_rtl else [doc.width * 0.92, doc.width * 0.08]
|
||||
header_table = Table([header_row], colWidths=header_col_widths)
|
||||
header_table.setStyle(
|
||||
TableStyle(
|
||||
[
|
||||
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
|
||||
("ALIGN", (0, 0), (-1, -1), "RIGHT" if locale.is_rtl else "LEFT"),
|
||||
("LEFTPADDING", (0, 0), (-1, -1), 0),
|
||||
("RIGHTPADDING", (0, 0), (-1, -1), 0),
|
||||
("TOPPADDING", (0, 0), (-1, -1), 0),
|
||||
("BOTTOMPADDING", (0, 0), (-1, -1), 0),
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
story = [header_table, Spacer(1, 6 * mm)]
|
||||
|
||||
meta_rows = [
|
||||
[locale.t("workspace"), scope["workspace"]["name"]],
|
||||
|
||||
Reference in New Issue
Block a user