mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-02 20:15:22 +02:00
Add partial account sync support (#653)
* Add partial account sync support * Fix indentation * Use historical balance as base when doing partial sync * Simplify controller crud tests * Fix linter errors
This commit is contained in:
parent
b3f8ab78d9
commit
ad4de99f1a
9 changed files with 260 additions and 111 deletions
|
@ -75,7 +75,7 @@ class TransactionsController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
if @transaction.save
|
||||
@transaction.account.sync_later
|
||||
@transaction.account.sync_later(@transaction.date)
|
||||
format.html { redirect_to transactions_url, notice: t(".success") }
|
||||
else
|
||||
format.html { render :new, status: :unprocessable_entity }
|
||||
|
@ -85,8 +85,9 @@ class TransactionsController < ApplicationController
|
|||
|
||||
def update
|
||||
respond_to do |format|
|
||||
sync_start_date = [ @transaction.date, Date.parse(transaction_params[:date]) ].compact.min
|
||||
if @transaction.update(transaction_params)
|
||||
@transaction.account.sync_later
|
||||
@transaction.account.sync_later(sync_start_date)
|
||||
|
||||
format.html { redirect_to transaction_url(@transaction), notice: t(".success") }
|
||||
format.turbo_stream do
|
||||
|
@ -102,8 +103,10 @@ class TransactionsController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
@account = @transaction.account
|
||||
sync_start_date = @account.transactions.where("date < ?", @transaction.date).order(date: :desc).first&.date
|
||||
@transaction.destroy!
|
||||
@transaction.account.sync_later
|
||||
@account.sync_later(sync_start_date)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to transactions_url, notice: t(".success") }
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
class ValuationsController < ApplicationController
|
||||
before_action :set_valuation, only: %i[ edit update destroy ]
|
||||
def create
|
||||
@account = Current.family.accounts.find(params[:account_id])
|
||||
|
||||
# TODO: placeholder logic until we have a better abstraction for trends
|
||||
@valuation = @account.valuations.new(valuation_params.merge(currency: Current.family.currency))
|
||||
if @valuation.save
|
||||
@valuation.account.sync_later
|
||||
@valuation.account.sync_later(@valuation.date)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to account_path(@account), notice: "Valuation created" }
|
||||
|
@ -24,13 +25,12 @@ class ValuationsController < ApplicationController
|
|||
end
|
||||
|
||||
def edit
|
||||
@valuation = Valuation.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@valuation = Valuation.find(params[:id])
|
||||
sync_start_date = [ @valuation.date, Date.parse(valuation_params[:date]) ].compact.min
|
||||
if @valuation.update(valuation_params)
|
||||
@valuation.account.sync_later
|
||||
@valuation.account.sync_later(sync_start_date)
|
||||
|
||||
redirect_to account_path(@valuation.account), notice: "Valuation updated"
|
||||
else
|
||||
|
@ -42,10 +42,10 @@ class ValuationsController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
@valuation = Valuation.find(params[:id])
|
||||
@account = @valuation.account
|
||||
sync_start_date = @account.valuations.where("date < ?", @valuation.date).order(date: :desc).first&.date
|
||||
@valuation.destroy!
|
||||
@account.sync_later
|
||||
@account.sync_later(sync_start_date)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to account_path(@account), notice: "Valuation deleted" }
|
||||
|
@ -59,6 +59,11 @@ class ValuationsController < ApplicationController
|
|||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_valuation
|
||||
@valuation = Valuation.find(params[:id])
|
||||
end
|
||||
|
||||
def valuation_params
|
||||
params.require(:valuation).permit(:date, :value)
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class AccountSyncJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(account)
|
||||
account.sync
|
||||
def perform(account, start_date = nil)
|
||||
account.sync(start_date)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ class Account::Balance::Calculator
|
|||
|
||||
prior_balance = current_balance
|
||||
|
||||
{ date: date, balance: current_balance, currency: @account.currency, updated_at: Time.current }
|
||||
{ date:, balance: current_balance, currency: @account.currency, updated_at: Time.current }
|
||||
end
|
||||
|
||||
@daily_balances = [
|
||||
|
@ -92,11 +92,15 @@ class Account::Balance::Calculator
|
|||
end
|
||||
|
||||
def implied_start_balance
|
||||
if @calc_start_date > @account.effective_start_date
|
||||
return @account.balance_on(@calc_start_date)
|
||||
end
|
||||
|
||||
oldest_valuation_date = normalized_valuations.first&.dig("date")
|
||||
oldest_transaction_date = normalized_transactions.first&.dig("date")
|
||||
oldest_entry_date = [ oldest_valuation_date, oldest_transaction_date ].compact.min
|
||||
|
||||
if oldest_entry_date == oldest_valuation_date
|
||||
if oldest_entry_date.present? && oldest_entry_date == oldest_valuation_date
|
||||
oldest_valuation = normalized_valuations.find { |v| v["date"] == oldest_valuation_date }
|
||||
oldest_valuation["value"].to_d
|
||||
else
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
module Account::Syncable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def sync_later
|
||||
AccountSyncJob.perform_later self
|
||||
def sync_later(start_date = nil)
|
||||
AccountSyncJob.perform_later(self, start_date)
|
||||
end
|
||||
|
||||
def sync
|
||||
def sync(start_date = nil)
|
||||
update!(status: "syncing")
|
||||
|
||||
sync_exchange_rates
|
||||
|
||||
calculator = Account::Balance::Calculator.new(self)
|
||||
calc_start_date = start_date - 1.day if start_date.present? && self.balance_on(start_date - 1.day).present?
|
||||
|
||||
calculator = Account::Balance::Calculator.new(self, { calc_start_date: })
|
||||
calculator.calculate
|
||||
self.balances.upsert_all(calculator.daily_balances, unique_by: :index_account_balances_on_account_id_date_currency_unique)
|
||||
self.balances.where("date < ?", effective_start_date).delete_all
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue