Remove item from cart
This commit is contained in:
parent
4be0f69511
commit
ad046bc389
@ -1,6 +1,7 @@
|
||||
use crate::database::Database;
|
||||
use crate::model::{
|
||||
AccountId, ProductId, Quantity, QuantityUnit, ShoppingCartItem, ShoppingCartState,
|
||||
AccountId, ProductId, Quantity, QuantityUnit, ShoppingCartId, ShoppingCartItem,
|
||||
ShoppingCartItemId, ShoppingCartState,
|
||||
};
|
||||
use crate::{cart_async_handler, database};
|
||||
use actix::{Actor, Addr, Context, Handler, Message, ResponseActFuture, WrapFuture};
|
||||
@ -15,6 +16,8 @@ pub enum Error {
|
||||
CantAddItem,
|
||||
#[error("{0}")]
|
||||
Db(#[from] database::Error),
|
||||
#[error("Unable to update cart item")]
|
||||
UpdateFailed,
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
@ -80,3 +83,35 @@ async fn add_item(msg: AddItem, db: Addr<Database>) -> Result<ShoppingCartItem>
|
||||
_ => Err(Error::CantAddItem),
|
||||
}
|
||||
}
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "Result<Option<ShoppingCartItem>>")]
|
||||
pub struct RemoveProduct {
|
||||
pub shopping_cart_id: ShoppingCartId,
|
||||
pub shopping_cart_item_id: ShoppingCartItemId,
|
||||
}
|
||||
|
||||
cart_async_handler!(RemoveProduct, remove_product, Option<ShoppingCartItem>);
|
||||
|
||||
pub(crate) async fn remove_product(
|
||||
msg: RemoveProduct,
|
||||
db: Addr<Database>,
|
||||
) -> Result<Option<ShoppingCartItem>> {
|
||||
match db
|
||||
.send(database::RemoveCartItem {
|
||||
shopping_cart_id: msg.shopping_cart_id,
|
||||
shopping_cart_item_id: Some(msg.shopping_cart_item_id),
|
||||
product_id: None,
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(Ok(row)) => Ok(row),
|
||||
Ok(Err(db_err)) => {
|
||||
log::error!("{db_err}");
|
||||
Err(Error::UpdateFailed)
|
||||
}
|
||||
Err(act_err) => {
|
||||
log::error!("{act_err:?}");
|
||||
Err(Error::UpdateFailed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use super::Result;
|
||||
pub enum Error {
|
||||
#[error("Can't create order item")]
|
||||
CantCreate,
|
||||
#[error("Can't find order item does to lack of identity")]
|
||||
#[error("Can't find order item doe to lack of identity")]
|
||||
NoIdentity,
|
||||
#[error("Order item does not exists")]
|
||||
NotExists,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::db_async_handler;
|
||||
use crate::{database, db_async_handler};
|
||||
use actix::{Handler, ResponseActFuture, WrapFuture};
|
||||
use sqlx::PgPool;
|
||||
|
||||
@ -21,6 +21,10 @@ pub enum Error {
|
||||
AccountCarts,
|
||||
#[error("Failed to load items for shopping cart {0}")]
|
||||
CartItems(ShoppingCartId),
|
||||
#[error("Can't find shopping cart item doe to lack of identity")]
|
||||
NoIdentity,
|
||||
#[error("Failed to update shopping cart item with id {shopping_cart_item_id:?} and/or product id {product_id:?}")]
|
||||
Update { shopping_cart_item_id: Option<ShoppingCartItemId>, product_id: Option<ProductId> },
|
||||
}
|
||||
|
||||
#[derive(actix::Message)]
|
||||
@ -199,3 +203,59 @@ WHERE shopping_cart_id = $1
|
||||
super::Error::ShoppingCartItem(Error::CartItems(shopping_cart_id))
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(actix::Message)]
|
||||
#[rtype(result = "Result<Option<ShoppingCartItem>>")]
|
||||
pub struct RemoveCartItem {
|
||||
pub shopping_cart_id: ShoppingCartId,
|
||||
pub shopping_cart_item_id: Option<ShoppingCartItemId>,
|
||||
pub product_id: Option<ProductId>,
|
||||
}
|
||||
|
||||
db_async_handler!(RemoveCartItem, remove_cart_item, Option<ShoppingCartItem>);
|
||||
|
||||
pub(crate) async fn remove_cart_item(
|
||||
msg: RemoveCartItem,
|
||||
pool: PgPool,
|
||||
) -> Result<Option<ShoppingCartItem>> {
|
||||
match (msg.shopping_cart_item_id, msg.product_id) {
|
||||
(Some(shopping_cart_item_id), None) => sqlx::query_as(
|
||||
r#"
|
||||
DELETE FROM shopping_cart_items
|
||||
WHERE shopping_cart_id = $1 AND id = $2
|
||||
RETURNING id, product_id, shopping_cart_id, quantity, quantity_unit
|
||||
"#,
|
||||
)
|
||||
.bind(msg.shopping_cart_id)
|
||||
.bind(shopping_cart_item_id),
|
||||
(Some(shopping_cart_item_id), Some(product_id)) => sqlx::query_as(
|
||||
r#"
|
||||
DELETE FROM shopping_cart_items
|
||||
WHERE shopping_cart_id = $1 AND id = $2 AND product_id = $3
|
||||
RETURNING id, product_id, shopping_cart_id, quantity, quantity_unit
|
||||
"#,
|
||||
)
|
||||
.bind(msg.shopping_cart_id)
|
||||
.bind(shopping_cart_item_id)
|
||||
.bind(product_id),
|
||||
(None, Some(product_id)) => sqlx::query_as(
|
||||
r#"
|
||||
DELETE FROM shopping_cart_items
|
||||
WHERE shopping_cart_id = $1 AND product_id = $2
|
||||
RETURNING id, product_id, shopping_cart_id, quantity, quantity_unit
|
||||
"#,
|
||||
)
|
||||
.bind(msg.shopping_cart_id)
|
||||
.bind(product_id),
|
||||
_ => return Err(database::Error::ShoppingCartItem(Error::NoIdentity)),
|
||||
}
|
||||
.fetch_optional(&pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("{e:?}");
|
||||
database::Error::ShoppingCartItem(Error::Update {
|
||||
shopping_cart_item_id: msg.shopping_cart_item_id,
|
||||
product_id: msg.product_id,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -326,30 +326,30 @@ impl From<FullAccount> for Account {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(sqlx::Type, Serialize, Deserialize)]
|
||||
#[derive(sqlx::Type, Serialize, Deserialize, Debug, Copy, Clone, Deref, Display, From)]
|
||||
#[sqlx(transparent)]
|
||||
#[serde(transparent)]
|
||||
pub struct ProductId(pub RecordId);
|
||||
pub struct ProductId(RecordId);
|
||||
|
||||
#[derive(sqlx::Type, Serialize, Deserialize)]
|
||||
#[derive(sqlx::Type, Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
||||
#[sqlx(transparent)]
|
||||
#[serde(transparent)]
|
||||
pub struct ProductName(pub String);
|
||||
pub struct ProductName(String);
|
||||
|
||||
#[derive(sqlx::Type, Serialize, Deserialize)]
|
||||
#[derive(sqlx::Type, Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
||||
#[sqlx(transparent)]
|
||||
#[serde(transparent)]
|
||||
pub struct ProductShortDesc(pub String);
|
||||
pub struct ProductShortDesc(String);
|
||||
|
||||
#[derive(sqlx::Type, Serialize, Deserialize)]
|
||||
#[derive(sqlx::Type, Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
||||
#[sqlx(transparent)]
|
||||
#[serde(transparent)]
|
||||
pub struct ProductLongDesc(pub String);
|
||||
pub struct ProductLongDesc(String);
|
||||
|
||||
#[derive(sqlx::Type, Serialize, Deserialize)]
|
||||
#[derive(sqlx::Type, Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
||||
#[sqlx(transparent)]
|
||||
#[serde(transparent)]
|
||||
pub struct ProductCategory(pub String);
|
||||
pub struct ProductCategory(String);
|
||||
|
||||
#[derive(sqlx::FromRow, Serialize, Deserialize)]
|
||||
pub struct Product {
|
||||
|
Loading…
Reference in New Issue
Block a user