Skip to content

Sistema de Selección de Departamentos y Municipios de Colombia

Este sistema proporciona una interfaz optimizada para seleccionar departamentos y municipios de Colombia con funcionalidad de búsqueda avanzada.

Características especificas

  • Datos Oficiales: Basado en información del DANE (Departamento Administrativo Nacional de Estadística)
  • Búsqueda Avanzada: Permite buscar departamentos y municipios escribiendo parte del nombre
  • Selección Dependiente: Los municipios se filtran automáticamente según el departamento seleccionado
  • Interfaz Moderna: Utiliza Select2 para una experiencia de usuario superior
  • Responsive: Se adapta a diferentes tamaños de pantalla
  • Fácil Integración: Se inicializa automáticamente en formularios existentes

Archivos del Sistema

public/
├── js/
│   ├── departamentos-municipios.json    # Datos de departamentos y municipios
│   └── departamentos-municipios.js      # Lógica de funcionamiento
└── css/
    └── departamentos-municipios.css     # Estilos personalizados

Uso Básico

1. Incluir las dependencias en tu vista

<!-- Select2 CSS -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<!-- CSS personalizado -->
<link href="{{ asset('css/departamentos-municipios.css') }}" rel="stylesheet" />

<!-- jQuery (requerido para Select2) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Select2 JS -->
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<!-- Script de Departamentos y Municipios -->
<script src="{{ asset('js/departamentos-municipios.js') }}"></script>

2. Crear los elementos HTML

<div class="form-group">
    <label for="departamento">Departamento</label>
    <select class="form-control" id="departamento" name="departamento" required>
        <option value="" disabled selected>Seleccione un departamento</option>
    </select>
</div>

<div class="form-group">
    <label for="ciudad">Municipio/Ciudad</label>
    <select class="form-control" id="ciudad" name="ciudad" required>
        <option value="" disabled selected>Seleccione primero un departamento</option>
    </select>
</div>

3. Inicialización Automática

El sistema se inicializa automáticamente cuando: - Se carga la página - Se abre un modal - Se completa una petición AJAX

Para inicialización manual:

window.initDepartamentosMunicipios('#departamento', '#ciudad');

Uso Avanzado

Configuración Manual de Selects

// Configurar un par específico de selects
window.departamentosMunicipios.setupCustomSelects('#mi_departamento', '#mi_ciudad');

// Poblar solo departamentos
window.departamentosMunicipios.populateDepartamentos('#departamento_select');

// Poblar municipios para un departamento específico
window.departamentosMunicipios.populateMunicipios('#ciudad_select', 'Antioquia');

Obtener Información Adicional

// Obtener código DANE de un municipio
const codigo = window.departamentosMunicipios.getCodigoDane('Antioquia', 'Medellín');
console.log(codigo); // "05001"

// Obtener información completa
const info = window.departamentosMunicipios.getInfoCompleta('Antioquia', 'Medellín');
console.log(info);
/*
{
    departamento: { codigo: "05", nombre: "Antioquia" },
    municipio: { codigo: "05001", nombre: "Medellín" }
}
*/

Eventos Personalizados

// Escuchar cambios en departamento
$('#departamento').on('change', function() {
    const departamento = $(this).val();
    console.log('Departamento seleccionado:', departamento);
});

// Escuchar cambios en municipio
$('#ciudad').on('change', function() {
    const municipio = $(this).val();
    const departamento = $('#departamento').val();
    console.log('Municipio seleccionado:', municipio, 'en', departamento);
});

Integración con Formularios Existentes

Laravel Blade

Para formularios de creación:

<select class="form-control" name="departamento" required>
    <option value="" disabled selected>Seleccione un departamento</option>
</select>

<select class="form-control" name="ciudad" required>
    <option value="" disabled selected>Seleccione primero un departamento</option>
</select>

Para formularios de edición:

<select class="form-control" name="departamento" required>
    <option value="" disabled>Seleccione un departamento</option>
    <option value="{{ $registro->departamento }}" selected>{{ $registro->departamento }}</option>
</select>

<select class="form-control" name="ciudad" required>
    <option value="" disabled>Seleccione un municipio</option>
    <option value="{{ $registro->ciudad }}" selected>{{ $registro->ciudad }}</option>
</select>

Validación del Lado del Servidor

Laravel

// En tu Request o Controller
$rules = [
    'departamento' => 'required|string|max:255',
    'ciudad' => 'required|string|max:255',
];

// Validación personalizada para verificar que el municipio pertenece al departamento
$validator = Validator::make($request->all(), $rules);

$validator->after(function ($validator) use ($request) {
    // Aquí puedes agregar validación adicional si necesitas verificar
    // que el municipio efectivamente pertenece al departamento seleccionado
});

Características Técnicas

Datos Incluidos

  • 32 Departamentos + Bogotá D.C.
  • 1,123 Municipios en total
  • Códigos DANE oficiales para cada entidad territorial
  • Información actualizada según la Divipola del DANE

Rendimiento

  • Carga Asíncrona: Los datos se cargan una vez al inicializar la página
  • Búsqueda Optimizada: Select2 maneja la búsqueda de manera eficiente
  • Cache del Navegador: Los archivos estáticos se cachean automáticamente

