/
itp_practice
/
itp_backend
Обзор
Документация
Войти
/
itp_practice
/
itp_backend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
app/Http/Controllers/Admin/OrderController.php
242 строки
9 KB
vivanenko
add purchase create from admin
29 май 2025, 11:13
29 май 2025, 11:13
25c496a
Код
Авторство
О чём код?
<?php namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Services\OrderService; use App\Services\CartService; use App\Http\Requests\Admin\CreateOrderRequest; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Models\User; use Illuminate\Support\Facades\DB; use App\DTOs\CartData; /** * Контроллер для управления заказами из админ-панели * Использует те же сервисы, что и обычный OrderController, * но работает с user_id из запроса, а не из сессии */ class OrderController extends Controller { public function __construct( private OrderService $orderService, private CartService $cartService ) {} /** * Создать заказ для пользователя из админ-панели * Процесс аналогичен пользовательскому, но user_id берется из запроса */ public function createOrder(CreateOrderRequest $request): JsonResponse { try { $data = $request->validated(); // Используем транзакцию для атомарности операции return DB::transaction(function () use ($data) { $userId = $data['user_id']; // Проверяем существование пользователя $user = User::findOrFail($userId); // Очищаем корзину пользователя перед добавлением $this->cartService->clearCart($userId); // Добавляем тариф в корзину $cartData = CartData::forAddTariff( tariffId: $data['tariff_id'], quantity: $data['quantity'], userId: $userId ); $this->cartService->addTariffToCart($cartData); // Подготавливаем данные для создания заказа $orderData = [ 'metadata' => $data['metadata'] ?? null ]; if (isset($data['currency'])) { $orderData['currency'] = $data['currency']; } // Применяем скидку если указана if (isset($data['discount_amount']) && $data['discount_amount'] > 0) { $orderData['admin_discount'] = $data['discount_amount']; } // Создаем заказ через сервис $result = $this->orderService->createOrderFromCart( userId: $userId, paymentGateway: $data['payment_gateway'] ?? 'demo', orderData: $orderData, couponCode: $data['coupon_code'] ?? null ); // Очищаем корзину после успешного создания заказа $this->cartService->clearCart($userId); return response()->json([ 'message' => 'Заказ успешно создан администратором', 'data' => $result, ], 201); }); } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { return response()->json([ 'message' => 'Пользователь не найден', ], 404); } catch (\InvalidArgumentException $e) { return response()->json([ 'message' => $e->getMessage(), ], 400); } catch (\Exception $e) { return response()->json([ 'message' => 'Ошибка создания заказа', 'error' => $e->getMessage(), ], 500); } } /** * Получить заказы конкретного пользователя */ public function getUserOrders(Request $request, int $userId): JsonResponse { try { $page = (int) $request->get('page', 1); $perPage = min((int) $request->get('per_page', 15), 50); $result = $this->orderService->getUserOrders($userId, $page, $perPage); return response()->json([ 'message' => 'Заказы пользователя получены успешно', 'data' => $result['orders'], 'meta' => $result['meta'], ]); } catch (\Exception $e) { return response()->json([ 'message' => 'Ошибка получения заказов', 'error' => $e->getMessage(), ], 500); } } /** * Получить конкретный заказ */ public function show(int $orderId): JsonResponse { try { // Для админа не проверяем принадлежность заказа пользователю $order = \App\Models\Order::with(['items.itemable', 'status', 'transactions', 'couponUsages', 'user']) ->findOrFail($orderId); return response()->json([ 'message' => 'Заказ получен успешно', 'data' => $order, ]); } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { return response()->json([ 'message' => 'Заказ не найден', ], 404); } catch (\Exception $e) { return response()->json([ 'message' => 'Ошибка получения заказа', 'error' => $e->getMessage(), ], 500); } } /** * Отменить заказ */ public function cancel(int $orderId): JsonResponse { try { // Для админа получаем заказ без проверки пользователя $order = \App\Models\Order::findOrFail($orderId); if ($order->isFinal()) { return response()->json([ 'message' => 'Невозможно отменить заказ в финальном статусе', ], 400); } $order->markAsCancelled()->save(); // Отменяем все ожидающие транзакции $order->transactions() ->where('status', \App\Models\Transaction::STATUS_PENDING) ->update([ 'status' => \App\Models\Transaction::STATUS_CANCELLED, 'processed_at' => now(), ]); return response()->json([ 'message' => 'Заказ успешно отменен администратором', ]); } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { return response()->json([ 'message' => 'Заказ не найден', ], 404); } catch (\Exception $e) { return response()->json([ 'message' => 'Ошибка отмены заказа', 'error' => $e->getMessage(), ], 500); } } /** * Получить статистику заказов для всех пользователей или конкретного пользователя */ public function stats(Request $request): JsonResponse { try { $userId = $request->get('user_id'); if ($userId) { // Статистика для конкретного пользователя $stats = $this->orderService->getOrderStats($userId); } else { // Общая статистика по всем заказам $stats = \App\Models\Order::selectRaw(' COUNT(*) as total_orders, COUNT(DISTINCT user_id) as unique_customers, SUM(CASE WHEN status_code = ? THEN 1 ELSE 0 END) as paid_orders, SUM(CASE WHEN status_code = ? THEN total_amount ELSE 0 END) as total_revenue, AVG(CASE WHEN status_code = ? THEN total_amount ELSE NULL END) as avg_order_value ', [\App\Models\OrderStatus::PAID, \App\Models\OrderStatus::PAID, \App\Models\OrderStatus::PAID]) ->first(); $stats = [ 'total_orders' => $stats->total_orders ?? 0, 'unique_customers' => $stats->unique_customers ?? 0, 'paid_orders' => $stats->paid_orders ?? 0, 'total_revenue' => $stats->total_revenue ?? 0, 'avg_order_value' => $stats->avg_order_value ?? 0, ]; } return response()->json([ 'message' => 'Статистика получена успешно', 'data' => $stats, ]); } catch (\Exception $e) { return response()->json([ 'message' => 'Ошибка получения статистики', 'error' => $e->getMessage(), ], 500); } } }