import os from fpdf import FPDF import config from fpdf import FPDF import os import config def format_amount(amount): return f"{amount:.2f}".replace(".", ",") def generate_uplatnica(order_id, payer_name, payer_address, amount): pdf = FPDF(orientation='P', unit='mm', format='A4') pdf.set_auto_page_break(False) pdf.add_page() pdf.set_font("helvetica", size=7) # === UPLATNICA AREA (top of A4) === pdf.rect(0, 0, 210, 99) # Vertical divider pdf.line(105, 0, 105, 99) # ===== TOP OPTIONS ===== labels = ["Hitnost", "Prenos", "Uplata", "Isplata"] start_x = 110 step = 22 for i, label in enumerate(labels): x = start_x + i * step pdf.set_xy(x, 2) pdf.cell(14, 4, label) pdf.rect(x + 14, 2, 4, 4) if label == "Uplata": pdf.line(x + 14, 2, x + 18, 6) pdf.line(x + 18, 2, x + 14, 6) # ===== LEFT ===== pdf.set_font("helvetica", "B", 8) pdf.set_xy(5, 5) pdf.cell(95, 5, "NALOG PLATIOCA", align="C") pdf.rect(5, 12, 95, 14) pdf.set_font("helvetica", size=9) pdf.set_xy(7, 14) pdf.cell(90, 4, payer_name[:40]) pdf.set_xy(7, 18) pdf.cell(90, 4, payer_address[:40]) pdf.set_font("helvetica", size=6) pdf.set_xy(5, 26) pdf.cell(95, 4, "(Naziv platioca)", align="C") pdf.rect(5, 30, 95, 14) pdf.set_font("helvetica", size=9) pdf.set_xy(7, 32) pdf.cell(90, 4, "Usluge 3D stampe") pdf.set_xy(7, 36) pdf.cell(90, 4, f"Narudzba {order_id}") pdf.set_font("helvetica", size=6) pdf.set_xy(5, 44) pdf.cell(95, 4, "(Svrha placanja)", align="C") pdf.rect(5, 48, 95, 14) pdf.set_font("helvetica", size=9) pdf.set_xy(7, 50) pdf.cell(90, 4, config.COMPANY_NAME[:40]) pdf.set_font("helvetica", size=6) pdf.set_xy(5, 62) pdf.cell(95, 4, "(Naziv primaoca)", align="C") pdf.line(5, 90, 100, 90) pdf.set_xy(5, 90) pdf.cell(95, 4, "(Potpis platioca)", align="C") # ===== RIGHT ===== pdf.rect(110, 12, 95, 8) pdf.set_font("helvetica", size=7) pdf.set_xy(110, 22) pdf.cell(10, 4, "EUR") pdf.rect(120, 22, 50, 10) pdf.rect(175, 22, 30, 10) pdf.set_font("helvetica", "B", 11) pdf.set_xy(120, 24) pdf.cell(50, 6, format_amount(amount), align="C") pdf.set_xy(175, 24) pdf.cell(30, 6, "121", align="C") pdf.set_font("helvetica", size=6) pdf.set_xy(120, 32) pdf.cell(50, 4, "(Iznos)", align="C") pdf.set_xy(175, 32) pdf.cell(30, 4, "(Sifra)", align="C") pdf.rect(110, 36, 95, 10) pdf.set_font("helvetica", size=10) pdf.set_xy(110, 38) pdf.cell(95, 6, config.ZIRO_RACUN, align="C") pdf.rect(110, 50, 20, 8) pdf.rect(135, 50, 70, 8) pdf.set_xy(110, 52) pdf.cell(20, 4, "00", align="C") pdf.set_xy(135, 52) pdf.cell(70, 4, str(order_id), align="C") pdf.line(110, 90, 205, 90) pdf.set_xy(110, 90) pdf.cell(95, 4, "(Potpis primaoca)", align="C") # ===== SAVE ===== pdf_dir = os.path.join(config.UPLOAD_DIR, "invoices") os.makedirs(pdf_dir, exist_ok=True) filename = f"uplatnica_order_{order_id}.pdf" filepath = os.path.join(pdf_dir, filename) pdf.output(filepath) return os.path.join("uploads", "invoices", filename).replace("\\", "/") def generate_predracun(order_id, company_name, company_pib, company_address, amount, items=None): """Generates a formal Proforma Invoice (Predračun) for companies""" pdf = FPDF(orientation='P', unit='mm', format='A4') pdf.add_page() # Fonts pdf.set_font("helvetica", "B", 16) pdf.cell(0, 10, "PREDRACUN (Proforma Invoice)", ln=True, align='C') pdf.set_font("helvetica", "", 10) pdf.cell(0, 10, f"Broj narudzbe / Order ID: {order_id}", ln=True, align='C') pdf.ln(5) # Supplier info (Left) pdf.set_font("helvetica", "B", 10) pdf.cell(95, 5, "PRODAVAC / SUPPLIER:", ln=False) # Customer info (Right) pdf.cell(95, 5, "KUPAC / CUSTOMER:", ln=True) pdf.set_font("helvetica", "", 10) current_y = pdf.get_y() # Left column (Supplier) pdf.set_xy(10, current_y) pdf.multi_cell(90, 5, f"{config.COMPANY_NAME}\n{config.COMPANY_ADDRESS}\nPIB: {config.COMPANY_PIB}\nZiro racun: {config.ZIRO_RACUN}") # Right column (Customer) pdf.set_xy(105, current_y) pdf.multi_cell(90, 5, f"{company_name}\nAddress: {company_address}\nPIB: {company_pib}") pdf.ln(10) pdf.set_xy(10, pdf.get_y() + 5) # Table Header pdf.set_font("helvetica", "B", 10) pdf.set_fill_color(240, 240, 240) pdf.cell(10, 8, "#", border=1, fill=True) pdf.cell(100, 8, "Opis / Description", border=1, fill=True) pdf.cell(20, 8, "Kol / Qty", border=1, fill=True, align='C') pdf.cell(30, 8, "Cjena / Price", border=1, fill=True, align='R') pdf.cell(30, 8, "Iznos / Total", border=1, fill=True, align='R', ln=True) # Table Content pdf.set_font("helvetica", "", 9) pdv_rate = getattr(config, 'PDV_RATE', 21) total_base = 0.0 total_pdv = 0.0 if not items: # Fallback price_total = float(amount) price_base = price_total / (1 + pdv_rate/100) pdv_amount = price_total - price_base total_base = price_base total_pdv = pdv_amount pdf.cell(10, 8, "1", border=1) pdf.cell(100, 8, f"Usluge 3D stampe (Narudzba {order_id})", border=1) pdf.cell(20, 8, "1", border=1, align='C') pdf.cell(30, 8, format_amount(price_base), border=1, align='R') pdf.cell(30, 8, format_amount(price_total), border=1, align='R', ln=True) else: for i, item in enumerate(items): pdf.cell(10, 8, str(i + 1), border=1) pdf.cell(100, 8, str(item.get('name', '3D Print'))[:50], border=1) pdf.cell(20, 8, str(item.get('quantity', 1)), border=1, align='C') p_total = float(item.get('price', 0)) * item.get('quantity', 1) p_base = p_total / (1 + pdv_rate/100) p_pdv = p_total - p_base total_base += p_base total_pdv += p_pdv pdf.cell(30, 8, format_amount(p_base / item.get('quantity', 1)), border=1, align='R') pdf.cell(30, 8, format_amount(p_total), border=1, align='R', ln=True) # Breakdown pdf.ln(5) pdf.set_font("helvetica", "", 10) pdf.cell(160, 6, "Osnovica / Base Amount:", align='R') pdf.cell(30, 6, format_amount(total_base), align='R', ln=True) pdf.cell(160, 6, f"PDV {pdv_rate}% / VAT Amount:", align='R') pdf.cell(30, 6, format_amount(total_pdv), align='R', ln=True) # Total pdf.set_font("helvetica", "B", 12) pdf.cell(160, 10, "UKUPNO / TOTAL (EUR):", align='R') pdf.cell(30, 10, format_amount(float(amount)), align='R', ln=True) # Footer pdf.ln(20) pdf.set_font("helvetica", "I", 8) pdf.multi_cell(0, 5, "Predracun je validan bez pecata i potpisa. Placanje se vrsi u roku od 3 dana na navedeni ziro racun.\nThis is a proforma invoice and is valid without stamp and signature.") # Save pdf_dir = os.path.join(config.UPLOAD_DIR, "invoices") os.makedirs(pdf_dir, exist_ok=True) filename = f"predracun_order_{order_id}.pdf" filepath = os.path.join(pdf_dir, filename) pdf.output(filepath) return os.path.join("uploads", "invoices", filename).replace("\\", "/")