CI / Tests (PHP 8.1) (pull_request) Successful in 6m39s
CI / Tests (PHP 8.2) (pull_request) Successful in 57s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m59s
CI / Tests (PHP 8.5) (pull_request) Successful in 3m31s
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards & Static Analysis (pull_request) Successful in 3m28s
CI / Build Plugin Zip (pull_request) Skipped
Two related gaps, closed together because the second is created by the first. A private lesson could only be booked by the student or their guardian, so a booking taken over the phone had no way in — where group classes have had "Add students directly" all along. "Book a lesson for a student" is now a panel on Scheduler and My Lessons: student, open time, lesson type, with weekly term reservations and a no-charge option for make-up lessons. The booking core is extracted to Booking\LessonBooker and shared with POST /bookings, so the two paths cannot drift on offering rules, slot claiming, or billing. That leaves a registration with no intake answers and no policy acceptances, because nobody was at a keyboard to give them — already true of every directly added group-class student. Ticking the boxes on a student's behalf would be an audit trail that says something untrue, so instead the answers are collected another way and recorded afterwards, from a lesson's or an enrolment's detail page. Every recording must say how it was collected, which is stamped on each row along with who typed it and shown in a new "How it was given" column: a policy ticked online and one transcribed from paper must never look alike. Only staff-made registrations qualify (us_lessons.booked_by, us_group_enrollments.enrolled_by) — one the student made already holds their own answers. Only what is still missing can be recorded, re-checked at write time, so a stale or double-posted form cannot duplicate or overwrite. No IP is stored for a transcription, and accepted_by stays the student while recorded_by names the staff member. Intake is now generic over Registration\IntakeSubject, which Lesson and Enrollment both implement; LessonDetail became Registration\IntakeAudit and is shared by both detail views rather than duplicated. Closes #182 Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QfHt6CyJHz6KkA4RuaS7WK
67 lines
3.5 KiB
PHP
67 lines
3.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Unsupervised\Schedular;
|
|
|
|
use Unsupervised\Schedular\Availability\AvailabilityEndpoint;
|
|
use Unsupervised\Schedular\Availability\AvailabilityRepository;
|
|
use Unsupervised\Schedular\Availability\WindowValidator;
|
|
use Unsupervised\Schedular\Booking\BookingEndpoint;
|
|
use Unsupervised\Schedular\Booking\BookingRepository;
|
|
use Unsupervised\Schedular\Booking\CancellationPolicy;
|
|
use Unsupervised\Schedular\Booking\LessonBooker;
|
|
use Unsupervised\Schedular\GroupClass\EnrollmentEndpoint;
|
|
use Unsupervised\Schedular\GroupClass\GroupAccessRepository;
|
|
use Unsupervised\Schedular\GroupClass\EnrollmentRepository;
|
|
use Unsupervised\Schedular\GroupClass\SessionSchedule;
|
|
use Unsupervised\Schedular\Guardian\GuardianService;
|
|
use Unsupervised\Schedular\Offering\OfferingEndpoint;
|
|
use Unsupervised\Schedular\Offering\OfferingRepository;
|
|
use Unsupervised\Schedular\Payment\PaymentEndpoint;
|
|
use Unsupervised\Schedular\Payment\PaymentService;
|
|
use Unsupervised\Schedular\Payment\StudioSettings;
|
|
use Unsupervised\Schedular\Policy\PolicyEndpoint;
|
|
use Unsupervised\Schedular\Policy\PolicyRepository;
|
|
use Unsupervised\Schedular\Policy\PolicyService;
|
|
use Unsupervised\Schedular\Policy\PolicyVersionRepository;
|
|
use Unsupervised\Schedular\Registration\QuestionEndpoint;
|
|
use Unsupervised\Schedular\Registration\QuestionRepository;
|
|
use Unsupervised\Schedular\Registration\RegistrationGate;
|
|
|
|
class RestRegistrar {
|
|
|
|
public const NAMESPACE = 'us-scheduler/v1';
|
|
|
|
private AvailabilityEndpoint $availabilityEndpoint;
|
|
private BookingEndpoint $bookingEndpoint;
|
|
private OfferingEndpoint $offeringEndpoint;
|
|
private QuestionEndpoint $questionEndpoint;
|
|
private PolicyEndpoint $policyEndpoint;
|
|
private EnrollmentEndpoint $enrollmentEndpoint;
|
|
private PaymentEndpoint $paymentEndpoint;
|
|
|
|
public function __construct( AvailabilityRepository $availability, BookingRepository $bookings, OfferingRepository $offerings, QuestionRepository $questions, PolicyRepository $policies, PolicyVersionRepository $policyVersions, PolicyService $policyService, RegistrationGate $gate, EnrollmentRepository $enrollments, GroupAccessRepository $groupAccess, PaymentService $paymentService, GuardianService $guardians, LessonBooker $booker ) {
|
|
$this->availabilityEndpoint = new AvailabilityEndpoint( $availability, new WindowValidator( $offerings ) );
|
|
$this->bookingEndpoint = new BookingEndpoint( $availability, $bookings, $offerings, $gate, $paymentService, $booker, new CancellationPolicy( new StudioSettings() ), $guardians, new SessionSchedule( $enrollments, $offerings ) );
|
|
$this->offeringEndpoint = new OfferingEndpoint( $offerings, $groupAccess );
|
|
$this->questionEndpoint = new QuestionEndpoint( $questions, $offerings );
|
|
$this->policyEndpoint = new PolicyEndpoint( $policies, $policyVersions, $policyService );
|
|
$this->enrollmentEndpoint = new EnrollmentEndpoint( $enrollments, $offerings, $gate, $paymentService, $groupAccess, $guardians );
|
|
$this->paymentEndpoint = new PaymentEndpoint( $paymentService );
|
|
}
|
|
|
|
public function register(): void {
|
|
add_action( 'rest_api_init', [ $this, 'registerRoutes' ] );
|
|
}
|
|
|
|
public function registerRoutes(): void {
|
|
$this->availabilityEndpoint->registerRoutes( self::NAMESPACE );
|
|
$this->bookingEndpoint->registerRoutes( self::NAMESPACE );
|
|
$this->offeringEndpoint->registerRoutes( self::NAMESPACE );
|
|
$this->questionEndpoint->registerRoutes( self::NAMESPACE );
|
|
$this->policyEndpoint->registerRoutes( self::NAMESPACE );
|
|
$this->enrollmentEndpoint->registerRoutes( self::NAMESPACE );
|
|
$this->paymentEndpoint->registerRoutes( self::NAMESPACE );
|
|
}
|
|
}
|