From a84fda2382aad22ae268e29b8a1628d3a6393dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Wo=C5=BAniak?= Date: Wed, 18 May 2022 16:10:39 +0200 Subject: [PATCH] Update shopping cart item --- actors/cart_manager/src/lib.rs | 45 ++++++++++++++----- .../src/shopping_cart_items.rs | 38 ++++++++++++++++ api/src/routes/public/api_v1/restricted.rs | 9 ++-- shared/model/src/api.rs | 2 +- shared/model/src/lib.rs | 2 +- 5 files changed, 79 insertions(+), 17 deletions(-) diff --git a/actors/cart_manager/src/lib.rs b/actors/cart_manager/src/lib.rs index c79ac33..64ba6fe 100644 --- a/actors/cart_manager/src/lib.rs +++ b/actors/cart_manager/src/lib.rs @@ -90,16 +90,16 @@ impl CartManager { #[derive(actix::Message)] #[rtype(result = "Result")] -pub struct AddItem { +pub struct ModifyItem { pub buyer_id: AccountId, pub product_id: ProductId, pub quantity: Quantity, pub quantity_unit: QuantityUnit, } -cart_async_handler!(AddItem, add_item, ShoppingCartItem); +cart_async_handler!(ModifyItem, modify_item, ShoppingCartItem); -async fn add_item(msg: AddItem, db: actix::Addr) -> Result { +async fn modify_item(msg: ModifyItem, db: actix::Addr) -> Result { let _cart = query_db!( db, database_manager::EnsureActiveShoppingCart { @@ -121,17 +121,40 @@ async fn add_item(msg: AddItem, db: actix::Addr) -> Result = query_db!( db, - database_manager::CreateShoppingCartItem { - product_id: msg.product_id, - shopping_cart_id: cart.id, - quantity: msg.quantity, - quantity_unit: msg.quantity_unit, + database_manager::ActiveCartItemByProduct { + product_id: msg.product_id }, - passthrough Error::Db, Error::CantAddItem - )) + ); + + match item { + Some(item) => Ok(query_db!( + db, + database_manager::UpdateShoppingCartItem { + id: item.id, + product_id: msg.product_id, + shopping_cart_id: cart.id, + quantity: msg.quantity, + quantity_unit: msg.quantity_unit, + }, + passthrough Error::Db, + Error::CantAddItem + )), + None => Ok(query_db!( + db, + database_manager::CreateShoppingCartItem { + product_id: msg.product_id, + shopping_cart_id: cart.id, + quantity: msg.quantity, + quantity_unit: msg.quantity_unit, + }, + passthrough Error::Db, + Error::CantAddItem + )), + } } #[derive(actix::Message)] diff --git a/actors/database_manager/src/shopping_cart_items.rs b/actors/database_manager/src/shopping_cart_items.rs index 366fb5f..d8b6377 100644 --- a/actors/database_manager/src/shopping_cart_items.rs +++ b/actors/database_manager/src/shopping_cart_items.rs @@ -222,6 +222,44 @@ WHERE id = $1 }) } +#[derive(actix::Message)] +#[rtype(result = "Result>")] +pub struct ActiveCartItemByProduct { + pub product_id: model::ProductId, +} + +db_async_handler!( + ActiveCartItemByProduct, + active_cart_item_by_product, + Option +); + +pub(crate) async fn active_cart_item_by_product( + msg: ActiveCartItemByProduct, + db: PgPool, +) -> Result> { + sqlx::query_as( + r#" +SELECT shopping_cart_items.id, + shopping_cart_items.product_id, + shopping_cart_items.shopping_cart_id, + shopping_cart_items.quantity, + shopping_cart_items.quantity_unit +FROM shopping_cart_items +INNER JOIN shopping_carts ON shopping_cart_items.shopping_cart_id = shopping_carts.id +WHERE product_id = $1 AND shopping_carts.state = $2 + "#, + ) + .bind(msg.product_id) + .bind(model::ShoppingCartState::Active) + .fetch_optional(&db) + .await + .map_err(|e| { + log::error!("{e:?}"); + super::Error::ShoppingCartItem(Error::NotExists) + }) +} + #[derive(actix::Message)] #[rtype(result = "Result>")] pub struct CartItems { diff --git a/api/src/routes/public/api_v1/restricted.rs b/api/src/routes/public/api_v1/restricted.rs index f9277b1..376fbc2 100644 --- a/api/src/routes/public/api_v1/restricted.rs +++ b/api/src/routes/public/api_v1/restricted.rs @@ -1,6 +1,6 @@ use actix::Addr; use actix_web::web::{scope, Data, Json, ServiceConfig}; -use actix_web::{delete, get, post, HttpRequest, HttpResponse}; +use actix_web::{delete, get, post, put, HttpRequest, HttpResponse}; use actix_web_httpauth::extractors::bearer::BearerAuth; use cart_manager::{query_cart, CartManager}; use database_manager::{query_db, Database}; @@ -88,8 +88,8 @@ async fn shopping_cart( Ok(Json(cart)) } -#[post("/shopping-cart-item")] -async fn create_cart_item( +#[put("/shopping-cart-item")] +async fn update_cart_item( cart: Data>, tm: Data>, credentials: BearerAuth, @@ -99,7 +99,7 @@ async fn create_cart_item( let item: model::ShoppingCartItem = query_cart!( cart, - cart_manager::AddItem { + cart_manager::ModifyItem { buyer_id: token.account_id(), product_id: payload.product_id, quantity: payload.quantity, @@ -108,6 +108,7 @@ async fn create_cart_item( routes::Error::Public(super::Error::AddItem.into()), routes::Error::Public(PublicError::DatabaseConnection) ); + Ok(Json(api::CreateItemOutput { success: true, shopping_cart_item: item.into(), diff --git a/shared/model/src/api.rs b/shared/model/src/api.rs index cd014e5..a8422e8 100644 --- a/shared/model/src/api.rs +++ b/shared/model/src/api.rs @@ -90,7 +90,7 @@ pub struct AccountOrder { #[cfg_attr(feature = "dummy", derive(fake::Dummy))] #[derive(Serialize, Deserialize, Debug)] pub struct ShoppingCartItem { - pub id: ShoppingCartId, + pub id: ShoppingCartItemId, pub product_id: ProductId, pub shopping_cart_id: ShoppingCartId, pub quantity: Quantity, diff --git a/shared/model/src/lib.rs b/shared/model/src/lib.rs index 3084a22..15cdeb9 100644 --- a/shared/model/src/lib.rs +++ b/shared/model/src/lib.rs @@ -932,7 +932,7 @@ pub struct ShoppingCartItemId(RecordId); #[cfg_attr(feature = "db", derive(sqlx::FromRow))] #[derive(Serialize, Deserialize)] pub struct ShoppingCartItem { - pub id: ShoppingCartId, + pub id: ShoppingCartItemId, pub product_id: ProductId, pub shopping_cart_id: ShoppingCartId, pub quantity: Quantity,