src/Entity/ChannelUserData/Cursus/AbstractCursus.php line 72

Open in your IDE?
  1. <?php
  2. namespace App\Entity\ChannelUserData\Cursus;
  3. use App\Entity\Account\User;
  4. use App\Entity\Channel\ChannelLicencesResourceInterface;
  5. use App\Entity\Channel\ChannelUserCursusPermission;
  6. use App\Entity\Channel\Organization;
  7. use App\Entity\Channel\Place;
  8. use App\Entity\Channel\Training;
  9. use App\Entity\ChannelUserData\Activity\ActivityFeed;
  10. use App\Entity\ChannelUserData\ChannelUserData;
  11. use App\Entity\Common\ImportableData\ImportableDataInterface;
  12. use App\Entity\Common\ImportableData\ImportableDataTrait;
  13. use App\Entity\Sync\SyncableInterface;
  14. use App\Enum\ChannelUserData\Activity\CursusActivityTagEnum;
  15. use App\Enum\ChannelUserData\CursusFoundingStatusEnum;
  16. use App\Enum\ChannelUserData\CursusInternshipStatus;
  17. use App\Enum\ChannelUserData\CursusStoppedStatusEnum;
  18. use App\Enum\ChannelUserData\ExamStatusEnum;
  19. use App\Repository\ChannelUserData\Cursus\AbstractCursusRepository;
  20. use App\Validator\Constraints as AppAssert;
  21. use App\Validator\Constraints\AbstractCursusConstraint;
  22. use App\Validator\Constraints\ChannelLicensesConstraint;
  23. use DateTimeInterface;
  24. use Doctrine\Common\Collections\ArrayCollection;
  25. use Doctrine\Common\Collections\Collection;
  26. use Doctrine\ORM\Mapping as ORM;
  27. use Drosalys\Bundle\ApiBundle\Serializer\Attributes\IdGroups;
  28. use Nellapp\Bundle\SDKBundle\Auth\Entity\UserInterface;
  29. use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelInterface;
  30. use Nellapp\Bundle\SDKBundle\Channel\Entity\Cursus\AbstractCursusInterface;
  31. use Nellapp\Bundle\SDKBundle\Channel\Entity\Cursus\AbstractCursusMethodTrait;
  32. use Nellapp\Bundle\SDKBundle\Enum\ChannelUserData\CursusCourseEnum;
  33. use Nellapp\Bundle\SDKBundle\Enum\ChannelUserData\CursusModalityEnum;
  34. use Nellapp\Bundle\SDKBundle\Enum\ChannelUserData\CursusSuspensionReasonEnum;
  35. use Nellapp\Bundle\SDKBundle\Permission\Entity\ChannelResourceInterface;
  36. use Nellapp\Bundle\SDKBundle\Permission\UserOwner\UserOwnerResourceInterface;
  37. use Nellapp\Bundle\SDKBundle\Permission\UsersResource\UsersResourceInterface;
  38. use Nellapp\Bundle\SDKBundle\Sync\EntityKeys;
  39. use Nellapp\Bundle\SDKBundle\TrackData\Attribute\TrackEntity;
  40. use Nellapp\Bundle\SDKBundle\TrackData\Attribute\TrackFIeld;
  41. use Nellapp\Bundle\SDKBundle\Utils\NellappFormatService;
  42. use Symfony\Component\Serializer\Annotation as Serial;
  43. use Symfony\Component\Validator\Constraints as Assert;
  44. #[
  45.     ORM\Entity(repositoryClassAbstractCursusRepository::class),
  46.     ORM\Table(name'channel_user_data_cursus'),
  47.     ORM\InheritanceType('JOINED'),
  48.     ORM\DiscriminatorColumn(name'type'type'string'),
  49.     ORM\DiscriminatorMap(['session-type' => SessionCursus::class, 'training-type' => TrainingCursus::class]),
  50.     AbstractCursusConstraint(message'abstract_cursus.abstract_cursus_constraint.message'),
  51.     TrackEntity(
  52.         fieldGroups: [
  53.             'progress' => [
  54.                 'tags' => [CursusActivityTagEnum::PROGRESSION],
  55.             ],
  56.             'internship' => [
  57.                 'tags' => [CursusActivityTagEnum::INTERNSHIP],
  58.             ],
  59.             'founding' => [
  60.                 'tags' => [CursusActivityTagEnum::FOUNDING]
  61.             ],
  62.             'exam' => [
  63.                 'tags' => [CursusActivityTagEnum::EXAM],
  64.             ]
  65.         ]
  66.     ),
  67.     ChannelLicensesConstraint
  68. ]
  69. abstract class AbstractCursus implements AbstractCursusInterfaceSyncableInterfaceChannelLicencesResourceInterfaceChannelResourceInterfaceImportableDataInterfaceUserOwnerResourceInterfaceUsersResourceInterface
  70. {
  71.     use AbstractCursusMethodTrait;
  72.     use ImportableDataTrait;
  73.     #[ORM\IdORM\GeneratedValueORM\Column(type'integer')]
  74.     #[Serial\Groups(['Sync''GlobalJSVariable'])]
  75.     private ?int $id null;
  76.     #[ORM\ManyToOne(targetEntityChannelUserData::class, cascade: ['persist'], inversedBy'cursuses')]
  77.     #[ORM\JoinColumn(nullablefalseonDelete'CASCADE')]
  78.     #[IdGroups(['Sync'])]
  79.     #[Assert\NotBlank]
  80.     private ?ChannelUserData $channelUserData null;
  81.     #[
  82.         ORM\ManyToOne(targetEntityTraining::class),
  83.         ORM\JoinColumn(nullabletrueonDelete'SET NULL')
  84.     ]
  85.     #[IdGroups(['Sync'])]
  86.     private ?Training $training null;
  87.     #[ORM\Column(type'datetime')]
  88.     #[Serial\Groups(['Sync'])]
  89.     #[Assert\NotBlank(groups: ['CursusProgress'])]
  90.     #[TrackFIeld(name'cursus.entity.startAt.label'fieldKey'progress', callable: 'format'callableParams: ['d/m/Y'])]
  91.     private ?DateTimeInterface $startAt null;
  92.     #[ORM\Column(type'datetime')]
  93.     #[Serial\Groups(['Sync'])]
  94.     #[
  95.         Assert\GreaterThanOrEqual(propertyPath'startAt'message'abstract_cursus.endAt.GreaterThan'groups: ['CursusProgress''Default']),
  96.         AppAssert\DateWithinIntervalOf(reference'startAt'maxInterval'P5Y'message'abstract_cursus.endAt.MaxDate'groups: ['CursusProgress''Default']),
  97.         Assert\NotBlank(groups: ['CursusProgress'])
  98.     ]
  99.     #[TrackFIeld(name'cursus.entity.endAt.label'fieldKey'progress', callable: 'format'callableParams: ['d/m/Y'])]
  100.     private ?DateTimeInterface $endAt null;
  101.     #[ORM\Column(type'integer'nullabletrue)]
  102.     #[
  103.         Assert\Type(type'integer'groups: ['CursusProgress']),
  104.         Assert\GreaterThanOrEqual(value1),
  105.         Assert\LessThanOrEqual(value24)
  106.     ]
  107.     #[TrackFIeld(name'cursus.entity.monthDuration.label'fieldKey'progress')]
  108.     private ?int $monthDuration null;
  109.     #[ORM\OneToOne(inversedBy'cursus'targetEntityAbstractCursusProgression::class, cascade: ['persist''remove'], orphanRemovaltrue)]
  110.     #[ORM\JoinColumn(nullabletrueonDelete'SET NULL')]
  111.     private ?AbstractCursusProgression $cursusProgression null;
  112.     #[ORM\Column(type'integer'nullabletrue)]
  113.     #[TrackFIeld(name'cursus.entity.physicalDuration.label'fieldKey'progress', callable: 'formatDuration'callableClassNellappFormatService::class)]
  114.     #[
  115.         Assert\Type(type'integer'),
  116.         Assert\GreaterThanOrEqual(value0)
  117.     ]
  118.     private ?int $physicalDuration null;
  119.     #[ORM\Column(type'integer'nullabletrue)]
  120.     #[TrackFIeld(name'cursus.entity.distanceSyncDuration.label'fieldKey'progress', callable: 'formatDuration'callableClassNellappFormatService::class)]
  121.     #[
  122.         Assert\Type(type'integer'),
  123.         Assert\GreaterThanOrEqual(value0)
  124.     ]
  125.     private ?int $distanceSyncDuration null;
  126.     #[ORM\Column(type'integer'nullabletrue)]
  127.     #[TrackFIeld(name'cursus.entity.distanceAsyncDuration.label'fieldKey'progress', callable: 'formatDuration'callableClassNellappFormatService::class)]
  128.     #[
  129.         Assert\Type(type'integer'),
  130.         Assert\GreaterThanOrEqual(value0)
  131.     ]
  132.     private ?int $distanceAsyncDuration null;
  133.     #[ORM\Column(type'integer'nullabletrue)]
  134.     #[TrackFIeld(name'cursus.entity.examDuration.label'fieldKey'progress', callable: 'formatDuration'callableClassNellappFormatService::class)]
  135.     #[
  136.         Assert\Type(type'integer'),
  137.         Assert\GreaterThanOrEqual(value0)
  138.     ]
  139.     private ?int $examDuration null;
  140.     #[ORM\Column(type'integer'nullabletrue)]
  141.     #[TrackFIeld(name'cursus.entity.internshipDuration.label'fieldKey'progress', callable: 'formatDuration'callableClassNellappFormatService::class)]
  142.     #[
  143.         Assert\Type(type'integer'),
  144.         Assert\GreaterThanOrEqual(value0)
  145.     ]
  146.     private ?int $internshipDuration null;
  147.     #[ORM\Column(type'integer'nullabletrue)]
  148.     #[TrackFIeld(name'cursus.entity.cursusModality.label'fieldKey'progress', callable: 'getStatusKey'callableClassCursusModalityEnum::class)]
  149.     #[Assert\NotBlank(groups: ['CursusProgress'])]
  150.     #[Serial\Groups(['Sync'])]
  151.     private ?int $cursusModality null;
  152.     #[ORM\Column(type'integer'nullabletrue)]
  153.     #[TrackFIeld(name'cursus.entity.cursusCourse.label'fieldKey'progress', callable: 'getStatusKey'callableClassCursusCourseEnum::class)]
  154.     #[Assert\NotBlank(groups: ['CursusProgress'])]
  155.     #[Serial\Groups(['Sync'])]
  156.     private ?int $cursusCourse null;
  157.     #[ORM\Column(type'integer'nullabletrue)]
  158.     #[TrackFIeld(name'cursus.entity.foundingStatus.label'fieldKey'founding', callable: 'getStatusKey'callableClassCursusFoundingStatusEnum::class)]
  159.     #[Assert\Choice(
  160.         callback: [CursusFoundingStatusEnum::class, 'getChoices'],
  161.         groups: ['CursusFounding']
  162.     )]
  163.     private ?int $foundingStatus null;
  164.     #[ORM\ManyToOne(targetEntityOrganization::class)]
  165.     #[ORM\JoinColumn(nullabletrueonDelete"SET NULL")]
  166.     private ?Organization $organization null;
  167.     #[ORM\OneToMany(mappedBy'cursus'targetEntityFounder::class, cascade: ['remove'], orphanRemovaltrue)]
  168.     private Collection $founders;
  169.     #[ORM\Column(type'integer'nullabletrue)]
  170.     #[
  171.         Assert\NotBlank(groups: ['CursusInternship']),
  172.         Assert\Type(type'integer'groups: ['CursusInternship'])
  173.     ]
  174.     #[TrackFIeld(name'cursus.entity.internshipStatus.label'fieldKey'internship', callable: 'getStatusKey'callableClassCursusInternshipStatus::class)]
  175.     private ?int $internshipStatus 0;
  176.     #[ORM\OneToMany(mappedBy'cursus'targetEntityInternship::class, cascade: ['remove''persist'], orphanRemovaltrue)]
  177.     private Collection $internships;
  178.     #[ORM\Column(type'integer'nullabletrue)]
  179.     #[Serial\Groups(['Sync'])]
  180.     #[TrackFIeld(name'cursus.entity.stoppedStatus.label'fieldKey'progress', callable: 'getStatusKey'callableClassCursusStoppedStatusEnum::class)]
  181.     private ?int $stoppedStatus null;
  182.     #[ORM\Column(type'integer'nullabletrue)]
  183.     #[Assert\NotBlank(groups: ['CursusStatus'])]
  184.     #[TrackFIeld(name'cursus.entity.stoppedDetails.label'fieldKey'progress', callable: 'getStatusKey'callableClassCursusStoppedStatusEnum::class)]
  185.     private ?int $stoppedDetails null;
  186.     #[ORM\Column(type'datetime'nullabletrue)]
  187.     #[Serial\Groups(['Sync'])]
  188.     #[
  189.         Assert\NotBlank(message'abstract_cursus.stoppedAt.NotBlank'groups: ['CursusStatus']),
  190.         Assert\GreaterThanOrEqual('-45 days'message'abstract_cursus.stoppedAt.GreaterThanOrEqual'groups: ['CursusStatus']),
  191.     ]
  192.     #[TrackFIeld(name'cursus.entity.stoppedAt.label'fieldKey'progress', callable: 'format'callableParams: ['d/m/Y'])]
  193.     private ?\DateTimeInterface $stoppedAt null;
  194.     #[ORM\Column(type'text'nullabletrue)]
  195.     #[
  196.         Assert\Length(max500groups: ['CursusStatus'])
  197.     ]
  198.     private ?string $stoppedInfos null;
  199.     #[ORM\Column(type'datetime'nullabletrue)]
  200.     #[Serial\Groups(['Sync'])]
  201.     #[TrackFIeld(name'cursus.entity.suspendedAt.label'fieldKey'progress', callable: 'format'callableParams: ['d/m/Y'])]
  202.     private ?\DateTimeInterface $suspendedAt null;
  203.     #[ORM\Column(type'integer'nullabletrue)]
  204.     #[Serial\Groups(['Sync'])]
  205.     #[TrackFIeld(name'cursus.entity.suspendedFor.label'fieldKey'progress', callable: 'getStatusKey'callableClassCursusSuspensionReasonEnum::class)]
  206.     private ?int $suspendedFor null;
  207.     #[ORM\ManyToOne(targetEntityPlace::class)]
  208.     #[ORM\JoinColumn(nullabletrueonDelete'SET NULL')]
  209.     #[TrackFIeld(name'cursus.entity.examPlace.label'fieldKey'exam')]
  210.     private ?Place $examPlace null;
  211.     #[ORM\Column(type'datetime'nullabletrue)]
  212.     #[TrackFIeld(
  213.         name'cursus.entity.examSession.label',
  214.         fieldKey'exam',
  215.         callable: 'format',
  216.         callableParams: ['m/Y'])
  217.     ]
  218.     #[Assert\NotBlank(groups: ['CursusExam'])]
  219.     private ?DateTimeInterface $examSession null;
  220.     #[ORM\Column(type'string'nullabletrue)]
  221.     #[TrackFIeld(name'cursus.entity.examCeres.label'fieldKey'exam')]
  222.     #[
  223.         Assert\Length(max255groups: ['CursusExam'])
  224.     ]
  225.     private ?string $examCeres null;
  226.     #[ORM\Column(type'integer'nullabletrue)]
  227.     #[TrackFIeld(name'cursus.entity.examStatus.label'fieldKey'exam', callable: 'getStatusKey'callableClassExamStatusEnum::class)]
  228.     #[Assert\Choice(
  229.         callback: [ExamStatusEnum::class, 'getChoices'],
  230.         groups: ['CursusExam']
  231.     )]
  232.     private ?int $examStatus null;
  233.     #[ORM\Column(type'string'nullabletrue)]
  234.     #[TrackFIeld(name'cursus.entity.examCCP.label'fieldKey'exam')]
  235.     #[
  236.         Assert\Length(max255groups: ['CursusExam'])
  237.     ]
  238.     private ?string $examCCP null;
  239.     #[ORM\OneToMany(mappedBy'cursus'targetEntityExam::class, cascade: ['remove'], orphanRemovaltrue)]
  240.     private Collection $exams;
  241.     #[ORM\ManyToOne(targetEntityPlace::class)]
  242.     #[ORM\JoinColumn(nullabletrueonDelete'SET NULL')]
  243.     #[TrackFIeld(name'cursus.entity.place.label'fieldKey'progress')]
  244.     #[IdGroups(['Sync'])]
  245.     private ?Place $place null;
  246.     #[ORM\OneToMany(mappedBy'cursus'targetEntityReportDetails::class, cascade: ['remove'], fetch'EXTRA_LAZY'orphanRemovaltrue)]
  247.     private Collection $reportDetailsList;
  248.     #[ORM\OneToOne(targetEntityActivityFeed::class, cascade: ['remove''persist'], orphanRemovaltrue)]
  249.     #[ORM\JoinColumn(nullablefalse)]
  250.     private ?ActivityFeed $activityFeed null;
  251.     public function __construct()
  252.     {
  253.         $this->founders = new ArrayCollection();
  254.         $this->internships = new ArrayCollection();
  255.         $this->exams = new ArrayCollection();
  256.         $this->reportDetailsList = new ArrayCollection();
  257.     }
  258.     public static function getSyncKey(): string
  259.     {
  260.         return EntityKeys::ABSTRACT_CURSUS;
  261.     }
  262.     public function getSyncDisplayLabel(): string
  263.     {
  264.         return $this->getLabel() ?? 'unknown';
  265.     }
  266.     abstract public function getLabelType(): string;
  267.     public static function getPermissionResourceClass(): ?string
  268.     {
  269.         return ChannelUserCursusPermission::class;
  270.     }
  271.     public function getUserOwners(): array
  272.     {
  273.         $learner $this->getChannelUserData()?->getUser();
  274.         return $learner ? [$learner] : [];
  275.     }
  276.     #[Serial\Groups(['GlobalJSVariable'])]
  277.     public function getLearnerName(): ?string
  278.     {
  279.         return $this->getChannelUserData()?->getUser();
  280.     }
  281.     public function __toString(): string
  282.     {
  283.         return 'cursus ' $this->getLabel() . ' pour ' $this->getChannelUserData()?->getUser();
  284.     }
  285.     public function isTrainingType(): bool
  286.     {
  287.         return $this instanceof TrainingCursus;
  288.     }
  289.     public function isSessionType(): bool
  290.     {
  291.         return $this instanceof SessionCursus;
  292.     }
  293.     public function getChannel(): ?ChannelInterface
  294.     {
  295.         return $this->getChannelUserData()?->getChannel();
  296.     }
  297.     public function getOwnerChannel(): ?ChannelInterface
  298.     {
  299.         return $this->getChannel();
  300.     }
  301.     public function hasOneOralExam(): bool
  302.     {
  303.         if (!$this->getExams()->isEmpty()) {
  304.             /** @var Exam $exam */
  305.             foreach ($this->getExams() as $exam) {
  306.                 if ($exam->getType() === $exam::ORAL_TYPE) {
  307.                     return true;
  308.                 }
  309.             }
  310.         }
  311.         return false;
  312.     }
  313.     public function hasUser(?UserInterface $user, array $tags = []): bool
  314.     {
  315.         if (!in_array('internship_tutor'$tags)) {
  316.             return false;
  317.         }
  318.         if (!$user instanceof User) {
  319.             return false;
  320.         }
  321.         return $this->getInternships()->exists(function ($kInternship $internship) use ($user): bool {
  322.             return $internship->getTutor()?->getUser() === $user && $internship->isActiveWithDelays();
  323.         });
  324.     }
  325.     public function getLabel(): ?string
  326.     {
  327.         return $this->training?->getName();
  328.     }
  329.     public function getTotalDuration(): ?int
  330.     {
  331.         return $this->getPhysicalDurationDisplayed()
  332.             + $this->getDistanceAsyncDurationDisplayed()
  333.             + $this->getDistanceSyncDurationDisplayed()
  334.             + $this->getInternshipDurationDisplayed()
  335.             + $this->getExamDurationDisplayed();
  336.     }
  337.     public function getPhysicalDuration(): ?int
  338.     {
  339.         return $this->physicalDuration;
  340.     }
  341.     public function setPhysicalDuration(?int $physicalDuration): self
  342.     {
  343.         $this->physicalDuration $physicalDuration;
  344.         return $this;
  345.     }
  346.     public function getDistanceSyncDuration(): ?int
  347.     {
  348.         return $this->distanceSyncDuration;
  349.     }
  350.     public function setDistanceSyncDuration(?int $distanceSyncDuration): self
  351.     {
  352.         $this->distanceSyncDuration $distanceSyncDuration;
  353.         return $this;
  354.     }
  355.     public function getDistanceAsyncDuration(): ?int
  356.     {
  357.         return $this->distanceAsyncDuration;
  358.     }
  359.     public function setDistanceAsyncDuration(?int $distanceAsyncDuration): self
  360.     {
  361.         $this->distanceAsyncDuration $distanceAsyncDuration;
  362.         return $this;
  363.     }
  364.     public function getExamDuration(): ?int
  365.     {
  366.         return $this->examDuration;
  367.     }
  368.     public function setExamDuration(?int $examDuration): AbstractCursus
  369.     {
  370.         $this->examDuration $examDuration;
  371.         return $this;
  372.     }
  373.     public function getInternshipDuration(): ?int
  374.     {
  375.         return $this->internshipDuration;
  376.     }
  377.     public function setInternshipDuration(?int $internshipDuration): AbstractCursus
  378.     {
  379.         $this->internshipDuration $internshipDuration;
  380.         return $this;
  381.     }
  382.     public function getFoundingStatus(): ?int
  383.     {
  384.         return $this->foundingStatus;
  385.     }
  386.     public function setFoundingStatus(?int $foundingStatus): AbstractCursus
  387.     {
  388.         $this->foundingStatus $foundingStatus;
  389.         return $this;
  390.     }
  391.     public function getFounders(): Collection
  392.     {
  393.         return $this->founders;
  394.     }
  395.     public function addFounder(Founder $founder): static
  396.     {
  397.         if (!$this->founders->contains($founder)) {
  398.             $this->founders->add($founder);
  399.         }
  400.         return $this;
  401.     }
  402.     public function setFounders(Collection $founders): AbstractCursus
  403.     {
  404.         $this->founders $founders;
  405.         return $this;
  406.     }
  407.     /**
  408.      * @return Collection<Internship>
  409.      */
  410.     public function getInternships(): Collection
  411.     {
  412.         return $this->internships;
  413.     }
  414.     public function addInternship(Internship $internship): static
  415.     {
  416.         if (!$this->internships->contains($internship)) {
  417.             $this->internships->add($internship);
  418.         }
  419.         return $this;
  420.     }
  421.     public function setInternships(Collection $internships): AbstractCursus
  422.     {
  423.         $this->internships $internships;
  424.         return $this;
  425.     }
  426.     public function getInternshipStatus(): ?int
  427.     {
  428.         return $this->internshipStatus;
  429.     }
  430.     public function setInternshipStatus(?int $internshipStatus): AbstractCursus
  431.     {
  432.         $this->internshipStatus $internshipStatus;
  433.         return $this;
  434.     }
  435.     public function getMonthDuration(): ?int
  436.     {
  437.         return $this->monthDuration;
  438.     }
  439.     public function setMonthDuration(?int $monthDuration): AbstractCursus
  440.     {
  441.         $this->monthDuration $monthDuration;
  442.         return $this;
  443.     }
  444.     public function getCursusProgression(): ?AbstractCursusProgression
  445.     {
  446.         return $this->cursusProgression;
  447.     }
  448.     public function setCursusProgression(?AbstractCursusProgression $cursusProgression): AbstractCursus
  449.     {
  450.         $this->cursusProgression $cursusProgression;
  451.         return $this;
  452.     }
  453.     public function getExamPlace(): ?Place
  454.     {
  455.         return $this->examPlace;
  456.     }
  457.     public function setExamPlace(?Place $examPlace): AbstractCursus
  458.     {
  459.         $this->examPlace $examPlace;
  460.         return $this;
  461.     }
  462.     public function getExamSession(): ?DateTimeInterface
  463.     {
  464.         return $this->examSession;
  465.     }
  466.     public function setExamSession(?DateTimeInterface $examSession): AbstractCursus
  467.     {
  468.         $this->examSession $examSession;
  469.         return $this;
  470.     }
  471.     public function getExamCeres(): ?string
  472.     {
  473.         return $this->examCeres;
  474.     }
  475.     public function setExamCeres(?string $examCeres): AbstractCursus
  476.     {
  477.         $this->examCeres $examCeres;
  478.         return $this;
  479.     }
  480.     public function getExamStatus(): ?int
  481.     {
  482.         return $this->examStatus;
  483.     }
  484.     public function setExamStatus(?int $examStatus): AbstractCursus
  485.     {
  486.         $this->examStatus $examStatus;
  487.         return $this;
  488.     }
  489.     public function getExamCCP(): ?string
  490.     {
  491.         return $this->examCCP;
  492.     }
  493.     public function setExamCCP(?string $examCCP): AbstractCursus
  494.     {
  495.         $this->examCCP $examCCP;
  496.         return $this;
  497.     }
  498.     public function getExams(): Collection
  499.     {
  500.         return $this->exams;
  501.     }
  502.     public function addExam(Exam $exam): AbstractCursus
  503.     {
  504.         if (!$this->getExams()->contains($exam)) {
  505.             $this->getExams()->add($exam);
  506.         }
  507.         return $this;
  508.     }
  509.     public function setExams(Collection $exams): AbstractCursus
  510.     {
  511.         $this->exams $exams;
  512.         return $this;
  513.     }
  514.     public function getStoppedInfos(): ?string
  515.     {
  516.         return $this->stoppedInfos;
  517.     }
  518.     public function setStoppedInfos(?string $stoppedInfos): AbstractCursus
  519.     {
  520.         $this->stoppedInfos $stoppedInfos;
  521.         return $this;
  522.     }
  523.     public function getStoppedDetails(): ?int
  524.     {
  525.         return $this->stoppedDetails;
  526.     }
  527.     public function setStoppedDetails(?int $stoppedDetails): AbstractCursus
  528.     {
  529.         $this->stoppedDetails $stoppedDetails;
  530.         return $this;
  531.     }
  532.     public function getPlace(): ?Place
  533.     {
  534.         return $this->place;
  535.     }
  536.     public function setPlace(?Place $place): static
  537.     {
  538.         $this->place $place;
  539.         return $this;
  540.     }
  541.     public function getPhysicalDurationDisplayed(): ?int
  542.     {
  543.         if ($this->getPhysicalDuration() !== null && $this->getPhysicalDuration() !== 0) {
  544.             return $this->getPhysicalDuration();
  545.         }
  546.         if ($this instanceof SessionCursus) {
  547.             return $this->getSession()?->getDurationInCenter();
  548.         }
  549.         return null;
  550.     }
  551.     public function getDistanceAsyncDurationDisplayed(): ?int
  552.     {
  553.         if ($this->getDistanceAsyncDuration() !== null && $this->getDistanceAsyncDuration() !== 0) {
  554.             return $this->getDistanceAsyncDuration();
  555.         }
  556.         if ($this instanceof SessionCursus) {
  557.             return $this->getSession()?->getDurationInELearning();
  558.         }
  559.         return null;
  560.     }
  561.     public function getDistanceSyncDurationDisplayed(): ?int
  562.     {
  563.         if ($this->getDistanceSyncDuration() !== null && $this->getDistanceSyncDuration() !== 0) {
  564.             return $this->getDistanceSyncDuration();
  565.         }
  566.         if ($this instanceof SessionCursus) {
  567.             return $this->getSession()?->getDurationInVisio();
  568.         }
  569.         return null;
  570.     }
  571.     public function getInternshipDurationDisplayed(): ?int
  572.     {
  573.         if ($this->getInternshipDuration() !== null && $this->getInternshipDuration() !== 0) {
  574.             return $this->getInternshipDuration();
  575.         }
  576.         if ($this instanceof SessionCursus) {
  577.             return $this->getSession()?->getDurationInCompany();
  578.         }
  579.         if (!$this->getInternships()->isEmpty()) {
  580.             $internshipDuration 0;
  581.             /** @var Internship $internship */
  582.             foreach ($this->getInternships() as $internship) {
  583.                 if ($internship->getDuration() !== null) {
  584.                     $internshipDuration += $internship->getDuration();
  585.                 }
  586.             }
  587.             return $internshipDuration;
  588.         }
  589.         return null;
  590.     }
  591.     public function getInternshipDurationForProgress(): ?int
  592.     {
  593.         if ($this->getInternshipDuration() !== null  && $this->getInternshipDuration() !== 0) {
  594.             return $this->getInternshipDuration();
  595.         }
  596.         if (!$this->getInternships()->isEmpty()) {
  597.             $internshipDuration 0;
  598.             /** @var Internship $internship */
  599.             foreach ($this->getInternships() as $internship) {
  600.                 if ($internship->getDuration() !== null) {
  601.                     $internshipDuration += $internship->getDuration();
  602.                 }
  603.             }
  604.             return $internshipDuration;
  605.         }
  606.         return null;
  607.     }
  608.     public function getExamDurationDisplayed(): ?int
  609.     {
  610.         if ($this->getExamDuration() !== null && $this->getExamDuration() !== 0) {
  611.             return $this->getExamDuration();
  612.         }
  613.         if ($this instanceof SessionCursus) {
  614.             return $this->getSession()?->getDurationInExam();
  615.         }
  616.         return null;
  617.     }
  618.     public function getOrganization(): ?Organization
  619.     {
  620.         return $this->organization;
  621.     }
  622.     public function setOrganization(?Organization $organization): AbstractCursus
  623.     {
  624.         $this->organization $organization;
  625.         return $this;
  626.     }
  627.     public function getReportDetailsList(): Collection
  628.     {
  629.         return $this->reportDetailsList ?? $this->reportDetailsList = new ArrayCollection();
  630.     }
  631.     public function setReportDetailsList(Collection $reportDetailsList): AbstractCursus
  632.     {
  633.         $this->reportDetailsList $reportDetailsList;
  634.         return $this;
  635.     }
  636.     public function getActivityFeed(): ?ActivityFeed
  637.     {
  638.         return $this->activityFeed;
  639.     }
  640.     public function setActivityFeed(?ActivityFeed $activityFeed): AbstractCursus
  641.     {
  642.         $this->activityFeed $activityFeed;
  643.         return $this;
  644.     }
  645. }