feat: bulk book instance sell
Some checks are pending
/ test (push) Waiting to run

This commit is contained in:
Ninjdai 2025-08-15 13:46:21 +02:00
parent b817d36816
commit bc7feb09d4
2 changed files with 54 additions and 0 deletions

View file

@ -157,6 +157,7 @@ pub async fn run_server(db: Arc<DatabaseConnection>, port: u16, serve_docs: bool
.routes(routes!(routes::book_instance::create_book_instance))
.routes(routes!(routes::book_instance::update_book_instance))
.routes(routes!(routes::book_instance::sell_book_instance))
.routes(routes!(routes::book_instance::bulk_sell_book_instance))
.routes(routes!(routes::book_instance::bulk_create_book_instance))
.routes(routes!(routes::book_instance::get_bal_owner_book_instances))
.routes(routes!(routes::book_instance::get_bal_book_instances_by_ean))

View file

@ -167,6 +167,7 @@ pub struct BookInstanceSaleParams {
security(("jwt" = [])),
responses(
(status = OK, body = book_instance::Model, description = "Successfully sold book instance"),
(status = CONFLICT, description = "The specified book instance is not available"),
(status = NOT_FOUND, description = "No book instance with specified id was found"),
(status = FORBIDDEN, description = "You don't own the specified book instance"),
),
@ -185,6 +186,9 @@ pub async fn sell_book_instance(
}
if let Ok(Some(book_instance)) = BookInstance::find_by_id(id).one(state.db_conn.as_ref()).await {
if !book_instance.available {
return (StatusCode::CONFLICT, Json(None));
}
let mut book_instance: book_instance::ActiveModel = book_instance.into();
book_instance.sold_price = Set(Some(instance_payload.price));
book_instance.available = Set(false);
@ -204,6 +208,55 @@ pub async fn sell_book_instance(
}
}
#[axum::debug_handler]
#[utoipa::path(
post,
path = "/book_instance/sell/bulk",
request_body = HashMap<u32, f32>,
security(("jwt" = [])),
responses(
(status = OK, description = "Successfully sold book instances"),
(status = CONFLICT, description = "One of the specified book instances is not available"),
(status = NOT_FOUND, description = "One of the specified book instances was not found"),
(status = FORBIDDEN, description = "You don't own one of the specified book instance"),
),
summary = "Sell book instances in bulk",
description = "Sell book instances in bulk. Payload: {book_instance_id: sold_price, ...}",
tag = "book-instance-api",
)]
pub async fn bulk_sell_book_instance(
State(state): State<Arc<AppState>>,
claims: Claims,
Json(payload): Json<HashMap<u32, f32>>,
) -> StatusCode {
// Here, we trust the client inputs valid book instances most of the time, so we already
// allocate vector memory the size of the input map
let mut book_instance_list: Vec<(book_instance::Model, f32)> = Vec::with_capacity(payload.len());
for instance in payload {
if let Ok(Some(book_instance)) = BookInstance::find_by_id(instance.0).one(state.db_conn.as_ref()).await {
if !user_is_bal_owner(claims.user_id, book_instance.bal_id, state.db_conn.as_ref()).await {
return StatusCode::FORBIDDEN
} else if !book_instance.available {
return StatusCode::CONFLICT
} else {
book_instance_list.push((book_instance, instance.1));
}
} else {
return StatusCode::NOT_FOUND
}
}
for instance in book_instance_list {
let mut book_instance: book_instance::ActiveModel = instance.0.into();
book_instance.sold_price = Set(Some(instance.1));
book_instance.available = Set(false);
let _ = book_instance.update(state.db_conn.as_ref()).await.unwrap();
}
StatusCode::OK
}
#[axum::debug_handler]
#[utoipa::path(
post,