feat(subscription): implement resource quota management based on subscription plans
This commit is contained in:
@@ -11,6 +11,8 @@ use App\Resource\Service\ResourceService;
|
||||
use App\Resource\Service\SkillAssignmentService;
|
||||
use App\Shared\Constant\ErrorCodes;
|
||||
use App\Shared\Controller\BaseController;
|
||||
use App\Subscription\Entity\SubscriptionPlan;
|
||||
use App\Subscription\Service\SubscriptionService;
|
||||
use OpenApi\Attributes as OA;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -35,6 +37,7 @@ class ResourceController extends BaseController
|
||||
private readonly \App\Appointment\Repository\AppointmentRepository $appointments,
|
||||
private readonly \App\Resource\Repository\ResourceServiceOfferingRepository $offerings,
|
||||
private readonly \App\Resource\Service\ResourceFreeTimeCalculator $freeTime,
|
||||
private readonly SubscriptionService $subscriptions,
|
||||
) {}
|
||||
|
||||
#[Route('/api/v1/resources', name: 'resource_list', methods: ['GET'])]
|
||||
@@ -77,6 +80,19 @@ class ResourceController extends BaseController
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'بدنهٔ درخواست نامعتبر است', 422);
|
||||
}
|
||||
|
||||
// سقف پلن پیش از هر اعتبارسنجی دیگری سنجیده میشود: کاربری که جا ندارد نباید
|
||||
// فرم را تا آخر پر کند و ته کار خطای بیربط بگیرد.
|
||||
[$entityType, $entityId] = $this->context->pair($user);
|
||||
$limit = $this->subscriptions->getResourceLimit($entityType, $entityId);
|
||||
|
||||
if ($limit !== SubscriptionPlan::UNLIMITED && $this->resources->countForPair($entityType, $entityId) >= $limit) {
|
||||
return $this->error(
|
||||
ErrorCodes::ERR_RESOURCE_LIMIT_001,
|
||||
sprintf('پلن فعلی حداکثر %d منبع را پشتیبانی میکند؛ برای افزودن، پنل را ارتقا دهید', $limit),
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_string($data['type_uuid'] ?? null)) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_002, 'فیلد type_uuid الزامی است', 422, 'type_uuid');
|
||||
}
|
||||
|
||||
@@ -64,6 +64,24 @@ class ClinicResourceRepository extends ServiceEntityRepository
|
||||
return $qb->orderBy('r.name', 'ASC')->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* همهٔ منابع یک محیط، فعال و غیرفعال — مبنای سقفِ پلن اشتراک.
|
||||
*
|
||||
* غیرفعالها هم شمرده میشوند وگرنه سقف با یک بار غیرفعالکردن دور زده میشد؛
|
||||
* منابعِ پلِ پزشک/پرسنل هم شمرده میشوند، چون از نظر محصول «منبع» همانقدر منبعاند.
|
||||
*/
|
||||
public function countForPair(string $entityType, int $entityId): int
|
||||
{
|
||||
return (int) $this->createQueryBuilder('r')
|
||||
->select('COUNT(r.id)')
|
||||
->where('r.entityType = :type')
|
||||
->andWhere('r.entityId = :id')
|
||||
->setParameter('type', $entityType)
|
||||
->setParameter('id', $entityId)
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
}
|
||||
|
||||
/** منابع فعال یک محیط — شرط آمادگیِ حالت نوبتدهی منبعمحور. */
|
||||
public function countActiveForPair(string $entityType, int $entityId): int
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user