From db01c27113b39a193352c6d099d328ab34721383 Mon Sep 17 00:00:00 2001 From: hackerESQ Date: Tue, 27 Aug 2024 18:12:51 -0500 Subject: [PATCH] WIP --- lang/en.json | 7 ++ lang/es.json | 7 ++ .../components/fifty-two-week-range.blade.php | 9 +- .../gain-loss-arrow-badge.blade.php | 27 ++++++ .../components/partials/nav-bar.blade.php | 6 +- resources/views/holding/show.blade.php | 90 +++++++++++++------ .../views/livewire/holdings-table.blade.php | 14 ++- .../manage-transaction-form.blade.php | 35 +++++++- .../livewire/top-performers-list.blade.php | 8 +- .../livewire/transactions-list.blade.php | 9 +- .../livewire/transactions-table.blade.php | 34 +++---- resources/views/transaction/index.blade.php | 23 ++++- 12 files changed, 202 insertions(+), 67 deletions(-) create mode 100644 resources/views/components/gain-loss-arrow-badge.blade.php diff --git a/lang/en.json b/lang/en.json index 020e82a..82e85cd 100644 --- a/lang/en.json +++ b/lang/en.json @@ -102,11 +102,14 @@ "Toggle Theme": "Toggle Theme", "Dashboard": "Dashboard", + "Gain/Loss": "Gain/Loss", "Market Gain/Loss": "Market Gain/Loss", "Total Cost Basis": "Total Cost Basis", + "Total Sale Price": "Total Sale Price", "Total Market Value": "Total Market Value", "Realized Gain/Loss": "Realized Gain/Loss", "Dividends Earned": "Dividends Earned", + "Split": "Split", "Splits": "Splits", "My portfolios": "My portfolios", "Create your first portfolio!": "Create your first portfolio!", @@ -130,6 +133,9 @@ "52 week": "52 week", "52 week low": "52 week low", "52 week high": "52 week high", + "Forward PE": "Forward PE", + "Trailing PE": "Trailing PE", + "Market Cap": "Market Cap", "Number of Transactions": "Number of Transactions", "Market Data Age": "Market Data Age", "Portfolio updated": "Portfolio updated", @@ -148,6 +154,7 @@ "Delete Transaction": "Delete Transaction", "Are you sure you want to delete this transaction?": "Are you sure you want to delete this transaction?", "Cost Basis": "Cost Basis", + "Sale Price": "Sale Price", "Market Gain": "Market Gain", "Realized Gains": "Realized Gains", "Performance": "Performance", diff --git a/lang/es.json b/lang/es.json index 06c5b8e..fbbd2e4 100644 --- a/lang/es.json +++ b/lang/es.json @@ -102,11 +102,14 @@ "Toggle Theme": "Cambiar Tema", "Dashboard": "Tablero", + "Gain/Loss": "Ganancia/Pérdida", "Market Gain/Loss": "Ganancia/Pérdida del Mercado", "Total Cost Basis": "Costo Total", + "Total Sale Price": "Precio de Venta Total", "Total Market Value": "Valor Total de Mercado", "Realized Gain/Loss": "Ganancia/Pérdida Realizada", "Dividends Earned": "Dividendos Ganados", + "Split": "Division", "Splits": "Divisiones", "My portfolios": "Mis portafolios", "Create your first portfolio!": "¡Crea tu primer portafolio!", @@ -130,6 +133,9 @@ "52 week": "52 semanas", "52 week low": "Mínimo de 52 semanas", "52 week high": "Máximo de 52 semanas", + "Forward PE": "PE a futuro", + "Trailing PE": "PE histórico", + "Market Cap": "Cap de mercado", "Number of Transactions": "Número de Transacciones", "Market Data Age": "Antigüedad de los Datos del Mercado", "Portfolio updated": "Portafolio actualizado", @@ -148,6 +154,7 @@ "Delete Transaction": "Eliminar Transacción", "Are you sure you want to delete this transaction?": "¿Estás seguro de que quieres eliminar esta transacción?", "Cost Basis": "Costo Base", + "Sale Price": "Precio de Venta", "Market Gain": "Ganancia del Mercado", "Realized Gains": "Ganancias Realizadas", "Performance": "Desempeño", diff --git a/resources/views/components/fifty-two-week-range.blade.php b/resources/views/components/fifty-two-week-range.blade.php index 9b884e5..46ddeae 100644 --- a/resources/views/components/fifty-two-week-range.blade.php +++ b/resources/views/components/fifty-two-week-range.blade.php @@ -1,8 +1,15 @@ + + @php + // 52-week low must be a non-zero + if (empty($low)) { + $low = 1; + } + @endphp @for ($x = 0; $x < 10; $x++) @if ((($current - $low) * 100) / ($high - $low) > ($x * 10)) diff --git a/resources/views/components/gain-loss-arrow-badge.blade.php b/resources/views/components/gain-loss-arrow-badge.blade.php new file mode 100644 index 0000000..1fe4753 --- /dev/null +++ b/resources/views/components/gain-loss-arrow-badge.blade.php @@ -0,0 +1,27 @@ + + @php + if (isset($percent)) { + + $isUp = $percent > 0; + + } else { + + $isUp = $costBasis <= $marketValue; + $percent = ($marketValue - $costBasis) / $costBasis; + } + + @endphp + + @if(!empty($percent)) + + + + {!! $isUp ? '▲' :'▼' !!} + {{ Number::percentage( + $percent, + $percent < 1 ? 2 : 0 + ) }} + + + + @endif \ No newline at end of file diff --git a/resources/views/components/partials/nav-bar.blade.php b/resources/views/components/partials/nav-bar.blade.php index 1feb767..0e25fb3 100644 --- a/resources/views/components/partials/nav-bar.blade.php +++ b/resources/views/components/partials/nav-bar.blade.php @@ -12,7 +12,7 @@ -
+
- @lang('Press :key to search', ['key' => '/']) + @lang('Click or press :key to search', ['key' => '/']) diff --git a/resources/views/holding/show.blade.php b/resources/views/holding/show.blade.php index 70d6146..3fd4bcc 100644 --- a/resources/views/holding/show.blade.php +++ b/resources/views/holding/show.blade.php @@ -18,26 +18,14 @@ {{ $market_data->name }} -

