diff --git a/app/Imports/MatchmakingProfileImport.php b/app/Imports/MatchmakingProfileImport.php index 3151ff404..9ac3b298c 100644 --- a/app/Imports/MatchmakingProfileImport.php +++ b/app/Imports/MatchmakingProfileImport.php @@ -44,6 +44,25 @@ protected function parseBool($value): bool return in_array($v, ['1', 'true', 'yes', 'y'], true); } + protected function normalizeEmail(?string $value): ?string + { + if ($value === null) { + return null; + } + $value = trim((string) $value); + if ($value === '' || $value === '—' || $value === '-') { + return null; + } + $lower = mb_strtolower($value); + if (in_array($lower, ['anonymous', 'n/a', 'na', 'none', 'null'], true)) { + return null; + } + if (!str_contains($value, '@')) { + return null; + } + return $value; + } + /** * Parse date values */ @@ -303,7 +322,7 @@ public function model(array $row): ?Model $row = $this->normalizeRowKeys($row); // Try to get email and organisation name with multiple possible key variations - $email = $this->getRowValue($row, [ + $rawEmail = $this->getRowValue($row, [ 'email', 'Email', 'email_address', @@ -341,6 +360,11 @@ public function model(array $row): ?Model 'Main email address', ]); + $emailAddress = $this->getRowValue($row, [ + 'email_address', + 'Email address', + ]); + // Optional location field (if present) $locationValue = $this->getRowValue($row, [ 'location', @@ -391,20 +415,15 @@ public function model(array $row): ?Model 'Do you give your consent to use your LinkedIn profile picture and display it in the matchmaking directory?', ]); - // Skip rows without essential data - if (empty($email) && empty($organisationName)) { - Log::warning('[MatchmakingProfileImport] Skipping row - missing email and organisation_name', $row); - return null; - } - // Trim values - $email = $email ? trim($email) : null; + $rawEmail = $rawEmail ? trim($rawEmail) : null; $organisationName = $organisationName ? trim($organisationName) : null; $fullName = $fullName ? trim($fullName) : null; $firstName = $firstName ? trim($firstName) : null; $lastName = $lastName ? trim($lastName) : null; $jobTitle = $jobTitle ? trim($jobTitle) : null; $mainEmailAddress = $mainEmailAddress ? trim($mainEmailAddress) : null; + $emailAddress = $emailAddress ? trim($emailAddress) : null; $locationValue = $locationValue ? trim($locationValue) : null; $languages = $languages ? trim($languages) : null; $linkedin = $linkedin ? trim($linkedin) : null; @@ -412,6 +431,17 @@ public function model(array $row): ?Model $whyVolunteeringValue = $whyVolunteeringValue ? trim($whyVolunteeringValue) : null; $formatValue = $formatValue ? trim($formatValue) : null; + // Prefer email address and main email address over "Email" (often "anonymous") + $email = $this->normalizeEmail($emailAddress) + ?? $this->normalizeEmail($mainEmailAddress) + ?? $this->normalizeEmail($rawEmail); + + // Skip rows without essential data + if (empty($email) && empty($organisationName) && empty($fullName)) { + Log::warning('[MatchmakingProfileImport] Skipping row - missing email, organisation_name, and name', $row); + return null; + } + // Optional explicit type override from CSV $typeOverride = $this->getRowValue($row, [ 'type', @@ -812,6 +842,13 @@ public function model(array $row): ?Model 'completion_time' => $completionTime, ]; + if ($existingProfile && empty($email)) { + unset($profileData['email']); + } + if ($existingProfile && empty($organisationName)) { + unset($profileData['organisation_name']); + } + // Only set slug if creating new profile if (!$existingProfile) { $profileData['slug'] = $slug;