From 3732004a299b10219fcc3b6c21af5c8c0161eded Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Fri, 19 Jun 2026 12:49:49 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- svc/routes/product_pricing_save.go | 10 +--- svc/routes/wholesale_campaigns.go | 95 +++++++++++++++++------------- 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/svc/routes/product_pricing_save.go b/svc/routes/product_pricing_save.go index e9606c3..d7bb4e1 100644 --- a/svc/routes/product_pricing_save.go +++ b/svc/routes/product_pricing_save.go @@ -568,19 +568,13 @@ DO UPDATE SET dim_id = EXCLUDED.dim_id, updated_at = EXCLUDED.updated_at if id, ok := resolveDimvalFromToken(pgTx, "dimval1", colorCode); ok { d1 = id resolvedDim1++ - } else if id, ok := resolveDimvalFromToken(pgTx, "dimval1", dim3Code); ok { - d1 = id - resolvedDim1++ - } else if id, ok := resolveDimvalFromToken(pgTx, "dimval1", dim1Code); ok { - d1 = id - resolvedDim1++ } if d1 <= 0 { continue } var d3 sql.NullInt64 // dim3 corresponds to mmitem_dim.val3. - if id, ok := resolveDimvalFromToken(pgTx, "dimval1", dim3Code); ok { + if id, ok := resolveDimvalFromToken(pgTx, "dimval3", dim3Code); ok { d3 = sql.NullInt64{Int64: id, Valid: true} resolvedDim3++ } @@ -620,7 +614,7 @@ DO UPDATE SET dim_id = EXCLUDED.dim_id, updated_at = EXCLUDED.updated_at continue } var v2any any = nil - // Active key: val1=color, val3=itemdim3. val2 is size and is not part of price/campaign key. + // Active key: val1=color, val3=ItemDim2Code/yaka. val2 is size and is not part of price/campaign key. v3 := int64(0) if c.Dim3.Valid && c.Dim3.Int64 > 0 { v3 = c.Dim3.Int64 diff --git a/svc/routes/wholesale_campaigns.go b/svc/routes/wholesale_campaigns.go index 191aaa3..4dc1249 100644 --- a/svc/routes/wholesale_campaigns.go +++ b/svc/routes/wholesale_campaigns.go @@ -435,6 +435,9 @@ func buildNebimVariantDisplayCode(colorCode string, dim3Code string) string { func chooseDisplayDimToken(raw string, resolvedID int64, reverse map[int64]string) string { raw = strings.TrimSpace(raw) + if raw != "" { + return raw + } if resolvedID > 0 { if tok := strings.TrimSpace(reverse[resolvedID]); tok != "" { return tok @@ -769,7 +772,8 @@ DO UPDATE SET dim_id = EXCLUDED.dim_id, updated_at = EXCLUDED.updated_at } tmpMap := make(map[string]tmpRow, 4096) hasMMItemDim := make(map[int64]bool, len(itemIDs)) - dimIDs := make([]int64, 0, 8192) + dim1IDs := make([]int64, 0, 8192) + dim3IDs := make([]int64, 0, 8192) if len(itemIDs) > 0 { rows, err := pg.QueryContext(ctx, ` SELECT mmitem_id, mmdim_id, val1, val2, val3 @@ -796,7 +800,7 @@ WHERE mmitem_id = ANY($1::bigint[]) if !v1.Valid || v1.Int64 <= 0 { continue } - // Variant key in this installation: (val1=color, val3=itemdim3_if_any). Ignore val2 (size). + // Variant key in this installation: (val1=color, val3=ItemDim2Code/yaka_if_any). Ignore val2 (size). d1 := v1.Int64 _ = mmdimID _ = v2 @@ -821,9 +825,9 @@ WHERE mmitem_id = ANY($1::bigint[]) Dim1: d1, Dim3Key: d3k, } - dimIDs = append(dimIDs, d1) + dim1IDs = append(dim1IDs, d1) if d3k > 0 { - dimIDs = append(dimIDs, d3k) + dim3IDs = append(dim3IDs, d3k) } } rows.Close() @@ -831,12 +835,16 @@ WHERE mmitem_id = ANY($1::bigint[]) // Resolve dim ids -> tokens for a fallback readable VariantCode. // MSSQL/Nebim tokens override this below; PG ids are only storage keys. - idToToken := map[int64]string{} - if len(dimIDs) > 0 { + idToDim1Token := map[int64]string{} + idToDim3Token := map[int64]string{} + loadReverseTokens := func(column string, ids []int64, out map[int64]string) { + if len(ids) == 0 { + return + } // uniq - uniq := make([]int64, 0, len(dimIDs)) - seen := make(map[int64]struct{}, len(dimIDs)) - for _, id := range dimIDs { + uniq := make([]int64, 0, len(ids)) + seen := make(map[int64]struct{}, len(ids)) + for _, id := range ids { if id <= 0 { continue } @@ -846,35 +854,38 @@ WHERE mmitem_id = ANY($1::bigint[]) seen[id] = struct{}{} uniq = append(uniq, id) } - if len(uniq) > 0 { - rows, err := pg.QueryContext(ctx, ` + if len(uniq) == 0 { + return + } + rows, err := pg.QueryContext(ctx, ` SELECT DISTINCT ON (dim_id) dim_id, token FROM mk_dim_token_map -WHERE dim_column = 'dimval1' - AND dim_id = ANY($1::bigint[]) +WHERE dim_column = $1 + AND dim_id = ANY($2::bigint[]) ORDER BY dim_id, updated_at DESC; -`, pq.Array(uniq)) - if err == nil { - for rows.Next() { - var id int64 - var tok string - _ = rows.Scan(&id, &tok) - tok = strings.TrimSpace(tok) - if tok != "" { - idToToken[id] = tok - } +`, column, pq.Array(uniq)) + if err == nil { + for rows.Next() { + var id int64 + var tok string + _ = rows.Scan(&id, &tok) + tok = strings.TrimSpace(tok) + if tok != "" { + out[id] = tok } - rows.Close() } + rows.Close() } } + loadReverseTokens("dimval1", dim1IDs, idToDim1Token) + loadReverseTokens("dimval3", dim3IDs, idToDim3Token) for k, v := range tmpMap { - t1 := strings.TrimSpace(idToToken[v.Dim1]) + t1 := strings.TrimSpace(idToDim1Token[v.Dim1]) if t1 == "" { t1 = fmt.Sprintf("%d", v.Dim1) } if v.Dim3Key > 0 { - t3 := strings.TrimSpace(idToToken[v.Dim3Key]) + t3 := strings.TrimSpace(idToDim3Token[v.Dim3Key]) if t3 == "" { t3 = fmt.Sprintf("%d", v.Dim3Key) } @@ -884,28 +895,32 @@ ORDER BY dim_id, updated_at DESC; } tmpMap[k] = v } - canonicalToken := func(id int64) string { + canonicalToken := func(column string, id int64) string { if id <= 0 { return "" } - if tok := strings.TrimSpace(idToToken[id]); tok != "" { + target := idToDim1Token + if column == "dimval3" { + target = idToDim3Token + } + if tok := strings.TrimSpace(target[id]); tok != "" { return tok } var tok string if err := pg.QueryRowContext(ctx, ` SELECT token FROM mk_dim_token_map -WHERE dim_column = 'dimval1' - AND dim_id = $1 +WHERE dim_column = $1 + AND dim_id = $2 ORDER BY CASE WHEN token ~ '^[0-9]{3}$' THEN 0 ELSE 1 END, length(token), updated_at DESC LIMIT 1 -`, id).Scan(&tok); err == nil { +`, column, id).Scan(&tok); err == nil { tok = strings.TrimSpace(tok) if tok != "" { - idToToken[id] = tok + target[id] = tok return tok } } @@ -936,8 +951,8 @@ LIMIT 1 continue } - // Map Nebim tokens to PG integer ids (dimval1 namespace). - // This app uses key: dim1=, dim3= to match mmitem_dim (val1,val3). + // Map Nebim tokens to PG integer ids. Color and yaka must use separate token namespaces, + // because the same visible token (for example "001") can exist in both dimensions. d1 := int64(0) if id, ok := resolveDimID("dimval1", colorCode); ok { d1 = id @@ -946,7 +961,7 @@ LIMIT 1 continue } d3k := int64(0) - if id, ok := resolveDimID("dimval1", dim3Code); ok { + if id, ok := resolveDimID("dimval3", dim3Code); ok { d3k = id } key := fmt.Sprintf("%d|%d|%d", itemID, d1, d3k) @@ -959,7 +974,7 @@ LIMIT 1 v2 = sizeID } v3 := int64(0) - if id, ok := resolveDimID("dimval1", dim3Code); ok { + if id, ok := resolveDimID("dimval3", dim3Code); ok { v3 = id } mmdimID := int64(2) @@ -995,9 +1010,9 @@ WHERE NOT EXISTS ( Dim3Key: d3k, } // Keep dim token cache for VariantCode formatting. - dimIDs = append(dimIDs, d1) + dim1IDs = append(dim1IDs, d1) if d3k > 0 { - dimIDs = append(dimIDs, d3k) + dim3IDs = append(dim3IDs, d3k) } prev = tmpMap[key] ok = true @@ -1011,8 +1026,8 @@ WHERE NOT EXISTS ( q = qty.Float64 } prev.StockQty += q - displayColor := chooseDisplayDimToken(colorCode, d1, map[int64]string{d1: canonicalToken(d1)}) - displayDim3 := chooseDisplayDimToken(dim3Code, d3k, map[int64]string{d3k: canonicalToken(d3k)}) + displayColor := chooseDisplayDimToken(colorCode, d1, map[int64]string{d1: canonicalToken("dimval1", d1)}) + displayDim3 := chooseDisplayDimToken(dim3Code, d3k, map[int64]string{d3k: canonicalToken("dimval3", d3k)}) prev.VariantCode = buildNebimVariantDisplayCode(displayColor, displayDim3) prev.HasMSSQL = true tmpMap[key] = prev