Ajout des commentaires dans le code
This commit is contained in:
@@ -28,6 +28,16 @@ final class QuotaModel extends BaseModel
|
||||
*/
|
||||
public const REFERENCE_MINUTES = 1607 * 60;
|
||||
|
||||
/**
|
||||
* Crée la ligne de quota annuel d'un agent, proratisée par sa quotité.
|
||||
*
|
||||
* Appelé à la création d'un agent (AgentModel::createWithDefaults()). Le
|
||||
* quota cible est FIGÉ à ce moment-là : modifier ensuite la quotité de
|
||||
* l'agent ne recalcule pas rétroactivement l'année en cours, ce qui
|
||||
* fausserait un suivi déjà entamé.
|
||||
*
|
||||
* @param float $rate Quotité en pourcentage (100 = temps plein).
|
||||
*/
|
||||
public function createForAgent(int $agentId, int $year, float $rate): void
|
||||
{
|
||||
$target = (int) round(self::REFERENCE_MINUTES * ($rate / 100));
|
||||
@@ -53,6 +63,19 @@ final class QuotaModel extends BaseModel
|
||||
*
|
||||
* Exemple : une date de contexte au 15/09/2026 renvoie toujours la période
|
||||
* 01/01/2026 -> 31/12/2026, quelle que soit la date de début du contrat.
|
||||
*
|
||||
* Les minutes VALIDÉES et les minutes en BROUILLON sont comptées
|
||||
* séparément mais s'additionnent toutes deux dans `minutes_affectees` :
|
||||
* un brouillon consomme déjà le quota du point de vue de la planification,
|
||||
* la distinction ne sert qu'à indiquer ce qui est acquis.
|
||||
*
|
||||
* Le filtre `m.compte_dans_quota = TRUE` est le point de bascule métier :
|
||||
* CONGE, AUTRE_ABSENCE et JNT sont ainsi exclus (voir REFERENCE_MINUTES).
|
||||
*
|
||||
* `minutes_restantes` peut être NÉGATIF — c'est un dépassement, signalé en
|
||||
* ALERTE à la validation, jamais bloqué.
|
||||
*
|
||||
* @return array<string, mixed> Période de référence enrichie des compteurs.
|
||||
*/
|
||||
public function forDate(int $agentId, string $contextDate): array
|
||||
{
|
||||
@@ -100,16 +123,33 @@ final class QuotaModel extends BaseModel
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Idem forDate(), avec les libellés lisibles ajoutés par enrich().
|
||||
* C'est cette variante que consomment tous les endpoints JSON.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function forDateForApi(int $agentId, string $contextDate): array
|
||||
{
|
||||
return $this->enrich($this->forDate($agentId, $contextDate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Quota d'une année entière. Le 1er janvier suffit comme point d'entrée,
|
||||
* la période étant de toute façon l'année civile complète.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function annual(int $agentId, int $year): array
|
||||
{
|
||||
return $this->forDate($agentId, sprintf('%04d-01-01', $year));
|
||||
}
|
||||
|
||||
/**
|
||||
* Idem annual(), enrichi des libellés.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function annualForApi(int $agentId, int $year): array
|
||||
{
|
||||
return $this->forDateForApi($agentId, sprintf('%04d-01-01', $year));
|
||||
@@ -118,6 +158,16 @@ final class QuotaModel extends BaseModel
|
||||
/**
|
||||
* Période de référence PTA : toujours l'année civile.
|
||||
* La date de contrat est retournée uniquement à titre informatif.
|
||||
*
|
||||
* Les clés `periode_contractuelle`, `periode_civile` et
|
||||
* `date_contrat_manquante` sont des VESTIGES d'une version où la période
|
||||
* pouvait être ancrée sur la date de contrat. Elles sont figées
|
||||
* (false / true / false) et conservées pour ne pas casser les écrans qui les
|
||||
* lisent encore. Ne pas construire de nouvelle logique dessus.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*
|
||||
* @throws InvalidArgumentException Si la date de contexte est malformée.
|
||||
*/
|
||||
public function referencePeriod(int $agentId, string $contextDate): array
|
||||
{
|
||||
@@ -151,6 +201,16 @@ final class QuotaModel extends BaseModel
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute les versions lisibles des compteurs à un quota brut.
|
||||
*
|
||||
* Les clés en minutes restent présentes : le JavaScript calcule sur les
|
||||
* minutes et n'affiche que les libellés.
|
||||
*
|
||||
* @param array<string, mixed> $quota
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function enrich(array $quota): array
|
||||
{
|
||||
return array_merge($quota, [
|
||||
@@ -162,6 +222,16 @@ final class QuotaModel extends BaseModel
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Met en forme une durée en minutes sous ses trois représentations.
|
||||
*
|
||||
* Gère les valeurs NÉGATIVES (dépassement de quota) : le signe est extrait
|
||||
* avant la division, sans quoi intdiv() et le modulo produiraient un libellé
|
||||
* incohérent du type « -1 h -30 ».
|
||||
*
|
||||
* @return array{minutes: int, heures_decimales: float, libelle: string}
|
||||
* Ex. : 90 → « 1 h 30 » ; -90 → « -1 h 30 ».
|
||||
*/
|
||||
public function formatMinutes(int $minutes): array
|
||||
{
|
||||
$sign = $minutes < 0 ? -1 : 1;
|
||||
@@ -176,6 +246,24 @@ final class QuotaModel extends BaseModel
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrouve la ligne de quota la plus pertinente pour une année donnée.
|
||||
*
|
||||
* Le tri du ORDER BY applique une règle de repli en trois temps :
|
||||
* 1. l'année demandée exactement ;
|
||||
* 2. sinon l'année ANTÉRIEURE la plus proche (la quotité connue la plus
|
||||
* récente reste la meilleure estimation) ;
|
||||
* 3. sinon l'année POSTÉRIEURE la plus proche.
|
||||
*
|
||||
* Sans aucune ligne — agent créé avant la mise en place des quotas — on
|
||||
* retombe sur un temps plein théorique plutôt que sur un quota nul, qui
|
||||
* afficherait un dépassement à la première heure planifiée.
|
||||
*
|
||||
* `quota_source_annee` indique quelle année a réellement servi, pour que
|
||||
* l'interface puisse signaler un quota emprunté à une autre année.
|
||||
*
|
||||
* @return array{quotite_travail: float, quota_reference_minutes: int, quota_cible_minutes: int, quota_source_annee: int}
|
||||
*/
|
||||
private function quotaProfile(int $agentId, int $year): array
|
||||
{
|
||||
$stmt = $this->pdo->prepare(
|
||||
|
||||
Reference in New Issue
Block a user