<?php
namespace App\Controller\Clients;
use App\Domain;
use App\Domain\Entities;
use App\Security\Voter\ClientVoter;
use DateTime;
use Doctrine\DBAL;
use Doctrine\ORM;
use Exception;
use Symfony\Bundle\FrameworkBundle;
use Symfony\Component\HttpFoundation;
class ClientController extends FrameworkBundle\Controller\AbstractController
{
private DBAL\Connection $connection;
private ORM\EntityManagerInterface $entityManager;
private Domain\Repositories\ApplicationRepository $applicationRepository;
public function __construct(
DBAL\Connection $connection,
ORM\EntityManagerInterface $entityManager,
Domain\Repositories\ApplicationRepository $applicationRepository,
) {
$this->connection = $connection;
$this->entityManager = $entityManager;
$this->applicationRepository = $applicationRepository;
}
public function index(): HttpFoundation\Response
{
return $this->render(
'clients/client/index.html.twig',
array(
'adminlevel' => $this->get('session')->get('adminlevel'),
)
);
}
public function search(HttpFoundation\Request $request): HttpFoundation\Response
{
$clientName = $request->get('criteria');
$criteria = preg_replace('/ +/', ' ', preg_replace('/[^\'a-z ]/', ' ', strtolower($clientName)));
$sql = "
SELECT *
FROM clients
WHERE (CONCAT_WS(' ', lower(clients.lname), lower(clients.fname)) LIKE lower(:criteria) OR CONCAT_WS(' ', lower(clients.fname), lower(clients.lname)) LIKE lower(:criteria))
ORDER BY lname";
$statement = $this->connection->prepare($sql);
$statement->bindValue(':criteria', $criteria . '%');
$result = $statement->executeQuery();
$clients = $result->fetchAllAssociative();
return $this->render(
'clients/client/search.html.twig',
array(
'clients' => $clients,
'criteria' => $clientName
)
);
}
public function add(HttpFoundation\Request $request): HttpFoundation\Response
{
$allow = $request->get('allow');
if ($this->get('session')->get('adminlevel') == 5 && empty($allow)) {
return $this->redirect('/clients/client');
}
$client = new Entities\Client();
if ($request->getMethod() == 'POST' && $this->setClient($client, $request)) {
$redirectTo = '/clients/client/edit/';
if (!empty($this->get('session')->get('redirecttype')) && $this->get('session')->get('redirecttype') == 'newclient' && !empty($this->get('session')->get('redirect'))) {
$redirectTo = $this->get('session')->get('redirect');
}
return $this->redirect($redirectTo . $client->getId());
}
return $this->render(
'clients/client/form.html.twig',
array(
'client' => $client,
'county' => '',
'applications' => $this->applicationRepository->applicationsOfClientIdentity($client->getId()),
'carriers' => $this->entityManager->getRepository(Entities\Carrier::class)->findAll([], ['name' => 'ASC']),
'showProtectedFields' => true,
)
);
}
public function edit(HttpFoundation\Request $request): HttpFoundation\Response
{
$id = $request->get('id');
$client = $this->entityManager->find(Entities\Client::class, $id);
if (!$client) {
return $this->redirect('/clients/client');
}
if ($request->getMethod() == "POST" && $this->setClient($client, $request)) {
$redirectTo = '/clients/client/edit/';
if (!empty($this->get('session')->get('redirecttype')) && $this->get('session')->get('redirecttype') == 'newclient' && !empty($this->get('session')->get('redirect'))) {
$redirectTo = $this->get('session')->get('redirect');
}
return $this->redirect($redirectTo . $client->getId());
}
return $this->render(
'clients/client/form.html.twig',
array(
'client' => $client,
'county' => $this->lookupCounty($client->getCity(), $client->getState()),
'applications' => $this->applicationRepository->applicationsOfClientIdentity($client->getId()),
'carriers' => $this->entityManager->getRepository(Entities\Carrier::class)->findAll([], ['name' => 'ASC']),
'showProtectedFields' => $this->showProtectedFields($client->getId()),
)
);
}
public function deleteComment(HttpFoundation\Request $request): HttpFoundation\Response
{
$id = $request->get('id');
$commentId = $request->get('commentId');
$client = $this->entityManager->find(Entities\Client::class, $id);
if (!$client) {
throw new Exception("Invalid client id specified");
}
$comment = $client->removeCommentById($commentId);
$this->entityManager->remove($comment);
$this->entityManager->flush();
return new HttpFoundation\Response();
}
public function loadApplications(HttpFoundation\Request $request)
{
$id = $request->get('id', -1);
$client = $this->entityManager->find(Entities\Client::class, $id);
if (!$client) {
throw new Exception("Invalid client id specified");
}
return $this->render(
'clients/client/applications.html.twig',
array(
'applications' => $this->entityManager->getRepository(Entities\Application::class)->findBy(['client' => $client], ['effectivedate' => 'desc']),
'agent' => $this->entityManager->getRepository(Entities\Agent::class)->find($this->get('session')->get('idagent')),
'isAdmin' => $this->get('session')->get('adminlevel') == 0,
)
);
return new HttpFoundation\Response();
}
public function checkForDuplicate(HttpFoundation\Request $request): HttpFoundation\Response
{
$id = $request->get('id', -1);
$firstName = $request->get('firstName');
$lastName = $request->get('lastName');
$clients = $this->entityManager->getRepository(Entities\Client::class)
->findBy([
'firstName' => $firstName,
'lastName' => $lastName,
]);
$hasDuplicate = false;
foreach ($clients as $client) {
if ($client->getId() == $id) {
continue;
}
$hasDuplicate = true;
break;
}
return $this->json([
'hasDuplicate' => $hasDuplicate,
'canOverride' => $this->get('session')->get('adminlevel') == 0
]);
}
protected function setClient(Entities\Client &$client, $request)
{
$firstName = $request->get('firstName');
$middle = $request->get('middle');
$lastName = $request->get('lastName');
$email = $request->get('email');
$suffix = $request->get('suffix');
$primaryPhone = $request->get('primaryPhone');
$altPhone = $request->get('altPhone');
$dateOfBirth = $request->get('dateOfBirth');
$dateOfDeath = $request->get('dateOfDeath');
$medicareNumber = $request->get('medicareNumber', null);
$medicaidNumber = $request->get('medicaidNumber', null);
$medicareAEffectiveDate = $request->get('medicareAEffectiveDate');
$medicareBEffectiveDate = $request->get('medicareBEffectiveDate');
$social = $request->get('social');
$smoker = $request->get('smoker');
$gender = $request->get('gender');
$street = $request->get('street');
$city = $request->get('city');
$state = $request->get('state');
$zip = $request->get('zip');
$poBoxStreet = $request->get('poBoxStreet');
$poBoxCity = $request->get('poBoxCity');
$poBoxState = $request->get('poBoxState');
$poBoxZip = $request->get('poBoxZip');
$spouseName = $request->get('spouseName');
$spouseDateOfBirth = $request->get('spouseDateOfBirth');
$spouseSmoker = $request->get('spouseSmoker', 0);
$comments = $request->get('comments');
if (!$firstName) {
$this->addFlash('error', 'You must specify a first name');
return false;
} else if (!$lastName) {
$this->addFlash('error', 'You must specify a last name');
return false;
} else if (!$dateOfBirth) {
$this->addFlash('error', 'You must specify a date of birth');
return false;
}
$client->setFirstName($firstName)
->setMiddle($middle)
->setLastName($lastName)
->setEmail($email)
->setSuffix($suffix)
->setDateOfBirth(new DateTime($dateOfBirth))
->setDateOfDeath(empty($dateOfDeath) ? null : new DateTime($dateOfDeath))
->setMedicareAEffectiveDate(empty($medicareAEffectiveDate) ? null : new DateTime($medicareAEffectiveDate))
->setMedicareBEffectiveDate(empty($medicareBEffectiveDate) ? null : new DateTime($medicareBEffectiveDate))
->setMedicareNumber($medicareNumber)
->setMedicaidNumber($medicaidNumber)
->setSmoker($smoker == 'null' ? null : $smoker)
->setGender($gender == 'null' ? '' : $gender)
->setStreet($street)
->setCity($city)
->setState($state)
->setZip($zip)
->setPoBoxStreet($poBoxStreet)
->setPoBoxCity($poBoxCity)
->setPoBoxState($poBoxState)
->setPoBoxZip($poBoxZip)
->setSpouseName($spouseName)
->setSpouseDateOfBirth(empty($spouseDateOfBirth) ? null : new DateTime($spouseDateOfBirth))
->setSpouseSmoker($spouseSmoker);
// Agents can only set this when the client is initially created but
// after that they cannot modify it.
if ($this->showProtectedFields($client->getId())) {
$client->setPrimaryPhone($primaryPhone)
->setAltPhone($altPhone)
->setSocial($social);
}
if (!empty($comments)) {
$comment = new Entities\ClientComment($client, $comments, $this->get('session')->get('userstamp'));
$client->addComment($comment);
}
try {
$this->entityManager->persist($client);
$this->entityManager->flush();
} catch (Exception $e) {
$this->addFlash('error', 'Unable to save client: ' . $e->getMessage());
return false;
}
$this->addFlash('success', 'Client saved successfully');
return true;
}
protected function lookupCounty(?string $city, ?string $state): string
{
if (empty($city) || empty($state)) {
return '';
}
$result = $this->connection->executeQuery(
'SELECT DISTINCT county FROM county_areas WHERE city = :city AND state = :state ORDER BY county',
['city' => $city, 'state' => $state]
);
return implode(' / ', array_column($result->fetchAllAssociative(), 'county'));
}
protected function showProtectedFields($idclient): bool
{
if (empty($idclient)) {
return true;
}
return $this->isGranted(ClientVoter::UPDATE, $idclient);
}
}