This commit is contained in:
2026-09-02 15:37:59 +05:30
parent 68871cb043
commit 09efc5403f
6 changed files with 289 additions and 46 deletions

View File

@@ -51,3 +51,37 @@ func InStockOnly(products []models.Products, locationID int) []models.Products {
}
return inStock
}
// InStockOnlyGrouped is InStockOnly for the grouped shape `getallproducts`
// returns: a tenant with its products, rather than a flat list.
//
// ── Why this one does NOT skip when locationID is 0 ──────────────────────────
//
// InStockOnly above returns early without an outlet, because the query behind
// it computes stock scoped to that outlet and answers 0 for everything when
// there is none — filtering that would empty the catalogue rather than filter
// it. FetchFilteredProducts is built differently: its stock subquery reads
// `(? = 0 OR locationid = ?)`, so with no outlet it aggregates the ledger across
// the tenant's outlets and still returns a real number. Measured 2026-09-02 on
// R mart: 24 products unscoped, 20 with a live balance and 4 at zero.
//
// So the number is trustworthy either way, and the rule can be applied either
// way: a shop that holds none of something anywhere is not offering it.
//
// A tenant left with no sellable products keeps its group, with an empty list.
// Dropping the group would tell the app the shop does not exist, which is a
// different and wrong statement — the shop is open, it has nothing on the shelf.
func InStockOnlyGrouped(groups []models.Tenantproducts) []models.Tenantproducts {
out := make([]models.Tenantproducts, 0, len(groups))
for _, group := range groups {
kept := make([]models.Products, 0, len(group.Products))
for _, product := range group.Products {
if product.Productstock > 0 {
kept = append(kept, product)
}
}
group.Products = kept
out = append(out, group)
}
return out
}