diff --git a/app/controllers/concerns/accountable_resource.rb b/app/controllers/concerns/accountable_resource.rb index 9daa0ae2..a7537a5a 100644 --- a/app/controllers/concerns/accountable_resource.rb +++ b/app/controllers/concerns/accountable_resource.rb @@ -2,7 +2,7 @@ module AccountableResource extend ActiveSupport::Concern included do - include ScrollFocusable, Periodable + include ScrollFocusable, Periodable, StreamExtensions before_action :set_account, only: [ :show, :edit, :update, :destroy ] before_action :set_link_options, only: :new @@ -39,7 +39,10 @@ module AccountableResource @account = Current.family.accounts.create_and_sync(account_params.except(:return_to)) @account.lock_saved_attributes! - redirect_to account_params[:return_to].presence || @account, notice: t("accounts.create.success", type: accountable_type.name.underscore.humanize) + respond_to do |format| + format.html { redirect_to account_params[:return_to].presence || @account, notice: accountable_type.name.underscore.humanize + " account created" } + format.turbo_stream { stream_redirect_to account_params[:return_to].presence || account_path(@account), notice: accountable_type.name.underscore.humanize + " account created" } + end end def update @@ -54,7 +57,7 @@ module AccountableResource end # Update remaining account attributes - update_params = account_params.except(:return_to, :balance, :currency) + update_params = account_params.except(:return_to, :balance, :currency, :tracking_start_date) unless @account.update(update_params) @error_message = @account.errors.full_messages.join(", ") render :edit, status: :unprocessable_entity @@ -62,7 +65,11 @@ module AccountableResource end @account.lock_saved_attributes! - redirect_back_or_to @account, notice: t("accounts.update.success", type: accountable_type.name.underscore.humanize) + + respond_to do |format| + format.html { redirect_back_or_to @account, notice: accountable_type.name.underscore.humanize + " account updated" } + format.turbo_stream { stream_redirect_to @account, notice: accountable_type.name.underscore.humanize + " account updated" } + end end def destroy @@ -90,7 +97,7 @@ module AccountableResource def account_params params.require(:account).permit( - :name, :balance, :subtype, :currency, :accountable_type, :return_to, + :name, :balance, :subtype, :currency, :accountable_type, :return_to, :tracking_start_date, accountable_attributes: self.class.permitted_accountable_attributes ) end diff --git a/app/models/account.rb b/app/models/account.rb index 09800168..4421a690 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -57,20 +57,20 @@ class Account < ApplicationRecord class << self def create_and_sync(attributes) + start_date = attributes.delete(:tracking_start_date) || 2.years.ago.to_date attributes[:accountable_attributes] ||= {} # Ensure accountable is created, even if empty account = new(attributes.merge(cash_balance: attributes[:balance])) initial_balance = attributes.dig(:accountable_attributes, :initial_balance)&.to_d || account.balance account.entries.build( name: Valuation::Name.new("opening_anchor", account.accountable_type).to_s, - date: 2.years.ago.to_date, + date: start_date, amount: initial_balance, currency: account.currency, entryable: Valuation.new( kind: "opening_anchor", balance: initial_balance, - cash_balance: initial_balance, - currency: account.currency + cash_balance: initial_balance ) ) diff --git a/app/models/account/balance_updater.rb b/app/models/account/balance_updater.rb index 1b50a9b5..d1e9f01e 100644 --- a/app/models/account/balance_updater.rb +++ b/app/models/account/balance_updater.rb @@ -18,12 +18,16 @@ class Account::BalanceUpdater end valuation_entry = account.entries.valuations.find_or_initialize_by(date: date) do |entry| - entry.entryable = Valuation.new + entry.entryable = Valuation.new( + kind: "recon", + balance: balance, + cash_balance: balance + ) end valuation_entry.amount = balance valuation_entry.currency = currency if currency.present? - valuation_entry.name = valuation_name(valuation_entry.entryable, account) + valuation_entry.name = valuation_name(valuation_entry, account) valuation_entry.notes = notes if notes.present? valuation_entry.save! end diff --git a/app/models/valuation.rb b/app/models/valuation.rb index b3a823cf..3f6a57b5 100644 --- a/app/models/valuation.rb +++ b/app/models/valuation.rb @@ -11,6 +11,7 @@ class Valuation < ApplicationRecord # Each account can have at most 1 opening anchor and 1 current anchor. All valuations between these anchors should # be either "recon" or "snapshot". This ensures we can reliably construct the account balance history solely from Entries. validate :unique_anchor_per_account, if: -> { opening_anchor? || current_anchor? } + validate :manual_accounts_cannot_have_current_anchor private def unique_anchor_per_account @@ -26,4 +27,12 @@ class Valuation < ApplicationRecord errors.add(:kind, "#{kind.humanize} already exists for this account") end end + + def manual_accounts_cannot_have_current_anchor + return unless entry&.account + + if entry.account.unlinked? && current_anchor? + errors.add(:kind, "Manual accounts cannot have a current anchor") + end + end end diff --git a/app/views/accounts/_form.html.erb b/app/views/accounts/_form.html.erb index ef2e0af5..0f6b8eda 100644 --- a/app/views/accounts/_form.html.erb +++ b/app/views/accounts/_form.html.erb @@ -1,10 +1,12 @@ <%# locals: (account:, url:) %> <% if @error_message.present? %> - <%= render AlertComponent.new(message: @error_message, variant: :error) %> +