diff --git a/app/controllers/concerns/accountable_resource.rb b/app/controllers/concerns/accountable_resource.rb index 23fd76107..479ad9efc 100644 --- a/app/controllers/concerns/accountable_resource.rb +++ b/app/controllers/concerns/accountable_resource.rb @@ -62,8 +62,10 @@ module AccountableResource end end - # Update remaining account attributes - update_params = account_params.except(:return_to, :balance, :currency, :opening_balance_date) + # Update remaining account attributes. Note: currency is intentionally allowed + # here so all account types (depositories, credit cards, loans, etc.) can + # have their currency changed via this shared update path. + update_params = account_params.except(:return_to, :balance, :opening_balance_date) unless @account.update(update_params) @error_message = @account.errors.full_messages.join(", ") render :edit, status: :unprocessable_entity diff --git a/app/controllers/properties_controller.rb b/app/controllers/properties_controller.rb index e937c4fb6..1de7a5f8c 100644 --- a/app/controllers/properties_controller.rb +++ b/app/controllers/properties_controller.rb @@ -10,7 +10,12 @@ class PropertiesController < ApplicationController def create @account = Current.family.accounts.create!( - property_params.merge(currency: Current.family.currency, balance: 0, status: "draft", owner: Current.user) + property_params.merge( + balance: 0, + status: "draft", + owner: Current.user, + currency: property_params[:currency].presence || Current.family.currency + ) ) @account.auto_share_with_family! if Current.family.share_all_by_default? @@ -39,9 +44,14 @@ class PropertiesController < ApplicationController end def update_balances - result = @account.set_current_balance(balance_params[:balance].to_d) + result = nil + Account.transaction do + @account.update!(currency: balance_params[:currency]) if balance_params[:currency].present? + result = @account.set_current_balance(balance_params[:balance].to_d) + raise ActiveRecord::Rollback unless result.success? + end - if result.success? + if result&.success? @success_message = "Balance updated successfully." if @account.active? @@ -50,7 +60,7 @@ class PropertiesController < ApplicationController redirect_to address_property_path(@account) end else - @error_message = result.error_message + @error_message = result&.error_message render :balances, status: :unprocessable_entity end end @@ -93,6 +103,7 @@ class PropertiesController < ApplicationController params.require(:account) .permit( :name, + :currency, :accountable_type, :institution_name, :institution_domain, diff --git a/test/controllers/properties_controller_test.rb b/test/controllers/properties_controller_test.rb index 890f8b17e..ce5a97847 100644 --- a/test/controllers/properties_controller_test.rb +++ b/test/controllers/properties_controller_test.rb @@ -14,6 +14,7 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest account: { name: "New Property", subtype: "house", + currency: "EUR", institution_name: "Property Lender", institution_domain: "propertylender.example", notes: "Property notes", @@ -31,6 +32,7 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest assert created_account.accountable.is_a?(Property) assert_equal "draft", created_account.status assert_equal 0, created_account.balance + assert_equal "EUR", created_account.currency assert_equal "Property Lender", created_account[:institution_name] assert_equal "propertylender.example", created_account[:institution_domain] assert_equal "Property notes", created_account[:notes] @@ -93,8 +95,12 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest } } + @account.reload + assert_equal 600000, @account.balance + assert_equal "EUR", @account.currency + # If account is active, it renders balances view; otherwise redirects to address - if @account.reload.active? + if @account.active? assert_response :success else assert_redirected_to address_property_path(@account) diff --git a/test/interfaces/accountable_resource_interface_test.rb b/test/interfaces/accountable_resource_interface_test.rb index 5ad9598e1..a17b6cf9e 100644 --- a/test/interfaces/accountable_resource_interface_test.rb +++ b/test/interfaces/accountable_resource_interface_test.rb @@ -14,4 +14,18 @@ module AccountableResourceInterfaceTest get edit_account_url(@account) assert_response :success end + + test "update saves currency change" do + @account.update!(currency: "USD") + + patch send("#{@account.accountable_type.underscore}_path", @account), params: { + account: { + name: @account.name, + currency: "EUR" + } + } + + @account.reload + assert_equal "EUR", @account.currency + end end