708 lines
29 KiB
PHP
Executable File
708 lines
29 KiB
PHP
Executable File
<?php
|
|
namespace App\Filament\Pages\Condomini\Components;
|
|
|
|
use App\Models\GestioneContabile;
|
|
use App\Models\User;
|
|
use App\Support\StabileContext;
|
|
use Filament\Actions\Action;
|
|
use Filament\Actions\BulkAction;
|
|
use Filament\Actions\Concerns\InteractsWithActions;
|
|
use Filament\Actions\Contracts\HasActions;
|
|
use Filament\Forms\Components\CheckboxList;
|
|
use Filament\Forms\Components\Toggle;
|
|
use Filament\Forms\Concerns\InteractsWithForms;
|
|
use Filament\Forms\Contracts\HasForms;
|
|
use Filament\Support\Contracts\TranslatableContentDriver;
|
|
use Filament\Tables\Columns\IconColumn;
|
|
use Filament\Tables\Columns\TextColumn;
|
|
use Filament\Tables\Columns\TextInputColumn;
|
|
use Filament\Tables\Columns\DatePickerColumn;
|
|
use Filament\Tables\Columns\SelectColumn;
|
|
use Filament\Tables\Columns\ToggleColumn;
|
|
use Filament\Tables\Concerns\InteractsWithTable;
|
|
use Filament\Tables\Contracts\HasTable;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Illuminate\Support\Str;
|
|
use Livewire\Component;
|
|
|
|
class GestioniStabileTable extends Component implements HasForms, HasTable, HasActions
|
|
{
|
|
use InteractsWithTable;
|
|
use InteractsWithForms;
|
|
use InteractsWithActions;
|
|
|
|
protected $listeners = [
|
|
'refresh-gestioni-stabile' => '$refresh',
|
|
];
|
|
|
|
public string $scope = 'aperte';
|
|
private bool $legacySyncAttempted = false;
|
|
|
|
public ?string $tipo = null;
|
|
|
|
public function mount(): void
|
|
{
|
|
$this->mountInteractsWithTable();
|
|
}
|
|
|
|
/**
|
|
* Query principale tabella gestioni.
|
|
* Applica ambito (aperte/archivio), tipo gestione e filtro riscaldamento.
|
|
*/
|
|
protected function getTableQuery(): Builder
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return GestioneContabile::query()->whereRaw('1 = 0');
|
|
}
|
|
|
|
$activeStabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $activeStabileId) {
|
|
return GestioneContabile::query()->whereRaw('1 = 0');
|
|
}
|
|
|
|
$stabile = \App\Models\Stabile::query()
|
|
->select('id', 'configurazione_avanzata')
|
|
->find($activeStabileId);
|
|
|
|
$this->syncLegacyOrdinarieForStabile($stabile);
|
|
|
|
$mostraRiscaldamento = (bool) data_get($stabile?->configurazione_avanzata, 'mostra_riscaldamento', false);
|
|
|
|
$query = GestioneContabile::query()
|
|
->where('stabile_id', $activeStabileId);
|
|
|
|
$tenantId = trim((string) ($user->tenant_id ?? ''));
|
|
if ($tenantId !== '') {
|
|
$query->where(function (Builder $builder) use ($tenantId): void {
|
|
$builder->where('tenant_id', $tenantId)
|
|
->orWhere('tenant_id', '00000000');
|
|
});
|
|
}
|
|
|
|
if ($this->scope === 'archivio') {
|
|
$query->whereIn('stato', ['chiusa', 'consolidata']);
|
|
} elseif ($this->scope === 'aperte') {
|
|
$query->aperte();
|
|
}
|
|
|
|
if ($this->tipo) {
|
|
$query->where('tipo_gestione', $this->tipo);
|
|
}
|
|
|
|
if (! $mostraRiscaldamento) {
|
|
$query->where('tipo_gestione', '!=', 'riscaldamento');
|
|
}
|
|
|
|
$query->whereRaw("gestioni_contabili.id = (
|
|
select gc2.id
|
|
from gestioni_contabili gc2
|
|
where gc2.tenant_id = gestioni_contabili.tenant_id
|
|
and gc2.stabile_id = gestioni_contabili.stabile_id
|
|
and gc2.anno_gestione = gestioni_contabili.anno_gestione
|
|
and gc2.tipo_gestione = gestioni_contabili.tipo_gestione
|
|
and (
|
|
(gc2.numero_straordinaria is null and gestioni_contabili.numero_straordinaria is null)
|
|
or gc2.numero_straordinaria = gestioni_contabili.numero_straordinaria
|
|
)
|
|
order by
|
|
case when gc2.denominazione like '%/%' then 1 else 0 end desc,
|
|
gc2.data_fine desc,
|
|
gc2.id desc
|
|
limit 1
|
|
)");
|
|
|
|
return $query;
|
|
}
|
|
|
|
private function syncLegacyOrdinarieForStabile( ? \App\Models\Stabile $stabile) : void
|
|
{
|
|
if ($this->legacySyncAttempted) {
|
|
return;
|
|
}
|
|
|
|
$this->legacySyncAttempted = true;
|
|
|
|
if (! $stabile) {
|
|
return;
|
|
}
|
|
|
|
if (! Schema::connection('gescon_import')->hasTable('gestioni_annuali')) {
|
|
return;
|
|
}
|
|
|
|
$legacyCode = trim((string) ($stabile->codice_stabile ?? ''));
|
|
if ($legacyCode === '') {
|
|
return;
|
|
}
|
|
|
|
$legacyRows = DB::connection('gescon_import')
|
|
->table('gestioni_annuali')
|
|
->where('cod_stabile', $legacyCode)
|
|
->orderByDesc('anno_ordinario')
|
|
->get(['anno_ordinario', 'anno_riscaldamento', 'descrizione', 'ordinaria_dal', 'ordinaria_al', 'riscaldamento_dal', 'riscaldamento_al', 'cartella']);
|
|
|
|
if ($legacyRows->isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
$tenantId = GestioneContabile::query()
|
|
->where('stabile_id', (int) $stabile->id)
|
|
->value('tenant_id');
|
|
|
|
if (! is_string($tenantId) || trim($tenantId) === '') {
|
|
$tenantId = (string) (Auth::user()?->tenant_id ?? 'default');
|
|
}
|
|
|
|
$mostraRiscaldamento = (bool) data_get($stabile->configurazione_avanzata, 'mostra_riscaldamento', false);
|
|
|
|
$latestYear = (int) $legacyRows
|
|
->map(fn($row) => is_numeric($row->anno_ordinario ?? null) ? (int) $row->anno_ordinario : null)
|
|
->filter()
|
|
->max();
|
|
|
|
foreach ($legacyRows as $row) {
|
|
$descrizione = trim((string) ($row->descrizione ?? $row->anno_ordinario ?? ''));
|
|
$labelOrd = $descrizione !== '' ? preg_replace('/\s+/', '', $descrizione) : trim((string) ($row->anno_ordinario ?? ''));
|
|
$labelRisc = trim((string) ($row->anno_riscaldamento ?? '')) ?: $labelOrd;
|
|
$year = is_numeric($row->anno_ordinario ?? null) ? (int) $row->anno_ordinario : null;
|
|
if (! $year) {
|
|
continue;
|
|
}
|
|
|
|
$records = [
|
|
[
|
|
'tipo' => 'ordinaria',
|
|
'inizio' => $row->ordinaria_dal ?: sprintf('%04d-01-01', $year),
|
|
'fine' => $row->ordinaria_al ?: sprintf('%04d-12-31', $year),
|
|
'prefix' => 'O' . $year,
|
|
'label' => $labelOrd,
|
|
],
|
|
];
|
|
|
|
if ($mostraRiscaldamento) {
|
|
$records[] = [
|
|
'tipo' => 'riscaldamento',
|
|
'inizio' => $row->riscaldamento_dal ?: ($row->ordinaria_dal ?: sprintf('%04d-01-01', $year)),
|
|
'fine' => $row->riscaldamento_al ?: ($row->ordinaria_al ?: sprintf('%04d-12-31', $year)),
|
|
'prefix' => 'R' . $year,
|
|
'label' => $labelRisc,
|
|
];
|
|
}
|
|
|
|
foreach ($records as $recordMeta) {
|
|
$lbl = $recordMeta['label'];
|
|
GestioneContabile::query()->updateOrCreate(
|
|
[
|
|
'tenant_id' => $tenantId,
|
|
'stabile_id' => (int) $stabile->id,
|
|
'anno_gestione' => $year,
|
|
'tipo_gestione' => $recordMeta['tipo'],
|
|
'numero_straordinaria' => null,
|
|
],
|
|
[
|
|
'denominazione' => Str::headline($recordMeta['tipo']) . ' ' . ($lbl !== '' ? $lbl : $year),
|
|
'data_inizio' => $recordMeta['inizio'],
|
|
'data_fine' => $recordMeta['fine'],
|
|
'stato' => $year === $latestYear ? 'aperta' : 'chiusa',
|
|
'protocollo_prefix' => $recordMeta['prefix'],
|
|
'gestione_attiva' => $year === $latestYear,
|
|
'codice_archivio_legacy' => 'legacy:gestioni_annuali:' . (trim((string) ($row->cartella ?? '')) ?: $year),
|
|
]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function table(Table $table): Table
|
|
{
|
|
return $table
|
|
->striped()
|
|
->defaultSort('anno_gestione', 'desc')
|
|
->recordUrl(fn(GestioneContabile $record): string => \App\Filament\Pages\Condomini\StabilePage::getUrl(panel: 'admin-filament') . '?tab=gestioni&gestioni_tab=periodi&gestione_id=' . $record->id)
|
|
->headerActions([
|
|
Action::make('nuova_gestione')
|
|
->label('Nuova gestione')
|
|
->icon('heroicon-o-plus')
|
|
->modalHeading('Nuova gestione')
|
|
->form([
|
|
|
|
\Filament\Forms\Components\Select::make('tipo_gestione')
|
|
->label('Tipo')
|
|
->options([
|
|
'ordinaria' => 'Ordinaria',
|
|
'riscaldamento' => 'Riscaldamento',
|
|
'straordinaria' => 'Straordinaria',
|
|
])
|
|
->required(),
|
|
|
|
\Filament\Forms\Components\TextInput::make('anno_gestione')
|
|
->label('Anno')
|
|
->numeric()
|
|
->required(),
|
|
|
|
\Filament\Forms\Components\TextInput::make('denominazione')
|
|
->label('Denominazione')
|
|
->maxLength(255),
|
|
|
|
\Filament\Forms\Components\DatePicker::make('data_inizio')
|
|
->label('Data inizio'),
|
|
|
|
\Filament\Forms\Components\DatePicker::make('data_fine')
|
|
->label('Data fine'),
|
|
|
|
CheckboxList::make('mesi')
|
|
->label('Mesi scadenza rate')
|
|
->options([
|
|
1 => 'Gen',
|
|
2 => 'Feb',
|
|
3 => 'Mar',
|
|
4 => 'Apr',
|
|
5 => 'Mag',
|
|
6 => 'Giu',
|
|
7 => 'Lug',
|
|
8 => 'Ago',
|
|
9 => 'Set',
|
|
10 => 'Ott',
|
|
11 => 'Nov',
|
|
12 => 'Dic',
|
|
])
|
|
->columns(6),
|
|
])
|
|
->action(function (array $data): void {
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return;
|
|
}
|
|
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId) {
|
|
return;
|
|
}
|
|
|
|
$tenantId = GestioneContabile::query()
|
|
->where('stabile_id', $stabileId)
|
|
->value('tenant_id');
|
|
if (! is_string($tenantId) || trim($tenantId) === '') {
|
|
$tenantId = (string) ($user->tenant_id ?? 'default');
|
|
}
|
|
|
|
$gestione = new GestioneContabile();
|
|
$gestione->tenant_id = $tenantId;
|
|
$gestione->stabile_id = $stabileId;
|
|
$gestione->anno_gestione = (int) ($data['anno_gestione'] ?? now()->year);
|
|
$gestione->tipo_gestione = (string) ($data['tipo_gestione'] ?? 'ordinaria');
|
|
$gestione->denominazione = $data['denominazione'] ?? null;
|
|
$gestione->data_inizio = $data['data_inizio'] ?? null;
|
|
$gestione->data_fine = $data['data_fine'] ?? null;
|
|
$gestione->stato = 'aperta';
|
|
$gestione->gestione_attiva = true;
|
|
|
|
$mesi = array_values(array_unique(array_map('intval', (array) ($data['mesi'] ?? []))));
|
|
sort($mesi);
|
|
$field = match ($gestione->tipo_gestione) {
|
|
'ordinaria' => 'mesi_rate_ordinaria',
|
|
'riscaldamento' => 'mesi_rate_riscaldamento',
|
|
'straordinaria' => 'mesi_rate_straordinaria',
|
|
default => 'mesi_rate_ordinaria',
|
|
};
|
|
$gestione->{$field} = $mesi;
|
|
|
|
$gestione->save();
|
|
}),
|
|
|
|
Action::make('duplica_gestione')
|
|
->label('Duplica gestione')
|
|
->icon('heroicon-o-squares-plus')
|
|
->modalHeading('Duplica gestione')
|
|
->form([
|
|
\Filament\Forms\Components\Select::make('gestione_id')
|
|
->label('Gestione da duplicare')
|
|
->options(fn() => GestioneContabile::query()
|
|
->where('stabile_id', StabileContext::resolveActiveStabileId(Auth::user()))
|
|
->orderByDesc('anno_gestione')
|
|
->get()
|
|
->mapWithKeys(fn(GestioneContabile $g) => [$g->id => ($g->anno_gestione . ' · ' . ($g->denominazione ?: $g->tipo_gestione))]))
|
|
->searchable()
|
|
->required(),
|
|
\Filament\Forms\Components\TextInput::make('anno_gestione')
|
|
->label('Anno nuovo')
|
|
->numeric()
|
|
->required(),
|
|
])
|
|
->action(function (array $data): void {
|
|
$gestione = GestioneContabile::query()->find((int) ($data['gestione_id'] ?? 0));
|
|
if (! $gestione) {
|
|
return;
|
|
}
|
|
|
|
$clone = $gestione->replicate([
|
|
'gestione_attiva',
|
|
'stato',
|
|
'created_at',
|
|
'updated_at',
|
|
]);
|
|
$clone->anno_gestione = (int) ($data['anno_gestione'] ?? $gestione->anno_gestione);
|
|
$clone->stato = 'aperta';
|
|
$clone->gestione_attiva = true;
|
|
$clone->save();
|
|
}),
|
|
])
|
|
->columns([
|
|
TextColumn::make('gestione_label')
|
|
->label('Gestione')
|
|
->getStateUsing(fn(GestioneContabile $record): string => $record->gestione_label)
|
|
->sortable(),
|
|
|
|
TextColumn::make('tipo_gestione')
|
|
->label('Tipo')
|
|
->sortable(),
|
|
|
|
TextColumn::make('numero_straordinaria')
|
|
->label('N° Straord.')
|
|
->sortable()
|
|
->toggleable(isToggledHiddenByDefault: true),
|
|
|
|
TextInputColumn::make('denominazione')
|
|
->label('Denominazione')
|
|
->searchable(),
|
|
|
|
DatePickerColumn::make('data_inizio')
|
|
->label('Data inizio')
|
|
->native(false),
|
|
|
|
DatePickerColumn::make('data_fine')
|
|
->label('Data fine')
|
|
->native(false),
|
|
|
|
SelectColumn::make('stato')
|
|
->label('Stato')
|
|
->options([
|
|
'aperta' => 'Aperta',
|
|
'consolidata' => 'Consolidata',
|
|
'chiusa' => 'Chiusa',
|
|
]),
|
|
|
|
ToggleColumn::make('gestione_attiva')
|
|
->label('Attiva'),
|
|
|
|
TextColumn::make('mesi_rate')
|
|
->label('Mesi rate')
|
|
->getStateUsing(function (GestioneContabile $record): string {
|
|
$mesi = match ($record->tipo_gestione) {
|
|
'ordinaria' => (array) ($record->mesi_rate_ordinaria ?? []),
|
|
'riscaldamento' => (array) ($record->mesi_rate_riscaldamento ?? []),
|
|
'straordinaria' => (array) ($record->mesi_rate_straordinaria ?? []),
|
|
default => [],
|
|
};
|
|
$mesi = array_values(array_unique(array_map('intval', $mesi)));
|
|
sort($mesi);
|
|
return $mesi ? implode(', ', $mesi) : '—';
|
|
})
|
|
->wrap(),
|
|
])
|
|
->actions([
|
|
Action::make('imposta_mesi_rate')
|
|
->label('Mesi rate')
|
|
->icon('heroicon-o-calendar')
|
|
->modalHeading('Imposta mesi emissione rate')
|
|
->fillForm(function (GestioneContabile $record): array {
|
|
$mesi = match ($record->tipo_gestione) {
|
|
'ordinaria' => (array) ($record->mesi_rate_ordinaria ?? []),
|
|
'riscaldamento' => (array) ($record->mesi_rate_riscaldamento ?? []),
|
|
'straordinaria' => (array) ($record->mesi_rate_straordinaria ?? []),
|
|
default => [],
|
|
};
|
|
$mesi = array_values(array_unique(array_map('intval', $mesi)));
|
|
sort($mesi);
|
|
|
|
return [
|
|
'mesi' => $mesi,
|
|
'replica_tutti_anni' => true,
|
|
];
|
|
})
|
|
->form([
|
|
CheckboxList::make('mesi')
|
|
->label('Mesi in cui emettere le rate')
|
|
->options([
|
|
1 => 'Gen',
|
|
2 => 'Feb',
|
|
3 => 'Mar',
|
|
4 => 'Apr',
|
|
5 => 'Mag',
|
|
6 => 'Giu',
|
|
7 => 'Lug',
|
|
8 => 'Ago',
|
|
9 => 'Set',
|
|
10 => 'Ott',
|
|
11 => 'Nov',
|
|
12 => 'Dic',
|
|
])
|
|
->columns(6)
|
|
->required(),
|
|
|
|
Toggle::make('replica_tutti_anni')
|
|
->label('Replica questi mesi su tutti gli anni (stesso tipo)')
|
|
->default(true),
|
|
])
|
|
->action(function (GestioneContabile $record, array $data): void {
|
|
$mesi = array_values(array_unique(array_map('intval', (array) ($data['mesi'] ?? []))));
|
|
sort($mesi);
|
|
|
|
$field = match ($record->tipo_gestione) {
|
|
'ordinaria' => 'mesi_rate_ordinaria',
|
|
'riscaldamento' => 'mesi_rate_riscaldamento',
|
|
'straordinaria' => 'mesi_rate_straordinaria',
|
|
default => 'mesi_rate_ordinaria',
|
|
};
|
|
|
|
$query = GestioneContabile::query()
|
|
->where('stabile_id', $record->stabile_id)
|
|
->where('tipo_gestione', $record->tipo_gestione);
|
|
|
|
if (empty($data['replica_tutti_anni'])) {
|
|
$query->whereKey($record->getKey());
|
|
}
|
|
|
|
$query->each(function (GestioneContabile $g) use ($field, $mesi): void {
|
|
$g->{$field} = $mesi;
|
|
$g->save();
|
|
});
|
|
}),
|
|
|
|
Action::make('apri_archivio_gestioni')
|
|
->label('Apri archivio')
|
|
->url(fn() => \App\Filament\Pages\Condomini\StabilePage::getUrl(panel: 'admin-filament') . '?tab=gestioni&gestioni_tab=archivio'),
|
|
Action::make('archivia_gestione')
|
|
->label('Sposta in archivio')
|
|
->icon('heroicon-o-archive-box')
|
|
->requiresConfirmation()
|
|
->visible(fn() => $this->scope !== 'archivio')
|
|
->action(fn(GestioneContabile $record) => $this->archiveGestione($record)),
|
|
Action::make('ripristina_gestione')
|
|
->label('Ripristina in gestione')
|
|
->icon('heroicon-o-arrow-path')
|
|
->requiresConfirmation()
|
|
->visible(fn() => $this->scope === 'archivio')
|
|
->action(fn(GestioneContabile $record) => $this->restoreGestione($record)),
|
|
])
|
|
->bulkActions([
|
|
BulkAction::make('imposta_mesi_rate')
|
|
->label('Imposta mesi rate')
|
|
->icon('heroicon-o-calendar')
|
|
->modalHeading('Imposta mesi emissione rate (selezionati)')
|
|
->form([
|
|
CheckboxList::make('mesi')
|
|
->label('Mesi in cui emettere le rate')
|
|
->options([
|
|
1 => 'Gen',
|
|
2 => 'Feb',
|
|
3 => 'Mar',
|
|
4 => 'Apr',
|
|
5 => 'Mag',
|
|
6 => 'Giu',
|
|
7 => 'Lug',
|
|
8 => 'Ago',
|
|
9 => 'Set',
|
|
10 => 'Ott',
|
|
11 => 'Nov',
|
|
12 => 'Dic',
|
|
])
|
|
->columns(6)
|
|
->required(),
|
|
])
|
|
->action(function ($records, array $data): void {
|
|
$mesi = array_values(array_unique(array_map('intval', (array) ($data['mesi'] ?? []))));
|
|
sort($mesi);
|
|
|
|
foreach ($records as $record) {
|
|
if (! $record instanceof GestioneContabile) {
|
|
continue;
|
|
}
|
|
|
|
$field = match ($record->tipo_gestione) {
|
|
'ordinaria' => 'mesi_rate_ordinaria',
|
|
'riscaldamento' => 'mesi_rate_riscaldamento',
|
|
'straordinaria' => 'mesi_rate_straordinaria',
|
|
default => 'mesi_rate_ordinaria',
|
|
};
|
|
|
|
$record->{$field} = $mesi;
|
|
$record->save();
|
|
}
|
|
}),
|
|
BulkAction::make('archivia_gestioni')
|
|
->label('Sposta in archivio')
|
|
->icon('heroicon-o-archive-box')
|
|
->requiresConfirmation()
|
|
->visible(fn() => $this->scope !== 'archivio')
|
|
->action(function ($records): void {
|
|
foreach ($records as $record) {
|
|
if (! $record instanceof GestioneContabile) {
|
|
continue;
|
|
}
|
|
|
|
$this->archiveGestione($record);
|
|
}
|
|
}),
|
|
BulkAction::make('ripristina_gestioni')
|
|
->label('Ripristina in gestione')
|
|
->icon('heroicon-o-arrow-path')
|
|
->requiresConfirmation()
|
|
->visible(fn() => $this->scope === 'archivio')
|
|
->action(function ($records): void {
|
|
foreach ($records as $record) {
|
|
if (! $record instanceof GestioneContabile) {
|
|
continue;
|
|
}
|
|
|
|
$this->restoreGestione($record);
|
|
}
|
|
}),
|
|
]);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('filament.pages.condomini.components.gestioni-stabile-table');
|
|
}
|
|
|
|
public function makeFilamentTranslatableContentDriver(): ?TranslatableContentDriver
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sposta una gestione in archivio logico (chiusa + non attiva).
|
|
*/
|
|
private function archiveGestione(GestioneContabile $gestione): void
|
|
{
|
|
if (in_array($gestione->stato, ['chiusa', 'consolidata'], true)) {
|
|
$gestione->gestione_attiva = false;
|
|
$gestione->save();
|
|
return;
|
|
}
|
|
|
|
$gestione->stato = 'chiusa';
|
|
$gestione->gestione_attiva = false;
|
|
$gestione->save();
|
|
}
|
|
|
|
/**
|
|
* Ripristina una gestione in elenco attivo.
|
|
*/
|
|
private function restoreGestione(GestioneContabile $gestione): void
|
|
{
|
|
$gestione->stato = 'aperta';
|
|
$gestione->gestione_attiva = true;
|
|
$gestione->save();
|
|
}
|
|
|
|
private function restoreBestGestioneYear(int $year): void
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return;
|
|
}
|
|
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId) {
|
|
return;
|
|
}
|
|
|
|
$gestioni = GestioneContabile::query()
|
|
->where('stabile_id', $stabileId)
|
|
->where('anno_gestione', $year)
|
|
->get();
|
|
|
|
if ($gestioni->isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
$keep = $this->selectEffectiveGestione($gestioni);
|
|
|
|
$gestioni->each(function (GestioneContabile $g) use ($keep): void {
|
|
if ($keep && $g->id === $keep->id) {
|
|
$this->restoreGestione($g);
|
|
return;
|
|
}
|
|
|
|
$this->archiveGestione($g);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Seleziona la gestione "migliore" del gruppo anno/tipo usando punteggio attività.
|
|
*/
|
|
private function selectEffectiveGestione(Collection $group): ?GestioneContabile
|
|
{
|
|
if ($group->isEmpty()) {
|
|
return null;
|
|
}
|
|
|
|
$ranked = $group->map(function (GestioneContabile $g): array {
|
|
return [
|
|
'gestione' => $g,
|
|
'score' => $this->getGestioneActivityScore($g),
|
|
'attiva' => $g->gestione_attiva ? 1 : 0,
|
|
'data_fine' => $g->data_fine?->timestamp ?? 0,
|
|
'data_inizio' => $g->data_inizio?->timestamp ?? 0,
|
|
'id' => $g->id,
|
|
];
|
|
})->sortByDesc(function (array $row): array {
|
|
return [$row['score'], $row['attiva'], $row['data_fine'], $row['data_inizio'], $row['id']];
|
|
})->values();
|
|
|
|
return $ranked->first()['gestione'] ?? $group->first();
|
|
}
|
|
|
|
/**
|
|
* Calcola un punteggio attività interrogando tabelle contabili collegate.
|
|
*/
|
|
private function getGestioneActivityScore(GestioneContabile $gestione): int
|
|
{
|
|
$score = 0;
|
|
|
|
if (Schema::hasTable('operazioni_contabili') && Schema::hasColumn('operazioni_contabili', 'gestione_id')) {
|
|
if (DB::table('operazioni_contabili')->where('gestione_id', $gestione->id)->exists()) {
|
|
$score += 100;
|
|
}
|
|
}
|
|
|
|
if (Schema::hasTable('incassi') && Schema::hasColumn('incassi', 'gestione_id')) {
|
|
if (DB::table('incassi')->where('gestione_id', $gestione->id)->exists()) {
|
|
$score += 50;
|
|
}
|
|
}
|
|
|
|
if (Schema::hasTable('incassi_estratto_conto') && Schema::hasColumn('incassi_estratto_conto', 'gestione_id')) {
|
|
if (DB::table('incassi_estratto_conto')->where('gestione_id', $gestione->id)->exists()) {
|
|
$score += 30;
|
|
}
|
|
}
|
|
|
|
if (Schema::hasTable('registro_ritenute_acconto') && Schema::hasColumn('registro_ritenute_acconto', 'gestione_id')) {
|
|
if (DB::table('registro_ritenute_acconto')->where('gestione_id', $gestione->id)->exists()) {
|
|
$score += 10;
|
|
}
|
|
}
|
|
|
|
if (Schema::hasTable('voci_spesa') && Schema::hasColumn('voci_spesa', 'gestione_contabile_id')) {
|
|
$exists = DB::table('voci_spesa')
|
|
->where('gestione_contabile_id', $gestione->id)
|
|
->exists();
|
|
|
|
if ($exists) {
|
|
$score += 20;
|
|
}
|
|
}
|
|
|
|
return $score;
|
|
}
|
|
}
|