191 lines
6.0 KiB
PHP
Executable File
191 lines
6.0 KiB
PHP
Executable File
<?php
|
|
|
|
class ElectricityPayment
|
|
{
|
|
/**
|
|
* Obtener matriz completa de pagos para un año
|
|
* OPTIMIZADO: Una sola query para todos los periodos
|
|
*/
|
|
public static function getMatrix($year)
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
$houses = $db->fetchAll(
|
|
"SELECT h.id, h.number, h.status, h.consumption_only, h.owner_name
|
|
FROM houses h
|
|
ORDER BY CAST(h.number AS UNSIGNED)"
|
|
);
|
|
|
|
$periods = ElectricityBill::getPeriods();
|
|
|
|
// OPTIMIZADO: Una sola query en lugar de 6 queries separadas
|
|
$allPayments = $db->fetchAll(
|
|
"SELECT house_id, period, amount, payment_date
|
|
FROM electricity_payments
|
|
WHERE year = ?
|
|
ORDER BY FIELD(period, 'Ene-Feb', 'Mar-Abr', 'May-Jun', 'Jul-Ago', 'Sep-Oct', 'Nov-Dic')",
|
|
[$year]
|
|
);
|
|
|
|
// Organizar pagos por periodo
|
|
$payments = [];
|
|
foreach ($periods as $period) {
|
|
$payments[$period] = [];
|
|
}
|
|
|
|
foreach ($allPayments as $p) {
|
|
$payments[$p['period']][$p['house_id']] = $p;
|
|
}
|
|
|
|
return ['houses' => $houses, 'payments' => $payments, 'periods' => $periods];
|
|
}
|
|
|
|
/**
|
|
* Actualizar un solo pago
|
|
*/
|
|
public static function update($houseId, $year, $period, $amount, $userId, $notes = null)
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
$existing = $db->fetchOne(
|
|
"SELECT id FROM electricity_payments WHERE house_id = ? AND year = ? AND period = ?",
|
|
[$houseId, $year, $period]
|
|
);
|
|
|
|
if ($amount == 0 && $existing) {
|
|
$db->execute(
|
|
"DELETE FROM electricity_payments WHERE id = ?",
|
|
[$existing['id']]
|
|
);
|
|
return ['success' => true, 'deleted' => true];
|
|
}
|
|
|
|
if ($existing) {
|
|
$db->execute(
|
|
"UPDATE electricity_payments SET amount = ?, payment_date = NOW(), notes = ?, created_by = ? WHERE id = ?",
|
|
[$amount, $notes, $userId, $existing['id']]
|
|
);
|
|
}
|
|
else {
|
|
$db->execute(
|
|
"INSERT INTO electricity_payments (house_id, year, period, amount, payment_date, notes, created_by)
|
|
VALUES (?, ?, ?, ?, NOW(), ?, ?)",
|
|
[$houseId, $year, $period, $amount, $notes, $userId]
|
|
);
|
|
}
|
|
|
|
return ['success' => true, 'deleted' => false];
|
|
}
|
|
|
|
/**
|
|
* Actualizar múltiples pagos en batch con transacción
|
|
* OPTIMIZADO: Similar a Payment::updateBatch()
|
|
*/
|
|
public static function updateBatch($changes, $userId)
|
|
{
|
|
$db = Database::getInstance();
|
|
$pdo = $db->getPDO();
|
|
|
|
try {
|
|
$pdo->beginTransaction();
|
|
|
|
$updateCount = 0;
|
|
$deleteCount = 0;
|
|
|
|
// Preparar statements una sola vez (reutilización)
|
|
$insertStmt = $pdo->prepare(
|
|
"INSERT INTO electricity_payments (house_id, year, period, amount, payment_date, created_by)
|
|
VALUES (?, ?, ?, ?, NOW(), ?)
|
|
ON DUPLICATE KEY UPDATE
|
|
amount = VALUES(amount),
|
|
payment_date = VALUES(payment_date),
|
|
created_by = VALUES(created_by)"
|
|
);
|
|
|
|
$deleteStmt = $pdo->prepare(
|
|
"DELETE FROM electricity_payments WHERE house_id = ? AND year = ? AND period = ?"
|
|
);
|
|
|
|
foreach ($changes as $change) {
|
|
// Validar que tenemos los datos mínimos
|
|
if (!isset($change['house_id'], $change['year'], $change['period'])) {
|
|
continue;
|
|
}
|
|
|
|
$amount = isset($change['amount']) ? (float)$change['amount'] : 0;
|
|
|
|
if ($amount == 0) {
|
|
// Eliminar si el monto es 0
|
|
$deleteStmt->execute([
|
|
$change['house_id'],
|
|
$change['year'],
|
|
$change['period']
|
|
]);
|
|
$deleteCount++;
|
|
}
|
|
else {
|
|
// Insertar o actualizar
|
|
$insertStmt->execute([
|
|
$change['house_id'],
|
|
$change['year'],
|
|
$change['period'],
|
|
$amount,
|
|
$userId
|
|
]);
|
|
$updateCount++;
|
|
}
|
|
}
|
|
|
|
$pdo->commit();
|
|
|
|
return [
|
|
'success' => true,
|
|
'count' => $updateCount + $deleteCount,
|
|
'updated' => $updateCount,
|
|
'deleted' => $deleteCount
|
|
];
|
|
|
|
}
|
|
catch (Exception $e) {
|
|
$pdo->rollback();
|
|
error_log("Error en ElectricityPayment::updateBatch: " . $e->getMessage());
|
|
return [
|
|
'success' => false,
|
|
'error' => $e->getMessage()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtener pagos de una casa específica
|
|
*/
|
|
public static function getByHouse($houseId, $year = null)
|
|
{
|
|
$db = Database::getInstance();
|
|
|
|
if ($year) {
|
|
return $db->fetchAll(
|
|
"SELECT * FROM electricity_payments WHERE house_id = ? AND year = ? ORDER BY FIELD(period, 'Ene-Feb', 'Mar-Abr', 'May-Jun', 'Jul-Ago', 'Sep-Oct', 'Nov-Dic')",
|
|
[$houseId, $year]
|
|
);
|
|
}
|
|
|
|
return $db->fetchAll(
|
|
"SELECT * FROM electricity_payments WHERE house_id = ? ORDER BY year DESC, FIELD(period, 'Ene-Feb', 'Mar-Abr', 'May-Jun', 'Jul-Ago', 'Sep-Oct', 'Nov-Dic') DESC",
|
|
[$houseId]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Obtener total de pagos de un año
|
|
*/
|
|
public static function getTotalByYear($year)
|
|
{
|
|
$db = Database::getInstance();
|
|
$result = $db->fetchOne(
|
|
"SELECT COALESCE(SUM(amount), 0) as total FROM electricity_payments WHERE year = ?",
|
|
[$year]
|
|
);
|
|
return $result['total'] ?? 0;
|
|
}
|
|
} |