Skip to content

Commit

Permalink
feat(invoice): add customer cli command
Browse files Browse the repository at this point in the history
- Add list command
- Add delete command
- Add better select_customer_or_use_default function utils
  • Loading branch information
tibs245 committed May 20, 2024
1 parent 804ef12 commit 62ea50b
Show file tree
Hide file tree
Showing 21 changed files with 378 additions and 43 deletions.
6 changes: 6 additions & 0 deletions src/cli/cli_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ pub enum CliError {
#[error("Invoice ref {0} not found")]
InvoiceRefNotFound(String),

#[error("Customer {0} not found")]
CustomerNotFound(String),

#[error("Invoice to load invoice folder : {0}")]
UnableLoadInvoiceFolder(String),

#[error("Invoice to read customer file : {0}")]
UnableReadCustomerFile(String),

#[error("Not implemented yet")]
NotImplementedYet(),

Expand Down
2 changes: 1 addition & 1 deletion src/cli/create_customer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use log::trace;

use crate::cli::context_parameters::ContextParameters;
use crate::entities::customer::Customer;
use crate::file_manager::file_manager::{FileManager, Manager};
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn create_customer(context_parameters: ContextParameters) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Create customer");
Expand Down
10 changes: 6 additions & 4 deletions src/cli/create_invoice.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::entities::invoice::Invoice;
use crate::entities::product::Product;
use crate::file_manager::file_manager::{FileManager, Manager};
use std::error::Error;

use chrono::Local;
use dialoguer::{Confirm, FuzzySelect, Input};
use log::trace;
use std::error::Error;

use crate::cli::context_parameters::ContextParameters;
use crate::entities::invoice::Invoice;
use crate::entities::product::Product;
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn create_invoice(context_parameters: ContextParameters) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Create invoice");
Expand Down
29 changes: 29 additions & 0 deletions src/cli/delete_customer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::error::Error;

use chrono::Local;
use log::trace;

use crate::cli::context_parameters::ContextParameters;
use crate::cli::utils::select_customer_or_use_default::select_customer_or_use_default;
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn delete_customer(context_parameters: ContextParameters, customer_ref: &Option<String>) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Delete customer");

let file_manager = FileManager::new(
context_parameters.invoice_manager_path,
context_parameters.invoice_path,
context_parameters.customer_file_path,
context_parameters.config_file_path,
)?;

let customer_ref_selected = select_customer_or_use_default(&file_manager, customer_ref)?.0;

let result = file_manager.remove_customer(&customer_ref_selected);

if result.is_ok() {
println!("Customer {} deleted", customer_ref_selected);
}

result
}
2 changes: 1 addition & 1 deletion src/cli/delete_invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::cli::context_parameters::ContextParameters;
use crate::cli::utils::select_invoice::select_invoice;
use crate::entities;
use crate::entities::product::Product;
use crate::file_manager::file_manager::{FileManager, Manager};
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn delete_invoice(context_parameters: ContextParameters) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Cancel invoice");
Expand Down
30 changes: 30 additions & 0 deletions src/cli/get_customer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::error::Error;

use log::trace;

use crate::cli::cli_error::CliError;
use crate::cli::cli_error::CliError::InvoiceRefNotFound;
use crate::cli::context_parameters::ContextParameters;
use crate::cli::utils::select_customer::select_customer;
use crate::cli::utils::select_customer_or_use_default::select_customer_or_use_default;
use crate::entities::customer::Customer;
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn get_customer(context_parameters: ContextParameters, customer_ref: &Option<String>) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Get customer");

let file_manager = FileManager::new(
context_parameters.invoice_manager_path,
context_parameters.invoice_path,
context_parameters.customer_file_path,
context_parameters.config_file_path,
)?;

let customer_selected: Customer = select_customer_or_use_default(&file_manager, customer_ref)?.1;

println!("Your customer : {}\n", customer_selected.name);

println!("Address : \n{}\n{} {}", customer_selected.address, customer_selected.postal, customer_selected.city);

Ok(())
}
3 changes: 2 additions & 1 deletion src/cli/get_invoice.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::error::Error;

use log::trace;

use crate::cli::cli_error::CliError;
use crate::cli::cli_error::CliError::InvoiceRefNotFound;
use crate::cli::context_parameters::ContextParameters;
use crate::cli::utils::select_invoice::select_invoice;
use crate::entities::invoice::Invoice;
use crate::file_manager::file_manager::{FileManager, Manager};
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn get_invoice(context_parameters: ContextParameters, invoice_ref: &Option<String>) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Get invoice");
Expand Down
2 changes: 1 addition & 1 deletion src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use log::trace;
use crate::cli::context_parameters::ContextParameters;
use crate::entities::settings::{Enterprise, Settings};
use crate::entities::siren::Siren;
use crate::file_manager::file_manager::{FileManager, Manager};
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn initiate_invoice_directory(context_parameters: ContextParameters) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Initiate invoice directory");
Expand Down
4 changes: 2 additions & 2 deletions src/cli/get_customers.rs → src/cli/list_customers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::error::Error;
use log::trace;

use crate::cli::context_parameters::ContextParameters;
use crate::file_manager::file_manager::{FileManager, Manager};
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn get_customers(context_parameters: ContextParameters) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
pub fn list_customers(context_parameters: ContextParameters) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== Get customers");

