176 lines
8.3 KiB
PHP
176 lines
8.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Middleware;
|
|
|
|
class HandleInertiaRequests extends Middleware
|
|
{
|
|
/**
|
|
* The root template that's loaded on the first page visit.
|
|
*
|
|
* @see https://inertiajs.com/server-side-setup#root-template
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $rootView = 'app';
|
|
|
|
/**
|
|
* Determines the current asset version.
|
|
*
|
|
* @see https://inertiajs.com/asset-versioning
|
|
*/
|
|
public function version(Request $request): ?string
|
|
{
|
|
return parent::version($request);
|
|
}
|
|
|
|
/**
|
|
* Define the props that are shared by default.
|
|
*
|
|
* @see https://inertiajs.com/shared-data
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function share(Request $request): array
|
|
{
|
|
return array_merge(parent::share($request), [
|
|
'auth' => [
|
|
'user' => function () use ($request) {
|
|
$user = $request->user();
|
|
if (! $user) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'id' => $user->id,
|
|
'name' => $user->name,
|
|
'email' => $user->email,
|
|
'roles' => $user->roles()->select('id', 'name', 'slug')->get(),
|
|
'permissions' => $user->permissions()->pluck('slug')->values(),
|
|
];
|
|
},
|
|
],
|
|
'flash' => [
|
|
'success' => fn () => $request->session()->get('success'),
|
|
'error' => fn () => $request->session()->get('error'),
|
|
'warning' => fn () => $request->session()->get('warning'),
|
|
'info' => fn () => $request->session()->get('info'),
|
|
],
|
|
'notifications' => function () use ($request) {
|
|
try {
|
|
$user = $request->user();
|
|
if (! $user) {
|
|
return null;
|
|
}
|
|
|
|
$today = now()->toDateString();
|
|
|
|
// Base fetch to avoid serialization issues; eager load relations afterwards
|
|
$activities = \App\Models\Activity::query()
|
|
->select(['id', 'due_date', 'amount', 'contract_id', 'client_case_id', 'created_at'])
|
|
->whereDate('due_date', $today)
|
|
// Exclude activities that have been marked as read by this user
|
|
->whereNotExists(function ($q) use ($user, $today) {
|
|
$q->select(\DB::raw(1))
|
|
->from('activity_notification_reads')
|
|
->whereColumn('activity_notification_reads.activity_id', 'activities.id')
|
|
->where('activity_notification_reads.user_id', $user->id)
|
|
->whereDate('activity_notification_reads.due_date', '<=', $today)
|
|
->whereNotNull('activity_notification_reads.read_at');
|
|
})
|
|
->orderBy('created_at')
|
|
->limit(20)
|
|
->get();
|
|
|
|
// Eager load needed relations (contracts and client cases) with qualified selects
|
|
$activities->load([
|
|
'contract' => function ($q) {
|
|
$q->select(['contracts.id', 'contracts.uuid', 'contracts.reference', 'contracts.client_case_id'])
|
|
->with([
|
|
// Include client (via case) so the UI can render client.person.full_name
|
|
'clientCase' => function ($qq) {
|
|
// Include person_id to ensure nested person loads correctly and to avoid null clientCase due to narrow selects
|
|
$qq->select(['client_cases.id', 'client_cases.uuid', 'client_cases.client_id', 'client_cases.person_id'])
|
|
->with([
|
|
'client' => function ($qqq) {
|
|
$qqq->select(['clients.id', 'clients.person_id'])
|
|
->with([
|
|
'person' => function ($qqqq) {
|
|
$qqqq->select(['person.id', 'person.full_name']);
|
|
},
|
|
]);
|
|
},
|
|
]);
|
|
},
|
|
'account' => function ($qq) {
|
|
$qq->select(['accounts.id', 'accounts.contract_id', 'accounts.balance_amount', 'accounts.initial_amount']);
|
|
},
|
|
]);
|
|
},
|
|
'clientCase' => function ($q) {
|
|
$q->select(['client_cases.id', 'client_cases.uuid', 'client_cases.person_id', 'client_cases.client_id'])
|
|
->with([
|
|
'person' => function ($qq) {
|
|
$qq->select(['person.id', 'person.full_name']);
|
|
},
|
|
'client' => function ($qq) {
|
|
$qq->select(['clients.id', 'clients.person_id'])
|
|
->with([
|
|
'person' => function ($qqq) {
|
|
$qqq->select(['person.id', 'person.full_name']);
|
|
},
|
|
]);
|
|
},
|
|
]);
|
|
},
|
|
]);
|
|
|
|
// For convenience on the frontend, mirror client onto the contract so it can be accessed as contract.client.person
|
|
// 1) Build a map of contract_id -> client_id using a lightweight join
|
|
$contractIds = $activities->pluck('contract_id')->filter()->unique()->values();
|
|
if ($contractIds->isNotEmpty()) {
|
|
$mapContractToClient = \App\Models\Contract::query()
|
|
->whereIn('contracts.id', $contractIds)
|
|
->join('client_cases', 'client_cases.id', '=', 'contracts.client_case_id')
|
|
->pluck('client_cases.client_id', 'contracts.id');
|
|
|
|
// 2) Load all needed clients with their person
|
|
$clientIds = $mapContractToClient->filter()->unique()->values();
|
|
$clientsById = $clientIds->isNotEmpty()
|
|
? \App\Models\Client::query()
|
|
->whereIn('clients.id', $clientIds)
|
|
->with(['person:id,full_name'])
|
|
->get(['clients.id', 'clients.uuid', 'clients.person_id'])
|
|
->keyBy('id')
|
|
: collect();
|
|
|
|
// 3) Attach client relation on each contract instance
|
|
foreach ($activities as $act) {
|
|
$contract = $act->getRelation('contract');
|
|
if (! $contract) {
|
|
continue;
|
|
}
|
|
$cid = $mapContractToClient->get($contract->id);
|
|
if ($cid && $clientsById->has($cid)) {
|
|
$contract->setRelation('client', $clientsById->get($cid));
|
|
}
|
|
}
|
|
}
|
|
|
|
return [
|
|
'dueToday' => [
|
|
'count' => $activities->count(),
|
|
'items' => $activities,
|
|
'date' => $today,
|
|
],
|
|
];
|
|
} catch (\Throwable $e) {
|
|
return null;
|
|
}
|
|
},
|
|
]);
|
|
}
|
|
}
|