++ fix prioritario display and add link sent toggle
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use App\Models\Assegnazione;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
@@ -14,6 +15,10 @@ class AssignmentPdfController extends Controller
|
||||
{
|
||||
$this->validateAccess($assignment, $code);
|
||||
|
||||
if ($expired = $this->linkScaduto($assignment)) {
|
||||
return $expired;
|
||||
}
|
||||
|
||||
$pdfUrl = route('assignments.pdf.file', [
|
||||
'assignment' => $assignment->id,
|
||||
'code' => $code,
|
||||
@@ -25,10 +30,14 @@ class AssignmentPdfController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function file(Request $request, Assegnazione $assignment, string $code): StreamedResponse
|
||||
public function file(Request $request, Assegnazione $assignment, string $code): StreamedResponse|View
|
||||
{
|
||||
$this->validateAccess($assignment, $code);
|
||||
|
||||
if ($expired = $this->linkScaduto($assignment)) {
|
||||
return $expired;
|
||||
}
|
||||
|
||||
$pdfPath = $assignment->territorio?->pdf_path;
|
||||
abort_unless($pdfPath && Storage::disk('public')->exists($pdfPath), 404);
|
||||
|
||||
@@ -48,4 +57,22 @@ class AssignmentPdfController extends Controller
|
||||
abort_unless($assignment->is_aperta, 403);
|
||||
abort_unless($assignment->territorio?->pdf_path, 404);
|
||||
}
|
||||
|
||||
protected function linkScaduto(Assegnazione $assignment): ?View
|
||||
{
|
||||
if (auth()->check()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ttlMonths = max(1, (int) \App\Models\Setting::getValue('assignment_link_ttl_hours', 1));
|
||||
|
||||
if ($assignment->assigned_at->copy()->addMonths($ttlMonths)->isPast()) {
|
||||
return view('assignments.link-scaduto', [
|
||||
'numero' => $assignment->territorio?->numero,
|
||||
]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,20 +3,32 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Assegnazione;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class ShortPdfLinkController extends Controller
|
||||
{
|
||||
public function __invoke(string $code): RedirectResponse
|
||||
public function __invoke(string $code): RedirectResponse|View
|
||||
{
|
||||
$assignment = Assegnazione::where('pdf_access_code', $code)->firstOrFail();
|
||||
|
||||
abort_unless($assignment->is_aperta, 403);
|
||||
abort_unless($assignment->territorio?->pdf_path, 404);
|
||||
|
||||
// Unauthenticated users (proclamatori) are subject to link TTL
|
||||
if (! auth()->check()) {
|
||||
$ttlMonths = max(1, (int) \App\Models\Setting::getValue('assignment_link_ttl_hours', 1));
|
||||
if ($assignment->assigned_at->copy()->addMonths($ttlMonths)->isPast()) {
|
||||
return view('assignments.link-scaduto', [
|
||||
'numero' => $assignment->territorio?->numero,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('assignments.pdf.viewer', [
|
||||
'assignment' => $assignment->id,
|
||||
'code' => $code,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,13 @@ class Assegna extends Component
|
||||
return $this->redirect(route('territori.show', $territorio), navigate: true);
|
||||
}
|
||||
|
||||
public function toggleLinkSent(int $assegnazioneId): void
|
||||
{
|
||||
$this->authorize('territori.assign');
|
||||
$assegnazione = Assegnazione::findOrFail($assegnazioneId);
|
||||
$assegnazione->forceFill(['link_sent' => ! $assegnazione->link_sent])->saveQuietly();
|
||||
}
|
||||
|
||||
#[Computed]
|
||||
public function selectedThumbnailUrl(): ?string
|
||||
{
|
||||
@@ -122,10 +129,13 @@ class Assegna extends Component
|
||||
->get()
|
||||
->sortBy(fn($a) => (int) $a->territorio?->numero);
|
||||
|
||||
$linkTtlMonths = max(1, (int) \App\Models\Setting::getValue('assignment_link_ttl_hours', 1));
|
||||
|
||||
return view('livewire.assegnazioni.assegna', [
|
||||
'territoriDisponibili' => $territoriDisponibili,
|
||||
'proclamatoriAttivi' => $proclamatoriAttivi,
|
||||
'assegnazioniAperte' => $assegnazioniAperte,
|
||||
'linkTtlMonths' => $linkTtlMonths,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,12 @@ class CampagnaShow extends Component
|
||||
|
||||
public function render()
|
||||
{
|
||||
// All assignments with returned_at in campaign range that were counted
|
||||
$conteggiate = Assegnazione::where('campagna_id', $this->campagna->id)
|
||||
// Assignments counted for this campaign:
|
||||
// - assigned on or after campaign start
|
||||
// - linked to this campaign (campaign_id), regardless of returned_at (retroactive returns allowed)
|
||||
$conteggiate = Assegnazione::where('campaign_id', $this->campagna->id)
|
||||
->where('counted_in_campaign', true)
|
||||
->where('assigned_at', '>=', $this->campagna->start_date)
|
||||
->with(['territorio', 'proclamatore'])
|
||||
->orderBy('returned_at')
|
||||
->get();
|
||||
|
||||
@@ -19,6 +19,7 @@ class Assegnazione extends Model
|
||||
'counted_in_campaign',
|
||||
'campaign_id',
|
||||
'pdf_access_code',
|
||||
'link_sent',
|
||||
'note',
|
||||
'created_by',
|
||||
'returned_by',
|
||||
@@ -30,6 +31,7 @@ class Assegnazione extends Model
|
||||
'assigned_at' => 'date',
|
||||
'returned_at' => 'date',
|
||||
'counted_in_campaign' => 'boolean',
|
||||
'link_sent' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -117,6 +119,11 @@ class Assegnazione extends Model
|
||||
return route('assignments.pdf.short', ['code' => $this->ensurePdfAccessCode()]);
|
||||
}
|
||||
|
||||
public function markLinkSent(): void
|
||||
{
|
||||
$this->forceFill(['link_sent' => true])->saveQuietly();
|
||||
}
|
||||
|
||||
// ─── Scopes ─────────────────────────────────────────────────
|
||||
|
||||
public function scopeAperte($query)
|
||||
|
||||
@@ -72,19 +72,19 @@ class Campagna extends Model
|
||||
/**
|
||||
* Campaign coverage percentage.
|
||||
* Numerator: assignments counted for campaign
|
||||
* Denominator: ALL assignments with assigned_at in campaign range (returned or not)
|
||||
* Denominator: total active territories
|
||||
*/
|
||||
public function getPercentualePercorrenzaAttribute(): float
|
||||
{
|
||||
$totaleNelRange = $this->assegnazioniNelRange()->count();
|
||||
$totaleAttivi = Territorio::where('attivo', true)->count();
|
||||
|
||||
if ($totaleNelRange === 0) {
|
||||
if ($totaleAttivi === 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$conteggiate = $this->assegnazioniConteggiate()->count();
|
||||
|
||||
return round(($conteggiate / $totaleNelRange) * 100, 1);
|
||||
return round(($conteggiate / $totaleAttivi) * 100, 1);
|
||||
}
|
||||
|
||||
public function scopeCompletate($query)
|
||||
|
||||
Reference in New Issue
Block a user