From 65710e279122ec304ca0e762471b99ef5485508f Mon Sep 17 00:00:00 2001 From: hackerESQ Date: Fri, 22 Aug 2025 16:37:33 -0500 Subject: [PATCH] dividend earnings not shared between portfolios --- app/Models/Holding.php | 7 ++++--- app/Models/Portfolio.php | 2 +- database/factories/TransactionFactory.php | 7 +++++++ tests/DividendsTest.php | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/app/Models/Holding.php b/app/Models/Holding.php index 6a27e7a..a86c540 100644 --- a/app/Models/Holding.php +++ b/app/Models/Holding.php @@ -341,11 +341,11 @@ class Holding extends Model ->on('cr.date', '=', 'dividends.date') ->where('cr.currency', '=', $currency); }) - ->select(['dividends.symbol']) + ->select(['dividends.symbol', 'tx.portfolio_id']) ->selectRaw( "SUM(((CASE WHEN transaction_type = 'BUY' THEN tx.quantity ELSE 0 END) - (CASE WHEN transaction_type = 'SELL' THEN tx.quantity ELSE 0 END)) * dividends.dividend_amount_base * COALESCE(cr.rate, 1)) AS total_dividends_earned" ) - ->groupBy(['dividends.symbol']); + ->groupBy(['dividends.symbol', 'tx.portfolio_id']); return $query->select([ 'holdings.symbol', @@ -402,7 +402,8 @@ class Holding extends Model ) ->leftJoinSub($dividends_sub, 'dividends_display', function ($join) { - $join->on('holdings.symbol', '=', 'dividends_display.symbol'); // todo: this isnt limiting to port ids + $join->on('holdings.symbol', '=', 'dividends_display.symbol') // todo: this isnt limiting to port ids + ->on('holdings.portfolio_id', '=', 'dividends_display.portfolio_id'); } ); diff --git a/app/Models/Portfolio.php b/app/Models/Portfolio.php index dad2e88..17c8d11 100644 --- a/app/Models/Portfolio.php +++ b/app/Models/Portfolio.php @@ -220,7 +220,7 @@ class Portfolio extends Model } cache()->forget('graph-YTD-'.$this->id); - cache()->forget('graph-YTD-'.request()->user()->id); + cache()->forget('graph-YTD-'.request()->user()?->id); } protected function getMostRecentCloseData($history, $date, $i = 0, $max_attempts = 5) diff --git a/database/factories/TransactionFactory.php b/database/factories/TransactionFactory.php index 38b4f85..9a1ca8f 100644 --- a/database/factories/TransactionFactory.php +++ b/database/factories/TransactionFactory.php @@ -59,6 +59,13 @@ class TransactionFactory extends Factory ]); } + public function sixMonthsAgo(): static + { + return $this->state(fn (array $attributes) => [ + 'date' => now()->subMonths(6)->toDateString(), + ]); + } + public function today(): static { return $this->state(fn (array $attributes) => [ diff --git a/tests/DividendsTest.php b/tests/DividendsTest.php index 3df4c4e..fac4858 100644 --- a/tests/DividendsTest.php +++ b/tests/DividendsTest.php @@ -70,4 +70,23 @@ class DividendsTest extends TestCase $this->assertEquals(3, $dividend_count); } + + public function test_dividend_earnings_are_not_shared_between_portfolios(): void + { + $this->actingAs($user = User::factory()->create()); + + $portfolioOne = Portfolio::factory()->create(); + Transaction::factory()->buy()->yearsAgo()->portfolio($portfolioOne->id)->symbol('ACME')->create(); + + $portfolioTwo = Portfolio::factory()->create(); + Transaction::factory(2)->buy()->sixMonthsAgo()->portfolio($portfolioTwo->id)->symbol('ACME')->create(); + + Dividend::refreshDividendData('ACME'); + + $holdingOne = Holding::query()->portfolio($portfolioOne->id)->symbol('ACME')->first(); + $holdingTwo = Holding::query()->portfolio($portfolioTwo->id)->symbol('ACME')->first(); + + $this->assertEquals(4.95, $holdingOne->dividends_earned); + $this->assertEquals(8, $holdingTwo->dividends_earned); + } }