2024-07-10 11:22:59 -04:00
|
|
|
class Account::Sync < ApplicationRecord
|
|
|
|
belongs_to :account
|
|
|
|
|
|
|
|
enum :status, { pending: "pending", syncing: "syncing", completed: "completed", failed: "failed" }
|
|
|
|
|
|
|
|
class << self
|
|
|
|
def for(account, start_date: nil)
|
|
|
|
create! account: account, start_date: start_date
|
|
|
|
end
|
|
|
|
|
|
|
|
def latest
|
|
|
|
order(created_at: :desc).first
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
|
|
|
start!
|
|
|
|
|
2024-08-16 12:13:48 -04:00
|
|
|
account.resolve_stale_issues
|
|
|
|
|
2024-07-10 11:22:59 -04:00
|
|
|
sync_balances
|
2024-07-16 09:26:49 -04:00
|
|
|
sync_holdings
|
2024-07-10 11:22:59 -04:00
|
|
|
|
|
|
|
complete!
|
|
|
|
rescue StandardError => error
|
2024-08-16 12:13:48 -04:00
|
|
|
account.observe_unknown_issue(error)
|
2024-07-10 11:22:59 -04:00
|
|
|
fail! error
|
2024-08-16 16:08:27 -04:00
|
|
|
|
|
|
|
raise error if Rails.env.development?
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def sync_balances
|
2024-08-16 12:13:48 -04:00
|
|
|
Account::Balance::Syncer.new(account, start_date: start_date).run
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
2024-07-16 09:26:49 -04:00
|
|
|
def sync_holdings
|
2024-08-16 12:13:48 -04:00
|
|
|
Account::Holding::Syncer.new(account, start_date: start_date).run
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def start!
|
|
|
|
update! status: "syncing", last_ran_at: Time.now
|
2024-07-18 14:39:38 -04:00
|
|
|
broadcast_start
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def complete!
|
|
|
|
update! status: "completed"
|
2024-08-16 12:13:48 -04:00
|
|
|
|
|
|
|
if account.has_issues?
|
|
|
|
broadcast_result type: "alert", message: account.highest_priority_issue.title
|
|
|
|
else
|
|
|
|
broadcast_result type: "notice", message: "Sync complete"
|
|
|
|
end
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def fail!(error)
|
|
|
|
update! status: "failed", error: error.message
|
2024-08-16 12:13:48 -04:00
|
|
|
broadcast_result type: "alert", message: I18n.t("account.sync.failed")
|
2024-07-18 14:39:38 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def broadcast_start
|
|
|
|
broadcast_append_to(
|
|
|
|
[ account.family, :notifications ],
|
|
|
|
target: "notification-tray",
|
|
|
|
partial: "shared/notification",
|
|
|
|
locals: { id: id, type: "processing", message: "Syncing account balances" }
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def broadcast_result(type:, message:)
|
|
|
|
broadcast_remove_to account.family, :notifications, target: id # Remove persistent syncing notification
|
|
|
|
broadcast_append_to(
|
|
|
|
[ account.family, :notifications ],
|
|
|
|
target: "notification-tray",
|
|
|
|
partial: "shared/notification",
|
|
|
|
locals: { type: type, message: message }
|
|
|
|
)
|
2024-08-16 12:13:48 -04:00
|
|
|
|
2024-07-25 16:46:04 -04:00
|
|
|
account.family.broadcast_refresh
|
2024-07-10 11:22:59 -04:00
|
|
|
end
|
|
|
|
end
|