""" Shared PDF generation helper for any model using the hospital letterhead (artboard). """ import io import base64 from django.conf import settings from django.template.loader import render_to_string from weasyprint import HTML def _img_to_data_uri(path): """Open an image file and return it as a base64 data URI.""" try: from PIL import Image as PILImage img = PILImage.open(path) buf = io.BytesIO() img.save(buf, format="PNG", optimize=True) return "data:image/png;base64," + base64.b64encode(buf.getvalue()).decode() except Exception: return None def _get_logo_data_uri(): """Load the HH_P_ICON as a base64 data URI for embedding in PDF.""" return _img_to_data_uri(settings.BASE_DIR / "static" / "img" / "HH_P_ICON.png") def _get_letterhead_data_uri(obj): """Load the hospital letterhead (artboard) for the given object's hospital. Priority: hospital.letterhead upload → static fallback artboard image. """ hospital = getattr(obj, "hospital", None) if hospital and hospital.letterhead: uri = _img_to_data_uri(hospital.letterhead.path) if uri: return uri # Static fallback return _img_to_data_uri(settings.BASE_DIR / "static" / "images" / "artboard" / "Artboard 1@3x.png") def generate_letterhead_pdf(template_name, context, filename, obj=None): """Render a template with the hospital letterhead (artboard) and return an HttpResponse with the PDF. Args: template_name: Django template path. context: Dict of template context variables. filename: Output PDF filename. obj: The model instance (used to resolve hospital.letterhead). If None, falls back to the static artboard image. """ from django.http import HttpResponse logo_path = _get_logo_data_uri() letterhead_path = _img_to_data_uri(settings.BASE_DIR / "static" / "images" / "artboard" / "Artboard 1@3x.png") if obj: letterhead_path = _get_letterhead_data_uri(obj) full_context = {**context, "logo_path": logo_path, "letterhead_path": letterhead_path} html_string = render_to_string(template_name, full_context) pdf_file = HTML(string=html_string, base_url=str(settings.BASE_DIR / "static")).write_pdf() response = HttpResponse(pdf_file, content_type="application/pdf") response["Content-Disposition"] = f'attachment; filename="{filename}"' return response