Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -548,6 +548,44 @@ func enrichAllProductPricingRows(ctx context.Context, out []models.ProductPricin
|
||||
}
|
||||
_ = pgRows.Close()
|
||||
}
|
||||
|
||||
// Last pricing date should reflect the most recent price publish, not the Nebim base price date.
|
||||
// E-commerce reads pg.sdprc; use its latest write timestamp as the authoritative "last pricing" signal.
|
||||
dateRows, err := pg.QueryContext(ctx, `
|
||||
SELECT
|
||||
mmitem.code AS code,
|
||||
to_char(MAX(sdprc.zlins_dttm), 'YYYY-MM-DD') AS last_pricing_date
|
||||
FROM sdprc
|
||||
JOIN mmitem ON mmitem.id = sdprc.mmitem_id
|
||||
WHERE mmitem.code = ANY($1)
|
||||
GROUP BY mmitem.code;
|
||||
`, pq.Array(chunk))
|
||||
if err == nil {
|
||||
for dateRows.Next() {
|
||||
var code, ymd string
|
||||
if err := dateRows.Scan(&code, &ymd); err != nil {
|
||||
_ = dateRows.Close()
|
||||
return err
|
||||
}
|
||||
code = strings.TrimSpace(code)
|
||||
ymd = strings.TrimSpace(ymd)
|
||||
if code == "" || len(ymd) != 10 {
|
||||
continue
|
||||
}
|
||||
if idx, ok := indexByCode[code]; ok {
|
||||
cur := strings.TrimSpace(out[idx].LastPricingDate)
|
||||
// both are YYYY-MM-DD, lexicographical compare is safe
|
||||
if cur == "" || cur < ymd {
|
||||
out[idx].LastPricingDate = ymd
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := dateRows.Err(); err != nil {
|
||||
_ = dateRows.Close()
|
||||
return err
|
||||
}
|
||||
_ = dateRows.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,13 @@ import (
|
||||
// GetProductPricingFilterOptions returns distinct option values for ProductPricing filters.
|
||||
// This is used to render filter dropdowns without loading the full dataset.
|
||||
func GetProductPricingFilterOptions(ctx context.Context, field string, q string, limit int, scopeUrunIlkGrubu []string) ([]string, error) {
|
||||
pg := db.PgDB
|
||||
mssql := db.MssqlDB
|
||||
if mssql == nil {
|
||||
return nil, fmt.Errorf("mssql db is nil")
|
||||
// Some option fields can still be served from PG cache table.
|
||||
if pg == nil {
|
||||
return nil, fmt.Errorf("mssql db is nil")
|
||||
}
|
||||
}
|
||||
field = strings.TrimSpace(field)
|
||||
q = strings.TrimSpace(q)
|
||||
@@ -24,6 +28,83 @@ func GetProductPricingFilterOptions(ctx context.Context, field string, q string,
|
||||
scopeUrunIlkGrubu = scopeUrunIlkGrubu[:3]
|
||||
}
|
||||
|
||||
// Fast path: use PG-derived pricing parameter cache for most fields.
|
||||
// This avoids scanning ProductFilterWithDescription('TR') on MSSQL, which can be slow and cause 504s.
|
||||
// productCode is not available in mk_urunpricingprmtr, keep MSSQL for that.
|
||||
if pg != nil && field != "productCode" {
|
||||
pgCol := ""
|
||||
switch field {
|
||||
case "brandGroupSelection":
|
||||
pgCol = "brand_group_sec"
|
||||
case "marka":
|
||||
pgCol = "marka"
|
||||
case "askiliYan":
|
||||
pgCol = "askili_yan"
|
||||
case "kategori":
|
||||
pgCol = "kategori"
|
||||
case "urunIlkGrubu":
|
||||
pgCol = "urun_ilk_grubu"
|
||||
case "urunAnaGrubu":
|
||||
pgCol = "urun_ana_grubu"
|
||||
case "urunAltGrubu":
|
||||
pgCol = "urun_alt_grubu"
|
||||
case "icerik":
|
||||
pgCol = "icerik"
|
||||
case "karisim":
|
||||
// "karisim" is intentionally deprecated in mk_urunpricingprmtr, keep MSSQL fallback.
|
||||
pgCol = ""
|
||||
default:
|
||||
pgCol = ""
|
||||
}
|
||||
|
||||
if pgCol != "" {
|
||||
args := make([]any, 0, 8)
|
||||
where := []string{
|
||||
"is_active = TRUE",
|
||||
fmt.Sprintf("NULLIF(BTRIM(%s), '') IS NOT NULL", pgCol),
|
||||
}
|
||||
if len(scopeUrunIlkGrubu) > 0 && field != "urunIlkGrubu" {
|
||||
args = append(args, scopeUrunIlkGrubu)
|
||||
where = append(where, fmt.Sprintf("urun_ilk_grubu = ANY($%d::text[])", len(args)))
|
||||
}
|
||||
if q != "" {
|
||||
like := q + "%"
|
||||
args = append(args, like)
|
||||
where = append(where, fmt.Sprintf("%s ILIKE $%d", pgCol, len(args)))
|
||||
}
|
||||
whereSQL := strings.Join(where, " AND ")
|
||||
|
||||
// Note: DISTINCT+ORDER+LIMIT is fine here due to small mk_urunpricingprmtr cardinality (~1000 rows).
|
||||
sqlText := fmt.Sprintf(`
|
||||
SELECT DISTINCT %s AS val
|
||||
FROM mk_urunpricingprmtr
|
||||
WHERE %s
|
||||
ORDER BY val ASC
|
||||
LIMIT %d
|
||||
`, pgCol, whereSQL, limit)
|
||||
|
||||
rows, err := pg.QueryContext(ctx, sqlText, args...)
|
||||
if err == nil {
|
||||
defer rows.Close()
|
||||
out := make([]string, 0, limit)
|
||||
for rows.Next() {
|
||||
var v sql.NullString
|
||||
if err := rows.Scan(&v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s := strings.TrimSpace(v.String); s != "" {
|
||||
out = append(out, s)
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
// If PG path fails, fall back to MSSQL below.
|
||||
}
|
||||
}
|
||||
|
||||
// Map UI filter fields -> MSSQL expression in ProductFilterWithDescription('TR')
|
||||
var expr string
|
||||
switch field {
|
||||
|
||||
99
svc/queries/wholesale_campaign_variants_mssql.go
Normal file
99
svc/queries/wholesale_campaign_variants_mssql.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package queries
|
||||
|
||||
// GetWholesaleCampaignVariantStockByProducts:
|
||||
// Returns per-product variant keys (ColorCode/ItemDim1Code/ItemDim3Code) and available stock qty.
|
||||
// We aggregate across warehouses/stores; semantics align with product-stock-query's "Kullanilabilir_Envanter".
|
||||
const GetWholesaleCampaignVariantStockByProducts = `
|
||||
DECLARE @Codes NVARCHAR(MAX) = @p1;
|
||||
|
||||
;WITH INP AS (
|
||||
-- SQL Server 2008 compatibility: string_split() does not exist.
|
||||
-- Split CSV via XML nodes().
|
||||
SELECT LTRIM(RTRIM(X.C.value('.', 'NVARCHAR(50)'))) AS ItemCode
|
||||
FROM (
|
||||
SELECT CAST('<i>' + REPLACE(REPLACE(@Codes, '&', '&'), ',', '</i><i>') + '</i>' AS XML) AS XmlData
|
||||
) D
|
||||
CROSS APPLY D.XmlData.nodes('/i') AS X(C)
|
||||
WHERE LTRIM(RTRIM(X.C.value('.', 'NVARCHAR(50)'))) <> ''
|
||||
),
|
||||
STOCK AS (
|
||||
SELECT
|
||||
S.ItemCode,
|
||||
LTRIM(RTRIM(ISNULL(S.ColorCode,''))) AS ColorCode,
|
||||
LTRIM(RTRIM(ISNULL(S.ItemDim3Code,''))) AS ItemDim3Code,
|
||||
MAX(LTRIM(RTRIM(ISNULL(S.ItemDim1Code,'')))) AS ItemDim1Code,
|
||||
SUM(S.In_Qty1 - S.Out_Qty1) AS InventoryQty1
|
||||
FROM trStock S WITH(NOLOCK)
|
||||
JOIN INP ON INP.ItemCode = S.ItemCode
|
||||
WHERE S.ItemTypeCode = 1
|
||||
AND LEN(S.ItemCode) = 13
|
||||
GROUP BY
|
||||
S.ItemCode, S.ColorCode, S.ItemDim3Code
|
||||
),
|
||||
PICK AS (
|
||||
SELECT
|
||||
P.ItemCode,
|
||||
LTRIM(RTRIM(ISNULL(P.ColorCode,''))) AS ColorCode,
|
||||
LTRIM(RTRIM(ISNULL(P.ItemDim3Code,''))) AS ItemDim3Code,
|
||||
MAX(LTRIM(RTRIM(ISNULL(P.ItemDim1Code,'')))) AS ItemDim1Code,
|
||||
SUM(P.Qty1) AS PickingQty1
|
||||
FROM PickingStates P
|
||||
JOIN INP ON INP.ItemCode = P.ItemCode
|
||||
WHERE P.ItemTypeCode = 1
|
||||
AND LEN(P.ItemCode) = 13
|
||||
GROUP BY
|
||||
P.ItemCode, P.ColorCode, P.ItemDim3Code
|
||||
),
|
||||
RESERVE AS (
|
||||
SELECT
|
||||
R.ItemCode,
|
||||
LTRIM(RTRIM(ISNULL(R.ColorCode,''))) AS ColorCode,
|
||||
LTRIM(RTRIM(ISNULL(R.ItemDim3Code,''))) AS ItemDim3Code,
|
||||
MAX(LTRIM(RTRIM(ISNULL(R.ItemDim1Code,'')))) AS ItemDim1Code,
|
||||
SUM(R.Qty1) AS ReserveQty1
|
||||
FROM ReserveStates R
|
||||
JOIN INP ON INP.ItemCode = R.ItemCode
|
||||
WHERE R.ItemTypeCode = 1
|
||||
AND LEN(R.ItemCode) = 13
|
||||
GROUP BY
|
||||
R.ItemCode, R.ColorCode, R.ItemDim3Code
|
||||
),
|
||||
DISP AS (
|
||||
SELECT
|
||||
D.ItemCode,
|
||||
LTRIM(RTRIM(ISNULL(D.ColorCode,''))) AS ColorCode,
|
||||
LTRIM(RTRIM(ISNULL(D.ItemDim3Code,''))) AS ItemDim3Code,
|
||||
MAX(LTRIM(RTRIM(ISNULL(D.ItemDim1Code,'')))) AS ItemDim1Code,
|
||||
SUM(D.Qty1) AS DispOrderQty1
|
||||
FROM DispOrderStates D
|
||||
JOIN INP ON INP.ItemCode = D.ItemCode
|
||||
WHERE D.ItemTypeCode = 1
|
||||
AND LEN(D.ItemCode) = 13
|
||||
GROUP BY
|
||||
D.ItemCode, D.ColorCode, D.ItemDim3Code
|
||||
)
|
||||
SELECT
|
||||
S.ItemCode AS ItemCode,
|
||||
S.ColorCode AS ColorCode,
|
||||
S.ItemDim1Code AS ItemDim1Code,
|
||||
S.ItemDim3Code AS ItemDim3Code,
|
||||
CAST(ROUND(
|
||||
S.InventoryQty1
|
||||
- ISNULL(PK.PickingQty1,0)
|
||||
- ISNULL(RS.ReserveQty1,0)
|
||||
- ISNULL(DP.DispOrderQty1,0),
|
||||
2
|
||||
) AS FLOAT) AS StockQty
|
||||
FROM STOCK S
|
||||
LEFT JOIN PICK PK
|
||||
ON PK.ItemCode=S.ItemCode AND PK.ColorCode=S.ColorCode AND PK.ItemDim3Code=S.ItemDim3Code
|
||||
LEFT JOIN RESERVE RS
|
||||
ON RS.ItemCode=S.ItemCode AND RS.ColorCode=S.ColorCode AND RS.ItemDim3Code=S.ItemDim3Code
|
||||
LEFT JOIN DISP DP
|
||||
ON DP.ItemCode=S.ItemCode AND DP.ColorCode=S.ColorCode AND DP.ItemDim3Code=S.ItemDim3Code
|
||||
WHERE (S.InventoryQty1
|
||||
- ISNULL(PK.PickingQty1,0)
|
||||
- ISNULL(RS.ReserveQty1,0)
|
||||
- ISNULL(DP.DispOrderQty1,0)) <> 0
|
||||
ORDER BY S.ItemCode, S.ColorCode, S.ItemDim3Code;
|
||||
`
|
||||
Reference in New Issue
Block a user