Compare commits
20 Commits
61d8cb2e3d
...
78d149c348
Author | SHA1 | Date | |
---|---|---|---|
78d149c348 | |||
de81c2ffb1 | |||
c76783b79f | |||
6287ec6e2f | |||
b2e90908cd | |||
c7c14b5726 | |||
f6addcc199 | |||
de08885e0b | |||
365a486c84 | |||
c2710b7142 | |||
db756d83e4 | |||
803ce84996 | |||
ef053bae29 | |||
a42ce28f14 | |||
f17be14174 | |||
4405cb19ff | |||
5975785580 | |||
9fc84a85e9 | |||
0ca406f635 | |||
804652ac67 |
11
config/packages/csrf.yaml
Normal file
11
config/packages/csrf.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
# Enable stateless CSRF protection for forms and logins/logouts
|
||||
framework:
|
||||
form:
|
||||
csrf_protection:
|
||||
token_id: submit
|
||||
|
||||
csrf_protection:
|
||||
stateless_token_ids:
|
||||
- submit
|
||||
- authenticate
|
||||
- logout
|
@ -1,16 +1,16 @@
|
||||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
#csrf_protection: true
|
||||
secret: "%env(APP_SECRET)%"
|
||||
csrf_protection: true
|
||||
|
||||
# Note that the session will be started ONLY if you read or write from it.
|
||||
session: true
|
||||
# Note that the session will be started ONLY if you read or write from it.
|
||||
session: true
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
#esi: true
|
||||
#fragments: true
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
||||
|
@ -34,7 +34,7 @@ class AdminController extends AbstractController
|
||||
public function adminDashboard(#[CurrentUser()] User $user): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$this->navLinks['admin_dashboard'] = 'nav-link text-white active bg-gradient-dark';
|
||||
$this->navLinks['admin_dashboard'] = NavList::PRESENT_LINK;
|
||||
|
||||
return $this->render(
|
||||
'internal/admin/admin-dashboard.html.twig',
|
||||
@ -66,7 +66,7 @@ class AdminController extends AbstractController
|
||||
$users[$idx]->setSupervisor($supervisor);
|
||||
}
|
||||
|
||||
$this->navLinks['user_list'] = 'nav-link text-white active bg-gradient-dark';
|
||||
$this->navLinks['user_list'] = NavList::PRESENT_LINK;
|
||||
|
||||
return $this->render(
|
||||
'internal/admin/users/list-users.html.twig',
|
||||
@ -136,7 +136,7 @@ class AdminController extends AbstractController
|
||||
return $this->redirectToRoute('app_list_users');
|
||||
}
|
||||
|
||||
$this->navLinks['user_list'] = 'nav-link text-white active bg-gradient-dark';
|
||||
$this->navLinks['user_list'] = NavList::PRESENT_LINK;
|
||||
|
||||
return $this->render(
|
||||
'internal/admin/users/add-user.html.twig',
|
||||
@ -166,7 +166,7 @@ class AdminController extends AbstractController
|
||||
$form = $this->createForm(EditUserFormType::class, $user);
|
||||
$form->handleRequest($request);
|
||||
|
||||
$this->navLinks['user_list'] = 'nav-link text-white active bg-gradient-dark';
|
||||
$this->navLinks['user_list'] = NavList::PRESENT_LINK;
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$user->setName($form->get('name')->getData())
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Exception;
|
||||
use App\Entity\MemberCase;
|
||||
use App\Entity\ReferralSource;
|
||||
use App\Entity\User;
|
||||
@ -25,16 +24,22 @@ class CaseController extends AbstractController
|
||||
private array $navLinks = []
|
||||
) {
|
||||
$this->navLinks = NavList::LIST;
|
||||
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
|
||||
}
|
||||
|
||||
#[Route('/list-cases', name: 'app_list_cases')]
|
||||
public function listCases(#[CurrentUser()] User $user): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$this->navLinks['case_list'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
$cases = $this->entityManager->getRepository(MemberCase::class)->findAll();
|
||||
if($this->isGranted('ROLE_ADMIN')) {
|
||||
$cases = $this->entityManager->getRepository(MemberCase::class)->findAll();
|
||||
} else {
|
||||
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
|
||||
$cases = [];
|
||||
foreach ($ucs as $uc) {
|
||||
/** @var UserCase $uc */
|
||||
$cases[] = $uc->getMemberCase();
|
||||
}
|
||||
}
|
||||
$workers = $this->entityManager->getRepository(User::class)->getCaseWorkers();
|
||||
|
||||
return $this->render(
|
||||
@ -58,8 +63,6 @@ class CaseController extends AbstractController
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$this->navLinks['case_list'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
$case = new MemberCase();
|
||||
$form = $this->createForm(MemberCaseFormType::class, $case);
|
||||
|
||||
@ -98,7 +101,6 @@ class CaseController extends AbstractController
|
||||
public function editCase(Request $request, #[CurrentUser()] User $admin, string $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$this->navLinks['case_list'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
|
||||
$form = $this->createForm(MemberCaseFormType::class, $case);
|
||||
@ -137,7 +139,6 @@ class CaseController extends AbstractController
|
||||
public function assignCase(string $id, Request $request, #[CurrentUser()] User $admin): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$this->navLinks['case_list'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
$caseWorkers = $this->entityManager->getRepository(User::class)->getCaseWorkers();
|
||||
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
|
||||
|
@ -32,7 +32,7 @@ class DefaultController extends AbstractController
|
||||
return $this->redirectToRoute('app_register_step', ['step' => RegistrationController::REGISTER_STEP_TWO]);
|
||||
}
|
||||
|
||||
$this->navLinks['user_dashboard'] = 'nav-link text-white active bg-gradient-dark';
|
||||
$this->navLinks['user_dashboard'] = NavList::PRESENT_LINK;
|
||||
|
||||
return $this->render(
|
||||
'internal/dashboard.html.twig',
|
||||
@ -53,7 +53,7 @@ class DefaultController extends AbstractController
|
||||
{
|
||||
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
||||
|
||||
$this->navLinks['profile'] = 'nav-link text-white active bg-gradient-dark';
|
||||
$this->navLinks['profile'] = NavList::PRESENT_LINK;
|
||||
|
||||
return $this->render(
|
||||
'internal/profile.html.twig',
|
||||
@ -68,5 +68,4 @@ class DefaultController extends AbstractController
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ class MemberController extends AbstractController
|
||||
private array $navLinks = [],
|
||||
) {
|
||||
$this->navLinks = NavList::LIST;
|
||||
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
|
||||
}
|
||||
|
||||
#[Route('/list-members/{id}', name: 'app_case_members')]
|
||||
@ -36,7 +37,7 @@ class MemberController extends AbstractController
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
new Breadcrumb($this->generateUrl('app_case_list'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $id]), 'List Members'),
|
||||
],
|
||||
'notifications' => $user->retrieveUnreadNotifications(),
|
||||
@ -105,7 +106,7 @@ class MemberController extends AbstractController
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
new Breadcrumb($this->generateUrl('app_case_list'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $id]), 'List Members'),
|
||||
new Breadcrumb($this->generateUrl('app_case_add_member', ['id' => $id]), 'Add Member'),
|
||||
],
|
||||
@ -170,7 +171,7 @@ class MemberController extends AbstractController
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
new Breadcrumb($this->generateUrl('app_case_list'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $caseId]), 'List Members'),
|
||||
new Breadcrumb($this->generateUrl('app_case_edit_member', ['caseId' => $caseId, 'memberId' => $memberId]), 'Edit Member'),
|
||||
],
|
||||
|
168
src/Controller/NoteController.php
Normal file
168
src/Controller/NoteController.php
Normal file
@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Member;
|
||||
use App\Entity\Referral;
|
||||
use App\Entity\StandardNote;
|
||||
use App\Entity\User;
|
||||
use App\Entity\UserCase;
|
||||
use App\Entity\VisitNote;
|
||||
use App\Enums\NoteLocation;
|
||||
use App\Enums\NoteMethod;
|
||||
use App\Enums\ReferralServiceType;
|
||||
use App\Form\StandardNoteFormType;
|
||||
use App\Form\VisitNoteFormType;
|
||||
use App\Libs\Breadcrumb;
|
||||
use App\Libs\NavList;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
||||
|
||||
class NoteController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private EntityManagerInterface $entityManager,
|
||||
private array $navLinks = [],
|
||||
) {
|
||||
$this->navLinks = NavList::LIST;
|
||||
$this->navLinks['case_notes'] = NavList::PRESENT_LINK;
|
||||
}
|
||||
|
||||
#[Route('/list-notes/{id?null}', name: 'app_list_notes')]
|
||||
public function listNotes(#[CurrentUser()] User $user, ?string $id = null): Response
|
||||
{
|
||||
/** @var UserCase[] $cases */
|
||||
$cases = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
|
||||
$referrals = [];
|
||||
$notes = [];
|
||||
|
||||
if ($id == 'null') {
|
||||
$id = null;
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$referrals[] = $this->entityManager->getRepository(Referral::class)->find($id);
|
||||
} else {
|
||||
foreach ($cases as $case) {
|
||||
$referrals = array_merge(
|
||||
$referrals,
|
||||
$this->entityManager->getRepository(Referral::class)->findBy(['memberCase' => $case->getMemberCase()])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($referrals as $referral) {
|
||||
$notes = array_merge(
|
||||
$notes,
|
||||
$this->entityManager->getRepository(VisitNote::class)->getOrderedNotes($referral),
|
||||
$this->entityManager->getRepository(StandardNote::class)->getOrderedNotes($referral),
|
||||
);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'internal/cases/notes/list-notes.html.twig',
|
||||
array_merge(
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
|
||||
],
|
||||
'notifications' => $user->retrieveUnreadNotifications(),
|
||||
'cases' => $cases,
|
||||
'notes' => $notes,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/add-note/{id?null}', name: 'app_add_note')]
|
||||
public function addNote(#[CurrentUser()] User $user, Request $request, ?string $id = null): Response
|
||||
{
|
||||
/** @var Referral $referral */
|
||||
$referral = $this->entityManager->getRepository(Referral::class)->find($id);
|
||||
$this->entityManager->getRepository(Referral::class)->populateNotes($referral);
|
||||
|
||||
//dd($referral);
|
||||
|
||||
$members = $this->entityManager->getRepository(Member::class)->findBy(['caseId' => $referral->getMemberCase()]);
|
||||
$defaultMethod = NoteMethod::BILLABLE;
|
||||
$defaultLocation = NoteLocation::COMMUNITY_OUTING;
|
||||
$form = $this->createForm(StandardNoteFormType::class, null, ['members' => $members]);
|
||||
$template = 'internal/cases/notes/add-standard-note.html.twig';
|
||||
|
||||
if ($id == 'null') {
|
||||
$id = null;
|
||||
}
|
||||
|
||||
if ($referral->getServiceCode() == ReferralServiceType::VS_THBB) {
|
||||
$form = $this->createForm(VisitNoteFormType::class, null, ['members' => $members]);
|
||||
$template = 'internal/cases/notes/add-visit-note.html.twig';
|
||||
$defaultMethod = NoteMethod::BILLABLE_SUPERVISED_VISIT;
|
||||
} elseif ($referral->getServiceCode() == ReferralServiceType::VS_THBBT) {
|
||||
$defaultMethod = NoteMethod::BILLABLE;
|
||||
$defaultLocation = NoteLocation::VEHICLE_TRANSPORTATION;
|
||||
}
|
||||
|
||||
$form = $form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
/** @var VisitNote|StandardNote $note */
|
||||
$note = $form->getData();
|
||||
$note->setReferral($referral);
|
||||
|
||||
$this->entityManager->persist($note);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('app_list_notes');
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$template,
|
||||
array_merge(
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
|
||||
],
|
||||
'notifications' => $user->retrieveUnreadNotifications(),
|
||||
'referral' => $referral,
|
||||
'form' => $form,
|
||||
'default_method' => $defaultMethod,
|
||||
'default_location' => $defaultLocation,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/edit-note', name: 'app_edit_note')]
|
||||
public function editNote(): Response
|
||||
{
|
||||
return $this->render(
|
||||
'internal/cases/notes/edit-note.html.twig',
|
||||
array_merge(
|
||||
$this->navLinks,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/api/filter-notes', name: 'api_filter_notes')]
|
||||
public function filterNotes(#[CurrentUser()] User $user, Request $request): Response
|
||||
{
|
||||
$startDate = $request->get('startDate');
|
||||
$endDate = $request->get('endDate');
|
||||
$referralId = $request->get('referralId');
|
||||
$referral = null;
|
||||
if ($referralId) {
|
||||
$referral = $this->entityManager->getRepository(Referral::class)->find($referralId);
|
||||
}
|
||||
|
||||
return $this->json(array_merge(
|
||||
$this->entityManager->getRepository(VisitNote::class)->filterNotes($user, $referral, $startDate, $endDate),
|
||||
$this->entityManager->getRepository(StandardNote::class)->filterNotes($user, $referral, $startDate, $endDate),
|
||||
));
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ use App\Entity\MemberCase;
|
||||
use App\Entity\Referral;
|
||||
use App\Entity\User;
|
||||
use App\Form\ReferralFormType;
|
||||
use App\Libs\Breadcrumb;
|
||||
use App\Libs\NavList;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
@ -21,6 +22,7 @@ class ReferralController extends AbstractController
|
||||
private array $navLinks = []
|
||||
) {
|
||||
$this->navLinks = NavList::LIST;
|
||||
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
|
||||
}
|
||||
|
||||
#[Route('/list-referrals/{id}', name: 'app_list_referrals')]
|
||||
@ -36,8 +38,8 @@ class ReferralController extends AbstractController
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
'Case',
|
||||
'Referrals'
|
||||
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_list_referrals', ['id' => $case->getId()]), 'Referrals'),
|
||||
],
|
||||
'notifications' => $user->retrieveUnreadNotifications(),
|
||||
'case' => $case,
|
||||
@ -74,8 +76,9 @@ class ReferralController extends AbstractController
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
'Case',
|
||||
'Add Referral'
|
||||
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_list_referrals', ['id' => $case->getId()]), 'Referrals'),
|
||||
new Breadcrumb($this->generateUrl('app_case_add_referral', ['id' => $case->getId()]), 'Add Referral')
|
||||
],
|
||||
'notifications' => $user->retrieveUnreadNotifications(),
|
||||
'case' => $case,
|
||||
@ -108,8 +111,9 @@ class ReferralController extends AbstractController
|
||||
$this->navLinks,
|
||||
[
|
||||
'breadcrumbs' => [
|
||||
'Case',
|
||||
'Edit Referral'
|
||||
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
|
||||
new Breadcrumb($this->generateUrl('app_list_referrals', ['id' => $case->getId()]), 'Referrals'),
|
||||
new Breadcrumb($this->generateUrl('app_case_edit_referral', ['caseId' => $case->getId(), 'referralId' => $referral->getId()]), 'Edit Referral'),
|
||||
],
|
||||
'notifications' => $user->retrieveUnreadNotifications(),
|
||||
'case' => $case,
|
||||
|
@ -21,13 +21,13 @@ class ReferralSourceController extends AbstractController
|
||||
private array $navList = []
|
||||
) {
|
||||
$this->navList = NavList::LIST;
|
||||
$this->navList['referral_sources'] = NavList::PRESENT_LINK;
|
||||
}
|
||||
|
||||
#[Route('/list-referral-sources', name: 'app_referral_source')]
|
||||
public function listReferralSources(#[CurrentUser()] User $user): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$this->navList['referral_sources'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
$sources = $this->entityManager->getRepository(ReferralSource::class)->retrieveOrderedList();
|
||||
|
||||
@ -50,7 +50,6 @@ class ReferralSourceController extends AbstractController
|
||||
public function addSource(Request $request, #[CurrentUser()] User $user): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$this->navList['referral_sources'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
$rs = new ReferralSource();
|
||||
$form = $this->createForm(ReferralSourceFormType::class, $rs);
|
||||
@ -88,7 +87,6 @@ class ReferralSourceController extends AbstractController
|
||||
public function editSource(Request $request, #[CurrentUser()] User $user, string $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$this->navList['referral_sources'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
$rs = $this->entityManager->getRepository(ReferralSource::class)->find($id);
|
||||
|
||||
|
@ -20,13 +20,12 @@ class StaffController extends AbstractController
|
||||
private array $navLinks = []
|
||||
) {
|
||||
$this->navLinks = NavList::LIST;
|
||||
$this->navLinks['staff_dashboard'] = NavList::PRESENT_LINK;
|
||||
}
|
||||
|
||||
#[Route('/staff-dashboard', name: 'app_staff_dashboard')]
|
||||
public function staffDashboard(#[CurrentUser()] User $user): Response
|
||||
{
|
||||
$this->navLinks['staff_dashboard'] = 'nav-link text-white active bg-gradient-dark';
|
||||
|
||||
return $this->render(
|
||||
'internal/staff/staff-dashboard.html.twig',
|
||||
array_merge(
|
||||
|
@ -144,6 +144,11 @@ class Member
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return "{$this->firstName} {$this->lastName}";
|
||||
}
|
||||
|
||||
public function getRelationship(): ?RelationshipType
|
||||
{
|
||||
return $this->relationship;
|
||||
|
199
src/Entity/Note.php
Normal file
199
src/Entity/Note.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Enums\NoteLocation;
|
||||
use App\Enums\NoteMethod;
|
||||
use App\Enums\NoteStatus;
|
||||
use App\Repository\NoteRepository;
|
||||
use DateTime;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\ORM\Mapping\MappedSuperclass;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[MappedSuperclass(NoteRepository::class)]
|
||||
class Note
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATE_MUTABLE)]
|
||||
private ?\DateTimeInterface $date = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'notes')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Referral $referral = null;
|
||||
|
||||
#[ORM\Column(type: Types::TIME_MUTABLE)]
|
||||
private ?\DateTimeInterface $startTime = null;
|
||||
|
||||
#[ORM\Column(type: Types::TIME_MUTABLE)]
|
||||
private ?\DateTimeInterface $endTime = null;
|
||||
|
||||
#[ORM\Column(enumType: NoteStatus::class)]
|
||||
private ?NoteStatus $status = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Member>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Member::class, mappedBy: 'note')]
|
||||
public Collection $members;
|
||||
|
||||
#[ORM\Column(enumType: NoteLocation::class)]
|
||||
private ?NoteLocation $location = null;
|
||||
|
||||
#[ORM\Column(enumType: NoteMethod::class)]
|
||||
private ?NoteMethod $method = null;
|
||||
|
||||
public function getId(): ?UUid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getDate(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function setDate(\DateTimeInterface $date): static
|
||||
{
|
||||
$this->date = $date;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReferral(): ?Referral
|
||||
{
|
||||
return $this->referral;
|
||||
}
|
||||
|
||||
public function setReferral(?Referral $referral): static
|
||||
{
|
||||
$this->referral = $referral;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStartTime(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->startTime;
|
||||
}
|
||||
|
||||
public function setStartTime(\DateTimeInterface $startTime): static
|
||||
{
|
||||
$this->startTime = $startTime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEndTime(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->endTime;
|
||||
}
|
||||
|
||||
public function setEndTime(\DateTimeInterface $endTime): static
|
||||
{
|
||||
$this->endTime = $endTime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStatus(): ?NoteStatus
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function setStatus(NoteStatus $status): static
|
||||
{
|
||||
$this->status = $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Member>
|
||||
*/
|
||||
public function getMembers(): Collection
|
||||
{
|
||||
return $this->members;
|
||||
}
|
||||
|
||||
public function addUser(Member $member): static
|
||||
{
|
||||
if (!$this->members->contains($member)) {
|
||||
$this->members->add($member);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeUser(Member $member): static
|
||||
{
|
||||
$this->members->removeElement($member);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLocation(): ?NoteLocation
|
||||
{
|
||||
return $this->location;
|
||||
}
|
||||
|
||||
public function setLocation(NoteLocation $location): static
|
||||
{
|
||||
$this->location = $location;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMethod(): ?NoteMethod
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
public function setMethod(NoteMethod $method): static
|
||||
{
|
||||
$this->method = $method;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to calculate the number of minutes used for a visit rounded to the nearest 15 min increment
|
||||
*
|
||||
* @param int $precision
|
||||
* The number of minutes to round the time to defaulted to 15
|
||||
*
|
||||
* @return int
|
||||
* The number of minutes calculated
|
||||
*/
|
||||
public function calcTimeUsed(int $precision = 15): int
|
||||
{
|
||||
// get the number of seconds between the two times
|
||||
$timestamp = $this->endTime->getTimestamp() - $this->startTime->getTimestamp();
|
||||
|
||||
// find out how many increments of precision there are between these two increments
|
||||
$increments = ($timestamp / 60) / $precision;
|
||||
|
||||
// if the number of increments is a float that means there is a difference
|
||||
if (is_float($increments)) {
|
||||
// calculate the modulo
|
||||
$mod = ($timestamp / 60) % $precision;
|
||||
// if the modulo is higher than half the precision increment increase the increments by 1
|
||||
if ($mod >= ($precision / 2)) {
|
||||
$increments++;
|
||||
}
|
||||
// convert the increments to an integer
|
||||
$increments = (int) $increments;
|
||||
}
|
||||
|
||||
// return the number of increments times the precision to the partials
|
||||
return $increments * $precision;
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ namespace App\Entity;
|
||||
use App\Enums\DischargeReason;
|
||||
use App\Enums\ReferralServiceType;
|
||||
use App\Repository\ReferralRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
@ -41,6 +43,32 @@ class Referral
|
||||
#[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
|
||||
private ?\DateTimeInterface $dischargeDate = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Note>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Note::class, mappedBy: 'referral', orphanRemoval: true)]
|
||||
private Collection $notes;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Member>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Member::class)]
|
||||
private Collection $present;
|
||||
|
||||
/**
|
||||
* @var float $hoursUsed
|
||||
*/
|
||||
private float $hoursUsed = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->notes = new ArrayCollection();
|
||||
$this->present = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
@ -129,4 +157,75 @@ class Referral
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Note>
|
||||
*/
|
||||
public function getNotes(): Collection
|
||||
{
|
||||
return $this->notes;
|
||||
}
|
||||
|
||||
public function addNote(Note $note): static
|
||||
{
|
||||
if (!$this->notes->contains($note)) {
|
||||
$this->notes->add($note);
|
||||
$note->setReferral($this);
|
||||
$this->hoursUsed += ($note->calcTimeUsed() / 60);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeNote(Note $note): static
|
||||
{
|
||||
if ($this->notes->removeElement($note)) {
|
||||
$this->hoursUsed -= $note->calcTimeUsed();
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($note->getReferral() === $this) {
|
||||
$note->setReferral(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setNotes(ArrayCollection $notes): void
|
||||
{
|
||||
$this->notes = $notes;
|
||||
$this->hoursUsed = 0.0;
|
||||
|
||||
foreach($this->notes as $note) {
|
||||
$this->hoursUsed += ($note->calcTimeUsed() / 60);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Member>
|
||||
*/
|
||||
public function getPresent(): Collection
|
||||
{
|
||||
return $this->present;
|
||||
}
|
||||
|
||||
public function addPresent(Member $present): static
|
||||
{
|
||||
if (!$this->present->contains($present)) {
|
||||
$this->present->add($present);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removePresent(Member $present): static
|
||||
{
|
||||
$this->present->removeElement($present);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHoursRemaining(): float
|
||||
{
|
||||
return $this->hours - $this->hoursUsed;
|
||||
}
|
||||
}
|
||||
|
26
src/Entity/StandardNote.php
Normal file
26
src/Entity/StandardNote.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\StandardNoteRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity(repositoryClass: StandardNoteRepository::class)]
|
||||
class StandardNote extends Note
|
||||
{
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
private ?string $note = null;
|
||||
|
||||
public function getNote(): ?string
|
||||
{
|
||||
return $this->note;
|
||||
}
|
||||
|
||||
public function setNote(?string $note): static
|
||||
{
|
||||
$this->note = $note;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
162
src/Entity/VisitNote.php
Normal file
162
src/Entity/VisitNote.php
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Enums\VisitQualityLevel;
|
||||
use App\Repository\VisitNoteRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity(repositoryClass: VisitNoteRepository::class)]
|
||||
class VisitNote extends Note
|
||||
{
|
||||
#[ORM\Column(type: Types::TEXT)]
|
||||
private ?string $narrative = null;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT)]
|
||||
private ?string $strengths = null;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT)]
|
||||
private ?string $issues = null;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT)]
|
||||
private ?string $recommendation = null;
|
||||
|
||||
#[ORM\Column(enumType: VisitQualityLevel::class)]
|
||||
private ?VisitQualityLevel $parentalRole = null;
|
||||
|
||||
#[ORM\Column(enumType: VisitQualityLevel::class)]
|
||||
private ?VisitQualityLevel $childDevelopment = null;
|
||||
|
||||
#[ORM\Column(enumType: VisitQualityLevel::class)]
|
||||
private ?VisitQualityLevel $appropriateResponse = null;
|
||||
|
||||
#[ORM\Column(enumType: VisitQualityLevel::class)]
|
||||
private ?VisitQualityLevel $childAheadOfSelf = null;
|
||||
|
||||
#[ORM\Column(enumType: VisitQualityLevel::class)]
|
||||
private ?VisitQualityLevel $showsEmpathy = null;
|
||||
|
||||
#[ORM\Column(enumType: VisitQualityLevel::class)]
|
||||
private ?VisitQualityLevel $childFocused = null;
|
||||
|
||||
public function getNarrative(): ?string
|
||||
{
|
||||
return $this->narrative;
|
||||
}
|
||||
|
||||
public function setNarrative(string $narrative): static
|
||||
{
|
||||
$this->narrative = $narrative;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStrengths(): ?string
|
||||
{
|
||||
return $this->strengths;
|
||||
}
|
||||
|
||||
public function setStrengths(string $strengths): static
|
||||
{
|
||||
$this->strengths = $strengths;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIssues(): ?string
|
||||
{
|
||||
return $this->issues;
|
||||
}
|
||||
|
||||
public function setIssues(string $issues): static
|
||||
{
|
||||
$this->issues = $issues;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRecommendation(): ?string
|
||||
{
|
||||
return $this->recommendation;
|
||||
}
|
||||
|
||||
public function setRecommendation(string $recommendation): static
|
||||
{
|
||||
$this->recommendation = $recommendation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParentalRole(): ?VisitQualityLevel
|
||||
{
|
||||
return $this->parentalRole;
|
||||
}
|
||||
|
||||
public function setParentalRole(VisitQualityLevel $parentalRole): static
|
||||
{
|
||||
$this->parentalRole = $parentalRole;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getChildDevelopment(): ?VisitQualityLevel
|
||||
{
|
||||
return $this->childDevelopment;
|
||||
}
|
||||
|
||||
public function setChildDevelopment(VisitQualityLevel $childDevelopment): static
|
||||
{
|
||||
$this->childDevelopment = $childDevelopment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAppropriateResponse(): ?VisitQualityLevel
|
||||
{
|
||||
return $this->appropriateResponse;
|
||||
}
|
||||
|
||||
public function setAppropriateResponse(VisitQualityLevel $appropriateResponse): static
|
||||
{
|
||||
$this->appropriateResponse = $appropriateResponse;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getChildAheadOfSelf(): ?VisitQualityLevel
|
||||
{
|
||||
return $this->childAheadOfSelf;
|
||||
}
|
||||
|
||||
public function setChildAheadOfSelf(VisitQualityLevel $childAheadOfSelf): static
|
||||
{
|
||||
$this->childAheadOfSelf = $childAheadOfSelf;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getShowsEmpathy(): ?VisitQualityLevel
|
||||
{
|
||||
return $this->showsEmpathy;
|
||||
}
|
||||
|
||||
public function setShowsEmpathy(VisitQualityLevel $showsEmpathy): static
|
||||
{
|
||||
$this->showsEmpathy = $showsEmpathy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getChildFocused(): ?VisitQualityLevel
|
||||
{
|
||||
return $this->childFocused;
|
||||
}
|
||||
|
||||
public function setChildFocused(VisitQualityLevel $childFocused): static
|
||||
{
|
||||
$this->childFocused = $childFocused;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
36
src/Enums/NoteLocation.php
Normal file
36
src/Enums/NoteLocation.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum NoteLocation: string
|
||||
{
|
||||
case AGENCY_OTHER_PROFESSIONAL = 'Agency/Other Professional';
|
||||
case AT_HOME = 'At Home';
|
||||
case CHILDPLACE = 'Childplace';
|
||||
case CHURCH = 'Church';
|
||||
case CLIENT_HOME = 'Client Home';
|
||||
case CLIENT_SEARCH = 'Client Search';
|
||||
case COMMUNITY_OUTING = 'Community Outing';
|
||||
case COURT_HOUSE = 'Court House';
|
||||
case DCS_OFFICE = 'DCS Office';
|
||||
case DENTIST_EYE_APPOINTMENT = 'Dentist/Eye appointment';
|
||||
case DOCTOR_DENTIST_APPOINTMENT = 'Doctor/Dentist Appointment';
|
||||
case EMPLOYMENT_SEARCH = 'Employment Search';
|
||||
case FOOD_PANTRY = 'Food Pantry';
|
||||
case FOSTER_HOME = 'Foster home';
|
||||
case HOUSING_SEARCH = 'Housing Search';
|
||||
case JAIL_CORRECTIONAL_FACILITY = 'Jail/Correctional Facility';
|
||||
case LIBRARY = 'Library';
|
||||
case OTHER = 'Other';
|
||||
case PARK = 'Park';
|
||||
case PROBATION_OFFICE = 'Probation Office';
|
||||
case RELATIVE_HOME = 'Relative home';
|
||||
case RESTAURANT = 'Restaurant';
|
||||
case SCHOOL = 'School';
|
||||
case SHOPPING_CENTER = 'Shopping Center';
|
||||
case TELEPHONE = 'Telephone';
|
||||
case TEXT_MESSAGE = 'Text Message';
|
||||
case THERAPY_APPOINTMENT = 'Therapy Appointment';
|
||||
case VEHICLE_TRANSPORTATION = 'Vehicle/Transportation';
|
||||
case WELLSTONE = 'Wellstone';
|
||||
}
|
25
src/Enums/NoteMethod.php
Normal file
25
src/Enums/NoteMethod.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum NoteMethod: int
|
||||
{
|
||||
case DCS_PROBATION_CONTACT = 0;
|
||||
case BILLABLE = 1;
|
||||
case BILLABLE_CASE_CONFERENCE = 2;
|
||||
case BILLABLE_CFTM = 3;
|
||||
case BILLABLE_COURT = 4;
|
||||
case BILLABLE_CRISIS_PHONE_CALL = 6;
|
||||
case BILLABLE_FACE_TO_FACE = 7;
|
||||
case BILLABLE_PA_DENIED_BY_MEDIACID_SERVICES_TO_BE_PAID_BY_DCS = 8;
|
||||
case BILLABLE_REPORT_WRITING = 9;
|
||||
case BILLABLE_SUPERVISED_VISIT = 10;
|
||||
case BILLABLE_TESTING_INTERPRETATION = 11;
|
||||
case BILLED_TO_MEDIACID_INSURANCE = 12;
|
||||
case CANCEL_BY_CLIENT = 13;
|
||||
case CANCEL_BY_PROVIDER = 14;
|
||||
case COLLATERAL = 15;
|
||||
case NO_SHOW = 16;
|
||||
case NON_BILLABLE = 17;
|
||||
case SUPERVISED_VISIT_PRIVATE = 18;
|
||||
}
|
15
src/Enums/NoteStatus.php
Normal file
15
src/Enums/NoteStatus.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum NoteStatus: string
|
||||
{
|
||||
case DRAFT = 'draft';
|
||||
case IN_PROGRESS = 'in progress';
|
||||
case IN_REVIEW = 'in review';
|
||||
case PUBLISHED = 'published';
|
||||
case SUBMITTED = 'submitted';
|
||||
case APPROVED = 'approved';
|
||||
case REJECTED = 'rejected';
|
||||
case PAID = 'paid';
|
||||
}
|
11
src/Enums/VisitQualityLevel.php
Normal file
11
src/Enums/VisitQualityLevel.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum VisitQualityLevel: int
|
||||
{
|
||||
case RARELY = 0;
|
||||
case OFTEN = 1;
|
||||
case OCCASIONALLY = 2;
|
||||
case ALWAYS = 3;
|
||||
}
|
69
src/Form/StandardNoteFormType.php
Normal file
69
src/Form/StandardNoteFormType.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Member;
|
||||
use App\Entity\Referral;
|
||||
use App\Entity\StandardNote;
|
||||
use App\Enums\NoteLocation;
|
||||
use App\Enums\NoteMethod;
|
||||
use App\Enums\NoteStatus;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class StandardNoteFormType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$members = $options['members'];
|
||||
|
||||
$builder
|
||||
->add('date', null, [
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('startTime', null, [
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('endTime', null, [
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('location', EnumType::class, [
|
||||
'class' => NoteLocation::class
|
||||
])
|
||||
->add('status', EnumType::class, [
|
||||
'class' => NoteStatus::class,
|
||||
])
|
||||
->add('note', null, [
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'class' => 'form-control',
|
||||
'placeholder' => 'Note',
|
||||
],
|
||||
])
|
||||
->add('members', EntityType::class, [
|
||||
'class' => Member::class,
|
||||
'choices' => $members,
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'choice_label' => 'name',
|
||||
])
|
||||
->add('method', EnumType::class, [
|
||||
'class' => NoteMethod::class,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => StandardNote::class,
|
||||
'members' => [],
|
||||
'csrf_protection' => true,
|
||||
'csrf_field_name' => '_token',
|
||||
'csrf_token_id' => 'standard_note',
|
||||
]);
|
||||
}
|
||||
}
|
84
src/Form/VisitNoteFormType.php
Normal file
84
src/Form/VisitNoteFormType.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Member;
|
||||
use App\Entity\VisitNote;
|
||||
use App\Enums\NoteLocation;
|
||||
use App\Enums\NoteMethod;
|
||||
use App\Enums\NoteStatus;
|
||||
use App\Enums\VisitQualityLevel;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class VisitNoteFormType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$members = $options['members'];
|
||||
|
||||
$builder
|
||||
->add('date', null, [
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('startTime', null, [
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('endTime', null, [
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('status', EnumType::class, [
|
||||
'class' => NoteStatus::class
|
||||
])
|
||||
->add('location', EnumType::class, [
|
||||
'class' => NoteLocation::class
|
||||
])
|
||||
->add('narrative')
|
||||
->add('strengths')
|
||||
->add('issues')
|
||||
->add('recommendation')
|
||||
->add('parentalRole', EnumType::class, [
|
||||
'class' => VisitQualityLevel::class
|
||||
])
|
||||
->add('childDevelopment', EnumType::class, [
|
||||
'class' => VisitQualityLevel::class
|
||||
])
|
||||
->add('appropriateResponse', EnumType::class, [
|
||||
'class' => VisitQualityLevel::class
|
||||
])
|
||||
->add('childAheadOfSelf', EnumType::class, [
|
||||
'class' => VisitQualityLevel::class
|
||||
])
|
||||
->add('showsEmpathy', EnumType::class, [
|
||||
'class' => VisitQualityLevel::class
|
||||
])
|
||||
->add('childFocused', EnumType::class, [
|
||||
'class' => VisitQualityLevel::class
|
||||
])
|
||||
->add('members', EntityType::class, [
|
||||
'class' => Member::class,
|
||||
'choices' => $members,
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'choice_label' => 'name',
|
||||
])
|
||||
->add('method', EnumType::class, [
|
||||
'class' => NoteMethod::class
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => VisitNote::class,
|
||||
'members' => [],
|
||||
'csrf_protection' => true,
|
||||
'csrf_field_name' => '_token',
|
||||
'csrf_token_id' => 'visit_note',
|
||||
]);
|
||||
}
|
||||
}
|
@ -13,5 +13,8 @@ class NavList
|
||||
'case_list' => 'nav-link text-dark',
|
||||
'add_user' => 'nav-link text-dark',
|
||||
'referral_sources' => 'nav-link text-dark',
|
||||
'case_notes' => 'nav-link text-dark',
|
||||
];
|
||||
|
||||
public const PRESENT_LINK = 'nav-link text-white active bg-gradient-dark';
|
||||
}
|
||||
|
61
src/Repository/NoteRepository.php
Normal file
61
src/Repository/NoteRepository.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Note;
|
||||
use App\Entity\Referral;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Notes>
|
||||
*/
|
||||
class NoteRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Note::class);
|
||||
}
|
||||
|
||||
public function getHoursUsed(Referral $referral): int
|
||||
{
|
||||
$ret = 0;
|
||||
|
||||
$query = $this->createQueryBuilder('n')
|
||||
->select('SUM(n.hours) AS hours')
|
||||
->andWhere('n.referral = :referral')
|
||||
->setParameter('referral', $referral->getId()->toBinary())
|
||||
->getQuery()
|
||||
//->getResult()
|
||||
;
|
||||
|
||||
dd($query->getSQL());
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Notes[] Returns an array of Notes objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('n')
|
||||
// ->andWhere('n.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('n.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?Notes
|
||||
// {
|
||||
// return $this->createQueryBuilder('n')
|
||||
// ->andWhere('n.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
@ -4,7 +4,9 @@ namespace App\Repository;
|
||||
|
||||
use App\Entity\MemberCase;
|
||||
use App\Entity\Referral;
|
||||
use App\Enums\ReferralServiceType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
@ -19,7 +21,7 @@ class ReferralRepository extends ServiceEntityRepository
|
||||
|
||||
public function getActiveReferrals(MemberCase $case): array
|
||||
{
|
||||
return $this->createQueryBuilder('r')
|
||||
$referrals = $this->createQueryBuilder('r')
|
||||
->andWhere('r.dischargeDate IS NULL')
|
||||
->andWhere('r.memberCase = :case')
|
||||
->setParameter('case', $case->getId()->toBinary())
|
||||
@ -27,11 +29,17 @@ class ReferralRepository extends ServiceEntityRepository
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
|
||||
foreach ($referrals as $idx => $ref) {
|
||||
$this->populateNotes($referrals[$idx]);
|
||||
}
|
||||
|
||||
return $referrals;
|
||||
}
|
||||
|
||||
public function getClosedReferrals(MemberCase $case): array
|
||||
{
|
||||
return $this->createQueryBuilder('r')
|
||||
$referrals = $this->createQueryBuilder('r')
|
||||
->andWhere('r.dischargeDate IS NOT NULL')
|
||||
->andWhere('r.memberCase = :case')
|
||||
->setParameter('case', $case->getId()->toBinary())
|
||||
@ -39,6 +47,35 @@ class ReferralRepository extends ServiceEntityRepository
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
|
||||
foreach ($referrals as $idx => $ref) {
|
||||
$this->populateNotes($referrals[$idx]);
|
||||
}
|
||||
|
||||
return $referrals;
|
||||
}
|
||||
|
||||
public function populateNotes(Referral &$referral): void
|
||||
{
|
||||
$noteType = 'App\Entity\StandardNote';
|
||||
|
||||
if ($referral->getServiceCode() == ReferralServiceType::VS_THBB) {
|
||||
$noteType = 'App\Entity\VisitNote';
|
||||
}
|
||||
|
||||
$query = $this->getEntityManager()->createQuery("
|
||||
SELECT n
|
||||
FROM $noteType n
|
||||
WHERE n.referral = :referral
|
||||
");
|
||||
$query->setParameter('referral', $referral->getId()->toBinary());
|
||||
$res = $query->getResult();
|
||||
|
||||
if (!count($res)){
|
||||
return;
|
||||
}
|
||||
|
||||
$referral->setNotes(new ArrayCollection($res));
|
||||
}
|
||||
|
||||
// /**
|
||||
|
86
src/Repository/StandardNoteRepository.php
Normal file
86
src/Repository/StandardNoteRepository.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Referral;
|
||||
use App\Entity\StandardNote;
|
||||
use App\Entity\User;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<StandardNote>
|
||||
*/
|
||||
class StandardNoteRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, StandardNote::class);
|
||||
}
|
||||
|
||||
public function getOrderedNotes(Referral $referral): array
|
||||
{
|
||||
return $this->createQueryBuilder('s')
|
||||
->andWhere('s.referral = :referral')
|
||||
->setParameter('referral', $referral->getId()->toBinary())
|
||||
->orderBy('s.date', 'DESC')
|
||||
->addOrderBy('s.startTime', 'DESC')
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
|
||||
public function filterNotes(User $user, ?Referral $referral = null, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null): array
|
||||
{
|
||||
$query = $this->createQueryBuilder('v')
|
||||
->join('v.referral', 'r')
|
||||
;
|
||||
|
||||
if ($referral) {
|
||||
$query->andWhere('v.referral = :referral')
|
||||
->setParameter('referral', $referral->getId()->toBinary());
|
||||
}
|
||||
|
||||
if ($startDate) {
|
||||
$query->andWhere('v.date >= :startDate')
|
||||
->setParameter('startDate', $startDate);
|
||||
}
|
||||
|
||||
if ($endDate) {
|
||||
$query->andWhere('v.date <= :endDate')
|
||||
->setParameter('endDate', $endDate);
|
||||
}
|
||||
|
||||
return $query->orderBy('v.date', 'DESC')
|
||||
->addOrderBy('v.startTime', 'DESC')
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return StandardNote[] Returns an array of StandardNote objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('s')
|
||||
// ->andWhere('s.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('s.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?StandardNote
|
||||
// {
|
||||
// return $this->createQueryBuilder('s')
|
||||
// ->andWhere('s.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
86
src/Repository/VisitNoteRepository.php
Normal file
86
src/Repository/VisitNoteRepository.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Referral;
|
||||
use App\Entity\User;
|
||||
use App\Entity\VisitNote;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<VisitNote>
|
||||
*/
|
||||
class VisitNoteRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, VisitNote::class);
|
||||
}
|
||||
|
||||
public function getOrderedNotes(Referral $referral): array
|
||||
{
|
||||
return $this->createQueryBuilder('v')
|
||||
->andWhere('v.referral = :referral')
|
||||
->setParameter('referral', $referral->getId()->toBinary())
|
||||
->orderBy('v.date', 'DESC')
|
||||
->addOrderBy('v.startTime', 'DESC')
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
|
||||
public function filterNotes(User $user, ?Referral $referral = null, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null): array
|
||||
{
|
||||
$query = $this->createQueryBuilder('v')
|
||||
->join('v.referral', 'r')
|
||||
;
|
||||
|
||||
if ($referral) {
|
||||
$query->andWhere('v.referral = :referral')
|
||||
->setParameter('referral', $referral->getId()->toBinary());
|
||||
}
|
||||
|
||||
if ($startDate) {
|
||||
$query->andWhere('v.date >= :startDate')
|
||||
->setParameter('startDate', $startDate);
|
||||
}
|
||||
|
||||
if ($endDate) {
|
||||
$query->andWhere('v.date <= :endDate')
|
||||
->setParameter('endDate', $endDate);
|
||||
}
|
||||
|
||||
return $query->orderBy('v.date', 'DESC')
|
||||
->addOrderBy('v.startTime', 'DESC')
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return VisitNote[] Returns an array of VisitNote objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('v')
|
||||
// ->andWhere('v.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('v.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?VisitNote
|
||||
// {
|
||||
// return $this->createQueryBuilder('v')
|
||||
// ->andWhere('v.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
@ -60,9 +60,13 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class='align-middle'>
|
||||
<a href='{{ path('app_edit_user', {id: user.id}) }}' class='text-secondary font-weight-bold text-xs' data-toggle='tooltip' data-original-title='Edit user'>Edit</a>
|
||||
<a href='{{ path('app_edit_user', {id: user.id}) }}' class='text-secondary font-weight-bold text-xs' tooltip='Edit User'>
|
||||
<i class="material-symbols-rounded opacity-5">edit</i>
|
||||
</a>
|
||||
|
||||
<a href='{{ path('app_assign_supervisor', {id: user.id}) }}' class='text-secondary text-xs' data-toggle='tooltip' data-original-title='Assign supervisor'>Assign</a>
|
||||
<a href='{{ path('app_assign_supervisor', {id: user.id}) }}' class='text-secondary text-xs' tooltip="Assign Supervisor">
|
||||
<i class='material-symbols-rounded opacity-5'>badge</i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -15,12 +15,15 @@
|
||||
<div>
|
||||
<h6 class="text-white text-capitalize ps-3">Case List</h6>
|
||||
</div>
|
||||
{% if is_granted('ROLE_CASE_MANAGER') or is_granted('ROLE_ADMIN') %}
|
||||
<div>
|
||||
<button type="button" class="btn btn-block btn-light mb-3" onclick="window.open('{{ path('app_add_case') }}', '_self')">Add Case</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body px-0 pb-2">
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<div>
|
||||
Filters:
|
||||
<select onchange='filterCasesByUser(this.value)'>
|
||||
@ -31,6 +34,7 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="table-responsive p-0">
|
||||
<table class="table align-items-center mb-0">
|
||||
<thead>
|
||||
@ -81,12 +85,14 @@
|
||||
</p>
|
||||
</td>
|
||||
<td class='align-right'>
|
||||
{% if is_granted('ROLE_CASE_MANAGER') or is_granted('ROLE_ADMIN') %}
|
||||
<a href='{{ path('app_edit_case', {id: c.id}) }}' class='' title='Edit Case' data-toggle='tooltip'>
|
||||
<i class="material-symbols-rounded opacity-5">edit</i>
|
||||
</a>
|
||||
<a href='{{ path('app_assign_case', {id: c.id}) }}' class='' title='Assign Case Worker' data-toggle='tooltip'>
|
||||
<i class='material-symbols-rounded opacity-5'>badge</i>
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href='{{ path('app_list_referrals', {id: c.id}) }}' class='' title='List Referrals' data-toggle='tooltip'>
|
||||
<i class='material-symbols-rounded opacity-5'>create_new_folder</i>
|
||||
</a>
|
||||
|
@ -165,7 +165,7 @@
|
||||
</div>
|
||||
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<input type='checkbox' name='{{ field_name(form.dcsApproved) }}' id='member_form_dcsApproved'/>
|
||||
<input type='checkbox' name='{{ field_name(form.dcsApproved) }}' id='member_form_dcsApproved'/>
|
||||
<label for='member_form_dcsApproved'>DCS Approved?</label>
|
||||
</div>
|
||||
</div>
|
||||
|
107
templates/internal/cases/notes/add-standard-note.html.twig
Normal file
107
templates/internal/cases/notes/add-standard-note.html.twig
Normal file
@ -0,0 +1,107 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ block('nav', 'internal/libs/nav.html.twig') }}
|
||||
|
||||
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg ">
|
||||
{{ block('topnav', 'internal/libs/top-nav.html.twig') }}
|
||||
|
||||
<section>
|
||||
<div class="card card-plain">
|
||||
<div class="card-header">
|
||||
<h4 class="font-weight-bolder">Add Referral Note</h4>
|
||||
<p class="mb-0">{{ referral.memberCase.caseName }}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
<div class='container'>
|
||||
<div class='row'>
|
||||
{% set endDateWarning = '' %}
|
||||
{% if date("+28 days") >= referral.endDate %}
|
||||
{% set endDateWarning = 'bg-gradient-warning' %}
|
||||
{% elseif date("+14 days") >= referral.endDate %}
|
||||
{% set endDateWarning = 'bg-gradient-danger text-white' %}
|
||||
{% endif %}
|
||||
<span class='col{% if referral.hours < 40 %} bg-gradient-danger text-white{% endif %}'>
|
||||
Hours:
|
||||
{{ referral.hours }}
|
||||
/
|
||||
Remaining:
|
||||
{{ referral.getHoursRemaining() }}
|
||||
</span>
|
||||
<span class='col {{ endDateWarning }}'>
|
||||
Expiration Date:
|
||||
{{ referral.endDate|date('M j, Y') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class='row' style='margin-top:10px;'>
|
||||
<div class='col'>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_date'></label>
|
||||
<input type='date' name='{{ field_name(form.date) }}' id='note_form_date' class='form-control' title='Visit Date'/>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_startTime'></label>
|
||||
<input type='time' name='{{ field_name(form.startTime) }}' id='note_form_startTime' onchange='calcTime()' class='form-control' title='Start Time'/>
|
||||
<label for='note_form_endTime'></label>
|
||||
<input type='time' name='{{ field_name(form.endTime) }}' id='note_form_endTime' onchange='calcTime()' class='form-control' title='End Time'/>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<input type='text' id='case-mins' style='width:49%;margin-right:5px;' disabled='disabled' title='Case Minutes'/>
|
||||
<input type='text' id='case-hours' style='width:49%;margin-left:5px;' disabled='disabled' title='Case Hours'/>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.status) }}' id='note_form_status' class='form-control'>
|
||||
<option value=''>-- Status --</option>
|
||||
|
||||
{% for s in enum('App\\Enums\\NoteStatus').cases() %}
|
||||
<option value='{{ s.value }}'>{{ s.value|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.location) }}' id='note_form_location' class='form-control'>
|
||||
<option value=''>-- Location --</option>
|
||||
|
||||
{% for l in enum('App\\Enums\\NoteLocation').cases() %}
|
||||
<option value='{{ l.value }}' {% if l == default_location %} selected='selected' {% endif %}>{{ l.value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.method) }}' id='note_form_method' class='form-control'>
|
||||
<option value=''>-- Method --</option>
|
||||
|
||||
{% for m in enum('App\\Enums\\NoteMethod').cases() %}
|
||||
<option value='{{ m.value }}' {% if m == default_method %} selected='selected' {% endif %}>{{ m.name|replace({'_': ' '})|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col'>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
{{ form_row(form.members, {
|
||||
'label': 'Members Present',
|
||||
'label_attr': {'class': ''},
|
||||
'attr': {'class': 'form-control'}
|
||||
}) }}
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='case_note_note' class='form-label'>Notes</label>
|
||||
<textarea name='{{ field_name(form.note) }}' id='case_note_note' class='form-control' style='width:100%;height:300px;'></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='row'>
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-lg bg-gradient-dark btn-lg w-100 mt-4 mb-0">Save Note</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
{% endblock %}
|
191
templates/internal/cases/notes/add-visit-note.html.twig
Normal file
191
templates/internal/cases/notes/add-visit-note.html.twig
Normal file
@ -0,0 +1,191 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ block('nav', 'internal/libs/nav.html.twig') }}
|
||||
|
||||
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg ">
|
||||
{{ block('topnav', 'internal/libs/top-nav.html.twig') }}
|
||||
|
||||
<section>
|
||||
<div class="card card-plain">
|
||||
<div class="card-header">
|
||||
<h4 class="font-weight-bolder">Add Referral Note</h4>
|
||||
<p class="mb-0">{{ referral.memberCase.caseName }}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
<div class='container'>
|
||||
<div class='row'>
|
||||
{% set endDateWarning = '' %}
|
||||
{% if date("+28 days") >= referral.endDate %}
|
||||
{% set endDateWarning = 'bg-gradient-warning' %}
|
||||
{% elseif date("+14 days") >= referral.endDate %}
|
||||
{% set endDateWarning = 'bg-gradient-danger text-white' %}
|
||||
{% endif %}
|
||||
<span class='col{% if referral.hours < 40 %} bg-gradient-danger text-white{% endif %}'>
|
||||
Hours:
|
||||
{{ referral.hours }}
|
||||
/
|
||||
Remaining:
|
||||
{{ referral.getHoursRemaining() }}
|
||||
</span>
|
||||
<span class='col {{ endDateWarning }}'>
|
||||
Expiration Date:
|
||||
{{ referral.endDate|date('M j, Y') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class='row' style='margin-top:10px;'>
|
||||
<div class='col'>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_date'></label>
|
||||
<input type='date' name='{{ field_name(form.date) }}' id='note_form_date' class='form-control' title='Visit Date'/>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_startTime'></label>
|
||||
<input type='time' name='{{ field_name(form.startTime) }}' id='note_form_startTime' onchange='calcTime()' class='form-control' title='Start Time'/>
|
||||
<label for='note_form_endTime'></label>
|
||||
<input type='time' name='{{ field_name(form.endTime) }}' id='note_form_endTime' onchange='calcTime()' class='form-control' title='End Time'/>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<input type='text' id='case-mins' style='width:49%;margin-right:5px;' disabled='disabled' title='Case Minutes'/>
|
||||
<input type='text' id='case-hours' style='width:49%;margin-left:5px;' disabled='disabled' title='Case Hours'/>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.status) }}' id='note_form_status' class='form-control'>
|
||||
<option value=''>-- Status --</option>
|
||||
|
||||
{% for s in enum('App\\Enums\\NoteStatus').cases() %}
|
||||
<option value='{{ s.value }}'>{{ s.value|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.location) }}' id='note_form_location' class='form-control'>
|
||||
<option value=''>-- Location --</option>
|
||||
|
||||
{% for l in enum('App\\Enums\\NoteLocation').cases() %}
|
||||
<option value='{{ l.value }}' {% if l == default_location %} selected='selected' {% endif %}>{{ l.value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.method) }}' id='note_form_method' class='form-control'>
|
||||
<option value=''>-- Method --</option>
|
||||
|
||||
{% for m in enum('App\\Enums\\NoteMethod').cases() %}
|
||||
<option value='{{ m.value }}' {% if m == default_method %} selected='selected' {% endif %}>{{ m.name|replace({'_': ' '})|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_parentalRole'>Parental Role</label>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.parentalRole) }}' id='note_form_parentalRole' class='form-control'>
|
||||
<option value=''>-- Select --</option>
|
||||
|
||||
{% for q in enum('App\\Enums\\VisitQualityLevel').cases() %}
|
||||
<option value='{{ q.value }}'>{{ q.name|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_childDevelopment'>Child Development</label>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.childDevelopment) }}' id='note_form_childDevelopment' class='form-control'>
|
||||
<option value=''>-- Select --</option>
|
||||
|
||||
{% for q in enum('App\\Enums\\VisitQualityLevel').cases() %}
|
||||
<option value='{{ q.value }}'>{{ q.name|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_appropriateResponse'>Appropriate Response</label>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.appropriateResponse) }}' id='note_form_appropriateResponse' class='form-control'>
|
||||
<option value=''>-- Select --</option>
|
||||
|
||||
{% for q in enum('App\\Enums\\VisitQualityLevel').cases() %}
|
||||
<option value='{{ q.value }}'>{{ q.name|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_childAheadOfSelf'>Child Ahead Of Self</label>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.childAheadOfSelf) }}' id='note_form_childAheadOfSelf' class='form-control'>
|
||||
<option value=''>-- Select --</option>
|
||||
|
||||
{% for q in enum('App\\Enums\\VisitQualityLevel').cases() %}
|
||||
<option value='{{ q.value }}'>{{ q.name|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_showsEmpathy'>Shows Empathy</label>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.showsEmpathy) }}' id='note_form_showsEmpathy' class='form-control'>
|
||||
<option value=''>-- Select --</option>
|
||||
|
||||
{% for q in enum('App\\Enums\\VisitQualityLevel').cases() %}
|
||||
<option value='{{ q.value }}'>{{ q.name|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_childFocused'>Child Focused</label>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<select name='{{ field_name(form.childFocused) }}' id='note_form_childFocused' class='form-control'>
|
||||
<option value=''>-- Select --</option>
|
||||
|
||||
{% for q in enum('App\\Enums\\VisitQualityLevel').cases() %}
|
||||
<option value='{{ q.value }}'>{{ q.name|lower|capitalize }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col'>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
{{ form_row(form.members, {
|
||||
'label': 'Members Present',
|
||||
'label_attr': {'class': ''},
|
||||
'attr': {'class': 'form-control'}
|
||||
}) }}
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_narrative'>Observed Narrative</label>
|
||||
<textarea name='{{ field_name(form.narrative) }}' id='note_form_narrative' class='form-control' style='width:100%;height:200px;'></textarea>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_strengths'>Observed Strengths</label>
|
||||
<textarea name='{{ field_name(form.strengths) }}' id='note_form_strengths' class='form-control' style='width:100%;height:200px;'></textarea>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_issues'>Observed Issues</label>
|
||||
<textarea name='{{ field_name(form.issues) }}' id='note_form_issues' class='form-control' style='width:100%;height:100px;'></textarea>
|
||||
</div>
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
<label for='note_form_recommendation'>Recommendation</label>
|
||||
<textarea name='{{ field_name(form.recommendation) }}' id='note_form_recommendation' class='form-control' style='width:100%;height:100px;'></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='row'>
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-lg bg-gradient-dark btn-lg w-100 mt-4 mb-0">Save Note</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
{% endblock %}
|
0
templates/internal/cases/notes/edit-note.html.twig
Normal file
0
templates/internal/cases/notes/edit-note.html.twig
Normal file
82
templates/internal/cases/notes/list-notes.html.twig
Normal file
82
templates/internal/cases/notes/list-notes.html.twig
Normal file
@ -0,0 +1,82 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ block('nav', 'internal/libs/nav.html.twig') }}
|
||||
|
||||
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg ">
|
||||
{{ block('topnav', 'internal/libs/top-nav.html.twig') }}
|
||||
|
||||
<div class="container-fluid py-2">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card my-4">
|
||||
<div class="card-header p-0 position-relative mt-n4 mx-3 z-index-2">
|
||||
<div class="d-flex justify-content-between bg-gradient-dark shadow-dark border-radius-lg pt-4 pb-3 ps-3 p-2">
|
||||
<div>
|
||||
<h6 class="text-white text-capitalize ps-3">Referral Note List</h6>
|
||||
</div>
|
||||
<div>
|
||||
<select id='referralList' onchange='filterNotes()'>
|
||||
<option value=''>-- Select Referral --</option>
|
||||
|
||||
{% for c in cases %}
|
||||
<optgroup label='{{ c.memberCase.caseName }}'>
|
||||
{% for r in c.memberCase.referrals %}
|
||||
<option value='{{ r.id }}'>
|
||||
{{ r.referralId }}
|
||||
/
|
||||
{{ r.serviceCode.value }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="button" class="btn btn-block btn-light mb-3" onclick="window.open('/index.php/add-note/'+document.getElementById('referralList').value, '_self')">Add Note</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body px-0 pb-2">
|
||||
<div>
|
||||
Filter:
|
||||
<input type='date' id='startDate' onchange='filterNotes()' title='Start Date'/>
|
||||
<input type='date' id='endDate' onchange='filterNotes()' title='End Date'/>
|
||||
</div>
|
||||
<div class="table-responsive p-0">
|
||||
<table class="table align-items-center mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">DOS</th>
|
||||
<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7 ps-2">Service</th>
|
||||
<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">Location</th>
|
||||
<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">Method</th>
|
||||
<th class='text-right text-uppercase text-secondary text-xxs font-weight-bolder opacity-7'>Members Present</th>
|
||||
<th class="text-secondary opacity-7"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id='note-list'>
|
||||
{% for note in notes %}
|
||||
{% set members = note.getMembers() %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ note.date|date('M j, Y') }}<br/>
|
||||
{{ note.startTime|date('g:i a') }}-{{ note.endTime|date('g:i a') }}
|
||||
</td>
|
||||
<td>{{ note.referral.serviceCode.value }}</td>
|
||||
<td class='text-center'>{{ note.location.value }}</td>
|
||||
<td>{{ note.method.name|replace({'_': ' '})|lower|capitalize }}</td>
|
||||
<td>
|
||||
{{ dump(members) }}
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{% endblock %}
|
@ -7,7 +7,6 @@
|
||||
{{ block('topnav', 'internal/libs/top-nav.html.twig') }}
|
||||
|
||||
<section>
|
||||
|
||||
<div class="card card-plain">
|
||||
<div class="card-header">
|
||||
<h4 class="font-weight-bolder">Add Referral</h4>
|
||||
@ -16,7 +15,6 @@
|
||||
<div class="card-body">
|
||||
<div class="container">
|
||||
{{ form_errors(form) }}
|
||||
|
||||
{{ form_start(form) }}
|
||||
|
||||
<div class='input-group input-group-outline mb-3'>
|
||||
|
@ -15,9 +15,11 @@
|
||||
<div>
|
||||
<h6 class="text-white text-capitalize ps-3">Referral List</h6>
|
||||
</div>
|
||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_CASE_MANAGER') %}
|
||||
<div>
|
||||
<button type="button" class="btn btn-block btn-light mb-3" onclick="window.open('{{ path('app_case_add_referral', {id: case.id}) }}', '_self')">Add Referral</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body px-0 pb-2">
|
||||
@ -37,6 +39,12 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for r in openReferrals %}
|
||||
{% set dateEndWarning = '' %}
|
||||
{% if date('+14 days') >= r.endDate %}
|
||||
{% set dateEndWarning = 'bg-gradient-danger text-white' %}
|
||||
{% elseif date('+28 days') >= r.endDate %}
|
||||
{% set dateEndWarning = 'bg-gradient-faded-warning' %}
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>
|
||||
<h6 class='mb-0 text-small'>{{ r.referralId }}</h6>
|
||||
@ -44,13 +52,13 @@
|
||||
<td>
|
||||
<p class='text-xs font-weight-bold mb-0'>{{ r.serviceCode.value }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class='text-xs font-weight-bold mb-0'>{{ r.hours }}</p>
|
||||
<td class='text-center {% if r.getHoursRemaining() < 40 %}bg-gradient-danger text-white{% endif %}'>
|
||||
<p class='text-xs font-weight-bold mb-0'>{{ r.hours }} / {{ r.getHoursRemaining() }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class='text-xs font-weight-bold mb-0'>{{ r.endDate|date("F j, Y") }}</p>
|
||||
<td class='text-center {{ dateEndWarning }}'>
|
||||
<p class='text-xs font-weight-bold mb-0'>{{ r.endDate|date("M j, Y") }}</p>
|
||||
</td>
|
||||
<td class='align-right'>
|
||||
<td class='text-center'>
|
||||
<a href='{{ path('app_case_edit_referral', {caseId: case.id, referralId: r.id}) }}' class='' title='Edit Referral' data-toggle='tooltip'>
|
||||
<i class="material-symbols-rounded opacity-5">edit</i>
|
||||
</a>
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% block nav %}
|
||||
<aside class="sidenav navbar navbar-vertical navbar-expand-xs border-radius-lg fixed-start ms-2 bg-white my-2" id="sidenav-main">
|
||||
<aside class="sidenav navbar navbar-vertical navbar-expand-xs border-radius-lg fixed-start ms-2 my-2 bg-white" id="sidenav-main">
|
||||
<div class="sidenav-header">
|
||||
<i class="fas fa-times p-3 cursor-pointer text-dark opacity-5 position-absolute end-0 top-0 d-none d-xl-none" aria-hidden="true" id="iconSidenav"></i>
|
||||
<a class="navbar-brand px-4 py-3 m-0" href="{{ path('app_dashboard') }}">
|
||||
@ -17,16 +17,19 @@
|
||||
<div class="collapse navbar-collapse w-auto " id="sidenav-collapse-main">
|
||||
<ul class="navbar-nav">
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<li class="nav-item mt-3">
|
||||
<h6 class="ps-4 ms-2 text-uppercase text-xs text-dark font-weight-bolder opacity-5">Admin pages</h6>
|
||||
</li>
|
||||
<li class='nav-item'>
|
||||
<a class="{{ admin_dashboard }}" href="{{ path('app_admin_dashboard') }}">
|
||||
<i class="material-symbols-rounded opacity-5">dashboard</i>
|
||||
<span class="nav-link-text ms-1">Admin Dashboard</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class='nav-item'>
|
||||
<a class='{{ case_list }}' href='{{ path('app_list_cases') }}'>
|
||||
<i class='material-symbols-rounded opacity-5'>cases</i>
|
||||
<span class='nav-link-text ms-1'>Case List</span>
|
||||
<li class="nav-item">
|
||||
<a class="{{ user_list }}" href="{{ path('app_list_users') }}">
|
||||
<i class="material-symbols-rounded opacity-5">assignment</i>
|
||||
<span class="nav-link-text ms-1">User List</span>
|
||||
</a>
|
||||
</li>
|
||||
<li clas='nav-item'>
|
||||
@ -37,7 +40,7 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('ROLE_CASE_MANAGER') %}
|
||||
{% if is_granted('ROLE_CASE_MANAGER') or is_granted('ROLE_ADMIN') %}
|
||||
<li class='nav-item'>
|
||||
<a class='{{ staff_dashboard }}' href='{{ path('app_staff_dashboard') }}'>
|
||||
<i class='material-symbols-rounded opacity-5'>dashboard</i>
|
||||
@ -46,12 +49,27 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class="nav-item mt-3">
|
||||
<h6 class="ps-4 ms-2 text-uppercase text-xs text-dark font-weight-bolder opacity-5">User pages</h6>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="{{ user_dashboard }}" href="{{ path('app_dashboard') }}">
|
||||
<i class="material-symbols-rounded opacity-5">dashboard</i>
|
||||
<span class="nav-link-text ms-1">Dashboard</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class='nav-item'>
|
||||
<a class='{{ case_list }}' href='{{ path('app_list_cases') }}'>
|
||||
<i class='material-symbols-rounded opacity-5'>cases</i>
|
||||
<span class='nav-link-text ms-1'>Case List</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class='nav-item'>
|
||||
<a class='{{ case_notes }}' href='{{ path('app_list_notes') }}'>
|
||||
<i class='material-symbols-rounded opacity-5'></i>
|
||||
<span class='nav-link-text ms-1'>Case Notes</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item mt-3">
|
||||
<h6 class="ps-4 ms-2 text-uppercase text-xs text-dark font-weight-bolder opacity-5">Account pages</h6>
|
||||
</li>
|
||||
@ -61,14 +79,6 @@
|
||||
<span class="nav-link-text ms-1">Profile</span>
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<li class="nav-item">
|
||||
<a class="{{ user_list }}" href="{{ path('app_list_users') }}">
|
||||
<i class="material-symbols-rounded opacity-5">assignment</i>
|
||||
<span class="nav-link-text ms-1">User List</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class='nav-item'>
|
||||
<a class='text-dark nav-link' href='{{ logout_path() }}'>
|
||||
<i class='material-symbols-rounded opacity-5'>logout</i>
|
||||
|
@ -20,6 +20,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<ul class="navbar-nav d-flex align-items-center justify-content-end">
|
||||
<li class="nav-item d-xl-none ps-3 d-flex align-items-center">
|
||||
<a href="javascript:;" class="nav-link p-0 text-body" id="iconNavbarSidenav">
|
||||
<div class="sidenav-toggler-inner">
|
||||
<i class="sidenav-toggler-line"></i>
|
||||
<i class="sidenav-toggler-line"></i>
|
||||
<i class="sidenav-toggler-line"></i>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<li class="nav-item px-3 d-flex align-items-center" title="Site Settings">
|
||||
<a href="javascript:;" class="nav-link text-body p-0">
|
||||
|
@ -17,7 +17,7 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-6 d-lg-flex d-none h-100 my-auto pe-0 position-absolute top-0 start-0 text-center justify-content-center flex-column">
|
||||
<div class="position-relative bg-gradient-primary h-100 m-3 px-7 border-radius-lg d-flex flex-column justify-content-center" style="background-image: url('/assets/img/illustrations/illustration-signup.jpg'); background-size: cover;"></div>
|
||||
<div class="position-relative bg-gradient-primary h-100 m-3 px-7 border-radius-lg d-flex flex-column justify-content-center" style="background-image: url('{{ asset('img/illustrations/illustration-signup.jpg') }}'); background-size: cover;"></div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-5 col-md-7 d-flex flex-column ms-auto me-auto ms-lg-auto me-lg-5">
|
||||
<div class="card card-plain">
|
||||
|
@ -17,13 +17,13 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-6 d-lg-flex d-none h-100 my-auto pe-0 position-absolute top-0 start-0 text-center justify-content-center flex-column">
|
||||
<div class="position-relative bg-gradient-primary h-100 m-3 px-7 border-radius-lg d-flex flex-column justify-content-center" style="background-image: url('/assets/img/illustrations/illustration-signup.jpg'); background-size: cover;"></div>
|
||||
<div class="position-relative bg-gradient-primary h-100 m-3 px-7 border-radius-lg d-flex flex-column justify-content-center" style="background-image: url('{{ asset('img/illustrations/illustration-signup.jpg') }}'); background-size: cover;"></div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-5 col-md-7 d-flex flex-column ms-auto me-auto ms-lg-auto me-lg-5">
|
||||
<div class="card card-plain">
|
||||
<div class="card-header">
|
||||
<h4 class="font-weight-bolder">Sign Up</h4>
|
||||
<p class="mb-0">Enter your email and password to register</p>
|
||||
<h4 class="font-weight-bolder">Add Company</h4>
|
||||
<p class="mb-0">Add company data</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ form_errors(form) }}
|
||||
|
Loading…
Reference in New Issue
Block a user