Files
timeoverflow/app/models/account.rb
2021-04-25 21:25:15 +02:00

72 lines
1.9 KiB
Ruby

# A time account for an accountable object (IE, a user, an organization...)
#
# The Account balance is denormalized in the database, and is recalculated
# every time a transfer is done from or to the account.
#
# The Account may also be flagged, if needed, when the balance overflows
# some set limits
#
class Account < ApplicationRecord
belongs_to :accountable, polymorphic: true, optional: true
belongs_to :organization, inverse_of: :all_accounts, optional: true
has_many :movements
before_create :add_organization
# Denormalizes the account's balance summing the amount in all its movements.
# It will flag the account if its balance falls out of the min or max limits.
def update_balance
new_balance = movements.sum(:amount)
self.balance = new_balance
self.flagged = !within_allowed_limits? if balance_changed?
save
end
# Print the account as its accountable reference
def to_s
accountable.to_s
end
protected
def add_organization
self.organization = case accountable
when Organization
accountable
when Member
accountable.organization
end
end
# Checks whether the balance falls within the max and min allowed balance,
# none of these included
#
# @return [Boolean]
def within_allowed_limits?
less_than_upper_limit? && greater_than_lower_limit?
end
def less_than_upper_limit?
balance < max_allowed_balance
end
def greater_than_lower_limit?
balance > min_allowed_balance
end
# Returns the maximum allowed balance, falling back to infinite it not set
#
# @return [Integer | Float]
def max_allowed_balance
super || Float::INFINITY
end
# Returns the minimum allowed balance, falling back to minus infinite it not
# set
#
# @return [Integer | Float]
def min_allowed_balance
super || -Float::INFINITY
end
end