Initial commit

This commit is contained in:
Ronald Huynen
2026-03-23 21:37:59 +01:00
commit 2547717edb
2193 changed files with 972171 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
<?php
namespace App\Http\Livewire;
use App\Helpers\ProfileAuthorizationHelper;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
class AccountInfoModal extends Component
{
public $show = false;
public $accounts = [];
public $totalBalance = 0;
public $totalBalanceFormatted = '';
public $decimalFormat = false;
public $totalBalanceDecimal = '0,00';
protected $listeners = ['openAccountInfoModal' => 'open'];
public function open()
{
$this->loadAccounts();
$this->show = true;
}
public function close()
{
$this->show = false;
}
public function updatedDecimalFormat()
{
$this->reformatBalances();
}
private function formatBalance($minutes)
{
if ($this->decimalFormat) {
$isNegative = $minutes < 0;
$decimal = number_format(abs($minutes) / 60, 2, ',', '.');
$value = ($isNegative ? '-' : '') . $decimal . ' ' . __('h.');
return $value;
}
return tbFormat($minutes);
}
private function reformatBalances()
{
$this->accounts = array_map(function ($account) {
$account['balanceFormatted'] = $this->formatBalance($account['balance']);
return $account;
}, $this->accounts);
$this->totalBalanceFormatted = $this->formatBalance($this->totalBalance);
}
private function loadAccounts()
{
$profileType = session('activeProfileType');
$profileId = session('activeProfileId');
if (!$profileType || !$profileId) {
$this->accounts = [];
$this->totalBalance = 0;
$this->totalBalanceFormatted = $this->formatBalance(0);
return;
}
// Resolve profile class and verify it has accounts
$profile = $profileType::find($profileId);
if (!$profile || !method_exists($profile, 'accounts')) {
$this->accounts = [];
$this->totalBalance = 0;
$this->totalBalanceFormatted = $this->formatBalance(0);
return;
}
// Verify authenticated user owns this profile (IDOR prevention)
ProfileAuthorizationHelper::authorize($profile);
// Load only accounts belonging to the authenticated active profile (IDOR safe)
$profileAccounts = $profile->accounts()->get();
if ($profileAccounts->isEmpty()) {
$this->accounts = [];
$this->totalBalance = 0;
$this->totalBalanceFormatted = $this->formatBalance(0);
return;
}
$accountIds = $profileAccounts->pluck('id')->toArray();
// Fetch all balances in a single query (no cache — fresh DB state)
$balanceRows = DB::table('transactions')
->whereIn('from_account_id', $accountIds)
->orWhereIn('to_account_id', $accountIds)
->select('from_account_id', 'to_account_id', 'amount')
->get();
// Calculate per-account balance from query results
$balanceMap = array_fill_keys($accountIds, 0);
foreach ($balanceRows as $row) {
if (isset($balanceMap[$row->to_account_id])) {
$balanceMap[$row->to_account_id] += $row->amount;
}
if (isset($balanceMap[$row->from_account_id])) {
$balanceMap[$row->from_account_id] -= $row->amount;
}
}
$this->totalBalance = 0;
$this->accounts = $profileAccounts->map(function ($account) use ($balanceMap) {
$balance = $balanceMap[$account->id] ?? 0;
$this->totalBalance += $balance;
return [
'name' => ucfirst(__('messages.' . strtolower($account->name) . '_account')) . ' ' . __('account'),
'balance' => $balance,
'balanceFormatted' => $this->formatBalance($balance),
];
})->toArray();
$this->totalBalanceFormatted = $this->formatBalance($this->totalBalance);
$this->totalBalanceDecimal = number_format(abs($this->totalBalance) / 60, 2, ',', '.');
}
public function render()
{
return view('livewire.account-info-modal');
}
}