<?php
namespace App\Controller;
use App\Entity\{Cases, LabTestMethod, Sample, TestMethod};
use App\Form\SampleType;
use App\Repository\{CaseLaboratoryRepository, HospitalRepository, LabTestRepository, SampleRepository, TestMethodRepository};
use App\Service\{Pagination, Abha};
use App\Util\CodeGenerator;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\{IsGranted, ParamConverter, Security};
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\{JsonResponse, Request, Response};
use Symfony\Component\Routing\Annotation\Route;
use Nzo\UrlEncryptorBundle\Annotations\ParamDecryptor;
use Nzo\UrlEncryptorBundle\Encryptor\Encryptor;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
#[Route(path: '/lab-tests'), IsGranted(data: 'ROLE_LAB_TECH')]
class CaseLaboratoryController extends AbstractController
{
private $encryptor;
private $abha;
public function __construct(Encryptor $encryptor, private ManagerRegistry $doctrine, Abha $abha)
{
$this->encryptor = $encryptor;
$this->abha = $abha;
}
#[Route(path: '/{status}', name: 'case_lab_test', methods: ['GET'])]
public function index(Request $request, Pagination $pagination, CaseLaboratoryRepository $caseLabRepo, string $status = 'all'): Response
{
$query = $caseLabRepo->getCaseLaboratoryList($this->getUser()->getHospital(), $status);
$cases = $pagination->paginate($query, $request, $this->getParameter('items_per_page'));
return $this->render('case_laboratory/index.html.twig', [
'cases' => $cases,
'last_page' => $pagination->lastPage($cases)
]);
}
#[Route(path: '/add-sample/{id}', name: 'case_lab_add_sample', methods: ['GET', 'POST'])]
#[ParamConverter(data: 'case', options: ['mapping' => ['id' => 'id']])]
#[ParamDecryptor(["id"])]
public function addSample(Request $request, Cases $case, EntityManagerInterface $entityManager, CaseLaboratoryRepository $caseLabRepo, LabTestRepository $labTestRepo): Response
{
if ($case->getLabTestStatus() != "Pending") {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
}
$caseId = $this->encryptor->encrypt($case->getId());
$hospitalId = $case->getHospital()->getId();
$sample = new Sample();
if ($request->isMethod('GET') || $request->isMethod('POST') && $case->getHospital()->getId() == $this->getUser()->getProfile()->getHospital()->getId() && $case->getPatient()->getId() == $request->attributes->get('case')->getPatient()->getId()) {
$form = $this->createForm(SampleType::class, $sample);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$sample->setCase($case);
$sample->setNumber((new CodeGenerator())->generateSampleNumber($case->getId()));
$entityManager->persist($sample);
$entityManager->flush();
$this->addFlash(
'success',
'Sample added successfully!'
);
return $this->redirectToRoute('case_lab_add_sample', ['id' => $caseId]);
}
$tests = $caseLabRepo->getCaseTestsForReport($case->getId());
$samples = $caseLabRepo->getCaseSamples($case->getId());
$hospitals = $labTestRepo->getOtherHospitals($hospitalId);
return $this->renderForm('case_laboratory/add_sample.html.twig', [
'patient_id' => $case->getPatient()->getId(),
'tests' => $tests,
'form' => $form,
'samples' => $samples,
'case_id' => $caseId,
'hospitals' => $hospitals
]);
} else {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
}
}
#[Route(path: '/delete-sample/{id}', name: 'case_lab_sample_delete', methods: ['GET'])]
#[ParamDecryptor(["id"])]
public function deleteSample(Sample $sample, EntityManagerInterface $entityManager, Request $request): Response
{
$case = $sample->getCase();
if ($sample->getCase()->getLabTestStatus() == "Pending" && $case->getHospital()->getId() == $this->getUser()->getProfile()->getHospital()->getId() && $case->getPatient()->getId() == $sample->getCase()->getPatient()->getId()) {
try {
$entityManager->remove($sample);
$entityManager->flush();
$this->addFlash(
'success',
'Sample deleted successfully!'
);
} catch (\Exception) {
$this->addFlash(
'danger',
'Sample could not be deleted! There may be related tests.'
);
}
return $this->redirectToRoute('case_lab_add_sample', ['id' => $this->encryptor->encrypt($case->getId())]);
} else {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
}
}
#[Route(path: '/assign-sample-to-test/{case_id}', name: 'case_lab_add_test_sample', methods: ['GET', 'POST'])]
#[ParamDecryptor(["case_id"])]
public function assignSampleToTest(Request $request, EntityManagerInterface $entityManager, CaseLaboratoryRepository $caseLabRepo, SampleRepository $sampleRepo, HospitalRepository $hospitalRepo): Response
{
$caseId = $this->encryptor->encrypt($request->attributes->get('case_id'));
if ($request->request->has('confirm_samples')) {
$confirmedSamples = (array)$request->request->get('confirm_samples');
$samples = $request->request->get('samples');
$hospitals = $request->request->get('hospitals');
$tests = (array)$request->request->get('tests');
$isAllDone = [];
foreach ($confirmedSamples as $subKey) {
$caseLab = $caseLabRepo->find($tests[$subKey]);
$sample = $sampleRepo->find($samples[$subKey]);
if ($sample) {
$caseLab->setSample($sample);
if ($hospitals[$subKey]) {
$hospital = $hospitalRepo->find($hospitals[$subKey]);
if ($hospital) {
$caseLab->setHospital($hospital);
}
}
$entityManager->persist($caseLab);
$isAllDone[] = $tests[$subKey];
} else {
$this->addFlash(
'danger',
'Invalid data submitted'
);
return $this->redirectToRoute('case_lab_add_sample', ['id' => $caseId]);
}
}
$entityManager->flush();
if (!empty($isAllDone) && !empty($tests) && count($isAllDone) == count($tests)) {
$entityManager->getConnection()->update('cases', ['lab_test_status' => 'Sample taken'], ['id' => $request->attributes->get('case_id')]);
$this->addFlash(
'success',
'Samples added to all tests successfully!'
);
return $this->redirectToRoute('case_lab_test');
}
$this->addFlash(
'success',
'Sample added to tests successfully!'
);
} else {
$this->addFlash(
'danger',
'Please select at least one report to submit.'
);
}
return $this->redirectToRoute('case_lab_add_sample', ['id' => $caseId]);
}
#[Route(path: '/results/add-result/{id}', name: 'case_lab_add_result', methods: ['GET', 'POST'])]
#[ParamConverter(data: 'case', options: ['mapping' => ['id' => 'id']])]
#[ParamDecryptor(["id"])]
public function addResult(Request $request, Cases $case, EntityManagerInterface $entityManager, CaseLaboratoryRepository $caseLabRepo, TestMethodRepository $testMethodRepo, LabTestRepository $labTestRepo): Response
{
$caseId = $case->getId();
$hospitalId = $this->encryptor->encrypt($case->getHospital()->getId());
if ($request->isMethod('GET') || $request->isMethod('POST') && $case->getHospital()->getId() == $this->getUser()->getProfile()->getHospital()->getId() && $case->getPatient()->getId() == $request->attributes->get('case')->getPatient()->getId()) {
if ($request->getMethod() == 'POST') {
if ($request->request->has('confirm_results')) {
$confirmedResults = (array)$request->request->get('confirm_results');
$methods = $request->request->get('methods');
$results = $request->request->get('results');
$tests = (array)$request->request->get('tests');
$otherMethods = $request->request->get('other_methods');
$newMethods = [];
if ($request->request->has('new_methods')) {
$newMethods = $request->request->get('new_methods');
}
$isAllDone = [];
foreach ($confirmedResults as $subKey) {
$caseLab = $caseLabRepo->find($tests[$subKey]);
if (isset($otherMethods[$subKey]) && $otherMethods[$subKey] != '') {
$methodData = explode('~~', $otherMethods[$subKey]);
foreach ($methodData as $method) {
$testMethod = new TestMethod();
$testMethod->setName($method);
$entityManager->persist($testMethod);
if (isset($newMethods[$subKey]) && $newMethods[$subKey] == $method) {
$caseLab->setMethod($testMethod);
}
$labTestMethod = new LabTestMethod();
$labTestMethod->setTest($caseLab->getLabTest());
$labTestMethod->setMethod($testMethod);
$entityManager->persist($labTestMethod);
}
$entityManager->flush();
}
if (isset($methods[$subKey]) && !empty($methods[$subKey])) {
$method = $testMethodRepo->find($methods[$subKey]);
if ($method) {
$caseLab->setMethod($method);
} else {
$this->addFlash(
'danger',
'Invalid data submitted'
);
return $this->redirectToRoute('case_lab_add_result', ['id' => $this->encryptor->encrypt($case->getId())]);
}
}
if (isset($results[$subKey]) && $results[$subKey] != '') {
$caseLab->setResult($results[$subKey]);
$entityManager->persist($caseLab);
$isAllDone[] = $tests[$subKey];
} else {
$this->addFlash(
'danger',
'Result is mandatory'
);
return $this->redirectToRoute('case_lab_add_result', ['id' => $this->encryptor->encrypt($case->getId())]);
}
}
$entityManager->flush();
if (!empty($isAllDone) && !empty($tests) && count($isAllDone) == count($tests)) {
$entityManager->getConnection()->update('cases', ['lab_test_status' => 'Completed'], ['id' => $caseId]);
}
$this->addFlash(
'success',
'Result to tests added successfully!'
);
return $this->redirectToRoute('case_lab_test');
} else {
$this->addFlash(
'danger',
'Please provide at least one result.'
);
return $this->redirectToRoute('case_lab_add_result', ['id' => $this->encryptor->encrypt($case->getId())]);
}
}
$caseTests = $caseLabRepo->getTestForResults($caseId);
$hospitals = $labTestRepo->getOtherHospitals($hospitalId);
return $this->render('case_laboratory/add_result.html.twig', [
'tests' => $caseTests,
'patient' => $case->getPatient(),
'hospitals' => $hospitals
]);
} else {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
}
}
#[Route(path: '/search-tests', name: 'search_tests', methods: ['GET', 'POST'])]
public function searchTests(Request $request, LabTestRepository $labTestRepo): JsonResponse
{
$q = $request->query->get('q');
$labTests = $labTestRepo->getSearchResults($q);
$searchResults = [
'total_count' => is_countable($labTests) ? count($labTests) : 0,
'incomplete_results' => true,
'items' => $labTests
];
return $this->json($searchResults);
}
#[Route(path: '/print/{id}', name: 'case_lab_print', methods: ['GET'])]
#[ParamDecryptor(["id"])]
#[Security("is_granted('ROLE_DOC') or is_granted('ROLE_LAB_TECH')")]
public function print(Request $request, Cases $case, CaseLaboratoryRepository $caseLabRepo): Response
{
if ($case->getHospital()->getId() == $this->getUser()->getProfile()->getHospital()->getId() && $case->getPatient()->getId() == $request->attributes->get('case')->getPatient()->getId()) {
return $this->render('case_laboratory/print.html.twig', [
'case' => $case,
'tests' => $caseLabRepo->getCaseTests($case->getId())
]);
} else {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
}
}
#[Route(path: '/consent/{id}', name: 'lab_consent', methods: ['GET'])]
#[ParamDecryptor(["id"])]
public function consent(Request $request, Abha $abha): Response
{
$id = $this->encryptor->encrypt($request->attributes->get('id'));
$arrData = $abha->getConsentList();
$uri = $this->generateUrl('lab_consent_req_form', ['id' => $id]);
return $this->render('abha/consent.html.twig', [
'consents' => $arrData,
'form_url' => $uri,
'data_request' => 'lab_data_request',
'view_data' => 'lab_view_data'
]);
}
/**
* M3 Start
*/
#[Route(path: '/consent-request/{id}', name: 'lab_consent_req_form', methods: ['GET'])]
#[ParamDecryptor(["id"])]
public function consentForm(Request $request, Abha $abha): Response
{
//cross site script
return $this->render('abha/consent_form.html.twig', [
'post_form_url' => 'lab_request_init',
'patient_find_url' => 'lab_patient_find',
'id' => $this->encryptor->encrypt($request->attributes->get('id'))
]);
}
#[Route(path: '/consent-request-init', name: 'lab_request_init', methods: ['GET', 'POST'])]
public function requestInit(Request $request, Abha $abha): Response
{
/* if ($this->getUser()->getHospital()->getId() == $case->getHospital()->getId()) {
} else {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
} */
//TODO :: get health address from patient table
$reqData = $request->request->all();
$reqData['hiuParName'] = $this->getUser()->getProfile()->getFirstName() . ' ' . $this->getUser()->getProfile()->getLastName(); // practitioner name
$reqData['hiuId'] = $this->getUser()->getProfile()->getHospital()->getHIUCode();
$request = $abha->requestInt($reqData);
if ($request) {
return $this->redirectToRoute('lab_case_consent', ['id' => $reqData['id']]);
} else {
return $this->render('abha/consent_form.html.twig', [
'post_form_url' => 'lab_request_init',
'patient_find_url' => 'lab_patient_find'
]);
}
}
#[Route(path: '/data-request/{id}', name: 'lab_data_request', methods: ['GET', 'POST'])]
#[ParamDecryptor(["id"])]
public function dataRequest(Request $request, Abha $abha): Response
{
/* if ($this->getUser()->getHospital()->getId() == $case->getHospital()->getId()) {
} else {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
} */
$id = $request->attributes->get('id');
$response = $abha->getDataRequest($id);
$id = $this->encryptor->encrypt($request->attributes->get('id'));
return $this->redirectToRoute('lab_consent', ['id' => $id]);
}
#[Route(path: '/view-data/{id}', name: 'lab_view_data', methods: ['GET', 'POST'])]
#[ParamDecryptor(["id"])]
public function viewRequest(Request $request, Abha $abha): Response
{
/* if ($this->getUser()->getHospital()->getId() == $case->getHospital()->getId()) {
} else {
return $this->render('bundles/TwigBundle/Exception/errorAccess.html.twig');
} */
$id = $request->attributes->get('id');
$response = $abha->getViewData($id);
$id = $this->encryptor->encrypt($id);
if ($response[0]) {
$uri = $this->generateUrl('lab_consent', ['id' => $id]);
return $this->render('abha/view_consent.html.twig', [
'data' => $response[1],
'back_url' => $uri
]);
} else {
return $this->redirectToRoute('lab_consent', ['id' => $id]);
}
}
#[Route('/patient-find', name: 'lab_patient_find', methods: ['GET', 'POST'])]
public function patientFind(Request $request, Abha $abha): Response
{
$healthId = $request->request->get('health_id');
if (!$healthId && strlen($healthId) <= 6) {
return $this->json('invalid');
}
$name = $abha->patientFind($healthId);
return $this->json($name);
}
/**
* M3 End
*/
}