diff --git a/src/create_lots_mvmts.rs b/src/create_lots_mvmts.rs index d837255..9c407ce 100644 --- a/src/create_lots_mvmts.rs +++ b/src/create_lots_mvmts.rs @@ -594,6 +594,20 @@ pub(crate) fn create_lots_and_movements( Ok(txns_map) } +/// Chooses the outgoing `ActionRecord`. Gets a `Vec` of its `Movement`s. Chooses its +/// first/earliest `Movement`. Gets that `Movement`'s `ActionRecord`. Gets that +/// `ActionRecord`'s `Account`. Gets the first `Lot` from that `Account`'s +/// `list_of_lots`. Get the `Movement`s from that `Lot`. Takes the first `Movement` +/// and gets that `Movement`'s `Transaction`. Gets base and quote keys from that.println! +/// +/// The rationale for this was to be able to determine whether this should be classifiable +/// as a Long or a Short. As it turns out, the two are basically indistinguishable and/or +/// interchangeable, so this `fn` should be simplified. +/// +/// Just kidding. You weren't paying attention, were you? This is a dual `ActionRecord` +/// `Flow` `Transaction`, meaning this is most likely recording a margin profit or a +/// margin loss. The `fn` was designed this was to definitely work for a margin profit, +/// but it might could use reworking to be generalized for margin profit or loss. fn get_base_and_quote_acct_for_dual_actionrecord_flow_tx( txn_num: u32, ar_map: &HashMap, @@ -606,7 +620,7 @@ fn get_base_and_quote_acct_for_dual_actionrecord_flow_tx( let og_flow_ar = ar_map.get(txn.action_record_idx_vec.first().unwrap()).unwrap(); // println!("Acct: {}, Amount: {}, Tx: {}, ar: {}", // outgoing_flow_ar.account_key, outgoing_flow_ar.amount, outgoing_flow_ar.tx_key, outgoing_flow_ar.self_ar_key); - let og_ar_mvmts_list = &og_flow_ar.get_mvmts_in_ar(acct_map, txns_map); // TODO: ... in margin profit, this just takes a list of one mvmt + let og_ar_mvmts_list = &og_flow_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); // TODO: ... in margin profit, this just takes a list of one mvmt let og_ar_list_first_mvmt = &og_ar_mvmts_list.first().unwrap(); // TODO: then this takes the one mvmt let og_ar_list_first_mvmt_ar = ar_map.get(&og_ar_list_first_mvmt.action_record_key).unwrap(); let og_ar_list_first_mvmt_ar_acct = acct_map.get(&og_ar_list_first_mvmt_ar.account_key).unwrap(); @@ -828,12 +842,12 @@ fn process_multiple_incoming_lots_and_mvmts( let mut all_but_last_incoming_mvmt_amt = d128!(0.0); let mut all_but_last_incoming_mvmt_ratio = d128!(0.0); // println!("Txn date: {}. Outgoing mvmts: {}, Outgoing amount: {}", txn.date, outgoing_ar.movements.borrow().len(), outgoing_ar.amount); - let list_of_mvmts_of_outgoing_ar = outgoing_ar.get_mvmts_in_ar(acct_map, txns_map); + let list_of_mvmts_of_outgoing_ar = outgoing_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); let final_mvmt = list_of_mvmts_of_outgoing_ar.last().unwrap(); // First iteration, for all but final movement for outgoing_mvmt in list_of_mvmts_of_outgoing_ar .iter() - .take(outgoing_ar.get_mvmts_in_ar(acct_map, txns_map).len() - 1) { + .take(outgoing_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map).len() - 1) { let ratio_of_outgoing_mvmt_to_total_ar = outgoing_mvmt.amount / outgoing_ar.amount; // Negative divided by negative is positive // println!("Ratio of outgoing amt to total actionrecord amt: {:.8}", ratio_of_outgoing_to_total_ar); let tentative_incoming_amt = ratio_of_outgoing_mvmt_to_total_ar * incoming_ar.amount; diff --git a/src/import_cost_proceeds_etc.rs b/src/import_cost_proceeds_etc.rs index 8256e25..4ba7266 100644 --- a/src/import_cost_proceeds_etc.rs +++ b/src/import_cost_proceeds_etc.rs @@ -32,7 +32,7 @@ pub(crate) fn add_cost_basis_to_movements( let ar = ars.get(ar_num).unwrap(); let acct = acct_map.get(&ar.account_key).unwrap(); let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap(); - let movements = ar.get_mvmts_in_ar(acct_map, txns_map); + let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); for mvmt in movements.iter() { @@ -168,7 +168,7 @@ pub(crate) fn add_cost_basis_to_movements( assert_eq!(other_ar_borrowed.direction(), Polarity::Outgoing); let mut basis = d128!(0); - let movements = other_ar_borrowed.get_mvmts_in_ar(acct_map, txns_map); + let movements = other_ar_borrowed.get_mvmts_in_ar_in_date_order(acct_map, txns_map); for mvmt in movements.iter() { basis += mvmt.cost_basis.get(); @@ -197,7 +197,7 @@ pub(crate) fn add_proceeds_to_movements( for ar_num in txn.action_record_idx_vec.iter() { let ar = ars.get(ar_num).unwrap(); - let movements = ar.get_mvmts_in_ar(acct_map, txns_map); + let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); for mvmt in movements.iter() { @@ -289,7 +289,7 @@ fn update_current_txn_for_prior_likekind_treatment( let ar = ars.get(ar_num).unwrap(); let acct = acct_map.get(&ar.account_key).unwrap(); let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap(); - let movements = ar.get_mvmts_in_ar(acct_map, txns_map); + let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); for mvmt in movements.iter() { @@ -386,7 +386,7 @@ fn perform_likekind_treatment_on_txn( for ar_num in txn.action_record_idx_vec.iter() { let ar = ars.get(ar_num).unwrap(); - let movements = ar.get_mvmts_in_ar(acct_map, txns_map); + let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); for mvmt in movements.iter() { @@ -431,7 +431,7 @@ fn perform_likekind_treatment_on_txn( for ar_num in txn.action_record_idx_vec.iter() { let ar = ars.get(ar_num).unwrap(); - let movements = ar.get_mvmts_in_ar(acct_map, txns_map); + let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); let polarity = ar.direction(); diff --git a/src/tests/test.rs b/src/tests/test.rs index ced1f2f..d466cc8 100644 --- a/src/tests/test.rs +++ b/src/tests/test.rs @@ -67,7 +67,7 @@ fn compare_movements_across_implementations( + " with amount: " + &ar.amount.to_string() + &"\n".to_string() ); - let mvmts = ar.get_mvmts_in_ar(&account_map, &transactions_map); + let mvmts = ar.get_mvmts_in_ar_in_date_order(&account_map, &transactions_map); let mut amts = d128!(0); for mvmt in mvmts { amts += mvmt.amount; @@ -156,7 +156,7 @@ pub fn test_action_records_amts_vs_mvmt_amts( for ar_num in &txn.action_record_idx_vec { let ar = action_records_map.get(&(ar_num)).unwrap(); - let mvmts = ar.get_mvmts_in_ar(&account_map, &transactions_map); + let mvmts = ar.get_mvmts_in_ar_in_date_order(&account_map, &transactions_map); for mvmt in mvmts { mvmt_amt_ar += mvmt.amount } diff --git a/src/transaction.rs b/src/transaction.rs index 5d323f9..ce823b9 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -164,7 +164,7 @@ impl Transaction { if !raw_acct.is_home_currency(user_home_currency) & !raw_acct.is_margin { - let movements = ar.get_mvmts_in_ar(acct_map, txns_map); + let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); match self.transaction_type(ars, raw_acct_map, acct_map)? { TxType::Exchange => { @@ -292,31 +292,47 @@ impl ActionRecord { // raw_acct.ticker.contains('_') // } - pub fn get_mvmts_in_ar( + /// Iterates through every `Lot` in the `list_of_lots` of the `ActionRecord`'s `Account` + /// until it finds all the `Movements` - cloning each along the way - and then returns + /// a `Vec` of `Rc`. + /// + /// Note that a `Lot`'s `date`, and generally its `basis_date` too, will increase + /// chronologically along with the `Lot`'s `lot_num` which is just it's `index` in the + /// `list_of_lots` plus `1`. Exceptions will occur, because `Lot`s are permanently + /// ordered by their creation date (`date`), so later `Lot`s may have earlier `basis_date`s + /// by virtue of them being the result of a `ToSelf` type `Transaction` that transferred + /// old "coins." + pub fn get_mvmts_in_ar_in_date_order( &self, acct_map: &HashMap, txns_map: &HashMap, ) -> Vec> { - // let polarity = Self::direction(self); let txn = txns_map.get(&self.tx_key).unwrap(); let mut movements_in_ar = [].to_vec(); let acct = acct_map.get(&self.account_key).unwrap(); + let target = self.amount; + let mut measure = d128!(0); + for lot in acct.list_of_lots.borrow().iter() { + for mvmt in lot.movements.borrow().iter() { + if (mvmt.date) <= txn.date { + if mvmt.action_record_key == self.self_ar_key { - // if polarity == Polarity::Incoming{ - // movements_in_ar.push(mvmt.clone()) - // } else { - movements_in_ar.insert(0, mvmt.clone()) - // } - // ^^ leaving that ugliness for this commit on purpose + + measure += mvmt.amount; + + movements_in_ar.push(mvmt.clone()); + + if measure == target { return movements_in_ar } } } } } + println!("ERROR: This should never print."); movements_in_ar } } @@ -331,11 +347,11 @@ pub enum TxType { impl fmt::Display for TxType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - TxType::Exchange => write!(f, "Exchange"), - TxType::ToSelf => write!(f, "ToSelf"), - TxType::Flow => write!(f, "Flow"), - } + match *self { + TxType::Exchange => write!(f, "Exchange"), + TxType::ToSelf => write!(f, "ToSelf"), + TxType::Flow => write!(f, "Flow"), + } } }