Distribution.php 29.2 KB
Newer Older
1
2
3
4
5
6
<?php
/**
 * @file
 * Contains \Drupal\query_example\Controller\QueryExampleController.
 */

7

8
9
10
11
12
13
14
15
16
namespace Drupal\epal\Controller;

use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Drupal\Core\Controller\ControllerBase;

use Symfony\Component\HttpFoundation\RedirectResponse;
17
use Drupal\Core\Database\Database;
18
19
20
21
22
use Drupal\Core\Database\Connection;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;

23
24
25
26
27
//use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\TypedData\Plugin\DataType\TimeStamp;

use Drupal\Core\Language\LanguageManagerInterface;

28
29
30
31
32
33
define("SUCCESS", 0);
define("ERROR_DB", -1);
define("NO_CLASS_LIMIT_DOWN", -2);
define("SMALL_CLASS", 1);
define("NON_SMALL_CLASS", 2);

34
35
36
37
38
39
class Distribution extends ControllerBase {

	protected $entity_query;
  protected $entityTypeManager;
  protected $logger;
  protected $connection;
40
41
	protected $language;
	protected $currentuser;
42
43
44

	protected $pendingStudents = array();
	protected $choice_id = 1;
45
	protected $globalCounterId = 1;
46
47
48
49
50

	public function __construct(
		EntityTypeManagerInterface $entityTypeManager,
		QueryFactory $entity_query,
		Connection $connection,
51

52
53
54
55
		LoggerChannelFactoryInterface $loggerChannel)
		{
			$this->entityTypeManager = $entityTypeManager;
			$this->entity_query = $entity_query;
56
			$connection = Database::getConnection();
57
			$this->connection = $connection;
58
59
60
61
			$language =  \Drupal::languageManager()->getCurrentLanguage()->getId();
			$this->language = $language;
			$currentuser = \Drupal::currentUser()->id();
			$this->currentuser = $currentuser;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
			$this->logger = $loggerChannel->get('epal');
    }

	public static function create(ContainerInterface $container)
    {
        return new static(
          $container->get('entity_type.manager'),
          $container->get('entity.query'),
          $container->get('database'),
          $container->get('logger.factory')
      );
    }


