Photos
This commit is contained in:
parent
e5fb90ae0e
commit
abe0d693e8
@ -48,6 +48,8 @@ pub enum Error {
|
|||||||
CreateProductStock(ProductVariantId),
|
CreateProductStock(ProductVariantId),
|
||||||
#[error("Failed to update stock for variant {0:?}")]
|
#[error("Failed to update stock for variant {0:?}")]
|
||||||
UpdateProductStock(ProductVariantId),
|
UpdateProductStock(ProductVariantId),
|
||||||
|
#[error("Failed to load all product photos")]
|
||||||
|
AllProductPhotos,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod rpc {
|
pub mod rpc {
|
||||||
@ -84,8 +86,12 @@ pub mod rpc {
|
|||||||
) -> delete_product_variant::Output;
|
) -> delete_product_variant::Output;
|
||||||
|
|
||||||
// Product photo
|
// Product photo
|
||||||
|
/// Load all photos
|
||||||
|
async fn all_product_photo(input: all_product_photo::Input) -> all_product_photo::Output;
|
||||||
|
|
||||||
/// Add new photo to product.
|
/// Add new photo to product.
|
||||||
async fn add_product_photo(input: add_product_photo::Input) -> add_product_photo::Output;
|
async fn add_product_photo(input: add_product_photo::Input) -> add_product_photo::Output;
|
||||||
|
|
||||||
/// Add delete photo from product.
|
/// Add delete photo from product.
|
||||||
async fn delete_product_photo(
|
async fn delete_product_photo(
|
||||||
input: delete_product_photo::Input,
|
input: delete_product_photo::Input,
|
||||||
|
@ -42,3 +42,31 @@ pub mod delete_product_photo {
|
|||||||
|
|
||||||
pub type Output = Result<Details, Error>;
|
pub type Output = Result<Details, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod all_product_photo {
|
||||||
|
use model::v2::*;
|
||||||
|
|
||||||
|
use crate::stocks::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct Input {
|
||||||
|
pub limit: Limit,
|
||||||
|
pub offset: Offset,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct Detail {
|
||||||
|
pub photo_id: ProductPhotoId,
|
||||||
|
pub product_variant_id: ProductVariantId,
|
||||||
|
pub local_path: LocalPath,
|
||||||
|
pub file_name: FileName,
|
||||||
|
pub unique_name: UniqueName,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct Details {
|
||||||
|
pub product_photos: Vec<Detail>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Output = Result<Details, Error>;
|
||||||
|
}
|
||||||
|
@ -1,11 +1,83 @@
|
|||||||
use channels::stocks::{add_product_photo, delete_product_photo, Error};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use channels::stocks::{add_product_photo, all_product_photo, delete_product_photo, Error};
|
||||||
use channels::AsyncClient;
|
use channels::AsyncClient;
|
||||||
use config::SharedAppConfig;
|
use config::SharedAppConfig;
|
||||||
use db_utils::PgT;
|
use db_utils::PgT;
|
||||||
|
use model::v2::{Photo, ProductPhoto};
|
||||||
|
use model::PhotoId;
|
||||||
|
|
||||||
use crate::begin_t;
|
use crate::begin_t;
|
||||||
use crate::db::Database;
|
use crate::db::Database;
|
||||||
|
|
||||||
|
pub async fn all_product_photo(
|
||||||
|
input: all_product_photo::Input,
|
||||||
|
db: Database,
|
||||||
|
_mqtt: AsyncClient,
|
||||||
|
_config: SharedAppConfig,
|
||||||
|
) -> all_product_photo::Output {
|
||||||
|
let mut t = begin_t!(db, Error::InternalServerError);
|
||||||
|
|
||||||
|
let res = inner_all_product_photo(input, &mut t).await;
|
||||||
|
|
||||||
|
t.commit().await.ok();
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn inner_all_product_photo(
|
||||||
|
input: all_product_photo::Input,
|
||||||
|
t: &mut PgT<'_>,
|
||||||
|
) -> all_product_photo::Output {
|
||||||
|
let dbm = crate::db::AllPhotos {
|
||||||
|
limit: input.limit,
|
||||||
|
offset: input.offset,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut photos: HashMap<PhotoId, Photo> = match dbm.run(t).await {
|
||||||
|
Ok(v) => {
|
||||||
|
let len = v.len();
|
||||||
|
v.into_iter()
|
||||||
|
.fold(HashMap::with_capacity(len), |mut h, photo: Photo| {
|
||||||
|
h.insert(photo.id, photo);
|
||||||
|
h
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
tracing::warn!("{}", e);
|
||||||
|
return Err(Error::AllProductPhotos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let dbm = crate::db::AllProductPhotos {
|
||||||
|
limit: Some(input.limit),
|
||||||
|
offset: Some(input.offset),
|
||||||
|
};
|
||||||
|
|
||||||
|
match dbm.run(t).await {
|
||||||
|
Ok(product_photos) => Ok(all_product_photo::Details {
|
||||||
|
product_photos: product_photos
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|product_photo: ProductPhoto| {
|
||||||
|
photos.remove(&product_photo.photo_id).map(|photo: Photo| {
|
||||||
|
all_product_photo::Detail {
|
||||||
|
photo_id: product_photo.id,
|
||||||
|
product_variant_id: product_photo.product_variant_id,
|
||||||
|
local_path: photo.local_path,
|
||||||
|
file_name: photo.file_name,
|
||||||
|
unique_name: photo.unique_name,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
}),
|
||||||
|
Err(e) => {
|
||||||
|
tracing::warn!("{}", e);
|
||||||
|
Err(Error::AllProductPhotos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn add_product_photo(
|
pub async fn add_product_photo(
|
||||||
input: add_product_photo::Input,
|
input: add_product_photo::Input,
|
||||||
db: Database,
|
db: Database,
|
||||||
|
@ -99,9 +99,7 @@ async fn inner_update_product_stock(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use channels::stocks::{
|
use channels::stocks::{create_product_stock, update_product_stock};
|
||||||
add_product_photo, create_product_stock, delete_product_photo, update_product_stock,
|
|
||||||
};
|
|
||||||
use config::UpdateConfig;
|
use config::UpdateConfig;
|
||||||
use db_utils::PgT;
|
use db_utils::PgT;
|
||||||
use model::v2::*;
|
use model::v2::*;
|
||||||
@ -154,11 +152,15 @@ mod tests {
|
|||||||
let product = test_product(&mut t).await;
|
let product = test_product(&mut t).await;
|
||||||
let variant = test_product_variant(product.id, &mut t).await;
|
let variant = test_product_variant(product.id, &mut t).await;
|
||||||
|
|
||||||
|
let product_variant_id = variant.id;
|
||||||
|
let quantity = Quantity::from_u32(4684);
|
||||||
|
let quantity_unit = QuantityUnit::Gram;
|
||||||
|
|
||||||
let res = inner_create_product_stock(
|
let res = inner_create_product_stock(
|
||||||
create_product_stock::Input {
|
create_product_stock::Input {
|
||||||
product_variant_id: variant.id,
|
product_variant_id,
|
||||||
quantity: Quantity::from_u32(4684),
|
quantity,
|
||||||
quantity_unit: QuantityUnit::Gram,
|
quantity_unit,
|
||||||
},
|
},
|
||||||
&mut t,
|
&mut t,
|
||||||
)
|
)
|
||||||
@ -167,6 +169,10 @@ mod tests {
|
|||||||
testx::db_rollback!(t);
|
testx::db_rollback!(t);
|
||||||
|
|
||||||
let res = res.unwrap();
|
let res = res.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(res.product_stock.product_variant_id, product_variant_id);
|
||||||
|
assert_eq!(res.product_stock.quantity, quantity);
|
||||||
|
assert_eq!(res.product_stock.quantity_unit, quantity_unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -70,6 +70,14 @@ pub mod rpc {
|
|||||||
actions::delete_product_variant(input, self.db, self.mqtt_client, self.config).await
|
actions::delete_product_variant(input, self.db, self.mqtt_client, self.config).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn all_product_photo(
|
||||||
|
self,
|
||||||
|
_: context::Context,
|
||||||
|
input: all_product_photo::Input,
|
||||||
|
) -> all_product_photo::Output {
|
||||||
|
actions::all_product_photo(input, self.db, self.mqtt_client, self.config).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn add_product_photo(
|
async fn add_product_photo(
|
||||||
self,
|
self,
|
||||||
_: context::Context,
|
_: context::Context,
|
||||||
|
Loading…
Reference in New Issue
Block a user