feat: apply season task deadlines to all open checklist entries
This commit is contained in:
1 parent
3fe510e64e
commit
300bb2058f
5 files changed
+81
-1
No files matched your search
@@ -46,6 +46,9 @@ class TaskDeadlineController extends AbstractController
|
|||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$applyToAll = true === $form->get('applyToAll')->getData();
|
||||||
|
$appliedCount = $applyToAll ? ($seasonAssignment?->applyDeadlinesToOpenTasks($task) ?? 0) : 0;
|
||||||
|
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$this->logger->info('Change season assignment task deadlines', [
|
$this->logger->info('Change season assignment task deadlines', [
|
||||||
@@ -54,9 +57,13 @@ class TaskDeadlineController extends AbstractController
|
|||||||
'task' => $task->getTaskKey(),
|
'task' => $task->getTaskKey(),
|
||||||
'deadline_override_1' => $task->getDeadlineOverride1()?->format('Y-m-d'),
|
'deadline_override_1' => $task->getDeadlineOverride1()?->format('Y-m-d'),
|
||||||
'deadline_override_2' => $task->getDeadlineOverride2()?->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);
|
return new HxRedirectResponse($returnUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,6 +208,30 @@ class SeasonAssignment implements BlameableEntityInterface, TimestampableEntityI
|
|||||||
return $this;
|
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<int, Upload>
|
* @return Collection<int, Upload>
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Form;
|
|||||||
|
|
||||||
use App\Entity\SeasonAssignmentTask;
|
use App\Entity\SeasonAssignmentTask;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
@@ -27,6 +28,13 @@ class SeasonTaskDeadlineType extends AbstractType
|
|||||||
'required' => false,
|
'required' => false,
|
||||||
'help' => 'Ohne Angabe gilt Frist 1.',
|
'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.',
|
||||||
|
])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{{ form_row(form.deadlineOverride1) }}
|
{{ form_row(form.deadlineOverride1) }}
|
||||||
{{ form_row(form.deadlineOverride2) }}
|
{{ form_row(form.deadlineOverride2) }}
|
||||||
|
{{ form_row(form.applyToAll) }}
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn">
|
<button type="submit" class="btn">
|
||||||
Speichern
|
Speichern
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace App\Tests\Entity;
|
|||||||
|
|
||||||
use App\Entity\JobProfile;
|
use App\Entity\JobProfile;
|
||||||
use App\Entity\SeasonAssignment;
|
use App\Entity\SeasonAssignment;
|
||||||
|
use App\Entity\SeasonAssignmentTask;
|
||||||
use App\Entity\Teamer;
|
use App\Entity\Teamer;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
@@ -100,4 +101,43 @@ class SeasonAssignmentTest extends TestCase
|
|||||||
$this->assertSame('2027-04-30', $seasonAssignment->getDateTo()->format('Y-m-d'));
|
$this->assertSame('2027-04-30', $seasonAssignment->getDateTo()->format('Y-m-d'));
|
||||||
$this->assertSame('AGR', $seasonAssignment->getHotelCode());
|
$this->assertSame('AGR', $seasonAssignment->getHotelCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testApplyingDeadlinesCopiesBothOverridesOntoOpenEntriesOnly(): void
|
||||||
|
{
|
||||||
|
$seasonAssignment = new SeasonAssignment();
|
||||||
|
$source = (new SeasonAssignmentTask())
|
||||||
|
->setDeadlineOverride1(new \DateTimeImmutable('2026-11-15'))
|
||||||
|
->setDeadlineOverride2(new \DateTimeImmutable('2026-11-30'));
|
||||||
|
$open = new SeasonAssignmentTask();
|
||||||
|
$done = (new SeasonAssignmentTask())
|
||||||
|
->setDone(true)
|
||||||
|
->setDeadlineOverride1(new \DateTimeImmutable('2026-10-01'));
|
||||||
|
$seasonAssignment->addTask($source)->addTask($open)->addTask($done);
|
||||||
|
|
||||||
|
$this->assertSame(1, $seasonAssignment->applyDeadlinesToOpenTasks($source));
|
||||||
|
|
||||||
|
$this->assertSame('2026-11-15', $open->getDeadlineOverride1()?->format('Y-m-d'));
|
||||||
|
$this->assertSame('2026-11-30', $open->getDeadlineOverride2()?->format('Y-m-d'));
|
||||||
|
$this->assertSame('2026-10-01', $done->getDeadlineOverride1()?->format('Y-m-d'));
|
||||||
|
$this->assertNull($done->getDeadlineOverride2());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty fields are applied as well: that is how the office resets every entry to its
|
||||||
|
* computed deadline in one go.
|
||||||
|
*/
|
||||||
|
public function testApplyingEmptyDeadlinesResetsTheOverrides(): void
|
||||||
|
{
|
||||||
|
$seasonAssignment = new SeasonAssignment();
|
||||||
|
$source = new SeasonAssignmentTask();
|
||||||
|
$other = (new SeasonAssignmentTask())
|
||||||
|
->setDeadlineOverride1(new \DateTimeImmutable('2026-11-15'))
|
||||||
|
->setDeadlineOverride2(new \DateTimeImmutable('2026-11-30'));
|
||||||
|
$seasonAssignment->addTask($source)->addTask($other);
|
||||||
|
|
||||||
|
$seasonAssignment->applyDeadlinesToOpenTasks($source);
|
||||||
|
|
||||||
|
$this->assertNull($other->getDeadlineOverride1());
|
||||||
|
$this->assertNull($other->getDeadlineOverride2());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user