	public function createDistribution(Request $request) {

78
79
80
		$numDistributions = 3;
		$sizeOfBlock = 100000;

81
		//POST method is checked
82
83
84
85
		if (!$request->isMethod('POST')) {
			return $this->respondWithStatus([
					"message" => t("Method Not Allowed")
				], Response::HTTP_METHOD_NOT_ALLOWED);
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    }

		//user validation
		$authToken = $request->headers->get('PHP_AUTH_USER');
		$users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
		$user = reset($users);
		if (!$user) {
				return $this->respondWithStatus([
								'message' => t("User not found"),
						], Response::HTTP_FORBIDDEN);
		}

		//user role validation
		$roles = $user->getRoles();
		$validRole = false;
		foreach ($roles as $role)
			if ($role === "ministry") {
				$validRole = true;
				break;
			}
		if (!$validRole) {
				return $this->respondWithStatus([
								'message' => t("User Invalid Role"),
						], Response::HTTP_FORBIDDEN);
		}
111

112
113
114
115
116

		//check where distribution can be done now ($capacityDisabled / $directorViewDisabled settings)
		$capacityDisabled = "0";
		$directorViewDisabled = "0";
		$applicantsResultsDisabled = "0";
117
118
119
120
121
122
123
124
125
126
127
		$config_storage = $this->entityTypeManager->getStorage('epal_config');
		$epalConfigs = $config_storage->loadByProperties(array('id' => 1));
		$epalConfig = reset($epalConfigs);
		if (!$epalConfig) {
			 return $this->respondWithStatus([
							 'message' => t("EpalConfig Enity not found"),
					 ], Response::HTTP_FORBIDDEN);
		}
		else {
			 $capacityDisabled = $epalConfig->lock_school_capacity->getString();
			 $directorViewDisabled = $epalConfig->lock_school_students_view->getString();
128
			 $applicantsResultsDisabled = $epalConfig->lock_results->getString();
129
		}
130
		if ($capacityDisabled === "0" || $directorViewDisabled === "0" || $applicantsResultsDisabled === "0")  {
131
132
133
134
135
136
137
			 return $this->respondWithStatus([
							 'message' => t("capacityDisabled and / or directorViewDisabled settings are false"),
					 ], Response::HTTP_FORBIDDEN);
		}



138

139
140


141
142
143
		$transaction = $this->connection->startTransaction();

		try {
144

145
			//initialize/empty epal_student_class if there are already data in it!
146
147
148
149
			if ($this->initializeResults() === ERROR_DB)
					return $this->respondWithStatus([
							"message" => t("Unexpected Error in initializeResults function")
						], Response::HTTP_INTERNAL_SERVER_ERROR);
150

151
152
			if ( ($limitUp_class = $this->retrieveCapacityLimitUp("1") ) === ERROR_DB)
			//if ($limitUp_class === DB_ERROR)
153
154
155
					return $this->respondWithStatus([
							"message" => t("Unexpected Error in retrieveCapacityLimitUp function")
						], Response::HTTP_INTERNAL_SERVER_ERROR);
156
			//print_r("<br> ΑΝΩΤΑΤΟ ΟΡΙΟ ΜΑΘΗΤΩΝ: " . $limitUp_class);
157

158
159
			while ($this->choice_id <= $numDistributions)	 {

160
161
				//υπολογισμός πλήθους non-finalized αιτήσεων για να καθοριστεί ο αριθμός των fetches που θα κάνουμε με συγκεκριμένο sizeOfBlock
				if ($this->choice_id === 1)	{
162
163
164
					$sCon = $this->connection->select('epal_student', 'eStudent')
																		->fields('eStudent', array('id'));
			 	  $numData = $sCon->countQuery()->execute()->fetchField();
165
					//print_r("<br>numData: " .  $numData);
166
167
168
169
170
171
				}

				$j = 1;
				$num = 1;
				if ($this->choice_id === 1) {
							while ($num <= $numData)	{
172

173
								//print_r("<br>FETCH: " .  $j);
174
175
176
177
178
179
								$sCon = $this->connection->select('epal_student', 'eStudent')
																					->fields('eStudent', array('id', 'name', 'currentclass', 'currentepal', 'points'))
																			    ->condition('eStudent.id', 1+ $sizeOfBlock*($j-1), '>=')
																					->condition('eStudent.id', $j*$sizeOfBlock, '<=');
								$epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);

180
181
182
183
								if ($this->locateStudent($this->choice_id, $epalStudents) === ERROR_DB)
										return $this->respondWithStatus([
												"message" => t("Unexpected Error in locateStudent function")
											], Response::HTTP_INTERNAL_SERVER_ERROR);
184

185
								$num = $num + sizeof($epalStudents);
186
187
188
189
								$j = $j + 1;
							}
						}
				else {
190
191
192
193
194
195
196

								if (sizeof($this->pendingStudents) != 0)	{
									$sCon = $this->connection->select('epal_student', 'eStudent')
																						->fields('eStudent', array('id', 'name', 'currentclass', 'currentepal', 'points'))
																						->condition('eStudent.id', $this->pendingStudents, 'IN');
									$epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);

197
198
199
200
201
									if ($this->locateStudent($this->choice_id, $epalStudents) === ERROR_DB)
											return $this->respondWithStatus([
													"message" => t("Unexpected Error in locateStudent function")
												], Response::HTTP_INTERNAL_SERVER_ERROR);

202
203
204
205
								}
								else {	//αν δεν υπάρχουν εκκρεμότητες, μην συνεχίζεις με άλλο πέρασμα
									break;
								}
206
207
208
209
210
211
						}

				//Για κάθε σχολείο βρες τα τμήματα
				//Για κάθε τμήμα βρες αν χωράνε και διευθέτησε (checkCapacityAndArrange)
				//checkCapacityAndArrange (school_id, class_id, sectorORcourse_id, limitUp, schoolCapacity)

212
				$sCon = $this->connection->select('eepal_school_field_data', 'eSchool')
213
																	->fields('eSchool', array('id', 'capacity_class_a', 'operation_shift'));
214
				$eepalSchools = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
215
216
217

				foreach ($eepalSchools as $eepalSchool)	{

218
219
220
221
						if ($this->checkCapacityAndArrange($eepalSchool->id, "1", "-1", $limitUp_class, $eepalSchool->capacity_class_a) === ERROR_DB)
								return $this->respondWithStatus([
										"message" => t("Unexpected Error in checkCapacityAndArrange function")
									], Response::HTTP_INTERNAL_SERVER_ERROR);
222

223
224
225
226
						$sCon = $this->connection->select('eepal_sectors_in_epal_field_data', 'eSchool')
																			->fields('eSchool', array('epal_id', 'sector_id', 'capacity_class_sector'))
																			->condition('eSchool.epal_id', $eepalSchool->id, '=');
						$eepalSectorsInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
227
						foreach ($eepalSectorsInEpal as $eepalSecInEp)	{
228
229
230
231
							if ($this->checkCapacityAndArrange($eepalSchool->id, "2", $eepalSecInEp->sector_id, $limitUp_class, $eepalSecInEp->capacity_class_sector) === ERROR_DB)
									return $this->respondWithStatus([
											"message" => t("Unexpected Error in checkCapacityAndArrange function")
										], Response::HTTP_INTERNAL_SERVER_ERROR);
232
233
					  }

234
235
236
237
						$sCon = $this->connection->select('eepal_specialties_in_epal_field_data', 'eSchool')
																			->fields('eSchool', array('epal_id', 'specialty_id', 'capacity_class_specialty'))
																			->condition('eSchool.epal_id', $eepalSchool->id, '=');
						$eepalSpecialtiesInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
238
						foreach ($eepalSpecialtiesInEpal as $eepalSpecialInEp)	{
239
240
241
242
243
							//Γ' Λυκείου
							if ($this->checkCapacityAndArrange($eepalSchool->id, "3", $eepalSpecialInEp->specialty_id, $limitUp_class, $eepalSpecialInEp->capacity_class_specialty) === ERROR_DB)
									return $this->respondWithStatus([
											"message" => t("Unexpected Error in checkCapacityAndArrange function")
										], Response::HTTP_INTERNAL_SERVER_ERROR);
244
							//Δ' Λυκείου
245
							if ($eepalSchool->operation_shift === "ΕΣΠΕΡΙΝΟ")	{
246
247
248
249
								if ($this->checkCapacityAndArrange($eepalSchool->id, "4", $eepalSpecialInEp->specialty_id, $limitUp_class, $eepalSpecialInEp->capacity_class_specialty) === ERROR_DB)
										return $this->respondWithStatus([
												"message" => t("Unexpected Error in checkCapacityAndArrange function")
											], Response::HTTP_INTERNAL_SERVER_ERROR);
250
							}
251
252
253
254
255
256
257
258
						}

					} //end for each school/department

					$this->choice_id++;

	  	} //end while

259
260
261
262
263
264
265
266
267
			if ($this->findSmallClasses() === ERROR_DB)	{
					return $this->respondWithStatus([
							"message" => t("Unexpected Error in findSmallClasses function AFTER initial Distribution!")
						], Response::HTTP_INTERNAL_SERVER_ERROR);
						//αν αποτύχει, δεν γίνεται rollback. --> Λύση: διαγρα΄φή των όποιων αποτελεσμάτων
						if ($this->initializeResults() === ERROR_DB)
								return $this->respondWithStatus([
										"message" => t("Unexpected Error in initializeResults function AFTER findSmallClasses call Function")
									], Response::HTTP_INTERNAL_SERVER_ERROR);
268

269
270
271
			}


272

273
274
275
276
277
		}	//end try

		catch (\Exception $e) {
			$this->logger->warning($e->getMessage());
			$transaction->rollback();
278
			return $this->respondWithStatus([
279
280
281
282
					"message" => t("An unexpected problem occured")
				], Response::HTTP_INTERNAL_SERVER_ERROR);
		}

