*/
package org.lilie.services.eliot.absences.statistiques.periode
+import org.lilie.services.eliot.absences.PreferencesEtablissementAbsences
import org.lilie.services.eliot.applications.absences.BilanService
import org.lilie.services.eliot.absences.statistiques.commons.StatsAbsencesParPeriode
import org.lilie.services.eliot.applications.absences.BilanAbsencesParPersonneInfo
*/
class StatsPeriodesService extends BilanService {
- StatsAbsencesParPeriode calculeStatsPeriodesAbsences(FicheEleveAbsencesReferentiel ficheEleveAbsencesReferentiel,
- BasicCriteresRecherche basicCriteresRecherche) {
-
- BilanAbsencesParPersonneInfo absencesDatas = findAbsencesDatas(basicCriteresRecherche)
+ StatsAbsencesParPeriode calculeStatsPeriodesAbsences(
+ FicheEleveAbsencesReferentiel ficheEleveAbsencesReferentiel,
+ BasicCriteresRecherche basicCriteresRecherche) {
StatsPeriodes statsPeriodes = new StatsPeriodes(
periodes: ficheEleveAbsencesReferentiel.periodes
ficheEleveAbsencesReferentiel.eleve
)
+ return calculeStatsPeriodesAbsences(
+ basicCriteresRecherche,
+ statsPeriodes,
+ ficheEleveAbsencesReferentiel.preferencesEtablissementAbsences
+ )
+ }
+
+ StatsAbsencesParPeriode calculeStatsPeriodesAbsences(
+ BasicCriteresRecherche criteres,
+ StatsAbsencesParPeriode stats,
+ PreferencesEtablissementAbsences pref
+ ) {
+
+ BilanAbsencesParPersonneInfo absencesDatas = findAbsencesDatas(criteres)
+
return calculeCountAbsences(
absencesDatas,
- ficheEleveAbsencesReferentiel.preferencesEtablissementAbsences,
- statsPeriodes,
+ pref,
+ stats,
NiveauDetail.ELEVE
)
}
log.info("Gestion paramètre complémentaire")
- if (options) {
+ if (options != null) {
return affecteParametre(
templateDocument,
import org.lilie.services.eliot.notes.notes.NoteTextuelleService
import grails.converters.JSON
import org.lilie.services.eliot.ExceptionHandler
+import org.lilie.services.eliot.impression.donnees.DonneesOptions
/**
* classe abstraite pour définir les controlleurs de note
List<BreadCrumbsItemInfo> breadCrumbsInfo = []
Etablissement etablissementCourant =
- (Etablissement) getSecuriteSession().etablissementCourant
+ (Etablissement) getSecuriteSession().etablissementCourant
BreadCrumbsItemInfo breadCrumbsItemInfoEnTete = new BreadCrumbsItemInfo(
codeLabel: 'notes.breadCrumbs.Etablissement',
protected Boolean isBulletinsPublies(Periode periode) {
if (
- securiteSession.hasFonctionIn(
- NotesFonction.ENSEIGNANT_ASSIMILE + NotesFonction.DIRECTION_ASSIMILE,
- etablissementCourant().id
- )
+ securiteSession.hasFonctionIn(
+ NotesFonction.ENSEIGNANT_ASSIMILE + NotesFonction.DIRECTION_ASSIMILE,
+ etablissementCourant().id
+ )
) {
return true
}
)
}
+ /**
+ * Cette fonction permet d'imprimer un document au format PDF
+ * à partir de données passée en paramètre
+ */
+ protected void imprimeDocumentPDF(DonneesOptions donneesOptions,
+ TemplateDocumentEnum templateDocumentEnum,
+ HttpServletResponse response) {
+ List<Object> data = []
+
+ data << donneesOptions.data[0]
+
+ ByteArrayOutputStream documentPDF = impressionMoteurService.creePdf(
+ etablissementCourant(),
+ templateDocumentEnum.toString(),
+ donneesOptions
+ )
+
+ sendPdfFile(
+ response,
+ documentPDF,
+ templateDocumentEnum.nom
+ )
+ }
/**
* Traduction d'un message fournie par l'application
* @return
*/
protected String traduis(String msgCode) {
- return message(code:msgCode)
+ return message(code: msgCode)
}
/**
* Retourne les données pour la construction du menu d'aide en ligne
*/
- protected AideItemInfo getAideInfo(){
+ protected AideItemInfo getAideInfo() {
AideItemInfo menuAideInfo = menuAideNotesService.getMenuAideInfo(securiteSession)
menuAideInfo.urlImage = resource(dir: 'images',
file: 'help.png',
- plugin :'eliot-app-plugin'
+ plugin: 'eliot-app-plugin'
)
return menuAideInfo
}
import org.lilie.services.eliot.notes.appreciationclasse.AppreciationClasseService
import org.lilie.services.eliot.notes.appreciationclasse.AppreciationClasse
import org.lilie.services.eliot.utils.NoteFormateur
+import org.lilie.services.eliot.impression.donnees.DonneesOptions
/**
* Cette classe représente le controleur de
if (classe) {
// La liste des période dans combo triée
List<Periode> periodes = classe.periodes.toList().sort()
-
+
periodeInfos = periodes.collect {
new PeriodeInfo(
idPeriode: it.id,
import org.lilie.services.eliot.urllabel.breadcrumbs.BreadCrumbsItemInfo
import org.lilie.services.eliot.impression.donnees.tdn.TableauDeNotesImpression
import org.lilie.services.eliot.notes.AbstractTableauDeNotesImpressionController
+import org.lilie.services.eliot.impression.donnees.DonneesOptions
/**
* Consultation des Tableau de Notes (profil directeur)
package org.lilie.services.eliot.notes.saisie
-import org.lilie.services.eliot.notes.page.Page
-import org.lilie.services.eliot.notes.fonctionnalites.FonctionnaliteSessionService
-import grails.converters.JSON
import org.lilie.services.eliot.scolarite.Service
import org.lilie.services.eliot.notes.NotesDroitService
-import org.lilie.services.eliot.notes.AbstractNotesController
+
import org.lilie.services.eliot.scolarite.StructureEnseignement
import org.lilie.services.eliot.scolarite.Periode
import org.lilie.services.eliot.droits.Action
import org.lilie.services.eliot.scolarite.personne.LocalPersonneService
-import org.lilie.services.eliot.notes.domaine.PeriodeInfo
-import org.lilie.services.eliot.notes.scolarite.NotesStructureEnseignementService
+
import org.lilie.services.eliot.scolarite.Personne
import org.lilie.services.eliot.scolarite.SousService
-import org.lilie.services.eliot.notes.resultat.synthese.SyntheseService
-import org.lilie.services.eliot.notes.resultat.synthese.Synthese
-import org.lilie.services.eliot.notes.consultation.BulletinComposant
+
import org.lilie.services.eliot.notes.resultat.bulletin.BulletinService
import org.lilie.services.eliot.impression.donnees.synthese.SyntheseImpression
import org.lilie.services.eliot.impression.constantes.TemplateDocumentEnum
import org.lilie.services.eliot.utils.NoteFormateur
import org.lilie.services.eliot.urllabel.breadcrumbs.BreadCrumbsItemInfo
import org.lilie.services.eliot.annuaire.SecuriteSession
-import org.lilie.services.eliot.notes.impression.synthese.ImpressionSyntheseService
+
import org.lilie.services.eliot.impression.donnees.tableauimpression.cellules.CelluleTypePeriode
import org.lilie.services.eliot.impression.donnees.tableauimpression.cellules.CelluleI18n
import org.lilie.services.eliot.notes.PreferenceUtilisateurNotes
-import org.lilie.services.eliot.notes.preferences.PreferenceUtilisateurNotesService
+
import org.lilie.services.eliot.PeriodeLibelleMode
+import org.lilie.services.eliot.impression.donnees.DonneesOptions
+
+import grails.converters.JSON
+import org.lilie.services.eliot.notes.AbstractNotesController
+import org.lilie.services.eliot.notes.consultation.BulletinComposant
+import org.lilie.services.eliot.notes.domaine.PeriodeInfo
+import org.lilie.services.eliot.notes.fonctionnalites.FonctionnaliteSessionService
+import org.lilie.services.eliot.notes.impression.synthese.ImpressionSyntheseService
+import org.lilie.services.eliot.notes.impression.synthese.OptionsImpressionParams
+import org.lilie.services.eliot.notes.page.Page
+import org.lilie.services.eliot.notes.preferences.PreferenceUtilisateurNotesService
+import org.lilie.services.eliot.notes.resultat.synthese.Synthese
+import org.lilie.services.eliot.notes.resultat.synthese.SyntheseService
+import org.lilie.services.eliot.notes.scolarite.NotesStructureEnseignementService
+
/**
* Cette classe représente le controleur de
* la vue "Synthèse" dans menu "Saisie"
SyntheseImpression syntheseImpression = donneesTableauSynthese(securiteSession, params)
+ Boolean appreciations = params.appreciations ? Boolean.parseBoolean(params.appreciations) : null
+
+ DonneesOptions donneesOptions=new DonneesOptions(
+ data:[syntheseImpression],
+ options:appreciations
+ )
+
imprimeDocumentPDF(
- syntheseImpression,
+ donneesOptions,
TemplateDocumentEnum.SYNTHESE_1,
response
)
)
)
+ OptionsImpressionParams optionsImpressionParams =
+ new OptionsImpressionParams(
+ moyennes : params.moyennes ? Boolean.parseBoolean(params.moyennes) : null,
+ sousMatieres : params.sousMatieres ? Boolean.parseBoolean(params.sousMatieres) : null,
+ appreciations : params.appreciations ? Boolean.parseBoolean(params.appreciations) : null,
+ vieScolaire : params.vieScolaire ? Boolean.parseBoolean(params.vieScolaire) : null
+ )
+
StructureEnseignement classe = StructureEnseignement.get(params.classeId)
Periode periode = Periode.get(params.periodeId)
Synthese synthese = syntheseService.construisSynthese(securiteSession, classe, periode)
// Crée la syntheseImpression
- return construisTableauImpression(synthese, securiteSession)
+ return construisTableauImpression(synthese, securiteSession, optionsImpressionParams)
}
* Convertion de l'objet synthese vers un objet capable d'être imprimé
*/
private SyntheseImpression construisTableauImpression(Synthese synthese,
- SecuriteSession securiteSession) {
+ SecuriteSession securiteSession,
+ OptionsImpressionParams optionsImpressionParams) {
SyntheseImpression tab =
- impressionSyntheseService.construisTableauImpression(synthese, securiteSession)
+ impressionSyntheseService.construisTableauImpression(synthese, securiteSession, optionsImpressionParams)
// i18n-isation des données du tableau
tab.periode = getTypePeriodeLibelle(synthese?.periode?.typePeriode)
import org.lilie.services.eliot.notes.notes.tableaudenotes.EnregistreTableauDeNotesParams
import org.lilie.services.eliot.impression.donnees.tdn.TableauDeNotesImpression
import org.lilie.services.eliot.notes.AbstractTableauDeNotesImpressionController
+import org.lilie.services.eliot.impression.donnees.DonneesOptions
/**
* Cette classe définit le controleur de la vue "tableau de notes" dans menu "Saisie"
eliot.notes.libelle.avisOrientation=Avis d'orientation
eliot.notes.libelle.absences=Absences
eliot.notes.libelle.retards=Retards
+eliot.notes.libelle.departsAnticipes=Departs anticipés
eliot.notes.libelle.excusees=justifiée(s)
eliot.notes.libelle.nonExcusees=non justifiée(s)
eliot.notes.libelle.pasDecompte.demijour=en demi-journée
eliot.notes.libelle.moyennesPrecedentes=Moyennes précédentes
eliot.notes.libelle.rang=Rang
+eliot.notes.libelle.sousMatieres=Sous-matières
+eliot.notes.libelle.vieScolaire=Vie Scolaire
+eliot.notes.libelle.vieScolaireDetail=Nombre d'absences, retards, et départs anticipés
+
groupePeriode.notation=Notation
groupePeriode.examen=Examen
groupePeriode.autre=Autre
package org.lilie.services.eliot.notes.impression.synthese
+import org.lilie.services.eliot.absences.statistiques.mensuelle.ModeCalcul
+import org.lilie.services.eliot.absences.statistiques.mensuelle.StatsMensuellesParams
+import org.lilie.services.eliot.absences.statistiques.Type
import org.lilie.services.eliot.impression.donnees.synthese.SyntheseImpression
import org.lilie.services.eliot.notes.resultat.synthese.Synthese
import org.lilie.services.eliot.utils.NoteFormateur
import org.lilie.services.eliot.notes.PreferenceUtilisateurNotes
import org.lilie.services.eliot.notes.impression.NotesImpressionService
import org.lilie.services.eliot.scolarite.PeriodeService
+import org.lilie.services.eliot.parametrages.motifs.MotifService
+import org.lilie.services.eliot.applications.absences.PriseEnCompteMotif
+import org.lilie.services.eliot.absences.PreferencesEtablissementAbsences
+import org.lilie.services.eliot.scolarite.etablissement.PreferencesEtablissementAbsencesService
+import org.lilie.services.eliot.absences.statistiques.periode.StatsPeriodesService
+import org.lilie.services.eliot.absences.statistiques.periode.StatsPeriodes
+import org.lilie.services.eliot.absences.statistiques.periode.StatsPeriodesLigne
/**
* Ce service permet de convertir un objet Synthese en objet SyntheseImpression
class ImpressionSyntheseService {
private static final POSITION_MOYENNE = 9999
+ private static final POSITION_ABSENCES = 10000
+ private static final POSITION_RETARDS = 10001
+ private static final POSITION_DEPARTS_ANTICIPES = 10002
LocalPersonneService localPersonneService
PreferenceUtilisateurNotesService preferenceUtilisateurNotesService
NotesImpressionService notesImpressionService
PeriodeService periodeService
+ MotifService motifService
+ PreferencesEtablissementAbsencesService preferencesEtablissementAbsencesService
+ StatsPeriodesService statsPeriodesService
public SyntheseImpression construisTableauImpression(Synthese synthese,
- SecuriteSession securiteSession) {
+ SecuriteSession securiteSession,
+ OptionsImpressionParams optionsImpressionParams) {
SyntheseImpression tab = new SyntheseImpression(
classe: synthese?.classe?.code,
etablissement: synthese?.classe?.etablissement?.nomAffichage
)
- tab.data = construitTableau(synthese, securiteSession)
+ tab.data = construitTableau(synthese, securiteSession, optionsImpressionParams)
return tab
}
* @return
*/
private List<CelluleTableau> construitTableau(Synthese synthese,
- SecuriteSession securiteSession) {
+ SecuriteSession securiteSession,
+ OptionsImpressionParams optionsImpressionParams) {
NoteFormateur nf =
synthese.classe.etablissement.etablissementNotes.getNoteFormateur()
ServiceOrdre ordreService = new ServiceOrdre()
+ List<Integer> serviceNoteList = []
+ List<Integer> sousServiceNoteList = []
+ getServiceEtSousServiceNotes(nf, synthese, serviceNoteList, sousServiceNoteList)
+
+ Periode periodeDeSynthese = synthese.periode
+
synthese.syntheseEleves.each { SyntheseEleve syntheseEleve ->
PreferenceUtilisateurNotes pref =
long index = 1
- syntheseEleve.services.each { Service service ->
-
- index = ordreService.getPosition(service)
-
- ResultatEleveServicePeriode resultatEleve =
- syntheseEleve.resultatEleveServicePeriodes?.find {
- it.service.id == service.id
- }
+ if (optionsImpressionParams.moyennes && optionsImpressionParams.appreciations == false){
+ syntheseEleve.services.each { Service service ->
- String note = nf.format(resultatEleve?.getValeurAffichage())
+ index = ordreService.getPosition(service)
- // Le resultat de la classe pour le service
- ResultatClasseServicePeriode resultatClasse =
- synthese.syntheseClasse.resultatClasseServicePeriodes?.find {
- it.service.id == service.id
- }
+ ResultatEleveServicePeriode resultatEleve =
+ syntheseEleve.resultatEleveServicePeriodes?.find {
+ it.service.id == service.id
+ }
- List<Personne> enseignants =
- localPersonneService.findAllPersonneBySetAutorite(
- service.enseignements.collect {it.enseignant} as Set
- )
+ String note = nf.format(resultatEleve?.getValeurAffichage())
- String nomsEnseignants = libelleListeEnseignants(enseignants)
+ // Le resultat de la classe pour le service
+ ResultatClasseServicePeriode resultatClasse =
+ synthese.syntheseClasse.resultatClasseServicePeriodes?.find {
+ it.service.id == service.id
+ }
- Periode periodeDeSynthese = synthese.periode
+ List<Personne> enseignants =
+ localPersonneService.findAllPersonneBySetAutorite(
+ service.enseignements.collect {it.enseignant} as Set
+ )
- // rechercher des sous-services
- List<SousService> sousServices = service.getSousServices(
- periodeDeSynthese.typePeriode
- )
+ String nomsEnseignants = libelleListeEnseignants(enseignants)
- if (sousServices) {
- // on a des sous-services
- prepareSousServices(
- index,
- nf,
- service,
- nomsEnseignants,
- sousServices,
- tableau,
- syntheseEleve,
- resultatClasse,
- resultatEleve
- )
- }
- else {
-
- // pas de sous-service
- tableau << getCelluleTableau(
- syntheseEleve,
- synthese,
- service,
- nomsEnseignants,
- note,
- resultatClasse,
- index
+ // rechercher des sous-services
+ List<SousService> sousServices = service.getSousServices(
+ periodeDeSynthese.typePeriode
)
+ // si le service a des sous-service et que l'utilisateur veut les afficher ...
+ if (sousServices && optionsImpressionParams.sousMatieres) {
+ prepareSousServices(
+ index,
+ nf,
+ service,
+ nomsEnseignants,
+ sousServices,
+ tableau,
+ syntheseEleve,
+ resultatClasse,
+ resultatEleve,
+ optionsImpressionParams,
+ sousServiceNoteList
+ )
+ }
+ // sinon ...
+ else {
+ // pas de sous-service
+ if (serviceNoteList.contains(service.id)){
+ tableau << getCelluleTableau(
+ syntheseEleve,
+ synthese,
+ service,
+ nomsEnseignants,
+ note,
+ resultatClasse,
+ index
+ )
+ }
+ }
}
+ }
- if (pref?.moyennesPrecedentes == true &&
- periodeDeSynthese.typePeriode?.isNotation()){
- periodeDeSynthese.getPeriodesPrecedentes()?.each{ Periode periodePrecedente ->
- tableau << getCelluleI18nMoyennePrecedente(syntheseEleve, synthese, periodePrecedente)
- }
+ if (pref?.moyennesPrecedentes == true &&
+ periodeDeSynthese.typePeriode?.isNotation()){
+ periodeDeSynthese.getPeriodesPrecedentes()?.each{ Periode periodePrecedente ->
+ tableau << getCelluleI18nMoyennePrecedente(syntheseEleve, synthese, periodePrecedente)
}
+ }
- tableau << getCelluleI18n(syntheseEleve, synthese)
+ tableau << getCelluleI18n(syntheseEleve, synthese)
- Integer rangInteger = syntheseEleve.resultatElevePeriode?.rang
- String rang = rangInteger ? rangInteger.toString() : ""
- if (pref?.rangs == true){
- tableau << getCelluleI18nRang(synthese, syntheseEleve, rang)
- }
+ Integer rangInteger = syntheseEleve.resultatElevePeriode?.rang
+ String rang = rangInteger ? rangInteger.toString() : ""
+ if (pref?.rangs == true){
+ tableau << getCelluleI18nRang(synthese, syntheseEleve, rang)
}
}
+ if (optionsImpressionParams.vieScolaire == true) {
+ listeVieScolaire(synthese, tableau, securiteSession)
+ }
+
return tableau
}
List<CelluleTableau> tableau,
SyntheseEleve syntheseEleve,
ResultatClasseServicePeriode resultatClasseServicePeriode,
- ResultatEleveServicePeriode resultatEleveServicePeriode) {
+ ResultatEleveServicePeriode resultatEleveServicePeriode,
+ OptionsImpressionParams optionsImpressionParams,
+ List<Integer> sousServiceNoteList) {
String appreciation = syntheseEleve.appreciationElevePeriode?.appreciation
Integer indexSousMatiere = 1
sousServices.each {SousService sousService ->
+ if (sousServiceNoteList.contains(sousService.id)){
- ResultatEleveSousServicePeriode resSousService =
- resultatEleveServicePeriode?.resultatsEleveSousServicePeriode.find {
- it.sousService.id == sousService.id
- }
+ ResultatEleveSousServicePeriode resSousService =
+ resultatEleveServicePeriode?.resultatsEleveSousServicePeriode.find {
+ it.sousService.id == sousService.id
+ }
- ResultatClasseSousServicePeriode resClasseSousService =
- resultatClasseServicePeriode?.resultatsClasseSousServicePeriode.find {
- it.sousService.id == sousService.id
- }
+ ResultatClasseSousServicePeriode resClasseSousService =
+ resultatClasseServicePeriode?.resultatsClasseSousServicePeriode.find {
+ it.sousService.id == sousService.id
+ }
+
+
+ tableau << new CelluleI18n(
+ enteteLigne: syntheseEleve.eleve.nomAffichage(),
+ entete1: service.matiere.codeGestion,
+ entete2: enseignants,
+ entete3: indexSousMatiere + sousService.modaliteMatiere.libelle,
+ entete4: sousService.coeff,
+ finLigne: appreciation ? appreciation : "",
+ valeur: nf.format(resSousService?.getValeurAffichage()),
+ pied1: nf.format(resClasseSousService?.moyenne),
+ pied2: nf.format(resClasseSousService?.moyenneMin),
+ pied3: nf.format(resClasseSousService?.moyenneMax),
+ index: index
+ )
+ indexSousMatiere++
+
+ }
+ }
+
+ if (indexSousMatiere != 1){
+ ResultatEleveServicePeriode resService = syntheseEleve.
+ resultatEleveServicePeriodes?.find {it.service.id == service.id}
tableau << new CelluleTableau(
enteteLigne: syntheseEleve.eleve.nomAffichage(),
entete1: service.matiere.codeGestion,
entete2: enseignants,
- entete3: indexSousMatiere + sousService.modaliteMatiere.libelle,
- entete4: sousService.coeff,
+ entete3: "3Moy.",
finLigne: appreciation ? appreciation : "",
- valeur: nf.format(resSousService?.getValeurAffichage()),
- pied1: nf.format(resClasseSousService?.moyenne),
- pied2: nf.format(resClasseSousService?.moyenneMin),
- pied3: nf.format(resClasseSousService?.moyenneMax),
+ valeur: nf.format(resService?.getValeurAffichage()),
+ pied1: nf.format(resultatClasseServicePeriode?.moyenne),
+ pied2: nf.format(resultatClasseServicePeriode?.moyenneMin),
+ pied3: nf.format(resultatClasseServicePeriode?.moyenneMax),
index: index
)
- indexSousMatiere++
-
}
- ResultatEleveServicePeriode resService = syntheseEleve.
- resultatEleveServicePeriodes?.find {it.service.id == service.id}
-
- tableau << new CelluleTableau(
- enteteLigne: syntheseEleve.eleve.nomAffichage(),
- entete1: service.matiere.codeGestion,
- entete2: enseignants,
- entete3: "3Moy.",
- finLigne: appreciation ? appreciation : "",
- valeur: nf.format(resService?.getValeurAffichage()),
- pied1: nf.format(resultatClasseServicePeriode?.moyenne),
- pied2: nf.format(resultatClasseServicePeriode?.moyenneMin),
- pied3: nf.format(resultatClasseServicePeriode?.moyenneMax),
- index: index
- )
}
- /**
- * Retourne le libellé de la liste des enseignants
- *
- * @param enseignants
- * @return : le libellé est calculé de la manière suivante :
- * <nom avec initiale prenom>,...
- */
+/**
+ * Retourne le libellé de la liste des enseignants
+ *
+ * @param enseignants
+ * @return : le libellé est calculé de la manière suivante :
+ * <nom avec initiale prenom>,...
+ */
private String libelleListeEnseignants(List<Personne> enseignants) {
String nomsEnseignants = ""
enseignants.each {Personne enseignant ->
return nomsEnseignants
}
+ /*
+ * Détection des matières et sous-matières qui n'ont pas de notes
+ */
+ private void getServiceEtSousServiceNotes(NoteFormateur nf,
+ Synthese synthese,
+ List<Integer> serviceNoteList,
+ List<Integer> sousServiceNoteList){
+ synthese.syntheseEleves.each{ SyntheseEleve syntheseEleve ->
+
+ syntheseEleve.services.each { Service service ->
+
+ ResultatEleveServicePeriode resultatEleve =
+ syntheseEleve.resultatEleveServicePeriodes?.find {
+ it.service.id == service.id
+ }
+ String note = nf.format(resultatEleve?.getValeurAffichage())
+ Boolean hasServiceNote = note != null && !"".equalsIgnoreCase(note)
+
+ if (hasServiceNote){
+ if (!serviceNoteList.find{it == service.id}){
+ serviceNoteList.add(service.id)
+ }
+ }
+
+ Periode periodeDeSynthese = synthese.periode
+ List<SousService> sousServices = service.getSousServices(
+ periodeDeSynthese.typePeriode
+ )
+ sousServices?.each{ SousService sousService ->
+ ResultatEleveSousServicePeriode resSousService =
+ resultatEleve?.resultatsEleveSousServicePeriode.find {
+ it.sousService.id == sousService.id
+ }
+ String noteSousService = nf.format(resSousService?.getValeurAffichage())
+ Boolean hasSousServiceNote =
+ noteSousService != null && !"".equalsIgnoreCase(noteSousService)
+
+ if (hasSousServiceNote){
+ if (!sousServiceNoteList.find{it == sousService.id}){
+ sousServiceNoteList.add(sousService.id)
+ }
+ }
+ }
+
+ }
+
+ }
+ }
+
+ /**
+ * Calcule les informations de vie scolaire des élèves de la synthèse
+ * - le nombre d'absences
+ * - de retards
+ * - de départs anticipés
+ *
+ * @param synthese synthèse en cours d'impression
+ * @param tableau
+ * @param securiteSession
+ * @return informations concernant la vie scolaire
+ */
+ protected void listeVieScolaire(
+ Synthese synthese,
+ List<CelluleTableau> tableau,
+ SecuriteSession securiteSession) {
+
+ PreferencesEtablissementAbsences preferencesEtablissementAbsences =
+ preferencesEtablissementAbsencesService.
+ getPreferencesEtablissementForEtablissement(
+ securiteSession.etablissementCourant)
+
+ List<Long> motifIds = motifService.findAllMotifForPriseEnCompteMotif(
+ preferencesEtablissementAbsences,
+ PriseEnCompteMotif.STATS,
+ false
+ )*.id
+
+ StatsPeriodes statsPeriodesAbsences =
+ calculeAbsencesTotales(synthese, preferencesEtablissementAbsences, motifIds)
+
+ statsPeriodesAbsences.lignes.each { statsPeriodesLigne ->
+
+ if (statsPeriodesLigne.tableauStatsPeriodes.valeurs.size() == 0) {
+ tableau << new CelluleI18n(
+ enteteLigne: statsPeriodesLigne.personne.nomAffichage(),
+ entete1: 'eliot.notes.libelle.absences',
+ entete2: "",
+ entete3: "",
+ entete4: "",
+ finLigne: "",
+ index: POSITION_ABSENCES,
+ valeur: "",
+ pied1: "",
+ pied2: "",
+ pied3: ""
+ )
+ }
+ else {
+ statsPeriodesLigne.tableauStatsPeriodes.valeurs.each { statsPeriodesValeur ->
+ tableau << new CelluleI18n(
+ enteteLigne: statsPeriodesLigne.personne.nomAffichage(),
+ entete1: 'eliot.notes.libelle.absences',
+ entete2: "",
+ entete3: "",
+ entete4: "",
+ finLigne: "",
+ index: POSITION_ABSENCES,
+ valeur: statsPeriodesValeur.valeurBrute,
+ pied1: "",
+ pied2: "",
+ pied3: ""
+ )
+ }
+ }
+ }
+
+ StatsPeriodes statsPeriodesRetards =
+ calculeRetards(synthese, preferencesEtablissementAbsences, motifIds)
+
+ statsPeriodesRetards.lignes.each { statsPeriodesLigne ->
+ if (statsPeriodesLigne.tableauStatsPeriodes.valeurs.size() == 0) {
+ tableau << new CelluleI18n(
+ enteteLigne: statsPeriodesLigne.personne.nomAffichage(),
+ entete1: 'eliot.notes.libelle.retards',
+ entete2: "",
+ entete3: "",
+ entete4: "",
+ finLigne: "",
+ index: POSITION_RETARDS,
+ valeur: "",
+ pied1: "",
+ pied2: "",
+ pied3: ""
+ )
+ }
+ else {
+ statsPeriodesLigne.tableauStatsPeriodes.valeurs.each { statsPeriodesValeur ->
+ tableau << new CelluleI18n(
+ enteteLigne: statsPeriodesLigne.personne.nomAffichage(),
+ entete1: 'eliot.notes.libelle.retards',
+ entete2: "",
+ entete3: "",
+ entete4: "",
+ finLigne: "",
+ index: POSITION_RETARDS,
+ valeur: statsPeriodesValeur.valeurBrute,
+ pied1: "",
+ pied2: "",
+ pied3: ""
+ )
+ }
+ }
+ }
+
+ StatsPeriodes statsPeriodesDepartsAnticipes =
+ calculeDepartsAnticipes(synthese, preferencesEtablissementAbsences, motifIds)
+
+ statsPeriodesDepartsAnticipes.lignes.each { statsPeriodesLigne ->
+
+ if (statsPeriodesLigne.tableauStatsPeriodes.valeurs.size() == 0) {
+ tableau << new CelluleI18n(
+ enteteLigne: statsPeriodesLigne.personne.nomAffichage(),
+ entete1: 'eliot.notes.libelle.departsAnticipes',
+ entete2: "",
+ entete3: "",
+ entete4: "",
+ finLigne: "",
+ index: POSITION_DEPARTS_ANTICIPES,
+ valeur: "",
+ pied1: "",
+ pied2: "",
+ pied3: ""
+ )
+ }
+ else {
+ statsPeriodesLigne.tableauStatsPeriodes.valeurs.each { statsPeriodesValeur ->
+ tableau << new CelluleI18n(
+ enteteLigne: statsPeriodesLigne.personne.nomAffichage(),
+ entete1: 'eliot.notes.libelle.departsAnticipes',
+ entete2: "",
+ entete3: "",
+ entete4: "",
+ finLigne: "",
+ index: POSITION_DEPARTS_ANTICIPES,
+ valeur: statsPeriodesValeur.valeurBrute,
+ pied1: "",
+ pied2: "",
+ pied3: ""
+ )
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Calcule les absences justifiées et non justifiées
+ * @param synthese
+ * @param preferencesEtablissementAbsences
+ * @param motifIds
+ * @return un StatsPeriodes
+ */
+ private StatsPeriodes calculeAbsencesTotales(
+ Synthese synthese,
+ PreferencesEtablissementAbsences preferencesEtablissementAbsences,
+ List<Long> motifIds) {
+
+ StatsMensuellesParams params =
+ creeBaseCriteresRecherche(synthese, preferencesEtablissementAbsences, motifIds)
+
+ params.absencesValables = true
+ params.absencesNonValables = true
+
+ return calculeStatistiquesAbsences(
+ synthese, preferencesEtablissementAbsences, params)
+ }
+
+ /**
+ * Calcule les retards
+ * @param synthese
+ * @param preferencesEtablissementAbsences
+ * @param motifIds
+ * @return un StatsPeriodes
+ */
+ StatsPeriodes calculeRetards(
+ Synthese synthese,
+ PreferencesEtablissementAbsences preferencesEtablissementAbsences,
+ List<Long> motifIds) {
+
+ StatsMensuellesParams params =
+ creeBaseCriteresRecherche(synthese, preferencesEtablissementAbsences, motifIds)
+
+ params.retards = true
+
+ return calculeStatistiquesAbsences(
+ synthese, preferencesEtablissementAbsences, params)
+ }
+
+ /**
+ * Calcule les départs anticipés
+ * @param synthese
+ * @param preferencesEtablissementAbsences
+ * @param motifIds
+ * @return un StatsPeriodes
+ */
+ StatsPeriodes calculeDepartsAnticipes(
+ Synthese synthese,
+ PreferencesEtablissementAbsences preferencesEtablissementAbsences,
+ List<Long> motifIds) {
+
+ StatsMensuellesParams params =
+ creeBaseCriteresRecherche(synthese, preferencesEtablissementAbsences, motifIds)
+
+ params.departsAnticipes = true
+
+ return calculeStatistiquesAbsences(
+ synthese, preferencesEtablissementAbsences, params)
+ }
+
+ /**
+ * Crée les critères de recherche de base
+ * @param synthese
+ * @param preferencesEtablissementAbsences
+ * @param motifIds
+ * @return un StatsMensuellesParams
+ */
+ protected StatsMensuellesParams creeBaseCriteresRecherche(
+ Synthese synthese,
+ PreferencesEtablissementAbsences preferencesEtablissementAbsences,
+ List<Long> motifIds) {
+
+ StatsMensuellesParams params = new StatsMensuellesParams(
+ modeCalcul: ModeCalcul.VOLUME,
+ type: Type.ABSENCES
+ )
+
+ params.dateDebut.setTime(synthese.periode.dateDebut)
+ params.dateFin.setTime(synthese.periode.dateFin)
+ params.eleveIds = synthese.syntheseEleves*.eleve.autorite.id
+ params.structIds = [synthese.classe.id]
+ params.motifIds = motifIds
+ params.etablissementId = preferencesEtablissementAbsences.etablissement.id
+
+ return params
+ }
+
+ /**
+ * Calcule les statistiques d'absences
+ * @param synthese
+ * @param preferencesEtablissementAbsences
+ * @param params
+ * @return StatsPeriodes
+ */
+ protected StatsPeriodes calculeStatistiquesAbsences(
+ Synthese synthese,
+ PreferencesEtablissementAbsences preferencesEtablissementAbsences,
+ StatsMensuellesParams params) {
+
+ StatsPeriodes statsPeriodes = new StatsPeriodes(
+ periodes: [synthese.periode]
+ )
+
+ statsPeriodes.lignes.addAll(
+ synthese.syntheseEleves.collect({
+ new StatsPeriodesLigne(it.eleve)
+ }))
+
+ return (StatsPeriodes) statsPeriodesService.calculeStatsPeriodesAbsences(
+ params,
+ statsPeriodes,
+ preferencesEtablissementAbsences
+ )
+ }
}
--- /dev/null
+/*
+ * Copyright © FYLAB and the Conseil Régional d'Île-de-France, 2009
+ * This file is part of L'Interface Libre et Interactive de l'Enseignement (Lilie).
+ *
+ * Lilie is free software. You can redistribute it and/or modify since
+ * you respect the terms of either (at least one of the both license) :
+ * - under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * - the CeCILL-C as published by CeCILL-C; either version 1 of the
+ * License, or any later version
+ *
+ * There are special exceptions to the terms and conditions of the
+ * licenses as they are applied to this software. View the full text of
+ * the exception in file LICENSE.txt in the directory of this software
+ * distribution.
+ *
+ * Lilie is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Licenses for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the CeCILL-C along with Lilie. If not, see :
+ * <http://www.gnu.org/licenses/> and
+ * <http://www.cecill.info/licences.fr.html>.
+ */
+
+package org.lilie.services.eliot.notes.impression.synthese
+
+/**
+ * Rassemble les choix d'impression de l'utilisateur concernant les synthèses
+ * @author agia
+ */
+class OptionsImpressionParams {
+
+ Boolean moyennes
+ Boolean sousMatieres
+ Boolean appreciations
+ Boolean vieScolaire
+
+}
eliot.notes.saisie.Modele.url.urlSynthese = '${createLink(action : 'index', controller : 'saisieSynthese')}';
eliot.notes.saisie.Modele.url.urlImprimerTdn = '${createLink(action : 'imprimerTableauDeNotes', controller : consultation?'consultationTableauDeNotes':'saisieTableauDeNotes')}';
- eliot.notes.saisie.Modele.url.urlImprimerSynthese = '${createLink(action : 'imprimerSynthese', controller : consultation?'consultationSynthese':'saisieSynthese')}';
+ eliot.notes.saisie.Modele.url.urlImprimerSynthese = '${createLink(action : 'imprimerSynthese', controller : 'saisieSynthese')}';
eliot.notes.saisie.Modele.url.urlSyntheseImprimable = '${createLink(action : 'syntheseImprimable', controller : 'saisieSynthese')}';
</g:javascript>
eliot.notes.saisie.synthese.Modele.libelle.moyennesPrecedentes = '${g.message(code: "eliot.notes.libelle.moyennesPrecedentes")?.encodeAsJavaScript()}';
eliot.notes.saisie.synthese.Modele.libelle.rang = '${g.message(code: "eliot.notes.libelle.rang")?.encodeAsJavaScript()}';
+ eliot.notes.saisie.synthese.Modele.libelle.ok = '${g.message(code: "eliot.notes.libelle.ok")?.encodeAsJavaScript()}';
+
+ eliot.notes.saisie.synthese.Modele.libelle.moyennes = '${g.message(code: "eliot.notes.libelle.moyennes")?.encodeAsJavaScript()}';
+ eliot.notes.saisie.synthese.Modele.libelle.sousMatieres = '${g.message(code: "eliot.notes.libelle.sousMatieres")?.encodeAsJavaScript()}';
+ eliot.notes.saisie.synthese.Modele.libelle.appreciationsGenerales = '${g.message(code: "eliot.notes.libelle.appreciationsGenerales")?.encodeAsJavaScript()}';
+ eliot.notes.saisie.synthese.Modele.libelle.vieScolaire = '${g.message(code: "eliot.notes.libelle.vieScolaire")?.encodeAsJavaScript()}';
+ eliot.notes.saisie.synthese.Modele.libelle.vieScolaireDetail = '${g.message(code: "eliot.notes.libelle.vieScolaireDetail")?.encodeAsJavaScript()}';
+
eliot.notes.saisie.synthese.Modele.messages.appreciationModifieEnCours = '${g.message(code: "eliot.notes.message.appreciationModifieEnCours")?.encodeAsJavaScript()}';
eliot.notes.saisie.synthese.Modele.messages.appreciationModifieSucces = '${g.message(code: "eliot.notes.message.appreciationModifieSucces")?.encodeAsJavaScript()}';
eliot.notes.saisie.synthese.Modele.messages.appreciationModifieEchou = '${g.message(code: "eliot.notes.message.appreciationModifieEchou")?.encodeAsJavaScript()}';
<g:javascript library="src/views/saisie/synthese/MoyenneClasseView"/>
<g:javascript library="src/views/saisie/synthese/TblNotesHeaderController"/>
<g:javascript library="src/views/saisie/synthese/TblNotesHeaderView"/>
+ <g:javascript library="src/views/saisie/synthese/ImpressionController"/>
+ <g:javascript library="src/views/saisie/synthese/ImpressionView"/>
<g:javascript library="src/views/saisie/synthese/Application"/>
</head>
--- /dev/null
+/*
+* Copyright © FYLAB and the Conseil Régional d'Île-de-France, 2009
+* This file is part of L'Interface Libre et Interactive de l'Enseignement (Lilie).
+*
+* Lilie is free software. You can redistribute it and/or modify since
+* you respect the terms of either (at least one of the both license) :
+* - under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+* - the CeCILL-C as published by CeCILL-C; either version 1 of the
+* License, or any later version
+*
+* There are special exceptions to the terms and conditions of the
+* licenses as they are applied to this software. View the full text of
+* the exception in file LICENSE.txt in the directory of this software
+* distribution.
+*
+* Lilie is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* Licenses for more details.
+*
+* You should have received a copy of the GNU General Public License
+* and the CeCILL-C along with Lilie. If not, see :
+* <http://www.gnu.org/licenses/> and
+* <http://www.cecill.info/licences.fr.html>.
+*/
+
+package org.lilie.services.eliot.notes.impression.synthese
+
+import grails.plugin.spock.UnitSpec
+import org.lilie.services.eliot.absences.statistiques.mensuelle.StatsMensuellesParams
+import org.lilie.services.eliot.absences.PreferencesEtablissementAbsences
+import org.lilie.services.eliot.notes.resultat.synthese.Synthese
+import org.lilie.services.eliot.absences.statistiques.periode.StatsPeriodesService
+import org.lilie.services.eliot.scolarite.Etablissement
+import org.lilie.services.eliot.scolarite.Periode
+import org.lilie.services.eliot.notes.resultat.synthese.SyntheseEleve
+import org.lilie.services.eliot.scolarite.Personne
+import org.lilie.services.eliot.absences.statistiques.mensuelle.ModeCalcul
+import org.lilie.services.eliot.absences.statistiques.Type
+import org.lilie.services.eliot.securite.impl.Autorite
+import org.lilie.services.eliot.scolarite.StructureEnseignement
+import org.lilie.services.eliot.impression.donnees.tableauimpression.cellules.CelluleTableau
+import org.lilie.services.eliot.scolarite.etablissement.PreferencesEtablissementAbsencesService
+import org.lilie.services.eliot.absences.statistiques.periode.StatsPeriodes
+import org.lilie.services.eliot.annuaire.SecuriteSession
+import org.lilie.services.eliot.parametrages.motifs.MotifService
+import org.lilie.services.eliot.applications.absences.PriseEnCompteMotif
+import org.lilie.services.eliot.absences.statistiques.periode.StatsPeriodesLigne
+import org.lilie.services.eliot.absences.statistiques.periode.TableauStatsPeriodes
+import org.lilie.services.eliot.absences.statistiques.periode.StatsPeriodesValeur
+import org.lilie.services.eliot.scolarite.personne.LocalPersonneService
+
+class ImpressionSyntheseServiceSpec extends UnitSpec {
+
+ ImpressionSyntheseService impressionSyntheseService
+ StatsPeriodesService statsPeriodesService
+ PreferencesEtablissementAbsencesService preferencesEtablissementAbsencesService
+ MotifService motifService
+ LocalPersonneService localPersonneService
+
+ org.lilie.services.eliot.annuaire.SecuriteSession securiteSession
+
+ def setup() {
+ statsPeriodesService = Mock(StatsPeriodesService)
+ preferencesEtablissementAbsencesService = Mock(PreferencesEtablissementAbsencesService)
+ motifService = Mock(MotifService)
+ localPersonneService = Mock(LocalPersonneService)
+
+ impressionSyntheseService = new ImpressionSyntheseService(
+ statsPeriodesService: statsPeriodesService,
+ preferencesEtablissementAbsencesService: preferencesEtablissementAbsencesService,
+ motifService: motifService
+ )
+
+ securiteSession = Mock(SecuriteSession)
+ }
+
+ def 'listeVieScolaire'() {
+ given:
+ securiteSession.getEtablissementCourant() >> etablissement
+
+ motifService.findAllMotifForPriseEnCompteMotif(
+ preferencesEtablissementAbsences,
+ PriseEnCompteMotif.STATS,
+ false
+ ) >> []
+
+ localPersonneService.getNomAffichage(_) >> 'Nom Affichage'
+
+ eleve1.localPersonneService = localPersonneService
+ eleve2.localPersonneService = localPersonneService
+
+ when:
+ impressionSyntheseService.listeVieScolaire(
+ synthese, tableau, securiteSession)
+
+ then:
+ 1 * preferencesEtablissementAbsencesService.getPreferencesEtablissementForEtablissement(
+ securiteSession.etablissementCourant
+ ) >> preferencesEtablissementAbsences
+
+ 3 * statsPeriodesService.calculeStatsPeriodesAbsences(_, _, _) >> statsPeriodes
+
+ tableau.size() == 6
+
+ where:
+
+ eleve1 = new Personne(
+ autorite: new Autorite(id: 1)
+ )
+ eleve2 = new Personne(
+ autorite: new Autorite(id: 2)
+ )
+
+ tableau = []
+ etablissement = new Etablissement(id: 1)
+
+ statsPeriodes = new StatsPeriodes(
+ lignes: [
+ creeStatsPeriodesLigne(eleve1),
+ creeStatsPeriodesLigne(eleve2)
+ ]
+ )
+
+ synthese = new Synthese(
+ classe: new StructureEnseignement(id: 1),
+ periode: new Periode(
+ id: 1,
+ dateDebut: new GregorianCalendar(2012, 8, 1).getTime(),
+ dateFin: new GregorianCalendar(2013, 6, 31).getTime()
+ ),
+ syntheseEleves: [
+ new SyntheseEleve(eleve: eleve1),
+ new SyntheseEleve(eleve: eleve2)
+ ]
+ )
+
+ preferencesEtablissementAbsences = new PreferencesEtablissementAbsences(
+ etablissement: etablissement
+ )
+
+ motifIds = []
+
+ }
+
+ private StatsPeriodesLigne creeStatsPeriodesLigne(Personne personne) {
+ StatsPeriodesLigne statsPeriodesLigne = new StatsPeriodesLigne(personne)
+
+ statsPeriodesLigne.tableauStatsPeriodes.valeurs <<
+ new StatsPeriodesValeur(valeurBrute: 1.0)
+
+ return statsPeriodesLigne
+ }
+
+ def 'calculeAbsencesTotales'() {
+ when:
+ statsPeriodes = impressionSyntheseService.calculeAbsencesTotales(
+ synthese,
+ preferencesEtablissementAbsences,
+ motifIds
+ )
+
+ then:
+ 1 * statsPeriodesService.calculeStatsPeriodesAbsences(
+ { statsMensuellesParams ->
+ statsMensuellesParams.absencesValables == true
+ statsMensuellesParams.absencesNonValables == true
+ },
+ _,
+ preferencesEtablissementAbsences
+ )
+
+ where:
+ statsPeriodes = null
+
+ eleve1 = new Personne(
+ autorite: new Autorite(id: 1)
+ )
+ eleve2 = new Personne(
+ autorite: new Autorite(id: 2)
+ )
+
+ synthese = new Synthese(
+ classe: new StructureEnseignement(id: 1),
+ periode: new Periode(
+ id: 1,
+ dateDebut: new GregorianCalendar(2012, 8, 1).getTime(),
+ dateFin: new GregorianCalendar(2013, 6, 31).getTime()
+ ),
+ syntheseEleves: [
+ new SyntheseEleve(eleve: eleve1),
+ new SyntheseEleve(eleve: eleve2)
+ ]
+ )
+
+ preferencesEtablissementAbsences = new PreferencesEtablissementAbsences(
+ etablissement: new Etablissement(id: 1)
+ )
+
+ motifIds = []
+
+ }
+
+ def 'calculeRetards'() {
+ when:
+ statsPeriodes = impressionSyntheseService.calculeRetards(
+ synthese,
+ preferencesEtablissementAbsences,
+ motifIds
+ )
+
+ then:
+ 1 * statsPeriodesService.calculeStatsPeriodesAbsences(
+ { statsMensuellesParams ->
+ statsMensuellesParams.retards == true
+ },
+ _,
+ preferencesEtablissementAbsences
+ )
+
+ where:
+ statsPeriodes = null
+
+ eleve1 = new Personne(
+ autorite: new Autorite(id: 1)
+ )
+ eleve2 = new Personne(
+ autorite: new Autorite(id: 2)
+ )
+
+ synthese = new Synthese(
+ classe: new StructureEnseignement(id: 1),
+ periode: new Periode(
+ id: 1,
+ dateDebut: new GregorianCalendar(2012, 8, 1).getTime(),
+ dateFin: new GregorianCalendar(2013, 6, 31).getTime()
+ ),
+ syntheseEleves: [
+ new SyntheseEleve(eleve: eleve1),
+ new SyntheseEleve(eleve: eleve2)
+ ]
+ )
+
+ preferencesEtablissementAbsences = new PreferencesEtablissementAbsences(
+ etablissement: new Etablissement(id: 1)
+ )
+
+ motifIds = []
+
+ }
+
+ def 'calculeDepartsAnticipes'() {
+ when:
+ statsPeriodes = impressionSyntheseService.calculeDepartsAnticipes(
+ synthese,
+ preferencesEtablissementAbsences,
+ motifIds
+ )
+
+ then:
+ 1 * statsPeriodesService.calculeStatsPeriodesAbsences(
+ { statsMensuellesParams ->
+ statsMensuellesParams.departsAnticipes == true
+ },
+ _,
+ preferencesEtablissementAbsences
+ )
+
+ where:
+ statsPeriodes = null
+
+ eleve1 = new Personne(
+ autorite: new Autorite(id: 1)
+ )
+ eleve2 = new Personne(
+ autorite: new Autorite(id: 2)
+ )
+
+ synthese = new Synthese(
+ classe: new StructureEnseignement(id: 1),
+ periode: new Periode(
+ id: 1,
+ dateDebut: new GregorianCalendar(2012, 8, 1).getTime(),
+ dateFin: new GregorianCalendar(2013, 6, 31).getTime()
+ ),
+ syntheseEleves: [
+ new SyntheseEleve(eleve: eleve1),
+ new SyntheseEleve(eleve: eleve2)
+ ]
+ )
+
+ preferencesEtablissementAbsences = new PreferencesEtablissementAbsences(
+ etablissement: new Etablissement(id: 1)
+ )
+
+ motifIds = []
+
+ }
+
+ def 'creeBaseCriteresRecherche'() {
+ when:
+ statsMensuellesParams = impressionSyntheseService.creeBaseCriteresRecherche(
+ synthese,
+ preferencesEtablissementAbsences,
+ motifIds
+ )
+
+ then:
+ statsMensuellesParams.modeCalcul == ModeCalcul.VOLUME
+ statsMensuellesParams.type == Type.ABSENCES
+ statsMensuellesParams.dateDebut.getTime() == synthese.periode.dateDebut
+ statsMensuellesParams.dateFin.getTime() == synthese.periode.dateFin
+ statsMensuellesParams.eleveIds.size() == synthese.syntheseEleves.size()
+
+ synthese.syntheseEleves.every {
+ statsMensuellesParams.eleveIds.contains(it.eleve.autorite.id)
+ }
+
+ statsMensuellesParams.structIds.size() == 1
+ statsMensuellesParams.structIds.contains(synthese.classe.id)
+ statsMensuellesParams.motifIds == motifIds
+ statsMensuellesParams.etablissementId == preferencesEtablissementAbsences.etablissement.id
+
+ where:
+ statsMensuellesParams = null
+
+ eleve1 = new Personne(
+ autorite: new Autorite(id: 1)
+ )
+
+ eleve2 = new Personne(
+ autorite: new Autorite(id: 2)
+ )
+
+ synthese = new Synthese(
+ classe: new StructureEnseignement(id: 1),
+ periode: new Periode(
+ id: 1,
+ dateDebut: new GregorianCalendar(2012, 8, 1).getTime(),
+ dateFin: new GregorianCalendar(2013, 6, 31).getTime()
+ ),
+ syntheseEleves: [
+ new SyntheseEleve(eleve: eleve1),
+ new SyntheseEleve(eleve: eleve2)
+ ]
+ )
+
+ preferencesEtablissementAbsences = new PreferencesEtablissementAbsences(
+ etablissement: new Etablissement(id: 1)
+ )
+
+ motifIds = []
+
+ }
+
+ def 'calculeStatistiquesAbsences'() {
+ when:
+ impressionSyntheseService.calculeStatistiquesAbsences(
+ synthese,
+ preferencesEtablissementAbsences,
+ params
+ )
+
+ then:
+ 1 * statsPeriodesService.calculeStatsPeriodesAbsences(
+ params,
+ { statsPeriodes ->
+
+ List eleves = statsPeriodes.lignes.collect { statsPeriodesLigne ->
+ statsPeriodesLigne.personne
+ }
+
+ (statsPeriodes.periodes.size == 1) &&
+ statsPeriodes.periodes.contains(synthese.periode) &&
+ (eleves.size() == synthese.syntheseEleves.size()) &&
+ eleves.contains(eleve1) &&
+ eleves.contains(eleve2)
+
+ },
+ preferencesEtablissementAbsences
+ )
+
+ where:
+ eleve1 = new Personne(
+ autorite: new Autorite(id: 1)
+ )
+
+ eleve2 = new Personne(
+ autorite: new Autorite(id: 2)
+ )
+
+ synthese = new Synthese(
+ classe: new StructureEnseignement(id: 1),
+ periode: new Periode(
+ id: 1,
+ dateDebut: new GregorianCalendar(2012, 8, 1).getTime(),
+ dateFin: new GregorianCalendar(2013, 6, 31).getTime()
+ ),
+ syntheseEleves: [
+ new SyntheseEleve(eleve: eleve1),
+ new SyntheseEleve(eleve: eleve2)
+ ]
+ )
+
+ preferencesEtablissementAbsences = new PreferencesEtablissementAbsences(
+ etablissement: new Etablissement(id: 1)
+ )
+
+ motifIds = []
+
+ params = new StatsMensuellesParams()
+ }
+
+
+
+}
this.ConfigServeur = this.ns.Modele;
this.Constantes = this.ns.Constantes;
+ this.creeImpressionItems();
+
// Classe
this.classeController = new this.ns.ClasseController();
this.classeView = new this.ns.ClasseView(this.classeController.storeClasse);
// Toolbar
this.toolbarView = new this.ns.ToolbarView({
- boutonExporter : boutonExporterView.bouton
+ boutonExporter : boutonExporterView.bouton,
+ impressionController: this.impressionController
});
// Une liste qui contient un grid(note) quand idService et idPeriode
}
});
+ },
+
+ creeImpressionItems: function() {
+ var controller = new this.ns.ImpressionController({}).getInterface();
+
+ var view = new this.ns.ImpressionView({
+ controller: controller
+ }).getInterface();
+
+ controller.observeViews({
+ view: view
+ });
+
+ this.impressionController = controller;
+ this.impressionView = view;
}
});
storeId:{
+ },
+
+ options: {
+ moyennes: 'moyennes',
+ appreciationsGenerales: 'appreciationsGenerales'
}
};
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright © FYLAB and the Conseil Régional d'Île-de-France, 2009
+ * This file is part of L'Interface Libre et Interactive de l'Enseignement (Lilie).
+ *
+ * Lilie is free software. You can redistribute it and/or modify since
+ * you respect the terms of either (at least one of the both license) :
+ * - under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * - the CeCILL-C as published by CeCILL-C; either version 1 of the
+ * License, or any later version
+ *
+ * There are special exceptions to the terms and conditions of the
+ * licenses as they are applied to this software. View the full text of
+ * the exception in file LICENSE.txt in the directory of this software
+ * distribution.
+ *
+ * Lilie is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Licenses for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the CeCILL-C along with Lilie. If not, see :
+ * <http://www.gnu.org/licenses/> and
+ * <http://www.cecill.info/licences.fr.html>.
+ */
+
+Ext.ns('eliot.notes.saisie.synthese');
+
+eliot.notes.saisie.synthese.ImpressionController = Ext.extend(Ext.util.Observable, {
+
+ constructor: function(config) {
+ this.init(eliot.notes.saisie.synthese, config);
+ },
+
+ init: function(ns, config) {
+ this.ns = ns;
+ this.Constantes = this.ns.Constantes;
+ this.ConfigServeur = this.ns.ConfigServeur;
+ this.config = Ext.apply(this.creeConfig(), config);
+ },
+
+ creeConfig:function () {
+ return {};
+ },
+
+ getInterface:function () {
+ return {
+ observeViews: this.observeViews.createDelegate(this),
+ ouvrePopup: this.ouvrePopup.createDelegate(this),
+ imprime: this.imprime.createDelegate(this)
+ }
+ },
+
+ observeViews: function(views) {
+ this.views = views;
+ },
+
+ ouvrePopup: function() {
+ this.views.view.ouvrePopup();
+ },
+
+ imprime: function(params) {
+ Ext.Ajax.request({
+
+ url : eliot.notes.saisie.Modele.url.urlSyntheseImprimable,
+
+ params : {
+ classeId: this.ConfigServeur.data.classeId,
+ periodeId: this.ConfigServeur.data.periodeId,
+ option: params.option,
+ sousMatieres: params.sousMatieres,
+ vieScolaire: params.vieScolaire
+ },
+
+ success : function(response, request) {
+ var reponse = Ext.decode(response.responseText);
+
+ if (reponse.tropGrand) {
+ eliot.notes.Messages.showErreur(reponse.errorMsg);
+ }
+ else {
+
+ var moyennes = params.option == this.Constantes.options.moyennes;
+ var appreciations = params.option == this.Constantes.options.appreciationsGenerales;
+
+ var url = eliot.notes.saisie.Modele.url.urlImprimerSynthese
+ + '?classeId=' + this.ConfigServeur.data.classeId
+ + '&periodeId=' + this.ConfigServeur.data.periodeId
+ + '&moyennes=' + moyennes
+ + '&sousMatieres=' + params.sousMatieres
+ + '&appreciations=' + appreciations
+ + '&vieScolaire=' + params.vieScolaire;
+
+ window.open(url, "_blank",
+ "height=600, width=800, toolbar=yes,menubar=no,scrollbars=yes");
+ }
+ },
+
+ failure : function() {
+ },
+
+ scope : this
+ });
+
+ }
+
+});
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright © FYLAB and the Conseil Régional d'Île-de-France, 2009
+ * This file is part of L'Interface Libre et Interactive de l'Enseignement (Lilie).
+ *
+ * Lilie is free software. You can redistribute it and/or modify since
+ * you respect the terms of either (at least one of the both license) :
+ * - under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * - the CeCILL-C as published by CeCILL-C; either version 1 of the
+ * License, or any later version
+ *
+ * There are special exceptions to the terms and conditions of the
+ * licenses as they are applied to this software. View the full text of
+ * the exception in file LICENSE.txt in the directory of this software
+ * distribution.
+ *
+ * Lilie is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Licenses for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the CeCILL-C along with Lilie. If not, see :
+ * <http://www.gnu.org/licenses/> and
+ * <http://www.cecill.info/licences.fr.html>.
+ */
+
+Ext.ns('eliot.notes.saisie.synthese');
+
+eliot.notes.saisie.synthese.ImpressionView = Ext.extend(Ext.util.Observable, {
+
+ constructor: function(config) {
+ this.init(eliot.notes.saisie.synthese, config);
+ this.creePopup();
+ },
+
+ init: function(ns, config) {
+ this.ns = ns;
+ this.Constantes = this.ns.Constantes;
+ this.ConfigServeur = this.ns.ConfigServeur;
+ this.config = Ext.apply(this.creeConfig(), config);
+ },
+
+ creeConfig:function () {
+ return {
+ controller: undefined
+ };
+ },
+
+ getInterface:function () {
+ return {
+ ouvrePopup: this.ouvrePopup.createDelegate(this)
+ }
+ },
+
+ creePopup: function() {
+ var params = {
+ option: this.Constantes.options.moyennes,
+ sousMatieres: false,
+ vieScolaire: false
+ };
+
+ var popup = new Ext.Window({
+
+ title: this.ConfigServeur.libelle.imprimer,
+ layout:'fit',
+ width:420,
+ height: 200,
+ closeAction:'hide',
+ resizable: false,
+ plain: true,
+
+ items: [
+ {
+ layout: 'form',
+ plain: false,
+ border: false,
+ frame: false,
+ labelWidth: 10,
+ unstyled: true,
+ defaults: {
+ width: 350
+ },
+ items: [
+ {
+ xtype: 'radiogroup',
+ columns: 1,
+ items: [
+ {
+ xtype: 'radio',
+ boxLabel: this.ConfigServeur.libelle.moyennes,
+ checked: true,
+ style: 'margin-left: 0px;',
+ name: 'option',
+ listeners: {
+ check: function (radio, checked) {
+ if (checked) {
+ params.option = this.Constantes.options.moyennes;
+ }
+ },
+ scope: this
+ }
+ },
+ {
+ xtype: 'checkbox',
+ boxLabel: this.ConfigServeur.libelle.sousMatieres,
+ checked: false,
+ style: 'margin-left: 50px;',
+ listeners: {
+ check: function (checkbox, checked) {
+ params.sousMatieres = checked;
+ },
+ scope: this
+ }
+ },
+ {
+ xtype: 'radio',
+ boxLabel: this.ConfigServeur.libelle.appreciationsGenerales,
+ checked: false,
+ style: 'margin-left: 0px; margin-top: 10px;',
+ name: 'option',
+ listeners: {
+ check: function (radio, checked) {
+ if (checked) {
+ params.option = this.Constantes.options.appreciationsGenerales;
+ }
+ },
+ scope: this
+ }
+ }
+ ]
+ },
+ {
+ xtype: 'checkbox',
+ boxLabel: this.ConfigServeur.libelle.vieScolaire
+ + ' ('
+ + this.ConfigServeur.libelle.vieScolaireDetail
+ + ')',
+ checked: false,
+ style: 'margin-left: 0px; margin-top: 20px;',
+ listeners: {
+ check: function (checkbox, checked) {
+ params.vieScolaire = checked;
+ },
+ scope: this
+ }
+ },
+ ]
+ }
+ ],
+ buttons: [
+ {
+ text: this.ConfigServeur.libelle.ok,
+ handler: function() {
+ popup.hide();
+ this.config.controller.imprime(params);
+ },
+ scope: this
+ },
+ {
+ text: this.ConfigServeur.libelle.annuler,
+ handler: function() {
+ popup.hide();
+ },
+ scope: this
+ }
+ ]
+ });
+
+ this.popup = popup;
+ },
+
+ ouvrePopup: function() {
+ this.popup.show();
+ }
+
+});
\ No newline at end of file
* Configuration serveur
* @author onic
*/
-eliot.notes.saisie.synthese.Modele = {
+eliot.notes.saisie.synthese.ConfigServeur = {
messages:{
appreciationModifieEnCours: undefined,
affichage: undefined,
moyennesPrecedentes: undefined,
- rang: undefined
+ rang: undefined,
+
+ ok: undefined,
+
+ moyennes: undefined,
+ sousMatieres: undefined,
+ appreciationsGenerales: undefined,
+ vieScolaire: undefined,
+ vieScolaireDetail: undefined
},
icon: {
periodesPrecedentes: []
}
-};
\ No newline at end of file
+};
+
+eliot.notes.saisie.synthese.Modele = eliot.notes.saisie.synthese.ConfigServeur;
\ No newline at end of file
*/
constructor: function(config) {
- this.ns = eliot.notes.saisie.synthese;
- this.ConfigServeur = this.ns.Modele;
- this.Constantes = this.ns.Constantes;
+ this.init(eliot.notes.saisie.synthese, config);
this.addEvents(
style:'margin-top: 3px;margin-left: 25px',
listeners: {
click: function() {
- this.actionImprimerSynthese();
+ this.config.impressionController.ouvrePopup();
},
scope: this
},
});
},
+ init: function(ns, config) {
+ this.ns = ns;
+ this.Constantes = this.ns.Constantes;
+ this.ConfigServeur = this.ns.Modele;
+ this.config = Ext.apply(this.creeConfig(), config);
+ },
+
+ creeConfig:function () {
+ return {
+ boutonExporter: undefined,
+ impressionController: undefined
+ };
+ },
+
creeBtnAffichage: function(desactiveBouton) {
button = new Ext.Button({
xtype: 'tbbutton',
*/
setModeEdition: function(edition) {
this.setButtonStatesDelayed(edition);
- },
-
- /**
- * La méthode permet d'imprimer tableau de synthese qui dépend d'un
- * service et période donnée
- */
- actionImprimerSynthese: function() {
- Ext.Ajax.request({
-
- url : eliot.notes.saisie.Modele.url.urlSyntheseImprimable,
-
- params : {
- classeId: this.ConfigServeur.data.classeId,
- periodeId:this.ConfigServeur.data.periodeId
- },
-
- success : function(response, request) {
- var reponse = Ext.decode(response.responseText);
-
- if (reponse.tropGrand) {
- eliot.notes.Messages.showErreur(reponse.errorMsg);
- }
- else {
-
- var url = eliot.notes.saisie.Modele.url.urlImprimerSynthese
- + '?classeId=' + this.ConfigServeur.data.classeId
- + '&periodeId=' + this.ConfigServeur.data.periodeId;
-
- window.open(
- url,
- "_blank",
- "height=600, width=800, toolbar=yes,menubar=no,scrollbars=yes"
- );
-
- }
- },
- failure : function() {
- },
- scope : this
- });
-
}
});
\ No newline at end of file
<style name="label" hAlign="Left" fontName="Arial" fontSize="10"/>
<style name="valeur_champ" fontName="Arial" fontSize="10"/>
<parameter name="tableau" class="java.lang.Object" isForPrompting="false"/>
+ <parameter name="options" class="java.lang.Boolean" isForPrompting="false"/>
<field name="data" class="java.util.List"/>
<field name="classe" class="java.lang.String"/>
<field name="periode" class="java.lang.String"/>
<band height="50">
<subreport>
<reportElement x="0" y="0" width="802" height="50"/>
+ <subreportParameter name="options">
+ <subreportParameterExpression><![CDATA[$P{options}]]></subreportParameterExpression>
+ </subreportParameter>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{data})]]></dataSourceExpression>
<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{tableau}]]></subreportExpression>
</subreport>
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="proto" language="groovy" pageWidth="842" pageHeight="595" orientation="Landscape" whenNoDataType="BlankPage" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
- <property name="ireport.zoom" value="1.5"/>
+ <property name="ireport.zoom" value="2.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<style name="cellule" mode="Transparent" backcolor="#FCFCFC" hAlign="Left" vAlign="Middle" fontName="Arial" fontSize="6">
<rightPen lineWidth="0.25" lineStyle="Solid" lineColor="#000000"/>
</box>
</style>
+ <parameter name="options" class="java.lang.Boolean" isForPrompting="false"/>
<field name="enteteLigne" class="java.lang.String"/>
<field name="entete1" class="java.lang.String"/>
<field name="entete3" class="java.lang.String"/>
<field name="entete4" class="java.lang.String"/>
<field name="index" class="java.lang.Long"/>
<summary>
- <band height="68" splitType="Stretch">
+ <band height="139" splitType="Stretch">
<crosstab columnBreakOffset="1000" ignoreWidth="false">
- <reportElement x="0" y="0" width="785" height="68"/>
+ <reportElement positionType="Float" x="0" y="0" width="785" height="68">
+ <printWhenExpression><![CDATA[$P{options}==true]]></printWhenExpression>
+ </reportElement>
<crosstabHeaderCell>
<cellContents>
<staticText>
<crosstabCell rowTotalGroup="eleve" columnTotalGroup="coeff">
<cellContents/>
</crosstabCell>
- <crosstabCell width="113" columnTotalGroup="index">
+ <crosstabCell width="113" height="14" columnTotalGroup="index">
<cellContents>
<textField isStretchWithOverflow="true">
<reportElement style="cellule_note" stretchType="RelativeToTallestObject" x="0" y="0" width="113" height="14"/>
<cellContents backcolor="#96C8FA" mode="Opaque" style="entete"/>
</crosstabCell>
</crosstab>
+ <crosstab columnBreakOffset="1000" ignoreWidth="false">
+ <reportElement positionType="Float" x="0" y="0" width="785" height="68">
+ <printWhenExpression><![CDATA[$P{options}==false]]></printWhenExpression>
+ </reportElement>
+ <crosstabHeaderCell>
+ <cellContents>
+ <staticText>
+ <reportElement style="Libelle_entete" x="0" y="0" width="85" height="14" forecolor="#000000"/>
+ <textElement textAlignment="Right"/>
+ <text><![CDATA[Matières]]></text>
+ </staticText>
+ <staticText>
+ <reportElement style="Libelle_entete" x="0" y="14" width="85" height="14" forecolor="#000000"/>
+ <textElement textAlignment="Right"/>
+ <text><![CDATA[Enseignants]]></text>
+ </staticText>
+ <staticText>
+ <reportElement style="Libelle_entete" x="0" y="28" width="85" height="14" forecolor="#000000"/>
+ <textElement textAlignment="Right"/>
+ <text><![CDATA[Sous-Matière]]></text>
+ </staticText>
+ <staticText>
+ <reportElement style="Libelle_entete" x="0" y="42" width="85" height="14" forecolor="#000000"/>
+ <textElement textAlignment="Right"/>
+ <text><![CDATA[Elèves | Coeff.]]></text>
+ </staticText>
+ </cellContents>
+ </crosstabHeaderCell>
+ <rowGroup name="eleve" width="85" totalPosition="End">
+ <bucket>
+ <bucketExpression class="java.lang.String"><![CDATA[$F{enteteLigne}]]></bucketExpression>
+ </bucket>
+ <crosstabRowHeader>
+ <cellContents backcolor="#F0F8FF" mode="Opaque" style="entete_ligne">
+ <textField>
+ <reportElement style="entete_ligne" stretchType="RelativeToBandHeight" x="0" y="0" width="85" height="14"/>
+ <textElement textAlignment="Left">
+ <font fontName="Arial" size="6" isBold="false"/>
+ </textElement>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{eleve}]]></textFieldExpression>
+ </textField>
+ </cellContents>
+ </crosstabRowHeader>
+ <crosstabTotalRowHeader>
+ <cellContents backcolor="#96C8FA" mode="Opaque">
+ <staticText>
+ <reportElement style="pied_page_texte" x="0" y="0" width="85" height="14"/>
+ <textElement textAlignment="Center"/>
+ <text><![CDATA[Moyenne]]></text>
+ </staticText>
+ <staticText>
+ <reportElement style="pied_page_texte" x="0" y="14" width="85" height="14"/>
+ <textElement textAlignment="Center"/>
+ <text><![CDATA[Moyenne Min. ]]></text>
+ </staticText>
+ <staticText>
+ <reportElement style="pied_page_texte" x="0" y="28" width="85" height="14"/>
+ <textElement textAlignment="Center"/>
+ <text><![CDATA[Moyenne Max. ]]></text>
+ </staticText>
+ </cellContents>
+ </crosstabTotalRowHeader>
+ </rowGroup>
+ <columnGroup name="index" height="0" totalPosition="End" headerPosition="Stretch">
+ <bucket>
+ <bucketExpression class="java.lang.Long"><![CDATA[$F{index}]]></bucketExpression>
+ </bucket>
+ <crosstabColumnHeader>
+ <cellContents/>
+ </crosstabColumnHeader>
+ <crosstabTotalColumnHeader>
+ <cellContents/>
+ </crosstabTotalColumnHeader>
+ </columnGroup>
+ <columnGroup name="matiere" height="14" headerPosition="Stretch">
+ <bucket>
+ <bucketExpression class="java.lang.String"><![CDATA[$F{entete1}]]></bucketExpression>
+ </bucket>
+ <crosstabColumnHeader>
+ <cellContents backcolor="#F0F8FF" mode="Opaque">
+ <textField>
+ <reportElement style="entete" x="0" y="0" width="37" height="14" forecolor="#000000"/>
+ <textElement/>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{matiere}]]></textFieldExpression>
+ </textField>
+ </cellContents>
+ </crosstabColumnHeader>
+ <crosstabTotalColumnHeader>
+ <cellContents backcolor="#FFFFFF" mode="Opaque">
+ <box>
+ <pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+ </box>
+ </cellContents>
+ </crosstabTotalColumnHeader>
+ </columnGroup>
+ <columnGroup name="prof" height="14" headerPosition="Stretch">
+ <bucket>
+ <bucketExpression class="java.lang.String"><![CDATA[$F{entete2}]]></bucketExpression>
+ </bucket>
+ <crosstabColumnHeader>
+ <cellContents>
+ <textField>
+ <reportElement style="entete" stretchType="RelativeToTallestObject" x="0" y="0" width="37" height="14"/>
+ <textElement/>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{prof}]]></textFieldExpression>
+ </textField>
+ </cellContents>
+ </crosstabColumnHeader>
+ <crosstabTotalColumnHeader>
+ <cellContents/>
+ </crosstabTotalColumnHeader>
+ </columnGroup>
+ <columnGroup name="sousMatiere" height="14" headerPosition="Stretch">
+ <bucket>
+ <bucketExpression class="java.lang.String"><![CDATA[$F{entete3}]]></bucketExpression>
+ </bucket>
+ <crosstabColumnHeader>
+ <cellContents backcolor="#F0F8FF" mode="Opaque">
+ <textField isBlankWhenNull="true">
+ <reportElement style="entete" x="0" y="0" width="37" height="14"/>
+ <textElement/>
+ <textFieldExpression class="java.lang.String"><![CDATA[($V{sousMatiere}.length()!=0) ? $V{sousMatiere}.substring(1) : ""]]></textFieldExpression>
+ </textField>
+ </cellContents>
+ </crosstabColumnHeader>
+ <crosstabTotalColumnHeader>
+ <cellContents backcolor="#BFE1FF" mode="Opaque"/>
+ </crosstabTotalColumnHeader>
+ </columnGroup>
+ <columnGroup name="coeff" height="14">
+ <bucket>
+ <bucketExpression class="java.lang.String"><![CDATA[$F{entete4}]]></bucketExpression>
+ </bucket>
+ <crosstabColumnHeader>
+ <cellContents>
+ <textField>
+ <reportElement style="entete" x="0" y="0" width="37" height="14"/>
+ <textElement/>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{coeff}]]></textFieldExpression>
+ </textField>
+ </cellContents>
+ </crosstabColumnHeader>
+ <crosstabTotalColumnHeader>
+ <cellContents/>
+ </crosstabTotalColumnHeader>
+ </columnGroup>
+ <measure name="noteMeasure" class="java.lang.String">
+ <measureExpression><![CDATA[$F{valeur}]]></measureExpression>
+ </measure>
+ <measure name="pied1" class="java.lang.String">
+ <measureExpression><![CDATA[$F{pied1}]]></measureExpression>
+ </measure>
+ <measure name="pied2" class="java.lang.String">
+ <measureExpression><![CDATA[$F{pied2}]]></measureExpression>
+ </measure>
+ <measure name="pied3" class="java.lang.String">
+ <measureExpression><![CDATA[$F{pied3}]]></measureExpression>
+ </measure>
+ <crosstabCell width="37" height="14">
+ <cellContents style="cellule_note">
+ <textField isBlankWhenNull="true">
+ <reportElement style="cellule_note" stretchType="RelativeToBandHeight" x="0" y="0" width="37" height="14"/>
+ <textElement/>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{noteMeasure}]]></textFieldExpression>
+ </textField>
+ </cellContents>
+ </crosstabCell>
+ <crosstabCell width="37" height="43" rowTotalGroup="eleve">
+ <cellContents backcolor="#96C8FA" mode="Opaque">
+ <textField>
+ <reportElement style="pied_page_texte" x="0" y="0" width="37" height="14"/>
+ <textElement textAlignment="Center"/>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{pied1}]]></textFieldExpression>
+ </textField>
+ <textField>
+ <reportElement style="pied_page_texte" x="0" y="14" width="37" height="14"/>
+ <textElement textAlignment="Center"/>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{pied2}]]></textFieldExpression>
+ </textField>
+ <textField>
+ <reportElement style="pied_page_texte" x="0" y="28" width="37" height="14"/>
+ <textElement textAlignment="Center"/>
+ <textFieldExpression class="java.lang.String"><![CDATA[$V{pied3}]]></textFieldExpression>
+ </textField>
+ </cellContents>
+ </crosstabCell>
+ <crosstabCell width="113" height="14" columnTotalGroup="matiere">
+ <cellContents backcolor="#FFFFFF" mode="Opaque" style="cellule_note"/>
+ </crosstabCell>
+ <crosstabCell width="113" height="43" rowTotalGroup="eleve" columnTotalGroup="matiere">
+ <cellContents backcolor="#96C8FA" mode="Opaque"/>
+ </crosstabCell>
+ <crosstabCell width="0" height="13" columnTotalGroup="sousMatiere">
+ <cellContents backcolor="#BFE1FF" mode="Opaque">
+ <box>
+ <pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+ </box>
+ </cellContents>
+ </crosstabCell>
+ <crosstabCell width="0" height="54" rowTotalGroup="eleve" columnTotalGroup="sousMatiere">
+ <cellContents backcolor="#BFE1FF" mode="Opaque">
+ <box>
+ <pen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+ </box>
+ </cellContents>
+ </crosstabCell>
+ <crosstabCell columnTotalGroup="prof">
+ <cellContents/>
+ </crosstabCell>
+ <crosstabCell rowTotalGroup="eleve" columnTotalGroup="prof">
+ <cellContents/>
+ </crosstabCell>
+ <crosstabCell columnTotalGroup="coeff">
+ <cellContents/>
+ </crosstabCell>
+ <crosstabCell rowTotalGroup="eleve" columnTotalGroup="coeff">
+ <cellContents/>
+ </crosstabCell>
+ <crosstabCell width="0" height="14" columnTotalGroup="index">
+ <cellContents/>
+ </crosstabCell>
+ <crosstabCell width="0" rowTotalGroup="eleve" columnTotalGroup="index">
+ <cellContents backcolor="#96C8FA" mode="Transparent" style="entete"/>
+ </crosstabCell>
+ </crosstab>
</band>
</summary>
</jasperReport>