Files
Prophet731 a3c4154fb2 fix(StockControl): match storageType code instead of pool id
The package field exposed by VirtFusion as `primaryStorageProfile` is a
storage *type code* (mirrors `server_packages.storage_type` in the VF
database), not a profile id. It's meant to filter to any pool whose
`storageType` matches — multiple pools across the fleet can carry the
same code, which is exactly how multi-hypervisor placement works for
mountpoint/datastore storage.

`capForStorage()` was checking `pool.id` against this code. Pool ids are
unique per hypervisor (e.g. for the same logical mountpoint on three
hypervisors, ids 23/28/30) and almost never match the type-code domain
(0=local default, 4=mountpoint, etc.). The mismatch silently returned 0
for every hypervisor, zeroing qty fleet-wide whenever the package's
type code didn't accidentally collide with some pool id.

Symptoms in the wild: every stock-controlled VPS product showed qty=0
in WHMCS even with abundant memory/CPU/IPv4 capacity. Disabling
`stockcontrol` on the product or removing `primaryStorageProfile` from
the package were the only known workarounds; both lose the actual stock
gating this module is meant to provide.

Fix:
- Match `pool.storageType` instead of `pool.id`.
- Walk all pools that match (a hypervisor may have multiple pools of
  the same type) and use the one that fits the most VMs, instead of
  short-circuiting on the first match. A disabled pool no longer kills
  the whole hypervisor's capacity for that type — we just skip it and
  keep looking for an enabled peer.
- Rename the parameter from `$profileId` to `$storageTypeId` so future
  readers don't fall into the same naming trap. Updated the docblock
  with a NOTE explaining the VirtFusion-side naming inconsistency.

Verified on a 3-hypervisor cluster with `storageType=4` (mountpoint)
packages: qty went from 0/0/0/0/0/0/0/0 to 66/32/15/7/3/1/32/15 across
the VPS-1 through VPS-32 + storage products without any other config
change.
2026-04-26 03:38:33 +00:00
..