ipdate
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
|
||||
/**
|
||||
* Renew VPS Service
|
||||
*/
|
||||
public function renew(Request $request)
|
||||
{
|
||||
try {
|
||||
$user = customer();
|
||||
if (!$user) {
|
||||
return redirect()->route('user.login')->with('error', __('Vui lòng đăng nhập.'));
|
||||
}
|
||||
|
||||
// 1. Validate Input
|
||||
$validator = FacadesValidator::make($request->all(), [
|
||||
'product_id' => 'required|string',
|
||||
'plan' => 'required',
|
||||
'months' => 'nullable|integer|min:2|max:60'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()->withErrors($validator)->withInput()->with('error', __('Dữ liệu không hợp lệ.'));
|
||||
}
|
||||
|
||||
$vmware_id = $this->sanitizeInput($request->product_id);
|
||||
$plan = $request->input('plan');
|
||||
$months = $plan === 'other' ? (int)$request->input('months') : (int)$plan;
|
||||
|
||||
if ($months < 2) {
|
||||
return redirect()->back()->with('error', __('Thời hạn gia hạn tối thiểu là 2 tháng.'));
|
||||
}
|
||||
|
||||
// 2. Find Service & Verify Ownership
|
||||
$vm = ModuleVmware::where('vmware_id', $vmware_id)
|
||||
->where('customer_id', $user->id)
|
||||
->first();
|
||||
|
||||
if (!$vm) {
|
||||
return redirect()->back()->with('error', __('Không tìm thấy dịch vụ hoặc bạn không có quyền truy cập.'));
|
||||
}
|
||||
|
||||
// 3. Calculate Price based on Original Order/InvoiceItem
|
||||
// Strategy: Find the InvoiceItem from the Order associated with this VM.
|
||||
// If multiple items, try to match type VPS (4).
|
||||
|
||||
$order = Order::find($vm->order_id);
|
||||
if (!$order) {
|
||||
// Fallback if order missing (rare)
|
||||
// Try finding by invoice_id if stored on VM? ModuleVmware has next_invoice but not current_invoice.
|
||||
return redirect()->back()->with('error', __('Không tìm thấy đơn hàng gốc của dịch vụ này.'));
|
||||
}
|
||||
|
||||
// Find InvoiceItem
|
||||
// Order has relationship to Invoice (order->invoice)
|
||||
// Or Order has orderItems (which are InvoiceItems)
|
||||
$invoiceItem = null;
|
||||
if ($order->invoice) {
|
||||
// Try finding item in the invoice related to this order
|
||||
// Note: The modal uses $invoice->invoiceItem->first(). We should try to be specific.
|
||||
// We don't have a direct link from ModuleVmware to InvoiceItem.
|
||||
// But ModuleVmware links to Order, which links to items.
|
||||
// Let's take the first item of type 4 (VPS) from the order's invoice.
|
||||
$invoiceItem = $order->invoice->invoiceItem->where('type_id', 4)->first();
|
||||
if (!$invoiceItem) {
|
||||
$invoiceItem = $order->invoice->invoiceItem->first();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$invoiceItem) {
|
||||
// Extreme fallback or failure
|
||||
return redirect()->back()->with('error', __('Không tìm thấy thông tin giá của dịch vụ.'));
|
||||
}
|
||||
|
||||
// Calculate Unit Price (Monthly)
|
||||
// 'amount' in InvoiceItem is total price for 'months' duration.
|
||||
$billing_months = $invoiceItem->months > 0 ? $invoiceItem->months : 1;
|
||||
if ($invoiceItem->amount <= 0) {
|
||||
// If amount is 0 (free?), unit price is 0.
|
||||
$base_unit_price = 0;
|
||||
} else {
|
||||
$base_unit_price = $invoiceItem->amount / $billing_months;
|
||||
}
|
||||
|
||||
// Calculate Addons Unit Price
|
||||
$addons_unit_price = 0;
|
||||
if ($invoiceItem->addons && $invoiceItem->addons->count() > 0) {
|
||||
foreach ($invoiceItem->addons as $addonPivot) {
|
||||
// Try to find price. Assuming Addon model has current price.
|
||||
// Ideally we should use the price stored in pivot if available, but pivot structure is unknown.
|
||||
// We'll use the Addon catalog price as fallback or primary if pivot doesn't store it.
|
||||
// $addonPivot->addonItems returns the Addon model.
|
||||
if ($addonPivot->addonItems) {
|
||||
$addons_unit_price += $addonPivot->addonItems->price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$total_unit_price = $base_unit_price + $addons_unit_price;
|
||||
$total_cost = $total_unit_price * $months;
|
||||
|
||||
// 4. Check Balance
|
||||
if ($user->credit < $total_cost) {
|
||||
return redirect()->back()->with('error', __('Số dư tài khoản không đủ để gia hạn (Cần: :amount). Vui lòng nạp thêm tiền.', ['amount' => number_format($total_cost) . ' VNĐ']));
|
||||
}
|
||||
|
||||
// 5. Process Renewal
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// Deduct Credit
|
||||
$user->decrement('credit', $total_cost);
|
||||
|
||||
// Create Renewal Invoice (Paid) - Optional but good for history
|
||||
$newInvoice = Invoice::create([
|
||||
'customer_id' => $user->id,
|
||||
'status' => 1, // Paid
|
||||
'date' => now(),
|
||||
'due_date' => now(),
|
||||
'total' => $total_cost,
|
||||
'payment_method' => 'credit_balance', // or similar
|
||||
'description' => "Gia hạn dịch vụ VPS #{$vm->name} ({$months} tháng)"
|
||||
]);
|
||||
|
||||
// Update VM Expiry
|
||||
// If current expiry is in the past, renew from NOW? Or from expiry?
|
||||
// Usually from expiry if it's recent grace period. If long expired, maybe from now.
|
||||
// Let's simply add to next_due_date.
|
||||
|
||||
$current_due = $vm->next_due_date ? \Carbon\Carbon::parse($vm->next_due_date) : now();
|
||||
if ($current_due->isPast()) {
|
||||
// If expired, maybe we should start from today?
|
||||
// Or just extend the gap. User usually pays for the gap.
|
||||
// Let's extend from current_due to maintain billing cycle.
|
||||
}
|
||||
$new_due_date = $current_due->copy()->addMonths($months);
|
||||
|
||||
$vm->update([
|
||||
'next_due_date' => $new_due_date,
|
||||
'status' => 1, // Ensure active if it was suspended
|
||||
]);
|
||||
|
||||
// Log or Notify (Optional)
|
||||
|
||||
DB::commit();
|
||||
|
||||
// Clear cache
|
||||
Cache::forget("vm_info_{$vm->vmware_id}");
|
||||
|
||||
return redirect()->back()->with('success', __('Gia hạn dịch vụ thành công! Hạn sử dụng mới: :date', ['date' => $new_due_date->format('d/m/Y')]));
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error("Error renewing VM: " . $e->getMessage());
|
||||
return redirect()->back()->with('error', __('Có lỗi xảy ra khi gia hạn dịch vụ. Vui lòng thử lại sau.'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user