- Removed individual commands for backfilling specialty parents, surrogate roles, and fixing IRIMC names. - Introduced RepairImportedDoctorsCommand to consolidate functionality. - Implemented a step-based approach for repairs, allowing for idempotent execution. - Added new service classes for handling specific repair steps, including BackfillSpecialtyParentsStep, BackfillSurrogateRoleStep, FixDegreeStep, and StripNameTitleStep. - Created RepairOptions and RepairResult classes to manage step execution options and results. - Updated tests to ensure new command structure and functionality are covered, including idempotency and dry-run behavior. - Added IrimcDegreeMapper for mapping IRIMC titles to degrees.
64 lines
2.6 KiB
PHP
64 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Doctor\Service;
|
|
|
|
use App\Doctor\Entity\Doctor;
|
|
|
|
/**
|
|
* نگاشت عنوان خام نظام پزشکی (ستون تخصص در membersearch.irimc.org) به کد درجهٔ ClinicPro.
|
|
*
|
|
* آینهٔ عمدیِ clinicpro-crawler/crawler_core.py::map_degree — خزنده در ریپوی جداست و
|
|
* درجه را از پیش محاسبهشده میفرستد، ولی این سمت هم باید بتواند همان محاسبه را
|
|
* بازتولید کند تا رکوردهای ایمپورتشدهٔ قدیمی قابل ترمیم باشند
|
|
* (app:doctors:fix-irimc-degrees). هر تغییری در یکی باید در دیگری هم اعمال شود.
|
|
*/
|
|
final class IrimcDegreeMapper
|
|
{
|
|
/** برچسب فارسیِ هر کد — همان چیزی که پنل ادمین نشان میدهد. */
|
|
public const LABELS = [
|
|
'general' => 'عمومی',
|
|
'specialist' => 'متخصص',
|
|
'expert' => 'فوق تخصص',
|
|
'subspecialistplus' => 'فلوشیپ',
|
|
];
|
|
|
|
/**
|
|
* ترتیب شرطها معنادار است:
|
|
* - «فوق تخصص» خودش شامل «تخصص» است، پس باید پیش از آن بررسی شود؛
|
|
* - بسیاری از عنوانها هم «تخصص …» دارند و هم «دکترای حرفهای پزشکی»،
|
|
* و داشتنِ تخصص بر مدرک عمومی مقدم است، پس general آخر میآید.
|
|
*
|
|
* عنوان ناشناخته → null؛ هرگز حدس نزن، چون درجهٔ غلط از نبودِ درجه بدتر است.
|
|
*/
|
|
public static function fromTitle(?string $title): ?string
|
|
{
|
|
if ($title === null || trim($title) === '') {
|
|
return null;
|
|
}
|
|
if (str_contains($title, 'فلوشیپ')) {
|
|
return 'subspecialistplus';
|
|
}
|
|
if (str_contains($title, 'فوق تخصص') || str_contains($title, 'فوقتخصص')) {
|
|
return 'expert';
|
|
}
|
|
if (str_contains($title, 'تخصص') || str_contains($title, 'متخصص')) {
|
|
return 'specialist';
|
|
}
|
|
if (str_contains($title, 'دکترای حرفهای') || str_contains($title, 'عموم')) {
|
|
return 'general';
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static function label(?string $degree): string
|
|
{
|
|
return self::LABELS[$degree] ?? var_export($degree, true);
|
|
}
|
|
|
|
public static function isValid(?string $degree): bool
|
|
{
|
|
return $degree !== null && in_array($degree, Doctor::DEGREES, true);
|
|
}
|
|
}
|