feat(Customer): Crée espace client, ajoute relation compte, envoie email.

This commit is contained in:
Serreau Jovann
2025-10-09 13:28:09 +02:00
parent 1931ae08e5
commit d996d3beaf
8 changed files with 187 additions and 3 deletions

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20251009110742 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE customer ADD account_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE customer ADD CONSTRAINT FK_81398E099B6B5FBA FOREIGN KEY (account_id) REFERENCES "account" (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_81398E099B6B5FBA ON customer (account_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE customer DROP CONSTRAINT FK_81398E099B6B5FBA');
$this->addSql('DROP INDEX IDX_81398E099B6B5FBA');
$this->addSql('ALTER TABLE customer DROP account_id');
}
}

View File

@@ -5,7 +5,8 @@ namespace App\Controller\Artemis\Intranet;
use App\Service\Echeance\EventEcheanceCreated;
use App\Service\Pdf\EmailListPdf;
use App\Service\Pdf\PaymentPdf;
use App\Entity\{Customer,
use App\Entity\{Account,
Customer,
CustomerAdvertPayment,
CustomerAdvertPaymentLine,
CustomerContact,
@@ -43,6 +44,7 @@ use App\Service\Customer\{CreateAvisEvent,
CreateFactureEvent,
CustomerSendPasswordEmail,
DeleteCustomerEvent,
EventSpaceCustomerCreated,
PdfList\SendPdfEmailListEvent,
RestoreCustomerEvent};
use App\Service\Logger\LoggerService;
@@ -56,6 +58,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Uid\Uuid;
@@ -183,6 +186,8 @@ class CustomerController extends AbstractController
VaultClient $vaultClient,
PaginatorInterface $paginator,
KernelInterface $kernel,
PasswordGenerator $passwordGenerator,
UserPasswordHasherInterface $userPasswordHasher,
Client $client,
?Customer $customer,
CustomerDnsRepository $customerDnsRepository,
@@ -631,8 +636,30 @@ class CustomerController extends AbstractController
}
}
$ev = new EventEcheanceCreated($splitList[0]);
$eventDispatcher->dispatch($ev);
if($request->query->has('act') && $request->query->get('act') == "enableSpaceAccount") {
$account = $entityManager->getRepository(Account::class)->findOneBy(['email'=>$customer->mainContact()->getEmail()]);
if($account instanceof Account) {
$this->addFlash("danger","Le compte client existe déja ! ");
return $this->redirectToRoute('artemis_intranet_customer_view', ['id' => $customer->getId()]);
}
$password = $passwordGenerator->generate();
$account = new Account();
$account->setEmail($customer->mainContact()->getEmail());
$account->setRoles(['ROLE_CUSTOMER']);
$account->setUsername($customer->mainContact()->getEmail());
$account->setUuid(Uuid::v4());
$account->setIsActif(true);
$account->setIsFirstLogin(true);
$account->setPassword($userPasswordHasher->hashPassword($account, $password));
$account->addCustomer($customer);
$entityManager->persist($account);
//event advert customer created space account
$event = new EventSpaceCustomerCreated($account,$password);
$eventDispatcher->dispatch($event);
dd($account,$password);
}
return $this->render('artemis/intranet/customer/edit.twig', [
'form' => $form->createView(),
@@ -640,6 +667,7 @@ class CustomerController extends AbstractController
'formNddEmail' => $formNddEmail->createView(),
'customer' => $customer,
'ndd' => $customerNdd,
'isAccountCreated' => $customer->getAccount() instanceof Account,
'nddEmails' => $nddEmails,
'splitList' => $paginator->paginate($splitList, $request->query->getInt('page', 1), 10),
'orderDevis' => $paginator->paginate($orderDevis, $request->query->getInt('page', 1), 20),

View File

@@ -0,0 +1,16 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class CustomerController extends AbstractController
{
#[Route(path: '/customer',name: 'app_customer_login')]
public function customerLogin(): Response
{
}
}

View File

@@ -74,10 +74,17 @@ class Account implements UserInterface, PasswordAuthenticatedUserInterface, \Ser
#[ORM\Column(nullable: true)]
private ?bool $isActif = null;
/**
* @var Collection<int, Customer>
*/
#[ORM\OneToMany(targetEntity: Customer::class, mappedBy: 'account')]
private Collection $customers;
public function __construct()
{
$this->accountLoginRegisters = new ArrayCollection();
$this->customers = new ArrayCollection();
}
public function getId(): ?int
@@ -333,4 +340,34 @@ class Account implements UserInterface, PasswordAuthenticatedUserInterface, \Ser
return $this;
}
/**
* @return Collection<int, Customer>
*/
public function getCustomers(): Collection
{
return $this->customers;
}
public function addCustomer(Customer $customer): static
{
if (!$this->customers->contains($customer)) {
$this->customers->add($customer);
$customer->setAccount($this);
}
return $this;
}
public function removeCustomer(Customer $customer): static
{
if ($this->customers->removeElement($customer)) {
// set the owning side to null (unless already changed)
if ($customer->getAccount() === $this) {
$customer->setAccount(null);
}
}
return $this;
}
}

