Compare commits

...

18 Commits

Author SHA1 Message Date
d85c1571e7 add update for personal and work phone number 2025-01-05 06:22:29 +00:00
adcd02ff2b add modal to send message to supervisor and contact info for supervisor 2025-01-05 06:20:38 +00:00
ec487ed1ac add icon and user profile image for message type and sender 2025-01-05 06:17:37 +00:00
83a886c134 add repositories 2025-01-05 06:13:39 +00:00
43bff55192 add method to filter notes 2025-01-05 06:11:35 +00:00
2031165afc add method to format phones 2025-01-05 06:10:22 +00:00
f14a4fa67c add staff_note enum type 2025-01-05 06:10:00 +00:00
f0853bfcb2 add connector class for notes and members 2025-01-05 06:09:29 +00:00
980affbfbb add personal and work phone 2025-01-05 06:08:02 +00:00
f9608bce18 add jsonSerialize 2025-01-05 06:07:46 +00:00
c78698ace4 reconfigure 2025-01-05 06:04:21 +00:00
91723ed9be reconfigure 2025-01-05 06:03:42 +00:00
758a439187 convert list-notes to not show anything by default but have a few filter fields to display what is needed, change add notes to use different member collection and tables, add filter method 2025-01-05 06:00:40 +00:00
6dc478d0b3 add exclusion for uploads folder 2025-01-05 05:56:57 +00:00
478cb006b4 for vich_uploader 2025-01-05 05:56:34 +00:00
5b3bb9f14c add mileage_rate .env variable 2025-01-05 05:56:08 +00:00
d5b3a56e0f add firewall path for uploads/user_images 2025-01-05 05:55:39 +00:00
ca379711e2 add vich_uploader config 2025-01-05 05:54:51 +00:00
23 changed files with 574 additions and 192 deletions

View File

@ -14,4 +14,5 @@ return [
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
Symfony\UX\Map\UXMapBundle::class => ['all' => true],
Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
];

View File

@ -11,6 +11,9 @@ security:
property: username
# used to reload user from session & other features (e.g. switch_user)
firewalls:
profile_images:
pattern: ^/uploads/user_images/
security: false
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
@ -21,7 +24,7 @@ security:
login_path: app_login
check_path: app_login
enable_csrf: false
default_target_path: /dashboard
default_target_path: app_dashboard
logout:
path: app_logout
# where to redirect after logout

View File

@ -1,5 +1,7 @@
twig:
file_name_pattern: '*.twig'
globals:
mileage_rate: '%env(MILEAGE_RATE)%'
when@test:
twig:

View File

@ -0,0 +1,20 @@
vich_uploader:
db_driver: orm
metadata:
auto_detection: true
cache: file
type: attribute
mappings:
imageName:
uri_prefix: "%app.path.imageName%"
upload_destination: "%kernel.project_dir%/public/upload/user/profiles"
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
inject_on_load: false
delete_on_update: true
delete_on_remove: true
#mappings:
# products:
# uri_prefix: /images/products
# upload_destination: '%kernel.project_dir%/public/images/products'
# namer: Vich\UploaderBundle\Naming\SmartUniqueNamer

View File

@ -4,6 +4,7 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
app.path.imageName: /upload/user/profiles
services:
# default configuration for services in *this* file

1
public/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
uploads

View File

