Marketplace, CSS, iCal and a lot of things... #4

Closed
valentin wants to merge 59 commits from dev into main
6 changed files with 151 additions and 40 deletions
Showing only changes of commit c022f4438b - Show all commits

View File

@ -0,0 +1,21 @@
# Generated by Django 5.0.4 on 2024-04-15 00:12
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('colloscope', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='periode',
options={'ordering': ['debut']},
),
migrations.RemoveField(
model_name='appartenance',
name='periode',
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 5.0.4 on 2024-04-15 00:14
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('colloscope', '0002_alter_periode_options_remove_appartenance_periode'),
]
operations = [
migrations.RemoveField(
model_name='creneau',
name='classe',
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 5.0.4 on 2024-04-15 00:17
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('colloscope', '0003_remove_creneau_classe'),
]
operations = [
migrations.AddField(
model_name='matiere',
name='classe',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='colloscope.classe'),
preserve_default=False,
),
]

View File

@ -1,5 +1,17 @@
from math import ceil
from datetime import date, datetime, timedelta
from django.db import models
from django.db.models import F
from django.db.models import F, Q
calendrier = {
"C" : [
( date(2023, 10, 21), date(2023, 11, 6) ),
( date(2023, 12, 23), date(2024, 1, 8) ),
( date(2024, 2, 10), date(2024, 2, 26) ),
( date(2024, 4, 6), date(2024, 4, 22) ),
]
}
class Lycee(models.Model):
uai = models.CharField(max_length=10)
@ -19,7 +31,40 @@ class Periode(models.Model):
debut = models.DateField()
fin = models.DateField()
class Meta:
ordering = ["debut"]
def no_semaine(self, jour):
zone = self.classe.lycee.vacances
vacances = calendrier[zone]
jour0 = self.classe.jour_zero
n = 1 + ((jour - jour0).days)//7
for debut, fin in vacances:
if jour > debut:
n -= 2
return n
def range_semaines(self):
return range(self.no_semaine(self.debut), self.no_semaine(self.fin)+1)
def date_debut_sem(self, n):
zone = self.classe.lycee.vacances
vacances = calendrier[zone]
jour0 = self.classe.jour_zero
jour = jour0 + (n-1) * timedelta(weeks=1)
for debut, _ in vacances:
if jour >= debut:
jour += 2*timedelta(weeks=1)
return jour
class Matiere(models.Model):
classe = models.ForeignKey(Classe, on_delete=models.CASCADE)
libelle = models.CharField(max_length=100)
code = models.CharField(max_length=20)
@ -35,6 +80,9 @@ class Groupe(models.Model):
critere = models.ForeignKey(Critere, null=True, on_delete=models.CASCADE)
libelle = models.CharField(max_length=100)
def membres(self):
return Etudiant.objects.filter(id__in=Appartenance.objects.filter(groupe=self))
class Etudiant(models.Model):
class Meta:
ordering=["classe", "nom", "prenom"]
@ -46,19 +94,18 @@ class Etudiant(models.Model):
#lv2 = models.ForeignKey(Matiere, on_delete=models.CASCADE)
def appartient(self, groupe, periode):
return Appartenance.objects.filter(periode=periode, etudiant=self, groupe=groupe).exists()
return Appartenance.objects.filter(etudiant=self, groupe=groupe).exists()
def groupe_du_critere(self, periode, critere):
if isinstance(critere, str):
critere = Critere.objects.get(periode=periode, libelle=critere)
return Appartenance.objects.get(periode=periode, etudiant=self, groupe__critere=critere).groupe
return Appartenance.objects.get(groupe__periode=periode, etudiant=self, groupe__critere=critere).groupe
def groupe_de_colle(self, periode):
return self.groupe_du_critere(periode, "colle")
class Appartenance(models.Model):
periode = models.ForeignKey(Periode, on_delete=models.CASCADE)
etudiant = models.ForeignKey(Etudiant, on_delete=models.CASCADE)
groupe = models.ForeignKey(Groupe, on_delete=models.CASCADE)
@ -67,12 +114,11 @@ class Colleur(models.Model):
nom = models.CharField(max_length=100)
class Creneau(models.Model):
classe = models.ForeignKey(Classe, on_delete=models.CASCADE)
periode = models.ForeignKey(Periode, on_delete=models.CASCADE)
jour = models.IntegerField()
heure = models.TimeField()
duree = models.DurationField()
salle = models.CharField(max_length=20)
periode = models.ForeignKey(Periode, on_delete=models.CASCADE)
matiere = models.ForeignKey(Matiere, on_delete=models.CASCADE)
colleur = models.ForeignKey(Colleur, on_delete=models.CASCADE)
est_colle = models.BooleanField()
@ -83,6 +129,21 @@ class Rotation(models.Model):
groupes = models.ManyToManyField(Groupe)
semaine = models.IntegerField()
def effectif(self):
n_base = sum(len(groupe.membres()) for groupe in self.groupes.all())
n_plus = len(Amendement.objects.filter(est_positif=True, rotation=self))
n_moins = len(Amendement.objects.filter(est_positif=False, rotation=self))
return n_base + n_plus - n_moins
def est_pleine(self):
eff = self.effectif()
if eff>self.creneau.capacite:
raise models.IntegrityError
else:
return eff==self.creneau.capacite
class Amendement(models.Model):
est_positif = models.BooleanField()
rotation = models.ForeignKey(Rotation, on_delete=models.CASCADE)

