| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- 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("\\", "/")
|