package queries import ( "bssapp-backend/auth" "bssapp-backend/internal/authz" "context" "database/sql" "fmt" ) // ======================================================== // 📌 GetOrderList — FINAL + CURRENCY SAFE + PIYASA AUTHZ // ======================================================== 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 { // hiç yetkisi yok → hiç kayıt dönmesin piyasaWhere = "1=0" } else { // ⚠️ EXISTS içinde kullanılacak 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(h.IsCreditableConfirmed,0) AS IsCreditableConfirmed, ISNULL(h.Description,'') AS Description, usd.Rate AS ExchangeRateUSD FROM dbo.trOrderHeader h JOIN ( SELECT OrderHeaderID, SUM(Qty1 * Price) AS TotalAmount FROM dbo.trOrderLine GROUP BY 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) }