From 4997d926c767d729803be3ccbbf0beb74b6de1d9 Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Tue, 17 Mar 2026 11:53:09 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- svc/routes/customer_balance_pdf.go | 111 ++++++++++++++++++++++++++++- svc/routes/statement_aging_pdf.go | 13 +++- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/svc/routes/customer_balance_pdf.go b/svc/routes/customer_balance_pdf.go index 721317d..688ab01 100644 --- a/svc/routes/customer_balance_pdf.go +++ b/svc/routes/customer_balance_pdf.go @@ -80,7 +80,7 @@ func ExportCustomerBalancePDFHandler(_ *sql.DB) http.HandlerFunc { return } - drawCustomerBalancePDF( + if err := safeDrawCustomerBalancePDF( pdf, selectedDate, params.CariSearch, @@ -89,7 +89,16 @@ func ExportCustomerBalancePDFHandler(_ *sql.DB) http.HandlerFunc { false, summaries, detailsByMaster, - ) + ); err != nil { + pdf = gofpdf.New("L", "mm", "A4", "") + pdf.SetMargins(8, 8, 8) + pdf.SetAutoPageBreak(true, 12) + if ferr := registerDejavuFonts(pdf, "dejavu"); ferr != nil { + http.Error(w, "pdf font error: "+ferr.Error(), http.StatusInternalServerError) + return + } + drawCustomerBalancePDFFallback(pdf, selectedDate, params.CariSearch, "Cari Bakiye Listesi", summaries, false) + } if err := pdf.Error(); err != nil { http.Error(w, "pdf render error: "+err.Error(), http.StatusInternalServerError) @@ -552,6 +561,104 @@ func drawCustomerBalancePDF( } } +func safeDrawCustomerBalancePDF( + pdf *gofpdf.Fpdf, + selectedDate string, + searchText string, + detailed bool, + reportTitle string, + includeVadeColumns bool, + summaries []balanceSummaryPDF, + detailsByMaster map[string][]models.CustomerBalanceListRow, +) (err error) { + defer func() { + if rec := recover(); rec != nil { + err = fmt.Errorf("draw panic: %v", rec) + } + }() + drawCustomerBalancePDF(pdf, selectedDate, searchText, detailed, reportTitle, includeVadeColumns, summaries, detailsByMaster) + return nil +} + +func drawCustomerBalancePDFFallback( + pdf *gofpdf.Fpdf, + selectedDate string, + searchText string, + reportTitle string, + summaries []balanceSummaryPDF, + includeVadeColumns bool, +) { + pdf.AddPage() + pdf.SetFont("dejavu", "B", 13) + pdf.SetTextColor(149, 113, 22) + pdf.CellFormat(0, 8, reportTitle+" (Fallback)", "", 1, "L", false, 0, "") + + pdf.SetFont("dejavu", "", 9) + pdf.SetTextColor(20, 20, 20) + pdf.CellFormat(0, 5, "Tarih: "+formatDateTR(selectedDate), "", 1, "L", false, 0, "") + if strings.TrimSpace(searchText) != "" { + pdf.CellFormat(0, 5, "Arama: "+searchText, "", 1, "L", false, 0, "") + } + pdf.Ln(1) + + header := []string{"Ana Cari Kod", "Ana Cari Detay", "1_2 USD", "1_2 TRY", "1_3 USD", "1_3 TRY"} + widths := normalizeWidths([]float64{24, 78, 18, 18, 18, 18}, 281) + if includeVadeColumns { + header = append(header, "Vade Gun", "Belge Tarihi Gun") + widths = normalizeWidths([]float64{24, 70, 17, 17, 17, 17, 12, 17}, 281) + } + + pdf.SetFont("dejavu", "B", 8) + pdf.SetFillColor(149, 113, 22) + pdf.SetTextColor(255, 255, 255) + x, y := 8.0, pdf.GetY() + for i, h := range header { + pdf.Rect(x, y, widths[i], 6, "DF") + pdf.SetXY(x+1, y+1) + pdf.CellFormat(widths[i]-2, 4, h, "", 0, "C", false, 0, "") + x += widths[i] + } + pdf.SetY(y + 6) + + pdf.SetFont("dejavu", "", 7.4) + pdf.SetTextColor(20, 20, 20) + for _, s := range summaries { + row := []string{ + s.AnaCariKodu, + s.AnaCariAdi, + formatMoneyPDF(s.USDBakiye12), + formatMoneyPDF(s.TLBakiye12), + formatMoneyPDF(s.USDBakiye13), + formatMoneyPDF(s.TLBakiye13), + } + if includeVadeColumns { + row = append(row, formatMoneyPDF(s.VadeGun), formatMoneyPDF(s.VadeBelge)) + } + + if pdf.GetY()+6 > 198 { + pdf.AddPage() + pdf.SetY(8) + } + + x = 8 + y = pdf.GetY() + for i, v := range row { + pdf.Rect(x, y, widths[i], 6, "") + align := "L" + if i >= 2 { + align = "R" + } + if includeVadeColumns && (i == len(row)-1 || i == len(row)-2) { + align = "C" + } + pdf.SetXY(x+1, y+1) + pdf.CellFormat(widths[i]-2, 4, v, "", 0, align, false, 0, "") + x += widths[i] + } + pdf.SetY(y + 6) + } +} + func formatDateTR(v string) string { s := strings.TrimSpace(v) if s == "" { diff --git a/svc/routes/statement_aging_pdf.go b/svc/routes/statement_aging_pdf.go index 5d59304..2640dd5 100644 --- a/svc/routes/statement_aging_pdf.go +++ b/svc/routes/statement_aging_pdf.go @@ -82,7 +82,7 @@ func ExportStatementAgingPDFHandler(_ *sql.DB) http.HandlerFunc { return } - drawCustomerBalancePDF( + if err := safeDrawCustomerBalancePDF( pdf, selectedDate, params.CariSearch, @@ -91,7 +91,16 @@ func ExportStatementAgingPDFHandler(_ *sql.DB) http.HandlerFunc { true, summaries, detailsByMaster, - ) + ); err != nil { + pdf = gofpdf.New("L", "mm", "A4", "") + pdf.SetMargins(8, 8, 8) + pdf.SetAutoPageBreak(true, 12) + if ferr := registerDejavuFonts(pdf, "dejavu"); ferr != nil { + http.Error(w, "pdf font error: "+ferr.Error(), http.StatusInternalServerError) + return + } + drawCustomerBalancePDFFallback(pdf, selectedDate, params.CariSearch, "Cari Yaslandirmali Ekstre", summaries, true) + } if err := pdf.Error(); err != nil { http.Error(w, "pdf render error: "+err.Error(), http.StatusInternalServerError)