We were using the same logic twice. I've moved the logic to the Ballot model, which to me is a more natural place to calculate whether there's enough money left than the Investment model. After all, the remaining money is in the ballot, and not in the investment.
84 lines
2.0 KiB
Ruby
84 lines
2.0 KiB
Ruby
class Budget
|
|
class Ballot < ApplicationRecord
|
|
belongs_to :user
|
|
belongs_to :budget
|
|
belongs_to :poll_ballot, class_name: "Poll::Ballot"
|
|
|
|
has_many :lines, dependent: :destroy
|
|
has_many :investments, through: :lines
|
|
has_many :groups, -> { distinct }, through: :lines
|
|
has_many :headings, -> { distinct }, through: :groups
|
|
|
|
def add_investment(investment)
|
|
lines.create(investment: investment).persisted?
|
|
end
|
|
|
|
def total_amount_spent
|
|
investments.sum(:price).to_i
|
|
end
|
|
|
|
def amount_spent(heading)
|
|
investments.by_heading(heading.id).sum(:price).to_i
|
|
end
|
|
|
|
def formatted_amount_spent(heading)
|
|
budget.formatted_amount(amount_spent(heading))
|
|
end
|
|
|
|
def amount_available(heading)
|
|
budget.heading_price(heading) - amount_spent(heading)
|
|
end
|
|
|
|
def formatted_amount_available(heading)
|
|
budget.formatted_amount(amount_available(heading))
|
|
end
|
|
|
|
def enough_money?(investment)
|
|
investment.price.to_i <= amount_available(investment.heading)
|
|
end
|
|
|
|
def has_lines_in_group?(group)
|
|
groups.include?(group)
|
|
end
|
|
|
|
def wrong_budget?(heading)
|
|
heading.budget_id != budget_id
|
|
end
|
|
|
|
def different_heading_assigned?(heading)
|
|
other_heading_ids = heading.group.heading_ids - [heading.id]
|
|
lines.where(heading_id: other_heading_ids).exists?
|
|
end
|
|
|
|
def valid_heading?(heading)
|
|
!wrong_budget?(heading) && !different_heading_assigned?(heading)
|
|
end
|
|
|
|
def has_lines_with_no_heading?
|
|
investments.no_heading.count > 0
|
|
end
|
|
|
|
def has_lines_with_heading?
|
|
heading_id.present?
|
|
end
|
|
|
|
def has_lines_in_heading?(heading)
|
|
investments.by_heading(heading.id).any?
|
|
end
|
|
|
|
def has_investment?(investment)
|
|
investment_ids.include?(investment.id)
|
|
end
|
|
|
|
def heading_for_group(group)
|
|
return nil unless has_lines_in_group?(group)
|
|
|
|
investments.find_by(group: group).heading
|
|
end
|
|
|
|
def casted_offline?
|
|
budget.poll&.voted_by?(user)
|
|
end
|
|
end
|
|
end
|