feat(services): add database storage for public holidays
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\WorkingDays\PublicHolidays;
|
||||
|
||||
use App\Models\NonWorkingDays;
|
||||
|
||||
/**
|
||||
* Storage for storing public holidays in persistent storage.
|
||||
*/
|
||||
interface PublicHolidaysStateStorageInterface
|
||||
{
|
||||
/**
|
||||
* Store a public holiday in the storage.
|
||||
* @param \DateTimeImmutable $publicHolidayDate
|
||||
* @return NonWorkingDays|null
|
||||
*/
|
||||
public function storePublicHoliday(\DateTimeImmutable $publicHolidayDate): ?NonWorkingDays;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\WorkingDays\PublicHolidays\Storage;
|
||||
|
||||
use App\Models\Country;
|
||||
use App\Models\NonWorkingDays;
|
||||
use Illuminate\Database\UniqueConstraintViolationException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class DatabaseStorage implements PublicHolidaysStorageInterface
|
||||
{
|
||||
public function isPublicHoliday(string $countryCode, \DateTimeImmutable $holidayDate): bool
|
||||
{
|
||||
$country = $this->getCountryByCountryCode($countryCode);
|
||||
|
||||
return NonWorkingDays::where('country_id', $country->id)
|
||||
->where('non_working_date', $holidayDate->format('Y-m-d'))
|
||||
->exists();
|
||||
}
|
||||
|
||||
public function storePublicHoliday(string $countryCode, \DateTimeImmutable $holidayDate): ?NonWorkingDays
|
||||
{
|
||||
$country = $this->getCountryByCountryCode($countryCode);
|
||||
|
||||
try {
|
||||
return NonWorkingDays::create([
|
||||
'country_id' => $country->id,
|
||||
'non_working_date' => $holidayDate->format('Y-m-d'),
|
||||
]);
|
||||
} catch (UniqueConstraintViolationException $e) {
|
||||
// safe to ignore ... combination exists
|
||||
Log::warning("Non-working day already exists for country: " . $country . ", date: {$holidayDate->format('Y-m-d')}");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPublicHolidaysInInterval(string $countryCode, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): array
|
||||
{
|
||||
$country = $this->getCountryByCountryCode($countryCode);
|
||||
return NonWorkingDays::where('country_id', $country->id)
|
||||
->whereBetween('non_working_date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
|
||||
->get()->all();
|
||||
}
|
||||
|
||||
|
||||
public function countPublicHolidaysInInterval(string $countryCode, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): int
|
||||
{
|
||||
$country = $this->getCountryByCountryCode($countryCode);
|
||||
return NonWorkingDays::where('country_id', $country->id)
|
||||
->whereBetween('non_working_date', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')])
|
||||
->count();
|
||||
}
|
||||
|
||||
protected function getCountryByCountryCode(string $countryCode): Country
|
||||
{
|
||||
return Country::where('country_code', $countryCode)->first() ?? throw new \InvalidArgumentException("Country code '$countryCode' does not exist.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\WorkingDays\PublicHolidays\Storage;
|
||||
|
||||
use App\Models\NonWorkingDays;
|
||||
|
||||
/**
|
||||
* Interface for storing and retrieving public holidays independent on country.
|
||||
*/
|
||||
interface PublicHolidaysStorageInterface
|
||||
{
|
||||
/**
|
||||
* Determine if a given public holiday is in a given country.
|
||||
* @param string $countryCode
|
||||
* @param \DateTimeImmutable $holidayDate
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublicHoliday(string $countryCode, \DateTimeImmutable $holidayDate): bool;
|
||||
|
||||
/**
|
||||
* Returns all public holidays in a given country within a given interval.
|
||||
* @param string $countryCode
|
||||
* @param \DateTimeImmutable $startDate
|
||||
* @param \DateTimeImmutable $endDate
|
||||
* @return NonWorkingDays[]
|
||||
*/
|
||||
public function getPublicHolidaysInInterval(string $countryCode, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): array;
|
||||
|
||||
/**
|
||||
* Counts all public holidays in a given country within a given interval.
|
||||
* @param string $countryCode
|
||||
* @param \DateTimeImmutable $startDate
|
||||
* @param \DateTimeImmutable $endDate
|
||||
* @return int
|
||||
*/
|
||||
public function countPublicHolidaysInInterval(string $countryCode, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): int;
|
||||
|
||||
/**
|
||||
* Stores a public holiday in the storage.
|
||||
* @param string $countryCode
|
||||
* @param \DateTimeImmutable $holidayDate
|
||||
* @return NonWorkingDays|null
|
||||
*/
|
||||
public function storePublicHoliday(string $countryCode, \DateTimeImmutable $holidayDate): ?NonWorkingDays;
|
||||
}
|
||||
Reference in New Issue
Block a user