Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -774,6 +774,19 @@ DO UPDATE SET dim_id = EXCLUDED.dim_id, updated_at = EXCLUDED.updated_at
|
||||
hasMMItemDim := make(map[int64]bool, len(itemIDs))
|
||||
dim1IDs := make([]int64, 0, 8192)
|
||||
dim3IDs := make([]int64, 0, 8192)
|
||||
itemDim1Candidates := make(map[int64][]int64, len(itemIDs))
|
||||
itemDim3Candidates := make(map[int64][]int64, len(itemIDs))
|
||||
addCandidate := func(dst map[int64][]int64, itemID int64, id int64) {
|
||||
if itemID <= 0 || id <= 0 {
|
||||
return
|
||||
}
|
||||
for _, existing := range dst[itemID] {
|
||||
if existing == id {
|
||||
return
|
||||
}
|
||||
}
|
||||
dst[itemID] = append(dst[itemID], id)
|
||||
}
|
||||
if len(itemIDs) > 0 {
|
||||
rows, err := pg.QueryContext(ctx, `
|
||||
SELECT mmitem_id, mmdim_id, val1, val2, val3
|
||||
@@ -804,9 +817,11 @@ WHERE mmitem_id = ANY($1::bigint[])
|
||||
d1 := v1.Int64
|
||||
_ = mmdimID
|
||||
_ = v2
|
||||
addCandidate(itemDim1Candidates, itemID, d1)
|
||||
d3k := int64(0)
|
||||
if v3.Valid && v3.Int64 > 0 {
|
||||
d3k = v3.Int64
|
||||
addCandidate(itemDim3Candidates, itemID, d3k)
|
||||
}
|
||||
|
||||
code := strings.TrimSpace(itemToCode[itemID])
|
||||
@@ -927,6 +942,84 @@ LIMIT 1
|
||||
return ""
|
||||
}
|
||||
|
||||
sortDimIDs := func(ids []int64) []int64 {
|
||||
out := append([]int64(nil), ids...)
|
||||
sort.Slice(out, func(i, j int) bool { return out[i] < out[j] })
|
||||
return out
|
||||
}
|
||||
sortTokens := func(tokens []string) []string {
|
||||
out := append([]string(nil), tokens...)
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
li := strings.TrimLeft(out[i], "0")
|
||||
lj := strings.TrimLeft(out[j], "0")
|
||||
if li == "" {
|
||||
li = "0"
|
||||
}
|
||||
if lj == "" {
|
||||
lj = "0"
|
||||
}
|
||||
ni, ei := strconv.ParseInt(li, 10, 64)
|
||||
nj, ej := strconv.ParseInt(lj, 10, 64)
|
||||
if ei == nil && ej == nil && ni != nj {
|
||||
return ni < nj
|
||||
}
|
||||
return out[i] < out[j]
|
||||
})
|
||||
return out
|
||||
}
|
||||
addToken := func(dst map[int64][]string, itemID int64, token string) {
|
||||
token = strings.ToUpper(normalizeDimParam(token))
|
||||
if itemID <= 0 || token == "" {
|
||||
return
|
||||
}
|
||||
for _, existing := range dst[itemID] {
|
||||
if existing == token {
|
||||
return
|
||||
}
|
||||
}
|
||||
dst[itemID] = append(dst[itemID], token)
|
||||
}
|
||||
buildInferredMap := func(column string, tokenByItem map[int64][]string, idsByItem map[int64][]int64) map[string]int64 {
|
||||
out := make(map[string]int64, 128)
|
||||
for itemID, tokens := range tokenByItem {
|
||||
sortedTokens := sortTokens(tokens)
|
||||
sortedIDs := sortDimIDs(idsByItem[itemID])
|
||||
if len(sortedTokens) == 0 || len(sortedTokens) != len(sortedIDs) {
|
||||
continue
|
||||
}
|
||||
for i, token := range sortedTokens {
|
||||
id := sortedIDs[i]
|
||||
if token == "" || id <= 0 {
|
||||
continue
|
||||
}
|
||||
key := column + "|" + token
|
||||
if _, exists := out[key]; !exists {
|
||||
out[key] = id
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
persistDimToken := func(column string, token string, id int64) {
|
||||
token = strings.ToUpper(normalizeDimParam(token))
|
||||
if column == "" || token == "" || id <= 0 {
|
||||
return
|
||||
}
|
||||
_, _ = pg.ExecContext(ctx, `
|
||||
INSERT INTO mk_dim_token_map (dim_column, token, dim_id, updated_at)
|
||||
VALUES ($1,$2,$3,now())
|
||||
ON CONFLICT (dim_column, token)
|
||||
DO UPDATE SET dim_id = EXCLUDED.dim_id, updated_at = EXCLUDED.updated_at
|
||||
`, column, token, id)
|
||||
}
|
||||
type msVariantRow struct {
|
||||
ItemCode string
|
||||
ColorCode string
|
||||
Dim1Code string
|
||||
Dim3Code string
|
||||
Qty sql.NullFloat64
|
||||
}
|
||||
|
||||
// MSSQL: stock list for selected products; map to (mmitem_id, dim1, dim3_key) via token->id mapping.
|
||||
joined := strings.Join(codes, ",")
|
||||
msRows, err := mssql.QueryContext(ctx, queries.GetWholesaleCampaignVariantStockByProducts, joined)
|
||||
@@ -934,11 +1027,14 @@ LIMIT 1
|
||||
http.Error(w, "variant stock query error: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer msRows.Close()
|
||||
msVariants := make([]msVariantRow, 0, 1024)
|
||||
colorTokensByItem := make(map[int64][]string, len(itemIDs))
|
||||
dim3TokensByItem := make(map[int64][]string, len(itemIDs))
|
||||
for msRows.Next() {
|
||||
var itemCode, colorCode, dim1Code, dim3Code string
|
||||
var qty sql.NullFloat64
|
||||
if err := msRows.Scan(&itemCode, &colorCode, &dim1Code, &dim3Code, &qty); err != nil {
|
||||
msRows.Close()
|
||||
http.Error(w, "variant stock scan error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -950,18 +1046,62 @@ LIMIT 1
|
||||
if itemID <= 0 {
|
||||
continue
|
||||
}
|
||||
msVariants = append(msVariants, msVariantRow{
|
||||
ItemCode: itemCode,
|
||||
ColorCode: colorCode,
|
||||
Dim1Code: dim1Code,
|
||||
Dim3Code: dim3Code,
|
||||
Qty: qty,
|
||||
})
|
||||
addToken(colorTokensByItem, itemID, colorCode)
|
||||
addToken(dim3TokensByItem, itemID, dim3Code)
|
||||
}
|
||||
if err := msRows.Err(); err != nil {
|
||||
msRows.Close()
|
||||
http.Error(w, "variant stock rows error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
msRows.Close()
|
||||
|
||||
inferredDim1 := buildInferredMap("dimval1", colorTokensByItem, itemDim1Candidates)
|
||||
inferredDim3 := buildInferredMap("dimval3", dim3TokensByItem, itemDim3Candidates)
|
||||
resolveProductDimID := func(column string, token string, inferred map[string]int64) (int64, bool) {
|
||||
if id, ok := resolveDimID(column, token); ok {
|
||||
return id, true
|
||||
}
|
||||
token = strings.ToUpper(normalizeDimParam(token))
|
||||
if token == "" {
|
||||
return 0, false
|
||||
}
|
||||
if id := inferred[column+"|"+token]; id > 0 {
|
||||
persistDimToken(column, token, id)
|
||||
return id, true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
for _, ms := range msVariants {
|
||||
itemCode := ms.ItemCode
|
||||
colorCode := ms.ColorCode
|
||||
dim1Code := ms.Dim1Code
|
||||
dim3Code := ms.Dim3Code
|
||||
qty := ms.Qty
|
||||
itemID := codeToItem[itemCode]
|
||||
if itemID <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 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 {
|
||||
if id, ok := resolveProductDimID("dimval1", colorCode, inferredDim1); ok {
|
||||
d1 = id
|
||||
}
|
||||
if d1 <= 0 {
|
||||
continue
|
||||
}
|
||||
d3k := int64(0)
|
||||
if id, ok := resolveDimID("dimval3", dim3Code); ok {
|
||||
if id, ok := resolveProductDimID("dimval3", dim3Code, inferredDim3); ok {
|
||||
d3k = id
|
||||
}
|
||||
key := fmt.Sprintf("%d|%d|%d", itemID, d1, d3k)
|
||||
@@ -974,7 +1114,7 @@ LIMIT 1
|
||||
v2 = sizeID
|
||||
}
|
||||
v3 := int64(0)
|
||||
if id, ok := resolveDimID("dimval3", dim3Code); ok {
|
||||
if id, ok := resolveProductDimID("dimval3", dim3Code, inferredDim3); ok {
|
||||
v3 = id
|
||||
}
|
||||
mmdimID := int64(2)
|
||||
|
||||
Reference in New Issue
Block a user