mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 12:04:08 +00:00
Implement SimpleFin API client and data models
- Add SimplefinItem model with sync capabilities and encryption - Add SimplefinAccount model for account data mapping - Implement Provider::Simplefin API client with token exchange - Add SimpleFin protocol support with proper error handling - Include sync jobs, importers, and processors for data flow - Add family SimpleFin connectivity mixin
This commit is contained in:
84
app/models/simplefin_account/processor.rb
Normal file
84
app/models/simplefin_account/processor.rb
Normal file
@@ -0,0 +1,84 @@
|
||||
class SimplefinAccount::Processor
|
||||
attr_reader :simplefin_account
|
||||
|
||||
def initialize(simplefin_account)
|
||||
@simplefin_account = simplefin_account
|
||||
end
|
||||
|
||||
def process
|
||||
ensure_account_exists
|
||||
process_transactions
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ensure_account_exists
|
||||
return if simplefin_account.account.present?
|
||||
|
||||
account = Account.create_from_simplefin_account(simplefin_account)
|
||||
simplefin_account.update!(account: account)
|
||||
end
|
||||
|
||||
def process_transactions
|
||||
return unless simplefin_account.raw_transactions_payload.present?
|
||||
|
||||
account = simplefin_account.account
|
||||
transactions_data = simplefin_account.raw_transactions_payload
|
||||
|
||||
transactions_data.each do |transaction_data|
|
||||
process_transaction(account, transaction_data)
|
||||
end
|
||||
end
|
||||
|
||||
def process_transaction(account, transaction_data)
|
||||
# Convert SimpleFin transaction to internal Transaction format
|
||||
amount_cents = parse_amount(transaction_data[:amount], account.currency)
|
||||
posted_date = parse_date(transaction_data[:posted])
|
||||
|
||||
transaction_attributes = {
|
||||
account: account,
|
||||
name: transaction_data[:description] || "Unknown transaction",
|
||||
amount: Money.new(amount_cents, account.currency),
|
||||
date: posted_date,
|
||||
currency: account.currency,
|
||||
raw_data: transaction_data
|
||||
}
|
||||
|
||||
# Use external ID to prevent duplicates
|
||||
external_id = "simplefin_#{transaction_data[:id]}"
|
||||
|
||||
Transaction.find_or_create_by(external_id: external_id) do |transaction|
|
||||
transaction.assign_attributes(transaction_attributes)
|
||||
end
|
||||
rescue => e
|
||||
Rails.logger.error("Failed to process SimpleFin transaction #{transaction_data[:id]}: #{e.message}")
|
||||
# Don't fail the entire sync for one bad transaction
|
||||
end
|
||||
|
||||
def parse_amount(amount_value, currency)
|
||||
case amount_value
|
||||
when String
|
||||
(BigDecimal(amount_value) * 100).to_i
|
||||
when Numeric
|
||||
(amount_value * 100).to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
rescue ArgumentError
|
||||
0
|
||||
end
|
||||
|
||||
def parse_date(date_value)
|
||||
case date_value
|
||||
when String
|
||||
Date.parse(date_value)
|
||||
when Integer
|
||||
# Unix timestamp
|
||||
Time.at(date_value).to_date
|
||||
else
|
||||
Date.current
|
||||
end
|
||||
rescue ArgumentError, TypeError
|
||||
Date.current
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user