Initial commit
This commit is contained in:
132
app/Http/Livewire/AccountInfoModal.php
Normal file
132
app/Http/Livewire/AccountInfoModal.php
Normal 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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user