feat: show overdue contracts on admin dashboard

This commit is contained in:
Björn Fromme
2024-07-01 12:54:18 +02:00
parent c5688c84bb
commit 0eb3d6ab3d
3 changed files with 75 additions and 22 deletions
+22 -22
View File
@@ -3,13 +3,12 @@
namespace App\Controller\Admin; namespace App\Controller\Admin;
use App\Entity\Application; use App\Entity\Application;
use App\Entity\Assignment;
use App\Entity\Availability;
use App\Entity\Disposition;
use App\Entity\Feedback; use App\Entity\Feedback;
use App\Entity\Upload; use App\Entity\Upload;
use App\Repository\ApplicationRepository; use Doctrine\ORM\EntityManagerInterface;
use App\Repository\AssignmentRepository;
use App\Repository\AvailabilityRepository;
use App\Repository\FeedbackRepository;
use App\Repository\UploadRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
@@ -17,33 +16,33 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController class IndexController extends AbstractController
{ {
public function __construct( public function __construct(private readonly EntityManagerInterface $entityManager)
private readonly ApplicationRepository $applicationRepository, {
private readonly FeedbackRepository $feedbackRepository,
private readonly AssignmentRepository $assignmentRepository,
private readonly AvailabilityRepository $availabilityRepository,
private readonly UploadRepository $uploadRepository
) {
} }
#[Route('/admin', name: 'app_admin_index')] #[Route('/admin', name: 'app_admin_index')]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMIN')]
public function index(): Response public function index(): Response
{ {
$applications = $this->applicationRepository->getNew(); $applicationRepository = $this->entityManager->getRepository(Application::class);
$newApplicationsCount = $this->applicationRepository->getCountByStatus(Application::STATUS_NEW); $applications = $applicationRepository->getNew();
$pendingApplicationsCount = $this->applicationRepository->getCountByStatus(Application::STATUS_PENDING); $newApplicationsCount = $applicationRepository->getCountByStatus(Application::STATUS_NEW);
$pendingApplicationsCount = $applicationRepository->getCountByStatus(Application::STATUS_PENDING);
$feedbacks = $this->feedbackRepository->getNew(); $feedbackRepository = $this->entityManager->getRepository(Feedback::class);
$pendingFeedbacksCount = $this->feedbackRepository->getCountByStatus(Feedback::STATUS_NEW); $feedbacks = $feedbackRepository->getNew();
$pendingFeedbacksCount = $feedbackRepository->getCountByStatus(Feedback::STATUS_NEW);
$assignments = $this->assignmentRepository->getNew(); $assignments = $this->entityManager->getRepository(Assignment::class)->getNew();
$availabilities = $this->availabilityRepository->getNew(); $availabilities = $this->entityManager->getRepository(Availability::class)->getNew();
$documents = $this->uploadRepository->getNew(); $uploadRepository = $this->entityManager->getRepository(Upload::class);
$newDocumentsCount = $this->uploadRepository->getCountByStatus(Upload::STATUS_NEW); $documents = $uploadRepository->getNew();
$pendingDocumentsCount = $this->uploadRepository->getCountByStatus(Upload::STATUS_PENDING); $newDocumentsCount = $uploadRepository->getCountByStatus(Upload::STATUS_NEW);
$pendingDocumentsCount = $uploadRepository->getCountByStatus(Upload::STATUS_PENDING);
$overdueContracts = $this->entityManager->getRepository(Disposition::class)->findOverdueContracts();
return $this->render('admin/index.html.twig', [ return $this->render('admin/index.html.twig', [
'applications' => $applications, 'applications' => $applications,
@@ -56,6 +55,7 @@ class IndexController extends AbstractController
'documents' => $documents, 'documents' => $documents,
'newDocumentsCount' => $newDocumentsCount, 'newDocumentsCount' => $newDocumentsCount,
'pendingDocumentsCount' => $pendingDocumentsCount, 'pendingDocumentsCount' => $pendingDocumentsCount,
'overdueContracts' => $overdueContracts,
]); ]);
} }
} }
+26
View File
@@ -5,8 +5,10 @@ namespace App\Repository;
use App\Entity\Assignment; use App\Entity\Assignment;
use App\Entity\Disposition; use App\Entity\Disposition;
use App\Entity\Teamer; use App\Entity\Teamer;
use App\Entity\Upload;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
/** /**
@@ -263,4 +265,28 @@ class DispositionRepository extends ServiceEntityRepository
->getResult() ->getResult()
; ;
} }
public function findOverdueContracts(): array
{
$dueDate = (new \DateTimeImmutable())->modify('-7 days');
$qb = $this->createQueryBuilder('disposition');
return $qb
->select('disposition', 'assignment', 'destination', 'document')
->innerJoin('disposition.assignment', 'assignment')
->innerJoin('assignment.destination', 'destination')
->leftJoin('disposition.documents', 'document', Join::WITH, 'document.type = :documentType')
->where($qb->expr()->andX(
$qb->expr()->lte('disposition.createdAt', ':dueDate'),
$qb->expr()->eq('disposition.status', ':status'),
$qb->expr()->isNull('document')
))
->setParameter('documentType', Upload::TYPE_CONTRACT)
->setParameter('dueDate', $dueDate)
->setParameter('status', Disposition::STATUS_CONFIRMED)
->getQuery()
->getResult()
;
}
} }
+27
View File
@@ -147,5 +147,32 @@
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<div class="bg-gray-100 border border-gray-200 rounded-md px-4 py-2">
<h2 class="font-bold text-lg pb-2">
Überfällige Honorarverträge
</h2>
<ul class="divide-y divide-gray-200">
{% for disposition in overdueContracts %}
{% set assignment = disposition.assignment %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_administrative_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}">
<div class="flex items-center space-x-1">
{{ icon('calendar', 'w-4 h-4 shrink-0') }}
<div class="flex items-center space-x-1 truncate">
<span class="whitespace-nowrap">{{ assignment.effectivePeriod.start|date('d.m.y') }} - {{ assignment.effectivePeriod.end|date('d.m.y') }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ assignment.jobProfile.name }}</span>
</div>
</div>
<div class="pl-5 whitespace-nowrap">{{ disposition.teamer.fullName(true) }}</div>
</a>
</li>
{% else %}
<li class="py-2 first:pt-0 last:pb-0">
-
</li>
{% endfor %}
</ul>
</div>
</div> </div>
{% endblock %} {% endblock %}