update document page

This commit is contained in:
2025-04-22 08:05:22 +02:00
parent b63606a48c
commit 1da7ee5208
21 changed files with 6480 additions and 2970 deletions
+799
View File
@@ -0,0 +1,799 @@
<?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>