Skip to content

Commit

Permalink
Ensure stock is checked when updating line items (#801)
Browse files Browse the repository at this point in the history
* Ensure stock is checked when updating line items

* remove extra line
  • Loading branch information
duncanmcclean authored Feb 1, 2023
1 parent 46c4e88 commit 6f2ba9b
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/Http/Controllers/CartItemController.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,23 @@ public function update(UpdateRequest $request, string $requestItem)
$data['quantity'] = (int) $data['quantity'];
}

$product = $lineItem->product();

// Ensure there's enough stock to fulfill the customer's quantity
if ($product->purchasableType() === ProductType::Product) {
if (is_int($product->stock()) && $product->stock() < $request->quantity) {
return $this->withErrors($request, __("There's not enough stock to fulfil the quantity you selected. Please try again later."));
}
} elseif ($product->purchasableType() === ProductType::Variant) {
$variant = $request->has('variant')
? $product->variant($request->get('variant'))
: $product->variant($lineItem->variant());

if ($variant !== null && is_int($variant->stock()) && $variant->stock() < $request->quantity) {
return $this->withErrors($request, __("There's not enough stock to fulfil the quantity you selected. Please try again later."));
}
}

$cart->updateLineItem(
$requestItem,
array_merge(
Expand Down
214 changes: 214 additions & 0 deletions tests/Http/Controllers/CartItemControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1820,6 +1820,220 @@ public function can_update_item_with_string_quantity_and_ensure_quantity_is_save
$this->assertIsInt($cart->lineItems()->toArray()[0]->quantity());
}

/** @test */
public function can_update_item_and_ensure_the_quantity_is_not_more_than_stock()
{
$product = Product::make()
->price(1000)
->stock(2)
->data([
'title' => 'Food',
'slug' => 'food',
]);

$product->save();

$cart = Order::make()
->lineItems([
[
'id' => Stache::generateId(),
'product' => $product->id,
'quantity' => 1,
'total' => 1000,
],
]);

$cart->save();

$data = [
'quantity' => 5,
];

$response = $this
->from('/cart')
->withSession(['simple-commerce-cart' => $cart->id])
->post(route('statamic.simple-commerce.cart-items.update', [
'item' => $cart->lineItems()->toArray()[0]->id(),
]), $data)
->assertSessionHasErrors();

$cart = $cart->fresh();

$this->assertSame(1, $cart->lineItems()->toArray()[0]->quantity());
}

/** @test */
public function can_update_item_with_variant_and_ensure_the_quantity_is_not_more_than_stock()
{
$product = Product::make()
->data([
'title' => 'Food',
'slug' => 'food',
])
->productVariants([
'variants' => [
[
'name' => 'Colours',
'values' => [
'Red',
],
],
[
'name' => 'Sizes',
'values' => [
'Small',
],
],
],
'options' => [
[
'key' => 'Red_Small',
'variant' => 'Red Small',
'price' => 1000,
'stock' => 2,
],
],
]);

$product->save();

$cart = Order::make()
->lineItems([
[
'id' => Stache::generateId(),
'product' => $product->id,
'variant' => 'Red_Small',
'quantity' => 1,
'total' => 1000,
],
]);

$cart->save();

$data = [
'quantity' => 5,
];

$response = $this
->from('/cart')
->withSession(['simple-commerce-cart' => $cart->id])
->post(route('statamic.simple-commerce.cart-items.update', [
'item' => $cart->lineItems()->toArray()[0]->id(),
]), $data)
->assertSessionHasErrors();

$cart = $cart->fresh();

$this->assertSame(1, $cart->lineItems()->toArray()[0]->quantity());
}

/** @test */
public function cant_update_item_when_standard_product_has_no_stock()
{
$product = Product::make()
->price(1000)
->stock(0)
->data([
'title' => 'Food',
'slug' => 'food',
]);

$product->save();

$cart = Order::make()
->lineItems([
[
'id' => Stache::generateId(),
'product' => $product->id,
'quantity' => 1,
'total' => 1000,
],
]);

$cart->save();

$data = [
'quantity' => 5,
];

$response = $this
->from('/cart')
->withSession(['simple-commerce-cart' => $cart->id])
->post(route('statamic.simple-commerce.cart-items.update', [
'item' => $cart->lineItems()->toArray()[0]->id(),
]), $data)
->assertSessionHasErrors();

$cart = $cart->fresh();

$this->assertSame(1, $cart->lineItems()->toArray()[0]->quantity());
}

/** @test */
public function cant_update_item_when_variant_product_has_no_stock()
{
$product = Product::make()
->data([
'title' => 'Food',
'slug' => 'food',
])
->productVariants([
'variants' => [
[
'name' => 'Colours',
'values' => [
'Red',
],
],
[
'name' => 'Sizes',
'values' => [
'Small',
],
],
],
'options' => [
[
'key' => 'Red_Small',
'variant' => 'Red Small',
'price' => 1000,
'stock' => 0,
],
],
]);

$product->save();

$cart = Order::make()
->lineItems([
[
'id' => Stache::generateId(),
'product' => $product->id,
'variant' => 'Red_Small',
'quantity' => 1,
'total' => 1000,
],
]);

$cart->save();

$data = [
'quantity' => 5,
];

$response = $this
->from('/cart')
->withSession(['simple-commerce-cart' => $cart->id])
->post(route('statamic.simple-commerce.cart-items.update', [
'item' => $cart->lineItems()->toArray()[0]->id(),
]), $data)
->assertSessionHasErrors();

$cart = $cart->fresh();

$this->assertSame(1, $cart->lineItems()->toArray()[0]->quantity());
}

/** @test */
public function can_update_item_and_request_json()
{
Expand Down

0 comments on commit 6f2ba9b

Please sign in to comment.