@ -3,12 +3,15 @@
namespace App\Controller;
use App\Entity\Member;
use App\Entity\MemberCase;
use App\Entity\Messages;
use App\Entity\Referral;
use App\Entity\StandardNote;
use App\Entity\StandardNoteMember;
use App\Entity\User;
use App\Entity\UserCase;
use App\Entity\VisitNote;
use App\Entity\VisitNoteMembers;
use App\Enums\NoteLocation;
use App\Enums\NoteMethod;
use App\Enums\ReferralServiceType;
@ -16,6 +19,8 @@ use App\Form\StandardNoteFormType;
use App\Form\VisitNoteFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
@ -42,39 +47,14 @@ class NoteController extends AbstractController
$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
#[Route('/list-notes/', name: 'app_list_notes')]
public function listNotes(#[CurrentUser()] User $user, Request $request): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
/** @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',
@ -86,18 +66,17 @@ class NoteController extends AbstractController
],
'notifications' => $this->msgs,
'cases' => $cases,
'notes' => $notes,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/add-note/{id?null}', name: 'app_add_note')]
public function addNote(#[CurrentUser()] User $user, Request $request, ?string $id = null): Response
#[Route('/add-note/{referralId}', name: 'app_add_note')]
public function addNote(#[CurrentUser()] User $user, Request $request, ?string $referralId = null): Response
{
/** @var Referral $referral */
$referral = $this->entityManager->getRepository(Referral::class)->find($id);
$referral = $this->entityManager->getRepository(Referral::class)->find($referralId);
$this->entityManager->getRepository(Referral::class)->populateNotes($referral);
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
@ -108,8 +87,8 @@ class NoteController extends AbstractController
$form = $this->createForm(StandardNoteFormType::class, null, ['members' => $members]);
$template = 'internal/cases/notes/add-standard-note.html.twig';
if ($id == 'null') {
$id = null;
if ($referralId == 'null') {
$referralId = null;
}
if ($referral->getServiceCode() == ReferralServiceType::VS_THBB) {
@ -153,19 +132,38 @@ class NoteController extends AbstractController
);
}
#[Route('/edit-note/{noteId}', name: 'app_edit_note')]
public function editNote(string $noteId, #[CurrentUser()] User $user, Request $request): Response
#[Route('/edit-note/{noteType}/{noteId}', name: 'app_edit_note')]
public function editNote(string $noteId, string $noteType, #[CurrentUser()] User $user, Request $request): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$form = null;
/** @var VisitNote|StandardNote $note */
if ($noteType == 'visit') {
$note = $this->entityManager->getRepository(VisitNote::class)->find($noteId);
$members = $this->entityManager->getRepository(Member::class)->findBy(['memberCase' => $note->getReferral()->getMemberCase()]);
$form = $this->createForm(VisitNoteFormType::class, $note, ['members' => $members]);
} elseif ($noteType == 'standard') {
$note = $this->entityManager->getRepository(StandardNote::class)->find($noteId);
$members = $this->entityManager->getRepository(Member::class)->findBy(['memberCase' => $note->getReferral()->getMemberCase()]);
$form = $this->createForm(StandardNoteFormType::class, $note, ['members' => $members]);
}
return $this->render(
'internal/cases/notes/edit-note.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'note' => $note,
'referral' => $note->getReferral(),
'form' => $form,
'noteType' => $noteType
]
)
);
@ -174,17 +172,54 @@ class NoteController extends AbstractController
#[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');
$startDate = null;
$endDate = null;
$referral = null;
if ($referralId) {
$referral = $this->entityManager->getRepository(Referral::class)->find($referralId);
$case = null;
if ($request->getPayload()->get('startDate')) {
$startDate = new DateTime($request->getPayload()->get('startDate'), new DateTimeZone('America/Indiana/Indianapolis'));
}
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),
));
if ($request->getPayload()->get('endDate')) {
$endDate = new DateTime($request->getPayload()->get('endDate'), new DateTimeZone('America/Indiana/Indianapolis'));
}
if ($request->getPayload()->get('referral')) {
$referral = $this->entityManager->getRepository(Referral::class)->find($request->getPayload()->get('referral'));
}
if ($request->getPayload()->get('case')) {
$case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('case'));
}
$params = [
'startDate' => $startDate,
'endDate' => $endDate,
'referral' => $referral,
'case' => $case,
];
$notes = array_merge(
$this->entityManager->getRepository(VisitNote::class)->filterNotes($user, $params),
$this->entityManager->getRepository(StandardNote::class)->filterNotes($user, $params),
);
foreach ($notes as $idx => $note) {
/** @var VisitNote|StandardNote $note */
/** @var VisitNoteMember[]|StandardNoteMember[] $members */
if ($note instanceof VisitNote) {
$members = $this->entityManager->getRepository(VisitNoteMembers::class)->findBy(['note' => $note]);
} elseif ($note instanceof StandardNote) {
$members = $this->entityManager->getRepository(StandardNoteMember::class)->findBy(['note' => $note]);
} else {
continue;
}
$notes[$idx]->setMembers($members);
}
return new Response(json_encode($notes, 0, 3));
}
}

