Files
sure/app/models/transaction.rb
soky srm 76dc91377c Merchants improvements (#594)
* FIX logos

* Implement merchant mods

* FIX confirm issue

* FIX linter

* Add recently seen merchants to re-add if needed

* Update merge.html.erb

* FIX do security check

* Add error handling for update failures.
2026-01-09 19:38:04 +01:00

55 lines
1.8 KiB
Ruby

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
after_save :clear_merchant_unlinked_association, if: :merchant_id_previously_changed?
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
private
def clear_merchant_unlinked_association
return unless merchant_id.present? && merchant.is_a?(ProviderMerchant)
family = entry&.account&.family
return unless family
FamilyMerchantAssociation.where(family: family, merchant: merchant).delete_all
end
end