Afficher les heures prévues et réalisées au calendrier
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run

This commit is contained in:
root 2026-08-20 20:47:28 +00:00
parent d16aefc3d8
commit 923f3a31a5
2 changed files with 28 additions and 4 deletions

View file

@ -23,7 +23,7 @@ def index():
from datetime import date, timedelta from datetime import date, timedelta
from calendar import monthrange from calendar import monthrange
from ..core.services.planning_service import PlanningService from ..core.services.planning_service import PlanningService
from ..core.models.planning import PlanningDay, PlanningItem, ClosureWorkDay from ..core.models.planning import PlanningDay, PlanningItem, ClosureWorkDay, WorkSchedule, TimeEntry, PersonalLeave
from ..core.models.settings import AppSettings from ..core.models.settings import AppSettings
from ..core.services.planning_service import get_french_public_holidays from ..core.services.planning_service import get_french_public_holidays
@ -53,6 +53,11 @@ def index():
CollegeClosure.end_date >= display_start CollegeClosure.end_date >= display_start
).all() ).all()
permanence_dates = {item.work_date for item in ClosureWorkDay.query.filter(ClosureWorkDay.work_date >= display_start, ClosureWorkDay.work_date <= display_end).all()} permanence_dates = {item.work_date for item in ClosureWorkDay.query.filter(ClosureWorkDay.work_date >= display_start, ClosureWorkDay.work_date <= display_end).all()}
permanence_map = {item.work_date: item for item in ClosureWorkDay.query.filter(ClosureWorkDay.work_date >= display_start, ClosureWorkDay.work_date <= display_end).all()}
assignments = {item.day_of_week: item for item in WorkSchedule.query.filter_by(user_id=current_user.id, is_active=True).all()}
time_entries = {item.work_date: item for item in TimeEntry.query.filter_by(user_id=current_user.id).filter(TimeEntry.work_date >= display_start, TimeEntry.work_date <= display_end).all()}
personal_leaves = PersonalLeave.query.filter(PersonalLeave.user_id == current_user.id, PersonalLeave.end_date >= display_start, PersonalLeave.start_date <= display_end).all()
leave_dates = {leave.start_date + timedelta(days=offset) for leave in personal_leaves for offset in range((leave.end_date - leave.start_date).days + 1)}
holiday_dates = {item[0] for item in get_french_public_holidays(year)} holiday_dates = {item[0] for item in get_french_public_holidays(year)}
if mode == 'school': if mode == 'school':
holiday_dates |= {item[0] for item in get_french_public_holidays(year + 1)} holiday_dates |= {item[0] for item in get_french_public_holidays(year + 1)}
@ -139,8 +144,24 @@ def index():
for day in range(1, days_in_month + 1): for day in range(1, days_in_month + 1):
d = date(actual_year, month, day) d = date(actual_year, month, day)
vacation = is_vacation(d) vacation = is_vacation(d)
leave = leave_dates.get(d) leave = d in leave_dates
weekday = d.weekday() weekday = d.weekday()
planned_minutes = 0
permanence = permanence_map.get(d)
if permanence:
planned_minutes = max((permanence.end_time.hour * 60 + permanence.end_time.minute) - (permanence.start_time.hour * 60 + permanence.start_time.minute), 0)
if permanence.lunch_start and permanence.lunch_end:
planned_minutes -= (permanence.lunch_end.hour * 60 + permanence.lunch_end.minute) - (permanence.lunch_start.hour * 60 + permanence.lunch_start.minute)
elif not holiday_dates.__contains__(d) and not leave and not vacation and weekday < 5:
assignment = assignments.get(weekday)
if assignment:
source = assignment.template if assignment.template and assignment.template.is_active else assignment
planned_minutes = max((source.end_time.hour * 60 + source.end_time.minute) - (source.start_time.hour * 60 + source.start_time.minute), 0)
if source.lunch_start and source.lunch_end:
planned_minutes -= (source.lunch_end.hour * 60 + source.lunch_end.minute) - (source.lunch_start.hour * 60 + source.lunch_start.minute)
entry = time_entries.get(d)
actual_minutes = entry.actual_minutes if entry else 0
fmt = lambda minutes: f"{minutes // 60}h{minutes % 60:02d}"
week.append({ week.append({
'day': day, 'day': day,
@ -150,8 +171,10 @@ def index():
'vacation_name': vacation, 'vacation_name': vacation,
'is_holiday': d in holiday_dates, 'is_holiday': d in holiday_dates,
'is_permanence': d in permanence_dates, 'is_permanence': d in permanence_dates,
'is_leave': leave is not None, 'is_leave': leave,
'leave_type': leave.availability_type if leave else None, 'leave_type': 'congé' if leave else None,
'worked_hours': fmt(actual_minutes),
'planned_hours': fmt(planned_minutes),
'events': events_by_date.get(d, []), 'events': events_by_date.get(d, []),
}) })

View file

@ -118,6 +118,7 @@
title="{{ day_info.vacation_name if day_info.vacation_name else '' }}"> title="{{ day_info.vacation_name if day_info.vacation_name else '' }}">
{{ day_info.day }} {{ day_info.day }}
</a> </a>
<small class="d-block text-nowrap {% if td_class == 'table-dark' %}text-white{% endif %}" title="Heures réalisées / prévues">{{ day_info.worked_hours }} / {{ day_info.planned_hours }}</small>
{% if day_info.events %} {% if day_info.events %}
<div class="mt-1 d-flex flex-column gap-1"> <div class="mt-1 d-flex flex-column gap-1">
{% for event in day_info.events[:3] %} {% for event in day_info.events[:3] %}