From 5bbec0ee2b6a24365560f2971dc9fa0e97296094 Mon Sep 17 00:00:00 2001 From: kusowl Date: Tue, 10 Mar 2026 19:01:52 +0530 Subject: [PATCH] feature: update quantity and remove product from cart add endpoint for update quantity of products (min:1, max:10) add endpoint for removing product from cart --- .../Actions/RemoveProductFromCartAction.php | 21 ++++++++++ .../app/Actions/UpdateProductInCartAction.php | 34 +++++++++++++++ .../app/Http/Controllers/CartController.php | 42 ++++++++++++++++--- .../Requests/RemoveProductFromCartRequest.php | 28 +++++++++++++ .../Requests/UpdateProductInCartRequest.php | 29 +++++++++++++ backend/routes/api.php | 5 ++- 6 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 backend/app/Actions/RemoveProductFromCartAction.php create mode 100644 backend/app/Actions/UpdateProductInCartAction.php create mode 100644 backend/app/Http/Requests/RemoveProductFromCartRequest.php create mode 100644 backend/app/Http/Requests/UpdateProductInCartRequest.php diff --git a/backend/app/Actions/RemoveProductFromCartAction.php b/backend/app/Actions/RemoveProductFromCartAction.php new file mode 100644 index 0000000..b9ddceb --- /dev/null +++ b/backend/app/Actions/RemoveProductFromCartAction.php @@ -0,0 +1,21 @@ +carts()->active()->sole(); + $cart->products()->detach($productId); + + return $this->activeCartAction->execute($user); + } +} diff --git a/backend/app/Actions/UpdateProductInCartAction.php b/backend/app/Actions/UpdateProductInCartAction.php new file mode 100644 index 0000000..9bb4d8f --- /dev/null +++ b/backend/app/Actions/UpdateProductInCartAction.php @@ -0,0 +1,34 @@ +carts()->active()->sole(); + + $productInCart = $cart->products()->find($cartData->productId); + + throw_if($productInCart === null, new InvalidArgumentException('Product not found')); + + $cart->products()->updateExistingPivot($cartData->productId, [ + 'quantity' => $cartData->quantity, + ]); + + return CartDTO::fromModel($cart->load(['products' => function ($query) { + $query->withPivot('quantity', 'price'); + }])); + + } +} diff --git a/backend/app/Http/Controllers/CartController.php b/backend/app/Http/Controllers/CartController.php index f54bfee..ffddc15 100644 --- a/backend/app/Http/Controllers/CartController.php +++ b/backend/app/Http/Controllers/CartController.php @@ -4,10 +4,13 @@ use App\Actions\AddProductToCartAction; use App\Actions\GetActiveUserCartAction; +use App\Actions\RemoveProductFromCartAction; +use App\Actions\UpdateProductInCartAction; use App\Data\AddToCartDTO; use App\Http\Requests\AddProductToCartRequest; +use App\Http\Requests\RemoveProductFromCartRequest; +use App\Http\Requests\UpdateProductInCartRequest; use App\Http\Resources\CartResource; -use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CartController extends Controller @@ -36,16 +39,45 @@ public function show(GetActiveUserCartAction $action) /** * Update the specified resource in storage. */ - public function update(Request $request, string $id) + public function update(UpdateProductInCartRequest $request, UpdateProductInCartAction $action) { - // + $updateCartData = AddToCartDTO::fromRequest($request); + $cart = $action->execute($updateCartData, $request->user()); + + return new CartResource($cart); } /** * Remove the specified resource from storage. */ - public function destroy(string $id) + public function destroy(RemoveProductFromCartRequest $request, RemoveProductFromCartAction $action) { - // + $user = $request->user(); + try { + $cart = $action->execute($request->productId, $user); + + return new CartResource($cart); + } catch (ModelNotFoundException $e) { + + Log::error('No active cart found when removing a product from cart.', [ + 'user' => $user->id, + 'error' => $e->getMessage(), + ]); + + return response()->json([ + 'message' => 'No active cart found.', + ], 404); + + } catch (MultipleRecordsFoundException $e) { + Log::error('Multiple active carts found for the user', [ + 'user' => $user->id, + 'error' => $e->getMessage(), + ]); + + return response()->json([ + 'message' => 'Multiple Active carts found.', + ], 409); + } + } } diff --git a/backend/app/Http/Requests/RemoveProductFromCartRequest.php b/backend/app/Http/Requests/RemoveProductFromCartRequest.php new file mode 100644 index 0000000..d388f6d --- /dev/null +++ b/backend/app/Http/Requests/RemoveProductFromCartRequest.php @@ -0,0 +1,28 @@ +|string> + */ + public function rules(): array + { + return [ + 'productId' => ['required', 'exists:products,id'], + ]; + } +} diff --git a/backend/app/Http/Requests/UpdateProductInCartRequest.php b/backend/app/Http/Requests/UpdateProductInCartRequest.php new file mode 100644 index 0000000..adbc4d9 --- /dev/null +++ b/backend/app/Http/Requests/UpdateProductInCartRequest.php @@ -0,0 +1,29 @@ +|string> + */ + public function rules(): array + { + return [ + 'productId' => ['required', 'exists:products,id'], + 'quantity' => ['required', 'min:0', 'max:10'], + ]; + } +} diff --git a/backend/routes/api.php b/backend/routes/api.php index 5da74c3..c1dc546 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -21,8 +21,9 @@ // Favorites Route::post('/products/{product}/favorite', [FavouriteProductController::class, 'toggle']); - Route::post('/cart', [CartController::class, 'store']); - Route::get('/cart', [CartController::class, 'show']); + Route::apiSingleton('/cart', CartController::class) + ->creatable() + ->destroyable(); }); Route::get('/categories', [ProductCategoryController::class, 'index']); Route::apiResource('products', ProductController::class);