Allow user to add buy and sell trade transactions for investment accounts #1066
Reference in New Issue
Block a user
Delete Branch "1048-user-can-create-buysell-investment-transactions"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Overview
Allows users to create buy and sell trades for their portfolio:
https://github.com/user-attachments/assets/f4c8bc65-31f6-4627-b4e7-477d0687c570
Other changes
In addition to this, I ran into some areas of the codebase that needed some cleanup and reworking to make it simpler to deal with this new account entry form. I have highlighted notable changes below:
Controller per-entry type
In #923, I introduced "entryable" delegated types and organized everything in the
entriesview and controller. The main purpose for this was to keep everything in one spot until we had a better reason to break it into separate types.With this PR, we introduce the final entryable type forms for
Account::Trade. Each entryable has a distinct view, so I decided to break it up into 4 controllers:Account::EntriesController- shared logic, such asshow,edit, anddestroy. Theshow/editactions delegate to their respective entryable templates, but by keeping things consolidated in the entries controller, we can render entries in a single list and add links to the respective "show" templates via the same path helper,account_entry_path(@account, @entry)new,index,update, andcreateAccount::TransactionsControllerAccount::ValuationsControllerAccount::TradesControllerThe primary goal here is to leverage our delegated types wherever possible while keeping type-specific concerns separate from each other.
Entry groups
Prior to this PR, it has been challenging to keep the view logic for grouping entries by date DRY while still being able to pass view-specific options to the entries within each group. While a little "clever", I think this helper strikes a balance that gives us some flexibility to "specialize" the date groups based on where they're being rendered.
For example, in the global transactions view, we render a list that also has transfers grouped in a special way:
While account entry lists are simpler:
Modal forms helper
Did a consolidation and cleanup of some logic that was duplicated many times across the codebase for displaying modal forms. To add a pre-styled modal form with a title, simply use the
modal_form_wrapperhelper:@@ -0,0 +1,5 @@class AddCurrencyFieldToTrade < ActiveRecord::Migration[7.2]def changeadd_column :account_trades, :currency, :stringIntroduces a bit of denormalization here, but the alternative was quite a bit of added complexity and DB joins to read the
currencyvalue fromAccount::Entryfor the sake of "monetizing" thepriceattribute onAccount::TradeFor a mixed list of entries,
entries = [@trade, @transaction], we want to be able to do this in our views:This delegation helps us avoid: