fix(secretary): scope plan limit to the acting environment
Secretary limit always read the doctor's plan, so a clinic on the professional plan hit the doctor's free-plan cap of one secretary. Limit and count are now per environment: clinic env uses the clinic subscription and counts the clinic's active secretaries, personal env uses the doctor's own plan. Counting is per person, not per row, so a secretary linked to several doctors of one clinic counts once, and re-linking an already-active person never trips the cap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ use App\Secretary\Entity\DoctorSecretary;
|
||||
use App\Secretary\Repository\DoctorSecretaryRepository;
|
||||
use App\Sms\Entity\SmsLog;
|
||||
use App\Sms\Service\SmsService;
|
||||
use App\Subscription\Entity\SubscriptionPlan;
|
||||
use App\Subscription\Service\SubscriptionService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
@@ -60,11 +61,61 @@ class SecretaryService
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function doctorAtSecretaryLimit(Doctor $doctor): bool
|
||||
/**
|
||||
* سقف منشیِ **محیط**؛ محیط کلینیک و محیط مطب شخصی هرکدام سقف و شمارش جدا دارند.
|
||||
*
|
||||
* منشی روی ردیفِ پزشک ثبت میشود، ولی صاحبِ سقف محیط است: در کلینیک پلنِ کلینیک،
|
||||
* در مطب شخصی پلنِ خودِ پزشک. بدون این، کلینیکِ حرفهای به سقف پلن free پزشک
|
||||
* میخورد و پلنِ کلینیک بیاثر میماند.
|
||||
*/
|
||||
public function secretaryLimitFor(?Clinic $clinic, ?Doctor $doctor = null): int
|
||||
{
|
||||
$limit = $this->subscriptionService->getSecretaryLimit('doctor', $doctor->getId());
|
||||
if ($clinic !== null) {
|
||||
return $this->subscriptionService->getSecretaryLimit('clinic', $clinic->getId());
|
||||
}
|
||||
|
||||
return $this->secretaryRepo->countActiveByDoctor($doctor) >= $limit;
|
||||
return $doctor !== null
|
||||
? $this->subscriptionService->getSecretaryLimit('doctor', $doctor->getId())
|
||||
: SubscriptionPlan::UNLIMITED;
|
||||
}
|
||||
|
||||
/** تعداد منشیِ فعالِ محیط، به تفکیک شخص (نه ردیف). */
|
||||
public function secretaryCountFor(?Clinic $clinic, ?Doctor $doctor = null): int
|
||||
{
|
||||
if ($clinic !== null) {
|
||||
return $this->secretaryRepo->countActiveDistinctSecretariesByClinic($clinic);
|
||||
}
|
||||
|
||||
return $doctor !== null
|
||||
? $this->secretaryRepo->countActiveDistinctSecretariesByDoctorScope($doctor)
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* آیا افزودنِ این منشی به این محیط از سقف پلن عبور میکند؟
|
||||
*
|
||||
* $secretary وقتی داده شود و همان شخص از قبل در همین محیط فعال باشد، نفر تازهای
|
||||
* اضافه نمیشود؛ وصلکردن او به پزشکِ دومِ همان کلینیک نباید سقف بخورد.
|
||||
*/
|
||||
public function atSecretaryLimit(Doctor $doctor, ?Clinic $clinic = null, ?User $secretary = null): bool
|
||||
{
|
||||
$limit = $this->secretaryLimitFor($clinic, $doctor);
|
||||
if ($limit === SubscriptionPlan::UNLIMITED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($secretary !== null && $this->secretaryIsActiveIn($secretary, $doctor, $clinic)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->secretaryCountFor($clinic, $doctor) >= $limit;
|
||||
}
|
||||
|
||||
private function secretaryIsActiveIn(User $secretary, Doctor $doctor, ?Clinic $clinic): bool
|
||||
{
|
||||
return $clinic !== null
|
||||
? $this->secretaryRepo->findActiveBySecretaryForClinic($secretary, $clinic) !== null
|
||||
: $this->secretaryRepo->findActiveBySecretaryForDoctor($secretary, $doctor) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +153,7 @@ class SecretaryService
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->doctorAtSecretaryLimit($doctor)) {
|
||||
if ($this->atSecretaryLimit($doctor, $clinic, $secretary)) {
|
||||
$skippedLimit[] = $doctorUuid;
|
||||
continue;
|
||||
}
|
||||
@@ -162,7 +213,7 @@ class SecretaryService
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ($this->doctorAtSecretaryLimit($doctor)) {
|
||||
if ($this->atSecretaryLimit($doctor, $clinic, $secretary)) {
|
||||
$skippedLimit[] = $doctorUuid;
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user