2026-06-23 10:10:28 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Modules\Client\Resources;
|
|
|
|
|
|
2026-07-18 09:34:18 +00:00
|
|
|
use App\Modules\CustomField\Models\CustomFieldDefinition;
|
2026-06-23 10:10:28 +00:00
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Illuminate\Http\Resources\Json\JsonResource;
|
2026-07-18 09:34:18 +00:00
|
|
|
use Illuminate\Support\Carbon;
|
2026-06-23 10:10:28 +00:00
|
|
|
|
|
|
|
|
class ClientResource extends JsonResource
|
|
|
|
|
{
|
|
|
|
|
public function toArray(Request $request): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'id' => $this->id,
|
|
|
|
|
'client_number' => $this->client_number,
|
|
|
|
|
'name' => $this->name,
|
|
|
|
|
'notes' => $this->notes ?? [],
|
|
|
|
|
'created_at' => $this->created_at->toISOString(),
|
|
|
|
|
'updated_at' => $this->updated_at->toISOString(),
|
2026-07-18 09:34:18 +00:00
|
|
|
// List/search endpoints load these via withCount/withMax; absent on
|
|
|
|
|
// the detail endpoint, so guard before exposing them.
|
|
|
|
|
'history_count' => $this->whenNotNull($this->history_entries_count),
|
|
|
|
|
'last_history_at' => $this->when(
|
|
|
|
|
$this->history_entries_count !== null,
|
|
|
|
|
fn () => $this->history_entries_max_created_at
|
|
|
|
|
? Carbon::parse($this->history_entries_max_created_at)->toISOString()
|
|
|
|
|
: null,
|
|
|
|
|
),
|
|
|
|
|
// Only present on the detail endpoint (where the relation is eager
|
|
|
|
|
// loaded); omitted from list responses to avoid per-row queries.
|
|
|
|
|
'custom_fields' => $this->when(
|
|
|
|
|
$this->resource->relationLoaded('customFieldValues'),
|
|
|
|
|
fn () => $this->buildCustomFields(),
|
|
|
|
|
),
|
2026-06-23 10:10:28 +00:00
|
|
|
];
|
|
|
|
|
}
|
2026-07-18 09:34:18 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Merge every active field definition (ordered) with this client's value,
|
|
|
|
|
* so unset fields still render with an empty state.
|
|
|
|
|
*
|
|
|
|
|
* @return array<int, array<string, mixed>>
|
|
|
|
|
*/
|
|
|
|
|
private function buildCustomFields(): array
|
|
|
|
|
{
|
|
|
|
|
$valuesByDefinition = $this->customFieldValues->keyBy('custom_field_definition_id');
|
|
|
|
|
|
|
|
|
|
return CustomFieldDefinition::orderBy('sort_order')->orderBy('id')->get()
|
|
|
|
|
->map(function (CustomFieldDefinition $definition) use ($valuesByDefinition) {
|
|
|
|
|
$value = $valuesByDefinition->get($definition->id);
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'definition_id' => $definition->id,
|
|
|
|
|
'key' => $definition->key,
|
|
|
|
|
'label' => $definition->label,
|
|
|
|
|
'type' => $definition->type->value,
|
|
|
|
|
'options' => $definition->options ?? [],
|
|
|
|
|
'is_required' => $definition->is_required,
|
|
|
|
|
'value' => $value?->value,
|
|
|
|
|
'author_name' => $value?->author?->name,
|
|
|
|
|
'updated_at' => $value?->updated_at?->toISOString(),
|
|
|
|
|
];
|
|
|
|
|
})
|
|
|
|
|
->all();
|
|
|
|
|
}
|
2026-06-23 10:10:28 +00:00
|
|
|
}
|