exec(" CREATE TABLE IF NOT EXISTS client_feasibility_checks ( id INT AUTO_INCREMENT PRIMARY KEY, client_id INT NOT NULL, check_name VARCHAR(255) DEFAULT 'Untitled Check', filters_json TEXT NOT NULL, available_samples INT NOT NULL DEFAULT 0, required_samples INT NOT NULL DEFAULT 0, incidence_rate DECIMAL(5,2) NOT NULL DEFAULT 100, response_rate DECIMAL(5,2) NOT NULL DEFAULT 20, possible_completes INT NOT NULL DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, KEY idx_client (client_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci "); } catch (Exception $e) { error_log("Feasibility table error: " . $e->getMessage()); } // Handle Delete if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'delete_check') { try { $pdo = getClientDBConnection(); $pdo->prepare("DELETE FROM client_feasibility_checks WHERE id = ? AND client_id = ?") ->execute([(int)$_POST['check_id'], $client_id]); $save_success = 'Feasibility check deleted.'; } catch (Exception $e) { $save_error = 'Error deleting check.'; } } // Handle Save if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'save_check') { try { $pdo = getClientDBConnection(); $pdo->prepare(" INSERT INTO client_feasibility_checks (client_id, check_name, filters_json, available_samples, required_samples, incidence_rate, response_rate, possible_completes) VALUES (?, ?, ?, ?, ?, ?, 20, ?) ")->execute([ $client_id, trim($_POST['check_name'] ?? 'Untitled Check'), $_POST['filters_json'] ?? '{}', (int)($_POST['available_samples'] ?? 0), (int)($_POST['required_samples'] ?? 0), (float)($_POST['incidence_rate'] ?? 100), (int)($_POST['possible_completes'] ?? 0) ]); $save_success = 'Feasibility check saved successfully!'; } catch (Exception $e) { error_log("Save feasibility error: " . $e->getMessage()); $save_error = 'Error saving. Please try again.'; } } // Load saved checks $saved_checks = []; try { $pdo = getClientDBConnection(); $stmt = $pdo->prepare("SELECT * FROM client_feasibility_checks WHERE client_id = ? ORDER BY created_at DESC LIMIT 30"); $stmt->execute([$client_id]); $saved_checks = $stmt->fetchAll(); } catch (Exception $e) { $saved_checks = []; } // Load profiler data $profilerSections = [ 'personal_background'=>'Personal Background','household_family'=>'Household & Family', 'shopping_lifestyle'=>'Shopping & Lifestyle','technology_digital'=>'Technology & Digital', 'travel_transportation'=>'Travel & Transportation','health_fitness'=>'Health & Fitness', 'entertainment_media'=>'Entertainment & Media','food_dining'=>'Food & Dining', 'financial_services'=>'Financial Services','communication_payments'=>'Communication & Payments' ]; $profilerQuestions = []; $profilerResponses = []; $hasProfiler = false; try { $panelPdo = getPanelDBConnection(); $stmt = $panelPdo->query("SELECT DISTINCT section, question_id FROM user_profiler ORDER BY section, question_id"); while ($row = $stmt->fetch()) { if (!isset($profilerQuestions[$row['section']])) $profilerQuestions[$row['section']] = []; $profilerQuestions[$row['section']][] = $row['question_id']; $respStmt = $panelPdo->prepare("SELECT DISTINCT response FROM user_profiler WHERE section = ? AND question_id = ? ORDER BY response"); $respStmt->execute([$row['section'], $row['question_id']]); $responses = []; while ($rr = $respStmt->fetch()) { $decoded = json_decode($rr['response'], true); if (is_array($decoded)) { foreach ($decoded as $v) { if (!in_array($v, $responses)) $responses[] = $v; } } else { $v = trim($rr['response'], '"'); if (!in_array($v, $responses)) $responses[] = $v; } } sort($responses); $profilerResponses[$row['section']][$row['question_id']] = $responses; } $hasProfiler = !empty($profilerQuestions); } catch (Exception $e) { $hasProfiler = false; } // Load states and cities from pin_lookup for filters $availableStates = []; $availableCities = []; try { $panelPdo2 = getPanelDBConnection(); $stmt = $panelPdo2->query("SELECT DISTINCT state FROM pin_lookup WHERE state != '' ORDER BY state"); $availableStates = $stmt->fetchAll(PDO::FETCH_COLUMN); $stmt = $panelPdo2->query("SELECT DISTINCT city FROM pin_lookup WHERE city != 'Others' AND city != '' ORDER BY city"); $availableCities = $stmt->fetchAll(PDO::FETCH_COLUMN); } catch (Exception $e) { /* pin_lookup may not exist yet */ } // Load projects for past project filter $projects = []; try { $pdo = getClientDBConnection(); $stmt = $pdo->query("SELECT project_id, project_name, status FROM projects ORDER BY created_at DESC"); $projects = $stmt->fetchAll(); } catch (Exception $e) { $projects = []; } include 'client-portal-header.php'; ?>

📊 Feasibility Check

Check real-time sample availability for your target audience before creating a project.

🎯 Target Audience Filters

Define your target audience using demographics, profiler responses, and past project participation. The sample count updates in real-time as you adjust filters.

👤 Demographics
to
Comma-separated (e.g. 110 for Delhi)
Others (Smaller Towns)
📋 Profiler Responses
⚠ No profiler data available yet. Use demographic filters above.
📂 Past Project Participation
'Complete','partial'=>'Partial','earlyscreenout'=>'Early SO','latescreenout'=>'Late SO','timeout'=>'Timeout','quotafull'=>'Quota Full'] as $v=>$l): ?>

📈 Feasibility Result

Available Samples
Active, verified members matching filters
How many completed interviews do you need?
What % of respondents are expected to qualify?
💡 Nominal Response Rate: 20% (for a one-week fieldwork window). This is applied automatically.

📚 Saved Feasibility Checks

📋

No saved checks yet. Run a feasibility check above and save it.

$ck): $p = (int)$ck['possible_completes']; $r = (int)$ck['required_samples']; if ($p >= $r) { $b='badge-pos'; $v='Feasible'; } elseif ($p >= $r*0.5) { $b='badge-caut'; $v='Marginal'; } else { $b='badge-neg'; $v='Unlikely'; } ?>
#NameAvailableRequiredIRRRPossibleVerdictDateAction
% 20% n