Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion app/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,25 @@
use function Safe\ini_get;

/**
* Class Controller.
* Class Controller
*
* Base controller class for all Firefly III web controllers. This abstract class
* provides common functionality shared across all controllers including view
* sharing, middleware configuration, and user session management.
*
* The controller sets up various view variables that are available across all
* pages including demo site configuration, version information, feature flags,
* authentication settings, and user preferences like dark mode and locale.
*
* Key responsibilities:
* - Sharing global view variables (version, demo mode, feature flags)
* - Setting up authentication guard configuration
* - Managing user locale and date format preferences
* - Handling webhook message sending via lottery system
* - Managing primary currency for the authenticated user
*
* All web controllers in Firefly III extend this base class to inherit
* common functionality and ensure consistent behavior across the application.
*
* @SuppressWarnings("PHPMD.CouplingBetweenObjects")
* @SuppressWarnings("PHPMD.NumberOfChildren")
Expand Down
18 changes: 17 additions & 1 deletion app/Http/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,23 @@
use Illuminate\Support\Facades\Log;

/**
* Class HomeController.
* Class HomeController
*
* Handles the main dashboard and home page functionality for Firefly III.
* This controller is responsible for rendering the primary user interface
* that users see after logging in, including account summaries, recent
* transactions, and financial overview widgets.
*
* The controller supports two layout versions (v1 and v2) and automatically
* redirects new users to the setup wizard if they haven't created any accounts yet.
*
* Key responsibilities:
* - Rendering the main dashboard with account summaries
* - Handling date range selection for filtering displayed data
* - Triggering version check notifications for administrators
* - Supporting both legacy (v1) and modern (v2) UI layouts
*
* @see \FireflyIII\Http\Controllers\Controller Base controller class
*/
class HomeController extends Controller
{
Expand Down
202 changes: 196 additions & 6 deletions app/Models/Account.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,37 @@
use Illuminate\Database\Eloquent\SoftDeletes;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
* Class Account
*
* Represents a financial account in Firefly III. Accounts are the core entity for tracking
* money flow and can be of various types including asset accounts (checking, savings),
* expense accounts (stores, vendors), revenue accounts (employers, clients), and
* liability accounts (loans, mortgages, debts).
*
* Each account belongs to a user and has an account type that determines its behavior
* in the double-entry bookkeeping system. Accounts can have associated metadata,
* attachments, notes, locations, and can be grouped for organizational purposes.
*
* Key features:
* - Supports virtual balance for credit card accounts
* - Can store IBAN for European bank accounts
* - Supports soft deletion for data preservation
* - Can be linked to piggy banks for savings goals
*
* @property int $id Primary key identifier
* @property int $user_id Foreign key to the owning user
* @property int $user_group_id Foreign key to the user group
* @property int $account_type_id Foreign key to the account type
* @property string $name Display name of the account
* @property bool $active Whether the account is currently active
* @property string|null $virtual_balance Virtual balance for credit accounts
* @property string|null $iban International Bank Account Number
* @property string|null $native_virtual_balance Virtual balance in native currency
* @property \Carbon\Carbon $created_at Timestamp of creation
* @property \Carbon\Carbon $updated_at Timestamp of last update
* @property \Carbon\Carbon|null $deleted_at Soft delete timestamp
*/
class Account extends Model
{
use HasFactory;
Expand All @@ -53,9 +84,15 @@ class Account extends Model
private bool $joinedAccountTypes = false;

/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
* Route binder for Laravel route model binding.
*
* Converts the account ID from the URL to an Account model instance.
* Ensures the authenticated user owns the requested account for security.
* Used by Laravel's implicit route model binding feature.
*
* @throws NotFoundHttpException
* @param string $value The account ID from the URL
* @return self The Account model instance
* @throws NotFoundHttpException When account is not found or user is not authenticated
*/
public static function routeBinder(string $value): self
{
Expand All @@ -75,21 +112,50 @@ public static function routeBinder(string $value): self
throw new NotFoundHttpException();
}

/**
* Get the user that owns this account.
*
* @return BelongsTo Relationship to the User model
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}

/**
* Get all balance records for this account.
*
* Account balances track the historical balance of the account
* at different points in time for reporting and reconciliation.
*
* @return HasMany Relationship to AccountBalance models
*/
public function accountBalances(): HasMany
{
return $this->hasMany(AccountBalance::class);
}

/**
* Get the type of this account.
*
* Account types define the behavior and categorization of accounts
* (e.g., asset, expense, revenue, liability).
*
* @return BelongsTo Relationship to the AccountType model
*/
public function accountType(): BelongsTo
{
return $this->belongsTo(AccountType::class);
}

/**
* Get all attachments associated with this account.
*
* Attachments can include documents, receipts, or other files
* related to the account.
*
* @return MorphMany Polymorphic relationship to Attachment models
*/
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
Expand All @@ -111,11 +177,29 @@ protected function accountNumber(): Attribute
});
}

/**
* Get all metadata associated with this account.
*
* Account metadata stores additional key-value pairs such as
* account numbers, BIC codes, interest rates, and other
* account-specific information.
*
* @return HasMany Relationship to AccountMeta models
*/
public function accountMeta(): HasMany
{
return $this->hasMany(AccountMeta::class);
}

