<?php
namespace App\Controller;
use App\Entity\Lead;
use App\Entity\Mailling;
use App\Entity\Task;
use App\Entity\User;
use App\Form\LeadType;
use App\Notification\MaillingNotification;
use App\Repository\DvfRepository;
use App\Repository\LeadRepository;
use App\Repository\UserRepository;
use App\Service\EstimatePrice;
use App\Service\SmsMode as ServiceSmsMode;
use DateInterval;
use DateTime;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class EstimateurController extends AbstractController
{
private $webDirectory;
public $maillingNotification;
private $token;
public function __construct($webDirectory, MaillingNotification $maillingNotification)
{
$this->webDirectory = $webDirectory;
$this->maillingNotification = $maillingNotification;
}
/**
*@Route("/estimateur/{step}", name="estimateur.index")
*/
public function index($step = "stepOne", Request $request, EntityManagerInterface $entityManager, DvfRepository $dvf, UserRepository $userRepository, LeadRepository $leadRepository, EstimatePrice $estimatePrice)
{
$this->token = $request->query->get('api_key');
if ($userRepository->findToken($this->token) == 0) {
return new Response('WRONG API KEY GIVEN');
}
if (empty($request->request->get('form')['uid'])) {
$lead = new Lead('new');
} else {
$lead = $leadRepository->find($this->encrypt_decrypt($request->request->get('form')['uid'], $this->token, 'decrypt'));
}
if ($request->request->get('form') != null) {
$lead = $this->updateLead($request, $entityManager, $userRepository, $leadRepository);
}
if ($request->request->get('step') == 'stepFive') {
if ($this->checkCodeSms($request)) {
/**
* Calcule de l'estimation
*/
$lead = $estimatePrice->estimatePrice($lead, $dvf);
$lead->setVerified(1);
$entityManager->flush();
$user = ($lead->getUser() != null) ? $lead->getUser() : $lead->getPossessor();
$task = new Task();
$task->setUser($user)
->setTitle('Première prise de contact avec ' . $lead->getLastName() . ' ' . $lead->getName())
->setNote('Tâche automatique')
->setType(0)
->setPriority(1)
->setState(0)
->setDueDate(time(), 259200)
->setLead($lead)
->setDueDay('P3D')
->setDueHour(28800)
->setReminderInterval('0')
->setIsSend(1)
->setUserAction($user);
$entityManager->persist($task);
$entityManager->flush();
$mailling = new Mailling();
$mailling->setEmailFrom($lead->getPossessor()->getCompanyName()." <".$lead->getPossessor()->getEmail().">");
$mailling->setEmailTo($lead->getEmail());
$mailling->setSubject('Estimation de votre bien immobilier');
$mailling->setMessage($this->messageEstimation($lead));
$mailling->headerSender = $lead->getPossessor()->getCompanyName();
$this->maillingNotification->notify($mailling, 'Voici votre estimatation');
$this->maillingNotification->notification($lead->getId(), 2);
$this->maillingNotification->notification($task->getId(), 0);
return $this->lastStep($request, $lead);
} else {
return new JsonResponse([
'error' => "Merci d'indiquer le code recu par sms",
]);
}
}
$form = $this->{$step}($lead);
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'step' => $this->renderView('estimateur/steps/' . $step . '.html.twig', [
'form' => $form->createView(),
'lead' => $lead,
'step' => $step,
]),
]);
}
return $this->render('estimateur/index.html.twig', [
'form' => $form->createView(),
'lead' => $lead,
'step' => $step
]);
}
private function messageEstimation(Lead $lead)
{
$return = "<p>Cher(e) {$lead->getName()} {$lead->getLastName()}</p>
<p>L'estimation que vous avez réalisée sur notre site vous a permis de nourrir votre réflexion quant à votre projet immobilier.
D'après les caractéristiques que vous nous avez transmises, voici le prix du marché de votre bien immobilier qui se situe dans la fourchette suivante :</p>
<h3>{$lead->getStreetNumber()} {$lead->getStreet()}, {$lead->getZipcode()}, {$lead->getCity()}</h3>";
if($lead->getMediumPrice()> 0){
$return .= "
<p>Les moins chers dans votre quartier : ".number_format($lead->getLowerPrice(), 0, ',', ' ')." € </p>
<p>Les plus chers dans votre quartier : ".number_format($lead->getHighPrice(), 0, ',', ' ')." €</p>";
}else{
$return .= "<p><br>Aucune évaluation n'a pu être réalisé pour votre bien immobilier.<br></p>";
}
$return .= "<p>Cette évaluation ne peut pas être aussi précise que celle réalisée par un professionnel.
C'est pour cela qu'un agent vous contactera très prochainement afin d'affiner votre recherche et vous communiquer un rapport d'estimation précis et complet.
Vous vous posez peut-être des questions sur l'état du marché local ? Ou peut-être sur la concrétisation de ce projet ?
Vous voulez acheter, vendre, louer ou même investir nous restons à votre disposition pour échanger.</p>
<p>
{$lead->getPossessor()->getPhone()} <br>
{$lead->getPossessor()->getCompanyName()} <br>
{$lead->getPossessor()->getStreetNumber()} {$lead->getPossessor()->getStreet()} <br>
{$lead->getPossessor()->getZipcode()}, {$lead->getPossessor()->getCity()}
</p>";
return $return;
}
/**
*@Route("/send-sms", name="estimateur.send_sms", methods={"POST"})
*/
public function sendSms(Request $request)
{
$result = '';
for ($i = 0; $i < 4; $i++) {
$result .= rand(0, 9);
}
$smsMode = new ServiceSmsMode("Bk5TH6EkshsXMJ5JpouMONDNrmIQ0DVY", "Afin de valider votre estimation immobilière, merci de renseigner ce code: " . $result . " Merci.", $request->request->get('form')['phone'], "Aquizio");
$smsMode->sendSmsGet();
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'code' => $this->encrypt_decrypt($result, $request->query->get('api_key'), 'encrypt')
]);
}
}
private function checkCodeSms(Request $request)
{
$code = $request->request->get('code');
$code_generate = $this->encrypt_decrypt($request->request->get('code_generate'), $this->token, 'decrypt');
if ($code === $code_generate) {
return true;
} else {
return false;
}
}
private function stepOne(Lead $lead)
{
$uid = '';
if ($lead->getId() != null) {
$uid = $this->encrypt_decrypt($lead->getId(), $this->token, 'encrypt');
}
return $this->createFormBuilder($lead, ['action' => $this->generateUrl('estimateur.index')])
->add('uid', HiddenType::class, ['mapped' => false, 'required' => false, 'data' => $uid])
->add('location_type', HiddenType::class, ['attr' => ['id' => 'location-type'], 'mapped' => false, 'data' => 'none'])
->add('latlng', HiddenType::class)
->add('zipcode', null, ['label' => 'Code postal'])
->add('city', null, ['label' => 'Ville'])
->add('street', null, ['label' => 'Rue'])
->add('street_number', null, ['label' => 'N°'])
->getForm();
}
private function stepTwo(Lead $lead)
{
$uid = '';
if ($lead->getId() != null) {
$uid = $this->encrypt_decrypt($lead->getId(), $this->token, 'encrypt');
}
return $this->createFormBuilder($lead, ['action' => $this->generateUrl('estimateur.index')])
->add('uid', HiddenType::class, ['mapped' => false, 'data' => $uid])
->add('property_type_code', ChoiceType::class, ['choices' => array_flip(Lead::TYPE_CODE), 'expanded' => true, 'label' => false])
->add('property_type_subcode_appartment', ChoiceType::class, ['mapped' => false, 'choices' => $this->removeValue(array_flip(Lead::TYPE_SUBCODE), [2, 3]), 'expanded' => true, 'label' => false])
->add('property_type_subcode_house', ChoiceType::class, ['mapped' => false, 'choices' => $this->removeValue(array_flip(Lead::TYPE_SUBCODE), [0, 1]), 'expanded' => true, 'label' => false])
->add('pool', ChoiceType::class, ['choices' => [0, 1], 'expanded' => true, 'label' => false])
->add('floor', null, ['label' => 'Étage de l\'appartement'])
->add('floor_building', null, ['label' => 'Nombre d\'étages de l\'immeuble'])
->add('elevator', ChoiceType::class, ['choices' => [0, 1], 'label' => 'Ascenseur'])
->add('isOwner', ChoiceType::class, ['choices' => [0, 1], 'expanded' => true, 'label' => false])
->add('best_description', ChoiceType::class, ['choices' => array_flip(Lead::BEST_DESCRIPTION), 'expanded' => true, 'label' => false])
->getForm();
}
private function stepThree(Lead $lead)
{
$uid = '';
if ($lead->getId() != null) {
$uid = $this->encrypt_decrypt($lead->getId(), $this->token, 'encrypt');
}
return $this->createFormBuilder($lead, ['action' => $this->generateUrl('estimateur.index')])
->add('uid', HiddenType::class, ['mapped' => false, 'data' => $uid])
->add('square_area', null, ['label' => 'Surface (Carrez)'])
->add('balcony_area', null, ['label' => 'Surface des balcons'])
->add('garden_area', null, ['label' => 'Surface du jardin'])
->add('land_area', null, ['label' => 'Surface du terrain'])
->add('year_construction', null, ['label' => 'Année de construction'])
->add('year_renovation', null, ['label' => 'Année de rénovation'])
->add('number_rooms', null, ['label' => 'Nombre de pièce'])
->add('number_bathroom', null, ['label' => 'Nombre de SdB'])
->add('parking_space_inside', null, ['label' => 'Place de parking intérieur'])
->add('parking_space_outside', null, ['label' => 'Place de parking extérieur'])
->add('condition_property', ChoiceType::class, ['choices' => array_flip([0 => 'À rénover', 1 => 'Bon état', 2 => 'Rénové', 3 => 'Neuf']), 'expanded' => true, 'label' => false])
->getForm();
}
private function stepFour(Lead $lead)
{
$uid = '';
if ($lead->getId() != null) {
$uid = $this->encrypt_decrypt($lead->getId(), $this->token, 'encrypt');
}
return $this->createFormBuilder($lead, ['action' => $this->generateUrl('estimateur.index')])
->add('uid', HiddenType::class, ['mapped' => false, 'data' => $uid])
->add('name', null, ['label' => 'Prénom'])
->add('last_name', null, ['label' => 'Nom'])
->add('email', null, ['label' => 'Email'])
->add('phone', null, ['label' => 'Téléphone'])
->getForm();
}
private function stepFive(Lead $lead)
{
$uid = '';
if ($lead->getId() != null) {
$uid = $this->encrypt_decrypt($lead->getId(), $this->token, 'encrypt');
}
return $this->createFormBuilder($lead, ['action' => $this->generateUrl('estimateur.index')])
->add('uid', HiddenType::class, ['mapped' => false, 'data' => $uid])
->getForm();
}
private function removeValue($value, $arr)
{
foreach ($value as $k => $v) {
if (in_array($v, $arr)) {
unset($value[$k]);
}
}
return $value;
}
private function updateLead(Request $request, EntityManagerInterface $entityManager, UserRepository $userRepository, LeadRepository $leadRepository)
{
// $this->this->token = $request->query->get('api_key');
// Première étape du formulaire passé
if (empty($request->request->get('form')['uid'])) {
$lead = new Lead('new');
$form = $this->stepOne($lead);
$form->handleRequest($request);
$usersPocess = $userRepository->findIdPocessor($this->token);
$possessor = $userRepository->find($usersPocess->getParentId());
$user = $userRepository->find($usersPocess->getId());
if ($this->token != $possessor->getApiKey()) {
$lead->setUser($user);
}
$lead->setPossessor($possessor)
->setAutomatisation(0)
->setVerified(0)
->setProspection(0)
->setToken($this->token);
$this->removeSpam($lead, $leadRepository, $entityManager);
$entityManager->persist($lead);
$entityManager->flush();
return $lead;
} else { // Les autres étapes du formulaire
$lead = $leadRepository->find($this->encrypt_decrypt($request->request->get('form')['uid'], $this->token, 'decrypt'));
$form = $this->{$request->request->get('step')}($lead);
$form->handleRequest($request);
if (isset($request->request->get('form')['property_type_code'])) {
if ($request->request->get('form')['property_type_code'] == 1) {
$lead->setPropertyTypeSubcode($request->request->get('form')['property_type_subcode_house'] ?? 'n/a');
} elseif ($request->request->get('form')['property_type_code'] == 0) {
$lead->setPropertyTypeSubcode($request->request->get('form')['property_type_subcode_appartment'] ?? 'n/a');
}
}
$entityManager->flush();
return $lead;
}
}
private function removeSpam(Lead $lead, LeadRepository $leadRepository, EntityManagerInterface $entityManager)
{
$spams = $leadRepository->findSpam($lead->getLatLng(), $lead->getToken());
foreach ($spams as $spam) {
$entityManager->remove($spam);
$entityManager->flush();
}
}
private function encrypt_decrypt($string, $token, $action = 'encrypt')
{
$encrypt_method = "AES-256-CBC";
$secret_key = $token; // user define private key
$secret_iv = '2dyk0c4p4aqz1qpvxh6g80lrf'; // user define secret key
$key = hash('sha256', $secret_key);
$iv = substr(hash('sha256', $secret_iv), 0, 16); // sha256 is hash_hmac_algo
if ($action == 'encrypt') {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if ($action == 'decrypt') {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
/**
*@Route("/estimateur-end", name="estimateur.end")
*/
public function lastStep(Request $request, Lead $lead): Response
{
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'step' => $this->renderView('estimateur/steps/lastStep.html.twig', ['lead' => $lead])
]);
}
return $this->render('estimateur/steps/lastStep.html.twig', []);
}
}