diff --git a/app/Console/Commands/Correction/CorrectsDatabase.php b/app/Console/Commands/Correction/CorrectsDatabase.php index 5850619f61..4288a4af40 100644 --- a/app/Console/Commands/Correction/CorrectsDatabase.php +++ b/app/Console/Commands/Correction/CorrectsDatabase.php @@ -75,7 +75,8 @@ class CorrectsDatabase extends Command 'correction:recalculates-liabilities', 'correction:preferences', // 'correction:transaction-types', // resource heavy, disabled. - 'correction:recalculate-pc-amounts', // not necessary, disabled. + 'correction:recalculate-pc-amounts', + 'correction:remove-links-to-deleted-objects', 'firefly-iii:report-integrity', ]; foreach ($commands as $command) { diff --git a/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php b/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php new file mode 100644 index 0000000000..56f0c737c9 --- /dev/null +++ b/app/Console/Commands/Correction/RemovesLinksToDeletedObjects.php @@ -0,0 +1,97 @@ +. + */ + +namespace FireflyIII\Console\Commands\Correction; + +use FireflyIII\Console\Commands\ShowsFriendlyMessages; +use FireflyIII\Models\Budget; +use FireflyIII\Models\Category; +use FireflyIII\Models\TransactionJournal; +use Illuminate\Console\Command; +use Illuminate\Support\Facades\DB; + +class RemovesLinksToDeletedObjects extends Command +{ + use ShowsFriendlyMessages; + + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'correction:remove-links-to-deleted-objects'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Removes deleted entries from intermediate tables.'; + + /** + * Execute the console command. + */ + public function handle() + { + // accounts + // remove soft-deleted accounts from account_balances + // remove soft-deleted accounts from account_meta + // remove soft-deleted accounts from account_piggy_bank + // remove soft-deleted accounts from attachments. + + // journals + // remove soft-deleted journals from attachments + // audit_log_entries + $deleted = TransactionJournal::withTrashed()->whereNotNull('deleted_at')->get('transaction_journals.id')->pluck('id')->toArray(); + $count = DB::table('tag_transaction_journal')->whereIn('transaction_journal_id', $deleted)->delete(); + if ($count > 0) { + $this->friendlyInfo(sprintf('Removed %d old relationship(s) between tags and transactions.', $count)); + } + unset($deleted); + // budgets + // from auto_budgets + // from budget_limits + $deleted = Budget::withTrashed()->whereNotNull('deleted_at')->get('budgets.id')->pluck('id')->toArray(); + $count = DB::table('budget_transaction')->whereIn('budget_id', $deleted)->delete(); + if ($count > 0) { + $this->friendlyInfo(sprintf('Removed %d old relationship(s) between budgets and transactions.', $count)); + } + $count = DB::table('budget_transaction_journal')->whereIn('budget_id', $deleted)->delete(); + if ($count > 0) { + $this->friendlyInfo(sprintf('Removed %d old relationship(s) between budgets and transactions.', $count)); + } + unset($deleted); + // -> category_transaction + // -> category_transaction_journal + $deleted = Category::withTrashed()->whereNotNull('deleted_at')->get('categories.id')->pluck('id')->toArray(); + $count = DB::table('category_transaction')->whereIn('category_id', $deleted)->delete(); + if ($count > 0) { + $this->friendlyInfo(sprintf('Removed %d old relationship(s) between categories and transactions.', $count)); + } + $count = DB::table('category_transaction_journal')->whereIn('category_id', $deleted)->delete(); + if ($count > 0) { + $this->friendlyInfo(sprintf('Removed %d old relationship(s) categories budgets and transactions.', $count)); + } + $this->friendlyNeutral('Validated links to deleted objects.'); + + + } +} diff --git a/database/migrations/2024_11_30_075826_multi_piggy.php b/database/migrations/2024_11_30_075826_multi_piggy.php index 19442cd051..a89f29440d 100644 --- a/database/migrations/2024_11_30_075826_multi_piggy.php +++ b/database/migrations/2024_11_30_075826_multi_piggy.php @@ -140,7 +140,7 @@ return new class () extends Migration { $table->dropColumn('transaction_currency_id'); // 2. make column non-nullable. - $table->unsignedInteger('account_id')->change(); + $table->unsignedInteger('account_id')->nullable()->change(); // 5. add new index $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');