false, 'ERROR' => 'missing_businessid', 'MESSAGE' => 'BusinessID is required.']); } if ($userId <= 0) { apiAbort(['OK' => false, 'ERROR' => 'not_authenticated']); } // Build query based on role $whereClause = ($role === 'guest') ? 'g.GuestBusinessID = ?' : 'g.OwnerBusinessID = ?'; $params = [$bizID]; $statusClause = ''; if ($statusFilter >= 0) { $statusClause = ' AND g.StatusID = ?'; $params[] = $statusFilter; } $rows = queryTimed( "SELECT g.ID AS GrantID, g.UUID, g.OwnerBusinessID, g.GuestBusinessID, g.ServicePointID, g.StatusID, g.EconomicsType, g.EconomicsValue, g.EligibilityScope, g.TimePolicyType, g.TimePolicyData, g.CreatedOn, g.AcceptedOn, g.RevokedOn, ob.Name AS OwnerBusinessName, gb.Name AS GuestBusinessName, sp.Name AS ServicePointName, sp.TypeID AS ServicePointTypeID FROM ServicePointGrants g JOIN Businesses ob ON ob.ID = g.OwnerBusinessID JOIN Businesses gb ON gb.ID = g.GuestBusinessID JOIN ServicePoints sp ON sp.ID = g.ServicePointID WHERE $whereClause$statusClause ORDER BY g.CreatedOn DESC LIMIT 200", $params ); $grants = []; foreach ($rows as $row) { $grants[] = [ 'GrantID' => (int) $row['GrantID'], 'UUID' => $row['UUID'], 'OwnerBusinessID' => (int) $row['OwnerBusinessID'], 'GuestBusinessID' => (int) $row['GuestBusinessID'], 'ServicePointID' => (int) $row['ServicePointID'], 'StatusID' => (int) $row['StatusID'], 'EconomicsType' => $row['EconomicsType'], 'EconomicsValue' => (float) $row['EconomicsValue'], 'EligibilityScope' => $row['EligibilityScope'], 'TimePolicyType' => $row['TimePolicyType'], 'TimePolicyData' => $row['TimePolicyData'] ?? '', 'CreatedOn' => $row['CreatedOn'], 'AcceptedOn' => $row['AcceptedOn'] ?? '', 'RevokedOn' => $row['RevokedOn'] ?? '', 'OwnerBusinessName' => $row['OwnerBusinessName'], 'GuestBusinessName' => $row['GuestBusinessName'], 'ServicePointName' => $row['ServicePointName'], 'ServicePointTypeID' => (int) $row['ServicePointTypeID'], ]; } jsonResponse([ 'OK' => true, 'Role' => $role, 'BusinessID' => $bizID, 'Count' => count($grants), 'Grants' => $grants, ]);