180 lines
6.0 KiB
PHP
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());
|
|
}
|
|
}
|
|
|
|
}
|