View File

@ -1,29 +1,11 @@
from datetime import date, timedelta
from colloscope.models import Etudiant, Critere, Classe
from colloscope.models import Etudiant, Critere, Classe, Rotation, Periode, Creneau
from fpdf import FPDF
from fpdf.fonts import FontFace
from fpdf.enums import TableCellFillMode
calendrier_zoneC = date(2023, 9, 18), [
( date(2023, 10, 21), date(2023, 11, 6) ),
( date(2023, 12, 23), date(2024, 1, 8) ),
( date(2024, 2, 10), date(2024, 2, 26) ),
( date(2024, 4, 6), date(2024, 4, 22) ),
]
def jour_of_sem(n, cal):
sem_1, vac = cal
jour = sem_1 + (n-1) * timedelta(weeks=1)
for (debut, fin) in vac:
if jour >= debut:
jour += 2*timedelta(weeks=1)
return jour
"""
etudiants = [
['Aboujaib', 'Alexandre', 4, 'A', '', ''],
@ -124,7 +106,12 @@ class PDF(FPDF):
row.cell("??") # LV2
def table_colloscope(self, creneaux, semaines, rotations):
def table_colloscope(self, periode):
semaines = periode.range_semaines()
lundis = [ periode.date_debut_sem(n) for n in semaines ]
creneaux = Creneau.objects.filter(periode=periode)
jours = ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
with self.table(
align="LEFT",
width=190,
@ -140,24 +127,29 @@ class PDF(FPDF):
header.cell(str(sem), align="CENTER")
header2 = table.row()
for sem in semaines:
header2.cell(jour_of_sem(sem, calendrier_zoneC).strftime("%d/%m/%y"), align="CENTER")
for lundi in lundis:
header2.cell(lundi.strftime("%d/%m/%y"), align="CENTER")
for i, tr in enumerate(creneaux):
matiere, jour, heure, colleur, salle = tr
for i, c in enumerate(creneaux):
matiere = c.matiere
jour = c.jour
heure = c.heure
colleur = c.colleur
salle = c.salle
row = table.row()
row.cell(matiere)
row.cell(jour)
row.cell(heure)
row.cell(colleur)
row.cell(matiere.libelle)
row.cell(jours[jour])
row.cell(heure.strftime("%H:%M"))
row.cell("{} {}".format("M." if colleur.civilite=="M" else "Mme", colleur.nom.upper()))
row.cell(salle)
for s in semaines:
for rot in rotations:
if rot[2] == i and rot[0] == s:
row.cell(str(rot[1]), align="CENTER")
break
if Rotation.objects.filter(creneau=c, semaine=s).exists():
rot = Rotation.objects.get(creneau=c, semaine=s)
groupes = rot.groupes
row.cell(", ".join(g.libelle for g in groupes.all()), align="CENTER")
else:
row.cell()
@ -195,8 +187,8 @@ def generate(periode):
base_y = pdf.t_margin + 10
pdf.set_y(base_y)
pdf.liste_eleves(periode)
#pdf.set_y(base_y)
#pdf.table_colloscope(creneaux, semaines, rotations)
pdf.set_y(base_y)
pdf.table_colloscope(periode)
#pdf.y += 3
#pdf.table_travaux()

BIN
test.pdf

Binary file not shown.