Pular para o conteúdo principal

Update address

PUT 

/company/address/

Atualiza os dados de um endereço existente identificado pelo campo '_id' no body da solicitação.

Fluxo de operação:

  1. Autenticação via JWT válido
  2. Validação do campo '_id' obrigatório no body
  3. Verificação de que o endereço pertence à empresa do usuário
  4. Validação de campos e formatos
  5. Processamento de dados do Google Maps (geocodificação reversa)
  6. Se is_default=true, desmarca qualquer endereço principal existente
  7. Persistência das alterações na base de dados
  8. Retorno do endereço atualizado

Características importantes:

  • O ID do endereço deve ser enviado no campo '_id' do body
  • Requer token JWT válido com permissões de administrador/editor
  • Campo 'name' obrigatório (3-100 caracteres)
  • Dados do Google Maps devem incluir:
    • formatted_address: Endereço completo formatado
    • geometry.location: Coordenadas {lat, lng}
  • Se is_default=true, desmarca qualquer endereço principal existente

Exemplo de solicitação:

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

{
_id: 507f1f77bcf86cd799439011,
name: Armazém Logístico Atualizado,
company_name: CargoOffer SL,
phone: +34912345678,
addressGoogleMaps: {
formatted_address: Calle de la Logística, 123, 28045 Madrid, Espanha,
geometry: {
location: {
lat: 40.123456,
lng: -3.987654
}
}
},
is_default: false
}

Exemplo de resposta bem-sucedida:

