package queries import ( "bssapp-backend/auth" "bssapp-backend/internal/authz" "context" "database/sql" "fmt" ) // ======================================================== // 📌 GetOrderProductionList — Üretime verilecek ürün içeren siparişler // ======================================================== func GetOrderProductionList( 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 (orderlist.go ile aynı kolonlar) // ---------------------------------------------------- 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, CAST(1 AS bit) AS HasUretimUrunu, 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 ) -- ✅ Üretime verilecek ürün filtresi AND EXISTS ( SELECT 1 FROM dbo.trOrderLine l2 WHERE l2.OrderHeaderID = h.OrderHeaderID AND ISNULL(l2.ItemCode,'') LIKE 'U%%' ) `, 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) }