feat: show due documents on teamer dashboard

This commit is contained in:
Björn Fromme
2024-01-29 18:27:38 +01:00
parent 26bb6d4f55
commit 92e3dde9b8
5 changed files with 150 additions and 64 deletions
@@ -45,6 +45,12 @@ class IndexController extends AbstractController
->getPendingForTeamer($teamer)
;
$currentDispositions = $this
->entityManager
->getRepository(Disposition::class)
->findCurrentDispositionsByTeamer($teamer)
;
$upcomingDispositions = $this
->entityManager
->getRepository(Disposition::class)
@@ -55,6 +61,7 @@ class IndexController extends AbstractController
'matchingAssignments' => $matchingAssignments,
'recentFeedback' => $recentFeedback,
'pendingApplications' => $pendingApplications,
'currentDispositions' => $currentDispositions,
'upcomingDispositions' => $upcomingDispositions,
]);
}
+32
View File
@@ -6,6 +6,8 @@ use App\Entity\Traits\BlameableEntity;
use App\Entity\Traits\SoftDeletableEntity;
use App\Entity\Traits\TimestampableEntity;
use App\Repository\DispositionRepository;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
@@ -187,4 +189,34 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf
return $this;
}
public function isContractDue(): bool
{
if (null !== $this->getDocumentByType(Upload::TYPE_CONTRACT)) {
return false;
}
$assignment = $this->getAssignment();
$assignmentPeriod = $assignment->getEffectivePeriod();
$dueDateFrom = $this->getCreatedAt()->modify('+ 7days');
$dueDateTo = $assignmentPeriod->end->modify('-1 day');
$period = CarbonPeriod::create($dueDateFrom, $dueDateTo);
return $period->isStarted();
}
public function isInvoiceDue(): bool
{
if (null !== $this->getDocumentByType(Upload::TYPE_INVOICE)) {
return false;
}
$assignment = $this->getAssignment();
$assignmentPeriod = $assignment->getEffectivePeriod();
$period = CarbonPeriod::create($assignmentPeriod->getEndDate(), $assignmentPeriod->getEndDate()->modify('+14 days'));
return $period->isStarted();
}
}
+23
View File
@@ -124,6 +124,29 @@ class DispositionRepository extends ServiceEntityRepository
;
}
public function findCurrentDispositionsByTeamer(Teamer $teamer): array
{
$qb = $this->createQueryBuilder('disposition');
return $qb
->select('disposition', 'assignment', 'destination')
->innerJoin('disposition.assignment', 'assignment')
->innerJoin('assignment.destination', 'destination')
->where($qb->expr()->andX(
$qb->expr()->eq('disposition.teamer', ':teamer'),
$qb->expr()->in('disposition.status', ':status')
))
->setParameter('teamer', $teamer)
->setParameter('status', [
Disposition::STATUS_NEW,
Disposition::STATUS_CONFIRMED,
])
->orderBy('destination.dateFrom', 'ASC')
->getQuery()
->getResult()
;
}
public function findNewDispositionsByHotelBusProIds(array $hotelBusProIds): array
{
$qb = $this->createQueryBuilder('disposition');
+31 -23
View File
@@ -15,15 +15,18 @@
{% for application in applications %}
{% set assignment = application.assignment %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_admin_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}" class="flex items-center space-x-1 truncate">
{{ icon('hand', 'w-4 h-4 shrink-0') }}
<span class="whitespace-nowrap">{{ application.teamer.fullName(true) }}</span>
{% include '_partials/_dot.html.twig' %}
<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.destination.hotel }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ assignment.jobProfile.name }}</span>
<a href="{{ path('app_admin_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}">
<div class="flex items-center space-x-1">
{{ icon('hand', 'w-4 h-4 shrink-0') }}
<div class="flex items-center space-x-1 truncate">
<span class="whitespace-nowrap">{{ application.teamer.fullName(true) }}</span>
{% include '_partials/_dot.html.twig' %}
<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.destination.hotel }}</span>
</div>
</div>
<div class="pl-5 whitespace-nowrap">{{ assignment.jobProfile.name }}</div>
</a>
</li>
{% else %}
@@ -71,13 +74,16 @@
<ul class="divide-y divide-gray-200">
{% for assignment in assignments %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_admin_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}" class="flex items-center space-x-1 truncate">
{{ icon('calendar', 'w-4 h-4 shrink-0') }}
<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>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ assignment.owner.fullName(true) }}</span>
<a href="{{ path('app_admin_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">{{ assignment.owner.fullName(true) }}</div>
</a>
</li>
{% else %}
@@ -121,18 +127,20 @@
{% for feedback in feedbacks %}
<li class="py-2 first:pt-0 last:pb-0">
<button type="button"
class="flex items-center space-x-1 truncate"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Feedback freigeben',
'url': path('app_admin_feedback_approve', { 'uuid': feedback.uuid })
}) }}>
{{ icon('feedback', 'w-4 h-4 shrink-0') }}
<span class="whitespace-nowrap">{{ feedback.teamer }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.destinationName }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.jobProfileName }}</span>
<div class="flex items-center space-x-1">
{{ icon('feedback', 'w-4 h-4 shrink-0') }}
<div class="flex items-center space-x-1 truncate">
<span class="whitespace-nowrap">{{ feedback.teamer }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.destinationName }}</span>
</div>
</div>
<div class="pl-5 whitespace-nowrap">{{ feedback.jobProfileName }}</div>
</button>
</li>
{% else %}
+57 -41
View File
@@ -17,13 +17,16 @@
{% for application in pendingApplications %}
{% set assignment = application.assignment %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_teamer_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}" class="flex items-center space-x-1 truncate">
{{ icon('hand', 'w-4 h-4 shrink-0') }}
<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.destination.hotel }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ assignment.jobProfile.name }}</span>
<a href="{{ path('app_teamer_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}">
<div class="flex items-center space-x-1">
{{ icon('hand', '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.destination.hotel }}</span>
</div>
</div>
<div class="pl-5 whitespace-nowrap">{{ assignment.jobProfile.name }}</div>
</a>
</li>
{% else %}
@@ -38,17 +41,23 @@
Meine Dokumente
</h2>
<ul class="divide-y divide-gray-200">
{% for disposition in upcomingDispositions %}
{% for document in disposition.assignment.documents %}
{% if is_granted('DOWNLOAD', document) %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_common_download', { 'uuid': document.uuid }) }}" class="flex items-center space-x-1 truncate" target="_blank">
{{ icon('download', 'w-4 h-4 shrink-0') }}
<span class="whitespace-nowrap">{{ document.displayName|default(document.originalFilename) }}</span>
</a>
</li>
{% endif %}
{% endfor %}
{% for disposition in currentDispositions %}
{% set assignment = disposition.assignment %}
{% if disposition.contractDue or disposition.invoiceDue %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_teamer_disposition_detail', { 'uuid': disposition.uuid }) }}">
<div class="flex items-center space-x-1">
{{ icon('alert', '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.destination.hotel }}</span>
</div>
</div>
<div class="pl-5 whitespace-nowrap">{% if disposition.contractDue %}Honorarvertrag{% else %}Honorarnote{% endif %} fällig</div>
</a>
</li>
{% endif %}
{% else %}
<li class="py-2 first:pt-0 last:pb-0">
-
@@ -63,20 +72,23 @@
<ul class="divide-y divide-gray-200">
{% for feedback in recentFeedback %}
<li class="py-2 first:pt-0 last:pb-0">
<button type="button" class="flex items-center space-x-1 truncate"
<button type="button"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, {
'title': feedback.destinationName ~ ' ' ~ feedback.assignmentDate|date('m.Y'),
'url': path('app_teamer_feedback', { 'uuid': feedback.uuid })
}) }}>
{{ icon('feedback', 'w-4 h-4 shrink-0') }}
<span class="whitespace-nowrap">{{ feedback.createdAt|date('d.m.y') }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.author }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.averageRating|format_rating }}</span>
{% include '_partials/_dot.html.twig' %}
<span>{{ feedback.comment }}</span>
<div class="flex items-center space-x-1">
{{ icon('feedback', 'w-4 h-4 shrink-0') }}
<div class="flex items-center space-x-1 truncate">
<span class="whitespace-nowrap">{{ feedback.createdAt|date('d.m.y') }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.author }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ feedback.averageRating|format_rating }}</span>
</div>
</div>
<div class="pl-5">{{ feedback.comment }}</div>
</button>
</li>
{% else %}
@@ -94,13 +106,16 @@
{% for disposition in upcomingDispositions %}
{% set assignment = disposition.assignment %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_teamer_disposition_detail', { 'uuid': disposition.uuid }) }}" class="flex items-center space-x-1 truncate">
{{ icon('hand', 'w-4 h-4 shrink-0') }}
<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.destination.hotel }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ assignment.jobProfile.name }}</span>
<a href="{{ path('app_teamer_disposition_detail', { 'uuid': disposition.uuid }) }}">
<div class="flex items-center space-x-1">
{{ icon('check', '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.destination.hotel }}</span>
</div>
</div>
<div class="pl-5 whitespace-nowrap">{{ assignment.jobProfile.name }}</div>
</a>
</li>
{% else %}
@@ -117,13 +132,14 @@
<ul class="divide-y divide-gray-200">
{% for assignment in matchingAssignments %}
<li class="py-2 first:pt-0 last:pb-0">
<a href="{{ path('app_teamer_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}" class="flex items-center space-x-1 truncate">
{{ icon('calendar', 'w-4 h-4 shrink-0') }}
<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.destination.hotel }}</span>
{% include '_partials/_dot.html.twig' %}
<span class="whitespace-nowrap">{{ assignment.jobProfile.name }}</span>
<a href="{{ path('app_teamer_assignment_detail', { 'uuid': assignment.uuid, 'r': return_url() }) }}">
<div class="flex items-center space-x-1 truncate">
{{ icon('calendar', 'w-4 h-4 shrink-0') }}
<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.destination.hotel }}</span>
</div>
<div class="pl-5 whitespace-nowrap">{{ assignment.jobProfile.name }}</div>
</a>
</li>
{% else %}