283
284
285
286
		$postData = null;
		if ($content = $request->getContent()) {
				$postData = json_decode($content);
				return $this->respondWithStatus([
287
						'message' => "Distribution has made successfully",
288
289
290
291
292
293
294
				], Response::HTTP_OK);
			}
			else {
				return $this->respondWithStatus([
						'message' => t("post with no data"),
				], Response::HTTP_BAD_REQUEST);
			}
295
296
297
298
299
300
301
302
303

	}


	public function locateStudent($choice_id, &$epalStudents)	{

		$epal_dist_id = -1;
		$specialization_id = -1;

304
		$transaction = $this->connection->startTransaction();
305

306
		try {
307
308

			foreach ($epalStudents as $epalStudent)	{
309
310
				//print_r("<br>ΚΑΤΑΝΟΜΗ ΜΑΘΗΤΩΝ ΝΟ: " . $choice_id);
				//print_r("<br>ΜΑΘΗΤΗΣ: " .  $epalStudent->id);
311
312
313
314
315
316

				$clCon = $this->connection->select('epal_student_epal_chosen', 'epals')
					->fields('epals', array('student_id', 'epal_id', 'choice_no'))
					->condition('epals.student_id', $epalStudent->id , '=')
					->condition('epals.choice_no', $choice_id , '=');
				$epalSchoolsChosen = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ);
317
318
319

				if (sizeof($epalSchoolsChosen) !==  0)	{
					$epalSchoolChos = reset($epalSchoolsChosen);
320
					//print_r(" SCHOOL_ID:" . $epalSchoolChos->epal_id . " STUDENT_ID " . $epalStudent->id);
321
322
323
324
325
326
327
					$epal_dist_id = $epalSchoolChos->epal_id;

					if ($epalStudent->currentclass === "2")	{
						$clCon = $this->connection->select('epal_student_sector_field', 'sectors')
							->fields('sectors', array('student_id', 'sectorfield_id'))
							->condition('sectors.student_id', $epalStudent->id , '=');
						$epalSectorChosen = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ);
328
329
						$epalSecChos = reset($epalSectorChosen);
					}
330
331
					//Δ'Λυκείου - Γ' Λυκείου
					elseif ($epalStudent->currentclass === "3" || $epalStudent->currentclass === "4")	{
332
333
334
335
						$clCon = $this->connection->select('epal_student_course_field', 'courses')
							->fields('courses', array('student_id', 'coursefield_id'))
							->condition('courses.student_id', $epalStudent->id , '=');
						$epalCourseChosen = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ);
336
337
338
						$epalCourChos = reset($epalCourseChosen);
					}

339
340
					if ($epalStudent->currentclass === "2")
						$specialization_id = $epalSecChos->sectorfield_id;
341
342
					//Δ'Λυκείου - Γ' Λυκείου
					elseif ($epalStudent->currentclass === "3" || $epalStudent->currentclass === "4")
343
						$specialization_id = $epalCourChos->coursefield_id;
344
345
346
					else
						$specialization_id = -1;

347
348
349
350
351
352
353
354
355
356
357
358
359
360

					$timestamp = strtotime(date("Y-m-d"));
					$this->connection->insert('epal_student_class')->fields(
						array('id' => $this->globalCounterId++,
							'uuid' => \Drupal::service('uuid')->generate(),
							'langcode' => $this->language,
							'user_id' => $this->currentuser,
							'student_id'=> $epalStudent->id,
							'epal_id'=> $epal_dist_id,
							'currentclass' => $epalStudent->currentclass,
							'currentepal' => $epalStudent->currentepal,
							'specialization_id' => $specialization_id,
							'points' => $epalStudent->points,
							'distribution_id' => $choice_id,
361
							'finalized' => 1,
362
363
364
365
							'status' => 1,
							'created' => $timestamp,
							'changed' => $timestamp,)
					)->execute();
366
367
368
369
370
371
372
373
374

			} //end if

		}	//foreach

	}

	catch (\Exception $e) {
		$this->logger->warning($e->getMessage());
375
		$transaction->rollback();
376
		return ERROR_DB;
377
378
	}

