Files
clinicpro/src/Doctor/Service/Repair/BackfillSourceProfileIdStep.php
T

66 lines
2.3 KiB
PHP

<?php
namespace App\Doctor\Service\Repair;
use App\Doctor\Entity\Doctor;
use App\Doctor\Service\SourceProfileId;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* پرکردن `source_profile_id` رکوردهای موجود از روی `source_ref` — پیش‌نیازِ یونیک‌ایندکس
* `(source, source_profile_id)`. بدون این، رکوردهای قدیمی `source_profile_id=NULL` می‌مانند
* و dedup مبتنی بر profile id فقط برای ایمپورت‌های جدید کار می‌کند.
*/
final class BackfillSourceProfileIdStep implements DoctorRepairStep
{
public function __construct(private readonly EntityManagerInterface $em)
{
}
public function name(): string
{
return 'source-profile-id';
}
public function description(): string
{
return 'پرکردن source_profile_id از روی source_ref برای رکوردهای موجود';
}
public function run(RepairOptions $options, SymfonyStyle $io): RepairResult
{
$qb = $this->em->getRepository(Doctor::class)->createQueryBuilder('d')
->where('d.sourceRef IS NOT NULL')
->andWhere('d.sourceProfileId IS NULL');
if (!$options->allSources) {
$qb->andWhere('d.source = :src')->setParameter('src', 'irimc');
}
/** @var Doctor[] $doctors */
$doctors = $qb->getQuery()->getResult();
$changed = 0;
$skipped = 0;
foreach ($doctors as $doctor) {
$id = SourceProfileId::fromRef($doctor->getSourceRef());
if ($id === null) {
// source_ref قالب شناسه‌دار ندارد — روی همان کد fallback می‌شود، تغییری نده.
$skipped++;
continue;
}
$io->text(sprintf(' #%d %s → %s', $doctor->getId(), $doctor->getName(), $id));
if (!$options->dryRun) {
$doctor->setSourceProfileId($id);
}
$changed++;
}
return new RepairResult(
scanned: count($doctors),
changed: $changed,
skipped: $skipped,
note: $skipped > 0 ? "$skipped رکورد بدون شناسهٔ قابل استخراج" : null,
);
}
}