Aller au contenu principal

Update address

PUT 

/company/address/

Met à jour les données d'une adresse existante identifiée par le champ '_id' dans le corps de la requête.

Flux d'opération :

  1. Authentification via un JWT valide
  2. Validation du champ '_id' obligatoire dans le corps
  3. Vérification que l'adresse appartient à la société de l'utilisateur
  4. Validation des champs et des formats
  5. Traitement des données Google Maps (géocodage inverse)
  6. Si is_default=true, désactive toute adresse principale existante
  7. Persistance des changements en base de données
  8. Retour de l'adresse mise à jour

Caractéristiques importantes :

  • L'ID de l'adresse doit être envoyé dans le champ '_id' du corps
  • Requiert un token JWT valide avec des permissions administrateur/éditeur
  • Champ 'name' obligatoire (3-100 caractères)
  • Les données Google Maps doivent inclure :
    • formatted_address : Adresse complète formatée
    • geometry.location : Coordonnées {lat, lng}
  • Si is_default=true, désactive toute adresse principale existante

Exemple de requête :

PUT /company/address
Authorization: Bearer {token}
Content-Type: application/json

{
_id: 507f1f77bcf86cd799439011,
name: Entrepôt Logistique Mis à Jour,
company_name: CargoOffer SL,
phone: +34912345678,
addressGoogleMaps: {
formatted_address: Calle de la Logística, 123, 28045 Madrid, España,
geometry: {
location: {
lat: 40.123456,
lng: -3.987654
}
}
},
is_default: false
}

Exemple de réponse réussie :

