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))
|
hasMMItemDim := make(map[int64]bool, len(itemIDs))
|
||||||
dim1IDs := make([]int64, 0, 8192)
|
dim1IDs := make([]int64, 0, 8192)
|
||||||
dim3IDs := 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 {
|
if len(itemIDs) > 0 {
|
||||||
rows, err := pg.QueryContext(ctx, `
|
rows, err := pg.QueryContext(ctx, `
|
||||||
SELECT mmitem_id, mmdim_id, val1, val2, val3
|
SELECT mmitem_id, mmdim_id, val1, val2, val3
|
||||||
@@ -804,9 +817,11 @@ WHERE mmitem_id = ANY($1::bigint[])
|
|||||||
d1 := v1.Int64
|
d1 := v1.Int64
|
||||||
_ = mmdimID
|
_ = mmdimID
|
||||||
_ = v2
|
_ = v2
|
||||||
|
addCandidate(itemDim1Candidates, itemID, d1)
|
||||||
d3k := int64(0)
|
d3k := int64(0)
|
||||||
if v3.Valid && v3.Int64 > 0 {
|
if v3.Valid && v3.Int64 > 0 {
|
||||||
d3k = v3.Int64
|
d3k = v3.Int64
|
||||||
|
addCandidate(itemDim3Candidates, itemID, d3k)
|
||||||
}
|
}
|
||||||
|
|
||||||
code := strings.TrimSpace(itemToCode[itemID])
|
code := strings.TrimSpace(itemToCode[itemID])
|
||||||
@@ -927,6 +942,84 @@ LIMIT 1
|
|||||||
return ""
|
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.
|
// MSSQL: stock list for selected products; map to (mmitem_id, dim1, dim3_key) via token->id mapping.
|
||||||
joined := strings.Join(codes, ",")
|
joined := strings.Join(codes, ",")
|
||||||
msRows, err := mssql.QueryContext(ctx, queries.GetWholesaleCampaignVariantStockByProducts, joined)
|
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)
|
http.Error(w, "variant stock query error: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
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() {
|
for msRows.Next() {
|
||||||
var itemCode, colorCode, dim1Code, dim3Code string
|
var itemCode, colorCode, dim1Code, dim3Code string
|
||||||
var qty sql.NullFloat64
|
var qty sql.NullFloat64
|
||||||
if err := msRows.Scan(&itemCode, &colorCode, &dim1Code, &dim3Code, &qty); err != nil {
|
if err := msRows.Scan(&itemCode, &colorCode, &dim1Code, &dim3Code, &qty); err != nil {
|
||||||
|
msRows.Close()
|
||||||
http.Error(w, "variant stock scan error", http.StatusInternalServerError)
|
http.Error(w, "variant stock scan error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -950,18 +1046,62 @@ LIMIT 1
|
|||||||
if itemID <= 0 {
|
if itemID <= 0 {
|
||||||
continue
|
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,
|
// 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.
|
// because the same visible token (for example "001") can exist in both dimensions.
|
||||||
d1 := int64(0)
|
d1 := int64(0)
|
||||||
if id, ok := resolveDimID("dimval1", colorCode); ok {
|
if id, ok := resolveProductDimID("dimval1", colorCode, inferredDim1); ok {
|
||||||
d1 = id
|
d1 = id
|
||||||
}
|
}
|
||||||
if d1 <= 0 {
|
if d1 <= 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
d3k := int64(0)
|
d3k := int64(0)
|
||||||
if id, ok := resolveDimID("dimval3", dim3Code); ok {
|
if id, ok := resolveProductDimID("dimval3", dim3Code, inferredDim3); ok {
|
||||||
d3k = id
|
d3k = id
|
||||||
}
|
}
|
||||||
key := fmt.Sprintf("%d|%d|%d", itemID, d1, d3k)
|
key := fmt.Sprintf("%d|%d|%d", itemID, d1, d3k)
|
||||||
@@ -974,7 +1114,7 @@ LIMIT 1
|
|||||||
v2 = sizeID
|
v2 = sizeID
|
||||||
}
|
}
|
||||||
v3 := int64(0)
|
v3 := int64(0)
|
||||||
if id, ok := resolveDimID("dimval3", dim3Code); ok {
|
if id, ok := resolveProductDimID("dimval3", dim3Code, inferredDim3); ok {
|
||||||
v3 = id
|
v3 = id
|
||||||
}
|
}
|
||||||
mmdimID := int64(2)
|
mmdimID := int64(2)
|
||||||
|
|||||||
Reference in New Issue
Block a user