// queries/statements_header_pdf.go package queries import ( "bssapp-backend/db" "bssapp-backend/models" "database/sql" "fmt" "log" "strings" ) // küçük yardımcı: boşlukları temizle, her değeri ayrı tırnakla sar func buildQuotedHList(vals []string) string { var pp []string for _, v := range vals { v = strings.TrimSpace(v) if v != "" { pp = append(pp, fmt.Sprintf("'%s'", v)) // '1','2' gibi } } if len(pp) == 0 { return "" } return strings.Join(pp, ",") } /* ============================ HEADER (Ana Tablo) ============================ */ func GetStatementsHPDF(accountCode, startDate, endDate string, parislemler []string) ([]models.StatementHeader, []string, error) { // Account normalize if len(accountCode) == 7 && strings.ContainsAny(accountCode, "0123456789") { accountCode = accountCode[:3] + " " + accountCode[3:] } // IN list parse et inList := buildQuotedHList(parislemler) parislemCond := "''" if inList != "" { parislemCond = inList } query := fmt.Sprintf(` ;WITH Opening AS ( SELECT b.CurrAccCode AS Cari_Kod, b.DocCurrencyCode AS Para_Birimi, SUM(c.Debit - c.Credit) AS Devir_Bakiyesi FROM trCurrAccBook b LEFT JOIN trCurrAccBookCurrency c ON c.CurrAccBookID = b.CurrAccBookID AND c.CurrencyCode = b.DocCurrencyCode WHERE b.CurrAccCode LIKE @Carikod AND b.DocumentDate < @StartDate AND EXISTS ( SELECT 1 FROM CurrAccBookATAttributesFilter f2 WHERE f2.CurrAccBookID = b.CurrAccBookID AND f2.ATAtt01 IN (%s) ) GROUP BY b.CurrAccCode, b.DocCurrencyCode ), Movements AS ( SELECT b.CurrAccCode AS Cari_Kod, d.CurrAccDescription AS Cari_Isim, CONVERT(varchar(10), b.DocumentDate, 23) AS Belge_Tarihi, CONVERT(varchar(10), b.DueDate, 23) AS Vade_Tarihi, b.RefNumber AS Belge_No, b.BaseApplicationCode AS Islem_Tipi, b.LineDescription AS Aciklama, b.DocCurrencyCode AS Para_Birimi, c.Debit AS Borc, c.Credit AS Alacak, SUM(c.Debit - c.Credit) OVER (PARTITION BY b.CurrAccCode, c.CurrencyCode ORDER BY b.DocumentDate, b.CurrAccBookID) AS Hareket_Bakiyesi, f.ATAtt01 AS Parislemler FROM trCurrAccBook b LEFT JOIN cdCurrAccDesc d ON b.CurrAccCode = d.CurrAccCode AND d.LangCode = 'TR' LEFT JOIN trCurrAccBookCurrency c ON b.CurrAccBookID = c.CurrAccBookID AND b.DocCurrencyCode = c.CurrencyCode LEFT JOIN CurrAccBookATAttributesFilter f ON b.CurrAccBookID = f.CurrAccBookID WHERE b.CurrAccCode LIKE @Carikod AND b.DocumentDate BETWEEN @StartDate AND @EndDate AND EXISTS ( SELECT 1 FROM CurrAccBookATAttributesFilter f2 WHERE f2.CurrAccBookID = b.CurrAccBookID AND f2.ATAtt01 IN (%s) ) )`, parislemCond, parislemCond) query += fmt.Sprintf(` SELECT m.Cari_Kod, m.Cari_Isim, m.Belge_Tarihi, m.Vade_Tarihi, m.Belge_No, m.Islem_Tipi, m.Aciklama, m.Para_Birimi, m.Borc, m.Alacak, ISNULL(o.Devir_Bakiyesi,0) + m.Hareket_Bakiyesi AS Bakiye, m.Parislemler FROM Movements m LEFT JOIN Opening o ON o.Cari_Kod = m.Cari_Kod AND o.Para_Birimi = m.Para_Birimi UNION ALL -- Devir satırı SELECT @Carikod AS Cari_Kod, MAX(d.CurrAccDescription) AS Cari_Isim, CONVERT(varchar(10), @StartDate, 23) AS Belge_Tarihi, CONVERT(varchar(10), @StartDate, 23) AS Vade_Tarihi, 'Baslangic_devir' AS Belge_No, 'Devir' AS Islem_Tipi, 'Devir Bakiyesi' AS Aciklama, b.DocCurrencyCode AS Para_Birimi, SUM(c.Debit) AS Borc, SUM(c.Credit) AS Alacak, SUM(c.Debit) - SUM(c.Credit) AS Bakiye, ( SELECT STRING_AGG(x.ATAtt01, ',') FROM ( SELECT DISTINCT f2.ATAtt01 FROM CurrAccBookATAttributesFilter f2 INNER JOIN trCurrAccBook bb ON f2.CurrAccBookID = bb.CurrAccBookID WHERE bb.CurrAccCode LIKE @Carikod AND bb.DocumentDate < @StartDate AND f2.ATAtt01 IN (%s) ) x ) AS Parislemler FROM trCurrAccBook b LEFT JOIN cdCurrAccDesc d ON b.CurrAccCode = d.CurrAccCode AND d.LangCode = 'TR' LEFT JOIN trCurrAccBookCurrency c ON b.CurrAccBookID = c.CurrAccBookID AND b.DocCurrencyCode = c.CurrencyCode WHERE b.CurrAccCode LIKE @Carikod AND b.DocumentDate < @StartDate GROUP BY b.DocCurrencyCode ORDER BY Para_Birimi, Belge_Tarihi;`, parislemCond) rows, err := db.MssqlDB.Query(query, sql.Named("Carikod", "%"+accountCode+"%"), sql.Named("StartDate", startDate), sql.Named("EndDate", endDate), ) if err != nil { log.Printf("❌ Header sorgu hatası: %v", err) return nil, nil, fmt.Errorf("header sorgu hatası: %v", err) } defer rows.Close() var headers []models.StatementHeader var belgeNos []string for rows.Next() { var h models.StatementHeader if err := rows.Scan( &h.CariKod, &h.CariIsim, &h.BelgeTarihi, &h.VadeTarihi, &h.BelgeNo, &h.IslemTipi, &h.Aciklama, &h.ParaBirimi, &h.Borc, &h.Alacak, &h.Bakiye, &h.Parislemler, ); err != nil { log.Printf("❌ Header scan hatası: %v", err) return nil, nil, err } headers = append(headers, h) if h.BelgeNo != "" { belgeNos = append(belgeNos, h.BelgeNo) } } log.Printf("✅ Header verileri alındı: %d kayıt, %d belge no", len(headers), len(belgeNos)) return headers, belgeNos, nil }