Nightly tasks: apply late fees, overdue reminder emails, and autopay retries at most once per invoice per day, and lock nightly to the daily schedule

This commit is contained in:
johnnyq
2026-07-30 17:50:11 -04:00
parent 36c9c030c0
commit 8436cd6296
7 changed files with 72 additions and 5 deletions

View File

@@ -9,6 +9,7 @@ $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM cron_jobs WHERE c
$registry = cronJobRegistryByName();
$job = $registry[$row['cron_job_name']] ?? null;
$cron_job_interval_safe = ($job['interval_safe'] ?? true);
$cron_job_name = escapeHtml($row['cron_job_name']);
$cron_job_label = escapeHtml($job['label'] ?? $row['cron_job_name']);
@@ -50,10 +51,15 @@ ob_start();
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
</div>
<select class="form-control" name="schedule" id="cronJobSchedule">
<option value="Interval" <?= $cron_job_schedule === 'Interval' ? 'selected' : '' ?>>Every so many minutes</option>
<option value="Daily" <?= $cron_job_schedule === 'Daily' ? 'selected' : '' ?>>Once a day</option>
<?php if ($cron_job_interval_safe) { ?>
<option value="Interval" <?= $cron_job_schedule === 'Interval' ? 'selected' : '' ?>>Every so many minutes</option>
<?php } ?>
<option value="Daily" <?= ($cron_job_schedule === 'Daily' || !$cron_job_interval_safe) ? 'selected' : '' ?>>Once a day</option>
</select>
</div>
<?php if (!$cron_job_interval_safe) { ?>
<small class="text-muted">This job's work repeats if it runs twice in one day, so it only runs on the daily schedule.</small>
<?php } ?>
</div>
<div class="form-group" id="cronJobIntervalGroup">

View File

@@ -28,6 +28,12 @@ if (isset($_POST['edit_cron_job'])) {
$enabled = isset($_POST['enabled']) ? 1 : 0;
$schedule = $_POST['schedule'] === 'Daily' ? 'Daily' : 'Interval';
// A job the registry marks interval-unsafe only accepts the daily schedule. The form
// does not offer anything else, so anything else arriving here is a crafted request
if (($registry[$row['cron_job_name']]['interval_safe'] ?? true) === false) {
$schedule = 'Daily';
}
// A job cannot be asked to run more than once a minute (the dispatcher only wakes that
// often) and anything over a day belongs on the daily schedule instead.
$interval_minutes = min(1440, max(1, intval($_POST['interval_minutes'])));