let file_manager = FileManager::new(
Expand Down
32 changes: 32 additions & 0 deletions src/cli/list_invoices.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::error::Error;

use log::trace;

use crate::cli::context_parameters::ContextParameters;
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub fn list_invoices(context_parameters: ContextParameters) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
trace!("=== List invoices");

let file_manager = FileManager::new(
context_parameters.invoice_manager_path,
context_parameters.invoice_path,
context_parameters.customer_file_path,
context_parameters.config_file_path,
)?;

let all_invoices = file_manager.get_all_invoices()?;

let mut plural_offset = "";
if all_invoices.len() > 1 {
plural_offset = "s";
}

println!("Get {} invoice{}\n", all_invoices.len(), plural_offset);

all_invoices
.iter()
.for_each(|invoice| println!("{}", invoice));

Ok(())
}
5 changes: 4 additions & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
pub mod cli_error;
pub mod create_customer;
pub mod create_invoice;
pub mod get_customers;
pub mod get_customer;
pub mod init;
pub mod context_parameters;
pub mod get_invoice;
pub mod delete_invoice;
mod utils;
pub mod list_invoices;
pub mod list_customers;
pub mod delete_customer;
7 changes: 7 additions & 0 deletions src/cli/utils/cli_utils_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum CliUtilsError {
#[error("No invoice already created found")]
NoInvoiceFound(),
}
5 changes: 4 additions & 1 deletion src/cli/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
pub(super) mod select_invoice;
pub(super) mod select_invoice;
pub(super) mod select_customer;
pub(super) mod select_customer_or_use_default;
mod cli_utils_error;
40 changes: 40 additions & 0 deletions src/cli/utils/select_customer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::collections::HashMap;
use std::error::Error;

use dialoguer::FuzzySelect;

use crate::entities::customer::Customer;
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub(crate) fn select_customer(file_manager: &FileManager) -> Result<(String, Customer), Box<dyn Error + Sync + Send + 'static>> {
let all_customers_hashmap: HashMap<String, Customer> = file_manager.get_all_customers()?;
let all_customers: Vec<(&String, &Customer)> = all_customers_hashmap.iter().collect();

let customer_index = FuzzySelect::new()
.with_prompt("What is your customer?")
.items(&all_customers.iter().map(|(_customer_ref, customer)| customer.name.clone()).collect::<Vec<String>>())
.interact()
.unwrap();

return Ok((all_customers[customer_index].0.to_string(), all_customers[customer_index].1.clone()));
}

#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::error::Error;
use crate::cli::utils::cli_utils_error::CliUtilsError;
use crate::entities::customer::Customer;

use crate::file_manager::file_manager::InvoiceManager;

pub(crate) fn mock_select_customer(file_manager: &impl InvoiceManager) -> Result<Customer, Box<dyn Error + Sync + Send + 'static>> {
let all_customers: HashMap<String, Customer> = file_manager.get_all_customers()?;

if all_customers.len() == 0 {
return Err(Box::new(CliUtilsError::NoInvoiceFound()))
}

Ok(all_customers.values().next().unwrap().clone())
}
}
24 changes: 24 additions & 0 deletions src/cli/utils/select_customer_or_use_default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::error::Error;

use crate::cli::cli_error::CliError;
use crate::cli::utils::select_customer::select_customer;
use crate::entities::customer::Customer;
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub(crate) fn select_customer_or_use_default(file_manager: &FileManager, customer_ref: &Option<String>) -> Result<(String, Customer), Box<dyn Error + Sync + Send + 'static>> {
if let Some(customer_preselected) = customer_ref {
match file_manager.get_all_customers() {
Ok(customer) => {
match customer.get(customer_preselected) {
Some(customer) => Ok((customer_preselected.to_owned(), customer.to_owned())),
None => Err(Box::new(CliError::CustomerNotFound(customer_preselected.to_owned())))
}
}
Err(err) => {
Err(err)
}
}
} else {
select_customer(&file_manager)
}
}
30 changes: 28 additions & 2 deletions src/cli/utils/select_invoice.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
use std::error::Error;

use dialoguer::FuzzySelect;
use crate::cli::utils::cli_utils_error::CliUtilsError;

use crate::entities::invoice::Invoice;
use crate::file_manager::file_manager::{FileManager, Manager};
use crate::file_manager::file_manager::{FileManager, InvoiceManager};

pub(crate) fn select_invoice(file_manager: &FileManager) -> Result<Invoice, Box<dyn Error + Sync + Send + 'static>> {
let all_invoices: Vec<Invoice> = file_manager.get_all_invoices()?;

if all_invoices.len() == 0 {
return Err(Box::new(CliUtilsError::NoInvoiceFound()))
}

let invoice_index = FuzzySelect::new()
.with_prompt("What is your customer?")
.with_prompt("What is your invoice?")
.items(&all_invoices)
.interact()
.unwrap();

return Ok(all_invoices[invoice_index].clone());
}

#[cfg(test)]
mod tests {
use std::error::Error;
use crate::cli::utils::cli_utils_error::CliUtilsError;

use crate::entities::invoice::Invoice;
use crate::file_manager::file_manager::InvoiceManager;

pub(crate) fn mock_select_invoice(file_manager: &impl InvoiceManager) -> Result<Invoice, Box<dyn Error + Sync + Send + 'static>> {
let all_invoices: Vec<Invoice> = file_manager.get_all_invoices()?;

if all_invoices.len() == 0 {
return Err(Box::new(CliUtilsError::NoInvoiceFound()))
}

Ok(all_invoices.get(0).unwrap().clone())
}
}
Loading

0 comments on commit 62ea50b

Please sign in to comment.