Fixed ToSelf txn cost basis bug. Resolves #52. Point release version bump, at a minimum, is warranted.
This commit is contained in:
parent
60f6de11a3
commit
80af666386
|
@ -606,7 +606,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();
|
let og_flow_ar = ar_map.get(txn.action_record_idx_vec.first().unwrap()).unwrap();
|
||||||
|
|
||||||
let og_ar_mvmts_list = &og_flow_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let og_ar_mvmts_list = &og_flow_ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
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 = &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 = 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();
|
let og_ar_list_first_mvmt_ar_acct = acct_map.get(&og_ar_list_first_mvmt_ar.account_key).unwrap();
|
||||||
|
@ -828,12 +828,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_amt = d128!(0.0);
|
||||||
let mut all_but_last_incoming_mvmt_ratio = 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);
|
// 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_in_date_order(acct_map, txns_map);
|
let list_of_mvmts_of_outgoing_ar = outgoing_ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
let final_mvmt = list_of_mvmts_of_outgoing_ar.last().unwrap();
|
let final_mvmt = list_of_mvmts_of_outgoing_ar.last().unwrap();
|
||||||
// First iteration, for all but final movement
|
// First iteration, for all but final movement
|
||||||
for outgoing_mvmt in list_of_mvmts_of_outgoing_ar
|
for outgoing_mvmt in list_of_mvmts_of_outgoing_ar
|
||||||
.iter()
|
.iter()
|
||||||
.take(outgoing_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map).len() - 1) {
|
.take(outgoing_ar.get_mvmts_in_ar_in_lot_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
|
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);
|
// 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;
|
let tentative_incoming_amt = ratio_of_outgoing_mvmt_to_total_ar * incoming_ar.amount;
|
||||||
|
|
|
@ -31,16 +31,17 @@ pub(crate) fn add_cost_basis_to_movements(
|
||||||
let ar = ars.get(ar_num).unwrap();
|
let ar = ars.get(ar_num).unwrap();
|
||||||
let acct = acct_map.get(&ar.account_key).unwrap();
|
let acct = acct_map.get(&ar.account_key).unwrap();
|
||||||
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
|
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
|
||||||
let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let movements = ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
|
|
||||||
for mvmt in movements.iter() {
|
for (idx, mvmt) in movements.iter().enumerate() {
|
||||||
|
|
||||||
let polarity = ar.direction();
|
let polarity = ar.direction();
|
||||||
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map)?;
|
let tx_type = txn.transaction_type(ars, raw_acct_map, acct_map)?;
|
||||||
let is_home_curr = raw_acct.is_home_currency(&settings.home_currency);
|
let is_home_curr = raw_acct.is_home_currency(&settings.home_currency);
|
||||||
let mvmt_copy = mvmt.clone();
|
let mvmt_copy = mvmt.clone();
|
||||||
let borrowed_mvmt = mvmt_copy.clone();
|
let borrowed_mvmt = mvmt_copy.clone();
|
||||||
// println!("Txn: {} on {} of type: {:?}",txn.tx_number,txn.date, txn.transaction_type());
|
// println!("Txn: {} on {} of type: {:?}",
|
||||||
|
// txn.tx_number,txn.date, txn.transaction_type(ars, raw_acct_map, acct_map));
|
||||||
|
|
||||||
if !raw_acct.is_margin {
|
if !raw_acct.is_margin {
|
||||||
|
|
||||||
|
@ -113,16 +114,17 @@ pub(crate) fn add_cost_basis_to_movements(
|
||||||
|
|
||||||
TxType::ToSelf => {
|
TxType::ToSelf => {
|
||||||
|
|
||||||
let ratio_of_amt_to_incoming_mvmts_in_a_r =
|
let cb_vec_outgoing_ar = retrieve_cb_vec_from_corresponding_outgoing_toself(
|
||||||
borrowed_mvmt.ratio_of_amt_to_incoming_mvmts_in_a_r;
|
|
||||||
let cb_outgoing_ar = retrieve_cost_basis_from_corresponding_outgoing_toself(
|
|
||||||
txn_num,
|
txn_num,
|
||||||
&ars,
|
&ars,
|
||||||
txns_map,
|
txns_map,
|
||||||
acct_map
|
acct_map
|
||||||
);
|
);
|
||||||
|
|
||||||
let unrounded_basis = cb_outgoing_ar * ratio_of_amt_to_incoming_mvmts_in_a_r;
|
assert!(idx <= cb_vec_outgoing_ar.len(),
|
||||||
|
"ToSelf txn had different # of in- and out- mvmts (more outs than ins).");
|
||||||
|
|
||||||
|
let unrounded_basis = cb_vec_outgoing_ar[idx];
|
||||||
let rounded_basis = round_d128_1e2(&unrounded_basis);
|
let rounded_basis = round_d128_1e2(&unrounded_basis);
|
||||||
|
|
||||||
mvmt.cost_basis.set(-rounded_basis);
|
mvmt.cost_basis.set(-rounded_basis);
|
||||||
|
@ -154,26 +156,27 @@ pub(crate) fn add_cost_basis_to_movements(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn retrieve_cost_basis_from_corresponding_outgoing_toself(
|
|
||||||
|
fn retrieve_cb_vec_from_corresponding_outgoing_toself(
|
||||||
txn_num: u32,
|
txn_num: u32,
|
||||||
ars: &HashMap<u32, ActionRecord>,
|
ars: &HashMap<u32, ActionRecord>,
|
||||||
txns_map: &HashMap<u32, Transaction>,
|
txns_map: &HashMap<u32, Transaction>,
|
||||||
acct_map: &HashMap<u16, Account>,
|
acct_map: &HashMap<u16, Account>,
|
||||||
) -> d128 {
|
) -> Vec<d128> {
|
||||||
|
|
||||||
let txn = txns_map.get(&txn_num).unwrap();
|
let txn = txns_map.get(&txn_num).unwrap();
|
||||||
let other_ar_borrowed = &ars.get(&txn.action_record_idx_vec[0]).unwrap();
|
let other_ar_borrowed = &ars.get(&txn.action_record_idx_vec[0]).unwrap();
|
||||||
|
|
||||||
assert_eq!(other_ar_borrowed.direction(), Polarity::Outgoing);
|
assert_eq!(other_ar_borrowed.direction(), Polarity::Outgoing);
|
||||||
|
|
||||||
let mut basis = d128!(0);
|
let movements = other_ar_borrowed.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
let movements = other_ar_borrowed.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
for mvmt in movements.iter() {
|
for mvmt in movements.iter() {
|
||||||
basis += mvmt.cost_basis.get();
|
vec.push(mvmt.cost_basis.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
basis
|
vec
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -198,7 +201,7 @@ pub(crate) fn add_proceeds_to_movements(
|
||||||
let ar = ars.get(ar_num).unwrap();
|
let ar = ars.get(ar_num).unwrap();
|
||||||
let acct = acct_map.get(&ar.account_key).unwrap();
|
let acct = acct_map.get(&ar.account_key).unwrap();
|
||||||
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
|
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
|
||||||
let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let movements = ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
|
|
||||||
if !raw_acct.is_margin {
|
if !raw_acct.is_margin {
|
||||||
|
|
||||||
|
@ -303,7 +306,7 @@ fn update_current_txn_for_prior_likekind_treatment(
|
||||||
let ar = ars.get(ar_num).unwrap();
|
let ar = ars.get(ar_num).unwrap();
|
||||||
let acct = acct_map.get(&ar.account_key).unwrap();
|
let acct = acct_map.get(&ar.account_key).unwrap();
|
||||||
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
|
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
|
||||||
let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let movements = ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
|
|
||||||
for mvmt in movements.iter() {
|
for mvmt in movements.iter() {
|
||||||
|
|
||||||
|
@ -400,7 +403,7 @@ fn perform_likekind_treatment_on_txn(
|
||||||
for ar_num in txn.action_record_idx_vec.iter() {
|
for ar_num in txn.action_record_idx_vec.iter() {
|
||||||
|
|
||||||
let ar = ars.get(ar_num).unwrap();
|
let ar = ars.get(ar_num).unwrap();
|
||||||
let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let movements = ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
|
|
||||||
for mvmt in movements.iter() {
|
for mvmt in movements.iter() {
|
||||||
|
|
||||||
|
@ -445,7 +448,7 @@ fn perform_likekind_treatment_on_txn(
|
||||||
for ar_num in txn.action_record_idx_vec.iter() {
|
for ar_num in txn.action_record_idx_vec.iter() {
|
||||||
|
|
||||||
let ar = ars.get(ar_num).unwrap();
|
let ar = ars.get(ar_num).unwrap();
|
||||||
let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let movements = ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
|
|
||||||
let polarity = ar.direction();
|
let polarity = ar.direction();
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ impl Transaction {
|
||||||
|
|
||||||
if !raw_acct.is_home_currency(user_home_currency) & !raw_acct.is_margin {
|
if !raw_acct.is_home_currency(user_home_currency) & !raw_acct.is_margin {
|
||||||
|
|
||||||
let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
|
let movements = ar.get_mvmts_in_ar_in_lot_date_order(acct_map, txns_map);
|
||||||
|
|
||||||
match self.transaction_type(ars, raw_acct_map, acct_map)? {
|
match self.transaction_type(ars, raw_acct_map, acct_map)? {
|
||||||
TxType::Exchange => {
|
TxType::Exchange => {
|
||||||
|
@ -307,7 +307,7 @@ impl ActionRecord {
|
||||||
/// ordered by their creation date (`date`), so later `Lot`s may have earlier `basis_date`s
|
/// 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
|
/// by virtue of them being the result of a `ToSelf` type `Transaction` that transferred
|
||||||
/// old "coins."
|
/// old "coins."
|
||||||
pub fn get_mvmts_in_ar_in_date_order(
|
pub fn get_mvmts_in_ar_in_lot_date_order(
|
||||||
&self,
|
&self,
|
||||||
acct_map: &HashMap<u16, Account>,
|
acct_map: &HashMap<u16, Account>,
|
||||||
txns_map: &HashMap<u32, Transaction>,
|
txns_map: &HashMap<u32, Transaction>,
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn compare_movements_across_implementations(
|
||||||
+ " with amount: "
|
+ " with amount: "
|
||||||
+ &ar.amount.to_string() + &"\n".to_string()
|
+ &ar.amount.to_string() + &"\n".to_string()
|
||||||
);
|
);
|
||||||
let mvmts = ar.get_mvmts_in_ar_in_date_order(&account_map, &transactions_map);
|
let mvmts = ar.get_mvmts_in_ar_in_lot_date_order(&account_map, &transactions_map);
|
||||||
let mut amts = d128!(0);
|
let mut amts = d128!(0);
|
||||||
for mvmt in mvmts {
|
for mvmt in mvmts {
|
||||||
amts += mvmt.amount;
|
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 {
|
for ar_num in &txn.action_record_idx_vec {
|
||||||
|
|
||||||
let ar = action_records_map.get(&(ar_num)).unwrap();
|
let ar = action_records_map.get(&(ar_num)).unwrap();
|
||||||
let mvmts = ar.get_mvmts_in_ar_in_date_order(&account_map, &transactions_map);
|
let mvmts = ar.get_mvmts_in_ar_in_lot_date_order(&account_map, &transactions_map);
|
||||||
for mvmt in mvmts {
|
for mvmt in mvmts {
|
||||||
mvmt_amt_ar += mvmt.amount
|
mvmt_amt_ar += mvmt.amount
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue