Files
portal-api/app/Http/Controllers/Api/Client/Domain/DomainOrderController.php
T
baodev0 dfb926055d Add feature tests for domain order management
- Implement AdminDomainOrderTest to cover admin functionalities for domain orders including listing, confirming registration, KYC updates, activation, rejection, and refunds.
- Implement ClientDomainOrderTest to cover client functionalities for placing domain orders, including validation for balance, duplicate orders, and domain normalization.
- Ensure proper handling of domain pricing and service statuses throughout the tests.
2026-07-10 14:16:35 +07:00

107 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api\Client\Domain;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Client\Domain\StoreDomainOrderRequest;
use App\Mail\Admin\DomainOrderNewNotification;
use App\Models\Notification;
use App\Models\Setting;
use App\Models\Template;
use App\Services\Api\Domain\DomainOrderService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class DomainOrderController extends Controller
{
public function __construct(
private readonly DomainOrderService $domainOrderService,
) {}
public function store(StoreDomainOrderRequest $request): JsonResponse
{
try {
$result = $this->domainOrderService->placeOrder($request->validated(), $request->user());
$this->notifyAdminNewDomainOrder($request->user(), $result);
return response()->json([
'success' => true,
'message' => 'Đặt mua tên miền thành công.',
'notice' => 'Việc đặt mua không đồng nghĩa tên miền đã được đăng ký thành công. Đơn hàng sẽ được nhân viên kiểm tra và xử lý. Nếu tên miền không còn khả dụng, số dư đã thanh toán sẽ được hoàn lại vào tài khoản.',
'data' => [
'order_num' => $result['order']->order_num,
'domain_name' => $result['order']->orderItems->first()?->domain_name,
'status' => 'pending',
'total' => $result['invoice']->total,
'invoice_number' => $result['invoice']->invoice_number,
],
], 201);
} catch (\InvalidArgumentException $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage(),
], 422);
} catch (\Throwable $e) {
Log::error('DomainOrderController@store', [
'error' => $e->getMessage(),
'customer_id' => $request->user()?->id,
'data' => $request->validated(),
]);
return response()->json([
'success' => false,
'message' => 'Đặt mua tên miền thất bại. Vui lòng thử lại.',
], 500);
}
}
private function notifyAdminNewDomainOrder($customer, array $result): void
{
$domainName = $result['order']->orderItems->first()?->domain_name ?? '';
$orderNum = $result['order']->order_num;
$total = number_format((int) $result['invoice']->total) . ' VNĐ';
Notification::notifyAdmins([
'type' => 'domain_order_new',
'title' => 'Đơn đăng ký tên miền mới',
'body' => "Khách hàng {$customer->fullname} vừa đặt mua tên miền {$domainName} (#{$orderNum})",
'link' => '/domain-orders',
]);
try {
$setting = Setting::where('key', 'setting')->first();
$settingValue = $setting ? json_decode((string) $setting->value, true) : [];
$adminEmail = $settingValue['admin_email'] ?? null;
if (empty($adminEmail)) {
return;
}
$template = Template::where('name', 'Domain Order New')->first();
if (!$template) {
return;
}
$adminUrl = rtrim(env('ADMIN_URL', config('app.url')), '/') . '/domain-orders';
Mail::to($adminEmail)->send(new DomainOrderNewNotification($template, [
'company_name' => $settingValue['company'] ?? config('app.name'),
'company_logo' => $settingValue['logo'] ?? '',
'domain_name' => $domainName,
'customer_name' => $customer->fullname,
'customer_email' => $customer->email,
'order_num' => $orderNum,
'order_total' => $total,
'created_at' => now()->format('d/m/Y H:i:s'),
'admin_url' => $adminUrl,
]));
} catch (\Throwable $e) {
Log::error('DomainOrderController: không thể gửi email admin: ' . $e->getMessage());
}
}
}