This commit is contained in:
hackerESQ
2025-08-21 20:54:14 -05:00
parent fc5cc1fee2
commit e427d5802c
8 changed files with 28 additions and 33 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ class CaptureDailyChange extends Command
'date' => now(),
'total_market_value' => $total_market_value,
'total_cost_basis' => $total_cost_basis,
'total_gain' => $total_market_value - $total_cost_basis,
'total_market_gain' => $total_market_value - $total_cost_basis,
'total_dividends_earned' => $metrics->get('total_dividends_earned'),
'realized_gains' => $metrics->get('realized_gain_dollars'),
]);
+15 -20
View File
@@ -32,7 +32,7 @@ class DailyChange extends Model
'date' => 'datetime',
'total_market_value' => 'float',
'total_cost_basis' => 'float',
'total_gain' => 'float',
'total_market_gain' => 'float',
'realized_gain_dollars' => 'float',
'total_dividends_earned' => 'float',
];
@@ -124,6 +124,9 @@ class DailyChange extends Model
->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('daily_change.total_market_value * COALESCE(cr.rate, 1)
- SUM(COALESCE(ccb.cumulative_cost_basis, 0))
AS total_market_gain')
->selectRaw('SUM(COALESCE(ccb.cumulative_realized_gains, 0)) AS realized_gain_dollars')
->selectSub(function ($query) use ($dividendSub) {
$query->fromSub($dividendSub, 'd')
@@ -143,28 +146,20 @@ class DailyChange extends Model
})
->groupBy(['daily_change.date', 'daily_change.portfolio_id', 'cr.rate'])
->orderBy('daily_change.date');
}
public function scopeGetDailyPerformance($query)
public function scopeWithMultipleDailyPerformance($query)
{
return $query->get()
->groupBy('date')
->map(function ($group) {
$total_market_value = $group->sum('total_market_value');
$total_cost_basis = $group->sum('total_cost_basis');
$total_market_gain = $total_market_value - $total_cost_basis;
return (object) [
'date' => $group->first()->date->toDateString(),
'total_market_value' => $total_market_value,
'total_cost_basis' => $total_cost_basis,
'total_gain' => $total_market_gain,
'realized_gain_dollars' => $group->sum('realized_gain_dollars'),
'total_dividends_earned' => $group->sum('total_dividends_earned'),
];
})
->values();
return DB::table(DB::raw("({$query->toSql()}) AS daily_query"))
->addBinding($query->getQuery()->getBindings(), 'join')
->select(['date'])
->selectRaw('SUM(total_market_value) AS total_market_value')
->selectRaw('SUM(total_cost_basis) AS total_cost_basis')
->selectRaw('SUM(total_market_gain) AS total_market_gain')
->selectRaw('SUM(realized_gain_dollars) AS realized_gain_dollars')
->selectRaw('SUM(total_dividends_earned) AS total_dividends_earned')
->groupBy('date');
}
public function portfolio()
+3 -3
View File
@@ -39,7 +39,7 @@ class Holding extends Model
'total_cost_basis' => 'float',
'realized_gain_dollars' => 'float',
'dividends_earned' => 'float',
'total_gain_dollars' => 'float',
'total_market_gain_dollars' => 'float',
'market_gain_dollars' => 'float',
'total_market_value' => 'float',
'total_dividends_earned' => 'float',
@@ -228,7 +228,7 @@ class Holding extends Model
return collect([
'total_cost_basis' => $result->sum('total_cost_basis'),
'total_market_value' => $result->sum('total_market_value'),
'total_gain_dollars' => $result->sum('total_gain_dollars'),
'total_market_gain_dollars' => $result->sum('total_market_gain_dollars'),
'realized_gain_dollars' => $result->sum('realized_gain_dollars'),
'total_dividends_earned' => $result->sum('total_dividends_earned'),
]);
@@ -391,7 +391,7 @@ class Holding extends Model
(holdings.quantity * market_data.market_value_base * COALESCE(cr.rate, 1))
- (SUM(transactions_display.total_cost_basis) / SUM(transactions_display.total_purchases))
* holdings.quantity
AS total_gain_dollars
AS total_market_gain_dollars
')
->leftJoinSub($cost_basis_sub, 'transactions_display',
function ($join) {
+1 -1
View File
@@ -9,7 +9,7 @@
<div class="grid sm:grid-cols-5 gap-5">
<x-card class="col-span-5 sm:col-span-1 bg-slate-100 dark:bg-base-200 rounded-lg">
<div class="text-sm text-gray-400 whitespace-nowrap truncate">{{ __('Market Gain/Loss') }}</div>
<div class="font-black text-xl"> {{ Number::currency($metrics->get('total_gain_dollars', 0)) }} </div>
<div class="font-black text-xl"> {{ Number::currency($metrics->get('total_market_gain_dollars', 0)) }} </div>
</x-card>
<x-card class="col-span-5 sm:col-span-1 bg-slate-100 dark:bg-base-200 rounded-lg">
@@ -57,7 +57,7 @@ new class extends Component
'graph-'.$this->scope.'-'.(isset($this->portfolio) ? $this->portfolio->id : request()->user()->id),
10,
function () use ($dailyChangeQuery) {
return $dailyChangeQuery->getDailyPerformance();
return $dailyChangeQuery->withMultipleDailyPerformance()->get();
}
);
@@ -73,7 +73,7 @@ new class extends Component
],
[
'name' => __('Market Gain'),
'data' => $dailyChange->map(fn ($data) => [$data->date, $data->total_gain])->toArray(),
'data' => $dailyChange->map(fn ($data) => [$data->date, $data->total_market_gain])->toArray(),
],
// [
+1 -1
View File
@@ -67,7 +67,7 @@
<x-card class="col-span-5 sm:col-span-1 bg-slate-100 dark:bg-base-200 rounded-lg">
<div class="text-sm text-gray-400 whitespace-nowrap truncate">{{ __('Market Gain/Loss') }}</div>
<div class="font-black text-xl"> {{ Number::currency($metrics->get('total_gain_dollars', 0)) }} </div>
<div class="font-black text-xl"> {{ Number::currency($metrics->get('total_market_gain_dollars', 0)) }} </div>
</x-card>
<x-card class="col-span-5 sm:col-span-1 bg-slate-100 dark:bg-base-200 rounded-lg">
+1 -1
View File
@@ -143,7 +143,7 @@ class DailyChangeTest extends TestCase
$daily_change = DailyChange::withDailyPerformance()
->portfolio($this->portfolio->id)
->whereDate('daily_change.date', '=', $sale_transaction->date->copy()->nextWeekday())
->getDailyPerformance()
// ->withMultipleDailyPerformance()
->first();
$realized_gain = ($sale_transaction->sale_price - $sale_transaction->cost_basis) * $sale_transaction->quantity;
+4 -4
View File
@@ -557,7 +557,7 @@ class MultiCurrencyTest extends TestCase
$dailyChange = DailyChange::withDailyPerformance()
->portfolio($portfolio->id)
->getDailyPerformance();
->get();
$metrics = Holding::query()
->portfolio($portfolio->id)
@@ -567,7 +567,7 @@ class MultiCurrencyTest extends TestCase
$this->assertEqualsWithDelta($metrics->get('total_cost_basis'), $dailyChange->last()->total_cost_basis, 0.01);
$this->assertEqualsWithDelta(Holding::get()->sum('total_cost_basis'), $dailyChange->last()->total_cost_basis, 0.01);
$this->assertEqualsWithDelta($metrics->get('realized_gain_dollars'), $dailyChange->last()->realized_gain_dollars, 0.01);
$this->assertEqualsWithDelta($metrics->get('total_market_value') - $metrics->get('total_cost_basis'), $dailyChange->last()->total_gain, 0.01);
$this->assertEqualsWithDelta($metrics->get('total_market_value') - $metrics->get('total_cost_basis'), $dailyChange->last()->total_market_gain, 0.01);
// add currency rates
$rates = collect([[
@@ -605,7 +605,7 @@ class MultiCurrencyTest extends TestCase
$dailyChange = DailyChange::withDailyPerformance()
->portfolio($portfolio->id)
->getDailyPerformance();
->get();
$metrics = Holding::query()
->portfolio($portfolio->id)
@@ -614,7 +614,7 @@ class MultiCurrencyTest extends TestCase
$this->assertEqualsWithDelta($metrics->get('total_market_value'), $dailyChange->last()->total_market_value, 0.01);
$this->assertEqualsWithDelta($metrics->get('total_cost_basis'), $dailyChange->last()->total_cost_basis, 0.01);
$this->assertEqualsWithDelta($metrics->get('realized_gain_dollars'), $dailyChange->last()->realized_gain_dollars, 0.01);
$this->assertEqualsWithDelta($metrics->get('total_market_value') - $metrics->get('total_cost_basis'), $dailyChange->last()->total_gain, 0.01);
$this->assertEqualsWithDelta($metrics->get('total_market_value') - $metrics->get('total_cost_basis'), $dailyChange->last()->total_market_gain, 0.01);
}
public function test_multi_currency_import_calculates_correct_holding_data(): void