379
	return SUCCESS;
380
381
382
383
384
385

	}


 public function retrieveCapacityLimitUp($className) {

386
387
388
389
390
391
392
393
394
395
396
397
	 $transaction = $this->connection->startTransaction();

	 try {
		 $clCon = $this->connection->select('epal_class_limits', 'classLimits')
			 ->fields('classLimits', array('limit_up'))
			 ->condition('classLimits.name', $className, '=');
		 $results = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ);
		 $row = reset($results);
 	}
	catch (\Exception $e) {
		$this->logger->warning($e->getMessage());
		$transaction->rollback();
398
		return ERROR_DB;
399
400
401
	}

	return $row->limit_up;
402
403
 }

404
405
406
407
408
409
410
411

public function checkCapacityAndArrange($epalId, $classId, $secCourId, $limitup, $capacity)	{

		if (!isset($capacity))	{
			//print_r("<br> ΜΠΗΚΑ!!! ");
			//print_r("<br> ΣΧΟΛΕΙΟ: " .  $epalId . " ΤΑΞΗ: "  . $classId . " ΤΟΜΕΑΣ/ΕΙΔΙΚΟΤΗΤΑ: " . $secCourId .  " ΧΩΡΗΤΙΚΟΤΗΤΑ: " . $capacity);
		 	$capacity = 0;
		}
412

413
414
415
416
417
418
419
420
421
422
423
424
425
		$transaction = $this->connection->startTransaction();

		try {

			$clCon = $this->connection->select('epal_student_class', 'studentClass')
				->fields('studentClass', array('epal_id', 'student_id', 'points', 'currentepal', 'currentclass', 'specialization_id'))
				->condition('studentClass.epal_id', $epalId, '=')
				->condition('studentClass.currentclass', $classId, '=')
				->condition('studentClass.specialization_id', $secCourId, '=');
			$epalStudentClass = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ);

			$limit = $limitup * $capacity;
			if (sizeof($epalStudentClass) > $limit)	{
426
				//print_r("<br>ΥΠΕΡΧΕΙΛΙΣΗ!");
427
428

				//foreach ($epalStudentClass as $epalStudCl)	{
429
430
					//Υπολογισμός μορίων του μαθητή και (πιθανή) αποθήκευσή τους
					//ΣΗΜΕΙΩΣΗ: Ο υπoλογισμός γίνεται στο front-end
431
				//}
432
				$this->makeSelectionOfStudents($epalStudentClass,$limit);
433
			}
434
435
436
437
438
439
			else { //αφαίρεσε όσους μαθητές βρίσκονται στον πίνακα εκκρεμοτήτων
				foreach ($epalStudentClass as $epalStudCl) {
					if ($this->choice_id !== 1)
						////διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί)
						$this->removeFromPendingStudents($epalStudCl->student_id);
				}
440
441
			}

442
	}	//end try
