From 5354d909b3ffcddaa6c9a9480ff8e269b249337a Mon Sep 17 00:00:00 2001 From: eraden Date: Sat, 16 Apr 2022 06:58:48 +0200 Subject: [PATCH] Add account orders db, add shopping cart sql --- api/src/actors/database.rs | 4 + api/src/actors/database/account_orders.rs | 93 +++++++++++++++++++ api/src/actors/database/accounts.rs | 23 +++++ api/src/model.rs | 12 +++ .../202204160624_create_shopping_cart.sql | 21 +++++ 5 files changed, 153 insertions(+) create mode 100644 api/src/actors/database/account_orders.rs create mode 100644 db/migrate/202204160624_create_shopping_cart.sql diff --git a/api/src/actors/database.rs b/api/src/actors/database.rs index 0ee117e..378ef60 100644 --- a/api/src/actors/database.rs +++ b/api/src/actors/database.rs @@ -1,10 +1,12 @@ use actix::{Actor, Context}; use sqlx::PgPool; +pub use account_orders::*; pub use accounts::*; pub use products::*; pub use stocks::*; +mod account_orders; mod accounts; mod products; mod stocks; @@ -30,6 +32,8 @@ pub enum Error { #[error("{0}")] Account(accounts::Error), #[error("{0}")] + AccountOrder(account_orders::Error), + #[error("{0}")] Product(products::Error), #[error("{0}")] Stock(stocks::Error), diff --git a/api/src/actors/database/account_orders.rs b/api/src/actors/database/account_orders.rs new file mode 100644 index 0000000..53ba9ef --- /dev/null +++ b/api/src/actors/database/account_orders.rs @@ -0,0 +1,93 @@ +use crate::async_handler; +use actix::{Handler, ResponseActFuture, WrapFuture}; +use sqlx::PgPool; + +use crate::database::Database; +use crate::model::*; + +use super::Result; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("Can't create account")] + CantCreate, + #[error("Can't find account does to lack of identity")] + NoIdentity, + #[error("Account order does not exists")] + NotExists, + #[error("Failed to load all accounts")] + All, +} + +#[derive(actix::Message)] +#[rtype(result = "Result>")] +pub struct AllAccountOrders; + +async_handler!(AllAccountOrders, all_account_orders, Vec); + +pub async fn all_account_orders(_msg: AllAccountOrders, pool: PgPool) -> Result> { + sqlx::query_as( + r#" +SELECT id, buyer_id, status +FROM account_orders + "#, + ) + .fetch_all(&pool) + .await + .map_err(|e| { + log::error!("{e:?}"); + super::Error::AccountOrder(Error::All) + }) +} + +#[derive(actix::Message)] +#[rtype(result = "Result")] +pub struct CreateAccountOrder { + pub buyer_id: AccountId, + pub status: OrderStatus, +} + +async_handler!(CreateAccountOrder, create_account_order, AccountOrder); + +async fn create_account_order(msg: CreateAccountOrder, db: PgPool) -> Result { + sqlx::query_as( + r#" +INSERT INTO account_orders (buyer_id, status) +VALUES ($1, $2) +RETURNING id, buyer_id, status + "#, + ) + .bind(msg.buyer_id) + .bind(msg.status) + .fetch_one(&db) + .await + .map_err(|e| { + log::error!("{e:?}"); + super::Error::AccountOrder(Error::CantCreate) + }) +} + +#[derive(actix::Message)] +#[rtype(result = "Result")] +pub struct FindAccountOrder { + pub id: AccountOrderId, +} + +async_handler!(FindAccountOrder, find_account_order, AccountOrder); + +async fn find_account_order(msg: FindAccountOrder, db: PgPool) -> Result { + sqlx::query_as( + r#" +SELECT id, buyer_id, status +FROM account_orders +WHERE id = $1 + "#, + ) + .bind(msg.id) + .fetch_one(&db) + .await + .map_err(|e| { + log::error!("{e:?}"); + super::Error::AccountOrder(Error::NotExists) + }) +} diff --git a/api/src/actors/database/accounts.rs b/api/src/actors/database/accounts.rs index 7939ee3..2578416 100644 --- a/api/src/actors/database/accounts.rs +++ b/api/src/actors/database/accounts.rs @@ -15,6 +15,29 @@ pub enum Error { NoIdentity, #[error("Account does not exists")] NotExists, + #[error("Failed to load all accounts")] + All, +} + +#[derive(actix::Message)] +#[rtype(result = "Result>")] +pub struct AllAccounts; + +async_handler!(AllAccounts, all_accounts, Vec); + +pub async fn all_accounts(_msg: AllAccounts, pool: PgPool) -> Result> { + sqlx::query_as( + r#" +SELECT id, email, login, pass_hash, role +FROM accounts + "#, + ) + .fetch_all(&pool) + .await + .map_err(|e| { + log::error!("{e:?}"); + super::Error::Account(Error::All) + }) } #[derive(actix::Message)] diff --git a/api/src/model.rs b/api/src/model.rs index 27c9ae5..20e48c4 100644 --- a/api/src/model.rs +++ b/api/src/model.rs @@ -226,3 +226,15 @@ pub struct Stock { pub quantity: Quantity, pub quantity_unit: QuantityUnit, } + +#[derive(sqlx::Type, Serialize, Deserialize)] +#[sqlx(transparent)] +#[serde(transparent)] +pub struct AccountOrderId(pub RecordId); + +#[derive(sqlx::FromRow, Serialize, Deserialize)] +pub struct AccountOrder { + pub id: AccountOrderId, + pub buyer_id: AccountId, + pub status: OrderStatus, +} diff --git a/db/migrate/202204160624_create_shopping_cart.sql b/db/migrate/202204160624_create_shopping_cart.sql new file mode 100644 index 0000000..c9844fe --- /dev/null +++ b/db/migrate/202204160624_create_shopping_cart.sql @@ -0,0 +1,21 @@ +CREATE TYPE "PaymentMethod" AS ENUM ( + 'payu', + 'payment_on_the_spot' + ); + +CREATE TABLE shopping_carts +( + id serial not null primary key, + buyer_id int references accounts (id) not null, + payment_method "PaymentMethod" NOT NULL DEFAULT 'payment_on_the_spot' +); + +CREATE TABLE shopping_cart_items +( + id serial not null primary key, + product_id int references products (id) not null, + order_id int references shopping_carts (id), + quantity int not null default 0, + quantity_unit "QuantityUnit" not null, + CONSTRAINT positive_quantity check ( quantity >= 0 ) +);