mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-09 15:35:22 +02:00
fix(sync): Fixing various sync issues
- Fixing credit card charges being considered income - Fixing family syncs not re-syncing SimpleFIN accounts - Fixing considerations for "credit card" account types
This commit is contained in:
parent
bf4ee058ec
commit
a4bbc22b4c
3 changed files with 35 additions and 26 deletions
|
@ -75,6 +75,11 @@ class Family < ApplicationRecord
|
||||||
account.sync_later(start_date: start_date, parent_sync: sync)
|
account.sync_later(start_date: start_date, parent_sync: sync)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Rails.logger.info("Syncing simple_fin items for family #{id}")
|
||||||
|
simple_fin_items.each do |simple_fin_item|
|
||||||
|
simple_fin_item.sync_later(start_date: start_date, parent_sync: sync)
|
||||||
|
end
|
||||||
|
|
||||||
Rails.logger.info("Applying rules for family #{id}")
|
Rails.logger.info("Applying rules for family #{id}")
|
||||||
rules.each do |rule|
|
rules.each do |rule|
|
||||||
rule.apply_later
|
rule.apply_later
|
||||||
|
|
|
@ -89,7 +89,7 @@ class Provider::SimpleFin
|
||||||
# @param [Boolean] trans_pending If we should include pending transactions. Default is false as I don't think maybe supports pending.
|
# @param [Boolean] trans_pending If we should include pending transactions. Default is false as I don't think maybe supports pending.
|
||||||
def get_available_accounts(accountable_type, trans_start_date = nil, trans_end_date = nil, trans_pending = false)
|
def get_available_accounts(accountable_type, trans_start_date = nil, trans_end_date = nil, trans_pending = false)
|
||||||
check_rate_limit
|
check_rate_limit
|
||||||
endpoint = "/accounts?pending=#{trans_pending}"
|
endpoint = "/accounts"
|
||||||
|
|
||||||
if trans_end_date == nil
|
if trans_end_date == nil
|
||||||
trans_end_date = Time.now.to_i
|
trans_end_date = Time.now.to_i
|
||||||
|
@ -100,6 +100,11 @@ class Provider::SimpleFin
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add any parameters we care about
|
# Add any parameters we care about
|
||||||
|
if trans_pending
|
||||||
|
endpoint += "?pending=1"
|
||||||
|
else
|
||||||
|
endpoint += "?"
|
||||||
|
end
|
||||||
if trans_start_date
|
if trans_start_date
|
||||||
endpoint += "&start-date=#{trans_start_date}"
|
endpoint += "&start-date=#{trans_start_date}"
|
||||||
end
|
end
|
||||||
|
@ -107,20 +112,10 @@ class Provider::SimpleFin
|
||||||
endpoint += "&end-date=#{trans_end_date}"
|
endpoint += "&end-date=#{trans_end_date}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# request_content = send_request_to_sf(endpoint)
|
response = send_request_to_sf(endpoint)
|
||||||
# # TODO: Remove JSON Reading for real requests. Disabled currently due to preventing rate limits.
|
|
||||||
json_file_path = Rails.root.join("sample.simple.fin.json")
|
|
||||||
accounts = []
|
|
||||||
error_messages = []
|
|
||||||
if File.exist?(json_file_path)
|
|
||||||
request_content = File.read(json_file_path)
|
|
||||||
else
|
|
||||||
Rails.logger.warn "SimpleFIN: Sample JSON file not found at #{json_file_path}. Returning empty accounts."
|
|
||||||
end
|
|
||||||
# Parse our content
|
# Parse our content
|
||||||
parsed_json = JSON.parse(request_content)
|
accounts = response["accounts"] || []
|
||||||
accounts = parsed_json["accounts"] || []
|
error_messages = response["errors"] || []
|
||||||
error_messages = parsed_json["errors"] || []
|
|
||||||
|
|
||||||
|
|
||||||
# The only way we can really determine types right now is by some properties. Try and set their types
|
# The only way we can really determine types right now is by some properties. Try and set their types
|
||||||
|
@ -128,7 +123,7 @@ class Provider::SimpleFin
|
||||||
# Accounts can be considered Investment accounts if they have any holdings associated to them
|
# Accounts can be considered Investment accounts if they have any holdings associated to them
|
||||||
if account.key?("holdings") && account["holdings"].is_a?(Array) && !account["holdings"].empty?
|
if account.key?("holdings") && account["holdings"].is_a?(Array) && !account["holdings"].empty?
|
||||||
account["type"] = "Investment"
|
account["type"] = "Investment"
|
||||||
elsif account["balance"].to_d <= 0 && account["name"]&.downcase&.include?("card")
|
elsif account["balance"].to_d <= 0 && (account["name"]&.downcase&.include?("card") || account["name"]&.downcase&.include?("signature"))
|
||||||
account["type"] = "CreditCard"
|
account["type"] = "CreditCard"
|
||||||
elsif account["balance"].to_d.negative? # Could be loan or credit card
|
elsif account["balance"].to_d.negative? # Could be loan or credit card
|
||||||
account["type"] = "Loan" # Default for negative balance if not clearly a card
|
account["type"] = "Loan" # Default for negative balance if not clearly a card
|
||||||
|
|
|
@ -19,21 +19,24 @@ class SimpleFinAccount < ApplicationRecord
|
||||||
|
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# Gets what balance we should use as our account balance
|
##
|
||||||
def get_adjusted_balance(sf_account_data)
|
# In most instances, SimpleFIN returns either negative or positive values based on the account type. So credit would be negative, cash would be positive.
|
||||||
balance_from_sf = sf_account_data["balance"].to_d
|
# This is however an issue for this application as it tries to handle that for you. This function is intended just to invert the type, based on the account type.
|
||||||
account_type = sf_account_data["type"]
|
def get_adjusted_number(sf_num, acc_type)
|
||||||
# Adjust balance: liabilities (CreditCard, Loan) should be negative
|
# Adjust balance: liabilities (CreditCard, Loan) should be negative
|
||||||
if [ "CreditCard", "Loan" ].include?(account_type)
|
if [ "CreditCard", "Loan" ].include?(acc_type)
|
||||||
balance_from_sf * -1
|
sf_num * -1
|
||||||
else
|
else
|
||||||
balance_from_sf
|
sf_num
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_or_create_from_simple_fin_data!(sf_account_data, sfc)
|
def find_or_create_from_simple_fin_data!(sf_account_data, sfc)
|
||||||
sfc.simple_fin_accounts.find_or_create_by!(external_id: sf_account_data["id"]) do |sfa|
|
sfc.simple_fin_accounts.find_or_create_by!(external_id: sf_account_data["id"]) do |sfa|
|
||||||
balance = get_adjusted_balance(sf_account_data)
|
balance_from_sf = sf_account_data["balance"].to_d
|
||||||
|
account_type = sf_account_data["type"]
|
||||||
|
balance = get_adjusted_number(balance_from_sf, account_type)
|
||||||
|
|
||||||
sfa.current_balance = balance
|
sfa.current_balance = balance
|
||||||
sfa.available_balance = sf_account_data["available-balance"]&.to_d
|
sfa.available_balance = sf_account_data["available-balance"]&.to_d
|
||||||
sfa.currency = sf_account_data["currency"]
|
sfa.currency = sf_account_data["currency"]
|
||||||
|
@ -93,8 +96,9 @@ class SimpleFinAccount < ApplicationRecord
|
||||||
##
|
##
|
||||||
# Syncs all account data for the given sf_account_data parameter
|
# Syncs all account data for the given sf_account_data parameter
|
||||||
def sync_account_data!(sf_account_data)
|
def sync_account_data!(sf_account_data)
|
||||||
balance = SimpleFinAccount.get_adjusted_balance(sf_account_data)
|
balance_from_sf = sf_account_data["balance"].to_d
|
||||||
puts "SFA #{sf_account_data} #{self.account.inspect}"
|
account_type = sf_account_data["type"]
|
||||||
|
balance = SimpleFinAccount.get_adjusted_number(balance_from_sf, account_type)
|
||||||
self.update!(
|
self.update!(
|
||||||
current_balance: balance,
|
current_balance: balance,
|
||||||
available_balance: sf_account_data["available-balance"]&.to_d
|
available_balance: sf_account_data["available-balance"]&.to_d
|
||||||
|
@ -166,9 +170,14 @@ class SimpleFinAccount < ApplicationRecord
|
||||||
sf_transactions_data.each do |transaction_data|
|
sf_transactions_data.each do |transaction_data|
|
||||||
entry = self.account.entries.find_or_initialize_by(simple_fin_transaction_id: transaction_data["id"])
|
entry = self.account.entries.find_or_initialize_by(simple_fin_transaction_id: transaction_data["id"])
|
||||||
|
|
||||||
|
amount_from_sf = transaction_data["amount"].to_d
|
||||||
|
account_type = self.account.accountable_type
|
||||||
|
amount = SimpleFinAccount.get_adjusted_number(amount_from_sf, account_type)
|
||||||
|
puts "AMOUNT #{amount} #{amount_from_sf} #{transaction_data}"
|
||||||
|
|
||||||
entry.assign_attributes(
|
entry.assign_attributes(
|
||||||
name: transaction_data["description"],
|
name: transaction_data["description"],
|
||||||
amount: transaction_data["amount"].to_d,
|
amount: amount,
|
||||||
currency: self.account.currency,
|
currency: self.account.currency,
|
||||||
date: Time.at(transaction_data["posted"].to_i).to_date,
|
date: Time.at(transaction_data["posted"].to_i).to_date,
|
||||||
source: "simple_fin"
|
source: "simple_fin"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue