bazzar/shared/model/src/api.rs

440 lines
12 KiB
Rust

use chrono::NaiveDateTime;
use derive_more::Deref;
#[cfg(feature = "dummy")]
use fake::Fake;
use serde::{Deserialize, Serialize};
use crate::*;
#[derive(Serialize, Deserialize, Debug)]
pub struct Failure {
pub errors: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Config {
pub pay_methods: Vec<PaymentMethod>,
pub coupons: bool,
pub currency: String,
pub shipping: bool,
pub shipping_methods: Vec<ShippingMethod>,
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Serialize, Deserialize, Debug)]
#[serde(transparent)]
pub struct AccountOrders(pub Vec<AccountOrder>);
impl From<(Vec<crate::AccountOrder>, Vec<crate::OrderItem>)> for AccountOrders {
fn from((orders, mut items): (Vec<crate::AccountOrder>, Vec<crate::OrderItem>)) -> Self {
Self(
orders
.into_iter()
.map(
|crate::AccountOrder {
id,
buyer_id,
status,
order_id,
order_ext_id: _,
service_order_id: _,
checkout_notes,
}| {
AccountOrder {
id,
buyer_id,
status,
order_id,
items: items.drain_filter(|item| item.order_id == id).collect(),
checkout_notes,
}
},
)
.collect(),
)
}
}
impl From<(crate::AccountOrder, Vec<crate::OrderItem>)> for AccountOrder {
fn from(
(
crate::AccountOrder {
id,
buyer_id,
status,
order_id,
order_ext_id: _,
service_order_id: _,
checkout_notes,
},
mut items,
): (crate::AccountOrder, Vec<crate::OrderItem>),
) -> Self {
AccountOrder {
id,
buyer_id,
status,
order_id,
items: items.drain_filter(|item| item.order_id == id).collect(),
checkout_notes,
}
}
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Serialize, Deserialize, Debug)]
pub struct AccountOrder {
pub id: crate::AccountOrderId,
pub buyer_id: crate::AccountId,
pub status: crate::OrderStatus,
pub order_id: Option<crate::OrderId>,
pub items: Vec<crate::OrderItem>,
pub checkout_notes: Option<String>,
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Serialize, Deserialize, Debug)]
pub struct ShoppingCartItem {
pub id: ShoppingCartItemId,
pub product_id: ProductId,
pub shopping_cart_id: ShoppingCartId,
pub quantity: Quantity,
pub quantity_unit: QuantityUnit,
}
impl From<crate::ShoppingCartItem> for ShoppingCartItem {
fn from(
crate::ShoppingCartItem {
id,
product_id,
shopping_cart_id,
quantity,
quantity_unit,
}: crate::ShoppingCartItem,
) -> Self {
Self {
id,
product_id,
shopping_cart_id,
quantity,
quantity_unit,
}
}
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Serialize, Deserialize, Debug)]
pub struct ShoppingCart {
pub id: ShoppingCartId,
pub buyer_id: AccountId,
pub payment_method: PaymentMethod,
pub state: ShoppingCartState,
pub items: Vec<ShoppingCartItem>,
pub checkout_notes: String,
}
impl From<(crate::ShoppingCart, Vec<crate::ShoppingCartItem>)> for ShoppingCart {
fn from(
(
crate::ShoppingCart {
id,
buyer_id,
payment_method,
state,
checkout_notes,
},
items,
): (crate::ShoppingCart, Vec<crate::ShoppingCartItem>),
) -> Self {
Self {
id,
buyer_id,
payment_method,
state,
checkout_notes: checkout_notes.unwrap_or_default(),
items: items
.into_iter()
.map(
|crate::ShoppingCartItem {
id,
product_id,
shopping_cart_id,
quantity,
quantity_unit,
}| ShoppingCartItem {
id,
product_id,
shopping_cart_id,
quantity,
quantity_unit,
},
)
.collect(),
}
}
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Serialize, Deserialize, Debug, Hash)]
pub struct Photo {
pub id: crate::PhotoId,
pub file_name: crate::FileName,
pub url: String,
pub unique_name: crate::UniqueName,
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Clone, Debug, Hash, PartialOrd, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub struct Category {
pub name: String,
pub key: String,
pub svg: String,
}
impl From<&crate::Category> for Category {
fn from(crate::Category { name, key, svg }: &crate::Category) -> Self {
Self {
name: (*name).into(),
key: (*key).into(),
svg: (*svg).into(),
}
}
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Serialize, Deserialize, Debug, Hash)]
pub struct Product {
pub id: crate::ProductId,
pub name: crate::ProductName,
pub short_description: crate::ProductShortDesc,
pub long_description: crate::ProductLongDesc,
pub category: Option<Category>,
pub price: crate::Price,
pub available: bool,
pub quantity_unit: crate::QuantityUnit,
pub deliver_days_flag: crate::Days,
pub photos: Vec<Photo>,
}
impl<'path>
From<(
crate::Product,
&mut Vec<ProductLinkedPhoto>,
&mut Vec<crate::Stock>,
&'path str,
)> for Product
{
fn from(
(
crate::Product {
id,
name,
short_description,
long_description,
category,
price,
deliver_days_flag,
},
photos,
product_stocks,
public_path,
): (
crate::Product,
&mut Vec<ProductLinkedPhoto>,
&mut Vec<crate::Stock>,
&'path str,
),
) -> Self {
let pos = product_stocks
.iter()
.position(|stock| stock.product_id == id);
let (available, quantity_unit) = pos
.map(|idx| product_stocks.remove(idx))
.map(|stock| (**stock.quantity > 0, stock.quantity_unit))
.unwrap_or_else(|| (false, crate::QuantityUnit::Piece));
Self {
id,
name,
short_description,
long_description,
category: category.and_then(|name| {
crate::CATEGORIES.iter().find_map(|c| {
if c.name == name.as_str() {
Some(Category::from(c))
} else {
None
}
})
}),
price,
available,
quantity_unit,
deliver_days_flag,
photos: photos
.drain_filter(|photo| photo.product_id == id)
.map(
|ProductLinkedPhoto {
id,
local_path: _,
file_name,
product_id: _,
unique_name,
}| Photo {
id,
url: format!("{}/{}", public_path, unique_name.as_str()),
unique_name,
file_name,
},
)
.collect(),
}
}
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[derive(Serialize, Deserialize, Debug, Deref)]
#[serde(transparent)]
pub struct Products(pub Vec<Product>);
impl
From<(
Vec<crate::Product>,
Vec<ProductLinkedPhoto>,
Vec<crate::Stock>,
String,
)> for Products
{
fn from(
(products, mut photos, mut products_stock, public_path): (
Vec<crate::Product>,
Vec<ProductLinkedPhoto>,
Vec<crate::Stock>,
String,
),
) -> Self {
Self(
products
.into_iter()
.map(|p| (p, &mut photos, &mut products_stock, public_path.as_str()).into())
.collect(),
)
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SignInInput {
pub login: Login,
pub password: Password,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SessionOutput {
pub access_token: AccessTokenString,
pub refresh_token: RefreshTokenString,
pub exp: NaiveDateTime,
pub role: Role,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CreateAccountInput {
pub email: Email,
pub login: Login,
pub password: Password,
pub password_confirmation: PasswordConfirmation,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CreateOrderInput {
/// Required customer e-mail
pub email: String,
/// Required customer phone number
pub phone: String,
/// Required customer first name
pub first_name: String,
/// Required customer last name
pub last_name: String,
/// Required customer language
pub language: String,
/// 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,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DeleteItemInput {
pub shopping_cart_item_id: ShoppingCartItemId,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DeleteItemOutput {
pub success: bool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct UpdateItemInput {
pub product_id: ProductId,
pub quantity: Quantity,
pub quantity_unit: QuantityUnit,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct UpdateItemOutput {
pub shopping_cart_item: ShoppingCartItem,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct UpdateCartInput {
pub items: Vec<UpdateItemInput>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct UpdateCartOutput {
pub items: Vec<ShoppingCartItem>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SearchRequest {
/// Match string
pub q: String,
pub lang: String,
}
pub mod admin {
use serde::{Deserialize, Serialize};
use crate::*;
#[derive(Deserialize, Serialize, Debug)]
pub struct RegisterInput {
pub login: Login,
pub email: Email,
pub password: Password,
pub password_confirmation: PasswordConfirmation,
pub role: Role,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct RegisterResponse {
pub errors: Vec<RegisterError>,
pub account: Option<Account>,
}
#[derive(Serialize, Deserialize, Debug)]
pub enum RegisterError {
PasswordDiffer,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SignInInput {
pub login: Option<Login>,
pub email: Option<Email>,
pub password: Password,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct LogoutResponse {}
}