Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-06-18 15:20:34 +03:00
parent f6f9ac55b8
commit 21b1242a5a
3 changed files with 132 additions and 9 deletions

View File

@@ -392,6 +392,45 @@ WHERE is_active = TRUE
Price float64 `json:"price"`
}
// sdprc has a unique constraint on the business key (tier/currency/dims).
// If input rows contain duplicates for the same key (can happen due to tier/group mapping),
// we must dedupe before bulk inserting to avoid 500s like "duplicate key violates uq_sdprc_2".
dedupeSdprcWriteRows := func(productCode string, in []sdprcWriteRow) []sdprcWriteRow {
if len(in) <= 1 {
return in
}
type key struct {
Cur string
Grp int
D1 int64
D3 int64 // 0 => NULL
}
idx := make(map[key]int, len(in))
out := make([]sdprcWriteRow, 0, len(in))
for _, r := range in {
cur := strings.ToUpper(strings.TrimSpace(r.Currency))
d3k := int64(0)
if r.Dim3 != nil && *r.Dim3 > 0 {
d3k = *r.Dim3
}
k := key{Cur: cur, Grp: r.SdprcGrpID, D1: r.Dim1, D3: d3k}
if i, ok := idx[k]; ok {
out[i] = r // keep last
continue
}
idx[k] = len(out)
out = append(out, r)
}
if len(out) != len(in) {
logger.Warn("save:pg:sdprc:dedupe",
"product_code", strings.TrimSpace(productCode),
"in_rows", len(in),
"out_rows", len(out),
)
}
return out
}
loadDimCombosFromCache := func(productCode string) ([]dimCombo, error) {
productCode = strings.TrimSpace(productCode)
if productCode == "" {
@@ -552,11 +591,17 @@ DO UPDATE SET dim_id = EXCLUDED.dim_id, updated_at = EXCLUDED.updated_at
if err := rows.Scan(&colorCode, &dim1Code, &dim3Code); err != nil {
return nil, err
}
// Resolve to PG dim ids (e-commerce expects integer ids, e.g. dim1=82).
// Resolve to PG dim ids (e-commerce expects integer ids, e.g. dim1=82, dim3=2182).
// Nebim varies by installation; we try a few fallbacks. In most setups:
// - dim1 is size (ItemDim1Code)
// - dim3 is color (ColorCode)
d1 := int64(0)
if id, ok := resolveDimvalFromToken(pgTx, "dimval1", dim1Code); ok {
d1 = id
resolvedDim1++
} else if id, ok := resolveDimvalFromToken(pgTx, "dimval1", dim3Code); ok {
d1 = id
resolvedDim1++
} else if id, ok := resolveDimvalFromToken(pgTx, "dimval1", colorCode); ok {
d1 = id
resolvedDim1++
@@ -565,7 +610,12 @@ DO UPDATE SET dim_id = EXCLUDED.dim_id, updated_at = EXCLUDED.updated_at
continue
}
var d3 sql.NullInt64
if id, ok := resolveDimvalFromToken(pgTx, "dimval3", dim3Code); ok {
// IMPORTANT: In this Nebim setup, both ItemDim1Code and ItemDim3Code are mapped in PG as dimval1 ids.
// We therefore resolve dim3 via dimval1 as well (not dimval3).
if id, ok := resolveDimvalFromToken(pgTx, "dimval1", dim3Code); ok {
d3 = sql.NullInt64{Int64: id, Valid: true}
resolvedDim3++
} else if id, ok := resolveDimvalFromToken(pgTx, "dimval1", colorCode); ok {
d3 = sql.NullInt64{Int64: id, Valid: true}
resolvedDim3++
}
@@ -1073,6 +1123,7 @@ VALUES (
}
}
if len(writeRows) > 0 {
writeRows = dedupeSdprcWriteRows(code, writeRows)
startPG := time.Now()
inserted, err := bulkAppendOnlyInsertSdprc(mmItemID, code, writeRows)
if err != nil {