netgescon-day0/resources/views/admin/stabili/tabs/tabelle-millesimali.blade.php

1479 lines
85 KiB
PHP
Executable File

<!-- Tab Tabelle Millesimali - NetGescon Layout Completo -->
<div class="space-y-6">
<!-- Header con azioni principali -->
<div class="flex justify-between items-center">
<div>
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<i class="fas fa-table mr-2 text-blue-600"></i>
Gestione Tabelle Millesimali e Voci di Spesa
</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Stabile: "{{ $stabile->denominazione }}" - Sistema integrato di ripartizione
</p>
</div>
<div class="flex space-x-3">
<button type="button"
class="netgescon-btn netgescon-btn-primary"
onclick="openGestioneCompleta()">
<i class="fas fa-calculator mr-2"></i>
Gestione Completa
</button>
<button type="button"
class="netgescon-btn netgescon-btn-secondary"
onclick="openProspettoRipartizione()">
<i class="fas fa-chart-pie mr-2"></i>
Prospetto Ripartizione
</button>
</div>
</div>
<!-- Sub-tabs principali (spostati in alto) -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border">
<div class="border-b border-gray-200 dark:border-gray-700 px-6 pt-4">
<nav class="-mb-px flex space-x-6" aria-label="Dettaglio-tabs" role="tablist">
<button class="netgescon-subtab-btn active"
data-subtab="gestione-principale"
type="button"
role="tab">
<i class="fas fa-table mr-2"></i>
Gestione Principale
</button>
<button class="netgescon-subtab-btn"
data-subtab="gestione-preventivi"
type="button"
role="tab">
<i class="fas fa-chart-line mr-2"></i>
Gestione Preventivi
</button>
<button class="netgescon-subtab-btn"
data-subtab="dettaglio-millesimi"
type="button"
role="tab">
<i class="fas fa-list-ul mr-2"></i>
Dettaglio Millesimi
</button>
<button class="netgescon-subtab-btn"
data-subtab="storico-ripartizioni"
type="button"
role="tab">
<i class="fas fa-history mr-2"></i>
Storico Ripartizioni
</button>
<button class="netgescon-subtab-btn"
data-subtab="configurazione-avanzata"
type="button"
role="tab">
<i class="fas fa-cogs mr-2"></i>
Configurazione Avanzata
</button>
</nav>
</div>
<!-- Contenuto sub-tabs -->
<div class="px-6 pb-6">
<!-- Gestione Principale (Layout a 2 colonne attuale) -->
<div id="gestione-principale" class="netgescon-subtab-content active pt-6">
<!-- Layout principale a 2 colonne -->
<div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
<!-- COLONNA SINISTRA: Tabelle Millesimali -->
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg shadow-sm border">
<div class="border-b border-gray-200 dark:border-gray-700 px-6 py-4">
<div class="flex justify-between items-center">
<h4 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<i class="fas fa-table mr-2 text-blue-600"></i>
Tabelle Millesimali
</h4>
<button type="button"
class="netgescon-btn netgescon-btn-sm netgescon-btn-primary"
onclick="openCreateTabellaModal()">
<i class="fas fa-plus mr-1"></i>
Nuova Tabella
</button>
</div>
</div>
<div class="px-6 py-4">
<!-- Lista Tabelle Millesimali con dati esempio -->
<div class="space-y-3 max-h-96 overflow-y-auto">
@forelse($stabile->tabelleMillesimali ?? [] as $index => $tabella)
<div class="tabella-item bg-white dark:bg-gray-800 p-4 rounded-lg border-l-4 border-blue-500 hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer transition-colors"
onclick="selectTabella({{ $tabella->id }}, '{{ $tabella->nome_tabella ?? 'Tabella Millesimale' }}')">
<div class="flex justify-between items-start">
<div class="flex-1">
<div class="flex items-center space-x-2 mb-2">
<h5 class="font-medium text-gray-900 dark:text-gray-100">
{{ $tabella->nome_tabella ?? 'Tabella Millesimale' }}
</h5>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium
{{ ($tabella->tipo_tabella ?? 'proprieta') === 'proprieta' ? 'bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100' : 'bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100' }}">
{{ ucfirst($tabella->tipo_tabella ?? 'Proprietà') }}
</span>
@if($tabella->attiva ?? true)
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
<i class="fas fa-check-circle mr-1"></i>
Attiva
</span>
@endif
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
{{ $tabella->descrizione ?? 'Tabella millesimale per ripartizione spese' }}
</p>
<div class="grid grid-cols-2 gap-4 text-xs">
<div>
<span class="text-gray-500 dark:text-gray-400">Unità:</span>
<span class="font-mono font-medium">{{ $stabile->unitaImmobiliari?->count() ?? 50 }}</span>
</div>
<div>
<span class="text-gray-500 dark:text-gray-400">Totale:</span>
<span class="font-mono font-medium">{{ number_format($tabella->totale_millesimi ?? 1000, 0) }}</span>
</div>
</div>
</div>
<div class="flex flex-col space-y-1 ml-4">
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-primary"
onclick="event.stopPropagation(); editTabella({{ $tabella->id }})">
<i class="fas fa-edit"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-secondary"
onclick="event.stopPropagation(); viewDettagliTabella({{ $tabella->id }})">
<i class="fas fa-eye"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-danger"
onclick="event.stopPropagation(); deleteTabella({{ $tabella->id }})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
@empty
<!-- Dati esempio se non ci sono tabelle -->
<div class="tabella-item bg-white dark:bg-gray-800 p-4 rounded-lg border-l-4 border-blue-500 hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer transition-colors"
onclick="selectTabella(1, 'Tabella Generale Proprietà')">
<div class="flex justify-between items-start">
<div class="flex-1">
<div class="flex items-center space-x-2 mb-2">
<h5 class="font-medium text-gray-900 dark:text-gray-100">
Tabella Generale Proprietà
</h5>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-800 dark:text-blue-100">
Proprietà
</span>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
<i class="fas fa-check-circle mr-1"></i>
Attiva
</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
Tabella millesimale generale per ripartizione spese ordinarie
</p>
<div class="grid grid-cols-2 gap-4 text-xs">
<div>
<span class="text-gray-500 dark:text-gray-400">Unità:</span>
<span class="font-mono font-medium">{{ $stabile->unitaImmobiliari?->count() ?? 50 }}</span>
</div>
<div>
<span class="text-gray-500 dark:text-gray-400">Totale:</span>
<span class="font-mono font-medium">1.000</span>
</div>
</div>
</div>
<div class="flex flex-col space-y-1 ml-4">
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-primary"
onclick="event.stopPropagation(); editTabella(1)">
<i class="fas fa-edit"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-secondary"
onclick="event.stopPropagation(); viewDettagliTabella(1)">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
</div>
<div class="tabella-item bg-white dark:bg-gray-800 p-4 rounded-lg border-l-4 border-green-500 hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer transition-colors"
onclick="selectTabella(2, 'Tabella Riscaldamento')">
<div class="flex justify-between items-start">
<div class="flex-1">
<div class="flex items-center space-x-2 mb-2">
<h5 class="font-medium text-gray-900 dark:text-gray-100">
Tabella Riscaldamento
</h5>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
Riscaldamento
</span>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
<i class="fas fa-check-circle mr-1"></i>
Attiva
</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
Tabella specifica per ripartizione spese riscaldamento
</p>
<div class="grid grid-cols-2 gap-4 text-xs">
<div>
<span class="text-gray-500 dark:text-gray-400">Unità:</span>
<span class="font-mono font-medium">{{ $stabile->unitaImmobiliari?->count() ?? 45 }}</span>
</div>
<div>
<span class="text-gray-500 dark:text-gray-400">Totale:</span>
<span class="font-mono font-medium">1.000</span>
</div>
</div>
</div>
<div class="flex flex-col space-y-1 ml-4">
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-success"
onclick="event.stopPropagation(); editTabella(2)">
<i class="fas fa-edit"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-secondary"
onclick="event.stopPropagation(); viewDettagliTabella(2)">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
</div>
<div class="tabella-item bg-white dark:bg-gray-800 p-4 rounded-lg border-l-4 border-purple-500 hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer transition-colors"
onclick="selectTabella(3, 'Tabella Ascensore')">
<div class="flex justify-between items-start">
<div class="flex-1">
<div class="flex items-center space-x-2 mb-2">
<h5 class="font-medium text-gray-900 dark:text-gray-100">
Tabella Ascensore
</h5>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-800 dark:text-purple-100">
Ascensore
</span>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
<i class="fas fa-check-circle mr-1"></i>
Attiva
</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
Tabella per ripartizione spese manutenzione ascensore
</p>
<div class="grid grid-cols-2 gap-4 text-xs">
<div>
<span class="text-gray-500 dark:text-gray-400">Unità:</span>
<span class="font-mono font-medium">{{ $stabile->unitaImmobiliari?->count() ?? 30 }}</span>
</div>
<div>
<span class="text-gray-500 dark:text-gray-400">Totale:</span>
<span class="font-mono font-medium">1.000</span>
</div>
</div>
</div>
<div class="flex flex-col space-y-1 ml-4">
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-info"
onclick="event.stopPropagation(); editTabella(3)">
<i class="fas fa-edit"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-secondary"
onclick="event.stopPropagation(); viewDettagliTabella(3)">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
</div>
@endforelse
</div>
<!-- Quick Stats Tabelle aggiornate -->
<div class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
<div class="grid grid-cols-3 gap-3 text-center text-sm">
<div class="bg-blue-50 dark:bg-blue-900/20 p-2 rounded">
<div class="font-bold text-blue-600">{{ count($stabile->tabelleMillesimali ?? []) + 3 }}</div>
<div class="text-gray-600 dark:text-gray-400">Totali</div>
</div>
<div class="bg-green-50 dark:bg-green-900/20 p-2 rounded">
<div class="font-bold text-green-600">{{ count($stabile->tabelleMillesimali ?? []) + 3 }}</div>
<div class="text-gray-600 dark:text-gray-400">Attive</div>
</div>
<div class="bg-yellow-50 dark:bg-yellow-900/20 p-2 rounded">
<div class="font-bold text-yellow-600">{{ $stabile->unitaImmobiliari?->count() ?? 50 }}</div>
<div class="text-gray-600 dark:text-gray-400">Unità</div>
</div>
</div>
</div>
</div>
</div>
<!-- COLONNA DESTRA: Voci di Spesa -->
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg shadow-sm border">
<div class="border-b border-gray-200 dark:border-gray-700 px-6 py-4">
<div class="flex justify-between items-center">
<h4 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<i class="fas fa-receipt mr-2 text-green-600"></i>
Voci di Spesa
</h4>
<button type="button"
class="netgescon-btn netgescon-btn-sm netgescon-btn-success"
onclick="openCreateVoceSpesaModal()">
<i class="fas fa-plus mr-1"></i>
Nuova Voce
</button>
</div>
</div>
<div class="px-6 py-4">
<!-- Lista Voci di Spesa con dati -->
<div class="space-y-3 max-h-96 overflow-y-auto">
@forelse($stabile->vociSpesa ?? [] as $voce)
<div class="voce-spesa-item bg-white dark:bg-gray-800 p-4 rounded-lg border-l-4 border-green-500 hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer transition-colors"
onclick="selectVoceSpesa({{ $voce->id }}, '{{ $voce->descrizione }}')">
<div class="flex justify-between items-start">
<div class="flex-1">
<div class="flex items-center space-x-2 mb-2">
<h5 class="font-medium text-gray-900 dark:text-gray-100">
{{ $voce->codice }} - {{ $voce->descrizione }}
</h5>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium
{{ $voce->tipo_gestione === 'ordinaria' ? 'bg-blue-100 text-blue-800' : ($voce->tipo_gestione === 'straordinaria' ? 'bg-red-100 text-red-800' : 'bg-purple-100 text-purple-800') }}">
{{ ucfirst($voce->tipo_gestione) }}
</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
Categoria: {{ $voce->categoria ?? 'Generale' }}
</p>
<div class="grid grid-cols-2 gap-4 text-xs">
<div>
<span class="text-gray-500 dark:text-gray-400">Tabella Default:</span>
<span class="font-mono font-medium">Generale</span>
</div>
<div>
<span class="text-gray-500 dark:text-gray-400">Ritenuta:</span>
<span class="font-mono font-medium">{{ $voce->ritenuta_acconto_default ?? 0 }}%</span>
</div>
</div>
</div>
<div class="flex flex-col space-y-1 ml-4">
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-success"
onclick="event.stopPropagation(); editVoceSpesa({{ $voce->id }})">
<i class="fas fa-edit"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-secondary"
onclick="event.stopPropagation(); viewRipartizioniVoce({{ $voce->id }})">
<i class="fas fa-chart-pie"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-danger"
onclick="event.stopPropagation(); deleteVoceSpesa({{ $voce->id }})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
@empty
<!-- Dati esempio se non ci sono voci di spesa -->
@foreach([
['id' => 1, 'codice' => 'A00', 'descrizione' => 'GESTIONE FISCALE', 'tipo' => 'ordinaria', 'categoria' => 'TAB.A'],
['id' => 2, 'codice' => 'A01', 'descrizione' => 'Assicurazione fabbricato', 'tipo' => 'ordinaria', 'categoria' => 'TAB.A'],
['id' => 3, 'codice' => 'A02', 'descrizione' => 'Tassa occ. spazi Via vai (COSAP)', 'tipo' => 'ordinaria', 'categoria' => 'TAB.A'],
['id' => 4, 'codice' => 'A08', 'descrizione' => 'Spese Postali generali', 'tipo' => 'ordinaria', 'categoria' => 'TAB.A'],
['id' => 5, 'codice' => 'A09', 'descrizione' => 'Riparazioni / lavori', 'tipo' => 'ordinaria', 'categoria' => 'TAB.A'],
['id' => 6, 'codice' => 'A10', 'descrizione' => 'Spese e bollo su CCP', 'tipo' => 'ordinaria', 'categoria' => 'TAB.A']
] as $voce)
<div class="voce-spesa-item bg-white dark:bg-gray-800 p-4 rounded-lg border-l-4 border-green-500 hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer transition-colors"
onclick="selectVoceSpesa({{ $voce['id'] }}, '{{ $voce['descrizione'] }}')">
<div class="flex justify-between items-start">
<div class="flex-1">
<div class="flex items-center space-x-2 mb-2">
<h5 class="font-medium text-gray-900 dark:text-gray-100">
{{ $voce['codice'] }} - {{ $voce['descrizione'] }}
</h5>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
{{ ucfirst($voce['tipo']) }}
</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
Categoria: {{ $voce['categoria'] }}
</p>
<div class="grid grid-cols-2 gap-4 text-xs">
<div>
<span class="text-gray-500 dark:text-gray-400">Tabella Default:</span>
<span class="font-mono font-medium">Generale</span>
</div>
<div>
<span class="text-gray-500 dark:text-gray-400">Ritenuta:</span>
<span class="font-mono font-medium">0,00%</span>
</div>
</div>
</div>
<div class="flex flex-col space-y-1 ml-4">
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-success"
onclick="event.stopPropagation(); editVoceSpesa({{ $voce['id'] }})">
<i class="fas fa-edit"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-secondary"
onclick="event.stopPropagation(); viewRipartizioniVoce({{ $voce['id'] }})">
<i class="fas fa-chart-pie"></i>
</button>
<button type="button"
class="netgescon-btn netgescon-btn-xs netgescon-btn-danger"
onclick="event.stopPropagation(); deleteVoceSpesa({{ $voce['id'] }})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
@endforeach
@endforelse
</div>
<!-- Quick Stats Voci aggiornate -->
<div class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
<div class="grid grid-cols-3 gap-3 text-center text-sm">
<div class="bg-green-50 dark:bg-green-900/20 p-2 rounded">
<div class="font-bold text-green-600">{{ count($stabile->vociSpesa ?? []) + 6 }}</div>
<div class="text-gray-600 dark:text-gray-400">Totali</div>
</div>
<div class="bg-blue-50 dark:bg-blue-900/20 p-2 rounded">
<div class="font-bold text-blue-600">{{ count($stabile->vociSpesa ?? []) + 6 }}</div>
<div class="text-gray-600 dark:text-gray-400">Ordinarie</div>
</div>
<div class="bg-red-50 dark:bg-red-900/20 p-2 rounded">
<div class="font-bold text-red-600">0</div>
<div class="text-gray-600 dark:text-gray-400">Straord.</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Sub-tab Dettaglio Millesimi -->
<div id="dettaglio-millesimi" class="netgescon-subtab-content hidden pt-6">
<div id="dettaglio-content" class="min-h-[200px]">
<div class="text-center py-8">
<i class="fas fa-list-ul text-4xl text-gray-400 mb-4"></i>
<p class="text-gray-600 dark:text-gray-400">Seleziona una tabella millesimale per visualizzare i dettagli</p>
</div>
</div>
</div>
<!-- Sub-tab Gestione Preventivi (nuovo - stile NetGescon originale) -->
<div id="gestione-preventivi" class="netgescon-subtab-content hidden pt-6">
<div class="bg-white dark:bg-gray-800 rounded-lg border overflow-hidden">
<!-- Header con controlli -->
<div class="border-b border-gray-200 dark:border-gray-700 px-6 py-4 bg-gradient-to-r from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/20">
<div class="flex justify-between items-center">
<div>
<h4 class="text-lg font-semibold text-gray-900 dark:text-gray-100">
<i class="fas fa-chart-line mr-2 text-blue-600"></i>
Gestione Preventivi e Consuntivi
</h4>
<p class="text-sm text-gray-600 dark:text-gray-400">
Sistema integrato per la gestione delle spese per scala e voce
</p>
</div>
<div class="flex space-x-2">
<select id="anno-gestione" class="netgescon-input text-sm">
<option value="2025">Anno 2025</option>
<option value="2024">Anno 2024</option>
</select>
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-success">
<i class="fas fa-save mr-1"></i>
Salva
</button>
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-info">
<i class="fas fa-print mr-1"></i>
Stampa
</button>
</div>
</div>
</div>
<!-- Tabella stile NetGescon originale -->
<div class="overflow-x-auto">
<table class="min-w-full bg-white dark:bg-gray-800">
<thead class="bg-gradient-to-r from-blue-600 to-blue-700 text-white">
<tr>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider border-r border-blue-500">
Voci di Spesa
</th>
<th class="px-3 py-3 text-center text-xs font-semibold uppercase tracking-wider border-r border-blue-500">
Preventivo
</th>
<th class="px-3 py-3 text-center text-xs font-semibold uppercase tracking-wider border-r border-blue-500">
Consuntivo
</th>
<th class="px-3 py-3 text-center text-xs font-semibold uppercase tracking-wider border-r border-blue-500">
Differenza
</th>
<th class="px-3 py-3 text-center text-xs font-semibold uppercase tracking-wider border-r border-blue-500">
Scala A
</th>
<th class="px-3 py-3 text-center text-xs font-semibold uppercase tracking-wider border-r border-blue-500">
Scala B
</th>
<th class="px-3 py-3 text-center text-xs font-semibold uppercase tracking-wider">
Scala C
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 dark:divide-gray-600">
<!-- Spese Generali -->
<tr class="bg-yellow-50 dark:bg-yellow-900/20">
<td colspan="7" class="px-4 py-2 font-bold text-gray-900 dark:text-gray-100 bg-yellow-100 dark:bg-yellow-800/30">
<i class="fas fa-folder-open mr-2 text-yellow-600"></i>
SPESE GENERALI
</td>
</tr>
@foreach([
['code' => '', 'desc' => 'Assicurazione fabbricato', 'prev' => '-1.074,00', 'cons' => '-1.074,00', 'diff' => '0,00'],
['code' => '', 'desc' => 'Compenso amministratore', 'prev' => '-1.500,00', 'cons' => '-1.013,93', 'diff' => '486,07'],
['code' => '', 'desc' => 'Redazione Mod. 770', 'prev' => '-160,00', 'cons' => '-180,75', 'diff' => '-20,75'],
['code' => '', 'desc' => 'Interessi e competenze banca', 'prev' => '-303,29', 'cons' => '-120,52', 'diff' => '182,77'],
['code' => '', 'desc' => 'Affitto sala riunioni', 'prev' => '-95,00', 'cons' => '-31,00', 'diff' => '64,00'],
['code' => '', 'desc' => 'Manutenzione cancelli pedonali', 'prev' => '-59,00', 'cons' => '0,00', 'diff' => '59,00'],
['code' => '', 'desc' => 'Manutenzione portoncini ingresso', 'prev' => '-50,00', 'cons' => '0,00', 'diff' => '50,00'],
['code' => '', 'desc' => 'Spese varie ed imprevisti', 'prev' => '-100,00', 'cons' => '-50,93', 'diff' => '49,07']
] as $spesa)
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
<td class="px-4 py-2 text-sm text-gray-900 dark:text-gray-100 border-r border-gray-200 dark:border-gray-600">
{{ $spesa['desc'] }}
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<input type="number" value="{{ str_replace(['-', ','], ['', '.'], $spesa['prev']) }}"
class="w-20 px-1 py-1 text-xs text-center border rounded preventivo-input"
step="0.01" onchange="calcolaDifferenza(this)">
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<input type="number" value="{{ str_replace(['-', ','], ['', '.'], $spesa['cons']) }}"
class="w-20 px-1 py-1 text-xs text-center border rounded consuntivo-input"
step="0.01" onchange="calcolaDifferenza(this)">
</td>
<td class="px-3 py-2 text-center text-sm font-mono text-{{ str_contains($spesa['diff'], '-') ? 'red' : 'green' }}-600 border-r border-gray-200 dark:border-gray-600">
<span class="differenza-value">{{ $spesa['diff'] }}</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<input type="number" class="w-20 px-1 py-1 text-xs text-center border rounded scala-input"
step="0.01" placeholder="0,00">
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<input type="number" class="w-20 px-1 py-1 text-xs text-center border rounded scala-input"
step="0.01" placeholder="0,00">
</td>
<td class="px-3 py-2 text-center text-sm font-mono">
<input type="number" class="w-20 px-1 py-1 text-xs text-center border rounded scala-input"
step="0.01" placeholder="0,00">
</td>
</tr>
@endforeach
<!-- Totale Spese Generali -->
<tr class="bg-red-100 dark:bg-red-900/30 font-bold">
<td class="px-4 py-2 text-sm text-gray-900 dark:text-gray-100 border-r border-gray-200 dark:border-gray-600">
TOTALE SPESE GENERALI
</td>
<td class="px-3 py-2 text-center text-sm font-mono text-red-600 border-r border-gray-200 dark:border-gray-600">
<span id="totale-prev-generale">-3.341,29</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono text-red-600 border-r border-gray-200 dark:border-gray-600">
<span id="totale-cons-generale">-2.471,13</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono text-green-600 border-r border-gray-200 dark:border-gray-600">
<span id="totale-diff-generale">870,16</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<span id="totale-scala-a-gen" class="font-bold">0,00</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<span id="totale-scala-b-gen" class="font-bold">0,00</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono">
<span id="totale-scala-c-gen" class="font-bold">0,00</span>
</td>
</tr>
<!-- Scala A -->
<tr class="bg-blue-50 dark:bg-blue-900/20">
<td colspan="7" class="px-4 py-2 font-bold text-gray-900 dark:text-gray-100 bg-blue-100 dark:bg-blue-800/30">
<i class="fas fa-building mr-2 text-blue-600"></i>
SCALA A
</td>
</tr>
@foreach([
['desc' => 'Luce', 'prev' => '-160,00', 'cons' => '-152,40'],
['desc' => 'Pulizia', 'prev' => '-900,00', 'cons' => '-885,47'],
['desc' => 'Sostituzione lampadine', 'prev' => '-5,00', 'cons' => '0,00'],
['desc' => 'Piccole riparazioni', 'prev' => '-50,00', 'cons' => '-119,87'],
['desc' => 'Riparazioni straordinarie', 'prev' => '0,00', 'cons' => '-227,59']
] as $spesa)
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
<td class="px-4 py-2 text-sm text-gray-900 dark:text-gray-100 border-r border-gray-200 dark:border-gray-600">
{{ $spesa['desc'] }}
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<input type="number" value="{{ str_replace(['-', ','], ['', '.'], $spesa['prev']) }}"
class="w-20 px-1 py-1 text-xs text-center border rounded preventivo-input scala-a"
step="0.01" onchange="calcolaDifferenza(this)">
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<input type="number" value="{{ str_replace(['-', ','], ['', '.'], $spesa['cons']) }}"
class="w-20 px-1 py-1 text-xs text-center border rounded consuntivo-input scala-a"
step="0.01" onchange="calcolaDifferenza(this)">
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<span class="differenza-value">{{ number_format((float)str_replace(['-', ','], ['', '.'], $spesa['cons']) - (float)str_replace(['-', ','], ['', '.'], $spesa['prev']), 2, ',', '.') }}</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono bg-blue-50 dark:bg-blue-900/20 border-r border-gray-200 dark:border-gray-600">
<input type="number" value="{{ str_replace(['-', ','], ['', '.'], $spesa['cons']) }}"
class="w-20 px-1 py-1 text-xs text-center border rounded scala-input scala-a-val font-bold"
step="0.01">
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<span class="text-gray-400">-</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono">
<span class="text-gray-400">-</span>
</td>
</tr>
@endforeach
<!-- Totale Scala A -->
<tr class="bg-red-100 dark:bg-red-900/30 font-bold">
<td class="px-4 py-2 text-sm text-gray-900 dark:text-gray-100 border-r border-gray-200 dark:border-gray-600">
TOTALE SCALA A
</td>
<td class="px-3 py-2 text-center text-sm font-mono text-red-600 border-r border-gray-200 dark:border-gray-600">
<span id="totale-prev-scala-a">-1.115,00</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono text-red-600 border-r border-gray-200 dark:border-gray-600">
<span id="totale-cons-scala-a">-1.385,33</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono text-red-600 border-r border-gray-200 dark:border-gray-600">
<span id="totale-diff-scala-a">-270,33</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono bg-blue-100 dark:bg-blue-800/30 border-r border-gray-200 dark:border-gray-600">
<span id="totale-scala-a" class="font-bold text-blue-700">-1.385,33</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono border-r border-gray-200 dark:border-gray-600">
<span class="text-gray-400">-</span>
</td>
<td class="px-3 py-2 text-center text-sm font-mono">
<span class="text-gray-400">-</span>
</td>
</tr>
<!-- Scala B e C (struttura simile) -->
<!-- ... altre scale ... -->
<!-- TOTALE GENERALE -->
<tr class="bg-gradient-to-r from-gray-800 to-gray-900 text-white font-bold text-lg">
<td class="px-4 py-3 text-sm border-r border-gray-600">
TOTALE GESTIONE (escluse quote fuori gestione)
</td>
<td class="px-3 py-3 text-center text-sm font-mono border-r border-gray-600">
<span id="totale-generale-prev">-8.836,29</span>
</td>
<td class="px-3 py-3 text-center text-sm font-mono border-r border-gray-600">
<span id="totale-generale-cons">-8.028,70</span>
</td>
<td class="px-3 py-3 text-center text-sm font-mono border-r border-gray-600">
<span id="totale-generale-diff" class="text-green-400">807,59</span>
</td>
<td class="px-3 py-3 text-center text-sm font-mono border-r border-gray-600">
<span id="finale-scala-a" class="font-bold">-2.770,66</span>
</td>
<td class="px-3 py-3 text-center text-sm font-mono border-r border-gray-600">
<span id="finale-scala-b" class="font-bold">-2.629,04</span>
</td>
<td class="px-3 py-3 text-center text-sm font-mono">
<span id="finale-scala-c" class="font-bold">-2.629,00</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Sub-tab Storico Ripartizioni -->
<div id="storico-ripartizioni" class="netgescon-subtab-content hidden pt-6">
<div class="text-center py-8">
<i class="fas fa-history text-4xl text-gray-400 mb-4"></i>
<p class="text-gray-600 dark:text-gray-400">Storico delle ripartizioni effettuate</p>
<p class="text-sm text-gray-500 mt-2">Funzionalità in sviluppo</p>
</div>
</div>
<!-- Sub-tab Configurazione Avanzata -->
<div id="configurazione-avanzata" class="netgescon-subtab-content hidden pt-6">
<div class="text-center py-8">
<i class="fas fa-cogs text-4xl text-gray-400 mb-4"></i>
<p class="text-gray-600 dark:text-gray-400">Configurazioni avanzate del sistema</p>
<p class="text-sm text-gray-500 mt-2">Funzionalità in sviluppo</p>
</div>
</div>
</div>
</div>
<!-- Area Prospetto di Ripartizione (stile NetGescon originale) -->
<div id="prospetto-ripartizione" class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border hidden">
<div class="border-b border-gray-200 dark:border-gray-700 px-6 py-4">
<div class="flex justify-between items-center">
<h4 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<i class="fas fa-calculator mr-2 text-purple-600"></i>
Prospetto di Ripartizione
</h4>
<div class="flex space-x-2">
<button type="button"
class="netgescon-btn netgescon-btn-sm netgescon-btn-success"
onclick="salvaProspetto()">
<i class="fas fa-save mr-1"></i>
Salva
</button>
<button type="button"
class="netgescon-btn netgescon-btn-sm netgescon-btn-secondary"
onclick="chiudiProspetto()">
<i class="fas fa-times mr-1"></i>
Chiudi
</button>
</div>
</div>
</div>
<div class="px-6 py-4">
<!-- Header info selezione -->
<div class="mb-6 p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Tabella Millesimale:
</label>
<span id="selected-tabella" class="text-sm font-mono bg-white dark:bg-gray-800 px-2 py-1 rounded border">
Nessuna selezionata
</span>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Voce di Spesa:
</label>
<span id="selected-voce" class="text-sm font-mono bg-white dark:bg-gray-800 px-2 py-1 rounded border">
Nessuna selezionata
</span>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Importo Totale:
</label>
<input type="number"
id="importo-totale"
class="netgescon-input text-sm w-full"
step="0.01"
placeholder="0.00"
onchange="calcolaRipartizione()">
</div>
</div>
</div>
<!-- Tabella di ripartizione (stile NetGescon) -->
<div class="overflow-x-auto">
<table id="tabella-ripartizione" class="min-w-full bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600">
<thead class="bg-gradient-to-r from-blue-500 to-blue-600 text-white">
<tr>
<th class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider border-r border-blue-400">
Cod.
</th>
<th class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider border-r border-blue-400">
Scala
</th>
<th class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider border-r border-blue-400">
Int.
</th>
<th class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider border-r border-blue-400">
Nome Condomino
</th>
<th class="px-4 py-3 text-center text-xs font-medium uppercase tracking-wider border-r border-blue-400">
Millesimi
</th>
<th class="px-4 py-3 text-center text-xs font-medium uppercase tracking-wider border-r border-blue-400">
Quota Calcolata
</th>
<th class="px-4 py-3 text-center text-xs font-medium uppercase tracking-wider">
Quota Finale
</th>
</tr>
</thead>
<tbody id="body-ripartizione" class="divide-y divide-gray-200 dark:divide-gray-600">
<tr>
<td colspan="7" class="px-6 py-8 text-center text-gray-500 dark:text-gray-400">
<i class="fas fa-info-circle text-2xl mb-2"></i>
<p>Seleziona una tabella millesimale per visualizzare il prospetto</p>
</td>
</tr>
</tbody>
<tfoot class="bg-gray-100 dark:bg-gray-700 font-bold">
<tr>
<td colspan="4" class="px-4 py-3 text-right border-r border-gray-300 dark:border-gray-600">
TOTALI GENERALI:
</td>
<td class="px-4 py-3 text-center border-r border-gray-300 dark:border-gray-600">
<span id="totale-millesimi">1.000,00</span>
</td>
<td class="px-4 py-3 text-center border-r border-gray-300 dark:border-gray-600">
<span id="totale-calcolato">0,00</span>
</td>
<td class="px-4 py-3 text-center">
<span id="totale-finale">0,00</span>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
<!-- CSS per stile NetGescon avanzato -->
<style>
.netgescon-subtab-btn {
@apply px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 border-b-2 border-transparent hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 focus:outline-none focus:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 transition-colors duration-200;
}
.netgescon-subtab-btn.active {
@apply text-blue-600 dark:text-blue-400 border-blue-500 dark:border-blue-400;
}
.netgescon-subtab-content {
@apply hidden;
}
.netgescon-subtab-content.active {
@apply block;
}
.tabella-item.selected {
@apply border-l-4 border-blue-600 bg-blue-50 dark:bg-blue-900/20;
}
.voce-spesa-item.selected {
@apply border-l-4 border-green-600 bg-green-50 dark:bg-green-900/20;
}
/* Stile tabella ripartizione stile NetGescon */
#tabella-ripartizione th {
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
color: white;
font-weight: 600;
text-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
#tabella-ripartizione tbody tr:nth-child(even) {
@apply bg-gray-50 dark:bg-gray-700;
}
#tabella-ripartizione tbody tr:hover {
@apply bg-yellow-50 dark:bg-yellow-900/20;
}
#tabella-ripartizione input[type="number"] {
@apply w-full px-2 py-1 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500;
}
/* Effetti hover per items */
.tabella-item:hover, .voce-spesa-item:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
transition: all 0.2s ease;
}
/* Loading states */
.loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255,255,255,0.9);
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
.spinner {
@apply animate-spin h-8 w-8 text-blue-600;
}
</style>
<!-- JavaScript avanzato per sistema NetGescon -->
<script>
// Variabili globali
let selectedTabella = null;
let selectedVoceSpesa = null;
let tabellaData = {};
let vociSpesaData = {};
let prospettoAttivo = false;
document.addEventListener('DOMContentLoaded', function() {
initializeNetGesconSystem();
initializeSubTabs();
});
// Inizializzazione sistema
function initializeNetGesconSystem() {
console.log('🚀 NetGescon - Sistema Tabelle Millesimali inizializzato');
// Carica dati iniziali se presenti
loadInitialData();
// Setup event listeners
setupEventListeners();
}
// Inizializzazione sub-tabs
function initializeSubTabs() {
const subtabButtons = document.querySelectorAll('.netgescon-subtab-btn');
const subtabContents = document.querySelectorAll('.netgescon-subtab-content');
subtabButtons.forEach(button => {
button.addEventListener('click', function() {
const targetSubtab = this.dataset.subtab;
// Rimuovi classe active da tutti i bottoni sub-tab
subtabButtons.forEach(btn => btn.classList.remove('active'));
// Nascondi tutti i contenuti dei sub-tab
subtabContents.forEach(content => {
content.classList.remove('active');
content.classList.add('hidden');
});
// Aggiungi classe active al bottone cliccato
this.classList.add('active');
// Mostra il contenuto del sub-tab selezionato
const targetContent = document.getElementById(targetSubtab);
if (targetContent) {
targetContent.classList.add('active');
targetContent.classList.remove('hidden');
}
});
});
}
// Setup event listeners
function setupEventListeners() {
// Listener per input importo totale
const importoInput = document.getElementById('importo-totale');
if (importoInput) {
importoInput.addEventListener('input', debounce(calcolaRipartizione, 500));
}
}
// Carica dati iniziali
function loadInitialData() {
// Simula caricamento dati dal server
// In produzione, questo farà chiamate AJAX reali
console.log('📊 Caricamento dati iniziali...');
}
// Selezione tabella millesimale
function selectTabella(id, nome) {
// Rimuovi selezione precedente
document.querySelectorAll('.tabella-item').forEach(item => {
item.classList.remove('selected');
});
// Seleziona nuova tabella
event.target.closest('.tabella-item').classList.add('selected');
selectedTabella = { id: id, nome: nome };
// Aggiorna UI
const selectedTabellaSpan = document.getElementById('selected-tabella');
if (selectedTabellaSpan) {
selectedTabellaSpan.textContent = nome;
}
console.log('✅ Tabella selezionata:', nome);
// Se anche voce spesa selezionata, mostra prospetto
if (selectedVoceSpesa) {
showProspettoRipartizione();
}
// Mostra dettagli se area attiva
const dettaglioTabs = document.getElementById('dettaglio-tabs');
if (dettaglioTabs && !dettaglioTabs.classList.contains('hidden')) {
loadDettagliTabella(id);
}
}
// Selezione voce di spesa
function selectVoceSpesa(id, descrizione) {
// Rimuovi selezione precedente
document.querySelectorAll('.voce-spesa-item').forEach(item => {
item.classList.remove('selected');
});
// Seleziona nuova voce
event.target.closest('.voce-spesa-item').classList.add('selected');
selectedVoceSpesa = { id: id, descrizione: descrizione };
// Aggiorna UI
const selectedVoceSpan = document.getElementById('selected-voce');
if (selectedVoceSpan) {
selectedVoceSpan.textContent = descrizione;
}
console.log('✅ Voce spesa selezionata:', descrizione);
// Se anche tabella selezionata, mostra prospetto
if (selectedTabella) {
showProspettoRipartizione();
}
}
// Mostra prospetto di ripartizione
function showProspettoRipartizione() {
if (!selectedTabella || !selectedVoceSpesa) {
console.warn('⚠️ Seleziona sia tabella che voce di spesa');
return;
}
const prospetto = document.getElementById('prospetto-ripartizione');
if (prospetto) {
prospetto.classList.remove('hidden');
prospettoAttivo = true;
// Scroll verso il prospetto
prospetto.scrollIntoView({ behavior: 'smooth', block: 'start' });
// Carica dati prospetto
loadProspettoData();
}
}
// Carica dati nel prospetto
function loadProspettoData() {
const tbody = document.getElementById('body-ripartizione');
if (!tbody) return;
// Show loading
tbody.innerHTML = `
<tr>
<td colspan="7" class="px-6 py-8 text-center">
<div class="flex items-center justify-center">
<i class="fas fa-spinner fa-spin text-2xl text-blue-600 mr-3"></i>
<span class="text-gray-600 dark:text-gray-400">Caricamento prospetto ripartizione...</span>
</div>
</td>
</tr>
`;
// Simula chiamata AJAX per caricare millesimi
setTimeout(() => {
loadMillesimiForTabella(selectedTabella.id);
}, 1000);
}
// Carica millesimi per tabella specifica
function loadMillesimiForTabella(tabellaId) {
// In produzione, questa sarà una chiamata AJAX reale
// Simulo dati di esempio
const millesimi = generateSampleMillesimi();
const tbody = document.getElementById('body-ripartizione');
if (!tbody) return;
let html = '';
let totaleMillesimi = 0;
millesimi.forEach((unita, index) => {
totaleMillesimi += unita.millesimi;
html += `
<tr class="hover:bg-yellow-50 dark:hover:bg-yellow-900/20 transition-colors">
<td class="px-4 py-3 text-sm font-mono border-r border-gray-200 dark:border-gray-600">
${unita.codice}
</td>
<td class="px-4 py-3 text-sm text-center border-r border-gray-200 dark:border-gray-600">
${unita.scala}
</td>
<td class="px-4 py-3 text-sm text-center border-r border-gray-200 dark:border-gray-600">
${unita.interno}
</td>
<td class="px-4 py-3 text-sm border-r border-gray-200 dark:border-gray-600">
${unita.intestatario}
</td>
<td class="px-4 py-3 text-center border-r border-gray-200 dark:border-gray-600">
<span class="font-mono font-bold text-blue-600">${unita.millesimi.toFixed(2)}</span>
</td>
<td class="px-4 py-3 text-center border-r border-gray-200 dark:border-gray-600">
<span id="quota-calc-${index}" class="font-mono text-green-600">€ 0,00</span>
</td>
<td class="px-4 py-3 text-center">
<input type="number"
id="quota-finale-${index}"
class="quota-finale-input"
step="0.01"
value="0.00"
data-index="${index}"
data-millesimi="${unita.millesimi}"
onchange="updateQuotaFinale(${index})"
style="width: 80px;">
</td>
</tr>
`;
});
tbody.innerHTML = html;
// Aggiorna totale millesimi
const totaleMillesimiSpan = document.getElementById('totale-millesimi');
if (totaleMillesimiSpan) {
totaleMillesimiSpan.textContent = totaleMillesimi.toFixed(2);
}
// Ricalcola se c'è già un importo
const importoInput = document.getElementById('importo-totale');
if (importoInput && parseFloat(importoInput.value) > 0) {
calcolaRipartizione();
}
console.log('📊 Prospetto caricato con', millesimi.length, 'unità');
}
// Genera dati di esempio per millesimi
function generateSampleMillesimi() {
return [
{ codice: 'A1', scala: 'A', interno: '1', intestatario: 'Rossi Mario', millesimi: 82.00 },
{ codice: 'A2', scala: 'A', interno: '2', intestatario: 'Bianchi Lucia', millesimi: 67.00 },
{ codice: 'A3', scala: 'A', interno: '3', intestatario: 'Verdi Giuseppe', millesimi: 75.00 },
{ codice: 'A4', scala: 'A', interno: '4', intestatario: 'Neri Anna', millesimi: 69.00 },
{ codice: 'B1', scala: 'B', interno: '1', intestatario: 'Gialli Roberto', millesimi: 89.00 },
{ codice: 'B2', scala: 'B', interno: '2', intestatario: 'Viola Francesco', millesimi: 71.00 },
{ codice: 'B3', scala: 'B', interno: '3', intestatario: 'Arancio Elena', millesimi: 78.00 },
{ codice: 'B4', scala: 'B', interno: '4', intestatario: 'Rosa Pietro', millesimi: 63.00 },
{ codice: 'C1', scala: 'C', interno: '1', intestatario: 'Blu Maria', millesimi: 85.00 },
{ codice: 'C2', scala: 'C', interno: '2', intestatario: 'Verde Laura', millesimi: 72.00 },
{ codice: 'C3', scala: 'C', interno: '3', intestatario: 'Grigio Marco', millesimi: 80.00 },
{ codice: 'C4', scala: 'C', interno: '4', intestatario: 'Marrone Sara', millesimi: 76.00 },
{ codice: 'TR1', scala: 'TERR', interno: '1', intestatario: 'Condominio Comune', millesimi: 87.00 },
{ codice: 'TR2', scala: 'TERR', interno: '2', intestatario: 'Condominio Comune', millesimi: 85.00 }
];
}
// Calcola ripartizione in base all'importo
function calcolaRipartizione() {
const importoInput = document.getElementById('importo-totale');
if (!importoInput) return;
const importoTotale = parseFloat(importoInput.value) || 0;
if (importoTotale === 0) return;
const quotaInputs = document.querySelectorAll('.quota-finale-input');
let totaleCalcolato = 0;
let totaleFinale = 0;
quotaInputs.forEach((input, index) => {
const millesimi = parseFloat(input.dataset.millesimi) || 0;
const quotaCalcolata = (importoTotale * millesimi) / 1000;
// Aggiorna quota calcolata
const quotaCalcSpan = document.getElementById(`quota-calc-${index}`);
if (quotaCalcSpan) {
quotaCalcSpan.textContent = `€ ${quotaCalcolata.toFixed(2)}`.replace('.', ',');
}
// Se input quota finale è vuoto o zero, usa quota calcolata
if (!input.value || parseFloat(input.value) === 0) {
input.value = quotaCalcolata.toFixed(2);
}
totaleCalcolato += quotaCalcolata;
totaleFinale += parseFloat(input.value) || 0;
});
// Aggiorna totali
const totaleCalcolatoSpan = document.getElementById('totale-calcolato');
const totaleFinaleSpan = document.getElementById('totale-finale');
if (totaleCalcolatoSpan) {
totaleCalcolatoSpan.textContent = totaleCalcolato.toFixed(2).replace('.', ',');
}
if (totaleFinaleSpan) {
totaleFinaleSpan.textContent = totaleFinale.toFixed(2).replace('.', ',');
}
console.log('🧮 Ripartizione calcolata - Totale:', importoTotale, 'Unità:', quotaInputs.length);
}
// Aggiorna quota finale singola
function updateQuotaFinale(index) {
// Ricalcola totali quando cambia una quota
setTimeout(calcolaRipartizione, 100);
}
// Gestione completa del sistema
function openGestioneCompleta() {
alert('🚀 Apertura gestione completa tabelle millesimali');
// Attiva il sub-tab "Dettaglio Millesimi"
const dettaglioBtn = document.querySelector('[data-subtab="dettaglio-millesimi"]');
if (dettaglioBtn) {
dettaglioBtn.click();
}
}
// Apre prospetto ripartizione
function openProspettoRipartizione() {
if (!selectedTabella || !selectedVoceSpesa) {
alert('⚠️ Seleziona prima una tabella millesimale e una voce di spesa');
return;
}
showProspettoRipartizione();
}
// Chiudi prospetto
function chiudiProspetto() {
const prospetto = document.getElementById('prospetto-ripartizione');
if (prospetto) {
prospetto.classList.add('hidden');
prospettoAttivo = false;
}
}
// Salva prospetto
function salvaProspetto() {
if (!selectedTabella || !selectedVoceSpesa) {
alert('⚠️ Nessun prospetto attivo da salvare');
return;
}
const importoTotale = document.getElementById('importo-totale').value;
const quotaInputs = document.querySelectorAll('.quota-finale-input');
const datiProspetto = {
tabella_id: selectedTabella.id,
voce_spesa_id: selectedVoceSpesa.id,
importo_totale: parseFloat(importoTotale),
ripartizioni: []
};
quotaInputs.forEach((input, index) => {
datiProspetto.ripartizioni.push({
index: index,
millesimi: parseFloat(input.dataset.millesimi),
quota_finale: parseFloat(input.value) || 0
});
});
console.log('💾 Salvataggio prospetto:', datiProspetto);
// In produzione, qui ci sarebbe la chiamata AJAX per salvare
alert('✅ Prospetto salvato con successo!\n\n' +
`Tabella: ${selectedTabella.nome}\n` +
`Voce: ${selectedVoceSpesa.descrizione}\n` +
`Importo: € ${importoTotale}\n` +
`Ripartizioni: ${datiProspetto.ripartizioni.length}`);
}
// Funzioni modali (placeholder per sviluppo futuro)
function openCreateTabellaModal() {
alert('🆕 Modal creazione nuova tabella millesimale\n\n(Da implementare)');
}
function openCreateVoceSpesaModal() {
alert('🆕 Modal creazione nuova voce di spesa\n\n(Da implementare)');
}
function editTabella(id) {
alert(`✏️ Modifica tabella millesimale ID: ${id}\n\n(Da implementare)`);
}
function editVoceSpesa(id) {
alert(`✏️ Modifica voce di spesa ID: ${id}\n\n(Da implementare)`);
}
function viewDettagliTabella(id) {
alert(`👁️ Visualizza dettagli tabella ID: ${id}\n\n(Da implementare)`);
// Attiva il sub-tab "Dettaglio Millesimi"
const dettaglioBtn = document.querySelector('[data-subtab="dettaglio-millesimi"]');
if (dettaglioBtn) {
dettaglioBtn.click();
loadDettagliTabella(id);
}
}
function viewRipartizioniVoce(id) {
alert(`📊 Visualizza ripartizioni voce ID: ${id}\n\n(Da implementare)`);
}
function deleteTabella(id) {
if (confirm('🗑️ Sei sicuro di voler eliminare questa tabella millesimale?')) {
alert(`❌ Eliminazione tabella ID: ${id}\n\n(Da implementare)`);
}
}
function deleteVoceSpesa(id) {
if (confirm('🗑️ Sei sicuro di voler eliminare questa voce di spesa?')) {
alert(`❌ Eliminazione voce spesa ID: ${id}\n\n(Da implementare)`);
}
}
// Carica dettagli tabella nell'area dettagli
function loadDettagliTabella(id) {
const dettaglioContent = document.getElementById('dettaglio-content');
if (!dettaglioContent) return;
dettaglioContent.innerHTML = `
<div class="flex items-center justify-center py-8">
<i class="fas fa-spinner fa-spin text-2xl text-blue-600 mr-3"></i>
<span class="text-gray-600 dark:text-gray-400">Caricamento dettagli tabella...</span>
</div>
`;
// Simula caricamento
setTimeout(() => {
dettaglioContent.innerHTML = `
<div class="bg-blue-50 dark:bg-blue-900/20 p-4 rounded-lg">
<h5 class="font-medium text-gray-900 dark:text-gray-100 mb-3">
📊 Dettagli Tabella Millesimale ID: ${id}
</h5>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-white dark:bg-gray-800 p-3 rounded border">
<h6 class="font-medium mb-2">Informazioni Generali</h6>
<ul class="text-sm space-y-1">
<li><strong>Tipo:</strong> Proprietà Generale</li>
<li><strong>Data Creazione:</strong> 15/07/2025</li>
<li><strong>Ultima Modifica:</strong> 27/07/2025</li>
<li><strong>Stato:</strong> <span class="text-green-600">Attiva</span></li>
</ul>
</div>
<div class="bg-white dark:bg-gray-800 p-3 rounded border">
<h6 class="font-medium mb-2">Statistiche</h6>
<ul class="text-sm space-y-1">
<li><strong>Unità Immobiliari:</strong> 14</li>
<li><strong>Totale Millesimi:</strong> 1.000,00‰</li>
<li><strong>Media per Unità:</strong> 71,43‰</li>
<li><strong>Utilizzi:</strong> 23 ripartizioni</li>
</ul>
</div>
</div>
<div class="mt-4 text-center">
<button class="netgescon-btn netgescon-btn-primary" onclick="editTabella(${id})">
<i class="fas fa-edit mr-2"></i>
Modifica Tabella
</button>
</div>
</div>
`;
}, 800);
}
// Utility function debounce
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Log di sistema
console.log('🎯 NetGescon - Sistema Tabelle Millesimali e Voci Spesa pronto!');
console.log('📋 Funzionalità disponibili:');
console.log(' - Selezione tabelle millesimali');
console.log(' - Selezione voci di spesa');
console.log(' - Prospetto ripartizione automatico');
console.log(' - Calcolo quote in tempo reale');
console.log(' - Sistema sub-tabs dettagliato');
console.log(' - Gestione preventivi/consuntivi');
// Funzioni per gestione preventivi/consuntivi
function calcolaDifferenza(input) {
const row = input.closest('tr');
const prevInput = row.querySelector('.preventivo-input');
const consInput = row.querySelector('.consuntivo-input');
const diffSpan = row.querySelector('.differenza-value');
if (prevInput && consInput && diffSpan) {
const preventivo = parseFloat(prevInput.value) || 0;
const consuntivo = parseFloat(consInput.value) || 0;
const differenza = consuntivo - preventivo;
diffSpan.textContent = differenza.toFixed(2).replace('.', ',');
diffSpan.className = `differenza-value ${differenza >= 0 ? 'text-red-600' : 'text-green-600'}`;
}
// Ricalcola totali
calcolaTotali();
}
function calcolaTotali() {
// Calcola totali per sezione
calcolaTotaleSezione('.preventivo-input:not(.scala-a):not(.scala-b):not(.scala-c)', '#totale-prev-generale');
calcolaTotaleSezione('.consuntivo-input:not(.scala-a):not(.scala-b):not(.scala-c)', '#totale-cons-generale');
// Calcola totali per scala A
calcolaTotaleSezione('.preventivo-input.scala-a', '#totale-prev-scala-a');
calcolaTotaleSezione('.consuntivo-input.scala-a', '#totale-cons-scala-a');
calcolaTotaleSezione('.scala-a-val', '#totale-scala-a');
// Aggiorna differenze
aggiornaDifferenzaTotale('#totale-prev-generale', '#totale-cons-generale', '#totale-diff-generale');
aggiornaDifferenzaTotale('#totale-prev-scala-a', '#totale-cons-scala-a', '#totale-diff-scala-a');
}
function calcolaTotaleSezione(selector, targetSelector) {
let totale = 0;
document.querySelectorAll(selector).forEach(input => {
totale += parseFloat(input.value) || 0;
});
const target = document.querySelector(targetSelector);
if (target) {
target.textContent = totale.toFixed(2).replace('.', ',');
}
}
function aggiornaDifferenzaTotale(prevSelector, consSelector, diffSelector) {
const prevElement = document.querySelector(prevSelector);
const consElement = document.querySelector(consSelector);
const diffElement = document.querySelector(diffSelector);
if (prevElement && consElement && diffElement) {
const prev = parseFloat(prevElement.textContent.replace(',', '.')) || 0;
const cons = parseFloat(consElement.textContent.replace(',', '.')) || 0;
const diff = cons - prev;
diffElement.textContent = diff.toFixed(2).replace('.', ',');
diffElement.className = `${diff >= 0 ? 'text-red-600' : 'text-green-600'}`;
}
}
// Inizializza calcoli al caricamento
document.addEventListener('DOMContentLoaded', function() {
setTimeout(() => {
calcolaTotali();
}, 500);
});
</script>