From 261c848ffd89e8b3e32b842990cc313813f12245 Mon Sep 17 00:00:00 2001 From: hackerESQ Date: Wed, 19 Mar 2025 16:16:38 -0500 Subject: [PATCH] fix: add unique constraint to split and dividends to prevent duplicate records --- app/Models/Dividend.php | 4 ++-- app/Models/Split.php | 2 +- ...21_02_25_041236_create_dividends_table.php | 2 ++ .../2021_02_25_041246_create_splits_table.php | 2 ++ tests/DividendsTest.php | 23 +++++++------------ 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/app/Models/Dividend.php b/app/Models/Dividend.php index 24ecd2f..9584cd3 100644 --- a/app/Models/Dividend.php +++ b/app/Models/Dividend.php @@ -68,7 +68,7 @@ class Dividend extends Model // nope, refresh forward looking only if ($dividends_meta->total_dividends) { - $start_date = $dividends_meta->last_dividend_update->addHours(24); + $start_date = $dividends_meta->last_dividend_update; } // skip refresh if there's already recent data @@ -90,7 +90,7 @@ class Dividend extends Model } // insert records - (new self)->insert($dividend_data->toArray()); + (new self)->insertOrIgnore($dividend_data->toArray()); // sync to holdings self::syncHoldings($symbol); diff --git a/app/Models/Split.php b/app/Models/Split.php index 4a948f9..954075a 100644 --- a/app/Models/Split.php +++ b/app/Models/Split.php @@ -73,7 +73,7 @@ class Split extends Model if ($split_data->isNotEmpty()) { // insert records - (new self)->insert($split_data->map(function ($split) { + (new self)->insertOrIgnore($split_data->map(function ($split) { return [...$split, ...['id' => Str::uuid()->toString()]]; })->toArray()); diff --git a/database/migrations/2021_02_25_041236_create_dividends_table.php b/database/migrations/2021_02_25_041236_create_dividends_table.php index 48d4eaa..e63dab7 100644 --- a/database/migrations/2021_02_25_041236_create_dividends_table.php +++ b/database/migrations/2021_02_25_041236_create_dividends_table.php @@ -21,6 +21,8 @@ class CreateDividendsTable extends Migration $table->string('symbol', 25); $table->float('dividend_amount', 12, 4); $table->timestamps(); + + $table->unique(['date', 'symbol']); }); } diff --git a/database/migrations/2021_02_25_041246_create_splits_table.php b/database/migrations/2021_02_25_041246_create_splits_table.php index e504a9b..b79a18a 100644 --- a/database/migrations/2021_02_25_041246_create_splits_table.php +++ b/database/migrations/2021_02_25_041246_create_splits_table.php @@ -21,6 +21,8 @@ class CreateSplitsTable extends Migration $table->string('symbol', 25); $table->float('split_amount', 12, 4); $table->timestamps(); + + $table->unique(['date', 'symbol']); }); } diff --git a/tests/DividendsTest.php b/tests/DividendsTest.php index e8bcaf6..3df4c4e 100644 --- a/tests/DividendsTest.php +++ b/tests/DividendsTest.php @@ -58,23 +58,16 @@ class DividendsTest extends TestCase $this->assertEqualsWithDelta(4.95, $dividendsReinvested * $market_data->market_value, 0.01); } - public function test_do_not_duplicate_recent_dividends(): void + public function test_cannot_insert_duplicate_dividends(): void { - $this->actingAs($user = User::factory()->create()); - - $portfolio = Portfolio::factory()->create(); - Transaction::factory()->buy()->yearsAgo()->portfolio($portfolio->id)->symbol('ACME')->create(); - - $holding = Holding::query()->portfolio($portfolio->id)->symbol('ACME')->first(); - - Dividend::create([ - 'symbol' => 'ACME', - 'date' => now()->subDay(2), - 'dividend_amount' => .01, - ]); - + // first insert Dividend::refreshDividendData('ACME'); - $this->assertCount(1, $holding->dividends); + // try to duplicate + Dividend::refreshDividendData('ACME'); + + $dividend_count = Dividend::count(); + + $this->assertEquals(3, $dividend_count); } }