[#339] Ajout d'une page listant les règles de calcules (#5)
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled

| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|        #339          |        Ajout d'une page listant les règles de calcules         |

## Description de la PR
[#339] Ajout d'une page listant les règles de calcules

## Modification du .env

## Check list

- [ ] Pas de régression
- [x] TU/TI/TF rédigée
- [x] TU/TI/TF OK
- [ ] CHANGELOG modifié

Reviewed-on: #5
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #5.
This commit is contained in:
2026-02-20 16:17:22 +00:00
committed by Autin
parent 49fecfc27a
commit f8ca5e50a0
16 changed files with 664 additions and 59 deletions

View File

@@ -8,6 +8,7 @@ use App\Entity\Absence;
use App\Entity\AbsenceType;
use App\Entity\Contract;
use App\Entity\Employee;
use App\Service\Contracts\EmployeeContractResolver;
use App\Service\WorkHours\WorkedHoursCreditPolicy;
use DateTime;
use PHPUnit\Framework\TestCase;
@@ -19,7 +20,7 @@ final class WorkedHoursCreditPolicyTest extends TestCase
{
public function testComputeCreditedMinutesFor35hHalfDay(): void
{
$policy = new WorkedHoursCreditPolicy();
$policy = new WorkedHoursCreditPolicy($this->buildResolverStub());
$absence = $this->buildAbsence(trackMode: Contract::TRACKING_TIME, weeklyHours: 35, countAsWorked: true);
$minutes = $policy->computeCreditedMinutes($absence, '2026-02-16', true, false);
@@ -29,7 +30,7 @@ final class WorkedHoursCreditPolicyTest extends TestCase
public function testComputeCreditedMinutesFor4hContractFullDay(): void
{
$policy = new WorkedHoursCreditPolicy();
$policy = new WorkedHoursCreditPolicy($this->buildResolverStub());
$absence = $this->buildAbsence(trackMode: Contract::TRACKING_TIME, weeklyHours: 4, countAsWorked: true);
$minutes = $policy->computeCreditedMinutes($absence, '2026-02-16', true, true);
@@ -39,21 +40,21 @@ final class WorkedHoursCreditPolicyTest extends TestCase
public function testComputeCreditedPresenceUnitsForPresenceContract(): void
{
$policy = new WorkedHoursCreditPolicy();
$policy = new WorkedHoursCreditPolicy($this->buildResolverStub());
$absence = $this->buildAbsence(trackMode: Contract::TRACKING_PRESENCE, weeklyHours: null, countAsWorked: true);
$units = $policy->computeCreditedPresenceUnits($absence, true, false);
$units = $policy->computeCreditedPresenceUnits($absence, '2026-02-16', true, false);
self::assertSame(0.5, $units);
}
public function testNoCreditWhenAbsenceTypeDoesNotCount(): void
{
$policy = new WorkedHoursCreditPolicy();
$policy = new WorkedHoursCreditPolicy($this->buildResolverStub());
$absence = $this->buildAbsence(trackMode: Contract::TRACKING_TIME, weeklyHours: 35, countAsWorked: false);
self::assertSame(0, $policy->computeCreditedMinutes($absence, '2026-02-16', true, true));
self::assertSame(0.0, $policy->computeCreditedPresenceUnits($absence, true, true));
self::assertSame(0.0, $policy->computeCreditedPresenceUnits($absence, '2026-02-16', true, true));
}
private function buildAbsence(string $trackMode, ?int $weeklyHours, bool $countAsWorked): Absence
@@ -79,6 +80,18 @@ final class WorkedHoursCreditPolicyTest extends TestCase
->setEmployee($employee)
->setType($type)
->setStartDate(new DateTime('2026-02-16'))
->setEndDate(new DateTime('2026-02-16'));
->setEndDate(new DateTime('2026-02-16'))
;
}
private function buildResolverStub(): EmployeeContractResolver
{
$resolver = $this->createStub(EmployeeContractResolver::class);
$resolver
->method('resolveForEmployeeAndDate')
->willReturnCallback(static fn (Employee $employee): ?Contract => $employee->getContract())
;
return $resolver;
}
}

View File

@@ -13,6 +13,7 @@ use App\Entity\User;
use App\Enum\HalfDay;
use App\Repository\Contract\AbsenceReadRepositoryInterface;
use App\Repository\Contract\EmployeeScopedRepositoryInterface;
use App\Service\Contracts\EmployeeContractResolver;
use App\Service\WorkHours\AbsenceSegmentsResolver;
use App\Service\WorkHours\WorkedHoursCreditPolicy;
use App\State\WorkHourDayContextProvider;
@@ -53,7 +54,7 @@ final class WorkHourDayContextProviderTest extends TestCase
$this->employeeRepository,
$this->absenceRepository,
new AbsenceSegmentsResolver(),
new WorkedHoursCreditPolicy()
new WorkedHoursCreditPolicy($this->buildResolverStub())
);
$this->expectException(AccessDeniedHttpException::class);
@@ -71,7 +72,7 @@ final class WorkHourDayContextProviderTest extends TestCase
$this->employeeRepository,
$this->absenceRepository,
new AbsenceSegmentsResolver(),
new WorkedHoursCreditPolicy()
new WorkedHoursCreditPolicy($this->buildResolverStub())
);
$this->expectException(UnprocessableEntityHttpException::class);
@@ -95,7 +96,7 @@ final class WorkHourDayContextProviderTest extends TestCase
$this->employeeRepository,
$this->absenceRepository,
new AbsenceSegmentsResolver(),
new WorkedHoursCreditPolicy()
new WorkedHoursCreditPolicy($this->buildResolverStub())
);
$result = $provider->provide(new Get());
@@ -151,4 +152,15 @@ final class WorkHourDayContextProviderTest extends TestCase
$property->setAccessible(true);
$property->setValue($entity, $id);
}
private function buildResolverStub(): EmployeeContractResolver
{
$resolver = $this->createStub(EmployeeContractResolver::class);
$resolver
->method('resolveForEmployeeAndDate')
->willReturnCallback(static fn (Employee $employee): ?Contract => $employee->getContract())
;
return $resolver;
}
}

