This commit is contained in:
baodev0
2026-07-09 11:19:50 +07:00
parent 64232d9168
commit 61c0e026c8
28 changed files with 939 additions and 230 deletions
+66 -35
View File
@@ -81,6 +81,23 @@ class OrderQueryService
->first();
}
public function findCustomerInvoiceByNumber(int $customerId, string $invoiceNumber): ?Invoice
{
return Invoice::query()
->with([
'order.orderItems.product',
'order.vmWare.ipAddress',
'order.vmWare.os',
'customer',
'attachments',
'invoiceItems.product',
'services.product',
])
->where('customer_id', $customerId)
->where('invoice_number', $invoiceNumber)
->first();
}
public function findCustomerInvoiceByOrderNum(int $customerId, string $orderNumber): ?Order
{
return Order::query()
@@ -168,10 +185,8 @@ class OrderQueryService
public function renewService(int $serviceId, int $customerId, int $months): array
{
$customer = \App\Models\Customer::find($customerId);
$service = Service::query()
->with(['orderItem.product'])
->with(['orderItem.product', 'invoice'])
->where('id', $serviceId)
->where('customer_id', $customerId)
->whereNotIn('status', ['terminated', 'cancelled'])
@@ -188,35 +203,60 @@ class OrderQueryService
$price = (int) $orderItem->price * $months;
if ($customer->total < $price) {
return ['ok' => false, 'message' => sprintf('Số dư không đủ. Hiện có: %s VNĐ, cần: %s VNĐ.', number_format($customer->total), number_format($price)), 'code' => 400];
if ($service->invoice_id && Invoice::where('id', $service->invoice_id)
->where('invoice_type', 2)
->whereIn('status', [InvoiceStatus::UNPAID->value, InvoiceStatus::OVERDUE->value])
->exists()) {
$invoice = Invoice::find($service->invoice_id);
return [
'ok' => true,
'message' => 'Dịch vụ đã có hóa đơn gia hạn đang chờ thanh toán.',
'data' => [
'order_id' => $invoice?->order_id,
'invoice_id' => $invoice?->id,
'invoice_number' => $invoice?->invoice_number,
'total' => (float) ($invoice?->total ?? 0),
'status' => $invoice?->status,
'payment_url' => url('/client/invoices/' . $invoice?->invoice_number . '/payment'),
],
];
}
$needsVmStart = $service->vm_id !== null;
$invoice = DB::transaction(function () use ($customer, $service, $orderItem, $price, $months) {
$customer->total -= $price;
$customer->save();
\App\Models\Log::create([
'agent' => 'api',
$invoice = DB::transaction(function () use ($service, $orderItem, $price, $months) {
$order = Order::create([
'order_num' => OrderHelper::generateOrderNumber(),
'customer_id' => $service->customer_id,
'sub_total' => $price,
'discount_amount' => 0,
'total' => $price,
'status' => OrderStatus::PENDING->value,
'client_ip' => request()?->ip(),
'customer_id' => $customer->id,
'description' => sprintf('Gia hạn dịch vụ #%s. Số tiền: %s VNĐ. Số dư còn: %s VNĐ.', $service->server_name ?? $service->id, number_format($price), number_format($customer->total)),
'note' => 'Đơn hàng gia hạn dịch vụ #' . $service->id,
]);
OrderItem::create([
'order_id' => $order->id,
'product_id' => $service->product_id,
'billing_cycle' => $orderItem->billing_cycle,
'months' => $months,
'os_id' => $orderItem->os_id,
'quantity' => 1,
'server_name' => $service->server_name,
'price' => $price,
]);
$invoice = Invoice::create([
'invoice_number' => OrderHelper::generateOrderNumber('INV'),
'customer_id' => $customer->id,
'order_id' => null,
'customer_id' => $service->customer_id,
'order_id' => $order->id,
'invoice_type' => 2,
'sub_total' => $price,
'discount_amount' => 0,
'tax' => 0,
'total' => $price,
'status' => InvoiceStatus::PAID->value,
'paid_at' => now(),
'payment_method' => 'credit',
'status' => InvoiceStatus::UNPAID->value,
'due_date' => now()->addDays(7)->toDateString(),
]);
\App\Models\InvoiceItem::create([
@@ -230,30 +270,21 @@ class OrderQueryService
'total_price' => $price,
]);
$baseDate = $service->expires_at && $service->expires_at->isFuture() ? $service->expires_at : now();
$expiresAt = Carbon::parse($baseDate)->addMonths($months);
$service->update([
'status' => 'active',
'expires_at' => $expiresAt,
'suspended_at' => null,
'invoice_id' => $invoice->id,
]);
$service->update(['invoice_id' => $invoice->id]);
return $invoice;
});
if ($needsVmStart) {
dispatch(new VMJobs((int) $service->vm_id, 'Start', false))->delay(now()->addSeconds(5));
}
return [
'ok' => true,
'message' => 'Gia hạn thành công. Dịch vụ đã được kích hoạt lại.',
'message' => 'Đã tạo hóa đơn gia hạn. Vui lòng thanh toán để gia hạn dịch vụ.',
'data' => [
'order_id' => $invoice->order_id,
'invoice_id' => $invoice->id,
'invoice_number' => $invoice->invoice_number,
'total' => (float) $invoice->total,
'expires_at' => $service->fresh()?->expires_at?->toISOString(),
'status' => $invoice->status,
'payment_url' => url('/client/invoices/' . $invoice->invoice_number . '/payment'),
],
];
}