Add cancellation cutoff limiting how close to a lesson a student can cancel
CI / Tests (PHP 8.1) (pull_request) Successful in 41s
CI / Tests (PHP 8.2) (pull_request) Successful in 53s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m51s
CI / Coding Standards (pull_request) Successful in 2m54s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m38s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 41s
CI / Tests (PHP 8.2) (pull_request) Successful in 53s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m51s
CI / Coding Standards (pull_request) Successful in 2m54s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m38s
CI / Build Plugin Zip (pull_request) Skipped
Students can no longer cancel their own lesson online once it starts within a configured window; instructors and studio admins can always cancel. - Studio default `us_cancellation_cutoff_hours` (stored/computed in hours, entered and displayed in days under Studio Settings → Cancellations). - Optional per-offering override `cancellation_cutoff_hours` (entered in hours); blank inherits the studio default, 0 allows anytime cancellation. - `Booking\CancellationPolicy` resolves the effective window and decides; `BookingEndpoint::cancel()` returns a 403 `cancellation_closed` when too late. The instructor status endpoint and studio-admin student actions bypass it. Closes #93 Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
@@ -104,6 +104,11 @@ class OfferingController {
|
||||
$duration = absint( Val::int( $_POST['duration_minutes'] ?? 0 ) );
|
||||
$capacity = absint( Val::int( $_POST['capacity'] ?? 0 ) );
|
||||
|
||||
// A blank cutoff means "use the studio default" (null); any entered value
|
||||
// (including 0 — cancel any time) is a per-offering override.
|
||||
$cutoffRaw = trim( sanitize_text_field( Val::string( wp_unslash( $_POST['cancellation_cutoff_hours'] ?? '' ) ) ) );
|
||||
$cutoffHours = '' === $cutoffRaw ? null : absint( Val::int( $cutoffRaw ) );
|
||||
|
||||
// Term dates: a class either meets once (term ends the day it starts)
|
||||
// or repeats weekly for a set number of sessions.
|
||||
$termStart = Offering::normalizeDate( sanitize_text_field( Val::string( wp_unslash( $_POST['term_start'] ?? '' ) ) ) );
|
||||
@@ -129,6 +134,7 @@ class OfferingController {
|
||||
termEnd: $termEnd,
|
||||
scheduleNote: $this->nullableText( sanitize_text_field( Val::string( wp_unslash( $_POST['schedule_note'] ?? '' ) ) ) ),
|
||||
etransferEmail: $this->nullableText( sanitize_email( Val::string( wp_unslash( $_POST['etransfer_email'] ?? '' ) ) ) ),
|
||||
cancellationCutoffHours: $cutoffHours,
|
||||
isActive: isset( $_POST['is_active'] ),
|
||||
id: $existing?->id,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user