<?php
/**
* Created by PhpStorm.
* User: SEBASTIAN TOVAR
* Date: 25/06/2019
* Time: 06:10 PM
*/
namespace App\EventSubscriber\Onboarding;
use App\Entity\App\Role;
use App\Entity\App\Ticket\Ticket;
use App\Entity\Onboarding\Invitation;
use App\Entity\Onboarding\Lead;
use App\Entity\Onboarding\LeadStaff;
use App\Repository\App\UserRepository;
use App\Repository\Onboarding\LeadStaffRepository;
use App\Services\InvitationService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\Translation\TranslatorInterface;
use ApiPlatform\Core\EventListener\EventPriorities;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\App\VendorRepository;
use App\Repository\App\CompanyRepository;
use App\Services\VendorService;
use App\Services\UserService;
use App\Entity\App\User;
use App\Entity\App\Vendor;
class LeadPostWriteSubcriber implements EventSubscriberInterface
{
private $userRepository;
private $leadStaffRepository;
private $invitationService;
private $translator;
private $vendorRepository;
private $userService;
private $vendorService;
private $entityManager;
private $companyRepository;
public function __construct(
EntityManagerInterface $entityManager,
UserRepository $userRepository,
LeadStaffRepository $leadStaffRepository,
CompanyRepository $companyRepository,
VendorRepository $vendorRepository,
VendorService $vendorService,
UserService $userService,
InvitationService $invitationService,
TranslatorInterface $translator)
{
$this->entityManager = $entityManager;
$this->userRepository = $userRepository;
$this->leadStaffRepository = $leadStaffRepository;
$this->invitationService = $invitationService;
$this->translator = $translator;
$this->vendorRepository = $vendorRepository;
$this->userService = $userService;
$this->vendorService = $vendorService;
$this->companyRepository = $companyRepository;
}
/**
* @param ViewEvent $event
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function onKernelView(ViewEvent $event)
{
$lead = $event->getControllerResult();
$request = $event->getRequest();
$route = $request->attributes->get('_route');
if (!($lead instanceof Lead))
return;
if(false == $this->entityManager->getConnection()->ping()){
$this->entityManager->getConnection()->close();
$this->entityManager->getConnection()->connect();
}
if ('api_leads_put_item' == $route) {
if ($lead->getFinish()) {
$lead->setIsCompleted(true);
$this->entityManager->persist($lead);
$this->entityManager->flush();
}
$data = json_decode($request->getContent(), true);
$version = $lead->getVersion();
switch ($version) {
case 1:
$this->runEntitiesCreationV1($lead,$data);
break;
case 2:
$this->runEntitiesCreationV2($lead,$data);
break;
}
}
}
/**
* @param $vendorName
* @return mixed|string
*/
protected function generateVendorCode($vendorName)
{
$baseCode = strtoupper(iconv('UTF-8', 'ASCII//TRANSLIT', preg_replace('/\s/', '', $vendorName)));
$baseCode = str_replace("'", '', $baseCode);
$code = $baseCode;
do {
$vendorWithCode = $this->entityManager->getRepository(Vendor::class)->findOneBy(['signUpCode' => $code]);
if (!$vendorWithCode instanceof Vendor) {
break;
}
$code = $baseCode.rand(1, 999);
} while (true);
return $code;
}
/**
* @param Lead $lead
* @param $data
* @throws \Doctrine\ORM\NonUniqueResultException
*/
protected function runEntitiesCreationV2(Lead $lead, $data)
{
//Se reporta que el formulario se ha completado
if ($lead->getIsCompleted()) {
$status = null;
$success = true;
//Create vendor
try {
$vendor = new Vendor();
$vendor->setName($lead->getVendorName());
$vendor->setSignUpCode($this->generateVendorCode($vendor->getName()));
$this->entityManager->persist($vendor);
//$this->entityManager->merge($vendor);
$lead->setVendor($vendor);
$this->entityManager->persist($lead);
//$this->entityManager->merge($lead);
$this->entityManager->flush();
$status['vendor'] = $this->translator->trans(
'Vendor was successfully created',
['%name%' => $lead->getVendorName()],
null,
'es'
);
} catch (\Exception $e) {
$status['vendor'] = $this->translator->trans(
'Error! Vendor was not created, user invitations could not be sent.',
['%name%' => $lead->getVendorName()],
null,
'es'
);
$success = false;
}
if ($success) {
//Create admin user
$criteria = $lead->getEmail() ?? $lead->getMobileNumber();
$dataType = $lead->getEmail() ? 'email' : 'mobile';
$msj = '';
$success = $this->invitationService->createUserInvitationV2($vendor, $lead, ['admin'], $msj);
$status['admin'] = array(
'criteria' => $criteria,
'status' => $success,
'msj' => $msj
);
if ($success) {
//Create Requests
$identify = 1;
if (!is_null($lead->getTask1())) {
$success = $this->invitationService->createTicket($identify, $vendor, $lead->getTask1());
$status['task'][1] = $success ? $this->translator->trans(
'Ticket was successfully created',
[],
null,
'es'
) : $this->translator->trans('Error!, Ticket could not be created', [], null, 'es');
$identify = $success ? 2 : $identify;
}
if (!is_null($lead->getTask2())) {
$success = $this->invitationService->createTicket($identify, $vendor, $lead->getTask2());
$status['task'][2] = $success ? $this->translator->trans(
'Ticket was successfully created',
[],
null,
'es'
) : $this->translator->trans('Error!, Ticket could not be created', [], null, 'es');
}
} else {
//$this->entityManager->remove($vendor);
$lead->setIsCompleted(false);
$lead->setVendor(null);
}
}
$lead->setStatusSummary($status);
if (false == $this->entityManager->getConnection()->ping()) {
$this->entityManager->getConnection()->close();
$this->entityManager->getConnection()->connect();
}
if (!$this->entityManager->isOpen()) {
$this->entityManager = \Doctrine\ORM\EntityManager::create(
$this->entityManager->getConnection(),
$this->entityManager->getConfiguration()
);
}
$this->entityManager->merge($lead);
$this->entityManager->flush();
$this->entityManager->clear();
}
}
/**
* @param Lead $lead
* @param $data
* @throws \Doctrine\ORM\NonUniqueResultException
*/
protected function runEntitiesCreationV1(Lead $lead, $data)
{
switch ($lead->getStep()) {
case Lead::USERS_STEP:
$this->createLeadStaff($data['users'], $lead, $lead->getStep());
break;
case Lead::OPERATORS_STEP:
$this->createLeadStaff($data['operators'], $lead, $lead->getStep());
break;
case Lead::TASKS_STEP:
break;
}
//Se reporta que el formulario se ha completado
if ($lead->getIsCompleted()) {
$status = null;
$success = true;
//Create vendor
try {
$vendor = new Vendor();
$vendor->setName($lead->getVendorName());
$vendor->setSignUpCode($this->generateVendorCode($vendor->getName()));
$this->entityManager->persist($vendor);
$lead->setVendor($vendor);
$this->entityManager->persist($lead);
$this->entityManager->flush();
$status['vendor'] = $this->translator->trans(
'Vendor was successfully created',
['%name%' => $lead->getVendorName()],
null,
'es'
);
} catch (\Exception $e) {
$status['vendor'] = $this->translator->trans(
'Error! Vendor was not created, user invitations could not be sent.',
['%name%' => $lead->getVendorName()],
null,
'es'
);
$success = false;
}
if ($success) {
//Create admin user
$criteria = $lead->getEmail() ?? $lead->getMobileNumber();
$dataType = $lead->getEmail() ? 'email' : 'mobile';
$msj = '';
$success = $this->invitationService->createUserInvitation(
$vendor,
$criteria,
$dataType,
[Role::ROLE_ADMIN],
$lead->getName(),
$msj,
true,
$lead->getName()
);
$status['admin'] = array(
'criteria' => $criteria,
'status' => $success,
'msj' => $msj
);
//Create staff
$leadStaff = $lead->getLeadStaff();
$count = 0;
foreach ($leadStaff as $staffItem) {
$roles = null;
if ($staffItem->getIsUser()) {
$roles[] = Role::ROLE_USER;
}
if ($staffItem->getIsOperator()) {
$roles[] = Role::ROLE_OPERATOR;
}
if (!is_null($roles)) {
$criteria = $staffItem->getEmail() ?? $staffItem->getPhoneNumber();
$dataType = $staffItem->getEmail() ? 'email' : 'mobile';
$msj = '';
$success = $this->invitationService->createUserInvitation(
$vendor,
$criteria,
$dataType,
$roles,
$lead->getName(),
$msj
);
$status['staff'][$count] = array(
"criteria" => $criteria,
"status" => $success,
"msj" => $msj
);
if ($success) {
$staffItem->setIsAlreadyInvited(true);
$this->entityManager->persist($staffItem);
$this->entityManager->flush();
}
$count++;
}
}
//Create Requests
$identify = 1;
if (!is_null($lead->getTask1())) {
$success = $this->invitationService->createTicket($identify, $vendor, $lead->getTask1());
$status['task'][1] = $success ? $this->translator->trans(
'Ticket was successfully created',
[],
null,
'es'
) : $this->translator->trans('Error!, Ticket could not be created', [], null, 'es');
$identify = $success ? 2 : $identify;
}
if (!is_null($lead->getTask2())) {
$success = $this->invitationService->createTicket($identify, $vendor, $lead->getTask2());
$status['task'][2] = $success ? $this->translator->trans(
'Ticket was successfully created',
[],
null,
'es'
) : $this->translator->trans('Error!, Ticket could not be created', [], null, 'es');
}
}
$lead->setStatusSummary($status);
if (false == $this->entityManager->getConnection()->ping()) {
$this->entityManager->getConnection()->close();
$this->entityManager->getConnection()->connect();
}
$this->entityManager->persist($lead);
$this->entityManager->flush();
}
}
protected function createLeadStaff($contactsField, Lead $lead, $step) {
$contactArray = array();
if (!is_null($contactsField)) {
$contactArray = explode(",",preg_replace('/\s+/','',$contactsField));
//Adding leadStaff
foreach ($contactArray as $contact) {
if(!empty($contact)) {
$leadStaff = $this->leadStaffRepository->loadLeadByEmailMobile($contact,$lead);
if (!$leadStaff instanceof LeadStaff) {
$leadStaff = new LeadStaff();
$leadStaff->setLead($lead);
if (filter_var($contact, FILTER_VALIDATE_EMAIL)) {
$leadStaff->setEmail($contact);
}
elseif (preg_match('/^\+[\d -]+$/', $contact)) {
$leadStaff->setPhoneNumber($contact);
}
}
if ($step == Lead::OPERATORS_STEP) {
$leadStaff->setIsOperator(true);
}
elseif ($step == Lead::USERS_STEP) {
$leadStaff->setIsUser(true);
}
$this->entityManager->persist($leadStaff);
$this->entityManager->flush();
}
}
}
//Removing leadStaff
$leadStaff = $lead->getLeadStaff();
foreach ($leadStaff as $leadStaffItem) {
$criteria = $leadStaffItem->getEmail() ?? $leadStaffItem->getPhoneNumber();
if (!in_array($criteria, $contactArray)) {
if ($step == Lead::USERS_STEP && $leadStaffItem->getIsUser()) {
$leadStaffItem->setIsUser(false);
}
elseif ($step == Lead::OPERATORS_STEP && $leadStaffItem->getIsOperator()) {
$leadStaffItem->setIsOperator(false);
}
$this->entityManager->persist($leadStaffItem);
$this->entityManager->flush();
}
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::POST_WRITE]
];
}
}