travail sur add transaction
This commit is contained in:
90
src/app.rs
90
src/app.rs
@@ -1,3 +1,4 @@
|
|||||||
|
use chrono::{DateTime, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
|
||||||
use sqlite::Connection;
|
use sqlite::Connection;
|
||||||
|
|
||||||
use crate::{data_layer, entities::*, enums::*};
|
use crate::{data_layer, entities::*, enums::*};
|
||||||
@@ -9,6 +10,8 @@ pub struct App {
|
|||||||
pub trx_table: TrxTable,
|
pub trx_table: TrxTable,
|
||||||
pub new_account: Account,
|
pub new_account: Account,
|
||||||
pub new_transaction: Transaction,
|
pub new_transaction: Transaction,
|
||||||
|
pub selected_transaction_input: TransactionInput,
|
||||||
|
pub current_input: String,
|
||||||
pub connection: Connection,
|
pub connection: Connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,6 +34,8 @@ impl App {
|
|||||||
trx_table: TrxTable::new(),
|
trx_table: TrxTable::new(),
|
||||||
new_account: Account::new(0, String::new(), AccountType::Cash),
|
new_account: Account::new(0, String::new(), AccountType::Cash),
|
||||||
new_transaction: Transaction::new_empty(),
|
new_transaction: Transaction::new_empty(),
|
||||||
|
selected_transaction_input: TransactionInput::Type,
|
||||||
|
current_input: String::new(),
|
||||||
connection: con,
|
connection: con,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -71,4 +76,89 @@ impl App {
|
|||||||
self.trx_table.add_tr(tr);
|
self.trx_table.add_tr(tr);
|
||||||
self.new_transaction = Transaction::new_empty();
|
self.new_transaction = Transaction::new_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn next_tr_input(&mut self) {
|
||||||
|
match self.selected_transaction_input {
|
||||||
|
TransactionInput::Type => {
|
||||||
|
self.selected_transaction_input = TransactionInput::Amount;
|
||||||
|
self.new_transaction.set_type(
|
||||||
|
self.current_input
|
||||||
|
.parse::<i64>()
|
||||||
|
.expect("Failed to parse data"),
|
||||||
|
&self.connection,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
TransactionInput::Amount => {
|
||||||
|
self.selected_transaction_input = TransactionInput::Date;
|
||||||
|
self.new_transaction.set_amount(
|
||||||
|
self.current_input
|
||||||
|
.parse::<f64>()
|
||||||
|
.expect("Failed to parse data"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
TransactionInput::Date => {
|
||||||
|
self.selected_transaction_input = TransactionInput::Description;
|
||||||
|
let date = NaiveDate::parse_from_str(&self.current_input, "%Y-%m-%d")
|
||||||
|
.expect("Faile to parse data");
|
||||||
|
let time = NaiveTime::from_hms_opt(5, 0, 0).unwrap(); // to account for my local datetime
|
||||||
|
self.new_transaction
|
||||||
|
.set_date(Local.from_utc_datetime(&NaiveDateTime::new(date, time)));
|
||||||
|
}
|
||||||
|
TransactionInput::Description => {
|
||||||
|
self.new_transaction.set_desc(self.current_input.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.set_current_input();
|
||||||
|
}
|
||||||
|
pub fn previous_tr_input(&mut self) {
|
||||||
|
match self.selected_transaction_input {
|
||||||
|
TransactionInput::Type => {
|
||||||
|
self.new_transaction.set_type(
|
||||||
|
self.current_input
|
||||||
|
.parse::<i64>()
|
||||||
|
.expect("Failed to parse data"),
|
||||||
|
&self.connection,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
TransactionInput::Amount => {
|
||||||
|
self.selected_transaction_input = TransactionInput::Type;
|
||||||
|
self.new_transaction.set_amount(
|
||||||
|
self.current_input
|
||||||
|
.parse::<f64>()
|
||||||
|
.expect("Failed to parse data"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
TransactionInput::Date => {
|
||||||
|
self.selected_transaction_input = TransactionInput::Amount;
|
||||||
|
let date = NaiveDate::parse_from_str(&self.current_input, "%Y-%m-%d")
|
||||||
|
.expect("Faile to parse data");
|
||||||
|
let time = NaiveTime::from_hms_opt(5, 0, 0).unwrap(); // to account for my local datetime
|
||||||
|
self.new_transaction
|
||||||
|
.set_date(Local.from_utc_datetime(&NaiveDateTime::new(date, time)));
|
||||||
|
}
|
||||||
|
TransactionInput::Description => {
|
||||||
|
self.selected_transaction_input = TransactionInput::Date;
|
||||||
|
self.new_transaction.set_desc(self.current_input.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.set_current_input();
|
||||||
|
}
|
||||||
|
fn set_current_input(&mut self) {
|
||||||
|
match self.selected_transaction_input {
|
||||||
|
TransactionInput::Type => {
|
||||||
|
self.current_input = self.new_transaction.get_type().get_id().to_string()
|
||||||
|
}
|
||||||
|
TransactionInput::Amount => {
|
||||||
|
self.current_input = self.new_transaction.get_amount().to_string()
|
||||||
|
}
|
||||||
|
TransactionInput::Date => {
|
||||||
|
self.current_input = self
|
||||||
|
.new_transaction
|
||||||
|
.get_date()
|
||||||
|
.format("%Y-%m-%d")
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
TransactionInput::Description => self.current_input = self.new_transaction.get_desc(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut statement = con.prepare(query).unwrap();
|
let mut statement = con.prepare(query).unwrap();
|
||||||
statement.bind((1, tr.get_account().get_id())).unwrap();
|
statement.bind((1, tr.get_account_id())).unwrap();
|
||||||
statement.bind((2, tr.get_type().get_id())).unwrap();
|
statement.bind((2, tr.get_type().get_id())).unwrap();
|
||||||
statement.bind((3, tr.get_amount())).unwrap();
|
statement.bind((3, tr.get_amount())).unwrap();
|
||||||
statement.bind((4, tr.get_date().timestamp())).unwrap();
|
statement.bind((4, tr.get_date().timestamp())).unwrap();
|
||||||
@@ -206,7 +206,7 @@ pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction {
|
|||||||
|
|
||||||
return Transaction::new(
|
return Transaction::new(
|
||||||
id,
|
id,
|
||||||
tr.get_account().get_id(),
|
tr.get_account_id(),
|
||||||
tr.get_amount(),
|
tr.get_amount(),
|
||||||
tr.get_date_utc(),
|
tr.get_date_utc(),
|
||||||
tr.get_desc(),
|
tr.get_desc(),
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ pub struct Transaction {
|
|||||||
description: String,
|
description: String,
|
||||||
type_id: i64,
|
type_id: i64,
|
||||||
|
|
||||||
account: Account,
|
|
||||||
tr_type: TransactionType,
|
tr_type: TransactionType,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ impl Transaction {
|
|||||||
date: date,
|
date: date,
|
||||||
description: desc,
|
description: desc,
|
||||||
type_id: type_id,
|
type_id: type_id,
|
||||||
account: data_layer::get_account(con, ac_id),
|
|
||||||
tr_type: data_layer::get_transaction_type(con, type_id),
|
tr_type: data_layer::get_transaction_type(con, type_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +43,6 @@ impl Transaction {
|
|||||||
date: DateTime::from_timestamp(0, 0).unwrap(),
|
date: DateTime::from_timestamp(0, 0).unwrap(),
|
||||||
description: "".to_string(),
|
description: "".to_string(),
|
||||||
type_id: 0,
|
type_id: 0,
|
||||||
account: Account::new(0, "".to_string(), super::AccountType::Cash),
|
|
||||||
tr_type: TransactionType::new(0, "".to_string()),
|
tr_type: TransactionType::new(0, "".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,6 +54,9 @@ impl Transaction {
|
|||||||
pub fn get_amount(&self) -> f64 {
|
pub fn get_amount(&self) -> f64 {
|
||||||
return self.amount;
|
return self.amount;
|
||||||
}
|
}
|
||||||
|
pub fn set_amount(&mut self, amnt: f64) {
|
||||||
|
self.amount = amnt;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_date(&self) -> DateTime<Local> {
|
pub fn get_date(&self) -> DateTime<Local> {
|
||||||
return Local.from_utc_datetime(&self.date.naive_local());
|
return Local.from_utc_datetime(&self.date.naive_local());
|
||||||
@@ -64,18 +64,31 @@ impl Transaction {
|
|||||||
pub fn get_date_utc(&self) -> DateTime<Utc> {
|
pub fn get_date_utc(&self) -> DateTime<Utc> {
|
||||||
return self.date;
|
return self.date;
|
||||||
}
|
}
|
||||||
|
pub fn set_date(&mut self, date: DateTime<Local>) {
|
||||||
|
self.date = date.to_utc();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_desc(&self) -> String {
|
pub fn get_desc(&self) -> String {
|
||||||
return self.description.clone();
|
return self.description.clone();
|
||||||
}
|
}
|
||||||
|
pub fn set_desc(&mut self, desc: String) {
|
||||||
|
self.description = desc;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_account(&self) -> Account {
|
pub fn get_account_id(&self) -> i64 {
|
||||||
return self.account.clone();
|
return self.account_id;
|
||||||
|
}
|
||||||
|
pub fn set_account_id(&mut self, ac_id: i64) {
|
||||||
|
self.account_id = ac_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_type(&self) -> TransactionType {
|
pub fn get_type(&self) -> TransactionType {
|
||||||
return self.tr_type.clone();
|
return self.tr_type.clone();
|
||||||
}
|
}
|
||||||
|
pub fn set_type(&mut self, tr_id: i64, con: &Connection) {
|
||||||
|
self.type_id = tr_id;
|
||||||
|
self.tr_type = data_layer::get_transaction_type(con, tr_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -8,3 +8,11 @@ pub enum CurrentScreen {
|
|||||||
NewAccount,
|
NewAccount,
|
||||||
NewTransaction,
|
NewTransaction,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum TransactionInput {
|
||||||
|
Type,
|
||||||
|
Amount,
|
||||||
|
Date,
|
||||||
|
Description,
|
||||||
|
}
|
||||||
|
|||||||
16
src/main.rs
16
src/main.rs
@@ -4,6 +4,7 @@ mod entities;
|
|||||||
mod enums;
|
mod enums;
|
||||||
mod ui;
|
mod ui;
|
||||||
use crate::{app::App, enums::*, ui::ui};
|
use crate::{app::App, enums::*, ui::ui};
|
||||||
|
use chrono::Local;
|
||||||
use entities::{Account, AccountType, Transaction};
|
use entities::{Account, AccountType, Transaction};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
Terminal,
|
Terminal,
|
||||||
@@ -87,6 +88,9 @@ where
|
|||||||
}
|
}
|
||||||
CurrentWidget::TrxList => {
|
CurrentWidget::TrxList => {
|
||||||
app.current_screen = CurrentScreen::NewTransaction;
|
app.current_screen = CurrentScreen::NewTransaction;
|
||||||
|
app.new_transaction
|
||||||
|
.set_account_id(app.acc_list.get_selected_id());
|
||||||
|
app.new_transaction.set_date(Local::now());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
@@ -104,10 +108,22 @@ where
|
|||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
CurrentScreen::NewTransaction => match key.code {
|
CurrentScreen::NewTransaction => match key.code {
|
||||||
|
KeyCode::Down => {
|
||||||
|
app.next_tr_input();
|
||||||
|
}
|
||||||
|
KeyCode::Up => {
|
||||||
|
app.previous_tr_input();
|
||||||
|
}
|
||||||
KeyCode::Enter => {
|
KeyCode::Enter => {
|
||||||
app.save_new_tr();
|
app.save_new_tr();
|
||||||
app.current_screen = CurrentScreen::Main;
|
app.current_screen = CurrentScreen::Main;
|
||||||
}
|
}
|
||||||
|
KeyCode::Backspace => {
|
||||||
|
app.current_input.pop();
|
||||||
|
}
|
||||||
|
KeyCode::Char(value) => {
|
||||||
|
app.current_input.push(value);
|
||||||
|
}
|
||||||
KeyCode::Esc => {
|
KeyCode::Esc => {
|
||||||
app.current_screen = CurrentScreen::Main;
|
app.current_screen = CurrentScreen::Main;
|
||||||
app.new_transaction = Transaction::new_empty();
|
app.new_transaction = Transaction::new_empty();
|
||||||
|
|||||||
58
src/ui.rs
58
src/ui.rs
@@ -3,6 +3,7 @@ use crate::{
|
|||||||
entities::{Account, Transaction},
|
entities::{Account, Transaction},
|
||||||
enums::*,
|
enums::*,
|
||||||
};
|
};
|
||||||
|
use chrono::{Date, Local};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
Frame,
|
Frame,
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
@@ -120,6 +121,41 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
|
|||||||
|
|
||||||
let area = centered_rect(50, 40, frame.area());
|
let area = centered_rect(50, 40, frame.area());
|
||||||
frame.render_widget(popup, area);
|
frame.render_widget(popup, area);
|
||||||
|
|
||||||
|
let chunks = Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.margin(1)
|
||||||
|
.constraints([
|
||||||
|
Constraint::Length(3),
|
||||||
|
Constraint::Length(3),
|
||||||
|
Constraint::Length(3),
|
||||||
|
Constraint::Length(3),
|
||||||
|
])
|
||||||
|
.split(area);
|
||||||
|
|
||||||
|
let tr_type = Paragraph::new(tr_input_str(TransactionInput::Type, app))
|
||||||
|
.style(tr_input_style(TransactionInput::Type, app))
|
||||||
|
.block(Block::default().borders(Borders::BOTTOM).title("Type"));
|
||||||
|
frame.render_widget(tr_type, chunks[0]);
|
||||||
|
|
||||||
|
let amnt = Paragraph::new(tr_input_str(TransactionInput::Amount, app))
|
||||||
|
.style(tr_input_style(TransactionInput::Amount, app))
|
||||||
|
.block(Block::default().borders(Borders::BOTTOM).title("Amount"));
|
||||||
|
frame.render_widget(amnt, chunks[1]);
|
||||||
|
|
||||||
|
let date = Paragraph::new(tr_input_str(TransactionInput::Date, app))
|
||||||
|
.style(tr_input_style(TransactionInput::Date, app))
|
||||||
|
.block(Block::default().borders(Borders::BOTTOM).title("Date"));
|
||||||
|
frame.render_widget(date, chunks[2]);
|
||||||
|
|
||||||
|
let desc = Paragraph::new(tr_input_str(TransactionInput::Description, app))
|
||||||
|
.style(tr_input_style(TransactionInput::Description, app))
|
||||||
|
.block(
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::BOTTOM)
|
||||||
|
.title("Description"),
|
||||||
|
);
|
||||||
|
frame.render_widget(desc, chunks[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let CurrentScreen::Exiting = app.current_screen {
|
if let CurrentScreen::Exiting = app.current_screen {
|
||||||
@@ -162,6 +198,28 @@ fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
|
|||||||
.split(popup_layout[1])[1];
|
.split(popup_layout[1])[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tr_input_style(input: TransactionInput, app: &mut App) -> Style {
|
||||||
|
if app.selected_transaction_input == input {
|
||||||
|
return SELECTED_STYLE;
|
||||||
|
}
|
||||||
|
return Style::default();
|
||||||
|
}
|
||||||
|
fn tr_input_str(input: TransactionInput, app: &mut App) -> String {
|
||||||
|
if app.selected_transaction_input == input {
|
||||||
|
return app.current_input.clone();
|
||||||
|
}
|
||||||
|
match input {
|
||||||
|
TransactionInput::Type => app.new_transaction.get_type().get_id().to_string(),
|
||||||
|
TransactionInput::Amount => app.new_transaction.get_amount().to_string(),
|
||||||
|
TransactionInput::Date => app
|
||||||
|
.new_transaction
|
||||||
|
.get_date()
|
||||||
|
.format("%Y-%m-%d")
|
||||||
|
.to_string(),
|
||||||
|
TransactionInput::Description => app.new_transaction.get_desc(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&Account> for ListItem<'_> {
|
impl From<&Account> for ListItem<'_> {
|
||||||
fn from(value: &Account) -> Self {
|
fn from(value: &Account) -> Self {
|
||||||
let line = Line::styled(
|
let line = Line::styled(
|
||||||
|
|||||||
Reference in New Issue
Block a user