value; /** @var array */ public array $outlet_ids = []; /** @var array */ public array $role_ids = []; public function rules(): array { return array_merge($this->getBasicRules(), $this->getRelationshipRules()); } private function getBasicRules(): array { return [ 'full_name' => ['required', 'string', 'max:100'], 'username' => ['required', 'alpha_num', 'min:5', 'max:20', Rule::unique('users', 'username')->ignore($this->user)], 'email' => ['required', 'email', 'max:100', Rule::unique('users', 'email')->ignore($this->user)], 'phone_number' => ['required', 'string', new PhoneNumber], 'base_salary' => ['required', new UnsignedInteger], 'birthdate' => ['required', 'date', 'before:'.Carbon::now()->subYears(18)->format('Y-m-d')], 'hire_date' => ['required', 'date'], 'address' => ['nullable', 'string'], 'gender' => ['required', Rule::in(Gender::cases())], 'status' => ['required', Rule::in(UserStatus::cases())], ]; } private function getRelationshipRules(): array { return [ 'outlet_ids' => ['required', 'array', 'min:1'], 'outlet_ids.*' => Rule::exists('outlets', 'id'), 'role_ids' => ['required', 'array', 'min:1'], 'role_ids.*' => Rule::exists('roles', 'id'), ]; } public function validationAttributes(): array { return [ 'full_name' => 'nama lengkap', 'username' => 'nama pengguna', 'phone_number' => 'nomor telepon', 'base_salary' => 'gaji pokok', 'birthdate' => 'tanggal lahir', 'hire_date' => 'tanggal bergabung', 'address' => 'alamat', 'gender' => 'jenis kelamin', 'outlet_ids' => 'outlet', 'outlet_ids.*' => 'outlet', 'role_ids' => 'peran', 'role_ids.*' => 'peran', ]; } public function setUser(User $user): void { $user->load(['employee', 'outlets', 'roles']); $this->user = $user; $this->fillBasicAttributes($user); $this->outlet_ids = $user->outlets->pluck('id')->toArray(); $this->role_ids = $user->roles->pluck('id')->toArray(); } private function fillBasicAttributes(User $user): void { $employee = $user->employee; $this->full_name = $employee->full_name; $this->username = $user->username; $this->email = $user->email; $this->phone_number = $employee->phone_number; $this->base_salary = $employee->base_salary; $this->birthdate = $employee->birthdate; $this->hire_date = $employee->hire_date; $this->address = $employee->address; $this->gender = $employee->gender->value; $this->status = $user->status->value; } public function store(): void { $this->validate(); $data = $this->prepareDataForSave(); DB::transaction(function () use ($data) { $user = $this->createUser($data); $this->createEmployee($user, $data); $this->createReferralCode($user, $data); $this->assignOutletsAndRoles($user); }); } private function prepareDataForSave(): array { $data = $this->all(); $data['resign_date'] = $data['status'] != UserStatus::ACTIVE->value ? now() : null; return $data; } private function createUser(array $data): User { return User::create([ 'username' => $data['username'], 'email' => $data['email'], 'password' => Hash::make(config('myconfig.password_default')), 'status' => $data['status'], ]); } private function createEmployee(User $user, array $data): void { Employee::create([ 'user_id' => $user->id, 'full_name' => $data['full_name'], 'code' => Employee::generateEmployeeCode(), 'phone_number' => $data['phone_number'], 'base_salary' => parseRupiahToInt($data['base_salary']), 'birthdate' => $data['birthdate'], 'hire_date' => $data['hire_date'], 'resign_date' => $data['resign_date'], 'address' => $data['address'], 'gender' => $data['gender'], ]); } private function createReferralCode(User $user, array $data): void { ReferralCode::create([ 'user_id' => $user->id, 'code' => generateReferralCode($data['username'], $user->id), ]); } private function assignOutletsAndRoles(User $user): void { $user->outlets()->attach($this->outlet_ids); $roles = Role::whereIn('id', $this->role_ids)->get(); $user->assignRole($roles); } public function update(): void { $this->validate(); $data = $this->prepareDataForSave(); DB::transaction(function () use ($data) { $this->updateUser($data); $this->updateEmployee($data); $this->syncOutletsAndRoles(); }); } private function updateUser(array $data): void { $this->user->update([ 'username' => $data['username'], 'email' => $data['email'], 'status' => $data['status'], ]); } private function updateEmployee(array $data): void { $this->user->employee->update([ 'full_name' => $data['full_name'], 'phone_number' => $data['phone_number'], 'base_salary' => parseRupiahToInt($data['base_salary']), 'birthdate' => $data['birthdate'], 'hire_date' => $data['hire_date'], 'resign_date' => $data['resign_date'], 'address' => $data['address'], 'gender' => $data['gender'], ]); } private function syncOutletsAndRoles(): void { $this->user->outlets()->sync($this->outlet_ids); $roles = Role::whereIn('id', $this->role_ids)->get(); $this->user->syncRoles($roles); } }