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:
93
models/ElectricityBill.php
Executable file
93
models/ElectricityBill.php
Executable file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
class ElectricityBill
|
||||
{
|
||||
/**
|
||||
* Obtener configuraciones de todos los periodos de un año
|
||||
*/
|
||||
public static function getYear($year)
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
$bills = $db->fetchAll(
|
||||
"SELECT * FROM electricity_bills WHERE year = ? ORDER BY FIELD(period, 'Ene-Feb', 'Mar-Abr', 'May-Jun', 'Jul-Ago', 'Sep-Oct', 'Nov-Dic')",
|
||||
[$year]
|
||||
);
|
||||
|
||||
// Organizar por periodo
|
||||
$result = [];
|
||||
foreach ($bills as $bill) {
|
||||
$result[$bill['period']] = $bill;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guardar o actualizar configuración de un periodo
|
||||
*/
|
||||
public static function save($data, $userId)
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
$id = $data['id'] ?? null;
|
||||
$year = $data['year'];
|
||||
$period = $data['period'];
|
||||
$totalAmount = $data['total_amount'] ?? 0;
|
||||
$amountPerHouse = $data['amount_per_house'] ?? 0;
|
||||
$notes = $data['notes'] ?? '';
|
||||
|
||||
if ($id) {
|
||||
// Actualizar existente
|
||||
$db->execute(
|
||||
"UPDATE electricity_bills
|
||||
SET total_amount = ?, amount_per_house = ?, notes = ?, updated_at = NOW()
|
||||
WHERE id = ?",
|
||||
[$totalAmount, $amountPerHouse, $notes, $id]
|
||||
);
|
||||
return $id;
|
||||
}
|
||||
else {
|
||||
// Insertar nuevo o actualizar si existe
|
||||
$db->execute(
|
||||
"INSERT INTO electricity_bills (year, period, total_amount, amount_per_house, notes)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
total_amount = VALUES(total_amount),
|
||||
amount_per_house = VALUES(amount_per_house),
|
||||
notes = VALUES(notes),
|
||||
updated_at = NOW()",
|
||||
[$year, $period, $totalAmount, $amountPerHouse, $notes]
|
||||
);
|
||||
return $db->lastInsertId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener periodos bimestrales
|
||||
*/
|
||||
public static function getPeriods()
|
||||
{
|
||||
return [
|
||||
'Ene-Feb',
|
||||
'Mar-Abr',
|
||||
'May-Jun',
|
||||
'Jul-Ago',
|
||||
'Sep-Oct',
|
||||
'Nov-Dic'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener configuración de un periodo específico
|
||||
*/
|
||||
public static function getByYearPeriod($year, $period)
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
return $db->fetchOne(
|
||||
"SELECT * FROM electricity_bills WHERE year = ? AND period = ?",
|
||||
[$year, $period]
|
||||
);
|
||||
}
|
||||
}
|
||||
191
models/ElectricityPayment.php
Executable file
191
models/ElectricityPayment.php
Executable file
@@ -0,0 +1,191 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user