feat: implement tax calculations for subscription and SMS wallet payments

- Updated SubscriptionPeriod interface to include tax-related fields: tax_percent, tax_rials, and payable_rials.
- Modified payment API documentation to reflect changes in tax handling for subscriptions and SMS wallet charges.
- Adjusted PaymentController to calculate payment amounts based on subscription period details instead of client input.
- Enhanced PaymentManager to handle net amounts for SMS wallet charges, ensuring tax is not credited to the wallet.
- Created PaymentTaxCalculator and SubscriptionTaxCalculator services to manage tax calculations consistently across payment types.
- Added tests for tax calculations in both subscription and SMS wallet contexts, ensuring correct behavior with and without tax enabled.
- Updated frontend components to display tax information appropriately during payment processes.
This commit is contained in:
hamed
2026-08-09 16:51:22 +03:30
parent 2471c90cbb
commit 7716b40f6a
18 changed files with 762 additions and 45 deletions
+17 -4
View File
@@ -34,6 +34,18 @@ class PaymentTenantTest extends ApiTestCase
parent::tearDown();
}
private function makePricedPeriod(int $priceRials): \App\Subscription\Entity\SubscriptionPeriod
{
$plan = new \App\Subscription\Entity\SubscriptionPlan('plan-' . bin2hex(random_bytes(4)), 5, 1, []);
$this->em->persist($plan);
$period = new \App\Subscription\Entity\SubscriptionPeriod($plan, 'یک ماهه', 1, $priceRials);
$this->em->persist($period);
$this->em->flush();
return $period;
}
private function makeDoctor(): Doctor
{
$doctor = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر پرداخت');
@@ -105,9 +117,10 @@ class PaymentTenantTest extends ApiTestCase
{
$doctor = $this->makeDoctor();
// مبلغ از خودِ دوره می‌آید (قیمت خالص + مالیات)، نه از بدنهٔ درخواست.
$res = $this->authJson('POST', '/api/v1/subscription-payment', $doctor->getUser(), [
'gateway' => 'mellat',
'amount_rials' => 1_000_000,
'gateway' => 'mellat',
'period_uuid' => $this->makePricedPeriod(1_000_000)->getUuid(),
]);
self::assertSame(200, $this->responseCode());
@@ -123,8 +136,8 @@ class PaymentTenantTest extends ApiTestCase
public function testSubscriptionPaymentWithoutAnOwnedEnvironmentIsRejected(): void
{
$res = $this->authJson('POST', '/api/v1/subscription-payment', $this->createUser(['ROLE_USER']), [
'gateway' => 'mellat',
'amount_rials' => 1_000_000,
'gateway' => 'mellat',
'period_uuid' => $this->makePricedPeriod(1_000_000)->getUuid(),
]);
self::assertSame(422, $this->responseCode());