Pastebin
Retrouvez, créez et partagez vos snippets en temps réel.
Rechercher un Pastebin
Aucun paste trouvé.
Créer un paste
Pastebin
Blog
yy
public class ServiceEtatIndividuelRecuperationsHeures { private static final String COULEUR_FOND_SEMAINE = "#dbe8f7"; private static final String LIBELLE_RECUP_ORS = "Absence - Récupération dépassement ORS"; private static final String CHEMIN_MODELE_DOCX = "modeles/modele_etat_individuel_recap_heures.docx"; private static final Locale LOCALE_FRANCAISE = Locale.FRENCH; private final EditiqueService serviceEditique; private final EditiqueFeignClient clientEditique; private final EtatIndividuelRecuperationDHeuresSierhService serviceSierhRecuperations; public ServiceEtatIndividuelRecuperationsHeures( EditiqueService serviceEditique, EditiqueFeignClient clientEditique, EtatIndividuelRecuperationDHeuresSierhService serviceSierhRecuperations ) { this.serviceEditique = serviceEditique; this.clientEditique = clientEditique; this.serviceSierhRecuperations = serviceSierhRecuperations; } public byte[] genererEtatIndividuelRecuperationsHeures( IdentifiantCompletAgentSI identifiantCompletAgentSI, String semainesDebutIso, String semainesFinIso ) throws IOException { LocalDate dateDebutPeriode = extraireDateDebutPeriode(semainesDebutIso); LocalDate dateFinPeriode = extraireDateFinPeriode(semainesFinIso); List<LigneRSInformationSemaineRemplacantSIERH> lignesRecuperations = serviceSierhRecuperations.recupererInformationSemaines( identifiantCompletAgentSI, dateDebutPeriode, dateFinPeriode ); Tableau tableauRecapitulatif = construireTableauRecapitulatifHeures( lignesRecuperations, semainesDebutIso, semainesFinIso ); ModeleDocument modele = ModeleDocument.extraireModeleDocument( FichierUtil.recupererFichierDepuisClasspath(CHEMIN_MODELE_DOCX) ); GenerateurDocument generateurDocument = GenerateurDocument.builder() .editiqueClient(clientEditique) .modele(modele) .build(); // TODO : à injecter depuis un service référentiel / SI String libelleAcademie = "Académie de LILLE"; String libelleDsden = "Direction des services départementaux de l'éducation nationale du Nord"; String libelleCirconscription = "0595716T - Circonscription d'inspection du 1er degré de Lille 1 Lille 3 - ASH - Lille"; String libelleEtablissement = "0590174U - Institut de Réhabilitation de la Parole et de l'Audition (I.R.P.A.) de Ronchin - Ronchin"; String libelleZoneRemplacement = libelleEtablissement; String nomPrenomAgent = "KRIKORIAN MARION"; generateurDocument .ajouterTexte("academieEtDSDEN", "Académie de " + libelleAcademie + "\n" + libelleDsden) .ajouterTexte("circonscription", libelleCirconscription) .ajouterTexte("nomEtPrenom", nomPrenomAgent) .ajouterTexte("ecoleDeRattachement", libelleEtablissement) .ajouterTexte("zoneRemplacement", libelleZoneRemplacement) .ajouterTexte("titreRecap", "Etat individuel : Récapitulatif des heures") .ajouterTableau("tableauRecap", tableauRecapitulatif); return serviceEditique.genererDocument(generateurDocument); } // ========================================================= // Construction du tableau // ========================================================= private Tableau construireTableauRecapitulatifHeures( List<LigneRSInformationSemaineRemplacantSIERH> lignesRecuperations, String semaineDebutIso, String semaineFinIso ) { Map<LocalDate, List<LigneRSInformationSemaineRemplacantSIERH>> lignesParJour = lignesRecuperations.stream() .collect(Collectors.groupingBy(LigneRSInformationSemaineRemplacantSIERH::getJourdt)); WeekFields normesSemaineIso = WeekFields.ISO; DateTimeFormatter formatDate = DateTimeFormatter.ofPattern("dd/MM/yyyy"); DateTimeFormatter formatJourSemaine = DateTimeFormatter.ofPattern("EEEE", LOCALE_FRANCAISE); LocalDate dateDebut = convertirSemaineIsoEnLundi(semaineDebutIso, normesSemaineIso); LocalDate dateFin = convertirSemaineIsoEnDimanche(semaineFinIso, normesSemaineIso); Tableau.TableauBuilder constructeurTableau = construireTableauAvecEntete(); int indexLigneTableau = 1; // 0 = entête LocalDate curseurDate = dateDebut; while (!curseurDate.isAfter(dateFin)) { LocalDate debutSemaineCourante = curseurDate.with(normesSemaineIso.dayOfWeek(), 1); LocalDate finSemaineCourante = curseurDate.with(normesSemaineIso.dayOfWeek(), 7); if (finSemaineCourante.isAfter(dateFin)) { finSemaineCourante = dateFin; } int numeroSemaine = debutSemaineCourante.get(normesSemaineIso.weekOfWeekBasedYear()); // Ligne "Semaine X" constructeurTableau .ligne("Semaine " + numeroSemaine, "", "", "", "", "", "", "") .styleCellule(0, creerStyleCellule(9, true, Alignement.GAUCHE, VAlignement.MILIEU, COULEUR_FOND_SEMAINE)); constructeurTableau.fusion(indexLigneTableau, indexLigneTableau, 0, 7); indexLigneTableau++; TotauxSemaine totauxSemaine = new TotauxSemaine(); for (LocalDate jour = debutSemaineCourante; !jour.isAfter(finSemaineCourante); jour = jour.plusDays(1)) { if (jour.getDayOfWeek() == DayOfWeek.SUNDAY) { continue; } List<LigneRSInformationSemaineRemplacantSIERH> lignesDuJour = lignesParJour.getOrDefault(jour, List.of()); String libelleJour = mettreMajusculePremiereLettre(jour.format(formatJourSemaine)); indexLigneTableau = ajouterLigneDemiJour( constructeurTableau, indexLigneTableau, libelleJour, jour, formatDate, "AM", lignesDuJour, true, totauxSemaine ); indexLigneTableau = ajouterLigneDemiJour( constructeurTableau, indexLigneTableau, "", jour, formatDate, "PM", lignesDuJour, false, totauxSemaine ); // Fusion jour + date sur AM/PM constructeurTableau.fusion(indexLigneTableau - 2, indexLigneTableau - 1, 0, 0); constructeurTableau.fusion(indexLigneTableau - 2, indexLigneTableau - 1, 1, 1); } // Ligne total semaine constructeurTableau .ligne( "Total Semaine " + numeroSemaine, "", "", "", "", "", convertirMinutesEnHeures(totauxSemaine.totalMinutesEffectuees), convertirMinutesEnHeures(totauxSemaine.totalMinutesRecuperees) ) .styleCellule(0, creerStyleCellule(9, true, Alignement.GAUCHE, VAlignement.MILIEU, null)) .styleCellule(6, creerStyleCellule(5, true, Alignement.CENTRE, VAlignement.MILIEU, null)) .styleCellule(7, creerStyleCellule(5, true, Alignement.CENTRE, VAlignement.MILIEU, null)); constructeurTableau.fusion(indexLigneTableau, indexLigneTableau, 0, 5); indexLigneTableau++; // Ligne résumé (TODO : calcul réel) constructeurTableau .ligne("Résumé de la semaine " + numeroSemaine + " : 0h00 en dépassement .....", "", "", "", "", "", "", "") .styleCellule(0, creerStyleCellule(9, true, Alignement.GAUCHE, VAlignement.MILIEU, null)); constructeurTableau.fusion(indexLigneTableau, indexLigneTableau, 0, 7); indexLigneTableau++; curseurDate = finSemaineCourante.plusDays(1); } return constructeurTableau.build(); } private Tableau.TableauBuilder construireTableauAvecEntete() { return Tableau.builder(8) .ligneEntete( "Jour", "", "", "Etablissement", "Enseignant remplacé", "Modalité", "Heures\neffectuées", "Heures\nrécupérées" ) .styleCellule(0, creerStyleCellule(6, true, Alignement.CENTRE, VAlignement.MILIEU, null)) .styleCellule(1, CelluleStyle.builder().largeur(7).build()) .styleCellule(2, CelluleStyle.builder().largeur(2).build()) .styleCellule(3, creerStyleCellule(42, true, Alignement.CENTRE, VAlignement.MILIEU, null)) .styleCellule(4, creerStyleCellule(20, true, Alignement.CENTRE, VAlignement.MILIEU, null)) .styleCellule(5, creerStyleCellule(5, true, Alignement.CENTRE, VAlignement.MILIEU, null)) .styleCellule(6, creerStyleCellule(5, true, Alignement.CENTRE, VAlignement.MILIEU, null)) .styleCellule(7, creerStyleCellule(5, true, Alignement.CENTRE, VAlignement.MILIEU, null)) .fusion(0, 0, 0, 2); } private int ajouterLigneDemiJour( Tableau.TableauBuilder constructeurTableau, int indexLigneTableau, String libelleJour, LocalDate date, DateTimeFormatter formatDate, String libelleDemiJour, List<LigneRSInformationSemaineRemplacantSIERH> lignesDuJour, boolean estMatin, TotauxSemaine totauxSemaine ) { LigneRSInformationSemaineRemplacantSIERH ligneRetenue = choisirLignePrioritairePourDemiJour(lignesDuJour, estMatin); String etablissement = ""; String enseignantRemplace = ""; String modalite = ""; String heuresEffectuees = ""; String heuresRecuperees = ""; if (ligneRetenue != null) { int minutes = estMatin ? ligneRetenue.getJouram() : ligneRetenue.getJourpm(); // ✅ PM => jourpm boolean estRecuperation = LIBELLE_RECUP_ORS.equals(ligneRetenue.getUaarne()); etablissement = nettoyerTexte(ligneRetenue.getUaarne()); enseignantRemplace = (nettoyerTexte(ligneRetenue.getAinomu()) + " " + nettoyerTexte(ligneRetenue.getAipren())).trim(); modalite = nettoyerTexte(ligneRetenue.getAfmico()); boolean afficher = ligneRetenue.getRang() != null && !ligneRetenue.getRang().startsWith("3"); String affichageMinutes = afficher ? convertirMinutesEnHeures(minutes) : ""; if (estRecuperation) { totauxSemaine.totalMinutesRecuperees += minutesValides(minutes); heuresRecuperees = affichageMinutes; } else { totauxSemaine.totalMinutesEffectuees += minutesValides(minutes); heuresEffectuees = affichageMinutes; } } constructeurTableau .ligne( libelleJour, libelleJour.isEmpty() ? "" : date.format(formatDate), libelleDemiJour, etablissement, enseignantRemplace, modalite, heuresEffectuees, heuresRecuperees ) .styleCellule(0, creerStyleCellule(6, false, Alignement.GAUCHE, VAlignement.BAS, null)) .styleCellule(1, creerStyleCellule(7, false, Alignement.GAUCHE, VAlignement.BAS, null)) .styleCellule(2, creerStyleCellule(2, false, Alignement.GAUCHE, VAlignement.MILIEU, null)) .styleCellule(3, creerStyleCellule(43, false, Alignement.GAUCHE, VAlignement.MILIEU, null)) .styleCellule(4, creerStyleCellule(20, false, Alignement.GAUCHE, VAlignement.MILIEU, null)) .styleCellule(5, creerStyleCellule(5, false, Alignement.GAUCHE, VAlignement.MILIEU, null)) .styleCellule(6, creerStyleCellule(5, false, Alignement.GAUCHE, VAlignement.MILIEU, null)) .styleCellule(7, creerStyleCellule(5, false, Alignement.GAUCHE, VAlignement.MILIEU, null)); return indexLigneTableau + 1; } // ========================================================= // Sélection / priorité // ========================================================= private LigneRSInformationSemaineRemplacantSIERH choisirLignePrioritairePourDemiJour( List<LigneRSInformationSemaineRemplacantSIERH> lignes, boolean estMatin ) { return lignes.stream() .filter(ligne -> minutesValides(estMatin ? ligne.getJouram() : ligne.getJourpm()) > 0) .min(Comparator.comparingInt(this::calculerPrioriteLigne)) .orElse(null); } private int calculerPrioriteLigne(LigneRSInformationSemaineRemplacantSIERH ligne) { String rang = ligne.getRang(); if ("1".equals(rang)) return 1; if ("2".equals(rang)) return 2; if ("3".equals(rang)) return 3; if (rang != null && rang.startsWith("3")) return 4; return 99; } // ========================================================= // Semaine ISO -> dates // ========================================================= private LocalDate convertirSemaineIsoEnLundi(String semaineIso, WeekFields normesSemaineIso) { String[] parties = semaineIso.split("-W"); int annee = Integer.parseInt(parties[0]); int numeroSemaine = Integer.parseInt(parties[1]); LocalDate base = LocalDate.of(annee, 1, 4); // toujours dans semaine ISO 1 return base.with(normesSemaineIso.weekOfWeekBasedYear(), numeroSemaine) .with(normesSemaineIso.dayOfWeek(), 1); } private LocalDate convertirSemaineIsoEnDimanche(String semaineIso, WeekFields normesSemaineIso) { return convertirSemaineIsoEnLundi(semaineIso, normesSemaineIso).plusDays(6); } private LocalDate extraireDateDebutPeriode(String semainesIso) { WeekFields normesSemaineIso = WeekFields.ISO; return Arrays.stream(semainesIso.split(",")) .map(String::trim) .map(s -> convertirSemaineIsoEnLundi(s, normesSemaineIso)) .min(LocalDate::compareTo) .orElseThrow(); } private LocalDate extraireDateFinPeriode(String semainesIso) { WeekFields normesSemaineIso = WeekFields.ISO; return Arrays.stream(semainesIso.split(",")) .map(String::trim) .map(s -> convertirSemaineIsoEnDimanche(s, normesSemaineIso)) .max(LocalDate::compareTo) .orElseThrow(); } // ========================================================= // Utils // ========================================================= private CelluleStyle creerStyleCellule(int largeur, boolean gras, Alignement alignement, VAlignement alignementVertical, String couleurFond) { return CelluleStyle.builder() .gras(gras) .alignement(alignement) .alignementVertical(alignementVertical) .tailleTexte(7) .largeur(largeur) .couleurFond(couleurFond) .build(); } private String convertirMinutesEnHeures(int minutes) { if (minutes <= 1) { return ""; } int heures = minutes / 60; int minutesRestantes = minutes % 60; return String.format("%dh%02d", heures, minutesRestantes); } private int minutesValides(int minutes) { return minutes > 1 ? minutes : 0; } private String nettoyerTexte(String texte) { return texte == null ? "" : texte.trim(); } private String mettreMajusculePremiereLettre(String texte) { if (texte == null || texte.isBlank()) return ""; return texte.substring(0, 1).toUpperCase(LOCALE_FRANCAISE) + texte.substring(1); } private static final class TotauxSemaine { int totalMinutesEffectuees = 0; int totalMinutesRecuperees = 0; } }
Créé il y a 1 mois.