View File

@ -6,8 +6,6 @@ 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;
@ -39,18 +37,19 @@ class Note
#[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;
private ?array $members = null;
public function __construct()
{
$this->members = [];
}
public function getId(): ?UUid
{
return $this->id;
@ -116,37 +115,6 @@ class Note
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 setMembers(?array $members): static
{
$this->members = $members;
return $this;
}
public function getLocation(): ?NoteLocation
{
return $this->location;
@ -171,6 +139,25 @@ class Note
return $this;
}
public function getMembers(): ?array
{
return $this->members;
}
public function setMembers(?array $members): static
{
$this->members = $members;
return $this;
}
public function addMember(Member $member): static
{
$this->members[] = $member;
return $this;
}
/**
* Method to calculate the number of minutes used for a visit rounded to the nearest 15 min increment
*

View File

@ -43,18 +43,6 @@ 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
*/
@ -65,8 +53,6 @@ class Referral
*/
public function __construct()
{
$this->notes = new ArrayCollection();
$this->present = new ArrayCollection();
$this->hoursUsed = 0.0;
}
@ -159,74 +145,13 @@ 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;
}
public function getHoursUsed(): float
{
return $this->hoursUsed;
}
}

View File

@ -2,12 +2,14 @@
namespace App\Entity;
use App\Enums\ReferralServiceType;
use App\Repository\StandardNoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
#[ORM\Entity(repositoryClass: StandardNoteRepository::class)]
class StandardNote extends Note
class StandardNote extends Note implements JsonSerializable
{
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $note = null;
@ -23,4 +25,26 @@ class StandardNote extends Note
return $this;
}
public function jsonSerialize(): array
{
$members = [];
foreach ($this->getMembers() as $member) {
/** @var Member $member */
$members[] = $member->getName();
}
return [
'id' => $this->getId()->toString(),
'date' => $this->getDate()->format('M j, Y'),
'startTime' => $this->getStartTime()->format('g:i a'),
'endTime' => $this->getEndTime()->format('g:i a'),
'serviceCode' => $this->getReferral()->getServiceCode()->value,
'noteType' => ($this->getReferral()->getServiceCode() == ReferralServiceType::VS_THBB ? 'visit' : 'standard'),
'status' => $this->getStatus()->value,
'location' => $this->getLocation()->value,
'method' => ucwords(str_replace('_', ' ', strtolower($this->getMethod()->name))),
'members' => implode(', ', $members),
'duration' => $this->calcTimeUsed(),
];
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Entity;
use App\Repository\StandardNoteMemberRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: StandardNoteMemberRepository::class)]
class StandardNoteMember
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?StandardNote $note = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Member $person = null;
public function getId(): ?Uuid
{
return $this->id;
}
public function getStandardNote(): ?StandardNote
{
return $this->note;
}
public function setStandardNote(?StandardNote $note): static
{
$this->note = $note;
return $this;
}
public function getPerson(): ?Member
{
return $this->person;
}
public function setPerson(?Member $person): static
{
$this->person = $person;
return $this;
}
}

View File

@ -92,6 +92,12 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $passwordChanged = null;
#[ORM\Column(length: 15, nullable: true)]
private ?string $personalPhone = null;
#[ORM\Column(length: 15)]
private ?string $workPhone = null;
public function __construct()
{
$this->userCases = new ArrayCollection();
@ -399,4 +405,38 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
public function getPersonalPhone(): ?string
{
return $this->personalPhone;
}
public function setPersonalPhone(?string $personalPhone): static
{
$this->personalPhone = $personalPhone;
return $this;
}
public function getWorkPhone(): ?string
{
return $this->workPhone;
}
public function setWorkPhone(string $workPhone): static
{
$this->workPhone = $workPhone;
return $this;
}
public function getFormattedPhone(): ?string
{
$ret = '';
if ($this->workPhone) {
$ret = '(' . substr($this->workPhone, 0, 3) . ') ' . substr($this->workPhone, 3, 3) . '-' . substr($this->workPhone, 6);
}
return $ret;
}
}

View File

