prepare("SELECT s.*, u.full_name as founder_name, u.university as founder_uni, u.graduation_year FROM startups s LEFT JOIN users u ON s.founder_id = u.id WHERE s.id = ?");
$stmt->execute([$startup_id]);
$startup = $stmt->fetch();
if (!$startup) {
header("Location: startups.php");
exit;
}
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$user = $stmt->fetch();
// Fetch active funding round
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE startup_id = ? AND status = 'Active' LIMIT 1");
$stmt->execute([$startup_id]);
$activeRound = $stmt->fetch();
// Fetch round history
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE startup_id = ? ORDER BY created_at DESC");
$stmt->execute([$startup_id]);
$rounds = $stmt->fetchAll();
$error = '';
$success = '';
// Handle Round Controls (Founder Only)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $startup['founder_id'] == $_SESSION['user_id']) {
$action = $_POST['action'];
$round_id = (int)($_POST['round_id'] ?? 0);
if ($action === 'finish_round_early' && $activeRound && $activeRound['id'] == $round_id) {
$stmt = db()->prepare("UPDATE funding_rounds SET status = 'Closed' WHERE id = ?");
$stmt->execute([$round_id]);
$success = "Funding round finished early. No new investments allowed.";
$activeRound = null; // Refresh for UI
} elseif ($action === 'cancel_round' && $activeRound && $activeRound['id'] == $round_id) {
db()->beginTransaction();
try {
// 1. Cancel round
$stmt = db()->prepare("UPDATE funding_rounds SET status = 'Cancelled' WHERE id = ?");
$stmt->execute([$round_id]);
// 2. Refund all investors for this round
$stmt = db()->prepare("SELECT * FROM investments WHERE funding_round_id = ? AND status = 'approved'");
$stmt->execute([$round_id]);
$investmentsToRefund = $stmt->fetchAll();
foreach ($investmentsToRefund as $inv) {
// Mark investment as refunded
$upd = db()->prepare("UPDATE investments SET status = 'Refunded' WHERE id = ?");
$upd->execute([$inv['id']]);
// Notify investor
$notif = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$notif->execute([$inv['investor_id'], "The funding round for " . $startup['name'] . " has been cancelled. Your investment of £" . number_format($inv['amount']) . " has been refunded."]);
}
db()->commit();
$success = "Funding round cancelled and investors refunded.";
$activeRound = null; // Refresh for UI
} catch (Exception $e) {
db()->rollBack();
$error = "Cancellation failed: " . $e->getMessage();
}
} elseif ($action === 'start_new_round') {
$newTarget = (float)($_POST['new_target'] ?? 0);
if ($newTarget < 50) {
$error = "Minimum target for a new round is £50.";
} elseif ($activeRound) {
$error = "An active round already exists.";
} else {
$stmt = db()->prepare("INSERT INTO funding_rounds (startup_id, funding_goal, status) VALUES (?, ?, 'Active')");
$stmt->execute([$startup_id, $newTarget]);
$success = "New funding round launched!";
// Refresh active round
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE startup_id = ? AND status = 'Active' LIMIT 1");
$stmt->execute([$startup_id]);
$activeRound = $stmt->fetch();
}
}
}
// Handle Investment (Investor Only)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'invest') {
if ($user['role'] !== 'investor') {
$error = "Founders cannot make investments.";
} elseif (!$activeRound) {
$error = "There is no active funding round for this startup.";
} else {
$amount = (float)($_POST['amount'] ?? 0);
if ($amount < 50) {
$error = "Minimum investment is £50.";
} else {
db()->beginTransaction();
try {
// Use funding_round_id for the investment
$stmt = db()->prepare("INSERT INTO investments (investor_id, startup_id, funding_round_id, amount, status) VALUES (?, ?, ?, ?, 'approved')");
$stmt->execute([$_SESSION['user_id'], $startup_id, $activeRound['id'], $amount]);
// Update funding_raised in funding_rounds (the dedicated pot)
$stmt = db()->prepare("UPDATE funding_rounds SET funding_raised = funding_raised + ? WHERE id = ?");
$stmt->execute([$amount, $activeRound['id']]);
// Update legacy field for backward compatibility in listing pages if needed
$stmt = db()->prepare("UPDATE startups SET funding_raised = funding_raised + ? WHERE id = ?");
$stmt->execute([$amount, $startup_id]);
$stmt = db()->prepare("INSERT INTO notifications (user_id, content) VALUES (?, ?)");
$stmt->execute([$startup['founder_id'], "New investment of £" . number_format($amount) . " in " . $startup['name'] . "!"]);
db()->commit();
$success = "Investment successful! You've backed the current round.";
// Refresh active round data
$stmt = db()->prepare("SELECT * FROM funding_rounds WHERE id = ?");
$stmt->execute([$activeRound['id']]);
$activeRound = $stmt->fetch();
} catch (Exception $e) {
db()->rollBack();
$error = "Investment failed: " . $e->getMessage();
}
}
}
}
$platformName = defined('PLATFORM_NAME') ? PLATFORM_NAME : 'Gatsby';
?>
= htmlspecialchars($startup['name']) ?> — = htmlspecialchars($platformName) ?>
= substr($startup['name'], 0, 1) ?>
= htmlspecialchars($startup['name']) ?>
Founded by = $startup['founder_name'] ? htmlspecialchars($startup['founder_name']) : 'Account Deleted' ?>
(= htmlspecialchars($startup['founder_uni']) ?>)
About Startup
= htmlspecialchars($startup['description']) ?>
Investment Terms (Dividend-Only Returns)
How it works:
- Investors are entitled to a share of future profits as **dividends**.
- No voting rights or equity control are granted to investors.
- Returns are primarily distributed through profit-sharing mechanisms.
- Each funding round is independent and maintains its own investment pot.
Funding Round History
= date('M d, Y', strtotime($r['created_at'])) ?> Round
Target: £= number_format($r['funding_goal']) ?>
£= number_format($r['funding_raised']) ?> Raised
= $r['status'] ?>
Current Funding Round
£= number_format($activeRound['funding_raised'], 0) ?>
of £= number_format($activeRound['funding_goal'], 0) ?>
= round(($activeRound['funding_raised'] / ($activeRound['funding_goal'] ?: 1)) * 100) ?>% Raised
= htmlspecialchars($success) ?>
= htmlspecialchars($error) ?>
No Active Round
This startup is not currently seeking investment.
Risk Disclosure
Student startups carry high risk. Dividends are not guaranteed and depend on the profitability of the venture. Each round is independent.