1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-25 08:09:38 +02:00

Prepare fixture data for account sync tests (#493)

* Rename account balance field for clarity

`original_balance` and `original_currency` may infer that these values are "original" to the account.  In reality, they represent the "current" balance and currency on the account.

* Prepare fixture data for account sync testing

* Update to new field

* Fix conflicts

* Remove local schema change
This commit is contained in:
Zach Gollwitzer 2024-02-27 12:43:49 -05:00 committed by GitHub
parent d3b326d273
commit 7d48c01833
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 230 additions and 265 deletions

View file

@ -3,7 +3,7 @@ class AccountsController < ApplicationController
def new
@account = Account.new(
original_balance: nil,
balance: nil,
accountable: Accountable.from_type(params[:type])&.new
)
end
@ -41,6 +41,6 @@ class AccountsController < ApplicationController
private
def account_params
params.require(:account).permit(:name, :accountable_type, :original_balance, :original_currency, :subtype)
params.require(:account).permit(:name, :accountable_type, :balance, :currency, :subtype)
end
end

View file

@ -6,11 +6,11 @@ class ConvertCurrencyJob < ApplicationJob
# Convert all account balances to new currency
family.accounts.each do |account|
if account.original_currency == family.currency
account.converted_balance = account.original_balance
account.converted_currency = account.original_currency
if account.currency == family.currency
account.converted_balance = account.balance
account.converted_currency = account.currency
else
account.converted_balance = ExchangeRate.convert(account.original_currency, family.currency, account.original_balance)
account.converted_balance = ExchangeRate.convert(account.currency, family.currency, account.balance)
account.converted_currency = family.currency
end
account.save!

View file

@ -37,11 +37,11 @@ class Account < ApplicationRecord
end
def check_currency
if self.original_currency == self.family.currency
self.converted_balance = self.original_balance
self.converted_currency = self.original_currency
if self.currency == self.family.currency
self.converted_balance = self.balance
self.converted_currency = self.currency
else
self.converted_balance = ExchangeRate.convert(self.original_currency, self.family.currency, self.original_balance)
self.converted_balance = ExchangeRate.convert(self.currency, self.family.currency, self.balance)
self.converted_currency = self.family.currency
end
end

View file

@ -1,90 +1,82 @@
<h1 class="text-3xl font-semibold font-display"><%= t('.title')%></h1>
<%= modal do %>
<div class="flex flex-col min-h-[530px]" data-controller="list-keyboard-navigation">
<% if @account.accountable.blank? %>
<div class="border-b border-alpha-black-25 p-4 text-gray-400">
<%= t '.select_accountable_type' %>
</div>
<div class="flex flex-col p-2 text-sm grow">
<button hidden data-controller="hotkey" data-hotkey="k,K,ArrowUp,ArrowLeft" data-action="list-keyboard-navigation#focusPrevious">Previous</button>
<button hidden data-controller="hotkey" data-hotkey="j,J,ArrowDown,ArrowRight" data-action="list-keyboard-navigation#focusNext">Next</button>
<%= render "account_type", type: Account::Depository.new, bg_color: "bg-blue-50", text_color: "text-blue-500", icon: "landmark" %>
<%= render "account_type", type: Account::Investment.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "line-chart" %>
<%= render "account_type", type: Account::Property.new, bg_color: "bg-pink-50", text_color: "text-pink-500", icon: "home" %>
<%= render "account_type", type: Account::Vehicle.new, bg_color: "bg-indigo-50", text_color: "text-indigo-500", icon: "car-front" %>
<%= render "account_type", type: Account::Credit.new, bg_color: "bg-violet-50", text_color: "text-violet-500", icon: "credit-card" %>
<%= render "account_type", type: Account::Loan.new, bg_color: "bg-yellow-50", text_color: "text-yellow-500", icon: "hand-coins" %>
<%= render "account_type", type: Account::OtherAsset.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "plus" %>
<%= render "account_type", type: Account::OtherLiability.new, bg_color: "bg-red-50", text_color: "text-red-500", icon: "minus" %>
</div>
<div class="border-t border-alpha-black-25 p-4 text-gray-500 text-sm flex justify-between">
<div class="flex space-x-5">
<div class="flex items-center space-x-2">
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('corner-down-left', class: 'inline w-3 h-3')%></kbd>
<% if @account.accountable.blank? %>
<div class="border-b border-alpha-black-25 p-4 text-gray-400">
<%= t '.select_accountable_type' %>
</div>
<div class="flex flex-col p-2 text-sm grow">
<button hidden data-controller="hotkey" data-hotkey="k,K,ArrowUp,ArrowLeft" data-action="list-keyboard-navigation#focusPrevious">Previous</button>
<button hidden data-controller="hotkey" data-hotkey="j,J,ArrowDown,ArrowRight" data-action="list-keyboard-navigation#focusNext">Next</button>
<%= render "account_type", type: Account::Depository.new, bg_color: "bg-blue-50", text_color: "text-blue-500", icon: "landmark" %>
<%= render "account_type", type: Account::Investment.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "line-chart" %>
<%= render "account_type", type: Account::Property.new, bg_color: "bg-pink-50", text_color: "text-pink-500", icon: "home" %>
<%= render "account_type", type: Account::Vehicle.new, bg_color: "bg-indigo-50", text_color: "text-indigo-500", icon: "car-front" %>
<%= render "account_type", type: Account::Credit.new, bg_color: "bg-violet-50", text_color: "text-violet-500", icon: "credit-card" %>
<%= render "account_type", type: Account::Loan.new, bg_color: "bg-yellow-50", text_color: "text-yellow-500", icon: "hand-coins" %>
<%= render "account_type", type: Account::OtherAsset.new, bg_color: "bg-green-50", text_color: "text-green-500", icon: "plus" %>
<%= render "account_type", type: Account::OtherLiability.new, bg_color: "bg-red-50", text_color: "text-red-500", icon: "minus" %>
</div>
<div class="border-t border-alpha-black-25 p-4 text-gray-500 text-sm flex justify-between">
<div class="flex space-x-5">
<div class="flex items-center space-x-2">
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('corner-down-left', class: 'inline w-3 h-3')%></kbd>
</div>
<div class="flex items-center space-x-2">
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-up', class: 'inline w-3 h-3')%></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-down', class: 'inline w-3 h-3')%></kbd>
</div>
</div>
<div class="flex items-center space-x-2">
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-up', class: 'inline w-3 h-3')%></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-down', class: 'inline w-3 h-3')%></kbd>
<button data-action="modal#close">Close</button> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-8 h-5 shrink-0 grow-0 items-center justify-center text-xs">ESC</kbd>
</div>
</div>
<div class="flex items-center space-x-2">
<button data-action="modal#close">Close</button> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-8 h-5 shrink-0 grow-0 items-center justify-center text-xs">ESC</kbd>
<% elsif params[:step] == 'method' && @account.accountable.present? %>
<div class="border-b border-alpha-black-25 p-4 text-gray-400 flex items-center space-x-3">
<%= link_to new_account_path, class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 back focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
<% end %>
<span>How would you like to add it?</span>
</div>
</div>
<% elsif params[:step] == 'method' && @account.accountable.present? %>
<div class="border-b border-alpha-black-25 p-4 text-gray-400 flex items-center space-x-3">
<%= link_to new_account_path, class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 back focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
<% end %>
<span>How would you like to add it?</span>
</div>
<div class="flex flex-col p-2 text-sm grow">
<button hidden data-controller="hotkey" data-hotkey="k,K,ArrowUp,ArrowLeft" data-action="list-keyboard-navigation#focusPrevious">Previous</button>
<button hidden data-controller="hotkey" data-hotkey="j,J,ArrowDown,ArrowRight" data-action="list-keyboard-navigation#focusNext">Next</button>
<%= render "entry_method", type: @account.accountable, text: 'Enter account balance manually', icon: "keyboard" %>
<%= render "entry_method", type: @account.accountable, text: 'Securely link bank account with data provider (coming soon)', icon: "link-2", disabled: true %>
<%= render "entry_method", type: @account.accountable, text: 'Upload spreadsheet (coming soon)', icon: "sheet", disabled: true %>
</div>
<div class="border-t border-alpha-black-25 p-4 text-gray-500 text-sm flex justify-between">
<div class="flex space-x-5">
<div class="flex items-center space-x-2">
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('corner-down-left', class: 'inline w-3 h-3')%></kbd>
<div class="flex flex-col p-2 text-sm grow">
<button hidden data-controller="hotkey" data-hotkey="k,K,ArrowUp,ArrowLeft" data-action="list-keyboard-navigation#focusPrevious">Previous</button>
<button hidden data-controller="hotkey" data-hotkey="j,J,ArrowDown,ArrowRight" data-action="list-keyboard-navigation#focusNext">Next</button>
<%= render "entry_method", type: @account.accountable, text: 'Enter account balance manually', icon: "keyboard" %>
<%= render "entry_method", type: @account.accountable, text: 'Securely link bank account with data provider (coming soon)', icon: "link-2", disabled: true %>
<%= render "entry_method", type: @account.accountable, text: 'Upload spreadsheet (coming soon)', icon: "sheet", disabled: true %>
</div>
<div class="border-t border-alpha-black-25 p-4 text-gray-500 text-sm flex justify-between">
<div class="flex space-x-5">
<div class="flex items-center space-x-2">
<span>Select</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('corner-down-left', class: 'inline w-3 h-3')%></kbd>
</div>
<div class="flex items-center space-x-2">
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-up', class: 'inline w-3 h-3')%></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-down', class: 'inline w-3 h-3')%></kbd>
</div>
</div>
<div class="flex items-center space-x-2">
<span>Navigate</span> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-up', class: 'inline w-3 h-3')%></kbd> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-5 h-5 shrink-0 grow-0 items-center justify-center"><%= lucide_icon('arrow-down', class: 'inline w-3 h-3')%></kbd>
<button data-action="modal#close">Close</button> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-8 h-5 shrink-0 grow-0 items-center justify-center text-xs">ESC</kbd>
</div>
</div>
<div class="flex items-center space-x-2">
<button data-action="modal#close">Close</button> <kbd class="bg-alpha-black-50 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)] p-1 rounded-md flex w-8 h-5 shrink-0 grow-0 items-center justify-center text-xs">ESC</kbd>
<% else %>
<div class="border-b border-alpha-black-25 p-4 text-gray-800 flex items-center space-x-3">
<%= link_to new_account_path(step: 'method', type: params[:type]), class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
<% end %>
<span>Add <%= @account.accountable.model_name.human.downcase %></span>
</div>
</div>
<% else %>
<div class="border-b border-alpha-black-25 p-4 text-gray-800 flex items-center space-x-3">
<%= link_to new_account_path(step: 'method', type: params[:type]), class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon('arrow-left', class: 'text-gray-500 w-5 h-5') %>
<% end %>
<span>Add <%= @account.accountable.model_name.human.downcase %></span>
</div>
<%= form_with model: @account, url: accounts_path, scope: :account, html: { class: "m-5 mt-1 flex flex-col justify-between grow", data: { turbo: false } } do |f| %>
<%= form_with model: @account, url: accounts_path, scope: :account, html: { class: "m-5 mt-1 flex flex-col justify-between grow", data: { turbo: false } } do |f| %>
<div class="space-y-4 grow">
<%= f.hidden_field :accountable_type %>
<%= f.text_field :name, placeholder: t('accounts.new.name.placeholder'), required: 'required', label: t('accounts.new.name.label'), autofocus: true %>
<%= render "accounts/#{permitted_accountable_partial(@account.accountable_type)}", f: f %>
<%= form_field_tag do %>
<%= f.label :original_balance, class: "form-field__label" %>
<%= f.number_field :original_balance, step: :any, placeholder: number_to_currency(0), in: 0.00..100000000.00, required: 'required', class: 'form-field__input max-w-[80%]' %>
<%= currency_dropdown(f: f, options: Currency.all.order(:iso_code).pluck(:iso_code)) if Currency.count > 1 %>
<% end %>
</div>
<%= f.submit "Add #{@account.accountable.model_name.human.downcase}" %>
<%= form_field_tag do %>
<%= f.label :balance, class: "form-field__label" %>
<%= f.number_field :balance, step: :any, placeholder: number_to_currency(0), in: 0.00..100000000.00, required: 'required', class: 'form-field__input max-w-[80%]' %>
<%= currency_dropdown(f: f, options: Currency.all.order(:iso_code).pluck(:iso_code)) if Currency.count > 1 %>
<% end %>
</div>
<%= f.submit "Add #{@account.accountable.model_name.human.downcase}" %>
<% end %>
<% end %>
<% end %>
</div>
<% end %>
<% end %>

