Aller au contenu principal

Create simplified address

POST 

/company/address/simple

Créez une nouvelle adresse de manière simplifiée en utilisant uniquement des coordonnées et des données de base.
Cet endpoint est optimisé pour les cas où les coordonnées exactes sont connues et où il est nécessaire de créer une adresse rapidement, sans la complexité des données Google Maps.

Flux d'opération :

  1. Authentification via un JWT valide
  2. Validation des champs obligatoires minimaux (lat, lng, name, company_name)
  3. Géocodage inverse automatique à partir des coordonnées
  4. Création automatique de l'adresse complète
  5. Association à l'entreprise de l'utilisateur
  6. Retour de l'adresse créée

Avantages de cet endpoint :

  • Nécessite seulement 4 champs obligatoires contre ~15 pour l'endpoint standard
  • Géocodage automatique à partir des coordonnées
  • Réutilise la logique éprouvée du système d'importation massive
  • Maintient la même qualité de données que la création normale

Cas d'utilisation typiques :

  • Applications mobiles avec GPS
  • Intégration depuis des systèmes tiers avec coordonnées
  • Création rapide depuis des cartes interactives
  • Création en masse simplifiée

Exemple de requête :

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

{
lat: 40.416775,
lng: -3.703790,
name: Siège Central,
company_name: CargoOffer SL,
phone: +34912345678,
isDefault: false
}

Exemple de réponse réussie :

\{
_id: 507f1f77bcf86cd799439011,
name: Siège Central,
company_name: CargoOffer SL,
phone: +34912345678,
street: Calle de Alcalá, 42,
city: madrid,
zipcode: 28014,
country: es,
location: \{
type: Point,
coordinates:

<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","properties":{"lat":{"type":"number","description":"Latitude en degrés décimaux (WGS84)","minimum":-90,"maximum":90,"example":40.416775},"lng":{"type":"number","description":"Longueur en degrés décimaux (WGS84)","minimum":-180,"maximum":180,"example":-3.70379},"name":{"type":"string","description":"Nom descriptif de l'adresse","minLength":3,"maxLength":100,"example":"Oficina Central"},"company_name":{"type":"string","description":"Raison sociale de la société à cette adresse","minLength":2,"maxLength":100,"example":"CargoOffer SL"},"phone":{"type":"string","description":"Téléphone de contact (facultatif, format international recommandé)","maxLength":20,"example":"+34912345678"},"isDefault":{"type":"boolean","description":"Indiquez si ce sera l'adresse principale de la société","default":false,"example":false}},"required":["lat","lng","name","company_name"],"example":{"lat":40.416775,"lng":-3.70379,"name":"Oficina Central","company_name":"CargoOffer SL","phone":"+34912345678","isDefault":false}},"example":{"lat":40.416775,"lng":-3.70379,"name":"Oficina Central","company_name":"CargoOffer SL","phone":"+34912345678","isDefault":false}}},"required":true}}
>

</RequestSchema>

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Adresse créée avec succès","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"}}},"headers":{}},"400":{"description":"Erreur de validation - Champs requis manquants ou format invalide","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["MISSING_FIELD_LAT","MISSING_FIELD_LNG","MISSING_FIELD_NAME","MISSING_FIELD_COMPANY_NAME","INVALID_COORDINATES"],"example":"MISSING_FIELD_LAT"}}}}},"headers":{}},"401":{"description":"Erreur d'authentification - Jeton invalide ou entreprise non trouvée","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["USER_NOT_FOUND","CIA_NOT_FOUND"],"example":"CIA_NOT_FOUND"}}}}},"headers":{}},"404":{"description":"Utilisateur non trouvé.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"USER_NOT_FOUND"}}}}},"headers":{}},"500":{"description":"Erreur interne du serveur","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["CANNOT_SAVE_ADDRESS","INTERNAL_ERROR"],"example":"CANNOT_SAVE_ADDRESS"}}}}},"headers":{}}}}
>

</StatusCodes>