From c7b88fd7f1333641d08faf08a33265d513a09db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Wi=C5=9Bniewski?= <58150098+daVitekPL@users.noreply.github.com> Date: Wed, 19 Apr 2023 11:01:55 +0200 Subject: [PATCH] Buyable checks the quantity in the basket (#111) * Buyable checks the quantity in the basket * Fix tests --- src/Models/Product.php | 2 +- src/Services/ProductService.php | 22 +++++++++++++++++++++- tests/API/CartApiTest.php | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Models/Product.php b/src/Models/Product.php index 7c33472..6442e62 100644 --- a/src/Models/Product.php +++ b/src/Models/Product.php @@ -161,7 +161,7 @@ public function getTaxRate(): float return $this->tax_rate ?? 0; } - public function getBuyableByUserAttribute(?CoreUser $user = null, int $quantity = 1): bool + public function getBuyableByUserAttribute(?CoreUser $user = null, ?int $quantity = null): bool { return app(ProductServiceContract::class)->productIsBuyableByUser($this, $user ?? Auth::user(), false, $quantity); } diff --git a/src/Services/ProductService.php b/src/Services/ProductService.php index 94fa206..73690f9 100644 --- a/src/Services/ProductService.php +++ b/src/Services/ProductService.php @@ -10,6 +10,7 @@ use EscolaLms\Cart\Events\ProductableDetached; use EscolaLms\Cart\Events\ProductAttached; use EscolaLms\Cart\Events\ProductDetached; +use EscolaLms\Cart\Models\Cart; use EscolaLms\Cart\Models\Product; use EscolaLms\Cart\Models\ProductProductable; use EscolaLms\Cart\Models\ProductUser; @@ -203,13 +204,17 @@ public function productProductablesAllOwnedByUser(Product $product, User $user): return Product::where('products.id', $product->getKey())->whereDoesntHaveProductablesNotOwnedByUser($user)->exists(); } - public function productIsBuyableByUser(Product $product, User $user, bool $check_productables = false, int $quantity = 1): bool + public function productIsBuyableByUser(Product $product, User $user, bool $check_productables = false, ?int $quantity = null): bool { $limit_per_user = $product->limit_per_user; $limit_total = $product->limit_total; $is_purchasable = $product->purchasable; + if (is_null($quantity)) { + $quantity = $this->productQuantityInCart($user, $product) + 1; + } + $is_under_limit_per_user = is_null($limit_per_user) || ($product->getOwnedByUserQuantityAttribute($user) + $quantity <= $limit_per_user); $is_under_limit_total = is_null($limit_total) || (($product->users_count ?? $product->users()->count()) + $quantity <= $limit_total); $is_productables_buyable = !$check_productables || $this->productProductablesAllBuyableByUser($product, $user); @@ -518,4 +523,19 @@ public function canDetachProductableFromUser(Productable $productable, User $use { return !$this->productableIsOwnedByUserThroughProduct($productable, $user); } + + private function productQuantityInCart(User $user, Product $product): int + { + $cart = Cart::where('user_id', $user->getAuthIdentifier())->latest()->firstOrCreate([ + 'user_id' => $user->getAuthIdentifier(), + ]); + if (!is_null($cart)) { + $cartItem = $cart + ->items() + ->whereHas('buyable', fn (Builder $query) => $query->where('products.id', '=', $product->getKey())) + ->first(); + return !is_null($cartItem) ? $cartItem->quantity : 0; + } + return 0; + } } diff --git a/tests/API/CartApiTest.php b/tests/API/CartApiTest.php index cf49c6d..32488d4 100644 --- a/tests/API/CartApiTest.php +++ b/tests/API/CartApiTest.php @@ -381,7 +381,7 @@ public function test_added_more_than_limit_per_user() ); $this->response = $this->actingAs($user, 'api')->json('GET', '/api/cart'); - $this->response->assertCreated(); + $this->response->assertOk(); $this->response->assertJson( fn (AssertableJson $json) => $json