443

444
445
446
	catch (\Exception $e) {
		$this->logger->warning($e->getMessage());
		$transaction->rollback();
447
		return ERROR_DB;
448
449
	}

450
	return SUCCESS;
451
452
453
454
455
456
457
458
459
460
461

	}


	public function removeFromPendingStudents($val)	{
		if(($key = array_search($val, $this->pendingStudents)) !== false) {
		   unset($this->pendingStudents[$key]);
		}
		//$this->pendingStudents = array_diff($this->pendingStudents, array($val));
	}

462
	public function makeSelectionOfStudents_VERSION_WITH_POINTS(&$students, $limit)	{
463
464
465
466
467
		//συνάρτηση επιλογής μαθητών σε περίπτωση υπερχείλισης
		// (1) έχουν απόλυτη προτεραιότητα όσοι ήδη φοιτούσαν στο σχολείο (σε περίπτωση που φοιτούσαν περισσότεροι από την χωρητικότητα, τους δεχόμαστε όλους)
		// (2) αν απομένουν κενές θέσεις, επέλεξε από τους εναπομείναντες μαθητές αυτούς με τα περισσότερα μόρια. Σε περίπτωση ισοβαθμίας δεχόμαστε όλους όσους ισοβαθμούν.

		foreach($students as $student)	{
468
			$student->student_id;
469
			//print_r("<br>STUDENT_ID:" . $student->student_id);
470
471
472
473
474
		}

		//εύρεση αριθμού μαθητών που ήδη φοιτούσαν στο σχολείο
		$cnt = 0;
		foreach($students as $student)	{
475
			if ($student->currentepal === $student->epal_id) {
476
477
478
				$cnt++;
				if ($this->choice_id !== 1)
					////διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί)
479
					$this->removeFromPendingStudents($student->student_id);
480
481
			}
		}
482
		//print_r("<br>#ΕΓΓΡΑΦΩΝ ΠΟΥ ΟΙ ΜΑΘΗΤΕΣ ΦΟΙΤΟΥΣΑΝ ΗΔΗ:" . $cnt);
483
484

		$newlimit = $limit - $cnt;
485
486
		//print_r("<br>ΑΝΩΤΑΤΟ ΟΡΙΟ ΜΑΘΗΤΩΝ:" . $limit);
		//print_r("<br>#ΜΑΘΗΤΩΝ ΓΙΑ ΝΑ ΕΠΙΛΕΓΟΥΝ ΜΕ ΜΟΡΙΑ:" . $newlimit);
487
488
489

		$points_arr = [];
		foreach($students as $student)	{
490
491
			if ($student->currentepal !== $student->epal_id)
				$points_arr[] = $student->points;
492
		}
493

494
		rsort($points_arr);
495
496
		//for ($i=0; $i < sizeof($points_arr); $i++)
			//print_r("<br>ΜΟΡΙΑ ΜΕΤΑ ΤΗΝ ΤΑΞΙΝΟΜΙΣΗ: " . $points_arr[$i]);
497

498
		//print_r("<br>ΟΡΙΟ ΜΟΡΙΩΝ: " . $points_arr[$newlimit-1]);
499

500
501
		$transaction = $this->connection->startTransaction();

502
		foreach($students as $student)	{
503
504
			if ($student->currentepal !== $student->epal_id)	{
				if ($student->points < $points_arr[$newlimit-1]) {
505
					//print_r("<br>ΣΕ ΕΚΚΡΕΜΟΤΗΤΑ - ΔΙΑΓΡΑΦΗ: " . $student->student_id);
506
					//βάλε τον μαθητή στον πίνακα εκκρεμοτήτων και διέγραψέ τον από τον προσωρινό πίνακα αποτελεσμάτων
507
508
509
510
511
512
513
514
515
516
517
518
519
520
					array_push($this->pendingStudents, $student->student_id);
					try {
						$this->connection->delete('epal_student_class')
													->condition('student_id', $student->student_id)
													->execute();
					}
					catch (\Exception $e) {
						$this->logger->warning($e->getMessage());
						$transaction->rollback();
						return $this->respondWithStatus([
									"message" => t("An unexpected problem occured during DELETE proccess in makeSelectionOfStudents Method of Distribution")
								], Response::HTTP_INTERNAL_SERVER_ERROR);
					}

521
522
523
524
				}
				else {
					if ($this->choice_id !== 1)
						//διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί)
525
						$this->removeFromPendingStudents($student->student_id);
526
527
528
529
530
531
532
533
534
				}
			}
		}

		return $this->respondWithStatus([
				"message" => t("makeSelectionOfStudents Method of Distribution has made successfully")
			], Response::HTTP_OK);
	}

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574


	public function makeSelectionOfStudents(&$students, $limit)	{
		//συνάρτηση επιλογής μαθητών σε περίπτωση υπερχείλισης
		// (1) έχουν απόλυτη προτεραιότητα όσοι ήδη φοιτούσαν στο σχολείο (σε περίπτωση που φοιτούσαν περισσότεροι από την χωρητικότητα, τους δεχόμαστε όλους)
		// (2) αν απομένουν κενές θέσεις,...τοποθέτησε και όλους τους άλλους!!.

		//εύρεση αριθμού μαθητών που ήδη φοιτούσαν στο σχολείο
		$cnt = 0;
		foreach($students as $student)	{
			if ($student->currentepal === $student->epal_id) {
				$cnt++;
				if ($this->choice_id !== 1)
					//διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί)
					//Κάτι τέτοιο δεν είναι δυνατό πια! (έκδοση χωρίς μόρια..)
					$this->removeFromPendingStudents($student->student_id);
			}
		}
		//print_r("<br>#ΕΓΓΡΑΦΩΝ ΠΟΥ ΟΙ ΜΑΘΗΤΕΣ ΦΟΙΤΟΥΣΑΝ ΗΔΗ:" . $cnt);

		$newlimit = $limit - $cnt;
		//print_r("<br>ΑΝΩΤΑΤΟ ΟΡΙΟ ΜΑΘΗΤΩΝ:" . $limit);

		$transaction = $this->connection->startTransaction();

		//Αν δεν απέμειναν θέσεις (δηλαδή αν η χωρητικότητα είναι μικρότερη ή ίση από το πλήθος μαθητών που ήδη φοιτούν στο σχολείο)
		//τότε διέγραψέ τους από τον προσωρινό πίνακα αποτελεσμάτων και βάλε τους στον στον πίνακα εκκρεμοτήτων
		if ($newlimit <= 0) {
			foreach($students as $student)	{
				if ($student->currentepal !== $student->epal_id)	{
						//print_r("<br>ΣΕ ΕΚΚΡΕΜΟΤΗΤΑ - ΔΙΑΓΡΑΦΗ: " . $student->student_id);
						array_push($this->pendingStudents, $student->student_id);
						try {
							$this->connection->delete('epal_student_class')
														->condition('student_id', $student->student_id)
														->execute();
						}
						catch (\Exception $e) {
							$this->logger->warning($e->getMessage());
							$transaction->rollback();
575
							return ERROR_DB;
576
577
578
579
580
						}
					} //end if currentepal
			 }	//end foreach
		}	//endif newlimit

581
		return SUCCESS;
582
583
584
585
586
587
588
589
590

	}	//end function







