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.
88 lines
5.7 KiB
C#
88 lines
5.7 KiB
C#
using TrajetKmTracker.Api.Models.DTOs;
|
|
|
|
namespace TrajetKmTracker.Api.Services;
|
|
|
|
/// <summary>
|
|
/// Logique métier de gestion des Trajets. Cette interface couvre pour l'instant la
|
|
/// création (tâche 8.2) ; la modification, la suppression et le réordonnancement
|
|
/// (tâche 8.5) l'étendront ultérieurement.
|
|
/// </summary>
|
|
public interface ITrajetService
|
|
{
|
|
/// <summary>
|
|
/// Crée un Trajet à partir de <paramref name="dto"/> :
|
|
/// <list type="bullet">
|
|
/// <item>parse la date au format JJ/MM/AAAA (la validation de forme est faite par le validateur MVC) ;</item>
|
|
/// <item>associe le véhicule : <c>VehiculeId</c> fourni sinon le véhicule courant à la date
|
|
/// du trajet, en copiant sa <c>PuissanceFiscale</c> (dénormalisation, Exigence 10.14) ;</item>
|
|
/// <item>calcule la distance via <see cref="IDistanceCalculator"/> (BAN puis ORS, fallback Haversine) ;</item>
|
|
/// <item>met en cache les adresses résolues via <see cref="IAdresseCacheService"/> ;</item>
|
|
/// <item>attribue la position en fin de journée (<c>max(Position)+1.0</c>) ;</item>
|
|
/// <item>persiste le Trajet en transaction. Lorsque la distance n'a pas pu être calculée,
|
|
/// le Trajet est tout de même persisté avec une Distance nulle et un avertissement (Exigence 2.4).</item>
|
|
/// </list>
|
|
/// </summary>
|
|
/// <param name="dto">Données de création transmises par le contrôleur (déjà validées côté MVC).</param>
|
|
/// <param name="cancellationToken">Jeton d'annulation.</param>
|
|
/// <returns>Le <see cref="TrajetCreationResult"/> (trajet créé + éventuel avertissement).</returns>
|
|
/// <exception cref="Exceptions.VehiculeNotFoundException">
|
|
/// Si aucun véhicule n'est applicable à la date du trajet et qu'aucun <c>VehiculeId</c> n'est fourni.
|
|
/// </exception>
|
|
Task<TrajetCreationResult> CreateAsync(CreateTrajetDto dto, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Modifie un Trajet existant à partir de <paramref name="dto"/> :
|
|
/// <list type="bullet">
|
|
/// <item>lève <see cref="Exceptions.TrajetNotFoundException"/> (404) si le Trajet est introuvable
|
|
/// (Exigence 5.6) ;</item>
|
|
/// <item>recalcule la Distance <b>uniquement</b> si au moins une adresse a changé (comparaison sur
|
|
/// le texte d'adresse normalisé) ou si le Trajet avait une Distance nulle et que les nouvelles
|
|
/// adresses deviennent résolubles (Exigences 5.2, 5.9, 5.10) ; sinon les autres champs (commentaire,
|
|
/// véhicule, date) sont mis à jour <b>sans</b> recalcul de distance (Exigence 5.3) ;</item>
|
|
/// <item>en cas d'échec du recalcul (coordonnées connues mais calcul impossible), annule la
|
|
/// modification (rollback) et lève <see cref="Exceptions.DistanceRecalculException"/> en préservant
|
|
/// les données existantes du Trajet (Exigence 5.8) ;</item>
|
|
/// <item>met en cache les adresses résolues (Exigences 6.7, 6.8) ;</item>
|
|
/// <item>persiste la modification en transaction.</item>
|
|
/// </list>
|
|
/// </summary>
|
|
/// <param name="id">Identifiant du Trajet à modifier.</param>
|
|
/// <param name="dto">Données de modification (déjà validées côté MVC).</param>
|
|
/// <param name="cancellationToken">Jeton d'annulation.</param>
|
|
/// <returns>Le <see cref="TrajetUpdateResult"/> (trajet mis à jour + éventuel avertissement).</returns>
|
|
/// <exception cref="Exceptions.TrajetNotFoundException">Si le Trajet n'existe pas.</exception>
|
|
/// <exception cref="Exceptions.DistanceRecalculException">Si le recalcul de la distance échoue.</exception>
|
|
/// <exception cref="Exceptions.VehiculeNotFoundException">
|
|
/// Si le <c>VehiculeId</c> fourni est introuvable, ou qu'aucun véhicule n'est applicable à la date.
|
|
/// </exception>
|
|
Task<TrajetUpdateResult> UpdateAsync(int id, UpdateTrajetDto dto, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Supprime un Trajet existant de manière transactionnelle (Exigence 5.5).
|
|
/// Lève <see cref="Exceptions.TrajetNotFoundException"/> (404) si le Trajet est introuvable (Exigence 5.6).
|
|
/// </summary>
|
|
/// <param name="id">Identifiant du Trajet à supprimer.</param>
|
|
/// <param name="cancellationToken">Jeton d'annulation.</param>
|
|
/// <exception cref="Exceptions.TrajetNotFoundException">Si le Trajet n'existe pas.</exception>
|
|
Task DeleteAsync(int id, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Applique un réordonnancement manuel des trajets d'une journée : met à jour uniquement la
|
|
/// <c>Position</c> des trajets fournis via <see cref="ITrajetRepository.ReordonnerAsync"/>,
|
|
/// sans altérer leurs autres champs (Exigence 11.9). Les identifiants inconnus sont ignorés.
|
|
/// </summary>
|
|
/// <param name="dto">Nouvelles positions des trajets à réordonner.</param>
|
|
/// <param name="cancellationToken">Jeton d'annulation.</param>
|
|
Task ReordonnerAsync(ReordonnerTrajetsDto dto, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Recalcule la Distance (et la géométrie d'itinéraire mise en cache) de TOUS les trajets
|
|
/// via <see cref="IDistanceCalculator"/> (BAN + ORS, fallback Haversine), indépendamment de
|
|
/// tout changement d'adresse. Utile pour « réparer » des distances calculées en mode dégradé
|
|
/// (ex. clé ORS invalide → distances à vol d'oiseau) une fois ORS de nouveau opérationnel.
|
|
/// Chaque trajet est traité de façon indépendante : un échec sur l'un n'interrompt pas les autres.
|
|
/// </summary>
|
|
/// <returns>Le nombre de trajets dont la distance a effectivement été recalculée.</returns>
|
|
Task<int> RecalculerToutesLesDistancesAsync(CancellationToken cancellationToken = default);
|
|
}
|