package routes import ( "bssapp-backend/queries" "bytes" "database/sql" "fmt" "net/http" "strings" "time" "github.com/jung-kurt/gofpdf" ) type orderListPDFRow struct { OrderNumber string OrderDate string TerminTarihi string CurrAccCode string CurrAccDescription string MusteriTemsilcisi string Piyasa string DocCurrencyCode string TotalAmount float64 TotalAmountUSD float64 PackedUSD float64 PackedRatePct float64 HasUretimUrunu bool Description string } func OrderListPDFRoute(db *sql.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { search := strings.TrimSpace(r.URL.Query().Get("search")) currAcc := strings.TrimSpace(r.URL.Query().Get("CurrAccCode")) orderDate := strings.TrimSpace(r.URL.Query().Get("OrderDate")) rows, err := queries.GetOrderListExcel(db, search, currAcc, orderDate) if err != nil { http.Error(w, "db error: "+err.Error(), http.StatusInternalServerError) return } defer rows.Close() out := make([]orderListPDFRow, 0, 256) for rows.Next() { var ( id, no, date, termin, code, name string rep, piyasa, cur string total float64 totalUSD float64 packedAmount float64 packedUSD float64 packedRatePct float64 hasUretim bool desc string usdRate float64 ) if err := rows.Scan( &id, &no, &date, &termin, &code, &name, &rep, &piyasa, &cur, &total, &totalUSD, &packedAmount, &packedUSD, &packedRatePct, &hasUretim, &desc, &usdRate, ); err != nil { http.Error(w, "scan error: "+err.Error(), http.StatusInternalServerError) return } _ = packedAmount _ = usdRate out = append(out, orderListPDFRow{ OrderNumber: no, OrderDate: date, TerminTarihi: termin, CurrAccCode: code, CurrAccDescription: name, MusteriTemsilcisi: rep, Piyasa: piyasa, DocCurrencyCode: cur, TotalAmount: total, TotalAmountUSD: totalUSD, PackedUSD: packedUSD, PackedRatePct: packedRatePct, HasUretimUrunu: hasUretim, Description: desc, }) } pdf := gofpdf.New("L", "mm", "A4", "") pdf.SetMargins(8, 8, 8) pdf.SetAutoPageBreak(true, 10) if err := registerDejavuFonts(pdf, "dejavu"); err != nil { http.Error(w, "pdf font error: "+err.Error(), http.StatusInternalServerError) return } drawOrderListPDF(pdf, out, search, currAcc, orderDate) if err := pdf.Error(); err != nil { http.Error(w, "pdf render error: "+err.Error(), http.StatusInternalServerError) return } var buf bytes.Buffer if err := pdf.Output(&buf); err != nil { http.Error(w, "pdf output error: "+err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/pdf") w.Header().Set("Content-Disposition", "inline; filename=\"siparis-listesi.pdf\"") _, _ = w.Write(buf.Bytes()) }) } func drawOrderListPDF(pdf *gofpdf.Fpdf, rows []orderListPDFRow, search, currAcc, orderDate string) { headers := []string{ "Siparis No", "Tarih", "Termin", "Cari Kod", "Cari Adi", "Temsilci", "Piyasa", "PB", "Tutar", "USD", "Paket USD", "%", "Uretim", "Aciklama", } widths := []float64{24, 14, 14, 18, 34, 16, 12, 8, 18, 18, 18, 10, 14, 43} pdf.AddPage() pdf.SetFont("dejavu", "B", 12) pdf.CellFormat(0, 7, "Siparis Listesi", "", 1, "L", false, 0, "") pdf.SetFont("dejavu", "", 8) filterLine := fmt.Sprintf( "Filtreler -> Arama: %s | Cari: %s | Siparis Tarihi: %s | Uretim: %s", emptyDash(search), emptyDash(currAcc), emptyDash(orderDate), time.Now().Format("2006-01-02 15:04"), ) pdf.CellFormat(0, 5, filterLine, "", 1, "L", false, 0, "") pdf.Ln(1) pdf.SetFont("dejavu", "B", 8) pdf.SetFillColor(240, 240, 240) for i, h := range headers { pdf.CellFormat(widths[i], 6, h, "1", 0, "C", true, 0, "") } pdf.Ln(-1) pdf.SetFont("dejavu", "", 7) for _, row := range rows { uretim := "" if row.HasUretimUrunu { uretim = "VAR" } cells := []string{ row.OrderNumber, row.OrderDate, row.TerminTarihi, row.CurrAccCode, shorten(row.CurrAccDescription, 24), shorten(row.MusteriTemsilcisi, 12), shorten(row.Piyasa, 10), row.DocCurrencyCode, fmt.Sprintf("%.2f", row.TotalAmount), fmt.Sprintf("%.2f", row.TotalAmountUSD), fmt.Sprintf("%.2f", row.PackedUSD), fmt.Sprintf("%.2f", row.PackedRatePct), uretim, shorten(row.Description, 34), } for i, v := range cells { align := "L" if i >= 8 && i <= 11 { align = "R" } if i == 1 || i == 2 || i == 7 || i == 12 { align = "C" } pdf.CellFormat(widths[i], 5, v, "1", 0, align, false, 0, "") } pdf.Ln(-1) } } func emptyDash(v string) string { if strings.TrimSpace(v) == "" { return "-" } return v } func shorten(v string, max int) string { s := strings.TrimSpace(v) if len([]rune(s)) <= max { return s } r := []rune(s) if max <= 1 { return string(r[:1]) } return string(r[:max-1]) + "…" }