@ -2,13 +2,15 @@
namespace App\Entity;
use App\Enums\ReferralServiceType;
use App\Enums\VisitQualityLevel;
use App\Repository\VisitNoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
#[ORM\Entity(repositoryClass: VisitNoteRepository::class)]
class VisitNote extends Note
class VisitNote extends Note implements JsonSerializable
{
#[ORM\Column(type: Types::TEXT)]
private ?string $narrative = null;
@ -159,4 +161,36 @@ class VisitNote extends Note
return $this;
}
public function jsonSerialize(): array
{
$members = [];
foreach ($this->getMembers() as $member) {
/** @var Member $member */
$members[] = $member->getName();
}
return [
'id' => $this->getId()->toString(),
'date' => $this->getDate()->format('M j, Y'),
'startTime' => $this->getStartTime()->format('g:i a'),
'endTime' => $this->getEndTime()->format('g:i a'),
'serviceCode' => $this->getReferral()->getServiceCode()->value,
'noteType' => ($this->getReferral()->getServiceCode() == ReferralServiceType::VS_THBB ? 'visit' : 'standard'),
'status' => $this->getStatus()->value,
'location' => $this->getLocation()->value,
'method' => ucwords(str_replace('_', ' ', strtolower($this->getMethod()->name))),
'narrative' => $this->getNarrative(),
'strengths' => $this->getStrengths(),
'issues' => $this->getIssues(),
'recommendation' => $this->getRecommendation(),
'parentalRole' => $this->getParentalRole(),
'childDevelopment' => $this->getChildDevelopment(),
'appropriateResponse' => $this->getAppropriateResponse(),
'childAheadOfSelf' => $this->getChildAheadOfSelf(),
'showsEmpathy' => $this->getShowsEmpathy(),
'childFocused' => $this->getChildFocused(),
'members' => implode(', ', $members),
'duration' => $this->calcTimeUsed(),
];
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Entity;
use App\Repository\VisitNoteMembersRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: VisitNoteMembersRepository::class)]
class VisitNoteMembers
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?VisitNote $note = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Member $person = null;
public function getId(): ?int
{
return $this->id;
}
public function getVisitNote(): ?VisitNote
{
return $this->note;
}
public function setVisitNote(?VisitNote $note): static
{
$this->note = $note;
return $this;
}
public function getPerson(): ?Member
{
return $this->person;
}
public function setPerson(?Member $person): static
{
$this->person = $person;
return $this;
}
}

View File

@ -11,6 +11,7 @@ enum MessageType: int
case NEW_CASE = 4;
case USER = 5;
case NEW_REFERRAL = 6;
case STAFF_NOTE = 7;
case CALENDAR = 97;
case REMINDER = 98;
case UNKNOWN = 99;

View File

