Permettre des horaires différents selon l'année scolaire
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
This commit is contained in:
parent
a086103343
commit
3257c9c8f1
4 changed files with 28 additions and 4 deletions
|
|
@ -11,6 +11,7 @@ class WorkSchedule(db.Model):
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
|
user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
|
||||||
|
academic_year = db.Column(db.Integer, nullable=True, index=True)
|
||||||
|
|
||||||
day_of_week = db.Column(db.Integer)
|
day_of_week = db.Column(db.Integer)
|
||||||
start_time = db.Column(db.Time)
|
start_time = db.Column(db.Time)
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
<div class="card"><div class="card-header"><strong>Historique {{ year }}</strong></div><div class="table-responsive"><table class="table table-sm mb-0"><thead><tr><th>Date</th><th>Type</th><th>Prévu</th><th>Réalisé</th><th>Écart</th><th>Note</th></tr></thead><tbody>{% for entry in entries[:50] %}<tr><td>{{ entry.work_date.strftime('%d/%m/%Y') }}</td><td>{{ entry.entry_type }}</td><td>{{ entry.planned_minutes }} min</td><td>{{ entry.actual_minutes }} min</td><td class="{% if entry.variance_minutes < 0 %}text-danger{% elif entry.variance_minutes > 0 %}text-success{% endif %}">{{ '+' if entry.variance_minutes > 0 else '' }}{{ entry.variance_minutes }} min</td><td>{{ entry.note or '—' }}</td></tr>{% else %}<tr><td colspan="6" class="text-muted">Aucune saisie.</td></tr>{% endfor %}</tbody></table></div></div>
|
<div class="card"><div class="card-header"><strong>Historique {{ year }}</strong></div><div class="table-responsive"><table class="table table-sm mb-0"><thead><tr><th>Date</th><th>Type</th><th>Prévu</th><th>Réalisé</th><th>Écart</th><th>Note</th></tr></thead><tbody>{% for entry in entries[:50] %}<tr><td>{{ entry.work_date.strftime('%d/%m/%Y') }}</td><td>{{ entry.entry_type }}</td><td>{{ entry.planned_minutes }} min</td><td>{{ entry.actual_minutes }} min</td><td class="{% if entry.variance_minutes < 0 %}text-danger{% elif entry.variance_minutes > 0 %}text-success{% endif %}">{{ '+' if entry.variance_minutes > 0 else '' }}{{ entry.variance_minutes }} min</td><td>{{ entry.note or '—' }}</td></tr>{% else %}<tr><td colspan="6" class="text-muted">Aucune saisie.</td></tr>{% endfor %}</tbody></table></div></div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
document.querySelectorAll('form[action*="assign_time_template"]').forEach(function (form) { var input = document.createElement('input'); input.type = 'hidden'; input.name = 'year'; input.value = '{{ year }}'; form.appendChild(input); });
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
document.querySelectorAll('input[name="work_dates"][checked]').forEach(function (input) {
|
document.querySelectorAll('input[name="work_dates"][checked]').forEach(function (input) {
|
||||||
input.disabled = true;
|
input.disabled = true;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,12 @@ def time_tracking():
|
||||||
db.session.add(config)
|
db.session.add(config)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
templates = WorkScheduleTemplate.query.filter_by(user_id=current_user.id, is_active=True).order_by(WorkScheduleTemplate.id).all()
|
templates = WorkScheduleTemplate.query.filter_by(user_id=current_user.id, is_active=True).order_by(WorkScheduleTemplate.id).all()
|
||||||
assignments = {item.day_of_week: item for item in WorkSchedule.query.filter_by(user_id=current_user.id, is_active=True).all()}
|
all_assignments = WorkSchedule.query.filter_by(user_id=current_user.id, is_active=True).all()
|
||||||
|
assignments = {item.day_of_week: item for item in all_assignments if item.academic_year == year}
|
||||||
|
# Compatibilité avec les affectations créées avant le suivi par année.
|
||||||
|
for item in all_assignments:
|
||||||
|
if item.academic_year is None and item.day_of_week not in assignments:
|
||||||
|
assignments[item.day_of_week] = item
|
||||||
closures = CollegeClosure.query.filter(
|
closures = CollegeClosure.query.filter(
|
||||||
CollegeClosure.end_date >= period_start, CollegeClosure.start_date <= period_end
|
CollegeClosure.end_date >= period_start, CollegeClosure.start_date <= period_end
|
||||||
).order_by(CollegeClosure.start_date).all()
|
).order_by(CollegeClosure.start_date).all()
|
||||||
|
|
@ -265,22 +270,23 @@ def edit_time_template(id):
|
||||||
@login_required
|
@login_required
|
||||||
def assign_time_template():
|
def assign_time_template():
|
||||||
day = request.form.get("day_of_week", type=int)
|
day = request.form.get("day_of_week", type=int)
|
||||||
|
year = request.form.get("year", _current_year(), type=int)
|
||||||
template_id = request.form.get("template_id", type=int)
|
template_id = request.form.get("template_id", type=int)
|
||||||
assignment = WorkSchedule.query.filter_by(user_id=current_user.id, day_of_week=day).first()
|
assignment = WorkSchedule.query.filter_by(user_id=current_user.id, day_of_week=day, academic_year=year).first()
|
||||||
if not template_id:
|
if not template_id:
|
||||||
if assignment:
|
if assignment:
|
||||||
db.session.delete(assignment)
|
db.session.delete(assignment)
|
||||||
else:
|
else:
|
||||||
template = WorkScheduleTemplate.query.filter_by(id=template_id, user_id=current_user.id, is_active=True).first_or_404()
|
template = WorkScheduleTemplate.query.filter_by(id=template_id, user_id=current_user.id, is_active=True).first_or_404()
|
||||||
if not assignment:
|
if not assignment:
|
||||||
assignment = WorkSchedule(user_id=current_user.id, day_of_week=day)
|
assignment = WorkSchedule(user_id=current_user.id, day_of_week=day, academic_year=year)
|
||||||
db.session.add(assignment)
|
db.session.add(assignment)
|
||||||
assignment.template_id = template.id
|
assignment.template_id = template.id
|
||||||
assignment.start_time, assignment.end_time = template.start_time, template.end_time
|
assignment.start_time, assignment.end_time = template.start_time, template.end_time
|
||||||
assignment.lunch_start, assignment.lunch_end = template.lunch_start, template.lunch_end
|
assignment.lunch_start, assignment.lunch_end = template.lunch_start, template.lunch_end
|
||||||
assignment.is_active = True
|
assignment.is_active = True
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return _redirect()
|
return _redirect(year)
|
||||||
|
|
||||||
|
|
||||||
@planning_bp.route("/time/entry", methods=["POST"])
|
@planning_bp.route("/time/entry", methods=["POST"])
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
"""Associe les horaires affectés à une année scolaire."""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
revision = "fa1b2c3d4e5f"
|
||||||
|
down_revision = "f9c3d4e5f6a7"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column("work_schedules", sa.Column("academic_year", sa.Integer(), nullable=True))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_column("work_schedules", "academic_year")
|
||||||
Loading…
Reference in a new issue