/
itp_practice
/
itp_backend
Обзор
Документация
Войти
/
itp_practice
/
itp_backend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
app/Services/CartService.php
275 строк
8 KB
vivanenko
fix taps and others structure
27 май 2025, 18:06
27 май 2025, 18:06
8cdc7d9
Код
Авторство
О чём код?
<?php namespace App\Services; use App\Contracts\CartRepositoryInterface; use App\DTOs\CartData; use App\Models\Cart; use App\Models\CartItem; use App\Models\Coupon; use App\Models\Tariff; use App\Models\User; use Illuminate\Database\Eloquent\Collection; class CartService { public function __construct( private readonly CartRepositoryInterface $cartRepository ) {} /** * Add tariff to user's cart */ public function addTariffToCart(CartData $data): array { $data->validateForAdd(); // Check if user exists $user = User::find($data->user_id); if (!$user) { throw new \InvalidArgumentException('User not found'); } // Check if tariff exists and is active $tariff = Tariff::where('id', $data->tariff_id) ->where('is_active', true) ->first(); if (!$tariff) { throw new \InvalidArgumentException('Tariff not found or inactive'); } // Add to cart $cartItem = $this->cartRepository->addTariffToCart( $data->user_id, $tariff, $data->quantity ); return $this->formatCartItemResponse($cartItem); } /** * Remove tariff from user's cart */ public function removeTariffFromCart(int $userId, int $tariffId): bool { if (!User::find($userId)) { throw new \InvalidArgumentException('User not found'); } return $this->cartRepository->removeTariffFromCart($userId, $tariffId); } /** * Update tariff quantity in cart */ public function updateTariffQuantity(CartData $data): array { $data->validateForUpdate(); // Check if user exists if (!User::find($data->user_id)) { throw new \InvalidArgumentException('User not found'); } // Check if tariff exists in cart if (!$this->cartRepository->hasTariffInCart($data->user_id, $data->tariff_id)) { throw new \InvalidArgumentException('Tariff not found in cart'); } // Update quantity $updated = $this->cartRepository->updateTariffQuantity( $data->user_id, $data->tariff_id, $data->quantity ); if (!$updated) { throw new \RuntimeException('Failed to update cart item'); } // Get updated cart summary return $this->getCartSummary($data->user_id); } /** * Get user's cart items */ public function getCartItems(int $userId): array { if (!User::find($userId)) { throw new \InvalidArgumentException('User not found'); } $cart = $this->cartRepository->getCartByUserId($userId); if (!$cart) { return [ 'items' => [], 'subtotal' => 0, 'quantity_discount' => 0, 'total' => 0, 'count' => 0, ]; } $totals = $cart->getTotalWithDiscounts(); return [ 'items' => $cart->items->map(fn($item) => $this->formatCartItemResponse($item)), 'subtotal' => $totals['subtotal'], 'quantity_discount' => $totals['quantity_discount'], 'total' => $totals['total'], 'count' => $cart->getItemsCount(), ]; } /** * Get cart summary (total, count, etc.) */ public function getCartSummary(int $userId): array { if (!User::find($userId)) { throw new \InvalidArgumentException('User not found'); } $cart = $this->cartRepository->getCartByUserId($userId); if (!$cart) { return [ 'subtotal' => 0, 'quantity_discount' => 0, 'total' => 0, 'count' => 0, 'items_count' => 0, ]; } $totals = $cart->getTotalWithDiscounts(); return [ 'subtotal' => $totals['subtotal'], 'quantity_discount' => $totals['quantity_discount'], 'total' => $totals['total'], 'count' => $cart->getItemsCount(), 'items_count' => $cart->items->count(), ]; } /** * Clear user's cart */ public function clearCart(int $userId): bool { if (!User::find($userId)) { throw new \InvalidArgumentException('User not found'); } return $this->cartRepository->clearCart($userId); } /** * Check if tariff is in cart */ public function hasTariffInCart(int $userId, int $tariffId): bool { return $this->cartRepository->hasTariffInCart($userId, $tariffId); } /** * Get available tariffs for cart (active tariffs) */ public function getAvailableTariffs(): Collection { return Tariff::where('is_active', true) ->orderBy('price', 'asc') ->get(); } /** * Apply coupon to cart */ public function applyCoupon(int $userId, string $couponCode): array { $coupon = Coupon::findValidByCode($couponCode); if (!$coupon) { throw new \InvalidArgumentException('Invalid or expired coupon'); } if (!$coupon->canBeUsedByUser($userId)) { throw new \InvalidArgumentException('Coupon cannot be used by this user'); } $cart = $this->cartRepository->getCartByUserId($userId); if (!$cart || $cart->isEmpty()) { throw new \InvalidArgumentException('Cart is empty'); } $totals = $cart->getTotalWithDiscounts(); $discountAmount = $coupon->calculateDiscount($totals['total']); return [ 'coupon' => [ 'code' => $coupon->code, 'name' => $coupon->name, 'discount_amount' => $discountAmount, ], 'cart_total' => $totals['total'], 'final_total' => $totals['total'] - $discountAmount, ]; } /** * Prepare cart for checkout * Returns cart data formatted for order creation */ public function prepareCartForCheckout(int $userId): array { $cart = $this->cartRepository->getCartByUserId($userId); if (!$cart || $cart->isEmpty()) { throw new \InvalidArgumentException('Cart is empty'); } $totals = $cart->getTotalWithDiscounts(); return [ 'user_id' => $userId, 'cart' => $cart, 'items' => $cart->toOrderItemsData(), 'subtotal_amount' => $totals['subtotal'], 'quantity_discount' => $totals['quantity_discount'], 'total_amount' => $totals['total'], 'items_count' => $cart->items->count(), ]; } /** * Format cart item response */ private function formatCartItemResponse(CartItem $cartItem): array { return [ 'id' => $cartItem->id, 'tariff_id' => $cartItem->itemable_id, 'tariff' => [ 'id' => $cartItem->itemable->id, 'name' => $cartItem->itemable->name, 'description' => $cartItem->itemable->description, 'duration_days' => $cartItem->itemable->duration_days, 'price' => $cartItem->itemable->getPrice(), 'is_active' => $cartItem->itemable->is_active, ], 'quantity' => $cartItem->quantity, 'free_quantity' => $cartItem->getFreeQuantity(), 'effective_quantity' => $cartItem->getEffectiveQuantity(), 'subtotal' => $cartItem->getSubtotal(), 'quantity_discount' => $cartItem->getQuantityDiscount(), 'created_at' => $cartItem->created_at, 'updated_at' => $cartItem->updated_at, ]; } }