Files
headroom/backend/app/Utilities/WorkingDaysCalculator.php
Santhosh Janardhanan 3324c4f156 feat(allocation): implement resource allocation feature
- Add AllocationController with CRUD + bulk endpoints
- Add AllocationValidationService for capacity/estimate validation
- Add AllocationMatrixService for optimized matrix queries
- Add AllocationPolicy for authorization
- Add AllocationResource for API responses
- Add frontend allocationService and matrix UI
- Add E2E tests for allocation matrix (20 tests)
- Add unit tests for validation service and policies
- Fix month format conversion (YYYY-MM to YYYY-MM-01)
2026-02-25 16:28:47 -05:00

60 lines
1.5 KiB
PHP

<?php
namespace App\Utilities;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
class WorkingDaysCalculator
{
public const TIMEZONE = 'America/New_York';
public static function calculate(string $month, array $holidays = []): int
{
$start = Carbon::createFromFormat('Y-m', $month, self::TIMEZONE)->startOfMonth();
$end = $start->copy()->endOfMonth();
return self::getWorkingDaysInRange($start->toDateString(), $end->toDateString(), $holidays);
}
public static function getWorkingDaysInRange(string $start, string $end, array $holidays = []): int
{
$period = CarbonPeriod::create(
Carbon::create($start, self::TIMEZONE),
Carbon::create($end, self::TIMEZONE)
);
$holidayLookup = array_flip($holidays);
$workingDays = 0;
foreach ($period as $day) {
$date = $day->toDateString();
if (self::isWorkingDay($date, $holidayLookup)) {
$workingDays++;
}
}
return $workingDays;
}
public static function isWorkingDay(string $date, array $holidays = []): bool
{
$carbonDate = Carbon::create($date, self::TIMEZONE);
if ($carbonDate->isWeekend()) {
return false;
}
if (isset($holidays[$carbonDate->toDateString()])) {
return false;
}
return true;
}
public static function isWeekend(string $date): bool
{
return Carbon::create($date, self::TIMEZONE)->isWeekend();
}
}