*/ public const VALID_STATUSES = [ self::STATUS_AVAILABLE, self::STATUS_CONSUMED ]; public function __construct( public readonly int $studentId, public readonly float $amount, public readonly float $remaining, public readonly string $currency = 'CAD', public readonly ?int $sourcePaymentId = null, public readonly ?int $sourceLessonId = null, public readonly ?string $reason = null, public readonly string $status = self::STATUS_AVAILABLE, public readonly ?string $createdAt = null, public readonly ?string $updatedAt = null, public readonly ?int $id = null, ) {} public static function fromRow( \stdClass $row ): self { return new self( studentId: Val::int( $row->student_id ), amount: Val::float( $row->amount ), remaining: Val::float( $row->remaining ), currency: Val::string( $row->currency ), sourcePaymentId: Val::intOrNull( $row->source_payment_id ?? null ), sourceLessonId: Val::intOrNull( $row->source_lesson_id ?? null ), reason: Val::stringOrNull( $row->reason ?? null ), status: Val::string( $row->status ), createdAt: Val::stringOrNull( $row->created_at ?? null ), updatedAt: Val::stringOrNull( $row->updated_at ?? null ), id: Val::int( $row->id ), ); } public function isAvailable(): bool { return self::STATUS_AVAILABLE === $this->status && $this->remaining > 0.0; } /** * Returns a plain array representation of the credit. * * @return array */ public function toArray(): array { return [ 'id' => $this->id, 'student_id' => $this->studentId, 'amount' => $this->amount, 'remaining' => $this->remaining, 'currency' => $this->currency, 'source_payment_id' => $this->sourcePaymentId, 'source_lesson_id' => $this->sourceLessonId, 'reason' => $this->reason, 'status' => $this->status, 'created_at' => $this->createdAt, 'updated_at' => $this->updatedAt, ]; } }