View file

@ -11,7 +11,7 @@
<div class="flex items-center gap-3">
<div class="relative cursor-not-allowed">
<div class="flex items-center gap-2 px-3 py-2">
<span class="text-gray-900"><%= @account.original_currency %> <%= @account.original_currency.unit %></span>
<span class="text-gray-900"><%= @account.currency %> <%= @account.currency.unit %></span>
<%= lucide_icon("chevron-down", class: "w-5 h-5 text-gray-500") %>
</div>
</div>
@ -29,10 +29,10 @@
<p class="text-sm text-gray-500">Total Value</p>
<%# TODO: Will need a better way to split a formatted monetary value into these 3 parts %>
<p class="text-gray-900">
<span class="text-gray-500"><%= @account.original_currency.unit %></span>
<span class="text-xl font-medium"><%= format_currency(@account.original_balance, precision: 0, unit: '') %></span>
<%- if @account.original_currency.precision.positive? -%>
<span class="text-gray-500"><%= @account.original_currency.separator %><%= @account.original_balance.cents(precision: @account.original_currency.precision) %></span>
<span class="text-gray-500"><%= @account.currency.unit %></span>
<span class="text-xl font-medium"><%= format_currency(@account.balance, precision: 0, unit: '') %></span>
<%- if @account.currency.precision.positive? -%>
<span class="text-gray-500"><%= @account.currency.separator %><%= @account.balance.cents(precision: @account.currency.precision) %></span>
<% end %>
</p>
<% if @balance_series.nil? %>

