Remove item from cart
This commit is contained in:
parent
4be0f69511
commit
ad046bc389
@ -1,6 +1,7 @@
|
|||||||
use crate::database::Database;
|
use crate::database::Database;
|
||||||
use crate::model::{
|
use crate::model::{
|
||||||
AccountId, ProductId, Quantity, QuantityUnit, ShoppingCartItem, ShoppingCartState,
|
AccountId, ProductId, Quantity, QuantityUnit, ShoppingCartId, ShoppingCartItem,
|
||||||
|
ShoppingCartItemId, ShoppingCartState,
|
||||||
};
|
};
|
||||||
use crate::{cart_async_handler, database};
|
use crate::{cart_async_handler, database};
|
||||||
use actix::{Actor, Addr, Context, Handler, Message, ResponseActFuture, WrapFuture};
|
use actix::{Actor, Addr, Context, Handler, Message, ResponseActFuture, WrapFuture};
|
||||||
@ -15,6 +16,8 @@ pub enum Error {
|
|||||||
CantAddItem,
|
CantAddItem,
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Db(#[from] database::Error),
|
Db(#[from] database::Error),
|
||||||
|
#[error("Unable to update cart item")]
|
||||||
|
UpdateFailed,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
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),
|
_ => 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 {
|
pub enum Error {
|
||||||
#[error("Can't create order item")]
|
#[error("Can't create order item")]
|
||||||
CantCreate,
|
CantCreate,
|
||||||
#[error("Can't find order item does to lack of identity")]
|
#[error("Can't find order item doe to lack of identity")]
|
||||||
NoIdentity,
|
NoIdentity,
|
||||||
#[error("Order item does not exists")]
|
#[error("Order item does not exists")]
|
||||||
NotExists,
|
NotExists,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::db_async_handler;
|
use crate::{database, db_async_handler};
|
||||||
use actix::{Handler, ResponseActFuture, WrapFuture};
|
use actix::{Handler, ResponseActFuture, WrapFuture};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
@ -21,6 +21,10 @@ pub enum Error {
|
|||||||
AccountCarts,
|
AccountCarts,
|
||||||
#[error("Failed to load items for shopping cart {0}")]
|
#[error("Failed to load items for shopping cart {0}")]
|
||||||
CartItems(ShoppingCartId),
|
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)]
|
#[derive(actix::Message)]
|
||||||
@ -199,3 +203,59 @@ WHERE shopping_cart_id = $1
|
|||||||
super::Error::ShoppingCartItem(Error::CartItems(shopping_cart_id))
|
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)]
|
#[sqlx(transparent)]
|
||||||
#[serde(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)]
|
#[sqlx(transparent)]
|
||||||
#[serde(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)]
|
#[sqlx(transparent)]
|
||||||
#[serde(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)]
|
#[sqlx(transparent)]
|
||||||
#[serde(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)]
|
#[sqlx(transparent)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct ProductCategory(pub String);
|
pub struct ProductCategory(String);
|
||||||
|
|
||||||
#[derive(sqlx::FromRow, Serialize, Deserialize)]
|
#[derive(sqlx::FromRow, Serialize, Deserialize)]
|
||||||
pub struct Product {
|
pub struct Product {
|
||||||
|
Loading…
Reference in New Issue
Block a user