error 500 fixed in orders
This commit is contained in:
@@ -54,6 +54,23 @@ pub async fn place(
|
|||||||
details: Checkout,
|
details: Checkout,
|
||||||
user: Option<&users::Model>,
|
user: Option<&users::Model>,
|
||||||
) -> Result<Model> {
|
) -> Result<Model> {
|
||||||
|
// Resolve the price of every line *before* opening the transaction. Pricing
|
||||||
|
// loads its context from the connection pool; doing it while the order
|
||||||
|
// transaction holds a connection would acquire a second one and can exhaust
|
||||||
|
// the pool (it times out under contention or a small pool). Prices are stable
|
||||||
|
// within a request, so this snapshot is what we charge; stock is still
|
||||||
|
// re-validated against the transaction below.
|
||||||
|
let line_variants = product_variants::Entity::find()
|
||||||
|
.filter(product_variants::Column::Id.is_in(items.iter().map(|(id, _)| *id)))
|
||||||
|
.all(&ctx.db)
|
||||||
|
.await?;
|
||||||
|
let priced = pricing::price_variants(ctx, &line_variants, user).await?;
|
||||||
|
let price_by_variant: std::collections::HashMap<i32, i64> = line_variants
|
||||||
|
.iter()
|
||||||
|
.zip(priced)
|
||||||
|
.map(|(v, p)| (v.id, p.price_cents))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let txn = ctx.db.begin().await?;
|
let txn = ctx.db.begin().await?;
|
||||||
|
|
||||||
let mut subtotal: i64 = 0;
|
let mut subtotal: i64 = 0;
|
||||||
@@ -78,10 +95,12 @@ pub async fn place(
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Snapshot the price the buyer actually pays — public sale or, for a
|
// The price the buyer actually pays — public sale or, for a business
|
||||||
// business account, their negotiated/lowest price (same resolver the
|
// account, their negotiated/lowest price (resolved above, outside the
|
||||||
// cart and storefront use).
|
// transaction, with the same resolver the cart and storefront use).
|
||||||
let unit_price_cents = pricing::price_variant(ctx, &variant, user).await?.price_cents;
|
let unit_price_cents = *price_by_variant
|
||||||
|
.get(&variant.id)
|
||||||
|
.ok_or_else(|| Error::BadRequest("an item is no longer available".to_string()))?;
|
||||||
subtotal += unit_price_cents * i64::from(*qty);
|
subtotal += unit_price_cents * i64::from(*qty);
|
||||||
|
|
||||||
if let Some(on_hand) = variant.stock {
|
if let Some(on_hand) = variant.stock {
|
||||||
|
|||||||
Reference in New Issue
Block a user