- Lịch sử thanh toán hoá đơn trả thêm `method` (tự động gia hạn / số dư / admin / chuyển khoản / hoàn tiền), bỏ đuôi `(method)` khỏi ghi chú - `DnsServer::panelUrl()` = https://<domain>/ dùng cho email cấp hosting và nút Plesk của khách - Order item trả thêm `uuid`/`type` của dịch vụ để FE dẫn tới trang quản lý - Yêu cầu huỷ dịch vụ, chứng chỉ SSL, lịch sử gia hạn, đổi mật khẩu hosting cho khách Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
69 lines
2.6 KiB
PHP
69 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Client\Service;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Service;
|
|
use App\Models\ServiceCancellationRequest;
|
|
use App\Services\ServiceCancellationNotifier;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class ServiceCancellationController extends Controller
|
|
{
|
|
private const CLOSED_STATUSES = ['cancelled', 'terminated'];
|
|
|
|
public function __construct(private readonly ServiceCancellationNotifier $notifier) {}
|
|
|
|
public function store(Request $request, string $uuid): JsonResponse
|
|
{
|
|
$service = $this->ownedService($request, $uuid);
|
|
$data = $request->validate([
|
|
'reason_code' => 'nullable|string|max:40',
|
|
'reason' => 'required|string|min:3|max:1000',
|
|
]);
|
|
|
|
if (in_array($service->status, self::CLOSED_STATUSES, true)) {
|
|
return response()->json(['error' => true, 'message' => 'Dịch vụ đã được hủy.'], 422);
|
|
}
|
|
|
|
if ($service->cancel_at_expiry) {
|
|
return response()->json(['error' => true, 'message' => 'Dịch vụ đã được lên lịch hủy khi hết hạn.'], 422);
|
|
}
|
|
|
|
if ($service->cancellationRequests()->pending()->exists()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn đã gửi yêu cầu hủy dịch vụ này, vui lòng chờ nhân viên xử lý.'], 422);
|
|
}
|
|
|
|
$cancellation = $service->cancellationRequests()->create([
|
|
'customer_id' => $service->customer_id,
|
|
'reason_code' => $data['reason_code'] ?? null,
|
|
'reason' => trim($data['reason']),
|
|
]);
|
|
|
|
$this->notifier->notify($cancellation, $request->ip());
|
|
|
|
return response()->json(['error' => false, 'message' => 'Đã gửi yêu cầu hủy dịch vụ.', 'data' => $this->payload($cancellation)], 201);
|
|
}
|
|
|
|
public function destroy(Request $request, string $uuid): JsonResponse
|
|
{
|
|
$this->ownedService($request, $uuid)->cancellationRequests()->pending()->delete();
|
|
|
|
return response()->json(['error' => false, 'message' => 'Đã rút yêu cầu hủy dịch vụ.']);
|
|
}
|
|
|
|
public static function payload(?ServiceCancellationRequest $request): ?array
|
|
{
|
|
return $request ? [
|
|
'reason' => $request->reason,
|
|
'requested_at' => $request->created_at?->toISOString(),
|
|
] : null;
|
|
}
|
|
|
|
private function ownedService(Request $request, string $uuid): Service
|
|
{
|
|
return Service::where('uuid', $uuid)->where('customer_id', $request->user()->id)->firstOrFail();
|
|
}
|
|
}
|