<?php
namespace App\Http\Controllers\Admin;
use App\Actions\Recap\GenerateVerificationQrCode;
use App\Actions\Recap\StoreRecapReport;
use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\Complaint;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
class RecapController extends Controller
{
public function index(): View
{
return view('admin.recap.index', [
'clients' => Client::query()->orderBy('name')->get(),
]);
}
/**
* Monthly recap per client. Price is set by admin per ticket when it's
* closed (§14/§16) — only closed tickets have a price and count toward
* the billable total; resolved-but-not-yet-invoiced tickets are shown
* separately as still pending.
*/
public function show(
Request $request,
GenerateVerificationQrCode $qrCode,
StoreRecapReport $storeRecapReport,
): Response {
$request->validate([
'client_id' => ['required', 'uuid', 'exists:client,id'],
'month' => ['required', 'integer', 'between:1,12'],
'year' => ['required', 'integer', 'min:2020'],
]);
$client = Client::findOrFail($request->string('client_id'));
$month = $request->integer('month');
$year = $request->integer('year');
$complaints = Complaint::query()
->where('client_id', $client->id)
->whereYear('report_date', $year)
->whereMonth('report_date', $month)
->with('assignedTechnician')
->orderBy('report_date')
->get();
$billable = $complaints->where('status', 'closed');
$report = $storeRecapReport->handle($client, $month, $year, $complaints);
$pdf = Pdf::loadView('admin.recap.pdf', [
'client' => $client,
'complaints' => $complaints,
'billableTotal' => $billable->sum('price'),
'billableCount' => $billable->count(),
'month' => $month,
'year' => $year,
'report' => $report,
'verificationQrCode' => $qrCode->handle(route('recap.verify', $report->token)),
])->setPaper('a4');
$filename = "rekap-{$client->name}-{$month}-{$year}.pdf";
return $pdf->stream($filename);
}
}