fetchAll($sql); } public static function findById($id) { $db = Database::getInstance(); return $db->fetchOne( "SELECT * FROM finance_collection_concepts WHERE id = ?", [$id] ); } public static function create($data, $userId) { $db = Database::getInstance(); $db->execute( "INSERT INTO finance_collection_concepts (name, description, total_amount, amount_per_house, concept_date, due_date, category, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $data['name'], $data['description'] ?? null, $data['total_amount'] ?? null, $data['amount_per_house'], $data['concept_date'], $data['due_date'] ?? null, $data['category'] ?? null, $userId ] ); return $db->lastInsertId(); } public static function update($id, $data) { $db = Database::getInstance(); return $db->execute( "UPDATE finance_collection_concepts SET name = ?, description = ?, total_amount = ?, amount_per_house = ?, concept_date = ?, due_date = ?, category = ? WHERE id = ?", [ $data['name'], $data['description'] ?? null, $data['total_amount'] ?? null, $data['amount_per_house'], $data['concept_date'], $data['due_date'] ?? null, $data['category'] ?? null, $id ] ); } public static function save($data, $userId) { if (isset($data['id']) && !empty($data['id'])) { return self::update($data['id'], $data); } else { return self::create($data, $userId); } } public static function delete($id) { $db = Database::getInstance(); return $db->execute( "DELETE FROM finance_collection_concepts WHERE id = ?", [$id] ); } public static function getPaymentsByConcept($conceptId) { $db = Database::getInstance(); return $db->fetchAll( "SELECT cp.*, h.number as house_number, h.owner_name FROM finance_collection_payments cp JOIN houses h ON cp.house_id = h.id WHERE cp.concept_id = ? ORDER BY CAST(h.number AS UNSIGNED)", [$conceptId] ); } public static function getTotalCollected($conceptId) { $db = Database::getInstance(); $result = $db->fetchOne( "SELECT COALESCE(SUM(amount), 0) as total FROM finance_collection_payments WHERE concept_id = ?", [$conceptId] ); return $result['total'] ?? 0; } public static function getCollectionStatus($conceptId) { $concept = self::findById($conceptId); $totalHouses = House::countActive(); $totalExpected = $concept['amount_per_house'] * $totalHouses; $totalCollected = self::getTotalCollected($conceptId); $totalExpenses = Expense::getTotalByConcept($conceptId); return [ 'total_houses' => $totalHouses, 'total_expected' => $totalExpected, 'total_collected' => $totalCollected, 'total_expenses' => $totalExpenses, 'balance' => $totalCollected - $totalExpenses, 'percentage' => $totalExpected > 0 ? round(($totalCollected / $totalExpected) * 100, 2) : 0, 'pending' => max(0, $totalExpected - $totalCollected) ]; } } class CollectionPayment { public static function getForConcept($conceptId) { $db = Database::getInstance(); $payments = $db->fetchAll( "SELECT cp.*, h.number as house_number, h.owner_name FROM finance_collection_payments cp JOIN houses h ON cp.house_id = h.id WHERE cp.concept_id = ? ORDER BY CAST(h.number AS UNSIGNED)", [$conceptId] ); $result = []; foreach ($payments as $p) { $result[$p['house_id']] = $p; } return $result; } public static function update($conceptId, $houseId, $amount, $userId, $notes = null, $paymentDate = null) { $db = Database::getInstance(); $existing = $db->fetchOne( "SELECT id FROM finance_collection_payments WHERE concept_id = ? AND house_id = ?", [$conceptId, $houseId] ); $currentDateTime = date('Y-m-d H:i:s'); $paymentDate = $paymentDate ? $paymentDate : $currentDateTime; if ($existing) { $db->execute( "UPDATE finance_collection_payments SET amount = ?, payment_date = ?, notes = ?, created_by = ? WHERE id = ?", [$amount, $paymentDate, $notes, $userId, $existing['id']] ); } else { $db->execute( "INSERT INTO finance_collection_payments (concept_id, house_id, amount, payment_date, notes, created_by) VALUES (?, ?, ?, ?, ?, ?)", [$conceptId, $houseId, $amount, $paymentDate, $notes, $userId] ); } return ['success' => true, 'deleted' => false]; } public static function getByHouse($houseId) { $db = Database::getInstance(); return $db->fetchAll( "SELECT cp.*, c.name as concept_name FROM finance_collection_payments cp JOIN finance_collection_concepts c ON cp.concept_id = c.id WHERE cp.house_id = ? ORDER BY cp.created_at DESC", [$houseId] ); } public static function initializePayments($conceptId, $userId) { require_once __DIR__ . '/House.php'; // Incluir House model $houses = House::getActive(); // Obtener solo casas activas $db = Database::getInstance(); $db->beginTransaction(); try { // Eliminar pagos existentes para este concepto antes de inicializar $db->execute("DELETE FROM finance_collection_payments WHERE concept_id = ?", [$conceptId]); foreach ($houses as $house) { self::update($conceptId, $house['id'], 0, $userId, 'Pago inicializado', date('Y-m-d H:i:s')); } $db->commit(); return true; } catch (Exception $e) { $db->rollBack(); error_log("Error al inicializar pagos de concepto: " . $e->getMessage()); return false; } } }