diff --git a/src/Controller/Administrative/SeasonAssignment/TaskDeadlineController.php b/src/Controller/Administrative/SeasonAssignment/TaskDeadlineController.php
index 7142a6e..d3c31db 100644
--- a/src/Controller/Administrative/SeasonAssignment/TaskDeadlineController.php
+++ b/src/Controller/Administrative/SeasonAssignment/TaskDeadlineController.php
@@ -46,6 +46,9 @@ class TaskDeadlineController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
+ $applyToAll = true === $form->get('applyToAll')->getData();
+ $appliedCount = $applyToAll ? ($seasonAssignment?->applyDeadlinesToOpenTasks($task) ?? 0) : 0;
+
$this->entityManager->flush();
$this->logger->info('Change season assignment task deadlines', [
@@ -54,9 +57,13 @@ class TaskDeadlineController extends AbstractController
'task' => $task->getTaskKey(),
'deadline_override_1' => $task->getDeadlineOverride1()?->format('Y-m-d'),
'deadline_override_2' => $task->getDeadlineOverride2()?->format('Y-m-d'),
+ 'apply_to_all' => $applyToAll,
+ 'applied_count' => $appliedCount,
]);
- $this->addFlash('success', 'Die Fristen wurden gespeichert');
+ $this->addFlash('success', $applyToAll
+ ? 'Die Fristen wurden für alle offenen Einträge gespeichert'
+ : 'Die Fristen wurden gespeichert');
return new HxRedirectResponse($returnUrl);
}
diff --git a/src/Entity/SeasonAssignment.php b/src/Entity/SeasonAssignment.php
index 97d9b41..29976b1 100644
--- a/src/Entity/SeasonAssignment.php
+++ b/src/Entity/SeasonAssignment.php
@@ -208,6 +208,30 @@ class SeasonAssignment implements BlameableEntityInterface, TimestampableEntityI
return $this;
}
+ /**
+ * Copies both deadline overrides of $source onto every other entry that is not ticked off,
+ * empty ones included - an empty override resets the entry to its computed deadline. Entries
+ * already done keep theirs: their deadline is history by then.
+ *
+ * @return int the number of entries changed, $source not counted
+ */
+ public function applyDeadlinesToOpenTasks(SeasonAssignmentTask $source): int
+ {
+ $count = 0;
+
+ foreach ($this->tasks as $task) {
+ if ($task === $source || $task->isDone()) {
+ continue;
+ }
+
+ $task->setDeadlineOverride1($source->getDeadlineOverride1());
+ $task->setDeadlineOverride2($source->getDeadlineOverride2());
+ ++$count;
+ }
+
+ return $count;
+ }
+
/**
* @return Collection
*/
diff --git a/src/Form/SeasonTaskDeadlineType.php b/src/Form/SeasonTaskDeadlineType.php
index 58e6a6b..deff894 100644
--- a/src/Form/SeasonTaskDeadlineType.php
+++ b/src/Form/SeasonTaskDeadlineType.php
@@ -4,6 +4,7 @@ namespace App\Form;
use App\Entity\SeasonAssignmentTask;
use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -27,6 +28,13 @@ class SeasonTaskDeadlineType extends AbstractType
'required' => false,
'help' => 'Ohne Angabe gilt Frist 1.',
])
+ // unmapped: the controller copies the entered deadlines onto the other entries
+ ->add('applyToAll', CheckboxType::class, [
+ 'label' => 'auf alle Fristen anwenden',
+ 'required' => false,
+ 'mapped' => false,
+ 'help' => 'Gilt für alle noch nicht erledigten Einträge. Leere Felder setzen deren Fristen auf den berechneten Wert zurück.',
+ ])
;
}
diff --git a/templates/administrative/season_assignment/modal_task_deadline.html.twig b/templates/administrative/season_assignment/modal_task_deadline.html.twig
index 31c2739..4a15abc 100644
--- a/templates/administrative/season_assignment/modal_task_deadline.html.twig
+++ b/templates/administrative/season_assignment/modal_task_deadline.html.twig
@@ -10,6 +10,7 @@
{{ form_row(form.deadlineOverride1) }}
{{ form_row(form.deadlineOverride2) }}
+ {{ form_row(form.applyToAll) }}