feat: import work hours from SaaS and exchange signed time sheet

This commit is contained in:
fromme committed 2026-09-26 12:13:59 +02:00
1 parent 7cf39850e6
commit 1a7c272414
73 files changed
+10488 -72

No files matched your search

@@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
namespace App\Tests\Repository;
use App\Entity\TeamerWorkMonth;
use App\Enum\WorkMonthStatus;
use App\Model\WorkMonthFilterDto;
use App\Repository\TeamerWorkMonthRepository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
/**
* The list's defaults are the part worth pinning: what an admin sees when they have chosen
* no filter at all is decided in DQL, not in the template.
*/
class TeamerWorkMonthRepositoryTest extends KernelTestCase
{
public function testTheListHidesApprovedMonthsUntilAskedFor(): void
{
$query = $this->createListQuery(new WorkMonthFilterDto());
$this->assertStringContainsString('work_month.status != :approved', $query->getDQL());
$this->assertSame(WorkMonthStatus::APPROVED, $query->getParameter('approved')->getValue());
}
public function testApprovedMonthsComeBackWhenTheFlagIsSet(): void
{
$query = $this->createListQuery((new WorkMonthFilterDto())->setIncludeApproved(true));
$this->assertStringNotContainsString(':approved', $query->getDQL());
}
/**
* An explicit status choice has to win over the "hide approved" default, or picking
* "Geprüft" from the filter would return nothing at all.
*/
public function testAnExplicitStatusChoiceOverridesTheDefault(): void
{
$query = $this->createListQuery(
(new WorkMonthFilterDto())->setStatuses([WorkMonthStatus::APPROVED])
);
$dql = $query->getDQL();
$this->assertStringContainsString('work_month.status IN (:statuses)', $dql);
$this->assertStringNotContainsString(':approved', $dql);
$this->assertSame([WorkMonthStatus::APPROVED], $query->getParameter('statuses')->getValue());
}
public function testFilteringByMonthSplitsThePeriodIntoItsColumns(): void
{
$query = $this->createListQuery(
(new WorkMonthFilterDto())->setPeriod(new \DateTimeImmutable('2026-03-01'))
);
$this->assertStringContainsString('work_month.year = :year', $query->getDQL());
$this->assertStringContainsString('work_month.month = :month', $query->getDQL());
$this->assertSame(2026, $query->getParameter('year')->getValue());
$this->assertSame(3, $query->getParameter('month')->getValue(), 'The calendar month, not the API index.');
}
/**
* The reminder must not chase someone who has already sent the sheet in, nor a deleted
* teamer.
*/
public function testTheReminderQueryOnlyLooksAtMonthsStillWaiting(): void
{
$repository = $this->createRepository();
$months = $repository->findAwaitingDocument(new \DateTimeImmutable('2026-03-04'));
// db_test starts empty, so this asserts the query runs at all - the semantics above
// are what the DQL assertions cover.
$this->assertSame([], $months);
}
private function createListQuery(WorkMonthFilterDto $filterDto): Query
{
return $this->createRepository()->getListQuery($filterDto);
}
private function createRepository(): TeamerWorkMonthRepository
{
self::bootKernel();
/** @var EntityManagerInterface $entityManager */
$entityManager = self::getContainer()->get(EntityManagerInterface::class);
/** @var TeamerWorkMonthRepository $repository */
$repository = $entityManager->getRepository(TeamerWorkMonth::class);
return $repository;
}
}