ui: add B2B olmayan stok (orphans) page

This commit is contained in:
M_Kececi
2026-06-24 23:08:28 +03:00
parent 6b9cd6fe5a
commit 701cc5e439

View File

@@ -353,14 +353,73 @@ WHERE product_code = ANY($1)
existing, _ := loadProductSeriesAssignments(ctx, pg, codes) existing, _ := loadProductSeriesAssignments(ctx, pg, codes)
// Per-request cache for per-mmitem dimval3 inference to avoid repeated dfblob scans. // Per-request cache for per-mmitem dimval3 inference to avoid repeated dfblob scans.
inferCache := map[string]int64{}
inferDim3ForMmitem := func(mmitemID int64, token string) int64 {
mmitemID = int64(mmitemID)
tok := strings.ToUpper(normalizeDimParam(token))
if mmitemID <= 0 || tok == "" {
return 0
}
key := fmt.Sprintf("%d|%s", mmitemID, tok)
if v, ok := inferCache[key]; ok {
return v
}
patterns := buildNameLikePatterns(tok)
if len(patterns) == 0 {
inferCache[key] = 0
return 0
}
var dimv string
err := pg.QueryRowContext(ctx, `
SELECT x.dimv
FROM (
SELECT COALESCE(dimval3::text, '') AS dimv, COUNT(*) AS cnt
FROM dfblob
WHERE src_table='mmitem'
AND typ='img'
AND src_id=$7
AND COALESCE(dimval3::text, '') <> ''
AND (
UPPER(COALESCE(file_name,'')) LIKE $1 OR
UPPER(COALESCE(file_name,'')) LIKE $2 OR
UPPER(COALESCE(file_name,'')) LIKE $3 OR
UPPER(COALESCE(file_name,'')) LIKE $4 OR
UPPER(COALESCE(file_name,'')) LIKE $5 OR
UPPER(COALESCE(file_name,'')) LIKE $6
)
GROUP BY COALESCE(dimval3::text, '')
) x
ORDER BY x.cnt DESC, x.dimv
LIMIT 1
`, patterns[0], patterns[1], patterns[2], patterns[3], patterns[4], patterns[5], mmitemID).Scan(&dimv)
if err != nil {
inferCache[key] = 0
return 0
}
dimv = strings.TrimSpace(dimv)
if dimv == "" || dimv == "0" {
inferCache[key] = 0
return 0
}
id, err := strconv.ParseInt(dimv, 10, 64)
if err != nil || id <= 0 {
inferCache[key] = 0
return 0
}
inferCache[key] = id
return id
}
out := make([]productSeriesMappingRow, 0, len(grouped)) out := make([]productSeriesMappingRow, 0, len(grouped))
for _, row := range grouped { for _, row := range grouped {
row.MmitemID = mmitemByCode[row.ProductCode] row.MmitemID = mmitemByCode[row.ProductCode]
row.Dim1ID = dim1ByToken[row.ColorCode] row.Dim1ID = dim1ByToken[row.ColorCode]
if row.Dim3Code != "" { if row.Dim3Code != "" {
// Strict: only accept explicit token map rows for dimval3. // Prefer token map; fallback to per-item inference (do not persist).
if v := dim3ByToken[row.Dim3Code]; v > 0 { if v := dim3ByToken[row.Dim3Code]; v > 0 {
row.Dim3ID = v row.Dim3ID = v
} else if inferred := inferDim3ForMmitem(row.MmitemID, row.Dim3Code); inferred > 0 {
row.Dim3ID = inferred
} }
} }
// Only show variants that are also known/valid on the PG side (product_code + dim1 + dim3_key). // Only show variants that are also known/valid on the PG side (product_code + dim1 + dim3_key).
@@ -582,6 +641,64 @@ WHERE product_code = ANY($1)
dim3ByToken, _ := loadDimTokenIDsStrict(ctx, pg, "dimval3", setToSortedSlice(dim3Set)) dim3ByToken, _ := loadDimTokenIDsStrict(ctx, pg, "dimval3", setToSortedSlice(dim3Set))
combos, _ := loadProductDimCombos(ctx, pg, codes) combos, _ := loadProductDimCombos(ctx, pg, codes)
// Per-request cache for per-mmitem dimval3 inference (dfblob scan).
inferCache := map[string]int64{}
inferDim3ForMmitem := func(mmitemID int64, token string) int64 {
mmitemID = int64(mmitemID)
tok := strings.ToUpper(normalizeDimParam(token))
if mmitemID <= 0 || tok == "" {
return 0
}
key := fmt.Sprintf("%d|%s", mmitemID, tok)
if v, ok := inferCache[key]; ok {
return v
}
patterns := buildNameLikePatterns(tok)
if len(patterns) == 0 {
inferCache[key] = 0
return 0
}
var dimv string
err := pg.QueryRowContext(ctx, `
SELECT x.dimv
FROM (
SELECT COALESCE(dimval3::text, '') AS dimv, COUNT(*) AS cnt
FROM dfblob
WHERE src_table='mmitem'
AND typ='img'
AND src_id=$7
AND COALESCE(dimval3::text, '') <> ''
AND (
UPPER(COALESCE(file_name,'')) LIKE $1 OR
UPPER(COALESCE(file_name,'')) LIKE $2 OR
UPPER(COALESCE(file_name,'')) LIKE $3 OR
UPPER(COALESCE(file_name,'')) LIKE $4 OR
UPPER(COALESCE(file_name,'')) LIKE $5 OR
UPPER(COALESCE(file_name,'')) LIKE $6
)
GROUP BY COALESCE(dimval3::text, '')
) x
ORDER BY x.cnt DESC, x.dimv
LIMIT 1
`, patterns[0], patterns[1], patterns[2], patterns[3], patterns[4], patterns[5], mmitemID).Scan(&dimv)
if err != nil {
inferCache[key] = 0
return 0
}
dimv = strings.TrimSpace(dimv)
if dimv == "" || dimv == "0" {
inferCache[key] = 0
return 0
}
id, err := strconv.ParseInt(dimv, 10, 64)
if err != nil || id <= 0 {
inferCache[key] = 0
return 0
}
inferCache[key] = id
return id
}
out := make([]productSeriesMappingRow, 0, len(grouped)) out := make([]productSeriesMappingRow, 0, len(grouped))
for _, row := range grouped { for _, row := range grouped {
if row.TotalQty <= 0 { if row.TotalQty <= 0 {
@@ -592,6 +709,8 @@ WHERE product_code = ANY($1)
if row.Dim3Code != "" { if row.Dim3Code != "" {
if v := dim3ByToken[row.Dim3Code]; v > 0 { if v := dim3ByToken[row.Dim3Code]; v > 0 {
row.Dim3ID = v row.Dim3ID = v
} else if inferred := inferDim3ForMmitem(row.MmitemID, row.Dim3Code); inferred > 0 {
row.Dim3ID = inferred
} }
} }