- Filtros por casas: selección múltiple con opción 'Todas las casas' - Filtros por conceptos: selección múltiple con opción 'Todos los conceptos' - Estado inicial: todos los filtros marcados por defecto (muestra toda la info) - Exportación PDF: incluye solo datos filtrados según selección - JavaScript interactivo: lógica de checkboxes con estados intermedios - Modelo actualizado: método getConceptDebtorsFiltered para filtrado avanzado - Interfaz intuitiva: scrollable containers para listas largas - Preserva permisos: respeta restricciones de acceso por casas
16 KiB
Executable File
16 KiB
Executable File
ESPECIFICACIÓN DETALLADA DE REGLAS DE NEGOCIO Y LÓGICA
Complemento para Desarrollo desde Cero sin Acceso al Código
🎯 REGLAS DE NEGOCIO CRÍTICAS (No incluidas en archivos anteriores)
1. Lógica de Pagos de Agua
Regla de Descuento por Consumo
// REGLA CRÍTICA: Descuento automático
if ($casa->consumo_only == true && $año >= 2025) {
$monto_esperado = max(0, $monto_base - 100.00);
}
// Explicación:
// - Casas marcadas como "consumo_only" reciben $100 de descuento
// - Solo aplica desde 2025 en adelante
// - El monto no puede ser negativo (mínimo $0)
// - Esto se aplica a cada mes individualmente
Cálculo de Montos Mensuales
// Lógica para distribuir costos entre casas activas
$total_mensual = 5000.00; // Ejemplo: costo total del mes
$casas_activas = 87; // Casas con status = 'activa'
$casas_consumo_only = 14; // Casas con consumo_only = true
// Monto base por casa activa
$monto_base = $total_mensual / $casas_activas; // ≈ $57.47
// Casas normales pagan el monto completo
$monto_casa_normal = $monto_base;
// Casas consumo_only pagan con descuento (desde 2025)
$monto_casa_consumo = max(0, $monto_base - 100.00); // $0 si el descuento es mayor
Estados de Pago
// Lógica de estados visuales
if ($casa->status == 'deshabitada') {
$estado = 'N/A'; // No aplica pagos
$color = 'gris';
} else {
if ($monto_esperado == 0) {
$estado = 'Sin monto configurado';
$color = 'amarillo';
} else if ($pago_realizado == 0) {
$estado = 'Sin pagos registrados';
$color = 'rojo';
} else if ($saldo >= 0) {
$estado = 'Pagado (+ ' . formatMoney($saldo) . ')';
$color = 'verde';
} else {
$estado = 'Pendiente (-: ' . formatMoney(abs($saldo)) . ')';
$color = 'rojo';
}
}
2. Reglas de Validación de Datos
Validaciones de Pagos
// Montos válidos
$monto_minimo = 0.00;
$monto_maximo = 999999.99;
// Validaciones específicas
if ($pago->amount < 0) {
throw new Exception("El monto no puede ser negativo");
}
if ($pago->amount > 100000) {
throw new Exception("El monto excede el límite permitido");
}
// Casos especiales
if ($pago->amount == 0) {
// Significa que se eliminó el pago
// Se debe eliminar el registro de la base de datos
}
Validaciones de Casas
// Números de casa válidos: 001-101
if (!preg_match('/^(0[1-9][0-9]|101)$/', $casa->number)) {
throw new Exception("Número de casa inválido");
}
// Estados permitidos
$estados_validos = ['activa', 'deshabitada'];
if (!in_array($casa->status, $estados_validos)) {
throw new Exception("Estado de casa no válido");
}
3. Lógica de Reportes
Balance General
// Cálculo de balance
$ingresos_totales = sum(pagos.monto where pagos.año = X and pagos.mes = Y);
$egresos_totales = sum(expenses.amount where expenses.fecha between X and Y);
$balance_neto = $ingresos_totales - $egresos_totales;
// Desglose por categoría
$ingresos_agua = sum(pagos.monto where pagos.concepto = 'agua');
$ingresos_especiales = sum(pagos.monto where pagos.concepto != 'agua');
$egresos_mantenimiento = sum(expenses.amount where expenses.category = 'mantenimiento');
$egresos_administrativos = sum(expenses.amount where expenses.category = 'administrativo');
Estado de Cuenta por Casa
// Para una casa específica
$estado_cuenta = [
'pagos_agua' => getPagosAgua($casa_id, $periodo),
'pagos_especiales' => getPagosEspeciales($casa_id, $periodo),
'cargos_adicionales' => getCargosAdicionales($casa_id, $periodo),
'total_ingresos' => sum($pagos_agua + $pagos_especiales),
'total_egresos' => getCuotaMantenimiento($casa_id, $periodo),
'balance_final' => $total_ingresos - $total_egresos
];
🔐 REGLAS DE SEGURIDAD Y PERMISOS
1. Matriz de Permisos
| Funcionalidad | Admin | Capturista | Viewer |
|---|---|---|---|
| Ver dashboard | ✅ | ✅ | ✅ |
| Editar pagos | ✅ | ✅ | ❌ |
| Crear conceptos | ✅ | ✅ | ❌ |
| Editar conceptos | ✅ | ❌ | ❌ |
| Ver reportes | ✅ | ✅ | ✅ |
| Exportar PDF | ✅ | ✅ | ❌ |
| Exportar CSV | ✅ | ❌ | ❌ |
| Gestionar usuarios | ✅ | ❌ | ❌ |
| Ver logs de actividad | ✅ | ❌ | ❌ |
| Editar casas | ✅ | ❌ | ❌ |
| Registrar gastos | ✅ | ✅ | ❌ |
2. Reglas de Acceso
Autenticación
// Login requiere username y password
// Password debe tener mínimo 8 caracteres
// Sesión expira después de 8 horas de inactividad
// Se debe regenerar ID de sesión en cada login
Validaciones de Sesión
// Cada página debe verificar:
if (!isset($_SESSION['user_id'])) {
header('Location: /login');
exit;
}
// Verificar rol para funcionalidades específicas
if (in_array($rol_requerido, ['admin', 'capturista']) && !in_array($user_rol, ['admin', 'capturista'])) {
throw new Exception("Acceso denegado");
}
📊 REGLAS DE CÁLCULO FINANCIERO
1. Fórmulas de Cálculo
Monto Esperado por Casa
function calcularMontoEsperado($casa, $año, $mes) {
// Obtener configuración mensual
$config_mensual = getMonthlyBill($año, $mes);
$total_mensual = $config_mensual->total_amount;
// Contar casas activas
$casas_activas = countActiveHouses($año, $mes);
// Calcular monto base
$monto_base = $total_mensual / $casas_activas;
// Aplicar descuento si corresponde
if ($casa->consumo_only && $año >= 2025) {
$monto_base = max(0, $monto_base - 100.00);
}
return round($monto_base, 2);
}
Saldo por Casa
function calcularSaldo($casa_id, $año, $mes) {
$pagos_realizados = getTotalPagado($casa_id, $año, $mes);
$monto_esperado = calcularMontoEsperado(getHouse($casa_id), $año, $mes);
return $pagos_realizados - $monto_esperado;
}
2. Reglas de Redondeo
// Todos los montos monetarios se redondean a 2 decimales
// Se usa round() en PHP, no floor() ni truncamiento
// Ejemplo: 57.471 → 57.47, 57.476 → 57.48
// Para cálculos de división:
$monto_individual = round($total / $cantidad, 2);
// Para evitar errores de redondeo acumulativo:
$primeras_casas = $cantidad - 1;
$monto_base = floor($total / $cantidad);
$resto = $total - ($monto_base * $cantidad);
// Distribuir el resto entre las primeras casas
for ($i = 0; $i < $primeras_casas; $i++) {
$montos[$i] = $monto_base;
}
$montos[$cantidad - 1] = $monto_base + $resto;
🎨 REGLAS DE INTERFAZ Y UX
1. Comportamiento de la Interfaz
Edición Inline de Pagos
// Al hacer clic en una celda de pago:
1. La celda debe volverse editable
2. Mostrar input numérico con el valor actual
3. Permitir edición con validación en tiempo real
4. Guardar automáticamente al perder foco o presionar Enter
5. Mostrar indicador de "guardando..."
6. Actualizar colores de estado automáticamente
7. Mostrar mensaje de éxito o error
Estados Visuales
/* Colores para estados de pago */
.paid { background-color: #d4edda; } /* verde claro */
.pending { background-color: #f8d7da; } /* rojo claro */
.partial { background-color: #fff3cd; } /* amarillo claro */
.inactive { background-color: #e2e3e5; } /* gris */
Navegación y Flujos
// Flujo de usuario típico:
1. Login → Dashboard
2. Dashboard → Módulo específico (Pagos/Finanzas)
3. Módulo → Acción específica
4. Acción → Confirmación → Regreso al listado
// Breadcrumbs siempre presentes
// Botón de regresar siempre visible
// Confirmación para acciones destructivas
2. Reglas de Diseño Responsivo
/* Desktop (1024px+) */
- Tabla completa con scroll horizontal
- Menú lateral completo
- Tarjetas de dashboard en grid 4x2
/* Tablet (768px-1023px) */
- Tabla con columnas colapsables
- Menú superior horizontal
- Tarjetas en grid 2x2
/* Móvil (320px-767px) */
- Tabla convertida a cards
- Menú hamburguesa
- Tarjetas en columna única
- Inputs con tipo numérico optimizado
🔄 REGLAS DE PROCESOS DE NEGOCIO
1. Flujo de Pagos Mensuales
Proceso Estándar
// 1. Configuración Mensual (Admin)
- Definir monto total del mes
- Especificar fecha de vencimiento
- Activar periodo de cobro
// 2. Registro de Pagos (Capturista)
- Ingresar pagos casa por casa
- Validar montos automáticamente
- Registrar fecha y método de pago
// 3. Seguimiento (Todos)
- Ver dashboard con estados
- Generar reportes de morosidad
- Exportar listados para gestión
// 4. Cierre del Mes (Admin)
- Generar balance final
- Archivar período
- Iniciar siguiente mes
Manejo de Casos Especiales
// Casa deshabitada
if ($casa->status == 'deshabitada') {
// No genera pagos
// No aparece en reportes de morosidad
// Puede reactivarse en cualquier momento
}
// Pago parcial
if ($pago < $monto_esperado) {
// Estado = "parcial"
// Calcula saldo pendiente
// Sigue apareciendo en reportes
}
// Pago excedente
if ($pago > $monto_esperado) {
// Estado = "pagado con saldo a favor"
// Muestra el excedente
// Puede aplicarse a meses siguientes (opcional)
}
2. Flujo de Conceptos Especiales
Creación de Concepto
// 1. Definir Concepto Global
- Nombre descriptivo
- Categoría (mantenimiento, mejora, emergencia)
- Descripción detallada
// 2. Configurar Recaudación
- Monto por casa
- Fecha de concepto
- Fecha de vencimiento
- Casas aplicables (todas o subset)
// 3. Gestionar Pagos
- Registrar pagos individuales
- Controlar estado de recaudación
- Generar reportes de avance
// 4. Cierre y Archivo
- Validar recaudación completa
- Generar balance del concepto
- Archivar documentación
📈 REGLAS DE REPORTES Y EXPORTACIÓN
1. Formatos de Exportación
PDF (Pagos de Agua)
// Estructura del documento:
1. Header: Logo, título "Concentrado de Pagos Año X", fecha
2. Filtros aplicados: Año, casa específica (si aplica)
3. Tabla principal:
- Columnas: Casa, Estado, Enero, Febrero, ..., Diciembre, Total, Estado
- 101 filas (una por casa)
- Colores de estado (verde/rojo/amarillo)
4. Resumen:
- Total casas activas
- Total pagos del período
- Porcentaje de cobranza
5. Footer: Página X de Y, fecha de generación
// Configuración:
- Orientación: Horizontal
- Tamaño: A3
- Fuente: Arial 10px (datos), 12px (títulos)
- Márgenes: 10mm
CSV (Finanzas)
// Estructura del archivo:
headers: ['Fecha', 'Concepto', 'Casa', 'Monto', 'Tipo', 'Método', 'Referencia']
// Formato de fechas: YYYY-MM-DD
// Separador: coma (,)
- Codificación: UTF-8 con BOM
- Decimales: punto (.)
- Sin comillas en campos numéricos
2. Reglas de Agregación
Reportes por Período
// Al filtrar por rango de fechas:
- Incluir todos los pagos con fecha >= start_date y <= end_date
- Para pagos sin fecha específica, usar mes/año como referencia
- Agrupar por mes natural (1 al último día del mes)
- Incluir totales acumulados por período
Reportes por Casa
// Al generar estado de cuenta por casa:
- Mostrar todos los movimientos en orden cronológico
- Incluir saldos acumulados
- Diferenciar entre ingresos y egresos
- Calcular balance final
- Mostrar estado actual (pagado/pendiente)
⚠️ REGLAS PARA MANEJO DE ERRORES Y CASOS EDGE
1. Validaciones Críticas
Antes de Guardar
// Validaciones obligatorias:
if (empty($casa_id)) throw new Exception("Debe seleccionar una casa");
if (empty($año) || $año < 2024 || $año > 2030) throw new Exception("Año inválido");
if (empty($mes) || !in_array($mes, $MESES_VALIDOS)) throw new Exception("Mes inválido");
if (!is_numeric($monto) || $monto < 0) throw new Exception("Monto inválido");
// Validaciones de negocio:
if ($casa->status == 'deshabitada' && $monto > 0) {
throw new Exception("No se pueden registrar pagos para casas deshabitadas");
}
if ($monto > 100000) {
throw new Exception("El monto excede el límite permitido ($100,000)");
}
Durante Procesos
// Manejo de concurrencia:
try {
$pdo->beginTransaction();
// Verificar que no haya modificación concurrente
$current_version = getCurrentVersion($payment_id);
if ($current_version != $expected_version) {
throw new Exception("El pago fue modificado por otro usuario");
}
// Procesar actualización
updatePayment($data);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollback();
logError($e->getMessage());
throw $e;
}
2. Casos Edge Específicos
Pagos de $0
// Un pago de $0 significa:
// 1. Eliminar el pago existente (si lo hay)
// 2. No crear un nuevo registro
// 3. Actualizar el estado a "pendiente"
// 4. Registrar en log de actividad
if ($monto == 0) {
deletePayment($house_id, $año, $mes);
logActivity('eliminar_pago', "Casa $house_id: $mes $año");
}
Cambios de Estado de Casa
// Al cambiar de 'activa' a 'deshabitada':
// 1. Eliminar pagos futuros no realizados
// 2. Mantener pagos históricos
// 3. Actualizar estado en reportes
// 4. Notificar a usuarios
// Al cambiar de 'deshabitada' a 'activa':
// 1. Crear registros de pago para meses futuros
// 2. Calcular montos esperados
// 3. Incluir en reportes activos
🔄 REGLAS DE MIGRACIÓN DE DATOS
1. Transformación de Datos
Desde Sistema Antiguo
// Mapeo de tablas antiguas → nuevas:
// houses → houses (mismo nombre)
- id → id
- number → number
- status → status
- consumo_only → consumptionOnly (camelCase)
// payments → payments
- house_id → house_id (relación)
- year → year
- month → month
- amount → amount
- created_by → created_by (relación con User)
// users → users
- id → id
- username → username
- password → password (migrar como hash)
- role → role
Limpieza de Datos
// Datos a limpiar durante migración:
1. Eliminar duplicados en payments
2. Corregir inconsistencias en mayúsculas/minúsculas
3. Validar que todas las casas tengan número válido
4. Asegurar que todos los pagos tengan casa válida
5. Corregir fechas inválidas o nulas
6. Estandarizar nombres de meses (español, primera letra mayúscula)
2. Validación Post-Migración
Chequeos de Integridad
// Validaciones obligatorias después de migrar:
1. Contar casas: deben ser 101
2. Verificar que todos los números del 001-101 existan
3. Validar que cada pago tenga casa válida
4. Chequear que no haya pagos duplicados
5. Verificar que los montos sean positivos
6. Validar que los usuarios tengan roles válidos
7. Correr reportes y comparar totales con sistema antiguo
📋 CHECKLIST DE DESARROLLO
✅ Fase 1: Setup y Configuración
- Configurar base de datos MySQL
- Crear entidades Doctrine
- Configurar sistema de seguridad
- Setup de assets (Bootstrap, Stimulus)
✅ Fase 2: Core del Sistema
- Implementar autenticación
- Crear dashboard principal
- Desarrollar módulo de casas
- Implementar módulo de pagos
- Crear sistema de roles
✅ Fase 3: Funcionalidades Avanzadas
- Módulo de conceptos especiales
- Sistema de gastos
- Generador de reportes
- Exportación PDF/CSV
- Sistema de logs
✅ Fase 4: Validación y Testing
- Implementar todas las reglas de negocio
- Probar casos edge
- Validar cálculos financieros
- Testing de permisos
- Pruebas de estrés
✅ Fase 5: Despliegue
- Configurar producción
- Migrar datos
- Capacitación de usuarios
- Go-live
- Monitoreo post-lanzamiento
🎯 CONCLUSIÓN
Con este documento complementario, el desarrollador tiene el 100% de la información necesaria para construir el sistema desde cero, incluyendo:
- Todas las reglas de negocio específicas
- Lógica de cálculo detallada
- Casos edge y manejo de errores
- Reglas de seguridad y permisos
- Especificaciones de UI/UX
- Proceso de migración de datos
Ahora sí puede construir el sistema completo sin necesidad de ver el código actual.