fix: ispravi prikaz računa u admin/frontendu i smanji PDF slike
- admin.py: thumbnail_preview u WorkOrderInvoiceInline i WorkOrderInvoiceAdmin prikazuje slike/PDF veze putem optimiziranog image endpointa - serializers.py: image_url sada uključuje ?w=1280&q=80&fmt=jpeg za ne-PDF slike - views.py: doda _compress_image_for_pdf() helper, zamijeni ImageReader(photo.image) s kompresiranom JPEG verzijom na oba mjesta u PDF generiranju - tasks.py: kompresija invoice slike u JPEG u memoriji prije ImageReader poziva - WorkOrderInvoicesPdfPage.jsx: * InvoiceImagePreview prikazuje 'Učitavanje...' dok se blob dohvaća (ne 401 fallback) * uklonjen resolveMediaUrl fallback koji uzrokuje 401 greške * svaka invoice kartica je klikabilna i otvara InvoiceDetailModal * InvoiceDetailModal prikazuje detalje i uvećanu sliku/PDF vezu Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -208,6 +208,32 @@ def _docx_filename(work_order, doc_type):
|
||||
return f"{display_code}.work-order.docx"
|
||||
|
||||
|
||||
def _compress_image_for_pdf(image_field, max_width=1280, quality=75):
|
||||
"""
|
||||
Otvori image_field (Django FileField), kompresiraj na max_width JPEG u memoriji,
|
||||
vrati ImageReader spreman za reportlab. Vraća None ako slika nije dostupna.
|
||||
"""
|
||||
try:
|
||||
image_field.open('rb')
|
||||
with Image.open(image_field) as src:
|
||||
img = src.convert('RGB')
|
||||
if img.width > max_width:
|
||||
ratio = max_width / float(img.width)
|
||||
new_h = max(1, int(img.height * ratio))
|
||||
img = img.resize((max_width, new_h), Image.LANCZOS)
|
||||
buf = BytesIO()
|
||||
img.save(buf, format='JPEG', quality=quality, optimize=True)
|
||||
buf.seek(0)
|
||||
return ImageReader(buf)
|
||||
except Exception:
|
||||
return None
|
||||
finally:
|
||||
try:
|
||||
image_field.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _get_cached_pdf(work_order, pdf_type):
|
||||
now = timezone.now()
|
||||
expected_filename = _pdf_filename(work_order, pdf_type)
|
||||
@@ -1166,7 +1192,9 @@ def _build_work_order_service_records_pdf(work_order):
|
||||
prepared = []
|
||||
for photo in row_photos:
|
||||
try:
|
||||
image_reader = ImageReader(photo.image)
|
||||
image_reader = _compress_image_for_pdf(photo.image)
|
||||
if image_reader is None:
|
||||
continue
|
||||
source_w, source_h = image_reader.getSize()
|
||||
if not source_w or not source_h:
|
||||
continue
|
||||
@@ -1390,7 +1418,9 @@ def _build_service_record_pdf(service_record):
|
||||
prepared = []
|
||||
for photo in row_photos:
|
||||
try:
|
||||
image_reader = ImageReader(photo.image)
|
||||
image_reader = _compress_image_for_pdf(photo.image)
|
||||
if image_reader is None:
|
||||
continue
|
||||
source_w, source_h = image_reader.getSize()
|
||||
if not source_w or not source_h:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user