\{
_id: 507f1f77bcf86cd799439011,
name: Entrepôt Logistique Mis à Jour,
company_name: CargoOffer SL,
phone: +34912345678,
street: Calle de

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>

<ParamsDetails
parameters={[]}
>

</ParamsDetails>

<RequestSchema
title={"Body"}
body={{"content":{"application/json":{"schema":{"type":"object","description":"Données requises pour créer une nouvelle adresse","required":["name","addressGoogleMaps"],"properties":{"_id":{"type":"string","description":"Identifiant unique de l'adresse à mettre à jour","example":"507f1f77bcf86cd799439011"},"name":{"type":"string","description":"Nom descriptif de l'adresse (3-100 caractères)","example":"Almacén Logístico"},"company_name":{"type":"string","description":"Dénomination sociale de la société à cette adresse (facultatif)","example":"CargoOffer SL"},"phone":{"type":"string","description":"Numéro de téléphone au format international (facultatif)","example":"+34912345678"},"addressGoogleMaps":{"type":"object","description":"Données Google Maps pour la géolocalisation","properties":{"formatted_address":{"type":"string","description":"Adresse complète formatée","example":"Calle de la Logística, 123, 28045 Madrid, España"},"geometry":{"type":"object","properties":{"location":{"type":"object","properties":{"lat":{"type":"number","format":"float","description":"Latitude en degrés décimaux","example":40.123456},"lng":{"type":"number","format":"float","description":"Longueur en degrés décimaux","example":-3.987654}},"required":["lat","lng"]}},"required":["location"]}},"required":["formatted_address","geometry"]},"is_default":{"type":"boolean","description":"Indiquez si ce sera l'adresse principale de l'entreprise.","example":false}},"example":{"_id":"507f1f77bcf86cd799439011","name":"Almacén Logístico","company_name":"CargoOffer SL","phone":"+34912345678","addressGoogleMaps":{"formatted_address":"Calle de la Logística, 123, 28045 Madrid, España","geometry":{"location":{"lat":40.123456,"lng":-3.987654}}},"is_default":false},"title":"CreateAddressRequest"},"example":{"_id":"64917511ef73c37ccae60bc4","name":"Almacén Logístico Actualizado","company_name":"CargoOffer SL","phone":"+34912345678","addressGoogleMaps":{"formatted_address":"Calle de la Logística, 123, 28045 Madrid, España","geometry":{"location":{"lat":40.123456,"lng":-3.987654}}},"isDefault":false}}},"required":true}}
>

</RequestSchema>

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Adresse mise à jour correctement","content":{"application/json":{"schema":{"type":"object","description":"Représente une adresse physique associée à une entreprise pour les opérations de chargement/déchargement.\n**Fonctionnalité** : - Point d'origine (ETL - Heure de chargement prévue) ou de destination (ETD - Heure de livraison prévue) dans les enchères de transport - Stockée par entreprise et réutilisable dans de multiples opérations - Géocodée automatiquement via l'API Google Maps lors de la création - Validée par rapport à son utilisation dans des enchères/livraisons actives avant suppression\n**Modèle** : `src/features/models/address.model.js`\n**Contrôleur** : `src/features/company/address/controller.js`","properties":{"_id":{"type":"string","description":"Identifiant unique MongoDB de l'adresse (24 caractères hexadécimaux). Généré automatiquement par le système lors de la création de l'adresse. Utilisé comme référence dans les modèles d'enchères (auction.etl_address, auction.etd_address) et de livraisons (delivery.etl_address, delivery.etd_address).","pattern":"^[a-f0-9]{24}$","example":"507f1f77bcf86cd799439011"},"name":{"type":"string","description":"Nom descriptif ou alias personnalisé de l'emplacement attribué par l'utilisateur. Utilisé pour une identification rapide dans les listes et la sélection d'adresses. **Obligatoire** - Minimum 3 caractères, maximum 100. Exemples : Entrepôt Nord, Siège Social, Client ABC - Usine Madrid","minLength":3,"maxLength":100,"example":"Oficina Central"},"company_name":{"type":"string","description":"Raison sociale ou nom commercial de l'entreprise à cette adresse. **Requis** - Apparaît sur les documents officiels (CMR, contrats). Peut différer du nom de la société principale s'il s'agit d'une adresse client/fournisseur. Minimum 2 caractères, maximum 100.","minLength":2,"maxLength":100,"example":"CargoOffer SL"},"phone":{"type":"string","description":"Numéro de téléphone de contact pour la coordination logistique à cette adresse. **Optionnel** - Format international recommandé (E.164 avec +code pays). Utilisé par les transporteurs pour confirmer l'arrivée et résoudre les incidents. Validé avec le motif : 9-15 chiffres.","pattern":"^\\+?[0-9]{9,15}$","maxLength":20,"example":"+34912345678"},"street":{"type":"string","description":"Rue complète avec numéro, générée automatiquement à partir de addressGoogleMaps. Format : Nom de Rue, Numéro. Utilisé pour l'affichage et les exportations CSV. Champ hérité combiné (voir street_address + street_number pour les champs séparés).","example":"Calle Ejemplo 123"},"street_address":{"type":"string","description":"Nom de la rue sans numéro (champ séparé). Parsé depuis la réponse de l'API Google Maps (composant route).","example":"Calle de Alcalá"},"street_number":{"type":"string","description":"Numéro de rue en tant que champ indépendant. Parsé à partir de la réponse de l'API Google Maps (composant street_number).","example":"42"},"city":{"type":"string","description":"Ville normalisée en minuscules, extraite automatiquement des coordonnées via l'API Google Maps Geocoding. Utilisée dans les filtres de recherche et le regroupement d'adresses par zone. Type : locality ou administrative_area_level_2 de Google Maps.","example":"madrid"},"state":{"type":"string","description":"État, communauté autonome ou région administrative (normalisé en minuscules). Extrait de administrative_area_level_1 de Google Maps. Optionnel - Peut être vide dans les pays sans division régionale.","example":"comunidad de madrid"},"zipcode":{"type":"string","description":"Code postal selon le format du pays correspondant. Extrait du composant postal_code de l'API Google Maps. Utilisé pour les validations de zone et les calculs de tarifs.","example":"28045"},"country":{"type":"string","description":"Code pays ISO 3166-1 alpha-2 en MAJUSCULES (2 lettres). **Critique** pour : validation du TaxID, format d'immatriculation, calcul des tarifs, restrictions ADR. Extrait du composant country (short_name) de l'API Google Maps. Doit correspondre aux pays actifs dans la collection 'countries'.","pattern":"^[A-Z]{2}$","example":"ES"},"neighborhood":{"type":"string","description":"Quartier ou zone à l'intérieur de la ville (facultatif). Tiré de neighborhood ou sublocality de Google Maps. Utilisé pour la précision dans les grandes zones urbaines.","example":"centro"},"province":{"type":"string","description":"Province ou division administrative provinciale. Tiré de administrative_area_level_2 de Google Maps (dans les pays ayant des provinces). Optionnel - Principalement pertinent en Espagne, Italie, etc.","example":"madrid"},"location":{"type":"object","description":"Coordonnées géographiques au format GeoJSON Point selon la norme RFC 7946. Système de référence : WGS84 (EPSG:4326). **REQUIS** - Utilisé par MongoDB pour les requêtes géospatiales ($near, $geoWithin). **CRITIQUE** : L'ordre dans le tableau `coordinates` est [longitude, latitude] (X, Y) - NE PAS inverser. Utilisé pour : le calcul des distances, les itinéraires optimaux, la validation des zones de service.","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"],"description":"Type de géométrie GeoJSON. Doit toujours être Point pour les adresses. Les autres types (LineString, Polygon) ne sont pas valides dans ce contexte.","example":"Point"},"coordinates":{"type":"array","description":"Tableau de deux nombres : [longitude, latitude] en degrés décimaux. **ORDRE CRITIQUE** : longitude d'abord (axe X, -180 à 180), latitude ensuite (axe Y, -90 à 90). Exemple valide : [-3.70379, 40.416775] = 3.70° Ouest, 40.41° Nord (Madrid). **ERREUR FRÉQUENTE** : Inverser l'ordre entraîne des calculs incorrects. Utilisé dans : model.find({location: {$near: {$geometry: {type: 'Point', coordinates: [lng, lat]}}}})","items":{"type":"number"},"minItems":2,"maxItems":2,"example":[-3.70379,40.416775]}}},"placeId":{"type":"string","description":"Identifiant Google Place unique et immuable pour cet emplacement. Utilisé pour : géocodage inversé, validation des modifications, obtention de détails actualisés. Format : Chaîne alphanumérique commençant généralement par ChIJ. Conservé pour éviter les géocodages répétés (économie de coûts API).","example":"ChIJi-AoYTIoQg0RnHvWosEVABQ"},"name_address":{"type":"string","description":"Adresse complète formatée générée par Google Maps (formatted_address). Inclut : rue, numéro, code postal, ville, pays au format local. Utilisée pour : l'affichage aux utilisateurs, les exportations, les documents officiels. Non modifiable manuellement - régénérée automatiquement lors de la mise à jour des coordonnées.","example":"Calle de Alcalá, 42, 28014 Madrid, España"},"isDefault":{"type":"boolean","description":"Indiquez si c'est l'adresse principale/par défaut de l'entreprise. **Contrainte** : Une seule adresse par entreprise peut avoir isDefault=true. Lorsque vous définissez isDefault=true sur une adresse, l'adresse précédente avec ce drapeau passe automatiquement à false. Utilisée dans : autocomplétion de formulaires, adresse par défaut pour les nouvelles enchères. Également stockée dans : company.address_default (référence au _id de cette adresse).","default":false,"example":true},"can_be_deleted":{"type":"boolean","description":"Drapeau calculé dynamiquement au moment de la requête (non stocké en base de données). **false** : L'adresse est référencée dans des enchères ou des livraisons actives (statut != annulé/livré). **true** : L'adresse n'a aucune dépendance et peut être supprimée en toute sécurité. Calculé dans : controller.get() en vérifiant le comptage des auction/delivery où etl_address ou etd_address == this._id. Empêche : la suppression accidentelle d'adresses en cours d'utilisation, ce qui créerait des données orphelines.","example":false},"destinations":{"type":"array","description":"Tableau de destinations fréquentes avec des itinéraires précalculés depuis cette adresse. **Optimisation** : Évite de recalculer des itinéraires répétitifs, améliore les performances lors de la recherche d'enchères. Rempli par : un cron nocturne ou à la demande pour des paires d'adresses fréquentes. Utilisé dans : le endpoint /company/minimal pour les calculs de coût/distance sans appeler une API externe. Structure : [{address: ObjectId, minimalRoute: {distance: Number(km), timeCost: Number(min)}}]","items":{"type":"object","properties":{"address":{"type":"string","description":"ObjectId de l'adresse de destination","example":"507f1f77bcf86cd799439012"},"minimalRoute":{"type":"object","properties":{"distance":{"type":"number","description":"Distance calculée en kilomètres (via API d'itinéraires)","example":523.7},"timeCost":{"type":"number","description":"Temps de trajet estimé en minutes (en tenant compte de la vitesse moyenne)","example":360}}}}}}},"required":["_id","name","location","isDefault","can_be_deleted"],"title":"Address"},"example":{"status":200,"data":{"location":{"type":"Point","coordinates":[-8.995213099999999,42.5668541]},"_id":"64917511ef73c37ccae60bc4","name":"Almacén Logístico Actualizado","company_name":"CargoOffer SL","phone":"+34912345678","city":"ribeira","state":"galicia","country":"españa","zipcode":"15960","street_number":"117","street_address":"Estrada Deán Norte","province":"A Coruña","placeId":"ChIJLdx3TsE5Lw0Rmh7qsvQUqII","name_address":"Estrada Deán Norte, 117, 15960 Ribeira, A Coruña, España","destinations":[],"createdAt":"2024-10-02T18:24:37.606Z","deleted":false}}}},"headers":{}},"400":{"description":"Données d'entrée invalides","headers":{}},"401":{"description":"Non autorisé (jeton JWT invalide ou manquant)","headers":{}},"403":{"description":"NON_AUTORISÉ - L'adresse n'appartient pas à cette entreprise","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"NOT_ALLOWED"}}}}},"headers":{}},"404":{"description":"Adresse non trouvée","headers":{}}}}
>

</StatusCodes>