Replace employee user_ref text field with Ladill user select.
Deploy Ladill Frontdesk / deploy (push) Successful in 40s
Deploy Ladill Frontdesk / deploy (push) Successful in 40s
Populate the dropdown from team members and linked hosts, show name and email labels, and block linking a user already tied to another employee. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,11 +8,14 @@ use App\Models\Branch;
|
||||
use App\Models\Employee;
|
||||
use App\Models\EmployeePresenceEvent;
|
||||
use App\Models\Host;
|
||||
use App\Models\Member;
|
||||
use App\Models\User;
|
||||
use App\Services\Frontdesk\EmployeePresenceService;
|
||||
use App\Services\Frontdesk\QrCodeService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
@@ -44,6 +47,7 @@ class EmployeeController extends Controller
|
||||
'organization' => $organization,
|
||||
'branches' => $this->branches($request, $organization->id),
|
||||
'hosts' => $this->hosts($request, $organization->id),
|
||||
'linkableUsers' => $this->linkableUsers($request, $organization->id),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -52,7 +56,7 @@ class EmployeeController extends Controller
|
||||
$this->authorizeAbility($request, 'employees.manage');
|
||||
$organization = $this->organization($request);
|
||||
|
||||
$validated = $this->validatedEmployee($request);
|
||||
$validated = $this->validatedEmployee($request, $organization->id);
|
||||
$pin = $validated['pin'];
|
||||
unset($validated['pin']);
|
||||
|
||||
@@ -77,6 +81,7 @@ class EmployeeController extends Controller
|
||||
'employee' => $employee->load('presence'),
|
||||
'branches' => $this->branches($request, $employee->organization_id),
|
||||
'hosts' => $this->hosts($request, $employee->organization_id),
|
||||
'linkableUsers' => $this->linkableUsers($request, $employee->organization_id, $employee),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -85,7 +90,7 @@ class EmployeeController extends Controller
|
||||
$this->authorizeAbility($request, 'employees.manage');
|
||||
$this->authorizeOwner($request, $employee);
|
||||
|
||||
$validated = $this->validatedEmployee($request, updating: true);
|
||||
$validated = $this->validatedEmployee($request, $employee->organization_id, updating: true, employee: $employee);
|
||||
|
||||
$payload = $this->employeePayload($validated);
|
||||
if (! empty($validated['pin'])) {
|
||||
@@ -277,12 +282,17 @@ class EmployeeController extends Controller
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
protected function validatedEmployee(Request $request, bool $updating = false): array
|
||||
protected function validatedEmployee(Request $request, int $organizationId, bool $updating = false, ?Employee $employee = null): array
|
||||
{
|
||||
$pinRules = $updating
|
||||
? ['nullable', 'string', 'regex:/^\d{4,6}$/']
|
||||
: ['required', 'string', 'regex:/^\d{4,6}$/'];
|
||||
|
||||
$linkableRefs = collect($this->linkableUsers($request, $organizationId, $employee))
|
||||
->reject(fn (array $user) => $user['taken'])
|
||||
->pluck('user_ref')
|
||||
->all();
|
||||
|
||||
return $request->validate([
|
||||
'employee_code' => ['required', 'string', 'max:32'],
|
||||
'full_name' => ['required', 'string', 'max:255'],
|
||||
@@ -292,10 +302,82 @@ class EmployeeController extends Controller
|
||||
'pin' => $pinRules,
|
||||
'branch_id' => ['nullable', 'integer'],
|
||||
'host_id' => ['nullable', 'integer'],
|
||||
'user_ref' => ['nullable', 'string', 'max:64'],
|
||||
'user_ref' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'max:64',
|
||||
Rule::when(
|
||||
filled($request->input('user_ref')),
|
||||
[Rule::in($linkableRefs)]
|
||||
),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ladill users that can be linked to an employee (team members and linked hosts).
|
||||
*
|
||||
* @return list<array{user_ref: string, label: string, taken: bool}>
|
||||
*/
|
||||
protected function linkableUsers(Request $request, int $organizationId, ?Employee $employee = null): array
|
||||
{
|
||||
$ownerRef = $this->ownerRef($request);
|
||||
|
||||
$refs = collect()
|
||||
->merge(
|
||||
Member::owned($ownerRef)
|
||||
->where('organization_id', $organizationId)
|
||||
->pluck('user_ref')
|
||||
)
|
||||
->merge(
|
||||
Host::owned($ownerRef)
|
||||
->where('organization_id', $organizationId)
|
||||
->whereNotNull('user_ref')
|
||||
->pluck('user_ref')
|
||||
)
|
||||
->merge(
|
||||
Employee::owned($ownerRef)
|
||||
->where('organization_id', $organizationId)
|
||||
->whereNotNull('user_ref')
|
||||
->pluck('user_ref')
|
||||
);
|
||||
|
||||
if ($employee?->user_ref) {
|
||||
$refs->push($employee->user_ref);
|
||||
}
|
||||
|
||||
$refs = $refs->filter()->unique()->values();
|
||||
|
||||
$users = User::query()
|
||||
->whereIn('public_id', $refs)
|
||||
->get(['public_id', 'name', 'email'])
|
||||
->keyBy('public_id');
|
||||
|
||||
$takenRefs = Employee::owned($ownerRef)
|
||||
->where('organization_id', $organizationId)
|
||||
->whereNotNull('user_ref')
|
||||
->when($employee, fn ($query) => $query->where('id', '!=', $employee->id))
|
||||
->pluck('user_ref')
|
||||
->flip();
|
||||
|
||||
return $refs
|
||||
->map(function (string $ref) use ($users, $takenRefs, $employee) {
|
||||
$user = $users->get($ref);
|
||||
$label = $user
|
||||
? trim($user->name.' · '.$user->email)
|
||||
: $ref;
|
||||
|
||||
return [
|
||||
'user_ref' => $ref,
|
||||
'label' => $label,
|
||||
'taken' => $takenRefs->has($ref) && $employee?->user_ref !== $ref,
|
||||
];
|
||||
})
|
||||
->sortBy('label', SORT_NATURAL | SORT_FLAG_CASE)
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
protected function employeePayload(array $validated): array
|
||||
{
|
||||
$payload = $validated;
|
||||
|
||||
Reference in New Issue
Block a user