dryRun) { $count = $this->countPotentialLinks($ctx); for ($i = 0; $i < $count; $i++) { $result->incrementImported(); } return $result; } $inserted = $this->linkContactsViaCompany($ctx); for ($i = 0; $i < $inserted; $i++) { $result->incrementImported(); } return $result; } private function linkContactsViaCompany(ImportContext $ctx): int { $portalFilter = $ctx->portal !== 'all' ? $ctx->portalEnum->value : null; // Alle (user_id, contact_id) Paare aus der Firmenzugehörigkeit ableiten $pairs = DB::table('company_user') ->join('contacts', 'contacts.company_id', '=', 'company_user.company_id') ->when($portalFilter, fn ($q) => $q->where('contacts.portal', $portalFilter)) ->whereNull('contacts.deleted_at') ->select( 'company_user.user_id', 'contacts.id as contact_id', DB::raw('NOW() as created_at'), DB::raw('NOW() as updated_at'), ) ->distinct() ->get(); if ($pairs->isEmpty()) { return 0; } // Chunked insert um Memory zu schonen $inserted = 0; foreach ($pairs->chunk(500) as $chunk) { $inserted += DB::table('contact_user')->insertOrIgnore( $chunk->map(fn ($row) => [ 'contact_id' => $row->contact_id, 'user_id' => $row->user_id, 'created_at' => $row->created_at, 'updated_at' => $row->updated_at, ])->all() ); } return $inserted; } private function countPotentialLinks(ImportContext $ctx): int { $portalFilter = $ctx->portal !== 'all' ? $ctx->portalEnum->value : null; return DB::table('company_user') ->join('contacts', 'contacts.company_id', '=', 'company_user.company_id') ->when($portalFilter, fn ($q) => $q->where('contacts.portal', $portalFilter)) ->whereNull('contacts.deleted_at') ->distinct() ->count(); } }