1479 lines
85 KiB
PHP
Executable File
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>
|