2022-11-10 06:36:55 +01:00
|
|
|
use db_utils::PgT;
|
2022-11-09 16:59:12 +01:00
|
|
|
use model::v2::*;
|
|
|
|
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
|
|
pub enum Error {
|
2022-11-10 06:36:55 +01:00
|
|
|
#[error("Failed to create product")]
|
2022-11-09 16:59:12 +01:00
|
|
|
CreateProductVariant,
|
2022-11-10 06:36:55 +01:00
|
|
|
#[error("Failed to load variants for products {0:?}")]
|
|
|
|
ProductsVariants(Vec<ProductId>),
|
|
|
|
#[error("Failed to delete product variant {0:?}")]
|
|
|
|
DeleteProductVariant(ProductVariantId),
|
2022-11-09 16:59:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct CreateProductVariant {
|
|
|
|
pub product_id: ProductId,
|
|
|
|
pub name: ProductName,
|
|
|
|
pub short_description: ProductShortDesc,
|
|
|
|
pub long_description: ProductLongDesc,
|
|
|
|
pub price: Price,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CreateProductVariant {
|
2022-11-10 06:36:55 +01:00
|
|
|
pub async fn run(self, pool: &mut PgT<'_>) -> Result<ProductVariant> {
|
2022-11-09 16:59:12 +01:00
|
|
|
sqlx::query_as(
|
|
|
|
r#"
|
|
|
|
INSERT INTO product_variants (
|
|
|
|
product_id,
|
|
|
|
name,
|
|
|
|
short_description,
|
|
|
|
long_description,
|
|
|
|
price
|
|
|
|
) VALUES ($1, $2, $3, $4, $5)
|
2022-11-10 06:36:55 +01:00
|
|
|
RETURNING id,
|
2022-11-09 16:59:12 +01:00
|
|
|
product_id,
|
|
|
|
name,
|
|
|
|
short_description,
|
|
|
|
long_description,
|
|
|
|
price
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.bind(self.product_id)
|
|
|
|
.bind(self.name)
|
|
|
|
.bind(self.short_description)
|
|
|
|
.bind(self.long_description)
|
|
|
|
.bind(self.price)
|
|
|
|
.fetch_one(pool)
|
|
|
|
.await
|
|
|
|
.map_err(|e| {
|
|
|
|
tracing::error!("{}", e);
|
|
|
|
dbg!(e);
|
|
|
|
Error::CreateProductVariant
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2022-11-10 06:36:55 +01:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ProductsVariants {
|
|
|
|
pub product_ids: Vec<ProductId>,
|
|
|
|
pub limit: Option<i32>,
|
|
|
|
pub offset: Option<i32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ProductsVariants {
|
|
|
|
pub async fn run(self, pool: &mut PgT<'_>) -> Result<Vec<ProductVariant>> {
|
|
|
|
db_utils::MultiLoad::new(
|
|
|
|
pool,
|
|
|
|
r#"
|
|
|
|
SELECT pv.id,
|
|
|
|
pv.product_id,
|
|
|
|
pv.name,
|
|
|
|
pv.short_description,
|
|
|
|
pv.long_description,
|
|
|
|
pv.price
|
|
|
|
FROM product_variants pv
|
|
|
|
INNER JOIN products ps
|
|
|
|
ON pv.product_id = ps.id
|
|
|
|
WHERE
|
|
|
|
"#,
|
|
|
|
"products.id = ",
|
|
|
|
)
|
|
|
|
.allow_over_max()
|
|
|
|
.with_size(1000)
|
|
|
|
.load(
|
|
|
|
self.product_ids.len(),
|
|
|
|
self.product_ids.iter().copied().map(|id| *id),
|
|
|
|
|_| Error::ProductsVariants(self.product_ids.clone()),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct DeleteProductVariant {
|
|
|
|
pub product_variant_id: ProductVariantId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DeleteProductVariant {
|
|
|
|
pub async fn run(self, pool: &mut PgT<'_>) -> Result<Option<ProductVariant>> {
|
|
|
|
sqlx::query_as(
|
|
|
|
r#"
|
|
|
|
DELETE FROM product_variants
|
|
|
|
WHERE id = $1
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.bind(self.product_variant_id)
|
|
|
|
.fetch_optional(pool)
|
|
|
|
.await
|
|
|
|
.map_err(|_e| Error::DeleteProductVariant(self.product_variant_id))
|
|
|
|
}
|
|
|
|
}
|