$streetSegment, 'street_number' => (string) ($data['number'] ?? $matches[1] ?? 'S/N'), 'neighborhood' => (string) ($data['district'] ?? $segments[1] ?? 'N/A'), 'reference_point' => (string) ($data['reference_point'] ?? 'N/A'), 'complementary' => (string) ($data['complement'] ?? 'N/A'), ]; } protected function formatBirthdate(mixed $birthdate): ?string { if ($birthdate === null || $birthdate === '') { return null; } if ($birthdate instanceof \DateTimeInterface) { return Carbon::instance($birthdate)->format('d/m/Y'); } $birthdate = trim((string) $birthdate); if (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $birthdate) === 1) { return $birthdate; } if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $birthdate) === 1) { return Carbon::createFromFormat('Y-m-d', $birthdate)->format('d/m/Y'); } return Carbon::parse($birthdate)->format('d/m/Y'); } protected function normalizeHolderName(string $holderName): string { $holderName = trim(preg_replace('/\s+/', ' ', $holderName) ?? ''); if (Str::length($holderName) < 30) { return $holderName; } $parts = explode(' ', $holderName); if (count($parts) >= 3) { $firstName = array_shift($parts); $lastName = array_pop($parts); $initials = array_map( static fn (string $part): string => Str::upper(Str::substr($part, 0, 1)), $parts ); $abbreviated = trim($firstName.' '.implode(' ', $initials).' '.$lastName); if (Str::length($abbreviated) < 30) { return $abbreviated; } $firstAndLast = trim($firstName.' '.$lastName); if (Str::length($firstAndLast) < 30) { return $firstAndLast; } } return Str::limit($holderName, 29, ''); } }