Validaciones MEYPAR Colombia - DocuCenter
Descripción
Documentación técnica de las validaciones implementadas para la integración con MEYPAR Colombia, incluyendo validaciones de documentos colombianos, límites de base de datos y optimizaciones de totales.
Validaciones de Documentos de Identificación
🏢 NIT Empresarial Colombiano
Formato Válido: XXXXXXXXX-X
- 9 dígitos numéricos
- Guión separador
- 1 dígito verificador
Ejemplos:
- ✅ 900123456-1
- ✅ 123456789-0
- ✅ 800123456-7
- ❌ 12345678 (falta guión y DV)
- ❌ 90012345-12 (DV debe ser 1 dígito)
Implementación:
private function validateColombianNIT(string $nit): bool
{
$pattern = '/^\d{9}-\d{1}$/';
return preg_match($pattern, $nit) === 1;
}
Resultado:
- ReceiverType: '1' (Contribuyente)
- Custom_field5: Código de ubicación de la organización
👤 Cédula Colombiana
Formato Válido: Solo números de 6 a 10 dígitos
Ejemplos:
- ✅ 123456 (6 dígitos)
- ✅ 79123456 (8 dígitos)
- ✅ 1234567890 (10 dígitos)
- ❌ 12345 (menos de 6 dígitos)
- ❌ 12345678901 (más de 10 dígitos)
- ❌ 79-123-456 (con guiones)
Implementación:
private function validateColombianCedula(string $cedula): bool
{
return preg_match('/^\d{6,10}$/', $cedula) === 1;
}
Resultado:
- ReceiverType: '2' (Persona natural)
- Custom_field5: null
🛒 Consumidor Final
Formatos Válidos:
- '0-0-0'
- Cadena vacía: ''
- Solo espacios: ' '
- Documento inválido (auto-corrección)
Resultado:
- ReceiverType: '2' (Consumidor final)
- Custom_field5: null
⚙️ Auto-corrección de Documentos
if (!$nitValidation['valid']) {
Log::warning("NIT/Cédula colombiana inválida en MEYPAR - usando consumidor final", [
'original_nit' => $nit,
'customer_name' => array_get($clientData, 'Customer_Bill_Name'),
'validation_message' => $nitValidation['message']
]);
// Auto-corrección a consumidor final
$nit = '0-0-0';
$nitValidation = ['valid' => true, 'type' => 'consumer'];
}
Ventajas: - ✅ No interrumpe el procesamiento - ✅ Logging detallado para auditoría - ✅ Conversión silenciosa a consumidor final - ✅ Mantiene la funcionalidad del sistema
Validaciones de Límites de Base de Datos
📏 Campos de Texto
| Campo | Límite BD | Validación Request | Campo BD |
|---|---|---|---|
documento.numero |
20 caracteres | max:20 |
InvoiceNumber |
documento.emisor.nombre |
100 caracteres | max:100 |
- |
documento.emisor.nit |
50 caracteres | max:50 |
- |
documento.adquiriente.nombre |
39 caracteres | max:39 |
CustomerName |
documento.adquiriente.nit |
20 caracteres | max:20 |
CustomerID |
documento.adquiriente.email |
100 caracteres | max:100 |
|
documento.adquiriente.direccion |
200 caracteres | max:200 |
AddressLine1 |
documento.adquiriente.telefono |
20 caracteres | max:20 |
- |
documento.terminal.CodigoExterno |
20 caracteres | max:20 |
DeviceId |
documento.terminal.NombreTerminal |
100 caracteres | max:100 |
IdStore |
documento.items.*.descripcion |
255 caracteres | max:255 |
Description |
documento.items.*.codigoProducto |
50 caracteres | max:50 |
Item_id, ProductID |
documento.items.*.unidadMedida |
10 caracteres | max:10 |
UnitMeasure |
autorizacion_prefijo.PrefijoId |
10 caracteres | max:10 |
- |
autorizacion_prefijo.ResolucionNumero |
50 caracteres | max:50 |
- |
Sanitización Automática en el Servicio
private function sanitizeTextField(string $value, int $maxLength, string $fieldName = 'field'): string
{
$value = trim($value);
if (strlen($value) > $maxLength) {
Log::warning("Campo MEYPAR excede límite de BD - truncado", [
'field' => $fieldName,
'original_length' => strlen($value),
'max_length' => $maxLength,
'original_value' => $value,
'truncated_value' => substr($value, 0, $maxLength)
]);
return substr($value, 0, $maxLength);
}
return $value;
}
💰 Validaciones Decimales
| Campo | Estructura BD | Validación Request | Regex |
|---|---|---|---|
precioUnitario |
decimal(16,4) | regex |
/^\d{1,12}(\.\d{1,4})?$/ |
precioTotalFinalDetalle |
decimal(16,4) | regex |
/^\d{1,12}(\.\d{1,4})?$/ |
importeMedioPago |
decimal(16,4) | regex |
/^\d{1,12}(\.\d{1,4})?$/ |
totales.total |
decimal(16,4) | regex |
/^\d{1,12}(\.\d{1,4})?$/ |
cantidad |
decimal(12,2) | max:9999999999.99 |
- |
Formateo de Números en el Servicio
private function numberFormat(float $number, int $decimals = 4): float
{
// Validar límites de BD (16,4)
$maxValue = 999999999999.9999; // 12 dígitos enteros + 4 decimales
if (abs($number) > $maxValue) {
Log::warning("Número excede límite de BD decimal(16,4)", [
'number' => $number,
'max_allowed' => $maxValue,
'truncated_to' => $maxValue * ($number < 0 ? -1 : 1)
]);
$number = $maxValue * ($number < 0 ? -1 : 1);
}
return round($number, $decimals);
}
Optimización de Totales
🎯 Estrategia de Totales Globales
Antes (Calculado):
// Se calculaba sumando Net_line de detalles
$subtotalSum += $netLineAmount;
$header->update(['Subtotal' => $subtotalSum]);
Después (Directo de MEYPAR):
// Usa totales directamente del JSON
'Subtotal' => $this->numberFormat($subtotalGlobal, 2),
'Net_due' => $this->numberFormat($totalGlobal, 2),
📊 Mapeo de Campos de Totales
| JSON MEYPAR | Campo BD | Descripción |
|---|---|---|
totales.subtotal |
Subtotal |
Subtotal antes de impuestos |
totales.total |
Net_due |
Total final de la factura |
totales.impuestos |
TotalTaxInvupos |
Total de impuestos |
totales.descuentos |
TotalDiscountInvupos |
Total de descuentos |
🔧 Mapeo de Líneas de Detalle
| Campo Origen | Campo BD | Cálculo |
|---|---|---|
precioTotalFinalDetalle |
Net_line |
Valor directo (para sumar al subtotal) |
cantidad × precioUnitario |
Sub_Total |
Cálculo base sin modificaciones |
precioUnitario |
Unit_Price |
Valor directo |
cantidad |
Quantity |
Valor directo |
Estructura de Campos Personalizados (CustomersImp)
🗂️ Sistema de Custom Fields
| Campo | Tipo Empresa | Tipo Persona | Consumidor Final |
|---|---|---|---|
Custom_field1 |
NIT validado | Cédula validada | '0-0-0' |
Custom_field2 |
'00' |
'00' |
'00' |
Custom_field3 |
null |
null |
null |
Custom_field4 |
'1' |
'2' |
'2' |
Custom_field5 |
Código ubicación org | null |
null |
ReceiverType Mapping
switch ($nitValidation['type']) {
case 'company':
$receiverType = '1'; // Contribuyente
$customField5 = $organization->codigo_provincia_distrito ?? null;
break;
case 'person':
case 'consumer':
default:
$receiverType = '2'; // Persona natural/Consumidor final
$customField5 = null;
break;
}
Mensajes de Error Específicos
📝 Validaciones de Request
Límites de Caracteres:
- "El número de documento no puede exceder 20 caracteres"
- "El nombre del cliente no puede exceder 39 caracteres"
- "El NIT del cliente no puede exceder 20 caracteres"
Formatos Decimales:
- "El precio unitario debe ser un decimal válido con máximo 4 decimales"
- "El precio total debe ser un decimal válido con máximo 4 decimales"
- "El importe del medio de pago debe ser un decimal válido con máximo 4 decimales"
Campos Requeridos:
- "Los datos del documento son requeridos"
- "El nombre del adquiriente es requerido"
- "Los items del documento son requeridos"
🔍 Logging de Validaciones
Documento Inválido:
NIT/Cédula colombiana inválida en MEYPAR - usando consumidor final
{
"original_nit": "123-INVALID-456",
"customer_name": "Cliente Test",
"validation_message": "Formato de documento inválido..."
}
Campo Truncado:
Campo MEYPAR excede límite de BD - truncado
{
"field": "CustomerName",
"original_length": 45,
"max_length": 39,
"original_value": "Nombre Muy Largo Que Excede El Límite De BD",
"truncated_value": "Nombre Muy Largo Que Excede El Límite"
}
Número Truncado:
Número excede límite de BD decimal(16,4)
{
"number": 9999999999999.99999,
"max_allowed": 999999999999.9999,
"truncated_to": 999999999999.9999
}
Beneficios de la Implementación
✅ Robustez
- Validación automática de documentos colombianos
- Auto-corrección para datos inválidos
- Límites exactos según estructura de BD
- Logging detallado para auditoría
⚡ Performance
- Totales directos de MEYPAR (no calculados)
- Validación en una pasada de documentos
- Formateo optimizado con límites exactos
- Sin operaciones de actualización innecesarias
🔧 Mantenibilidad
- Mensajes claros en español
- Logging estructurado para debugging
- Separación de responsabilidades (Request vs Service)
- Documentación completa de validaciones
🎯 Precisión
- Compatibilidad exacta con estructura de BD
- Validaciones específicas para Colombia
- Formato decimal preciso (16,4 y 18,4)
- Coherencia de datos entre request y BD
Testing de Validaciones
🧪 Casos de Prueba Documentos
NITs Válidos:
- 900123456-1 → Empresa
- 800234567-0 → Empresa
- 123456789-7 → Empresa
Cédulas Válidas:
- 79123456 → Persona
- 1234567890 → Persona
- 123456 → Persona
Casos Inválidos (Auto-corrección):
- 123-INVALID → Consumidor final
- 900123456 → Consumidor final (falta DV)
- '' → Consumidor final
📊 Casos de Prueba Límites
Campos de Texto: - Nombre 40 caracteres → Truncado a 39 - Descripción 300 caracteres → Truncada a 255 - Email 150 caracteres → Truncado a 100
Decimales:
- 1234567890123.12345 → Truncado a límites BD
- -999.9999 → Válido
- 0.1 → Válido
Esta implementación asegura que todos los datos de MEYPAR Colombia sean procesados correctamente con validaciones robustas y compatibilidad total con la estructura de base de datos de DocuCenter.