adding and listing transactions baby
This commit is contained in:
parent
4c4967d50a
commit
d512dedd21
@ -1,4 +1,5 @@
|
|||||||
use crate::entities::*;
|
use crate::entities::*;
|
||||||
|
use chrono::DateTime;
|
||||||
use sqlite::{Connection, State};
|
use sqlite::{Connection, State};
|
||||||
|
|
||||||
pub fn setup(con: &Connection) {
|
pub fn setup(con: &Connection) {
|
||||||
@ -20,7 +21,7 @@ pub fn setup(con: &Connection) {
|
|||||||
account_id INTEGER NOT NULL,
|
account_id INTEGER NOT NULL,
|
||||||
type_id INTEGER NOT NULL,
|
type_id INTEGER NOT NULL,
|
||||||
amount FLOAT NOT NULL,
|
amount FLOAT NOT NULL,
|
||||||
date DATE NOT NULL,
|
date INTEGER NOT NULL,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
FOREIGN KEY(account_id) REFERENCES Accounts(id),
|
FOREIGN KEY(account_id) REFERENCES Accounts(id),
|
||||||
FOREIGN KEY(type_id) REFERENCES TransactionTypes(id)
|
FOREIGN KEY(type_id) REFERENCES TransactionTypes(id)
|
||||||
@ -150,3 +151,106 @@ pub fn get_transaction_types(con: &Connection) -> Vec<TransactionType> {
|
|||||||
|
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction {
|
||||||
|
let query;
|
||||||
|
if tr.get_id() == 0 {
|
||||||
|
query = "INSERT INTO Transactions
|
||||||
|
(account_id, type_id, amount, date, description)
|
||||||
|
VALUES (?, ?, ?, ?, ?)
|
||||||
|
RETURNING id;";
|
||||||
|
} else {
|
||||||
|
query = "UPDATE Transactions
|
||||||
|
SET account_id = ?, type_id = ?, amount = ?, date = ?, description = ?
|
||||||
|
WHERE id = ? RETURNING id;";
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut statement = con.prepare(query).unwrap();
|
||||||
|
statement.bind((1, tr.get_account().get_id())).unwrap();
|
||||||
|
statement.bind((2, tr.get_type().get_id())).unwrap();
|
||||||
|
statement.bind((3, tr.get_amount())).unwrap();
|
||||||
|
statement.bind((4, tr.get_date().timestamp())).unwrap();
|
||||||
|
statement.bind((5, &tr.get_desc() as &str)).unwrap();
|
||||||
|
|
||||||
|
if tr.get_id() != 0 {
|
||||||
|
statement.bind((6, tr.get_id())).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let id;
|
||||||
|
if let Ok(State::Row) = statement.next() {
|
||||||
|
id = statement.read::<i64, _>("id").unwrap();
|
||||||
|
} else {
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Transaction::new(
|
||||||
|
id,
|
||||||
|
tr.get_account().get_id(),
|
||||||
|
tr.get_amount(),
|
||||||
|
tr.get_date(),
|
||||||
|
tr.get_desc(),
|
||||||
|
tr.get_type().get_id(),
|
||||||
|
con,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_transaction(con: &Connection, id: i64) -> Transaction {
|
||||||
|
let query = "SELECT * FROM Transactions WHERE id = ?";
|
||||||
|
let mut statement = con.prepare(query).unwrap();
|
||||||
|
statement.bind((1, id)).unwrap();
|
||||||
|
|
||||||
|
if let Ok(State::Row) = statement.next() {
|
||||||
|
return Transaction::new(
|
||||||
|
statement.read::<i64, _>("id").unwrap(),
|
||||||
|
statement.read::<i64, _>("account_id").unwrap(),
|
||||||
|
statement.read::<f64, _>("amount").unwrap(),
|
||||||
|
DateTime::from_timestamp(statement.read::<i64, _>("date").unwrap(), 0).unwrap(),
|
||||||
|
statement.read::<String, _>("description").unwrap(),
|
||||||
|
statement.read::<i64, _>("type_id").unwrap(),
|
||||||
|
con,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Transaction::new_empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_account_transactions(con: &Connection, ac_id: i64) -> Vec<Transaction> {
|
||||||
|
let query = "SELECT * FROM Transactions WHERE account_id = ?";
|
||||||
|
let mut statement = con.prepare(query).unwrap();
|
||||||
|
statement.bind((1, ac_id)).unwrap();
|
||||||
|
let mut vec = Vec::<Transaction>::new();
|
||||||
|
|
||||||
|
while let Ok(State::Row) = statement.next() {
|
||||||
|
vec.push(Transaction::new(
|
||||||
|
statement.read::<i64, _>("id").unwrap(),
|
||||||
|
statement.read::<i64, _>("account_id").unwrap(),
|
||||||
|
statement.read::<f64, _>("amount").unwrap(),
|
||||||
|
DateTime::from_timestamp(statement.read::<i64, _>("date").unwrap(), 0).unwrap(),
|
||||||
|
statement.read::<String, _>("description").unwrap(),
|
||||||
|
statement.read::<i64, _>("type_id").unwrap(),
|
||||||
|
con,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_transactions(con: &Connection) -> Vec<Transaction> {
|
||||||
|
let query = "SELECT * FROM TransactionTypes";
|
||||||
|
let mut statement = con.prepare(query).unwrap();
|
||||||
|
let mut vec = Vec::<Transaction>::new();
|
||||||
|
|
||||||
|
while let Ok(State::Row) = statement.next() {
|
||||||
|
vec.push(Transaction::new(
|
||||||
|
statement.read::<i64, _>("id").unwrap(),
|
||||||
|
statement.read::<i64, _>("account_id").unwrap(),
|
||||||
|
statement.read::<f64, _>("amount").unwrap(),
|
||||||
|
DateTime::from_timestamp(statement.read::<i64, _>("date").unwrap(), 0).unwrap(),
|
||||||
|
statement.read::<String, _>("description").unwrap(),
|
||||||
|
statement.read::<i64, _>("type_id").unwrap(),
|
||||||
|
con,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|||||||
@ -36,6 +36,19 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_empty() -> Self {
|
||||||
|
Transaction {
|
||||||
|
id: 0,
|
||||||
|
account_id: 0,
|
||||||
|
amount: 0.0,
|
||||||
|
date: DateTime::from_timestamp(0, 0).unwrap(),
|
||||||
|
description: "".to_string(),
|
||||||
|
type_id: 0,
|
||||||
|
account: Account::new(0, "".to_string(), super::AccountType::Cash),
|
||||||
|
tr_type: TransactionType::new(0, "".to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_id(&self) -> i64 {
|
pub fn get_id(&self) -> i64 {
|
||||||
return self.id;
|
return self.id;
|
||||||
}
|
}
|
||||||
|
|||||||
69
src/main.rs
69
src/main.rs
@ -1,9 +1,10 @@
|
|||||||
mod data_layer;
|
mod data_layer;
|
||||||
mod entities;
|
mod entities;
|
||||||
|
use chrono::DateTime;
|
||||||
use sqlite::Connection;
|
use sqlite::Connection;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use crate::entities::{Account, TransactionType};
|
use crate::entities::{Account, Transaction, TransactionType};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let connection = match Connection::open("ft_rs.db") {
|
let connection = match Connection::open("ft_rs.db") {
|
||||||
@ -22,6 +23,8 @@ fn main() {
|
|||||||
println!("2. Add an account");
|
println!("2. Add an account");
|
||||||
println!("3. List transaction types");
|
println!("3. List transaction types");
|
||||||
println!("4. Add a transaction type");
|
println!("4. Add a transaction type");
|
||||||
|
println!("5. List transactions");
|
||||||
|
println!("6. Add a transaction");
|
||||||
println!("0. Exit");
|
println!("0. Exit");
|
||||||
|
|
||||||
let mut choice = String::new();
|
let mut choice = String::new();
|
||||||
@ -64,12 +67,74 @@ fn main() {
|
|||||||
let tr_type = TransactionType::new(0, desc.to_string());
|
let tr_type = TransactionType::new(0, desc.to_string());
|
||||||
data_layer::upsert_transaction_type(&connection, tr_type);
|
data_layer::upsert_transaction_type(&connection, tr_type);
|
||||||
}
|
}
|
||||||
|
"5" => {
|
||||||
|
println!("Please enter the account id:");
|
||||||
|
let mut ac_id_str = String::new();
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut ac_id_str)
|
||||||
|
.expect("Failed to read line");
|
||||||
|
ac_id_str = ac_id_str.trim().to_string();
|
||||||
|
let ac_id = ac_id_str.parse::<i64>().unwrap();
|
||||||
|
let trx: Vec<entities::Transaction> =
|
||||||
|
data_layer::get_account_transactions(&connection, ac_id);
|
||||||
|
// .sort_by(|a, b| b.get_date().cmp(&a.get_date()))
|
||||||
|
// .try_into()
|
||||||
|
// .unwrap();
|
||||||
|
for t in trx.iter() {
|
||||||
|
println!(
|
||||||
|
"Date: {}, Type: {}, Description: {}, Amount: {}$",
|
||||||
|
t.get_date(),
|
||||||
|
t.get_type().get_description(),
|
||||||
|
t.get_desc(),
|
||||||
|
t.get_amount()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"6" => {
|
||||||
|
println!("Please enter the account id:");
|
||||||
|
let mut ac_id_str = String::new();
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut ac_id_str)
|
||||||
|
.expect("Failed to read line");
|
||||||
|
ac_id_str = ac_id_str.trim().to_string();
|
||||||
|
let ac_id = ac_id_str.parse::<i64>().unwrap();
|
||||||
|
println!("Please enter the transaction type id:");
|
||||||
|
let mut tr_type_id_str = String::new();
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut tr_type_id_str)
|
||||||
|
.expect("Failed to read line");
|
||||||
|
tr_type_id_str = tr_type_id_str.trim().to_string();
|
||||||
|
let type_id = tr_type_id_str.parse::<i64>().unwrap();
|
||||||
|
println!("Please enter the amount:");
|
||||||
|
let mut amnt_str = String::new();
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut amnt_str)
|
||||||
|
.expect("Failed to read line");
|
||||||
|
amnt_str = amnt_str.trim().to_string();
|
||||||
|
let amount = amnt_str.parse::<f64>().unwrap();
|
||||||
|
println!("Please enter the description:");
|
||||||
|
let mut desc = String::new();
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut desc)
|
||||||
|
.expect("Failed to read line");
|
||||||
|
desc = desc.trim().to_string();
|
||||||
|
let tr = Transaction::new(
|
||||||
|
0,
|
||||||
|
ac_id,
|
||||||
|
amount,
|
||||||
|
chrono::offset::Utc::now(),
|
||||||
|
desc,
|
||||||
|
type_id,
|
||||||
|
&connection,
|
||||||
|
);
|
||||||
|
data_layer::upsert_transaction(&connection, tr);
|
||||||
|
}
|
||||||
"0" => {
|
"0" => {
|
||||||
println!("Exiting...");
|
println!("Exiting...");
|
||||||
break; // Exit the loop
|
break; // Exit the loop
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("Invalid choice. Please enter 1, 2, or 3.");
|
println!("Invalid choice.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user