- Added UnsubscribeFromNewsletter action and input/output classes. - Introduced CrmHashcode value object and its cast. - Updated NewsletterController to use the new unsubscribe action. - Enhanced validation in UnsubscribeNewsletterRequest.
127 lines
4.3 KiB
PHP
127 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Contracts\Repositories\EmployeeRepository;
|
|
use App\Exceptions\Crm\CrmCustomerExistsException;
|
|
use App\Exceptions\CrmServiceException;
|
|
use App\Models\Customer;
|
|
use Domain\Enums\Country;
|
|
use Domain\Models\ValueObjects\Code;
|
|
use Domain\Models\ValueObjects\CrmCustomer;
|
|
use Domain\Models\ValueObjects\Email;
|
|
use Domain\Models\ValueObjects\Matricule;
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Infrastructure\Adapters\Services\AppCustomerAuthService;
|
|
use Ramsey\Uuid\Uuid;
|
|
use Shared\ValueObjects\CrmHashcode;
|
|
use UnexpectedValueException;
|
|
|
|
class CustomerRegistrationService
|
|
{
|
|
public function __construct(
|
|
private readonly AppCustomerAuthService $authService,
|
|
private readonly CrmService $crmService,
|
|
private readonly EmployeeRepository $employeeRepository
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @param array{
|
|
* matricule:string,
|
|
* code:string,
|
|
* lastname:string,
|
|
* firstname:string,
|
|
* phone:string|null,
|
|
* address:string|null,
|
|
* postal_code:string,
|
|
* city:string,
|
|
* email:string,
|
|
* password:string,
|
|
* optin:bool,
|
|
* birth_date:\DateTimeImmutable
|
|
* } $data
|
|
*
|
|
* @throws ValidationException
|
|
* @throws UnexpectedValueException
|
|
*/
|
|
public function registerCustomer(array $data): void
|
|
{
|
|
DB::transaction(function () use ($data) {
|
|
$requestMatricule = $data['matricule'];
|
|
$requestCode = $data['code'];
|
|
|
|
// * Persist and associate Customer + Salarie
|
|
$customer = new Customer([
|
|
'email' => new Email($data['email']),
|
|
]);
|
|
// * Temp hashcode to satisfy constraint
|
|
$customer->hashcode = new CrmHashcode(Uuid::uuid4());
|
|
$customer->saveOrFail();
|
|
|
|
$employee = $this->employeeRepository
|
|
->findByMatriculeAndCode(
|
|
new Matricule($requestMatricule),
|
|
new Code($requestCode)
|
|
);
|
|
|
|
if (! $employee) {
|
|
throw new ModelNotFoundException('Employee not found');
|
|
}
|
|
|
|
$employee->customer()->associate($customer);
|
|
$employee->saveOrFail();
|
|
|
|
$phone = Arr::get($data, 'phone');
|
|
$address = Arr::get($data, 'address');
|
|
|
|
$crmCustomer = new CrmCustomer(
|
|
hashcode: null,
|
|
email: Arr::string($data, 'email'),
|
|
password: Arr::string($data, 'password'),
|
|
firstname: Arr::string($data, 'firstname'),
|
|
lastname: Arr::string($data, 'lastname'),
|
|
birthDate: $data['birth_date']->format('Y-m-d'),
|
|
phone: is_string($phone) ? $phone : null,
|
|
address: is_string($address) ? $address : null,
|
|
address2: null,
|
|
city: Arr::string($data, 'city'),
|
|
postcode: Arr::string($data, 'postal_code'),
|
|
country: Country::france,
|
|
optIn: Arr::boolean($data, 'optin'),
|
|
status: false,
|
|
lastConnection: null,
|
|
);
|
|
|
|
try {
|
|
$result = $this->crmService->persist($crmCustomer);
|
|
|
|
if (! $result->hashcode) {
|
|
throw new UnexpectedValueException(
|
|
'CRM did not return a hashcode for the created customer'
|
|
);
|
|
}
|
|
$customer->hashcode = new CrmHashcode(Uuid::uuid4());
|
|
$customer->saveOrFail();
|
|
|
|
$customer->sendEmailVerificationNotification();
|
|
|
|
$this->authService->logIn($customer);
|
|
} catch (CrmCustomerExistsException $e) {
|
|
throw ValidationException::withMessages([
|
|
'error' => trans('An account is already associated with this email address'),
|
|
]);
|
|
} catch (CrmServiceException $e) {
|
|
report($e);
|
|
throw ValidationException::withMessages([
|
|
'error' => trans('An error has occurred. Please try again later'),
|
|
]);
|
|
}
|
|
});
|
|
}
|
|
}
|