<?php
namespace App\Application\Internit\LeadBundle\Controller;
// Include PhpSpreadsheet required namespaces
use App\Application\Internit\RealEstateBundle\Entity\RealEstate;
use App\Application\Sonata\UserBundle\Entity\User;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Csv;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use App\Application\Internit\ContentBundle\Controller\CRUD;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use App\Application\Internit\LeadBundle\Entity\ProductUser;
use App\Application\Internit\LeadBundle\Entity\realStatePercent;
use App\Application\Internit\LeadBundle\Entity\Product;
/**
* Client Admin controller.
*
* @Route("/admin/internit/lead/product")
*/
class ProductAdminController extends CRUD
{
public $base = "@ApplicationInternit/LeadBundle/Resources/views/Product/";
public $bundle = "ApplicationInternitLeadBundle:Product";
private $listActionRoles = array('ROLE_CONSTRUTORA', 'ROLE_DIRETORIA', 'ROLE_IMOBILIARIA');
private $createActionRoles = array('ROLE_CONSTRUTORA');
private $editActionRoles = array('ROLE_CONSTRUTORA');
private $showActionRoles = array('ROLE_CONSTRUTORA', 'ROLE_DIRETORIA', 'ROLE_IMOBILIARIA');
private $exportFilteredActionRoles = array('ROLE_CONSTRUTORA', 'ROLE_DIRETORIA', 'ROLE_IMOBILIARIA');
public function listAction($order = array('id' => 'DESC'))
{
if (!$this->get('security.token_storage')->getToken()->getUser()->hasRole($this->listActionRoles))
{
return $this->renderWithExtraParams("@ApplicationInternit/ContentBundle/Resources/views/permission.html.twig");
}
return parent::listAction($order);
}
public function createAction()
{
if (!$this->get('security.token_storage')->getToken()->getUser()->hasRole($this->createActionRoles))
{
return $this->renderWithExtraParams("@ApplicationInternit/ContentBundle/Resources/views/permission.html.twig");
}
$request = $this->getRequest();
// the key used to lookup the template
$templateKey = 'edit';
$this->admin->checkAccess('create');
$class = new \ReflectionClass($this->admin->hasActiveSubClass() ? $this->admin->getActiveSubClass() : $this->admin->getClass());
$newObject = $this->admin->getNewInstance();
$preResponse = $this->preCreate($request, $newObject);
if (null !== $preResponse) {
return $preResponse;
}
$this->admin->setSubject($newObject);
$form = $this->admin->getForm();
$form->setData($newObject);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$isFormValid = $form->isValid();
// persist if the form was valid and if in preview mode the preview was approved
if ($isFormValid && (!$this->isInPreviewMode() || $this->isPreviewApproved())) {
$this->persistImageApresentation($form);
$submittedObject = $form->getData();
$this->admin->setSubject($submittedObject);
$this->admin->checkAccess('create', $submittedObject);
try {
$token = md5(random_bytes(10).date('dmYHis'));
$realStatePercentList = $submittedObject->getRealStatePercents();
$productUserList = $submittedObject->getProductUsers();
$newObject->setProductUsers(null);
$newObject->setToken($token);
if($realStatePercentList)
{
//Checa percent = 100%
$totalPercent = 0;
foreach ($realStatePercentList as $rsPercent) {
$totalPercent += $rsPercent->getPercent();
}
if($totalPercent != 100)
{
$this->get('session')->getFlashBag()->set('flash_create_error', 'As porcentagens das imobiliárias devem somar 100%');
return $this->redirectToRoute('admin_internit_lead_product_create');
}
foreach ($realStatePercentList as $imob => $rsPercent) {
$imobComEspaco = str_replace(
array('_'),
' ',
$imob
);
$realEstate = $this->getDoctrine()->getRepository('ApplicationInternitRealEstateBundle:RealEstate')->findOneByName($imobComEspaco);
if($realEstate){
$rsPercent->setProduct($newObject);
$rsPercent->setRealEstate($realEstate);
$newRealStatePercent = $this->admin->create($rsPercent);
$newObject->addRealStatePercents($newRealStatePercent);
}
}
}
if($productUserList)
{
$i=0;
foreach ($productUserList as $user) {
$userImob = explode(':',$user);
$corretor = $this->getDoctrine()->getRepository('ApplicationSonataUserBundle:User')->findOneById($userImob[1]);
$realEstate = $this->getDoctrine()->getRepository('ApplicationInternitRealEstateBundle:RealEstate')->findOneById($userImob[0]);
if($corretor && $realEstate){
$productUser = new ProductUser();
$productUser->setUser($corretor);
$productUser->setRealEstate($realEstate);
$productUser->setProduct($newObject);
$productUser->setPosition($i);
$newProductUser = $this->admin->create($productUser);
$newObject->addProductUsers($newProductUser);
$i++;
}
}
}
$newObject = $this->admin->create($newObject);
$this->get('session')->getFlashBag()->set('flash_create_success', 'Mensagem enviada com sucesso');
// redirect to edit mode
return $this->redirectTo($newObject);
} catch (ModelManagerException $e) {
$this->handleModelManagerException($e);
$isFormValid = false;
}
}
// show an error message if the form failed validation
if (!$isFormValid) {
if (!$this->isXmlHttpRequest())
{
$errors = array();
foreach ($form->getErrors(true) as $error) {
$errors[] = $error->getMessage();
}
$this->get('session')->getFlashBag()->set('flash_create_error', implode('<br>', $errors));
}
}
}
$formView = $form->createView();
return $this->renderWithExtraParams($this->base."create.html.twig", [
'form' => $formView
], null);
}
public function saveExtraLeadsAction(Request $request)
{
$realEstate = $request->get('realStateId');
$extraLeads = $request->get('extraLeads');
$productId = $request->get('product');
$product = $this->getDoctrine()->getRepository('ApplicationInternitLeadBundle:realStatePercent')->findOneBy(['product' => $productId, 'realEstate' => $realEstate]);
if($product){
$product->setExtraLeads($extraLeads);
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
}
$route = $request->headers->get('referer');
return $this->redirect($route);
}
public function editAction($id = null)
{
if (!$this->get('security.token_storage')->getToken()->getUser()->hasRole($this->editActionRoles))
{
return $this->renderWithExtraParams("@ApplicationInternit/ContentBundle/Resources/views/permission.html.twig");
}
// return parent::editAction($id = null);
$request = $this->getRequest();
$templateKey = 'edit';
$id = $request->get($this->admin->getIdParameter());
$existingObject = $this->admin->getObject($id);
//dump($existingObject->getUpdatedAt());
if (!$existingObject) {
throw $this->createNotFoundException(sprintf('unable to find the object with id: %s', $id));
}
$form = $this->admin->getForm();
$form->setData($existingObject);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$isFormValid = $form->isValid();
$submittedObject = $form->getData();
$this->admin->setSubject($submittedObject);
try {
$realStatePercentList = $submittedObject->getRealStatePercents();
//Checa percent = 100%
$totalPercent = 0;
foreach ($realStatePercentList as $imob => $rsPercent) {
if (is_string($imob)) {
$totalPercent += $rsPercent->getPercent();
}
}
if($totalPercent != 100)
{
$this->get('session')->getFlashBag()->set('flash_create_error', 'As porcentagens das imobiliárias devem somar 100%');
$isFormValid = false;
// redirect to edit mode
return $this->redirectTo($existingObject);
}
$realStatePercent = $this->getDoctrine()->getRepository('ApplicationInternitLeadBundle:realStatePercent')->findBy(['product' => $submittedObject]);
$rpLastExtraLeads = [];
/** @var $rp realStatePercent */
foreach ($realStatePercent as $rp) {
$rpLastExtraLeads[$rp->getRealEstate()->getId()] = $rp->getExtraLeads();
}
//Clean corretores selecionados para atualizar
$this->getDoctrine()->getRepository('ApplicationInternitLeadBundle:Product')->cleanProductUser($submittedObject->getId());
$productUserList = $submittedObject->getProductUsers();
//Atualizar corretores selecionados
$submittedObject->setProductUsers(null);
if($productUserList){
$i=0;
foreach ($productUserList as $user) {
$userImob = explode(':',$user);
$corretor = $this->getDoctrine()->getRepository('ApplicationSonataUserBundle:User')->findOneById($userImob[1]);
$realEstate = $this->getDoctrine()->getRepository('ApplicationInternitRealEstateBundle:RealEstate')->findOneById($userImob[0]);
if($corretor && $realEstate){
$productUser = new ProductUser();
$productUser->setUser($corretor);
$productUser->setRealEstate($realEstate);
$productUser->setProduct($submittedObject);
$productUser->setPosition($i);
$newProductUser = $this->admin->create($productUser);
$submittedObject->addProductUsers($newProductUser);
$i++;
}
}
}
$lastRealStatePercent = $this->getDoctrine()->getRepository(realStatePercent::class)->findBy(['product' => $id]);
$this->getDoctrine()->getRepository('ApplicationInternitLeadBundle:Product')->cleanRealEstatePercent($submittedObject->getId());
// Salvar historico das turnos das imobiliarias do produto atual
// Quando for criar as novas realState_percent manter o campo turn
//Atualizar porcentagem das imobiliarias nas campanhas
if($realStatePercentList)
{
foreach ($realStatePercentList as $imob => $rsPercent) {
$imobComEspaco = str_replace(
array('_'),
' ',
$imob
);
$realEstate = $this->getDoctrine()->getRepository('ApplicationInternitRealEstateBundle:RealEstate')->findOneByName($imobComEspaco);
if($realEstate){
/**
* @var $lastRP realStatePercent
*/
foreach ($lastRealStatePercent as $lastRP){
if($lastRP->getRealEstate() === $realEstate){
$rsPercent->setTurn($lastRP->getTurn());
}
}
$rsPercent->setProduct($submittedObject);
$rsPercent->setRealEstate($realEstate);
$rsPercent->setExtraLeads($rpLastExtraLeads[$realEstate->getId()]?? 0);
$newRealStatePercent = $this->admin->create($rsPercent);
$submittedObject->addRealStatePercents($newRealStatePercent);
}
}
}
$existingObject = $this->admin->update($submittedObject);
$this->get('session')->getFlashBag()->set('flash_create_success', 'Mensagem enviada com sucesso');
// redirect to edit mode
return $this->redirectTo($existingObject);
} catch (ModelManagerException $e) {
$this->handleModelManagerException($e);
$isFormValid = false;
} catch (LockException $e) {
$this->get('session')->getFlashBag()->set('flash_create_error', 'Mensagem enviada com sucesso');
}
//}
// show an error message if the form failed validation
if (!$isFormValid) {
if (!$this->isXmlHttpRequest()) {
$this->addFlash(
'sonata_flash_error',
$this->trans(
'flash_edit_error',
['%name%' => $this->escapeHtml($this->admin->toString($existingObject))],
'SonataAdminBundle'
)
);
}
} elseif ($this->isPreviewRequested()) {
// enable the preview template if the form was valid and preview was requested
$templateKey = 'preview';
$this->admin->getShow();
}
}
$formView = $form->createView();
/* dump($existingObject);
dump($existingObject->getLeadsGroupByRealState());
dump($existingObject->getRealStateProductInfo());*/
// $realStatePercents = [];
// foreach ($existingObject->realStatePercentByName() as $realState)
// {
// $realStatePercents[] =
// }
return $this->renderWithExtraParams($this->base."edit.html.twig", [
'action' => 'edit',
'form' => $formView,
'obj' => $existingObject
], null);
}
public function showAction($id = null)
{
if (!$this->get('security.token_storage')->getToken()->getUser()->hasRole($this->showActionRoles))
{
return $this->renderWithExtraParams("@ApplicationInternit/ContentBundle/Resources/views/permission.html.twig");
}
$request = $this->getRequest();
$id = $request->get($this->admin->getIdParameter());
$filter=[
'from' => '',
'to' => '',
'imob' => '',
'group' => '',
'user' => '',
];
if(isset($_POST['filter']))
{
$filter = $_POST['filter'];
}
$data = $this->getDoctrine()->getRepository($this->bundle)->find($id);
$template = $this->base.'show.html.twig';
//$imobFilter = $this->getDoctrine()->getRepository('ApplicationInternitLeadBundle:Lead')->findAllImobs($id);
$imobs = $this->getDoctrine()->getRepository(RealEstate::class)->findAll();
foreach ($imobs as $imob){
$imobFilter[] = [ 'name' => $imob->getName() ];
}
$users = $this->getDoctrine()->getRepository(User::class)->findAll();
foreach ($users as $user){
$userFilter[] = [ 'name' => $user->getFirstname() ];
}
// dd($imobFilter);
$userGroup = $this->get('security.token_storage')->getToken()->getUser()->getGroups()[0]->getName();
return $this->renderWithExtraParams($template, [
'action' => 'show',
'data' => $data,
'imobFilter' => $imobFilter,
'userFilter' => $userFilter,
'filter' => $filter,
'userGroup' => $userGroup,
], null);
return parent::showAction($id = null);
}
/**
* Trata a requisição para exportar os leads filtrados em um arquivo csv.
* @param int $id - ID da campanha cujos leads serão exportados.
*/
public function exportFilteredAction($id = null)
{
if (!$this->get('security.token_storage')->getToken()->getUser()->hasRole($this->exportFilteredActionRoles))
{
return $this->renderWithExtraParams("@ApplicationInternit/ContentBundle/Resources/views/permission.html.twig");
}
$request = $this->getRequest();
$id = $request->get($this->admin->getIdParameter());
$product = $this->getDoctrine()->getRepository($this->bundle)->find($id);
$productName = is_null($product) ? '' : $product->getName();
$filter = $_POST['filter'];
$leads = $this->getDoctrine()->getRepository('ApplicationInternitLeadBundle:Lead')
->findLeadByGroup($id, $filter['group'], $filter);
$data = [];
if($filter['user'])
{
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(['firstname' => $filter['user']]);
$data = [];
foreach ($leads as $lead)
if($lead['brokerEmail'] == $user->getEmail())
$data[] = $lead;
$leads = $data;
}
$spreadsheet = new Spreadsheet();
/* @var $sheet \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet */
$sheet = $spreadsheet->getActiveSheet();
$date = date('d/m/Y H:i:s');
$dateFileName = date('d-m-y__H-i-s');
$this->generateFileContent($sheet, $leads);
$writer = new Csv($spreadsheet);
$group = empty($filter['group']) ? '' : $filter['group'];
$fileName = "leads_{$productName}_{$group}_$dateFileName.csv";
$contentType = 'text/csv';
return $this->generateFileResponse($fileName, $contentType, $writer);
}
/**
* Escreve os leads em um arquivo de spreadsheet.
*
* @param \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet $sheet - planilha de trabalho atual
* @param array $leads - array dos leads filtrados para escrita.
*/
private function generateFileContent($sheet, $leads)
{
$columns = [
'A' => ['label' => 'Nome', 'field' => 'name'],
'B' => ['label' => 'E-mail', 'field' => 'email'],
'C' => ['label' => 'Telefone', 'field' => 'phone'],
'D' => ['label' => 'Imobiliária', 'field' => 'brokerRealState'],
'E' => ['label' => 'E-mail corretor', 'field' => 'brokerEmail'],
'F' => ['label' => 'Origem', 'field' => 'origem'],
'G' => ['label' => 'Grupo', 'field' => 'group'],
'H' => ['label' => 'Data de envio', 'field' => 'createdAt'],
'I' => ['label' => 'Utm Source', 'field' => 'utm_source'],
'J' => ['label' => 'Utm Medium', 'field' => 'utm_medium'],
'K' => ['label' => 'Utm Campaign', 'field' => 'utm_campaign'],
];
$indRow = 1;
foreach($columns as $col => $content) {
$sheet->setCellValue($col . $indRow, $content['label']);
}
$indRow = 2;
foreach($leads as $lead) {
foreach ($columns as $col => $content) {
$field = $content['field'];
$sheet->setCellValue($col . $indRow, $lead[$field]);
}
$indRow++;
}
}
/**
* Gera o arquivo csv exportado como uma resposta para o cliente.
*
* @param string $fileName - nome do arquivo
* @param string $contentType - tipo mime do arquivo
* @param use PhpOffice\PhpSpreadsheet\Writer\Csv $writer - objeto que vai exportar o arquivo csv
* @return StreamedResponse
*/
private function generateFileResponse($fileName, $contentType, $writer)
{
$response = new StreamedResponse();
$response->headers->set('Content-Type', $contentType);
$response->headers->set('Content-Disposition', 'attachment;filename="'.$fileName.'"');
$response->setPrivate();
$response->headers->addCacheControlDirective('no-cache', true);
$response->headers->addCacheControlDirective('must-revalidate', true);
$response->setCallback(function() use ($writer) {
$writer->save('php://output');
});
return $response;
}
public function getBundleName()
{
return 'ApplicationInternitLeadBundle';
}
public function getEntityName()
{
return 'Product';
}
public function getFormType()
{
return 'App\Application\Internit\LeadBundle\Form\ProductType';
}
}