CluPilotCloud/app/Livewire/Admin/Invoices.php

81 lines
2.5 KiB
PHP

<?php
namespace App\Livewire\Admin;
use App\Models\Invoice;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;
/**
* Every document that has been issued, newest first.
*
* Read-only by design, and that is the feature. An issued invoice cannot be
* edited or deleted here or anywhere else — a wrong one is corrected by issuing
* a cancellation and a new document, which is the only lawful way to correct
* one. There is no edit button to explain the absence of.
*/
#[Layout('layouts.admin')]
class Invoices extends Component
{
use WithPagination;
#[Url]
public string $search = '';
#[Url]
public string $year = '';
public function mount(): void
{
$this->authorize('site.manage');
}
public function updatedSearch(): void
{
$this->resetPage();
}
public function updatedYear(): void
{
$this->resetPage();
}
public function render()
{
$invoices = Invoice::query()
->with(['customer', 'series'])
->when($this->search !== '', function ($q) {
$term = '%'.$this->search.'%';
$q->where(fn ($w) => $w->where('number', 'like', $term)
->orWhereHas('customer', fn ($c) => $c->where('name', 'like', $term)));
})
->when($this->year !== '', fn ($q) => $q->whereYear('issued_on', (int) $this->year))
->orderByDesc('issued_on')
->orderByDesc('id')
->paginate(25);
return view('livewire.admin.invoices', [
'invoices' => $invoices,
// Straight from the rows rather than a fixed range: a list of years
// with nothing in them is a filter that mostly returns nothing.
//
// Derived in PHP rather than with YEAR() in raw SQL. That function
// is MySQL's; SQLite has no such thing, and a query that only runs
// on one engine turns the test database into a different product
// from the real one.
'years' => Invoice::query()
->orderByDesc('issued_on')
->pluck('issued_on')
// ->local() even for a year (R19): on New Year's night the UTC
// year is still the previous one, so the filter would offer a
// year the operator is no longer in.
->map(fn ($date) => $date?->local()->format('Y'))
->filter()
->unique()
->values(),
]);
}
}