<?php
namespace App\Entity\Training;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Entity\User;
use App\Repository\Training\GroupeRepository;
use App\Traits\Actions;
use App\Entity\Schoolyear;
use DateInterval;
use DatePeriod;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: GroupeRepository::class)]
#[ORM\Table(name: 'hs_tc_training_groupe')]
#[ApiResource]
class Groupe implements \Stringable
{
use Actions;
#[ORM\ManyToOne(inversedBy: 'groupes')]
private ?Training $training = null;
#[ORM\ManyToOne(targetEntity: Schoolyear::class)]
#[ORM\JoinColumn(nullable: true)]
private ?Schoolyear $schoolyear1 = null;
#[ORM\OneToMany(mappedBy: "groupe", targetEntity: Trainee::class)]
#[ORM\OrderBy(["regNumber" => "ASC"])]
private Collection $trainees;
#[ORM\OneToMany(mappedBy: "groupe", targetEntity: Planning::class, cascade: ["all"], orphanRemoval: true)]
private Collection $plannings;
#[ORM\OneToMany(mappedBy: "groupe", targetEntity: Assignation::class, cascade: ["all"], orphanRemoval: true)]
private Collection $assignations;
#[ORM\OneToMany(mappedBy: "groupe", targetEntity: Schedule::class, cascade: ["all"], orphanRemoval: true)]
private Collection $schedules;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: "groupes")]
#[ORM\JoinColumn(nullable: true)]
private ?User $responsable;
public function __construct()
{
$this->trainees = new ArrayCollection();
$this->createAt=new \DateTime('now');
$this->published=true;
}
public function getStartAt($period='formation'): ?\DateTime{
if($this->getTraining()==null){
return null;
}
$startMonth=$this->getTraining()->getListMonths()[0];
if($period=='formation' or $period=='firstYear'){
return \DateTime::createFromFormat('d/m/Y H:i', '1/'.$startMonth.'/' . $this->getFirstYear()->getFirstYear(). ' 00:00');
}
elseif($period=='secondYear'){
return \DateTime::createFromFormat('d/m/Y H:i', '1/'.$startMonth.'/' . ($this->getFirstYear()->getFirstYear()+1). ' 00:00');
}
else{
return \DateTime::createFromFormat('d/m/Y H:i', '1/'.$startMonth.'/' . ($this->getFirstYear()->getFirstYear()+2). ' 00:00');
}
}
public function getEndAt($period='formation'): ?\DateTime{
if($this->getTraining()==null){
return null;
}
$endMonth=$this->getTraining()->getListMonths()[count($this->getTraining()->getListMonths())-1];
if($period=='thirdYear'){
return \DateTime::createFromFormat('d/m/Y H:i', '1/'.$endMonth.'/' . ($this->getFirstYear()->getSecondYear()+2). ' 23:59');
}
elseif($period=='secondYear'){
return \DateTime::createFromFormat('d/m/Y H:i', '1/'.$endMonth.'/' . ($this->getFirstYear()->getSecondYear()+1). ' 23:59');
}
elseif($period=='firstYear'){
return \DateTime::createFromFormat('d/m/Y H:i', '1/'.$endMonth.'/' . $this->getFirstYear()->getSecondYear(). ' 23:59');
}
else{
return \DateTime::createFromFormat('d/m/Y H:i', '1/'.$endMonth.'/' . ($this->getFirstYear()->getSecondYear()+$this->getTraining()->getSchoolYearsNumber()-1). ' 23:59');
}
}
public function setTraining(Training $training)
{
$this->training = $training;
return $this;
}
public function getTraining()
{
return $this->training;
}
public function getSchoolyear1()
{
return $this->schoolyear1;
}
public function setSchoolyear1(Schoolyear $schoolyear1=null)
{
$this->schoolyear1 = $schoolyear1;
return $this;
}
public function getSchoolyear2()
{
if($this->training->getNbrYears()>=2 && $this->getSchoolyear1() != null) return $this->getSchoolyear1()->getNext();
else return null;
}
public function getSchoolyear3()
{
if($this->training->getNbrYears()>=3 && $this->getSchoolyear2() != null) return $this->getSchoolyear2()->getNext();
else return null;
}
public function addTrainee(Trainee $trainee)
{
$trainee->setGroupe($this);
$this->trainees[] = $trainee;
return $this;
}
public function removeTrainee(Trainee $trainee)
{
$this->trainees->removeElement($trainee);
}
public function getTrainees()
{
return $this->trainees;
}
public function getNbrTrainees(){
$n=0;
/** @var Trainee $trainee */
foreach ($this->trainees as $trainee){
if($trainee->getStatus()!="Abandonné") $n++;
}
return $n;
}
public function getNbrAbandonnes(){
$n=0;
/** @var Trainee $trainee */
foreach ($this->trainees as $trainee){
if($trainee->getStatus()=="Abandonné") $n++;
}
return $n;
}
public function addAssignation(Assignation $assignation)
{
$assignation->setGroupe($this);
$this->assignations[] = $assignation;
return $this;
}
public function removeAssignation(Assignation $assignation)
{
$this->assignations->removeElement($assignation);
}
public function getAssignations()
{
return $this->assignations;
}
public function getAssignationByModule(Module $module)
{
foreach ($this->assignations as $assignation){
if($assignation->getModule()==$module){
return $assignation;
}
}
return null;
}
public function addSchedule(Schedule $schedule)
{
$schedule->setGroupe($this);
$this->schedules[] = $schedule;
return $this;
}
public function removeSchedule(Schedule $schedule)
{
$this->schedules->removeElement($schedule);
}
public function getSchedules()
{
return $this->schedules;
}
public function getResponsable(): ?User
{
return $this->responsable;
}
public function setResponsable(?User $responsable): void
{
$this->responsable = $responsable;
}
public function getOthersGroupes(){
$groupes=[];
foreach ($this->getTraining()->getGroupesBySY($this->getSchoolyear1()) as $groupe){
if($groupe !== $this) $groupes[] = $groupe;
}
return $groupes;
}
public function getNum()
{
}
public function getLabel(){
$i=1;
foreach ($this->getTraining()->getGroupesBySY($this->getSchoolyear1()) as $groupe){
if($groupe->getId()<$this->getId()) $i++;
}
$label=count($this->getTraining()->getGroupesBySY($this->getSchoolyear1()))>1?' G'.$i:'';
return $this->training->getAbbreviation().' '.$label;
}
public function getDiplome(){
return $this->getTraining()->getDiploma();
}
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-info 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('add_trainee',$actionsItems))
$actions.="<li><a title='Ajouter un nouveau stagiaire' class='action' target='_self' href='javascript:void(0)' data-id='".$this->id."' data-route='hs_training_center_trainee_new'>"
."<i class='fa text-success fa-fw fa-plus'></i> Stagiaire</a></li>";
$actions.="</ul></div>";
return $actions;
}
public function getYears(){
return $this->getSchoolyear1()->getFirstYear().'-'.($this->getSchoolyear1()->getFirstYear()+$this->getTraining()->getNbrYears());
}
public function getFirstYear(){
return $this->schoolyear1;
}
public function getLastYear(){
if($this->getTraining()->getNbrYears()==3) return $this->getSchoolyear3();
elseif($this->getTraining()->getNbrYears()==2) return $this->getSchoolyear2();
return $this->schoolyear1;
}
public function getSecondYear(){
$first=intval(substr($this->schoolyear1->getTitle(),0,4));
if($this->training->getNbrYears()<2) return '-------';
else return ($first+1).'/'.($first+2);
}
public function getThirdYear(){
$first=intval(substr($this->schoolyear1->getTitle(),0,4));
if($this->training->getNbrYears()<3) return '-------';
else return ($first+2).'/'.($first+3);
}
public function getTrainingYear(Schoolyear $schoolyear){
if ($schoolyear===$this->schoolyear1) return 'first_year';
elseif($schoolyear===$this->getSchoolyear2()) return 'second_year';
elseif($schoolyear===$this->getSchoolyear3()) return 'third_year';
return "none";
}
public function getTrainingYearFr(Schoolyear $schoolyear){
if ($schoolyear===$this->schoolyear1) return '1ère année';
elseif($schoolyear===$this->getSchoolyear2()) return '2ème année';
elseif($schoolyear===$this->getSchoolyear3()) return '3ème année';
return " ";
}
public function geSchoolYear($ty){
if ($ty=='first_year') return $this->schoolyear1;
elseif($ty=='second_year') return $this->getSchoolyear2();
elseif($ty=='third_year') return $this->getSchoolyear3();
return null;
}
public function getTrainingYears(){
$sys=[$this->schoolyear1];
if($this->training->getNbrYears()>=2) $sys[]=$this->getSchoolyear2();
if($this->training->getNbrYears()>=3) $sys[]=$this->getSchoolyear3();
return $sys;
}
public function getSchoolYearByMonth($month){
$sy=null;
foreach ($this->getTrainingYears() as $schoolyear){
$level=$this->getTrainingYear($schoolyear);
$months=$this->getMonthsByYear($level, 'number');
foreach ($months as $m) if($m==$month) $sy=$schoolyear;
}
return $sy;
}
public function isEncours(Schoolyear $schoolyear){
if(in_array($schoolyear, $this->getTrainingYears())) return true;
return false;
}
public function getMonths($format='long'): array
{
$mountsArray=[
'01'=>['number'=>'01','short'=>'Janv','long'=>'Janvier'],
'02'=>['number'=>'02','short'=>'Févr','long'=>'Février'],
'03'=>['number'=>'03', 'short'=>'Mars','long'=>'Mars'],
'04'=>['number'=>'04', 'short'=>'Avr','long'=>'Avril'],
'05'=>['number'=>'05','short'=>'Mai','long'=>'Mai'],
'06'=>['number'=>'06','short'=>'Juin','long'=>'Juin'],
'07'=>['number'=>'07', 'short'=>'Juil','long'=>'Juillet'],
'08'=>['number'=>'08', 'short'=>'Aout','long'=>'Août'],
'09'=>['number'=>'09', 'short'=>'Sept','long'=>'Septembre'],
'10'=>['number'=>'10','short'=>'Oct','long'=>'Octobre'],
'11'=>['number'=>'11','short'=>'Nov','long'=>'Novembre'],
'12'=> ['number'=>'12','short'=>'Déc','long'=>'Décembre'],
];
if($format=='short') {
$sep=" ";
$yearformat='y';
}
elseif($format=='long') {
$sep=" ";
$yearformat='Y';
}
else {
$sep="/";
$yearformat='y';
}
$months = [];
$start = $this->getStartAt();
$end = $this->getEndAt();
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
$month = $date->format('m');
if(in_array($month, $this->getTraining()->getListMonths())){
$monthName=$mountsArray[$month][$format];
$year= $date->format($yearformat);
$months[] = $monthName.$sep.$year;
}
}
return $months;
}
public function getMonthsByYear(string $year, $format='long'){
if($year=='third_year') $n=2;
elseif($year=='second_year') $n=1;
elseif ($year=='first_year') $n=0;
else return $this->getMonths($format);
return array_slice($this->getMonths($format), $n*count($this->getTraining()->getListMonths()), count($this->getTraining()->getListMonths()));
}
public function getMonth($index, $format='long'){
$mounts=$this->getMonths($format);
return $index>=0?$mounts[$index]:null;
}
public function getIndexMonth($month){
if(array_search($month,$this->getMonths())) return array_search($month,$this->getMonths());
elseif(array_search($month,$this->getMonths('short'))) return array_search($month,$this->getMonths('short'));
else return array_search($month,$this->getMonths('number'));
}
public function getShortMonth($m){
return $this->getMonth($this->getIndexMonth($m),'short');
}
public function getCurrent($format='long'){
// date_default_timezone_set('Africa/Casablanca');
$now=new \DateTime('now');
$endAt= clone $this->schoolyear1->getEndAt();
$endAt->modify('+1 years');
if($now<$this->schoolyear1->getStartAt()) return 'before';
elseif($now>$endAt) return 'after';
elseif($now->format('m')=='08' || $now->format('m')=='09') $mc='07/'.$now->format('y');
else $mc=$now->format('m/y');
$index=array_search($mc, $this->getMonths('number'));
return $this->getMonth($index, $format);
}
public function getMonthsPassed($format='long'){
if ($this->getCurrent('number')=='before') return [];
elseif ($this->getCurrent('number')=='after') return $this->getMonths($format);
else{
$index=array_search($this->getCurrent('number'), $this->getMonths('number'));
$paased=[];
for($i=0; $i<=$index; $i++){
$paased[]=$this->getMonths($format)[$i];
}
return $paased;
}
}
public function getMonthsPassedByYear($year, $format='long'){
if ($this->getCurrent('number')=='before') return [];
elseif ($this->getCurrent('number')=='after') return $this->getMonthsByYear($year, $format);
else{
$index=array_search($this->getCurrent('number'), $this->getMonthsByYear($year, $format));
$paased=[];
for($i=0; $i<=$index; $i++){
$paased[]=$this->getMonthsByYear($year, $format)[$i];
}
return $paased;
}
}
public function getStatutMonth($index){
if($this->getCurrent('number')==$index){
return 'current';
}
elseif($this->getCurrent('number')>$index){
return 'passed';
}
else return 'coming';
}
public function getBgClass($m){
$m=$this->getMonth($this->getIndexMonth($m), 'short');
if($this->getCurrent('short')==$m){
return 'bg-yellow';
}
elseif(in_array($m,$this->getMonthsPassed('short'),true)){
return 'bg-red';
}
else return 'bg-gray';
}
public function __toString(): string
{
return $this->training->getAbbreviation().' '.$this->getYears();
}
public function getAbreviation(Schoolyear $schoolyear){
$i=1;
foreach ($this->getTraining()->getGroupesBySY($this->getSchoolyear1()) as $groupe){
if($groupe->getId()<$this->getId()) $i++;
}
$nbGroupe=count($this->getTraining()->getGroupesBySY($this->getSchoolyear1()))>1?' G'.$i:'';
if($this->getTraining()->getNbrYears()>1){
$level=match($this->getTrainingYear($schoolyear)){
'first_year' => '1',
'second_year' => '2',
'third_year' => '3',
};
}
else $level='';
return $this->training->getAbbreviation().$level.$nbGroupe;
}
public function getTraineesSorted($note){
$items=$this->getTrainees()->toArray();
usort($items,[$this, $note]);
return $items;
}
public function getTraineesSortedByAbsence($nombre, $startAt, $endAt){
// Récupérer tous les stagiaires
$trainees = $this->getTrainees();
$traineeAbsences = [];
/** @var Trainee $trainee */
foreach ($trainees as $trainee) {
// Compter les absences pour chaque stagiaire
if($trainee->getStatus()!="Abandonné")
$traineeAbsences[] = [
'trainee' => $trainee,
'absenceCount' => count($trainee->getAbsencesByPeriod($startAt, $endAt)),
];
}
usort($traineeAbsences, function ($a, $b) {
return $b['absenceCount'] <=> $a['absenceCount'];
});
$top10Trainees = array_slice($traineeAbsences, 0, $nombre, true);
return array_column($top10Trainees, 'trainee');
}
public function getModulesSortedByAbsence($nombre, Schoolyear $schoolyear){
$assigns = $this->getAssignationsBySY($schoolyear);
$assignsAbsences = [];
/** @var Trainee $trainee */
foreach ($assigns as $assign) {
// Compter les absences pour chaque stagiaire
$assignsAbsences[] = [
'assign' => $assign,
'absenceCount' => count($assign->getAbsences()),
];
}
usort($assignsAbsences, function ($a, $b) {
return $b['absenceCount'] <=> $a['absenceCount'];
});
$top10Assigns = array_slice($assignsAbsences, 0, $nombre, true);
return array_column($top10Assigns, 'assign');
}
public function getSeances(Schoolyear $schoolyear)
{
$allSeances = [];
foreach ($this->getAssignationsBySY($schoolyear) as $assign) {
$allSeances=array_merge($allSeances, $assign->getSeances());
}
usort($allSeances, function($a, $b) {
$dateA = DateTime::createFromFormat('d-m-Y H:i', $a->getTakesplaceOn()->format('d-m-Y').' '.$a->getStartAt());
$dateB = DateTime::createFromFormat('d-m-Y H:i', $b->getTakesplaceOn()->format('d-m-Y').' '.$b->getStartAt());
return $dateA <=> $dateB;
});
return $allSeances;
}
public function getSeancesCancelled(Schoolyear $schoolyear)
{
$allSeances = [];
foreach ($this->getAssignationsBySY($schoolyear) as $assign) {
$allSeances=array_merge($allSeances, $assign->getSeancesCancelled());
}
usort($allSeances, function($a, $b) {
$dateA = DateTime::createFromFormat('d-m-Y H:i', $a['seanceDate'].' '.$a['scheduleitem']->getStartAt());
$dateB = DateTime::createFromFormat('d-m-Y H:i', $b['seanceDate'].' '.$b['scheduleitem']->getStartAt());
return $dateA <=> $dateB;
});
return $allSeances;
}
public function getSeancesNotCreate(Schoolyear $schoolyear)
{
$allSeances = [];
foreach ($this->getAssignationsBySY($schoolyear) as $assign) {
$allSeances=array_merge($allSeances, $assign->getSeancesNotCreate());
}
usort($allSeances, function($a, $b) {
$dateA = DateTime::createFromFormat('d-m-Y H:i', $a['seanceDate'].' '.$a['scheduleitem']->getStartAt());
$dateB = DateTime::createFromFormat('d-m-Y H:i', $b['seanceDate'].' '.$b['scheduleitem']->getStartAt());
return $dateA <=> $dateB;
});
return $allSeances;
}
function mg1(Trainee $a, Trainee $b)
{
return $b->getMG('first_year') <=> $a->getMG('first_year');
}
public function getFeesByMonth(Schoolyear $schoolyear){
$months=$this->getMonthsByYear($this->getTrainingYear($schoolyear), 'number');
$fees=[];
foreach ($months as $month) {
$toPay=0;
$pay=0;
$retard=0;
foreach ($this->getTrainees() as $trainee) {
$fee=$trainee->getFeeByTypeNameSy('monthlyPayment', $month , $this->getTrainingYear($schoolyear));
if ($fee==null) continue;
$toPay+=$fee->getMontant();
$pay+=$fee->amountPaied();
$retard+=$fee->restToPay();
}
$fees[]=['month'=>(\DateTime::createFromFormat('d/m/y','01/'.$month))->format('Y-m-d') , 'toPay'=>$toPay, 'pay'=>$pay, 'retard'=>$retard ];
}
return $fees;
}
public function getToPay($type='all', $year=null)
{
$toPay=0;
foreach ($this->getTrainees() as $trainee) {
$toPay+=$trainee->getToPay($type, $year);
}
return $toPay;
}
public function getTotalFees($type, $year=null){
$pay=0;
foreach ($this->getTrainees() as $trainee) {
$pay+=$trainee->getTotalFees($type, $year);
}
return $pay;
}
public function getPay(){
$pay=0;
foreach ($this->getTrainees() as $trainee) {
$pay+=$trainee->getPay();
}
return $pay;
}
public function getTotalPay($fees, $year=null){
$pay=0;
foreach ($this->getTrainees() as $trainee) {
$pay+=$trainee->getTotalPay($fees, $year);
}
return $pay;
}
public function getRestPay($fees, $year=null)
{
$restPay=0;
foreach ($this->getTrainees() as $trainee) {
$restPay+=$trainee->getRestPay($fees, $year);
}
return $restPay;
}
public function getNbrRetard($fees, $year=null)
{
$nbr=0;
foreach ($this->getTrainees() as $trainee) {
$nbr=$trainee->getRestPay($fees, $year)>0?$nbr+1:$nbr;
}
return $nbr;
}
public function getAdvance($fees, $year=null)
{
$advence=0;
foreach ($this->getTrainees() as $trainee) {
$advence+=$trainee->getAdvance($fees, $year);
}
return $advence;
}
public function getAssignationsBySY(Schoolyear $schoolyear){
$level=$this->getTrainingYear($schoolyear);
$modules=$this->getTraining()->getModulesByLevel($level);
return $this->assignations->filter(function (Assignation $assignation) use ($modules) {
return $modules->contains($assignation->getModule());
});
}
public function getSpecialsTrainees()
{
$specialNumber=$this->docs!==null?explode(',',$this->docs):[];
$items=[];
/** @var Trainee $trainee */
foreach ($this->getTrainees() as $trainee) {
if(in_array($trainee->getRegNumber(), $specialNumber)) $items[]=$trainee;
}
return $items;
}
}