use crate::cli::{BarcodeCommand, ProductCommand, UnitCommand, UnitPropertyCommand}; use anyhow::{Context, Result}; use rocie_client::{ apis::{ api_get_inventory_api::amount_by_id, api_get_product_api::{product_by_id, products}, api_get_unit_api::{unit_by_id, units}, api_get_unit_property_api::{unit_properties, unit_property_by_id}, api_set_barcode_api::{buy_barcode, consume_barcode}, api_set_product_api::{associate_barcode, register_product}, api_set_unit_api::register_unit, api_set_unit_property_api::register_unit_property, configuration::Configuration, }, models::{ Barcode, BarcodeId, ProductId, UnitAmount, UnitId, UnitPropertyId, UnitPropertyStub, UnitStub, }, }; pub(crate) async fn product(config: &Configuration, command: ProductCommand) -> Result<()> { match command { ProductCommand::Register { name, description, parent, unit_property, } => { let new_id = register_product( config, rocie_client::models::ProductStub { description: Some(description), // TODO: Fix the duplicate option name, unit_property: UnitPropertyId { value: unit_property, }, parent: Some(parent.map(|p| ProductId { value: p })), }, ) .await .context("Failed to register new product")?; println!("Registered new product with id: {new_id}"); } ProductCommand::Get { id } => { let product = product_by_id(config, ProductId { value: id }) .await .with_context(|| format!("Failed to get product with id: {id}"))?; println!("{product:#?}"); } ProductCommand::AssociateBarcode { product_id, barcode_number, amount_value, amount_unit_id, } => { associate_barcode( config, ProductId { value: product_id }, Barcode { id: BarcodeId { value: barcode_number, }, amount: UnitAmount { unit: UnitId { value: amount_unit_id, }, value: amount_value, }, }, ) .await .context("Failed to associated barcode")?; let unit = unit_by_id( config, UnitId { value: amount_unit_id, }, ) .await?; let product = product_by_id(config, ProductId { value: product_id }).await?; println!( "Associated barcode ({barcode_number} - {amount_value} {}) with product: {} ", unit.short_name, product.name ); } ProductCommand::List {} => { let all = products(config) .await .context("Failed to get all products")?; for product in all { print!("{}: {}", product.name, product.id); { let product_amount = amount_by_id(config, product.id).await.with_context(|| { format!("Failed to get amount of product: {}", product.id) })?; let unit = unit_by_id(config, product_amount.amount.unit).await?; print!( " available: {} {}", product_amount.amount.value, unit.short_name ); } if let Some(description) = product .description .expect("Superflous Option wrapping in api") { println!(" ({description})"); } else { println!(); } if !product.associated_bar_codes.is_empty() { println!(" Barcodes:"); } for barcode in product.associated_bar_codes { let unit = unit_by_id(config, barcode.amount.unit).await?; println!( " - {}: {} {}", barcode.id, barcode.amount.value, if barcode.amount.value == 1 { unit.full_name_singular } else { unit.full_name_plural } ); } } } } Ok(()) } pub(crate) async fn barcode(config: &Configuration, command: BarcodeCommand) -> Result<()> { match command { BarcodeCommand::Buy { id } => { buy_barcode(config, BarcodeId { value: id }).await?; } BarcodeCommand::Consume { id, amount, unit_id, } => { consume_barcode( config, BarcodeId { value: id }, UnitAmount { unit: UnitId { value: unit_id }, value: amount, }, ) .await?; } } Ok(()) } pub(crate) async fn unit(config: &Configuration, command: UnitCommand) -> Result<()> { match command { UnitCommand::Register { full_name_singular, full_name_plural, short_name, description, unit_property, } => { let new_id = register_unit( config, UnitStub { description: Some(description), full_name_plural, full_name_singular, short_name, unit_property: UnitPropertyId { value: unit_property, }, }, ) .await .context("Failed to register unit")?; println!("Registered new unit with id: {new_id}"); } UnitCommand::List {} => { let all = units(config).await.context("Failed to get all units")?; for unit in all { print!("{}: {}", unit.full_name_singular, unit.id); if let Some(description) = unit.description.expect("Superflous Option wrapping in api") { println!(" ({description})"); } else { println!(); } } } UnitCommand::GetById { id } => { let unit = unit_by_id(config, UnitId { value: id }) .await .context("Failed to find unit")?; println!( "Unit: {} ({},{},{})", unit.id, unit.full_name_singular, unit.full_name_plural, unit.short_name ); } } Ok(()) } pub(crate) async fn unit_property( config: &Configuration, command: UnitPropertyCommand, ) -> Result<()> { match command { UnitPropertyCommand::Register { name, description } => { let new_id = register_unit_property( config, UnitPropertyStub { description: Some(description), name, }, ) .await .context("Failed to register unit property")?; println!("Registered new unit property with id: {new_id}"); } UnitPropertyCommand::List {} => { let all = unit_properties(config) .await .context("Failed to get all unit properties")?; for unit_prop in all { print!("{}: {}", unit_prop.name, unit_prop.id); if let Some(description) = unit_prop .description .expect("Superflous Option wrapping in api") { println!(" ({description})"); } else { println!(); } } } UnitPropertyCommand::GetById { id } => { let unit = unit_property_by_id(config, UnitPropertyId { value: id }) .await .context("Failed to find unit property")?; println!("Unit property: {} ({})", unit.id, unit.name); } } Ok(()) }