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:
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Api\Domain;
|
||||
|
||||
use App\Models\Customer;
|
||||
use App\Models\Service;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Shared\Html;
|
||||
use PhpOffice\PhpWord\Writer\Word2007;
|
||||
|
||||
class DomainRegistrantService
|
||||
{
|
||||
/**
|
||||
* Registrant info for `$service`, pre-filled from the customer's profile
|
||||
* on first view. Once saved on the service, the saved data always wins.
|
||||
*
|
||||
* @return array{type: string, info: array<string, mixed>}
|
||||
*/
|
||||
public function get(Service $service, ?Customer $customer): array
|
||||
{
|
||||
if ($service->registrant_info) {
|
||||
return [
|
||||
'type' => $service->registrant_type ?? 'individual',
|
||||
'info' => $service->registrant_info,
|
||||
];
|
||||
}
|
||||
|
||||
$isOrganization = $customer && filled($customer->company);
|
||||
|
||||
return [
|
||||
'type' => $isOrganization ? 'organization' : 'individual',
|
||||
'info' => $isOrganization ? $this->defaultOrganizationInfo($customer) : $this->defaultIndividualInfo($customer),
|
||||
];
|
||||
}
|
||||
|
||||
public function update(Service $service, string $type, array $info): Service
|
||||
{
|
||||
$service->update([
|
||||
'registrant_type' => $type,
|
||||
'registrant_info' => $info,
|
||||
]);
|
||||
|
||||
return $service->fresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the VNNIC domain registration form as a .docx and return its binary contents.
|
||||
*/
|
||||
public function renderDocx(string $domainName, string $type, array $info): string
|
||||
{
|
||||
$view = $type === 'organization' ? 'domain.registrant-tochuc' : 'domain.registrant-canhan';
|
||||
$html = view($view, ['domain' => $domainName, 'r' => $info])->render();
|
||||
|
||||
$phpWord = new PhpWord();
|
||||
$phpWord->setDefaultFontName('Times New Roman');
|
||||
$phpWord->setDefaultFontSize(13);
|
||||
$section = $phpWord->addSection(['marginLeft' => 1000, 'marginRight' => 1000]);
|
||||
Html::addHtml($section, $html, false, false);
|
||||
|
||||
$writer = new Word2007($phpWord);
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'domain_reg_');
|
||||
$writer->save($tmp);
|
||||
$contents = file_get_contents($tmp);
|
||||
unlink($tmp);
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
private function defaultIndividualInfo(?Customer $customer): array
|
||||
{
|
||||
return [
|
||||
'fullname' => $customer?->fullname,
|
||||
'birth_date' => null,
|
||||
'identity_number' => $customer?->identity_number,
|
||||
'perm_address' => $customer?->address,
|
||||
'perm_ward' => $customer?->ward?->name,
|
||||
'perm_province' => $customer?->province?->name,
|
||||
'temp_address' => null,
|
||||
'temp_ward' => null,
|
||||
'temp_province' => null,
|
||||
'phone' => $customer?->phone,
|
||||
'email' => $customer?->email,
|
||||
'sign_place' => $customer?->province?->name,
|
||||
'sign_date' => now()->toDateString(),
|
||||
];
|
||||
}
|
||||
|
||||
private function defaultOrganizationInfo(?Customer $customer): array
|
||||
{
|
||||
$address = $customer?->address;
|
||||
$ward = $customer?->ward?->name;
|
||||
$province = $customer?->province?->name;
|
||||
|
||||
return [
|
||||
'org_name' => $customer?->company,
|
||||
'org_tax_code' => null,
|
||||
'org_address' => $address,
|
||||
'org_ward' => $ward,
|
||||
'org_province' => $province,
|
||||
'org_phone' => $customer?->phone,
|
||||
'org_email' => $customer?->email,
|
||||
|
||||
'manager_name' => $customer?->fullname,
|
||||
'manager_identity_number' => $customer?->identity_number,
|
||||
'manager_address' => $address,
|
||||
'manager_ward' => $ward,
|
||||
'manager_province' => $province,
|
||||
'manager_phone' => $customer?->phone,
|
||||
'manager_email' => $customer?->email,
|
||||
|
||||
'tech_name' => $customer?->fullname,
|
||||
'tech_address' => $address,
|
||||
'tech_ward' => $ward,
|
||||
'tech_province' => $province,
|
||||
'tech_phone' => $customer?->phone,
|
||||
'tech_email' => $customer?->email,
|
||||
|
||||
'payer_org_name' => $customer?->company,
|
||||
'payer_name' => $customer?->fullname,
|
||||
'payer_address' => $address,
|
||||
'payer_ward' => $ward,
|
||||
'payer_province' => $province,
|
||||
'payer_phone' => $customer?->phone,
|
||||
'payer_email' => $customer?->email,
|
||||
|
||||
'signer_title' => null,
|
||||
'sign_place' => $province,
|
||||
'sign_date' => now()->toDateString(),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user