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
+30 -16
View File
@@ -12,7 +12,7 @@ use App\Http\Controllers\Api\Admin\Customer\CustomerController;
use App\Http\Controllers\Api\Admin\Employee\EmployeeController;
use App\Http\Controllers\Api\Admin\Role\RolePermissionController;
use App\Http\Controllers\Api\Admin\Invoice\InvoiceController;
use App\Http\Controllers\Api\Admin\Invoice\InvoiceTestController;
use App\Http\Controllers\Api\Admin\Report\ExportController;
use App\Http\Controllers\Api\Admin\Order\OrderController;
use App\Http\Controllers\Api\Admin\Payment\PaymentController;
use App\Http\Controllers\Api\Admin\Addon\AddonController;
@@ -50,7 +50,6 @@ use App\Models\ModuleVmware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Barryvdh\DomPDF\Facade\Pdf;
/*
|--------------------------------------------------------------------------
@@ -64,24 +63,16 @@ use Barryvdh\DomPDF\Facade\Pdf;
*/
Route::prefix('v1')
->group(function () {
// Invoice Test — Send invoice email with PDF attachment
Route::prefix('invoice-test')
->controller(InvoiceTestController::class)
->group(function () {
Route::post('{invoiceNumber}/send-email', 'sendInvoiceEmail');
Route::get('{invoiceNumber}/preview-pdf', 'previewInvoicePdf');
});
})
/* Api for Admin */
->group(function () {
Route::prefix('administrator')->group(function () {
Route::post('login', [AuthController::class, 'login']);
Route::post('login', [AuthController::class, 'login'])->middleware('throttle:5,1');
Route::middleware('api.auth:admin')->group(function () {
Route::post('logout', [AuthController::class, 'logout']);
Route::post('refresh', [AuthController::class, 'refresh']);
Route::get('me', [AuthController::class, 'me']);
Route::put('profile', [AuthController::class, 'updateProfile']);
// Role Permissions
Route::prefix('role-permissions')->group(function () {
@@ -89,6 +80,7 @@ Route::prefix('v1')
Route::get('mine', [RolePermissionController::class, 'mine']);
// Các endpoint sau chỉ dành cho Full Administrator (kiểm tra trong controller)
Route::get('/', [RolePermissionController::class, 'index']);
Route::post('/', [RolePermissionController::class, 'store']);
Route::get('all-permissions', [RolePermissionController::class, 'allPermissions']);
Route::post('permissions', [RolePermissionController::class, 'createPermissionGroup']);
Route::delete('permissions/group/{module}', [
@@ -327,6 +319,18 @@ Route::prefix('v1')
Route::post('{id}/send-mail', 'sendMail')->middleware('perm:invoice.edit');
});
// Reports / Data exports
Route::prefix('reports/export')
->controller(ExportController::class)
->middleware('perm:report.view')
->group(function () {
Route::get('history', 'history');
Route::post('preview', 'preview');
Route::post('/', 'store');
Route::get('{uuid}', 'show');
Route::get('{uuid}/download', 'download');
});
// Payments (module: payment)
Route::prefix('payments')
->controller(PaymentController::class)
@@ -471,11 +475,15 @@ Route::prefix('v1')
Route::patch('{id}/kyc', 'updateKyc')->middleware('perm:order.edit');
Route::patch('{id}/activate', 'activate')->middleware('perm:order.edit');
Route::post('{id}/reject-and-refund', 'rejectAndRefund')->middleware('perm:order.edit');
Route::get('{id}/registrant', 'getRegistrant')->middleware('perm:order.view');
Route::patch('{id}/registrant', 'updateRegistrant')->middleware('perm:order.edit');
Route::get('{id}/registrant/docx', 'downloadRegistrantDocx')->middleware('perm:order.view');
});
// Domain Pricing (module: settings)
Route::prefix('domain-pricing')
->controller(AdminDomainPricingController::class)
->middleware('perm:setting.manager')
->group(function () {
Route::get('/', 'index');
Route::put('/', 'update');
@@ -496,6 +504,7 @@ Route::prefix('v1')
// Settings (module: administrator)
Route::prefix('settings')
->controller(AdminSettingController::class)
->middleware('perm:setting.manager')
->group(function () {
Route::get('/', 'index');
Route::put('/', 'update');
@@ -577,6 +586,7 @@ Route::prefix('v1')
// Banks — deposit bank accounts (module: settings)
Route::prefix('banks')
->controller(BankController::class)
->middleware('perm:setting.manager')
->group(function () {
Route::get('/', 'index');
Route::post('/', 'store');
@@ -588,6 +598,7 @@ Route::prefix('v1')
// Email Templates (module: settings)
Route::prefix('email-templates')
->controller(EmailTemplateController::class)
->middleware('perm:email-template.manager')
->group(function () {
Route::get('/', 'index');
Route::post('/', 'store');
@@ -602,6 +613,7 @@ Route::prefix('v1')
// Notification Email Templates — block-based editor
Route::prefix('notification-templates')
->controller(EmailNotificationTemplateController::class)
->middleware('perm:email-template.manager')
->group(function () {
Route::get('/', 'index');
Route::post('/', 'store');
@@ -658,10 +670,10 @@ Route::prefix('v1')
Route::prefix('tickets')
->controller(AdminTicketController::class)
->group(function () {
Route::get('/', 'index');
Route::get('{ticket_num}', 'show');
Route::patch('{ticket_num}/status', 'updateStatus');
Route::post('{ticket_num}/reply', 'reply');
Route::get('/', 'index')->middleware('perm:support.view');
Route::get('{ticket_num}', 'show')->middleware('perm:support.view');
Route::patch('{ticket_num}/status', 'updateStatus')->middleware('perm:support.edit');
Route::post('{ticket_num}/reply', 'reply')->middleware('perm:support.edit');
});
Route::prefix('notifications')
@@ -685,6 +697,7 @@ Route::prefix('v1')
// Activity Logs
Route::prefix('activity-logs')
->controller(ActivityLogController::class)
->middleware('perm:system-log.manager')
->group(function () {
Route::get('/', 'index');
Route::get('modules', 'modules');
@@ -695,6 +708,7 @@ Route::prefix('v1')
// Email Logs
Route::prefix('email-logs')
->controller(EmailLogController::class)
->middleware('perm:system-log.manager')
->group(function () {
Route::get('/', 'index');
Route::get('{id}', 'show')->whereNumber('id');