bugs on variant id

This commit is contained in:
2026-08-29 16:45:47 +05:30
parent c5109bf216
commit 76554d26e5
8 changed files with 204 additions and 1 deletions

View File

@@ -51,6 +51,7 @@ type ProductRepository interface {
GetTenantCategories(tenantid int) ([]models.TenantCategory, error)
UpdateProductPricing(productid int, retailprice, productcost, taxpercent float64) error
UpdateProductCategory(productid, categoryid, subcategoryid int) error
UpdateProductVariant(productid, variantid int) error
}
type productRepository struct {
@@ -945,7 +946,26 @@ func (r *productRepository) GetProductByVariant(tenantid, variantid, locationid,
case productid > 0:
q = q.Where("p.tenantid = ? AND p.productid = ?", tenantid, productid)
default:
q = q.Where("p.tenantid = ? AND p.variants = ?", tenantid, variantid)
// Neither a group nor a product was named, so there is nothing to
// return — and returning nothing is the point.
//
// This branch used to run `WHERE p.variants = 0`, which is not "no
// match": EVERY ungrouped product carries variants 0, so asking for
// variant 0 handed back the tenant's entire ungrouped catalogue as if
// those products were variants of one another. Measured on tenant 1135:
// six unrelated products — a chocolate bar, a chewing gum and an apple —
// returned as each other's variants.
//
// That is what stops an order being placed. The app sends the tapped
// product's `variants` value, which is 0 for almost every product, and
// receives six things it must choose between. There is no correct choice
// to make, so the screen cannot proceed.
//
// An empty result is the honest answer to a question that named nothing.
// The controller rejects this case outright with a message naming
// `productid`; this is the second line of defence, so no future caller
// can reach the match-everything behaviour by another route.
return data, nil
}
err := q.
@@ -1261,6 +1281,37 @@ func (r *productRepository) UpdateProductCategory(productid, categoryid, subcate
return r.db.Table("products").Where("productid = ?", productid).Updates(updates).Error
}
// UpdateProductVariant puts an existing product into a variant group, or takes
// it out of one.
//
// It exists because nothing else could. `products.variants` is the grouping the
// ordering screen reads — it is what makes three pack sizes one choice rather
// than three unrelated products — and until now it could only ever be set at
// CREATE time, by a caller that already knew the group id:
//
// products/create writes whatever the body carries, variants included
// importcatalogueproduct never sets it, so every imported product is 0
// UpdateProduct writes productlocations.status only, despite the name
//
// Since importing from the catalogue is how products actually arrive, every
// product this console creates is ungrouped and there was no call that could
// change that. Groups could be created (createproductvariant) and never used.
//
// Zero is allowed here, unlike UpdateProductCategory: ungrouping a product is a
// real thing to want, and 0 is what ungrouped means. The guard that matters for
// this column lives in the read path, which refuses to treat 0 as a group.
func (r *productRepository) UpdateProductVariant(productid, variantid int) error {
if productid <= 0 {
return fmt.Errorf("productid is required")
}
if variantid < 0 {
variantid = 0
}
return r.db.Table("products").
Where("productid = ?", productid).
Update("variants", variantid).Error
}
func (r *productRepository) UpdateProductPricing(productid int, retailprice, productcost, taxpercent float64) error {
return r.db.Table("products").
Where("productid = ?", productid).