\{
_id: 507f1f77bcf86cd799439011,
name: Armazém Logístico Atualizado,
company_name: CargoOffer SL,
phone: +34912345678,
street: Calle de la

<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":"Dados necessários para criar um novo endereço","required":["name","addressGoogleMaps"],"properties":{"_id":{"type":"string","description":"ID único do endereço a ser atualizado","example":"507f1f77bcf86cd799439011"},"name":{"type":"string","description":"Nome descritivo do endereço (3-100 caracteres)","example":"Almacén Logístico"},"company_name":{"type":"string","description":"Razão social da empresa neste endereço (opcional)","example":"CargoOffer SL"},"phone":{"type":"string","description":"Telefone de contato com formato internacional (opcional)","example":"+34912345678"},"addressGoogleMaps":{"type":"object","description":"Dados do Google Maps para geolocalização","properties":{"formatted_address":{"type":"string","description":"Endereço completo formatado","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 em graus decimais","example":40.123456},"lng":{"type":"number","format":"float","description":"Comprimento em graus decimais","example":-3.987654}},"required":["lat","lng"]}},"required":["location"]}},"required":["formatted_address","geometry"]},"is_default":{"type":"boolean","description":"Indica se este será o endereço principal da empresa","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":"Endereço atualizado corretamente","content":{"application/json":{"schema":{"type":"object","description":"Representa um endereço físico associado a uma empresa para operações de carga/descarga.\n**Funcionalidade**: - Ponto de origem (ETL - Tempo Esperado de Carregamento) ou destino (ETD - Tempo Esperado de Entrega) em leilões de transporte - Armazenado por empresa e reutilizável em múltiplas operações - Geocodificado automaticamente via Google Maps API ao criar - Validado contra uso em leilões/entregas ativas antes de excluir\n**Modelo**: `src/features/models/address.model.js`\n**Controlador**: `src/features/company/address/controller.js`","properties":{"_id":{"type":"string","description":"Identificador único MongoDB do endereço (24 caracteres hexadecimais). Gerado automaticamente pelo sistema ao criar o endereço. Utilizado como referência nos modelos de leilões (auction.etl_address, auction.etd_address) e entregas (delivery.etl_address, delivery.etd_address).","pattern":"^[a-f0-9]{24}$","example":"507f1f77bcf86cd799439011"},"name":{"type":"string","description":"Nome descritivo ou apelido personalizado da localização atribuído pelo usuário. Usado para identificação rápida em listas e seleção de endereços. **Obrigatório** - Mínimo de 3 caracteres, máximo de 100. Exemplos: Armazém Norte, Escritório Central, Cliente ABC - Fábrica Madrid","minLength":3,"maxLength":100,"example":"Oficina Central"},"company_name":{"type":"string","description":"Razão social ou nome comercial da empresa nesta localização. **Obrigatório** - Aparece em documentos oficiais (CMR, contratos). Pode diferir do nome da empresa principal se for um endereço de cliente/fornecedor. Mínimo de 2 caracteres, máximo de 100.","minLength":2,"maxLength":100,"example":"CargoOffer SL"},"phone":{"type":"string","description":"Número de telefone de contato para coordenação logística neste endereço. **Opcional** - Formato internacional recomendado (E.164 com +código do país). Usado por transportadoras para confirmar a chegada e resolver incidentes. Validado com padrão: 9-15 dígitos.","pattern":"^\\+?[0-9]{9,15}$","maxLength":20,"example":"+34912345678"},"street":{"type":"string","description":"Rua completa com número, gerada automaticamente a partir de addressGoogleMaps. Formato: 'Nome da Rua, Número'. Usado em visualização e exportações CSV. Campo legado combinado (ver street_address + street_number para separados).","example":"Calle Ejemplo 123"},"street_address":{"type":"string","description":"Nome da rua sem número (campo separado). Parseado da resposta da API do Google Maps (componente de rota).","example":"Calle de Alcalá"},"street_number":{"type":"string","description":"Número da rua como campo independente. Extraído da resposta da API do Google Maps (componente street_number).","example":"42"},"city":{"type":"string","description":"Cidade normalizada em minúsculas, extraída automaticamente de coordenadas via Google Maps Geocoding API. Usada em filtros de busca e agrupamento de endereços por zona. Tipo: locality ou administrative_area_level_2 do Google Maps.","example":"madrid"},"state":{"type":"string","description":"Estado, comunidade autónoma ou região administrativa (normalizado em minúsculas). Extraído de administrative_area_level_1 do Google Maps. Opcional - Pode estar vazio em países sem divisão regional.","example":"comunidad de madrid"},"zipcode":{"type":"string","description":"Código postal conforme ao formato do país correspondente. Extraído do componente postal_code da API do Google Maps. Utilizado em validações de zona e cálculos de tarifas.","example":"28045"},"country":{"type":"string","description":"Código do país ISO 3166-1 alpha-2 em MAIÚSCULAS (2 letras). **Crítico** para: validação de TaxID, formato de matrícula, cálculo de tarifas, restrições ADR. Extraído do componente de país (short_name) da API do Google Maps. Deve corresponder aos países ativos na collection 'countries'.","pattern":"^[A-Z]{2}$","example":"ES"},"neighborhood":{"type":"string","description":"Bairro ou zona dentro da cidade (opcional). Extraído de neighborhood ou sublocality do Google Maps. Usado para precisão em grandes zonas urbanas.","example":"centro"},"province":{"type":"string","description":"Província ou divisão administrativa provincial. Extraído de administrative_area_level_2 do Google Maps (em países com províncias). Opcional - Relevante principalmente na Espanha, Itália, etc.","example":"madrid"},"location":{"type":"object","description":"Coordenadas geográficas no formato GeoJSON Point conforme ao padrão RFC 7946. Sistema de referência: WGS84 (EPSG:4326). **OBRIGATÓRIO** - Usado pelo MongoDB para consultas geoespaciais ($near, $geoWithin). **CRÍTICO**: A ordem no array coordinates é [longitude, latitude] (X, Y) - NÃO inverter. Usado em: cálculo de distâncias, rotas ótimas, validação de zonas de serviço.","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"],"description":"Tipo de geometria GeoJSON. Deve ser sempre Point para endereços. Outros tipos (LineString, Polygon) não são válidos neste contexto.","example":"Point"},"coordinates":{"type":"array","description":"Array de dois números: [longitude, latitude] em graus decimais. **ORDEM CRÍTICA**: longitude primeiro (eixo X, -180 a 180), latitude segundo (eixo Y, -90 a 90). Exemplo válido: [-3.70379, 40.416775] = 3.70° Oeste, 40.41° Norte (Madrid). **ERRO COMUM**: Inverter a ordem causa cálculos incorretos. Usado em: 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":"Identificador único e imutável do Google Place para esta localização. Usado para: geocodificação reversa, validação de alterações, obtenção de detalhes atualizados. Formato: String alfanumérica que geralmente começa com ChIJ. Persistido para evitar geocodificações repetidas (economia de custos de API).","example":"ChIJi-AoYTIoQg0RnHvWosEVABQ"},"name_address":{"type":"string","description":"Endereço completo formatado gerado pelo Google Maps (formatted_address). Inclui: rua, número, código postal, cidade, país no formato local. Usado em: exibição para usuários, exportações, documentos oficiais. Não editável manualmente - regenerado automaticamente ao atualizar coordenadas.","example":"Calle de Alcalá, 42, 28014 Madrid, España"},"isDefault":{"type":"boolean","description":"Indica se este é o endereço principal/padrão da empresa. **Restrição**: Só pode haver um endereço com isDefault=true por empresa. Ao definir isDefault=true em um endereço, o anterior com este flag é automaticamente alterado para false. Usado em: preenchimento automático de formulários, endereço padrão em novos leilões. Também armazenado em: company.address_default (referência ao _id deste endereço).","default":false,"example":true},"can_be_deleted":{"type":"boolean","description":"Flag calculado dinamicamente no momento da consulta (não armazenado no banco de dados). **false**: O endereço está referenciado em leilões ou entregas ativas (status != canceled/delivered). **true**: O endereço não tem dependências e pode ser excluído com segurança. Calculado em: controller.get() verificando a contagem de auction/delivery onde etl_address ou etd_address == this._id Previne: exclusão acidental de endereços em uso que causaria dados órfãos.","example":false},"destinations":{"type":"array","description":"Array de destinos frequentes com rotas pré-calculadas a partir deste endereço. **Otimização**: Evita recálculo de rotas repetitivas, melhora desempenho na busca de leilões. Populado em: cron noturno ou sob demanda para pares de endereços frequentes. Usado em: endpoint /company/minimal para cálculos de custo/distância sem chamar API externa. Estrutura: [{address: ObjectId, minimalRoute: {distance: Number(km), timeCost: Number(min)}}]","items":{"type":"object","properties":{"address":{"type":"string","description":"ObjectId do endereço de destino","example":"507f1f77bcf86cd799439012"},"minimalRoute":{"type":"object","properties":{"distance":{"type":"number","description":"Distância calculada em quilômetros (via API de rotas)","example":523.7},"timeCost":{"type":"number","description":"Tempo estimado de viagem em minutos (considerando velocidade média)","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":"Dados de entrada inválidos","headers":{}},"401":{"description":"Não autorizado (token JWT inválido ou ausente)","headers":{}},"403":{"description":"NÃO_PERMITIDO - O endereço não pertence a esta empresa","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"NOT_ALLOWED"}}}}},"headers":{}},"404":{"description":"Endereço não encontrado","headers":{}}}}
>

</StatusCodes>