@ -61,4 +61,12 @@ class Libs
return null;
}
public static function Phone(string $phone): string
{
$phone = preg_replace('/[^0-9]/', '', $phone);
if(strlen($phone) > 10 && substr($phone, 0, 1) == '1') {
$phone = substr($phone, 1);
}
return $phone;
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\StandardNoteMember;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<StandardNoteMember>
*/
class StandardNoteMemberRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, StandardNoteMember::class);
}
// /**
// * @return StandardNoteMember[] Returns an array of StandardNoteMember 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): ?StandardNoteMember
// {
// return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -5,7 +5,7 @@ namespace App\Repository;
use App\Entity\Referral;
use App\Entity\StandardNote;
use App\Entity\User;
use DateTimeImmutable;
use App\Entity\UserCase;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
@ -31,29 +31,39 @@ class StandardNoteRepository extends ServiceEntityRepository
;
}
public function filterNotes(User $user, ?Referral $referral = null, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null): array
public function filterNotes(User $user, array $params = []): array
{
$query = $this->createQueryBuilder('v')
->join('v.referral', 'r')
$query = $this->createQueryBuilder('s')
->leftJoin(Referral::class, 'r', 'WITH', 's.referral = r.id')
->leftJoin(UserCase::class, 'uc', 'WITH', 'r.memberCase = uc.memberCase')
->andWhere('uc.user = :user')
->setParameter('user', $user->getId()->toBinary())
;
if ($referral) {
$query->andWhere('v.referral = :referral')
->setParameter('referral', $referral->getId()->toBinary());
if ($params['case']) {
$query->andWhere('r.memberCase = :memberCase')
->setParameter('memberCase', $params['case']->getId()->toBinary());
}
if ($startDate) {
$query->andWhere('v.date >= :startDate')
->setParameter('startDate', $startDate);
if ($params['referral']) {
$query->andWhere('s.referral = :referral')
->setParameter('referral', $params['referral']->getId()->toBinary());
}
if ($endDate) {
$query->andWhere('v.date <= :endDate')
->setParameter('endDate', $endDate);
if ($params['startDate']) {
$query->andWhere('s.date >= :startDate')
->setParameter('startDate', $params['startDate']);
}
return $query->orderBy('v.date', 'DESC')
->addOrderBy('v.startTime', 'DESC')
if ($params['endDate']) {
$query->andWhere('s.date <= :endDate')
->setParameter('endDate', $params['endDate']);
}
//dd($query->getQuery()->getResult());
return $query->orderBy('s.date', 'DESC')
->addOrderBy('s.startTime', 'DESC')
->getQuery()
->getResult()
;

View File

@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\VisitNoteMembers;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<VisitNoteMembers>
*/
class VisitNoteMembersRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, VisitNoteMembers::class);
}
// /**
// * @return VisitNoteMembers[] Returns an array of VisitNoteMembers 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): ?VisitNoteMembers
// {
// return $this->createQueryBuilder('v')
// ->andWhere('v.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -3,8 +3,10 @@
namespace App\Repository;
use App\Entity\Referral;
use App\Entity\UserCase;
use App\Entity\User;
use App\Entity\VisitNote;
use App\Entity\VisitNoteMembers;
use DateTimeImmutable;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
@ -31,25 +33,33 @@ class VisitNoteRepository extends ServiceEntityRepository
;
}
public function filterNotes(User $user, ?Referral $referral = null, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null): array
public function filterNotes(User $user, array $params = []): array
{
$query = $this->createQueryBuilder('v')
->join('v.referral', 'r')
->leftJoin(Referral::class, 'r', 'WITH', 'v.referral = r.id')
->leftJoin(UserCase::class, 'uc', 'WITH', 'r.memberCase = uc.memberCase')
->andWhere('uc.user = :user')
->setParameter('user', $user->getId()->toBinary())
;
if ($referral) {
if ($params['case']) {
$query->andWhere('r.memberCase = :memberCase')
->setParameter('memberCase', $params['case']->getId()->toBinary());
}
if ($params['referral']) {
$query->andWhere('v.referral = :referral')
->setParameter('referral', $referral->getId()->toBinary());
->setParameter('referral', $params['referral']->getId()->toBinary());
}
if ($startDate) {
if ($params['startDate']) {
$query->andWhere('v.date >= :startDate')
->setParameter('startDate', $startDate);
->setParameter('startDate', $params['startDate']);
}
if ($endDate) {
if ($params['endDate']) {
$query->andWhere('v.date <= :endDate')
->setParameter('endDate', $endDate);
->setParameter('endDate', $params['endDate']);
}
return $query->orderBy('v.date', 'DESC')

View File

@ -47,7 +47,31 @@
<a class='dropdown-item border-radius-md' href="javascript:openNotification('{{ note.id }}');">
<div class='d-flex py-1'>
<div class='my-auto'>
<img src='' class='avatar avatar-sm me-3'>
{% if note.sender.imageName %}<img src='/uploads/user_images/{{ note.sender.imageName }}' class='avatar avatar-sm me-3'><br/>
{% endif %}
<i class='material-symbols-rounded opacity-7'>
{% if note.type == enum('App\\Enums\\MessageType').CASE %}
cases
{% elseif note.type == enum('App\\Enums\\MessageType').STAFFING %}
person
{% elseif note.type == enum('App\\Enums\\MessageType').GENERAL %}
chat_bubble
{% elseif note.type == enum('App\\Enums\\MessageType').BILLING %}
local_atm
{% elseif note.type == enum('App\\Enums\\MessageType').NEW_CASE %}
business_center
{% elseif note.type == enum('App\\Enums\\MessageType').USER %}
person_add
{% elseif note.type == enum('App\\Enums\\MessageType').NEW_REFERRAL %}
add_to_queue
{% elseif note.type == enum('App\\Enums\\MessageType').STAFF_NOTE %}
add_notes
{% elseif note.type == enum('App\\Enums\\MessageType').CALENDAR %}
calendar_month
{% elseif note.type == enum('App\\Enums\\MessageType').REMINDER %}
notifications
{% endif %}
</i>
</div>
<div class='d-flex flex-column justify-content-center'>
<h6 class='text-sm font-weight-normal mb-1'>

View File

@ -30,10 +30,21 @@
<input type='email' name='{{ field_name(form.email) }}' id='profile_form_email' class='form-control' value='{{ currentUser.email }}'/>
</div>
<div class='input-group input-group-outline mb-3 {% if currentUser.personalPhone %}is-filled{% endif %}'>
<label for='profile_form_phone' class='form-label'>Phone</label>
<input type='tel' name='{{ field_name(form.personalPhone) }}' id='profile_form_phone' class='form-control' value='{{ currentUser.personalPhone }}'/>
</div>
<div class='input-group input-group-outline mb-3 {% if currentUser.workPhone %}is-filled{% endif %}'>
<label for='profile_form_workPhone' class='form-label'>Work Phone</label>
<input type='tel' name='{{ field_name(form.workPhone) }}' id='profile_form_workPhone' class='form-control' value='{{ currentUser.workPhone }}'/>
</div>
<div class='input-group input-group-outline mb-3'>
<label for='profile_form_password' class='form-label'>Password</label>
<input type='password' name='{{ field_name(form.password.first) }}' id='profile_form_password' class='form-control' autocomplete='new-password'/>
</div>
<div class='input-group input-group-outline mb-3'>
<label for='profile_form_confirmPassword' class='form-label'>Confirm Password</label>
<input type='password' name='{{ field_name(form.password.second) }}' id='profile_form_confirmPassword' class='form-control' autocomplete='new-password'/>

View File

@ -10,9 +10,11 @@
<div class='ms-3'>
<h3 class='mb-0 h4 font-weight-bolder'>My Cases</h3>
<p class='mb-4'>
{{ supervisor.name }}<br/>
{{ supervisor.name }}&nbsp;&nbsp;<a href='#' id='message-supervisor'>
<i class='material-symbols-rounded opacity-10'>message</i>
</a><br/>
<a href='mailto:{{ supervisor.email }}'>{{ supervisor.email }}</a><br/>
<a href='tel:'></a>
{% if supervisor.workPhone %}<a href='tel:{{ supervisor.workPhone }}'>{{ supervisor.getFormattedPhone() }}</a>{% endif %}
</p>
</div>
{% for c in cases %}
@ -44,5 +46,52 @@
{% endfor %}
</div>
</div>
<div class='modal fade' id='message-modal' tabindex='-1' role='dialog' aria-labelledby='message-modal-title'>
<div class='modal-dialog modal-dialog-centered' role='document'>
<div class='modal-content'>
<div class="modal-header">
<h6 class="modal-title font-weight-normal" id="message-modal-label">Message Supervisor</h6>
<button type="button" class="btn-close text-dark" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class='modal-body'>
<form>
<div class='input-group input-group-outline my-3'>
<select id='my-cases' name='case'>
<option value=''>-- Case --</option>
{% for c in cases %}
<option value='{{ c.id }}'>{{ c.caseName }}</option>
{% endfor %}
</select>
</div>
<div class='input-group input-group-outline my-3'>
<textarea name='message' id='message' style='width:100%;height:100px;'></textarea>
</div>
</form>
</div>
<div class='modal-footer'>
<button type='button' id='close-modal' class='btn bg-gradient-secondary' data-bs-dismiss='modal'>Close</button>
<button type='button' id='send-supervisor-message' class='btn bg-gradient-primary'>Send Message</button>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
{% block page_js %}
<script type='module'>
import $ from "{{ asset('vendor/jquery/jquery.index.js') }}";
import {messageSupervisor, sendMessage} from '{{ asset("js/app/message.js") }}';
window.$ = $;
$(function () {
document.getElementById('message-supervisor').addEventListener('click', messageSupervisor);
document.getElementById('send-supervisor-message').addEventListener('click', sendMessage);
});
</script>
{% endblock %}