<?php
namespace App\Service;
use App\Entity\Child;
use App\Entity\ChildPreference;
use App\Entity\ChildPreferenceDeclineHistory;
use App\Entity\ChildPreferenceTime;
use App\Entity\Guardian;
use App\Entity\GuardianRegister\GuardianRegisterChild;
use App\Entity\Lesson;
use App\Entity\LessonDeleted;
use App\Entity\Teacher;
use App\Entity\TeacherHoliday;
use App\Entity\TeacherSickLeaves;
use App\Entity\TeacherUnavailableRange;
use App\Message\AssignChildPreferenceTeacherMessage;
use App\Message\SendMailMessage;
use App\Message\SendSMSMessage;
use App\Repository\ChildPreferenceDeclineHistoryRepository;
use App\Repository\ChildPreferenceHistoryRepository;
use App\Repository\ChildPreferenceRepository;
use App\Repository\ChildPreferenceTimeRepository;
use App\Repository\LessonDeletedRepository;
use App\Repository\LessonRepository;
use App\Repository\NotificationRepository;
use App\Repository\ReminderConfigurationRepository;
use App\Repository\TeacherHolidayRepository;
use App\Repository\TeacherRepository;
use App\Repository\TeacherSickLeavesRepository;
use App\Repository\TeacherUnavailableRangeRepository;
use App\Repository\UserFireBaseTokenRepository;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\DelayStamp;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Serializer\SerializerInterface;
class ChildPreferenceService
{
public const NEW_CHILD_ASSIGNMENT_VACATION_BUFFER_DAYS = 14;
private $testMode = false;
private $testEmailTeacher = 'thelincius@gmail.com';
// private $testPhoneTeacher = '37065520239';
private $testPhoneTeacher = '37063794090';
// private $testEmailGuardian = 'tomas970506@gmail.com';
private $testEmailGuardian = 'apolskis.linas@gmail.com';
// private $testPhoneGuardian = '37065520239';
private $testPhoneGuardian = '37063794090';
private ReminderConfigurationRepository $reminderConfigurationRepository;
private UrlGeneratorInterface $urlGenerator;
private SmsService $smsService;
private EntityManagerInterface $entityManager;
private ContainerInterface $container;
private RequestStack $requestStack;
private LessonRepository $lessonRepository;
private MessageBusInterface $bus;
private LessonDeletedRepository $lessonDeletedRepository;
private PaymentService $paymentService;
private MessageBusInterface $messageBus;
private TeacherRepository $teacherRepository;
private ChildPreferenceTimeRepository $childPreferenceTimeRepository;
private ChildPreferenceRepository $childPreferenceRepository;
private ChildPreferenceHistoryRepository $childPreferenceHistoryRepository;
private SerializerInterface $serializer;
private TeacherSickLeavesRepository $teacherSickLeavesRepository;
private TeacherHolidayRepository $teacherHolidayRepository;
private TeacherUnavailableRangeRepository $teacherUnavailableRangeRepository;
private NotificationService $notificationService;
private GetStreamService $getStreamService;
private FcmService $fcmService;
private UserFireBaseTokenRepository $userFireBaseTokenRepository;
private LessonDeletionService $lessonDeletionService;
private GuardianLogService $guardianLogService;
public function __construct(
SmsService $smsService,
LessonRepository $lessonRepository,
EntityManagerInterface $entityManager,
ContainerInterface $container,
RequestStack $requestStack,
UrlGeneratorInterface $urlGenerator,
ReminderConfigurationRepository $reminderConfigurationRepository,
MessageBusInterface $bus,
LessonDeletedRepository $lessonDeletedRepository,
PaymentService $paymentService,
MessageBusInterface $messageBus,
TeacherRepository $teacherRepository,
ChildPreferenceTimeRepository $childPreferenceTimeRepository,
ChildPreferenceRepository $childPreferenceRepository,
ChildPreferenceHistoryRepository $childPreferenceHistoryRepository,
ChildPreferenceDeclineHistoryRepository $childPreferenceDeclineHistoryRepository,
SerializerInterface $serializer,
TeacherSickLeavesRepository $teacherSickLeavesRepository,
TeacherHolidayRepository $teacherHolidayRepository,
TeacherUnavailableRangeRepository $teacherUnavailableRangeRepository,
NotificationService $notificationService,
GetStreamService $getStreamService,
FcmService $fcmService,
UserFireBaseTokenRepository $userFireBaseTokenRepository,
LessonDeletionService $lessonDeletionService,
GuardianLogService $guardianLogService
)
{
$this->entityManager = $entityManager;
$this->container = $container;
$this->requestStack = $requestStack;
$this->reminderConfigurationRepository = $reminderConfigurationRepository;
$this->urlGenerator = $urlGenerator;
$this->smsService = $smsService;
$this->lessonRepository = $lessonRepository;
$this->bus = $bus;
$this->lessonDeletedRepository = $lessonDeletedRepository;
$this->paymentService = $paymentService;
$this->messageBus = $messageBus;
$this->teacherRepository = $teacherRepository;
$this->childPreferenceTimeRepository = $childPreferenceTimeRepository;
$this->childPreferenceRepository = $childPreferenceRepository;
$this->childPreferenceHistoryRepository = $childPreferenceHistoryRepository;
$this->childPreferenceDeclineHistoryRepository = $childPreferenceDeclineHistoryRepository;
$this->serializer = $serializer;
$this->teacherSickLeavesRepository = $teacherSickLeavesRepository;
$this->teacherHolidayRepository = $teacherHolidayRepository;
$this->teacherUnavailableRangeRepository = $teacherUnavailableRangeRepository;
$this->notificationService = $notificationService;
$this->getStreamService = $getStreamService;
$this->fcmService = $fcmService;
$this->userFireBaseTokenRepository = $userFireBaseTokenRepository;
$this->lessonDeletionService = $lessonDeletionService;
$this->guardianLogService = $guardianLogService;
}
public function assignTeacher(ChildPreference $childPreferenceObjectToAssign, ?Child $child = null, ?Teacher $teacherToForceAssign = null, $maxClass = null, $debug = false)
{
if(!$child)
{
$child = $childPreferenceObjectToAssign->getChild();
}
$this->entityManager->refresh($childPreferenceObjectToAssign);
if($childPreferenceObjectToAssign->getStatus() == ChildPreference::STATUS_ASSIGNED['value'])
{
return;
}
// if(in_array($childPreferenceObjectToAssign->getStatus(), ['CANCELLED','NOT_FOUND']))
// {
if(!$debug) {
foreach ($childPreferenceObjectToAssign->getChildPreferenceTimes() as $childPreferenceTime) {
$childPreferenceObjectToAssign->removeChildPreferenceTime($childPreferenceTime);
$this->entityManager->remove($childPreferenceTime);
$this->entityManager->flush();
}
$childPreferenceObjectToAssign->setTeacher(null);
$childPreferenceObjectToAssign->setStatus(ChildPreference::STATUS_TO_ASSIGN['value']);
$this->entityManager->persist($childPreferenceObjectToAssign);
$this->entityManager->flush();
}
// }
//First filter teachers by status, discipline, class, available
$discipline = $childPreferenceObjectToAssign->getDiscipline();
$class = $child->getClass();
$minClass = $child->getClass();
if(!$maxClass) {
$maxClass = $child->getClass();
}
$amount = $childPreferenceObjectToAssign->getEmailDuration() / $childPreferenceObjectToAssign->getSingleEmailDuration();
$duration = $childPreferenceObjectToAssign->getEmailDuration();
$school = $child->getSchool();
$ielts = $child->isFlagIelts();
$flagRU = $child->getFlagRU();
$flagPL = $child->getFlagPL();
$flagENG = $child->getFlagENG();
$flagIB = $child->getFlagIB();
$flagDyslexia = $child->getFlagDyslexia();
$flagVbeOver90 = $child->isVbeOver90();
$flagExperienceOver12Month = $child->isExperienceOver12Month();
$flagExperienceAtSchool = $child->isFlagExperienceAtSchool();
//Optional
$flagSensitive = $child->getFlagSensitive();
$gender = $child->getGender();
$flagStrict = $child->isFlagStrict();
//dump($class);
//die();
// $condition = "dc.maxClass {$classSearchType} :class AND dc.discipline = :discipline";
// $condition = '';
// foreach ($class as $selectedClass)
// {
// if($condition)
// {
// $condition .= ' OR ';
// }
// $selectedClass = str_replace('–', '%', $selectedClass);
// $selectedClass = str_replace('š', '%', $selectedClass);
// $condition = "dc.classes like '%{$selectedClass}%' AND dc.discipline = :discipline";
// }
// $classSearchType = $form->get('classSearchType')->getData() ? '=' : '>=';
$busyTeacherIds = [];
$busyTeachers = $this->childPreferenceRepository
->createQueryBuilder('c')
->select('teacher.id')
->leftJoin('c.teacher', 'teacher')
->where('c.status = :status')
->setParameter('status', ChildPreference::STATUS_ASSIGNED['value'])
->getQuery()
->getArrayResult();
foreach ($busyTeachers as $busyTeacherId)
{
$busyTeacherIds[] = $busyTeacherId['id'];
}
$declinedAt = new \DateTime();
$declinedAt->modify('-3 hours');
$query = $this->childPreferenceDeclineHistoryRepository->createQueryBuilder('a');
$query
->andWhere('a.declinedAt > :declined_at')
->setParameter('declined_at', $declinedAt);
$histories = $query->getQuery()->getResult();
/** @var ChildPreferenceDeclineHistory $history */
foreach ($histories as $history)
{
if($history && $history->getTeacher()) {
$busyTeacherIds[] = $history->getTeacher()->getId();
}
}
$sickLeaves = $this
->teacherSickLeavesRepository
->createQueryBuilder('t')
->andWhere('t.dateStart <= :currentTime')
->andWhere('t.dateEnd >= :currentTime')
->setParameter('currentTime', new \DateTime())
->getQuery()
->getResult();
/** @var TeacherSickLeaves $sickLeave */
foreach ($sickLeaves as $sickLeave)
{
$busyTeacherIds[] = $sickLeave->getTeacher()->getId();
}
// Also excludes a holiday that hasn't started yet but starts soon: a
// teacher whose vacation begins within NEW_CHILD_ASSIGNMENT_VACATION_BUFFER_DAYS
// must not be handed new children whose first lessons would land right
// before/inside it (see [issue: teacher 2197 vacation]). A vacation
// further out than that is not excluded here — it's still safe, since
// generateLessonsForChildPreference() marks any occurrence landing
// inside it as INFORMED_MISSED regardless of how far away it is.
$vacationSoonThreshold = (new \DateTime())->modify(
'+' . self::NEW_CHILD_ASSIGNMENT_VACATION_BUFFER_DAYS . ' days'
);
$teacherHolidays = $this
->teacherHolidayRepository
->createQueryBuilder('t')
->andWhere('t.dateStart <= :vacationSoonThreshold')
->andWhere('t.dateEnd >= :currentTime')
->setParameter('vacationSoonThreshold', $vacationSoonThreshold)
->setParameter('currentTime', new \DateTime())
->getQuery()
->getResult();
/** @var TeacherHoliday $teacherHoliday */
foreach ($teacherHolidays as $teacherHoliday)
{
$busyTeacherIds[] = $teacherHoliday->getTeacher()->getId();
}
$teacherUnavailableRanges = $this
->teacherUnavailableRangeRepository
->createQueryBuilder('t')
->andWhere('t.startTime <= :currentTime')
->andWhere('t.endTime >= :currentTime')
->setParameter('currentTime', new \DateTime())
->getQuery()
->getResult();
/** @var TeacherUnavailableRange $teacherUnavailableRange */
foreach ($teacherUnavailableRanges as $teacherUnavailableRange)
{
$busyTeacherIds[] = $teacherUnavailableRange->getTeacher()->getId();
}
// dump($busyTeacherIds);
// die();
$query = $this->teacherRepository->createQueryBuilder('t');
$query
->andWhere('t.roles LIKE :roles')
->setParameter('roles', '%"ROLE_TEACHER"%');
if($debug)
{
dump('busy teachers:');
dump($busyTeacherIds);
}
$declinedAt = new \DateTime();
$declinedAt->modify('-72 hours');
$histories = $this->childPreferenceDeclineHistoryRepository->createQueryBuilder('a')
->andWhere('a.declinedAt > :declined_at')
->setParameter('declined_at', $declinedAt)
->andWhere('a.discipline = :discipline')
->setParameter('discipline', $discipline)
->andWhere('a.child = :child')
->setParameter('child', $child)
->getQuery()
->getResult();
if(count($histories) >= 2) {
$query->andWhere('t.flagAutoAcceptAssignment = 1');
}
$busyTeacherIds = array_filter($busyTeacherIds);
if($busyTeacherIds && !$teacherToForceAssign) {
$query
->andWhere('t.id NOT IN (:busyTeacherIds)')
->setParameter('busyTeacherIds', $busyTeacherIds);
}
if($teacherToForceAssign)
{
$query
->andWhere('t.id = :teacherToForceAssign')
->setParameter('teacherToForceAssign', $teacherToForceAssign->getId());
}
$available = $duration / 60;
if($minClass == 0){
$minClass = 'Priešmokyklinukai';
}
if($maxClass == 0){
$maxClass = 'Priešmokyklinukai';
}
if($minClass == 13){
$minClass = 'Suaugę';
}
if($maxClass == 13){
$maxClass = 'Suaugę';
}
$availableClasses = [
'Priešmokyklinukai' => 'Priešmokyklinukai',
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
'Suaugę' => 'Suaugę',
];
$selectedClassesRange = [];
$doNotIncludeClassesRange = [];
if(!$maxClass && !$minClass){
return new JsonResponse([
"data" => [],
'timeSlots' => [],
]);
}
elseif($maxClass && !$minClass) {
foreach ($availableClasses as $class) {
if($class != $maxClass) {
continue;
}
$selectedClassesRange[] = $class;
if($class == $maxClass) {
break;
}
}
$reached = false;
foreach ($availableClasses as $class) {
if($class != $maxClass && !$reached) {
continue;
}
if($reached) {
$doNotIncludeClassesRange[] = $class;
}
$reached = true;
}
}
elseif(!$maxClass && $minClass)
{
foreach ($availableClasses as $class) {
if($class != $minClass && !$selectedClassesRange) {
continue;
}
$selectedClassesRange[] = $class;
}
}
elseif($maxClass && $minClass)
{
foreach ($availableClasses as $class) {
if($class != $minClass && !$selectedClassesRange) {
continue;
}
$selectedClassesRange[] = $class;
if($class == $maxClass) {
break;
}
}
$reached = false;
foreach ($availableClasses as $class) {
if($class != $maxClass && !$reached) {
continue;
}
if($reached) {
$doNotIncludeClassesRange[] = $class;
}
$reached = true;
}
}
$condition = '';
if($debug)
{
dump('selectedClassesRange:');
dump($selectedClassesRange);
dump('doNotIncludeClassesRange:');
dump($doNotIncludeClassesRange);
}
$hiddenCases = "";
// dump($selectedClassesRange);
// die();
if($selectedClassesRange) {
foreach ($selectedClassesRange as $class) {
if(!$condition)
{
$condition .= '( ';
}
if(substr($condition, -2, 2) == '1 ' || substr($condition, -3, 3) == "%' ")
{
$condition .= 'OR ';
}
if(is_int($class)) {
$condition .= "JSON_CONTAINS(dc.classYears, '{$class}') = 1 ";
}
else
{
if($class == 'Suaugę')
{
$condition .= "dc.classes like '%Suaug%' ";
}
if($class == 'Priešmokyklinukai')
{
$condition .= "dc.classes like '%mokyklinukai%' ";
}
}
}
$condition .= ") AND dc.discipline = :discipline";
if($flagVbeOver90){
$condition .= " AND dc.vbe >= 90 ";
}
}
if($doNotIncludeClassesRange)
{
// $condition .= " AND ( ";
foreach ($doNotIncludeClassesRange as $class) {
// if(substr($condition, -2, 2) == '0 ' || substr($condition, -3, 3) == "%' ")
// {
// $condition .= ' AND ';
// }
if(is_int($class)) {
// $condition .= " JSON_CONTAINS(dc.classYears, '{$class}') = 0 ";
//
//
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN JSON_CONTAINS(dc.classYears, '{$class}') = 0 THEN -1 ELSE 0 END)";
}
else
{
if($class == 'Suaugę')
{
// $condition .= " dc.classes not like '%Suaug%' ";
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN dc.classes not like '%Suaug%' THEN -1 ELSE 0 END)";
}
if($class == 'Priešmokyklinukai')
{
// $condition .= " dc.classes not like '%mokyklinukai%' ";
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN dc.classes not like '%mokyklinukai%' THEN -1 ELSE 0 END)";
}
}
}
// $condition .= " ) ";
}
// dump($condition);
// die();
$query
->andWhere('t.status = :status')
->setParameter('status', Teacher::STATUS_ACTIVE)
->andWhere('t.workedHours <= :workedHours')
->setParameter('workedHours', 1424)
->andWhere('t.available >= :available')
->setParameter('available', $available)
->innerJoin('t.teacherDisciplineClasses', 'dc', 'WITH', $condition)
->setParameter('discipline', $discipline);
if($debug)
{
dump($condition);
}
if ($ielts) { $query->andWhere('t.ielts > 0'); }
if ($flagRU) { $query->andWhere('t.flagRU = :flagRU')->setParameter('flagRU', $flagRU); }
if ($flagPL) { $query->andWhere('t.flagPL = :flagPL')->setParameter('flagPL', $flagPL); }
if ($flagENG) { $query->andWhere('t.flagENG = :flagENG')->setParameter('flagENG', $flagENG); }
if ($flagIB) {
$query->andWhere('t.flagIB = :flagIB')->setParameter('flagIB', $flagIB);
}
else
{
$query->andWhere('t.flagOnlyIB IS NULL OR t.flagOnlyIB = :flagOnlyIB')->setParameter('flagOnlyIB', 0);
}
if ($flagDyslexia) { $query->andWhere('t.flagDyslexia = :flagDyslexia')->setParameter('flagDyslexia', $flagDyslexia); }
if ($flagSensitive) { $query->andWhere('t.flagSensitive = :flagSensitive')->setParameter('flagSensitive', $flagSensitive); }
if ($flagStrict) { $query->andWhere('t.flagStrict = :flagStrict')->setParameter('flagStrict', $flagStrict); }
if ($flagExperienceAtSchool) { $query->andWhere('t.flagExperienceAtSchool = :flagExperienceAtSchool')->setParameter('flagExperienceAtSchool', $flagExperienceAtSchool); }
$dateNow = new \DateTime();
$dateNow->modify('-1 year');
if ($flagExperienceOver12Month) { $query->andWhere('t.workStart <= :workStart')->setParameter('workStart', $dateNow); }
if ($school) { $query->andWhere('t.school = :school')->setParameter('school', $school); }
if ($gender && $gender != 'Nesvarbu')
{
$query->andWhere('t.gender = :gender')->setParameter('gender', $gender);
}
// $query->addSelect("0 AS HIDDEN ORD ");
//optional
// $dateNow = new \DateTime();
// $dateNow->modify('-1 year');
// if ($flagExperienceOver12Month)
// {
// if($hiddenCases)
// {
// $hiddenCases.= ' + ';
// }
// $hiddenCases .= "(CASE WHEN t.workStart <= :workStart THEN 1 ELSE 0 END)";
// $query->setParameter('workStart', $dateNow);
//
// $query
// ->andWhere('t.workedHours >= :workedHours2')
// ->setParameter('workedHours2', 840);
// }
// if ($gender && $gender != 'Nesvarbu')
// {
// if($hiddenCases)
// {
// $hiddenCases.= ' + ';
// }
// $hiddenCases .= "(CASE WHEN t.gender = :gender THEN 1 ELSE 0 END)";
// $query->setParameter('gender', $gender);
// }
// if ($flagExperienceAtSchool)
// {
// if($hiddenCases)
// {
// $hiddenCases.= ' + ';
// }
// $hiddenCases .= "(CASE WHEN t.flagExperienceAtSchool = :flagExperienceAtSchool THEN 1 ELSE 0 END)";
// $query->setParameter('flagExperienceAtSchool', $flagExperienceAtSchool);
// }
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.flagPriorityAssignment = :flagPriorityAssignment THEN 1 ELSE 0 END)";
$query->setParameter('flagPriorityAssignment', 1);
$workStart30d = new \DateTime();
$workStart30d->modify('-30 days');
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.workStart >= :workStart30d THEN 2 ELSE 0 END)";
$query->setParameter('workStart30d', $workStart30d);
$workStart60d = new \DateTime();
$workStart60d->modify('-60 days');
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.workStart >= :workStart60d AND t.workStart <= :workStart30d THEN 1 ELSE 0 END)";
$query->setParameter('workStart60d', $workStart60d);
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.workStart >= :workStart60d AND t.workStart <= :workStart30d THEN 1 ELSE 0 END)";
if ($hiddenCases)
{
$hiddenCases .= ' + ';
}
$hiddenCases .= "(CASE
WHEN SIZE(t.childPreferences) = 0 THEN 3
WHEN SIZE(t.childPreferences) = 1 THEN 2
WHEN SIZE(t.childPreferences) = 2 THEN 1
ELSE 0
END)";
$twoWeeksAgo = new \DateTime();
$twoWeeksAgo->modify('-14 days');
if ($hiddenCases)
{
$hiddenCases .= ' + ';
}
$hiddenCases .= "(CASE
WHEN (
(SELECT COUNT(cp2.id) FROM App\\Entity\\ChildPreference cp2 WHERE cp2.teacher = t AND cp2.assignedAt >= :twoWeeksAgo) = 0
AND (t.available < (0.5 * t.maxLoad))
) THEN 3
ELSE 0
END)";
$query->setParameter('twoWeeksAgo', $twoWeeksAgo);
// if ($hiddenCases)
// {
// $hiddenCases .= ' + ';
// }
// $hiddenCases .= "(CASE WHEN t.maxLoad - t.available >= 4 THEN -10 ELSE 0 END)";
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.flagAutoAcceptAssignment = :flagAutoAcceptAssignment THEN 2 ELSE 0 END)";
$query->setParameter('flagAutoAcceptAssignment', 1);
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.levelName = :level1 THEN 3 ELSE 0 END)";
$query->setParameter('level1', 'Senior Tutor');
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.levelName = :level2 THEN 2 ELSE 0 END)";
$query->setParameter('level2', 'Pro Tutor');
if($hiddenCases)
{
$hiddenCases.= ' + ';
}
$hiddenCases .= "(CASE WHEN t.levelName = :level3 THEN 1 ELSE 0 END)";
$query->setParameter('level3', 'Expert Tutor');
if($hiddenCases) {
$hiddenSql = "({$hiddenCases}) AS HIDDEN ORD";
$query->addSelect($hiddenSql);
$query->addOrderBy('ORD', 'DESC');
}
//dump($hiddenSql);
$query->addOrderBy('t.available', 'DESC');
// dump($query->getQuery()->getSQL());
// die();
$teachers = $query
->getQuery()
->getResult();
// if($_SERVER['REMOTE_ADDR'] == '86.38.84.66' && $maxClass == 4) {
// dump($teachers);
// die();
// }
//Filter by times
$startTime1Priority = false;
$startTime2Priority = false;
$startTime3Priority = false;
$startTime4Priority = false;
$startTime5Priority = false;
$startTime6Priority = false;
$startTime7Priority = false;
$startTime1 = false;
$startTime2 = false;
$startTime3 = false;
$startTime4 = false;
$startTime5 = false;
$startTime6 = false;
$startTime7 = false;
$endTime1 = false;
$endTime2 = false;
$endTime3 = false;
$endTime4 = false;
$endTime5 = false;
$endTime6 = false;
$endTime7 = false;
$fittingTimes = $childPreferenceObjectToAssign->getChild()->getFittingTimes();
if($childPreferenceObjectToAssign->getFittingTimes())
{
$fittingTimes = $childPreferenceObjectToAssign->getFittingTimes();
}
$fittingTimes = str_replace(PHP_EOL, '', $fittingTimes);
$fittingTimes = str_replace("\r", '', $fittingTimes);
$fittingTimes = str_replace(" ", '', $fittingTimes);
$fittingTimes = explode(';', $fittingTimes);
$fittingTimes = array_filter($fittingTimes);
foreach ($fittingTimes as $fittingTime) {
$fittingDates = explode(',', $fittingTime);
if(!isset($fittingDates[1]))
{
continue;
}
$fittingHours = explode('-', $fittingDates[1]);
$fittingHours[0] = new \Datetime("1970-01-01 ".$fittingHours[0]);
$fittingHours[1] = new \Datetime("1970-01-01 ".$fittingHours[1]);
if ($fittingDates[0] == 'Pirmadienis') {
$startTime1 = $fittingHours[0];
$endTime1 = $fittingHours[1];
}
if ($fittingDates[0] == 'Antradienis') {
$startTime2 = $fittingHours[0];
$endTime2 = $fittingHours[1];
}
if ($fittingDates[0] == 'Trečiadienis') {
$startTime3 = $fittingHours[0];
$endTime3 = $fittingHours[1];
}
if ($fittingDates[0] == 'Ketvirtadienis') {
$startTime4 = $fittingHours[0];
$endTime4 = $fittingHours[1];
}
if ($fittingDates[0] == 'Penktadienis') {
$startTime5 = $fittingHours[0];
$endTime5 = $fittingHours[1];
}
if ($fittingDates[0] == 'Šeštadienis') {
$startTime6 = $fittingHours[0];
$endTime6 = $fittingHours[1];
}
if ($fittingDates[0] == 'Sekmadienis') {
$startTime7 = $fittingHours[0];
$endTime7 = $fittingHours[1];
}
}
$fittingTimes = $childPreferenceObjectToAssign->getChild()->getFittingTimesPriority();
if($childPreferenceObjectToAssign->getFittingTimesPriority())
{
$fittingTimes = $childPreferenceObjectToAssign->getFittingTimesPriority();
}
if($fittingTimes == null)
{
$fittingTimes = '';
}
$fittingTimes = str_replace(PHP_EOL, '', $fittingTimes);
$fittingTimes = str_replace("\r", '', $fittingTimes);
$fittingTimes = str_replace(" ", '', $fittingTimes);
$fittingTimes = explode(';', $fittingTimes);
$fittingTimes = array_filter($fittingTimes);
foreach ($fittingTimes as $fittingTime) {
$fittingDates = explode(',', $fittingTime);
$fittingHours = explode('-', $fittingDates[1]);
$fittingHours[0] = new \Datetime("1970-01-01 ".$fittingHours[0]);
$fittingHours[1] = new \Datetime("1970-01-01 ".$fittingHours[1]);
if ($fittingDates[0] == 'Pirmadienis') {
$startTime1 = $fittingHours[0];
$endTime1 = $fittingHours[1];
$startTime1Priority = true;
}
if ($fittingDates[0] == 'Antradienis') {
$startTime2 = $fittingHours[0];
$endTime2 = $fittingHours[1];
$startTime2Priority = true;
}
if ($fittingDates[0] == 'Trečiadienis') {
$startTime3 = $fittingHours[0];
$endTime3 = $fittingHours[1];
$startTime3Priority = true;
}
if ($fittingDates[0] == 'Ketvirtadienis') {
$startTime4 = $fittingHours[0];
$endTime4 = $fittingHours[1];
$startTime4Priority = true;
}
if ($fittingDates[0] == 'Penktadienis') {
$startTime5 = $fittingHours[0];
$endTime5 = $fittingHours[1];
$startTime5Priority = true;
}
if ($fittingDates[0] == 'Šeštadienis') {
$startTime6 = $fittingHours[0];
$endTime6 = $fittingHours[1];
$startTime6Priority = true;
}
if ($fittingDates[0] == 'Sekmadienis') {
$startTime7 = $fittingHours[0];
$endTime7 = $fittingHours[1];
$startTime7Priority = true;
}
}
$timesOriginal = [
1 => ['start' => $startTime1, 'end' => $endTime1, 'priority' => $startTime1Priority, 'weekday' => 1],
2 => ['start' => $startTime2, 'end' => $endTime2, 'priority' => $startTime2Priority, 'weekday' => 2],
3 => ['start' => $startTime3, 'end' => $endTime3, 'priority' => $startTime3Priority, 'weekday' => 3],
4 => ['start' => $startTime4, 'end' => $endTime4, 'priority' => $startTime4Priority, 'weekday' => 4],
5 => ['start' => $startTime5, 'end' => $endTime5, 'priority' => $startTime5Priority, 'weekday' => 5],
6 => ['start' => $startTime6, 'end' => $endTime6, 'priority' => $startTime6Priority, 'weekday' => 6],
7 => ['start' => $startTime7, 'end' => $endTime7, 'priority' => $startTime7Priority, 'weekday' => 7],
];
$availableTeachers = [];
$availableTimeSlots = [];
// dump($teachers);
// die();
//dump($timesOriginal);
//die();
if($debug)
{
dump('Teachers:');
foreach ($teachers as $teacher) {
dump($teacher->getId().' '.$teacher->getFullName().' '.$teacher->getAvailable());
}
dump('Times:');
dump($timesOriginal);
}
$workEndCheck = new \DateTime();
/**
* @var Teacher $teacher
*/
foreach ($teachers as $teacherKey => $teacher) {
// if($teacher->getId() != 1){
// continue;
// }
if ($teacher->getAvailable() < $available || $teacher->getAvailable() < 1) {
unset($teachers[$teacherKey]);
continue;
}
$teacherWorkEnd = null;
if($teacher->getWorkEnd())
{
$teacherWorkEnd = clone $teacher->getWorkEnd();
$teacherWorkEnd->modify('-60 days');
}
// 2025-10-25 2025-12-08
if ($teacherWorkEnd && $teacherWorkEnd < $workEndCheck) {
unset($teachers[$teacherKey]);
continue;
}
$foundAvailableTimeSlots = 0;
$availableTimeSlotsTeacher = [];
$addedWeekdays = [];
foreach ($teacher->getTeacherAvailabilityTimes() as $teacherAvailabilityTime) {
$times = $timesOriginal;
if($teacherAvailabilityTime->getStartTime() >= $teacherAvailabilityTime->getEndTime()) {
continue;
}
//dump($times);
//die();
$weekday = $teacherAvailabilityTime->getWeekday();
if ($times[$weekday]['start'] && $times[$weekday]['end']) {
// $debug = [
// "searchStart"=>$times[$weekday]['start'],
// "searchEnd"=>$times[$weekday]['end'],
// "teacherFoundStart"=>$teacherAvailabilityTime->getStartTime(),
// "teacherFoundEnd"=>$teacherAvailabilityTime->getEndTime(),
// "ifState1"=>($teacherAvailabilityTime->getEndTime() < $times[$weekday]['end'] && $teacherAvailabilityTime->getStartTime() > $times[$weekday]['start']),
// "ifState2"=>( $times[$weekday]['start'] < $teacherAvailabilityTime->getStartTime() && $times[$weekday]['end'] < $teacherAvailabilityTime->getEndTime() && $teacherAvailabilityTime->getStartTime() < $times[$weekday]['end']),
// "ifState3"=>($times[$weekday]['end'] > $teacherAvailabilityTime->getEndTime() && $times[$weekday]['start'] > $teacherAvailabilityTime->getStartTime() && $times[$weekday]['start'] < $teacherAvailabilityTime->getEndTime() )
// ];
// dump($debug);
// die();
//20:00 < 19:01 and 17:00 > 16:00
// dump($teacherAvailabilityTime->getEndTime());
// dump($times[$weekday]['end']);
// die();
if ($teacherAvailabilityTime->getEndTime() <= $times[$weekday]['end'] && $teacherAvailabilityTime->getStartTime() >= $times[$weekday]['start']) {
$times[$weekday]['end'] = $teacherAvailabilityTime->getEndTime();
$times[$weekday]['start'] = $teacherAvailabilityTime->getStartTime();
} // 16:00 < 17:00 ir 20:00 < 20:00
else if ($times[$weekday]['start'] < $teacherAvailabilityTime->getStartTime() && $times[$weekday]['end'] < $teacherAvailabilityTime->getEndTime() && $teacherAvailabilityTime->getStartTime() < $times[$weekday]['end']) {
$times[$weekday]['start'] = $teacherAvailabilityTime->getStartTime();
} else if ($times[$weekday]['end'] > $teacherAvailabilityTime->getEndTime() && $times[$weekday]['start'] > $teacherAvailabilityTime->getStartTime() && $times[$weekday]['start'] < $teacherAvailabilityTime->getEndTime()) {
$times[$weekday]['end'] = $teacherAvailabilityTime->getEndTime();
}
$afterIfs = [
'afterStart' => $times[$weekday]['start'],
'afterEnd' => $times[$weekday]['end']
];
if ($teacherAvailabilityTime->getStartTime() <= $times[$weekday]['start'] && $teacherAvailabilityTime->getEndTime() >= $times[$weekday]['end']) {
// dump('x');
// die();
$childPreferenceTimes = [];
$start = clone $teacherAvailabilityTime->getStartTime();
$end = clone $teacherAvailabilityTime->getEndTime();
$childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
$childPreferenceTimesSide = $childPreferenceTimesQuery
->leftJoin('cpt.childPreference', 'cp')
->andWhere('cp.teacher = :teacher')
->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPendTime')
->andWhere('cpt.startTime >= :startTime')
->andWhere('cpt.endTime <= :endTime')
->andWhere('cpt.weekday = :weekday')
->setParameter('teacher', $teacher)
->setParameter('startTime', $start)
->setParameter('endTime', $end)
->setParameter('weekday', $weekday)
->setParameter('CPendTime', $childPreferenceObjectToAssign->getStartTime())
->orderBy('cpt.startTime', 'ASC')
->getQuery()
->getResult();
foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
$childPreferenceTimes[] = $childPreferenceTimesSideElement;
}
}
$start = clone $teacherAvailabilityTime->getStartTime();
$end = clone $teacherAvailabilityTime->getEndTime();
$childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
$childPreferenceTimesSide = $childPreferenceTimesQuery
->leftJoin('cpt.childPreference', 'cp')
->andWhere('cp.teacher = :teacher')
->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPendTime')
->andWhere('cpt.startTime <= :startTime')
->andWhere('cpt.endTime >= :startTime')
->andWhere('cpt.weekday = :weekday')
->setParameter('teacher', $teacher)
->setParameter('startTime', $start)
->setParameter('weekday', $weekday)
->setParameter('CPendTime', $childPreferenceObjectToAssign->getStartTime())
->orderBy('cpt.startTime', 'ASC')
->getQuery()
->getResult();
foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
$childPreferenceTimes[] = $childPreferenceTimesSideElement;
}
}
$start = clone $teacherAvailabilityTime->getStartTime();
$end = clone $teacherAvailabilityTime->getEndTime();
$childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
$childPreferenceTimesSide = $childPreferenceTimesQuery
->leftJoin('cpt.childPreference', 'cp')
->andWhere('cp.teacher = :teacher')
->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPendTime')
->andWhere('cpt.startTime <= :endTime')
->andWhere('cpt.endTime >= :endTime')
->andWhere('cpt.weekday = :weekday')
->setParameter('teacher', $teacher)
->setParameter('endTime', $end)
->setParameter('CPendTime', $childPreferenceObjectToAssign->getStartTime())
->setParameter('weekday', $weekday)
->orderBy('cpt.startTime', 'ASC')
->getQuery()
->getResult();
foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
$childPreferenceTimes[] = $childPreferenceTimesSideElement;
}
}
//child Part
$start = clone $teacherAvailabilityTime->getStartTime();
$end = clone $teacherAvailabilityTime->getEndTime();
$childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
$childPreferenceTimesQuery
->leftJoin('cpt.childPreference', 'cp')
->andWhere('cp.child = :child')
->andWhere('cpt.startTime >= :startTime')
->andWhere('cpt.endTime <= :endTime')
->andWhere('cpt.weekday = :weekday')
->setParameter('child', $childPreferenceObjectToAssign->getChild())
->setParameter('startTime', $start)
->setParameter('endTime', $end)
->setParameter('weekday', $weekday)
->orderBy('cpt.startTime', 'ASC');
if($childPreferenceObjectToAssign->getStartTime())
{
$childPreferenceTimesQuery
->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPstartTime')->setParameter('CPstartTime', $childPreferenceObjectToAssign->getStartTime());
}
$childPreferenceTimesSide = $childPreferenceTimesQuery->getQuery()->getResult();
foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
$childPreferenceTimes[] = $childPreferenceTimesSideElement;
}
}
$start = clone $teacherAvailabilityTime->getStartTime();
$end = clone $teacherAvailabilityTime->getEndTime();
$childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
$childPreferenceTimesQuery
->leftJoin('cpt.childPreference', 'cp')
->andWhere('cp.child = :child')
->andWhere('cpt.startTime <= :startTime')
->andWhere('cpt.endTime >= :startTime')
->andWhere('cpt.weekday = :weekday')
->setParameter('child', $childPreferenceObjectToAssign->getChild())
->setParameter('startTime', $start)
->setParameter('weekday', $weekday)
->orderBy('cpt.startTime', 'ASC');
if($childPreferenceObjectToAssign->getStartTime())
{
$childPreferenceTimesQuery
->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPstartTime')->setParameter('CPstartTime', $childPreferenceObjectToAssign->getStartTime());
}
$childPreferenceTimesSide = $childPreferenceTimesQuery->getQuery()->getResult();
foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
$childPreferenceTimes[] = $childPreferenceTimesSideElement;
}
}
$start = clone $teacherAvailabilityTime->getStartTime();
$end = clone $teacherAvailabilityTime->getEndTime();
$childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
$childPreferenceTimesQuery
->leftJoin('cpt.childPreference', 'cp')
->andWhere('cp.child = :child')
->andWhere('cpt.startTime <= :endTime')
->andWhere('cpt.endTime >= :endTime')
->andWhere('cpt.weekday = :weekday')
->setParameter('child', $childPreferenceObjectToAssign->getChild())
->setParameter('endTime', $end)
->setParameter('weekday', $weekday)
->orderBy('cpt.startTime', 'ASC');
if($childPreferenceObjectToAssign->getStartTime())
{
$childPreferenceTimesQuery
->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPstartTime')->setParameter('CPstartTime', $childPreferenceObjectToAssign->getStartTime());
}
$childPreferenceTimesSide = $childPreferenceTimesQuery->getQuery()->getResult();
/** @var ChildPreferenceTime $childPreferenceTimesSideElement */
foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
$childPreferenceTimes[] = $childPreferenceTimesSideElement;
}
}
/**
* @var ChildPreferenceTime $childPreferenceTime
*/
foreach ($childPreferenceTimes as $key => $childPreferenceTime) {
$start = clone $childPreferenceTime->getStartTime();
$end = clone $childPreferenceTime->getEndTime();
if($teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments())
{
$start->modify('-'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
$end->modify('+'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
}
if ($end <= $times[$weekday]['start']) {
unset($childPreferenceTimes[$key]);
}
if ($start >= $times[$weekday]['end']) {
unset($childPreferenceTimes[$key]);
}
}
usort($childPreferenceTimes,
static fn($a, $b) => $a->getStartTime() <=> $b->getStartTime()
);
$childPreferenceTimes = array_values(array_filter($childPreferenceTimes));
if (count($childPreferenceTimes) == 0) {
//There are no child preferences just check if slot time
$slotTimeDuration = date_diff($times[$weekday]['start'], $times[$weekday]['end']);
$slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
// if($_SERVER['REMOTE_ADDR'] == '86.38.84.66' && $maxClass == 4) {
// dump($slotTime);
// dump($duration);
// }
if ($slotTime >= $duration/$amount) {
if(in_array($weekday, $addedWeekdays)) {
continue;
}
$foundAvailableTimeSlots++;
$availableTimeSlotsTeacher[] = [
'0start' => $times[$weekday]['start'],
'1end' => $times[$weekday]['end'],
'weekday' => $weekday
];
$addedWeekdays[] = $weekday;
continue;
}
}
//Find slots between other child preferences
/**
* @var ChildPreferenceTime $childPreferenceTime
*/
foreach ($childPreferenceTimes as $key => $childPreferenceTime) {
$start = clone $childPreferenceTime->getStartTime();
$end = clone $childPreferenceTime->getEndTime();
if($teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments())
{
$start->modify('-'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
$end->modify('+'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
}
if ($key == 0 && $start >= $times[$weekday]['start']) {
$slotTimeDuration = date_diff($times[$weekday]['start'], $start);
$slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
if ($slotTime >= $duration/$amount) {
if(in_array($weekday, $addedWeekdays)) {
continue;
}
$foundAvailableTimeSlots++;
$availableTimeSlotsTeacher[] = [
'0start' => $times[$weekday]['start'],
'1end' => $start,
'weekday' => $weekday
];
$addedWeekdays[] = $weekday;
continue 2;
}
}
if ($key + 1 == count($childPreferenceTimes) && $end <= $times[$weekday]['end']) {
//Last element
$slotTimeDuration = date_diff($end, $times[$weekday]['end']);
$slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
if ($slotTime >= $duration/$amount) {
if(in_array($weekday, $addedWeekdays)) {
continue;
}
$foundAvailableTimeSlots++;
$availableTimeSlotsTeacher[] = [
'0start' => $end,
'1end' => $times[$weekday]['end'],
'weekday' => $weekday
];
$addedWeekdays[] = $weekday;
continue 2;
}
} elseif ($end <= $times[$weekday]['end']) {
//Not last element
/**
* @var ChildPreferenceTime $nextChildPreferenceTime
*/
$nextChildPreferenceTime = $childPreferenceTimes[$key + 1];
$nextStart = clone $nextChildPreferenceTime->getStartTime();
if($teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments()){
$nextStart->modify('-'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
}
if ($end >= $nextStart) {
continue;
}
$slotTimeDuration = date_diff($end, $nextStart);
$slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
if ($slotTime >= $duration/$amount) {
if(in_array($weekday, $addedWeekdays)) {
continue;
}
$foundAvailableTimeSlots++;
$availableTimeSlotsTeacher[] = [
'0start' => $end,
'1end' => $nextStart,
'weekday' => $weekday
];
$addedWeekdays[] = $weekday;
continue 2;
}
}
}
}
}
}
// if($_SERVER['REMOTE_ADDR'] == '86.38.84.66' && $maxClass == 4) {
// dump($foundAvailableTimeSlots);
// dump($amount);
// dump($teacher->getId());
// die();
// }
// die();
if ($foundAvailableTimeSlots >= $amount) {
$availableTeachers[] = $teacher;
$availableTimeSlots[] = [
'times' => $availableTimeSlotsTeacher,
'teacher' => $teacher->getFullname(true)
];
}
// else
// {
// unset($teachers[$key]);
// }
}
$teachers = $this->serializer->normalize($availableTeachers, null, ['groups' => "TeacherList"]);
$dateNow = new \DateTime();
foreach ($teachers as $key => $teacher)
{
$teacherObj = $this->teacherRepository->find($teacher['id']);
$teacherHolidaysString = '';
foreach ($teacherObj->getTeacherHolidays() as $teacherHoliday)
{
if($teacherHoliday->getDateEnd() > $dateNow)
{
if($teacherHolidaysString)
{
$teacherHolidaysString .= '<br>';
}
$teacherHolidaysString .= "Nuo: {$teacherHoliday->getDateStart()->format('Y-m-d')} <br> Iki: {$teacherHoliday->getDateEnd()->format('Y-m-d')}";
}
}
$teachers[$key]['holiday'] = $teacherHolidaysString;
$teachers[$key]['fullname'] = $teacherObj->getFullname(true);
$teachers[$key]['have_moved_lessons'] = false;
$teachers[$key]['unavailableUntil'] = '';
foreach ($teacher['teacherUnavailableRanges'] as $teacherUnavailableRange)
{
if(new \DateTime($teacherUnavailableRange['startTime']) < new \DateTime() && new \DateTime($teacherUnavailableRange['endTime']) > new \DateTime())
{
$teachers[$key]['unavailableUntil'] = $teacherUnavailableRange['endTime'];
}
}
foreach ($timesOriginal as $weekdayKey => $originalTime) {
if (!$originalTime['start'] || !$originalTime['end']) {
continue;
}
$weeksToSearch = [0,1,2];
foreach ($weeksToSearch as $weekToSearch) {
$end = new \DateTime($originalTime['end']->format('H:i'));
$start = new \DateTime($originalTime['start']->format('H:i'));
$end->modify("next {$this->getWeekdayEnglishFromNumber($weekdayKey)}");
$end->setTime($originalTime['end']->format('H'), $originalTime['end']->format('i'));
$start->modify("next {$this->getWeekdayEnglishFromNumber($weekdayKey)}");
$start->setTime($originalTime['start']->format('H'), $originalTime['start']->format('i'));
$end->modify("+{$weekToSearch} weeks");
$start->modify("+{$weekToSearch} weeks");
$query = $this->lessonRepository->createQueryBuilder('l');
$lessons = $query
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $teacherObj)
->andWhere('l.status = :status')
->setParameter('status', Lesson::STATUS_REGULAR_MOVED['value'])
->andWhere('l.startTime < :end')
->setParameter('end', $end)
->andWhere('l.endTime > :start')
->setParameter('start', $start)
->getQuery()
->getResult();
if ($lessons) {
unset($teachers[$key]);
unset($availableTimeSlots[$key]);
break;
}
}
}
}
foreach ($availableTimeSlots as $key => &$availableTimeSlot) {
$priorities = array_column($timesOriginal, 'priority', 'weekday');
usort($availableTimeSlot['times'], function($a, $b) use ($priorities) {
$priorityA = $priorities[$a['weekday']] ?? false;
$priorityB = $priorities[$b['weekday']] ?? false;
if ($priorityA === $priorityB) {
return 0;
}
return $priorityA ? -1 : 1;
});
// $availableTimeSlots['times'] = [];
// dump($availableTimeSlot);
// dump($timesOriginal);
// dump($times);
// die();
}
// dump($timesOriginal);
// die();
// dump($availableTimeSlots);
// die();
//if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
// foreach ($teachers as $teacher)
// {
// dump($teacher['fullname']);
// }
// dump($teachers);
//// dump(["data" => $timesOriginal, 'timeSlots' => $availableTimeSlots]);
// dump($timesOriginal);
// dump($availableTimeSlots);
//// dump($childPreferenceObjectToAssign->getChildPreferenceTimes()->getValues());
//// dump($availableTimeSlots[1]['times'][0]);
// die();
//}
$this->entityManager->refresh($childPreferenceObjectToAssign);
if($childPreferenceObjectToAssign->getStatus() == ChildPreference::STATUS_ASSIGNED['value'])
{
return;
}
if($debug)
{
dump('availableTimeSlots:');
dump($availableTimeSlots);
}
$firstKey = array_key_first($teachers);
// if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
// $firstKey = 1;
// }
if(isset($teachers[$firstKey]) && $teachers[$firstKey])
{
if(!count($childPreferenceObjectToAssign->getChildPreferenceTimes()->getValues())) {
for($i = 0; $i < $amount; $i++) {
if (isset($availableTimeSlots[$firstKey]['times'][$i]['weekday'])) {
if(!$debug)
{
$childPreferenceTime = (new ChildPreferenceTime())
->setChildPreference($childPreferenceObjectToAssign)
->setCreatedAt(new \DateTime())
->setWeekday($availableTimeSlots[$firstKey]['times'][$i]['weekday'])
->setStartTime((new \DateTime("{$availableTimeSlots[$firstKey]['times'][$i]['0start']->format('H:i')}")))
->setEndTime((new \DateTime("{$availableTimeSlots[$firstKey]['times'][$i]['0start']->format('H:i')}"))->modify("+{$childPreferenceObjectToAssign->getSingleEmailDuration()} minutes"));
// if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
// dump($availableTimeSlots[$firstKey]);
// dump($childPreferenceTime);
// die();
// }
$this->entityManager->persist($childPreferenceTime);
$childPreferenceObjectToAssign->addChildPreferenceTime($childPreferenceTime);
$this->entityManager->persist($childPreferenceObjectToAssign);
$this->entityManager->flush();
}
}
}
}
// if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
// die();
// }
if(!$debug) {
$oldChildPreferenceObjectToAssign = clone $childPreferenceObjectToAssign;
$childPreferenceObjectToAssign->setTeacher($this->teacherRepository->find($teachers[$firstKey]['id']));
$childPreferenceObjectToAssign->setStatus(ChildPreference::STATUS_ASSIGNED['value']);
$childPreferenceObjectToAssign->setAssignedAt(new \DateTime());
$childPreferenceObjectToAssign->setAssignedAutomaticly(new \DateTime());
$this->entityManager->persist($childPreferenceObjectToAssign);
$this->entityManager->flush();
$this->guardianLogService->addGuardianActionLog(
"Automatinis priskyrimas ({$childPreferenceObjectToAssign->getChild()->getFullname()} {$childPreferenceObjectToAssign->getDiscipline()->getName()}): {$childPreferenceObjectToAssign->getTeacher()->getFullname()}",
$childPreferenceObjectToAssign->getChild()->getGuardian(),
$childPreferenceObjectToAssign,
'update'
);
$this->entityManager->flush();
$this->handleStatusChange($oldChildPreferenceObjectToAssign, $childPreferenceObjectToAssign);
}
if($debug)
{
die();
}
}
// elseif ($maxClass < 13)
// {
// $maxClass++;
// $this->assignTeacher($childPreferenceObjectToAssign, $child ,$teacherToForceAssign, $maxClass, $debug);
// }
else {
if($debug)
{
die();
}
$childPreferenceObjectToAssign->setStatus(ChildPreference::STATUS_NOT_FOUND['value']);
$this->entityManager->persist($childPreferenceObjectToAssign);
$this->entityManager->flush();
}
}
public function sendAssignedNotification(ChildPreference $childPreference)
{
$guardian = $childPreference->getChild()->getGuardian();
$child = $childPreference->getChild();
$teacher = $childPreference->getTeacher();
$message = "Sveiki,
Pirmasis mūsų užsiėmimas jau netoliese, jeigu turite klausimų, galite parašyti čia.
Iki pasimatymo!
{$childPreference->getTeacher()->getFullname()}
";
try {
$this->getStreamService->sendMessage($teacher, $guardian, $message);
$this->getStreamService->sendMessage($teacher, $child, $message);
}
catch (\Exception $e)
{
}
if(!$guardian->getMobileAppLastUsedAt()) {
$dateToSendAt = new \DateTime();
$this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
DelayStamp::delayUntil($dateToSendAt),
]));
$dateToSendAt = new \DateTime();
$dateToSendAt->modify('+24 hours');
$dateToSendAt->setTime(9, 0, 0);
$this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
DelayStamp::delayUntil($dateToSendAt),
]));
$dateToSendAt = new \DateTime();
$dateToSendAt->modify('+48 hours');
$dateToSendAt->setTime(9, 0, 0);
$this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
DelayStamp::delayUntil($dateToSendAt),
]));
$dateToSendAt = new \DateTime();
$dateToSendAt->modify('+72 hours');
$dateToSendAt->setTime(9, 0, 0);
$this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
DelayStamp::delayUntil($dateToSendAt),
]));
}
}
public function handleStatusChange(ChildPreference $oldChildPreference, ChildPreference $childPreference, $oldChildPreferenceTimes = [])
{
if ($oldChildPreference->getStatus() != $childPreference->getStatus() && $childPreference->getStatus() == ChildPreference::STATUS_AUTOMATIC_ASSIGNMENT['value']) {
$dateToSendAt = new \DateTime();
$this->messageBus->dispatch(new Envelope(new AssignChildPreferenceTeacherMessage($childPreference->getId(), $childPreference->getTeacher()), [
DelayStamp::delayUntil($dateToSendAt),
]));
}
//Jeigu keiciasi mokytojas, metam i priskirta
//Notif 0
if ($oldChildPreference->getTeacher() != $childPreference->getTeacher() || ($oldChildPreference->getStatus() != $childPreference->getStatus() && $childPreference->getStatus() == ChildPreference::STATUS_ASSIGNED['value'])) {
$childPreference->setStatus(ChildPreference::STATUS_ASSIGNED['value']);
$childPreference->setAssignedAt(new \DateTime());
$childPreference->setTeacherAssignRemindCount(0);
$this->entityManager->persist($childPreference);
$this->entityManager->flush();
if($childPreference->getTeacher() && $childPreference->getTeacher()->isFlagAutoAcceptAssignment())
{
if ($childPreference->getChild()->getLessonsEnd()) {
$child = $childPreference->getChild();
$child->setLessonsEnd(null);
$this->entityManager->persist($child);
$this->entityManager->flush();
}
$childPreference->setStatus(ChildPreference::STATUS_ACCEPTED['value']);
$childPreference->setAcceptedAt(new \Datetime());
$startTime = $this->findFirstLessonDate($childPreference);
if($startTime) {
$childPreference->setStartTime($startTime);
}
$oldChildPreference = clone $childPreference;
$this->entityManager->persist($childPreference);
$this->entityManager->flush();
$this->entityManager->refresh($childPreference);
$this->generateLessonsForChildPreference($childPreference);
if($startTime) {
$this->recalculatePricesForFurtherLessons($childPreference->getChild()->getGuardian(), $startTime);
}
$this->sendAcceptedEmailAndSMS($childPreference);
$this->sendAssignedNotification($childPreference);
$teacherComments = $this->findPreviousComments($childPreference);
$teacherCommentsString = '';
if ($teacherComments) {
foreach ($teacherComments as $teacherComment) {
$date = $teacherComment->getCreatedAt()->format('Y-m-d');
$teacherCommentsString .= "<strong>{$date}</strong>:<br>{$teacherComment->getComment()}<br>";
}
}
$preferenceSummary = "";
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
}
$replacements = [
'[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
'[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
'[FIRST_LESSON_DATE]' => $childPreference->getStartTime()->format('Y-m-d H:i'),
'[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
'[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
'[SINGLE_LESSON_AMOUNT]' => $childPreference->getAmount(),
'[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
'[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
'[FIRST_LESSON_DATE_TIME]' => $childPreference->getStartTime()->format('Y-m-d H:i'),
'[PREFERENCE_COMMENT]' => $childPreference->getComment(),
'[TEACHER_COMMENTS]' => $teacherCommentsString,
'[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
'[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
];
$this->notificationService->sendNotificationTemplate($childPreference->getTeacher(),'TEACHER_NEW_AUTO_ACCEPT_ASSIGNMENT', $replacements, true);
if($childPreference->getTeacher() && $childPreference->getTeacher()->getPhoneNumber()) {
$this->messageBus->dispatch(new SendSMSMessage($childPreference->getTeacher()->getPhoneNumber(), '', $replacements, 'ASSIGNMENT_NEW_AUTO_NOTIF_1'));
}
}
if (!$childPreference->getIgnoreNotifications() && (!$childPreference->getTeacher() || !$childPreference->getTeacher()->isFlagAutoAcceptAssignment())) {
$this->sendAssignedEmailandSMS($childPreference);
}
}
//Jeigu mokytojas patvirtino
//Notif 1
if ($oldChildPreference->getStatus() != $childPreference->getStatus() && $childPreference->getStatus() == ChildPreference::STATUS_ACCEPTED['value'] && $childPreference->getTeacher()) {
$this->sendAcceptedEmailAndSMS($childPreference);
}
//Jeigu keicia mokytoja, uzsetinam priezasti jeigu jos neirase tiesiog.
if ($childPreference->getTeacherChange() && !$childPreference->getTerminateReason()) {
if ($childPreference->getTeacherChange() == 'teacherChangeTeacher') {
$childPreference->setTerminateReason('Korepetitoriaus prašymu');
}
if ($childPreference->getTeacherChange() == 'teacherChangeGuardian') {
$childPreference->setTerminateReason('Kliento prašymas');
}
if ($childPreference->getTeacherChange() == 'amountDiscipline') {
$childPreference->setTerminateReason('Dažnio/ krūvio/ disciplinos keitimas');
}
$this->entityManager->persist($childPreference);
$this->entityManager->flush();
}
//Jeigu nera priezasties, nesaugom ir pabaigos datos. Administracijos klaida.
if (!$childPreference->getTerminateReason() && $childPreference->getEndTime()) {
$childPreference->setEndTime(null);
$this->entityManager->persist($childPreference);
$this->entityManager->flush();
}
//Jeigu tiesiog nutraukia uzsiemimus
//Notif 2
if (!$oldChildPreference->getEndTime() && $childPreference->getTerminateReason() && $childPreference->getEndTime() && !$childPreference->getTeacherChange() && $childPreference->getTeacher()) {
$childPreference->setStatus(ChildPreference::STATUS_TERMINATING['value']);
$this->entityManager->persist($childPreference);
$this->entityManager->flush();
$this->deleteLessonAfterPreferenceEndPeriod($childPreference);
if (!$childPreference->getIgnoreNotifications()) {
$this->sendTerminatingEmailAndSMS($childPreference);
}
}
//Jeigu nutraukia su senu mokytoju, bet skirs nauja keiciasi mokytojas
if ($childPreference->getTeacherChange() && $childPreference->getEndTime() && !$oldChildPreference->getTerminateReason() && !$oldChildPreference->getEndTime() && $childPreference->getTeacher()) {
$childPreference->setStatus(ChildPreference::STATUS_TERMINATING['value']);
//Notif 3
$this->deleteLessonAfterPreferenceEndPeriod($childPreference);
$newChildPreference = new ChildPreference();
$newChildPreference->setChild($childPreference->getChild());
$newChildPreference->setAdminComment($childPreference->getAdminComment());
$newChildPreference->setEmailDuration($childPreference->getEmailDuration());
$newChildPreference->setSingleEmailDuration($childPreference->getSingleEmailDuration());
$newChildPreference->setDiscipline($childPreference->getDiscipline());
$newChildPreference->setComment($childPreference->getComment());
$newChildPreference->setType($childPreference->getType());
$newChildPreference->setFittingTimes($childPreference->getFittingTimes());
$this->entityManager->persist($newChildPreference);
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$newChildPreferenceTime = new ChildPreferenceTime();
$newChildPreferenceTime->setChildPreference($newChildPreference);
$newChildPreferenceTime->setEndTime($childPreferenceTime->getEndTime());
$newChildPreferenceTime->setStartTime($childPreferenceTime->getStartTime());
$newChildPreferenceTime->setWeekday($childPreferenceTime->getWeekday());
$this->entityManager->persist($newChildPreferenceTime);
$newChildPreference->addChildPreferenceTime($newChildPreferenceTime);
}
$this->entityManager->flush();
if ($childPreference->getTeacherChange() == 'teacherChangeTeacher') {
if (!$childPreference->getIgnoreNotifications()) {
$this->sendTerminatingByTeacherEmailAndSMS($childPreference);
}
}
//Notif 4
if ($childPreference->getTeacherChange() == 'teacherChangeGuardian') {
if (!$childPreference->getIgnoreNotifications()) {
$this->sendTerminatingByGuardianEmailAndSMS($childPreference);
}
}
//Notif 4
if ($childPreference->getTeacherChange() == 'amountDiscipline') {
if (!$childPreference->getIgnoreNotifications()) {
$this->sendTerminatingByChangeEmailAndSMS($childPreference);
}
}
}
if ($childPreference->getIgnoreNotifications() && $childPreference->getRegenerateLessonsFrom()) {
$this->deleteLessonBeforeRegenerate($oldChildPreference, $oldChildPreferenceTimes, $childPreference->getRegenerateLessonsFrom());
$this->generateLessonsForChildPreference($childPreference, $childPreference->getRegenerateLessonsFrom()->format('Y-m-d H:i'));
}
if ($childPreference->getRegenerateAllLessons() && $childPreference->getRegenerateLessonsFrom()) {
$this->deleteChildLessons($childPreference->getChild(), $childPreference->getRegenerateLessonsFrom());
foreach ($childPreference->getChild()->getChildPreferences() as $childPreferenceForRegenerating) {
$this->generateLessonsForChildPreference($childPreferenceForRegenerating, $childPreference->getRegenerateLessonsFrom()->format('Y-m-d H:i'));
}
}
}
public function sendAssignedEmailAndSMS(ChildPreference $childPreference, $onlySMS = false)
{
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_NEW_NOTIF_0']);
$preferenceSummary = "";
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
}
$startTime = $childPreference->getStartTime();
if (!$startTime) {
$startTime = new \DateTime();
}
$childName = $childPreference->getChild()->getFullname();
$childName = explode(' ', $childName);
$childName = $childName[0];
$replacements = [
'[FIRST_LESSON_DATE]' => "{$this->getWeekdayFromNumber($startTime->format('N'))} {$startTime->format('(Y-m-d) H:i')}",
'[PREFERENCE_SUMMARY]' => $preferenceSummary,
'[CHILD_NAME]' => $childName,
'[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
'[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
'[ACCEPT_LINK]' => 'https://cor.lt' . $this->urlGenerator->generate('app_teacher_my_students'),
// '[ACCEPT_LINK]' => 'https://corepetitus.tlprojektai.lt' . $this->urlGenerator->generate('app_teacher_my_students'),
'[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
];
$emailAddress = $childPreference->getTeacher()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailTeacher;
}
if (!$onlySMS) {
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_NEW_NOTIF_0'));
}
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneTeacher;
}
$this->smsService->send($phoneNumber, $smsContent);
foreach ($this->userFireBaseTokenRepository->findBy(['userClass' => 'teacher', 'userId' => $childPreference->getTeacher()->getId()]) as $userFireBaseToken) {
$token = $userFireBaseToken->getToken();
$this->fcmService->send($token, 'Naujas priskyrimas', 'Prašome per 1 val. patvirtinti mokinio priskyrimą');
}
}
private function isDateWithinVacationForDiscipline(Child $child, \DateTimeInterface $date, int $disciplineId): bool
{
foreach ($child->getChildVacations() as $vacation) {
if ($vacation->isIsDeleted()) {
continue;
}
if ($vacation->getDateFrom() >= $date || $vacation->getDateTo() <= $date) {
continue;
}
$vacationDisciplineIds = $vacation->getDisciplineIds();
if ($vacationDisciplineIds === null || in_array($disciplineId, $vacationDisciplineIds)) {
return true;
}
}
return false;
}
public function sendAcceptedEmailAndSMS(ChildPreference $childPreference)
{
$startTime = $childPreference->getStartTime();
if (!$startTime) {
$startTime = new \DateTime();
}
if ($this->isDateWithinVacationForDiscipline(
$childPreference->getChild(),
$startTime,
$childPreference->getDiscipline()->getId()
)) {
return;
}
//Tutor Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CONFIRMED_TUTOR_NOTIF_1']);
$preferenceSummary = "";
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
}
$childName = $childPreference->getChild()->getFullname();
$childName = explode(' ', $childName);
$childName = $childName[0];
$teacherComments = $this->findPreviousComments($childPreference);
$teacherCommentsString = '';
if ($teacherComments) {
$teacherCommentsString = "<strong>Buvusio korepetitoriaus atsiliepimai apie mokinį:</strong><br>";
foreach ($teacherComments as $teacherComment) {
$date = $teacherComment->getCreatedAt()->format('Y-m-d');
$teacherCommentsString .= "<strong>{$date}</strong>:<br>{$teacherComment->getComment()}<br>";
}
}
// dump($teacherCommentsString);
// die();
$replacements = [
'[FIRST_LESSON_DATE]' => "{$this->getWeekdayFromNumber($startTime->format('N'))} {$startTime->format('(Y-m-d) H:i')}",
'[CHILD_NAME]' => $childName,
'[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
'[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
'[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
'[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
'[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
'[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
'[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
'[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
'[PREFERENCE_COMMENT]' => $childPreference->getComment(),
'[FIRST_LESSON_DATE_TIME]' => "{$this->getWeekdayFromNumber($startTime->format('N'))} {$startTime->format('(Y-m-d) H:i')}",
'[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
'[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
'[TEACHER_COMMENTS]' => $teacherCommentsString,
'[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
];
$emailAddress = $childPreference->getTeacher()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailTeacher;
}
$this->bus->dispatch(new SendMailMessage($emailAddress,'','', $replacements, 'ASSIGNMENT_CONFIRMED_TUTOR_NOTIF_1'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneTeacher;
}
// $this->smsService->send($phoneNumber, $smsContent);
if($phoneNumber) {
$this->bus->dispatch(new SendSMSMessage($phoneNumber, $smsContent));
}
//Guardian Part
$replacements['[CHILD_NAME]'] = $childPreference->getChild()->getFullname();
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CONFIRMED_GUARDIAN_NOTIF_1']);
$emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailGuardian;
}
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneGuardian;
}
$dateNow = new \DateTime();
$dateMax = new \DateTime();
$dateMax->setTime(19, 0);
$dateMin = new \DateTime();
$dateMin->setTime(8, 59);
if ($dateNow < $dateMin || $dateNow > $dateMax) {
$dateToSendAt = new \DateTime();
if ($dateNow > $dateMax) {
$dateToSendAt->modify('+1 day');
}
$dateToSendAt->setTime(9, 0);
$this->bus->dispatch(new Envelope(new SendMailMessage($emailAddress,'','', $replacements, 'ASSIGNMENT_CONFIRMED_GUARDIAN_NOTIF_1'), [
DelayStamp::delayUntil($dateToSendAt),
]));
$this->bus->dispatch(new Envelope(new SendSMSMessage($phoneNumber, $smsContent), [
DelayStamp::delayUntil($dateToSendAt),
]));
} else {
//send Now
$this->bus->dispatch(new SendMailMessage($emailAddress,'','', $replacements, 'ASSIGNMENT_CONFIRMED_GUARDIAN_NOTIF_1'));
$this->bus->dispatch(new SendSMSMessage($phoneNumber, $smsContent));
// $this->smsService->send($phoneNumber, $smsContent);
}
}
public function sendTerminatingEmailAndSMS(ChildPreference $childPreference)
{
//Tutor Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_STOP_TUTOR_NOTIF_2']);
$preferenceSummary = "";
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
}
$endTime = $childPreference->getEndTime();
if (!$endTime) {
$endTime = new \DateTime();
}
$replacements = [
'[LAST_LESSON_DATE]' => "{$this->getWeekdayFromNumber($endTime->format('N'))} {$endTime->format('(Y-m-d)')}",
'[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
'[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
'[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
'[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
'[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
'[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
'[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
'[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
'[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
'[PREFERENCE_COMMENT]' => $childPreference->getComment(),
'[LAST_LESSON_DATE_TIME]' => "{$this->getWeekdayFromNumber($endTime->format('N'))} {$endTime->format('(Y-m-d) H:i')}",
'[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
'[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
'[CANCEL_REASON]' => $childPreference->getTerminateReason(),
'[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
];
$emailAddress = $childPreference->getTeacher()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailTeacher;
}
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CLIENT_STOP_TUTOR_NOTIF_2'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneTeacher;
}
$this->smsService->send($phoneNumber, $smsContent);
//Guardian Part
if ($childPreference->getChild()->getGuardian()->getSummer() && (new \DateTime()) < (new \DateTime('2024-08-31'))) {
return;
}
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_STOP_GUARDIAN_NOTIF_2']);
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneGuardian;
}
$this->smsService->send($phoneNumber, $smsContent);
}
public function sendTerminatingByTeacherEmailAndSMS(ChildPreference $childPreference)
{
//Tutor Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_TUTOR_STOP_TUTOR_NOTIF_3']);
$preferenceSummary = "";
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
}
$endTime = $childPreference->getEndTime();
if (!$endTime) {
$endTime = new \DateTime();
}
$replacements = [
'[LAST_LESSON_DATE]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
'[LAST_LESSON_DATE_TEACHER]' => "{$this->getWeekdayFromNumber($endTime->format('N'))} {$endTime->format('(Y-m-d)')}",
'[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
'[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
'[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
'[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
'[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
'[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
'[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
'[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
'[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
'[PREFERENCE_COMMENT]' => $childPreference->getComment(),
'[LAST_LESSON_DATE_TIME]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
'[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
'[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
'[CANCEL_REASON]' => $childPreference->getTerminateReason(),
'[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
'[TUTOR_TERMINATE_COMMENT]' => $childPreference->getTutorTerminateComment(),
];
$emailAddress = $childPreference->getTeacher()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailTeacher;
}
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_TUTOR_STOP_TUTOR_NOTIF_3'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneTeacher;
}
$this->smsService->send($phoneNumber, $smsContent);
//Guardian Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_TUTOR_STOP_GUARDIAN_NOTIF_3']);
$emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailGuardian;
}
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_TUTOR_STOP_GUARDIAN_NOTIF_3'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneGuardian;
}
$this->smsService->send($phoneNumber, $smsContent);
}
public function sendTerminatingByGuardianEmailAndSMS(ChildPreference $childPreference)
{
//Tutor Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_CHANGE_TUTOR_NOTIF_4']);
$preferenceSummary = "";
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
}
$endTime = $childPreference->getEndTime();
if (!$endTime) {
$endTime = new \DateTime();
}
$replacements = [
'[LAST_LESSON_DATE]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
'[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
'[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
'[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
'[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
'[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
'[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
'[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
'[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
'[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
'[PREFERENCE_COMMENT]' => $childPreference->getComment(),
'[LAST_LESSON_DATE_TIME]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
'[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
'[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
'[CANCEL_REASON]' => $childPreference->getTerminateReason(),
'[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
'[TUTOR_TERMINATE_COMMENT]' => $childPreference->getTutorTerminateComment(),
];
$emailAddress = $childPreference->getTeacher()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailTeacher;
}
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CLIENT_CHANGE_TUTOR_NOTIF_4'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneTeacher;
}
$this->smsService->send($phoneNumber, $smsContent);
//Guardian Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_CHANGE_GUARDIAN_NOTIF_4']);
$emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailGuardian;
}
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CLIENT_CHANGE_GUARDIAN_NOTIF_4'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneGuardian;
}
$this->smsService->send($phoneNumber, $smsContent);
}
public function sendTerminatingByChangeEmailAndSMS(ChildPreference $childPreference)
{
//Tutor Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CHANGE_AMOUNT_TUTOR']);
$preferenceSummary = "";
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
}
$endTime = $childPreference->getEndTime();
if (!$endTime) {
$endTime = new \DateTime();
}
$replacements = [
'[LAST_LESSON_DATE]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
'[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
'[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
'[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
'[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
'[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
'[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
'[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
'[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
'[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
'[PREFERENCE_COMMENT]' => $childPreference->getComment(),
'[LAST_LESSON_DATE_TIME]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
'[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
'[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
'[CANCEL_REASON]' => $childPreference->getTerminateReason(),
'[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
];
$emailAddress = $childPreference->getTeacher()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailTeacher;
}
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CHANGE_AMOUNT_TUTOR'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneTeacher;
}
$this->smsService->send($phoneNumber, $smsContent);
//Guardian Part
$reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CHANGE_AMOUNT_GUARDIAN']);
$emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
if ($this->testMode) {
$emailAddress = $this->testEmailGuardian;
}
$this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CHANGE_AMOUNT_GUARDIAN'));
$smsContent = $reminderObject->getSmsTemplate();
$smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
$phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
if ($this->testMode) {
$phoneNumber = $this->testPhoneGuardian;
}
$this->smsService->send($phoneNumber, $smsContent);
}
public function findPreviousComments(ChildPreference $childPreference)
{
$teacherComments = [];
foreach (array_reverse($childPreference->getChild()->getTeacherSurveyResponses()->getValues()) as $teacherComment) {
if ($childPreference->getDiscipline() == $teacherComment->getDiscipline()) {
$teacherComments[] = $teacherComment;
if (count($teacherComments) == 3) {
break;
}
}
}
usort($teacherComments, function ($a, $b) {
return $a->getCreatedAt() < $b->getCreatedAt();
});
return $teacherComments;
}
public function findFirstLessonDate(ChildPreference $childPreference)
{
$currentTime = new \DateTime();
if (!$childPreference->getStartTime()) {
$dateNow = new \DateTime();
$dateNow->modify('+24 hours');
} elseif ($childPreference->getStartTime() < new \DateTime()) {
$dateNow = new \DateTime();
} else {
$dateNow = $childPreference->getStartTime();
}
$firstLessonDate = null;
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$startTimePreference = $childPreferenceTime->getStartTime();
$weekday = $this->getWeekdayEnglishFromNumber($childPreferenceTime->getWeekday());
for ($i = 0; $i <= 24; $i++) {
$startTime = new \DateTime();
$startTime->modify("first {$weekday} of {$startTime->format('Y-M')}");
$startTime->setTime((int)$startTimePreference->format('H'), (int)$startTimePreference->format('i'));
$startTime->modify("+{$i} weeks");
if ($currentTime <= $startTime && $startTime >= $dateNow && (!$firstLessonDate || $startTime <= $firstLessonDate)) {
$firstLessonDate = $startTime;
}
}
}
$childPreference->setStartTime($firstLessonDate);
return $firstLessonDate;
}
public function findFirstLessonDateForAccepted(ChildPreference $childPreference)
{
$query = $this->lessonRepository->createQueryBuilder('l');
$lesson = $query
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $childPreference->getTeacher())
->andWhere('l.discipline = :discipline')
->setParameter('discipline', $childPreference->getDiscipline())
->andWhere(':child member of l.children')
->setParameter('child', $childPreference->getChild()->getId())
->setMaxResults(1)
->orderBy('l.startTime', 'ASC')
->getQuery()
->getOneOrNullResult();
if ($lesson) {
$childPreference->setStartTime($lesson->getStartTime());
}
return $childPreference->getStartTime();
}
public function deleteLessonAfterPreferenceEndPeriod(ChildPreference $childPreference, $doNotDeleteList = null)
{
$lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
$dateStart = new \DateTime($childPreference->getEndTime()->format('Y-m-d H:i'));
$lessons = $lessonsQuery
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $childPreference->getTeacher())
->andWhere('l.startTime >= :dateStart')
->setParameter('dateStart', $dateStart)
->andWhere(':child MEMBER OF l.children')
->setParameter('child', $childPreference->getChild()->getId())
->andWhere('l.discipline = :discipline')
->setParameter('discipline', $childPreference->getDiscipline())
->andWhere('l.type = :type')
->setParameter('type', $childPreference->getType())
->getQuery()
->getResult();
/**
* @var $lesson Lesson
*/
foreach ($lessons as $lesson) {
// if($lesson->getStatusValue() == Lesson::STATUS_REGULAR_MOVED['value']){
// continue;
// }
$skip = false;
if ($doNotDeleteList) {
foreach ($doNotDeleteList as $doNotDeleteDate) {
if ($doNotDeleteDate->format('Y-m-d H:i') == $lesson->getStartTime()->format('Y-m-d H:i')) {
$skip = true;
}
}
}
if (!$skip) {
foreach ($lesson->getTeacherPaymentLogs() as $teacherPaymentLog) {
$this->entityManager->remove($teacherPaymentLog);
}
$this->lessonDeletionService->delete(
$lesson,
LessonDeletionService::REASON_PREFERENCE_END_PERIOD
);
$this->entityManager->flush();
}
}
}
public function deleteLessonBeforeRegenerate(ChildPreference $childPreference, $childPreferenceTimes, $dateStart)
{
if (!$childPreference->getChild()) {
return true;
}
$lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
$lessons = $lessonsQuery
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $childPreference->getTeacher())
->andWhere('l.startTime >= :dateStart')
->setParameter('dateStart', $dateStart)
->andWhere(':child MEMBER OF l.children')
->setParameter('child', $childPreference->getChild()->getId())
->andWhere('l.discipline = :discipline')
->setParameter('discipline', $childPreference->getDiscipline())
->andWhere('l.type = :type')
->setParameter('type', $childPreference->getType())
->getQuery()
->getResult();
/**
* @var $lesson Lesson
*/
foreach ($lessons as $lesson) {
if (in_array($lesson->getStatusValue(), [Lesson::STATUS_REGULAR_MOVED['value'], Lesson::STATUS_ADDITIONAL['value']])) {
continue;
}
$this->lessonDeletionService->delete(
$lesson,
LessonDeletionService::REASON_PREFERENCE_REGENERATED
);
$this->entityManager->flush();
}
}
public function deleteChildLessons(Child $child, $dateStart)
{
if (!$child || !$dateStart) {
return true;
}
$lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
$lessons = $lessonsQuery
->andWhere(':child MEMBER OF l.children')
->setParameter('child', $child)
->andWhere('l.startTime >= :dateStart')
->setParameter('dateStart', $dateStart)
->getQuery()
->getResult();
/**
* @var $lesson Lesson
*/
foreach ($lessons as $lesson) {
if (in_array($lesson->getStatusValue(), [Lesson::STATUS_REGULAR_MOVED['value'], Lesson::STATUS_ADDITIONAL['value']])) {
continue;
}
$this->lessonDeletionService->delete(
$lesson,
LessonDeletionService::REASON_CHILD_LESSONS_REMOVED
);
$this->entityManager->flush();
}
}
public function deleteLessonsForRemovedPreferenceTime(ChildPreference $childPreference, ChildPreferenceTime $removedTime): void
{
if (!$childPreference->getChild() || !$childPreference->getTeacher() || !$childPreference->getDiscipline()) {
return;
}
$removedWeekday = (int) $removedTime->getWeekday();
$removedStartTime = $removedTime->getStartTime()->format('H:i');
foreach ($childPreference->getChildPreferenceTimes() as $stillActiveTime) {
if ((int) $stillActiveTime->getWeekday() === $removedWeekday
&& $stillActiveTime->getStartTime()->format('H:i') === $removedStartTime) {
// A remaining row still covers this weekday/time (e.g. it was re-added), so its lessons are legitimate.
return;
}
}
$lessons = $this->lessonRepository->createQueryBuilder('l')
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $childPreference->getTeacher())
->andWhere(':child MEMBER OF l.children')
->setParameter('child', $childPreference->getChild()->getId())
->andWhere('l.discipline = :discipline')
->setParameter('discipline', $childPreference->getDiscipline())
->andWhere('l.type = :type')
->setParameter('type', $childPreference->getType())
->andWhere('l.startTime >= :now')
->setParameter('now', new \DateTime())
->getQuery()
->getResult();
/** @var Lesson $lesson */
foreach ($lessons as $lesson) {
if (in_array($lesson->getStatusValue(), [Lesson::STATUS_REGULAR_MOVED['value'], Lesson::STATUS_ADDITIONAL['value']])) {
continue;
}
if ((int) $lesson->getStartTime()->format('N') !== $removedWeekday) {
continue;
}
if ($lesson->getStartTime()->format('H:i') !== $removedStartTime) {
continue;
}
$this->lessonDeletionService->delete($lesson, LessonDeletionService::REASON_PREFERENCE_TIME_REMOVED);
$this->entityManager->flush();
$guardian = $childPreference->getChild()->getGuardian();
if ($guardian) {
$this->guardianLogService->addGuardianActionLog(
LessonDeletionService::REASON_PREFERENCE_TIME_REMOVED,
$guardian,
$lesson,
'delete'
);
}
}
}
public function generateLessonsForChildPreference(ChildPreference $preference, $dateFrom = null, $doNotCreateList = null, $isPaid = false, $byPassStatusCheck = false, $byPassEarlyPaymentDateStart = false)
{
if ($dateFrom) {
$generateFrom = $dateFrom;
} else {
$generateFrom = $preference->getStartTime()->format('Y-m-d H:i');
}
// if($_SERVER['REMOTE_ADDR'] == '86.38.84.66')
// {
// dump('ok');
// die();
// }
$generateForMonth = new \DateTime($generateFrom);
$generateForMonth->modify("first day of {$generateForMonth->format('Y-M')}");
$dateMonthToGenerateFor = $generateForMonth->format('Y-m-d');
$generateTo = new \DateTime($dateMonthToGenerateFor);
$generateTo->modify("last day of {$generateTo->format('Y-M')}");
$generateTo->modify("+31 days");
$generateTo->setTime(23, 59);
$maxGenerateTo = new \DateTime();
$maxGenerateTo->modify("first day of {$maxGenerateTo->format('Y-M')}");
$maxGenerateTo->modify("+35 days");
$maxGenerateTo->setTime(23, 59);
$maxGenerateTo->modify("last day of {$maxGenerateTo->format('Y-M')}");
if ($generateTo > $maxGenerateTo) {
$generateTo = $maxGenerateTo;
}
$guardian = $preference->getChild()->getGuardian();
if($guardian->isFlagEarlyPayment() && !$byPassEarlyPaymentDateStart)
{
$paymentDay = $guardian->getEarlyPaymentDay();
$dateNow = new \DateTime();
$generateFromDate = new \DateTime($generateFrom);
if ($generateFromDate > $dateNow) {
// Future-dated preference start (delayed cutover): anchor on it, else $generateTo lands before $generateFrom and skips every lesson.
$dateNow = $generateFromDate;
}
$periodEndTime = new \DateTime("{$dateNow->format('Y-m-')}{$paymentDay}");
while ($dateNow->format('Y-m') == $periodEndTime->format('Y-m'))
{
$periodEndTime->modify('+7 days');
}
$periodEndTime->setDate($periodEndTime->format('Y'), $periodEndTime->format('m'), $paymentDay);
$generateTo = clone $periodEndTime;
}
// dump($generateTo);
// die();
$child = $preference->getChild();
// START CREATING INDIVIDUAL LESSONS
foreach ($child->getChildPreferences() as $childPreference) {
if($childPreference->getStatus() != ChildPreference::STATUS_ACCEPTED['value'] && !$byPassStatusCheck)
{
continue;
}
foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
$childPreference = $childPreferenceTime->getChildPreference();
if ($childPreference->getType() != Lesson::TYPE_INDIVIDUAL) {
continue;
}
if ($childPreference->getId() != $preference->getId()) {
continue;
}
$startTimePreference = $childPreferenceTime->getStartTime();
$endTimePreference = $childPreferenceTime->getEndTime();
$weekday = $this->getWeekdayEnglishFromNumber($childPreferenceTime->getWeekday());
for ($i = 0; $i <= 8; $i++) {
$startTime = new \DateTime($generateFrom);
$startTime->modify("first {$weekday} of {$startTime->format('Y-M')}");
$startTime->setTime((int)$startTimePreference->format('H'), (int)$startTimePreference->format('i'));
$startTime->modify("+{$i} weeks");
$endTime = new \DateTime($generateFrom);
$endTime->modify("first {$weekday} of {$endTime->format('Y-M')}");
$endTime->setTime((int)$endTimePreference->format('H'), (int)$endTimePreference->format('i'));
$endTime->modify("+{$i} weeks");
if ($generateTo <= $startTime) {
continue;
}
if ($startTime < new \DateTime($generateFrom)) {
continue;
}
if ($childPreference->getChild()->getLessonsEnd()) {
if ($startTime > $childPreference->getChild()->getLessonsEnd()) {
continue;
}
}
if ($childPreference->getStartTime() && $childPreference->getStartTime() > $startTime) {
continue;
}
if ($childPreference->getEndTime() && $childPreference->getEndTime() < $endTime) {
continue;
}
if (!$childPreference->getTeacher()) {
continue;
}
foreach ($child->getChildVacations() as $vacation) {
if ($vacation->isIsDeleted()) {
continue;
}
if ($vacation->getDateFrom() >= $startTime || $vacation->getDateTo() <= $startTime) {
continue;
}
$vacationDisciplineIds = $vacation->getDisciplineIds();
if ($vacationDisciplineIds === null || in_array($childPreference->getDiscipline()->getId(), $vacationDisciplineIds)) {
continue 2;
}
}
$skip = false;
if ($doNotCreateList) {
foreach ($doNotCreateList as $doNotCreateDate) {
if ($doNotCreateDate->format('Y-m-d H:i') == $startTime->format('Y-m-d H:i')) {
$skip = true;
}
}
}
if ($skip) {
continue;
}
$duration = date_diff($startTime, $endTime);
$duration = (int)$duration->i + (int)$duration->h * 60;
$lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
$lessons = $lessonsQuery
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $childPreference->getTeacher()->getId())
->andWhere('l.discipline = :discipline')
->setParameter('discipline', $childPreference->getDiscipline()->getId())
->andWhere(':child MEMBER OF l.children')
->setParameter('child', $childPreference->getChild()->getId())
->andWhere('l.startTime = :startTime OR l.originalStartTime = :startTime')
->setParameter('startTime', $startTime->format('Y-m-d H:i'))
->andWhere('l.endTime = :endTime OR l.originalEndTime = :endTime')
->setParameter('endTime', $endTime->format('Y-m-d H:i'))
->andWhere('l.type = :type')
->setParameter('type', $childPreference->getType())
->andWhere('l.duration = :duration')
->setParameter('duration', $duration)
->getQuery()
->getResult();
$guardian = $childPreference->getChild()->getGuardian();
//sita nutrinam nes: uzkeisdavo esamas pamokas i regular statusa su sumoketa suma, bet niekada neatminusuoja is balanso, bugas palikdavo pamokas apmoketas nepakeitus balanso
// dump($childPreference->getTeacher()->getStatus());
// dump(Teacher::STATUS_ACTIVE);
if (!$lessons && $childPreference->getTeacher()->getStatus() == Teacher::STATUS_ACTIVE) {
$lesson = (new Lesson())
->setType($childPreference->getType())
->setStatus(Lesson::STATUS_REGULAR['value'])
->setClass($childPreference->getChild()->getClass())
->setDiscipline($childPreference->getDiscipline())
->setTeacher($childPreference->getTeacher())
->setDuration($duration)
->setStartTime($startTime)
->setEndTime($endTime)
->setOriginalStartTime($startTime)
->setOriginalEndTime($endTime);
$lesson->addChild($childPreference->getChild());
if ($guardian->isFlagEarlyPayment()) {
$lesson->setPaid(0);
$lesson->setStatus(Lesson::STATUS_WAITING_PAYMENT['value']);
}
if ($this->teacherHolidayRepository->isTeacherOnHolidayAt($childPreference->getTeacher(), $startTime)) {
$lesson->setStatus(Lesson::STATUS_INFORMED_MISSED['value']);
}
$this->entityManager->persist($lesson);
$this->entityManager->flush();
}
}
}
}
}
public function restoreLessonsForChildPreference(ChildPreference $preference, $restoreDeletedList = null)
{
if (!$restoreDeletedList) {
return;
}
foreach ($restoreDeletedList as $restoreDeletedDate) {
$query = $this->lessonDeletedRepository->createQueryBuilder('l');
/** @var LessonDeleted $deletedLessonToRestore */
$deletedLessonToRestore = $query
->andWhere('l.discipline = :discipline')
->setParameter('discipline', $preference->getDiscipline()->getId())
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $preference->getTeacher()->getId())
->andWhere('l.startTime = :startTime')
->setParameter('startTime', $restoreDeletedDate)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
if (!$deletedLessonToRestore) {
return;
}
$startTime = $deletedLessonToRestore->getStartTime();
$endTime = $deletedLessonToRestore->getEndTime();
$duration = $deletedLessonToRestore->getDuration();
$lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
$lessons = $lessonsQuery
->andWhere('l.teacher = :teacher')
->setParameter('teacher', $preference->getTeacher()->getId())
->andWhere('l.discipline = :discipline')
->setParameter('discipline', $preference->getDiscipline()->getId())
->andWhere(':child MEMBER OF l.children')
->setParameter('child', $preference->getChild()->getId())
->andWhere('l.startTime = :startTime')
->setParameter('startTime', $startTime->format('Y-m-d H:i'))
->andWhere('l.endTime = :endTime')
->setParameter('endTime', $endTime->format('Y-m-d H:i'))
->andWhere('l.type = :type')
->setParameter('type', $preference->getType())
->andWhere('l.duration = :duration')
->setParameter('duration', $duration)
->getQuery()
->getResult();
if (!$lessons && $preference->getTeacher()->getStatus() == Teacher::STATUS_ACTIVE) {
$lesson = (new Lesson())
->setType($preference->getType())
->setStatus(Lesson::STATUS_REGULAR['value'])
->setClass($preference->getChild()->getClass())
->setDiscipline($preference->getDiscipline())
->setTeacher($preference->getTeacher())
->setDuration($duration)
->setStartTime($startTime)
->setEndTime($endTime);
$lesson->addChild($preference->getChild());
$this->entityManager->persist($lesson);
$this->entityManager->flush();
}
}
}
public function recalculatePricesForFurtherLessons(Guardian $guardian, \Datetime $dateFrom)
{
$lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
$lessons = $lessonsQuery
->andWhere(':children member of l.children')
->setParameter('children', $guardian->getChildren())
->andWhere('l.startTime > :startTime')
->setParameter('startTime', $dateFrom)
->getQuery()
->getResult();
foreach ($lessons as $lesson) {
$this->paymentService->editPayment($lesson);
}
}
public function getWeekdayFromNumber(int $day)
{
if ($day == 1) {
return 'Pirmadienis';
}
if ($day == 2) {
return 'Antradienis';
}
if ($day == 3) {
return 'Trečiadienis';
}
if ($day == 4) {
return 'Ketvirtadienis';
}
if ($day == 5) {
return 'Penktadienis';
}
if ($day == 6) {
return 'Šeštadienis';
}
if ($day == 7) {
return 'Sekmadienis';
} else {
return "";
}
}
public function getWeekdayEnglishFromNumber(int $day)
{
if ($day == 1) {
return 'monday';
}
if ($day == 2) {
return 'tuesday';
}
if ($day == 3) {
return 'wednesday';
}
if ($day == 4) {
return 'thursday';
}
if ($day == 5) {
return 'friday';
}
if ($day == 6) {
return 'saturday';
}
if ($day == 7) {
return 'sunday';
} else {
return "";
}
}
}