render( ':site:become_member.html.twig', [ 'membership_fee_natural_person' => AFUP_COTISATION_PERSONNE_PHYSIQUE, 'membership_fee_legal_entity' => AFUP_COTISATION_PERSONNE_MORALE ] ); } public function companyAction(Request $request) { $subscribeForm = $this->createForm(CompanyMemberType::class); $subscribeForm->handleRequest($request); if ($subscribeForm->isSubmitted() && $subscribeForm->isValid()) { /** * @var $member CompanyMember */ $member = $subscribeForm->getData(); $this->get('ting')->get(CompanyMemberRepository::class)->save($member); /** * @var $invitationRepository CompanyMemberInvitationRepository */ $invitationRepository = $this->get('ting')->get(CompanyMemberInvitationRepository::class); foreach ($member->getInvitations() as $index => $invitation) { if ($invitation->getEmail() === null) { continue; } $invitation ->setSubmittedOn(new \DateTime()) ->setCompanyId($member->getId()) ->setToken(base64_encode(random_bytes(30))) ->setStatus(CompanyMemberInvitation::STATUS_PENDING) ; if ($index === 0) { // By security, force first employee to be defined as a manager $invitation->setManager(true); } $invitationRepository->save($invitation); // Send mail to the other guy, begging for him to join the company $this->get('event_dispatcher')->addListener(KernelEvents::TERMINATE, function () use ($member, $invitation) { $this->get(\AppBundle\Association\CompanyMembership\InvitationMail::class)->sendInvitation($member, $invitation); }); } $subscriptionManager = $this->get(\AppBundle\Association\CompanyMembership\SubscriptionManagement::class); $invoice = $subscriptionManager->createInvoiceForInscription($member, count($member->getInvitations())); return $this->redirectToRoute('company_membership_payment', ['invoiceNumber' => $invoice['invoice'], 'token' => $invoice['token']]); } return $this->render(':site/company_membership:adhesion_entreprise.html.twig', ['form' => $subscribeForm->createView()]); } public function paymentAction($invoiceNumber, $token) { /** * @var $subscription Cotisations */ $subscription = $this->get(\AppBundle\LegacyModelFactory::class)->createObject(Cotisations::class); $invoice = $subscription->getByInvoice($invoiceNumber, $token); /** * @var $company CompanyMember */ $company = $this->get('ting')->get(CompanyMemberRepository::class)->get($invoice['id_personne']); if (!$invoice || $company === null) { throw $this->createNotFoundException(sprintf('Could not find the invoice "%s" with token "%s"', $invoiceNumber, $token)); } $paybox = $this->get(\AppBundle\Payment\PayboxFactory::class)->createPayboxForSubscription( 'F' . $invoiceNumber, (float) $invoice['montant'], $company->getEmail() ); return $this->render(':site/company_membership:payment.html.twig', [ 'paybox' => $paybox, 'invoice' => $invoice, 'rib' => $this->legacyConfiguration->obtenir('rib'), 'afup' => $this->legacyConfiguration->obtenir('afup') ]); } public function invoiceAction($invoiceNumber, $token) { /** * @var $subscription Cotisations */ $subscription = $this->get(\AppBundle\LegacyModelFactory::class)->createObject(Cotisations::class); $invoice = $subscription->getByInvoice($invoiceNumber, $token); if (!$invoice) { throw $this->createNotFoundException(sprintf('Could not find the invoice "%s" with token "%s"', $invoiceNumber, $token)); } ob_start(); $subscription->genererFacture($invoice['id']); $pdf = ob_get_clean(); $response = new Response($pdf); $response->headers->set('Content-Type', 'application/pdf'); return $response; } public function memberInvitationAction(Request $request, $invitationId, $token) { /** * @var $invitationRepository CompanyMemberInvitationRepository */ $invitationRepository = $this->get('ting')->get(CompanyMemberInvitationRepository::class); /** * @var $invitation CompanyMemberInvitation */ $invitation = $invitationRepository->getOneBy(['id' => $invitationId, 'token' => $token, 'status' => CompanyMemberInvitation::STATUS_PENDING]); $company = null; if ($invitation) { /** * @var $company CompanyMember */ $company = $this->get('ting')->get(CompanyMemberRepository::class)->get($invitation->getCompanyId()); } if ($invitation === null || $company === null) { throw $this->createNotFoundException(sprintf('Could not find invitation with token "%s"', $token)); } $userForm = $this->createForm(UserType::class); $userForm->handleRequest($request); if ($userForm->isSubmitted() && $userForm->isValid()) { /** * @var $user User */ $user = $userForm->getData(); $user->setCivility(''); $user->setPlainPassword($user->getPassword()); $user ->setStatus(User::STATUS_ACTIVE) ->setCompanyId($company->getId()) ; if ($invitation->getManager()) { $user->setRoles(['ROLE_COMPANY_MANAGER', 'ROLE_USER']); } $invitation->setStatus(CompanyMemberInvitation::STATUS_ACCEPTED); $this->get('ting')->get(UserRepository::class)->save($user); $invitationRepository->save($invitation); $this->addFlash('success', 'Votre compte a été créé !'); $event = new NewMemberEvent($user); $this->get('event_dispatcher')->dispatch($event::NAME, $event); return $this->redirectToRoute('member_index'); } return $this->render(':site/company_membership:member_invitation.html.twig', ['company' => $company, 'form' => $userForm->createView()]); } public function slackInviteRequestAction(Request $request) { $user = $this->getUser(); if (!$user->canRequestSlackInvite()) { throw $this->createAccessDeniedException("Vous n'êtes pas autorité à demander une invitation"); } $this->get('slack_members_legacy_client')->invite($this->getUser()->getEmail()); $this->addFlash('success', 'Un email vous a été envoyé pour rejoindre le Slack des membres !'); $user->setSlackInviteStatus(User::SLACK_INVITE_STATUS_REQUESTED); $this->get('ting')->get(UserRepository::class)->save($user); $this->log('Demande invitation slack', $this->getUser()); return $this->redirectToRoute('admin_home'); } public function payboxCallbackAction(Request $request) { $payboxResponse = PayboxResponseFactory::createFromRequest($request); $userRepository = $this->get(UserRepository::class); /** * @var $cotisations Cotisations */ $cotisations = $this->get(\AppBundle\LegacyModelFactory::class)->createObject(Cotisations::class); $logs = $this->get(\AppBundle\LegacyModelFactory::class)->createObject(Logs::class); $status = $payboxResponse->getStatus(); $etat = AFUP_COTISATIONS_PAIEMENT_ERREUR; if ($status === '00000') { $etat = AFUP_COTISATIONS_PAIEMENT_REGLE; } elseif ($status === '00015') { // Designe un paiement deja effectue : on a surement deja eu le retour donc on s'arrete return new Response(); } elseif ($status === '00117') { $etat = AFUP_COTISATIONS_PAIEMENT_ANNULE; } elseif (substr($status, 0, 3) === '001') { $etat = AFUP_COTISATIONS_PAIEMENT_REFUSE; } if ($etat == AFUP_COTISATIONS_PAIEMENT_REGLE) { $account = $cotisations->getAccountFromCmd($payboxResponse->getCmd()); $lastCotisation = $cotisations->obtenirDerniere($account['type'], $account['id']); if ($lastCotisation === false && $account['type'] == UserRepository::USER_TYPE_PHYSICAL) { $user = $userRepository->get($account['id']); $event = new NewMemberEvent($user); $this->get('event_dispatcher')->dispatch($event::NAME, $event); } $cotisations->validerReglementEnLigne($payboxResponse->getCmd(), round($payboxResponse->getTotal() / 100, 2), $payboxResponse->getAuthorizationId(), $payboxResponse->getTransactionId()); $cotisations->notifierRegelementEnLigneAuTresorier($payboxResponse->getCmd(), round($payboxResponse->getTotal() / 100, 2), $payboxResponse->getAuthorizationId(), $payboxResponse->getTransactionId(), $userRepository); $logs::log("Ajout de la cotisation " . $payboxResponse->getCmd() . " via Paybox."); } return new Response(); } public function contactDetailsAction(Request $request) { $logs = $this->get(LegacyModelFactory::class)->createObject(Logs::class); $repo = $this->get('ting')->get(UserRepository::class); $user = $repo->get($this->getUserId()); $data = [ 'email' => $user->getEmail(), 'address' => $user->getAddress(), 'username' => $user->getUsername(), 'zipcode' => $user->getZipCode(), 'city' => $user->getCity(), 'phone' => $user->getPhone(), 'mobilephone' => $user->getMobilePhone(), 'country' => $user->getCountry(), 'nearest_office' => $user->getNearestOffice(), ]; $userForm = $this->createForm(ContactDetailsType::class, $data); $userForm->handleRequest($request); if ($userForm->isValid()) { $data = $userForm->getData(); $user->setEmail($data['email']); $user->setAddress($data['address']); $user->setZipCode($data['zipcode']); $user->setCity($data['city']); $user->setUsername($data['username']); $user->setPhone($data['phone']); $user->setMobilePhone($data['mobilephone']); $user->setCountry($data['country']); $user->setNearestOffice($data['nearest_office']); // Save password if not empty if (! empty($data['password'])) { $user->setPassword(md5($data['password'])); /** @TODO We should change that */ } $repo->save($user); $logs::log("Modification des coordonnées de l'utilisateur " . $user->getUsername() . " effectuée avec succès."); $this->addFlash('success', 'Votre compte a été modifié !'); } return $this->render(':admin/association/membership:member_contact_details.html.twig', ['title' => 'Mes coordonnées', 'form' => $userForm->createView()]); } private function getUserId() { return $this->getDroits()->obtenirIdentifiant(); } private function getDroits() { return Utils::fabriqueDroits($GLOBALS['AFUP_DB'], $this->get('security.token_storage'), $this->get('security.authorization_checker')); } public function membershipFeeAction() { $bdd = $GLOBALS['AFUP_DB']; $userRepository = $this->get(UserRepository::class); $userService = $this->get(UserService::class); $cotisations = $this->getCotisations(); $identifiant = $this->getDroits()->obtenirIdentifiant(); $user = $userRepository->get($identifiant); Assertion::notNull($user); $cotisation = $userService->getLastSubscription($user); if (!$cotisation) { $message = ''; } else { $endSubscription = $cotisations->finProchaineCotisation($cotisation); $message = sprintf( 'Votre dernière cotisation -- %s %s -- est valable jusqu\'au %s.
Si vous renouvellez votre cotisation maintenant, celle-ci sera valable jusqu\'au %s.', number_format($cotisation['montant'], 2, ',', ' '), EURO, date("d/m/Y", $cotisation['date_fin']), $endSubscription->format('d/m/Y') ); } $cotisation_physique = $cotisations->obtenirListe(0, $user->getId()); $cotisation_morale = $cotisations->obtenirListe(1, $user->getCompanyId()); if (is_array($cotisation_morale) && is_array($cotisation_physique)) { $cotisations = array_merge($cotisation_physique, $cotisation_morale); } elseif (is_array($cotisation_morale)) { $cotisations = $cotisation_morale; } elseif (is_array($cotisation_physique)) { $cotisations = $cotisation_physique; } else { $cotisations = []; } if ($user->getCompanyId() > 0) { $id_personne = $user->getCompanyId(); $personne_morale = new \Afup\Site\Association\Personnes_Morales($bdd); $type_personne = AFUP_PERSONNES_MORALES; $prefixe = 'Personne morale'; $montant = $personne_morale->getMembershipFee($id_personne); } else { $id_personne = $identifiant; $type_personne = AFUP_PERSONNES_PHYSIQUES; $prefixe = 'Personne physique'; $montant = AFUP_COTISATION_PERSONNE_PHYSIQUE; } $formattedMontant = number_format($montant, 2, ',', ' '); $libelle = sprintf("%s : %s€", $prefixe, $formattedMontant); $reference = (new \AppBundle\Association\MembershipFeeReferenceGenerator())->generate(new \DateTimeImmutable('now'), $type_personne, $id_personne, $user->getLastName()); $paybox = $this->get(\AppBundle\Payment\PayboxFactory::class)->createPayboxForSubscription( $reference, (float) $montant, $user->getEmail() ); $paybox = str_replace('INPUT TYPE=SUBMIT', 'INPUT TYPE=SUBMIT class="button button--call-to-action"', $paybox); return $this->render( ':admin/association/membership:membershipfee.html.twig', [ 'title' => 'Ma cotisation', 'cotisations' => $cotisations, 'time' => time(), 'montant' => $montant, 'libelle' => $libelle, 'paybox' => $paybox, 'message' => $message, ] ); } private function getCotisations() { return new Cotisations($GLOBALS['AFUP_DB'], $this->getDroits()); } public function membershipFeeDownloadAction(Request $request) { $cotisations = $this->getCotisations(); $identifiant = $this->getDroits()->obtenirIdentifiant(); $id = $request->get('id'); $logs = $this->get(LegacyModelFactory::class)->createObject(Logs::class); if (false === $cotisations->isCurrentUserAllowedToReadInvoice($id)) { $logs::log("L'utilisateur id: " . $identifiant . ' a tenté de voir la facture id:' . $id); throw $this->createAccessDeniedException('Cette facture ne vous appartient pas, vous ne pouvez la visualiser.'); } $tempfile = tempnam(sys_get_temp_dir(), 'membership_fee_download'); $numeroFacture = $cotisations->genererFacture($id, $tempfile); $response = new BinaryFileResponse($tempfile, 200, [], false); $response->deleteFileAfterSend(true); $response->setContentDisposition('attachment', 'facture-' . $numeroFacture . '.pdf'); return $response; } public function membershipFeeSendMailAction(Request $request) { $cotisations = $this->getCotisations(); $identifiant = $this->getDroits()->obtenirIdentifiant(); $id = $request->get('id'); $logs = $this->get(LegacyModelFactory::class)->createObject(Logs::class); $userRepository = $this->get(UserRepository::class); if (false === $cotisations->isCurrentUserAllowedToReadInvoice($id)) { $logs::log("L'utilisateur id: " . $identifiant . ' a tenté de voir la facture id:' . $id); throw $this->createAccessDeniedException('Cette facture ne vous appartient pas, vous ne pouvez la visualiser.'); } if ($cotisations->envoyerFacture($id, $this->get(\AppBundle\Email\Mailer\Mailer::class), $userRepository)) { $logs::log('Envoi par email de la facture pour la cotisation n°' . $id); $this->addFlash('success', 'La facture a été envoyée par mail'); } else { $this->addFlash('error', "La facture n'a pas pu être envoyée par mail"); } return $this->redirectToRoute('member_membership_fee'); } public function generalMeetingAction(Request $request) { $userService = $this->get(UserService::class); /** @var User $user */ $user = $this->getUser(); Assertion::isInstanceOf($user, User::class); $title = 'Présence prochaine AG'; $generalMeetingRepository = $this->get(GeneralMeetingRepository::class); $latestDate = $generalMeetingRepository->getLatestDate(); Assertion::notNull($latestDate); $generalMeetingPlanned = $generalMeetingRepository->hasGeneralMeetingPlanned(); $cotisation = $userService->getLastSubscription($user); $needsMembersheepFeePayment = $latestDate->getTimestamp() > strtotime("+14 day", $cotisation['date_fin']); if ($needsMembersheepFeePayment) { return $this->render('admin/association/membership/generalmeeting_membersheepfee.html.twig', [ 'title' => $title, 'latest_date' => $latestDate, ]); } $attendee = $generalMeetingRepository->getAttendee($user->getUsername(), $latestDate); $lastGeneralMeetingDescription = $generalMeetingRepository->obtenirDescription($latestDate); $defaultPresence = 0; $defaultPowerId = null; if (null !== $attendee) { $defaultPresence = $attendee->getPresence(); $defaultPowerId = $attendee->getPowerId(); } $form = $this->createFormBuilder() ->add('presence', ChoiceType::class, ['expanded' => true, 'choices' => ['Oui' => 1, 'Non' => 2, 'Je ne sais pas encore' => 0]]) ->add( 'id_personne_avec_pouvoir', ChoiceType::class, [ 'choices' => array_flip($generalMeetingRepository->getPowerSelectionList($latestDate, $user->getUsername())), 'label' => 'Je donne mon pouvoir à', 'required' => false, ] ) ->add('save', SubmitType::class, ['label' => 'Confirmer']) ->setData([ 'presence' => $defaultPresence, 'id_personne_avec_pouvoir' => $defaultPowerId, ]) ->getForm(); $form->handleRequest($request); if ($form->isValid()) { $data = $form->getData(); if (null !== $attendee) { $ok = $generalMeetingRepository->editAttendee( $user->getUsername(), $latestDate, $data['presence'], (int) $data['id_personne_avec_pouvoir'] ); } else { $ok = $generalMeetingRepository->addAttendee( $user->getId(), $latestDate, $data['presence'], (int) $data['id_personne_avec_pouvoir'] ); } if ($ok) { $this->log('Modification de la présence et du pouvoir de la personne physique'); $this->addFlash('success', 'La présence et le pouvoir ont été modifiés'); return $this->redirectToRoute('member_general_meeting'); } $this->addFlash('error', 'Une erreur est survenue lors de la modification de la présence et du pouvoir'); } $attendeesWithPower = $generalMeetingRepository->getAttendees($latestDate, 'nom', 'asc', $user->getId()); $generalMeetingQuestionRepository = $this->get(GeneralMeetingQuestionRepository::class); $generalMeetingVoteRepository = $this->get(GeneralMeetingVoteRepository::class); $currentQuestion = $generalMeetingQuestionRepository->loadNextOpenedQuestion($latestDate); $voteForCurrentQuestion = null; if (null !== $currentQuestion) { $voteForCurrentQuestion = $generalMeetingVoteRepository->loadByQuestionIdAndUserId($currentQuestion->getId(), $this->getUserId()); } $questionResults = []; foreach ($generalMeetingQuestionRepository->loadClosedQuestions($latestDate) as $question) { $results = $generalMeetingVoteRepository->getResultsForQuestionId($question->getId()); $questionResults[] = [ 'question' => $question, 'count_oui' => $results[GeneralMeetingVote::VALUE_YES], 'count_non' => $results[GeneralMeetingVote::VALUE_NO], 'count_abstention' => $results[GeneralMeetingVote::VALUE_ABSTENTION], ]; } return $this->render('admin/association/membership/generalmeeting.html.twig', [ 'question_results' => $questionResults, 'question' => $currentQuestion, 'vote_for_current_question' => $voteForCurrentQuestion, 'vote_labels_by_values' => GeneralMeetingVote::getVoteLabelsByValue(), 'title' => $title, 'latest_date' => $latestDate, 'form' => $form->createView(), 'reports' => $this->prepareGeneralMeetingsReportsList(), 'general_meeting_planned' => $generalMeetingPlanned, 'last_general_meeting_description' => $lastGeneralMeetingDescription, 'personnes_avec_pouvoir' => $attendeesWithPower, ]); } public function generalMeetingVoteAction(Request $request) { $generalMeetingRepository = $this->get(GeneralMeetingRepository::class); $generalMeetingQuestionRepository = $this->get(GeneralMeetingQuestionRepository::class); $generalMeetingVoteRepository = $this->get(GeneralMeetingVoteRepository::class); if (null === ($questionId = $request->get('questionId'))) { throw $this->createNotFoundException('QuestionId manquant'); } if (false === GeneralMeetingVote::isValueAllowed($vote = $request->query->getAlpha('vote'))) { throw $this->createNotFoundException('Vote manquant'); } /** @var $question GeneralMeetingQuestion */ if (null === ($question = $generalMeetingQuestionRepository->get($questionId))) { throw $this->createNotFoundException('QuestionId missing'); } $redirection = $this->redirectToRoute('member_general_meeting'); if (false === $question->hasStatusOpened()) { $this->addFlash('error', "Ce vote n'est pas ouvert"); return $redirection; } $userId = $this->getUserId(); if (null !== $generalMeetingVoteRepository->loadByQuestionIdAndUserId($questionId, $userId)) { $this->addFlash('error', 'Vous avez déjà voté pour cette question'); return $redirection; } $weight = 1 + count($generalMeetingRepository->getAttendees($question->getDate(), 'nom', 'asc', $userId)); $generalMeetingVote = new GeneralMeetingVote(); $generalMeetingVote ->setQuestionId($question->getId()) ->setUserId($this->getUserId()) ->setWeight($weight) ->setValue($vote) ->setCreatedAt(new \DateTime()) ; $generalMeetingVoteRepository->save($generalMeetingVote); $this->addFlash('notice', 'Votre vote a été pris en compte'); return $redirection; } public function generalMettingDownloadReportAction($filename) { $reports = $this->prepareGeneralMeetingsReportsList(); if (!isset($reports[$filename])) { throw $this->createNotFoundException(); } if ($this->getUser()->hasRole('ROLE_MEMBER_EXPIRED')) { throw $this->createNotFoundException(); } return new BinaryFileResponse($reports[$filename]['path']); } private function prepareGeneralMeetingsReportsList() { $dir = $this->container->getParameter('kernel.project_dir') . DIRECTORY_SEPARATOR . '/htdocs/uploads/general_meetings_reports'; $finder = new Finder(); $files = $finder->name("*.pdf")->in($dir); $reports = []; foreach ($files as $file) { $reports[$file->getFilename()] = [ 'date' => substr($file->getFilename(), 0, 10), 'label' => substr($file->getFilename(), 11, -4), 'filename' => $file->getFilename(), 'path' => $file->getRealPath(), ]; } krsort($reports); return $reports; } public function techletterAction() { return $this->render(':site/member:techletter.html.twig', [ 'subscribed' => $this->get('ting')->get(TechletterSubscriptionsRepository::class)->hasUserSubscribed($this->getUser()), 'feeUpToDate' => ($this->getUser() !== null and $this->getUser()->getLastSubscription() > new \DateTime()), 'token' => $this->get('security.csrf.token_manager')->getToken('techletter_subscription'), 'techletter_history' => $this->get('ting')->get(SendingRepository::class)->getAllPastSent(), ]); } public function techletterSubscribeAction(Request $request) { $user = $this->getUser(); $token = $this->get('security.csrf.token_manager')->getToken('techletter_subscription'); if ( $user === null || $user->getLastSubscription() < new \DateTime() || $request->request->has('_csrf_token') === false || $request->request->get('_csrf_token') !== $token->getValue() ) { throw $this->createAccessDeniedException('You cannot subscribe to the techletter'); } $this->addFlash('success', "Vous êtes maintenant abonné à la veille de l'AFUP"); $this->get('ting')->get(TechletterSubscriptionsRepository::class)->subscribe($user); return $this->redirectToRoute('member_techletter'); } public function techletterUnsubscribeAction(Request $request) { $techletterUnsubscriptionRepository = $this->get('ting')->get(TechletterUnsubscriptionsRepository::class); $techletterUnsubscription = $techletterUnsubscriptionRepository->createFromUser($this->getUser()); $techletterUnsubscriptionRepository->save($techletterUnsubscription); $this->addFlash('success', "Vous êtes maintenant désabonné à la veille de l'AFUP"); return $this->redirectToRoute('member_techletter'); } }