This commit is contained in:
hackerESQ
2025-08-21 20:12:59 -05:00
parent fb3c19d3bf
commit fc5cc1fee2
3 changed files with 50 additions and 7 deletions
+46 -4
View File
@@ -62,6 +62,30 @@ class DailyChange extends Model
{ {
$currency = auth()->user()?->getCurrency() ?? config('investbrain.base_currency'); $currency = auth()->user()?->getCurrency() ?? config('investbrain.base_currency');
$dividendSub = DB::table('holdings')
->join('dividends', 'dividends.symbol', '=', 'holdings.symbol')
->leftJoin('currency_rates as cr', function ($join) use ($currency) {
$join->on('cr.date', '=', 'dividends.date')
->where('cr.currency', '=', $currency);
})
->join('transactions as tx', function ($join) {
$join->on('tx.symbol', '=', 'holdings.symbol')
->on('tx.portfolio_id', '=', 'holdings.portfolio_id')
->whereColumn('tx.date', '<=', 'dividends.date');
})
->select(['holdings.portfolio_id', 'dividends.date'])
->selectRaw("
((CASE WHEN tx.transaction_type = 'BUY'
THEN tx.quantity ELSE 0 END)
- (CASE WHEN tx.transaction_type = 'SELL'
THEN tx.quantity ELSE 0 END))
* SUM(
dividends.dividend_amount_base
* COALESCE(cr.rate, 1)
)
AS total_dividends_earned")
->groupBy(['holdings.portfolio_id', 'dividends.date', 'tx.transaction_type', 'tx.quantity']);
$transactionTotals = DB::table('transactions') $transactionTotals = DB::table('transactions')
->select(['transactions.portfolio_id', 'transactions.date']) ->select(['transactions.portfolio_id', 'transactions.date'])
->selectRaw(" ->selectRaw("
@@ -72,6 +96,16 @@ class DailyChange extends Model
* COALESCE(cr.rate, 1) * COALESCE(cr.rate, 1)
) AS daily_cost_basis ) AS daily_cost_basis
") ")
->selectRaw("
SUM(
(CASE
WHEN transactions.transaction_type = 'SELL'
THEN ( transactions.sale_price_base - transactions.cost_basis_base )
* transactions.quantity
* COALESCE(cr.rate, 1)
END)
) AS daily_realized_gains
")
->leftJoin('currency_rates as cr', function ($join) use ($currency) { ->leftJoin('currency_rates as cr', function ($join) use ($currency) {
$join $join
->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(transactions.date)')) ->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(transactions.date)'))
@@ -83,9 +117,20 @@ class DailyChange extends Model
->mergeBindings($transactionTotals) ->mergeBindings($transactionTotals)
->select(['portfolio_id', 'date']) ->select(['portfolio_id', 'date'])
->selectRaw('SUM(daily_cost_basis) AS cumulative_cost_basis') ->selectRaw('SUM(daily_cost_basis) AS cumulative_cost_basis')
->selectRaw('SUM(daily_realized_gains) AS cumulative_realized_gains')
->groupBy('portfolio_id', 'date'); ->groupBy('portfolio_id', 'date');
return $query return $query
->select(['daily_change.portfolio_id', 'daily_change.date'])
->selectRaw('daily_change.total_market_value * COALESCE(cr.rate, 1) AS total_market_value')
->selectRaw('SUM(COALESCE(ccb.cumulative_cost_basis, 0)) AS total_cost_basis')
->selectRaw('SUM(COALESCE(ccb.cumulative_realized_gains, 0)) AS realized_gain_dollars')
->selectSub(function ($query) use ($dividendSub) {
$query->fromSub($dividendSub, 'd')
->selectRaw('SUM(d.total_dividends_earned)')
->whereColumn('d.date', '<=', 'daily_change.date')
->whereColumn('d.portfolio_id', '=', 'daily_change.portfolio_id');
}, 'total_dividends_earned')
->leftJoin('currency_rates as cr', function ($join) use ($currency) { ->leftJoin('currency_rates as cr', function ($join) use ($currency) {
$join $join
->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(daily_change.date)')) ->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(daily_change.date)'))
@@ -96,9 +141,6 @@ class DailyChange extends Model
->on('ccb.portfolio_id', '=', 'daily_change.portfolio_id') ->on('ccb.portfolio_id', '=', 'daily_change.portfolio_id')
->whereRaw('ccb.date <= daily_change.date'); ->whereRaw('ccb.date <= daily_change.date');
}) })
->select(['daily_change.portfolio_id', 'daily_change.date'])
->selectRaw('daily_change.total_market_value * COALESCE(cr.rate, 1) AS total_market_value')
->selectRaw('SUM(COALESCE(ccb.cumulative_cost_basis, 0)) AS total_cost_basis')
->groupBy(['daily_change.date', 'daily_change.portfolio_id', 'cr.rate']) ->groupBy(['daily_change.date', 'daily_change.portfolio_id', 'cr.rate'])
->orderBy('daily_change.date'); ->orderBy('daily_change.date');
} }
@@ -119,7 +161,7 @@ class DailyChange extends Model
'total_cost_basis' => $total_cost_basis, 'total_cost_basis' => $total_cost_basis,
'total_gain' => $total_market_gain, 'total_gain' => $total_market_gain,
'realized_gain_dollars' => $group->sum('realized_gain_dollars'), 'realized_gain_dollars' => $group->sum('realized_gain_dollars'),
// 'total_dividends_earned' => $group->sum('total_dividends_earned'), 'total_dividends_earned' => $group->sum('total_dividends_earned'),
]; ];
}) })
->values(); ->values();
@@ -7,7 +7,7 @@ use Livewire\Volt\Component;
new class extends Component new class extends Component
{ {
// props // props
public ?Portfolio $portfolio; public ?Portfolio $portfolio = null;
public string $name = 'portfolio'; public string $name = 'portfolio';
@@ -55,7 +55,7 @@ new class extends Component
$dailyChange = cache()->remember( $dailyChange = cache()->remember(
'graph-'.$this->scope.'-'.(isset($this->portfolio) ? $this->portfolio->id : request()->user()->id), 'graph-'.$this->scope.'-'.(isset($this->portfolio) ? $this->portfolio->id : request()->user()->id),
30, 10,
function () use ($dailyChangeQuery) { function () use ($dailyChangeQuery) {
return $dailyChangeQuery->getDailyPerformance(); return $dailyChangeQuery->getDailyPerformance();
} }
@@ -92,7 +92,7 @@ new class extends Component
{ {
$this->scope = $scope; $this->scope = $scope;
cache()->forget('graph-'.isset($this->portfolio) ? $this->portfolio->id : request()->user()->id); cache()->forget('graph-'.$this->scope.'-'.(isset($this->portfolio) ? $this->portfolio->id : request()->user()->id));
$this->chartSeries = $this->generatePerformanceData(); $this->chartSeries = $this->generatePerformanceData();
} }
+1
View File
@@ -143,6 +143,7 @@ class DailyChangeTest extends TestCase
$daily_change = DailyChange::withDailyPerformance() $daily_change = DailyChange::withDailyPerformance()
->portfolio($this->portfolio->id) ->portfolio($this->portfolio->id)
->whereDate('daily_change.date', '=', $sale_transaction->date->copy()->nextWeekday()) ->whereDate('daily_change.date', '=', $sale_transaction->date->copy()->nextWeekday())
->getDailyPerformance()
->first(); ->first();
$realized_gain = ($sale_transaction->sale_price - $sale_transaction->cost_basis) * $sale_transaction->quantity; $realized_gain = ($sale_transaction->sale_price - $sale_transaction->cost_basis) * $sale_transaction->quantity;