Files
bssapp/svc/routes/order_list_pdf.go
2026-03-05 10:45:12 +03:00

212 lines
5.2 KiB
Go

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]) + "…"
}