70 lines
2.4 KiB
Python
70 lines
2.4 KiB
Python
"""
|
|
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
|