app/models/membership.rb
class Membership < ActiveRecord::Base
after_create :add_accounts_after_create
belongs_to :group
belongs_to :member, class_name: "User"
validates :group_id, presence: true
validates :member_id, presence: true, uniqueness: { scope: :group_id }
scope :with_totals, -> {
joins('LEFT JOIN (SELECT user_id, group_id, sum(amount) AS total_allocations
FROM allocations
GROUP BY user_id, group_id) AS alloc
ON memberships.member_id = alloc.user_id AND memberships.group_id = alloc.group_id
LEFT JOIN (SELECT contributions.user_id, group_id, sum(amount) AS total_contributions
FROM contributions, buckets
WHERE contributions.bucket_id = buckets.id
GROUP BY contributions.user_id, buckets.group_id) as contrib
ON memberships.member_id = contrib.user_id AND memberships.group_id = contrib.group_id')
.select('memberships.*, COALESCE(alloc.total_allocations,0) AS total_allocations_db,
COALESCE(contrib.total_contributions,0) AS total_contributions_db')
}
scope :archived, -> { where.not(archived_at: nil) }
scope :active, -> { where(archived_at: nil) }
after_create :update_member_if_this_is_their_first_membership
def total_allocations
has_attribute?(:total_allocations_db) ? total_allocations_db : Allocation.where(user_id: member_id, group_id: group_id).sum(:amount)
end
def total_contributions
has_attribute?(:total_contributions_db) ? total_contributions_db : get_total_contributions
end
def get_total_contributions
group_bucket_ids = group.bucket_ids
Contribution.where(bucket_id: group_bucket_ids, user_id: member_id).sum(:amount)
end
def raw_balance
total_allocations - total_contributions
end
def balance
raw_balance.floor
end
def formatted_balance
Money.new(balance * 100, currency_code).format
end
def archived?
archived_at
end
def active?
!archived?
end
def archive!
update(archived_at: DateTime.now.utc)
end
def reactivate!
update(archived_at: nil)
end
def balance_on_status_account
AccountService.balance(status_account_id)
end
def balance_on_incoming_account
AccountService.balance(incoming_account_id)
end
def transactions_data_ok?
(balance_on_status_account == raw_balance)
end
private
def currency_code
group.currency_code
end
def update_member_if_this_is_their_first_membership
unless member.has_ever_joined_a_group?
member.update(joined_first_group_at: Time.now.utc)
end
end
def add_accounts_after_create
status_account = Account.new({group_id: group_id})
in_account = Account.new({group_id: group_id})
out_account = Account.new({group_id: group_id})
if status_account.save && in_account.save && out_account.save
self.status_account_id = status_account.id
self.incoming_account_id = in_account.id
self.outgoing_account_id = out_account.id
save!
end
end
end