Refactor shopping cart

This commit is contained in:
Adrian Woźniak 2022-05-05 13:34:04 +02:00
parent cb0e721dc0
commit cb096b600c
No known key found for this signature in database
GPG Key ID: 0012845A89C7352B
3 changed files with 91 additions and 70 deletions

View File

@ -67,3 +67,60 @@ pub struct AccountOrder {
pub order_id: Option<OrderId>,
pub items: Vec<OrderItem>,
}
#[derive(Serialize, Debug)]
pub struct ShoppingCartItem {
pub id: model::ShoppingCartId,
pub product_id: model::ProductId,
pub shopping_cart_id: model::ShoppingCartId,
pub quantity: model::Quantity,
pub quantity_unit: model::QuantityUnit,
}
#[derive(Serialize, Debug)]
pub struct ShoppingCart {
pub id: model::ShoppingCartId,
pub buyer_id: AccountId,
pub payment_method: model::PaymentMethod,
pub state: model::ShoppingCartState,
pub items: Vec<ShoppingCartItem>,
}
impl From<(model::ShoppingCart, Vec<model::ShoppingCartItem>)> for ShoppingCart {
fn from(
(
model::ShoppingCart {
id,
buyer_id,
payment_method,
state,
},
items,
): (model::ShoppingCart, Vec<model::ShoppingCartItem>),
) -> Self {
Self {
id,
buyer_id,
payment_method,
state,
items: items
.into_iter()
.map(
|model::ShoppingCartItem {
id,
product_id,
shopping_cart_id,
quantity,
quantity_unit,
}| ShoppingCartItem {
id,
product_id,
shopping_cart_id,
quantity,
quantity_unit,
},
)
.collect(),
}
}
}

View File

