Files
portal-api/app/Http/Controllers/frontend/InvoiceController.php
T
2025-08-10 21:50:26 +07:00

180 lines
6.0 KiB
PHP

<?php
namespace App\Http\Controllers\frontend;
use App\Enums\Invoice\InvoiceStatus;
use App\Enums\Order\OrderStatus;
use App\Http\Controllers\Controller;
use App\Http\Services\Discord;
use App\Http\Services\Invoice\InvoiceService;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter;
use App\Jobs\VirtualMachine\Create\CreateVirtualMachineJob;
use App\Models\Cart;
use App\Models\Invoice;
use App\Models\InvoiceAddons;
use App\Models\InvoiceItem;
use App\Models\Payment;
use App\Repositories\Invoice\InvoiceRepositoryInterface;
use App\Repositories\Order\OrderRepositoryInterface;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
class InvoiceController extends Controller
{
public function __construct(
public OrderRepositoryInterface $orderRepository,
public InvoiceRepositoryInterface $invoiceRepository,
) {
parent::__construct();
}
//
public function index()
{
$title = "Danh sách hoá đơn";
return view("frontend.invoice.index", compact('title'));
}
public function show($invoice_id, $order_num)
{
$title = "Chi tiết hoá đơn " . $order_num;
// Tìm invoice theo order_num thay vì invoice_id
$invoice = $this->invoiceRepository->findWithRelationships($order_num, [
'order',
'invoiceItem.addons',
'invoiceItem.os.osGroup',
'customer'
]);
// Log để debug
if (!$invoice) {
Log::warning('Invoice not found', [
'invoice_id' => $invoice_id,
'order_num' => $order_num,
'user_id' => customer()?->id ?? 'guest'
]);
} else {
// Kiểm tra quyền truy cập - chỉ cho phép customer xem invoice của chính mình
$currentCustomer = customer();
if ($currentCustomer && $invoice->customer_id !== $currentCustomer->id) {
Log::warning('Unauthorized invoice access attempt', [
'invoice_id' => $invoice->id,
'order_num' => $order_num,
'customer_id' => $currentCustomer->id,
'invoice_customer_id' => $invoice->customer_id
]);
abort(403, 'Bạn không có quyền xem hóa đơn này.');
}
}
return view("frontend.invoice.show", compact('title', 'order_num', 'invoice'));
}
public function show_bk(Request $request)
{
$validator = Validator::make(
$request->all(),
[
'invoice_id' => 'required|not__in:0|numeric'
],
[
'invoice_id' => [
'required' => 'Yêu cầu không hợp lệ'
]
]
);
if ($validator->fails()) {
return back()->withErrors($validator);
}
$invoice = Invoice::with('InvoiceItem', 'Payment', 'Customer', 'Order')->find($request->invoice_id);
if (!$invoice) {
return back()->withErrors('Yêu cầu không hợp lệ');
}
$title = "Chi tiết hoá đơn #" . $invoice->id;
return view("frontend.invoice.view", compact('title', 'invoice'));
}
public function store(
Request $request,
$order_id,
$order_num,
InvoiceService $invoiceService,
Discord $discord,
vCenter $vCenter
) {
$order = $this->orderRepository->findWithRelationships($order_id, [
'orderItems.addons',
'orderItems.os.osGroup',
'customer',
'orderItems.ipAddress.host.oneDatastore',
'orderItems.ipAddress.host.datacenter.vCenter'
]);
if (!$order) {
return redirect()->route('home')->with('error', 'Không tìm thấy đơn hàng.');
}
$user = customer();
if ($user->credit < (int) $order->amount) {
return redirect()->route('recharge.index')->with('error', 'Tài khoản không đủ số dư để thanh toán.');
}
DB::beginTransaction();
try {
$invoice = Invoice::where('order_id', $order_id)->firstOrFail();
// Cập nhật trạng thái đơn hàng thành "Processing" thay vì "Paid"
$order->update(['status' => OrderStatus::PROCESSING->value]);
DB::commit();
// ✅ Gửi thông báo Discord về việc bắt đầu xử lý
$discord->SendJobRunInfo(
'Order Payment Processing',
'processing',
[
'order_id' => $order->id,
'order_num' => $order->order_num,
'customer_email' => $user->email,
'amount' => $order->amount,
'has_addons' => $order->orderItems->some(function($item) {
return $item->addons->isNotEmpty();
})
]
);
// ✅ Dispatch job để xử lý thanh toán và tạo VM
\App\Jobs\VirtualMachine\ProcessOrderPaymentJob::dispatch($order)
->delay(now()->addSeconds(5));
return redirect()->route('invoice.index', $order->id)
->with('success', 'Đơn hàng đang được xử lý. Hệ thống sẽ khởi tạo máy ảo và trừ tiền khi hoàn thành. Bạn sẽ nhận được email thông báo kết quả.');
} catch (\Throwable $e) {
DB::rollBack();
Log::error('Lỗi xử lý đơn hàng: ' . $e->getMessage());
$discord->SendErrorMessage([
'error' => $e->getMessage(),
'order_id' => $order_id,
'order_num' => $order_num,
'customer_email' => $user->email
], 'InvoiceController - Order Processing Error');
return back()->with('error', 'Có lỗi xảy ra: ' . $e->getMessage());
}
}
}