package routes import ( "bssapp-backend/auth" "bssapp-backend/models" "bssapp-backend/queries" "database/sql" "fmt" "net/http" "strings" "time" "github.com/xuri/excelize/v2" ) func ExportCustomerBalanceExcelHandler(_ *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { claims, ok := auth.GetClaimsFromContext(r.Context()) if !ok || claims == nil { http.Error(w, "unauthorized", http.StatusUnauthorized) return } selectedDate := strings.TrimSpace(r.URL.Query().Get("selected_date")) if selectedDate == "" { selectedDate = time.Now().Format("2006-01-02") } params := models.CustomerBalanceListParams{ SelectedDate: selectedDate, CariSearch: strings.TrimSpace(r.URL.Query().Get("cari_search")), CariIlkGrup: strings.TrimSpace(r.URL.Query().Get("cari_ilk_grup")), Piyasa: strings.TrimSpace(r.URL.Query().Get("piyasa")), Temsilci: strings.TrimSpace(r.URL.Query().Get("temsilci")), RiskDurumu: strings.TrimSpace(r.URL.Query().Get("risk_durumu")), IslemTipi: strings.TrimSpace(r.URL.Query().Get("islem_tipi")), Ulke: strings.TrimSpace(r.URL.Query().Get("ulke")), Il: strings.TrimSpace(r.URL.Query().Get("il")), Ilce: strings.TrimSpace(r.URL.Query().Get("ilce")), } excludeZero12 := parseBoolQuery(r.URL.Query().Get("exclude_zero_12")) excludeZero13 := parseBoolQuery(r.URL.Query().Get("exclude_zero_13")) rows, err := queries.GetCustomerBalanceList(r.Context(), params) if err != nil { http.Error(w, "db error: "+err.Error(), http.StatusInternalServerError) return } rows = filterCustomerBalanceRowsForPDF(rows, excludeZero12, excludeZero13) summaries, _ := buildCustomerBalancePDFData(rows) f := excelize.NewFile() sheet := "CariBakiye" f.SetSheetName("Sheet1", sheet) headers := []string{ "Ana Cari Kodu", "Ana Cari Detay", "Piyasa", "Temsilci", "Risk Durumu", "1_2 Bakiye Pr.Br", "1_3 Bakiye Pr.Br", "1_2 USD Bakiye", "1_2 TRY Bakiye", "1_3 USD Bakiye", "1_3 TRY Bakiye", "Vade Gun", "Belge Tarihi Gun", } for i, h := range headers { cell, _ := excelize.CoordinatesToCellName(i+1, 1) f.SetCellValue(sheet, cell, h) } var totalUSD12, totalTRY12, totalUSD13, totalTRY13 float64 var totalVadeBase, totalVadeSum, totalVadeBelgeSum float64 totalPrBr12 := map[string]float64{} totalPrBr13 := map[string]float64{} for _, s := range summaries { totalUSD12 += s.USDBakiye12 totalTRY12 += s.TLBakiye12 totalUSD13 += s.USDBakiye13 totalTRY13 += s.TLBakiye13 w := absFloatExcel(s.USDBakiye12) + absFloatExcel(s.TLBakiye12) + absFloatExcel(s.USDBakiye13) + absFloatExcel(s.TLBakiye13) if w > 0 { totalVadeBase += w totalVadeSum += s.VadeGun * w totalVadeBelgeSum += s.VadeBelge * w } for k, v := range s.Bakiye12Map { totalPrBr12[k] += v } for k, v := range s.Bakiye13Map { totalPrBr13[k] += v } } totalVade := 0.0 totalVadeBelge := 0.0 if totalVadeBase > 0 { totalVade = totalVadeSum / totalVadeBase totalVadeBelge = totalVadeBelgeSum / totalVadeBase } f.SetSheetRow(sheet, "A2", &[]any{ "TOPLAM", "", "", "", "", formatCurrencyMapPDF(totalPrBr12), formatCurrencyMapPDF(totalPrBr13), totalUSD12, totalTRY12, totalUSD13, totalTRY13, totalVade, totalVadeBelge, }) rowNo := 3 for _, s := range summaries { f.SetSheetRow(sheet, fmt.Sprintf("A%d", rowNo), &[]any{ s.AnaCariKodu, s.AnaCariAdi, s.Piyasa, s.Temsilci, s.RiskDurumu, formatCurrencyMapPDF(s.Bakiye12Map), formatCurrencyMapPDF(s.Bakiye13Map), s.USDBakiye12, s.TLBakiye12, s.USDBakiye13, s.TLBakiye13, s.VadeGun, s.VadeBelge, }) rowNo++ } _ = f.SetColWidth(sheet, "A", "A", 16) _ = f.SetColWidth(sheet, "B", "B", 34) _ = f.SetColWidth(sheet, "C", "E", 18) _ = f.SetColWidth(sheet, "F", "G", 34) _ = f.SetColWidth(sheet, "H", "M", 18) buf, err := f.WriteToBuffer() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } filename := fmt.Sprintf("cari_bakiye_listesi_%s.xlsx", time.Now().Format("20060102_150405")) w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") w.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"") w.Header().Set("Content-Length", fmt.Sprint(len(buf.Bytes()))) w.WriteHeader(http.StatusOK) _, _ = w.Write(buf.Bytes()) } } func absFloatExcel(v float64) float64 { if v < 0 { return -v } return v }