@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\StoreDeviceAccessUserRequest;
|
||||
use App\Http\Requests\UpdateDeviceAccessUserRequest;
|
||||
use App\Jobs\SyncDeviceUser;
|
||||
use App\Models\Device;
|
||||
use App\Models\DeviceAccessUser;
|
||||
use App\Models\DeviceUserAssignment;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class DeviceAccessUserController extends Controller
|
||||
{
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
abort_unless($request->user()->can('device.user.view'), 403);
|
||||
$users = DeviceAccessUser::query()->with(['assignments' => fn ($query) => $query->with('device:id,name')])
|
||||
->when($request->integer('device_id'), fn ($query, $deviceId) => $query->whereHas('assignments', fn ($assignment) => $assignment->where('device_id', $deviceId)))
|
||||
->when($request->string('search')->isNotEmpty(), fn ($query) => $query->where(fn ($nested) => $nested->where('display_name', 'ilike', '%'.$request->string('search').'%')->orWhere('username', 'ilike', '%'.$request->string('search').'%')))
|
||||
->orderBy('display_name')->paginate(15)->withQueryString();
|
||||
|
||||
return Inertia::render('device-users/index', ['deviceUsers' => $users, 'devices' => Device::orderBy('name')->get(['id', 'name']), 'filters' => $request->only('search', 'device_id')]);
|
||||
}
|
||||
|
||||
public function create(): Response
|
||||
{
|
||||
abort_unless(request()->user()->can('device.user.create'), 403);
|
||||
|
||||
return Inertia::render('device-users/form', ['deviceUser' => null, 'devices' => $this->devices()]);
|
||||
}
|
||||
|
||||
public function store(StoreDeviceAccessUserRequest $request): RedirectResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
$assignments = DB::transaction(function () use ($request, $data) {
|
||||
$user = DeviceAccessUser::create(['tenant_id' => $request->user()->tenant_id, 'display_name' => $data['display_name'], 'username' => $data['username'], 'password' => $data['password'], 'is_enabled' => $data['is_enabled'] ?? true, 'notes' => $data['notes'] ?? null, 'created_by' => $request->user()->id, 'updated_by' => $request->user()->id]);
|
||||
|
||||
return collect($data['device_ids'])->map(fn ($deviceId) => DeviceUserAssignment::create(['tenant_id' => $request->user()->tenant_id, 'device_access_user_id' => $user->id, 'device_id' => $deviceId, 'group_name' => $data['group_name'], 'remote_username' => $user->username, 'sync_status' => 'queued']));
|
||||
});
|
||||
$this->syncAssignments($assignments, $request->user()->tenant_id);
|
||||
|
||||
return to_route('device-users.index')->with('success', $this->syncResultMessage($assignments, 'User perangkat berhasil dibuat.'));
|
||||
}
|
||||
|
||||
public function edit(DeviceAccessUser $deviceAccessUser): Response
|
||||
{
|
||||
$this->ensureOwned($deviceAccessUser);
|
||||
abort_unless(request()->user()->can('device.user.update'), 403);
|
||||
|
||||
return Inertia::render('device-users/form', ['deviceUser' => $deviceAccessUser->load('assignments:id,device_access_user_id,device_id,group_name'), 'devices' => $this->devices()]);
|
||||
}
|
||||
|
||||
public function update(UpdateDeviceAccessUserRequest $request, DeviceAccessUser $deviceAccessUser): RedirectResponse
|
||||
{
|
||||
$this->ensureOwned($deviceAccessUser);
|
||||
$data = $request->validated();
|
||||
$assignments = DB::transaction(function () use ($request, $data, $deviceAccessUser) {
|
||||
$oldUsername = $deviceAccessUser->username;
|
||||
$attributes = ['display_name' => $data['display_name'], 'username' => $data['username'], 'is_enabled' => $data['is_enabled'] ?? false, 'notes' => $data['notes'] ?? null, 'updated_by' => $request->user()->id];
|
||||
if (filled($data['password'] ?? null)) {
|
||||
$attributes['password'] = $data['password'];
|
||||
}
|
||||
$deviceAccessUser->update($attributes);
|
||||
$deviceAccessUser->assignments()->whereNull('remote_username')->update(['remote_username' => $oldUsername]);
|
||||
$selected = collect($data['device_ids'])->map(fn ($id) => (int) $id);
|
||||
$deviceAccessUser->assignments()->whereNotIn('device_id', $selected)->update(['desired_operation' => 'delete', 'sync_status' => 'queued']);
|
||||
foreach ($selected as $deviceId) {
|
||||
$deviceAccessUser->assignments()->updateOrCreate(['device_id' => $deviceId], ['tenant_id' => $request->user()->tenant_id, 'group_name' => $data['group_name'], 'desired_operation' => 'upsert', 'sync_status' => 'queued', 'error_code' => null]);
|
||||
}
|
||||
|
||||
return $deviceAccessUser->assignments()->where('sync_status', 'queued')->get();
|
||||
});
|
||||
$this->syncAssignments($assignments, $request->user()->tenant_id);
|
||||
|
||||
return to_route('device-users.index')->with('success', $this->syncResultMessage($assignments, 'Perubahan user berhasil disimpan.'));
|
||||
}
|
||||
|
||||
public function destroy(DeviceAccessUser $deviceAccessUser): RedirectResponse
|
||||
{
|
||||
$this->ensureOwned($deviceAccessUser);
|
||||
abort_unless(request()->user()->can('device.user.delete'), 403);
|
||||
$assignments = DB::transaction(function () use ($deviceAccessUser) {
|
||||
$deviceAccessUser->assignments()->update(['desired_operation' => 'delete', 'sync_status' => 'queued']);
|
||||
$items = $deviceAccessUser->assignments()->get();
|
||||
$deviceAccessUser->delete();
|
||||
|
||||
return $items;
|
||||
});
|
||||
$this->syncAssignments($assignments, request()->user()->tenant_id);
|
||||
|
||||
return back()->with('success', $this->syncResultMessage($assignments, 'Penghapusan user perangkat diproses.'));
|
||||
}
|
||||
|
||||
private function devices()
|
||||
{
|
||||
return Device::with('vendor:id,name')->where('is_active', true)->orderBy('name')->get(['id', 'name', 'device_vendor_id', 'status', 'activation_status']);
|
||||
}
|
||||
|
||||
private function ensureOwned(DeviceAccessUser $user): void
|
||||
{
|
||||
abort_unless(! request()->user()->is_platform_admin && $user->tenant_id === request()->user()->tenant_id, 404);
|
||||
}
|
||||
|
||||
private function syncResultMessage($assignments, string $prefix): string
|
||||
{
|
||||
$remaining = DeviceUserAssignment::withoutGlobalScope('tenant')->whereIn('id', $assignments->pluck('id'))->get()->keyBy('id');
|
||||
$statuses = $assignments->map(function ($assignment) use ($remaining) {
|
||||
return $remaining->get($assignment->id)?->sync_status
|
||||
?? ($assignment->desired_operation === 'delete' ? 'synced' : 'failed');
|
||||
});
|
||||
$pending = $statuses->filter(fn ($status) => in_array($status, ['pending', 'queued'], true))->count();
|
||||
$synced = $statuses->where('synced')->count();
|
||||
$failed = $statuses->filter(fn ($status) => in_array($status, ['failed', 'unsupported'], true))->count();
|
||||
|
||||
return $prefix." {$synced} perangkat langsung tersinkron"
|
||||
.($pending ? ", {$pending} perangkat pending dan akan dicoba scheduler" : '')
|
||||
.($failed ? ", {$failed} perangkat memerlukan pemeriksaan" : '').'.';
|
||||
}
|
||||
|
||||
private function syncAssignments($assignments, int $tenantId): void
|
||||
{
|
||||
$assignments->each(function (DeviceUserAssignment $assignment) use ($tenantId): void {
|
||||
$isSshOlt = in_array($assignment->device()->with('vendor:id,slug')->first()?->vendor?->slug, ['zte', 'hsgq'], true);
|
||||
$isSshOlt
|
||||
? SyncDeviceUser::dispatch($tenantId, $assignment->id)
|
||||
: SyncDeviceUser::dispatchSync($tenantId, $assignment->id);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user