mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 05:09:38 +02:00
Integrate money-rails gem (#268)
* Integrate money-rails gem * Fix Lint issues * Basic test for monetize feature * Merge main branch * Changes to monetize balance field --------- Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
This commit is contained in:
parent
323a8ccf50
commit
1182ab39bd
12 changed files with 176 additions and 14 deletions
1
Gemfile
1
Gemfile
|
@ -27,6 +27,7 @@ gem "bcrypt", "~> 3.1.7"
|
|||
gem "inline_svg"
|
||||
gem "jbuilder"
|
||||
gem "tzinfo-data", platforms: %i[ windows jruby ]
|
||||
gem "money-rails", "~> 1.12"
|
||||
|
||||
group :development, :test do
|
||||
gem "debug", platforms: %i[ mri windows ]
|
||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -202,6 +202,15 @@ GEM
|
|||
matrix (0.4.2)
|
||||
mini_mime (1.1.5)
|
||||
minitest (5.21.2)
|
||||
monetize (1.13.0)
|
||||
money (~> 6.12)
|
||||
money (6.16.0)
|
||||
i18n (>= 0.6.4, <= 2)
|
||||
money-rails (1.15.0)
|
||||
activesupport (>= 3.0)
|
||||
monetize (~> 1.9)
|
||||
money (~> 6.13)
|
||||
railties (>= 3.0)
|
||||
msgpack (1.7.2)
|
||||
net-imap (0.4.10)
|
||||
date
|
||||
|
@ -382,6 +391,7 @@ DEPENDENCIES
|
|||
inline_svg
|
||||
jbuilder
|
||||
letter_opener
|
||||
money-rails (~> 1.12)
|
||||
pg (~> 1.1)
|
||||
propshaft
|
||||
puma (>= 5.0)
|
||||
|
|
|
@ -30,7 +30,7 @@ class AccountsController < ApplicationController
|
|||
private
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:name, :accountable_type, :balance, :subtype)
|
||||
params.require(:account).permit(:name, :accountable_type, :balance, :balance_cents, :subtype)
|
||||
end
|
||||
|
||||
def account_type_class
|
||||
|
|
|
@ -4,4 +4,6 @@ class Account < ApplicationRecord
|
|||
delegated_type :accountable, types: %w[ Account::Credit Account::Depository Account::Investment Account::Loan Account::OtherAsset Account::OtherLiability Account::Property Account::Vehicle], dependent: :destroy
|
||||
|
||||
delegate :type_name, to: :accountable
|
||||
|
||||
monetize :balance_cents
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<%= account.accountable %>
|
||||
</div>
|
||||
<p class="text-sm text-right">
|
||||
<span class="block mb-1"><%= number_to_currency account.balance %></span>
|
||||
<span class="block mb-1"><%= humanized_money_with_symbol account.balance %></span>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<div class="relative p-4 border border-gray-100 bg-offwhite rounded-xl focus-within:bg-white focus-within:shadow focus-within:opacity-100">
|
||||
<label for="account_balance" class="block text-sm font-medium opacity-50 focus-within:opacity-100">Balance</label>
|
||||
<div class="flex">
|
||||
<%= f.number_field :balance, placeholder: "$0.00", in: 0.00..100000000.00, required: 'required', class: "p-0 mt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100" %>
|
||||
<%= f.number_field :balance, placeholder: "$0.00", in: 0.00..100000000.00, step: :any, required: 'required', class: "p-0 mt-1 bg-transparent border-none opacity-50 focus:outline-none focus:ring-0 focus-within:opacity-100" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
<%= account.name %>
|
||||
</div>
|
||||
<p class="text-sm text-right">
|
||||
<span class="block mb-1"><%= number_to_currency account.balance %></span>
|
||||
<span class="block mb-1"><%= humanized_money_with_symbol account.balance %></span>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
114
config/initializers/money.rb
Normal file
114
config/initializers/money.rb
Normal file
|
@ -0,0 +1,114 @@
|
|||
# encoding : utf-8
|
||||
|
||||
MoneyRails.configure do |config|
|
||||
# To set the default currency
|
||||
#
|
||||
config.default_currency = :usd
|
||||
|
||||
# Set default bank object
|
||||
#
|
||||
# Example:
|
||||
# config.default_bank = EuCentralBank.new
|
||||
|
||||
# Add exchange rates to current money bank object.
|
||||
# (The conversion rate refers to one direction only)
|
||||
#
|
||||
# Example:
|
||||
# config.add_rate "USD", "CAD", 1.24515
|
||||
# config.add_rate "CAD", "USD", 0.803115
|
||||
|
||||
# To handle the inclusion of validations for monetized fields
|
||||
# The default value is true
|
||||
#
|
||||
# config.include_validations = true
|
||||
|
||||
# Default ActiveRecord migration configuration values for columns:
|
||||
#
|
||||
# config.amount_column = { prefix: '', # column name prefix
|
||||
# postfix: '_cents', # column name postfix
|
||||
# column_name: nil, # full column name (overrides prefix, postfix and accessor name)
|
||||
# type: :integer, # column type
|
||||
# present: true, # column will be created
|
||||
# null: false, # other options will be treated as column options
|
||||
# default: 0
|
||||
# }
|
||||
#
|
||||
# config.currency_column = { prefix: '',
|
||||
# postfix: '_currency',
|
||||
# column_name: nil,
|
||||
# type: :string,
|
||||
# present: true,
|
||||
# null: false,
|
||||
# default: 'USD'
|
||||
# }
|
||||
|
||||
# Register a custom currency
|
||||
#
|
||||
# Example:
|
||||
# config.register_currency = {
|
||||
# priority: 1,
|
||||
# iso_code: "EU4",
|
||||
# name: "Euro with subunit of 4 digits",
|
||||
# symbol: "€",
|
||||
# symbol_first: true,
|
||||
# subunit: "Subcent",
|
||||
# subunit_to_unit: 10000,
|
||||
# thousands_separator: ".",
|
||||
# decimal_mark: ","
|
||||
# }
|
||||
|
||||
# Specify a rounding mode
|
||||
# Any one of:
|
||||
#
|
||||
# BigDecimal::ROUND_UP,
|
||||
# BigDecimal::ROUND_DOWN,
|
||||
# BigDecimal::ROUND_HALF_UP,
|
||||
# BigDecimal::ROUND_HALF_DOWN,
|
||||
# BigDecimal::ROUND_HALF_EVEN,
|
||||
# BigDecimal::ROUND_CEILING,
|
||||
# BigDecimal::ROUND_FLOOR
|
||||
#
|
||||
# set to BigDecimal::ROUND_HALF_EVEN by default
|
||||
#
|
||||
config.rounding_mode = BigDecimal::ROUND_HALF_UP
|
||||
|
||||
# Set default money format globally.
|
||||
# Default value is nil meaning "ignore this option".
|
||||
# Example:
|
||||
#
|
||||
# config.default_format = {
|
||||
# no_cents_if_whole: nil,
|
||||
# symbol: nil,
|
||||
# sign_before_symbol: nil
|
||||
# }
|
||||
|
||||
# If you would like to use I18n localization (formatting depends on the
|
||||
# locale):
|
||||
config.locale_backend = :i18n
|
||||
#
|
||||
# Example (using default localization from rails-i18n):
|
||||
#
|
||||
# I18n.locale = :en
|
||||
# Money.new(10_000_00, 'USD').format # => $10,000.00
|
||||
# I18n.locale = :es
|
||||
# Money.new(10_000_00, 'USD').format # => $10.000,00
|
||||
#
|
||||
# For the legacy behaviour of "per currency" localization (formatting depends
|
||||
# only on currency):
|
||||
# config.locale_backend = :currency
|
||||
#
|
||||
# Example:
|
||||
# Money.new(10_000_00, 'USD').format # => $10,000.00
|
||||
# Money.new(10_000_00, 'EUR').format # => €10.000,00
|
||||
#
|
||||
# In case you don't need localization and would like to use default values
|
||||
# (can be redefined using config.default_format):
|
||||
# config.locale_backend = nil
|
||||
|
||||
# Set default raise_error_on_money_parsing option
|
||||
# It will be raise error if assigned different currency
|
||||
# The default value is false
|
||||
#
|
||||
# Example:
|
||||
# config.raise_error_on_money_parsing = false
|
||||
end
|
14
db/migrate/20240206031739_replace_money_field.rb
Normal file
14
db/migrate/20240206031739_replace_money_field.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
class ReplaceMoneyField < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
add_monetize :accounts, :balance
|
||||
change_column :accounts, :balance_cents, :integer, limit: 8
|
||||
|
||||
Account.reset_column_information
|
||||
|
||||
Account.find_each do |account|
|
||||
account.update_columns(balance_cents: Money.from_amount(account.balance, account.currency).cents)
|
||||
end
|
||||
|
||||
remove_column :accounts, :balance
|
||||
end
|
||||
end
|
5
db/schema.rb
generated
5
db/schema.rb
generated
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_02_03_050018) do
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_02_06_031739) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pgcrypto"
|
||||
enable_extension "plpgsql"
|
||||
|
@ -59,12 +59,13 @@ ActiveRecord::Schema[7.2].define(version: 2024_02_03_050018) do
|
|||
t.string "subtype"
|
||||
t.uuid "family_id", null: false
|
||||
t.string "name"
|
||||
t.bigint "balance", default: 0
|
||||
t.string "currency", default: "USD"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "accountable_type"
|
||||
t.uuid "accountable_id"
|
||||
t.bigint "balance_cents", default: 0, null: false
|
||||
t.string "balance_currency", default: "USD", null: false
|
||||
t.index ["accountable_type"], name: "index_accounts_on_accountable_type"
|
||||
t.index ["family_id"], name: "index_accounts_on_family_id"
|
||||
end
|
||||
|
|
6
test/fixtures/accounts.yml
vendored
6
test/fixtures/accounts.yml
vendored
|
@ -1,14 +1,14 @@
|
|||
dylan_checking:
|
||||
family: dylan_family
|
||||
name: Bob's Checking
|
||||
balance: 1200
|
||||
balance_cents: 1200
|
||||
|
||||
dylan_roth:
|
||||
family: dylan_family
|
||||
name: Bob's Roth IRA
|
||||
balance: 1200
|
||||
balance_cents: 1200
|
||||
|
||||
richards_savings:
|
||||
family: richards_family
|
||||
name: Keef's HYSA
|
||||
balance: 1500
|
||||
balance_cents: 1500
|
||||
|
|
|
@ -1,11 +1,31 @@
|
|||
require "test_helper"
|
||||
|
||||
class AccountTest < ActiveSupport::TestCase
|
||||
test "new account should be valid" do
|
||||
def setup
|
||||
depository = Account::Depository.create!
|
||||
account = Account.create!(family: families(:dylan_family), name: "Explicit Checking", balance: 1200, accountable: depository)
|
||||
assert account.valid?
|
||||
assert_not_nil account.accountable_id
|
||||
assert_not_nil account.accountable
|
||||
@account = Account.create!(family: families(:dylan_family), name: "Explicit Checking", balance_cents: 1200, accountable: depository)
|
||||
end
|
||||
|
||||
test "new account should be valid" do
|
||||
assert @account.valid?
|
||||
assert_not_nil @account.accountable_id
|
||||
assert_not_nil @account.accountable
|
||||
end
|
||||
|
||||
test "balance returns Money object" do
|
||||
@account.balance = 10
|
||||
assert_instance_of Money, @account.balance
|
||||
assert_equal :usd, @account.balance.currency.id
|
||||
end
|
||||
|
||||
test "correctly assigns Money objects to the attribute" do
|
||||
@account.balance = Money.new(2500, "USD")
|
||||
assert_equal 2500, @account.balance_cents
|
||||
end
|
||||
|
||||
test "balance_cents can be updated" do
|
||||
new_balance = Money.new(10000, "USD")
|
||||
@account.balance = new_balance
|
||||
assert_equal new_balance, @account.balance
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue