Mock server: dnevni izveštaj sad generiše pravi PDF (reportlab + DejaVu Sans Mono)

This commit is contained in:
2026-07-02 20:19:17 +02:00
parent fb80ee910c
commit c82b17f9c1
3 changed files with 46 additions and 2 deletions
+42
View File
@@ -6,9 +6,24 @@ Prati izgled definisan u LPFR VM template-u i locale fajlovima.
from pathlib import Path from pathlib import Path
from datetime import datetime from datetime import datetime
import io
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
DATA_DIR = Path(__file__).parent / "data" DATA_DIR = Path(__file__).parent / "data"
_FONT_NAME = "Courier"
_FONT_PATH = Path("/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf")
if _FONT_PATH.exists():
try:
pdfmetrics.registerFont(TTFont("DejaVuSansMono", str(_FONT_PATH)))
_FONT_NAME = "DejaVuSansMono"
except Exception:
pass
def load_locale(lang="latin"): def load_locale(lang="latin"):
"""Učitava lokalizacioni fajl u dict.""" """Učitava lokalizacioni fajl u dict."""
filename = f"locale_{lang}.properties" filename = f"locale_{lang}.properties"
@@ -646,3 +661,30 @@ def generate_report(report_data, lang="latin"):
lines.append(separator("=", W)) lines.append(separator("=", W))
return "\n".join(lines) return "\n".join(lines)
def render_report_pdf(report_text):
"""Renderuje monospace tekst izveštaja (48 kolona) u pravi PDF (A4, Courier).
Vraća bajtove gotovog PDF fajla."""
buf = io.BytesIO()
c = canvas.Canvas(buf, pagesize=A4)
width, height = A4
font_name = _FONT_NAME
font_size = 10
line_height = font_size * 1.15
margin_left = 20 * (72 / 25.4) # 20mm u tačkama
margin_top = 15 * (72 / 25.4) # 15mm u tačkama
c.setFont(font_name, font_size)
y = height - margin_top
for line in report_text.split("\n"):
if y < margin_top:
c.showPage()
c.setFont(font_name, font_size)
y = height - margin_top
c.drawString(margin_left, y, line)
y -= line_height
c.showPage()
c.save()
return buf.getvalue()
+1
View File
@@ -1,2 +1,3 @@
qrcode qrcode
pillow pillow
reportlab
+3 -2
View File
@@ -21,7 +21,7 @@ import socket
import urllib.parse import urllib.parse
import qrcode import qrcode
from receipt import generate_receipt, generate_receipt_html, generate_report, load_locale from receipt import generate_receipt, generate_receipt_html, generate_report, render_report_pdf, load_locale
# ── Konfiguracija ────────────────────────────────────────── # ── Konfiguracija ──────────────────────────────────────────
PORT = 4566 # Teron standard port PORT = 4566 # Teron standard port
@@ -665,7 +665,8 @@ def resp_financial_report_summary(request_body=None):
"perTransactionType": [], "perTransactionType": [],
} }
tekst = generate_report(report_data, lang) tekst = generate_report(report_data, lang)
pdf_b64 = base64.b64encode(tekst.encode("utf-8")).decode("ascii") pdf_bytes = render_report_pdf(tekst)
pdf_b64 = base64.b64encode(pdf_bytes).decode("ascii")
filename = f"{title} - {report_data['startDate']} - {report_data['endDate']}.pdf" filename = f"{title} - {report_data['startDate']} - {report_data['endDate']}.pdf"
log(f" 📄 Dnevni izveštaj #{report_data['number']} generisan ({summary['invoiceCount']} računa)") log(f" 📄 Dnevni izveštaj #{report_data['number']} generisan ({summary['invoiceCount']} računa)")
return {"reportPdfBase64": pdf_b64, "reportName": title, "filename": filename} return {"reportPdfBase64": pdf_b64, "reportName": title, "filename": filename}