- {{ Number::currency($market_data->market_value) }} +

+ {{ Number::currency($market_data->market_value ?? 0) }} - @if ($holding->average_cost_basis) - - @php - $isUp = $holding->average_cost_basis <= $market_data->market_value; - $percent = ($market_data->market_value - $holding->average_cost_basis) / $holding->average_cost_basis - @endphp - - - {!! $isUp ? '▲' :'▼' !!} - {{ Number::percentage( - $percent, - $percent < 1 ? 2 : 1 - ) }} - - @endif - -

+ +

{{ __('Quantity Owned') }}: @@ -46,22 +34,22 @@

{{ __('Average Cost Basis') }}: - {{ Number::currency($holding->average_cost_basis) }} + {{ Number::currency($holding->average_cost_basis ?? 0) }}

{{ __('Total Cost Basis') }}: - {{ Number::currency($holding->total_cost_basis) }} + {{ Number::currency($holding->total_cost_basis ?? 0) }}

{{ __('Realized Gain/Loss') }}: - {{ Number::currency($holding->realized_gain_dollars) }} + {{ Number::currency($holding->realized_gain_dollars ?? 0) }}

{{ __('Dividends Earned') }}: - {{ Number::currency($holding->dividends_earned) }} + {{ Number::currency($holding->dividends_earned ?? 0) }}

@@ -84,25 +72,75 @@ - +

+ {{ __('Forward PE') }}: + {{ $market_data->forward_pe }} +

+ +

+ {{ __('Trailing PE') }}: + {{ $market_data->trailing_pe }} +

+ +

+ {{ __('Market Cap') }}: + ${{ Number::forHumans($market_data->market_cap ?? 0) }} +

