252 lines
9.9 KiB
PHP
252 lines
9.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\FieldJob;
|
|
use App\Services\ReferenceDataCache;
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
|
|
class PhoneViewController extends Controller
|
|
{
|
|
public function __construct(protected ReferenceDataCache $referenceCache) {}
|
|
public function index(Request $request)
|
|
{
|
|
$userId = $request->user()->id;
|
|
$search = $request->input('search');
|
|
$clientFilter = $request->input('client');
|
|
$perPage = $request->integer('per_page', 15);
|
|
$perPage = max(1, min(100, $perPage));
|
|
|
|
$query = FieldJob::query()
|
|
->where('assigned_user_id', $userId)
|
|
->whereNull('completed_at')
|
|
->whereNull('cancelled_at')
|
|
->with([
|
|
'contract' => function ($q) {
|
|
$q->with([
|
|
'type:id,name',
|
|
'account',
|
|
'clientCase.person.address.type',
|
|
'clientCase.person.phones',
|
|
'clientCase.client:id,uuid,person_id',
|
|
'clientCase.client.person:id,full_name',
|
|
]);
|
|
},
|
|
])
|
|
->orderByDesc('assigned_at');
|
|
|
|
// Apply client filter
|
|
if ($clientFilter) {
|
|
$query->whereHas('contract.clientCase.client', function ($q) use ($clientFilter) {
|
|
$q->where('uuid', $clientFilter);
|
|
});
|
|
}
|
|
|
|
// Apply search filter
|
|
if ($search) {
|
|
$query->where(function ($q) use ($search) {
|
|
$q->whereHas('contract', function ($cq) use ($search) {
|
|
$cq->where('reference', 'ilike', '%'.$search.'%')
|
|
->orWhereHas('clientCase.person', function ($pq) use ($search) {
|
|
$pq->where('full_name', 'ilike', '%'.$search.'%');
|
|
})
|
|
->orWhereHas('clientCase.client.person', function ($pq) use ($search) {
|
|
$pq->where('full_name', 'ilike', '%'.$search.'%');
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
$jobs = $query->paginate($perPage)->withQueryString();
|
|
|
|
// Get unique clients for filter dropdown
|
|
$clients = \App\Models\Client::query()
|
|
->whereHas('clientCases.contracts.fieldJobs', function ($q) use ($userId) {
|
|
$q->where('assigned_user_id', $userId)
|
|
->whereNull('completed_at')
|
|
->whereNull('cancelled_at');
|
|
})
|
|
->with(['person:id,full_name'])
|
|
->get(['uuid', 'person_id'])
|
|
->map(fn ($c) => [
|
|
'uuid' => (string) $c->uuid,
|
|
'name' => (string) optional($c->person)->full_name,
|
|
])
|
|
->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE)
|
|
->values();
|
|
|
|
return Inertia::render('Phone/Index', [
|
|
'jobs' => $jobs,
|
|
'clients' => $clients,
|
|
'view_mode' => 'assigned',
|
|
'filters' => [
|
|
'search' => $search,
|
|
'client' => $clientFilter,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function completedToday(Request $request)
|
|
{
|
|
$userId = $request->user()->id;
|
|
$search = $request->input('search');
|
|
$clientFilter = $request->input('client');
|
|
$perPage = $request->integer('per_page', 15);
|
|
$perPage = max(1, min(100, $perPage));
|
|
|
|
$start = now()->startOfDay();
|
|
$end = now()->endOfDay();
|
|
|
|
$query = FieldJob::query()
|
|
->where('assigned_user_id', $userId)
|
|
->whereNull('cancelled_at')
|
|
->whereBetween('completed_at', [$start, $end])
|
|
->with([
|
|
'contract' => function ($q) {
|
|
$q->with([
|
|
'type:id,name',
|
|
'account',
|
|
'clientCase.person.address.type',
|
|
'clientCase.person.phones',
|
|
'clientCase.client:id,uuid,person_id',
|
|
'clientCase.client.person:id,full_name',
|
|
]);
|
|
},
|
|
])
|
|
->orderByDesc('completed_at');
|
|
|
|
// Apply client filter
|
|
if ($clientFilter) {
|
|
$query->whereHas('contract.clientCase.client', function ($q) use ($clientFilter) {
|
|
$q->where('uuid', $clientFilter);
|
|
});
|
|
}
|
|
|
|
// Apply search filter
|
|
if ($search) {
|
|
$query->where(function ($q) use ($search) {
|
|
$q->whereHas('contract', function ($cq) use ($search) {
|
|
$cq->where('reference', 'ilike', '%'.$search.'%')
|
|
->orWhereHas('clientCase.person', function ($pq) use ($search) {
|
|
$pq->where('full_name', 'ilike', '%'.$search.'%');
|
|
})
|
|
->orWhereHas('clientCase.client.person', function ($pq) use ($search) {
|
|
$pq->where('full_name', 'ilike', '%'.$search.'%');
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
$jobs = $query->paginate($perPage)->withQueryString();
|
|
|
|
// Get unique clients for filter dropdown
|
|
$clients = \App\Models\Client::query()
|
|
->whereHas('clientCases.contracts.fieldJobs', function ($q) use ($userId, $start, $end) {
|
|
$q->where('assigned_user_id', $userId)
|
|
->whereNull('cancelled_at')
|
|
->whereBetween('completed_at', [$start, $end]);
|
|
})
|
|
->with(['person:id,full_name'])
|
|
->get(['uuid', 'person_id'])
|
|
->map(fn ($c) => [
|
|
'uuid' => (string) $c->uuid,
|
|
'name' => (string) optional($c->person)->full_name,
|
|
])
|
|
->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE)
|
|
->values();
|
|
|
|
return Inertia::render('Phone/Index', [
|
|
'jobs' => $jobs,
|
|
'clients' => $clients,
|
|
'view_mode' => 'completed-today',
|
|
'filters' => [
|
|
'search' => $search,
|
|
'client' => $clientFilter,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function showCase(\App\Models\ClientCase $clientCase, Request $request)
|
|
{
|
|
$userId = $request->user()->id;
|
|
$completedMode = $request->boolean('completed');
|
|
|
|
// Eager load case with person details
|
|
$case = $clientCase->load('person.address.type', 'person.phones', 'person.emails', 'person.bankAccounts');
|
|
|
|
// Query contracts based on field jobs
|
|
$contractsQuery = FieldJob::query()
|
|
->where('assigned_user_id', $userId)
|
|
->whereHas('contract', fn ($q) => $q->where('client_case_id', $case->id))
|
|
->when($completedMode,
|
|
fn ($q) => $q->whereNull('cancelled_at')->whereBetween('completed_at', [now()->startOfDay(), now()->endOfDay()]),
|
|
fn ($q) => $q->whereNull('completed_at')->whereNull('cancelled_at')
|
|
);
|
|
|
|
// Get contracts with relationships
|
|
$contracts = \App\Models\Contract::query()
|
|
->where('client_case_id', $case->id)
|
|
->whereIn('id', $contractsQuery->pluck('contract_id')->unique())
|
|
->with(['type:id,name', 'account', 'latestObject'])
|
|
->orderByDesc('created_at')
|
|
->get();
|
|
|
|
// Build merged documents
|
|
$documents = $case->documents()
|
|
->orderByDesc('created_at')
|
|
->get()
|
|
->map(fn ($d) => array_merge($d->toArray(), [
|
|
'documentable_type' => \App\Models\ClientCase::class,
|
|
'client_case_uuid' => $case->uuid,
|
|
]))
|
|
->concat(
|
|
\App\Models\Document::query()
|
|
->where('documentable_type', \App\Models\Contract::class)
|
|
->whereIn('documentable_id', $contracts->pluck('id'))
|
|
->with('documentable:id,uuid,reference')
|
|
->orderByDesc('created_at')
|
|
->get()
|
|
->map(fn ($d) => array_merge($d->toArray(), [
|
|
'contract_reference' => $d->documentable?->reference,
|
|
'contract_uuid' => $d->documentable?->uuid,
|
|
]))
|
|
)
|
|
->sortByDesc('created_at')
|
|
->values();
|
|
|
|
// Get segment IDs for filtering actions
|
|
$segmentIds = \App\Models\FieldJobSetting::query()
|
|
->whereIn('id', $contractsQuery->pluck('field_job_setting_id')->filter()->unique())
|
|
->pluck('segment_id')
|
|
->filter()
|
|
->unique();
|
|
|
|
return Inertia::render('Phone/Case/Index', [
|
|
'client' => $case->client->load('person.address.type', 'person.phones', 'person.emails', 'person.bankAccounts'),
|
|
'client_case' => $case,
|
|
'contracts' => $contracts,
|
|
'documents' => $documents,
|
|
'types' => [
|
|
'address_types' => \App\Models\Person\AddressType::all(),
|
|
'phone_types' => \App\Models\Person\PhoneType::all(),
|
|
],
|
|
'account_types' => \App\Models\AccountType::all(),
|
|
'actions' => \App\Models\Action::query()
|
|
->when($segmentIds->isNotEmpty(), fn ($q) => $q->whereIn('segment_id', $segmentIds))
|
|
->with([
|
|
'decisions:id,name,color_tag,auto_mail,email_template_id',
|
|
'decisions.emailTemplate:id,name,entity_types,allow_attachments',
|
|
])
|
|
->get(['id', 'name', 'color_tag', 'segment_id']),
|
|
'activities' => $case->activities()
|
|
->with(['action', 'decision', 'contract:id,uuid,reference', 'user:id,name'])
|
|
->orderByDesc('created_at')
|
|
->limit(20)
|
|
->get()
|
|
->map(fn ($a) => $a->setAttribute('user_name', $a->user?->name)),
|
|
'completed_mode' => $completedMode,
|
|
]);
|
|
}
|
|
}
|