Merge remote-tracking branch 'origin/master'
This commit is contained in:
19
svc/models/orderproductionitem.go
Normal file
19
svc/models/orderproductionitem.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package models
|
||||
|
||||
// ========================================================
|
||||
// 📌 OrderProductionItem — U ile başlayan ürün satırı
|
||||
// ========================================================
|
||||
type OrderProductionItem struct {
|
||||
OrderHeaderID string `json:"OrderHeaderID"`
|
||||
OrderLineID string `json:"OrderLineID"`
|
||||
|
||||
OldItemCode string `json:"OldItemCode"`
|
||||
OldColor string `json:"OldColor"`
|
||||
OldDim2 string `json:"OldDim2"`
|
||||
OldDesc string `json:"OldDesc"`
|
||||
|
||||
NewItemCode string `json:"NewItemCode"`
|
||||
NewColor string `json:"NewColor"`
|
||||
NewDim2 string `json:"NewDim2"`
|
||||
NewDesc string `json:"NewDesc"`
|
||||
}
|
||||
31
svc/queries/orderproduction_items.go
Normal file
31
svc/queries/orderproduction_items.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package queries
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
// ========================================================
|
||||
// 📌 GetOrderProductionItems — OrderHeaderID için U ürünleri
|
||||
// ========================================================
|
||||
func GetOrderProductionItems(mssql *sql.DB, orderHeaderID string) (*sql.Rows, error) {
|
||||
return mssql.Query(`
|
||||
SELECT
|
||||
CAST(l.OrderHeaderID AS NVARCHAR(50)) AS OrderHeaderID,
|
||||
CAST(l.OrderLineID AS NVARCHAR(50)) AS OrderLineID,
|
||||
|
||||
-- Şimdilik eski alanlar boş döndürülür
|
||||
CAST('' AS NVARCHAR(50)) AS OldItemCode,
|
||||
CAST('' AS NVARCHAR(50)) AS OldColor,
|
||||
CAST('' AS NVARCHAR(50)) AS OldDim2,
|
||||
CAST('' AS NVARCHAR(250)) AS OldDesc,
|
||||
|
||||
ISNULL(l.ItemCode,'') AS NewItemCode,
|
||||
ISNULL(l.ColorCode,'') AS NewColor,
|
||||
ISNULL(l.ItemDim2Code,'') AS NewDim2,
|
||||
ISNULL(l.LineDescription,'') AS NewDesc
|
||||
FROM dbo.trOrderLine l
|
||||
WHERE l.OrderHeaderID = @p1
|
||||
AND ISNULL(l.ItemCode,'') LIKE 'U%'
|
||||
ORDER BY l.SortOrder, l.OrderLineID
|
||||
`, orderHeaderID)
|
||||
}
|
||||
269
svc/queries/orderproductionlist.go
Normal file
269
svc/queries/orderproductionlist.go
Normal file
@@ -0,0 +1,269 @@
|
||||
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)
|
||||
}
|
||||
66
svc/routes/orderproductionitems.go
Normal file
66
svc/routes/orderproductionitems.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bssapp-backend/models"
|
||||
"bssapp-backend/queries"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// ======================================================
|
||||
// 📌 OrderProductionItemsRoute — U ürün satırları
|
||||
// ======================================================
|
||||
func OrderProductionItemsRoute(mssql *sql.DB) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
id := mux.Vars(r)["id"]
|
||||
if id == "" {
|
||||
http.Error(w, "OrderHeaderID bulunamadı", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := queries.GetOrderProductionItems(mssql, id)
|
||||
if err != nil {
|
||||
log.Printf("❌ SQL sorgu hatası: %v", err)
|
||||
http.Error(w, "Veritabanı hatası", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
list := make([]models.OrderProductionItem, 0, 100)
|
||||
|
||||
for rows.Next() {
|
||||
var o models.OrderProductionItem
|
||||
if err := rows.Scan(
|
||||
&o.OrderHeaderID,
|
||||
&o.OrderLineID,
|
||||
&o.OldItemCode,
|
||||
&o.OldColor,
|
||||
&o.OldDim2,
|
||||
&o.OldDesc,
|
||||
&o.NewItemCode,
|
||||
&o.NewColor,
|
||||
&o.NewDim2,
|
||||
&o.NewDesc,
|
||||
); err != nil {
|
||||
log.Printf("⚠️ SCAN HATASI: %v", err)
|
||||
continue
|
||||
}
|
||||
list = append(list, o)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
log.Printf("⚠️ rows.Err(): %v", err)
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(list); err != nil {
|
||||
log.Printf("❌ encode error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
130
svc/routes/orderproductionlist.go
Normal file
130
svc/routes/orderproductionlist.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bssapp-backend/auth"
|
||||
"bssapp-backend/db"
|
||||
"bssapp-backend/models"
|
||||
"bssapp-backend/queries"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ======================================================
|
||||
// 📌 OrderProductionListRoute — Üretime verilecek siparişler
|
||||
// ======================================================
|
||||
func OrderProductionListRoute(mssql *sql.DB) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
// --------------------------------------------------
|
||||
// 🔍 Query Param (RAW + TRIM)
|
||||
// --------------------------------------------------
|
||||
raw := r.URL.Query().Get("search")
|
||||
search := strings.TrimSpace(raw)
|
||||
|
||||
log.Printf(
|
||||
"📥 /api/orders/production-list search raw=%q trimmed=%q lenRaw=%d lenTrim=%d",
|
||||
raw,
|
||||
search,
|
||||
len(raw),
|
||||
len(search),
|
||||
)
|
||||
|
||||
// --------------------------------------------------
|
||||
// 🗄 SQL CALL (WITH CONTEXT)
|
||||
// --------------------------------------------------
|
||||
rows, err := queries.GetOrderProductionList(
|
||||
r.Context(),
|
||||
mssql,
|
||||
db.PgDB,
|
||||
search,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("❌ SQL sorgu hatası: %v", err)
|
||||
http.Error(w, "Veritabanı hatası", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
// --------------------------------------------------
|
||||
// 📦 Sonuç Listesi
|
||||
// --------------------------------------------------
|
||||
list := make([]models.OrderList, 0, 100)
|
||||
count := 0
|
||||
|
||||
// ==================================================
|
||||
// 🧠 SCAN — SQL SELECT ile BİRE BİR (18 kolon)
|
||||
// ==================================================
|
||||
for rows.Next() {
|
||||
|
||||
var o models.OrderList
|
||||
|
||||
err = rows.Scan(
|
||||
&o.OrderHeaderID, // 1
|
||||
&o.OrderNumber, // 2
|
||||
&o.OrderDate, // 3
|
||||
|
||||
&o.CurrAccCode, // 4
|
||||
&o.CurrAccDescription, // 5
|
||||
|
||||
&o.MusteriTemsilcisi, // 6
|
||||
&o.Piyasa, // 7
|
||||
|
||||
&o.CreditableConfirmedDate, // 8
|
||||
&o.DocCurrencyCode, // 9
|
||||
|
||||
&o.TotalAmount, // 10
|
||||
&o.TotalAmountUSD, // 11
|
||||
&o.PackedAmount, // 12
|
||||
&o.PackedUSD, // 13
|
||||
&o.PackedRatePct, // 14
|
||||
|
||||
&o.IsCreditableConfirmed, // 15
|
||||
&o.HasUretimUrunu, // 16
|
||||
&o.Description, // 17
|
||||
|
||||
&o.ExchangeRateUSD, // 18
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Printf(
|
||||
"⚠️ SCAN HATASI | OrderHeaderID=%v | err=%v",
|
||||
o.OrderHeaderID,
|
||||
err,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
list = append(list, o)
|
||||
count++
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
log.Printf("⚠️ rows.Err(): %v", err)
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// 📊 RESULT LOG
|
||||
// --------------------------------------------------
|
||||
claims, _ := auth.GetClaimsFromContext(r.Context())
|
||||
|
||||
log.Printf(
|
||||
"✅ Order production list DONE | user=%d | search=%q | resultCount=%d",
|
||||
claims.ID,
|
||||
search,
|
||||
count,
|
||||
)
|
||||
|
||||
// --------------------------------------------------
|
||||
// ✅ JSON RESPONSE
|
||||
// --------------------------------------------------
|
||||
if err := json.NewEncoder(w).Encode(list); err != nil {
|
||||
log.Printf("❌ encode error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user