- - + + @livewire('transactions-list', [ + 'portfolio' => $holding->portfolio, + 'transactions' => $holding->transactions + ]) + @foreach ($holding->dividends->take(5) as $dividend) + + + + + Purchased {{$dividend->purchased}}
+ Sold {{$dividend->sold}}
+ @php + $owned = ($dividend->purchased - $dividend->sold); + @endphp + + {{ Number::currency($dividend->dividend_amount) }} + x {{ $owned }} + = {{ Number::currency($owned * $dividend->dividend_amount) }} + +
+ + {{ $dividend->date->format('F d, Y') }} + +
+ @endforeach
+ @foreach ($holding->splits->take(5) as $split) + + + + + 1:{{ $split->split_amount }} + + + + {{ $split->date->format('F d, Y') }} + + + @endforeach diff --git a/resources/views/livewire/holdings-table.blade.php b/resources/views/livewire/holdings-table.blade.php index 449ce69..a9461d9 100644 --- a/resources/views/livewire/holdings-table.blade.php +++ b/resources/views/livewire/holdings-table.blade.php @@ -45,11 +45,21 @@ new class extends Component { ->get(); } + public function goToHolding($holding) + { + return $this->redirect(route('holding.show', ['portfolio' => $holding['portfolio_id'], 'symbol' => $holding['symbol']])); + } + }; ?>
- + @scope('cell_average_cost_basis', $row) {{ Number::currency($row->average_cost_basis ?? 0) }} @endscope @@ -63,7 +73,7 @@ new class extends Component { {{ Number::currency($row->market_gain_dollars ?? 0) }} @endscope @scope('cell_market_gain_percent', $row) - {{ Number::percentage($row->market_gain_percent ?? 0) }} + @endscope @scope('cell_market_data_market_value', $row) {{ Number::currency($row->market_data_market_value ?? 0) }} diff --git a/resources/views/livewire/manage-transaction-form.blade.php b/resources/views/livewire/manage-transaction-form.blade.php index 6472f67..97bebcb 100644 --- a/resources/views/livewire/manage-transaction-form.blade.php +++ b/resources/views/livewire/manage-transaction-form.blade.php @@ -15,6 +15,7 @@ new class extends Component { public ?Portfolio $portfolio; public ?Transaction $transaction; + public ?String $portfolio_id; public String $symbol; public String $transaction_type; public String $date; @@ -31,6 +32,7 @@ new class extends Component { return [ 'symbol' => ['required', 'string', new SymbolValidationRule], 'transaction_type' => 'required|string|in:BUY,SELL', + 'portfolio_id' => 'required|exists:portfolios,id', 'date' => 'required|date_format:Y-m-d', 'quantity' => 'required|min:0|numeric', 'cost_basis' => 'exclude_if:transaction_type,SELL|min:0|numeric', @@ -44,6 +46,7 @@ new class extends Component { $this->symbol = $this->transaction->symbol; $this->transaction_type = $this->transaction->transaction_type; + $this->portfolio_id = $this->transaction->portfolio_id; $this->date = $this->transaction->date->format('Y-m-d'); $this->quantity = $this->transaction->quantity; $this->cost_basis = $this->transaction->cost_basis; @@ -51,6 +54,7 @@ new class extends Component { } else { $this->transaction_type = 'BUY'; + $this->portfolio_id = isset($this->portfolio) ? $this->portfolio->id : ''; $this->date = now()->format('Y-m-d'); } } @@ -62,15 +66,25 @@ new class extends Component { // $this->transaction->owner_id = auth()->user()->id; $this->transaction->save(); - $this->success(__('Transaction updated'), redirectTo: route('portfolio.show', ['portfolio' => $this->transaction->portfolio_id])); + $this->success(__('Transaction updated')); + + $this->dispatch('toggle-manage-transaction'); + $this->dispatch('transaction-updated'); } public function save() { + $validated = $this->validate(); - $transaction = $this->portfolio->transactions()->create($this->validate()); + if (!isset($this->portfolio)) { + $this->portfolio = Portfolio::find($this->portfolio_id); + } + + $transaction = $this->portfolio->transactions()->create($validated); $transaction->save(); + $this->dispatch('transaction-saved'); + $this->success(__('Transaction created'), redirectTo: route('portfolio.show', ['portfolio' => $this->portfolio->id])); } @@ -86,6 +100,19 @@ new class extends Component {
+ @if(empty($portfolio)) + + + + @endif + {{ $holding->market_data?->name }} ({{ $holding->symbol }}) - - - - {{ Number::percentage($holding->market_gain_percent) }} - - + + diff --git a/resources/views/livewire/transactions-list.blade.php b/resources/views/livewire/transactions-list.blade.php index ce3464b..60cb27d 100644 --- a/resources/views/livewire/transactions-list.blade.php +++ b/resources/views/livewire/transactions-list.blade.php @@ -12,6 +12,11 @@ new class extends Component { public ?Portfolio $portfolio; public ?Transaction $editingTransaction; + protected $listeners = [ + 'transaction-updated' => '$refresh', + 'transaction-saved' => '$refresh' + ]; + // methods public function showTransactionDialog($transactionId) { @@ -45,7 +50,6 @@ new class extends Component { ? 'badge-success' : 'badge-error' }} badge-sm mr-3" /> - {{ $transaction->date->format('M j, Y') }} {{ $transaction->symbol }} ({{ $transaction->quantity }} @ {{ $transaction->transaction_type == 'BUY' @@ -54,6 +58,9 @@ new class extends Component { + + {{ $transaction->date->format('F j, Y') }} + @endforeach diff --git a/resources/views/livewire/transactions-table.blade.php b/resources/views/livewire/transactions-table.blade.php index 777f48b..08cfc2f 100644 --- a/resources/views/livewire/transactions-table.blade.php +++ b/resources/views/livewire/transactions-table.blade.php @@ -14,6 +14,11 @@ new class extends Component { public User $user; public ?Transaction $editingTransaction; + protected $listeners = [ + 'transaction-updated' => '$refresh', + 'transaction-saved' => '$refresh' + ]; + public array $sortBy = ['column' => 'date', 'direction' => 'desc']; public array $headers; @@ -33,16 +38,10 @@ new class extends Component { ['key' => 'symbol', 'label' => __('Symbol'), 'class' => ''], ['key' => 'market_data_name', 'label' => __('Name')], ['key' => 'transaction_type', 'label' => __('Type')], + ['key' => 'split', 'label' => __('Split')], ['key' => 'quantity', 'label' => __('Quantity')], ['key' => 'cost_basis', 'label' => __('Cost Basis')], - ['key' => 'total_cost_basis', 'label' => __('Total Cost Basis')], - ['key' => 'market_data_market_value', 'label' => __('Market Value')], - ['key' => 'total_market_value', 'label' => __('Total Market Value')], - // ['key' => 'market_gain_dollars', 'label' => __('Market Gain/Loss')], - // ['key' => 'market_gain_percent', 'label' => __('Market Gain/Loss')], - // ['key' => 'realized_gain_dollars', 'label' => __('Realized Gain/Loss')], - // ['key' => 'dividends_earned', 'label' => __('Dividends Earned')], - // ['key' => 'market_data_updated_at', 'label' => __('Market Data Age')], + ['key' => 'gain_dollars', 'label' => __('Gain/Loss')], ]; } @@ -82,6 +81,9 @@ new class extends Component { @scope('cell_date', $row) {{ $row->date->format('M d, Y') }} @endscope + @scope('cell_split', $row) + {{ $row->split ? 'Yes' : '' }} + @endscope @scope('cell_transaction_type', $row) total_cost_basis ?? 0) }} @endscope - @scope('cell_realized_gain_dollars', $row) - {{ Number::currency($row->realized_gain_dollars ?? 0) }} - @endscope - @scope('cell_market_gain_dollars', $row) - {{ Number::currency($row->market_gain_dollars ?? 0) }} - @endscope - @scope('cell_market_gain_percent', $row) - {{ Number::percentage($row->market_gain_percent ?? 0) }} + @scope('cell_gain_dollars', $row) + {{ Number::currency($row->gain_dollars ?? 0) }} @endscope @scope('cell_market_data_market_value', $row) {{ Number::currency($row->market_data_market_value ?? 0) }} @@ -111,12 +107,6 @@ new class extends Component { @scope('cell_total_market_value', $row) {{ Number::currency($row->total_market_value ?? 0) }} @endscope - @scope('cell_dividends_earned', $row) - {{ Number::currency($row->dividends_earned ?? 0) }} - @endscope - @scope('cell_market_data_updated_at', $row) - {{ \Carbon\Carbon::parse($row->market_data_updated_at)->diffForHumans() }} - @endscope -
+
- + + @livewire('manage-transaction-form') + + + + + + + +
+ +
+
@livewire('transactions-table')