63 lines
2.2 KiB
Rust
63 lines
2.2 KiB
Rust
|
|
use api::{CreateRecipeRequest, CreateRecipeResponse};
|
||
|
|
use axum::{extract::State, Json};
|
||
|
|
use sea_orm::{prelude::*, ActiveValue, TransactionTrait};
|
||
|
|
|
||
|
|
use crate::entity::{ingredient, prelude::*, recipe, recipe_ingerdients, recipe_steps};
|
||
|
|
|
||
|
|
use super::{household::AuthorizedHousehold, AppState, JsonResult, RouteError};
|
||
|
|
|
||
|
|
pub(super) async fn create_recipe(
|
||
|
|
AuthorizedHousehold(household): AuthorizedHousehold,
|
||
|
|
State(state): State<AppState>,
|
||
|
|
Json(request): Json<CreateRecipeRequest>,
|
||
|
|
) -> JsonResult<CreateRecipeResponse> {
|
||
|
|
let id = state
|
||
|
|
.db
|
||
|
|
.transaction(|txn| {
|
||
|
|
Box::pin(async move {
|
||
|
|
let model = recipe::ActiveModel {
|
||
|
|
name: ActiveValue::Set(request.name),
|
||
|
|
ranking: ActiveValue::Set(request.rating as i32),
|
||
|
|
..Default::default()
|
||
|
|
};
|
||
|
|
|
||
|
|
let recipe = model.insert(txn).await?;
|
||
|
|
for (num, text) in request.steps.into_iter().enumerate() {
|
||
|
|
let model = recipe_steps::ActiveModel {
|
||
|
|
num: ActiveValue::Set(num as _),
|
||
|
|
recipe_id: ActiveValue::Set(recipe.id),
|
||
|
|
text: ActiveValue::Set(text),
|
||
|
|
};
|
||
|
|
|
||
|
|
model.insert(txn).await?;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (ig, amount) in request.ingredients {
|
||
|
|
if 0 == household
|
||
|
|
.find_related(Ingredient)
|
||
|
|
.filter(ingredient::Column::Id.eq(ig))
|
||
|
|
.count(txn)
|
||
|
|
.await?
|
||
|
|
{
|
||
|
|
Err(RouteError::InvalidRequest(format!(
|
||
|
|
"No such ingredient {ig}"
|
||
|
|
)))?;
|
||
|
|
}
|
||
|
|
|
||
|
|
let model = recipe_ingerdients::ActiveModel {
|
||
|
|
recipe_id: ActiveValue::Set(recipe.id),
|
||
|
|
ingredient_id: ActiveValue::Set(ig),
|
||
|
|
amount: ActiveValue::Set(amount),
|
||
|
|
};
|
||
|
|
|
||
|
|
model.insert(txn).await?;
|
||
|
|
}
|
||
|
|
|
||
|
|
Ok(recipe.id)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
.await?;
|
||
|
|
|
||
|
|
Ok(CreateRecipeResponse { id }.into())
|
||
|
|
}
|