casadoc/public/userportal/tabs/proprietari.php
2025-04-22 08:05:22 +02:00

799 lines
34 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
global $idhome, $isNew, $homeData, $namedb, $addressdb, $countrydb, $citydb, $zipdb, $commentdb, $latitudedb, $longitudedb, $fulladdressdb;
require_once dirname(__DIR__) . '/class/db-functions.php';
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Recupera i dettagli dell'immobile
$stmt = $pdo->prepare("SELECT name, address, zip, city, country FROM home WHERE idhome = ?");
$stmt->execute([$idhome]);
$homeDetails = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$homeDetails) {
die("Immobile non trovato o accesso non autorizzato.");
}
// Recupera i proprietari associati all'immobile
$stmt = $pdo->prepare("
SELECT
po.owner_id,
po.first_name,
po.last_name,
po.company_name,
po.tax_code,
po.email,
ho.ownership_percentage,
ho.notes
FROM
home_owners AS ho
INNER JOIN
property_owners AS po ON ho.owner_id = po.owner_id
WHERE
ho.home_id = ?
");
$stmt->execute([$idhome]);
$owners = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Recupera tutti i proprietari disponibili dell'utente per la selezione
$stmt = $pdo->prepare("
SELECT
owner_id,
first_name,
last_name,
company_name,
tax_code
FROM
property_owners
WHERE
user_id = ?
AND owner_id NOT IN (
SELECT owner_id FROM home_owners WHERE home_id = ?
)
");
$stmt->execute([$iduserlogin, $idhome]);
$availableOwners = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<style>
/* Stile per l'overlay dello spinner */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9999;
display: none;
}
.loading-overlay .spinner-custom {
width: 4rem;
height: 4rem;
border: 4px solid #fff;
border-top: 4px solid #007bff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loading-overlay .spinner-text {
color: #fff;
font-size: 1.2rem;
margin-top: 1rem;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<div class="card card-body">
<!-- Overlay dello spinner -->
<div id="loading-overlay" class="loading-overlay">
<div class="spinner-custom"></div>
<div class="spinner-text">Caricamento...</div>
</div>
<!-- Dettagli dell'immobile -->
<div class="card-header bg-warning text-white mb-4">
<h4 class="mb-0"><?php echo htmlspecialchars($homeDetails['name']); ?></h4>
<span class="badge bg-info text-primary">
<?php echo htmlspecialchars($homeDetails['address'] . ', ' . $homeDetails['zip'] . ', ' . $homeDetails['city'] . ', ' . $homeDetails['country']); ?>
</span>
</div>
<!-- Proprietari associati -->
<div class="card mb-4">
<div class="card-header bg-success text-white">
<h5 class="mb-0">Proprietari</h5>
</div>
<div class="card-body">
<?php if (!empty($owners)) { ?>
<div id="ownersTable">
<table class="table table-bordered">
<thead>
<tr>
<th>Nome</th>
<th>Codice Fiscale</th>
<th>%</th>
<th>Note</th>
<th>Azioni</th>
</tr>
</thead>
<tbody id="ownersTableBody">
<?php
$totalPercentage = 0;
foreach ($owners as $owner) {
$totalPercentage += $owner['ownership_percentage'];
echo "<tr>
<td>" . htmlspecialchars($owner['first_name'] . ' ' . $owner['last_name']) . "</td>
<td>" . htmlspecialchars($owner['tax_code']) . "</td>
<td class='ownership-percentage'>" . htmlspecialchars($owner['ownership_percentage']) . "</td>
<td>" . htmlspecialchars($owner['notes']) . "</td>
<td>
<button class='btn btn-danger btn-sm remove-owner-btn' data-id='" . $owner['owner_id'] . "'>
<i class='fas fa-trash-alt'></i> Rimuovi
</button>
</td>
</tr>";
}
?>
</tbody>
<tfoot>
<tr>
<td colspan="2"><strong>Totale % Proprietà:</strong></td>
<td id="totalOwnership" class="font-weight-bold text-center"><?php echo $totalPercentage; ?>%</td>
<td colspan="2"></td>
</tr>
</tfoot>
</table>
</div>
<?php } else { ?>
<div id="ownersTable">
<p class="text-muted">Nessun proprietario associato.</p>
</div>
<?php } ?>
</div>
</div>
<!-- Aggiungi proprietari -->
<div class="card mb-4">
<div class="card-header bg-info text-white">
<h5 class="mb-0">Assegna Proprietari</h5>
</div>
<div class="card-body">
<form id="addOwnerForm" method="POST">
<input type="hidden" name="idhome" value="<?php echo $idhome; ?>">
<div class="form-group">
<label for="ownerSelect">Seleziona Proprietario</label>
<select class="form-control" id="ownerSelect" name="owner_id" required>
<option value="">-- Seleziona --</option>
<?php foreach ($availableOwners as $availableOwner) { ?>
<option value="<?php echo $availableOwner['owner_id']; ?>">
<?php
echo htmlspecialchars($availableOwner['first_name'] . ' ' . $availableOwner['last_name']);
if ($availableOwner['company_name']) {
echo ' (' . htmlspecialchars($availableOwner['company_name']) . ')';
}
echo ' - ' . htmlspecialchars($availableOwner['tax_code']);
?>
</option>
<?php } ?>
<option value="new_owner"> Aggiungi nuovo proprietario</option>
</select>
</div>
<div class="form-group">
<label for="ownershipPercentage">Percentuale di Proprietà</label>
<input type="number" step="0.01" class="form-control" id="ownershipPercentage" name="ownership_percentage" placeholder="Inserisci la percentuale (es. 50.00)" required>
</div>
<div class="form-group">
<label for="notes">Note</label>
<textarea class="form-control" id="notes" name="notes" rows="3" placeholder="Aggiungi eventuali note"></textarea>
</div>
<!-- Messaggio di errore -->
<small id="percentageError" class="text-danger" style="display:none;">La somma totale non può superare il 100%.</small>
<button type="submit" id="addOwnerBtn" class="btn btn-success mt-3">Aggiungi</button>
</form>
</div>
</div>
</div>
<!-- Modal Aggiungi Nuovo Proprietario -->
<div class="modal fade" id="newOwnerModal" tabindex="-1" aria-labelledby="newOwnerModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="newOwnerModalLabel">Aggiungi Nuovo Proprietario</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form id="newOwnerForm">
<input type="hidden" name="user_id" value="<?php echo $iduserlogin; ?>">
<div class="row">
<!-- Tipo Proprietario -->
<div class="col-md-6">
<div class="form-group">
<label for="ownerType">Tipo Proprietario</label>
<select class="form-control" id="ownerType" name="owner_type" required>
<option value="individual">Persona Fisica</option>
<option value="company">Azienda</option>
</select>
</div>
</div>
<!-- Codice Fiscale / P. IVA -->
<div class="col-md-6">
<div class="form-group">
<label for="taxCode">Codice Fiscale / Partita IVA</label>
<input type="text" class="form-control" id="taxCode" name="tax_code" required>
</div>
</div>
<!-- Nome -->
<div class="col-md-6">
<div class="form-group">
<label for="firstName">Nome</label>
<input type="text" class="form-control" id="firstName" name="first_name">
</div>
</div>
<!-- Cognome -->
<div class="col-md-6">
<div class="form-group">
<label for="lastName">Cognome</label>
<input type="text" class="form-control" id="lastName" name="last_name">
</div>
</div>
<!-- Nome Azienda -->
<div class="col-md-12">
<div class="form-group">
<label for="companyName">Nome Azienda</label>
<input type="text" class="form-control" id="companyName" name="company_name" disabled>
</div>
</div>
<!-- Email -->
<div class="col-md-6">
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
</div>
<!-- Telefono -->
<div class="col-md-6">
<div class="form-group">
<label for="phone">Telefono</label>
<input type="text" class="form-control" id="phone" name="phone">
</div>
</div>
<!-- Indirizzo -->
<div class="col-md-6">
<div class="form-group">
<label for="address">Indirizzo</label>
<input type="text" class="form-control" id="address" name="address">
</div>
</div>
<!-- CAP -->
<div class="col-md-3">
<div class="form-group">
<label for="postalCode">CAP</label>
<input type="text" class="form-control" id="postalCode" name="postal_code">
</div>
</div>
<!-- Città -->
<div class="col-md-3">
<div class="form-group">
<label for="city">Città</label>
<input type="text" class="form-control" id="city" name="city">
</div>
</div>
<!-- Provincia -->
<div class="col-md-6">
<div class="form-group">
<label for="province">Provincia</label>
<input type="text" class="form-control" id="province" name="province">
</div>
</div>
<!-- Nazione -->
<div class="col-md-6">
<div class="form-group">
<label for="country">Nazione</label>
<select class="form-control" id="country" name="country">
<option value="">-- Seleziona --</option>
<?php
$stmt = $pdo->query("SELECT id, name FROM auth_countries ORDER BY name");
while ($country = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<option value='{$country['id']}'>" . htmlspecialchars($country['name']) . "</option>";
}
?>
</select>
</div>
</div>
<!-- Ruolo -->
<div class="col-md-6">
<div class="form-group">
<label for="role">Ruolo</label>
<input type="text" class="form-control" id="role" name="role">
</div>
</div>
<!-- Note -->
<div class="col-md-12">
<div class="form-group">
<label for="notes">Note</label>
<textarea class="form-control" id="notes" name="notes" rows="3"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annulla</button>
<button type="submit" class="btn btn-success">Salva Proprietario</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
// Passa iduserlogin come variabile JavaScript
const iduserlogin = <?php echo $iduserlogin; ?>;
$(document).ready(function() {
// Verifica che jQuery sia caricato
if (typeof jQuery === "undefined") {
console.error("jQuery non è caricato!");
Swal.fire({
icon: "error",
title: "Errore",
text: "jQuery non è caricato. Contatta l'amministratore."
});
return;
}
// Verifica che Bootstrap modal sia caricato
if (typeof $.fn.modal === "undefined") {
console.error("Bootstrap modal non è caricato!");
Swal.fire({
icon: "error",
title: "Errore",
text: "Bootstrap modal non è caricato. Contatta l'amministratore."
});
return;
}
// Inizializza Select2 se disponibile, altrimenti usa il dropdown nativo
let isSelect2Available = typeof $.fn.select2 !== "undefined";
if (isSelect2Available) {
$("#country").select2({
width: '100%',
placeholder: "Seleziona un paese...",
allowClear: true
});
$("#ownerSelect").select2({
width: '100%',
placeholder: "-- Seleziona --"
});
} else {
console.warn("Select2 non è disponibile, utilizzo dropdown nativo.");
}
// Gestione del totale percentuale e colore
function updateTotalOwnership() {
let total = 0;
document.querySelectorAll(".ownership-percentage").forEach(function(el) {
total += parseFloat(el.textContent) || 0;
});
const totalCell = document.getElementById("totalOwnership");
// Controlla se totalCell esiste prima di aggiornarlo
if (!totalCell) {
console.warn("Elemento #totalOwnership non trovato nel DOM. Probabilmente non ci sono proprietari associati.");
return total;
}
totalCell.textContent = total.toFixed(2) + "%";
if (total >= 100) {
totalCell.style.backgroundColor = "#28a745"; // Verde
totalCell.style.color = "#fff";
document.getElementById("addOwnerForm").style.display = "none"; // Nasconde il form se il totale è 100%
} else {
totalCell.style.backgroundColor = "#ffc107"; // Arancione
totalCell.style.color = "#212529";
document.getElementById("addOwnerForm").style.display = "block";
}
return total;
}
// Validazione percentuale in tempo reale
$("#ownershipPercentage").on("input", function() {
let totalOwnership = updateTotalOwnership();
let newPercentage = parseFloat(this.value) || 0;
let remainingPercentage = 100 - totalOwnership;
let errorMsg = document.getElementById("percentageError");
let submitBtn = document.getElementById("addOwnerBtn");
if (newPercentage > remainingPercentage) {
errorMsg.style.display = "block";
submitBtn.disabled = true;
} else {
errorMsg.style.display = "none";
submitBtn.disabled = false;
}
});
// Inizializza il totale all'avvio
updateTotalOwnership();
// Selezione del proprietario nel dropdown
$("#ownerSelect").on("change", function() {
console.log("ownerSelect cambiato, valore:", $(this).val());
if ($(this).val() === "new_owner") {
try {
$("#newOwnerModal").modal("show");
$(this).val("").trigger("change");
} catch (e) {
console.error("Errore apertura modale:", e);
Swal.fire({
icon: "error",
title: "Errore",
text: "Impossibile aprire il modale per aggiungere un nuovo proprietario: " + e.message
});
}
}
});
// Abilita/disabilita i campi in base al tipo di proprietario
$("#ownerType").on("change", function() {
if ($(this).val() === "company") {
$("#companyName").prop("disabled", false);
$("#firstName, #lastName").prop("disabled", true).val("");
} else {
$("#companyName").prop("disabled", true).val("");
$("#firstName, #lastName").prop("disabled", false);
}
});
// Funzione per aggiornare il dropdown
function updateOwnerSelect() {
return fetch(`get-available-owners.php?idhome=<?php echo $idhome; ?>&iduser=${iduserlogin}`)
.then(response => {
if (!response.ok) {
throw new Error('Errore nella risposta del server: ' + response.statusText);
}
return response.text();
})
.then(html => {
const tempDiv = document.createElement("div");
tempDiv.innerHTML = html;
const newSelect = tempDiv.querySelector("select#ownerSelect");
if (newSelect) {
const ownerSelect = document.getElementById("ownerSelect");
ownerSelect.innerHTML = newSelect.innerHTML;
if (isSelect2Available) {
// Distruggi l'istanza precedente di Select2
$("#ownerSelect").select2('destroy');
// Inizializza Select2
$("#ownerSelect").select2({
width: "100%",
placeholder: "-- Seleziona --",
allowClear: true
});
// Forza Select2 a mostrare l'opzione vuota come selezionabile
const optionsCount = ownerSelect.options.length;
if (optionsCount <= 2) {
$("#ownerSelect").val(null).trigger('change');
}
}
// Debug: verifica quante opzioni ci sono nel dropdown
const optionsCount = ownerSelect.options.length;
console.log("Numero di opzioni nel dropdown dopo aggiornamento:", optionsCount);
// Verifica se il dropdown ha almeno l'opzione "Aggiungi nuovo"
const hasAddNewOption = Array.from(ownerSelect.options).some(option => option.value === "new_owner");
if (!hasAddNewOption) {
const newOption = new Option(" Aggiungi nuovo proprietario", "new_owner");
ownerSelect.appendChild(newOption);
if (isSelect2Available) {
$("#ownerSelect").trigger('change');
}
}
} else {
throw new Error("Elemento select#ownerSelect non trovato nel risultato.");
}
})
.catch(error => {
console.error("Errore aggiornamento dropdown:", error);
const ownerSelect = document.getElementById("ownerSelect");
ownerSelect.innerHTML = '<option value="">-- Seleziona --</option><option value="new_owner"> Aggiungi nuovo proprietario</option>';
if (isSelect2Available) {
$("#ownerSelect").select2({
width: "100%",
placeholder: "-- Seleziona --",
allowClear: true
});
}
Swal.fire({
icon: "error",
title: "Errore",
text: "Errore nell'aggiornamento del dropdown dei proprietari: " + error.message
});
});
}
// Funzione per aggiornare la tabella
function updateOwnersTable() {
return fetch("get-owners.php?idhome=<?php echo $idhome; ?>")
.then(response => {
if (!response.ok) {
throw new Error('Errore nella risposta del server: ' + response.statusText);
}
return response.text();
})
.then(html => {
document.getElementById("ownersTable").innerHTML = html;
updateTotalOwnership();
})
.catch(error => {
console.error("Errore aggiornamento tabella:", error);
Swal.fire({
icon: "error",
title: "Errore",
text: "Errore nell'aggiornamento della tabella dei proprietari: " + error.message
});
});
}
// Validazione client-side del form del nuovo proprietario
$("#newOwnerForm").on("submit", function(e) {
e.preventDefault();
const taxCode = $("#taxCode").val().trim();
const email = $("#email").val().trim();
const ownerType = $("#ownerType").val();
const firstName = $("#firstName").val().trim();
const lastName = $("#lastName").val().trim();
const companyName = $("#companyName").val().trim();
// Controlli di validazione
if (!taxCode) {
Swal.fire({
icon: "error",
title: "Errore",
text: "Il codice fiscale o partita IVA è obbligatorio."
});
return;
}
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
Swal.fire({
icon: "error",
title: "Errore",
text: "Inserisci un'email valida."
});
return;
}
if (ownerType === "individual" && (!firstName || !lastName)) {
Swal.fire({
icon: "error",
title: "Errore",
text: "Nome e cognome sono obbligatori per una persona fisica."
});
return;
}
if (ownerType === "company" && !companyName) {
Swal.fire({
icon: "error",
title: "Errore",
text: "Il nome dell'azienda è obbligatorio per un'azienda."
});
return;
}
const loadingOverlay = document.getElementById("loading-overlay");
loadingOverlay.style.display = "flex";
$.post("add-new-owner.php", $(this).serialize(), function(response) {
loadingOverlay.style.display = "none";
let result;
try {
result = JSON.parse(response);
} catch (e) {
Swal.fire({
icon: "error",
title: "Errore",
text: "Risposta non valida dal server: " + e.message
});
return;
}
if (result.success) {
Swal.fire({
icon: "success",
title: "Proprietario aggiunto!",
text: result.message,
timer: 1500,
showConfirmButton: false
}).then(() => {
$("#newOwnerModal").modal("hide");
// Aggiorna la tabella dei proprietari
updateOwnersTable();
// Aggiorna il dropdown dei proprietari disponibili
updateOwnerSelect();
// Resetta il form del modale
$("#newOwnerForm")[0].reset();
$("#companyName").prop("disabled", true);
$("#firstName, #lastName").prop("disabled", false);
});
} else {
Swal.fire({
icon: "error",
title: "Errore",
text: result.message
});
}
}).fail(function(jqXHR, textStatus, errorThrown) {
loadingOverlay.style.display = "none";
Swal.fire({
icon: "error",
title: "Errore",
text: "Si è verificato un problema con la richiesta: " + textStatus + " - " + errorThrown
});
});
});
// Aggiunta di un proprietario esistente
$("#addOwnerForm").on("submit", function(e) {
e.preventDefault();
const ownerId = $("#ownerSelect").val();
const percentage = parseFloat($("#ownershipPercentage").val()) || 0;
const totalOwnership = updateTotalOwnership();
if (!ownerId) {
Swal.fire({
icon: "error",
title: "Errore",
text: "Seleziona un proprietario."
});
return;
}
if (totalOwnership + percentage > 100) {
Swal.fire({
icon: "error",
title: "Errore",
text: "La somma totale dei proprietari supererebbe il 100%."
});
return;
}
const loadingOverlay = document.getElementById("loading-overlay");
loadingOverlay.style.display = "flex";
let formData = new FormData(this);
fetch("add-owner-to-home.php", {
method: "POST",
body: formData,
})
.then(response => response.json())
.then(data => {
loadingOverlay.style.display = "none";
if (data.success) {
Swal.fire({
icon: "success",
title: "Proprietario aggiunto!",
text: data.message,
timer: 1500,
showConfirmButton: false
}).then(() => {
// Aggiorna la tabella dei proprietari
updateOwnersTable();
// Aggiorna il dropdown dei proprietari disponibili
updateOwnerSelect();
// Resetta il form
this.reset();
$("#ownerSelect").val("").trigger("change");
});
} else {
Swal.fire({
icon: "error",
title: "Errore",
text: data.message
});
}
})
.catch(error => {
loadingOverlay.style.display = "none";
Swal.fire({
icon: "error",
title: "Errore",
text: "Si è verificato un problema con la richiesta: " + error.message
});
});
});
// Rimozione di un proprietario
$(document).on("click", ".remove-owner-btn", function() {
const ownerId = $(this).data("id");
const idhome = "<?php echo $idhome; ?>";
Swal.fire({
title: "Sei sicuro?",
text: "Questa azione rimuoverà il proprietario selezionato.",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#d33",
cancelButtonColor: "#3085d6",
confirmButtonText: "Sì, rimuovi",
cancelButtonText: "Annulla",
}).then((result) => {
if (result.isConfirmed) {
const loadingOverlay = document.getElementById("loading-overlay");
loadingOverlay.style.display = "flex";
$.post("remove-owner-from-home.php", {
owner_id: ownerId,
idhome: idhome
}, function(response) {
loadingOverlay.style.display = "none";
let result;
try {
result = JSON.parse(response);
} catch (e) {
Swal.fire({
icon: "error",
title: "Errore",
text: "Risposta non valida dal server: " + e.message
});
return;
}
if (result.success) {
Swal.fire({
icon: "success",
title: "Rimosso",
text: result.message,
timer: 1500,
showConfirmButton: false,
}).then(() => {
// Aggiorna la tabella dei proprietari
updateOwnersTable();
// Aggiorna il dropdown dei proprietari disponibili
updateOwnerSelect();
});
} else {
Swal.fire({
icon: "error",
title: "Errore",
text: result.message,
});
}
}).fail(function(jqXHR, textStatus, errorThrown) {
loadingOverlay.style.display = "none";
Swal.fire({
icon: "error",
title: "Errore",
text: "Impossibile completare la richiesta: " + textStatus + " - " + errorThrown
});
});
}
});
});
});
</script>