diff --git a/src/cli/cli_error.rs b/src/cli/cli_error.rs index c89d0b9..6c45ed8 100644 --- a/src/cli/cli_error.rs +++ b/src/cli/cli_error.rs @@ -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(), diff --git a/src/cli/create_customer.rs b/src/cli/create_customer.rs index 23d8a52..178a07f 100644 --- a/src/cli/create_customer.rs +++ b/src/cli/create_customer.rs @@ -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> { trace!("=== Create customer"); diff --git a/src/cli/create_invoice.rs b/src/cli/create_invoice.rs index 5cd4cf9..d91b477 100644 --- a/src/cli/create_invoice.rs +++ b/src/cli/create_invoice.rs @@ -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> { trace!("=== Create invoice"); diff --git a/src/cli/delete_customer.rs b/src/cli/delete_customer.rs new file mode 100644 index 0000000..8920b93 --- /dev/null +++ b/src/cli/delete_customer.rs @@ -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) -> Result<(), Box> { + 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 +} diff --git a/src/cli/delete_invoice.rs b/src/cli/delete_invoice.rs index c83bbfa..7328a0d 100644 --- a/src/cli/delete_invoice.rs +++ b/src/cli/delete_invoice.rs @@ -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> { trace!("=== Cancel invoice"); diff --git a/src/cli/get_customer.rs b/src/cli/get_customer.rs new file mode 100644 index 0000000..ceefed0 --- /dev/null +++ b/src/cli/get_customer.rs @@ -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) -> Result<(), Box> { + 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(()) +} diff --git a/src/cli/get_invoice.rs b/src/cli/get_invoice.rs index 66991b4..638fb4b 100644 --- a/src/cli/get_invoice.rs +++ b/src/cli/get_invoice.rs @@ -1,4 +1,5 @@ use std::error::Error; + use log::trace; use crate::cli::cli_error::CliError; @@ -6,7 +7,7 @@ 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) -> Result<(), Box> { trace!("=== Get invoice"); diff --git a/src/cli/init.rs b/src/cli/init.rs index b4d58c1..6e35562 100644 --- a/src/cli/init.rs +++ b/src/cli/init.rs @@ -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> { trace!("=== Initiate invoice directory"); diff --git a/src/cli/get_customers.rs b/src/cli/list_customers.rs similarity index 79% rename from src/cli/get_customers.rs rename to src/cli/list_customers.rs index 6c50c4a..649aa2e 100644 --- a/src/cli/get_customers.rs +++ b/src/cli/list_customers.rs @@ -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> { +pub fn list_customers(context_parameters: ContextParameters) -> Result<(), Box> { trace!("=== Get customers"); let file_manager = FileManager::new( diff --git a/src/cli/list_invoices.rs b/src/cli/list_invoices.rs new file mode 100644 index 0000000..50eb9f6 --- /dev/null +++ b/src/cli/list_invoices.rs @@ -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> { + 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(()) +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index fe02ecc..f93f296 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -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; diff --git a/src/cli/utils/cli_utils_error.rs b/src/cli/utils/cli_utils_error.rs new file mode 100644 index 0000000..8f47552 --- /dev/null +++ b/src/cli/utils/cli_utils_error.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum CliUtilsError { + #[error("No invoice already created found")] + NoInvoiceFound(), +} \ No newline at end of file diff --git a/src/cli/utils/mod.rs b/src/cli/utils/mod.rs index 6551480..6110d72 100644 --- a/src/cli/utils/mod.rs +++ b/src/cli/utils/mod.rs @@ -1 +1,4 @@ -pub(super) mod select_invoice; \ No newline at end of file +pub(super) mod select_invoice; +pub(super) mod select_customer; +pub(super) mod select_customer_or_use_default; +mod cli_utils_error; \ No newline at end of file diff --git a/src/cli/utils/select_customer.rs b/src/cli/utils/select_customer.rs new file mode 100644 index 0000000..6f5508a --- /dev/null +++ b/src/cli/utils/select_customer.rs @@ -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> { + let all_customers_hashmap: HashMap = 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::>()) + .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> { + let all_customers: HashMap = file_manager.get_all_customers()?; + + if all_customers.len() == 0 { + return Err(Box::new(CliUtilsError::NoInvoiceFound())) + } + + Ok(all_customers.values().next().unwrap().clone()) + } +} \ No newline at end of file diff --git a/src/cli/utils/select_customer_or_use_default.rs b/src/cli/utils/select_customer_or_use_default.rs new file mode 100644 index 0000000..d2fedc9 --- /dev/null +++ b/src/cli/utils/select_customer_or_use_default.rs @@ -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) -> Result<(String, Customer), Box> { + 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) + } +} diff --git a/src/cli/utils/select_invoice.rs b/src/cli/utils/select_invoice.rs index 8d0b8fe..c90ddbe 100644 --- a/src/cli/utils/select_invoice.rs +++ b/src/cli/utils/select_invoice.rs @@ -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> { let all_invoices: Vec = 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> { + let all_invoices: Vec = file_manager.get_all_invoices()?; + + if all_invoices.len() == 0 { + return Err(Box::new(CliUtilsError::NoInvoiceFound())) + } + + Ok(all_invoices.get(0).unwrap().clone()) + } } \ No newline at end of file diff --git a/src/file_manager/customer/delete_customer.rs b/src/file_manager/customer/delete_customer.rs new file mode 100644 index 0000000..2f6441b --- /dev/null +++ b/src/file_manager/customer/delete_customer.rs @@ -0,0 +1,92 @@ +use std::fs; +use std::path::Path; + +use super::get_all_customers::get_all_customers; +use super::invoice_customer_manager_error::InvoiceCustomerManagerError; + +pub fn delete_customer( + customer_file_path: &Path, + customer_ref: &str, +) -> Result<(), InvoiceCustomerManagerError> { + if !customer_file_path.is_file() { + return Err(InvoiceCustomerManagerError::CustomerStorePathNotFound( + customer_file_path.to_string_lossy().to_string(), + )); + } + + let mut all_customers = get_all_customers(customer_file_path)?; + + if !all_customers.contains_key(customer_ref) { + return Err( + InvoiceCustomerManagerError::UnableDeleteCustomerRefNotFound( + customer_ref.to_owned(), + ), + ); + } + + all_customers.remove(customer_ref); + + match fs::write( + customer_file_path, + serde_yaml::to_string(&all_customers).unwrap(), + ) { + Ok(()) => Ok(()), + Err(error) => Err(InvoiceCustomerManagerError::UnableToWriteCustomerFile( + customer_file_path.to_string_lossy().to_string(), + error, + )), + } +} + +#[cfg(test)] +mod tests { + use std::fs; + + use crate::file_manager::customer::delete_customer::delete_customer; + use crate::file_manager::customer::get_all_customers::get_all_customers; + + #[test] + pub fn test_delete_customer() { + let customer_map_yaml = "king:\n".to_owned() + + " name: King SARL\n" + + " address: 1 rue des champs\n" + + " city: Paris\n" + + " postal: '75000'\n" + + "last_king:\n" + + " name: Last King SARL\n" + + " address: 2 rue des champs\n" + + " city: Paris\n" + + " postal: '75000'\n"; + + let temp_dir_assert_fs = assert_fs::TempDir::new().unwrap(); + let temp_customer_file_path = temp_dir_assert_fs.path().join("customer.yaml"); + + fs::write(&temp_customer_file_path, &customer_map_yaml) + .expect("Unable to delete king in customer file"); + + delete_customer(&temp_customer_file_path, "king").unwrap(); + + let all_customer = get_all_customers(&temp_customer_file_path) + .expect("Unable read customer created"); + + assert_eq!(all_customer.len(), 1); + assert!(!all_customer.contains_key("king")); + assert!(all_customer.contains_key("last_king")); + + delete_customer(&temp_customer_file_path, "last_king") + .expect("Unable to delete the second customer"); + + let all_customer = get_all_customers(&temp_customer_file_path) + .expect("Unable read customer created"); + + assert_eq!(all_customer.len(), 0); + assert!(!all_customer.contains_key("king")); + assert!(!all_customer.contains_key("last_king")); + + let error_customer_not_exist = delete_customer(&temp_customer_file_path, "king"); + + assert!(error_customer_not_exist.is_err()); + + temp_dir_assert_fs.close().unwrap(); + } +} diff --git a/src/file_manager/customer/invoice_customer_manager_error.rs b/src/file_manager/customer/invoice_customer_manager_error.rs index 9a1d8ab..47d32df 100644 --- a/src/file_manager/customer/invoice_customer_manager_error.rs +++ b/src/file_manager/customer/invoice_customer_manager_error.rs @@ -13,4 +13,7 @@ pub enum InvoiceCustomerManagerError { #[error("Unable to create customer with duplicated id: {1} in {0}")] UnableCreateCustomerDuplicatedId(String, String), + + #[error("Unable to delete customer with ref : `{0}`: Ref not found")] + UnableDeleteCustomerRefNotFound(String) } diff --git a/src/file_manager/customer/mod.rs b/src/file_manager/customer/mod.rs index 015c1bb..5c2b31c 100644 --- a/src/file_manager/customer/mod.rs +++ b/src/file_manager/customer/mod.rs @@ -1,3 +1,4 @@ pub(super) mod create_customer; pub(super) mod get_all_customers; mod invoice_customer_manager_error; +pub(super) mod delete_customer; diff --git a/src/file_manager/file_manager.rs b/src/file_manager/file_manager.rs index 3eea131..453ebed 100644 --- a/src/file_manager/file_manager.rs +++ b/src/file_manager/file_manager.rs @@ -1,7 +1,16 @@ +use std::collections::HashMap; +use std::error::Error; +use std::fs; +use std::path::{Path, PathBuf}; + +use chrono::NaiveDate; +use log::{error, info}; + use crate::entities::customer::Customer; use crate::entities::invoice::Invoice; use crate::entities::settings::Settings; use crate::file_manager::customer::create_customer::create_customer; +use crate::file_manager::customer::delete_customer::delete_customer; use crate::file_manager::customer::get_all_customers::get_all_customers; use crate::file_manager::invoice::create_invoice::create_invoice; use crate::file_manager::invoice::get_all_invoices::get_all_invoices; @@ -12,14 +21,8 @@ use crate::file_manager::invoice::get_invoice_by_filepath::get_invoice_by_file_p use crate::file_manager::invoice_manager_error::InvoiceManagerError; use crate::file_manager::settings::get_settings::get_settings; use crate::file_manager::settings::save_settings::save_settings; -use chrono::NaiveDate; -use log::{error, info}; -use std::collections::HashMap; -use std::error::Error; -use std::fs; -use std::path::{Path, PathBuf}; -pub trait Manager { +pub trait InvoiceManager { fn create_invoice( &self, invoice: Invoice, @@ -51,6 +54,14 @@ pub trait Manager { &self, customer: Customer, ) -> Result>; + fn edit_customer( + &self, + customer: Customer, + ) -> Result>; + fn remove_customer<'a>( + &self, + customer_ref: &'a str, + ) -> Result<(), Box>; fn create_settings( &self, settings: Settings, @@ -87,7 +98,7 @@ impl FileManager { return Err(Box::try_from(InvoiceManagerError::UnableInitFolderInto( root_path.to_string_lossy().to_string(), )) - .unwrap()); + .unwrap()); } let invoice_path = match invoice_path { @@ -132,7 +143,7 @@ impl FileManager { return Err(Box::try_from(InvoiceManagerError::InvoiceStorePathNotFound( root_path.to_string_lossy().to_string(), )) - .unwrap()); + .unwrap()); } if !file_manager.invoice_path.is_dir() { @@ -144,7 +155,7 @@ impl FileManager { return Err(Box::try_from(InvoiceManagerError::InvoiceStorePathNotFound( file_manager.invoice_path.to_string_lossy().to_string(), )) - .unwrap()); + .unwrap()); } if !file_manager.customer_file_path.exists() { @@ -157,7 +168,7 @@ impl FileManager { Box::try_from(InvoiceManagerError::CustomerStorePathNotFound( file_manager.customer_file_path.to_string_lossy().to_string(), )) - .unwrap(), + .unwrap(), ); } @@ -188,7 +199,7 @@ impl FileManager { root_path.to_string_lossy().to_string(), error, )) - .unwrap()); + .unwrap()); } } @@ -206,7 +217,7 @@ impl FileManager { file_manager.invoice_path.to_string_lossy().to_string(), error, )) - .unwrap()); + .unwrap()); } } @@ -226,7 +237,7 @@ impl FileManager { error, ), ) - .unwrap()); + .unwrap()); } } @@ -246,7 +257,7 @@ impl FileManager { error, ), ) - .unwrap()); + .unwrap()); } } @@ -254,7 +265,7 @@ impl FileManager { } } -impl Manager for FileManager { +impl InvoiceManager for FileManager { fn create_invoice( &self, invoice: Invoice, @@ -278,7 +289,7 @@ impl Manager for FileManager { .as_path() .join(invoice_reference.to_string() + ".yaml"), ) - .map_err(|e| Box::new(e) as Box) + .map_err(|e| Box::new(e) as Box) } fn get_invoice_by_date( &self, @@ -320,6 +331,21 @@ impl Manager for FileManager { .map_err(|e| Box::new(e) as Box) } + fn edit_customer( + &self, + customer: Customer, + ) -> Result> { + todo!("Edit customer not implemented yet") + } + + fn remove_customer( + &self, + customer_ref: &str, + ) -> Result<(), Box> { + delete_customer(self.customer_file_path.as_path(), customer_ref) + .map_err(|e| Box::new(e) as Box) + } + fn create_settings( &self, settings: Settings, @@ -344,10 +370,12 @@ impl Manager for FileManager { #[cfg(test)] mod tests { - use super::*; + use chrono::NaiveDate; + use crate::entities::invoice::InvoiceDayId; use crate::entities::product::Product; - use chrono::NaiveDate; + + use super::*; #[test] pub fn file_manager_generate_instance() { @@ -375,7 +403,7 @@ mod tests { Some(&(temp_dir.to_owned().join("custom_enterprise"))), Some(&(temp_dir.to_owned().join("custom_settings"))), ) - .expect("Unable initiate file manager"); + .expect("Unable initiate file manager"); assert_eq!( file_manager.invoice_path, diff --git a/src/main.rs b/src/main.rs index c835aae..be8b1f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,15 +4,18 @@ use std::path::PathBuf; use clap::{Parser, Subcommand}; use log::LevelFilter; -use crate::cli::cli_error::CliError; +use crate::cli::cli_error::CliError; use crate::cli::context_parameters::ContextParameters; use crate::cli::create_customer::create_customer; use crate::cli::create_invoice::create_invoice; +use crate::cli::delete_customer::delete_customer; use crate::cli::delete_invoice::delete_invoice; -use crate::cli::get_customers::get_customers; +use crate::cli::get_customer::get_customer; use crate::cli::get_invoice::get_invoice; use crate::cli::init::initiate_invoice_directory; +use crate::cli::list_customers::list_customers; +use crate::cli::list_invoices::list_invoices; mod cli; mod entities; @@ -66,11 +69,14 @@ enum Commands { #[derive(Subcommand)] enum CrudAction { Create, + List, Get { element: Option }, Edit, - Delete, + Delete { + element: Option + }, } fn main() { @@ -98,24 +104,26 @@ fn main() { parameters ), Some(Commands::Invoice { action }) => match action { + Some(CrudAction::List) => list_invoices(parameters), Some(CrudAction::Get { element }) => get_invoice(parameters, element), Some(CrudAction::Create) => create_invoice(parameters), Some(CrudAction::Edit) => { Err(Box::new(CliError::CommandNotExists("You can't edit a invoice. You can only delete the old invoice and create another".to_string()))) } - Some(CrudAction::Delete) => delete_invoice(parameters), + Some(CrudAction::Delete { element }) => delete_invoice(parameters), None => { Err(Box::new(CliError::CommandNotExists("You can get, create or delete invoice".to_string()))) } }, Some(Commands::Customer { action }) => match action { - Some(CrudAction::Get { element }) => get_customers(parameters), + Some(CrudAction::List) => list_customers(parameters), + Some(CrudAction::Get { element }) => get_customer(parameters, element), Some(CrudAction::Create) => create_customer(parameters), - Some(CrudAction::Edit) => {Err(Box::new(CliError::NotImplementedYet()))} - Some(CrudAction::Delete) => {Err(Box::new(CliError::NotImplementedYet()))} - None => {Err(Box::new(CliError::NotImplementedYet()))} + Some(CrudAction::Edit) => { Err(Box::new(CliError::NotImplementedYet())) } + Some(CrudAction::Delete { element }) => { delete_customer(parameters, element) } + None => { Err(Box::new(CliError::NotImplementedYet())) } }, - Some(Commands::Stats {}) => {Err(Box::new(CliError::NotImplementedYet()))} + Some(Commands::Stats {}) => { Err(Box::new(CliError::NotImplementedYet())) } None => Err(Box::new(CliError::CommandNotExists("The option is not correct. Try to get help".to_string()))) };