#[cfg(feature = "dummy")] use fake::Fake; use model::*; use sqlx::PgPool; use super::Result; use crate::db_async_handler; #[derive(Debug, Copy, Clone, serde::Serialize, thiserror::Error)] pub enum Error { #[error("Can't create order item")] CantCreate, #[error("Can't find order item doe to lack of identity")] NoIdentity, #[error("Order item does not exists")] NotExists, #[error("Failed to load all order items")] All, #[error("Failed to load order items")] OrderItems, } #[derive(actix::Message)] #[rtype(result = "Result>")] pub struct AllOrderItems; db_async_handler!(AllOrderItems, all_order_items, Vec); pub(crate) async fn all_order_items(_msg: AllOrderItems, pool: PgPool) -> Result> { sqlx::query_as( r#" SELECT id, product_id, order_id, quantity, quantity_unit FROM order_items ORDER BY id DESC "#, ) .fetch_all(&pool) .await .map_err(|e| { log::error!("{e:?}"); super::Error::from(Error::All) }) } #[cfg_attr(feature = "dummy", derive(fake::Dummy))] #[derive(actix::Message)] #[rtype(result = "Result")] pub struct CreateOrderItem { pub product_id: ProductId, pub order_id: AccountOrderId, pub quantity: Quantity, pub quantity_unit: QuantityUnit, } db_async_handler!(CreateOrderItem, inner_create_order_item, OrderItem); async fn inner_create_order_item(msg: CreateOrderItem, db: PgPool) -> Result { create_order_item(msg, &db).await } pub(crate) async fn create_order_item<'e, E>(msg: CreateOrderItem, db: E) -> Result where E: sqlx::Executor<'e, Database = sqlx::Postgres>, { sqlx::query_as( r#" INSERT INTO order_items (product_id, order_id, quantity, quantity_unit) VALUES ($1, $2, $3, $4) RETURNING id, product_id, order_id, quantity, quantity_unit "#, ) .bind(msg.product_id) .bind(msg.order_id) .bind(msg.quantity) .bind(msg.quantity_unit) .fetch_one(db) .await .map_err(|e| { log::error!("{e:?}"); super::Error::OrderItem(Error::CantCreate) }) } #[derive(actix::Message)] #[rtype(result = "Result")] pub struct FindOrderItem { pub id: OrderItemId, } db_async_handler!(FindOrderItem, find_order_item, OrderItem); pub(crate) async fn find_order_item(msg: FindOrderItem, db: PgPool) -> Result { sqlx::query_as( r#" SELECT id, product_id, order_id, quantity, quantity_unit FROM order_items WHERE id = $1 "#, ) .bind(msg.id) .fetch_one(&db) .await .map_err(|e| { log::error!("{e:?}"); super::Error::OrderItem(Error::NotExists) }) } #[derive(actix::Message)] #[rtype(result = "Result>")] pub struct OrderItems { pub order_id: model::AccountOrderId, } db_async_handler!(OrderItems, order_items, Vec); pub(crate) async fn order_items(msg: OrderItems, pool: PgPool) -> Result> { sqlx::query_as( r#" SELECT id, product_id, order_id, quantity, quantity_unit FROM order_items WHERE order_id = $1 ORDER BY id DESC "#, ) .bind(msg.order_id) .fetch_all(&pool) .await .map_err(|e| { log::error!("{e:?}"); super::Error::OrderItem(Error::OrderItems) }) }