Mock server: dnevni izveštaj sad generiše pravi PDF (reportlab + DejaVu Sans Mono)
This commit is contained in:
@@ -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,2 +1,3 @@
|
|||||||
qrcode
|
qrcode
|
||||||
pillow
|
pillow
|
||||||
|
reportlab
|
||||||
|
|||||||
+3
-2
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user