132 lines
4.4 KiB
PHP
132 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Models;
|
|
|
|
use DateTimeImmutable;
|
|
use PDO;
|
|
|
|
final class VacationModel extends BaseModel
|
|
{
|
|
public function all(?string $schoolYear = null): array
|
|
{
|
|
$sql = "SELECT id_periode, libelle, date_debut, date_fin, annee_scolaire,
|
|
academie, zone, source, date_creation
|
|
FROM periode_vacance
|
|
WHERE actif = TRUE";
|
|
$params = [];
|
|
|
|
if ($schoolYear !== null && $schoolYear !== '') {
|
|
$sql .= ' AND annee_scolaire = :annee_scolaire';
|
|
$params['annee_scolaire'] = $schoolYear;
|
|
}
|
|
|
|
$sql .= ' ORDER BY date_debut, libelle';
|
|
$stmt = $this->pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
public function saveMany(array $periods): int
|
|
{
|
|
if ($periods === []) {
|
|
return 0;
|
|
}
|
|
|
|
$sql = "INSERT INTO periode_vacance
|
|
(libelle, date_debut, date_fin, annee_scolaire, academie, zone, source, actif)
|
|
VALUES
|
|
(:libelle, :date_debut, :date_fin, :annee_scolaire, :academie, :zone, :source, TRUE)
|
|
ON DUPLICATE KEY UPDATE
|
|
libelle = VALUES(libelle),
|
|
zone = VALUES(zone),
|
|
source = VALUES(source),
|
|
actif = TRUE";
|
|
$stmt = $this->pdo->prepare($sql);
|
|
|
|
$this->pdo->beginTransaction();
|
|
try {
|
|
foreach ($periods as $period) {
|
|
$stmt->execute([
|
|
'libelle' => $period['libelle'],
|
|
'date_debut' => $period['date_debut'],
|
|
'date_fin' => $period['date_fin'],
|
|
'annee_scolaire' => $period['annee_scolaire'],
|
|
'academie' => $period['academie'],
|
|
'zone' => $period['zone'],
|
|
'source' => $period['source'],
|
|
]);
|
|
}
|
|
$this->pdo->commit();
|
|
} catch (\Throwable $e) {
|
|
if ($this->pdo->inTransaction()) {
|
|
$this->pdo->rollBack();
|
|
}
|
|
throw $e;
|
|
}
|
|
|
|
return count($periods);
|
|
}
|
|
|
|
public function delete(int $id): bool
|
|
{
|
|
$stmt = $this->pdo->prepare('DELETE FROM periode_vacance WHERE id_periode = :id');
|
|
$stmt->execute(['id' => $id]);
|
|
return $stmt->rowCount() > 0;
|
|
}
|
|
|
|
public function periodsBetween(string $startDate, string $endDate): array
|
|
{
|
|
$stmt = $this->pdo->prepare(
|
|
"SELECT id_periode, libelle, date_debut, date_fin, annee_scolaire, academie, zone, source
|
|
FROM periode_vacance
|
|
WHERE actif = TRUE
|
|
AND date_debut <= :date_fin
|
|
AND date_fin >= :date_debut
|
|
ORDER BY date_debut"
|
|
);
|
|
$stmt->execute([
|
|
'date_debut' => $startDate,
|
|
'date_fin' => $endDate,
|
|
]);
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
/**
|
|
* Retourne le type de période pour les cinq jours ouvrés d'une semaine ISO.
|
|
* Une date comprise dans une période de vacances confirmée est EXTRASCOLAIRE,
|
|
* sinon elle est PERISCOLAIRE.
|
|
*/
|
|
public function typesForIsoWeek(int $year, int $week): array
|
|
{
|
|
$monday = (new DateTimeImmutable())->setISODate($year, $week, 1)->setTime(0, 0);
|
|
$friday = $monday->modify('+4 days');
|
|
$periods = $this->periodsBetween($monday->format('Y-m-d'), $friday->format('Y-m-d'));
|
|
$days = [];
|
|
|
|
for ($offset = 0; $offset < 5; $offset++) {
|
|
$date = $monday->modify('+' . $offset . ' days')->format('Y-m-d');
|
|
$matchingPeriod = null;
|
|
foreach ($periods as $period) {
|
|
if ($date >= $period['date_debut'] && $date <= $period['date_fin']) {
|
|
$matchingPeriod = $period;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$days[] = [
|
|
'date' => $date,
|
|
'type_affectation' => $matchingPeriod ? 'EXTRASCOLAIRE' : 'PERISCOLAIRE',
|
|
'vacances' => $matchingPeriod ? [
|
|
'id_periode' => (int) $matchingPeriod['id_periode'],
|
|
'libelle' => (string) $matchingPeriod['libelle'],
|
|
'annee_scolaire' => (string) $matchingPeriod['annee_scolaire'],
|
|
] : null,
|
|
];
|
|
}
|
|
|
|
return $days;
|
|
}
|
|
}
|