Show sourcecode
The following files exists in this folder. Click to view.
public_html/smartkortet/includes/
auth.php
data.php
functions.php
layout.php
data.php
266 lines UTF-8 Windows (CRLF)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
<?php
declare(strict_types=1);
require_once __DIR__ . '/../config/database.php';
function getUserSettings(int $userId): ?array
{
$stmt = db()->prepare('SELECT * FROM user_settings WHERE user_id = :user_id LIMIT 1');
$stmt->execute(['user_id' => $userId]);
$settings = $stmt->fetch();
return $settings ?: null;
}
function saveUserBudget(int $userId, float $startingBalance, string $periodEnd): void
{
$sql = 'INSERT INTO user_settings (user_id, starting_balance, period_start, period_end)
VALUES (:user_id, :starting_balance, CURDATE(), :period_end)
ON DUPLICATE KEY UPDATE starting_balance = VALUES(starting_balance), period_start = CURDATE(), period_end = VALUES(period_end)';
$stmt = db()->prepare($sql);
$stmt->execute([
'user_id' => $userId,
'starting_balance' => $startingBalance,
'period_end' => $periodEnd,
]);
}
function addSpendEntry(int $userId, float $amount, string $spentOn, ?string $placeName): void
{
$stmt = db()->prepare('INSERT INTO spend_entries (user_id, amount, spent_on, place_name) VALUES (:user_id, :amount, :spent_on, :place_name)');
$stmt->execute([
'user_id' => $userId,
'amount' => $amount,
'spent_on' => $spentOn,
'place_name' => $placeName,
]);
}
function getFavoritePlaces(int $userId): array
{
$stmt = db()->prepare('SELECT id, name FROM favorite_places WHERE user_id = :user_id ORDER BY name ASC');
$stmt->execute(['user_id' => $userId]);
return $stmt->fetchAll();
}
function monthDateRange(int $year, int $month): array
{
$start = sprintf('%04d-%02d-01', $year, $month);
$end = date('Y-m-t', strtotime($start));
return [$start, $end];
}
function calculateBudgetMetrics(int $userId): array
{
$settings = getUserSettings($userId);
$periodStart = $settings['period_start'] ?? date('Y-m-d');
$periodEnd = $settings['period_end'] ?? date('Y-m-d');
$startingBalance = isset($settings['starting_balance']) ? (float) $settings['starting_balance'] : 0.0;
$totalSpent = spentInPeriod($userId, $periodStart, $periodEnd);
$remaining = $startingBalance - $totalSpent;
$todaySpent = spentToday($userId);
$hasSpendEntryToday = $todaySpent > 0;
$today = new DateTimeImmutable('today');
$endDate = new DateTimeImmutable($periodEnd);
$dailyMax = 90.0;
$daysLeftStartDate = $hasSpendEntryToday ? $today->modify('+1 day') : $today;
$daysLeft = countSwedishBusinessDays($daysLeftStartDate, $endDate);
$spendPerDayLeft = $daysLeft > 0 ? max(0, $remaining) / $daysLeft : 0;
$todayBudgetLeft = min($dailyMax, $spendPerDayLeft);
$todayBudgetRemaining = max(0, $todayBudgetLeft - $todaySpent);
return [
'settings' => $settings,
'period_start' => $periodStart,
'period_end' => $periodEnd,
'starting_balance' => $startingBalance,
'total_spent' => $totalSpent,
'remaining' => $remaining,
'today_spent' => $todaySpent,
'has_spend_entry_today' => $hasSpendEntryToday,
'days_left' => $daysLeft,
'spend_per_day_left' => $spendPerDayLeft,
'today_budget_remaining' => $todayBudgetRemaining,
];
}
function getMatkortRestaurantNames(): array
{
return [
'Bamses Pizzeria',
'Bastard Burger',
'Bengal Bites',
'Casa Piadina',
'Cafeterian Värmdö gymnasium',
'Falafel House',
'Gullmarsplan Bowling',
'Gradi',
'Happie Hands',
'Hemköp',
'Hermans',
'Hjälmaren',
'ICA Supermarket Globen',
'ICA Nära Årsta',
'Il Coure',
'KEB',
'Max Hammarby Sjöstad',
'Max Medborgarplatsen',
'Riviera Pizzeria',
'Seven Eleven',
'Stenugnsbageriet',
'Subway Globen',
'Subway Skrapan',
'Subway Ringvägen',
'Sushi Bar Nikko',
'Sushi Yama',
'Sushirullen',
'Taco Bar Globen',
'Taco Bar Hammarby',
'Tastory',
'Trafiket',
'Tullfritt',
'Årsta kvarterskrog',
];
}
function saveFavoritePlace(int $userId, string $name): void
{
$stmt = db()->prepare('INSERT IGNORE INTO favorite_places (user_id, name) VALUES (:user_id, :name)');
$stmt->execute([
'user_id' => $userId,
'name' => $name,
]);
}
function removeFavoritePlace(int $userId, int $placeId): void
{
$stmt = db()->prepare('DELETE FROM favorite_places WHERE id = :id AND user_id = :user_id');
$stmt->execute([
'id' => $placeId,
'user_id' => $userId,
]);
}
function spentInPeriod(int $userId, string $startDate, string $endDate): float
{
$stmt = db()->prepare('SELECT COALESCE(SUM(amount), 0) AS total FROM spend_entries WHERE user_id = :user_id AND spent_on BETWEEN :start_date AND :end_date');
$stmt->execute([
'user_id' => $userId,
'start_date' => $startDate,
'end_date' => $endDate,
]);
$row = $stmt->fetch();
return (float) ($row['total'] ?? 0);
}
function spentToday(int $userId): float
{
$stmt = db()->prepare('SELECT COALESCE(SUM(amount), 0) AS total FROM spend_entries WHERE user_id = :user_id AND spent_on = CURDATE()');
$stmt->execute(['user_id' => $userId]);
$row = $stmt->fetch();
return (float) ($row['total'] ?? 0);
}
function getTodaySpendEntries(int $userId): array
{
$stmt = db()->prepare("SELECT id, spent_on, amount, COALESCE(NULLIF(TRIM(place_name), ''), 'Okänd') AS place_name FROM spend_entries WHERE user_id = :user_id AND spent_on = CURDATE() ORDER BY id DESC");
$stmt->execute(['user_id' => $userId]);
return $stmt->fetchAll();
}
function getDailySpendForMonth(int $userId, int $year, int $month): array
{
[$start, $end] = monthDateRange($year, $month);
$stmt = db()->prepare('SELECT spent_on, SUM(amount) AS total FROM spend_entries WHERE user_id = :user_id AND spent_on BETWEEN :start_date AND :end_date GROUP BY spent_on ORDER BY spent_on ASC');
$stmt->execute([
'user_id' => $userId,
'start_date' => $start,
'end_date' => $end,
]);
return $stmt->fetchAll();
}
function getRestaurantDistributionForMonth(int $userId, int $year, int $month): array
{
[$start, $end] = monthDateRange($year, $month);
$stmt = db()->prepare("SELECT COALESCE(NULLIF(TRIM(place_name), ''), 'Okänd') AS label, SUM(amount) AS total FROM spend_entries WHERE user_id = :user_id AND spent_on BETWEEN :start_date AND :end_date GROUP BY label ORDER BY total DESC");
$stmt->execute([
'user_id' => $userId,
'start_date' => $start,
'end_date' => $end,
]);
return $stmt->fetchAll();
}
function getHistoryEntriesForMonth(int $userId, int $year, int $month): array
{
[$start, $end] = monthDateRange($year, $month);
$stmt = db()->prepare("SELECT id, spent_on, amount, COALESCE(NULLIF(TRIM(place_name), ''), '') AS place_name FROM spend_entries WHERE user_id = :user_id AND spent_on BETWEEN :start_date AND :end_date ORDER BY spent_on DESC, id DESC");
$stmt->execute([
'user_id' => $userId,
'start_date' => $start,
'end_date' => $end,
]);
return $stmt->fetchAll();
}
function updateSpendEntry(int $userId, int $entryId, float $amount, string $spentOn, ?string $placeName): void
{
$stmt = db()->prepare('UPDATE spend_entries SET amount = :amount, spent_on = :spent_on, place_name = :place_name WHERE id = :id AND user_id = :user_id');
$stmt->execute([
'amount' => $amount,
'spent_on' => $spentOn,
'place_name' => $placeName,
'id' => $entryId,
'user_id' => $userId,
]);
}
function deleteSpendEntry(int $userId, int $entryId): void
{
$stmt = db()->prepare('DELETE FROM spend_entries WHERE id = :id AND user_id = :user_id');
$stmt->execute([
'id' => $entryId,
'user_id' => $userId,
]);
}
function getUserTheme(int $userId): string
{
$stmt = db()->prepare('SELECT theme_preference FROM user_settings WHERE user_id = :user_id LIMIT 1');
$stmt->execute(['user_id' => $userId]);
$row = $stmt->fetch();
$theme = $row['theme_preference'] ?? 'dark';
return $theme === 'light' ? 'light' : 'dark';
}
function saveUserTheme(int $userId, string $theme): void
{
$theme = $theme === 'dark' ? 'dark' : 'light';
$sql = 'INSERT INTO user_settings (user_id, starting_balance, period_start, period_end, theme_preference)
VALUES (:user_id, 0, CURDATE(), CURDATE(), :theme_preference)
ON DUPLICATE KEY UPDATE theme_preference = VALUES(theme_preference)';
$stmt = db()->prepare($sql);
$stmt->execute([
'user_id' => $userId,
'theme_preference' => $theme,
]);
}