133 lines
4.1 KiB
PHP
133 lines
4.1 KiB
PHP
<?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');
|
|
}
|
|
}
|