Files
alrahma_sunday_school_api/app/Services/Parents/ParentAttendanceReportCalendarService.php
T
2026-04-24 02:12:01 -04:00

128 lines
3.8 KiB
PHP

<?php
namespace App\Services\Parents;
use Illuminate\Support\Facades\DB;
class ParentAttendanceReportCalendarService
{
public function __construct(private ParentConfigService $configService)
{
}
/**
* @return array{0: array<int, array{value:string,label:string}>, 1: string}
*/
public function computeSundays(int $weeksBefore = 4, int $weeksAfter = 26): array
{
$today = new \DateTime('today');
$dow = (int) $today->format('w');
$thisSunday = clone $today;
if ($dow !== 0) {
$thisSunday->modify('last sunday');
}
$default = clone $today;
if ($dow !== 0) {
$default->modify('next sunday');
}
$schoolYear = (string) ($this->configService->context()['school_year'] ?? '');
$cap = $this->firstSundayOfJune($schoolYear);
$dates = [];
for ($i = $weeksBefore; $i >= 1; $i--) {
$dates[] = (clone $thisSunday)->modify('-' . $i . ' week');
}
$cursor = clone $thisSunday;
while ($cursor <= $cap) {
$dates[] = clone $cursor;
$cursor->modify('+1 week');
}
$rangeStart = reset($dates);
$rangeEnd = end($dates);
$rangeStartStr = $rangeStart instanceof \DateTime ? $rangeStart->format('Y-m-d') : null;
$rangeEndStr = $rangeEnd instanceof \DateTime ? $rangeEnd->format('Y-m-d') : null;
$noSchool = [];
if ($rangeStartStr && $rangeEndStr) {
$rows = DB::table('calendar_events')
->select('date')
->where('no_school', 1)
->where(function ($query) use ($schoolYear) {
$query->where('school_year', $schoolYear)
->orWhereNull('school_year');
})
->where('date', '>=', $rangeStartStr)
->where('date', '<=', $rangeEndStr)
->get()
->toArray();
foreach ($rows as $row) {
$d = substr((string) ($row->date ?? ''), 0, 10);
if ($d !== '') {
$noSchool[$d] = true;
}
}
}
$filtered = [];
foreach ($dates as $d) {
$ymd = $d->format('Y-m-d');
if (!isset($noSchool[$ymd]) && $d >= $today && $d <= $cap) {
$filtered[] = $d;
}
}
$defaultYmd = $default->format('Y-m-d');
if (!empty($filtered)) {
$defaultYmd = $filtered[0]->format('Y-m-d');
}
$out = [];
foreach ($filtered as $d) {
$out[] = [
'value' => $d->format('Y-m-d'),
'label' => $d->format('m-d-Y'),
];
}
return [$out, $defaultYmd];
}
public function normalizeCutoffTime(string $raw, string $default = '09:00'): string
{
$raw = trim($raw);
if ($raw === '') {
return $default;
}
if (preg_match('/^(\\d{1,2}):(\\d{2})$/', $raw, $m)) {
$hh = str_pad((string) ((int) $m[1]), 2, '0', STR_PAD_LEFT);
return $hh . ':' . $m[2];
}
return $default;
}
public function firstSundayOfJune(string $schoolYear): \DateTime
{
$today = new \DateTime('today');
$endYear = null;
if (preg_match('/^(\\d{4})\\D(\\d{4})$/', $schoolYear, $m)) {
$endYear = (int) $m[2];
}
if ($endYear === null) {
$y = (int) $today->format('Y');
$endYear = ((int) $today->format('n') > 6) ? ($y + 1) : $y;
}
$juneFirst = new \DateTime(sprintf('%04d-06-01', $endYear));
if ((int) $juneFirst->format('w') !== 0) {
$juneFirst->modify('next sunday');
}
return $juneFirst;
}
}