<?php
namespace App\Entity\Tutoring;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Entity\Schoolyear;
use App\Entity\User;
use App\Repository\Tutoring\CourseRepository;
use App\Traits\Actions;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\OrderBy;
/**
* Course
*/
#[ORM\Entity(repositoryClass: CourseRepository::class)]
#[ORM\Table(name: 'hs_tc_tutoring_course')]
#[ApiResource]
class Course implements \Stringable
{
use Actions;
/**
* @var string
*/
#[ORM\Column(name: 'name', type: 'string', length: 255, nullable: true)]
private $name;
#[ORM\ManyToMany(targetEntity: Level::class, inversedBy: "courses", cascade: ['persist'])]
private ?Collection $levels = null;
#[ORM\ManyToOne(targetEntity: Subject::class, cascade: ['persist'], inversedBy: 'courses')]
private ?Subject $subject = null;
/**
* @var float
*/
#[ORM\Column(name: 'price', type: 'float', nullable: true)]
private $price;
#[ORM\Column(name: 'fees_registration', type: 'float', nullable: true)]
private ?float $feesRegistration = 0;
#[ORM\Column(name: 'days', type: 'string', length: 255, nullable: true)]
private ?string $days = null;
#[ORM\Column(name: 'start_at', type: 'datetime', nullable: true)]
private ?\DateTime $startAt = null;
#[ORM\Column(name: 'end_at', type: 'datetime', nullable: true)]
private ?\DateTime $endAt = null;
#[ORM\ManyToOne(targetEntity: Tutor::class, inversedBy: 'courses')]
#[ORM\JoinColumn(nullable: false)]
private ?Tutor $tutor = null;
#[ORM\OneToMany(mappedBy: 'course', targetEntity: Rowscourse::class, cascade: ['persist'], orphanRemoval: true)]
private ?Collection $rowscourses = null;
#[ORM\OneToMany(mappedBy: 'course', targetEntity: Ressource::class, cascade: ['persist'], orphanRemoval: true)]
private ?Collection $ressources = null;
/**
* @OrderBy({"position" = "asc"})
*/
#[ORM\OneToMany(mappedBy: 'course', targetEntity: Month::class, cascade: ['persist'], orphanRemoval: true)]
private ?Collection $months = null;
/**
* @var Schoolyear
*/
#[ORM\ManyToOne(targetEntity: Schoolyear::class)]
#[ORM\JoinColumn(nullable: false)]
private $schoolyear;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: "courses")]
#[ORM\JoinColumn(nullable: true)]
private ?User $responsable;
/**
* @OrderBy({"createAt" = "ASC"})
*/
#[ORM\OneToMany(mappedBy: 'course', targetEntity: Regulation::class, cascade: ['persist'], orphanRemoval: true)]
private ?Collection $regulations = null;
public function __construct()
{
$this->createAt=new \DateTime('now');
$this->published=true;
$this->regulations=new ArrayCollection();
$this->levels=new ArrayCollection();
$this->months=new ArrayCollection();
$this->ressources=new ArrayCollection();
}
/**
* Set nom
*
* @param string $name
* @return Course
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
if($this->id!=null && $this->name == null) return $this->__toString();
else return $this->name;
}
public function getDays(): array
{
return explode(',',$this->days);
}
public function getDaysString(){
return $this->days;
}
/**
* @param string $days
*/
public function setDays(array $days): Course
{
$this->days = implode(",", $days);
return $this;
}
function __toString(): string
{
return implode(" ",$this->getLevels()->toArray()).' - '.$this->getSubject();
}
/**
* Add level
*
*
* @return Course
*/
public function addLevel(Level $level)
{
$this->levels[] = $level;
return $this;
}
/**
* Remove level
*/
public function removeLevel(Level $level)
{
$this->levels->removeElement($level);
}
/**
* Get levels
*
* @return ArrayCollection
*/
public function getLevels()
{
return $this->levels;
}
/**
* Set subject
*
*
* @return Course
*/
public function setSubject(Subject $subject = null)
{
$this->subject = $subject;
return $this;
}
/**
* Get subject
*
* @return Subject
*/
public function getSubject()
{
return $this->subject;
}
/**
* @return float
*/
public function getPrice()
{
return $this->price;
}
/**
* @param float $price
* @return Course
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
public function getFeesRegistration(): ?float
{
return $this->feesRegistration;
}
public function setFeesRegistration(?float $feesRegistration): Course
{
$this->feesRegistration = $feesRegistration;
return $this;
}
/**
* @return \DateTime
*/
public function getStartAt(): ?\DateTime
{
if($this->startAt instanceof \DateTime)
return $this->startAt;
else
return $this->getSchoolyear()->getStartAt();
}
/**
* @param \DateTime $startAt
*/
public function setStartAt(?\DateTime $startAt): Course
{
$this->startAt = $startAt;
return $this;
}
/**
* @return \DateTime
*/
public function getEndAt(): ?\DateTime
{
if($this->endAt instanceof \DateTime)
return $this->endAt;
else
return $this->getSchoolyear()->getEndAt();
}
/**
* @param \DateTime $endAt
*/
public function setEndAt(?\DateTime $endAt): Course
{
$this->endAt = $endAt;
return $this;
}
/**
* @return Schoolyear
*/
public function getSchoolyear()
{
return $this->schoolyear;
}
/**
* @param Schoolyear $schoolyear
* @return Course
*/
public function setSchoolyear($schoolyear)
{
$this->schoolyear = $schoolyear;
return $this;
}
/**
* @return Tutor
*/
public function getTutor(): ?Tutor
{
return $this->tutor;
}
/**
* @param Tutor $tutor
*/
public function setTutor(?Tutor $tutor): Course
{
$this->tutor = $tutor;
return $this;
}
/**
* Add rowscourse
*
*
* @return Course
*/
public function addRowscourse(Rowscourse $rowscourse)
{
$rowscourse->setCourse($this);
$this->rowscourses[] = $rowscourse;
return $this;
}
/**
* Remove rowscourse
*/
public function removeRowscourse(Rowscourse $rowscourse)
{
$this->rowscourses->removeElement($rowscourse);
}
/**
* Get rowscourses
*
* @return Collection
*/
public function getRowscourses()
{
return $this->rowscourses;
}
public function getRowscoursesSorted()
{
$items = $this->rowscourses->toArray();
usort($items, function($a, $b) {
$studentA = $a->getStudent();
$studentB = $b->getStudent();
$cmp = strcmp($studentA->getFirstName(), $studentB->getFirstName());
if ($cmp === 0) {
return strcmp($studentA->getLastName(), $studentB->getLastName());
}
return $cmp;
});
return $items;
}
/**
* Add ressource
*
*
* @return Course
*/
public function addRessource(Ressource $ressource)
{
$ressource->setCourse($this);
$this->ressources[] = $ressource;
return $this;
}
/**
* Remove ressource
*/
public function removeRessource(Ressource $ressource)
{
$this->ressources->removeElement($ressource);
}
/**
* Get ressources
*
* @return ArrayCollection
*/
public function getRessources()
{
return $this->ressources;
}
/**
* Add month
*
*
* @return Course
*/
public function addMonth(Month $month)
{
$month->setCourse($this);
$this->months[] = $month;
return $this;
}
/**
* Remove month
*/
public function removeMonth(Month $month)
{
$this->months->removeElement($month);
}
/**
* Get months
*
* @return ArrayCollection
*/
public function getMonths()
{
return $this->months;
}
public function getMonth(string $m)
{
/** @var Month $month */
foreach ($this->months as $month){
if($month->getName()==$m) return $month;
}
return null;
}
/**
* @return array
*
*/
public function getCountedMonths(){
$list=[];
if(!$this->getMonths()->isEmpty())
{
/** @var Month $month */
foreach ($this->getMonths() as $month){
if ($month->isPassed()){
$list[]=$month;
}
}
}
return $list;
}
public function getMeetings(): Collection
{
$meetings = new ArrayCollection();
foreach ($this->months as $month) {
foreach ($month->getMeetings() as $meeting) {
$meetings->add($meeting);
}
}
return $meetings;
}
public function getMeetingPassed(): array
{
$meetings = [];
foreach ($this->months as $month) {
if($month->isPassed()) $meetings=array_merge($meetings,$month->getMeetings()->toArray());
else{
foreach ($month->getMeetings() as $meeting) {
if($meeting->getCreateAt()<new \DateTime('now'))
$meetings[]=$meeting;
}
}
}
return $meetings;
}
public function getMeetingFuture(): array
{
$meetings = [];
foreach ($this->months as $month) {
if(!$month->isPassed()) {
foreach ($month->getMeetings() as $meeting) {
if($meeting->getCreateAt()>=new \DateTime('now'))
$meetings[]=$meeting;
}
}
}
return $meetings;
}
public function getNbrMeetingsPassed()
{
return count($this->getMeetingPassed());
}
public function getNbrMeetingsFuture()
{
return count($this->getMeetingFuture());
}
public function getLastMeeting(): ?Meeting
{
$now = new \DateTime();
$lastMeeting = null;
foreach ($this->getMeetings() as $meeting) {
if ($meeting->getCreateAt() < $now) {
if ($lastMeeting === null || $meeting->getCreateAt() > $lastMeeting->getCreateAt()) {
$lastMeeting = $meeting;
}
}
}
return $lastMeeting;
}
/**
* Add regulation
*
*
* @return Course
*/
public function addRegulation(Regulation $regulation)
{
$regulation->setCourse($this);
$this->regulations[] = $regulation;
return $this;
}
/**
* Remove regulation
*/
public function removeRegulation(Regulation $regulation)
{
$this->regulations->removeElement($regulation);
}
/**
* Get regulations
*
* @return ArrayCollection
*/
public function getRegulations()
{
return $this->regulations;
}
public function getResponsable(): ?User
{
return $this->responsable;
}
public function setResponsable(?User $responsable): void
{
$this->responsable = $responsable;
}
public function getDaysTexte(){
$days=['','Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi','Dimanche'];
$daysText=[];
foreach ($this->getDays() as $day){
$daysText[]=$days[$day];
}
return $daysText;
}
public function getCountGenre($genre){
$i=0;
/** @var Ressource $ressource */
foreach ($this->getRessources() as $ressource){
if($ressource->getGenre()==$genre && $ressource->isPublished()) $i++;
}
return $i;
}
public function isStill(){
$now=new \DateTime('now');
return ($now>=$this->getStartAt() && $now<=$this->getEndAt()) ? true : false;
}
public function isStillInMonth(Month $month){
//return (($month->getStartAt()>=$this->getStartAt() && $month->getStartAt()<=$this->getEndAt()) || ($month->getEndAt()>=$this->getStartAt() && $month->getEndAt()<=$this->getEndAt())) ? true : false;
return ($month->getStartAt()>=$this->getStartAt() && $month->getStartAt()<=$this->getEndAt()) || ($month->getEndAt()>=$this->getStartAt() && $month->getEndAt()<=$this->getEndAt());
}
public function getSumToPaid(){
$s=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$s+=$rowscours->getSumToPaid();
}
return $s;
}
public function getSumPaidForTutor()
{
$s=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$s+=$rowscours->getSumPaidForTutor();
}
return $s;
}
public function getTotalPaidByMonth($month)
{
$sum=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$sum+=$rowscours->getAmountPaidByMonth($month);
}
return $sum;
}
public function getRestToPaidByMonth($month)
{
return $this->getOweByMonth($month)-$this->getTotalPaidByMonth($month);
}
public function getSumOutDate(){
$s=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$s+=$rowscours->getOutDate();
}
return $s;
}
public function getSumPaid(){
$s=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$s+=$rowscours->getSumPaid();
}
return $s;
}
public function getRest(){
$s=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$s+=$rowscours->getRest();
}
return $s;
}
public function getAdvance(){
$s=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$s+=$rowscours->getAdvance();
}
return $s;
}
public function getLatePaid(){
$s=0;
/** @var Rowscourse $rowscours */
foreach ($this->rowscourses as $rowscours){
$s+=$rowscours->getLatePaid();
}
return $s;
}
public function getRowsRetards()
{
$items = [];
/** @var Rowscourse $rowscours */
foreach ($this->getRowscoursesSorted() as $rowscours){
if($rowscours->getLatePaid()>0) $items[]=$rowscours;
}
return $items;
}
public function getNbrRetard()
{
return count($this->getRowsRetards());
}
public function getPcPay(){
if($this->getSumToPaid()!=0)
return round($this->getSumPaid()/$this->getSumToPaid()*100,0);
else
return 0;
}
public function getOweByMonth($month){
$t=0;
/** @var Rowscourse $rowscours */
foreach ($this->getRowscourses() as $rowscours){
$t+=$rowscours->getOweByMonth($month)!==null?$rowscours->getOweByMonth($month)->getPrice():0;
}
return $t;
}
public function getTotalFees(){
if($this->tutor->getTypePay()=='Fixe'){
$f=$this->tutor->getPcPay()*count($this->getCountedMonths());
}
else{
$f=$this->getSumPaidForTutor()*$this->tutor->getPcPay()/100;
}
return $f;
}
public function getFeesByMonths($month){
if($this->tutor->getTypePay()=='Fixe'){
return $this->tutor->getPcPay();
}
else{
return $this->getTotalPaidByMonth($month)*$this->tutor->getPcPay()/100;
}
}
public function getTotalRegulations(){
$t=0;
/** @var Regulation $regulation */
foreach ($this->regulations as $regulation){
$t+=$regulation->getAmount();
}
return $t;
}
public function getRegulationDetails()
{
$details=[];
$total=$this->getTotalRegulations();
foreach ($this->getSchoolyear()->getMonths() as $month){
$details[$month]=min($total,$this->getFeesByMonths($month));
$total=max($total-$this->getFeesByMonths($month),0);
}
return $details;
}
public function getRegulationByMonth($month){
if(array_key_exists($month,$this->getRegulationDetails())){
return $this->getRegulationDetails()[$month];
}
return 0;
}
public function getRestByMonth($month)
{
return $this->getFeesByMonths($month)-$this->getRegulationByMonth($month);
}
public function getRestRegulation(){
return $this->getTotalFees()-$this->getTotalRegulations();
}
public function getInProgress()
{
$items = [];
$abandonsIds = array_map(fn($a) => $a->getId(), $this->getAbandons());
foreach ($this->getRowscourses() as $rowscourse) {
if (!in_array($rowscourse->getId(), $abandonsIds)) {
$items[] = $rowscourse;
}
}
// Tri par nom puis prénom de l'élève
usort($items, function($a, $b) {
$studentA = $a->getStudent();
$studentB = $b->getStudent();
$cmp = strcmp($studentA->getFirstName(), $studentB->getFirstName());
if ($cmp === 0) {
return strcmp($studentA->getLastName(), $studentB->getLastName());
}
return $cmp;
});
return $items;
}
public function getAbandons()
{
$abandons = [];
$abandonsIds = []; // To avoid duplicates
foreach ($this->getMonths() as $month) {
if (!$month->isPassed()) continue;
foreach ($this->getRowscourses() as $rowscourse) {
if ($rowscourse->isAbandoned($month) && !in_array($rowscourse->getId(), $abandonsIds)) {
$abandons[] = $rowscourse;
$abandonsIds[] = $rowscourse->getId(); // Store the ID to avoid duplicates
}
}
}
return $abandons;
}
public function getActionsS($actionsItems=[])
{
$actions="<div class='btn-group'>" .
"<button type='button' class='btn btn-default btn-flat dropdown-toggle' data-toggle='dropdown' aria-expanded='false'>" .
"<span class='fa fa-ellipsis-v'></span>" .
"<span class='sr-only'>Toggle Dropdown</span>" .
"</button>" .
"<ul class='dropdown-menu dropdown-menu-right' role='menu'>";
if(in_array('edit', $actionsItems))
$actions.="<li><a title='Modifier' class='action' target='_self' href='javascript:void(0)' data-id='".$this->id."' data-route='".$this->getRoute('edit')."'>"
."<i class='fa text-warning fa-fw fa-edit'></i> Modifier</a></li>";
if(in_array('show', $actionsItems))
$actions.="<li><a title='Afficher' class='action' target='_self' href='javascript:void(0)' data-id='".$this->id."' data-route='".$this->getRoute('show')."'>"
."<i class='fa text-warning fa-fw fa-eye'></i> Afficher</a></li>";
if(in_array('remove', $actionsItems))
$actions.="<li><a title='Supprimer ?'
data-toggle='confirmation'
data-btn-ok-label='Supprimer'
data-btn-ok-icon='glyphicon glyphicon-ok'
data-btn-ok-class='btn-success'
data-btn-cancel-label='Annuler'
data-btn-cancel-icon='glyphicon glyphicon-remove'
data-btn-cancel-class='btn-danger'
data-title='Supprimer ?'
data-popout='true'
data-content='Voulez-vous vraiment supprimer cet élément ?'
class='action' target='_self' href='javascript:void(0)' data-id='".$this->id."' data-route='".$this->getRoute('remove')."'>"
."<i class='fa text-red fa-fw fa-trash-o'></i> Supprimer</a></li>";
if(in_array('list_items', $actionsItems))
$actions.="<li><a title='Liste des élèves' class='action' target='_self' href='javascript:void(0)' data-id='".$this->id."' data-route='hs_training_center_course_list_students'>"
."<i class='fa text-blue fa-fw fa-list-ul'></i> Liste des élèves</a></li>";
if(in_array('edit_seances', $actionsItems))
$actions.="<li><a title='Editer les séances' class='action' target='_parent' href='javascript:void(0)' data-id='".$this->id."' data-route='hs_training_center_course_meetings'>"
."<i class='fa text-red fa-fw fa-calendar-check-o'></i> Editer les séances</a></li>";
if(in_array('list_payments', $actionsItems))
$actions.="<li><a title='Liste des paiements' class='action' target='_blank' href='javascript:void(0)' data-id='".$this->id."' data-route='hs_training_center_course_paymentsheet'>"
."<i class='fa text-green fa-fw fa-credit-card'></i> Liste des paiements</a></li>";
// $actions.="<li><a title='Générer PDF' class='action' target='_blank' href='javascript:void(0)' data-id='".$this->id."' data-route='hs_training_center_student_paymentsheet_detail'>"
// ."<i class='fa text-green fa-fw fa-credit-card'></i> Liste des paiements Detail</a></li>";
$actions.="</ul></div>";
return $actions;
}
}