CompanyRegistrationController
extends AbstractController
in package
Contrôleur du tunnel d'inscription d'une entreprise à l'offre B-Card.
Il orchestre un parcours en cinq étapes : saisie de l'identité du contact et création du compte
(ROLE_MANAGER), vérification de l'adresse email par code, renseignement des informations de
l'entreprise, choix de l'abonnement au plan « Entreprise » puis paiement par Stripe Checkout et
confirmation. L'état intermédiaire du parcours n'est pas persisté en base mais conservé en session par
CompanyRegistrationService ; l'entreprise, l'abonnement et le mot de passe définitif
ne sont créés qu'au retour d'un paiement effectivement encaissé, le mot de passe temporaire étant alors
envoyé par email au gestionnaire.
Préfixe de route : /company. Aucun contrôle d'accès au niveau de la classe : le parcours est public
puisqu'il précède l'existence d'un compte utilisable.
Attributes
- #[Route]
- '/company'
Table of Contents
Properties
- $auditLogger : AuditLogger
- $emailVerificationService : EmailVerificationService
- $entityManager : EntityManagerInterface
- $mailerService : MailerService
- $passwordHasher : UserPasswordHasherInterface
- $paymentService : PaymentService
- $planRepository : PlanRepository
- $registrationService : CompanyRegistrationService
- $stripeService : StripeService
- $userRepository : UserRepository
- $validator : ValidatorInterface
Methods
- __construct() : mixed
- calculateAmount() : Response
- AJAX endpoint for calculating subscription amount
- cancel() : Response
- Cancel registration process
- confirmation() : Response
- Step 5: Confirmation and Final Processing
- details() : Response
- Step 2: Company Details (after email verification)
- payment() : Response
- Step 4: Payment and Address Information
- paymentCancel() : Response
- Handle cancelled Stripe payment
- paymentProcess() : Response
- Enregistre le moyen de paiement choisi et déclenche le paiement correspondant.
- paymentSuccess() : Response
- Handle successful Stripe payment
- register() : Response
- Step 1: Company Details Registration
- resendVerification() : Response
- Renvoie un code de vérification d'email au contact de l'entreprise.
- subscription() : Response
- Step 3: Subscription Selection
- verifyEmail() : Response
- Affiche l'écran de saisie du code de vérification d'email et le valide.
- redirectToStripeCheckout() : Response
- Redirect to Stripe Checkout for subscription payment
- sendTemporaryPasswordEmail() : void
- Send temporary password email to user
Properties
$auditLogger read-only
private
AuditLogger
$auditLogger
$emailVerificationService read-only
private
EmailVerificationService
$emailVerificationService
$entityManager read-only
private
EntityManagerInterface
$entityManager
$mailerService read-only
private
MailerService
$mailerService
$passwordHasher read-only
private
UserPasswordHasherInterface
$passwordHasher
$paymentService read-only
private
PaymentService
$paymentService
$planRepository read-only
private
PlanRepository
$planRepository
$registrationService read-only
private
CompanyRegistrationService
$registrationService
$stripeService read-only
private
StripeService
$stripeService
$userRepository read-only
private
UserRepository
$userRepository
$validator read-only
private
ValidatorInterface
$validator
Methods
__construct()
public
__construct(CompanyRegistrationService $registrationService, PaymentService $paymentService, StripeService $stripeService, PlanRepository $planRepository, EmailVerificationService $emailVerificationService, UserRepository $userRepository, ValidatorInterface $validator, UserPasswordHasherInterface $passwordHasher, EntityManagerInterface $entityManager, MailerService $mailerService, AuditLogger $auditLogger) : mixed
Parameters
- $registrationService : CompanyRegistrationService
-
Conserve en session les données du parcours et finalise l'inscription.
- $paymentService : PaymentService
-
Calcule et formate le montant de l'abonnement selon le plan, le cycle et l'effectif.
- $stripeService : StripeService
-
Crée et relit les sessions Stripe Checkout.
- $planRepository : PlanRepository
-
Charge les plans d'abonnement, notamment le plan « Entreprise » actif.
- $emailVerificationService : EmailVerificationService
-
Envoie et valide les codes de vérification d'email.
- $userRepository : UserRepository
-
Recherche les utilisateurs par identifiant ou par email.
- $validator : ValidatorInterface
-
Valide l'adresse email saisie à la première étape.
- $passwordHasher : UserPasswordHasherInterface
-
Hache le mot de passe temporaire du compte gestionnaire créé.
- $entityManager : EntityManagerInterface
-
Gestionnaire d'entités Doctrine (persistance de l'utilisateur).
- $mailerService : MailerService
-
Envoie l'email contenant les identifiants de connexion.
- $auditLogger : AuditLogger
-
Trace la création ou la mise à jour du compte gestionnaire.
calculateAmount()
AJAX endpoint for calculating subscription amount
public
calculateAmount(Request $request) : Response
Calcule à la volée le montant d'un abonnement pour l'affichage dynamique du tunnel.
Lit plan_id, billing_cycle et employee_count (converti en entier, 1 par défaut) dans le corps de
la requête, puis délègue le calcul et le formatage au service de paiement. Aucune donnée n'est
modifiée ni stockée en session : le résultat sert uniquement à rafraîchir l'affichage côté client.
Route : /company/calculate-amount (POST), nom company_calculate_amount.
Parameters
- $request : Request
-
Requête HTTP contenant
plan_id,billing_cycleetemployee_count.
Attributes
- #[Route]
- '/calculate-amount'
- $name: 'company_calculate_amount'
- $methods: ['POST']
Return values
Response —Réponse JSON array{success: true, amount: mixed, formatted_amount: string} en
HTTP 200, ou array{success: false, message: string} en HTTP 400 si le calcul lève
une exception (plan inconnu, cycle invalide, etc.).
cancel()
Cancel registration process
public
cancel() : Response
Annule volontairement le tunnel d'inscription en cours.
Vide les données du parcours stockées en session et informe l'utilisateur. Le compte utilisateur éventuellement créé à l'étape 1 et déjà persisté en base n'est pas supprimé.
Route : /company/cancel (POST), nom company_registration_cancel.
Attributes
- #[Route]
- '/cancel'
- $name: 'company_registration_cancel'
- $methods: ['POST']
Return values
Response —Redirection vers app_home.
confirmation()
Step 5: Confirmation and Final Processing
public
confirmation() : Response
Étape 5 du tunnel : affiche le récapitulatif final de l'inscription.
Relit les données d'entreprise et d'utilisateur conservées en session et les fusionne en injectant l'email et le nom du contact dans le tableau transmis au template. Malgré son intitulé, la méthode n'effectue aucun traitement final : la création effective de l'entreprise est réalisée par CompanyRegistrationController::paymentSuccess() au retour de Stripe. Aucune vérification de présence des données n'est faite, la page peut donc être atteinte avec un contexte vide.
Route : /company/confirmation (GET, POST), nom company_confirmation.
Attributes
- #[Route]
- '/confirmation'
- $name: 'company_confirmation'
- $methods: ['GET', 'POST']
Return values
Response —Page de confirmation rendue (company/registration/confirmation.html.twig, étape 5/5).
details()
Step 2: Company Details (after email verification)
public
details(Request $request, int $user_id, SessionInterface $session) : Response
Étape 2 du tunnel : collecte les informations de l'entreprise et du contact.
L'accès exige un utilisateur existant ET vérifié, sinon retour à l'étape 1 ; si le compte est déjà
rattaché à une entreprise, le parcours est interrompu au profit du tableau de bord. Les données de
l'utilisateur sont poussées en session par le service d'inscription, et le formulaire est pré-alimenté
avec le contenu déjà présent sous la clé de session company_registration, complété de l'email et du
nom du contact. À la soumission valide, la position et le téléphone du contact sont écrits sur
l'entité User et immédiatement persistés, tandis qu'un objet Company est
seulement hydraté puis stocké en session — l'entreprise n'est pas encore enregistrée en base à ce
stade.
Route : /company/details/{user_id} (GET, POST), nom company_details.
Parameters
- $request : Request
-
Requête HTTP portant le formulaire CompanyDetailsType.
- $user_id : int
-
Identifiant du contact/gestionnaire à l'origine de l'inscription.
- $session : SessionInterface
-
Session utilisée pour relire les données d'inscription déjà saisies.
Attributes
- #[Route]
- '/details/{user_id}'
- $name: 'company_details'
- $methods: ['GET', 'POST']
Return values
Response —Redirection vers company_register ou app_dashboard selon les contrôles d'accès,
vers company_subscription après soumission valide, sinon le formulaire rendu
(company/registration/details.html.twig, étape 2/5).
payment()
Step 4: Payment and Address Information
public
payment() : Response
Étape 4 du tunnel : récapitule la commande avant le choix du moyen de paiement.
Les données d'abonnement sont relues en session ; leur absence interrompt le parcours et renvoie à
l'étape 1. Le nom du plan est résolu depuis son identifiant (repli sur « Entreprise » si le plan n'est
plus trouvé) et le montant est formaté en francs guinéens (séparateur décimal virgule, séparateur de
milliers espace, suffixe GNF). Aucune donnée n'est modifiée ni persistée.
Route : /company/payment (GET, POST), nom company_payment.
Attributes
- #[Route]
- '/payment'
- $name: 'company_payment'
- $methods: ['GET', 'POST']
Return values
Response —Redirection vers company_register si les données de souscription manquent, sinon la
page de paiement rendue (company/registration/payment.html.twig, étape 4/5).
paymentCancel()
Handle cancelled Stripe payment
public
paymentCancel() : Response
Traite le retour de Stripe lorsque l'utilisateur abandonne le paiement.
Purge intégralement les données du parcours conservées en session, puis affiche un avertissement invitant à réessayer. À noter : la session étant vidée, la page de paiement vers laquelle l'utilisateur est renvoyé ne retrouvera plus les données de souscription et le renverra à son tour vers le début du tunnel.
Route : /company/payment/cancel (GET), nom company_registration_payment_cancel.
Attributes
- #[Route]
- '/payment/cancel'
- $name: 'company_registration_payment_cancel'
- $methods: ['GET']
Return values
Response —Redirection vers company_payment.
paymentProcess()
Enregistre le moyen de paiement choisi et déclenche le paiement correspondant.
public
paymentProcess(Request $request) : Response
Seules les valeurs card et orange_money sont acceptées ; toute autre valeur est journalisée et
ramène à la page de paiement avec un message d'erreur. Le choix est conservé en session, puis le
paiement par carte est délégué à CompanyRegistrationController::redirectToStripeCheckout().
Orange Money n'est pas encore implémenté : l'utilisateur est informé par un message d'information et
renvoyé à l'accueil, ce qui interrompt le tunnel sans annuler les données stockées en session.
Route : /company/payment-process (POST), nom company_registration_payment_process.
Parameters
- $request : Request
-
Requête HTTP contenant le champ
method.
Attributes
- #[Route]
- '/payment-process'
- $name: 'company_registration_payment_process'
- $methods: ['POST']
Return values
Response —Redirection vers Stripe Checkout pour un paiement par carte, vers app_home pour
Orange Money, ou vers company_payment si la méthode est invalide.
paymentSuccess()
Handle successful Stripe payment
public
paymentSuccess(Request $request) : Response
Traite le retour de Stripe après un paiement et finalise l'inscription de l'entreprise.
Le paramètre de requête session_id est obligatoire ; la session Checkout correspondante est relue
auprès de Stripe et l'inscription n'est finalisée que si son payment_status vaut paid — c'est le
seul point du parcours où l'entreprise, l'abonnement et le compte définitif sont réellement créés,
via CompanyRegistrationService::completeRegistration(). En cas de succès, le mot
de passe temporaire est envoyé au gestionnaire par
CompanyRegistrationController::sendTemporaryPasswordEmail() et l'utilisateur est redirigé vers
la page de confirmation. Un paiement non confirmé, un échec de finalisation ou une exception ramènent
à la page de paiement ou de confirmation avec un message flash explicatif.
Route : /company/payment/success (GET), nom company_registration_payment_success.
Parameters
- $request : Request
-
Requête HTTP contenant le paramètre
session_idfourni par Stripe.
Attributes
- #[Route]
- '/payment/success'
- $name: 'company_registration_payment_success'
- $methods: ['GET']
Return values
Response —Redirection vers company_confirmation si l'inscription est finalisée, sinon vers
company_payment (session absente, paiement non confirmé, exception) ou vers
company_confirmation sans succès si la finalisation échoue.
register()
Step 1: Company Details Registration
public
register(Request $request) : Response
Étape 1 du tunnel : identifie le contact et crée (ou réutilise) le compte gestionnaire.
En POST, les champs email et name sont lus directement dans la requête et doivent être renseignés ;
l'email est ensuite validé par les contraintes NotBlank et Email (la contrainte
BusinessEmail, qui interdirait les adresses personnelles, est
présente mais commentée). Trois cas se présentent ensuite : un compte existant et déjà vérifié bloque
l'inscription ; un compte existant non vérifié est réutilisé, son nom étant mis à jour si nécessaire ;
sinon un nouvel utilisateur est créé avec le rôle ROLE_MANAGER et un mot de passe temporaire
aléatoire haché. La création ou la mise à jour est tracée au journal d'audit, puis un code de
vérification est envoyé par email. Toute exception pendant cette phase est écrite dans le journal PHP
et convertie en message flash, le formulaire étant alors réaffiché.
Route : /company/register (GET, POST), nom company_register.
Parameters
- $request : Request
-
Requête HTTP contenant les champs
emailetnameen POST.
Tags
Attributes
- #[Route]
- '/register'
- $name: 'company_register'
- $methods: ['GET', 'POST']
Return values
Response —Redirection vers company_verify_email en cas de succès, sinon le formulaire rendu
(company/registration/register.html.twig) avec l'état de progression (étape 1/5).
resendVerification()
Renvoie un code de vérification d'email au contact de l'entreprise.
public
resendVerification(int $user_id) : Response
Refuse l'envoi si l'utilisateur est introuvable (retour à l'étape 1), s'il est déjà vérifié (passage à l'étape des informations d'entreprise) ou si le délai anti-spam de EmailVerificationService::canResendCode() n'est pas écoulé. Les échecs d'envoi sont silencieusement écrits dans le journal PHP : une exception applicative produit en plus un message flash d'erreur, tandis qu'une erreur de transport n'est que journalisée, l'utilisateur voyant alors potentiellement un message de succès trompeur.
Route : /company/resend-verification/{user_id} (GET, POST), nom company_resend_verification.
Parameters
- $user_id : int
-
Identifiant de l'utilisateur destinataire du nouveau code.
Attributes
- #[Route]
- '/resend-verification/{user_id}'
- $name: 'company_resend_verification'
Return values
Response —Redirection vers company_verify_email dans le cas nominal, vers company_register
si l'utilisateur est introuvable ou vers company_details s'il est déjà vérifié.
subscription()
Step 3: Subscription Selection
public
subscription(Request $request) : Response
Étape 3 du tunnel : choix du cycle de facturation de l'abonnement « Entreprise ».
L'effectif est repris des données d'entreprise en session (1 par défaut) et sert à dimensionner le
formulaire. Seul le plan nommé « Entreprise » et actif est proposé ; s'il est absent du catalogue, un
message d'erreur est affiché et l'utilisateur est renvoyé vers company_details — redirection générée
sans le paramètre user_id, ce qui peut échouer si la route l'exige. À la soumission valide, le
montant total est calculé par le service de paiement à partir du plan, du cycle de facturation et de
l'effectif, affecté à l'abonnement, puis l'ensemble est stocké en session avant de passer au paiement.
Comme à l'étape 2, aucun abonnement n'est persisté en base ici.
Route : /company/subscription (GET, POST), nom company_subscription.
Parameters
- $request : Request
-
Requête HTTP portant le formulaire SubscriptionType.
Attributes
- #[Route]
- '/subscription'
- $name: 'company_subscription'
- $methods: ['GET', 'POST']
Return values
Response —Redirection vers company_details si le plan « Entreprise » est indisponible, vers
company_payment après soumission valide, sinon le formulaire rendu
(company/registration/subscription.html.twig, étape 3/5).
verifyEmail()
Affiche l'écran de saisie du code de vérification d'email et le valide.
public
verifyEmail(Request $request, int $user_id) : Response
L'utilisateur est identifié par le paramètre d'URL {user_id} : s'il est introuvable, retour à
l'étape 1 ; s'il est déjà vérifié, le parcours saute directement à l'étape des informations
d'entreprise. En POST, un code vide produit un message d'erreur et le réaffichage du formulaire ;
un code correct fait passer à company_details, un code invalide ou expiré n'affiche qu'un message
flash sans limitation du nombre de tentatives. Aucun contrôle d'accès ne protège cette route : le seul
identifiant numérique de l'utilisateur suffit à y accéder.
Route : /company/verify-email/{user_id} (GET, POST), nom company_verify_email.
Parameters
- $request : Request
-
Requête HTTP contenant le champ
verification_codeen POST. - $user_id : int
-
Identifiant de l'utilisateur dont l'email doit être vérifié.
Attributes
- #[Route]
- '/verify-email/{user_id}'
- $name: 'company_verify_email'
Return values
Response —Redirection vers company_register si l'utilisateur est introuvable, vers
company_details si l'email est vérifié, sinon le formulaire rendu
(company/registration/email-verification.html.twig).
redirectToStripeCheckout()
Redirect to Stripe Checkout for subscription payment
private
redirectToStripeCheckout(array<string, mixed> $subscriptionData) : Response
Crée la session Stripe Checkout de l'abonnement et redirige l'utilisateur vers la page de paiement.
Construit une ligne de facturation unique libellée « Abonnement gnf et pour un montant transmis tel quel en unité entière. Les URL de
retour absolues sont générées vers company_registration_payment_success (avec le marqueur
{CHECKOUT_SESSION_ID} remplacé par Stripe) et company_registration_payment_cancel. Les données de
souscription sérialisées et l'identifiant de l'utilisateur sont attachés en métadonnées Stripe ;
l'absence de données utilisateur en session provoque une exception. L'identifiant de session Stripe
est ensuite mémorisé en session pour la vérification ultérieure. Toute exception est journalisée et
convertie en message flash.
Parameters
- $subscriptionData : array<string, mixed>
-
Données de souscription en session :
plan_id,amount,billing_cycle,employee_count.
Tags
Return values
Response —Redirection vers l'URL de la session Stripe Checkout, ou vers company_payment en
cas d'erreur.
sendTemporaryPasswordEmail()
Send temporary password email to user
private
sendTemporaryPasswordEmail(User $user, string $temporaryPassword) : void
Envoie au gestionnaire l'email contenant ses identifiants de connexion.
Utilise le template company_registration/temporary_password avec l'utilisateur, son entreprise, le
mot de passe temporaire en clair et l'URL absolue de connexion. La méthode est volontairement
tolérante aux pannes : les exceptions applicatives comme les erreurs de transport sont uniquement
écrites dans le journal PHP, afin qu'un échec d'envoi ne remette pas en cause une inscription déjà
payée et finalisée.
Parameters
- $user : User
-
Gestionnaire destinataire, dont l'entreprise est jointe au message.
- $temporaryPassword : string
-
Mot de passe temporaire en clair généré lors de la finalisation.