diff --git a/crates/channels/src/stocks/mod.rs b/crates/channels/src/stocks/mod.rs index 32febe4..47a9fed 100644 --- a/crates/channels/src/stocks/mod.rs +++ b/crates/channels/src/stocks/mod.rs @@ -48,6 +48,8 @@ pub enum Error { CreateProductStock(ProductVariantId), #[error("Failed to update stock for variant {0:?}")] UpdateProductStock(ProductVariantId), + #[error("Failed to load all product photos")] + AllProductPhotos, } pub mod rpc { @@ -84,8 +86,12 @@ pub mod rpc { ) -> delete_product_variant::Output; // Product photo + /// Load all photos + async fn all_product_photo(input: all_product_photo::Input) -> all_product_photo::Output; + /// Add new photo to product. async fn add_product_photo(input: add_product_photo::Input) -> add_product_photo::Output; + /// Add delete photo from product. async fn delete_product_photo( input: delete_product_photo::Input, diff --git a/crates/channels/src/stocks/product_photo.rs b/crates/channels/src/stocks/product_photo.rs index 203da5e..62d418c 100644 --- a/crates/channels/src/stocks/product_photo.rs +++ b/crates/channels/src/stocks/product_photo.rs @@ -42,3 +42,31 @@ pub mod delete_product_photo { pub type Output = Result; } + +pub mod all_product_photo { + use model::v2::*; + + use crate::stocks::Error; + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + pub struct Input { + pub limit: Limit, + pub offset: Offset, + } + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + pub struct Detail { + pub photo_id: ProductPhotoId, + pub product_variant_id: ProductVariantId, + pub local_path: LocalPath, + pub file_name: FileName, + pub unique_name: UniqueName, + } + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + pub struct Details { + pub product_photos: Vec, + } + + pub type Output = Result; +} diff --git a/crates/stock_manager/src/actions/product_photo.rs b/crates/stock_manager/src/actions/product_photo.rs index ec4f84b..ce6c9ba 100644 --- a/crates/stock_manager/src/actions/product_photo.rs +++ b/crates/stock_manager/src/actions/product_photo.rs @@ -1,11 +1,83 @@ -use channels::stocks::{add_product_photo, delete_product_photo, Error}; +use std::collections::HashMap; + +use channels::stocks::{add_product_photo, all_product_photo, delete_product_photo, Error}; use channels::AsyncClient; use config::SharedAppConfig; use db_utils::PgT; +use model::v2::{Photo, ProductPhoto}; +use model::PhotoId; use crate::begin_t; use crate::db::Database; +pub async fn all_product_photo( + input: all_product_photo::Input, + db: Database, + _mqtt: AsyncClient, + _config: SharedAppConfig, +) -> all_product_photo::Output { + let mut t = begin_t!(db, Error::InternalServerError); + + let res = inner_all_product_photo(input, &mut t).await; + + t.commit().await.ok(); + + res +} + +async fn inner_all_product_photo( + input: all_product_photo::Input, + t: &mut PgT<'_>, +) -> all_product_photo::Output { + let dbm = crate::db::AllPhotos { + limit: input.limit, + offset: input.offset, + }; + + let mut photos: HashMap = match dbm.run(t).await { + Ok(v) => { + let len = v.len(); + v.into_iter() + .fold(HashMap::with_capacity(len), |mut h, photo: Photo| { + h.insert(photo.id, photo); + h + }) + } + Err(e) => { + tracing::warn!("{}", e); + return Err(Error::AllProductPhotos); + } + }; + + let dbm = crate::db::AllProductPhotos { + limit: Some(input.limit), + offset: Some(input.offset), + }; + + match dbm.run(t).await { + Ok(product_photos) => Ok(all_product_photo::Details { + product_photos: product_photos + .into_iter() + .filter_map(|product_photo: ProductPhoto| { + photos.remove(&product_photo.photo_id).map(|photo: Photo| { + all_product_photo::Detail { + photo_id: product_photo.id, + product_variant_id: product_photo.product_variant_id, + local_path: photo.local_path, + file_name: photo.file_name, + unique_name: photo.unique_name, + } + }) + }) + .collect(), + }), + Err(e) => { + tracing::warn!("{}", e); + Err(Error::AllProductPhotos) + } + } +} + pub async fn add_product_photo( input: add_product_photo::Input, db: Database, diff --git a/crates/stock_manager/src/actions/product_stock.rs b/crates/stock_manager/src/actions/product_stock.rs index acb8bab..d8e4dcf 100644 --- a/crates/stock_manager/src/actions/product_stock.rs +++ b/crates/stock_manager/src/actions/product_stock.rs @@ -99,9 +99,7 @@ async fn inner_update_product_stock( #[cfg(test)] mod tests { - use channels::stocks::{ - add_product_photo, create_product_stock, delete_product_photo, update_product_stock, - }; + use channels::stocks::{create_product_stock, update_product_stock}; use config::UpdateConfig; use db_utils::PgT; use model::v2::*; @@ -154,11 +152,15 @@ mod tests { let product = test_product(&mut t).await; let variant = test_product_variant(product.id, &mut t).await; + let product_variant_id = variant.id; + let quantity = Quantity::from_u32(4684); + let quantity_unit = QuantityUnit::Gram; + let res = inner_create_product_stock( create_product_stock::Input { - product_variant_id: variant.id, - quantity: Quantity::from_u32(4684), - quantity_unit: QuantityUnit::Gram, + product_variant_id, + quantity, + quantity_unit, }, &mut t, ) @@ -167,6 +169,10 @@ mod tests { testx::db_rollback!(t); let res = res.unwrap(); + + assert_eq!(res.product_stock.product_variant_id, product_variant_id); + assert_eq!(res.product_stock.quantity, quantity); + assert_eq!(res.product_stock.quantity_unit, quantity_unit); } #[tokio::test] diff --git a/crates/stock_manager/src/rpc.rs b/crates/stock_manager/src/rpc.rs index 6142076..2d20a83 100644 --- a/crates/stock_manager/src/rpc.rs +++ b/crates/stock_manager/src/rpc.rs @@ -70,6 +70,14 @@ pub mod rpc { actions::delete_product_variant(input, self.db, self.mqtt_client, self.config).await } + async fn all_product_photo( + self, + _: context::Context, + input: all_product_photo::Input, + ) -> all_product_photo::Output { + actions::all_product_photo(input, self.db, self.mqtt_client, self.config).await + } + async fn add_product_photo( self, _: context::Context,