src/Service/ChildPreferenceService.php line 82

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\Child;
  4. use App\Entity\ChildPreference;
  5. use App\Entity\ChildPreferenceDeclineHistory;
  6. use App\Entity\ChildPreferenceTime;
  7. use App\Entity\Guardian;
  8. use App\Entity\GuardianRegister\GuardianRegisterChild;
  9. use App\Entity\Lesson;
  10. use App\Entity\LessonDeleted;
  11. use App\Entity\Teacher;
  12. use App\Entity\TeacherHoliday;
  13. use App\Entity\TeacherSickLeaves;
  14. use App\Entity\TeacherUnavailableRange;
  15. use App\Message\AssignChildPreferenceTeacherMessage;
  16. use App\Message\SendMailMessage;
  17. use App\Message\SendSMSMessage;
  18. use App\Repository\ChildPreferenceDeclineHistoryRepository;
  19. use App\Repository\ChildPreferenceHistoryRepository;
  20. use App\Repository\ChildPreferenceRepository;
  21. use App\Repository\ChildPreferenceTimeRepository;
  22. use App\Repository\LessonDeletedRepository;
  23. use App\Repository\LessonRepository;
  24. use App\Repository\NotificationRepository;
  25. use App\Repository\ReminderConfigurationRepository;
  26. use App\Repository\TeacherHolidayRepository;
  27. use App\Repository\TeacherRepository;
  28. use App\Repository\TeacherSickLeavesRepository;
  29. use App\Repository\TeacherUnavailableRangeRepository;
  30. use App\Repository\UserFireBaseTokenRepository;
  31. use Doctrine\ORM\EntityManagerInterface;
  32. use Psr\Container\ContainerInterface;
  33. use Symfony\Component\HttpFoundation\RequestStack;
  34. use Symfony\Component\Messenger\Envelope;
  35. use Symfony\Component\Messenger\MessageBusInterface;
  36. use Symfony\Component\Messenger\Stamp\DelayStamp;
  37. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  38. use Symfony\Component\Serializer\SerializerInterface;
  39. class ChildPreferenceService
  40. {
  41. public const NEW_CHILD_ASSIGNMENT_VACATION_BUFFER_DAYS = 14;
  42. private $testMode = false;
  43. private $testEmailTeacher = 'thelincius@gmail.com';
  44. // private $testPhoneTeacher = '37065520239';
  45. private $testPhoneTeacher = '37063794090';
  46. // private $testEmailGuardian = 'tomas970506@gmail.com';
  47. private $testEmailGuardian = 'apolskis.linas@gmail.com';
  48. // private $testPhoneGuardian = '37065520239';
  49. private $testPhoneGuardian = '37063794090';
  50. private ReminderConfigurationRepository $reminderConfigurationRepository;
  51. private UrlGeneratorInterface $urlGenerator;
  52. private SmsService $smsService;
  53. private EntityManagerInterface $entityManager;
  54. private ContainerInterface $container;
  55. private RequestStack $requestStack;
  56. private LessonRepository $lessonRepository;
  57. private MessageBusInterface $bus;
  58. private LessonDeletedRepository $lessonDeletedRepository;
  59. private PaymentService $paymentService;
  60. private MessageBusInterface $messageBus;
  61. private TeacherRepository $teacherRepository;
  62. private ChildPreferenceTimeRepository $childPreferenceTimeRepository;
  63. private ChildPreferenceRepository $childPreferenceRepository;
  64. private ChildPreferenceHistoryRepository $childPreferenceHistoryRepository;
  65. private SerializerInterface $serializer;
  66. private TeacherSickLeavesRepository $teacherSickLeavesRepository;
  67. private TeacherHolidayRepository $teacherHolidayRepository;
  68. private TeacherUnavailableRangeRepository $teacherUnavailableRangeRepository;
  69. private NotificationService $notificationService;
  70. private GetStreamService $getStreamService;
  71. private FcmService $fcmService;
  72. private UserFireBaseTokenRepository $userFireBaseTokenRepository;
  73. private LessonDeletionService $lessonDeletionService;
  74. private GuardianLogService $guardianLogService;
  75. public function __construct(
  76. SmsService $smsService,
  77. LessonRepository $lessonRepository,
  78. EntityManagerInterface $entityManager,
  79. ContainerInterface $container,
  80. RequestStack $requestStack,
  81. UrlGeneratorInterface $urlGenerator,
  82. ReminderConfigurationRepository $reminderConfigurationRepository,
  83. MessageBusInterface $bus,
  84. LessonDeletedRepository $lessonDeletedRepository,
  85. PaymentService $paymentService,
  86. MessageBusInterface $messageBus,
  87. TeacherRepository $teacherRepository,
  88. ChildPreferenceTimeRepository $childPreferenceTimeRepository,
  89. ChildPreferenceRepository $childPreferenceRepository,
  90. ChildPreferenceHistoryRepository $childPreferenceHistoryRepository,
  91. ChildPreferenceDeclineHistoryRepository $childPreferenceDeclineHistoryRepository,
  92. SerializerInterface $serializer,
  93. TeacherSickLeavesRepository $teacherSickLeavesRepository,
  94. TeacherHolidayRepository $teacherHolidayRepository,
  95. TeacherUnavailableRangeRepository $teacherUnavailableRangeRepository,
  96. NotificationService $notificationService,
  97. GetStreamService $getStreamService,
  98. FcmService $fcmService,
  99. UserFireBaseTokenRepository $userFireBaseTokenRepository,
  100. LessonDeletionService $lessonDeletionService,
  101. GuardianLogService $guardianLogService
  102. )
  103. {
  104. $this->entityManager = $entityManager;
  105. $this->container = $container;
  106. $this->requestStack = $requestStack;
  107. $this->reminderConfigurationRepository = $reminderConfigurationRepository;
  108. $this->urlGenerator = $urlGenerator;
  109. $this->smsService = $smsService;
  110. $this->lessonRepository = $lessonRepository;
  111. $this->bus = $bus;
  112. $this->lessonDeletedRepository = $lessonDeletedRepository;
  113. $this->paymentService = $paymentService;
  114. $this->messageBus = $messageBus;
  115. $this->teacherRepository = $teacherRepository;
  116. $this->childPreferenceTimeRepository = $childPreferenceTimeRepository;
  117. $this->childPreferenceRepository = $childPreferenceRepository;
  118. $this->childPreferenceHistoryRepository = $childPreferenceHistoryRepository;
  119. $this->childPreferenceDeclineHistoryRepository = $childPreferenceDeclineHistoryRepository;
  120. $this->serializer = $serializer;
  121. $this->teacherSickLeavesRepository = $teacherSickLeavesRepository;
  122. $this->teacherHolidayRepository = $teacherHolidayRepository;
  123. $this->teacherUnavailableRangeRepository = $teacherUnavailableRangeRepository;
  124. $this->notificationService = $notificationService;
  125. $this->getStreamService = $getStreamService;
  126. $this->fcmService = $fcmService;
  127. $this->userFireBaseTokenRepository = $userFireBaseTokenRepository;
  128. $this->lessonDeletionService = $lessonDeletionService;
  129. $this->guardianLogService = $guardianLogService;
  130. }
  131. public function assignTeacher(ChildPreference $childPreferenceObjectToAssign, ?Child $child = null, ?Teacher $teacherToForceAssign = null, $maxClass = null, $debug = false)
  132. {
  133. if(!$child)
  134. {
  135. $child = $childPreferenceObjectToAssign->getChild();
  136. }
  137. $this->entityManager->refresh($childPreferenceObjectToAssign);
  138. if($childPreferenceObjectToAssign->getStatus() == ChildPreference::STATUS_ASSIGNED['value'])
  139. {
  140. return;
  141. }
  142. // if(in_array($childPreferenceObjectToAssign->getStatus(), ['CANCELLED','NOT_FOUND']))
  143. // {
  144. if(!$debug) {
  145. foreach ($childPreferenceObjectToAssign->getChildPreferenceTimes() as $childPreferenceTime) {
  146. $childPreferenceObjectToAssign->removeChildPreferenceTime($childPreferenceTime);
  147. $this->entityManager->remove($childPreferenceTime);
  148. $this->entityManager->flush();
  149. }
  150. $childPreferenceObjectToAssign->setTeacher(null);
  151. $childPreferenceObjectToAssign->setStatus(ChildPreference::STATUS_TO_ASSIGN['value']);
  152. $this->entityManager->persist($childPreferenceObjectToAssign);
  153. $this->entityManager->flush();
  154. }
  155. // }
  156. //First filter teachers by status, discipline, class, available
  157. $discipline = $childPreferenceObjectToAssign->getDiscipline();
  158. $class = $child->getClass();
  159. $minClass = $child->getClass();
  160. if(!$maxClass) {
  161. $maxClass = $child->getClass();
  162. }
  163. $amount = $childPreferenceObjectToAssign->getEmailDuration() / $childPreferenceObjectToAssign->getSingleEmailDuration();
  164. $duration = $childPreferenceObjectToAssign->getEmailDuration();
  165. $school = $child->getSchool();
  166. $ielts = $child->isFlagIelts();
  167. $flagRU = $child->getFlagRU();
  168. $flagPL = $child->getFlagPL();
  169. $flagENG = $child->getFlagENG();
  170. $flagIB = $child->getFlagIB();
  171. $flagDyslexia = $child->getFlagDyslexia();
  172. $flagVbeOver90 = $child->isVbeOver90();
  173. $flagExperienceOver12Month = $child->isExperienceOver12Month();
  174. $flagExperienceAtSchool = $child->isFlagExperienceAtSchool();
  175. //Optional
  176. $flagSensitive = $child->getFlagSensitive();
  177. $gender = $child->getGender();
  178. $flagStrict = $child->isFlagStrict();
  179. //dump($class);
  180. //die();
  181. // $condition = "dc.maxClass {$classSearchType} :class AND dc.discipline = :discipline";
  182. // $condition = '';
  183. // foreach ($class as $selectedClass)
  184. // {
  185. // if($condition)
  186. // {
  187. // $condition .= ' OR ';
  188. // }
  189. // $selectedClass = str_replace('–', '%', $selectedClass);
  190. // $selectedClass = str_replace('š', '%', $selectedClass);
  191. // $condition = "dc.classes like '%{$selectedClass}%' AND dc.discipline = :discipline";
  192. // }
  193. // $classSearchType = $form->get('classSearchType')->getData() ? '=' : '>=';
  194. $busyTeacherIds = [];
  195. $busyTeachers = $this->childPreferenceRepository
  196. ->createQueryBuilder('c')
  197. ->select('teacher.id')
  198. ->leftJoin('c.teacher', 'teacher')
  199. ->where('c.status = :status')
  200. ->setParameter('status', ChildPreference::STATUS_ASSIGNED['value'])
  201. ->getQuery()
  202. ->getArrayResult();
  203. foreach ($busyTeachers as $busyTeacherId)
  204. {
  205. $busyTeacherIds[] = $busyTeacherId['id'];
  206. }
  207. $declinedAt = new \DateTime();
  208. $declinedAt->modify('-3 hours');
  209. $query = $this->childPreferenceDeclineHistoryRepository->createQueryBuilder('a');
  210. $query
  211. ->andWhere('a.declinedAt > :declined_at')
  212. ->setParameter('declined_at', $declinedAt);
  213. $histories = $query->getQuery()->getResult();
  214. /** @var ChildPreferenceDeclineHistory $history */
  215. foreach ($histories as $history)
  216. {
  217. if($history && $history->getTeacher()) {
  218. $busyTeacherIds[] = $history->getTeacher()->getId();
  219. }
  220. }
  221. $sickLeaves = $this
  222. ->teacherSickLeavesRepository
  223. ->createQueryBuilder('t')
  224. ->andWhere('t.dateStart <= :currentTime')
  225. ->andWhere('t.dateEnd >= :currentTime')
  226. ->setParameter('currentTime', new \DateTime())
  227. ->getQuery()
  228. ->getResult();
  229. /** @var TeacherSickLeaves $sickLeave */
  230. foreach ($sickLeaves as $sickLeave)
  231. {
  232. $busyTeacherIds[] = $sickLeave->getTeacher()->getId();
  233. }
  234. // Also excludes a holiday that hasn't started yet but starts soon: a
  235. // teacher whose vacation begins within NEW_CHILD_ASSIGNMENT_VACATION_BUFFER_DAYS
  236. // must not be handed new children whose first lessons would land right
  237. // before/inside it (see [issue: teacher 2197 vacation]). A vacation
  238. // further out than that is not excluded here — it's still safe, since
  239. // generateLessonsForChildPreference() marks any occurrence landing
  240. // inside it as INFORMED_MISSED regardless of how far away it is.
  241. $vacationSoonThreshold = (new \DateTime())->modify(
  242. '+' . self::NEW_CHILD_ASSIGNMENT_VACATION_BUFFER_DAYS . ' days'
  243. );
  244. $teacherHolidays = $this
  245. ->teacherHolidayRepository
  246. ->createQueryBuilder('t')
  247. ->andWhere('t.dateStart <= :vacationSoonThreshold')
  248. ->andWhere('t.dateEnd >= :currentTime')
  249. ->setParameter('vacationSoonThreshold', $vacationSoonThreshold)
  250. ->setParameter('currentTime', new \DateTime())
  251. ->getQuery()
  252. ->getResult();
  253. /** @var TeacherHoliday $teacherHoliday */
  254. foreach ($teacherHolidays as $teacherHoliday)
  255. {
  256. $busyTeacherIds[] = $teacherHoliday->getTeacher()->getId();
  257. }
  258. $teacherUnavailableRanges = $this
  259. ->teacherUnavailableRangeRepository
  260. ->createQueryBuilder('t')
  261. ->andWhere('t.startTime <= :currentTime')
  262. ->andWhere('t.endTime >= :currentTime')
  263. ->setParameter('currentTime', new \DateTime())
  264. ->getQuery()
  265. ->getResult();
  266. /** @var TeacherUnavailableRange $teacherUnavailableRange */
  267. foreach ($teacherUnavailableRanges as $teacherUnavailableRange)
  268. {
  269. $busyTeacherIds[] = $teacherUnavailableRange->getTeacher()->getId();
  270. }
  271. // dump($busyTeacherIds);
  272. // die();
  273. $query = $this->teacherRepository->createQueryBuilder('t');
  274. $query
  275. ->andWhere('t.roles LIKE :roles')
  276. ->setParameter('roles', '%"ROLE_TEACHER"%');
  277. if($debug)
  278. {
  279. dump('busy teachers:');
  280. dump($busyTeacherIds);
  281. }
  282. $declinedAt = new \DateTime();
  283. $declinedAt->modify('-72 hours');
  284. $histories = $this->childPreferenceDeclineHistoryRepository->createQueryBuilder('a')
  285. ->andWhere('a.declinedAt > :declined_at')
  286. ->setParameter('declined_at', $declinedAt)
  287. ->andWhere('a.discipline = :discipline')
  288. ->setParameter('discipline', $discipline)
  289. ->andWhere('a.child = :child')
  290. ->setParameter('child', $child)
  291. ->getQuery()
  292. ->getResult();
  293. if(count($histories) >= 2) {
  294. $query->andWhere('t.flagAutoAcceptAssignment = 1');
  295. }
  296. $busyTeacherIds = array_filter($busyTeacherIds);
  297. if($busyTeacherIds && !$teacherToForceAssign) {
  298. $query
  299. ->andWhere('t.id NOT IN (:busyTeacherIds)')
  300. ->setParameter('busyTeacherIds', $busyTeacherIds);
  301. }
  302. if($teacherToForceAssign)
  303. {
  304. $query
  305. ->andWhere('t.id = :teacherToForceAssign')
  306. ->setParameter('teacherToForceAssign', $teacherToForceAssign->getId());
  307. }
  308. $available = $duration / 60;
  309. if($minClass == 0){
  310. $minClass = 'Priešmokyklinukai';
  311. }
  312. if($maxClass == 0){
  313. $maxClass = 'Priešmokyklinukai';
  314. }
  315. if($minClass == 13){
  316. $minClass = 'Suaugę';
  317. }
  318. if($maxClass == 13){
  319. $maxClass = 'Suaugę';
  320. }
  321. $availableClasses = [
  322. 'Priešmokyklinukai' => 'Priešmokyklinukai',
  323. 1 => 1,
  324. 2 => 2,
  325. 3 => 3,
  326. 4 => 4,
  327. 5 => 5,
  328. 6 => 6,
  329. 7 => 7,
  330. 8 => 8,
  331. 9 => 9,
  332. 10 => 10,
  333. 11 => 11,
  334. 12 => 12,
  335. 'Suaugę' => 'Suaugę',
  336. ];
  337. $selectedClassesRange = [];
  338. $doNotIncludeClassesRange = [];
  339. if(!$maxClass && !$minClass){
  340. return new JsonResponse([
  341. "data" => [],
  342. 'timeSlots' => [],
  343. ]);
  344. }
  345. elseif($maxClass && !$minClass) {
  346. foreach ($availableClasses as $class) {
  347. if($class != $maxClass) {
  348. continue;
  349. }
  350. $selectedClassesRange[] = $class;
  351. if($class == $maxClass) {
  352. break;
  353. }
  354. }
  355. $reached = false;
  356. foreach ($availableClasses as $class) {
  357. if($class != $maxClass && !$reached) {
  358. continue;
  359. }
  360. if($reached) {
  361. $doNotIncludeClassesRange[] = $class;
  362. }
  363. $reached = true;
  364. }
  365. }
  366. elseif(!$maxClass && $minClass)
  367. {
  368. foreach ($availableClasses as $class) {
  369. if($class != $minClass && !$selectedClassesRange) {
  370. continue;
  371. }
  372. $selectedClassesRange[] = $class;
  373. }
  374. }
  375. elseif($maxClass && $minClass)
  376. {
  377. foreach ($availableClasses as $class) {
  378. if($class != $minClass && !$selectedClassesRange) {
  379. continue;
  380. }
  381. $selectedClassesRange[] = $class;
  382. if($class == $maxClass) {
  383. break;
  384. }
  385. }
  386. $reached = false;
  387. foreach ($availableClasses as $class) {
  388. if($class != $maxClass && !$reached) {
  389. continue;
  390. }
  391. if($reached) {
  392. $doNotIncludeClassesRange[] = $class;
  393. }
  394. $reached = true;
  395. }
  396. }
  397. $condition = '';
  398. if($debug)
  399. {
  400. dump('selectedClassesRange:');
  401. dump($selectedClassesRange);
  402. dump('doNotIncludeClassesRange:');
  403. dump($doNotIncludeClassesRange);
  404. }
  405. $hiddenCases = "";
  406. // dump($selectedClassesRange);
  407. // die();
  408. if($selectedClassesRange) {
  409. foreach ($selectedClassesRange as $class) {
  410. if(!$condition)
  411. {
  412. $condition .= '( ';
  413. }
  414. if(substr($condition, -2, 2) == '1 ' || substr($condition, -3, 3) == "%' ")
  415. {
  416. $condition .= 'OR ';
  417. }
  418. if(is_int($class)) {
  419. $condition .= "JSON_CONTAINS(dc.classYears, '{$class}') = 1 ";
  420. }
  421. else
  422. {
  423. if($class == 'Suaugę')
  424. {
  425. $condition .= "dc.classes like '%Suaug%' ";
  426. }
  427. if($class == 'Priešmokyklinukai')
  428. {
  429. $condition .= "dc.classes like '%mokyklinukai%' ";
  430. }
  431. }
  432. }
  433. $condition .= ") AND dc.discipline = :discipline";
  434. if($flagVbeOver90){
  435. $condition .= " AND dc.vbe >= 90 ";
  436. }
  437. }
  438. if($doNotIncludeClassesRange)
  439. {
  440. // $condition .= " AND ( ";
  441. foreach ($doNotIncludeClassesRange as $class) {
  442. // if(substr($condition, -2, 2) == '0 ' || substr($condition, -3, 3) == "%' ")
  443. // {
  444. // $condition .= ' AND ';
  445. // }
  446. if(is_int($class)) {
  447. // $condition .= " JSON_CONTAINS(dc.classYears, '{$class}') = 0 ";
  448. //
  449. //
  450. if($hiddenCases)
  451. {
  452. $hiddenCases.= ' + ';
  453. }
  454. $hiddenCases .= "(CASE WHEN JSON_CONTAINS(dc.classYears, '{$class}') = 0 THEN -1 ELSE 0 END)";
  455. }
  456. else
  457. {
  458. if($class == 'Suaugę')
  459. {
  460. // $condition .= " dc.classes not like '%Suaug%' ";
  461. if($hiddenCases)
  462. {
  463. $hiddenCases.= ' + ';
  464. }
  465. $hiddenCases .= "(CASE WHEN dc.classes not like '%Suaug%' THEN -1 ELSE 0 END)";
  466. }
  467. if($class == 'Priešmokyklinukai')
  468. {
  469. // $condition .= " dc.classes not like '%mokyklinukai%' ";
  470. if($hiddenCases)
  471. {
  472. $hiddenCases.= ' + ';
  473. }
  474. $hiddenCases .= "(CASE WHEN dc.classes not like '%mokyklinukai%' THEN -1 ELSE 0 END)";
  475. }
  476. }
  477. }
  478. // $condition .= " ) ";
  479. }
  480. // dump($condition);
  481. // die();
  482. $query
  483. ->andWhere('t.status = :status')
  484. ->setParameter('status', Teacher::STATUS_ACTIVE)
  485. ->andWhere('t.workedHours <= :workedHours')
  486. ->setParameter('workedHours', 1424)
  487. ->andWhere('t.available >= :available')
  488. ->setParameter('available', $available)
  489. ->innerJoin('t.teacherDisciplineClasses', 'dc', 'WITH', $condition)
  490. ->setParameter('discipline', $discipline);
  491. if($debug)
  492. {
  493. dump($condition);
  494. }
  495. if ($ielts) { $query->andWhere('t.ielts > 0'); }
  496. if ($flagRU) { $query->andWhere('t.flagRU = :flagRU')->setParameter('flagRU', $flagRU); }
  497. if ($flagPL) { $query->andWhere('t.flagPL = :flagPL')->setParameter('flagPL', $flagPL); }
  498. if ($flagENG) { $query->andWhere('t.flagENG = :flagENG')->setParameter('flagENG', $flagENG); }
  499. if ($flagIB) {
  500. $query->andWhere('t.flagIB = :flagIB')->setParameter('flagIB', $flagIB);
  501. }
  502. else
  503. {
  504. $query->andWhere('t.flagOnlyIB IS NULL OR t.flagOnlyIB = :flagOnlyIB')->setParameter('flagOnlyIB', 0);
  505. }
  506. if ($flagDyslexia) { $query->andWhere('t.flagDyslexia = :flagDyslexia')->setParameter('flagDyslexia', $flagDyslexia); }
  507. if ($flagSensitive) { $query->andWhere('t.flagSensitive = :flagSensitive')->setParameter('flagSensitive', $flagSensitive); }
  508. if ($flagStrict) { $query->andWhere('t.flagStrict = :flagStrict')->setParameter('flagStrict', $flagStrict); }
  509. if ($flagExperienceAtSchool) { $query->andWhere('t.flagExperienceAtSchool = :flagExperienceAtSchool')->setParameter('flagExperienceAtSchool', $flagExperienceAtSchool); }
  510. $dateNow = new \DateTime();
  511. $dateNow->modify('-1 year');
  512. if ($flagExperienceOver12Month) { $query->andWhere('t.workStart <= :workStart')->setParameter('workStart', $dateNow); }
  513. if ($school) { $query->andWhere('t.school = :school')->setParameter('school', $school); }
  514. if ($gender && $gender != 'Nesvarbu')
  515. {
  516. $query->andWhere('t.gender = :gender')->setParameter('gender', $gender);
  517. }
  518. // $query->addSelect("0 AS HIDDEN ORD ");
  519. //optional
  520. // $dateNow = new \DateTime();
  521. // $dateNow->modify('-1 year');
  522. // if ($flagExperienceOver12Month)
  523. // {
  524. // if($hiddenCases)
  525. // {
  526. // $hiddenCases.= ' + ';
  527. // }
  528. // $hiddenCases .= "(CASE WHEN t.workStart <= :workStart THEN 1 ELSE 0 END)";
  529. // $query->setParameter('workStart', $dateNow);
  530. //
  531. // $query
  532. // ->andWhere('t.workedHours >= :workedHours2')
  533. // ->setParameter('workedHours2', 840);
  534. // }
  535. // if ($gender && $gender != 'Nesvarbu')
  536. // {
  537. // if($hiddenCases)
  538. // {
  539. // $hiddenCases.= ' + ';
  540. // }
  541. // $hiddenCases .= "(CASE WHEN t.gender = :gender THEN 1 ELSE 0 END)";
  542. // $query->setParameter('gender', $gender);
  543. // }
  544. // if ($flagExperienceAtSchool)
  545. // {
  546. // if($hiddenCases)
  547. // {
  548. // $hiddenCases.= ' + ';
  549. // }
  550. // $hiddenCases .= "(CASE WHEN t.flagExperienceAtSchool = :flagExperienceAtSchool THEN 1 ELSE 0 END)";
  551. // $query->setParameter('flagExperienceAtSchool', $flagExperienceAtSchool);
  552. // }
  553. if($hiddenCases)
  554. {
  555. $hiddenCases.= ' + ';
  556. }
  557. $hiddenCases .= "(CASE WHEN t.flagPriorityAssignment = :flagPriorityAssignment THEN 1 ELSE 0 END)";
  558. $query->setParameter('flagPriorityAssignment', 1);
  559. $workStart30d = new \DateTime();
  560. $workStart30d->modify('-30 days');
  561. if($hiddenCases)
  562. {
  563. $hiddenCases.= ' + ';
  564. }
  565. $hiddenCases .= "(CASE WHEN t.workStart >= :workStart30d THEN 2 ELSE 0 END)";
  566. $query->setParameter('workStart30d', $workStart30d);
  567. $workStart60d = new \DateTime();
  568. $workStart60d->modify('-60 days');
  569. if($hiddenCases)
  570. {
  571. $hiddenCases.= ' + ';
  572. }
  573. $hiddenCases .= "(CASE WHEN t.workStart >= :workStart60d AND t.workStart <= :workStart30d THEN 1 ELSE 0 END)";
  574. $query->setParameter('workStart60d', $workStart60d);
  575. if($hiddenCases)
  576. {
  577. $hiddenCases.= ' + ';
  578. }
  579. $hiddenCases .= "(CASE WHEN t.workStart >= :workStart60d AND t.workStart <= :workStart30d THEN 1 ELSE 0 END)";
  580. if ($hiddenCases)
  581. {
  582. $hiddenCases .= ' + ';
  583. }
  584. $hiddenCases .= "(CASE
  585. WHEN SIZE(t.childPreferences) = 0 THEN 3
  586. WHEN SIZE(t.childPreferences) = 1 THEN 2
  587. WHEN SIZE(t.childPreferences) = 2 THEN 1
  588. ELSE 0
  589. END)";
  590. $twoWeeksAgo = new \DateTime();
  591. $twoWeeksAgo->modify('-14 days');
  592. if ($hiddenCases)
  593. {
  594. $hiddenCases .= ' + ';
  595. }
  596. $hiddenCases .= "(CASE
  597. WHEN (
  598. (SELECT COUNT(cp2.id) FROM App\\Entity\\ChildPreference cp2 WHERE cp2.teacher = t AND cp2.assignedAt >= :twoWeeksAgo) = 0
  599. AND (t.available < (0.5 * t.maxLoad))
  600. ) THEN 3
  601. ELSE 0
  602. END)";
  603. $query->setParameter('twoWeeksAgo', $twoWeeksAgo);
  604. // if ($hiddenCases)
  605. // {
  606. // $hiddenCases .= ' + ';
  607. // }
  608. // $hiddenCases .= "(CASE WHEN t.maxLoad - t.available >= 4 THEN -10 ELSE 0 END)";
  609. if($hiddenCases)
  610. {
  611. $hiddenCases.= ' + ';
  612. }
  613. $hiddenCases .= "(CASE WHEN t.flagAutoAcceptAssignment = :flagAutoAcceptAssignment THEN 2 ELSE 0 END)";
  614. $query->setParameter('flagAutoAcceptAssignment', 1);
  615. if($hiddenCases)
  616. {
  617. $hiddenCases.= ' + ';
  618. }
  619. $hiddenCases .= "(CASE WHEN t.levelName = :level1 THEN 3 ELSE 0 END)";
  620. $query->setParameter('level1', 'Senior Tutor');
  621. if($hiddenCases)
  622. {
  623. $hiddenCases.= ' + ';
  624. }
  625. $hiddenCases .= "(CASE WHEN t.levelName = :level2 THEN 2 ELSE 0 END)";
  626. $query->setParameter('level2', 'Pro Tutor');
  627. if($hiddenCases)
  628. {
  629. $hiddenCases.= ' + ';
  630. }
  631. $hiddenCases .= "(CASE WHEN t.levelName = :level3 THEN 1 ELSE 0 END)";
  632. $query->setParameter('level3', 'Expert Tutor');
  633. if($hiddenCases) {
  634. $hiddenSql = "({$hiddenCases}) AS HIDDEN ORD";
  635. $query->addSelect($hiddenSql);
  636. $query->addOrderBy('ORD', 'DESC');
  637. }
  638. //dump($hiddenSql);
  639. $query->addOrderBy('t.available', 'DESC');
  640. // dump($query->getQuery()->getSQL());
  641. // die();
  642. $teachers = $query
  643. ->getQuery()
  644. ->getResult();
  645. // if($_SERVER['REMOTE_ADDR'] == '86.38.84.66' && $maxClass == 4) {
  646. // dump($teachers);
  647. // die();
  648. // }
  649. //Filter by times
  650. $startTime1Priority = false;
  651. $startTime2Priority = false;
  652. $startTime3Priority = false;
  653. $startTime4Priority = false;
  654. $startTime5Priority = false;
  655. $startTime6Priority = false;
  656. $startTime7Priority = false;
  657. $startTime1 = false;
  658. $startTime2 = false;
  659. $startTime3 = false;
  660. $startTime4 = false;
  661. $startTime5 = false;
  662. $startTime6 = false;
  663. $startTime7 = false;
  664. $endTime1 = false;
  665. $endTime2 = false;
  666. $endTime3 = false;
  667. $endTime4 = false;
  668. $endTime5 = false;
  669. $endTime6 = false;
  670. $endTime7 = false;
  671. $fittingTimes = $childPreferenceObjectToAssign->getChild()->getFittingTimes();
  672. if($childPreferenceObjectToAssign->getFittingTimes())
  673. {
  674. $fittingTimes = $childPreferenceObjectToAssign->getFittingTimes();
  675. }
  676. $fittingTimes = str_replace(PHP_EOL, '', $fittingTimes);
  677. $fittingTimes = str_replace("\r", '', $fittingTimes);
  678. $fittingTimes = str_replace(" ", '', $fittingTimes);
  679. $fittingTimes = explode(';', $fittingTimes);
  680. $fittingTimes = array_filter($fittingTimes);
  681. foreach ($fittingTimes as $fittingTime) {
  682. $fittingDates = explode(',', $fittingTime);
  683. if(!isset($fittingDates[1]))
  684. {
  685. continue;
  686. }
  687. $fittingHours = explode('-', $fittingDates[1]);
  688. $fittingHours[0] = new \Datetime("1970-01-01 ".$fittingHours[0]);
  689. $fittingHours[1] = new \Datetime("1970-01-01 ".$fittingHours[1]);
  690. if ($fittingDates[0] == 'Pirmadienis') {
  691. $startTime1 = $fittingHours[0];
  692. $endTime1 = $fittingHours[1];
  693. }
  694. if ($fittingDates[0] == 'Antradienis') {
  695. $startTime2 = $fittingHours[0];
  696. $endTime2 = $fittingHours[1];
  697. }
  698. if ($fittingDates[0] == 'Trečiadienis') {
  699. $startTime3 = $fittingHours[0];
  700. $endTime3 = $fittingHours[1];
  701. }
  702. if ($fittingDates[0] == 'Ketvirtadienis') {
  703. $startTime4 = $fittingHours[0];
  704. $endTime4 = $fittingHours[1];
  705. }
  706. if ($fittingDates[0] == 'Penktadienis') {
  707. $startTime5 = $fittingHours[0];
  708. $endTime5 = $fittingHours[1];
  709. }
  710. if ($fittingDates[0] == 'Šeštadienis') {
  711. $startTime6 = $fittingHours[0];
  712. $endTime6 = $fittingHours[1];
  713. }
  714. if ($fittingDates[0] == 'Sekmadienis') {
  715. $startTime7 = $fittingHours[0];
  716. $endTime7 = $fittingHours[1];
  717. }
  718. }
  719. $fittingTimes = $childPreferenceObjectToAssign->getChild()->getFittingTimesPriority();
  720. if($childPreferenceObjectToAssign->getFittingTimesPriority())
  721. {
  722. $fittingTimes = $childPreferenceObjectToAssign->getFittingTimesPriority();
  723. }
  724. if($fittingTimes == null)
  725. {
  726. $fittingTimes = '';
  727. }
  728. $fittingTimes = str_replace(PHP_EOL, '', $fittingTimes);
  729. $fittingTimes = str_replace("\r", '', $fittingTimes);
  730. $fittingTimes = str_replace(" ", '', $fittingTimes);
  731. $fittingTimes = explode(';', $fittingTimes);
  732. $fittingTimes = array_filter($fittingTimes);
  733. foreach ($fittingTimes as $fittingTime) {
  734. $fittingDates = explode(',', $fittingTime);
  735. $fittingHours = explode('-', $fittingDates[1]);
  736. $fittingHours[0] = new \Datetime("1970-01-01 ".$fittingHours[0]);
  737. $fittingHours[1] = new \Datetime("1970-01-01 ".$fittingHours[1]);
  738. if ($fittingDates[0] == 'Pirmadienis') {
  739. $startTime1 = $fittingHours[0];
  740. $endTime1 = $fittingHours[1];
  741. $startTime1Priority = true;
  742. }
  743. if ($fittingDates[0] == 'Antradienis') {
  744. $startTime2 = $fittingHours[0];
  745. $endTime2 = $fittingHours[1];
  746. $startTime2Priority = true;
  747. }
  748. if ($fittingDates[0] == 'Trečiadienis') {
  749. $startTime3 = $fittingHours[0];
  750. $endTime3 = $fittingHours[1];
  751. $startTime3Priority = true;
  752. }
  753. if ($fittingDates[0] == 'Ketvirtadienis') {
  754. $startTime4 = $fittingHours[0];
  755. $endTime4 = $fittingHours[1];
  756. $startTime4Priority = true;
  757. }
  758. if ($fittingDates[0] == 'Penktadienis') {
  759. $startTime5 = $fittingHours[0];
  760. $endTime5 = $fittingHours[1];
  761. $startTime5Priority = true;
  762. }
  763. if ($fittingDates[0] == 'Šeštadienis') {
  764. $startTime6 = $fittingHours[0];
  765. $endTime6 = $fittingHours[1];
  766. $startTime6Priority = true;
  767. }
  768. if ($fittingDates[0] == 'Sekmadienis') {
  769. $startTime7 = $fittingHours[0];
  770. $endTime7 = $fittingHours[1];
  771. $startTime7Priority = true;
  772. }
  773. }
  774. $timesOriginal = [
  775. 1 => ['start' => $startTime1, 'end' => $endTime1, 'priority' => $startTime1Priority, 'weekday' => 1],
  776. 2 => ['start' => $startTime2, 'end' => $endTime2, 'priority' => $startTime2Priority, 'weekday' => 2],
  777. 3 => ['start' => $startTime3, 'end' => $endTime3, 'priority' => $startTime3Priority, 'weekday' => 3],
  778. 4 => ['start' => $startTime4, 'end' => $endTime4, 'priority' => $startTime4Priority, 'weekday' => 4],
  779. 5 => ['start' => $startTime5, 'end' => $endTime5, 'priority' => $startTime5Priority, 'weekday' => 5],
  780. 6 => ['start' => $startTime6, 'end' => $endTime6, 'priority' => $startTime6Priority, 'weekday' => 6],
  781. 7 => ['start' => $startTime7, 'end' => $endTime7, 'priority' => $startTime7Priority, 'weekday' => 7],
  782. ];
  783. $availableTeachers = [];
  784. $availableTimeSlots = [];
  785. // dump($teachers);
  786. // die();
  787. //dump($timesOriginal);
  788. //die();
  789. if($debug)
  790. {
  791. dump('Teachers:');
  792. foreach ($teachers as $teacher) {
  793. dump($teacher->getId().' '.$teacher->getFullName().' '.$teacher->getAvailable());
  794. }
  795. dump('Times:');
  796. dump($timesOriginal);
  797. }
  798. $workEndCheck = new \DateTime();
  799. /**
  800. * @var Teacher $teacher
  801. */
  802. foreach ($teachers as $teacherKey => $teacher) {
  803. // if($teacher->getId() != 1){
  804. // continue;
  805. // }
  806. if ($teacher->getAvailable() < $available || $teacher->getAvailable() < 1) {
  807. unset($teachers[$teacherKey]);
  808. continue;
  809. }
  810. $teacherWorkEnd = null;
  811. if($teacher->getWorkEnd())
  812. {
  813. $teacherWorkEnd = clone $teacher->getWorkEnd();
  814. $teacherWorkEnd->modify('-60 days');
  815. }
  816. // 2025-10-25 2025-12-08
  817. if ($teacherWorkEnd && $teacherWorkEnd < $workEndCheck) {
  818. unset($teachers[$teacherKey]);
  819. continue;
  820. }
  821. $foundAvailableTimeSlots = 0;
  822. $availableTimeSlotsTeacher = [];
  823. $addedWeekdays = [];
  824. foreach ($teacher->getTeacherAvailabilityTimes() as $teacherAvailabilityTime) {
  825. $times = $timesOriginal;
  826. if($teacherAvailabilityTime->getStartTime() >= $teacherAvailabilityTime->getEndTime()) {
  827. continue;
  828. }
  829. //dump($times);
  830. //die();
  831. $weekday = $teacherAvailabilityTime->getWeekday();
  832. if ($times[$weekday]['start'] && $times[$weekday]['end']) {
  833. // $debug = [
  834. // "searchStart"=>$times[$weekday]['start'],
  835. // "searchEnd"=>$times[$weekday]['end'],
  836. // "teacherFoundStart"=>$teacherAvailabilityTime->getStartTime(),
  837. // "teacherFoundEnd"=>$teacherAvailabilityTime->getEndTime(),
  838. // "ifState1"=>($teacherAvailabilityTime->getEndTime() < $times[$weekday]['end'] && $teacherAvailabilityTime->getStartTime() > $times[$weekday]['start']),
  839. // "ifState2"=>( $times[$weekday]['start'] < $teacherAvailabilityTime->getStartTime() && $times[$weekday]['end'] < $teacherAvailabilityTime->getEndTime() && $teacherAvailabilityTime->getStartTime() < $times[$weekday]['end']),
  840. // "ifState3"=>($times[$weekday]['end'] > $teacherAvailabilityTime->getEndTime() && $times[$weekday]['start'] > $teacherAvailabilityTime->getStartTime() && $times[$weekday]['start'] < $teacherAvailabilityTime->getEndTime() )
  841. // ];
  842. // dump($debug);
  843. // die();
  844. //20:00 < 19:01 and 17:00 > 16:00
  845. // dump($teacherAvailabilityTime->getEndTime());
  846. // dump($times[$weekday]['end']);
  847. // die();
  848. if ($teacherAvailabilityTime->getEndTime() <= $times[$weekday]['end'] && $teacherAvailabilityTime->getStartTime() >= $times[$weekday]['start']) {
  849. $times[$weekday]['end'] = $teacherAvailabilityTime->getEndTime();
  850. $times[$weekday]['start'] = $teacherAvailabilityTime->getStartTime();
  851. } // 16:00 < 17:00 ir 20:00 < 20:00
  852. else if ($times[$weekday]['start'] < $teacherAvailabilityTime->getStartTime() && $times[$weekday]['end'] < $teacherAvailabilityTime->getEndTime() && $teacherAvailabilityTime->getStartTime() < $times[$weekday]['end']) {
  853. $times[$weekday]['start'] = $teacherAvailabilityTime->getStartTime();
  854. } else if ($times[$weekday]['end'] > $teacherAvailabilityTime->getEndTime() && $times[$weekday]['start'] > $teacherAvailabilityTime->getStartTime() && $times[$weekday]['start'] < $teacherAvailabilityTime->getEndTime()) {
  855. $times[$weekday]['end'] = $teacherAvailabilityTime->getEndTime();
  856. }
  857. $afterIfs = [
  858. 'afterStart' => $times[$weekday]['start'],
  859. 'afterEnd' => $times[$weekday]['end']
  860. ];
  861. if ($teacherAvailabilityTime->getStartTime() <= $times[$weekday]['start'] && $teacherAvailabilityTime->getEndTime() >= $times[$weekday]['end']) {
  862. // dump('x');
  863. // die();
  864. $childPreferenceTimes = [];
  865. $start = clone $teacherAvailabilityTime->getStartTime();
  866. $end = clone $teacherAvailabilityTime->getEndTime();
  867. $childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
  868. $childPreferenceTimesSide = $childPreferenceTimesQuery
  869. ->leftJoin('cpt.childPreference', 'cp')
  870. ->andWhere('cp.teacher = :teacher')
  871. ->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPendTime')
  872. ->andWhere('cpt.startTime >= :startTime')
  873. ->andWhere('cpt.endTime <= :endTime')
  874. ->andWhere('cpt.weekday = :weekday')
  875. ->setParameter('teacher', $teacher)
  876. ->setParameter('startTime', $start)
  877. ->setParameter('endTime', $end)
  878. ->setParameter('weekday', $weekday)
  879. ->setParameter('CPendTime', $childPreferenceObjectToAssign->getStartTime())
  880. ->orderBy('cpt.startTime', 'ASC')
  881. ->getQuery()
  882. ->getResult();
  883. foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
  884. if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
  885. $childPreferenceTimes[] = $childPreferenceTimesSideElement;
  886. }
  887. }
  888. $start = clone $teacherAvailabilityTime->getStartTime();
  889. $end = clone $teacherAvailabilityTime->getEndTime();
  890. $childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
  891. $childPreferenceTimesSide = $childPreferenceTimesQuery
  892. ->leftJoin('cpt.childPreference', 'cp')
  893. ->andWhere('cp.teacher = :teacher')
  894. ->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPendTime')
  895. ->andWhere('cpt.startTime <= :startTime')
  896. ->andWhere('cpt.endTime >= :startTime')
  897. ->andWhere('cpt.weekday = :weekday')
  898. ->setParameter('teacher', $teacher)
  899. ->setParameter('startTime', $start)
  900. ->setParameter('weekday', $weekday)
  901. ->setParameter('CPendTime', $childPreferenceObjectToAssign->getStartTime())
  902. ->orderBy('cpt.startTime', 'ASC')
  903. ->getQuery()
  904. ->getResult();
  905. foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
  906. if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
  907. $childPreferenceTimes[] = $childPreferenceTimesSideElement;
  908. }
  909. }
  910. $start = clone $teacherAvailabilityTime->getStartTime();
  911. $end = clone $teacherAvailabilityTime->getEndTime();
  912. $childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
  913. $childPreferenceTimesSide = $childPreferenceTimesQuery
  914. ->leftJoin('cpt.childPreference', 'cp')
  915. ->andWhere('cp.teacher = :teacher')
  916. ->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPendTime')
  917. ->andWhere('cpt.startTime <= :endTime')
  918. ->andWhere('cpt.endTime >= :endTime')
  919. ->andWhere('cpt.weekday = :weekday')
  920. ->setParameter('teacher', $teacher)
  921. ->setParameter('endTime', $end)
  922. ->setParameter('CPendTime', $childPreferenceObjectToAssign->getStartTime())
  923. ->setParameter('weekday', $weekday)
  924. ->orderBy('cpt.startTime', 'ASC')
  925. ->getQuery()
  926. ->getResult();
  927. foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
  928. if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
  929. $childPreferenceTimes[] = $childPreferenceTimesSideElement;
  930. }
  931. }
  932. //child Part
  933. $start = clone $teacherAvailabilityTime->getStartTime();
  934. $end = clone $teacherAvailabilityTime->getEndTime();
  935. $childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
  936. $childPreferenceTimesQuery
  937. ->leftJoin('cpt.childPreference', 'cp')
  938. ->andWhere('cp.child = :child')
  939. ->andWhere('cpt.startTime >= :startTime')
  940. ->andWhere('cpt.endTime <= :endTime')
  941. ->andWhere('cpt.weekday = :weekday')
  942. ->setParameter('child', $childPreferenceObjectToAssign->getChild())
  943. ->setParameter('startTime', $start)
  944. ->setParameter('endTime', $end)
  945. ->setParameter('weekday', $weekday)
  946. ->orderBy('cpt.startTime', 'ASC');
  947. if($childPreferenceObjectToAssign->getStartTime())
  948. {
  949. $childPreferenceTimesQuery
  950. ->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPstartTime')->setParameter('CPstartTime', $childPreferenceObjectToAssign->getStartTime());
  951. }
  952. $childPreferenceTimesSide = $childPreferenceTimesQuery->getQuery()->getResult();
  953. foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
  954. if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
  955. $childPreferenceTimes[] = $childPreferenceTimesSideElement;
  956. }
  957. }
  958. $start = clone $teacherAvailabilityTime->getStartTime();
  959. $end = clone $teacherAvailabilityTime->getEndTime();
  960. $childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
  961. $childPreferenceTimesQuery
  962. ->leftJoin('cpt.childPreference', 'cp')
  963. ->andWhere('cp.child = :child')
  964. ->andWhere('cpt.startTime <= :startTime')
  965. ->andWhere('cpt.endTime >= :startTime')
  966. ->andWhere('cpt.weekday = :weekday')
  967. ->setParameter('child', $childPreferenceObjectToAssign->getChild())
  968. ->setParameter('startTime', $start)
  969. ->setParameter('weekday', $weekday)
  970. ->orderBy('cpt.startTime', 'ASC');
  971. if($childPreferenceObjectToAssign->getStartTime())
  972. {
  973. $childPreferenceTimesQuery
  974. ->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPstartTime')->setParameter('CPstartTime', $childPreferenceObjectToAssign->getStartTime());
  975. }
  976. $childPreferenceTimesSide = $childPreferenceTimesQuery->getQuery()->getResult();
  977. foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
  978. if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
  979. $childPreferenceTimes[] = $childPreferenceTimesSideElement;
  980. }
  981. }
  982. $start = clone $teacherAvailabilityTime->getStartTime();
  983. $end = clone $teacherAvailabilityTime->getEndTime();
  984. $childPreferenceTimesQuery = $this->childPreferenceTimeRepository->createQueryBuilder('cpt');
  985. $childPreferenceTimesQuery
  986. ->leftJoin('cpt.childPreference', 'cp')
  987. ->andWhere('cp.child = :child')
  988. ->andWhere('cpt.startTime <= :endTime')
  989. ->andWhere('cpt.endTime >= :endTime')
  990. ->andWhere('cpt.weekday = :weekday')
  991. ->setParameter('child', $childPreferenceObjectToAssign->getChild())
  992. ->setParameter('endTime', $end)
  993. ->setParameter('weekday', $weekday)
  994. ->orderBy('cpt.startTime', 'ASC');
  995. if($childPreferenceObjectToAssign->getStartTime())
  996. {
  997. $childPreferenceTimesQuery
  998. ->andWhere('cp.endTime IS NULL OR cp.endTime >= :CPstartTime')->setParameter('CPstartTime', $childPreferenceObjectToAssign->getStartTime());
  999. }
  1000. $childPreferenceTimesSide = $childPreferenceTimesQuery->getQuery()->getResult();
  1001. /** @var ChildPreferenceTime $childPreferenceTimesSideElement */
  1002. foreach ($childPreferenceTimesSide as $childPreferenceTimesSideElement) {
  1003. if (!in_array($childPreferenceTimesSideElement, $childPreferenceTimes)) {
  1004. $childPreferenceTimes[] = $childPreferenceTimesSideElement;
  1005. }
  1006. }
  1007. /**
  1008. * @var ChildPreferenceTime $childPreferenceTime
  1009. */
  1010. foreach ($childPreferenceTimes as $key => $childPreferenceTime) {
  1011. $start = clone $childPreferenceTime->getStartTime();
  1012. $end = clone $childPreferenceTime->getEndTime();
  1013. if($teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments())
  1014. {
  1015. $start->modify('-'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
  1016. $end->modify('+'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
  1017. }
  1018. if ($end <= $times[$weekday]['start']) {
  1019. unset($childPreferenceTimes[$key]);
  1020. }
  1021. if ($start >= $times[$weekday]['end']) {
  1022. unset($childPreferenceTimes[$key]);
  1023. }
  1024. }
  1025. usort($childPreferenceTimes,
  1026. static fn($a, $b) => $a->getStartTime() <=> $b->getStartTime()
  1027. );
  1028. $childPreferenceTimes = array_values(array_filter($childPreferenceTimes));
  1029. if (count($childPreferenceTimes) == 0) {
  1030. //There are no child preferences just check if slot time
  1031. $slotTimeDuration = date_diff($times[$weekday]['start'], $times[$weekday]['end']);
  1032. $slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
  1033. // if($_SERVER['REMOTE_ADDR'] == '86.38.84.66' && $maxClass == 4) {
  1034. // dump($slotTime);
  1035. // dump($duration);
  1036. // }
  1037. if ($slotTime >= $duration/$amount) {
  1038. if(in_array($weekday, $addedWeekdays)) {
  1039. continue;
  1040. }
  1041. $foundAvailableTimeSlots++;
  1042. $availableTimeSlotsTeacher[] = [
  1043. '0start' => $times[$weekday]['start'],
  1044. '1end' => $times[$weekday]['end'],
  1045. 'weekday' => $weekday
  1046. ];
  1047. $addedWeekdays[] = $weekday;
  1048. continue;
  1049. }
  1050. }
  1051. //Find slots between other child preferences
  1052. /**
  1053. * @var ChildPreferenceTime $childPreferenceTime
  1054. */
  1055. foreach ($childPreferenceTimes as $key => $childPreferenceTime) {
  1056. $start = clone $childPreferenceTime->getStartTime();
  1057. $end = clone $childPreferenceTime->getEndTime();
  1058. if($teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments())
  1059. {
  1060. $start->modify('-'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
  1061. $end->modify('+'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
  1062. }
  1063. if ($key == 0 && $start >= $times[$weekday]['start']) {
  1064. $slotTimeDuration = date_diff($times[$weekday]['start'], $start);
  1065. $slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
  1066. if ($slotTime >= $duration/$amount) {
  1067. if(in_array($weekday, $addedWeekdays)) {
  1068. continue;
  1069. }
  1070. $foundAvailableTimeSlots++;
  1071. $availableTimeSlotsTeacher[] = [
  1072. '0start' => $times[$weekday]['start'],
  1073. '1end' => $start,
  1074. 'weekday' => $weekday
  1075. ];
  1076. $addedWeekdays[] = $weekday;
  1077. continue 2;
  1078. }
  1079. }
  1080. if ($key + 1 == count($childPreferenceTimes) && $end <= $times[$weekday]['end']) {
  1081. //Last element
  1082. $slotTimeDuration = date_diff($end, $times[$weekday]['end']);
  1083. $slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
  1084. if ($slotTime >= $duration/$amount) {
  1085. if(in_array($weekday, $addedWeekdays)) {
  1086. continue;
  1087. }
  1088. $foundAvailableTimeSlots++;
  1089. $availableTimeSlotsTeacher[] = [
  1090. '0start' => $end,
  1091. '1end' => $times[$weekday]['end'],
  1092. 'weekday' => $weekday
  1093. ];
  1094. $addedWeekdays[] = $weekday;
  1095. continue 2;
  1096. }
  1097. } elseif ($end <= $times[$weekday]['end']) {
  1098. //Not last element
  1099. /**
  1100. * @var ChildPreferenceTime $nextChildPreferenceTime
  1101. */
  1102. $nextChildPreferenceTime = $childPreferenceTimes[$key + 1];
  1103. $nextStart = clone $nextChildPreferenceTime->getStartTime();
  1104. if($teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments()){
  1105. $nextStart->modify('-'.$teacherAvailabilityTime->getTeacher()->getGapBetweenAssignments().' minutes');
  1106. }
  1107. if ($end >= $nextStart) {
  1108. continue;
  1109. }
  1110. $slotTimeDuration = date_diff($end, $nextStart);
  1111. $slotTime = (int)$slotTimeDuration->i + (int)$slotTimeDuration->h * 60;
  1112. if ($slotTime >= $duration/$amount) {
  1113. if(in_array($weekday, $addedWeekdays)) {
  1114. continue;
  1115. }
  1116. $foundAvailableTimeSlots++;
  1117. $availableTimeSlotsTeacher[] = [
  1118. '0start' => $end,
  1119. '1end' => $nextStart,
  1120. 'weekday' => $weekday
  1121. ];
  1122. $addedWeekdays[] = $weekday;
  1123. continue 2;
  1124. }
  1125. }
  1126. }
  1127. }
  1128. }
  1129. }
  1130. // if($_SERVER['REMOTE_ADDR'] == '86.38.84.66' && $maxClass == 4) {
  1131. // dump($foundAvailableTimeSlots);
  1132. // dump($amount);
  1133. // dump($teacher->getId());
  1134. // die();
  1135. // }
  1136. // die();
  1137. if ($foundAvailableTimeSlots >= $amount) {
  1138. $availableTeachers[] = $teacher;
  1139. $availableTimeSlots[] = [
  1140. 'times' => $availableTimeSlotsTeacher,
  1141. 'teacher' => $teacher->getFullname(true)
  1142. ];
  1143. }
  1144. // else
  1145. // {
  1146. // unset($teachers[$key]);
  1147. // }
  1148. }
  1149. $teachers = $this->serializer->normalize($availableTeachers, null, ['groups' => "TeacherList"]);
  1150. $dateNow = new \DateTime();
  1151. foreach ($teachers as $key => $teacher)
  1152. {
  1153. $teacherObj = $this->teacherRepository->find($teacher['id']);
  1154. $teacherHolidaysString = '';
  1155. foreach ($teacherObj->getTeacherHolidays() as $teacherHoliday)
  1156. {
  1157. if($teacherHoliday->getDateEnd() > $dateNow)
  1158. {
  1159. if($teacherHolidaysString)
  1160. {
  1161. $teacherHolidaysString .= '<br>';
  1162. }
  1163. $teacherHolidaysString .= "Nuo: {$teacherHoliday->getDateStart()->format('Y-m-d')} <br> Iki: {$teacherHoliday->getDateEnd()->format('Y-m-d')}";
  1164. }
  1165. }
  1166. $teachers[$key]['holiday'] = $teacherHolidaysString;
  1167. $teachers[$key]['fullname'] = $teacherObj->getFullname(true);
  1168. $teachers[$key]['have_moved_lessons'] = false;
  1169. $teachers[$key]['unavailableUntil'] = '';
  1170. foreach ($teacher['teacherUnavailableRanges'] as $teacherUnavailableRange)
  1171. {
  1172. if(new \DateTime($teacherUnavailableRange['startTime']) < new \DateTime() && new \DateTime($teacherUnavailableRange['endTime']) > new \DateTime())
  1173. {
  1174. $teachers[$key]['unavailableUntil'] = $teacherUnavailableRange['endTime'];
  1175. }
  1176. }
  1177. foreach ($timesOriginal as $weekdayKey => $originalTime) {
  1178. if (!$originalTime['start'] || !$originalTime['end']) {
  1179. continue;
  1180. }
  1181. $weeksToSearch = [0,1,2];
  1182. foreach ($weeksToSearch as $weekToSearch) {
  1183. $end = new \DateTime($originalTime['end']->format('H:i'));
  1184. $start = new \DateTime($originalTime['start']->format('H:i'));
  1185. $end->modify("next {$this->getWeekdayEnglishFromNumber($weekdayKey)}");
  1186. $end->setTime($originalTime['end']->format('H'), $originalTime['end']->format('i'));
  1187. $start->modify("next {$this->getWeekdayEnglishFromNumber($weekdayKey)}");
  1188. $start->setTime($originalTime['start']->format('H'), $originalTime['start']->format('i'));
  1189. $end->modify("+{$weekToSearch} weeks");
  1190. $start->modify("+{$weekToSearch} weeks");
  1191. $query = $this->lessonRepository->createQueryBuilder('l');
  1192. $lessons = $query
  1193. ->andWhere('l.teacher = :teacher')
  1194. ->setParameter('teacher', $teacherObj)
  1195. ->andWhere('l.status = :status')
  1196. ->setParameter('status', Lesson::STATUS_REGULAR_MOVED['value'])
  1197. ->andWhere('l.startTime < :end')
  1198. ->setParameter('end', $end)
  1199. ->andWhere('l.endTime > :start')
  1200. ->setParameter('start', $start)
  1201. ->getQuery()
  1202. ->getResult();
  1203. if ($lessons) {
  1204. unset($teachers[$key]);
  1205. unset($availableTimeSlots[$key]);
  1206. break;
  1207. }
  1208. }
  1209. }
  1210. }
  1211. foreach ($availableTimeSlots as $key => &$availableTimeSlot) {
  1212. $priorities = array_column($timesOriginal, 'priority', 'weekday');
  1213. usort($availableTimeSlot['times'], function($a, $b) use ($priorities) {
  1214. $priorityA = $priorities[$a['weekday']] ?? false;
  1215. $priorityB = $priorities[$b['weekday']] ?? false;
  1216. if ($priorityA === $priorityB) {
  1217. return 0;
  1218. }
  1219. return $priorityA ? -1 : 1;
  1220. });
  1221. // $availableTimeSlots['times'] = [];
  1222. // dump($availableTimeSlot);
  1223. // dump($timesOriginal);
  1224. // dump($times);
  1225. // die();
  1226. }
  1227. // dump($timesOriginal);
  1228. // die();
  1229. // dump($availableTimeSlots);
  1230. // die();
  1231. //if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
  1232. // foreach ($teachers as $teacher)
  1233. // {
  1234. // dump($teacher['fullname']);
  1235. // }
  1236. // dump($teachers);
  1237. //// dump(["data" => $timesOriginal, 'timeSlots' => $availableTimeSlots]);
  1238. // dump($timesOriginal);
  1239. // dump($availableTimeSlots);
  1240. //// dump($childPreferenceObjectToAssign->getChildPreferenceTimes()->getValues());
  1241. //// dump($availableTimeSlots[1]['times'][0]);
  1242. // die();
  1243. //}
  1244. $this->entityManager->refresh($childPreferenceObjectToAssign);
  1245. if($childPreferenceObjectToAssign->getStatus() == ChildPreference::STATUS_ASSIGNED['value'])
  1246. {
  1247. return;
  1248. }
  1249. if($debug)
  1250. {
  1251. dump('availableTimeSlots:');
  1252. dump($availableTimeSlots);
  1253. }
  1254. $firstKey = array_key_first($teachers);
  1255. // if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
  1256. // $firstKey = 1;
  1257. // }
  1258. if(isset($teachers[$firstKey]) && $teachers[$firstKey])
  1259. {
  1260. if(!count($childPreferenceObjectToAssign->getChildPreferenceTimes()->getValues())) {
  1261. for($i = 0; $i < $amount; $i++) {
  1262. if (isset($availableTimeSlots[$firstKey]['times'][$i]['weekday'])) {
  1263. if(!$debug)
  1264. {
  1265. $childPreferenceTime = (new ChildPreferenceTime())
  1266. ->setChildPreference($childPreferenceObjectToAssign)
  1267. ->setCreatedAt(new \DateTime())
  1268. ->setWeekday($availableTimeSlots[$firstKey]['times'][$i]['weekday'])
  1269. ->setStartTime((new \DateTime("{$availableTimeSlots[$firstKey]['times'][$i]['0start']->format('H:i')}")))
  1270. ->setEndTime((new \DateTime("{$availableTimeSlots[$firstKey]['times'][$i]['0start']->format('H:i')}"))->modify("+{$childPreferenceObjectToAssign->getSingleEmailDuration()} minutes"));
  1271. // if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
  1272. // dump($availableTimeSlots[$firstKey]);
  1273. // dump($childPreferenceTime);
  1274. // die();
  1275. // }
  1276. $this->entityManager->persist($childPreferenceTime);
  1277. $childPreferenceObjectToAssign->addChildPreferenceTime($childPreferenceTime);
  1278. $this->entityManager->persist($childPreferenceObjectToAssign);
  1279. $this->entityManager->flush();
  1280. }
  1281. }
  1282. }
  1283. }
  1284. // if($_SERVER['REMOTE_ADDR'] == '78.63.47.47') {
  1285. // die();
  1286. // }
  1287. if(!$debug) {
  1288. $oldChildPreferenceObjectToAssign = clone $childPreferenceObjectToAssign;
  1289. $childPreferenceObjectToAssign->setTeacher($this->teacherRepository->find($teachers[$firstKey]['id']));
  1290. $childPreferenceObjectToAssign->setStatus(ChildPreference::STATUS_ASSIGNED['value']);
  1291. $childPreferenceObjectToAssign->setAssignedAt(new \DateTime());
  1292. $childPreferenceObjectToAssign->setAssignedAutomaticly(new \DateTime());
  1293. $this->entityManager->persist($childPreferenceObjectToAssign);
  1294. $this->entityManager->flush();
  1295. $this->guardianLogService->addGuardianActionLog(
  1296. "Automatinis priskyrimas ({$childPreferenceObjectToAssign->getChild()->getFullname()} {$childPreferenceObjectToAssign->getDiscipline()->getName()}): {$childPreferenceObjectToAssign->getTeacher()->getFullname()}",
  1297. $childPreferenceObjectToAssign->getChild()->getGuardian(),
  1298. $childPreferenceObjectToAssign,
  1299. 'update'
  1300. );
  1301. $this->entityManager->flush();
  1302. $this->handleStatusChange($oldChildPreferenceObjectToAssign, $childPreferenceObjectToAssign);
  1303. }
  1304. if($debug)
  1305. {
  1306. die();
  1307. }
  1308. }
  1309. // elseif ($maxClass < 13)
  1310. // {
  1311. // $maxClass++;
  1312. // $this->assignTeacher($childPreferenceObjectToAssign, $child ,$teacherToForceAssign, $maxClass, $debug);
  1313. // }
  1314. else {
  1315. if($debug)
  1316. {
  1317. die();
  1318. }
  1319. $childPreferenceObjectToAssign->setStatus(ChildPreference::STATUS_NOT_FOUND['value']);
  1320. $this->entityManager->persist($childPreferenceObjectToAssign);
  1321. $this->entityManager->flush();
  1322. }
  1323. }
  1324. public function sendAssignedNotification(ChildPreference $childPreference)
  1325. {
  1326. $guardian = $childPreference->getChild()->getGuardian();
  1327. $child = $childPreference->getChild();
  1328. $teacher = $childPreference->getTeacher();
  1329. $message = "Sveiki,
  1330. Pirmasis mūsų užsiėmimas jau netoliese, jeigu turite klausimų, galite parašyti čia.
  1331. Iki pasimatymo!
  1332. {$childPreference->getTeacher()->getFullname()}
  1333. ";
  1334. try {
  1335. $this->getStreamService->sendMessage($teacher, $guardian, $message);
  1336. $this->getStreamService->sendMessage($teacher, $child, $message);
  1337. }
  1338. catch (\Exception $e)
  1339. {
  1340. }
  1341. if(!$guardian->getMobileAppLastUsedAt()) {
  1342. $dateToSendAt = new \DateTime();
  1343. $this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
  1344. DelayStamp::delayUntil($dateToSendAt),
  1345. ]));
  1346. $dateToSendAt = new \DateTime();
  1347. $dateToSendAt->modify('+24 hours');
  1348. $dateToSendAt->setTime(9, 0, 0);
  1349. $this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
  1350. DelayStamp::delayUntil($dateToSendAt),
  1351. ]));
  1352. $dateToSendAt = new \DateTime();
  1353. $dateToSendAt->modify('+48 hours');
  1354. $dateToSendAt->setTime(9, 0, 0);
  1355. $this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
  1356. DelayStamp::delayUntil($dateToSendAt),
  1357. ]));
  1358. $dateToSendAt = new \DateTime();
  1359. $dateToSendAt->modify('+72 hours');
  1360. $dateToSendAt->setTime(9, 0, 0);
  1361. $this->messageBus->dispatch(new Envelope(new SendSMSMessage($guardian->getPhoneNumber(), '', ['[GUARDIAN_ID]' => $guardian->getId()], 'GUARDIAN_MISSED_MESSAGE'), [
  1362. DelayStamp::delayUntil($dateToSendAt),
  1363. ]));
  1364. }
  1365. }
  1366. public function handleStatusChange(ChildPreference $oldChildPreference, ChildPreference $childPreference, $oldChildPreferenceTimes = [])
  1367. {
  1368. if ($oldChildPreference->getStatus() != $childPreference->getStatus() && $childPreference->getStatus() == ChildPreference::STATUS_AUTOMATIC_ASSIGNMENT['value']) {
  1369. $dateToSendAt = new \DateTime();
  1370. $this->messageBus->dispatch(new Envelope(new AssignChildPreferenceTeacherMessage($childPreference->getId(), $childPreference->getTeacher()), [
  1371. DelayStamp::delayUntil($dateToSendAt),
  1372. ]));
  1373. }
  1374. //Jeigu keiciasi mokytojas, metam i priskirta
  1375. //Notif 0
  1376. if ($oldChildPreference->getTeacher() != $childPreference->getTeacher() || ($oldChildPreference->getStatus() != $childPreference->getStatus() && $childPreference->getStatus() == ChildPreference::STATUS_ASSIGNED['value'])) {
  1377. $childPreference->setStatus(ChildPreference::STATUS_ASSIGNED['value']);
  1378. $childPreference->setAssignedAt(new \DateTime());
  1379. $childPreference->setTeacherAssignRemindCount(0);
  1380. $this->entityManager->persist($childPreference);
  1381. $this->entityManager->flush();
  1382. if($childPreference->getTeacher() && $childPreference->getTeacher()->isFlagAutoAcceptAssignment())
  1383. {
  1384. if ($childPreference->getChild()->getLessonsEnd()) {
  1385. $child = $childPreference->getChild();
  1386. $child->setLessonsEnd(null);
  1387. $this->entityManager->persist($child);
  1388. $this->entityManager->flush();
  1389. }
  1390. $childPreference->setStatus(ChildPreference::STATUS_ACCEPTED['value']);
  1391. $childPreference->setAcceptedAt(new \Datetime());
  1392. $startTime = $this->findFirstLessonDate($childPreference);
  1393. if($startTime) {
  1394. $childPreference->setStartTime($startTime);
  1395. }
  1396. $oldChildPreference = clone $childPreference;
  1397. $this->entityManager->persist($childPreference);
  1398. $this->entityManager->flush();
  1399. $this->entityManager->refresh($childPreference);
  1400. $this->generateLessonsForChildPreference($childPreference);
  1401. if($startTime) {
  1402. $this->recalculatePricesForFurtherLessons($childPreference->getChild()->getGuardian(), $startTime);
  1403. }
  1404. $this->sendAcceptedEmailAndSMS($childPreference);
  1405. $this->sendAssignedNotification($childPreference);
  1406. $teacherComments = $this->findPreviousComments($childPreference);
  1407. $teacherCommentsString = '';
  1408. if ($teacherComments) {
  1409. foreach ($teacherComments as $teacherComment) {
  1410. $date = $teacherComment->getCreatedAt()->format('Y-m-d');
  1411. $teacherCommentsString .= "<strong>{$date}</strong>:<br>{$teacherComment->getComment()}<br>";
  1412. }
  1413. }
  1414. $preferenceSummary = "";
  1415. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1416. $preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
  1417. }
  1418. $replacements = [
  1419. '[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
  1420. '[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
  1421. '[FIRST_LESSON_DATE]' => $childPreference->getStartTime()->format('Y-m-d H:i'),
  1422. '[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
  1423. '[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
  1424. '[SINGLE_LESSON_AMOUNT]' => $childPreference->getAmount(),
  1425. '[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
  1426. '[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
  1427. '[FIRST_LESSON_DATE_TIME]' => $childPreference->getStartTime()->format('Y-m-d H:i'),
  1428. '[PREFERENCE_COMMENT]' => $childPreference->getComment(),
  1429. '[TEACHER_COMMENTS]' => $teacherCommentsString,
  1430. '[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
  1431. '[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
  1432. ];
  1433. $this->notificationService->sendNotificationTemplate($childPreference->getTeacher(),'TEACHER_NEW_AUTO_ACCEPT_ASSIGNMENT', $replacements, true);
  1434. if($childPreference->getTeacher() && $childPreference->getTeacher()->getPhoneNumber()) {
  1435. $this->messageBus->dispatch(new SendSMSMessage($childPreference->getTeacher()->getPhoneNumber(), '', $replacements, 'ASSIGNMENT_NEW_AUTO_NOTIF_1'));
  1436. }
  1437. }
  1438. if (!$childPreference->getIgnoreNotifications() && (!$childPreference->getTeacher() || !$childPreference->getTeacher()->isFlagAutoAcceptAssignment())) {
  1439. $this->sendAssignedEmailandSMS($childPreference);
  1440. }
  1441. }
  1442. //Jeigu mokytojas patvirtino
  1443. //Notif 1
  1444. if ($oldChildPreference->getStatus() != $childPreference->getStatus() && $childPreference->getStatus() == ChildPreference::STATUS_ACCEPTED['value'] && $childPreference->getTeacher()) {
  1445. $this->sendAcceptedEmailAndSMS($childPreference);
  1446. }
  1447. //Jeigu keicia mokytoja, uzsetinam priezasti jeigu jos neirase tiesiog.
  1448. if ($childPreference->getTeacherChange() && !$childPreference->getTerminateReason()) {
  1449. if ($childPreference->getTeacherChange() == 'teacherChangeTeacher') {
  1450. $childPreference->setTerminateReason('Korepetitoriaus prašymu');
  1451. }
  1452. if ($childPreference->getTeacherChange() == 'teacherChangeGuardian') {
  1453. $childPreference->setTerminateReason('Kliento prašymas');
  1454. }
  1455. if ($childPreference->getTeacherChange() == 'amountDiscipline') {
  1456. $childPreference->setTerminateReason('Dažnio/ krūvio/ disciplinos keitimas');
  1457. }
  1458. $this->entityManager->persist($childPreference);
  1459. $this->entityManager->flush();
  1460. }
  1461. //Jeigu nera priezasties, nesaugom ir pabaigos datos. Administracijos klaida.
  1462. if (!$childPreference->getTerminateReason() && $childPreference->getEndTime()) {
  1463. $childPreference->setEndTime(null);
  1464. $this->entityManager->persist($childPreference);
  1465. $this->entityManager->flush();
  1466. }
  1467. //Jeigu tiesiog nutraukia uzsiemimus
  1468. //Notif 2
  1469. if (!$oldChildPreference->getEndTime() && $childPreference->getTerminateReason() && $childPreference->getEndTime() && !$childPreference->getTeacherChange() && $childPreference->getTeacher()) {
  1470. $childPreference->setStatus(ChildPreference::STATUS_TERMINATING['value']);
  1471. $this->entityManager->persist($childPreference);
  1472. $this->entityManager->flush();
  1473. $this->deleteLessonAfterPreferenceEndPeriod($childPreference);
  1474. if (!$childPreference->getIgnoreNotifications()) {
  1475. $this->sendTerminatingEmailAndSMS($childPreference);
  1476. }
  1477. }
  1478. //Jeigu nutraukia su senu mokytoju, bet skirs nauja keiciasi mokytojas
  1479. if ($childPreference->getTeacherChange() && $childPreference->getEndTime() && !$oldChildPreference->getTerminateReason() && !$oldChildPreference->getEndTime() && $childPreference->getTeacher()) {
  1480. $childPreference->setStatus(ChildPreference::STATUS_TERMINATING['value']);
  1481. //Notif 3
  1482. $this->deleteLessonAfterPreferenceEndPeriod($childPreference);
  1483. $newChildPreference = new ChildPreference();
  1484. $newChildPreference->setChild($childPreference->getChild());
  1485. $newChildPreference->setAdminComment($childPreference->getAdminComment());
  1486. $newChildPreference->setEmailDuration($childPreference->getEmailDuration());
  1487. $newChildPreference->setSingleEmailDuration($childPreference->getSingleEmailDuration());
  1488. $newChildPreference->setDiscipline($childPreference->getDiscipline());
  1489. $newChildPreference->setComment($childPreference->getComment());
  1490. $newChildPreference->setType($childPreference->getType());
  1491. $newChildPreference->setFittingTimes($childPreference->getFittingTimes());
  1492. $this->entityManager->persist($newChildPreference);
  1493. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1494. $newChildPreferenceTime = new ChildPreferenceTime();
  1495. $newChildPreferenceTime->setChildPreference($newChildPreference);
  1496. $newChildPreferenceTime->setEndTime($childPreferenceTime->getEndTime());
  1497. $newChildPreferenceTime->setStartTime($childPreferenceTime->getStartTime());
  1498. $newChildPreferenceTime->setWeekday($childPreferenceTime->getWeekday());
  1499. $this->entityManager->persist($newChildPreferenceTime);
  1500. $newChildPreference->addChildPreferenceTime($newChildPreferenceTime);
  1501. }
  1502. $this->entityManager->flush();
  1503. if ($childPreference->getTeacherChange() == 'teacherChangeTeacher') {
  1504. if (!$childPreference->getIgnoreNotifications()) {
  1505. $this->sendTerminatingByTeacherEmailAndSMS($childPreference);
  1506. }
  1507. }
  1508. //Notif 4
  1509. if ($childPreference->getTeacherChange() == 'teacherChangeGuardian') {
  1510. if (!$childPreference->getIgnoreNotifications()) {
  1511. $this->sendTerminatingByGuardianEmailAndSMS($childPreference);
  1512. }
  1513. }
  1514. //Notif 4
  1515. if ($childPreference->getTeacherChange() == 'amountDiscipline') {
  1516. if (!$childPreference->getIgnoreNotifications()) {
  1517. $this->sendTerminatingByChangeEmailAndSMS($childPreference);
  1518. }
  1519. }
  1520. }
  1521. if ($childPreference->getIgnoreNotifications() && $childPreference->getRegenerateLessonsFrom()) {
  1522. $this->deleteLessonBeforeRegenerate($oldChildPreference, $oldChildPreferenceTimes, $childPreference->getRegenerateLessonsFrom());
  1523. $this->generateLessonsForChildPreference($childPreference, $childPreference->getRegenerateLessonsFrom()->format('Y-m-d H:i'));
  1524. }
  1525. if ($childPreference->getRegenerateAllLessons() && $childPreference->getRegenerateLessonsFrom()) {
  1526. $this->deleteChildLessons($childPreference->getChild(), $childPreference->getRegenerateLessonsFrom());
  1527. foreach ($childPreference->getChild()->getChildPreferences() as $childPreferenceForRegenerating) {
  1528. $this->generateLessonsForChildPreference($childPreferenceForRegenerating, $childPreference->getRegenerateLessonsFrom()->format('Y-m-d H:i'));
  1529. }
  1530. }
  1531. }
  1532. public function sendAssignedEmailAndSMS(ChildPreference $childPreference, $onlySMS = false)
  1533. {
  1534. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_NEW_NOTIF_0']);
  1535. $preferenceSummary = "";
  1536. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1537. $preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
  1538. }
  1539. $startTime = $childPreference->getStartTime();
  1540. if (!$startTime) {
  1541. $startTime = new \DateTime();
  1542. }
  1543. $childName = $childPreference->getChild()->getFullname();
  1544. $childName = explode(' ', $childName);
  1545. $childName = $childName[0];
  1546. $replacements = [
  1547. '[FIRST_LESSON_DATE]' => "{$this->getWeekdayFromNumber($startTime->format('N'))} {$startTime->format('(Y-m-d) H:i')}",
  1548. '[PREFERENCE_SUMMARY]' => $preferenceSummary,
  1549. '[CHILD_NAME]' => $childName,
  1550. '[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
  1551. '[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
  1552. '[ACCEPT_LINK]' => 'https://cor.lt' . $this->urlGenerator->generate('app_teacher_my_students'),
  1553. // '[ACCEPT_LINK]' => 'https://corepetitus.tlprojektai.lt' . $this->urlGenerator->generate('app_teacher_my_students'),
  1554. '[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
  1555. ];
  1556. $emailAddress = $childPreference->getTeacher()->getEmail();
  1557. if ($this->testMode) {
  1558. $emailAddress = $this->testEmailTeacher;
  1559. }
  1560. if (!$onlySMS) {
  1561. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_NEW_NOTIF_0'));
  1562. }
  1563. $smsContent = $reminderObject->getSmsTemplate();
  1564. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1565. $phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
  1566. if ($this->testMode) {
  1567. $phoneNumber = $this->testPhoneTeacher;
  1568. }
  1569. $this->smsService->send($phoneNumber, $smsContent);
  1570. foreach ($this->userFireBaseTokenRepository->findBy(['userClass' => 'teacher', 'userId' => $childPreference->getTeacher()->getId()]) as $userFireBaseToken) {
  1571. $token = $userFireBaseToken->getToken();
  1572. $this->fcmService->send($token, 'Naujas priskyrimas', 'Prašome per 1 val. patvirtinti mokinio priskyrimą');
  1573. }
  1574. }
  1575. private function isDateWithinVacationForDiscipline(Child $child, \DateTimeInterface $date, int $disciplineId): bool
  1576. {
  1577. foreach ($child->getChildVacations() as $vacation) {
  1578. if ($vacation->isIsDeleted()) {
  1579. continue;
  1580. }
  1581. if ($vacation->getDateFrom() >= $date || $vacation->getDateTo() <= $date) {
  1582. continue;
  1583. }
  1584. $vacationDisciplineIds = $vacation->getDisciplineIds();
  1585. if ($vacationDisciplineIds === null || in_array($disciplineId, $vacationDisciplineIds)) {
  1586. return true;
  1587. }
  1588. }
  1589. return false;
  1590. }
  1591. public function sendAcceptedEmailAndSMS(ChildPreference $childPreference)
  1592. {
  1593. $startTime = $childPreference->getStartTime();
  1594. if (!$startTime) {
  1595. $startTime = new \DateTime();
  1596. }
  1597. if ($this->isDateWithinVacationForDiscipline(
  1598. $childPreference->getChild(),
  1599. $startTime,
  1600. $childPreference->getDiscipline()->getId()
  1601. )) {
  1602. return;
  1603. }
  1604. //Tutor Part
  1605. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CONFIRMED_TUTOR_NOTIF_1']);
  1606. $preferenceSummary = "";
  1607. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1608. $preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
  1609. }
  1610. $childName = $childPreference->getChild()->getFullname();
  1611. $childName = explode(' ', $childName);
  1612. $childName = $childName[0];
  1613. $teacherComments = $this->findPreviousComments($childPreference);
  1614. $teacherCommentsString = '';
  1615. if ($teacherComments) {
  1616. $teacherCommentsString = "<strong>Buvusio korepetitoriaus atsiliepimai apie mokinį:</strong><br>";
  1617. foreach ($teacherComments as $teacherComment) {
  1618. $date = $teacherComment->getCreatedAt()->format('Y-m-d');
  1619. $teacherCommentsString .= "<strong>{$date}</strong>:<br>{$teacherComment->getComment()}<br>";
  1620. }
  1621. }
  1622. // dump($teacherCommentsString);
  1623. // die();
  1624. $replacements = [
  1625. '[FIRST_LESSON_DATE]' => "{$this->getWeekdayFromNumber($startTime->format('N'))} {$startTime->format('(Y-m-d) H:i')}",
  1626. '[CHILD_NAME]' => $childName,
  1627. '[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
  1628. '[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
  1629. '[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
  1630. '[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
  1631. '[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
  1632. '[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
  1633. '[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
  1634. '[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
  1635. '[PREFERENCE_COMMENT]' => $childPreference->getComment(),
  1636. '[FIRST_LESSON_DATE_TIME]' => "{$this->getWeekdayFromNumber($startTime->format('N'))} {$startTime->format('(Y-m-d) H:i')}",
  1637. '[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
  1638. '[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
  1639. '[TEACHER_COMMENTS]' => $teacherCommentsString,
  1640. '[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
  1641. ];
  1642. $emailAddress = $childPreference->getTeacher()->getEmail();
  1643. if ($this->testMode) {
  1644. $emailAddress = $this->testEmailTeacher;
  1645. }
  1646. $this->bus->dispatch(new SendMailMessage($emailAddress,'','', $replacements, 'ASSIGNMENT_CONFIRMED_TUTOR_NOTIF_1'));
  1647. $smsContent = $reminderObject->getSmsTemplate();
  1648. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1649. $phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
  1650. if ($this->testMode) {
  1651. $phoneNumber = $this->testPhoneTeacher;
  1652. }
  1653. // $this->smsService->send($phoneNumber, $smsContent);
  1654. if($phoneNumber) {
  1655. $this->bus->dispatch(new SendSMSMessage($phoneNumber, $smsContent));
  1656. }
  1657. //Guardian Part
  1658. $replacements['[CHILD_NAME]'] = $childPreference->getChild()->getFullname();
  1659. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CONFIRMED_GUARDIAN_NOTIF_1']);
  1660. $emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
  1661. if ($this->testMode) {
  1662. $emailAddress = $this->testEmailGuardian;
  1663. }
  1664. $smsContent = $reminderObject->getSmsTemplate();
  1665. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1666. $phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
  1667. if ($this->testMode) {
  1668. $phoneNumber = $this->testPhoneGuardian;
  1669. }
  1670. $dateNow = new \DateTime();
  1671. $dateMax = new \DateTime();
  1672. $dateMax->setTime(19, 0);
  1673. $dateMin = new \DateTime();
  1674. $dateMin->setTime(8, 59);
  1675. if ($dateNow < $dateMin || $dateNow > $dateMax) {
  1676. $dateToSendAt = new \DateTime();
  1677. if ($dateNow > $dateMax) {
  1678. $dateToSendAt->modify('+1 day');
  1679. }
  1680. $dateToSendAt->setTime(9, 0);
  1681. $this->bus->dispatch(new Envelope(new SendMailMessage($emailAddress,'','', $replacements, 'ASSIGNMENT_CONFIRMED_GUARDIAN_NOTIF_1'), [
  1682. DelayStamp::delayUntil($dateToSendAt),
  1683. ]));
  1684. $this->bus->dispatch(new Envelope(new SendSMSMessage($phoneNumber, $smsContent), [
  1685. DelayStamp::delayUntil($dateToSendAt),
  1686. ]));
  1687. } else {
  1688. //send Now
  1689. $this->bus->dispatch(new SendMailMessage($emailAddress,'','', $replacements, 'ASSIGNMENT_CONFIRMED_GUARDIAN_NOTIF_1'));
  1690. $this->bus->dispatch(new SendSMSMessage($phoneNumber, $smsContent));
  1691. // $this->smsService->send($phoneNumber, $smsContent);
  1692. }
  1693. }
  1694. public function sendTerminatingEmailAndSMS(ChildPreference $childPreference)
  1695. {
  1696. //Tutor Part
  1697. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_STOP_TUTOR_NOTIF_2']);
  1698. $preferenceSummary = "";
  1699. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1700. $preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
  1701. }
  1702. $endTime = $childPreference->getEndTime();
  1703. if (!$endTime) {
  1704. $endTime = new \DateTime();
  1705. }
  1706. $replacements = [
  1707. '[LAST_LESSON_DATE]' => "{$this->getWeekdayFromNumber($endTime->format('N'))} {$endTime->format('(Y-m-d)')}",
  1708. '[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
  1709. '[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
  1710. '[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
  1711. '[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
  1712. '[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
  1713. '[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
  1714. '[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
  1715. '[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
  1716. '[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
  1717. '[PREFERENCE_COMMENT]' => $childPreference->getComment(),
  1718. '[LAST_LESSON_DATE_TIME]' => "{$this->getWeekdayFromNumber($endTime->format('N'))} {$endTime->format('(Y-m-d) H:i')}",
  1719. '[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
  1720. '[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
  1721. '[CANCEL_REASON]' => $childPreference->getTerminateReason(),
  1722. '[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
  1723. ];
  1724. $emailAddress = $childPreference->getTeacher()->getEmail();
  1725. if ($this->testMode) {
  1726. $emailAddress = $this->testEmailTeacher;
  1727. }
  1728. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CLIENT_STOP_TUTOR_NOTIF_2'));
  1729. $smsContent = $reminderObject->getSmsTemplate();
  1730. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1731. $phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
  1732. if ($this->testMode) {
  1733. $phoneNumber = $this->testPhoneTeacher;
  1734. }
  1735. $this->smsService->send($phoneNumber, $smsContent);
  1736. //Guardian Part
  1737. if ($childPreference->getChild()->getGuardian()->getSummer() && (new \DateTime()) < (new \DateTime('2024-08-31'))) {
  1738. return;
  1739. }
  1740. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_STOP_GUARDIAN_NOTIF_2']);
  1741. $smsContent = $reminderObject->getSmsTemplate();
  1742. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1743. $phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
  1744. if ($this->testMode) {
  1745. $phoneNumber = $this->testPhoneGuardian;
  1746. }
  1747. $this->smsService->send($phoneNumber, $smsContent);
  1748. }
  1749. public function sendTerminatingByTeacherEmailAndSMS(ChildPreference $childPreference)
  1750. {
  1751. //Tutor Part
  1752. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_TUTOR_STOP_TUTOR_NOTIF_3']);
  1753. $preferenceSummary = "";
  1754. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1755. $preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
  1756. }
  1757. $endTime = $childPreference->getEndTime();
  1758. if (!$endTime) {
  1759. $endTime = new \DateTime();
  1760. }
  1761. $replacements = [
  1762. '[LAST_LESSON_DATE]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
  1763. '[LAST_LESSON_DATE_TEACHER]' => "{$this->getWeekdayFromNumber($endTime->format('N'))} {$endTime->format('(Y-m-d)')}",
  1764. '[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
  1765. '[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
  1766. '[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
  1767. '[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
  1768. '[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
  1769. '[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
  1770. '[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
  1771. '[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
  1772. '[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
  1773. '[PREFERENCE_COMMENT]' => $childPreference->getComment(),
  1774. '[LAST_LESSON_DATE_TIME]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
  1775. '[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
  1776. '[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
  1777. '[CANCEL_REASON]' => $childPreference->getTerminateReason(),
  1778. '[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
  1779. '[TUTOR_TERMINATE_COMMENT]' => $childPreference->getTutorTerminateComment(),
  1780. ];
  1781. $emailAddress = $childPreference->getTeacher()->getEmail();
  1782. if ($this->testMode) {
  1783. $emailAddress = $this->testEmailTeacher;
  1784. }
  1785. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_TUTOR_STOP_TUTOR_NOTIF_3'));
  1786. $smsContent = $reminderObject->getSmsTemplate();
  1787. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1788. $phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
  1789. if ($this->testMode) {
  1790. $phoneNumber = $this->testPhoneTeacher;
  1791. }
  1792. $this->smsService->send($phoneNumber, $smsContent);
  1793. //Guardian Part
  1794. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_TUTOR_STOP_GUARDIAN_NOTIF_3']);
  1795. $emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
  1796. if ($this->testMode) {
  1797. $emailAddress = $this->testEmailGuardian;
  1798. }
  1799. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_TUTOR_STOP_GUARDIAN_NOTIF_3'));
  1800. $smsContent = $reminderObject->getSmsTemplate();
  1801. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1802. $phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
  1803. if ($this->testMode) {
  1804. $phoneNumber = $this->testPhoneGuardian;
  1805. }
  1806. $this->smsService->send($phoneNumber, $smsContent);
  1807. }
  1808. public function sendTerminatingByGuardianEmailAndSMS(ChildPreference $childPreference)
  1809. {
  1810. //Tutor Part
  1811. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_CHANGE_TUTOR_NOTIF_4']);
  1812. $preferenceSummary = "";
  1813. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1814. $preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
  1815. }
  1816. $endTime = $childPreference->getEndTime();
  1817. if (!$endTime) {
  1818. $endTime = new \DateTime();
  1819. }
  1820. $replacements = [
  1821. '[LAST_LESSON_DATE]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
  1822. '[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
  1823. '[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
  1824. '[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
  1825. '[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
  1826. '[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
  1827. '[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
  1828. '[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
  1829. '[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
  1830. '[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
  1831. '[PREFERENCE_COMMENT]' => $childPreference->getComment(),
  1832. '[LAST_LESSON_DATE_TIME]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
  1833. '[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
  1834. '[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
  1835. '[CANCEL_REASON]' => $childPreference->getTerminateReason(),
  1836. '[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
  1837. '[TUTOR_TERMINATE_COMMENT]' => $childPreference->getTutorTerminateComment(),
  1838. ];
  1839. $emailAddress = $childPreference->getTeacher()->getEmail();
  1840. if ($this->testMode) {
  1841. $emailAddress = $this->testEmailTeacher;
  1842. }
  1843. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CLIENT_CHANGE_TUTOR_NOTIF_4'));
  1844. $smsContent = $reminderObject->getSmsTemplate();
  1845. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1846. $phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
  1847. if ($this->testMode) {
  1848. $phoneNumber = $this->testPhoneTeacher;
  1849. }
  1850. $this->smsService->send($phoneNumber, $smsContent);
  1851. //Guardian Part
  1852. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CLIENT_CHANGE_GUARDIAN_NOTIF_4']);
  1853. $emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
  1854. if ($this->testMode) {
  1855. $emailAddress = $this->testEmailGuardian;
  1856. }
  1857. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CLIENT_CHANGE_GUARDIAN_NOTIF_4'));
  1858. $smsContent = $reminderObject->getSmsTemplate();
  1859. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1860. $phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
  1861. if ($this->testMode) {
  1862. $phoneNumber = $this->testPhoneGuardian;
  1863. }
  1864. $this->smsService->send($phoneNumber, $smsContent);
  1865. }
  1866. public function sendTerminatingByChangeEmailAndSMS(ChildPreference $childPreference)
  1867. {
  1868. //Tutor Part
  1869. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CHANGE_AMOUNT_TUTOR']);
  1870. $preferenceSummary = "";
  1871. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1872. $preferenceSummary .= "{$childPreferenceTime->getWeekdayString()} {$childPreferenceTime->getStartTime()->format('H:i')}-{$childPreferenceTime->getEndTime()->format('H:i')}<br>";
  1873. }
  1874. $endTime = $childPreference->getEndTime();
  1875. if (!$endTime) {
  1876. $endTime = new \DateTime();
  1877. }
  1878. $replacements = [
  1879. '[LAST_LESSON_DATE]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
  1880. '[CHILD_NAME]' => $childPreference->getChild()->getFullname(),
  1881. '[DISCIPLINE_SHORT_NAME]' => $childPreference->getDiscipline()->getName(),
  1882. '[PREFERENCES_TIMES_SUMMARY]' => $preferenceSummary,
  1883. '[SINGLE_LESSON_DURATION]' => $childPreference->getSingleEmailDuration(),
  1884. '[SINGLE_LESSON_AMOUNT]' => count($childPreference->getChildPreferenceTimes()),
  1885. '[CHILD_CLASS]' => $childPreference->getChild()->getClass(),
  1886. '[CHILD_EMAIL]' => $childPreference->getChild()->getEmail(),
  1887. '[GUARDIAN_EMAIL]' => $childPreference->getChild()->getGuardian()->getEmail(),
  1888. '[GUARDIAN_NAME]' => $childPreference->getChild()->getGuardian()->getFullname(),
  1889. '[PREFERENCE_COMMENT]' => $childPreference->getComment(),
  1890. '[LAST_LESSON_DATE_TIME]' => "{$endTime->format('Y-m-d')} ({$this->getWeekdayFromNumber($endTime->format('N'))})",
  1891. '[TUTOR_FULLNAME]' => $childPreference->getTeacher()->getFullname(),
  1892. '[TUTOR_PHONE]' => $childPreference->getTeacher()->getPhoneNumber(),
  1893. '[CANCEL_REASON]' => $childPreference->getTerminateReason(),
  1894. '[CURRENT_TIME]' => (new \DateTime())->format('H:i'),
  1895. ];
  1896. $emailAddress = $childPreference->getTeacher()->getEmail();
  1897. if ($this->testMode) {
  1898. $emailAddress = $this->testEmailTeacher;
  1899. }
  1900. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CHANGE_AMOUNT_TUTOR'));
  1901. $smsContent = $reminderObject->getSmsTemplate();
  1902. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1903. $phoneNumber = $childPreference->getTeacher()->getPhoneNumber();
  1904. if ($this->testMode) {
  1905. $phoneNumber = $this->testPhoneTeacher;
  1906. }
  1907. $this->smsService->send($phoneNumber, $smsContent);
  1908. //Guardian Part
  1909. $reminderObject = $this->reminderConfigurationRepository->findOneBy(['reminder_key' => 'ASSIGNMENT_CHANGE_AMOUNT_GUARDIAN']);
  1910. $emailAddress = $childPreference->getChild()->getGuardian()->getEmail();
  1911. if ($this->testMode) {
  1912. $emailAddress = $this->testEmailGuardian;
  1913. }
  1914. $this->messageBus->dispatch(new SendMailMessage($emailAddress, '', '', $replacements, 'ASSIGNMENT_CHANGE_AMOUNT_GUARDIAN'));
  1915. $smsContent = $reminderObject->getSmsTemplate();
  1916. $smsContent = str_replace(array_keys($replacements), array_values($replacements), $smsContent);
  1917. $phoneNumber = $childPreference->getChild()->getGuardian()->getPhoneNumber();
  1918. if ($this->testMode) {
  1919. $phoneNumber = $this->testPhoneGuardian;
  1920. }
  1921. $this->smsService->send($phoneNumber, $smsContent);
  1922. }
  1923. public function findPreviousComments(ChildPreference $childPreference)
  1924. {
  1925. $teacherComments = [];
  1926. foreach (array_reverse($childPreference->getChild()->getTeacherSurveyResponses()->getValues()) as $teacherComment) {
  1927. if ($childPreference->getDiscipline() == $teacherComment->getDiscipline()) {
  1928. $teacherComments[] = $teacherComment;
  1929. if (count($teacherComments) == 3) {
  1930. break;
  1931. }
  1932. }
  1933. }
  1934. usort($teacherComments, function ($a, $b) {
  1935. return $a->getCreatedAt() < $b->getCreatedAt();
  1936. });
  1937. return $teacherComments;
  1938. }
  1939. public function findFirstLessonDate(ChildPreference $childPreference)
  1940. {
  1941. $currentTime = new \DateTime();
  1942. if (!$childPreference->getStartTime()) {
  1943. $dateNow = new \DateTime();
  1944. $dateNow->modify('+24 hours');
  1945. } elseif ($childPreference->getStartTime() < new \DateTime()) {
  1946. $dateNow = new \DateTime();
  1947. } else {
  1948. $dateNow = $childPreference->getStartTime();
  1949. }
  1950. $firstLessonDate = null;
  1951. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  1952. $startTimePreference = $childPreferenceTime->getStartTime();
  1953. $weekday = $this->getWeekdayEnglishFromNumber($childPreferenceTime->getWeekday());
  1954. for ($i = 0; $i <= 24; $i++) {
  1955. $startTime = new \DateTime();
  1956. $startTime->modify("first {$weekday} of {$startTime->format('Y-M')}");
  1957. $startTime->setTime((int)$startTimePreference->format('H'), (int)$startTimePreference->format('i'));
  1958. $startTime->modify("+{$i} weeks");
  1959. if ($currentTime <= $startTime && $startTime >= $dateNow && (!$firstLessonDate || $startTime <= $firstLessonDate)) {
  1960. $firstLessonDate = $startTime;
  1961. }
  1962. }
  1963. }
  1964. $childPreference->setStartTime($firstLessonDate);
  1965. return $firstLessonDate;
  1966. }
  1967. public function findFirstLessonDateForAccepted(ChildPreference $childPreference)
  1968. {
  1969. $query = $this->lessonRepository->createQueryBuilder('l');
  1970. $lesson = $query
  1971. ->andWhere('l.teacher = :teacher')
  1972. ->setParameter('teacher', $childPreference->getTeacher())
  1973. ->andWhere('l.discipline = :discipline')
  1974. ->setParameter('discipline', $childPreference->getDiscipline())
  1975. ->andWhere(':child member of l.children')
  1976. ->setParameter('child', $childPreference->getChild()->getId())
  1977. ->setMaxResults(1)
  1978. ->orderBy('l.startTime', 'ASC')
  1979. ->getQuery()
  1980. ->getOneOrNullResult();
  1981. if ($lesson) {
  1982. $childPreference->setStartTime($lesson->getStartTime());
  1983. }
  1984. return $childPreference->getStartTime();
  1985. }
  1986. public function deleteLessonAfterPreferenceEndPeriod(ChildPreference $childPreference, $doNotDeleteList = null)
  1987. {
  1988. $lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
  1989. $dateStart = new \DateTime($childPreference->getEndTime()->format('Y-m-d H:i'));
  1990. $lessons = $lessonsQuery
  1991. ->andWhere('l.teacher = :teacher')
  1992. ->setParameter('teacher', $childPreference->getTeacher())
  1993. ->andWhere('l.startTime >= :dateStart')
  1994. ->setParameter('dateStart', $dateStart)
  1995. ->andWhere(':child MEMBER OF l.children')
  1996. ->setParameter('child', $childPreference->getChild()->getId())
  1997. ->andWhere('l.discipline = :discipline')
  1998. ->setParameter('discipline', $childPreference->getDiscipline())
  1999. ->andWhere('l.type = :type')
  2000. ->setParameter('type', $childPreference->getType())
  2001. ->getQuery()
  2002. ->getResult();
  2003. /**
  2004. * @var $lesson Lesson
  2005. */
  2006. foreach ($lessons as $lesson) {
  2007. // if($lesson->getStatusValue() == Lesson::STATUS_REGULAR_MOVED['value']){
  2008. // continue;
  2009. // }
  2010. $skip = false;
  2011. if ($doNotDeleteList) {
  2012. foreach ($doNotDeleteList as $doNotDeleteDate) {
  2013. if ($doNotDeleteDate->format('Y-m-d H:i') == $lesson->getStartTime()->format('Y-m-d H:i')) {
  2014. $skip = true;
  2015. }
  2016. }
  2017. }
  2018. if (!$skip) {
  2019. foreach ($lesson->getTeacherPaymentLogs() as $teacherPaymentLog) {
  2020. $this->entityManager->remove($teacherPaymentLog);
  2021. }
  2022. $this->lessonDeletionService->delete(
  2023. $lesson,
  2024. LessonDeletionService::REASON_PREFERENCE_END_PERIOD
  2025. );
  2026. $this->entityManager->flush();
  2027. }
  2028. }
  2029. }
  2030. public function deleteLessonBeforeRegenerate(ChildPreference $childPreference, $childPreferenceTimes, $dateStart)
  2031. {
  2032. if (!$childPreference->getChild()) {
  2033. return true;
  2034. }
  2035. $lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
  2036. $lessons = $lessonsQuery
  2037. ->andWhere('l.teacher = :teacher')
  2038. ->setParameter('teacher', $childPreference->getTeacher())
  2039. ->andWhere('l.startTime >= :dateStart')
  2040. ->setParameter('dateStart', $dateStart)
  2041. ->andWhere(':child MEMBER OF l.children')
  2042. ->setParameter('child', $childPreference->getChild()->getId())
  2043. ->andWhere('l.discipline = :discipline')
  2044. ->setParameter('discipline', $childPreference->getDiscipline())
  2045. ->andWhere('l.type = :type')
  2046. ->setParameter('type', $childPreference->getType())
  2047. ->getQuery()
  2048. ->getResult();
  2049. /**
  2050. * @var $lesson Lesson
  2051. */
  2052. foreach ($lessons as $lesson) {
  2053. if (in_array($lesson->getStatusValue(), [Lesson::STATUS_REGULAR_MOVED['value'], Lesson::STATUS_ADDITIONAL['value']])) {
  2054. continue;
  2055. }
  2056. $this->lessonDeletionService->delete(
  2057. $lesson,
  2058. LessonDeletionService::REASON_PREFERENCE_REGENERATED
  2059. );
  2060. $this->entityManager->flush();
  2061. }
  2062. }
  2063. public function deleteChildLessons(Child $child, $dateStart)
  2064. {
  2065. if (!$child || !$dateStart) {
  2066. return true;
  2067. }
  2068. $lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
  2069. $lessons = $lessonsQuery
  2070. ->andWhere(':child MEMBER OF l.children')
  2071. ->setParameter('child', $child)
  2072. ->andWhere('l.startTime >= :dateStart')
  2073. ->setParameter('dateStart', $dateStart)
  2074. ->getQuery()
  2075. ->getResult();
  2076. /**
  2077. * @var $lesson Lesson
  2078. */
  2079. foreach ($lessons as $lesson) {
  2080. if (in_array($lesson->getStatusValue(), [Lesson::STATUS_REGULAR_MOVED['value'], Lesson::STATUS_ADDITIONAL['value']])) {
  2081. continue;
  2082. }
  2083. $this->lessonDeletionService->delete(
  2084. $lesson,
  2085. LessonDeletionService::REASON_CHILD_LESSONS_REMOVED
  2086. );
  2087. $this->entityManager->flush();
  2088. }
  2089. }
  2090. public function deleteLessonsForRemovedPreferenceTime(ChildPreference $childPreference, ChildPreferenceTime $removedTime): void
  2091. {
  2092. if (!$childPreference->getChild() || !$childPreference->getTeacher() || !$childPreference->getDiscipline()) {
  2093. return;
  2094. }
  2095. $removedWeekday = (int) $removedTime->getWeekday();
  2096. $removedStartTime = $removedTime->getStartTime()->format('H:i');
  2097. foreach ($childPreference->getChildPreferenceTimes() as $stillActiveTime) {
  2098. if ((int) $stillActiveTime->getWeekday() === $removedWeekday
  2099. && $stillActiveTime->getStartTime()->format('H:i') === $removedStartTime) {
  2100. // A remaining row still covers this weekday/time (e.g. it was re-added), so its lessons are legitimate.
  2101. return;
  2102. }
  2103. }
  2104. $lessons = $this->lessonRepository->createQueryBuilder('l')
  2105. ->andWhere('l.teacher = :teacher')
  2106. ->setParameter('teacher', $childPreference->getTeacher())
  2107. ->andWhere(':child MEMBER OF l.children')
  2108. ->setParameter('child', $childPreference->getChild()->getId())
  2109. ->andWhere('l.discipline = :discipline')
  2110. ->setParameter('discipline', $childPreference->getDiscipline())
  2111. ->andWhere('l.type = :type')
  2112. ->setParameter('type', $childPreference->getType())
  2113. ->andWhere('l.startTime >= :now')
  2114. ->setParameter('now', new \DateTime())
  2115. ->getQuery()
  2116. ->getResult();
  2117. /** @var Lesson $lesson */
  2118. foreach ($lessons as $lesson) {
  2119. if (in_array($lesson->getStatusValue(), [Lesson::STATUS_REGULAR_MOVED['value'], Lesson::STATUS_ADDITIONAL['value']])) {
  2120. continue;
  2121. }
  2122. if ((int) $lesson->getStartTime()->format('N') !== $removedWeekday) {
  2123. continue;
  2124. }
  2125. if ($lesson->getStartTime()->format('H:i') !== $removedStartTime) {
  2126. continue;
  2127. }
  2128. $this->lessonDeletionService->delete($lesson, LessonDeletionService::REASON_PREFERENCE_TIME_REMOVED);
  2129. $this->entityManager->flush();
  2130. $guardian = $childPreference->getChild()->getGuardian();
  2131. if ($guardian) {
  2132. $this->guardianLogService->addGuardianActionLog(
  2133. LessonDeletionService::REASON_PREFERENCE_TIME_REMOVED,
  2134. $guardian,
  2135. $lesson,
  2136. 'delete'
  2137. );
  2138. }
  2139. }
  2140. }
  2141. public function generateLessonsForChildPreference(ChildPreference $preference, $dateFrom = null, $doNotCreateList = null, $isPaid = false, $byPassStatusCheck = false, $byPassEarlyPaymentDateStart = false)
  2142. {
  2143. if ($dateFrom) {
  2144. $generateFrom = $dateFrom;
  2145. } else {
  2146. $generateFrom = $preference->getStartTime()->format('Y-m-d H:i');
  2147. }
  2148. // if($_SERVER['REMOTE_ADDR'] == '86.38.84.66')
  2149. // {
  2150. // dump('ok');
  2151. // die();
  2152. // }
  2153. $generateForMonth = new \DateTime($generateFrom);
  2154. $generateForMonth->modify("first day of {$generateForMonth->format('Y-M')}");
  2155. $dateMonthToGenerateFor = $generateForMonth->format('Y-m-d');
  2156. $generateTo = new \DateTime($dateMonthToGenerateFor);
  2157. $generateTo->modify("last day of {$generateTo->format('Y-M')}");
  2158. $generateTo->modify("+31 days");
  2159. $generateTo->setTime(23, 59);
  2160. $maxGenerateTo = new \DateTime();
  2161. $maxGenerateTo->modify("first day of {$maxGenerateTo->format('Y-M')}");
  2162. $maxGenerateTo->modify("+35 days");
  2163. $maxGenerateTo->setTime(23, 59);
  2164. $maxGenerateTo->modify("last day of {$maxGenerateTo->format('Y-M')}");
  2165. if ($generateTo > $maxGenerateTo) {
  2166. $generateTo = $maxGenerateTo;
  2167. }
  2168. $guardian = $preference->getChild()->getGuardian();
  2169. if($guardian->isFlagEarlyPayment() && !$byPassEarlyPaymentDateStart)
  2170. {
  2171. $paymentDay = $guardian->getEarlyPaymentDay();
  2172. $dateNow = new \DateTime();
  2173. $generateFromDate = new \DateTime($generateFrom);
  2174. if ($generateFromDate > $dateNow) {
  2175. // Future-dated preference start (delayed cutover): anchor on it, else $generateTo lands before $generateFrom and skips every lesson.
  2176. $dateNow = $generateFromDate;
  2177. }
  2178. $periodEndTime = new \DateTime("{$dateNow->format('Y-m-')}{$paymentDay}");
  2179. while ($dateNow->format('Y-m') == $periodEndTime->format('Y-m'))
  2180. {
  2181. $periodEndTime->modify('+7 days');
  2182. }
  2183. $periodEndTime->setDate($periodEndTime->format('Y'), $periodEndTime->format('m'), $paymentDay);
  2184. $generateTo = clone $periodEndTime;
  2185. }
  2186. // dump($generateTo);
  2187. // die();
  2188. $child = $preference->getChild();
  2189. // START CREATING INDIVIDUAL LESSONS
  2190. foreach ($child->getChildPreferences() as $childPreference) {
  2191. if($childPreference->getStatus() != ChildPreference::STATUS_ACCEPTED['value'] && !$byPassStatusCheck)
  2192. {
  2193. continue;
  2194. }
  2195. foreach ($childPreference->getChildPreferenceTimes() as $childPreferenceTime) {
  2196. $childPreference = $childPreferenceTime->getChildPreference();
  2197. if ($childPreference->getType() != Lesson::TYPE_INDIVIDUAL) {
  2198. continue;
  2199. }
  2200. if ($childPreference->getId() != $preference->getId()) {
  2201. continue;
  2202. }
  2203. $startTimePreference = $childPreferenceTime->getStartTime();
  2204. $endTimePreference = $childPreferenceTime->getEndTime();
  2205. $weekday = $this->getWeekdayEnglishFromNumber($childPreferenceTime->getWeekday());
  2206. for ($i = 0; $i <= 8; $i++) {
  2207. $startTime = new \DateTime($generateFrom);
  2208. $startTime->modify("first {$weekday} of {$startTime->format('Y-M')}");
  2209. $startTime->setTime((int)$startTimePreference->format('H'), (int)$startTimePreference->format('i'));
  2210. $startTime->modify("+{$i} weeks");
  2211. $endTime = new \DateTime($generateFrom);
  2212. $endTime->modify("first {$weekday} of {$endTime->format('Y-M')}");
  2213. $endTime->setTime((int)$endTimePreference->format('H'), (int)$endTimePreference->format('i'));
  2214. $endTime->modify("+{$i} weeks");
  2215. if ($generateTo <= $startTime) {
  2216. continue;
  2217. }
  2218. if ($startTime < new \DateTime($generateFrom)) {
  2219. continue;
  2220. }
  2221. if ($childPreference->getChild()->getLessonsEnd()) {
  2222. if ($startTime > $childPreference->getChild()->getLessonsEnd()) {
  2223. continue;
  2224. }
  2225. }
  2226. if ($childPreference->getStartTime() && $childPreference->getStartTime() > $startTime) {
  2227. continue;
  2228. }
  2229. if ($childPreference->getEndTime() && $childPreference->getEndTime() < $endTime) {
  2230. continue;
  2231. }
  2232. if (!$childPreference->getTeacher()) {
  2233. continue;
  2234. }
  2235. foreach ($child->getChildVacations() as $vacation) {
  2236. if ($vacation->isIsDeleted()) {
  2237. continue;
  2238. }
  2239. if ($vacation->getDateFrom() >= $startTime || $vacation->getDateTo() <= $startTime) {
  2240. continue;
  2241. }
  2242. $vacationDisciplineIds = $vacation->getDisciplineIds();
  2243. if ($vacationDisciplineIds === null || in_array($childPreference->getDiscipline()->getId(), $vacationDisciplineIds)) {
  2244. continue 2;
  2245. }
  2246. }
  2247. $skip = false;
  2248. if ($doNotCreateList) {
  2249. foreach ($doNotCreateList as $doNotCreateDate) {
  2250. if ($doNotCreateDate->format('Y-m-d H:i') == $startTime->format('Y-m-d H:i')) {
  2251. $skip = true;
  2252. }
  2253. }
  2254. }
  2255. if ($skip) {
  2256. continue;
  2257. }
  2258. $duration = date_diff($startTime, $endTime);
  2259. $duration = (int)$duration->i + (int)$duration->h * 60;
  2260. $lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
  2261. $lessons = $lessonsQuery
  2262. ->andWhere('l.teacher = :teacher')
  2263. ->setParameter('teacher', $childPreference->getTeacher()->getId())
  2264. ->andWhere('l.discipline = :discipline')
  2265. ->setParameter('discipline', $childPreference->getDiscipline()->getId())
  2266. ->andWhere(':child MEMBER OF l.children')
  2267. ->setParameter('child', $childPreference->getChild()->getId())
  2268. ->andWhere('l.startTime = :startTime OR l.originalStartTime = :startTime')
  2269. ->setParameter('startTime', $startTime->format('Y-m-d H:i'))
  2270. ->andWhere('l.endTime = :endTime OR l.originalEndTime = :endTime')
  2271. ->setParameter('endTime', $endTime->format('Y-m-d H:i'))
  2272. ->andWhere('l.type = :type')
  2273. ->setParameter('type', $childPreference->getType())
  2274. ->andWhere('l.duration = :duration')
  2275. ->setParameter('duration', $duration)
  2276. ->getQuery()
  2277. ->getResult();
  2278. $guardian = $childPreference->getChild()->getGuardian();
  2279. //sita nutrinam nes: uzkeisdavo esamas pamokas i regular statusa su sumoketa suma, bet niekada neatminusuoja is balanso, bugas palikdavo pamokas apmoketas nepakeitus balanso
  2280. // dump($childPreference->getTeacher()->getStatus());
  2281. // dump(Teacher::STATUS_ACTIVE);
  2282. if (!$lessons && $childPreference->getTeacher()->getStatus() == Teacher::STATUS_ACTIVE) {
  2283. $lesson = (new Lesson())
  2284. ->setType($childPreference->getType())
  2285. ->setStatus(Lesson::STATUS_REGULAR['value'])
  2286. ->setClass($childPreference->getChild()->getClass())
  2287. ->setDiscipline($childPreference->getDiscipline())
  2288. ->setTeacher($childPreference->getTeacher())
  2289. ->setDuration($duration)
  2290. ->setStartTime($startTime)
  2291. ->setEndTime($endTime)
  2292. ->setOriginalStartTime($startTime)
  2293. ->setOriginalEndTime($endTime);
  2294. $lesson->addChild($childPreference->getChild());
  2295. if ($guardian->isFlagEarlyPayment()) {
  2296. $lesson->setPaid(0);
  2297. $lesson->setStatus(Lesson::STATUS_WAITING_PAYMENT['value']);
  2298. }
  2299. if ($this->teacherHolidayRepository->isTeacherOnHolidayAt($childPreference->getTeacher(), $startTime)) {
  2300. $lesson->setStatus(Lesson::STATUS_INFORMED_MISSED['value']);
  2301. }
  2302. $this->entityManager->persist($lesson);
  2303. $this->entityManager->flush();
  2304. }
  2305. }
  2306. }
  2307. }
  2308. }
  2309. public function restoreLessonsForChildPreference(ChildPreference $preference, $restoreDeletedList = null)
  2310. {
  2311. if (!$restoreDeletedList) {
  2312. return;
  2313. }
  2314. foreach ($restoreDeletedList as $restoreDeletedDate) {
  2315. $query = $this->lessonDeletedRepository->createQueryBuilder('l');
  2316. /** @var LessonDeleted $deletedLessonToRestore */
  2317. $deletedLessonToRestore = $query
  2318. ->andWhere('l.discipline = :discipline')
  2319. ->setParameter('discipline', $preference->getDiscipline()->getId())
  2320. ->andWhere('l.teacher = :teacher')
  2321. ->setParameter('teacher', $preference->getTeacher()->getId())
  2322. ->andWhere('l.startTime = :startTime')
  2323. ->setParameter('startTime', $restoreDeletedDate)
  2324. ->setMaxResults(1)
  2325. ->getQuery()
  2326. ->getOneOrNullResult();
  2327. if (!$deletedLessonToRestore) {
  2328. return;
  2329. }
  2330. $startTime = $deletedLessonToRestore->getStartTime();
  2331. $endTime = $deletedLessonToRestore->getEndTime();
  2332. $duration = $deletedLessonToRestore->getDuration();
  2333. $lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
  2334. $lessons = $lessonsQuery
  2335. ->andWhere('l.teacher = :teacher')
  2336. ->setParameter('teacher', $preference->getTeacher()->getId())
  2337. ->andWhere('l.discipline = :discipline')
  2338. ->setParameter('discipline', $preference->getDiscipline()->getId())
  2339. ->andWhere(':child MEMBER OF l.children')
  2340. ->setParameter('child', $preference->getChild()->getId())
  2341. ->andWhere('l.startTime = :startTime')
  2342. ->setParameter('startTime', $startTime->format('Y-m-d H:i'))
  2343. ->andWhere('l.endTime = :endTime')
  2344. ->setParameter('endTime', $endTime->format('Y-m-d H:i'))
  2345. ->andWhere('l.type = :type')
  2346. ->setParameter('type', $preference->getType())
  2347. ->andWhere('l.duration = :duration')
  2348. ->setParameter('duration', $duration)
  2349. ->getQuery()
  2350. ->getResult();
  2351. if (!$lessons && $preference->getTeacher()->getStatus() == Teacher::STATUS_ACTIVE) {
  2352. $lesson = (new Lesson())
  2353. ->setType($preference->getType())
  2354. ->setStatus(Lesson::STATUS_REGULAR['value'])
  2355. ->setClass($preference->getChild()->getClass())
  2356. ->setDiscipline($preference->getDiscipline())
  2357. ->setTeacher($preference->getTeacher())
  2358. ->setDuration($duration)
  2359. ->setStartTime($startTime)
  2360. ->setEndTime($endTime);
  2361. $lesson->addChild($preference->getChild());
  2362. $this->entityManager->persist($lesson);
  2363. $this->entityManager->flush();
  2364. }
  2365. }
  2366. }
  2367. public function recalculatePricesForFurtherLessons(Guardian $guardian, \Datetime $dateFrom)
  2368. {
  2369. $lessonsQuery = $this->lessonRepository->createQueryBuilder('l');
  2370. $lessons = $lessonsQuery
  2371. ->andWhere(':children member of l.children')
  2372. ->setParameter('children', $guardian->getChildren())
  2373. ->andWhere('l.startTime > :startTime')
  2374. ->setParameter('startTime', $dateFrom)
  2375. ->getQuery()
  2376. ->getResult();
  2377. foreach ($lessons as $lesson) {
  2378. $this->paymentService->editPayment($lesson);
  2379. }
  2380. }
  2381. public function getWeekdayFromNumber(int $day)
  2382. {
  2383. if ($day == 1) {
  2384. return 'Pirmadienis';
  2385. }
  2386. if ($day == 2) {
  2387. return 'Antradienis';
  2388. }
  2389. if ($day == 3) {
  2390. return 'Trečiadienis';
  2391. }
  2392. if ($day == 4) {
  2393. return 'Ketvirtadienis';
  2394. }
  2395. if ($day == 5) {
  2396. return 'Penktadienis';
  2397. }
  2398. if ($day == 6) {
  2399. return 'Šeštadienis';
  2400. }
  2401. if ($day == 7) {
  2402. return 'Sekmadienis';
  2403. } else {
  2404. return "";
  2405. }
  2406. }
  2407. public function getWeekdayEnglishFromNumber(int $day)
  2408. {
  2409. if ($day == 1) {
  2410. return 'monday';
  2411. }
  2412. if ($day == 2) {
  2413. return 'tuesday';
  2414. }
  2415. if ($day == 3) {
  2416. return 'wednesday';
  2417. }
  2418. if ($day == 4) {
  2419. return 'thursday';
  2420. }
  2421. if ($day == 5) {
  2422. return 'friday';
  2423. }
  2424. if ($day == 6) {
  2425. return 'saturday';
  2426. }
  2427. if ($day == 7) {
  2428. return 'sunday';
  2429. } else {
  2430. return "";
  2431. }
  2432. }
  2433. }