91 lines
2.9 KiB
PHP
91 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Import;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
/**
|
|
* Post-Import-Schritt: verknüpft User direkt mit Kontakten.
|
|
*
|
|
* Logik: User → company_user → company → contacts
|
|
* Ein User der mit einer Firma verknüpft ist, bekommt automatisch alle
|
|
* Kontakte dieser Firma direkt in contact_user eingetragen.
|
|
*
|
|
* Läuft auf der NEUEN Datenbank (kein Legacy-DB-Zugriff nötig).
|
|
* Idempotent: insertOrIgnore() verhindert Duplikate bei Mehrfachläufen.
|
|
* Manuelle Admin-Zuordnungen (über Admin-UI erstellt) bleiben erhalten.
|
|
*/
|
|
class UserAssociationLinker
|
|
{
|
|
public function run(ImportContext $ctx): ImportResult
|
|
{
|
|
$result = new ImportResult;
|
|
|
|
if ($ctx->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();
|
|
}
|
|
}
|