add : extend user subscription
This commit is contained in:
@@ -41,3 +41,16 @@ export class SubscribeServiceDto {
|
|||||||
@ApiProperty({ description: "Array of user IDs to add as staff", type: [String], required: false })
|
@ApiProperty({ description: "Array of user IDs to add as staff", type: [String], required: false })
|
||||||
staff?: string[];
|
staff?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ExtendUSerSubscribeServiceDto {
|
||||||
|
@IsNotEmpty({ message: SubscriptionMessage.PLAN_ID_REQUIRED })
|
||||||
|
@IsUUID(4, { message: SubscriptionMessage.PLAN_ID_SHOULD_BE_UUID })
|
||||||
|
@ApiProperty({ description: "The plan id to subscribe to", example: "f7b3b3b3-7b3b-4b3b-8b3b-3b3b3b3b3b3b" })
|
||||||
|
planId: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: SubscriptionMessage.SERVICE_MUST_BE_UUID })
|
||||||
|
@IsUUID(4, { message: SubscriptionMessage.SERVICE_MUST_BE_UUID })
|
||||||
|
@ApiProperty({ description: "The service id ", example: "f7b3b3b3-7b3b-4b3b-8b3b-3b3b3b3b3b3b" })
|
||||||
|
serviceId: string;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { IsNotEmpty, IsUUID } from "class-validator";
|
||||||
|
|
||||||
|
import { CommonMessage } from "../../../common/enums/message.enum";
|
||||||
|
|
||||||
|
export class UserSubscriptionIdParamDto {
|
||||||
|
@IsNotEmpty({ message: CommonMessage.ID_REQUIRED })
|
||||||
|
@IsUUID("4", { message: CommonMessage.ID_SHOULD_BE_UUID })
|
||||||
|
@ApiProperty({ description: "Id of user Subscription Id", example: "8b1e8b1e-8b1e-8b1e-8b1e-8b1e8b1e8b1e" })
|
||||||
|
userSubscriptionId: string;
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ import { SUBSCRIPTIONS } from "../constants";
|
|||||||
import { AddSubscriptionsToServiceDto } from "../DTO/create-subscription.dto";
|
import { AddSubscriptionsToServiceDto } from "../DTO/create-subscription.dto";
|
||||||
import { SearchUserSubsQueryDto } from "../DTO/search-user-subs-query.dto";
|
import { SearchUserSubsQueryDto } from "../DTO/search-user-subs-query.dto";
|
||||||
import { ServiceSubsQueryDto } from "../DTO/service-subs-query.dto";
|
import { ServiceSubsQueryDto } from "../DTO/service-subs-query.dto";
|
||||||
import { SubscribeServiceDto } from "../DTO/subscribe-service.dto";
|
import { ExtendUSerSubscribeServiceDto, SubscribeServiceDto } from "../DTO/subscribe-service.dto";
|
||||||
import { SubscriptionAccessDto } from "../DTO/subscription-access-dto";
|
import { SubscriptionAccessDto } from "../DTO/subscription-access-dto";
|
||||||
import { UpdateSubscriptionPlanDto } from "../DTO/update-subscription.dto";
|
import { UpdateSubscriptionPlanDto } from "../DTO/update-subscription.dto";
|
||||||
import { SubscriptionPlan } from "../entities/subscription.entity";
|
import { SubscriptionPlan } from "../entities/subscription.entity";
|
||||||
@@ -300,6 +300,86 @@ export class SubscriptionsService {
|
|||||||
await queryRunner.release();
|
await queryRunner.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//************************************ */
|
||||||
|
|
||||||
|
async extendSubscribeToPlan(userSubscriptionId: string, dto: ExtendUSerSubscribeServiceDto, userId: string) {
|
||||||
|
const queryRunner = this.dataSource.createQueryRunner();
|
||||||
|
|
||||||
|
let isFree = false;
|
||||||
|
try {
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
|
const userSubscription = await queryRunner.manager.findOne(UserSubscription, {
|
||||||
|
where: { id: userSubscriptionId },
|
||||||
|
relations: {
|
||||||
|
user: true,
|
||||||
|
plan: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!userSubscription) throw new BadRequestException(SubscriptionMessage.NOT_FOUND);
|
||||||
|
|
||||||
|
const user = await this.usersService.findOneByIdWithQueryRunner(userId, queryRunner);
|
||||||
|
|
||||||
|
const plan = await queryRunner.manager.findOne(SubscriptionPlan, {
|
||||||
|
where: { id: dto.planId, service: { id: dto.serviceId } },
|
||||||
|
relations: { service: true, directDiscount: true, }
|
||||||
|
});
|
||||||
|
if (!plan) throw new BadRequestException(SubscriptionMessage.NOT_FOUND);
|
||||||
|
|
||||||
|
if (plan.isFree) {
|
||||||
|
isFree = true;
|
||||||
|
const oneMonthAgo = dayjs().subtract(1, "month").toDate();
|
||||||
|
const existingFreePlanSubscription = await queryRunner.manager.findOne(UserSubscription, {
|
||||||
|
where: {
|
||||||
|
user: { id: userId },
|
||||||
|
plan: { isFree: true },
|
||||||
|
startDate: MoreThan(oneMonthAgo),
|
||||||
|
},
|
||||||
|
relations: {
|
||||||
|
plan: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingFreePlanSubscription) {
|
||||||
|
throw new BadRequestException(SubscriptionMessage.FREE_PLAN_LIMIT_EXCEEDED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const startDate =
|
||||||
|
userSubscription && dayjs(userSubscription.endDate).isAfter(dayjs()) ? dayjs(userSubscription.endDate).toDate() : dayjs().toDate();
|
||||||
|
|
||||||
|
const endDate = dayjs(startDate).add(plan.duration, "day").toDate();
|
||||||
|
|
||||||
|
// await queryRunner.manager.save(UserSubscription, userSubscription);
|
||||||
|
const invoiceDueDate = dayjs().add(INVOICE.DUEDATE, "day").toDate();
|
||||||
|
|
||||||
|
const invoice = await this.invoicesService.createInvoiceForSubscription(user, plan, userSubscription, invoiceDueDate, queryRunner);
|
||||||
|
|
||||||
|
userSubscription.plan = plan;
|
||||||
|
userSubscription.endDate = endDate;
|
||||||
|
await queryRunner.manager.save(userSubscription);
|
||||||
|
|
||||||
|
await this.addProvisioningJob(userSubscription, plan, user);
|
||||||
|
|
||||||
|
if (isFree) {
|
||||||
|
await this.invoicesService.payInvoice(invoice.id, user.id, undefined, queryRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
return {
|
||||||
|
message: SubscriptionMessage.SUBSCRIBED,
|
||||||
|
userSubscription,
|
||||||
|
invoice,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//************************************ */
|
//************************************ */
|
||||||
async getServiceSubscriptions(serviceId: string, queryDto: ServiceSubsQueryDto) {
|
async getServiceSubscriptions(serviceId: string, queryDto: ServiceSubsQueryDto) {
|
||||||
const service = await this.danakServices.findServiceById(serviceId);
|
const service = await this.danakServices.findServiceById(serviceId);
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from "@nestjs/common";
|
import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query } from "@nestjs/common";
|
||||||
import { ApiOperation } from "@nestjs/swagger";
|
import { ApiOperation } from "@nestjs/swagger";
|
||||||
|
|
||||||
import { AddSubscriptionsToServiceDto } from "./DTO/create-subscription.dto";
|
import { AddSubscriptionsToServiceDto } from "./DTO/create-subscription.dto";
|
||||||
import { SearchUserSubsQueryDto } from "./DTO/search-user-subs-query.dto";
|
import { SearchUserSubsQueryDto } from "./DTO/search-user-subs-query.dto";
|
||||||
import { ServiceIdParamDto } from "./DTO/service-id.param.dto";
|
import { ServiceIdParamDto } from "./DTO/service-id.param.dto";
|
||||||
import { ServiceSubsQueryDto } from "./DTO/service-subs-query.dto";
|
import { ServiceSubsQueryDto } from "./DTO/service-subs-query.dto";
|
||||||
import { SubscribeServiceDto } from "./DTO/subscribe-service.dto";
|
import { ExtendUSerSubscribeServiceDto, SubscribeServiceDto } from "./DTO/subscribe-service.dto";
|
||||||
import { SubscriptionAccessDto } from "./DTO/subscription-access-dto";
|
import { SubscriptionAccessDto } from "./DTO/subscription-access-dto";
|
||||||
import { UpdateSubscriptionPlanDto } from "./DTO/update-subscription.dto";
|
import { UpdateSubscriptionPlanDto } from "./DTO/update-subscription.dto";
|
||||||
|
import { UserSubscriptionIdParamDto } from "./DTO/user-subscription-id.param.dto";
|
||||||
import { SubscriptionsService } from "./providers/subscriptions.service";
|
import { SubscriptionsService } from "./providers/subscriptions.service";
|
||||||
import { UserQuickAccessService } from "./providers/users-quick-access.service";
|
import { UserQuickAccessService } from "./providers/users-quick-access.service";
|
||||||
import { ApiKeyGuards } from "../../common/decorators/api-key-guard.decorator";
|
import { ApiKeyGuards } from "../../common/decorators/api-key-guard.decorator";
|
||||||
@@ -79,6 +80,16 @@ export class SubscriptionsController {
|
|||||||
return this.subscriptionService.subscribeToPlan(paramDto.serviceId, subscribeDto, userId);
|
return this.subscriptionService.subscribeToPlan(paramDto.serviceId, subscribeDto, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: "Extend subscribtion to a service ==> user route" })
|
||||||
|
@Put(":userSubscriptionId/subscribe")
|
||||||
|
extendSubscribe(
|
||||||
|
@Param() paramDto: UserSubscriptionIdParamDto,
|
||||||
|
@Body() subscribeDto: ExtendUSerSubscribeServiceDto,
|
||||||
|
@UserDec("id") userId: string,
|
||||||
|
) {
|
||||||
|
return this.subscriptionService.extendSubscribeToPlan(paramDto.userSubscriptionId, subscribeDto, userId);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: "add quick access a service ==> user route" })
|
@ApiOperation({ summary: "add quick access a service ==> user route" })
|
||||||
@Post(":id/add-quick-access")
|
@Post(":id/add-quick-access")
|
||||||
addQuickAccess(@Param() paramDto: ParamDto, @UserDec("id") userId: string) {
|
addQuickAccess(@Param() paramDto: ParamDto, @UserDec("id") userId: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user