View File

@@ -15,6 +15,7 @@ use App\Enum\HalfDay;
use App\Repository\Contract\AbsenceReadRepositoryInterface;
use App\Repository\Contract\EmployeeScopedRepositoryInterface;
use App\Repository\Contract\WorkHourReadRepositoryInterface;
use App\Service\Contracts\EmployeeContractResolver;
use App\Service\WorkHours\AbsenceSegmentsResolver;
use App\Service\WorkHours\WorkedHoursCreditPolicy;
use App\State\WorkHourWeeklySummaryProvider;
@@ -58,7 +59,8 @@ final class WorkHourWeeklySummaryProviderTest extends TestCase
$this->workHourRepository,
$this->absenceRepository,
new AbsenceSegmentsResolver(),
new WorkedHoursCreditPolicy()
new WorkedHoursCreditPolicy($this->buildResolverStub()),
$this->buildResolverStub()
);
$this->expectException(AccessDeniedHttpException::class);
@@ -117,7 +119,8 @@ final class WorkHourWeeklySummaryProviderTest extends TestCase
$this->workHourRepository,
$this->absenceRepository,
new AbsenceSegmentsResolver(),
new WorkedHoursCreditPolicy()
new WorkedHoursCreditPolicy($this->buildResolverStub()),
$this->buildWeeklyResolverStub($employees)
);
$result = $provider->provide(new Get());
@@ -167,4 +170,50 @@ final class WorkHourWeeklySummaryProviderTest extends TestCase
$property->setAccessible(true);
$property->setValue($entity, $id);
}
private function buildResolverStub(): EmployeeContractResolver
{
$resolver = $this->createStub(EmployeeContractResolver::class);
$resolver
->method('resolveForEmployeeAndDate')
->willReturnCallback(static fn (Employee $employee): ?Contract => $employee->getContract())
;
$resolver
->method('resolveForEmployeesAndDays')
->willReturn([])
;
return $resolver;
}
/**
* @param list<Employee> $employees
*/
private function buildWeeklyResolverStub(array $employees): EmployeeContractResolver
{
$resolver = $this->createStub(EmployeeContractResolver::class);
$resolver
->method('resolveForEmployeeAndDate')
->willReturnCallback(static fn (Employee $employee): ?Contract => $employee->getContract())
;
$resolver
->method('resolveForEmployeesAndDays')
->willReturnCallback(static function (array $scopedEmployees, array $days): array {
$map = [];
foreach ($scopedEmployees as $employee) {
$employeeId = $employee->getId();
if (!$employeeId) {
continue;
}
foreach ($days as $day) {
$map[$employeeId][$day] = $employee->getContract();
}
}
return $map;
})
;
return $resolver;
}
}