/**
* Get the editable name of the account.
*
* Returns an empty string for cash accounts since they
* don't have editable names. For all other account types,
* returns the account name.
*
* @return Attribute Accessor for the edit name
*/
protected function editName(): Attribute
{
return Attribute::make(get: function () {
Expand All @@ -128,32 +212,69 @@ protected function editName(): Attribute
});
}

/**
* Get all geographic locations associated with this account.
*
* Locations can be used to track where transactions occur
* or where the account is physically located.
*
* @return MorphMany Polymorphic relationship to Location models
*/
public function locations(): MorphMany
{
return $this->morphMany(Location::class, 'locatable');
}

/**
* Get all the notes.
* Get all notes associated with this account.
*
* Notes allow users to add free-form text descriptions
* or reminders about the account.
*
* @return MorphMany Polymorphic relationship to Note models
*/
public function notes(): MorphMany
{
return $this->morphMany(Note::class, 'noteable');
}

/**
* Get all the tags for the post.
* Get all object groups this account belongs to.
*
* Object groups allow users to organize accounts into
* custom categories for better organization and filtering.
*
* @return MorphToMany Polymorphic many-to-many relationship to ObjectGroup models
*/
public function objectGroups(): MorphToMany
{
return $this->morphToMany(ObjectGroup::class, 'object_groupable');
}

/**
* Get all piggy banks linked to this account.
*
* Piggy banks are savings goals that can be funded from
* asset accounts. Multiple piggy banks can be linked to
* a single account.
*
* @return BelongsToMany Many-to-many relationship to PiggyBank models
*/
public function piggyBanks(): BelongsToMany
{
return $this->belongsToMany(PiggyBank::class);
}

/**
* Query scope to filter accounts by their type.
*
* Joins the account_types table if not already joined and filters
* accounts to only include those matching the specified types.
*
* @param EloquentBuilder $query The query builder instance
* @param array $types Array of account type strings to filter by
* @return void
*/
#[Scope]
protected function accountTypeIn(EloquentBuilder $query, array $types): void
{
Expand All @@ -164,6 +285,16 @@ protected function accountTypeIn(EloquentBuilder $query, array $types): void
$query->whereIn('account_types.type', $types);
}

/**
* Set the virtual balance attribute.
*
* Converts the value to string and sets to null if empty.
* Virtual balance is used for credit card accounts to track
* the credit limit or expected balance.
*
* @param mixed $value The virtual balance value to set
* @return void
*/
public function setVirtualBalanceAttribute(mixed $value): void
{
$value = (string) $value;
Expand All @@ -173,16 +304,40 @@ public function setVirtualBalanceAttribute(mixed $value): void
$this->attributes['virtual_balance'] = $value;
}

/**
* Get all transactions associated with this account.
*
* Transactions represent individual money movements in or out
* of this account as part of the double-entry bookkeeping system.
*
* @return HasMany Relationship to Transaction models
*/
public function transactions(): HasMany
{
return $this->hasMany(Transaction::class);
}

/**
* Get the user group this account belongs to.
*
* User groups allow multiple users to share access to accounts
* and financial data for household or team budgeting.
*
* @return BelongsTo Relationship to the UserGroup model
*/
public function userGroup(): BelongsTo
{
return $this->belongsTo(UserGroup::class);
}

/**
* Get the account ID as an integer.
*
* Ensures the account ID is always returned as an integer type
* for consistent type handling throughout the application.
*
* @return Attribute Accessor for the account ID
*/
protected function accountId(): Attribute
{
return Attribute::make(
Expand All @@ -191,7 +346,12 @@ protected function accountId(): Attribute
}

/**
* Get the user ID
* Get the account type ID as an integer.
*
* Ensures the account type ID is always returned as an integer type
* for consistent type handling throughout the application.
*
* @return Attribute Accessor for the account type ID
*/
protected function accountTypeId(): Attribute
{
Expand All @@ -200,13 +360,29 @@ protected function accountTypeId(): Attribute
);
}

/**
* Get the IBAN with spaces removed.
*
* Normalizes the IBAN by removing all spaces for consistent
* storage and comparison. Returns null if no IBAN is set.
*
* @return Attribute Accessor for the IBAN
*/
protected function iban(): Attribute
{
return Attribute::make(
get: static fn ($value) => null === $value ? null : trim(str_replace(' ', '', (string) $value)),
);
}

/**
* Get the display order as an integer.
*
* The order determines how accounts are sorted in lists
* and can be customized by the user.
*
* @return Attribute Accessor for the order
*/
protected function order(): Attribute
{
return Attribute::make(
Expand All @@ -215,7 +391,13 @@ protected function order(): Attribute
}

/**
* Get the virtual balance
* Get the virtual balance as a string.
*
* Virtual balance is used for credit card accounts to represent
* the credit limit or expected balance. Stored as string for
* precise decimal handling.
*
* @return Attribute Accessor for the virtual balance
*/
protected function virtualBalance(): Attribute
{
Expand All @@ -224,6 +406,14 @@ protected function virtualBalance(): Attribute
);
}

/**
* Define the attribute casting for this model.
*
* Specifies how database columns should be cast to PHP types
* when retrieved from the database.
*
* @return array<string, string> Array of attribute names to cast types
*/
protected function casts(): array
{
return [
Expand Down
Loading
Loading