feat: réutilisation des coordonnées déjà géocodées (domicile, insertion de trajets)
Expose les coordonnées déjà géocodées dans ProfilDto (DomicileLatitude/Longitude) et TrajetDto (DepartLatitude/Longitude, ArriveeLatitude/Longitude) afin que le Frontend les réutilise sans déclencher un nouveau géocodage BAN : - Bouton « Utiliser mon domicile » (trajet-form) : utilise désormais les coordonnées du Profil au lieu de forcer un re-géocodage. - Actions « insérer avant/après » (trajet-list) : transmettent les coordonnées déjà connues du point de fin repris au formulaire d'insertion. Le résumé mensuel (ResumeService) résout les coordonnées via le Cache_Adresses pour chaque trajet (nouvelle méthode ConstruireResumeMensuelAvecCoordonneesAsync) ; le résumé annuel reste inchangé pour éviter des lookups de cache inutiles sur une vue qui n'affiche pas le détail des trajets. Met à jour design.md et design-requirements.md (Requirements 10 et 11) pour refléter le nouveau contrat d'API.
This commit is contained in:
@@ -7,6 +7,10 @@ export interface Profil {
|
||||
matricule: string | null;
|
||||
adresseDomicile: string | null;
|
||||
domicileGeocode: boolean;
|
||||
// Coordonnées du domicile déjà géocodées (null si non résolues). Permettent de
|
||||
// transmettre les coordonnées lors de « Utiliser mon domicile » sans re-géocoder.
|
||||
domicileLatitude: number | null;
|
||||
domicileLongitude: number | null;
|
||||
}
|
||||
|
||||
/** Création / mise à jour du profil — miroir de SaveProfilDto. */
|
||||
|
||||
@@ -44,6 +44,12 @@ export interface Trajet {
|
||||
vehiculeId: number;
|
||||
puissanceFiscale: number;
|
||||
allerRetour: boolean; // information aller/retour conservée par trajet
|
||||
// Coordonnées déjà géocodées (via le Cache_Adresses), si connues ; null sinon. Permettent de
|
||||
// réutiliser l'adresse d'un trajet existant (ex. « Insérer avant/après ») sans re-géocoder.
|
||||
departLatitude?: number | null;
|
||||
departLongitude?: number | null;
|
||||
arriveeLatitude?: number | null;
|
||||
arriveeLongitude?: number | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -73,6 +73,15 @@ export interface TrajetInsertionPrefill {
|
||||
* le nouveau trajet soit rattaché à la BONNE journée (Exigences 11.1–11.4).
|
||||
*/
|
||||
date?: string | null;
|
||||
/**
|
||||
* Coordonnées du point de fin repris (adresse de départ/arrivée du Trajet_Précédent
|
||||
* ou Trajet_Suivant), si déjà géocodées. Transmises pour éviter un re-géocodage BAN
|
||||
* côté backend lors de la création du trajet inséré.
|
||||
*/
|
||||
departLatitude?: number | null;
|
||||
departLongitude?: number | null;
|
||||
arriveeLatitude?: number | null;
|
||||
arriveeLongitude?: number | null;
|
||||
}
|
||||
|
||||
/** Identifie lequel des deux champs adresse est concerné. */
|
||||
@@ -427,9 +436,23 @@ export class TrajetFormComponent implements OnInit, OnDestroy {
|
||||
// Backend) : source fiable, pas d'avertissement de coordonnées manquantes.
|
||||
if (this.prefill.adresseDepart?.trim()) {
|
||||
this.sourceFiableDepart.set(true);
|
||||
// Coordonnées déjà géocodées transmises par le conteneur (trajet-list) si connues :
|
||||
// on les mémorise pour éviter un re-géocodage BAN côté backend.
|
||||
if (this.prefill.departLatitude != null && this.prefill.departLongitude != null) {
|
||||
this.coordDepart.set({
|
||||
latitude: this.prefill.departLatitude,
|
||||
longitude: this.prefill.departLongitude
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.prefill.adresseArrivee?.trim()) {
|
||||
this.sourceFiableArrivee.set(true);
|
||||
if (this.prefill.arriveeLatitude != null && this.prefill.arriveeLongitude != null) {
|
||||
this.coordArrivee.set({
|
||||
latitude: this.prefill.arriveeLatitude,
|
||||
longitude: this.prefill.arriveeLongitude
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.prefill.vehiculeId != null) {
|
||||
this.vehiculeId = this.prefill.vehiculeId;
|
||||
@@ -509,20 +532,20 @@ export class TrajetFormComponent implements OnInit, OnDestroy {
|
||||
if (!adresse) {
|
||||
return;
|
||||
}
|
||||
// On remplit le libellé du domicile ; les coordonnées seront résolues côté
|
||||
// backend via le Cache_Adresses ou la BAN (Exigence 2.4). On ne dispose pas
|
||||
// des coordonnées du domicile dans le profil exposé au frontend.
|
||||
const controle = champ === 'depart' ? this.departCtrl : this.arriveeCtrl;
|
||||
controle.setValue(adresse);
|
||||
controle.markAsTouched();
|
||||
if (champ === 'depart') {
|
||||
this.coordDepart.set(null);
|
||||
this.sourceFiableDepart.set(true);
|
||||
this.suggestionsDepart.set([]);
|
||||
} else {
|
||||
this.coordArrivee.set(null);
|
||||
this.sourceFiableArrivee.set(true);
|
||||
this.suggestionsArrivee.set([]);
|
||||
// On remplit le libellé du domicile ET on transmet ses coordonnées déjà
|
||||
// géocodées (exposées dans le Profil), afin d'éviter un re-géocodage BAN côté
|
||||
// backend à chaque trajet. Si le domicile n'a pas été géocodé (coordonnées
|
||||
// absentes), on retombe sur null : le Backend résoudra alors l'adresse (Exigence 2.4).
|
||||
const profil = this.profil();
|
||||
const coord =
|
||||
profil?.domicileLatitude != null && profil?.domicileLongitude != null
|
||||
? { latitude: profil.domicileLatitude, longitude: profil.domicileLongitude }
|
||||
: null;
|
||||
// `appliquerAdresse` remplit le champ, mémorise les coordonnées, marque la source
|
||||
// comme fiable et vide les suggestions du champ concerné.
|
||||
this.appliquerAdresse(champ, adresse, coord);
|
||||
|
||||
if (champ === 'arrivee') {
|
||||
// Confort de saisie : un trajet dont l'arrivée est le domicile est typiquement
|
||||
// un retour. On pré-remplit le commentaire avec « Retour domicile » s'il est
|
||||
// encore vide (on ne remplace jamais un commentaire déjà saisi).
|
||||
|
||||
@@ -343,9 +343,15 @@ export class TrajetListComponent {
|
||||
*/
|
||||
insererApres(trajet: Trajet): void {
|
||||
const pointDeFin = trajet.allerRetour ? trajet.adresseDepart : trajet.adresseArrivee;
|
||||
// Coordonnées du point de fin (déjà géocodées si connues) : évite un re-géocodage
|
||||
// BAN côté backend pour une adresse déjà résolue.
|
||||
const latitudeFin = trajet.allerRetour ? trajet.departLatitude : trajet.arriveeLatitude;
|
||||
const longitudeFin = trajet.allerRetour ? trajet.departLongitude : trajet.arriveeLongitude;
|
||||
this.insertAfter.emit({
|
||||
prefill: {
|
||||
adresseDepart: pointDeFin,
|
||||
departLatitude: latitudeFin,
|
||||
departLongitude: longitudeFin,
|
||||
vehiculeId: trajet.vehiculeId,
|
||||
// Rattache l'insertion à la JOURNÉE du trajet concerné (et non à la date de
|
||||
// la carte), pour éviter les erreurs de saisie de date.
|
||||
@@ -369,11 +375,19 @@ export class TrajetListComponent {
|
||||
// Point de fin du trajet courant : son arrivée, ou son départ s'il est aller/retour
|
||||
// (le véhicule est alors revenu à son point d'origine).
|
||||
const finCourant = courant.allerRetour ? courant.adresseDepart : courant.adresseArrivee;
|
||||
// Coordonnées du point de fin du trajet courant et du départ du trajet suivant
|
||||
// (déjà géocodées si connues) : évite un re-géocodage BAN côté backend.
|
||||
const latitudeFinCourant = courant.allerRetour ? courant.departLatitude : courant.arriveeLatitude;
|
||||
const longitudeFinCourant = courant.allerRetour ? courant.departLongitude : courant.arriveeLongitude;
|
||||
this.insertBetween.emit({
|
||||
prefill: {
|
||||
adresseDepart: finCourant,
|
||||
departLatitude: latitudeFinCourant,
|
||||
departLongitude: longitudeFinCourant,
|
||||
// Le trajet suivant part toujours de son adresse de départ (indépendant de l'A/R).
|
||||
adresseArrivee: suivant.adresseDepart,
|
||||
arriveeLatitude: suivant.departLatitude,
|
||||
arriveeLongitude: suivant.departLongitude,
|
||||
vehiculeId: courant.vehiculeId,
|
||||
// Journée du trajet courant (insertion au sein de la même journée).
|
||||
date: (courant.date ?? '').slice(0, 10)
|
||||
|
||||
Reference in New Issue
Block a user