feat(services): add public holidays states infra
This commit is contained in:
		
							parent
							
								
									da77779525
								
							
						
					
					
						commit
						78bb9e6f09
					
				@ -0,0 +1,43 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Services\WorkingDays\PublicHolidays;
 | 
			
		||||
 | 
			
		||||
use App\Models\NonWorkingDays;
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\Storage\PublicHolidaysStorageInterface;
 | 
			
		||||
use App\Services\WorkingDays\WorkingDayDeterminerInterface;
 | 
			
		||||
 | 
			
		||||
class PublicHolidaysStateDeterminer implements PublicHolidaysStateDeterminerInterface, PublicHolidaysStateStorageInterface, WorkingDayDeterminerInterface
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        protected readonly PublicHolidaysStorageInterface $publicHolidaysStorage,
 | 
			
		||||
        protected readonly string $country
 | 
			
		||||
    ) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isPublicHoliday(\DateTimeImmutable $publicHolidayDate): bool
 | 
			
		||||
    {
 | 
			
		||||
        return $this->publicHolidaysStorage->isPublicHoliday($this->country, $publicHolidayDate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function storePublicHoliday(\DateTimeImmutable $publicHolidayDate): ?NonWorkingDays
 | 
			
		||||
    {
 | 
			
		||||
        return $this->publicHolidaysStorage->storePublicHoliday($this->country, $publicHolidayDate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isWorkingDay(\DateTimeImmutable $date): bool
 | 
			
		||||
    {
 | 
			
		||||
        return !$this->isPublicHoliday($date);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getPublicHolidaysInInterval(\DateTimeImmutable $startDate, \DateTimeImmutable $endDate): array
 | 
			
		||||
    {
 | 
			
		||||
        return $this->publicHolidaysStorage->getPublicHolidaysInInterval($this->country, $startDate, $endDate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getWorkingDaysCount(\DateTimeImmutable $startDate, int $workingDays): int
 | 
			
		||||
    {
 | 
			
		||||
        return $workingDays - $this->publicHolidaysStorage->countPublicHolidaysInInterval($this->country, $startDate, $startDate->add(new \DateInterval(sprintf('P%dD', $workingDays))));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,28 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Services\WorkingDays\PublicHolidays;
 | 
			
		||||
 | 
			
		||||
use App\Models\NonWorkingDays;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface for determining public holidays in a given interval/day.
 | 
			
		||||
 */
 | 
			
		||||
interface PublicHolidaysStateDeterminerInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if a given date is a public holiday.
 | 
			
		||||
     * @param \DateTimeImmutable $publicHolidayDate
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function isPublicHoliday(\DateTimeImmutable $publicHolidayDate): bool;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if is a public holiday in a given interval.
 | 
			
		||||
     * @param \DateTimeImmutable $startDate
 | 
			
		||||
     * @param \DateTimeImmutable $endDate
 | 
			
		||||
     * @return array<NonWorkingDays>
 | 
			
		||||
     */
 | 
			
		||||
    public function getPublicHolidaysInInterval(\DateTimeImmutable $startDate, \DateTimeImmutable $endDate): array;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,35 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Services\WorkingDays\PublicHolidays;
 | 
			
		||||
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\Storage\PublicHolidaysStorageInterface;
 | 
			
		||||
use App\Services\WorkingDays\WorkingDayDeterminerInterface;
 | 
			
		||||
 | 
			
		||||
class PublicHolidaysStateFactory
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        private readonly PublicHolidaysStorageInterface $holidaysStorage,
 | 
			
		||||
    ) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createStoreForCountry(string $countryCode): PublicHolidaysStateStorageInterface
 | 
			
		||||
    {
 | 
			
		||||
        return $this->getStateImpl($countryCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createDeterminerForCountry(string $countryCode): PublicHolidaysStateDeterminerInterface&WorkingDayDeterminerInterface
 | 
			
		||||
    {
 | 
			
		||||
        return $this->getStateImpl($countryCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $countryCode
 | 
			
		||||
     * @return PublicHolidaysStateDeterminer
 | 
			
		||||
     */
 | 
			
		||||
    protected function getStateImpl(string $countryCode): PublicHolidaysStateDeterminer
 | 
			
		||||
    {
 | 
			
		||||
        return new PublicHolidaysStateDeterminer($this->holidaysStorage, $countryCode);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Tests\Unit\Services\WorkingDays\PublicHolidays;
 | 
			
		||||
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\PublicHolidaysStateDeterminer;
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\Storage\PublicHolidaysStorageInterface;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class PublicHolidaysStateDeterminerTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testStorageCalledWhenDeterminatePublicHoliday(): void
 | 
			
		||||
    {
 | 
			
		||||
        $date = new \DateTimeImmutable('2024-01-01');
 | 
			
		||||
        $storage = $this->createMock(PublicHolidaysStorageInterface::class);
 | 
			
		||||
        $storage->expects($this->once())->method('isPublicHoliday')->with('CZ', $date);
 | 
			
		||||
        $determiner = new PublicHolidaysStateDeterminer($storage, 'CZ');
 | 
			
		||||
        $determiner->isPublicHoliday($date);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testStorageCalledWhenStorePublicHoliday(): void
 | 
			
		||||
    {
 | 
			
		||||
        $date = new \DateTimeImmutable('2024-01-01');
 | 
			
		||||
        $storage = $this->createMock(PublicHolidaysStorageInterface::class);
 | 
			
		||||
        $storage->expects($this->once())->method('storePublicHoliday')->with('CZ', $date);
 | 
			
		||||
        $determiner = new PublicHolidaysStateDeterminer($storage, 'CZ');
 | 
			
		||||
        $determiner->storePublicHoliday($date);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,24 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Tests\Unit\Services\WorkingDays;
 | 
			
		||||
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\PublicHolidaysStateDeterminer;
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\PublicHolidaysStateFactory;
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\PublicHolidaysStateStorageInterface;
 | 
			
		||||
use App\Services\WorkingDays\PublicHolidays\Storage\PublicHolidaysStorageInterface;
 | 
			
		||||
use Tests\TestCase;
 | 
			
		||||
 | 
			
		||||
class PublicHolidaysStateFactoryTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testCreateStoreForCountryWillReturnCzechStorageForCZ(): void
 | 
			
		||||
    {
 | 
			
		||||
        $storage = $this->createMock(PublicHolidaysStorageInterface::class);
 | 
			
		||||
        $factory = new PublicHolidaysStateFactory($storage);
 | 
			
		||||
        $store =  $factory->createStoreForCountry('CZ');
 | 
			
		||||
        $determiner = $factory->createDeterminerForCountry('CZ');
 | 
			
		||||
        $this->assertInstanceOf(PublicHolidaysStateStorageInterface::class, $store);
 | 
			
		||||
        $this->assertInstanceOf(PublicHolidaysStateDeterminer::class, $determiner);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user