diff --git a/api/manage_recurring.php b/api/manage_recurring.php index 546c629..cfff818 100644 --- a/api/manage_recurring.php +++ b/api/manage_recurring.php @@ -147,18 +147,21 @@ function calculateNextRun($scheduleType, $scheduleDay, $scheduleTime) { break; case 'weekly': - $days = ['', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; - $dayName = $days[$scheduleDay] ?? 'Monday'; + $days = [1 => 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + $dayName = $days[(int)$scheduleDay] ?? 'Monday'; $next = new DateTime("next {$dayName} " . $time); break; case 'monthly': - $day = max(1, min(28, (int)$scheduleDay)); + $day = max(1, min(31, (int)$scheduleDay)); $next = new DateTime(); $next->modify('first day of next month'); - $next->setDate($next->format('Y'), $next->format('m'), $day); - list($h, $m) = explode(':', $time); - $next->setTime((int)$h, (int)$m, 0); + // Clamp to last day of target month (handles Feb, 30-day months) + $daysInMonth = (int)$next->format('t'); + $day = min($day, $daysInMonth); + $next->setDate((int)$next->format('Y'), (int)$next->format('m'), $day); + $parts = explode(':', $time . ':00'); // ensure at least H:M + $next->setTime((int)$parts[0], (int)$parts[1], 0); break; default: diff --git a/models/RecurringTicketModel.php b/models/RecurringTicketModel.php index 8d0f3f8..a066bca 100644 --- a/models/RecurringTicketModel.php +++ b/models/RecurringTicketModel.php @@ -176,7 +176,8 @@ class RecurringTicketModel { break; case 'weekly': - $dayName = ['', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'][$scheduleDay] ?? 'Monday'; + $dayNames = [1 => 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + $dayName = $dayNames[(int)$scheduleDay] ?? 'Monday'; $next = new DateTime("next {$dayName} " . $scheduleTime); break;