Compatibilidad

  • Navegadores: Chrome, Firefox, Safari, Edge (versiones modernas)
  • Móviles: Responsive design, funciona en dispositivos táctiles
  • Framework: Compatible con Laravel, pero puede usarse en cualquier aplicación web

Solución de Problemas

Problemas Comunes

  1. Los selects no se inicializan
  2. Verificar que jQuery y Select2 estén cargados
  3. Comprobar que el archivo JSON sea accesible
  4. Revisar la consola del navegador para errores

  5. Los municipios no se cargan al seleccionar departamento

  6. Verificar que el evento de cambio esté configurado correctamente
  7. Comprobar que el archivo de datos esté en la ruta correcta

  8. Problemas de estilo

  9. Verificar que el CSS personalizado esté cargado
  10. Comprobar conflictos con otros frameworks CSS

Integración con API de Factus

Funcionalidad de Municipios

El sistema ahora incluye integración completa con la API de Factus para obtener y mapear municipios colombianos:

Características Implementadas

  1. Obtención de Municipios desde API

    // Endpoint para obtener todos los municipios
    GET /factus/municipios
    
    // Endpoint para buscar municipios por nombre
    GET /factus/municipios?name=Bogotá
    

  2. Mapeo Automático de Municipios

  3. Mapea municipios locales (del sistema) a IDs de la API de Factus
  4. Incluye estrategias de búsqueda inteligente
  5. Maneja variaciones de nombres (acentos, prefijos, etc.)
  6. Sistema de caché para optimizar rendimiento

  7. Inclusión en Facturación

  8. Cuando se genera una factura, automáticamente incluye el municipality_id del tercero
  9. Solo se incluye si el municipio es de Colombia y se encuentra en la API de Factus

Endpoints Disponibles

  1. Obtener Municipios

    GET /factus/municipios
    Parámetros opcionales:
    - name: string (nombre del municipio a buscar)
    

  2. Buscar ID de Municipio

    POST /factus/municipio-id
    Body:
    {
      "municipio": "Bogotá, D.C.",
      "departamento": "Bogotá D.C."
    }
    

Implementación en Facturación

En el FacturaService, cuando se preparan los datos del cliente:

$datos['customer'] = [
    'identification' => $tercero->num_iden,
    'names' => $tercero->tipo_persona === 'natural' ? $tercero->nombre : '',
    'company' => $tercero->tipo_persona === 'juridica' ? $tercero->nombre : '',
    'address' => $tercero->direccion,
    'email' => $tercero->correo,
    'phone' => $tercero->num_contact,
    'identification_document_id' => $this->obtenerTipoIdentificacion($tercero->tipo_iden),
    'legal_organization_id' => $tercero->tipo_persona === 'natural' ? 2 : 1,
    'tribute_id' => 21,
    'municipality_id' => $municipalityId // ← Agregado automáticamente
];

Estrategias de Mapeo

El sistema implementa múltiples estrategias para encontrar coincidencias:

  1. Búsqueda Exacta: Busca el nombre exacto del municipio
  2. Variaciones de Nombre:
  3. Remoción de acentos
  4. Remoción de prefijos comunes (San, Santa, El, La, etc.)
  5. Mapeos especiales para casos conocidos
  6. Filtrado por Departamento: Cuando hay múltiples coincidencias
  7. Sistema de Caché: Los resultados se almacenan en caché por 24 horas

Logs: Todas las operaciones se registran en logs para monitoreo:

Log::info("Municipality ID obtenido: {$municipalityId} para {$tercero->ciudad}, {$tercero->departamento}");
Log::warning("No se pudo mapear el municipio: {$nombreMunicipio}, {$nombreDepartamento}");

Manejo de Errores

  • Si no se encuentra el municipio en la API de Factus, la factura se genera sin el municipality_id
  • Se registran warnings en los logs para facilitar el debugging
  • El sistema no falla si hay problemas de conectividad con la API

Optimizaciones

  1. Caché Inteligente:
  2. Municipios específicos: 24 horas
  3. Lista completa: 24 horas
  4. Mapeos exitosos: 24 horas

  5. Búsquedas Optimizadas:

  6. Se evitan búsquedas repetidas para el mismo municipio
  7. Se utilizan estrategias progresivas (exacta → variaciones)

  8. Manejo de Rate Limits:

  9. Sistema preparado para manejar límites de la API
  10. Reintentos inteligentes en caso de errores temporales

Esta integración garantiza que las facturas electrónicas generadas incluyan toda la información geográfica requerida por la DIAN y optimiza la experiencia del usuario al automatizar la obtención de códigos de municipios.

Personalización

Modificar Estilos

Editar public/css/departamentos-municipios.css para personalizar la apariencia.

Agregar Nuevos Municipios

Editar public/js/departamentos-municipios.json siguiendo la estructura existente.

Cambiar Comportamiento

Modificar public/js/departamentos-municipios.js para ajustar la funcionalidad.

Mantenimiento

Actualización de Datos

Los datos deben actualizarse periódicamente según las actualizaciones oficiales del DANE.

Backup

Mantener backup de los archivos de configuración antes de realizar cambios.

Testing

Probar la funcionalidad después de cualquier actualización o modificación.