diff --git a/crates/cart_manager/src/db/shopping_cart_items.rs b/crates/cart_manager/src/db/shopping_cart_items.rs index 7b991c3..393241d 100644 --- a/crates/cart_manager/src/db/shopping_cart_items.rs +++ b/crates/cart_manager/src/db/shopping_cart_items.rs @@ -79,7 +79,8 @@ SELECT shopping_cart_items.id as id, FROM shopping_cart_items LEFT JOIN shopping_carts ON shopping_carts.id = shopping_cart_id -WHERE shopping_carts.buyer_id = $1 AND shopping_carts.id = $2 +WHERE shopping_carts.buyer_id = $1 AND shopping_carts.id = $2 +ORDER BY shopping_cart_items.id "#, ) .bind(msg.account_id) @@ -93,8 +94,9 @@ SELECT shopping_cart_items.id as id, shopping_cart_items.quantity_unit as quantity_unit FROM shopping_cart_items LEFT JOIN shopping_carts - ON shopping_carts.id = shopping_cart_id + ON shopping_carts.id = shopping_cart_id WHERE shopping_carts.buyer_id = $1 +ORDER BY shopping_cart_items.id "#, ) .bind(msg.account_id), diff --git a/crates/channels/src/stocks/mod.rs b/crates/channels/src/stocks/mod.rs index 213d85b..132fadc 100644 --- a/crates/channels/src/stocks/mod.rs +++ b/crates/channels/src/stocks/mod.rs @@ -32,6 +32,8 @@ pub enum Error { CreateProduct, #[error("Failed to update product {0:?}")] UpdateProduct(ProductId), + #[error("Failed to delete product {0:?}")] + DeleteProduct(ProductId), #[error("Failed to create variant of product {0:?}")] CreateProductVariant(ProductId), #[error("Failed to create stock of variant {0:?}")] diff --git a/crates/channels/src/stocks/product.rs b/crates/channels/src/stocks/product.rs index 03383b2..e0aaff7 100644 --- a/crates/channels/src/stocks/product.rs +++ b/crates/channels/src/stocks/product.rs @@ -84,6 +84,7 @@ pub mod delete_product { pub enum Topic { ProductCreated, ProductUpdated, + ProductDeleted, } impl Topic { @@ -91,6 +92,7 @@ impl Topic { match self { Topic::ProductCreated => "product/created", Topic::ProductUpdated => "product/updated", + Topic::ProductDeleted => "product/deleted", } } } @@ -106,6 +108,7 @@ impl DeserializePayload for Topic { match self { Topic::ProductCreated => bincode::deserialize(bytes.as_ref()).ok(), Topic::ProductUpdated => bincode::deserialize(bytes.as_ref()).ok(), + Topic::ProductDeleted => bincode::deserialize(bytes.as_ref()).ok(), } } } @@ -120,4 +123,9 @@ impl AsyncClient { self.publish_or_log(Topic::ProductUpdated, QoS::AtLeastOnce, true, product) .await } + + pub async fn emit_product_deleted(&self, product: &model::v2::ProductId) { + self.publish_or_log(Topic::ProductDeleted, QoS::AtLeastOnce, true, product) + .await + } } diff --git a/crates/stock_manager/src/actions/product.rs b/crates/stock_manager/src/actions/product.rs index 0a1e84d..c1bda09 100644 --- a/crates/stock_manager/src/actions/product.rs +++ b/crates/stock_manager/src/actions/product.rs @@ -2,7 +2,7 @@ use channels::stocks::{create_product, delete_product, update_product, Error}; use channels::AsyncClient; use config::SharedAppConfig; use db_utils::PgT; -use model::v2::{DetailedProduct, DetailedProductVariant, ProductVariantName}; +use model::v2::*; use crate::begin_t; use crate::db::Database; @@ -157,12 +157,44 @@ async fn inner_update_product( } pub async fn delete_product( - _input: delete_product::Input, - _db: Database, - _mqtt: AsyncClient, + input: delete_product::Input, + db: Database, + mqtt: AsyncClient, _config: SharedAppConfig, ) -> delete_product::Output { - todo!() + let mut t = begin_t!(db, Error::InternalServerError); + let product_id = input.product_id; + let res = inner_delete_product(input, &mut t).await; + + match res { + Ok((product_id, _maybe_product)) => { + if let Err(e) = t.commit().await { + tracing::error!("{}", e); + return Err(Error::InternalServerError); + } + mqtt.emit_product_deleted(&product_id).await; + Ok(delete_product::Details { product_id }) + } + Err(e) => { + tracing::error!("{}", e); + t.rollback().await.map_err(|e| { + tracing::error!("{}", e); + Error::InternalServerError + })?; + Err(Error::DeleteProduct(product_id)) + } + } +} + +pub async fn inner_delete_product( + input: delete_product::Input, + t: &mut PgT<'_>, +) -> crate::db::products::Result<(ProductId, Option)> { + let dbm = crate::db::DeleteProduct { + product_id: input.product_id, + }; + + dbm.run(t).await.map(|product| (input.product_id, product)) } #[cfg(test)] diff --git a/crates/stock_manager/src/db/mod.rs b/crates/stock_manager/src/db/mod.rs index fc9a25a..c1c5511 100644 --- a/crates/stock_manager/src/db/mod.rs +++ b/crates/stock_manager/src/db/mod.rs @@ -2,11 +2,11 @@ use config::SharedAppConfig; use sqlx_core::pool::Pool; use sqlx_core::postgres::Postgres; -mod photos; -mod product_photos; -mod product_variants; -mod products; -mod stocks; +pub mod photos; +pub mod product_photos; +pub mod product_variants; +pub mod products; +pub mod stocks; pub use photos::*; pub use product_photos::*;