Task: Misc adjustments

This commit is contained in:
Björn Fromme
2023-10-25 15:22:38 +02:00
parent 3e540e215d
commit 011f1faf0f
20 changed files with 125 additions and 57 deletions
+35
View File
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231025131443 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE application DROP FOREIGN KEY FK_A45BDDC1DF01D017');
$this->addSql('DROP INDEX IDX_A45BDDC1DF01D017 ON application');
$this->addSql('ALTER TABLE application ADD comment_visible TINYINT(1) NOT NULL, DROP remarks_by_id, CHANGE remarks comment LONGTEXT DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE application ADD remarks_by_id INT DEFAULT NULL, DROP comment_visible, CHANGE comment remarks LONGTEXT DEFAULT NULL');
$this->addSql('ALTER TABLE application ADD CONSTRAINT FK_A45BDDC1DF01D017 FOREIGN KEY (remarks_by_id) REFERENCES user (id)');
$this->addSql('CREATE INDEX IDX_A45BDDC1DF01D017 ON application (remarks_by_id)');
}
}
@@ -4,9 +4,9 @@ namespace App\Controller\Admin\Application;
use App\Entity\Application; use App\Entity\Application;
use App\Event\ApplicationStatusEvent; use App\Event\ApplicationStatusEvent;
use App\Form\ApplicationCheckType; use App\Form\ApplicationStatusType;
use App\Model\AjaxModalResponseDto; use App\Model\AjaxModalResponseDto;
use App\Model\ApplicationCheckDto; use App\Model\ApplicationStatusDto;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -32,20 +32,24 @@ class StatusController extends AbstractController
{ {
$response = new AjaxModalResponseDto(); $response = new AjaxModalResponseDto();
$formAction = $this->generateUrl('app_admin_application_status', ['uuid' => $application->getUuid()]); $formAction = $this->generateUrl('app_admin_application_status', ['uuid' => $application->getUuid()]);
$formData = new ApplicationCheckDto($application); $statusDto = new ApplicationStatusDto($application);
$form = $this->createForm(ApplicationCheckType::class, $formData, ['action' => $formAction, 'ajax_submit' => true]); $form = $this->createForm(ApplicationStatusType::class, $statusDto, ['action' => $formAction, 'ajax_submit' => true]);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->eventDispatcher->dispatch(new ApplicationStatusEvent($formData), ApplicationStatusEvent::NAME); $this->eventDispatcher->dispatch(new ApplicationStatusEvent($statusDto), ApplicationStatusEvent::NAME);
$application->setStatus($formData->getStatus()); $application
->setStatus($statusDto->getStatus())
->setComment($statusDto->getComment())
->setCommentVisible($statusDto->isCommentVisible())
;
$this->entityManager->flush(); $this->entityManager->flush();
$this->addFlash('success', 'Der Status der Bewerbung wurde aktualisiert'); $this->addFlash('success', 'Der Status der Bewerbung wurde aktualisiert');
$this->logger->info('Update application status', [ $this->logger->info('Update application status', [
'application_id' => $application->getId(), 'application_id' => $application->getId(),
'status_new' => $formData->getStatus(), 'status_new' => $statusDto->getStatus(),
'teamer' => (string) $application->getTeamer(), 'teamer' => (string) $application->getTeamer(),
]); ]);
+19 -19
View File
@@ -38,10 +38,10 @@ class Application implements TimestampableEntityInterface
private ?string $status; private ?string $status;
#[ORM\Column(type: Types::TEXT, nullable: true)] #[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $remarks = null; private ?string $comment = null;
#[ORM\ManyToOne] #[ORM\Column]
private ?User $remarksBy = null; private ?bool $commentVisible = false;
public function __construct(Assignment $assignment, Teamer $teamer) public function __construct(Assignment $assignment, Teamer $teamer)
{ {
@@ -109,18 +109,6 @@ class Application implements TimestampableEntityInterface
return $this; return $this;
} }
public function getRemarks(): ?string
{
return $this->remarks;
}
public function setRemarks(?string $remarks): static
{
$this->remarks = $remarks;
return $this;
}
public function matchesPickup(): bool public function matchesPickup(): bool
{ {
if (0 === $pickupId = (int) $this->getAssignment()->getPickup()) { if (0 === $pickupId = (int) $this->getAssignment()->getPickup()) {
@@ -147,14 +135,26 @@ class Application implements TimestampableEntityInterface
return $count === $requiredTrainings->count(); return $count === $requiredTrainings->count();
} }
public function getRemarksBy(): ?User public function getComment(): ?string
{ {
return $this->remarksBy; return $this->comment;
} }
public function setRemarksBy(?User $remarksBy): static public function setComment(?string $comment): static
{ {
$this->remarksBy = $remarksBy; $this->comment = $comment;
return $this;
}
public function isCommentVisible(): ?bool
{
return $this->commentVisible;
}
public function setCommentVisible(bool $commentVisible): static
{
$this->commentVisible = $commentVisible;
return $this; return $this;
} }
-1
View File
@@ -54,7 +54,6 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf
$this->status = static::STATUS_NEW; $this->status = static::STATUS_NEW;
$this->assignment = $application->getAssignment(); $this->assignment = $application->getAssignment();
$this->teamer = $application->getTeamer(); $this->teamer = $application->getTeamer();
$this->remarks = $application->getRemarks();
$this->documents = new ArrayCollection(); $this->documents = new ArrayCollection();
} }
+2 -2
View File
@@ -3,7 +3,7 @@
namespace App\Event; namespace App\Event;
use App\Entity\Application; use App\Entity\Application;
use App\Model\ApplicationCheckDto; use App\Model\ApplicationStatusDto;
use Symfony\Contracts\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\Event;
class ApplicationStatusEvent extends Event class ApplicationStatusEvent extends Event
@@ -13,7 +13,7 @@ class ApplicationStatusEvent extends Event
private Application $application; private Application $application;
private ?string $comment; private ?string $comment;
public function __construct(ApplicationCheckDto $applicationCheckDto) public function __construct(ApplicationStatusDto $applicationCheckDto)
{ {
$this->application = $applicationCheckDto->getApplication(); $this->application = $applicationCheckDto->getApplication();
$this->comment = $applicationCheckDto->getComment(); $this->comment = $applicationCheckDto->getComment();
@@ -3,14 +3,15 @@
namespace App\Form; namespace App\Form;
use App\Entity\Application; use App\Entity\Application;
use App\Model\ApplicationCheckDto; use App\Model\ApplicationStatusDto;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
class ApplicationCheckType extends AbstractType class ApplicationStatusType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options): void public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
@@ -29,13 +30,17 @@ class ApplicationCheckType extends AbstractType
'rows' => 3, 'rows' => 3,
], ],
]) ])
->add('commentVisible', CheckboxType::class, [
'label' => 'Kommentar/Begründung sichtbar für Teamer:in',
'required' => false,
])
; ;
} }
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => ApplicationCheckDto::class, 'data_class' => ApplicationStatusDto::class,
]); ]);
} }
} }
+1 -1
View File
@@ -86,7 +86,7 @@ class AssignmentType extends AbstractType
'expanded' => true, 'expanded' => true,
]) ])
->add('contact', EntityType::class, [ ->add('contact', EntityType::class, [
'label' => 'Ansprechpartner RM', 'label' => 'Ansprechperson für den Einsatz',
'class' => User::class, 'class' => User::class,
'choice_label' => 'fullName', 'choice_label' => 'fullName',
'query_builder' => function (EntityRepository $repository) { 'query_builder' => function (EntityRepository $repository) {
+2 -2
View File
@@ -92,8 +92,8 @@ abstract class AbstractMenuBuilder
{ {
if ($this->security->isGranted('ROLE_TEAMER')) { if ($this->security->isGranted('ROLE_TEAMER')) {
$menu $menu
->addChild('zum Teamerbereich', ['route' => 'app_teamer_index']) ->addChild('zum Teamer:innenbereich', ['route' => 'app_teamer_index'])
->setChildrenAttribute('title', 'zum Teamerbereich') ->setChildrenAttribute('title', 'zum Teamer:innenbereich')
->setExtra('icon', 'user') ->setExtra('icon', 'user')
; ;
} }
+1 -1
View File
@@ -39,7 +39,7 @@ class AdminMenuBuilder extends AbstractMenuBuilder
], ],
[ [
'route' => 'app_admin_teamer_index', 'route' => 'app_admin_teamer_index',
'title' => 'Teamerübersicht', 'title' => 'Teamer:innenübersicht',
'icon' => 'users', 'icon' => 'users',
'hideChildren' => true, 'hideChildren' => true,
'children' => $this->getTeamerMenuItems(), 'children' => $this->getTeamerMenuItems(),
@@ -4,16 +4,19 @@ namespace App\Model;
use App\Entity\Application; use App\Entity\Application;
class ApplicationCheckDto class ApplicationStatusDto
{ {
private Application $application; private Application $application;
private string $status; private string $status;
private ?string $comment = null; private ?string $comment;
private bool $commentVisible;
public function __construct(Application $application) public function __construct(Application $application)
{ {
$this->application = $application; $this->application = $application;
$this->status = $application->getStatus(); $this->status = $application->getStatus();
$this->comment = $application->getComment();
$this->commentVisible = $application->isCommentVisible();
} }
public function getApplication(): Application public function getApplication(): Application
@@ -44,4 +47,16 @@ class ApplicationCheckDto
return $this; return $this;
} }
public function isCommentVisible(): bool
{
return $this->commentVisible;
}
public function setCommentVisible(bool $commentVisible): static
{
$this->commentVisible = $commentVisible;
return $this;
}
} }
+2 -2
View File
@@ -28,10 +28,10 @@ class AppRuntime implements RuntimeExtensionInterface
public function teamerStatusLabel(string $status): string public function teamerStatusLabel(string $status): string
{ {
if (Teamer::STATUS_NEW === $status) { if (Teamer::STATUS_NEW === $status) {
return 'Neuteamer'; return 'Neuteamer:in';
} }
return 'Bestandsteamer'; return 'Bestandsteamer:in';
} }
public function licenseLabel(string $type): string public function licenseLabel(string $type): string
+2 -2
View File
@@ -24,7 +24,7 @@
{{ knp_pagination_sortable(pagination, 'Bus', 'destination.pickup') }} {{ knp_pagination_sortable(pagination, 'Bus', 'destination.pickup') }}
</th> </th>
<th> <th>
{{ knp_pagination_sortable(pagination, 'Bewerber*in', 'teamer.lastName') }} {{ knp_pagination_sortable(pagination, 'Bewerber:in', 'teamer.lastName') }}
</th> </th>
<th></th> <th></th>
</tr> </tr>
@@ -74,7 +74,7 @@
aria-label="Bewerber:innen-Info anzeigen" aria-label="Bewerber:innen-Info anzeigen"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }} {{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', 'click', { {{ stimulus_action('modal-button', 'ajax', 'click', {
'title': 'Teeamer-Info ' ~ application.teamer, 'title': 'Teamer:innen-Info ' ~ application.teamer,
'url': path('app_admin_application_info', { 'uuid': application.uuid }) 'url': path('app_admin_application_info', { 'uuid': application.uuid })
}) }}> }) }}>
{% if assignment.pickup %} {% if assignment.pickup %}
@@ -2,6 +2,7 @@
<div class="flex flex-col space-y-4 pb-4"> <div class="flex flex-col space-y-4 pb-4">
{{ form_row(form.status) }} {{ form_row(form.status) }}
{{ form_row(form.comment) }} {{ form_row(form.comment) }}
{{ form_row(form.commentVisible) }}
</div> </div>
<button type="submit" class="btn"> <button type="submit" class="btn">
Aktualisieren Aktualisieren
+3 -3
View File
@@ -38,7 +38,7 @@
class="flex items-center space-x-1" class="flex items-center space-x-1"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }} {{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, { {{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Teamerinfo ' ~ application.teamer, 'title': 'Teamer:inneninfo ' ~ application.teamer,
'url': path('app_admin_teamer_info', { 'uuid': application.teamer.uuid }) 'url': path('app_admin_teamer_info', { 'uuid': application.teamer.uuid })
}) }}> }) }}>
<span>{{ application.teamer }}</span> <span>{{ application.teamer }}</span>
@@ -59,7 +59,7 @@
{{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }} {{ stimulus_controller('modal-button', [], [], {'confirmation-modal': '#confirmation-modal'}) }}
{{ stimulus_action('modal-button', 'confirmation', null, { {{ stimulus_action('modal-button', 'confirmation', null, {
'title': 'Bist du sicher?', 'title': 'Bist du sicher?',
'content': 'Möchtest du den Teamer ' ~ application.teamer ~ ' wirklich einteilen?', 'content': 'Möchtest du den/die Teamer:in ' ~ application.teamer ~ ' wirklich einteilen?',
'target-url': path('app_admin_application_dispose', { 'uuid': application.uuid }) 'target-url': path('app_admin_application_dispose', { 'uuid': application.uuid })
}) }}> }) }}>
einteilen einteilen
@@ -128,7 +128,7 @@
class="flex items-center space-x-1" class="flex items-center space-x-1"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }} {{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, { {{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Teamerinfo ' ~ disposition.teamer, 'title': 'Teamer:inneninfo ' ~ disposition.teamer,
'url': path('app_admin_teamer_info', { 'uuid': disposition.teamer.uuid }) 'url': path('app_admin_teamer_info', { 'uuid': disposition.teamer.uuid })
}) }}> }) }}>
<span>{{ disposition.teamer }}</span> <span>{{ disposition.teamer }}</span>
+1 -1
View File
@@ -24,7 +24,7 @@
{{ knp_pagination_sortable(pagination, 'Dokument', 'upload.type') }} {{ knp_pagination_sortable(pagination, 'Dokument', 'upload.type') }}
</th> </th>
<th> <th>
{{ knp_pagination_sortable(pagination, 'Teamer', 'teamer.lastName') }} {{ knp_pagination_sortable(pagination, 'Teamer:in', 'teamer.lastName') }}
</th> </th>
<th> <th>
{{ knp_pagination_sortable(pagination, 'Status', 'disposition.status') }} {{ knp_pagination_sortable(pagination, 'Status', 'disposition.status') }}
+2
View File
@@ -25,6 +25,8 @@
{{ _self.dot() }} {{ _self.dot() }}
<span class="whitespace-nowrap">{{ assignment.effectivePeriod.start|date('d.m.y') }} - {{ assignment.effectivePeriod.end|date('d.m.y') }}</span> <span class="whitespace-nowrap">{{ assignment.effectivePeriod.start|date('d.m.y') }} - {{ assignment.effectivePeriod.end|date('d.m.y') }}</span>
{{ _self.dot() }} {{ _self.dot() }}
<span class="whitespace-nowrap">{{ assignment.destination.hotel }}</span>
{{ _self.dot() }}
<span class="whitespace-nowrap">{{ assignment.jobProfile.name }}</span> <span class="whitespace-nowrap">{{ assignment.jobProfile.name }}</span>
</a> </a>
</li> </li>
+4 -4
View File
@@ -1,18 +1,18 @@
{% extends 'admin/layout.html.twig' %} {% extends 'admin/layout.html.twig' %}
{% block title %}Teamerübersicht{% endblock %} {% block title %}Teamer:innenübersicht{% endblock %}
{% block content %} {% block content %}
<div class="flex items-start justify-between pb-4"> <div class="flex items-start justify-between pb-4">
<h1 class="text-2xl font-bold"> <h1 class="text-2xl font-bold">
Teamerübersicht Teamer:innenübersicht
</h1> </h1>
<div class="flex flex-col items-end space-y-2 md:flex-row md:items-center md:space-x-2 md:space-y-0"> <div class="flex flex-col items-end space-y-2 md:flex-row md:items-center md:space-x-2 md:space-y-0">
<button type="button" <button type="button"
class="{{ html_classes('btn btn--small', { 'btn--secondary': filterDto.active }) }}" class="{{ html_classes('btn btn--small', { 'btn--secondary': filterDto.active }) }}"
{{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }} {{ stimulus_controller('modal-button', [], [], {'ajax-modal': '#ajax-modal'}) }}
{{ stimulus_action('modal-button', 'ajax', null, { {{ stimulus_action('modal-button', 'ajax', null, {
'title': 'Teamer filtern', 'title': 'Teamer:innen filtern',
'url': path('app_common_teamer_filter', { 'r': return_url() }) 'url': path('app_common_teamer_filter', { 'r': return_url() })
}) }}> }) }}>
<div class="flex items-center space-x-1"> <div class="flex items-center space-x-1">
@@ -94,7 +94,7 @@
</td> </td>
<td> <td>
<div class="flex items-center space-x-1 justify-end"> <div class="flex items-center space-x-1 justify-end">
<a href="{{ path('app_admin_teamer_profile', { 'uuid': teamer.uuid }) }}" title="Teamerprofil {{ teamer }}"> <a href="{{ path('app_admin_teamer_profile', { 'uuid': teamer.uuid }) }}" title="Teamer:innenprofil {{ teamer }}">
{{ icon('user') }} {{ icon('user') }}
</a> </a>
</div> </div>
+9 -2
View File
@@ -23,8 +23,15 @@
{% include '_partials/_errorbox.html.twig' with { {% include '_partials/_errorbox.html.twig' with {
'message': 'Deine Bewerbung wurde leider abgelehnt.' 'message': 'Deine Bewerbung wurde leider abgelehnt.'
} %} } %}
{% if application.remarks %} {% if application.comment and application.commentVisible %}
<strong>Begründung:</strong> {{ application.remarks|nl2br}} <strong>Begründung:</strong> {{ application.comment|nl2br}}
{% endif %}
{% elseif application.status == constant('App\\Entity\\Application::STATUS_PENDING') %}
{% include '_partials/_infobox.html.twig' with {
'message': 'Deine Bewerbung befindet sich in Bearbeitung.'
} %}
{% if application.comment and application.commentVisible %}
<strong>Begründung:</strong> {{ application.comment|nl2br}}
{% endif %} {% endif %}
{% else %} {% else %}
{% include '_partials/_infobox.html.twig' with { {% include '_partials/_infobox.html.twig' with {
+2 -2
View File
@@ -41,8 +41,8 @@
Kontakt Kontakt
</h1> </h1>
<p class="pb-4"> <p class="pb-4">
Hast du allgemeine Fragen zum Teamer-sein bei E&amp;P Reisen, zur Benutzung von MyE&amp;P Team, zur Abrechnung Hast du allgemeine Fragen zum Teamer:innen-sein bei E&amp;P Reisen, zur Benutzung von MyE&amp;P Team, zur
oder Sonstigem? Hast du schon geschaut, ob deine Frage in den FAQs beantwortet wird? Abrechnung oder Sonstigem? Hast du schon geschaut, ob deine Frage in den FAQs beantwortet wird?
</p> </p>
<p> <p>
Dann melde dich gerne beim Team Personalplanung! Dann melde dich gerne beim Team Personalplanung!
@@ -4,7 +4,7 @@
{% block content %} {% block content %}
<h1 class="text-2xl font-bold pb-4"> <h1 class="text-2xl font-bold pb-4">
Meine Vergfügbarkeit Meine Verfügbarkeit
</h1> </h1>
<p class="pb-8"> <p class="pb-8">
Hier kannst du angeben, wann du allgemein Zeit und Lust hättest, Einsätze zu absolvieren. Wenn wir in diesem Hier kannst du angeben, wann du allgemein Zeit und Lust hättest, Einsätze zu absolvieren. Wenn wir in diesem
@@ -28,7 +28,7 @@
</h4> </h4>
{% for availability in availabilities %} {% for availability in availabilities %}
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<span>{{ availability }}</span> <span>{{ availability }}{% if availability.description %} ({{ availability.description }}){% endif %}</span>
{% if is_granted('DELETE', availability) %} {% if is_granted('DELETE', availability) %}
<button type="button" <button type="button"
title="Zeitraum entfernen/löschen" title="Zeitraum entfernen/löschen"
@@ -70,7 +70,7 @@
</h4> </h4>
{% for availability in availabilities %} {% for availability in availabilities %}
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<span>{{ availability }}</span> <span>{{ availability }}{% if availability.description %} ({{ availability.description }}){% endif %}</span>
<a href="{{ path('app_teamer_profile_availability_add', { 'id': availability.id }) }}" <a href="{{ path('app_teamer_profile_availability_add', { 'id': availability.id }) }}"
title="Zeitraum hinzufügen"> title="Zeitraum hinzufügen">
{{ icon('plus', 'w-5 h-5') }} {{ icon('plus', 'w-5 h-5') }}