Compare commits
9 Commits
2e163d526c
...
577dee227d
Author | SHA1 | Date | |
---|---|---|---|
577dee227d | |||
79bb26e9f3 | |||
109384ec99 | |||
781935821b | |||
81ba235b08 | |||
c3bc40561b | |||
af41590fd3 | |||
03c7153565 | |||
b42b1ea410 |
@ -2,7 +2,7 @@ export function filterAddressesByCase() {
|
|||||||
if (!document.getElementById('case-filter').value) {
|
if (!document.getElementById('case-filter').value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fetch('/index.php/api/filter-address-by-case/' + document.getElementById('case-filter').value, {
|
fetch('/api/filter-address-by-case/' + document.getElementById('case-filter').value, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
header: {
|
header: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -47,3 +47,52 @@ export function filterAddressesByCase() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function filterItineraryByCase() {
|
||||||
|
let caseId = null;
|
||||||
|
let startDate = null;
|
||||||
|
let endDate = null;
|
||||||
|
|
||||||
|
if (document.getElementById('case-filter').value) {
|
||||||
|
caseId = document.getElementById('case-filter').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getElementById('start-date-filter').value) {
|
||||||
|
startDate = document.getElementById('start-date-filter').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getElementById('end-date-filter').value) {
|
||||||
|
endDate = document.getElementById('end-date-filter').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('/api/filter-itinerary-by-case', {
|
||||||
|
method: 'POST',
|
||||||
|
header: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
caseId: caseId,
|
||||||
|
startDate: startDate,
|
||||||
|
endDate: endDate,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(result => {
|
||||||
|
const itineraryList = document.getElementById('itineraryList');
|
||||||
|
itineraryList.innerHTML = '';
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
result.forEach(i => {
|
||||||
|
itineraryList.innerHTML += `
|
||||||
|
<tr>
|
||||||
|
<td>${i.date}</td>
|
||||||
|
<td>${i.case}</td>
|
||||||
|
<td>${i.origin.name}</td>
|
||||||
|
<td>${i.destination.name}</td>
|
||||||
|
<td>${i.duration}</td>
|
||||||
|
<td>${i.distance}</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>`;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -45,12 +45,9 @@ export function addLocationToItinerary() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function openMap() {
|
export function openMap() {
|
||||||
if (!document.getElementById('case-filter').value || !document.getElementById('date-filter').value) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('caseId').value = document.getElementById('case-filter').value;
|
document.getElementById('caseId').value = document.getElementById('case-filter').value;
|
||||||
document.getElementById('caseDate').value = document.getElementById('date-filter').value;
|
document.getElementById('startDate').value = document.getElementById('start-date-filter').value;
|
||||||
|
document.getElementById('endDate').value = document.getElementById('end-date-filter').value;
|
||||||
|
|
||||||
document.getElementById('map-form').submit();
|
document.getElementById('map-form').submit();
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ use App\Entity\Location;
|
|||||||
use App\Entity\MemberCase;
|
use App\Entity\MemberCase;
|
||||||
use App\Entity\Messages;
|
use App\Entity\Messages;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
|
use App\Entity\UserCase;
|
||||||
use App\Libs\Breadcrumb;
|
use App\Libs\Breadcrumb;
|
||||||
use App\Libs\Libs;
|
use App\Libs\Libs;
|
||||||
use App\Libs\NavList;
|
use App\Libs\NavList;
|
||||||
@ -38,15 +39,57 @@ class ItineraryController extends AbstractController
|
|||||||
$this->navLinks = NavList::LIST;
|
$this->navLinks = NavList::LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/itinerary/map', name: 'app_map_itinerary')]
|
#[Route('/itinerary/report', name: 'app_report_itinerary')]
|
||||||
public function mapItinerary(Request $request, #[CurrentUser()] ?User $user): Response
|
public function reportItinerary(Request $request, #[CurrentUser()] ?User $user): Response
|
||||||
{
|
{
|
||||||
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
|
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
|
||||||
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
|
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
|
||||||
|
|
||||||
$itineraries = $this->entityManager->getRepository(CaseItinerary::class)->findBy([
|
$itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel(
|
||||||
'memberCase' => $request->getPayload()->get('caseId'),
|
$user
|
||||||
'date' => new DateTime($request->getPayload()->get('caseDate'))
|
);
|
||||||
|
|
||||||
|
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
|
||||||
|
$cases = [];
|
||||||
|
foreach ($ucs as $uc) {
|
||||||
|
/** @var UserCase $uc */
|
||||||
|
$cases[] = $uc->getMemberCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'internal/cases/itinerary/report.html.twig',
|
||||||
|
array_merge(
|
||||||
|
$this->navLinks,
|
||||||
|
[
|
||||||
|
'breadcrumbs' => [
|
||||||
|
new Breadcrumb($this->generateUrl('app_dashboard'), 'Dashboard'),
|
||||||
|
],
|
||||||
|
'notifications' => $this->msgs,
|
||||||
|
'notificationCount' => $this->notificationCount,
|
||||||
|
'itineraries' => $itineraries,
|
||||||
|
'cases' => $cases
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/itinerary/map', name: 'app_map_itinerary')]
|
||||||
|
public function mapItinerary(Request $request, #[CurrentUser()] ?User $user): Response
|
||||||
|
{
|
||||||
|
$case = null;
|
||||||
|
if ($request->getPayload()->get('caseId')) {
|
||||||
|
$case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('caseId'));
|
||||||
|
}
|
||||||
|
$startDate = ($request->getPayload()->get('startDate') ?new DateTime($request->getPayload()->get('startDate')) : null);
|
||||||
|
$endDate = ($request->getPayload()->get('endDate') ? new DateTime($request->getPayload()->get('endDate')) : null);
|
||||||
|
|
||||||
|
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
|
||||||
|
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
|
||||||
|
|
||||||
|
$itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel($user, [
|
||||||
|
'case' => $case,
|
||||||
|
'from' => $startDate,
|
||||||
|
'to' => $endDate,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$map = new Map('default');
|
$map = new Map('default');
|
||||||
@ -55,20 +98,48 @@ class ItineraryController extends AbstractController
|
|||||||
;
|
;
|
||||||
|
|
||||||
$total_distance = 0;
|
$total_distance = 0;
|
||||||
$total_duration = 0;
|
$total_duration = new DateTime('00:00:00');
|
||||||
|
|
||||||
foreach ($itineraries as $itinerary) {
|
foreach ($itineraries as $itinerary) {
|
||||||
|
/** @var CaseItinerary $itinerary */
|
||||||
|
$map->addMarker(new Marker(
|
||||||
|
position: new Point(
|
||||||
|
$itinerary->getOriginLocation()->getLat(),
|
||||||
|
$itinerary->getOriginLocation()->getLon()
|
||||||
|
),
|
||||||
|
title: $itinerary->getOriginLocation()->getName(),
|
||||||
|
infoWindow: new InfoWindow(
|
||||||
|
content: $itinerary->getOriginLocation()->getName(),
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
$map->addMarker(new Marker(
|
||||||
|
position: new Point(
|
||||||
|
$itinerary->getDestLocation()->getLat(),
|
||||||
|
$itinerary->getDestLocation()->getLon()
|
||||||
|
),
|
||||||
|
title: $itinerary->getDestLocation()->getName(),
|
||||||
|
infoWindow: new InfoWindow(
|
||||||
|
content: $itinerary->getDestLocation()->getName(),
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
/** @var CaseItinerary $itinerary */
|
/** @var CaseItinerary $itinerary */
|
||||||
$map->addPolyline(new Polyline(
|
$map->addPolyline(new Polyline(
|
||||||
points: $itinerary->getGPSPolyLines(),
|
points: $itinerary->getGPSPolyLines(),
|
||||||
infoWindow: new InfoWindow(
|
infoWindow: new InfoWindow(
|
||||||
content: $itinerary->getMemberCase()->getCaseName()
|
content: $itinerary->getMemberCase()->getCaseName()
|
||||||
)
|
),
|
||||||
|
extra: ['color' => '#FF0000']
|
||||||
));
|
));
|
||||||
|
|
||||||
$total_distance += $itinerary->getDistance();
|
$total_distance += $itinerary->getDistance();
|
||||||
$total_duration += $itinerary->getDuration()->s;
|
$total_duration->add($itinerary->getDuration());
|
||||||
}
|
}
|
||||||
|
$map->fitBoundsToMarkers(true);
|
||||||
|
|
||||||
|
$diff = new DateTime('00:00:00');
|
||||||
|
$di = $diff->diff($total_duration);
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
'internal/cases/itinerary/map.html.twig',
|
'internal/cases/itinerary/map.html.twig',
|
||||||
@ -77,12 +148,13 @@ class ItineraryController extends AbstractController
|
|||||||
[
|
[
|
||||||
'breadcrumbs' => [
|
'breadcrumbs' => [
|
||||||
new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases'),
|
new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases'),
|
||||||
|
new Breadcrumb($this->generateUrl('app_itinerary_report'), 'Itinerary Report'),
|
||||||
],
|
],
|
||||||
'notifications' => $this->msgs,
|
'notifications' => $this->msgs,
|
||||||
'notificationCount' => $this->notificationCount,
|
'notificationCount' => $this->notificationCount,
|
||||||
'map' => $map,
|
'map' => $map,
|
||||||
'total_distance' => $total_distance,
|
'total_distance' => $total_distance,
|
||||||
'total_duration' => $total_duration,
|
'total_duration' => $di->format("%H:%i'%s''"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -142,4 +214,50 @@ class ItineraryController extends AbstractController
|
|||||||
);
|
);
|
||||||
return $this->json(['success' => true, 'message' => 'Location added to itinerary']);
|
return $this->json(['success' => true, 'message' => 'Location added to itinerary']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Route('/api/filter-itinerary-by-case', name: 'ajax_filter_itinerary_by_case')]
|
||||||
|
public function filterItineraryByCase(Request $request, #[CurrentUser()] ?User $user): Response
|
||||||
|
{
|
||||||
|
$case = null;
|
||||||
|
$startDate = null;
|
||||||
|
$endDate = null;
|
||||||
|
|
||||||
|
//dd($request->getPayload());
|
||||||
|
|
||||||
|
if ($request->getPayload()->get('caseId')) {
|
||||||
|
$caseId = $request->getPayload()->get('caseId');
|
||||||
|
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->getPayload()->get('startDate')) {
|
||||||
|
$startDate = new DateTime($request->getPayload()->get('startDate'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->getPayload()->get('endDate')) {
|
||||||
|
$endDate = new DateTime($request->getPayload()->get('endDate'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel($user, [
|
||||||
|
'case' => $case,
|
||||||
|
'from' => $startDate,
|
||||||
|
'to' => $endDate,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$ret = [];
|
||||||
|
|
||||||
|
foreach ($itineraries as $itinerary) {
|
||||||
|
/** @var CaseItinerary $itinerary */
|
||||||
|
$ret[] = [
|
||||||
|
'id' => $itinerary->getId()->toString(),
|
||||||
|
'date' => $itinerary->getDate()->format('F j, Y'),
|
||||||
|
'origin' => $itinerary->getOriginLocation(),
|
||||||
|
'destination' => $itinerary->getDestLocation(),
|
||||||
|
'distance' => $itinerary->getDistance(),
|
||||||
|
'duration' => $itinerary->getDuration()->format("%h:%i'%s''"),
|
||||||
|
'case' => $itinerary->getMemberCase()->getCaseName(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json($ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,15 @@ class MessageController extends AbstractController
|
|||||||
#[Route('/api/notifications/{msgId}', name: 'app_read_message')]
|
#[Route('/api/notifications/{msgId}', name: 'app_read_message')]
|
||||||
public function readMessage(string $msgId): Response
|
public function readMessage(string $msgId): Response
|
||||||
{
|
{
|
||||||
|
/** @var Messages $message */
|
||||||
$message = $this->entityManager->getRepository(Messages::class)->find($msgId);
|
$message = $this->entityManager->getRepository(Messages::class)->find($msgId);
|
||||||
$message->setReceived(new \DateTimeImmutable());
|
$message->setReceived(new \DateTimeImmutable());
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
return new JsonResponse(true, Response::HTTP_OK);
|
return $this->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Message marked as read',
|
||||||
|
'link' => $message->getLink(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,6 +202,7 @@ class StaffController extends AbstractController
|
|||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
/** @var StaffNote $note */
|
||||||
$note = $form->getData();
|
$note = $form->getData();
|
||||||
$note->setMemberCase($case);
|
$note->setMemberCase($case);
|
||||||
|
|
||||||
@ -209,9 +210,12 @@ class StaffController extends AbstractController
|
|||||||
$sup = $this->entityManager->getRepository(Supervision::class)->findOneBy(['worker' => $user]);
|
$sup = $this->entityManager->getRepository(Supervision::class)->findOneBy(['worker' => $user]);
|
||||||
|
|
||||||
$msg = MessageFactory::createStaffing($user, $sup->getSupervisor());
|
$msg = MessageFactory::createStaffing($user, $sup->getSupervisor());
|
||||||
|
|
||||||
$this->entityManager->persist($msg);
|
|
||||||
$this->entityManager->persist($note);
|
$this->entityManager->persist($note);
|
||||||
|
$this->entityManager->persist($msg);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$msg->setLink("/staff/sup-sign-note/" . $note->getId());
|
||||||
|
$this->entityManager->persist($msg);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->addFlash('info', 'Staff note added');
|
$this->addFlash('info', 'Staff note added');
|
||||||
@ -256,7 +260,7 @@ class StaffController extends AbstractController
|
|||||||
$note = $this->entityManager->getRepository(StaffNote::class)->find($noteId);
|
$note = $this->entityManager->getRepository(StaffNote::class)->find($noteId);
|
||||||
$case = $note->getMemberCase();
|
$case = $note->getMemberCase();
|
||||||
|
|
||||||
if ($note->supervisorSignDateTime || $note->workerSignDateTime) {
|
if ($note->getSupervisorSignDateTime() || $note->getWorkerSignDateTime()) {
|
||||||
$this->addFlash('error', 'This note has already been signed');
|
$this->addFlash('error', 'This note has already been signed');
|
||||||
return $this->redirectToRoute('app_staff_view_note', ['noteId' => $noteId]);
|
return $this->redirectToRoute('app_staff_view_note', ['noteId' => $noteId]);
|
||||||
}
|
}
|
||||||
@ -362,10 +366,10 @@ class StaffController extends AbstractController
|
|||||||
$note->setSupervisorSignDateTime(new \DateTimeImmutable());
|
$note->setSupervisorSignDateTime(new \DateTimeImmutable());
|
||||||
|
|
||||||
/** @var UserCase $uc */
|
/** @var UserCase $uc */
|
||||||
$uc = $this->entityManager->getRepository(UserCase::class)->findOneBy(['case' => $case]);
|
$uc = $this->entityManager->getRepository(UserCase::class)->findOneBy(['memberCase' => $case]);
|
||||||
|
|
||||||
$msg = MessageFactory::createSupervisorSignStaffNote($user, $uc->getUser(), $case);
|
$msg = MessageFactory::createSupervisorSignStaffNote($user, $uc->getUser(), $case);
|
||||||
|
$msg->setLink('/staff/sign-my-note/' . $note->getId());
|
||||||
$this->entityManager->persist($msg);
|
$this->entityManager->persist($msg);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
@ -41,6 +41,9 @@ class Messages
|
|||||||
#[ORM\JoinColumn(nullable: false)]
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
private ?User $sender = null;
|
private ?User $sender = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255, nullable: true)]
|
||||||
|
private ?string $link = null;
|
||||||
|
|
||||||
public function getId(): ?Uuid
|
public function getId(): ?Uuid
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -141,4 +144,16 @@ class Messages
|
|||||||
'message' => $this->message
|
'message' => $this->message
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLink(): ?string
|
||||||
|
{
|
||||||
|
return $this->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLink(?string $link): static
|
||||||
|
{
|
||||||
|
$this->link = $link;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use App\Entity\CaseItinerary;
|
use App\Entity\CaseItinerary;
|
||||||
|
use App\Entity\MemberCase;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Entity\UserCase;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
@ -16,6 +19,36 @@ class CaseItineraryRepository extends ServiceEntityRepository
|
|||||||
parent::__construct($registry, CaseItinerary::class);
|
parent::__construct($registry, CaseItinerary::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRecentTravel(User $user, ?array $params = null): ?array
|
||||||
|
{
|
||||||
|
//dd($params);
|
||||||
|
|
||||||
|
$query = $this->createQueryBuilder('ci')
|
||||||
|
->leftJoin(UserCase::class, 'uc', 'WITH', 'uc.memberCase = ci.memberCase')
|
||||||
|
->andWhere('uc.user = :user')
|
||||||
|
->setParameter('user', $user->getId()->toBinary())
|
||||||
|
;
|
||||||
|
|
||||||
|
if (isset($params['case']) && is_a($params['case'], MemberCase::class)) {
|
||||||
|
$query->andWhere('ci.memberCase = :case')->setParameter('case', $params['case']->getId()->toBinary());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['from']) && is_a($params['from'], \DateTime::class)) {
|
||||||
|
$query->andWhere('ci.date >= :from')->setParameter('from', $params['from']->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['to']) && is_a($params['to'], \DateTime::class)) {
|
||||||
|
$query->andWhere('ci.date <= :to')->setParameter('to', $params['to']->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$query->orderBy('ci.date', 'DESC')
|
||||||
|
->addOrderBy('ci.arrival', 'DESC');
|
||||||
|
|
||||||
|
//dd($query->getQuery());
|
||||||
|
|
||||||
|
return $query->getQuery()->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * @return CaseLocation[] Returns an array of CaseLocation objects
|
// * @return CaseLocation[] Returns an array of CaseLocation objects
|
||||||
// */
|
// */
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
</title>
|
</title>
|
||||||
|
|
||||||
<!-- Simple CSS
|
<!-- Simple CSS
|
||||||
<link
|
<link
|
||||||
rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">-->
|
rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">-->
|
||||||
|
|
||||||
<!-- Fonts and icons -->
|
<!-- Fonts and icons -->
|
||||||
<link
|
<link
|
||||||
|
@ -16,11 +16,7 @@
|
|||||||
<h6 class="text-white text-capitalize ps-3">Case Address List</h6>
|
<h6 class="text-white text-capitalize ps-3">Case Address List</h6>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<form action='{{ path('app_map_itinerary') }}' method='post' id='map-form' style='display:inline;'>
|
<button type='button' class='btn bg-gradient-info btn-block mb-3' id='itinerary-report' onclick="window.open('{{ path('app_report_itinerary') }}', '_self')">Itinerary Report</button>
|
||||||
<input type='hidden' name='caseId' id='caseId'/>
|
|
||||||
<input type='hidden' name='caseDate' id='caseDate'/>
|
|
||||||
<button type='button' class='btn bg-gradient-info btn-block mb-3' id='map-itinerary'>Map Itinerary</button>
|
|
||||||
</form>
|
|
||||||
<button type='button' class='btn bg-gradient-success btn-block mb-3' id='create-itinerary'>Create Itinerary</button>
|
<button type='button' class='btn bg-gradient-success btn-block mb-3' id='create-itinerary'>Create Itinerary</button>
|
||||||
<button type="button" class="btn btn-block btn-light mb-3" onclick="window.open('{{ path('app_case_add_address') }}', '_self')">Add Address</button>
|
<button type="button" class="btn btn-block btn-light mb-3" onclick="window.open('{{ path('app_case_add_address') }}', '_self')">Add Address</button>
|
||||||
</div>
|
</div>
|
||||||
@ -36,7 +32,6 @@
|
|||||||
<option value='{{ c.id }}'>{{ c.caseName }}</option>
|
<option value='{{ c.id }}'>{{ c.caseName }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<input type='date' id='date-filter'/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="table-responsive p-0">
|
<div class="table-responsive p-0">
|
||||||
<table class="table align-items-center mb-0">
|
<table class="table align-items-center mb-0">
|
||||||
@ -136,14 +131,13 @@
|
|||||||
import * as notify from "{{ asset('vendor/notify.js/notify.js.index.js') }}";
|
import * as notify from "{{ asset('vendor/notify.js/notify.js.index.js') }}";
|
||||||
|
|
||||||
import {filterAddressesByCase} from '{{ asset("js/app/filter.js") }}';
|
import {filterAddressesByCase} from '{{ asset("js/app/filter.js") }}';
|
||||||
import {createItinerary, addLocationToItinerary, openMap} from '{{ asset("js/app/itinerary.js") }}';
|
import {createItinerary, addLocationToItinerary} from '{{ asset("js/app/itinerary.js") }}';
|
||||||
window.$ = $;
|
window.$ = $;
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
document.getElementById('case-filter').addEventListener('change', filterAddressesByCase);
|
document.getElementById('case-filter').addEventListener('change', filterAddressesByCase);
|
||||||
document.getElementById('create-itinerary').addEventListener('click', createItinerary);
|
document.getElementById('create-itinerary').addEventListener('click', createItinerary);
|
||||||
document.getElementById('add-location-to-itinerary').addEventListener('click', addLocationToItinerary);
|
document.getElementById('add-location-to-itinerary').addEventListener('click', addLocationToItinerary);
|
||||||
document.getElementById('map-itinerary').addEventListener('click', openMap);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
92
templates/internal/cases/itinerary/report.html.twig
Normal file
92
templates/internal/cases/itinerary/report.html.twig
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{% 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">Travel Report</h6>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<form action='{{ path('app_map_itinerary') }}' method='post' id='map-form' style='display:inline;'>
|
||||||
|
<input type='hidden' name='caseId' id='caseId'/>
|
||||||
|
<input type='hidden' name='caseStartDate' id='startDate'/>
|
||||||
|
<input type='hidden' name='caseEndDate' id='endDate'/>
|
||||||
|
<button type='button' class='btn bg-gradient-info btn-block mb-3' id='map-itinerary'>Map Itinerary</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body px-0 pb-2">
|
||||||
|
<div class=''>
|
||||||
|
Filters:
|
||||||
|
<select id='case-filter'>
|
||||||
|
<option value=''>-- Select --</option>
|
||||||
|
|
||||||
|
{% for c in cases %}
|
||||||
|
<option value='{{ c.id }}'>{{ c.caseName }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<input type='date' id='start-date-filter'/>
|
||||||
|
<input type='date' id='end-date-filter'/>
|
||||||
|
</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">Date</th>
|
||||||
|
<th class='text-uppercase text-secondary text-xxs font-weight-bolder opacity-7'>Case</th>
|
||||||
|
<th class="text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">Origin</th>
|
||||||
|
<th class='text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7'>Destination</th>
|
||||||
|
<th class="text-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7">Duration</th>
|
||||||
|
<th class='test-center text-uppercase text-secondary text-xxs font-weight-bolder opacity-7'>Distance</th>
|
||||||
|
<th class="text-secondary opacity-7"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id='itineraryList'>
|
||||||
|
{% for i in itineraries %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ i.date|date('F j, Y') }}</td>
|
||||||
|
<td>{{ i.memberCase.caseName }}</td>
|
||||||
|
<td>{{ i.originLocation.name }}</td>
|
||||||
|
<td>{{ i.destLocation.name }}</td>
|
||||||
|
<td>{{ i.duration|date("%h:%i'%s''") }}</td>
|
||||||
|
<td>{{ i.distance }}</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_js %}
|
||||||
|
<script type='module'>
|
||||||
|
import $ from "{{ asset('vendor/jquery/jquery.index.js') }}";
|
||||||
|
import {filterItineraryByCase} from '{{ asset("js/app/filter.js") }}';
|
||||||
|
import {openMap} from '{{ asset("js/app/itinerary.js") }}';
|
||||||
|
window.$ = $;
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
document.getElementById('case-filter').addEventListener('change', filterItineraryByCase);
|
||||||
|
document.getElementById('start-date-filter').addEventListener('change', filterItineraryByCase);
|
||||||
|
document.getElementById('end-date-filter').addEventListener('change', filterItineraryByCase);
|
||||||
|
document.getElementById('map-itinerary').addEventListener('click', openMap);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
@ -41,7 +41,7 @@
|
|||||||
<i class="material-symbols-rounded">notifications</i>
|
<i class="material-symbols-rounded">notifications</i>
|
||||||
<span class='badge' {% if notificationCount == 0 %} style='display:none;' {% endif %}>{{ notificationCount }}</span>
|
<span class='badge' {% if notificationCount == 0 %} style='display:none;' {% endif %}>{{ notificationCount }}</span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu dropdown-menu-end px-2 py-3 me-sm-n4" aria-labelledby="dropdownMenuButton">
|
<ul class="dropdown-menu dropdown-menu-end px-2 py-3 me-sm-n4" aria-labelledby="dropdownMenuButton">
|
||||||
{% for note in notifications %}
|
{% for note in notifications %}
|
||||||
<li class='mb-2'>
|
<li class='mb-2'>
|
||||||
<a class='dropdown-item border-radius-md' href="javascript:openNotification('{{ note.id }}');">
|
<a class='dropdown-item border-radius-md' href="javascript:openNotification('{{ note.id }}');">
|
||||||
|
@ -36,6 +36,11 @@
|
|||||||
<input type='date' name='{{ field_name(form.date) }}' value='{{ field_value(form.date) }}' id='note_form_date' class='form-control'/>
|
<input type='date' name='{{ field_name(form.date) }}' value='{{ field_value(form.date) }}' id='note_form_date' class='form-control'/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class='input-group input-group-outline mb-3 is-filled'>
|
||||||
|
<label for='note_form_recommendations' class='form-label'>Recommendations</label>
|
||||||
|
<input type='text' name='note_form_recommendations' value='{{ note.recommendations }}' disabled='disabled' class='form-control'/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class='input-group input-group-outline mb-3'>
|
<div class='input-group input-group-outline mb-3'>
|
||||||
{{ form_row(form.servicesProvided) }}
|
{{ form_row(form.servicesProvided) }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,11 +17,14 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class='col'>
|
<div class='col'>
|
||||||
<div class='input-group input-group-outline mb-3'>
|
<div>
|
||||||
<p>Supervisor Signed:
|
<div>Supervisor:
|
||||||
{{ note.supervisorSignDateTime|date("F j, Y h:i a") }}</p>
|
{{ note.supervisorSignDateTime|date("F j, Y h:i a") }}</div>
|
||||||
<p>Case Worker Signed:
|
<div>Case Worker:
|
||||||
{{ note.workerSignDatetime|date("F j, Y h:i a") }}</p>
|
{% if note.workerSignDatetime %}
|
||||||
|
{{ note.workerSignDatetime|date("F j, Y h:i a") }}{% else %}Unsigned
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='input-group input-group-outline mb-3'>
|
<div class='input-group input-group-outline mb-3'>
|
||||||
|
Reference in New Issue
Block a user