chore: fix python style violations
Co-authored-by: OpenAI/GPT-5.6-Terra <vibecoder@antoineve.me> Co-authored-by: OpenAI/GPT-5.6-Luna <vibecoder@antoineve.me> Co-authored-by: MiniMax/MiniMax-M3 <vibecoder@antoineve.me> Co-authored-by: DeepSeek/DeepSeek-v4-Flash <vibecoder@antoineve.me>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import os
|
||||
|
||||
import sqlalchemy as sa
|
||||
import tomllib
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
import tomllib
|
||||
import os
|
||||
import sqlalchemy as sa
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
@@ -10,6 +11,7 @@ db = SQLAlchemy()
|
||||
def _migrate_db(app):
|
||||
"""Applique les migrations de schéma manquantes (pas d'Alembic)."""
|
||||
import sqlite3
|
||||
|
||||
db_path = os.path.join(app.instance_path, "worklog.db")
|
||||
if not os.path.exists(db_path):
|
||||
return # Nouvelle DB, create_all() s'en charge
|
||||
@@ -25,27 +27,40 @@ def _migrate_db(app):
|
||||
engine = db.engine
|
||||
if "motor_vehicle_id" not in columns:
|
||||
with engine.connect() as conn:
|
||||
conn.execute(sa.text(
|
||||
"ALTER TABLE work_entries ADD COLUMN motor_vehicle_id VARCHAR(64)"
|
||||
))
|
||||
conn.execute(
|
||||
sa.text("ALTER TABLE work_entries ADD COLUMN motor_vehicle_id VARCHAR(64)")
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
|
||||
_JOURS_FR = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"]
|
||||
_MOIS_FR = ["", "janvier", "février", "mars", "avril", "mai", "juin",
|
||||
"juillet", "août", "septembre", "octobre", "novembre", "décembre"]
|
||||
_MOIS_FR = [
|
||||
"",
|
||||
"janvier",
|
||||
"février",
|
||||
"mars",
|
||||
"avril",
|
||||
"mai",
|
||||
"juin",
|
||||
"juillet",
|
||||
"août",
|
||||
"septembre",
|
||||
"octobre",
|
||||
"novembre",
|
||||
"décembre",
|
||||
]
|
||||
|
||||
|
||||
_DAY_TYPE_LABELS = {
|
||||
"WORK": "Travail",
|
||||
"TT": "Télétravail",
|
||||
"GARDE": "Garde",
|
||||
"ASTREINTE": "Astreinte",
|
||||
"FORMATION": "Formation",
|
||||
"RTT": "RTT",
|
||||
"CONGE": "Congé",
|
||||
"MALADE": "Maladie",
|
||||
"FERIE": "Férié",
|
||||
"WORK": "Travail",
|
||||
"TT": "Télétravail",
|
||||
"GARDE": "Garde",
|
||||
"ASTREINTE": "Astreinte",
|
||||
"FORMATION": "Formation",
|
||||
"RTT": "RTT",
|
||||
"CONGE": "Congé",
|
||||
"MALADE": "Maladie",
|
||||
"FERIE": "Férié",
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +70,6 @@ def _day_type_fr(code):
|
||||
|
||||
def _date_fr(d):
|
||||
"""Formate une date en français : 'mercredi 11 mars 2026'."""
|
||||
from datetime import date as date_type
|
||||
jour = _JOURS_FR[d.weekday()]
|
||||
mois = _MOIS_FR[d.month]
|
||||
return f"{jour} {d.day} {mois} {d.year}"
|
||||
@@ -66,7 +80,9 @@ def create_app(config_path=None):
|
||||
|
||||
os.makedirs(app.instance_path, exist_ok=True)
|
||||
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{os.path.join(app.instance_path, 'worklog.db')}"
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = (
|
||||
f"sqlite:///{os.path.join(app.instance_path, 'worklog.db')}"
|
||||
)
|
||||
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
||||
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "dev-secret-change-in-prod")
|
||||
|
||||
@@ -86,6 +102,7 @@ def create_app(config_path=None):
|
||||
from app.routes.dashboard import bp as dashboard_bp
|
||||
from app.routes.entries import bp as entries_bp
|
||||
from app.routes.reports import bp as reports_bp
|
||||
|
||||
app.register_blueprint(dashboard_bp)
|
||||
app.register_blueprint(entries_bp)
|
||||
app.register_blueprint(reports_bp)
|
||||
|
||||
@@ -1,34 +1,40 @@
|
||||
from app import db
|
||||
from app.models import WorkEntry, LeaveBalance
|
||||
import sqlalchemy as sa
|
||||
from datetime import date
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from app import db
|
||||
from app.models import LeaveBalance, WorkEntry
|
||||
|
||||
|
||||
def compute_leave_used(year: int) -> dict[str, int]:
|
||||
start = date(year, 1, 1)
|
||||
end = date(year, 12, 31)
|
||||
|
||||
conges = db.session.scalar(
|
||||
sa.select(sa.func.count()).where(
|
||||
WorkEntry.date.between(start, end),
|
||||
WorkEntry.day_type == "CONGE",
|
||||
conges = (
|
||||
db.session.scalar(
|
||||
sa.select(sa.func.count()).where(
|
||||
WorkEntry.date.between(start, end),
|
||||
WorkEntry.day_type == "CONGE",
|
||||
)
|
||||
)
|
||||
) or 0
|
||||
or 0
|
||||
)
|
||||
|
||||
rtt = db.session.scalar(
|
||||
sa.select(sa.func.count()).where(
|
||||
WorkEntry.date.between(start, end),
|
||||
WorkEntry.day_type == "RTT",
|
||||
rtt = (
|
||||
db.session.scalar(
|
||||
sa.select(sa.func.count()).where(
|
||||
WorkEntry.date.between(start, end),
|
||||
WorkEntry.day_type == "RTT",
|
||||
)
|
||||
)
|
||||
) or 0
|
||||
or 0
|
||||
)
|
||||
|
||||
return {"conges": conges, "rtt": rtt}
|
||||
|
||||
|
||||
def get_or_create_balance(year: int) -> LeaveBalance:
|
||||
balance = db.session.scalar(
|
||||
sa.select(LeaveBalance).where(LeaveBalance.year == year)
|
||||
)
|
||||
balance = db.session.scalar(sa.select(LeaveBalance).where(LeaveBalance.year == year))
|
||||
if balance is None:
|
||||
balance = LeaveBalance(year=year)
|
||||
db.session.add(balance)
|
||||
|
||||
@@ -32,7 +32,9 @@ def compute_co2_grams(km_by_vehicle: dict[str, int], vehicles: dict) -> float:
|
||||
return total
|
||||
|
||||
|
||||
def compute_frais_reels(total_km_moteur: float, tranches: list[dict], electric: bool = False) -> float:
|
||||
def compute_frais_reels(
|
||||
total_km_moteur: float, tranches: list[dict], electric: bool = False
|
||||
) -> float:
|
||||
"""
|
||||
Calcule les frais réels fiscaux selon le barème kilométrique.
|
||||
km_max = 0 signifie "pas de limite" (dernière tranche).
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from app import db
|
||||
from datetime import date, time, datetime
|
||||
from datetime import date, datetime, time
|
||||
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy.orm as so
|
||||
|
||||
from app import db
|
||||
|
||||
|
||||
class WorkEntry(db.Model):
|
||||
__tablename__ = "work_entries"
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from flask import Blueprint, render_template
|
||||
from datetime import date, timedelta
|
||||
|
||||
import sqlalchemy as sa
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
from app import db
|
||||
from app.models import WorkEntry
|
||||
from app.business.time_calc import minutes_to_str, work_minutes_reference
|
||||
from app.business.travel_calc import compute_km_for_entry, compute_co2_grams
|
||||
from app.business.leave_calc import compute_leave_used, get_or_create_balance
|
||||
from app.config_loader import get_vehicles, get_journeys
|
||||
from app.business.time_calc import minutes_to_str, work_minutes_reference
|
||||
from app.business.travel_calc import compute_co2_grams, compute_km_for_entry
|
||||
from app.config_loader import get_journeys, get_vehicles
|
||||
from app.models import WorkEntry
|
||||
|
||||
bp = Blueprint("dashboard", __name__)
|
||||
|
||||
@@ -45,9 +47,7 @@ def index():
|
||||
balance = get_or_create_balance(year)
|
||||
used = compute_leave_used(year)
|
||||
|
||||
today_entry = db.session.scalar(
|
||||
sa.select(WorkEntry).where(WorkEntry.date == today)
|
||||
)
|
||||
today_entry = db.session.scalar(sa.select(WorkEntry).where(WorkEntry.date == today))
|
||||
|
||||
return render_template(
|
||||
"dashboard.html",
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash
|
||||
from datetime import date, time
|
||||
|
||||
import sqlalchemy as sa
|
||||
from flask import Blueprint, flash, redirect, render_template, request, url_for
|
||||
|
||||
from app import db
|
||||
from app.models import WorkEntry, TimeSlot
|
||||
from app.config_loader import get_journeys, get_motor_vehicles, day_types_without_journey, journey_has_motor
|
||||
from app.config_loader import (
|
||||
day_types_without_journey,
|
||||
get_journeys,
|
||||
get_motor_vehicles,
|
||||
journey_has_motor,
|
||||
)
|
||||
from app.models import TimeSlot, WorkEntry
|
||||
|
||||
bp = Blueprint("entries", __name__, url_prefix="/entries")
|
||||
|
||||
@@ -22,9 +29,7 @@ DAY_TYPES = [
|
||||
|
||||
@bp.route("/")
|
||||
def list_entries():
|
||||
entries = db.session.scalars(
|
||||
sa.select(WorkEntry).order_by(WorkEntry.date.desc())
|
||||
).all()
|
||||
entries = db.session.scalars(sa.select(WorkEntry).order_by(WorkEntry.date.desc())).all()
|
||||
return render_template("entry_list.html", entries=entries)
|
||||
|
||||
|
||||
@@ -51,9 +56,7 @@ def entry_form(entry_id=None):
|
||||
journey_profile_id = None
|
||||
|
||||
if entry is None:
|
||||
existing = db.session.scalar(
|
||||
sa.select(WorkEntry).where(WorkEntry.date == entry_date)
|
||||
)
|
||||
existing = db.session.scalar(sa.select(WorkEntry).where(WorkEntry.date == entry_date))
|
||||
if existing:
|
||||
flash(f"Une entrée existe déjà pour le {entry_date}.", "error")
|
||||
return redirect(url_for("entries.entry_form"))
|
||||
@@ -72,11 +75,13 @@ def entry_form(entry_id=None):
|
||||
ends = request.form.getlist("end_time")
|
||||
for s, e in zip(starts, ends):
|
||||
if s and e:
|
||||
db.session.add(TimeSlot(
|
||||
entry=entry,
|
||||
start_time=time.fromisoformat(s),
|
||||
end_time=time.fromisoformat(e),
|
||||
))
|
||||
db.session.add(
|
||||
TimeSlot(
|
||||
entry=entry,
|
||||
start_time=time.fromisoformat(s),
|
||||
end_time=time.fromisoformat(e),
|
||||
)
|
||||
)
|
||||
|
||||
db.session.commit()
|
||||
flash("Entrée enregistrée.", "success")
|
||||
|
||||
@@ -1,19 +1,30 @@
|
||||
from flask import Blueprint, render_template, request
|
||||
from datetime import date
|
||||
from collections import defaultdict
|
||||
from datetime import date
|
||||
|
||||
import sqlalchemy as sa
|
||||
from flask import Blueprint, render_template, request
|
||||
|
||||
from app import db
|
||||
from app.business.time_calc import count_day_types, minutes_to_str, monthly_stats
|
||||
from app.business.travel_calc import compute_co2_grams, compute_frais_reels, compute_km_for_entry
|
||||
from app.config_loader import get_bareme, get_journeys, get_vehicles
|
||||
from app.models import WorkEntry
|
||||
from app.business.travel_calc import compute_km_for_entry, compute_co2_grams, compute_frais_reels
|
||||
from app.business.time_calc import count_day_types, monthly_stats, minutes_to_str
|
||||
from app.config_loader import get_vehicles, get_journeys, get_bareme
|
||||
|
||||
bp = Blueprint("reports", __name__, url_prefix="/reports")
|
||||
|
||||
MONTHS_FR = {
|
||||
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",
|
||||
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",
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +84,9 @@ def index():
|
||||
"km_by_vehicle": month_km,
|
||||
"km_total": sum(month_km.values()),
|
||||
"median_daily_str": minutes_to_str(stats["median_daily_min"]) if month_entries else "–",
|
||||
"median_weekly_str": minutes_to_str(stats["median_weekly_min"]) if month_entries else "–",
|
||||
"median_weekly_str": minutes_to_str(stats["median_weekly_min"])
|
||||
if month_entries
|
||||
else "–",
|
||||
}
|
||||
|
||||
return render_template(
|
||||
|
||||
Reference in New Issue
Block a user