diff --git a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php index 3373d6c708..1c29c51bec 100644 --- a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php +++ b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php @@ -105,7 +105,7 @@ class PiggyBankController extends Controller /** @var PiggyBank $piggy */ foreach ($piggies as $piggy) { $currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency; - $currentAmount = $this->piggyRepository->getRepetition($piggy)->currentamount ?? '0'; + $currentAmount = $this->piggyRepository->getRepetition($piggy)->current_amount ?? '0'; $objectGroup = $piggy->objectGroups()->first(); $response[] = [ 'id' => (string)$piggy->id, diff --git a/app/Console/Commands/Correction/CorrectAmounts.php b/app/Console/Commands/Correction/CorrectAmounts.php index ad30463120..73ff3b3309 100644 --- a/app/Console/Commands/Correction/CorrectAmounts.php +++ b/app/Console/Commands/Correction/CorrectAmounts.php @@ -173,7 +173,7 @@ class CorrectAmounts extends Command /** @var PiggyBankRepetition $item */ foreach ($set as $item) { - $item->currentamount = app('steam')->positive($item->currentamount); + $item->currentamount = app('steam')->positive($item->current_amount); $item->save(); } $this->friendlyInfo(sprintf('Corrected %d piggy bank repetition amount(s).', $count)); @@ -191,7 +191,7 @@ class CorrectAmounts extends Command /** @var PiggyBank $item */ foreach ($set as $item) { - $item->targetamount = app('steam')->positive($item->targetamount); + $item->targetamount = app('steam')->positive($item->target_amount); $item->save(); } $this->friendlyInfo(sprintf('Corrected %d piggy bank amount(s).', $count)); diff --git a/app/Handlers/Observer/PiggyBankObserver.php b/app/Handlers/Observer/PiggyBankObserver.php index 5bd961f0e5..2857f7c2b7 100644 --- a/app/Handlers/Observer/PiggyBankObserver.php +++ b/app/Handlers/Observer/PiggyBankObserver.php @@ -37,11 +37,11 @@ class PiggyBankObserver app('log')->debug('Observe "created" of a piggy bank.'); $repetition = new PiggyBankRepetition(); $repetition->piggyBank()->associate($piggyBank); - $repetition->startdate = $piggyBank->startdate; - $repetition->startdate_tz = $piggyBank->startdate->format('e'); - $repetition->targetdate = $piggyBank->targetdate; - $repetition->targetdate_tz = $piggyBank->targetdate?->format('e'); - $repetition->currentamount = '0'; + $repetition->start_date = $piggyBank->startdate; + $repetition->start_date_tz = $piggyBank->startdate->format('e'); + $repetition->target_date = $piggyBank->targetdate; + $repetition->target_date_tz = $piggyBank->targetdate?->format('e'); + $repetition->current_amount = '0'; $repetition->save(); } diff --git a/app/Http/Controllers/PiggyBank/IndexController.php b/app/Http/Controllers/PiggyBank/IndexController.php index 72396eb20d..9c3578550e 100644 --- a/app/Http/Controllers/PiggyBank/IndexController.php +++ b/app/Http/Controllers/PiggyBank/IndexController.php @@ -27,6 +27,7 @@ namespace FireflyIII\Http\Controllers\PiggyBank; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\Models\Account; use FireflyIII\Models\PiggyBank; use FireflyIII\Repositories\ObjectGroup\OrganisesObjectGroups; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php index abef05764f..0edfa05b9e 100644 --- a/app/Models/PiggyBank.php +++ b/app/Models/PiggyBank.php @@ -27,6 +27,7 @@ use FireflyIII\Support\Models\ReturnsIntegerIdTrait; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphToMany; @@ -46,17 +47,15 @@ class PiggyBank extends Model 'created_at' => 'datetime', 'updated_at' => 'datetime', 'deleted_at' => 'datetime', - 'startdate' => 'date', - 'targetdate' => 'date', + 'start_date' => 'date', + 'target_date' => 'date', 'order' => 'int', 'active' => 'boolean', 'encrypted' => 'boolean', - 'targetamount' => 'string', + 'target_amount' => 'string', ]; - protected $fillable = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'startdate_tz', 'targetdate', 'targetdate_tz', 'active']; - - protected $hidden = ['targetamount_encrypted', 'encrypted']; + protected $fillable = ['name', 'account_id', 'order', 'target_amount', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'active']; /** * Route binder. Converts the key in the URL to the specified object (or throw 404). @@ -110,6 +109,11 @@ class PiggyBank extends Model return $this->hasMany(PiggyBankEvent::class); } + public function accounts(): BelongsToMany + { + return $this->belongsToMany(Account::class); + } + public function piggyBankRepetitions(): HasMany { return $this->hasMany(PiggyBankRepetition::class); @@ -118,9 +122,9 @@ class PiggyBank extends Model /** * @param mixed $value */ - public function setTargetamountAttribute($value): void + public function setTargetAmountAttribute($value): void { - $this->attributes['targetamount'] = (string)$value; + $this->attributes['target_amount'] = (string)$value; } protected function accountId(): Attribute @@ -140,7 +144,7 @@ class PiggyBank extends Model /** * Get the max amount */ - protected function targetamount(): Attribute + protected function targetAmount(): Attribute { return Attribute::make( get: static fn ($value) => (string)$value, diff --git a/app/Models/PiggyBankRepetition.php b/app/Models/PiggyBankRepetition.php index 38008361dd..eaa42bed7d 100644 --- a/app/Models/PiggyBankRepetition.php +++ b/app/Models/PiggyBankRepetition.php @@ -47,7 +47,7 @@ class PiggyBankRepetition extends Model 'virtual_balance' => 'string', ]; - protected $fillable = ['piggy_bank_id', 'startdate', 'startdate_tz', 'targetdate', 'targetdate_tz', 'currentamount']; + protected $fillable = ['piggy_bank_id', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'current_amount']; public function piggyBank(): BelongsTo { diff --git a/database/migrations/2021_08_28_073733_user_groups.php b/database/migrations/2021_08_28_073733_user_groups.php index 21a25beed4..1111ddc671 100644 --- a/database/migrations/2021_08_28_073733_user_groups.php +++ b/database/migrations/2021_08_28_073733_user_groups.php @@ -42,6 +42,7 @@ class UserGroups extends Migration 'categories', 'recurrences', 'object_groups', + 'preferences', 'rule_groups', 'rules', 'tags', diff --git a/database/migrations/2024_11_30_075826_multi_piggy.php b/database/migrations/2024_11_30_075826_multi_piggy.php new file mode 100644 index 0000000000..d1675663f2 --- /dev/null +++ b/database/migrations/2024_11_30_075826_multi_piggy.php @@ -0,0 +1,103 @@ +dropForeign('piggy_banks_account_id_foreign'); + }); + Schema::table('piggy_banks', static function (Blueprint $table) { + // 2. make column nullable. + $table->unsignedInteger('account_id')->nullable()->change(); + }); + Schema::table('piggy_banks', static function (Blueprint $table) { + // 3. add currency + $table->integer('transaction_currency_id', false, true)->after('account_id'); + $table->foreign('transaction_currency_id','unique_currency')->references('id')->on('transaction_currencies')->onDelete('cascade'); + }); + Schema::table('piggy_banks', static function (Blueprint $table) { + // 4. rename columns + $table->renameColumn('targetamount', 'target_amount'); + $table->renameColumn('startdate', 'start_date'); + $table->renameColumn('targetdate', 'target_date'); + $table->renameColumn('startdate_tz', 'start_date_tz'); + $table->renameColumn('targetdate_tz', 'target_date_tz'); + }); + Schema::table('piggy_banks', static function (Blueprint $table) { + // 5. add new index + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('set null'); + }); + + // rename some fields in piggy bank reps. + Schema::table('piggy_bank_repetitions', static function (Blueprint $table) { + // 6. rename columns + $table->renameColumn('currentamount', 'current_amount'); + $table->renameColumn('startdate', 'start_date'); + $table->renameColumn('targetdate', 'target_date'); + $table->renameColumn('startdate_tz', 'start_date_tz'); + $table->renameColumn('targetdate_tz', 'target_date_tz'); + }); + + // create table account_piggy_bank + Schema::create('account_piggy_bank', static function (Blueprint $table) { + $table->id(); + $table->integer('account_id', false, true); + $table->integer('piggy_bank_id',false, true); + $table->decimal('current_amount', 32, 12)->default('0'); + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); + $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade'); + $table->unique(['account_id', 'piggy_bank_id'],'unique_piggy_save'); + }); + + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('piggy_banks', static function (Blueprint $table) { + // 1. drop account index again. + $table->dropForeign('piggy_banks_account_id_foreign'); + + // rename columns again. + $table->renameColumn('target_amount', 'targetamount'); + $table->renameColumn('start_date', 'startdate'); + $table->renameColumn('target_date', 'targetdate'); + $table->renameColumn('start_date_tz', 'startdate_tz'); + $table->renameColumn('target_date_tz', 'targetdate_tz'); + + // 3. drop currency again + index + $table->dropForeign('unique_currency'); + $table->dropColumn('transaction_currency_id'); + + // 2. make column non-nullable. + $table->unsignedInteger('account_id')->change(); + + // 5. add new index + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); + }); + + // rename some fields in piggy bank reps. + Schema::table('piggy_bank_repetitions', static function (Blueprint $table) { + // 6. rename columns + $table->renameColumn('current_amount', 'currentamount'); + $table->renameColumn('start_date', 'startdate'); + $table->renameColumn('target_date', 'targetdate'); + $table->renameColumn('start_date_tz', 'startdate_tz'); + $table->renameColumn('target_date_tz', 'targetdate_tz'); + }); + + Schema::dropIfExists('account_piggy_bank'); + } +};