/
itp_practice
/
itp_backend
Обзор
Документация
Войти
/
itp_practice
/
itp_backend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
app/Services/PurchaseFromCartService.php
196 строк
7 KB
vivanenko
cart
27 май 2025, 11:45
27 май 2025, 11:45
934cbb5
Код
Авторство
О чём код?
<?php namespace App\Services; use App\Contracts\CartRepositoryInterface; use App\DTOs\Admin\PurchaseData; use App\Enums\Currency; use App\Enums\PaymentMethod; use App\Enums\PurchaseStatus; use App\Models\Purchase; use App\Models\User; use App\Services\Admin\PurchaseService; use Illuminate\Support\Facades\DB; class PurchaseFromCartService { public function __construct( private readonly CartRepositoryInterface $cartRepository, private readonly CartService $cartService, private readonly PurchaseService $purchaseService ) {} /** * Create purchase from cart items */ public function createPurchaseFromCart( int $userId, PaymentMethod $paymentMethod, Currency $currency = Currency::USD ): array { return DB::transaction(function () use ($userId, $paymentMethod, $currency) { // Validate user $user = User::find($userId); if (!$user) { throw new \InvalidArgumentException('User not found'); } // Get cart data for checkout $checkoutData = $this->cartService->prepareCartForCheckout($userId); if (empty($checkoutData['items'])) { throw new \InvalidArgumentException('Cart is empty'); } // Create individual purchases for each tariff type in cart $purchases = []; foreach ($checkoutData['items'] as $item) { // Create PurchaseData DTO for each item $purchaseData = new PurchaseData( user_id: $userId, tariff_level: $item['tariff_name'], amount: $item['subtotal'], currency: $currency->value, status: PurchaseStatus::PENDING->value, payment_method: $paymentMethod->value, transaction_id: null, payment_details: [ 'quantity' => $item['quantity'], 'unit_price' => $item['price'], 'cart_checkout' => true, 'checkout_timestamp' => now()->toISOString(), ] ); // Create purchase using existing PurchaseService $purchase = $this->purchaseService->createPurchase($purchaseData); $purchases[] = $purchase; } // Clear cart after successful purchase creation $this->cartService->clearCart($userId); return [ 'message' => 'Purchases created successfully from cart', 'purchases' => $purchases, 'total_amount' => $checkoutData['total_amount'], 'items_count' => $checkoutData['items_count'], 'checkout_summary' => $checkoutData, ]; }); } /** * Create single purchase with combined cart total * Alternative approach - creates one purchase with total amount */ public function createCombinedPurchaseFromCart( int $userId, PaymentMethod $paymentMethod, Currency $currency = Currency::USD, string $combinedTariffName = 'Combined Cart Purchase' ): Purchase { return DB::transaction(function () use ($userId, $paymentMethod, $currency, $combinedTariffName) { // Validate user $user = User::find($userId); if (!$user) { throw new \InvalidArgumentException('User not found'); } // Get cart data for checkout $checkoutData = $this->cartService->prepareCartForCheckout($userId); if (empty($checkoutData['items'])) { throw new \InvalidArgumentException('Cart is empty'); } // Create combined purchase data $purchaseData = new PurchaseData( user_id: $userId, tariff_level: $combinedTariffName, amount: $checkoutData['total_amount'], currency: $currency->value, status: PurchaseStatus::PENDING->value, payment_method: $paymentMethod->value, transaction_id: null, payment_details: [ 'cart_items' => $checkoutData['items'], 'items_count' => $checkoutData['items_count'], 'cart_checkout' => true, 'checkout_timestamp' => now()->toISOString(), ] ); // Create purchase using existing PurchaseService $purchase = $this->purchaseService->createPurchase($purchaseData); // Clear cart after successful purchase creation $this->cartService->clearCart($userId); return $purchase; }); } /** * Get cart checkout preview * Shows what the purchase will look like without creating it */ public function getCartCheckoutPreview(int $userId): array { // Validate user if (!User::find($userId)) { throw new \InvalidArgumentException('User not found'); } // Get cart data $checkoutData = $this->cartService->prepareCartForCheckout($userId); return [ 'preview' => $checkoutData, 'estimated_purchases' => $checkoutData['items']->map(function ($item) { return [ 'tariff_name' => $item['tariff_name'], 'amount' => $item['subtotal'], 'quantity' => $item['quantity'], 'unit_price' => $item['price'], ]; }), 'total_amount' => $checkoutData['total_amount'], 'total_items' => $checkoutData['items_count'], ]; } /** * Validate cart before checkout */ public function validateCartForCheckout(int $userId): array { $issues = []; try { $checkoutData = $this->cartService->prepareCartForCheckout($userId); // Check if cart is empty if (empty($checkoutData['items'])) { $issues[] = 'Cart is empty'; } // Check each item availability foreach ($checkoutData['items'] as $item) { $tariff = \App\Models\Tariff::find($item['tariff_id']); if (!$tariff || !$tariff->is_active) { $issues[] = "Tariff '{$item['tariff_name']}' is no longer available"; } } } catch (\Exception $e) { $issues[] = $e->getMessage(); } return [ 'is_valid' => empty($issues), 'issues' => $issues, ]; } }