WIP: Implement application process

This commit is contained in:
Björn Fromme
2023-10-10 17:50:50 +02:00
parent 6910ab6134
commit 7084e1528e
11 changed files with 225 additions and 6 deletions
@@ -0,0 +1,49 @@
<?php
namespace App\Controller\Teamer\Application;
use App\Entity\User;
use App\Repository\ApplicationRepository;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController
{
public function __construct(
private readonly ApplicationRepository $applicationRepository,
private readonly PaginatorInterface $paginator
) {
}
#[Route('/teamer/application/pending', name: 'app_teamer_application_index')]
#[IsGranted('ROLE_TEAMER')]
public function index(Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
$teamer = $user->getTeamer();
$query = $this
->applicationRepository
->getPendingForTeamerQuery($teamer)
;
$pagination = $this->paginator->paginate(
$query,
$request->query->getInt('page', 1),
10,
[
'defaultSortFieldName' => 'assignment.dateFrom',
'defaultSortDirection' => 'asc',
]
);
return $this->render('teamer/application/index.html.twig', [
'pagination' => $pagination,
]);
}
}
@@ -2,20 +2,25 @@
namespace App\Controller\Teamer\Disposition;
use App\Controller\Traits\ReturnUrlTrait;
use App\Entity\Disposition;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class DetailController extends AbstractController
{
use ReturnUrlTrait;
#[Route('/teamer/disposition/detail/{uuid}', name: 'app_teamer_disposition_detail')]
#[IsGranted('VIEW', subject: 'disposition')]
public function index(Disposition $disposition): Response
public function index(Disposition $disposition, Request $request): Response
{
return $this->render('teamer/disposition/detail.html.twig', [
'disposition' => $disposition,
'returnUrl' => $this->getReturnUrl($request, 'app_teamer_index'),
]);
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Controller\Teamer\Document;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController
{
#[Route('/teamer/document', name: 'app_teamer_document_index')]
#[IsGranted('ROLE_TEAMER')]
public function index(): Response
{
return $this->render('');
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Controller\Teamer\Feedback;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController
{
#[Route('/teamer/feedback', name: 'app_teamer_feedback_index')]
#[IsGranted('ROLE_TEAMER')]
public function index(): Response
{
return $this->render('');
}
}
+4
View File
@@ -17,10 +17,14 @@ class Upload implements BlameableEntityInterface, TimestampableEntityInterface
public const TYPE_PHOTO = 'photo';
public const TYPE_CERTIFICATE = 'certificate';
public const TYPE_CONTRACT = 'contract';
public const TYPE_INVOICE = 'invoice';
public const STATUS_NEW = 'new';
public const STATUS_IN_PROCESS = 'in_process';
public const STATUS_CHECKED = 'checked';
public const STATUS_PAYED = 'payed';
public const STATUS_ERROR = 'error';
#[ORM\Id]
#[ORM\GeneratedValue]
+4 -4
View File
@@ -45,13 +45,13 @@ class TeamerMenuBuilder extends AbstractMenuBuilder
'route' => false,
'title' => 'Meine Einsätze',
'icon' => 'bus',
'children' => [
'children' => [#
[
'route' => 'app_teamer_bookmark_index',
'title' => 'Merkliste',
],
[
'route' => 'app_teamer_bookmark_index',
'route' => 'app_teamer_application_index',
'title' => 'Offene Bewerbungen',
],
[
@@ -63,11 +63,11 @@ class TeamerMenuBuilder extends AbstractMenuBuilder
'title' => 'Letzte Einsätze',
],
[
'route' => 'app_teamer_bookmark_index',
'route' => 'app_teamer_document_index',
'title' => 'Meine Dokumente',
],
[
'route' => 'app_teamer_bookmark_index',
'route' => 'app_teamer_feedback_index',
'title' => 'Mein Feedback',
],
],
+16
View File
@@ -3,6 +3,7 @@
namespace App\Repository;
use App\Entity\Application;
use App\Entity\Teamer;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query;
use Doctrine\Persistence\ManagerRegistry;
@@ -35,4 +36,19 @@ class ApplicationRepository extends ServiceEntityRepository
->getQuery()
;
}
public function getPendingForTeamerQuery(Teamer $teamer): Query
{
$qb = $this->createQueryBuilder('application');
return $qb
->select('application', 'assignment', 'destination', 'job_profile')
->innerJoin('application.assignment', 'assignment')
->innerJoin('assignment.destination', 'destination')
->innerJoin('assignment.jobProfile', 'job_profile')
->where($qb->expr()->eq('application.teamer', ':teamer'))
->setParameter('teamer', $teamer)
->getQuery()
;
}
}
+3 -1
View File
@@ -57,7 +57,9 @@
{{ application.teamer }}
</td>
<td>
<button type="button" class="btn">
Welche Funktion?
</button>
</td>
</tr>
{% else %}
@@ -0,0 +1,85 @@
{% extends 'teamer/layout.html.twig' %}
{% block title %}Meine Bewerbungen{% endblock %}
{% block content %}
<h1 class="text-2xl font-bold pb-8">
Meine offenen Bewerbungen
</h1>
<div class="data-table-wrapper">
<div class="data-table-wrapper__inner">
<table class="data-table">
<thead>
<tr>
<th>
{{ knp_pagination_sortable(pagination, 'Einsatz&shy;beginn', 'assignment.dateFrom') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Einsatz&shy;ende', 'assignment.dateTo') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Jobprofil', 'assignment.jobProfile') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Destination', 'destination.dateFrom') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Busbegleitung', 'assignment.pickup') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Status', 'application.status') }}
</th>
<th></th>
</tr>
</thead>
<tbody>
{% for application in pagination %}
{% set assignment = application.assignment %}
<tr>
<td>
{% set dateFrom = assignment.dateFrom ? assignment.dateFrom : assignment.destination.dateFrom %}
{{ dateFrom|date('d.m.Y') }}
</td>
<td>
{% set dateTo = assignment.dateTo ? assignment.dateTo : assignment.destination.dateTo %}
{{ dateTo|date('d.m.Y') }}
</td>
<td>
{{ assignment.jobProfile.name }}
</td>
<td>
{{ assignment.destination.product }}
<br>
{{ assignment.destination.hotel }}
</td>
<td>
{{ assignment.pickup ? assignment.pickup|bpn_pickup_label|default('-') : '-' }}
<br>
{{ assignment.pickupDate ? assignment.pickupDate|date('d.m.Y') : '' }}
</td>
<td>
{{ ('label.application.status.' ~ application.status)|trans }}
</td>
<td>
<div class="flex items-center space-x-1 justify-end">
<a href="{{ path('app_teamer_assignment', { 'uuid': assignment.uuid, 'r': return_url() }) }}">
{{ icon('info', 'w-5 h-5') }}
</a>
</div>
</td>
</tr>
{% else %}
<tr>
<td colspan="6">
<div class="text-center">
Keine Daten
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ knp_pagination_render(pagination) }}
</div>
</div>
{% endblock %}
@@ -20,6 +20,9 @@
<br>
{{ assignment.contact }}, <a href="mailto:{{ assignment.contact.email }}" class="underline">{{ assignment.contact.email }}</a>
</p>
<a href="{{ returnUrl }}" class="underline">
zurück
</a>
</div>
</div>
{% endblock %}
+19
View File
@@ -1,3 +1,22 @@
label:
application:
status:
new: neu
pending: in Bearbeitung
rejected: abgelehnt
document:
type:
invoice: Honorarnote
contract: Honorarvertrag
certificate: Lizenznachweis
photo: Foto
status:
new: neu
in_process: in Bearbeitung
checked: geprüft
payed: bezahlt
error: Fehler
uploader:
drop_files: Dateien hier ablegen oder
click_here: hier klicken