<?php
namespace App\Entity;
use App\Entity\Traits\Timestampable;
use App\Repository\StudentCapsuleProgressRepository;
use Doctrine\ORM\Mapping as ORM;
// Progression d'un élève sur une Capsule (consultation, pas seulement les
// activités) — un élève peut avoir lu une capsule sans avoir encore répondu à
// ses activités. `classe`/`year` sont dénormalisés (comme Absences.yearId...)
// pour permettre le reporting enseignant par classe sans jointure via Student.
#[ORM\HasLifecycleCallbacks]
#[ORM\Entity(repositoryClass: StudentCapsuleProgressRepository::class)]
#[ORM\UniqueConstraint(name: 'uniq_student_capsule_year', columns: ['student_id', 'capsule_id', 'year_id'])]
class StudentCapsuleProgress
{
use Timestampable;
public const STATUS_NOT_STARTED = 'not_started';
public const STATUS_IN_PROGRESS = 'in_progress';
public const STATUS_DONE = 'done';
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private ?Student $student = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private ?Capsule $capsule = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?TheClass $classe = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?SchoolYear $year = null;
#[ORM\Column(length: 20, options: ['default' => self::STATUS_NOT_STARTED])]
private string $status = self::STATUS_NOT_STARTED;
#[ORM\Column]
private int $progressPercent = 0;
// Temps cumulé (en secondes) passé par l'élève sur cette capsule, toutes
// sessions confondues — le mobile envoie des mises à jour périodiques
// (heartbeat) pendant la lecture. Comparé à Capsule::timeLimitSeconds
// pour déclencher le verrouillage de l'écran élève.
#[ORM\Column]
private int $timeSpentSeconds = 0;
#[ORM\Column(type: 'datetime', nullable: true)]
private ?\DateTimeInterface $startedAt = null;
#[ORM\Column(type: 'datetime', nullable: true)]
private ?\DateTimeInterface $completedAt = null;
public function getId(): ?int
{
return $this->id;
}
public function getStudent(): ?Student
{
return $this->student;
}
public function setStudent(?Student $student): static
{
$this->student = $student;
return $this;
}
public function getCapsule(): ?Capsule
{
return $this->capsule;
}
public function setCapsule(?Capsule $capsule): static
{
$this->capsule = $capsule;
return $this;
}
public function getClasse(): ?TheClass
{
return $this->classe;
}
public function setClasse(?TheClass $classe): static
{
$this->classe = $classe;
return $this;
}
public function getYear(): ?SchoolYear
{
return $this->year;
}
public function setYear(?SchoolYear $year): static
{
$this->year = $year;
return $this;
}
public function getStatus(): string
{
return $this->status;
}
public function setStatus(string $status): static
{
$this->status = $status;
return $this;
}
public function getProgressPercent(): int
{
return $this->progressPercent;
}
public function setProgressPercent(int $progressPercent): static
{
$this->progressPercent = $progressPercent;
return $this;
}
public function getTimeSpentSeconds(): int
{
return $this->timeSpentSeconds;
}
public function setTimeSpentSeconds(int $timeSpentSeconds): static
{
$this->timeSpentSeconds = $timeSpentSeconds;
return $this;
}
public function getStartedAt(): ?\DateTimeInterface
{
return $this->startedAt;
}
public function setStartedAt(?\DateTimeInterface $startedAt): static
{
$this->startedAt = $startedAt;
return $this;
}
public function getCompletedAt(): ?\DateTimeInterface
{
return $this->completedAt;
}
public function setCompletedAt(?\DateTimeInterface $completedAt): static
{
$this->completedAt = $completedAt;
return $this;
}
}