254 lines
8.3 KiB
PHP
254 lines
8.3 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Territori;
|
|
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Livewire\Component;
|
|
use Livewire\WithPagination;
|
|
use App\Models\Territorio;
|
|
use App\Models\Zona;
|
|
use App\Models\Tipologia;
|
|
|
|
class TerritorioIndex extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
public string $search = '';
|
|
public string $filterZona = '';
|
|
public string $filterTipologia = '';
|
|
public string $filterStato = '';
|
|
public string $filterPriorita = '';
|
|
public string $filterPdf = '';
|
|
public string $filterContenuti = '';
|
|
public string $sortField = 'numero';
|
|
public string $sortDirection = 'asc';
|
|
|
|
protected $queryString = [
|
|
'search' => ['except' => ''],
|
|
'filterZona' => ['except' => ''],
|
|
'filterTipologia' => ['except' => ''],
|
|
'filterStato' => ['except' => ''],
|
|
'filterPriorita' => ['except' => ''],
|
|
'filterPdf' => ['except' => ''],
|
|
'filterContenuti' => ['except' => ''],
|
|
];
|
|
|
|
public function updatingSearch()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingFilterZona()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingFilterTipologia()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingFilterStato()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingFilterPriorita()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingFilterPdf()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingFilterContenuti()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function sortBy(string $field)
|
|
{
|
|
if ($this->sortField === $field) {
|
|
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
|
|
} else {
|
|
$this->sortField = $field;
|
|
$this->sortDirection = 'asc';
|
|
}
|
|
}
|
|
|
|
public function clearFilters(): void
|
|
{
|
|
$this->reset([
|
|
'search',
|
|
'filterZona',
|
|
'filterTipologia',
|
|
'filterStato',
|
|
'filterPriorita',
|
|
'filterPdf',
|
|
'filterContenuti',
|
|
]);
|
|
$this->sortField = 'numero';
|
|
$this->sortDirection = 'asc';
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function toggleActive(Territorio $territorio)
|
|
{
|
|
$territorio->update(['attivo' => !$territorio->attivo]);
|
|
activity()->causedBy(auth()->user())
|
|
->performedOn($territorio)
|
|
->withProperties(['attivo' => $territorio->attivo])
|
|
->log($territorio->attivo ? 'activated' : 'deactivated');
|
|
}
|
|
|
|
public function togglePriority(Territorio $territorio)
|
|
{
|
|
$territorio->update(['prioritario' => !$territorio->prioritario]);
|
|
activity()->causedBy(auth()->user())
|
|
->performedOn($territorio)
|
|
->withProperties(['prioritario' => $territorio->prioritario])
|
|
->log($territorio->prioritario ? 'set_priority' : 'unset_priority');
|
|
}
|
|
|
|
public function deleteTerritorio(Territorio $territorio)
|
|
{
|
|
activity()->causedBy(auth()->user())
|
|
->performedOn($territorio)
|
|
->log('soft_deleted');
|
|
$territorio->delete();
|
|
session()->flash('success', "Territorio {$territorio->numero} spostato nel cestino.");
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$query = Territorio::with(['zona', 'tipologia', 'assegnazioneCorrente.proclamatore']);
|
|
|
|
if ($this->search) {
|
|
$search = $this->search;
|
|
$query->where(function ($subQuery) use ($search) {
|
|
$subQuery->where('numero', 'like', "%{$search}%")
|
|
->orWhere('note', 'like', "%{$search}%")
|
|
->orWhere('confini', 'like', "%{$search}%")
|
|
->orWhereHas('zona', fn($zonaQuery) => $zonaQuery->where('nome', 'like', "%{$search}%"))
|
|
->orWhereHas('tipologia', fn($tipologiaQuery) => $tipologiaQuery->where('nome', 'like', "%{$search}%"));
|
|
});
|
|
}
|
|
|
|
if ($this->filterZona) {
|
|
$query->where('zona_id', $this->filterZona);
|
|
}
|
|
|
|
if ($this->filterTipologia) {
|
|
$query->where('tipologia_id', $this->filterTipologia);
|
|
}
|
|
|
|
if ($this->filterStato) {
|
|
match ($this->filterStato) {
|
|
'in_reparto' => $query->inReparto(),
|
|
'assegnato' => $query->assegnato(),
|
|
'da_rientrare' => $query->daRientrare(),
|
|
'inattivo' => $query->where('attivo', false),
|
|
'prioritari' => $query->inReparto(),
|
|
default => null,
|
|
};
|
|
}
|
|
|
|
if ($this->filterPdf) {
|
|
match ($this->filterPdf) {
|
|
'con_pdf' => $query->whereNotNull('pdf_path'),
|
|
'senza_pdf' => $query->whereNull('pdf_path'),
|
|
'con_thumbnail' => $query->whereNotNull('thumbnail_path'),
|
|
'senza_thumbnail' => $query->whereNull('thumbnail_path'),
|
|
default => null,
|
|
};
|
|
}
|
|
|
|
if ($this->filterContenuti) {
|
|
match ($this->filterContenuti) {
|
|
'con_note' => $query->whereNotNull('note')->where('note', '!=', ''),
|
|
'senza_note' => $query->where(function ($subQuery) {
|
|
$subQuery->whereNull('note')->orWhere('note', '');
|
|
}),
|
|
'con_confini' => $query->whereNotNull('confini')->where('confini', '!=', ''),
|
|
'senza_confini' => $query->where(function ($subQuery) {
|
|
$subQuery->whereNull('confini')->orWhere('confini', '');
|
|
}),
|
|
default => null,
|
|
};
|
|
}
|
|
|
|
$territori = $query->get();
|
|
|
|
if ($this->filterStato === 'prioritari') {
|
|
$territori = $territori->filter(fn(Territorio $territorio) => $territorio->is_prioritario)->values();
|
|
}
|
|
|
|
if ($this->filterPriorita) {
|
|
$territori = $territori->filter(function (Territorio $territorio) {
|
|
return match ($this->filterPriorita) {
|
|
'prioritari' => $territorio->is_prioritario,
|
|
'manuali' => $territorio->prioritario,
|
|
'automatici' => $territorio->is_prioritario && !$territorio->prioritario,
|
|
'non_prioritari' => !$territorio->is_prioritario,
|
|
default => true,
|
|
};
|
|
})->values();
|
|
}
|
|
|
|
if ($this->usesPriorityOrdering()) {
|
|
$territori = $territori->sort(function (Territorio $left, Territorio $right) {
|
|
$priorityComparison = (int) $right->is_prioritario <=> (int) $left->is_prioritario;
|
|
|
|
if ($priorityComparison !== 0) {
|
|
return $priorityComparison;
|
|
}
|
|
|
|
$giacenzaComparison = $right->giorni_giacenza <=> $left->giorni_giacenza;
|
|
|
|
if ($giacenzaComparison !== 0) {
|
|
return $giacenzaComparison;
|
|
}
|
|
|
|
return strnatcasecmp((string) $left->numero, (string) $right->numero);
|
|
})->values();
|
|
} else {
|
|
$territori = $territori->sort(function (Territorio $left, Territorio $right) {
|
|
$result = strnatcasecmp((string) data_get($left, $this->sortField), (string) data_get($right, $this->sortField));
|
|
|
|
return $this->sortDirection === 'asc' ? $result : -$result;
|
|
})->values();
|
|
}
|
|
|
|
$perPage = 20;
|
|
$page = $this->getPage();
|
|
$items = $territori->slice(($page - 1) * $perPage, $perPage)->values();
|
|
$paginatedTerritori = new LengthAwarePaginator(
|
|
$items,
|
|
$territori->count(),
|
|
$perPage,
|
|
$page,
|
|
['path' => request()->url(), 'query' => request()->query()]
|
|
);
|
|
|
|
return view('livewire.territori.territorio-index', [
|
|
'territori' => $paginatedTerritori,
|
|
'zone' => Zona::attive()->get(),
|
|
'tipologie' => Tipologia::attive()->get(),
|
|
'usesPriorityOrdering' => $this->usesPriorityOrdering(),
|
|
]);
|
|
}
|
|
|
|
protected function usesPriorityOrdering(): bool
|
|
{
|
|
return $this->sortField === 'numero'
|
|
&& $this->sortDirection === 'asc'
|
|
&& (
|
|
in_array($this->filterStato, ['in_reparto', 'prioritari'], true)
|
|
|| $this->filterPriorita !== ''
|
|
);
|
|
}
|
|
|
|
}
|