package queries import ( "bssapp-backend/auth" "bssapp-backend/internal/authz" "context" "database/sql" "fmt" ) // ======================================================== // 📌 GetOrderList — FINAL + CURRENCY SAFE + PIYASA AUTHZ // // ✅ TotalAmount artık trOrderLineCurrency(NetAmount) üzerinden // ve CurrencyCode = Header.DocCurrencyCode satırından gelir. // // ======================================================== func GetOrderList( ctx context.Context, mssql *sql.DB, pg *sql.DB, search string, ) (*sql.Rows, error) { claims, ok := auth.GetClaimsFromContext(ctx) if !ok || claims == nil { return nil, fmt.Errorf("unauthorized: claims not found") } // ---------------------------------------------------- // 🔐 PIYASA FILTER (ADMIN BYPASS) // ---------------------------------------------------- piyasaWhere := "1=1" if !claims.IsAdmin() { codes, err := authz.GetUserPiyasaCodes(pg, int(claims.ID)) if err != nil { return nil, fmt.Errorf("piyasa codes load error: %w", err) } if len(codes) == 0 { piyasaWhere = "1=0" } else { piyasaWhere = authz.BuildINClause( "UPPER(f2.CustomerAtt01)", codes, ) } } // ---------------------------------------------------- // 📄 BASE QUERY // ---------------------------------------------------- baseQuery := fmt.Sprintf(` SELECT CAST(h.OrderHeaderID AS NVARCHAR(50)) AS OrderHeaderID, ISNULL(h.OrderNumber, '') AS OrderNumber, CONVERT(varchar, h.OrderDate, 23) AS OrderDate, ISNULL(h.CurrAccCode, '') AS CurrAccCode, ISNULL(ca.CurrAccDescription, '') AS CurrAccDescription, ISNULL(mt.AttributeDescription, '') AS MusteriTemsilcisi, ISNULL(py.AttributeDescription, '') AS Piyasa, CONVERT(varchar, h.CreditableConfirmedDate,23) AS CreditableConfirmedDate, ISNULL(h.DocCurrencyCode,'TRY') AS DocCurrencyCode, ISNULL(l.TotalAmount,0) AS TotalAmount, ---------------------------------------------------------------- -- USD HESABI (TRY / EUR / GBP / USD DESTEKLİ) ---------------------------------------------------------------- CASE WHEN h.DocCurrencyCode = 'USD' THEN ISNULL(l.TotalAmount,0) WHEN h.DocCurrencyCode = 'TRY' AND usd.Rate > 0 THEN ISNULL(l.TotalAmount,0) / usd.Rate WHEN h.DocCurrencyCode IN ('EUR','GBP') AND cur.Rate > 0 AND usd.Rate > 0 THEN (ISNULL(l.TotalAmount,0) * cur.Rate) / usd.Rate ELSE 0 END AS TotalAmountUSD, ISNULL(l.PackedAmount,0) AS PackedAmount, CASE WHEN h.DocCurrencyCode = 'USD' THEN ISNULL(l.PackedAmount,0) WHEN h.DocCurrencyCode = 'TRY' AND usd.Rate > 0 THEN ISNULL(l.PackedTRY,0) / usd.Rate WHEN cur.Rate > 0 AND usd.Rate > 0 THEN (ISNULL(l.PackedAmount,0) * cur.Rate) / usd.Rate ELSE 0 END AS PackedUSD, CASE WHEN ISNULL(l.TotalAmount,0) > 0 THEN (ISNULL(l.PackedAmount,0) * 100.0) / NULLIF(l.TotalAmount,0) ELSE 0 END AS PackedRatePct, ISNULL(h.IsCreditableConfirmed,0) AS IsCreditableConfirmed, ISNULL(h.Description,'') AS Description, usd.Rate AS ExchangeRateUSD FROM dbo.trOrderHeader h -- ✅ TOPLAM ARTIK trOrderLineCurrency'den: CurrencyCode = DocCurrencyCode JOIN ( SELECT l.OrderHeaderID, SUM(ISNULL(c.NetAmount,0)) AS TotalAmount, SUM( CASE WHEN ISNULL(c.CurrencyCode,'') = 'TRY' THEN ISNULL(c.NetAmount,0) ELSE 0 END ) AS TotalTRY, SUM( CASE WHEN ISNULL(l.IsClosed,0) = 1 THEN ISNULL(c.NetAmount,0) ELSE 0 END ) AS PackedAmount, SUM( CASE WHEN ISNULL(l.IsClosed,0) = 1 AND ISNULL(c.CurrencyCode,'') = 'TRY' THEN ISNULL(c.NetAmount,0) ELSE 0 END ) AS PackedTRY FROM dbo.trOrderLine l JOIN dbo.trOrderHeader h2 ON h2.OrderHeaderID = l.OrderHeaderID LEFT JOIN dbo.trOrderLineCurrency c ON c.OrderLineID = l.OrderLineID AND c.CurrencyCode = ISNULL(h2.DocCurrencyCode,'TRY') GROUP BY l.OrderHeaderID ) l ON l.OrderHeaderID = h.OrderHeaderID LEFT JOIN dbo.cdCurrAccDesc ca ON ca.CurrAccCode = h.CurrAccCode AND ca.LangCode = 'TR' -- müşteri temsilcisi + piyasa açıklamaları LEFT JOIN dbo.CustomerAttributesFilter f ON f.CurrAccCode = h.CurrAccCode LEFT JOIN dbo.cdCurrAccAttributeDesc mt ON mt.CurrAccTypeCode = 3 AND mt.AttributeTypeCode = 2 AND mt.AttributeCode = f.CustomerAtt02 AND mt.LangCode = 'TR' LEFT JOIN dbo.cdCurrAccAttributeDesc py ON py.CurrAccTypeCode = 3 AND py.AttributeTypeCode = 1 AND py.AttributeCode = f.CustomerAtt01 AND py.LangCode = 'TR' ---------------------------------------------------------------- -- USD → TRY ---------------------------------------------------------------- OUTER APPLY ( SELECT TOP 1 Rate FROM dbo.AllExchangeRates WHERE CurrencyCode = 'USD' AND RelationCurrencyCode = 'TRY' AND ExchangeTypeCode = 6 AND Rate > 0 AND Date <= CAST(GETDATE() AS date) ORDER BY Date DESC ) usd ---------------------------------------------------------------- -- ORDER PB → TRY ---------------------------------------------------------------- OUTER APPLY ( SELECT TOP 1 Rate FROM dbo.AllExchangeRates WHERE CurrencyCode = h.DocCurrencyCode AND RelationCurrencyCode = 'TRY' AND ExchangeTypeCode = 6 AND Rate > 0 AND Date <= CAST(GETDATE() AS date) ORDER BY Date DESC ) cur WHERE ISNULL(h.IsCancelOrder,0) = 0 AND h.OrderTypeCode = 1 AND h.ProcessCode = 'WS' AND h.IsClosed = 0 -- 🔐 PIYASA AUTHZ (EXISTS — SAĞLAM YOL) AND EXISTS ( SELECT 1 FROM dbo.CustomerAttributesFilter f2 WHERE f2.CurrAccCode = h.CurrAccCode AND %s ) `, piyasaWhere) // ---------------------------------------------------- // 🔍 SEARCH FILTER (CASE + TR SAFE) // ---------------------------------------------------- if search != "" { baseQuery += ` AND EXISTS ( SELECT 1 FROM dbo.trOrderHeader h2 LEFT JOIN dbo.cdCurrAccDesc ca2 ON ca2.CurrAccCode = h2.CurrAccCode AND ca2.LangCode = 'TR' WHERE h2.OrderHeaderID = h.OrderHeaderID AND ( LOWER(REPLACE(REPLACE(h2.OrderNumber,'İ','I'),'ı','i')) COLLATE Latin1_General_CI_AI LIKE LOWER(@p1) OR LOWER(REPLACE(REPLACE(h2.CurrAccCode,'İ','I'),'ı','i')) COLLATE Latin1_General_CI_AI LIKE LOWER(@p1) OR LOWER(REPLACE(REPLACE(ca2.CurrAccDescription,'İ','I'),'ı','i')) COLLATE Latin1_General_CI_AI LIKE LOWER(@p1) OR LOWER(REPLACE(REPLACE(h2.Description,'İ','I'),'ı','i')) COLLATE Latin1_General_CI_AI LIKE LOWER(@p1) ) ) ` } // ---------------------------------------------------- // 📌 ORDER // ---------------------------------------------------- baseQuery += ` ORDER BY h.CreatedDate DESC ` // ---------------------------------------------------- // ▶ EXECUTE // ---------------------------------------------------- if search != "" { searchLike := fmt.Sprintf("%%%s%%", search) return mssql.Query(baseQuery, searchLike) } return mssql.Query(baseQuery) }