Ajout des commentaires dans le code
This commit is contained in:
@@ -10,6 +10,13 @@ use DateTimeZone;
|
||||
|
||||
/**
|
||||
* Génère un bilan annuel synthétique du temps d'un agent, ventilé par motif.
|
||||
*
|
||||
* Complément du contrat horaire : là où celui-ci fixe le volume DÛ, ce bilan
|
||||
* montre le volume RÉELLEMENT planifié et sa ventilation. A4 portrait également.
|
||||
*
|
||||
* La ventilation s'appuie sur App\Core\MotifCategories, partagé avec l'écran et
|
||||
* les autres PDF : tous les motifs de travail effectif alimentent une seule
|
||||
* ligne « Heures travaillées », le détail par motif figurant en dessous.
|
||||
*/
|
||||
final class AgentTimeSummaryPdfService
|
||||
{
|
||||
@@ -17,6 +24,16 @@ final class AgentTimeSummaryPdfService
|
||||
private const PAGE_HEIGHT = 841.89;
|
||||
private const MARGIN = 42.0;
|
||||
|
||||
/**
|
||||
* Assemble le bilan d'heures annuel.
|
||||
*
|
||||
* @param array<string, mixed> $agent
|
||||
* @param array<string, mixed> $quota Quota enrichi (forDateForApi).
|
||||
* @param array<int, array<string, mixed>> $rows Cumuls par motif issus de
|
||||
* AgentModel::timeSummaryForRange().
|
||||
*
|
||||
* @return string Octets du PDF.
|
||||
*/
|
||||
public function annualSummary(array $agent, array $quota, array $rows): string
|
||||
{
|
||||
$pdf = new SimplePdf(self::PAGE_WIDTH, self::PAGE_HEIGHT);
|
||||
@@ -33,6 +50,7 @@ final class AgentTimeSummaryPdfService
|
||||
return $pdf->output();
|
||||
}
|
||||
|
||||
/** Titre, période couverte et date d'édition. */
|
||||
private function drawHeader(SimplePdf $pdf, array $agent, string $periodLabel, DateTimeImmutable $generatedAt): void
|
||||
{
|
||||
$pdf->text(self::MARGIN, 34, 'PTA', 10, true);
|
||||
@@ -42,6 +60,7 @@ final class AgentTimeSummaryPdfService
|
||||
$pdf->line(self::MARGIN, 94, self::PAGE_WIDTH - self::MARGIN, 94, 0.72);
|
||||
}
|
||||
|
||||
/** Bloc d'identité de l'agent. */
|
||||
private function drawIdentity(SimplePdf $pdf, array $agent): void
|
||||
{
|
||||
$x = self::MARGIN;
|
||||
@@ -58,6 +77,10 @@ final class AgentTimeSummaryPdfService
|
||||
$pdf->text($x + 270, $y + 73, 'Lieu principal : ' . (($agent['structure_principale_nom'] ?? '') ?: 'Non renseigné'), 9.2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tableau de ventilation : une ligne par catégorie, chacune avec sa couleur,
|
||||
* puis le détail des motifs de travail sous la ligne « Heures travaillées ».
|
||||
*/
|
||||
private function drawBreakdown(SimplePdf $pdf, array $totals): void
|
||||
{
|
||||
$x = self::MARGIN;
|
||||
@@ -109,6 +132,14 @@ final class AgentTimeSummaryPdfService
|
||||
* @param array<string, int> $detail
|
||||
* @return string[]
|
||||
*/
|
||||
/**
|
||||
* Met en forme le détail des motifs de travail pour tenir dans la largeur
|
||||
* disponible.
|
||||
*
|
||||
* @param array<string, int> $detail Minutes indexées par libellé de motif.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function detailLines(SimplePdf $pdf, array $detail, float $width): array
|
||||
{
|
||||
arsort($detail);
|
||||
@@ -143,6 +174,10 @@ final class AgentTimeSummaryPdfService
|
||||
return $pdf->wrap($truncated ? $text . ' …' : $text, $width, 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bloc de conclusion : quota cible, temps décompté, et écart.
|
||||
* C'est la seule partie du document qui confronte le réalisé à l'attendu.
|
||||
*/
|
||||
private function drawResult(SimplePdf $pdf, array $quota, array $totals): void
|
||||
{
|
||||
// Le décompte suit le drapeau compte_dans_quota du motif, comme QuotaModel :
|
||||
@@ -182,6 +217,7 @@ final class AgentTimeSummaryPdfService
|
||||
}
|
||||
}
|
||||
|
||||
/** Pied de page : origine du document, matricule, horodatage. */
|
||||
private function drawFooter(SimplePdf $pdf, array $agent, DateTimeImmutable $generatedAt): void
|
||||
{
|
||||
$pdf->text(
|
||||
@@ -197,6 +233,15 @@ final class AgentTimeSummaryPdfService
|
||||
* (ALP matin, ALP soir, restauration, mercredi périscolaire, extrascolaire,
|
||||
* préparations, ménage de fond…) alimentent la ligne « Heures travaillées », et pas
|
||||
* seulement le motif générique TRAVAIL.
|
||||
*
|
||||
* Le total « DECOMPTE » est calculé indépendamment des catégories, sur le
|
||||
* seul drapeau `compte_dans_quota` : c'est lui qui se compare au quota
|
||||
* cible, et il ne se déduit pas de la somme des catégories.
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $rows
|
||||
*
|
||||
* @return array<string, mixed> Une clé par catégorie, plus « DECOMPTE » et
|
||||
* « DETAIL_TRAVAIL » (minutes par libellé de motif).
|
||||
*/
|
||||
private function normalizeTotals(array $rows): array
|
||||
{
|
||||
@@ -230,7 +275,11 @@ final class AgentTimeSummaryPdfService
|
||||
return $totals;
|
||||
}
|
||||
|
||||
/** @return array{accent:string} */
|
||||
/**
|
||||
* Couleur d'accent d'une catégorie, alignée sur celle des PDF de planning.
|
||||
*
|
||||
* @return array{accent:string}
|
||||
*/
|
||||
private function palette(string $code): array
|
||||
{
|
||||
return match (strtoupper($code)) {
|
||||
@@ -242,6 +291,7 @@ final class AgentTimeSummaryPdfService
|
||||
};
|
||||
}
|
||||
|
||||
/** 450 → « 7 h 30 ». Gère les valeurs négatives (écart de quota). */
|
||||
private function minutesLabel(int $minutes): string
|
||||
{
|
||||
$sign = $minutes < 0 ? '-' : '';
|
||||
|
||||
Reference in New Issue
Block a user