app sbucategories
This commit is contained in:
@@ -21,11 +21,21 @@ type Productcount struct {
|
|||||||
Outofstock int `json:"outofstock"`
|
Outofstock int `json:"outofstock"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProductCategoryUpdate is one row of a bulk re-filing: which product, and
|
// ProductCategoryUpdate is one row of a bulk re-filing: which product, which
|
||||||
// which category it should sit in.
|
// category it sits in, and — the field that actually decides what a shopper
|
||||||
|
// sees — which subcategory.
|
||||||
|
//
|
||||||
|
// Both are here because they do different jobs. GetProducts filters on
|
||||||
|
// categoryid (the customer app asks for 2), while GetProductsBySubcategory
|
||||||
|
// GROUPS on subcategoryid, so the aisle heading in the app comes from the
|
||||||
|
// second and the first only decides whether the product is returned at all.
|
||||||
|
// A caller re-filing products into aisles sends categoryid 2 unchanged and the
|
||||||
|
// subcategory it worked out.
|
||||||
type ProductCategoryUpdate struct {
|
type ProductCategoryUpdate struct {
|
||||||
Productid int `json:"productid"`
|
Productid int `json:"productid"`
|
||||||
Categoryid int `json:"categoryid"`
|
Categoryid int `json:"categoryid"`
|
||||||
|
// Optional: 0 leaves whatever the product already has.
|
||||||
|
Subcategoryid int `json:"subcategoryid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductCategory struct {
|
type ProductCategory struct {
|
||||||
|
|||||||
@@ -1429,7 +1429,7 @@ func (r *productRepository) RecategoriseProducts(tenantID int, updates []models.
|
|||||||
}
|
}
|
||||||
|
|
||||||
placeholders := make([]string, 0, len(updates))
|
placeholders := make([]string, 0, len(updates))
|
||||||
args := make([]any, 0, len(updates)*2)
|
args := make([]any, 0, len(updates)*3)
|
||||||
for _, u := range updates {
|
for _, u := range updates {
|
||||||
if u.Productid == 0 || u.Categoryid == 0 {
|
if u.Productid == 0 || u.Categoryid == 0 {
|
||||||
// categoryid 0 is the value the customer app rejects outright.
|
// categoryid 0 is the value the customer app rejects outright.
|
||||||
@@ -1437,18 +1437,27 @@ func (r *productRepository) RecategoriseProducts(tenantID int, updates []models.
|
|||||||
// product from every shopper.
|
// product from every shopper.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
placeholders = append(placeholders, "(?::bigint, ?::bigint)")
|
placeholders = append(placeholders, "(?::bigint, ?::bigint, ?::bigint)")
|
||||||
args = append(args, u.Productid, u.Categoryid)
|
args = append(args, u.Productid, u.Categoryid, u.Subcategoryid)
|
||||||
}
|
}
|
||||||
if len(placeholders) == 0 {
|
if len(placeholders) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subcategoryid is written only when the caller sent one.
|
||||||
|
//
|
||||||
|
// It is the field the customer app groups by, so a 0 arriving from a caller
|
||||||
|
// that does not know about aisles would silently move a product back into
|
||||||
|
// the app's "Uncategorized" bucket. Zero therefore means "leave it alone",
|
||||||
|
// the same rule UpdateProductCategory already follows.
|
||||||
args = append(args, tenantID)
|
args = append(args, tenantID)
|
||||||
tx := r.db.Exec(`
|
tx := r.db.Exec(`
|
||||||
UPDATE products p
|
UPDATE products p
|
||||||
SET categoryid = v.categoryid
|
SET categoryid = v.categoryid,
|
||||||
FROM (VALUES `+strings.Join(placeholders, ",")+`) AS v(productid, categoryid)
|
subcategoryid = CASE WHEN v.subcategoryid > 0
|
||||||
|
THEN v.subcategoryid
|
||||||
|
ELSE p.subcategoryid END
|
||||||
|
FROM (VALUES `+strings.Join(placeholders, ",")+`) AS v(productid, categoryid, subcategoryid)
|
||||||
WHERE p.productid = v.productid
|
WHERE p.productid = v.productid
|
||||||
AND p.tenantid = ?
|
AND p.tenantid = ?
|
||||||
`, args...)
|
`, args...)
|
||||||
|
|||||||
Reference in New Issue
Block a user