Finalización del módulo Luz Cámara: Corrección de errores JS, exportación profesional a PDF y reportes de deudores

This commit is contained in:
2026-02-14 16:07:25 -06:00
parent 5f90790c7a
commit 9850f1a85e
13 changed files with 2849 additions and 536 deletions

View File

@@ -1,7 +1,9 @@
<?php
class Report {
public static function getGeneralBalance($startDate = null, $endDate = null) {
class Report
{
public static function getGeneralBalance($startDate = null, $endDate = null)
{
$db = Database::getInstance();
$whereClause = '';
@@ -19,7 +21,8 @@ class Report {
if ($whereClause) {
$whereClause .= " AND cp.house_id IN ($placeholders)";
} else {
}
else {
$whereClause = " WHERE cp.house_id IN ($placeholders)";
}
@@ -66,7 +69,8 @@ class Report {
];
}
public static function getConceptDetailsByYear($year = null) {
public static function getConceptDetailsByYear($year = null)
{
$db = Database::getInstance();
$concepts = $db->fetchAll(
"SELECT c.id, c.name, c.amount_per_house, c.concept_date, c.description
@@ -152,7 +156,8 @@ class Report {
];
}
public static function getHouseStatement($houseId, $year = null) {
public static function getHouseStatement($houseId, $year = null)
{
$db = Database::getInstance();
$house = House::findById($houseId);
@@ -171,7 +176,7 @@ class Report {
"SELECT 'Concepto' as type, c.name as description, cp.amount, cp.payment_date, cp.notes
FROM finance_collection_payments cp
JOIN finance_collection_concepts c ON cp.concept_id = c.id
WHERE cp.house_id = ?" .
WHERE cp.house_id = ?" .
($year ? " AND YEAR(cp.payment_date) = ?" : "") . "
ORDER BY cp.payment_date DESC",
$year ? [$houseId, $year] : [$houseId]
@@ -184,10 +189,11 @@ class Report {
];
}
public static function getPaymentsByYear($year) {
public static function getPaymentsByYear($year)
{
$db = Database::getInstance();
$months = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
$months = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
$data = [];
foreach ($months as $month) {
@@ -195,7 +201,7 @@ class Report {
"SELECT COALESCE(SUM(amount), 0) as total, COUNT(*) as count
FROM payments
WHERE year = ? AND month = ?",
[$year, $month]
[$year, $month]
);
$data[$month] = [
'total' => $result['total'] ?? 0,
@@ -206,7 +212,8 @@ class Report {
return $data;
}
public static function getExpensesByCategory($startDate = null, $endDate = null) {
public static function getExpensesByCategory($startDate = null, $endDate = null)
{
$db = Database::getInstance();
$sql = "SELECT category, COALESCE(SUM(amount), 0) as total
@@ -224,7 +231,8 @@ class Report {
return $db->fetchAll($sql, $params);
}
public static function getCollectionReport($conceptId) {
public static function getCollectionReport($conceptId)
{
$concept = CollectionConcept::findById($conceptId);
$status = CollectionConcept::getCollectionStatus($conceptId);
$payments = CollectionConcept::getPaymentsByConcept($conceptId);
@@ -236,7 +244,8 @@ class Report {
];
}
public static function getDashboardStats($year = null, $accessibleHouseIds = []) {
public static function getDashboardStats($year = null, $accessibleHouseIds = [])
{
$year = $year ?? date('Y');
$db = Database::getInstance();
@@ -263,7 +272,8 @@ class Report {
$totalExpenses = 0;
$balance = $conceptPayments;
} else {
}
else {
$totalHouses = House::countAll();
$activeHouses = House::countActive();
@@ -271,7 +281,7 @@ class Report {
"SELECT COALESCE(SUM(cp.amount), 0) as total
FROM finance_collection_payments cp
WHERE YEAR(cp.payment_date) = ?",
[$year]
[$year]
);
$conceptPayments = $conceptPayments['total'] ?? 0;
@@ -279,7 +289,7 @@ class Report {
"SELECT COALESCE(SUM(amount), 0) as total
FROM expenses
WHERE YEAR(expense_date) = ?",
[$year]
[$year]
);
$totalExpenses = $totalExpenses['total'] ?? 0;
@@ -304,10 +314,11 @@ class Report {
];
}
public static function getWaterDebtors($filters = []) {
public static function getWaterDebtors($filters = [])
{
$db = Database::getInstance();
$allMonths = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
$year = $filters['year'] ?? null;
$months = $filters['months'] ?? $allMonths;
@@ -338,7 +349,8 @@ class Report {
if ($year) {
$yearsToCheck = [$year];
} else {
}
else {
$years = $db->fetchAll("SELECT DISTINCT year FROM payments ORDER BY year");
$yearsToCheck = array_column($years, 'year');
}
@@ -357,7 +369,7 @@ class Report {
$expected = Payment::getExpectedAmount($house, $yr, $month);
$payment = $db->fetchOne(
"SELECT amount FROM payments WHERE house_id = ? AND year = ? AND month = ?",
[$house['id'], $yr, $month]
[$house['id'], $yr, $month]
);
$paid = $payment['amount'] ?? 0;
$due = $expected - $paid;
@@ -404,7 +416,8 @@ class Report {
];
}
public static function getConceptDebtors($accessibleHouseIds = []) {
public static function getConceptDebtors($accessibleHouseIds = [])
{
$db = Database::getInstance();
$concepts = $db->fetchAll(
"SELECT c.id, c.name, c.amount_per_house
@@ -441,7 +454,7 @@ class Report {
$payment = $db->fetchOne(
"SELECT amount FROM finance_collection_payments
WHERE concept_id = ? AND house_id = ?",
[$concept['id'], $house['id']]
[$concept['id'], $house['id']]
);
$paid = $payment['amount'] ?? 0;
@@ -483,7 +496,8 @@ class Report {
];
}
public static function getConceptDebtorsFiltered($houseIds, $conceptIds = null) {
public static function getConceptDebtorsFiltered($houseIds, $conceptIds = null)
{
$db = Database::getInstance();
$whereConditions = [];
@@ -578,4 +592,123 @@ class Report {
'total_due' => $grandTotal
];
}
}
public static function getElectricityDebtors($filters = [])
{
$db = Database::getInstance();
require_once __DIR__ . '/ElectricityBill.php';
require_once __DIR__ . '/ElectricityPayment.php';
$year = $filters['year'] ?? null;
$periods = $filters['periods'] ?? ElectricityBill::getPeriods();
$houseId = $filters['house_id'] ?? null;
$accessibleHouseIds = $filters['accessible_house_ids'] ?? [];
// 1. Obtener Casas Activas
$whereHouse = '';
$houseParams = [];
if ($houseId) {
$whereHouse = "AND h.id = ?";
$houseParams = [$houseId];
}
$sql = "SELECT h.id, h.number, h.owner_name, h.status
FROM houses h
WHERE h.status = 'activa' $whereHouse";
if (!empty($accessibleHouseIds) && !Auth::isAdmin()) {
$placeholders = str_repeat('?,', count($accessibleHouseIds) - 1) . '?';
$sql .= " AND h.id IN ($placeholders)";
$houseParams = array_merge($houseParams, $accessibleHouseIds);
}
$sql .= " ORDER BY CAST(h.number AS UNSIGNED)";
$houses = $db->fetchAll($sql, $houseParams);
// 2. Determinar Años a revisar
if ($year) {
$yearsToCheck = [$year];
}
else {
// Revisar años donde hay configuración de recibos
$years = $db->fetchAll("SELECT DISTINCT year FROM electricity_bills ORDER BY year DESC");
$yearsToCheck = array_column($years, 'year');
if (empty($yearsToCheck))
$yearsToCheck = [date('Y')];
}
// 3. Calcular Deudas
$debtors = [];
$grandTotalExpected = 0;
$grandTotalPaid = 0;
foreach ($houses as $house) {
$totalExpected = 0;
$totalPaid = 0;
$periodDetails = [];
foreach ($yearsToCheck as $yr) {
// Obtener configuración del año para optimizar (evitar queries por periodo)
$billsConfig = ElectricityBill::getYear($yr);
foreach ($periods as $period) {
$config = $billsConfig[$period] ?? null;
// Solo cobrar si hay configuración y monto > 0
if (!$config || $config['amount_per_house'] <= 0) {
continue;
}
$expected = $config['amount_per_house'];
// Obtener pago
$payment = $db->fetchOne(
"SELECT amount FROM electricity_payments WHERE house_id = ? AND year = ? AND period = ?",
[$house['id'], $yr, $period]
);
$paid = $payment['amount'] ?? 0;
$due = $expected - $paid;
$totalExpected += $expected;
$totalPaid += $paid;
if ($due > 0.01) { // Tolerancia pequeña a flotantes
$periodDetails[] = [
'year' => $yr,
'period' => $period,
'expected' => $expected,
'paid' => $paid,
'due' => $due
];
}
}
}
$houseTotalDue = $totalExpected - $totalPaid;
if ($houseTotalDue > 0.01) {
$debtors[] = [
'house_id' => $house['id'],
'house_number' => $house['number'],
'owner_name' => $house['owner_name'],
'periods_due' => $periodDetails,
'total_due' => $houseTotalDue
];
}
$grandTotalExpected += $totalExpected;
$grandTotalPaid += $totalPaid;
}
$grandTotalDue = $grandTotalExpected - $grandTotalPaid;
return [
'debtors' => $debtors,
'total_due' => $grandTotalDue,
'total_expected' => $grandTotalExpected,
'total_paid' => $grandTotalPaid,
'filters' => $filters
];
}
}