. */ declare(strict_types=1); namespace FireflyIII\Models; use Carbon\Carbon; use Eloquent; use FireflyIII\User; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Query\Builder; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class Account * * @property int $id * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $deleted_at * @property int $user_id * @property int $account_type_id * @property string $name * @property string|null $virtual_balance * @property string|null $iban * @property bool $active * @property bool $encrypted * @property int $order * @property-read Collection|AccountMeta[] $accountMeta * @property-read int|null $account_meta_count * @property AccountType $accountType * @property-read Collection|Attachment[] $attachments * @property-read int|null $attachments_count * @property-read string $account_number * @property-read string $edit_name * @property-read Collection|Location[] $locations * @property-read int|null $locations_count * @property-read Collection|Note[] $notes * @property-read int|null $notes_count * @property-read Collection|ObjectGroup[] $objectGroups * @property-read int|null $object_groups_count * @property-read Collection|PiggyBank[] $piggyBanks * @property-read int|null $piggy_banks_count * @property-read Collection|Transaction[] $transactions * @property-read int|null $transactions_count * @property-read User $user * @method static EloquentBuilder|Account accountTypeIn($types) * @method static EloquentBuilder|Account newModelQuery() * @method static EloquentBuilder|Account newQuery() * @method static Builder|Account onlyTrashed() * @method static EloquentBuilder|Account query() * @method static EloquentBuilder|Account whereAccountTypeId($value) * @method static EloquentBuilder|Account whereActive($value) * @method static EloquentBuilder|Account whereCreatedAt($value) * @method static EloquentBuilder|Account whereDeletedAt($value) * @method static EloquentBuilder|Account whereEncrypted($value) * @method static EloquentBuilder|Account whereIban($value) * @method static EloquentBuilder|Account whereId($value) * @method static EloquentBuilder|Account whereName($value) * @method static EloquentBuilder|Account whereOrder($value) * @method static EloquentBuilder|Account whereUpdatedAt($value) * @method static EloquentBuilder|Account whereUserId($value) * @method static EloquentBuilder|Account whereVirtualBalance($value) * @method static Builder|Account withTrashed() * @method static Builder|Account withoutTrashed() * @mixin Eloquent * @property Carbon $lastActivityDate * @property string $startBalance * @property string $endBalance * @property string $difference * @property string $interest * @property string $interestPeriod * @property string $accountTypeString * @property string $location * @property string $liability_direction * @property string $current_debt * @property int|null $user_group_id * @method static EloquentBuilder|Account whereUserGroupId($value) */ class Account extends Model { use SoftDeletes, HasFactory; /** * The attributes that should be casted to native types. * * @var array */ protected $casts = [ 'created_at' => 'datetime', 'updated_at' => 'datetime', 'user_id' => 'integer', 'deleted_at' => 'datetime', 'active' => 'boolean', 'encrypted' => 'boolean', ]; /** @var array Fields that can be filled */ protected $fillable = ['user_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban']; /** @var array Hidden from view */ protected $hidden = ['encrypted']; /** @var bool */ private $joinedAccountTypes; /** * Route binder. Converts the key in the URL to the specified object (or throw 404). * * @param string $value * * @return Account * @throws NotFoundHttpException */ public static function routeBinder(string $value): Account { if (auth()->check()) { $accountId = (int) $value; /** @var User $user */ $user = auth()->user(); /** @var Account $account */ $account = $user->accounts()->find($accountId); if (null !== $account) { return $account; } } throw new NotFoundHttpException; } /** * @return BelongsTo * @codeCoverageIgnore */ public function accountType(): BelongsTo { return $this->belongsTo(AccountType::class); } /** * @codeCoverageIgnore * @return MorphMany */ public function attachments(): MorphMany { return $this->morphMany(Attachment::class, 'attachable'); } /** * Get the account number. * * @return string */ public function getAccountNumberAttribute(): string { /** @var AccountMeta $metaValue */ $metaValue = $this->accountMeta() ->where('name', 'account_number') ->first(); return $metaValue ? $metaValue->data : ''; } /** * @return HasMany * @codeCoverageIgnore */ public function accountMeta(): HasMany { return $this->hasMany(AccountMeta::class); } /** * @return string * @codeCoverageIgnore */ public function getEditNameAttribute(): string { $name = $this->name; if (AccountType::CASH === $this->accountType->type) { return ''; } return $name; } /** * @codeCoverageIgnore * @return MorphMany */ public function locations(): MorphMany { return $this->morphMany(Location::class, 'locatable'); } /** * @codeCoverageIgnore * Get all of the notes. */ public function notes(): MorphMany { return $this->morphMany(Note::class, 'noteable'); } /** * Get all of the tags for the post. */ public function objectGroups() { return $this->morphToMany(ObjectGroup::class, 'object_groupable'); } /** * @return HasMany * @codeCoverageIgnore */ public function piggyBanks(): HasMany { return $this->hasMany(PiggyBank::class); } /** * @codeCoverageIgnore * * @param EloquentBuilder $query * @param array $types */ public function scopeAccountTypeIn(EloquentBuilder $query, array $types): void { if (null === $this->joinedAccountTypes) { $query->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id'); $this->joinedAccountTypes = true; } $query->whereIn('account_types.type', $types); } /** * @codeCoverageIgnore * * @param mixed $value * * @codeCoverageIgnore */ public function setVirtualBalanceAttribute($value): void { $value = (string) $value; if ('' === $value) { $value = null; } $this->attributes['virtual_balance'] = $value; } /** * @return HasMany * @codeCoverageIgnore */ public function transactions(): HasMany { return $this->hasMany(Transaction::class); } /** * @return BelongsTo * @codeCoverageIgnore */ public function user(): BelongsTo { return $this->belongsTo(User::class); } }