class Transaction < ApplicationRecord include Entryable, Transferable, Ruleable belongs_to :category, optional: true belongs_to :merchant, optional: true has_many :taggings, as: :taggable, dependent: :destroy has_many :tags, through: :taggings accepts_nested_attributes_for :taggings, allow_destroy: true enum :kind, { standard: "standard", # A regular transaction, included in budget analytics funds_movement: "funds_movement", # Movement of funds between accounts, excluded from budget analytics cc_payment: "cc_payment", # A CC payment, excluded from budget analytics (CC payments offset the sum of expense transactions) loan_payment: "loan_payment", # A payment to a Loan account, treated as an expense in budgets one_time: "one_time" # A one-time expense/income, excluded from budget analytics } # Overarching grouping method for all transfer-type transactions def transfer? funds_movement? || cc_payment? || loan_payment? end def set_category!(category) if category.is_a?(String) category = entry.account.family.categories.find_or_create_by!( name: category ) end update!(category: category) end def pending? extra_data = extra.is_a?(Hash) ? extra : {} ActiveModel::Type::Boolean.new.cast(extra_data.dig("simplefin", "pending")) || ActiveModel::Type::Boolean.new.cast(extra_data.dig("plaid", "pending")) rescue false end end