SchotzIAD KM Tracker : suivi des trajets kilométriques (Angular + .NET 8)
Application complète de saisie et de suivi des trajets kilométriques avec calcul de distance routière (OpenRouteService), barème kilométrique, résumés et régularisation annuelle. Backend (ASP.NET Core .NET 8, EF Core, SQLite) : - Trajets (CRUD, réordonnancement, insertion), calcul de distance ORS avec fallback Haversine, géométrie d'itinéraire stockée par trajet, recalcul en masse. - Profil, véhicules (avec dénomination), carnet d'adresses nommées, cache d'adresses. - Barème kilométrique : tranches multiples par puissance fiscale, borne max exclusive avec 'illimité' (KmMax nullable), coefficient à 3 décimales, recopie du dernier barème connu. - Résumés mensuel/annuel, montants réglés, régularisation, export PDF. Frontend (Angular 22, zoneless + signals) : - Consultation par jour, navigation temporelle synchronisée, carte Leaflet, formulaire de trajet (adresses nommées, domicile, autocomplétion BAN). - Détection de changement zoneless (indépendante de zone.js). Hébergement : Docker Compose (nginx + backend), scripts run-dev.sh / run-docker.sh.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using TrajetKmTracker.Api.Models.DTOs;
|
||||
using TrajetKmTracker.Api.Services;
|
||||
using TrajetKmTracker.Api.Services.Exceptions;
|
||||
|
||||
namespace TrajetKmTracker.Api.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoints des résumés kilométriques : Résumé_Mensuel et Résumé_Annuel.
|
||||
/// Le filtre par véhicule est optionnel (Véhicule_Courant utilisé si omis).
|
||||
/// Les paramètres hors bornes (mois ∉ [1, 12], année ∉ [2000, 2100]) sont
|
||||
/// rejetés avec un code HTTP 400 (Exigences 3.6, 3.8, 4.1).
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/resumes")]
|
||||
public class ResumesController : ControllerBase
|
||||
{
|
||||
private readonly IResumeService _resumeService;
|
||||
|
||||
public ResumesController(IResumeService resumeService)
|
||||
{
|
||||
_resumeService = resumeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retourne le Résumé_Mensuel d'un (année, mois) pour le véhicule indiqué
|
||||
/// (Véhicule_Courant si <paramref name="vehiculeId"/> est omis). Rejette (400)
|
||||
/// les paramètres hors bornes (Exigences 3.6, 3.8).
|
||||
/// </summary>
|
||||
[HttpGet("mensuel/{annee:int}/{mois:int}")]
|
||||
[ProducesResponseType(typeof(ResumeMensuelDto), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<ResumeMensuelDto>> GetResumeMensuel(
|
||||
int annee, int mois, [FromQuery] int? vehiculeId, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var resume = await _resumeService.GetResumeMensuelAsync(annee, mois, vehiculeId, cancellationToken);
|
||||
return Ok(resume);
|
||||
}
|
||||
catch (ResumeParametreInvalideException ex)
|
||||
{
|
||||
return Problem(detail: ex.Message, statusCode: StatusCodes.Status400BadRequest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retourne le Résumé_Annuel d'une année (12 résumés mensuels) pour le véhicule
|
||||
/// indiqué (Véhicule_Courant si <paramref name="vehiculeId"/> est omis). Rejette (400)
|
||||
/// une année hors bornes (Exigences 3.6, 4.1).
|
||||
/// </summary>
|
||||
[HttpGet("annuel/{annee:int}")]
|
||||
[ProducesResponseType(typeof(ResumeAnnuelDto), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<ResumeAnnuelDto>> GetResumeAnnuel(
|
||||
int annee, [FromQuery] int? vehiculeId, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var resume = await _resumeService.GetResumeAnnuelAsync(annee, vehiculeId, cancellationToken);
|
||||
return Ok(resume);
|
||||
}
|
||||
catch (ResumeParametreInvalideException ex)
|
||||
{
|
||||
return Problem(detail: ex.Message, statusCode: StatusCodes.Status400BadRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user