1
0
Fork 0
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:
Zach Gollwitzer 2024-08-22 14:54:14 -04:00
parent 4433488562
commit 5ea2fd5a23
17 changed files with 258 additions and 2 deletions

View 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

View file

@ -0,0 +1,2 @@
module PropertiesHelper
end

View file

@ -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
View 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
View 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

View file

@ -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

View file

@ -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.*'

View 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}

View file

@ -0,0 +1,7 @@
---
en:
properties:
create:
success: Property created successfully
update:
success: Property updated successfully

View file

@ -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"

View 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

View 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
View file

@ -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|

View 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
View 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

View file

@ -1 +1,4 @@
one: { }
one:
year_built: 2002
area_value: 1000
area_unit: "sqft"

View 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