diff --git a/app/controllers/account/trades_controller.rb b/app/controllers/account/trades_controller.rb index 6ace6538..fd9b7d48 100644 --- a/app/controllers/account/trades_controller.rb +++ b/app/controllers/account/trades_controller.rb @@ -10,7 +10,7 @@ class Account::TradesController < ApplicationController def create_entry_params params.require(:account_entry).permit( - :account_id, :date, :amount, :currency, :qty, :price, :ticker, :type, :transfer_account_id + :account_id, :date, :amount, :currency, :qty, :price, :ticker, :manual_ticker, :type, :transfer_account_id ).tap do |params| account_id = params.delete(:account_id) params[:account] = Current.family.accounts.find(account_id) diff --git a/app/models/account/trade_builder.rb b/app/models/account/trade_builder.rb index 704d851f..c632f272 100644 --- a/app/models/account/trade_builder.rb +++ b/app/models/account/trade_builder.rb @@ -2,7 +2,7 @@ class Account::TradeBuilder include ActiveModel::Model attr_accessor :account, :date, :amount, :currency, :qty, - :price, :ticker, :type, :transfer_account_id + :price, :ticker, :manual_ticker, :type, :transfer_account_id attr_reader :buildable @@ -110,8 +110,9 @@ class Account::TradeBuilder account.family end + # Users can either look up a ticker from our provider (Synth) or enter a manual, "offline" ticker (that we won't fetch prices for) def security - ticker_symbol, exchange_operating_mic = ticker.split("|") + ticker_symbol, exchange_operating_mic = ticker.present? ? ticker.split("|") : [ manual_ticker, nil ] Security.find_or_create_by(ticker: ticker_symbol, exchange_operating_mic: exchange_operating_mic) do |s| FetchSecurityInfoJob.perform_later(s.id) diff --git a/app/models/security.rb b/app/models/security.rb index 46672fb5..991ac202 100644 --- a/app/models/security.rb +++ b/app/models/security.rb @@ -1,5 +1,6 @@ class Security < ApplicationRecord include Providable + before_save :upcase_ticker has_many :trades, dependent: :nullify, class_name: "Account::Trade" @@ -9,6 +10,10 @@ class Security < ApplicationRecord validates :ticker, uniqueness: { scope: :exchange_operating_mic, case_sensitive: false } class << self + def provider + security_prices_provider + end + def search(query) security_prices_provider.search_securities( query: query[:search], diff --git a/app/views/account/trades/_form.html.erb b/app/views/account/trades/_form.html.erb index c8dae4d3..a74d401f 100644 --- a/app/views/account/trades/_form.html.erb +++ b/app/views/account/trades/_form.html.erb @@ -27,9 +27,18 @@ }} %> <% if %w[buy sell].include?(type) %> -
- <%= form.combobox :ticker, securities_path(country_code: Current.family.country), label: t(".holding"), placeholder: t(".ticker_placeholder"), required: true %> -
+ <% if Security.provider.present? %> +
+ <%= form.combobox :ticker, + securities_path(country_code: Current.family.country), + name_when_new: "account_entry[manual_ticker]", + label: t(".holding"), + placeholder: t(".ticker_placeholder"), + required: true %> +
+ <% else %> + <%= form.text_field :manual_ticker, label: "Ticker", placeholder: "AAPL", required: true %> + <% end %> <% end %> <%= form.date_field :date, label: true, value: Date.current, required: true %>