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:
baodev0
2026-08-22 17:30:55 +07:00
parent eec2c5906e
commit c377c7e195
58 changed files with 3063 additions and 418 deletions
@@ -31,6 +31,7 @@ use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use App\Enums\Invoice\InvoiceStatus;
use App\Enums\Order\OrderStatus;
use App\Enums\TransactionStatus;
use App\Helpers\OrderHelper;
class CustomerController extends Controller
@@ -73,8 +74,6 @@ class CustomerController extends Controller
public function store(CreateCustomerRequest $request): JsonResponse
{
$request->validated();
$existingCustomer = $this->customerRepository->findBy('email', $request->get('email'));
if ($existingCustomer) {
return response()->json([
@@ -85,7 +84,7 @@ class CustomerController extends Controller
try {
DB::beginTransaction();
$data = $request->all();
$data = $request->validated();
$data['password'] = Hash::make($request->password);
$data['email_marketing'] = $request->email_marketing === "on" ? 1 : 0;
@@ -170,11 +169,10 @@ class CustomerController extends Controller
], 404);
}
$request->validated();
try {
DB::beginTransaction();
$data = $request->except(['_token', 'password']);
$data = $request->validated();
unset($data['password']);
if (!empty($request->password)) {
$data['password'] = Hash::make($request->password);
@@ -413,10 +411,15 @@ class CustomerController extends Controller
$this->customerRepository->update($customer->id, ['password' => Hash::make($password)]);
DB::commit();
Mail::to($customer->email)->send(new \App\Mail\Customer\PasswordResetByAdmin([
'fullname' => $customer->fullname,
'email' => $customer->email,
'password' => $password,
]));
return response()->json([
'error' => false,
'message' => 'Password reset successfully',
'data' => ['new_password' => $password]
'message' => 'Password reset successfully, new password has been sent to customer email',
]);
} catch (\Exception $e) {
DB::rollBack();
@@ -616,12 +619,15 @@ class CustomerController extends Controller
], 404);
}
$admin = Auth::guard('admin')->user();
try {
DB::beginTransaction();
$amount = (int) $request->amount;
if ($request->action === "+") {
$isAdd = $request->action === "+";
if ($isAdd) {
$this->customerRepository->update($customer->id, [
'credit' => (int) $customer->credit + $amount,
'total' => (int) $customer->total + $amount,
@@ -633,6 +639,22 @@ class CustomerController extends Controller
]);
}
Transaction::create([
'uuid' => (string) Str::uuid(),
'trans' => 'ADMIN' . now()->format('YmdHis'),
'amount' => $amount,
'customer_id' => $customer->id,
'user_id' => $admin?->id,
'status' => TransactionStatus::COMPLETED->value,
'type' => $isAdd ? 'admin_add_credit' : 'admin_deduct_credit',
'note' => sprintf(
'%s %s tiền trực tiếp cho khách hàng: %s VNĐ',
$admin->username ?? $admin->email ?? 'Admin',
$isAdd ? 'cộng' : 'trừ',
number_format($amount)
),
]);
DB::commit();
return response()->json([