route('id'); $rules = [ 'document' => [ 'sometimes', 'string', 'regex:/^[0-9]{11}$|^[0-9]{14}$/', function ($attribute, $value, $fail) { if (!$this->isValidCpfCnpj($value)) { $fail(__('validation.custom.document.invalid')); } }, ], 'user_id' => [ 'sometimes', 'exists:users,id', function ($attribute, $value, $fail) use ($clientId) { $clientExists = \DB::table('clients') ->where('user_id', $value) ->whereNull('deleted_at') ->when($clientId, function ($query) use ($clientId) { $query->where('id', '!=', $clientId); }) ->exists(); if ($clientExists) { $fail(__('validation.custom.user_id.already_linked_to_client')); } $providerExists = \DB::table('providers') ->where('user_id', $value) ->whereNull('deleted_at') ->exists(); if ($providerExists) { $fail(__('validation.custom.user_id.already_linked_to_provider')); } }, ], ]; if ($this->isMethod('post')) { $rules['document'] = [ 'required', 'string', 'regex:/^[0-9]{11}$|^[0-9]{14}$/', function ($attribute, $value, $fail) { if (!$this->isValidCpfCnpj($value)) { $fail(__('validation.custom.document.invalid')); } }, ]; $rules['user_id'] = [ 'required', 'exists:users,id', function ($attribute, $value, $fail) { $clientExists = \DB::table('clients') ->where('user_id', $value) ->whereNull('deleted_at') ->exists(); if ($clientExists) { $fail(__('validation.custom.user_id.already_linked_to_client')); } $providerExists = \DB::table('providers') ->where('user_id', $value) ->whereNull('deleted_at') ->exists(); if ($providerExists) { $fail(__('validation.custom.user_id.already_linked_to_provider')); } }, ]; } return $rules; } private function isValidCpfCnpj(string $value): bool { $value = preg_replace('/[^0-9]/', '', $value); if (strlen($value) === 11) { return $this->isValidCpf($value); } elseif (strlen($value) === 14) { return $this->isValidCnpj($value); } return false; } private function isValidCpf(string $cpf): bool { if (preg_match('/(\d)\1{10}/', $cpf)) { return false; } for ($t = 9; $t < 11; $t++) { for ($d = 0, $c = 0; $c < $t; $c++) { $d += $cpf[$c] * (($t + 1) - $c); } $d = ((10 * $d) % 11) % 10; if ($cpf[$c] != $d) { return false; } } return true; } private function isValidCnpj(string $cnpj): bool { if (preg_match('/(\d)\1{13}/', $cnpj)) { return false; } $length = strlen($cnpj) - 2; $numbers = substr($cnpj, 0, $length); $digits = substr($cnpj, $length); $sum = 0; $pos = $length - 7; for ($i = $length; $i >= 1; $i--) { $sum += $numbers[$length - $i] * $pos--; if ($pos < 2) { $pos = 9; } } $result = $sum % 11 < 2 ? 0 : 11 - $sum % 11; if ($result != $digits[0]) { return false; } $length = $length + 1; $numbers = substr($cnpj, 0, $length); $sum = 0; $pos = $length - 7; for ($i = $length; $i >= 1; $i--) { $sum += $numbers[$length - $i] * $pos--; if ($pos < 2) { $pos = 9; } } $result = $sum % 11 < 2 ? 0 : 11 - $sum % 11; if ($result != $digits[1]) { return false; } return true; } }