diff --git a/crates/channels/src/stocks/mod.rs b/crates/channels/src/stocks/mod.rs index e76590b..134b5a6 100644 --- a/crates/channels/src/stocks/mod.rs +++ b/crates/channels/src/stocks/mod.rs @@ -28,6 +28,12 @@ pub enum Error { VariantStocks(Vec), #[error("Failed to load stocks for products variants {0:?}")] VariantPhotos(Vec), + #[error("Failed to create product")] + CreateProduct, + #[error("Failed to create variant of product {0:?}")] + CreateProductVariant(ProductId), + #[error("Failed to create stock of variant {0:?}")] + CreateVariantStock(ProductVariantId), } pub mod rpc { diff --git a/crates/channels/src/stocks/product.rs b/crates/channels/src/stocks/product.rs index c26d3c3..4c66960 100644 --- a/crates/channels/src/stocks/product.rs +++ b/crates/channels/src/stocks/product.rs @@ -28,9 +28,7 @@ pub mod create_product { #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct Details { - pub product: model::Product, - pub stocks: Vec, - pub photos: Vec, + pub product: DetailedProduct, } pub type Output = Result; diff --git a/crates/stock_manager/src/actions/product.rs b/crates/stock_manager/src/actions/product.rs index bd808a8..0a7cf40 100644 --- a/crates/stock_manager/src/actions/product.rs +++ b/crates/stock_manager/src/actions/product.rs @@ -1,16 +1,72 @@ -use channels::stocks::{create_product, delete_product, update_product}; +use channels::stocks::{create_product, delete_product, update_product, Error}; use channels::AsyncClient; use config::SharedAppConfig; +use db_utils::PgT; +use crate::begin_t; use crate::db::Database; pub async fn create_product( - _input: create_product::Input, - _db: Database, + input: create_product::Input, + db: Database, _mqtt: AsyncClient, _config: SharedAppConfig, ) -> create_product::Output { - todo!() + let mut t = begin_t!(db, Error::InternalServerError); + + let res = inner_create_product(input, &mut t, _mqtt, _config).await; + + t.commit().await.ok(); + + res +} + +async fn inner_create_product( + input: create_product::Input, + t: &mut PgT<'_>, + _mqtt: AsyncClient, + _config: SharedAppConfig, +) -> create_product::Output { + let dbm = crate::db::CreateProduct { + name: input.product.name.clone(), + category: input.product.category, + deliver_days_flag: input.product.deliver_days_flag, + }; + let product = match dbm.run(t).await { + Ok(product) => product, + Err(e) => { + tracing::error!("{}", e); + return Err(Error::CreateProduct); + } + }; + + let dbm = crate::db::CreateProductVariant { + product_id: product.id, + name: input.product.name, + short_description: input.product.short_description, + long_description: input.product.long_description, + price: input.product.price, + }; + let variant = match dbm.run(t).await { + Ok(variant) => variant, + Err(e) => { + tracing::warn!("{}", e); + return Err(Error::CreateProductVariant(product.id)); + } + }; + + let dbm = crate::db::CreateStock { + product_variant_id: variant.id, + quantity: input.stock.quantity, + quantity_unit: input.stock.quantity_unit, + }; + let stock = match dbm.run(t).await { + Ok(stock) => stock, + Err(e) => { + tracing::warn!("{}", e); + return Err(Error::CreateVariantStock(variant.id)); + } + }; } pub async fn update_product(