Créneaux de nuit rattachés à leur journée de festival
Un créneau saisi « 00:00–01:00 » sur la carte du samedi était enregistré le samedi à 00:00 (nuit de vendredi à samedi), donc affiché la veille dans la grille des besoins. Une heure de début avant le début de journée (premier créneau type) désigne désormais la nuit qui suit : dimanche 00:00, à la suite de la soirée du samedi. Même « journée de festival » partout (validation/engine.py:day_boundary, festival_day ; miroir front lib/planning.ts:festivalDay) : écran Postes & créneaux, feuilles de poste (une seule page pour une soirée qui passe minuit) et chaînage du solveur (00h–01h enchaîne 23h–00h). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c60bc11795
commit
a6e7b6e7fb
@@ -17,7 +17,7 @@ from app.api.deps import get_edition
|
||||
from app.api.schemas import PositionSheetsRequest
|
||||
from app.auth.deps import require_coordinator
|
||||
from app.db import get_session
|
||||
from app.models import Account, Artist, Assignment, Edition, Position, Shift, Volunteer
|
||||
from app.models import Account, Artist, Assignment, DayPart, Edition, Position, Shift, Volunteer
|
||||
from app.sheets.pdf import (
|
||||
PositionDaySheet,
|
||||
SheetArtist,
|
||||
@@ -25,6 +25,7 @@ from app.sheets.pdf import (
|
||||
SheetVolunteer,
|
||||
generate_position_sheets_pdf,
|
||||
)
|
||||
from app.validation.engine import day_boundary, festival_day
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/editions/{edition_id}/position-sheets", tags=["position-sheets"]
|
||||
@@ -69,6 +70,13 @@ def generate_position_sheets(
|
||||
for vs in volunteers_by_shift.values():
|
||||
vs.sort(key=lambda v: (v.last_name, v.first_name))
|
||||
|
||||
# « Jour » = journée de festival (CLAUDE.md § 3), pas date du calendrier :
|
||||
# une soirée qui passe minuit (23h–00h, 00h–01h…) reste sur une seule
|
||||
# feuille, celle du jour où elle a commencé.
|
||||
boundary = day_boundary(
|
||||
session.exec(select(DayPart).where(DayPart.edition_id == edition.id))
|
||||
)
|
||||
|
||||
# Un jour sans aucun besoin réel (créneau 0/0 généré automatiquement,
|
||||
# jamais rempli) n'apparaît pas — évite des pages « personne affecté »
|
||||
# pour des créneaux qui ne représentent aucun besoin.
|
||||
@@ -77,7 +85,8 @@ def generate_position_sheets(
|
||||
undefined_need = shift.min_staff == 0 and shift.ideal_staff == 0
|
||||
if undefined_need and not volunteers_by_shift.get(shift.id):
|
||||
continue
|
||||
shifts_by_position_day[(shift.position_id, shift.starts_at.date())].append(shift)
|
||||
day = festival_day(shift.starts_at, boundary)
|
||||
shifts_by_position_day[(shift.position_id, day)].append(shift)
|
||||
|
||||
Referent = aliased(Volunteer)
|
||||
referent_rows = session.exec(
|
||||
|
||||
Reference in New Issue
Block a user