Dev branch
This commit is contained in:
@@ -3,57 +3,51 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Services\ReferenceDataCache;
|
||||
use DB;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientController extends Controller
|
||||
{
|
||||
public function __construct(protected ReferenceDataCache $referenceCache) {}
|
||||
|
||||
public function index(Client $client, Request $request)
|
||||
{
|
||||
$search = $request->input('search');
|
||||
|
||||
$query = $client::query()
|
||||
->with('person')
|
||||
->when($request->input('search'), function ($que, $search) {
|
||||
$que->whereHas('person', function ($q) use ($search) {
|
||||
$q->where('full_name', 'ilike', '%'.$search.'%');
|
||||
});
|
||||
->select('clients.*')
|
||||
->when($search, function ($que) use ($search) {
|
||||
$que->join('person', 'person.id', '=', 'clients.person_id')
|
||||
->where('person.full_name', 'ilike', '%'.$search.'%')
|
||||
->groupBy('clients.id');
|
||||
})
|
||||
->where('active', 1)
|
||||
->where('clients.active', 1)
|
||||
// Use LEFT JOINs for aggregated data to avoid subqueries
|
||||
->leftJoin('client_cases', 'client_cases.client_id', '=', 'clients.id')
|
||||
->leftJoin('contracts', function ($join) {
|
||||
$join->on('contracts.client_case_id', '=', 'client_cases.id')
|
||||
->whereNull('contracts.deleted_at');
|
||||
})
|
||||
->leftJoin('contract_segment', function ($join) {
|
||||
$join->on('contract_segment.contract_id', '=', 'contracts.id')
|
||||
->where('contract_segment.active', true);
|
||||
})
|
||||
->leftJoin('accounts', 'accounts.contract_id', '=', 'contracts.id')
|
||||
->groupBy('clients.id')
|
||||
->addSelect([
|
||||
// Number of client cases for this client that have at least one active contract
|
||||
'cases_with_active_contracts_count' => DB::query()
|
||||
->from('client_cases')
|
||||
->join('contracts', 'contracts.client_case_id', '=', 'client_cases.id')
|
||||
->selectRaw('COUNT(DISTINCT client_cases.id)')
|
||||
->whereColumn('client_cases.client_id', 'clients.id')
|
||||
->whereNull('contracts.deleted_at')
|
||||
->whereExists(function ($q) {
|
||||
$q->from('contract_segment')
|
||||
->whereColumn('contract_segment.contract_id', 'contracts.id')
|
||||
->where('contract_segment.active', true);
|
||||
}),
|
||||
// Sum of account balances for active contracts that belong to this client's cases
|
||||
'active_contracts_balance_sum' => DB::query()
|
||||
->from('contracts')
|
||||
->join('accounts', 'accounts.contract_id', '=', 'contracts.id')
|
||||
->selectRaw('COALESCE(SUM(accounts.balance_amount), 0)')
|
||||
->whereExists(function ($q) {
|
||||
$q->from('client_cases')
|
||||
->whereColumn('client_cases.id', 'contracts.client_case_id')
|
||||
->whereColumn('client_cases.client_id', 'clients.id');
|
||||
})
|
||||
->whereNull('contracts.deleted_at')
|
||||
->whereExists(function ($q) {
|
||||
$q->from('contract_segment')
|
||||
->whereColumn('contract_segment.contract_id', 'contracts.id')
|
||||
->where('contract_segment.active', true);
|
||||
}),
|
||||
DB::raw('COUNT(DISTINCT CASE WHEN contract_segment.id IS NOT NULL THEN client_cases.id END) as cases_with_active_contracts_count'),
|
||||
// Sum of account balances for active contracts
|
||||
DB::raw('COALESCE(SUM(CASE WHEN contract_segment.id IS NOT NULL THEN accounts.balance_amount END), 0) as active_contracts_balance_sum'),
|
||||
])
|
||||
->orderByDesc('created_at');
|
||||
->with('person')
|
||||
->orderByDesc('clients.created_at');
|
||||
|
||||
return Inertia::render('Client/Index', [
|
||||
'clients' => $query
|
||||
->paginate($request->integer('perPage', 15))
|
||||
->paginate($request->integer('per_page', 15))
|
||||
->withQueryString(),
|
||||
'filters' => $request->only(['search']),
|
||||
]);
|
||||
@@ -67,44 +61,37 @@ public function show(Client $client, Request $request)
|
||||
->findOrFail($client->id);
|
||||
|
||||
$types = [
|
||||
'address_types' => \App\Models\Person\AddressType::all(),
|
||||
'phone_types' => \App\Models\Person\PhoneType::all(),
|
||||
'address_types' => $this->referenceCache->getAddressTypes(),
|
||||
'phone_types' => $this->referenceCache->getPhoneTypes(),
|
||||
];
|
||||
|
||||
return Inertia::render('Client/Show', [
|
||||
'client' => $data,
|
||||
'client_cases' => $data->clientCases()
|
||||
->with(['person', 'client.person'])
|
||||
->when($request->input('search'), fn ($que, $search) => $que->whereHas(
|
||||
'person',
|
||||
fn ($q) => $q->where('full_name', 'ilike', '%'.$search.'%')
|
||||
))
|
||||
->select('client_cases.*')
|
||||
->when($request->input('search'), function ($que, $search) {
|
||||
$que->join('person', 'person.id', '=', 'client_cases.person_id')
|
||||
->where('person.full_name', 'ilike', '%'.$search.'%')
|
||||
->groupBy('client_cases.id');
|
||||
})
|
||||
->leftJoin('contracts', function ($join) {
|
||||
$join->on('contracts.client_case_id', '=', 'client_cases.id')
|
||||
->whereNull('contracts.deleted_at');
|
||||
})
|
||||
->leftJoin('contract_segment', function ($join) {
|
||||
$join->on('contract_segment.contract_id', '=', 'contracts.id')
|
||||
->where('contract_segment.active', true);
|
||||
})
|
||||
->leftJoin('accounts', 'accounts.contract_id', '=', 'contracts.id')
|
||||
->groupBy('client_cases.id')
|
||||
->addSelect([
|
||||
'active_contracts_count' => \DB::query()
|
||||
->from('contracts')
|
||||
->selectRaw('COUNT(*)')
|
||||
->whereColumn('contracts.client_case_id', 'client_cases.id')
|
||||
->whereNull('contracts.deleted_at')
|
||||
->whereExists(function ($q) {
|
||||
$q->from('contract_segment')
|
||||
->whereColumn('contract_segment.contract_id', 'contracts.id')
|
||||
->where('contract_segment.active', true);
|
||||
}),
|
||||
'active_contracts_balance_sum' => \DB::query()
|
||||
->from('contracts')
|
||||
->join('accounts', 'accounts.contract_id', '=', 'contracts.id')
|
||||
->selectRaw('COALESCE(SUM(accounts.balance_amount), 0)')
|
||||
->whereColumn('contracts.client_case_id', 'client_cases.id')
|
||||
->whereNull('contracts.deleted_at')
|
||||
->whereExists(function ($q) {
|
||||
$q->from('contract_segment')
|
||||
->whereColumn('contract_segment.contract_id', 'contracts.id')
|
||||
->where('contract_segment.active', true);
|
||||
}),
|
||||
\DB::raw('COUNT(DISTINCT CASE WHEN contract_segment.id IS NOT NULL THEN contracts.id END) as active_contracts_count'),
|
||||
\DB::raw('COALESCE(SUM(CASE WHEN contract_segment.id IS NOT NULL THEN accounts.balance_amount END), 0) as active_contracts_balance_sum'),
|
||||
])
|
||||
->where('active', 1)
|
||||
->orderByDesc('created_at')
|
||||
->paginate($request->integer('perPage', 15))
|
||||
->with(['person', 'client.person'])
|
||||
->where('client_cases.active', 1)
|
||||
->orderByDesc('client_cases.created_at')
|
||||
->paginate($request->integer('per_page', 15))
|
||||
->withQueryString(),
|
||||
'types' => $types,
|
||||
'filters' => $request->only(['search']),
|
||||
@@ -121,8 +108,31 @@ public function contracts(Client $client, Request $request)
|
||||
$segmentId = $request->input('segment');
|
||||
|
||||
$contractsQuery = \App\Models\Contract::query()
|
||||
->whereHas('clientCase', function ($q) use ($client) {
|
||||
$q->where('client_id', $client->id);
|
||||
->select(['contracts.id', 'contracts.uuid', 'contracts.reference', 'contracts.start_date', 'contracts.client_case_id'])
|
||||
->join('client_cases', 'client_cases.id', '=', 'contracts.client_case_id')
|
||||
->where('client_cases.client_id', $client->id)
|
||||
->whereNull('contracts.deleted_at')
|
||||
->when($from || $to, function ($q) use ($from, $to) {
|
||||
if (! empty($from)) {
|
||||
$q->whereDate('contracts.start_date', '>=', $from);
|
||||
}
|
||||
if (! empty($to)) {
|
||||
$q->whereDate('contracts.start_date', '<=', $to);
|
||||
}
|
||||
})
|
||||
->when($search, function ($q) use ($search) {
|
||||
$q->leftJoin('person', 'person.id', '=', 'client_cases.person_id')
|
||||
->where(function ($inner) use ($search) {
|
||||
$inner->where('contracts.reference', 'ilike', '%'.$search.'%')
|
||||
->orWhere('person.full_name', 'ilike', '%'.$search.'%');
|
||||
});
|
||||
})
|
||||
->when($segmentId, function ($q) use ($segmentId) {
|
||||
$q->join('contract_segment', function ($join) use ($segmentId) {
|
||||
$join->on('contract_segment.contract_id', '=', 'contracts.id')
|
||||
->where('contract_segment.segment_id', $segmentId)
|
||||
->where('contract_segment.active', true);
|
||||
});
|
||||
})
|
||||
->with([
|
||||
'clientCase:id,uuid,person_id',
|
||||
@@ -132,42 +142,18 @@ public function contracts(Client $client, Request $request)
|
||||
},
|
||||
'account:id,accounts.contract_id,balance_amount',
|
||||
])
|
||||
->select(['id', 'uuid', 'reference', 'start_date', 'client_case_id'])
|
||||
->whereNull('deleted_at')
|
||||
->when($from || $to, function ($q) use ($from, $to) {
|
||||
if (! empty($from)) {
|
||||
$q->whereDate('start_date', '>=', $from);
|
||||
}
|
||||
if (! empty($to)) {
|
||||
$q->whereDate('start_date', '<=', $to);
|
||||
}
|
||||
})
|
||||
->when($search, function ($q) use ($search) {
|
||||
$q->where(function ($inner) use ($search) {
|
||||
$inner->where('reference', 'ilike', '%'.$search.'%')
|
||||
->orWhereHas('clientCase.person', function ($p) use ($search) {
|
||||
$p->where('full_name', 'ilike', '%'.$search.'%');
|
||||
});
|
||||
});
|
||||
})
|
||||
->when($segmentId, function ($q) use ($segmentId) {
|
||||
$q->whereHas('segments', function ($s) use ($segmentId) {
|
||||
$s->where('segments.id', $segmentId)
|
||||
->where('contract_segment.active', true);
|
||||
});
|
||||
})
|
||||
->orderByDesc('start_date');
|
||||
->orderByDesc('contracts.start_date');
|
||||
|
||||
$segments = \App\Models\Segment::orderBy('name')->get(['id', 'name']);
|
||||
|
||||
$types = [
|
||||
'address_types' => \App\Models\Person\AddressType::all(),
|
||||
'phone_types' => \App\Models\Person\PhoneType::all(),
|
||||
'address_types' => $this->referenceCache->getAddressTypes(),
|
||||
'phone_types' => $this->referenceCache->getPhoneTypes(),
|
||||
];
|
||||
|
||||
return Inertia::render('Client/Contracts', [
|
||||
'client' => $data,
|
||||
'contracts' => $contractsQuery->paginate($request->integer('perPage', 20))->withQueryString(),
|
||||
'contracts' => $contractsQuery->paginate($request->integer('per_page', 20))->withQueryString(),
|
||||
'filters' => $request->only(['from', 'to', 'search', 'segment']),
|
||||
'segments' => $segments,
|
||||
'types' => $types,
|
||||
|
||||
Reference in New Issue
Block a user