mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-24 07:39:39 +02:00
Add backend for property account details
This commit is contained in:
parent
4433488562
commit
5ea2fd5a23
17 changed files with 258 additions and 2 deletions
34
app/controllers/properties_controller.rb
Normal file
34
app/controllers/properties_controller.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
class PropertiesController < ApplicationController
|
||||
before_action :set_account, only: :update
|
||||
|
||||
def create
|
||||
account = Current.family.accounts.create!(account_params)
|
||||
account.sync_later
|
||||
redirect_to account, notice: t(".success")
|
||||
end
|
||||
|
||||
def update
|
||||
@account.update!(account_params)
|
||||
@account.sync_later
|
||||
redirect_to @account, notice: t(".success")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
@account = Current.family.accounts.find(params[:id])
|
||||
end
|
||||
|
||||
def account_params
|
||||
params.require(:account)
|
||||
.permit(
|
||||
:name, :balance, :currency, :accountable_type,
|
||||
accountable_attributes: [
|
||||
:id,
|
||||
:year_built,
|
||||
:area,
|
||||
address_attributes: [ :line1, :line2, :locality, :region, :country, :postal_code ]
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
2
app/helpers/properties_helper.rb
Normal file
2
app/helpers/properties_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
module PropertiesHelper
|
||||
end
|
|
@ -28,6 +28,8 @@ class Account < ApplicationRecord
|
|||
|
||||
delegated_type :accountable, types: Accountable::TYPES, dependent: :destroy
|
||||
|
||||
accepts_nested_attributes_for :accountable
|
||||
|
||||
delegate :value, :series, to: :accountable
|
||||
|
||||
class << self
|
||||
|
|
26
app/models/address.rb
Normal file
26
app/models/address.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
class Address < ApplicationRecord
|
||||
belongs_to :addressable, polymorphic: true
|
||||
|
||||
validates :line1, :locality, presence: true
|
||||
validates :region, presence: true, format: { with: /\A[A-Z]{1,3}(-[A-Z\d]{1,3})?\z/, message: "must be a valid ISO3166-2 code" }
|
||||
validates :country, presence: true, format: { with: /\A[A-Z]{2}\z/, message: "must be a valid ISO3166-1 Alpha-2 code" }
|
||||
validates :postal_code, presence: true, if: :postal_code_required?
|
||||
|
||||
def to_s
|
||||
I18n.t("address.format",
|
||||
line1: line1,
|
||||
line2: line2,
|
||||
county: county,
|
||||
locality: locality,
|
||||
region: region,
|
||||
country: country,
|
||||
postal_code: postal_code
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def postal_code_required?
|
||||
country.in?(%w[US CA GB])
|
||||
end
|
||||
end
|
20
app/models/measurement.rb
Normal file
20
app/models/measurement.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
class Measurement
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_reader :value, :unit
|
||||
|
||||
VALID_UNITS = %w[sqft sqm]
|
||||
|
||||
validates :unit, inclusion: { in: VALID_UNITS }
|
||||
validates :value, presence: true
|
||||
|
||||
def initialize(value, unit)
|
||||
@value = value.to_f
|
||||
@unit = unit.to_s.downcase.strip
|
||||
validate!
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{@value.to_i} #{@unit}"
|
||||
end
|
||||
end
|
|
@ -1,3 +1,11 @@
|
|||
class Property < ApplicationRecord
|
||||
include Accountable
|
||||
|
||||
has_one :address, as: :addressable, dependent: :destroy
|
||||
|
||||
accepts_nested_attributes_for :address
|
||||
|
||||
def area
|
||||
Measurement.new(area_value, area_unit)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,3 +29,4 @@ ignore_unused:
|
|||
- 'helpers.submit.*' # i18n-tasks does not detect used at forms
|
||||
- 'helpers.label.*' # i18n-tasks does not detect used at forms
|
||||
- 'accounts.show.sync_message_*' # messages generated in the sync ActiveJob
|
||||
- 'address.attributes.*'
|
||||
|
|
15
config/locales/models/address/en.yml
Normal file
15
config/locales/models/address/en.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
en:
|
||||
address:
|
||||
attributes:
|
||||
country: Country
|
||||
line1: Address Line 1
|
||||
line2: Address Line 2
|
||||
locality: Locality
|
||||
postal_code: Postal Code
|
||||
region: Region
|
||||
format: |-
|
||||
%{line1}
|
||||
%{line2}
|
||||
%{locality}, %{region} %{postal_code}
|
||||
%{country}
|
7
config/locales/views/properties/en.yml
Normal file
7
config/locales/views/properties/en.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
en:
|
||||
properties:
|
||||
create:
|
||||
success: Property created successfully
|
||||
update:
|
||||
success: Property updated successfully
|
|
@ -89,6 +89,8 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :properties, only: %i[ create update ]
|
||||
|
||||
resources :transactions, only: %i[ index new create ] do
|
||||
collection do
|
||||
post "bulk_delete"
|
||||
|
|
16
db/migrate/20240822174006_create_addresses.rb
Normal file
16
db/migrate/20240822174006_create_addresses.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
class CreateAddresses < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
create_table :addresses, id: :uuid do |t|
|
||||
t.references :addressable, type: :uuid, polymorphic: true
|
||||
t.string :line1
|
||||
t.string :line2
|
||||
t.string :county
|
||||
t.string :locality
|
||||
t.string :region
|
||||
t.string :country
|
||||
t.integer :postal_code
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
7
db/migrate/20240822180845_add_property_attributes.rb
Normal file
7
db/migrate/20240822180845_add_property_attributes.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class AddPropertyAttributes < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
add_column :properties, :year_built, :integer
|
||||
add_column :properties, :area_value, :integer
|
||||
add_column :properties, :area_unit, :string
|
||||
end
|
||||
end
|
20
db/schema.rb
generated
20
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_08_17_144454) do
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_08_22_180845) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pgcrypto"
|
||||
enable_extension "plpgsql"
|
||||
|
@ -152,6 +152,21 @@ ActiveRecord::Schema[7.2].define(version: 2024_08_17_144454) do
|
|||
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
|
||||
end
|
||||
|
||||
create_table "addresses", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||
t.string "addressable_type"
|
||||
t.uuid "addressable_id"
|
||||
t.string "line1"
|
||||
t.string "line2"
|
||||
t.string "county"
|
||||
t.string "locality"
|
||||
t.string "region"
|
||||
t.string "country"
|
||||
t.integer "postal_code"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["addressable_type", "addressable_id"], name: "index_addresses_on_addressable"
|
||||
end
|
||||
|
||||
create_table "categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "color", default: "#6172F3", null: false
|
||||
|
@ -358,6 +373,9 @@ ActiveRecord::Schema[7.2].define(version: 2024_08_17_144454) do
|
|||
create_table "properties", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "year_built"
|
||||
t.integer "area_value"
|
||||
t.string "area_unit"
|
||||
end
|
||||
|
||||
create_table "securities", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||
|
|
71
test/controllers/properties_controller_test.rb
Normal file
71
test/controllers/properties_controller_test.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
require "test_helper"
|
||||
|
||||
class PropertiesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in @user = users(:family_admin)
|
||||
@account = accounts(:property)
|
||||
end
|
||||
|
||||
test "creates property" do
|
||||
assert_difference [ "Account.count", "Property.count" ] do
|
||||
post properties_path, params: {
|
||||
account: {
|
||||
name: "Property",
|
||||
balance: 500000,
|
||||
currency: "USD",
|
||||
accountable_type: "Property",
|
||||
accountable_attributes: {
|
||||
year_built: 2002,
|
||||
area_value: 1000,
|
||||
area_unit: "sqft",
|
||||
address_attributes: {
|
||||
line1: "123 Main St",
|
||||
line2: "Apt 1",
|
||||
locality: "Los Angeles",
|
||||
region: "CA", # ISO3166-2 code
|
||||
country: "US", # ISO3166-1 Alpha-2 code
|
||||
postal_code: "90001"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
created_account = Account.order(:created_at).last
|
||||
|
||||
assert_redirected_to account_path(created_account)
|
||||
assert_equal "Property created successfully", flash[:notice]
|
||||
assert_enqueued_with(job: AccountSyncJob)
|
||||
end
|
||||
|
||||
test "updates property" do
|
||||
assert_no_difference [ "Account.count", "Property.count" ] do
|
||||
patch property_path(@account), params: {
|
||||
account: {
|
||||
name: "Updated Property",
|
||||
balance: 500000,
|
||||
currency: "USD",
|
||||
accountable_type: "Property",
|
||||
accountable_attributes: {
|
||||
id: @account.accountable_id,
|
||||
year_built: 2002,
|
||||
area_value: 1000,
|
||||
area_unit: "sqft",
|
||||
address_attributes: {
|
||||
line1: "123 Main St",
|
||||
line2: "Apt 1",
|
||||
locality: "Los Angeles",
|
||||
region: "CA", # ISO3166-2 code
|
||||
country: "US", # ISO3166-1 Alpha-2 code
|
||||
postal_code: "90001"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
assert_redirected_to account_path(@account)
|
||||
assert_equal "Property updated successfully", flash[:notice]
|
||||
assert_enqueued_with(job: AccountSyncJob)
|
||||
end
|
||||
end
|
9
test/fixtures/addresses.yml
vendored
Normal file
9
test/fixtures/addresses.yml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
one:
|
||||
line1: 123 Main Street
|
||||
line2: Apt 4B
|
||||
locality: Los Angeles
|
||||
region: CA
|
||||
country: US
|
||||
postal_code: 90001
|
||||
addressable: one
|
||||
addressable_type: Property
|
5
test/fixtures/properties.yml
vendored
5
test/fixtures/properties.yml
vendored
|
@ -1 +1,4 @@
|
|||
one: { }
|
||||
one:
|
||||
year_built: 2002
|
||||
area_value: 1000
|
||||
area_unit: "sqft"
|
15
test/models/address_test.rb
Normal file
15
test/models/address_test.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
require "test_helper"
|
||||
|
||||
class AddressTest < ActiveSupport::TestCase
|
||||
test "can print a formatted address" do
|
||||
address = Address.new(
|
||||
line1: "123 Main St",
|
||||
locality: "San Francisco",
|
||||
region: "CA",
|
||||
country: "US",
|
||||
postal_code: "94101"
|
||||
)
|
||||
|
||||
assert_equal "123 Main St\n\nSan Francisco, CA 94101\nUS", address.to_s
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue