From 14373bb66525bd1520478d21b74ca8591eeb5114 Mon Sep 17 00:00:00 2001 From: mahyargdz Date: Mon, 17 Feb 2025 15:56:34 +0330 Subject: [PATCH] chore: add get user subscriptions route --- src/common/enums/message.enum.ts | 1 + .../DTO/search-user-subs-query.dto.ts | 11 +++++ .../providers/subscriptions.service.ts | 46 ++++++++++++++++++- .../subscriptions/subscriptions.controller.ts | 15 ++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/modules/subscriptions/DTO/search-user-subs-query.dto.ts diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index ee5f54a..3edc7c4 100644 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -317,6 +317,7 @@ export const enum SubscriptionMessage { SUBS_MIN_SIZE = "حداقل یک اشتراک باید انتخاب شود", SUBS_REQUIRED = "اشتراک مورد نیاز است", SUBS_SHOULD_BE_ARRAY = "اشتراک باید یک آرایه باشد", + USER_SUBS_NOT_FOUND = "اشتراک کاربر یافت نشد", } export const enum InvoiceMessage { diff --git a/src/modules/subscriptions/DTO/search-user-subs-query.dto.ts b/src/modules/subscriptions/DTO/search-user-subs-query.dto.ts new file mode 100644 index 0000000..db48999 --- /dev/null +++ b/src/modules/subscriptions/DTO/search-user-subs-query.dto.ts @@ -0,0 +1,11 @@ +import { ApiPropertyOptional } from "@nestjs/swagger"; +import { IsOptional, IsString } from "class-validator"; + +import { SubscriptionMessage } from "../../../common/enums/message.enum"; + +export class SearchUserSubsQueryDto { + @IsOptional() + @IsString({ message: SubscriptionMessage.SEARCH_QUERY_STRING }) + @ApiPropertyOptional({ description: "Search query", example: "search query" }) + q?: string; +} diff --git a/src/modules/subscriptions/providers/subscriptions.service.ts b/src/modules/subscriptions/providers/subscriptions.service.ts index 5b56999..4f00a12 100644 --- a/src/modules/subscriptions/providers/subscriptions.service.ts +++ b/src/modules/subscriptions/providers/subscriptions.service.ts @@ -11,6 +11,7 @@ import { PaginationUtils } from "../../utils/providers/pagination.utils"; import { Wallet } from "../../wallets/entities/wallet.entity"; import { WalletsService } from "../../wallets/providers/wallets.service"; import { AddSubscriptionsToServiceDto } from "../DTO/create-subscription.dto"; +import { SearchUserSubsQueryDto } from "../DTO/search-user-subs-query.dto"; import { ServiceSubsQueryDto } from "../DTO/service-subs-query.dto"; import { SubscribeServiceDto } from "../DTO/subscribe-service.dto"; import { UpdateSubscriptionPlanDto } from "../DTO/update-subscription.dto"; @@ -18,13 +19,13 @@ import { SubscriptionPlan } from "../entities/subscription.entity"; import { UserSubscription } from "../entities/user-subscription.entity"; import { SubscriptionStatus } from "../enums/subscription-status.enum"; import { SubscriptionsPlanRepository } from "../repositories/subscriptions.repository"; -// import { UserSubscriptionsRepository } from "../repositories/user-subscriptions.repository"; +import { UserSubscriptionsRepository } from "../repositories/user-subscriptions.repository"; @Injectable() export class SubscriptionsService { constructor( private readonly subscriptionsPlanRepository: SubscriptionsPlanRepository, - // private readonly userSubscriptionsRepository: UserSubscriptionsRepository, + private readonly userSubscriptionsRepository: UserSubscriptionsRepository, private readonly invoicesService: InvoicesService, private readonly usersService: UsersService, private readonly walletsService: WalletsService, @@ -58,6 +59,47 @@ export class SubscriptionsService { subscriptions: createdSubscriptions, }; } + + //************************************ */ + async getUserSubscriptions(userId: string, queryDto: SearchUserSubsQueryDto) { + const queryBuilder = this.userSubscriptionsRepository + .createQueryBuilder("userSubscription") + .leftJoinAndSelect("userSubscription.plan", "plan") + .leftJoinAndSelect("plan.service", "service") + .where("userSubscription.user.id = :userId", { userId }); + + if (queryDto.q) { + queryBuilder.andWhere("(service.name ILIKE :query OR service.title ILIKE :query OR service.description ILIKE :query)", { + query: `%${queryDto.q}%`, + }); + } + + const subscriptions = await queryBuilder.getMany(); + + return { + subscriptions, + }; + } + //************************************ */ + + async getUserSubscriptionById(userSubId: string, userId: string) { + const userSubscription = await this.userSubscriptionsRepository.findOne({ + where: { id: userSubId, user: { id: userId } }, + relations: { + plan: { + service: { + images: true, + subscriptionPlans: true, + }, + }, + }, + }); + if (!userSubscription) throw new BadRequestException(SubscriptionMessage.USER_SUBS_NOT_FOUND); + + return { + userSubscription, + }; + } //************************************ */ async updateSubscriptionPlan(id: string, updateDto: UpdateSubscriptionPlanDto) { if (updateDto.serviceId) { diff --git a/src/modules/subscriptions/subscriptions.controller.ts b/src/modules/subscriptions/subscriptions.controller.ts index afbcf00..8d644f4 100644 --- a/src/modules/subscriptions/subscriptions.controller.ts +++ b/src/modules/subscriptions/subscriptions.controller.ts @@ -2,6 +2,7 @@ import { Body, Controller, Get, Param, Patch, Post, Query } from "@nestjs/common import { ApiOperation } from "@nestjs/swagger"; import { AddSubscriptionsToServiceDto } from "./DTO/create-subscription.dto"; +import { SearchUserSubsQueryDto } from "./DTO/search-user-subs-query.dto"; import { ServiceIdParamDto } from "./DTO/service-id.param.dto"; import { ServiceSubsQueryDto } from "./DTO/service-subs-query.dto"; import { SubscribeServiceDto } from "./DTO/subscribe-service.dto"; @@ -33,6 +34,20 @@ export class SubscriptionsController { return this.subscriptionService.getServiceSubscriptions(paramDto.serviceId, queryDto); } + @ApiOperation({ summary: "get all user subscriptions ==> user route" }) + @AuthGuards() + @Get("user") + getUserSubscriptions(@UserDec("id") userId: string, @Query() queryDto: SearchUserSubsQueryDto) { + return this.subscriptionService.getUserSubscriptions(userId, queryDto); + } + + @ApiOperation({ summary: "get a user subscription by id ==> user route" }) + @AuthGuards() + @Get("user/:id") + getUserSubscriptionById(@Param() paramDto: ParamDto, @UserDec("id") userId: string) { + return this.subscriptionService.getUserSubscriptionById(paramDto.id, userId); + } + @ApiOperation({ summary: "toggle status of service subs" }) @AuthGuards() @PermissionsDec(PermissionEnum.SERVICES)