View file

@ -1,14 +1,14 @@
<div data-controller="currency-dropdown" class="absolute right-1 bottom-[10px] flex items-end">
<button type="button" class="flex items-center justify-between w-20 px-2 py-1 text-sm rounded-lg hover:bg-gray-100 focus:bg-gray-100" data-action="click->currency-dropdown#toggleMenu">
<div data-currency-dropdown-target="label"><%= f.object.original_currency %></div>
<div data-currency-dropdown-target="label"><%= f.object.currency %></div>
<%# Example of how account currency value is updated %>
<%= f.hidden_field :original_currency, data: {currency_dropdown_target: "input"} %>
<%= f.hidden_field :currency, data: {currency_dropdown_target: "input"} %>
<%= lucide_icon("chevron-down", class: "text-gray-500 w-5 h-5" ) %>
</button>
<ul data-currency-dropdown-target="menu" class="hidden fixed p-1 bg-white rounded-[10px] min-w-[112px] z-50 translate-y-2 border border-alpha-black-100 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.1)]">
<% options.each do |option| %>
<li data-action="click->currency-dropdown#selectOption" data-currency-dropdown-target="option" data-value="<%= option %>" class="flex justify-between items-center p-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer rounded-lg <%= "bg-gray-100" if option === f.object.original_currency %>"><%= option %>
<%= inline_svg_tag('icn-check.svg', class: "text-gray-500 fill-current #{'hidden'if option != f.object.original_currency}") %>
<li data-action="click->currency-dropdown#selectOption" data-currency-dropdown-target="option" data-value="<%= option %>" class="flex justify-between items-center p-2 text-sm text-gray-700 hover:bg-gray-100 cursor-pointer rounded-lg <%= "bg-gray-100" if option === f.object.currency %>"><%= option %>
<%= inline_svg_tag('icn-check.svg', class: "text-gray-500 fill-current #{'hidden'if option != f.object.currency}") %>
</li>
<% end %>
</ul>