View File

@@ -114,6 +114,9 @@ class Customer
#[ORM\OneToMany(targetEntity: CustomerSplit::class, mappedBy: 'customer')]
private Collection $customerSplits;
#[ORM\ManyToOne(inversedBy: 'customers')]
private ?Account $account = null;
public function __clone(): void
{
@@ -581,4 +584,16 @@ class Customer
return $this;
}
public function getAccount(): ?Account
{
return $this->account;
}
public function setAccount(?Account $account): static
{
$this->account = $account;
return $this;
}
}

View File

@@ -38,6 +38,7 @@ use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
#[AsEventListener(event: CreateFactureEventSend::class, method: 'onCreateFactureEventSend')]
#[AsEventListener(event: SiteconseilAdvertPaymentComplete::class, method: 'onSiteconseilAdvertPaymentComplete')]
#[AsEventListener(event: CustomerAdvertPaymentComplete::class, method: 'onCustomerAdvertPaymentComplete')]
#[AsEventListener(event: EventSpaceCustomerCreated::class, method: 'onEventSpaceCustomerCreated')]
class BillingEventSusbriber
{
@@ -53,6 +54,19 @@ class BillingEventSusbriber
){
}
public function onEventSpaceCustomerCreated(EventSpaceCustomerCreated $event): void
{
$account = $event->getAccount();
$password = $account->getPassword();
$this->mailer->send($account->getEmail(),$account->getEmail(),"[SARL SITECONSEIL] - Création de votre espace client","mails/customer/created_space_customer.twig",[
'account' => $account,
'password' => $password,
'url' => $this->urlGenerator->generate('app_customer_login',[],UrlGeneratorInterface::ABSOLUTE_URL),
]);
}
public function onSiteconseilAdvertPaymentComplete(SiteconseilAdvertPaymentComplete $advertPaymentComplete): void
{
/** @var CustomerAdvertPayment $currentAdvert */

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Service\Customer;
use App\Entity\Account;
class EventSpaceCustomerCreated
{
public function __construct(private Account $account,private string $password)
{
}
/**
* @return string
*/
public function getPassword(): string
{
return $this->password;
}
/**
* @return Account
*/
public function getAccount(): Account
{
return $this->account;
}
}

View File

@@ -58,3 +58,13 @@
{{ form_end(form) }}
</div>
{% if isAccountCreated %}
{% else %}
<div class="mt-5 bg-gray-800 rounded-lg shadow-lg p-6 space-y-4">
<h3 class="text-red-300 text-weight-bold text-center">/!\ Le client ne dispose pas espace client /!\</h3>
<a href="{{ path('artemis_intranet_customer_view',{id:customer.id,act:'enableSpaceAccount'}) }}" class="text-center block w-full bg-purple-600 hover:bg-purple-700 text-white font-semibold px-4 py-2 rounded w-100">Crée l'espace client</a>
</div>
{% endif %}