591
592
593
594
595
596
597
598
599
600
601
602
	public function calculatePoints()	{

			return rand(0,20);

	}

	private function respondWithStatus($arr, $s) {
				$res = new JsonResponse($arr);
				$res->setStatusCode($s);
				return $res;
		}

603
	private function initializeResults() {
604
605
606
607
608
609
610

			//initialize/empty epal_student_class if there are already data in it!
			try  {
				$this->connection->delete('epal_student_class')->execute();
			}
			catch (\Exception $e) {
				$this->logger->warning($e->getMessage());
611
				return ERROR_DB;
612
			}
613
			return SUCCESS;
614
615
616
617
618
		}



	private function findSmallClasses()	{
619

620
621
622
623
		//Για κάθε σχολείο βρες τα ολιγομελή τμήματα
		$sCon = $this->connection->select('eepal_school_field_data', 'eSchool')
															->fields('eSchool', array('id', 'metathesis_region','operation_shift'));
		$eepalSchools = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
624

625
		foreach ($eepalSchools as $eepalSchool)	{
626

627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
				//isSmallClass (school_id, class_id, sectorORcourse_id, school_category_metathesis)

				// Α' τάξη
				if ($this->isSmallClass($eepalSchool->id, "1", "-1", $eepalSchool->metathesis_region) === SMALL_CLASS)	{
					//print_r("<br> ΚΛΗΣΗ markStudentsInSmallClass: SCHOOL_ID: " . $eepalSchool->id . " CLASSID: " . "1 " . "SECTOR/COURSE ID: " . "-1 ");
					if ($this->markStudentsInSmallClass($eepalSchool->id, "1", "-1") === ERROR_DB )
						return ERROR_DB;
				}

				//print_r("<br>");


				// Β' τάξη
				$sCon = $this->connection->select('eepal_sectors_in_epal_field_data', 'eSchool')
																	->fields('eSchool', array('epal_id', 'sector_id'))
																	->condition('eSchool.epal_id', $eepalSchool->id, '=');
				$eepalSectorsInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
				foreach ($eepalSectorsInEpal as $eepalSecInEp)	{
					if ($this->isSmallClass($eepalSchool->id, "2", $eepalSecInEp->sector_id, $eepalSchool->metathesis_region) === SMALL_CLASS)	{
						//print_r("<br> ΚΛΗΣΗ markStudentsInSmallClass: SCHOOL_ID: " . $eepalSchool->id . " CLASSID: " . "2 " . "SECTOR/COURSE ID: " . $eepalSecInEp->sector_id);
						if ($this->markStudentsInSmallClass($eepalSchool->id, "2", $eepalSecInEp->sector_id) === ERROR_DB )
							return ERROR_DB;
					}
					//print_r("<br>");
				}

				// Γ' τάξη
				$sCon = $this->connection->select('eepal_specialties_in_epal_field_data', 'eSchool')
																	->fields('eSchool', array('epal_id', 'specialty_id'))
																	->condition('eSchool.epal_id', $eepalSchool->id, '=');
				$eepalSpecialtiesInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
				foreach ($eepalSpecialtiesInEpal as $eepalSpecialInEp)	{
					if ($this->isSmallClass($eepalSchool->id, "3", $eepalSpecialInEp->specialty_id, $eepalSchool->metathesis_region) === SMALL_CLASS)	{
						//print_r("<br> ΚΛΗΣΗ markStudentsInSmallClass: SCHOOL_ID: " . $eepalSchool->id . " CLASSID: " . "3 " . "SECTOR/COURSE ID: " . $eepalSpecialInEp->specialty_id);
						if ($this->markStudentsInSmallClass($eepalSchool->id, "3", $eepalSpecialInEp->specialty_id) === ERROR_DB )
							return ERROR_DB;
					}
					//print_r("<br>");
				}

				// Δ' τάξη
				if ($eepalSchool->operation_shift === "ΕΣΠΕΡΙΝΟ")	{
					$sCon = $this->connection->select('eepal_specialties_in_epal_field_data', 'eSchool')
																		->fields('eSchool', array('epal_id', 'specialty_id'))
																		->condition('eSchool.epal_id', $eepalSchool->id, '=');
					$eepalSpecialtiesInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
					foreach ($eepalSpecialtiesInEpal as $eepalSpecialInEp)	{
						if ($this->isSmallClass($eepalSchool->id, "4", $eepalSpecialInEp->specialty_id, $eepalSchool->metathesis_region) === SMALL_CLASS)	{
							//print_r("<br> ΚΛΗΣΗ markStudentsInSmallClass: SCHOOL_ID: " . $eepalSchool->id . " CLASSID: " . "4 " . "SECTOR/COURSE ID: " . $eepalSpecialInEp->specialty_id);
							if ($this->markStudentsInSmallClass($eepalSchool->id, "4", $eepalSpecialInEp->specialty_id) === ERROR_DB )
								return ERROR_DB;
						}
						//print_r("<br>");
					}
				}	//end if ΕΣΠΕΡΙΝΟ



			} //end for each school/department

687
688
			return SUCCESS;

689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
	}	//end function


	private function isSmallClass($schoolId, $classId, $sectorOrcourseId, $regionId)	{

		//print_r("<br> ΚΛΗΣΗ isSmallClass: SCHOOL_ID: " . $schoolId . " CLASSID: " . $classId . "SECTOR/COURSE ID: " . $sectorOrcourseId . "ΠΕΡΙΟΧΗ ΜΕΤΑΘΕΣΗΣ: " . $regionId);

		$limitDown = $this->retrieveLimitDown($classId, $regionId);
		//print_r("<br> ΚΑΤΩΤΑΤΟ ΟΡΙΟ ΜΑΘΗΤΩΝ: " . $limitDown);

		if ($limitDown === NO_CLASS_LIMIT_DOWN)
			return NO_CLASS_LIMIT_DOWN;
		else if ($limitDown === ERROR_DB)
			return ERROR_DB;

		$numStudents = $this->countStudents($schoolId, $classId, $sectorOrcourseId);
		//print_r("<br> ΑΡΙΘΜΟΣ ΜΑΘΗΤΩΝ: " . $numStudents);

		if ($numStudents === ERROR_DB)
			return ERROR_DB;

		//Αν $numStudents == 0, γύρισε fasle, ώστε να μη γίνει περιττή κλήση στην markStudentsInSmallClass
		if ( ($numStudents < $limitDown) && ($numStudents > 0) )
			return SMALL_CLASS;
		else
			return NON_SMALL_CLASS;

	}

	private function retrieveLimitDown($classId, $regionId)	{

		try {
			$sCon = $this->connection->select('epal_class_limits', 'eClassLimit')
																->fields('eClassLimit', array('limit_down'))
																->condition('eClassLimit.name', $classId, '=')
																->condition('eClassLimit.category', $regionId, '=');
			$classLimits = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
			if (sizeof($classLimits) === 1)	{
				$classLimit = reset($classLimits);
				return $classLimit->limit_down;
			}
			else {
				return NO_CLASS_LIMIT_DOWN;
			}
		}	//end try
		catch (\Exception $e) {
			$this->logger->warning($e->getMessage());
			return ERROR_DB;
		}

	}	//end function

	private function countStudents($schoolId, $classId, $sectorOrcourseId)	{

		try {
			$sCon = $this->connection->select('epal_student_class', 'eStudent')
																->fields('eStudent', array('id'))
																->condition('eStudent.epal_id', $schoolId , '=')
																->condition('eStudent.currentclass', $classId , '=')
																->condition('eStudent.specialization_id', $sectorOrcourseId , '=');
			return $sCon->countQuery()->execute()->fetchField();
		}
		catch (\Exception $e) {
			$this->logger->warning($e->getMessage());
			return ERROR_DB;
754
755
		}

756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
	}

	private function markStudentsInSmallClass($schoolId, $classId, $sectorOrcourseId)	{

		try  {
			$query = $this->connection->update('epal_student_class');
			$query->fields([
				'finalized' => 0,
			]);
			$query->condition('epal_id', $schoolId);
			$query->condition('currentclass', $classId);
			if ($sectorOrcourseId !== "-1")
				$query->condition('specialization_id', $sectorOrcourseId);
			$query->execute();
		}
		catch (\Exception $e) {
			$this->logger->warning($e->getMessage());
			return ERROR_DB;
		}
		return SUCCESS;

	}

779
780
781



782
}