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:
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
- Los selects no se inicializan
- Verificar que jQuery y Select2 estén cargados
- Comprobar que el archivo JSON sea accesible
-
Revisar la consola del navegador para errores
-
Los municipios no se cargan al seleccionar departamento
- Verificar que el evento de cambio esté configurado correctamente
-
Comprobar que el archivo de datos esté en la ruta correcta
-
Problemas de estilo
- Verificar que el CSS personalizado esté cargado
- 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
-
Obtención de Municipios desde API
-
Mapeo Automático de Municipios
- Mapea municipios locales (del sistema) a IDs de la API de Factus
- Incluye estrategias de búsqueda inteligente
- Maneja variaciones de nombres (acentos, prefijos, etc.)
-
Sistema de caché para optimizar rendimiento
-
Inclusión en Facturación
- Cuando se genera una factura, automáticamente incluye el
municipality_iddel tercero - Solo se incluye si el municipio es de Colombia y se encuentra en la API de Factus
Endpoints Disponibles
-
Obtener Municipios
-
Buscar ID de Municipio
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:
- Búsqueda Exacta: Busca el nombre exacto del municipio
- Variaciones de Nombre:
- Remoción de acentos
- Remoción de prefijos comunes (San, Santa, El, La, etc.)
- Mapeos especiales para casos conocidos
- Filtrado por Departamento: Cuando hay múltiples coincidencias
- 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
- Caché Inteligente:
- Municipios específicos: 24 horas
- Lista completa: 24 horas
-
Mapeos exitosos: 24 horas
-
Búsquedas Optimizadas:
- Se evitan búsquedas repetidas para el mismo municipio
-
Se utilizan estrategias progresivas (exacta → variaciones)
-
Manejo de Rate Limits:
- Sistema preparado para manejar límites de la API
- 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.