*/ public array $blockers, ) {} /** * @param array $target the catalogue entry being moved to */ public static function for(Customer $customer, ?Instance $instance, array $target): self { $blockers = []; $seats = Seat::query() ->where('customer_id', $customer->id) ->whereIn('status', ['active', 'invited']) ->count(); $seatLimit = (int) ($target['seats'] ?? 0); if ($seatLimit > 0 && $seats > $seatLimit) { $blockers[] = [ 'key' => 'seats', 'current' => (string) $seats, 'limit' => (string) $seatLimit, ]; } // Storage is checked against the last real reading. Falling back to the // contractual allowance would refuse a downgrade to anyone who has ever // bought a large plan, however empty their instance is. $quotaGb = (int) ($target['quota_gb'] ?? 0); $metric = $instance !== null ? InstanceMetric::latestDisk($instance) : null; if ($quotaGb > 0 && $metric !== null && $metric->disk_used_bytes > $quotaGb * 1024 ** 3) { $blockers[] = [ 'key' => 'storage', 'current' => Bytes::human($metric->disk_used_bytes), 'limit' => $quotaGb.' GB', ]; } return new self($blockers === [], $blockers); } }