feat(subscription): allow admin to delete a granted subscription
Granting stacks a new row and extends the existing expiry, so a mistaken
grant had no way back: the report tab was read-only and no endpoint deleted
a subscription (only DELETE .../subscription/period/{uuid}, a different
resource).
Adds DELETE /api/v1/admin/subscription/{uuid}. Payment-backed subscriptions
are refused with 409 — deleting one would leave the sales report with a
payment that owns nothing; refunds are the correct path there.
The report tab gets a per-row delete with a confirm dialog, plus a button
that jumps to the grant tab so add and remove live in the same place.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -330,6 +330,25 @@ class SubscriptionController extends BaseController
|
||||
return $this->success($subscription->toArray(), 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* حذف اشتراک — برگرداندنِ اعطای اشتباه.
|
||||
*
|
||||
* `grant` هر بار ردیف تازه میسازد و روی انقضای قبلی سوار میشود، پس بدون این
|
||||
* مسیر، یک کلیک اضافی در تب اعطا راه برگشت نداشت.
|
||||
*/
|
||||
#[Route('/api/v1/admin/subscription/{uuid}', methods: ['DELETE'])]
|
||||
#[IsGranted('ROLE_ADMIN')]
|
||||
public function adminRevoke(string $uuid): JsonResponse
|
||||
{
|
||||
try {
|
||||
$this->subscriptionService->revoke($uuid);
|
||||
} catch (AppException $e) {
|
||||
return $this->error($e->getErrorCode(), $e->getMessage(), $e->getHttpStatus());
|
||||
}
|
||||
|
||||
return $this->success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* اشتراک فعالِ یک مقصد — پیش از اعطا، تا ادمین downgrade را ناخواسته انجام ندهد.
|
||||
*/
|
||||
|
||||
@@ -170,6 +170,31 @@ class SubscriptionService
|
||||
return $subscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* حذف اشتراک توسط ادمین.
|
||||
*
|
||||
* فقط اشتراکِ اعطایی یا تریال حذف میشود: اشتراکِ متصل به پرداخت سند مالی دارد و
|
||||
* پاک شدنش گزارش فروش را با ردیف پرداختِ بیاشتراک ناسازگار میکند. مسیر درستِ
|
||||
* آن استرداد است (`deleteByPayment`).
|
||||
*/
|
||||
public function revoke(string $uuid): void
|
||||
{
|
||||
$subscription = $this->subscriptionRepo->findByUuid($uuid);
|
||||
if ($subscription === null) {
|
||||
throw new AppException(ErrorCodes::ERR_SUBSCRIPTION_NOT_FOUND, null, 404);
|
||||
}
|
||||
|
||||
if ($subscription->getPayment() !== null) {
|
||||
throw new AppException(
|
||||
ErrorCodes::ERR_CONFLICT_001,
|
||||
'اشتراک پرداختشده حذف نمیشود؛ از مسیر استرداد وجه اقدام کنید',
|
||||
409,
|
||||
);
|
||||
}
|
||||
|
||||
$this->subscriptionRepo->remove($subscription);
|
||||
}
|
||||
|
||||
/** حذف اشتراکِ ساختهشده از یک پرداخت (هنگام استرداد/برگشت وجه). */
|
||||
public function deleteByPayment(\App\Payment\Entity\Payment $payment): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user