feat: email gửi tay/nhắc gia hạn, gói hosting, sửa dữ liệu sản phẩm
- Gửi email theo template cho 1 khách, tab lịch sử email, nhắc gia hạn dịch vụ hàng loạt - Mail lưu from/bcc/sent_by; mẫu MARKETING và mẫu cũ trong TemplateSeeder - Gói hosting: giới hạn, trạng thái, lấy plan Plesk qua CLI gateway - Backfill payment_method và ngày đơn hàng còn thiếu - Bổ sung field CPU/RAM/Disk/Băng thông cho loại sản phẩm vps và cloud Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8651dde6b1
commit
30898ea46f
@@ -13,6 +13,7 @@ use App\Jobs\Mail\Customer\OrderCreatedJob;
|
||||
use App\Jobs\VirtualMachine\Create\CreateVirtualMachineJob;
|
||||
use App\Jobs\VirtualMachine\Upgrade\UpgradeVirtualMachine;
|
||||
use App\Models\Customer;
|
||||
use App\Models\DomainPricing;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Payment;
|
||||
@@ -155,11 +156,15 @@ class OrderService
|
||||
|
||||
$orderData = [
|
||||
'order_num' => Helper::generateUniqueCode(),
|
||||
'date' => Carbon::today()->toDateString(),
|
||||
'customer_id' => $data['customer_id'],
|
||||
'discount_id' => $data['discount_id'] ?? null,
|
||||
'sub_total' => $total,
|
||||
'total' => $orderTotal,
|
||||
'payment_method' => $paymentRecord?->code ?? null,
|
||||
// `payment` has no `code` column. Store its primary key in the
|
||||
// legacy string column so the selected method can be resolved
|
||||
// consistently on both orders and invoices.
|
||||
'payment_method' => $paymentRecord?->id,
|
||||
'payment_proof' => $data['payment_proof'] ?? null,
|
||||
'user_id' => Auth::guard('admin')->id(),
|
||||
'status' => $effectiveOrderStatus,
|
||||
@@ -287,7 +292,20 @@ class OrderService
|
||||
};
|
||||
|
||||
$billingDetails = $this->calculateBillingDetails($item['billing']);
|
||||
$priceSelect = $item['price_custom'] ?? $product->price_sale ?? $product->price;
|
||||
$isDomain = $categoryType === ProductTypeEnums::DOMAIN;
|
||||
$billingMultiplier = $isDomain ? 1 : $billingDetails['billing'];
|
||||
|
||||
if ($isDomain) {
|
||||
$domainName = strtolower(trim((string) ($item['server_name'] ?? $item['domain'] ?? '')));
|
||||
if ($domainName === '') {
|
||||
throw new \InvalidArgumentException('Vui lòng nhập đầy đủ tên miền.');
|
||||
}
|
||||
|
||||
$domainPrice = DomainPricing::findByDomain($domainName)->orderPrice(1);
|
||||
$priceSelect = $item['price_custom'] ?? $domainPrice;
|
||||
} else {
|
||||
$priceSelect = $item['price_custom'] ?? $product->price_sale ?? $product->price;
|
||||
}
|
||||
|
||||
$billingCycle = ProductBillingCycle::fromLegacyCode((int) $item['billing']);
|
||||
$generalCode = Helper::generateUniqueCode();
|
||||
@@ -312,8 +330,8 @@ class OrderService
|
||||
'customer_id' => $data['customer_id'],
|
||||
'status' => 0,
|
||||
'name' => $item['server_name'] ?? $item['domain'] ?? $product->name,
|
||||
'first_payment' => $priceSelect * $billingDetails['billing'],
|
||||
'next_payment' => ($item['price_custom'] ?? $product->price) * $billingDetails['billing'],
|
||||
'first_payment' => $priceSelect * $billingMultiplier,
|
||||
'next_payment' => $priceSelect * $billingMultiplier,
|
||||
...$billingDetails,
|
||||
],
|
||||
];
|
||||
@@ -326,7 +344,7 @@ class OrderService
|
||||
}
|
||||
}
|
||||
|
||||
$total += $item['quantity'] * ($item['price_custom'] ?? ($product->price_sale ?? $product->price)) * $billingDetails['billing'];
|
||||
$total += $item['quantity'] * $priceSelect * $billingMultiplier;
|
||||
}
|
||||
|
||||
return [$productItems, $relIdData, $total];
|
||||
|
||||
Reference in New Issue
Block a user