diff --git a/app/Models/Person/Person.php b/app/Models/Person/Person.php index ba4ea8a..06692d7 100644 --- a/app/Models/Person/Person.php +++ b/app/Models/Person/Person.php @@ -46,6 +46,7 @@ class Person extends Model 'group_id', 'type_id', 'user_id', + 'employer' ]; protected $hidden = [ diff --git a/app/Services/ImportProcessor.php b/app/Services/ImportProcessor.php index dac06bf..e44af1e 100644 --- a/app/Services/ImportProcessor.php +++ b/app/Services/ImportProcessor.php @@ -24,6 +24,7 @@ use App\Models\Person\PersonPhone; use App\Models\Person\PersonType; use App\Models\Person\PhoneType; +use Exception; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Database\QueryException; use Illuminate\Support\Carbon; @@ -2974,7 +2975,7 @@ private function findOrCreatePersonId(array $p): ?int // Create person if any fields present; ensure required foreign keys if (! empty($p)) { $data = []; - foreach (['first_name', 'last_name', 'full_name', 'tax_number', 'social_security_number', 'birthday', 'gender', 'description', 'group_id', 'type_id'] as $k) { + foreach (['first_name', 'last_name', 'full_name', 'tax_number', 'social_security_number', 'birthday', 'gender', 'description', 'group_id', 'type_id', 'employer'] as $k) { if (array_key_exists($k, $p)) { $data[$k] = $p[$k]; } @@ -2987,6 +2988,16 @@ private function findOrCreatePersonId(array $p): ?int $data['full_name'] = trim($fn.' '.$ln); } } + + // normalise birthday date + if (!empty($data['birthday'])) { + try { + $data['birthday'] = date('Y-m-d', strtotime($data['birthday'])); + } catch (Exception $e) { + Log::warning('ImportProcessor::findOrCreatePersonId ' . $e->getMessage()); + } + + } // ensure required group/type ids $data['group_id'] = $data['group_id'] ?? $this->getDefaultPersonGroupId(); $data['type_id'] = $data['type_id'] ?? $this->getDefaultPersonTypeId(); @@ -3163,10 +3174,38 @@ private function upsertAddress(int $personId, array $addrData, $mappings): array if (! isset($addrData['country']) || $addrData['country'] === null || $addrData['country'] === '') { $addrData['country'] = 'SLO'; } + + if (!empty($addrData['city']) && empty($addrData['post_code'])) { + if (preg_match('/^\d{3,}\s+/',trim($addrData['city']))) { + $cleanStrCity = str($addrData['city'])->squish()->value(); + $splitCity = preg_split('/\s/', $cleanStrCity, 2); + if (count($splitCity) >= 2) { + $addrData['post_code'] = $splitCity[0]; + $addrData['city'] = $splitCity[1]; + } + } + } // Compare addresses with all spaces removed to handle whitespace variations - $addressLineNoSpaces = preg_replace('/\s+/', '', $addressLine); + /*$addressLineNoSpaces = preg_replace('/\s+/', '', $addressLine); + + $existing = PersonAddress::where('person_id', $personId) ->whereRaw("REPLACE(address, ' ', '') = ?", [$addressLineNoSpaces]) + ->first();*/ + + // Build search query combining address, post_code and city + $searchParts = [$addrData['post_code']]; + if (!empty($addrData['post_code'])) { + $searchParts[] = $addrData['post_code']; + } + if (!empty($addrData['city'])) { + $searchParts[] = $addrData['city']; + } + + $searchQuery = implode(' ', $searchParts); + // Use fulltext search (GIN index optimized) + $existing = PersonAddress::where('person_id', $personId) + ->whereRaw("search_vector @@ plainto_tsquery('simple', ?)", [$searchQuery]) ->first(); $applyInsert = []; @@ -3211,6 +3250,11 @@ private function upsertAddress(int $personId, array $addrData, $mappings): array $data['person_id'] = $personId; $data['country'] = $data['country'] ?? 'SLO'; $data['type_id'] = $data['type_id'] ?? $this->getDefaultAddressTypeId(); + + if (!empty($addrData['post_code']) && $addrData['post_code'] !== '0' && !isset($applyUpdate['post_code'])) { + $data['post_code'] = $addrData['post_code']; + } + try { $created = PersonAddress::create($data); diff --git a/database/migrations/2026_01_14_183008_alter_table_person_add_column_employer.php b/database/migrations/2026_01_14_183008_alter_table_person_add_column_employer.php new file mode 100644 index 0000000..bfb1f8b --- /dev/null +++ b/database/migrations/2026_01_14_183008_alter_table_person_add_column_employer.php @@ -0,0 +1,28 @@ +string('employer', 125)->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('person', function (Blueprint $table){ + $table->dropColumn('employer'); + }); + } +}; diff --git a/database/migrations/2026_01_14_191129_alter_table_person_addresses_add_fulltext.php b/database/migrations/2026_01_14_191129_alter_table_person_addresses_add_fulltext.php new file mode 100644 index 0000000..ef535d0 --- /dev/null +++ b/database/migrations/2026_01_14_191129_alter_table_person_addresses_add_fulltext.php @@ -0,0 +1,37 @@ +dropIndex('person_addresses_search_vector_idx'); + $table->dropColumn('search_vector'); + }); + } +}; \ No newline at end of file diff --git a/database/seeders/ImportEntitySeeder.php b/database/seeders/ImportEntitySeeder.php index 2ec1be7..87f7db7 100644 --- a/database/seeders/ImportEntitySeeder.php +++ b/database/seeders/ImportEntitySeeder.php @@ -14,7 +14,7 @@ public function run(): void 'key' => 'person', 'canonical_root' => 'person', 'label' => 'Person', - 'fields' => ['first_name', 'last_name', 'full_name', 'gender', 'birthday', 'tax_number', 'social_security_number', 'description'], + 'fields' => ['first_name', 'last_name', 'full_name', 'gender', 'birthday', 'tax_number', 'social_security_number', 'description', 'employer'], 'field_aliases' => [ 'dob' => 'birthday', 'date_of_birth' => 'birthday', @@ -30,6 +30,7 @@ public function run(): void ['pattern' => '/^(spol|gender)\b/i', 'field' => 'gender'], ['pattern' => '/^(rojstvo|datum\s*rojstva|dob|birth|birthday|date\s*of\s*birth)\b/i', 'field' => 'birthday'], ['pattern' => '/^(komentar|opis|opomba|comment|description|note)\b/i', 'field' => 'description'], + ['pattern' => '/^(delodajalec|služba)\b/i', 'field' => 'employer'] ], 'ui' => ['order' => 1], ],