Corriger le calcul du solde horaire
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:30:06 +00:00
parent 84b4f1326c
commit 1f23a9582a
2 changed files with 5 additions and 1 deletions

View file

@ -11,7 +11,7 @@
<div class="col-md-3"><div class="card border-primary h-100"><div class="card-body"><small>À réaliser</small><h3>{{ '%d h %02d'|format(required_minutes // 60, required_minutes % 60) }}</h3><small class="text-muted">1607 h moins pénibilité</small></div></div></div> <div class="col-md-3"><div class="card border-primary h-100"><div class="card-body"><small>À réaliser</small><h3>{{ '%d h %02d'|format(required_minutes // 60, required_minutes % 60) }}</h3><small class="text-muted">1607 h moins pénibilité</small></div></div></div>
<div class="col-md-3"><div class="card border-info h-100"><div class="card-body"><small>Prévu par calendrier</small><h3>{{ '%d h %02d'|format(planned_minutes // 60, planned_minutes % 60) }}</h3></div></div></div> <div class="col-md-3"><div class="card border-info h-100"><div class="card-body"><small>Prévu par calendrier</small><h3>{{ '%d h %02d'|format(planned_minutes // 60, planned_minutes % 60) }}</h3></div></div></div>
<div class="col-md-3"><div class="card border-success h-100"><div class="card-body"><small>Réalisé saisi</small><h3>{{ '%d h %02d'|format(actual_minutes // 60, actual_minutes % 60) }}</h3></div></div></div> <div class="col-md-3"><div class="card border-success h-100"><div class="card-body"><small>Réalisé saisi</small><h3>{{ '%d h %02d'|format(actual_minutes // 60, actual_minutes % 60) }}</h3></div></div></div>
<div class="col-md-3"><div class="card {% if variance_minutes >= 0 %}border-success{% else %}border-danger{% endif %} h-100"><div class="card-body"><small>Solde réalisé / dû</small><h3 class="{% if variance_minutes >= 0 %}text-success{% else %}text-danger{% endif %}">{{ '+' if variance_minutes >= 0 else '' }}{{ '%d h %02d'|format((variance_minutes|abs) // 60, (variance_minutes|abs) % 60) }}</h3><small>{% if variance_minutes >= 0 %}heures à récupérer{% else %}heures à faire{% endif %}</small></div></div></div> <div class="col-md-3"><div class="card {% if balance_minutes > 0 %}border-danger{% else %}border-success{% endif %} h-100"><div class="card-body"><small>Solde réalisé / dû</small><h3 class="{% if balance_minutes > 0 %}text-danger{% else %}text-success{% endif %}">{{ '%d h %02d'|format((balance_minutes|abs) // 60, (balance_minutes|abs) % 60) }}</h3><small>{% if balance_minutes > 0 %}heures à faire{% else %}heures en excédent{% endif %}</small></div></div></div>
</div> </div>
<div class="card mb-3"><div class="card-header"><strong>Récapitulatif mensuel</strong><small class="d-block text-muted">Les heures de travail prévues excluent les permanences, affichées séparément.</small></div><div class="table-responsive"><table class="table table-sm align-middle mb-0"><thead><tr><th>Mois</th><th>Travail prévu</th><th>Permanences</th><th>Retards</th><th>Heures supplémentaires</th><th>Formations</th></tr></thead><tbody>{% for item in monthly_summary %}<tr><td><strong>{{ months[item.month.month] }} {{ item.month.year }}</strong></td><td>{{ '%d h %02d'|format(item.planned // 60, item.planned % 60) }}</td><td>{{ '%d h %02d'|format(item.permanence // 60, item.permanence % 60) }}</td><td class="{% if item.retard %}text-danger{% endif %}">{{ '%d h %02d'|format(item.retard // 60, item.retard % 60) }}</td><td class="{% if item.supplementaire %}text-success{% endif %}">{{ '%d h %02d'|format(item.supplementaire // 60, item.supplementaire % 60) }}</td><td>{{ '%d h %02d'|format(item.formation // 60, item.formation % 60) }}</td></tr>{% else %}<tr><td colspan="6" class="text-muted">Aucune donnée pour cette période.</td></tr>{% endfor %}</tbody></table></div></div> <div class="card mb-3"><div class="card-header"><strong>Récapitulatif mensuel</strong><small class="d-block text-muted">Les heures de travail prévues excluent les permanences, affichées séparément.</small></div><div class="table-responsive"><table class="table table-sm align-middle mb-0"><thead><tr><th>Mois</th><th>Travail prévu</th><th>Permanences</th><th>Retards</th><th>Heures supplémentaires</th><th>Formations</th></tr></thead><tbody>{% for item in monthly_summary %}<tr><td><strong>{{ months[item.month.month] }} {{ item.month.year }}</strong></td><td>{{ '%d h %02d'|format(item.planned // 60, item.planned % 60) }}</td><td>{{ '%d h %02d'|format(item.permanence // 60, item.permanence % 60) }}</td><td class="{% if item.retard %}text-danger{% endif %}">{{ '%d h %02d'|format(item.retard // 60, item.retard % 60) }}</td><td class="{% if item.supplementaire %}text-success{% endif %}">{{ '%d h %02d'|format(item.supplementaire // 60, item.supplementaire % 60) }}</td><td>{{ '%d h %02d'|format(item.formation // 60, item.formation % 60) }}</td></tr>{% else %}<tr><td colspan="6" class="text-muted">Aucune donnée pour cette période.</td></tr>{% endfor %}</tbody></table></div></div>

View file

@ -175,6 +175,9 @@ def time_tracking():
"supplementaire": sum(item.actual_minutes or 0 for item in month_entries if item.entry_type == "supplementaire"), "supplementaire": sum(item.actual_minutes or 0 for item in month_entries if item.entry_type == "supplementaire"),
"formation": training_minutes, "formation": training_minutes,
}) })
# Solde restant selon la règle de l'agent : objectif - prévu - retards
# + heures supplémentaires + formations.
balance_minutes = config.minutes_to_work - sum(item["planned"] for item in monthly_summary) - sum(item["retard"] for item in monthly_summary) + sum(item["supplementaire"] for item in monthly_summary) + sum(item["formation"] for item in monthly_summary)
return render_template( return render_template(
"planning/time_tracking.html", year=year, period_start=period_start, period_end=period_end, time_config=config, templates=templates, "planning/time_tracking.html", year=year, period_start=period_start, period_end=period_end, time_config=config, templates=templates,
assignments=assignments, closures=closures, permanence_options=permanence_options, permanence_groups=permanence_groups, entries=entries, assignments=assignments, closures=closures, permanence_options=permanence_options, permanence_groups=permanence_groups, entries=entries,
@ -182,6 +185,7 @@ def time_tracking():
months={1: "Janvier", 2: "Février", 3: "Mars", 4: "Avril", 5: "Mai", 6: "Juin", 7: "Juillet", 8: "Août", 9: "Septembre", 10: "Octobre", 11: "Novembre", 12: "Décembre"}, months={1: "Janvier", 2: "Février", 3: "Mars", 4: "Avril", 5: "Mai", 6: "Juin", 7: "Juillet", 8: "Août", 9: "Septembre", 10: "Octobre", 11: "Novembre", 12: "Décembre"},
planned_minutes=planned, actual_minutes=actual, planned_minutes=planned, actual_minutes=actual,
required_minutes=config.minutes_to_work, variance_minutes=actual - config.minutes_to_work, required_minutes=config.minutes_to_work, variance_minutes=actual - config.minutes_to_work,
balance_minutes=balance_minutes,
monthly_summary=monthly_summary, monthly_summary=monthly_summary,
) )