1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::data_handler::DataError;
use crate::transaction::{Transaction, TransactionType};
use crate::helpers::*;
pub struct RawTransaction {
pub id: Option<i64>,
pub trans_type: String,
pub asset: Option<i64>,
pub cash_amount: f64,
pub cash_currency: String,
pub cash_date: String,
pub related_trans: Option<i64>,
pub position: Option<f64>,
pub note: Option<String>,
}
const CASH: &str = "c";
const ASSET: &str = "a";
const DIVIDEND: &str = "d";
const INTEREST: &str = "i";
const TAX: &str = "t";
const FEE: &str = "f";
impl RawTransaction {
pub fn to_transaction(&self) -> Result<Transaction, DataError> {
let id = i64_to_usize(self.id);
let cash_flow = raw_to_cash_flow(self.cash_amount, &self.cash_currency, &self.cash_date)?;
let note = self.note.clone();
let transaction_type = match self.trans_type.as_str() {
CASH => TransactionType::Cash,
ASSET => TransactionType::Asset {
asset_id: self.asset.ok_or(DataError::InvalidTransaction(
"missing asset id".to_string(),
))? as usize,
position: self.position.ok_or(DataError::InvalidTransaction(
"missing position value".to_string(),
))?,
},
DIVIDEND => TransactionType::Dividend {
asset_id: self.asset.ok_or(DataError::InvalidTransaction(
"missing asset id".to_string(),
))? as usize,
},
INTEREST => TransactionType::Interest {
asset_id: self.asset.ok_or(DataError::InvalidTransaction(
"missing asset id".to_string(),
))? as usize,
},
TAX => TransactionType::Tax {
transaction_ref: i64_to_usize(self.id),
},
FEE => TransactionType::Fee {
transaction_ref: i64_to_usize(self.id),
},
unknown => {
return Err(DataError::InvalidTransaction(unknown.to_string()));
}
};
Ok(Transaction {
id,
transaction_type,
cash_flow,
note,
})
}
pub fn from_transaction(transaction: &Transaction) -> RawTransaction {
let id = usize_to_i64(transaction.id);
let cash_amount = transaction.cash_flow.amount.amount;
let cash_currency = transaction.cash_flow.amount.currency.to_string();
let cash_date = transaction.cash_flow.date.format("%Y-%m-%d").to_string();
let note = transaction.note.clone();
let mut raw_transaction = RawTransaction {
id,
trans_type: String::new(),
asset: None,
cash_amount,
cash_currency,
cash_date,
related_trans: None,
position: None,
note,
};
match transaction.transaction_type {
TransactionType::Cash => raw_transaction.trans_type = CASH.to_string(),
TransactionType::Asset { asset_id, position } => {
raw_transaction.trans_type = ASSET.to_string();
raw_transaction.asset = Some(asset_id as i64);
raw_transaction.position = Some(position);
}
TransactionType::Dividend { asset_id } => {
raw_transaction.trans_type = DIVIDEND.to_string();
raw_transaction.asset = Some(asset_id as i64);
}
TransactionType::Interest { asset_id } => {
raw_transaction.trans_type = INTEREST.to_string();
raw_transaction.asset = Some(asset_id as i64);
}
TransactionType::Tax { transaction_ref } => {
raw_transaction.trans_type = TAX.to_string();
raw_transaction.related_trans = usize_to_i64(transaction_ref);
}
TransactionType::Fee { transaction_ref } => {
raw_transaction.trans_type = FEE.to_string();
raw_transaction.related_trans = usize_to_i64(transaction_ref);
}
};
raw_transaction
}
}