Teren-app/app/Http/Controllers/ClientController.php
Simon Pocrnjič 078b08cbc5 mails clients
2025-10-09 00:09:23 +02:00

233 lines
9.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers;
use App\Models\Client;
use DB;
use Illuminate\Http\Request;
use Inertia\Inertia;
class ClientController extends Controller
{
public function index(Client $client, Request $request)
{
$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.'%');
});
})
->where('active', 1)
->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);
}),
])
->orderByDesc('created_at');
return Inertia::render('Client/Index', [
'clients' => $query
->paginate(15)
->withQueryString(),
'filters' => $request->only(['search']),
]);
}
public function show(Client $client, Request $request)
{
$data = $client::query()
->with(['person' => fn ($que) => $que->with(['addresses', 'phones', 'bankAccounts', 'emails'])])
->findOrFail($client->id);
$types = [
'address_types' => \App\Models\Person\AddressType::all(),
'phone_types' => \App\Models\Person\PhoneType::all(),
];
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.'%')
)
)
->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);
}),
])
->where('active', 1)
->orderByDesc('created_at')
->paginate(15)
->withQueryString(),
'types' => $types,
'filters' => $request->only(['search']),
]);
}
public function store(Request $request)
{
DB::transaction(function () use ($request) {
$address = $request->input('address');
$phone = $request->input('phone');
$person = \App\Models\Person\Person::create([
'nu' => rand(100000, 200000),
'first_name' => $request->input('first_name'),
'last_name' => $request->input('last_name'),
'full_name' => $request->input('full_name'),
'gender' => null,
'birthday' => null,
'tax_number' => $request->input('tax_number'),
'social_security_number' => $request->input('social_security_number'),
'description' => $request->input('description'),
'group_id' => 1,
'type_id' => 2,
]);
$person->addresses()->create([
'address' => $address['address'],
'country' => $address['country'],
'type_id' => $address['type_id'],
]);
$person->phones()->create([
'nu' => $phone['nu'],
'country_code' => $phone['country_code'],
'type_id' => $phone['type_id'],
]);
$person->client()->create();
});
// \App\Models\Person\PersonAddress::create($address);
return to_route('client');
}
public function update(Client $client, Request $request)
{
return to_route('client.show', $client);
}
/**
* Emergency endpoint: if the linked person record is missing (hard deleted) or soft deleted,
* create a new minimal Person and re-point all related child records (emails, phones, addresses, bank accounts,
* client cases) from the old person_id to the new one, then update the client itself.
*/
public function emergencyCreatePerson(Client $client, Request $request)
{
$oldPersonId = $client->person_id;
// If person exists and is not trashed, abort nothing to do
/** @var \App\Models\Person\Person|null $existing */
$existing = \App\Models\Person\Person::withTrashed()->find($oldPersonId);
if ($existing && ! $existing->trashed()) {
return redirect()->back()->with('flash', [
'type' => 'info',
'message' => 'Person already exists emergency creation not needed.',
]);
}
$data = $request->validate([
'full_name' => ['nullable', 'string', 'max:255'],
'first_name' => ['nullable', 'string', 'max:255'],
'last_name' => ['nullable', 'string', 'max:255'],
'tax_number' => ['nullable', 'string', 'max:99'],
'social_security_number' => ['nullable', 'string', 'max:99'],
'description' => ['nullable', 'string', 'max:500'],
]);
// Provide sensible fallbacks.
$fullName = $data['full_name'] ?? trim(($data['first_name'] ?? '').' '.($data['last_name'] ?? ''));
if ($fullName === '') {
$fullName = 'Unknown Person';
}
$newPerson = null;
\DB::transaction(function () use ($oldPersonId, $client, $fullName, $data, &$newPerson) {
$newPerson = \App\Models\Person\Person::create([
'nu' => null, // boot event will generate
'first_name' => $data['first_name'] ?? null,
'last_name' => $data['last_name'] ?? null,
'full_name' => $fullName,
'gender' => null,
'birthday' => null,
'tax_number' => $data['tax_number'] ?? null,
'social_security_number' => $data['social_security_number'] ?? null,
'description' => $data['description'] ?? 'Emergency recreated person',
'group_id' => 1,
'type_id' => 2,
]);
// Re-point related records referencing the old (missing) person id
$tables = [
'emails', 'person_phones', 'person_addresses', 'bank_accounts', 'client_cases',
];
foreach ($tables as $table) {
\DB::table($table)->where('person_id', $oldPersonId)->update(['person_id' => $newPerson->id]);
}
// Finally update the client itself (only this one; avoid touching other potential clients)
$client->person_id = $newPerson->id;
$client->save();
});
return redirect()->back()->with('flash', [
'type' => 'success',
'message' => 'New person created and related records re-linked.',
'person_uuid' => $newPerson?->uuid,
]);
}
}