diff --git a/app/controllers/concerns/accountable_resource.rb b/app/controllers/concerns/accountable_resource.rb index 007a5f33a..003d61edc 100644 --- a/app/controllers/concerns/accountable_resource.rb +++ b/app/controllers/concerns/accountable_resource.rb @@ -34,7 +34,15 @@ module AccountableResource end def create - @account = Current.family.accounts.create_and_sync(account_params.except(:return_to)) + opening_balance_date = begin + account_params[:opening_balance_date].presence&.to_date + rescue Date::Error + nil + end || (Time.zone.today - 2.years) + @account = Current.family.accounts.create_and_sync( + account_params.except(:return_to, :opening_balance_date), + opening_balance_date: opening_balance_date + ) @account.lock_saved_attributes! redirect_to account_params[:return_to].presence || @account, notice: t("accounts.create.success", type: accountable_type.name.underscore.humanize) @@ -52,7 +60,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, :opening_balance_date) unless @account.update(update_params) @error_message = @account.errors.full_messages.join(", ") render :edit, status: :unprocessable_entity @@ -85,6 +93,7 @@ module AccountableResource def account_params params.require(:account).permit( :name, :balance, :subtype, :currency, :accountable_type, :return_to, + :opening_balance_date, :institution_name, :institution_domain, :notes, accountable_attributes: self.class.permitted_accountable_attributes ) diff --git a/app/models/account.rb b/app/models/account.rb index cfb6b4478..3c0f8eccf 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -79,7 +79,7 @@ class Account < ApplicationRecord super(attribute, options) end - def create_and_sync(attributes, skip_initial_sync: false) + def create_and_sync(attributes, skip_initial_sync: false, opening_balance_date: nil) attributes[:accountable_attributes] ||= {} # Ensure accountable is created, even if empty # Default cash_balance to balance unless explicitly provided (e.g., Crypto sets it to 0) attrs = attributes.dup @@ -91,7 +91,10 @@ class Account < ApplicationRecord account.save! manager = Account::OpeningBalanceManager.new(account) - result = manager.set_opening_balance(balance: initial_balance || account.balance) + result = manager.set_opening_balance( + balance: initial_balance || account.balance, + date: opening_balance_date + ) raise result.error if result.error end diff --git a/app/views/accounts/_form.html.erb b/app/views/accounts/_form.html.erb index 7f3ede919..c29962a79 100644 --- a/app/views/accounts/_form.html.erb +++ b/app/views/accounts/_form.html.erb @@ -15,6 +15,13 @@ <%= form.money_field :balance, label: t(".balance"), required: true, default_currency: Current.family.currency %> <% end %> + <% if account.new_record? && !account.linked? %> + <%= form.date_field :opening_balance_date, + label: t(".opening_balance_date_label"), + value: Time.zone.today - 2.years, + required: true %> + <% end %> + <%= yield form %>
diff --git a/config/locales/views/accounts/de.yml b/config/locales/views/accounts/de.yml index 0e9196476..298a6a6e1 100644 --- a/config/locales/views/accounts/de.yml +++ b/config/locales/views/accounts/de.yml @@ -14,7 +14,8 @@ de: new_account: Neues Konto no_accounts: Noch keine Konten vorhanden form: - balance: Aktueller Kontostand + balance: "Kontostand zum Datum:" + opening_balance_date_label: Eröffnungsdatum des Kontostands name_label: Kontoname name_placeholder: Beispielkontoname index: diff --git a/config/locales/views/accounts/en.yml b/config/locales/views/accounts/en.yml index ef748b6b7..4e2d61faa 100644 --- a/config/locales/views/accounts/en.yml +++ b/config/locales/views/accounts/en.yml @@ -18,7 +18,8 @@ en: new_account: New account no_accounts: No accounts yet form: - balance: Current balance + balance: "Balance on date:" + opening_balance_date_label: Opening balance date name_label: Account name name_placeholder: Example account name additional_details: Additional details diff --git a/test/models/account_test.rb b/test/models/account_test.rb index 5a41f432e..a8284d3db 100644 --- a/test/models/account_test.rb +++ b/test/models/account_test.rb @@ -72,6 +72,27 @@ class AccountTest < ActiveSupport::TestCase assert_equal 1000, opening_anchor.entry.amount end + test "create_and_sync uses provided opening balance date" do + Account.any_instance.stubs(:sync_later) + opening_date = Time.zone.today + + account = Account.create_and_sync( + { + family: @family, + name: "Test Account", + balance: 1000, + currency: "USD", + accountable_type: "Depository", + accountable_attributes: {} + }, + skip_initial_sync: true, + opening_balance_date: opening_date + ) + + opening_anchor = account.valuations.opening_anchor.first + assert_equal opening_date, opening_anchor.entry.date + end + test "gets short/long subtype label" do investment = Investment.new(subtype: "hsa") account = @family.accounts.create!(