<?php
namespace App\Entity;
use App\Entity\Traits\Timestampable;
use App\Repository\AgendaElementRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Groups;
#[ORM\HasLifecycleCallbacks]
#[ORM\Entity(repositoryClass: AgendaElementRepository::class)]
class AgendaElement
{
use Timestampable;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['getAgenda'])]
private ?int $id = null;
#[ORM\Column(type: Types::TIME_MUTABLE)]
#[Groups(['getAgenda'])]
private ?\DateTimeInterface $startAt = null;
#[ORM\Column(type: Types::TIME_MUTABLE)]
#[Groups(['getAgenda'])]
private ?\DateTimeInterface $endAt = null;
#[ORM\Column(length: 255)]
#[Groups(['getAgenda'])]
private ?int $duration = null;
#[ORM\Column(length: 255, nullable: true)]
#[Groups(['getAgenda'])]
private ?int $other = null;
#[ORM\ManyToOne(inversedBy: 'agendaElements')]
#[Groups(['getAgenda'])]
private ?Subject $subject = null;
#[ORM\ManyToOne(inversedBy: 'elements')]
#[ORM\JoinColumn(nullable: false)]
private ?AgendaDay $agendaDay = null;
#[ORM\Column(options: ["default" => false])]
private ?bool $isPermanence = false;
#[ORM\ManyToOne(inversedBy: 'agendaElements')]
#[ORM\JoinColumn(nullable: false)]
private ?User $author = null;
#[ORM\Column]
private ?bool $active = null;
#[ORM\Column(nullable: true)]
private ?\DateTimeImmutable $descativatedAt = null;
#[ORM\OneToMany(mappedBy: 'agendaElement', targetEntity: ProfTime::class)]
private Collection $profTimes;
#[ORM\ManyToOne(inversedBy: 'agendaElements')]
#[ORM\JoinColumn(nullable: false)]
private ?School $school = null;
#[ORM\ManyToOne(inversedBy: 'agendaElements')]
#[ORM\JoinColumn(nullable: false)]
private ?SchoolYear $year = null;
#[ORM\ManyToOne(inversedBy: 'agendaElements')]
#[ORM\JoinColumn(nullable: false)]
private ?TheClass $classe = null;
#[ORM\OneToMany(mappedBy: 'agendaElement', targetEntity: TeacherActivity::class, cascade: ['remove'], orphanRemoval: true)]
private Collection $teacherActivities;
#[ORM\OneToMany(mappedBy: 'agendaElement', targetEntity: TeacherAbsence::class, cascade: ['remove'], orphanRemoval: true)]
private Collection $teacherAbsences;
#[ORM\OneToMany(mappedBy: 'agendaElement', targetEntity: AttendanceActivity::class,cascade: ['remove'], orphanRemoval: true)]
private Collection $attendanceActivities;
#[ORM\OneToMany(mappedBy: 'agendaElement', targetEntity: AttendanceMissed::class, cascade: ['remove'], orphanRemoval: true)]
private Collection $attendanceMisseds;
#[ORM\Column(nullable: true)]
private ?int $position = null;
#[ORM\ManyToMany(targetEntity: TimeRange::class, inversedBy: 'agendaElements')]
private Collection $timeRanges;
#[ORM\OneToMany(mappedBy: 'agendaElement', targetEntity: Absence::class, cascade: ['remove'], orphanRemoval: true)]
private Collection $absences;
/**
* Cahier de texte : entrées saisies par le prof pour ce créneau précis
* (avec ou sans chapitre du programme national concerné).
*/
#[ORM\OneToMany(mappedBy: 'agendaElement', targetEntity: LessonLog::class, cascade: ['remove'], orphanRemoval: true)]
private Collection $lessonLogs;
public function __construct()
{
$this->profTimes = new ArrayCollection();
$this->teacherActivities = new ArrayCollection();
$this->teacherAbsences = new ArrayCollection();
$this->attendanceActivities = new ArrayCollection();
$this->attendanceMisseds = new ArrayCollection();
$this->timeRanges = new ArrayCollection();
$this->absences = new ArrayCollection();
$this->lessonLogs = new ArrayCollection();
}
public function __toString()
{
return $this->id;
}
public function getId(): ?int
{
return $this->id;
}
public function getStartAt(): ?\DateTimeInterface
{
return $this->startAt;
}
public function setStartAt(\DateTimeInterface $startAt): static
{
$this->startAt = $startAt;
return $this;
}
public function getEndAt(): ?\DateTimeInterface
{
return $this->endAt;
}
public function setEndAt(\DateTimeInterface $endAt): static
{
$this->endAt = $endAt;
return $this;
}
public function getDuration(): ?int
{
return $this->duration;
}
public function setDuration(int $duration): static
{
$this->duration = $duration;
return $this;
}
public function getOther(): ?int
{
return $this->other;
}
public function setOther(?int $other): static
{
$this->other = $other;
return $this;
}
public function getSubject(): ?Subject
{
return $this->subject;
}
public function setSubject(?Subject $subject): static
{
$this->subject = $subject;
return $this;
}
public function getAgendaDay(): ?AgendaDay
{
return $this->agendaDay;
}
public function setAgendaDay(?AgendaDay $agendaDay): static
{
$this->agendaDay = $agendaDay;
return $this;
}
public function getAuthor(): ?User
{
return $this->author;
}
public function setAuthor(?User $author): static
{
$this->author = $author;
return $this;
}
public function isActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): static
{
$this->active = $active;
return $this;
}
public function isPermanence(): ?bool { return $this->isPermanence; }
public function setIsPermanence(bool $isPermanence): static {
$this->isPermanence = $isPermanence;
return $this;
}
#[ORM\PrePersist]
#[ORM\PreUpdate]
public function syncMetadata(): void
{
if (!$this->timeRanges->isEmpty()) {
$ranges = $this->timeRanges->toArray();
usort($ranges, fn($a, $b) => $a->getPosition() <=> $b->getPosition());
// 1. Heures de début et fin
$this->startAt = $ranges[0]->getStartAt();
$this->endAt = end($ranges)->getEndAt();
// 2. Duration = Nombre de tranches (slots)
$this->duration = count($ranges);
}
}
#[ORM\PrePersist]
#[ORM\PreUpdate]
public function updateMetadata(): void
{
if (!$this->timeRanges->isEmpty()) {
$ranges = $this->timeRanges->toArray();
// Tri par position pour avoir le vrai début et la vraie fin
usort($ranges, fn($a, $b) => $a->getPosition() <=> $b->getPosition());
$this->startAt = $ranges[0]->getStartAt();
$this->endAt = end($ranges)->getEndAt();
// La durée est maintenant le nombre de tranches sélectionnées
$this->duration = count($ranges);
}
}
public function areRangesConsecutive(): bool
{
if ($this->timeRanges->isEmpty()) return false;
$positions = array_map(fn($r) => $r->getPosition(), $this->timeRanges->toArray());
sort($positions);
for ($i = 0; $i < count($positions) - 1; $i++) {
if ($positions[$i + 1] !== $positions[$i] + 1) return false;
}
return true;
}
public function getDescativatedAt(): ?\DateTimeImmutable
{
return $this->descativatedAt;
}
public function setDescativatedAt(?\DateTimeImmutable $descativatedAt): static
{
$this->descativatedAt = $descativatedAt;
return $this;
}
/**
* @return Collection<int, ProfTime>
*/
public function getProfTimes(): Collection
{
return $this->profTimes;
}
public function addProfTime(ProfTime $profTime): static
{
if (!$this->profTimes->contains($profTime)) {
$this->profTimes->add($profTime);
$profTime->setAgendaElement($this);
}
return $this;
}
public function removeProfTime(ProfTime $profTime): static
{
if ($this->profTimes->removeElement($profTime)) {
// set the owning side to null (unless already changed)
if ($profTime->getAgendaElement() === $this) {
$profTime->setAgendaElement(null);
}
}
return $this;
}
public function getSchool(): ?School
{
return $this->school;
}
public function setSchool(?School $school): static
{
$this->school = $school;
return $this;
}
public function getYear(): ?SchoolYear
{
return $this->year;
}
public function setYear(?SchoolYear $year): static
{
$this->year = $year;
return $this;
}
public function getClasse(): ?TheClass
{
return $this->classe;
}
public function setClasse(?TheClass $classe): static
{
$this->classe = $classe;
return $this;
}
/**
* @return Collection<int, TeacherActivity>
*/
public function getTeacherActivities(): Collection
{
return $this->teacherActivities;
}
public function addTeacherActivity(TeacherActivity $teacherActivity): static
{
if (!$this->teacherActivities->contains($teacherActivity)) {
$this->teacherActivities->add($teacherActivity);
$teacherActivity->setAgendaElement($this);
}
return $this;
}
public function removeTeacherActivity(TeacherActivity $teacherActivity): static
{
if ($this->teacherActivities->removeElement($teacherActivity)) {
// set the owning side to null (unless already changed)
if ($teacherActivity->getAgendaElement() === $this) {
$teacherActivity->setAgendaElement(null);
}
}
return $this;
}
/**
* @return Collection<int, TeacherAbsence>
*/
public function getTeacherAbsences(): Collection
{
return $this->teacherAbsences;
}
public function addTeacherAbsence(TeacherAbsence $teacherAbsence): static
{
if (!$this->teacherAbsences->contains($teacherAbsence)) {
$this->teacherAbsences->add($teacherAbsence);
$teacherAbsence->setAgendaElement($this);
}
return $this;
}
public function removeTeacherAbsence(TeacherAbsence $teacherAbsence): static
{
if ($this->teacherAbsences->removeElement($teacherAbsence)) {
// set the owning side to null (unless already changed)
if ($teacherAbsence->getAgendaElement() === $this) {
$teacherAbsence->setAgendaElement(null);
}
}
return $this;
}
/**
* @return Collection<int, AttendanceActivity>
*/
public function getAttendanceActivities(): Collection
{
return $this->attendanceActivities;
}
public function addAttendanceActivity(AttendanceActivity $attendanceActivity): static
{
if (!$this->attendanceActivities->contains($attendanceActivity)) {
$this->attendanceActivities->add($attendanceActivity);
$attendanceActivity->setAgendaElement($this);
}
return $this;
}
public function removeAttendanceActivity(AttendanceActivity $attendanceActivity): static
{
if ($this->attendanceActivities->removeElement($attendanceActivity)) {
// set the owning side to null (unless already changed)
if ($attendanceActivity->getAgendaElement() === $this) {
$attendanceActivity->setAgendaElement(null);
}
}
return $this;
}
/**
* @return Collection<int, AttendanceMissed>
*/
public function getAttendanceMisseds(): Collection
{
return $this->attendanceMisseds;
}
public function addAttendanceMissed(AttendanceMissed $attendanceMissed): static
{
if (!$this->attendanceMisseds->contains($attendanceMissed)) {
$this->attendanceMisseds->add($attendanceMissed);
$attendanceMissed->setAgendaElement($this);
}
return $this;
}
public function removeAttendanceMissed(AttendanceMissed $attendanceMissed): static
{
if ($this->attendanceMisseds->removeElement($attendanceMissed)) {
// set the owning side to null (unless already changed)
if ($attendanceMissed->getAgendaElement() === $this) {
$attendanceMissed->setAgendaElement(null);
}
}
return $this;
}
public function getPosition(): ?int
{
return $this->position;
}
public function setPosition(?int $position): static
{
$this->position = $position;
return $this;
}
/**
* @return Collection<int, TimeRange>
*/
public function getTimeRanges(): Collection
{
return $this->timeRanges;
}
public function addTimeRange(TimeRange $timeRange): static
{
if (!$this->timeRanges->contains($timeRange)) {
$this->timeRanges->add($timeRange);
}
return $this;
}
public function removeTimeRange(TimeRange $timeRange): static
{
$this->timeRanges->removeElement($timeRange);
return $this;
}
/**
* @return Collection<int, Absence>
*/
public function getAbsences(): Collection
{
return $this->absences;
}
public function addAbsence(Absence $absence): static
{
if (!$this->absences->contains($absence)) {
$this->absences->add($absence);
$absence->setAgendaElement($this);
}
return $this;
}
public function removeAbsence(Absence $absence): static
{
if ($this->absences->removeElement($absence)) {
// set the owning side to null (unless already changed)
if ($absence->getAgendaElement() === $this) {
$absence->setAgendaElement(null);
}
}
return $this;
}
/**
* @return Collection<int, LessonLog>
*/
public function getLessonLogs(): Collection
{
return $this->lessonLogs;
}
public function addLessonLog(LessonLog $lessonLog): static
{
if (!$this->lessonLogs->contains($lessonLog)) {
$this->lessonLogs->add($lessonLog);
$lessonLog->setAgendaElement($this);
}
return $this;
}
public function removeLessonLog(LessonLog $lessonLog): static
{
if ($this->lessonLogs->removeElement($lessonLog)) {
if ($lessonLog->getAgendaElement() === $this) {
$lessonLog->setAgendaElement(null);
}
}
return $this;
}
}