payment
This commit is contained in:
@@ -20,6 +20,8 @@ import { AllowWithoutSubscription } from '../auth/decorators/allow-without-subsc
|
||||
import { PurchaseSmsPackageDto } from './dto/purchase-sms-package.dto';
|
||||
import { PurchaseSubscriptionDto } from './dto/purchase-subscription.dto';
|
||||
import { SalonSubscriptionsService } from './salon-subscriptions.service';
|
||||
import { PaymentsService } from '../payments/payments.service';
|
||||
import { PaymentUrlResponseDto } from '../payments/dto/payment-url-response.dto';
|
||||
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||
import {
|
||||
ApiStandardController,
|
||||
@@ -37,18 +39,19 @@ import { SalonSubscription } from './entities/salon-subscription.entity';
|
||||
export class SalonSubscriptionsController {
|
||||
constructor(
|
||||
private readonly salonSubscriptionsService: SalonSubscriptionsService,
|
||||
private readonly paymentsService: PaymentsService,
|
||||
) {}
|
||||
|
||||
@Roles(UserRole.ADMIN, UserRole.SALON)
|
||||
@Permissions(PermissionCode.SUBSCRIPTIONS_WRITE)
|
||||
@AllowWithoutSubscription()
|
||||
@ApiStandardOkResponse(SalonSubscription)
|
||||
@ApiStandardOkResponse(PaymentUrlResponseDto)
|
||||
@Post('purchase')
|
||||
purchaseSubscription(
|
||||
@Body() dto: PurchaseSubscriptionDto,
|
||||
@CurrentUser() user: AuthUser,
|
||||
) {
|
||||
return this.salonSubscriptionsService.purchaseSubscription(dto, user);
|
||||
return this.paymentsService.initiateSubscriptionPayment(dto, user);
|
||||
}
|
||||
|
||||
@Roles(UserRole.ADMIN, UserRole.SALON)
|
||||
|
||||
@@ -11,7 +11,6 @@ import { SubscriptionPolicy } from '../authorization/policies/subscription.polic
|
||||
import { SalonsService } from '../salons/salons.service';
|
||||
import { SMS_ROLLOVER_GRACE_DAYS } from './constants/subscription.constants';
|
||||
import { PurchaseSmsPackageDto } from './dto/purchase-sms-package.dto';
|
||||
import { PurchaseSubscriptionDto } from './dto/purchase-subscription.dto';
|
||||
import { SalonSmsPurchase } from './entities/salon-sms-purchase.entity';
|
||||
import { SalonSubscription } from './entities/salon-subscription.entity';
|
||||
import { SalonSubscriptionStatus } from './enums/salon-subscription-status.enum';
|
||||
@@ -32,27 +31,22 @@ export class SalonSubscriptionsService {
|
||||
private readonly subscriptionPolicy: SubscriptionPolicy,
|
||||
) {}
|
||||
|
||||
async purchaseSubscription(
|
||||
dto: PurchaseSubscriptionDto,
|
||||
user: AuthUser,
|
||||
async fulfillSubscriptionPurchase(
|
||||
salonId: string,
|
||||
planId: string,
|
||||
): Promise<SalonSubscription> {
|
||||
const salon = await this.salonsService.findOne(dto.salonId);
|
||||
if (!this.subscriptionPolicy.canPurchase(user, salon)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
const plan = await this.subscriptionPlansService.findActiveById(dto.planId);
|
||||
const activeSubscription = await this.findActiveSubscription(dto.salonId);
|
||||
const activeSubscription = await this.findActiveSubscription(salonId);
|
||||
if (activeSubscription) {
|
||||
throw new BadRequestException('Salon already has an active subscription');
|
||||
}
|
||||
|
||||
const plan = await this.subscriptionPlansService.findActiveById(planId);
|
||||
const now = new Date();
|
||||
const rolloverSms = await this.calculateSmsRollover(dto.salonId, now);
|
||||
const rolloverSms = await this.calculateSmsRollover(salonId, now);
|
||||
const freeSmsGranted = plan.freeSmsCount + rolloverSms;
|
||||
|
||||
const subscription = this.subscriptionsRepository.create({
|
||||
salonId: dto.salonId,
|
||||
salonId,
|
||||
planId: plan.id,
|
||||
status: SalonSubscriptionStatus.ACTIVE,
|
||||
startDate: now,
|
||||
@@ -63,7 +57,28 @@ export class SalonSubscriptionsService {
|
||||
});
|
||||
|
||||
const saved = await this.subscriptionsRepository.save(subscription);
|
||||
return this.findOne(saved.id, user);
|
||||
return this.subscriptionsRepository.findOneOrFail({
|
||||
where: { id: saved.id },
|
||||
relations: { plan: true, salon: true },
|
||||
});
|
||||
}
|
||||
|
||||
async validateSubscriptionPurchase(
|
||||
salonId: string,
|
||||
planId: string,
|
||||
user: AuthUser,
|
||||
): Promise<void> {
|
||||
const salon = await this.salonsService.findOne(salonId);
|
||||
if (!this.subscriptionPolicy.canPurchase(user, salon)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
await this.subscriptionPlansService.findActiveById(planId);
|
||||
|
||||
const activeSubscription = await this.findActiveSubscription(salonId);
|
||||
if (activeSubscription) {
|
||||
throw new BadRequestException('Salon already has an active subscription');
|
||||
}
|
||||
}
|
||||
|
||||
async purchaseSmsPackage(
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { Module, forwardRef } from '@nestjs/common';
|
||||
import { APP_GUARD } from '@nestjs/core';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { AuthGuardsModule } from '../auth/auth-guards.module';
|
||||
import { AuthorizationModule } from '../authorization/authorization.module';
|
||||
import { PaymentsModule } from '../payments/payments.module';
|
||||
import { SalonsModule } from '../salons/salons.module';
|
||||
import { SalonSmsPurchase } from './entities/salon-sms-purchase.entity';
|
||||
import { SalonSubscription } from './entities/salon-subscription.entity';
|
||||
@@ -27,6 +28,7 @@ import { SubscriptionPlansService } from './subscription-plans.service';
|
||||
SalonsModule,
|
||||
AuthorizationModule,
|
||||
AuthGuardsModule,
|
||||
forwardRef(() => PaymentsModule),
|
||||
],
|
||||
controllers: [
|
||||
SubscriptionPlansController,
|
||||
@@ -42,6 +44,6 @@ import { SubscriptionPlansService } from './subscription-plans.service';
|
||||
useClass: ActiveSubscriptionGuard,
|
||||
},
|
||||
],
|
||||
exports: [SalonSubscriptionsService],
|
||||
exports: [SalonSubscriptionsService, SubscriptionPlansService],
|
||||
})
|
||||
export class SubscriptionsModule {}
|
||||
|
||||
Reference in New Issue
Block a user