Files
project-work/worker-toolkit-stocks-in-the-future/repo/app/models/portfolio.rb
Eric Bell 2854619bc9 chore: init commit
in worker.../repo/GITFOLDER.zip is the .git folder.
2026-08-11 14:44:09 -04:00

106 lines
2.3 KiB
Ruby

# frozen_string_literal: true
class Portfolio < ApplicationRecord
include ::UrlHelpers
belongs_to :user
validate :user_must_be_student
delegate :username, :student?, :school_name, :trading_enabled?, to: :user
has_many :portfolio_transactions, dependent: :destroy
has_many :portfolio_stocks, dependent: :destroy
has_many :stocks, through: :portfolio_stocks
has_many :portfolio_snapshots, dependent: :destroy
def cash_balance
cash_on_hand
end
def path
portfolio_path(self)
end
def shares_owned(stock_id)
portfolio_stocks.where(stock_id: stock_id).sum(:shares)
end
def positions
PortfolioPosition.for_portfolio(self)
end
def calculate_total_value_cents
cash_on_hand_in_cents + holdings_value_cents
end
def calculate_total_value
calculate_total_value_cents / 100.0
end
def total_portfolio_worth
calculate_total_value
end
def holdings_value
holdings_value_cents / 100.0
end
def holdings_value_cents
portfolio_stocks.joins(:stock).sum(
"portfolio_stocks.shares * stocks.price_cents"
)
end
def chart_data
snapshots = portfolio_snapshots.order(date: :asc).last(12)
snapshots.map do |snapshot|
{
label: snapshot.date.strftime("%b %Y"),
value: snapshot.current_worth
}
end
end
private
def cash_on_hand
cash_on_hand_in_cents / 100.0
end
def cash_on_hand_in_cents
credits = total_credits + total_deposits
debits = total_debits + total_withdrawals + total_fees + pending_transaction_fee
credits - debits
end
def total_withdrawals
portfolio_transactions.withdrawals.sum(:amount_cents)
end
def total_deposits
portfolio_transactions.deposits.sum(:amount_cents)
end
def total_fees
portfolio_transactions.fees.sum(:amount_cents)
end
def total_credits
portfolio_transactions.credits.sum(:amount_cents)
end
def total_debits
pending_orders_amount = user.orders.pending.buy.sum(&:purchase_cost) || 0
portfolio_transactions.debits.sum(:amount_cents) + pending_orders_amount
end
def pending_transaction_fee
user.orders.pending.exists? ? PortfolioTransaction::TRANSACTION_FEE_CENTS : 0
end
def user_must_be_student
errors.add(:user, "must be a student") unless user&.student?
end
end