feat: add domain registration form and email notifications
- Create a new Blade view for domain registration (`registrant-tochuc.blade.php`) to capture organization and manager details. - Implement email templates for new domain orders for both admin (`domain-order-new.blade.php`) and customers (`domain-order-received.blade.php`). - Add CSV exports for client and domain data. - Introduce tests for customer mass assignment, password reset, login throttling, and permission gating. - Ensure service renewals use current pricing and validate ownership for virtual machines. - Validate mass assignment behavior in service model.
This commit is contained in:
@@ -13,11 +13,11 @@ use App\Models\DnsDomain;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceItem;
|
||||
use App\Models\Log as CustomerActivityLog;
|
||||
use App\Models\DomainPricing;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Product;
|
||||
use App\Models\Service;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Transaction;
|
||||
use App\Repositories\Api\Domain\DomainOrderRepository;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -53,6 +53,10 @@ class DomainOrderService
|
||||
return DB::transaction(function () use ($customer, $product, $domainName, $price, $months, $years) {
|
||||
$lockedCustomer = Customer::lockForUpdate()->find($customer->id);
|
||||
|
||||
if (!$lockedCustomer->front_identity_number || !$lockedCustomer->back_identity_number) {
|
||||
throw new \InvalidArgumentException('Vui lòng bổ sung ảnh CMND/CCCD (2 mặt) trước khi đặt mua tên miền.');
|
||||
}
|
||||
|
||||
if ((int) $lockedCustomer->total < $price) {
|
||||
throw new \InvalidArgumentException('Số dư không đủ để đặt mua tên miền. Vui lòng nạp thêm tiền vào tài khoản.');
|
||||
}
|
||||
@@ -367,29 +371,7 @@ class DomainOrderService
|
||||
*/
|
||||
private function findDomainPricing(string $domain): array
|
||||
{
|
||||
$setting = Setting::where('key', 'domain_pricing')->first();
|
||||
|
||||
if (!$setting || empty($setting->value)) {
|
||||
throw new \InvalidArgumentException('Không tìm thấy cấu hình giá tên miền.');
|
||||
}
|
||||
|
||||
$pricingData = is_string($setting->value)
|
||||
? json_decode($setting->value, true)
|
||||
: (array) $setting->value;
|
||||
|
||||
$domains = $pricingData['domains'] ?? [];
|
||||
|
||||
// Longest-match: sort TLDs by length descending so ".com.vn" beats ".vn"
|
||||
usort($domains, fn ($a, $b) => strlen($b['tld']) - strlen($a['tld']));
|
||||
|
||||
foreach ($domains as $entry) {
|
||||
$tld = ltrim($entry['tld'], '.');
|
||||
if (str_ends_with($domain, '.' . $tld)) {
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException("Tên miền không được hỗ trợ. Vui lòng chọn đuôi tên miền có trong danh sách.");
|
||||
return DomainPricing::findByDomain($domain)->toDomainArray();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user