@ -80,7 +80,10 @@ impl Default for Command {
}
}
pub struct ConfigInfo {}
#[derive(Options, Debug)]
pub struct ConfigInfo {
pub help: bool,
}
#[derive(Options, Debug)]
pub struct GenerateHashOpts {

View File

@ -6,83 +6,42 @@ use actix_web_httpauth::extractors::bearer::BearerAuth;
use crate::actors::cart_manager;
use crate::actors::cart_manager::CartManager;
use crate::database::Database;
use crate::model::{
AccountId, ProductId, Quantity, QuantityUnit, ShoppingCart, ShoppingCartItem,
ShoppingCartItemId,
};
use crate::model::{api, AccountId, ProductId, Quantity, QuantityUnit, ShoppingCartItemId};
use crate::payment_manager::PaymentManager;
use crate::routes::public::api_v1::ShoppingCartError;
use crate::routes::public::api_v1::{Error as ApiV1Error, ShoppingCartError};
use crate::routes::public::Error as PublicError;
use crate::routes::{RequireUser, Result};
use crate::token_manager::TokenManager;
use crate::{database, model, payment_manager, query_pay, routes};
use crate::{database, model, payment_manager, query_db, query_pay, routes};
#[get("/shopping-cart")]
async fn shopping_cart(
db: Data<Addr<Database>>,
tm: Data<Addr<TokenManager>>,
credentials: BearerAuth,
) -> Result<HttpResponse> {
) -> Result<Json<api::ShoppingCart>> {
let (token, _) = credentials.require_user(tm.into_inner()).await?;
match db
.send(database::EnsureActiveShoppingCart {
let cart: model::ShoppingCart = query_db!(
db,
database::EnsureActiveShoppingCart {
buyer_id: AccountId::from(token.subject),
})
.await
{
Ok(Ok(cart)) => Ok(HttpResponse::Ok().json(cart)),
Ok(Err(e)) => {
log::error!("{e}");
Err(ShoppingCartError::Ensure.into())
}
Err(e) => {
log::error!("{e:?}");
Err(ShoppingCartError::Ensure.into())
}
}
}
#[get("/shopping-cart-items")]
async fn shopping_cart_items(
db: Data<Addr<Database>>,
tm: Data<Addr<TokenManager>>,
credentials: BearerAuth,
) -> Result<HttpResponse> {
let (token, _) = credentials.require_user(tm.into_inner()).await?;
let cart: ShoppingCart = match db
.send(database::EnsureActiveShoppingCart {
buyer_id: AccountId::from(token.subject),
})
.await
{
Ok(Ok(cart)) => cart,
Ok(Err(e)) => {
log::error!("{e}");
return Err(ShoppingCartError::Ensure.into());
}
Err(e) => {
log::error!("{e:?}");
return Err(ShoppingCartError::Ensure.into());
}
};
match db
.send(database::AccountShoppingCartItems {
},
routes::Error::Public(PublicError::ApiV1(ApiV1Error::ShoppingCart(
ShoppingCartError::Ensure
)))
);
let items: Vec<model::ShoppingCartItem> = query_db!(
db,
database::AccountShoppingCartItems {
account_id: cart.buyer_id,
shopping_cart_id: Some(cart.id),
})
.await
{
Ok(Ok(items)) => Ok(HttpResponse::Ok().json(items)),
Ok(Err(e)) => {
log::error!("{e}");
Err(ShoppingCartError::Ensure.into())
}
Err(e) => {
log::error!("{e:?}");
Err(ShoppingCartError::Ensure.into())
}
}
},
routes::Error::Public(PublicError::ApiV1(ApiV1Error::ShoppingCart(
ShoppingCartError::Ensure
)))
);
let cart = api::ShoppingCart::from((cart, items));
Ok(Json(cart))
}
#[derive(serde::Deserialize)]
@ -95,7 +54,7 @@ pub struct CreateItemInput {
#[derive(serde::Serialize)]
pub struct CreateItemOutput {
pub success: bool,
pub shopping_cart_item: ShoppingCartItem,
pub shopping_cart_item: model::ShoppingCartItem,
}
#[post("/shopping-cart-item")]
@ -104,7 +63,7 @@ async fn create_cart_item(
tm: Data<Addr<TokenManager>>,
credentials: BearerAuth,
Json(payload): Json<CreateItemInput>,
) -> Result<HttpResponse> {
) -> Result<Json<CreateItemOutput>> {
let (token, _) = credentials.require_user(tm.into_inner()).await?;
match cart
@ -116,7 +75,7 @@ async fn create_cart_item(
})
.await
{
Ok(Ok(item)) => Ok(HttpResponse::Created().json(CreateItemOutput {
Ok(Ok(item)) => Ok(Json(CreateItemOutput {
success: true,
shopping_cart_item: item,
})),
@ -151,7 +110,7 @@ async fn delete_cart_item(
) -> Result<HttpResponse> {
let (token, _) = credentials.require_user(tm.into_inner()).await?;
let sc: ShoppingCart = match db
let sc: model::ShoppingCart = match db
.send(database::EnsureActiveShoppingCart {
buyer_id: AccountId::from(token.subject),
})
@ -203,6 +162,8 @@ pub struct CreateOrderInput {
/// False if customer is allowed to be charged on site.
/// Otherwise it should be true to use payment service for charging
pub charge_client: bool,
/// User currency
pub currency: String,
}
#[post("/order")]
@ -237,6 +198,7 @@ pub(crate) async fn create_order(
last_name,
language,
charge_client,
currency,
} = payload;
let ip = match req.peer_addr() {
Some(ip) => ip,
@ -246,7 +208,7 @@ pub(crate) async fn create_order(
let payment_manager::CreatePaymentResult { redirect_uri, .. } = query_pay!(
payment,
payment_manager::RequestPayment {
currency: "PLN".to_string(),
currency,
buyer: payment_manager::Buyer {
email,
phone,
@ -274,7 +236,6 @@ pub(crate) fn configure(config: &mut ServiceConfig) {
.realm("user api")
.scope("customer_id role subject audience expiration_time not_before_time issued_at_time"))
.service(shopping_cart)
.service(shopping_cart_items)
.service(delete_cart_item)
.service(create_order));
}