ProductionCalendarService.php 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Services;
  4. use App\Models\ProductionCalendarDay;
  5. use Carbon\CarbonImmutable;
  6. use DateTimeInterface;
  7. use InvalidArgumentException;
  8. class ProductionCalendarService
  9. {
  10. public function addWorkingDays(DateTimeInterface|string $startDate, int $workingDays): CarbonImmutable
  11. {
  12. if ($workingDays < 0) {
  13. throw new InvalidArgumentException('Количество рабочих дней не может быть отрицательным.');
  14. }
  15. $date = CarbonImmutable::parse($startDate)->startOfDay();
  16. if ($workingDays === 0) {
  17. return $date;
  18. }
  19. $overrides = ProductionCalendarDay::query()
  20. ->pluck('is_working_day', 'date')
  21. ->map(static fn (mixed $value): bool => (bool) $value);
  22. $remaining = $workingDays;
  23. while ($remaining > 0) {
  24. $date = $date->addDay();
  25. $key = $date->toDateString();
  26. $isWorkingDay = $overrides->has($key)
  27. ? $overrides->get($key)
  28. : ! $date->isWeekend();
  29. if ($isWorkingDay) {
  30. $remaining--;
  31. }
  32. }
  33. return $date;
  34. }
  35. }