chore: quick access

This commit is contained in:
Matin
2025-02-25 10:38:32 +03:30
parent 37b8e00445
commit 35a61ce90e
9 changed files with 160 additions and 5 deletions
+6
View File
@@ -503,3 +503,9 @@ export const enum RealUserMessage {
export const enum LegalUserMessage {
LEGAL_DATA_EXIST = "اطلاعات حقوقی این کاربر وجود دارد",
}
export const enum UserQuickAccessMessage {
USER_SUBS_NOT_FOUND = "کاربر اشتراک فعالی برای این سرویس ندارد",
QUICK_ACCESS_LIMIT_REACHED = "حداکثر تعداد دسترسی سریع برای این کاربر ایجاد شده است",
QUICK_ACCESS_EXIST = "این دسترسی سریع قبلا ایجاد شده است",
}
@@ -7,6 +7,7 @@ import { BaseEntity } from "../../../common/entities/base.entity";
import { Ads } from "../../ads/entities/ads.entity";
import { Announcement } from "../../announcements/entities/announcement.entity";
import { SubscriptionPlan } from "../../subscriptions/entities/subscription.entity";
import { UserQuickAccess } from "../../subscriptions/entities/user-quick-access.entity";
import { Ticket } from "../../tickets/entities/ticket.entity";
import { ServicesLanguage } from "../enums/services-language.enum";
@@ -76,6 +77,8 @@ export class DanakService extends BaseEntity {
@OneToMany(() => DanakServiceReview, (danakServiceReview) => danakServiceReview.service)
reviews: DanakServiceReview[];
@OneToMany(() => UserQuickAccess, (quickAccess) => quickAccess.service)
quickAccess: UserQuickAccess[];
// @ManyToMany(() => Discount, (discount) => discount.services, { nullable: true })
// discounts?: Discount[];
}
@@ -0,0 +1,18 @@
import { Column, Entity, ManyToOne, Unique } from "typeorm";
import { BaseEntity } from "../../../common/entities/base.entity";
import { DanakService } from "../../danak-services/entities/danak-service.entity";
import { User } from "../../users/entities/user.entity";
@Entity()
@Unique(["user", "service"])
export class UserQuickAccess extends BaseEntity {
@ManyToOne(() => User, (user) => user.quickAccesses, { nullable: false, onDelete: "SET NULL" })
user: User;
@ManyToOne(() => DanakService, { nullable: false, onDelete: "SET NULL" })
service: DanakService;
@Column({ type: "boolean", default: true })
isActive: boolean;
}
@@ -419,4 +419,19 @@ export class SubscriptionsService {
const growthRate = ((currentYearCount - lastYearCount) / lastYearCount) * 100;
return Math.round(growthRate * 100) / 100;
}
/********************************* */
async activeUserSubscription(userId: string, serviceId: string) {
const activeSubscription = await this.userSubscriptionsRepository.findOne({
where: {
user: { id: userId },
plan: { service: { id: serviceId } },
status: SubscriptionStatus.ACTIVE,
},
relations: ["plan", "plan.service"],
});
console.log(activeSubscription);
return activeSubscription;
}
}
@@ -0,0 +1,63 @@
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
import { SubscriptionsService } from "./subscriptions.service";
import { CommonMessage, ServiceMessage, UserMessage, UserQuickAccessMessage } from "../../../common/enums/message.enum";
import { DanakServicesService } from "../../danak-services/providers/danak-services.service";
import { UsersService } from "../../users/providers/users.service";
import { UserQuickAccessRepository } from "../repositories/users-quick-access.repository";
@Injectable()
export class UserQuickAccessService {
constructor(
private readonly quickAccessRepository: UserQuickAccessRepository,
private readonly usersService: UsersService,
private readonly danakServicesService: DanakServicesService,
private readonly subscriptionService: SubscriptionsService,
) {}
async addQuickAccess(userId: string, serviceId: string) {
const { user } = await this.usersService.findOneById(userId);
if (!user) throw new NotFoundException(UserMessage.USER_NOT_FOUND);
const service = await this.danakServicesService.findServiceById(serviceId);
if (!service) throw new NotFoundException(ServiceMessage.SERVICE_NOT_EXIST);
const activeSubscription = await this.subscriptionService.activeUserSubscription(user.id, service.id);
if (!activeSubscription) {
throw new BadRequestException(UserQuickAccessMessage.USER_SUBS_NOT_FOUND);
}
const userQuickAccesses = await this.quickAccessRepository.count({ where: { user: { id: userId }, isActive: true } });
if (userQuickAccesses >= 4) {
throw new BadRequestException(UserQuickAccessMessage.QUICK_ACCESS_LIMIT_REACHED);
}
const existQuickAccess = await this.quickAccessRepository.findOne({ where: { user: { id: user.id }, service: { id: service.id } } });
console.log(existQuickAccess);
if (existQuickAccess) throw new BadRequestException(UserQuickAccessMessage.QUICK_ACCESS_EXIST);
const quickAccess = this.quickAccessRepository.create({ user, service });
await this.quickAccessRepository.save(quickAccess);
return {
message: CommonMessage.CREATED,
quickAccess,
};
}
async removeQuickAccess(userId: string, serviceId: string) {
await this.quickAccessRepository.delete({ user: { id: userId }, service: { id: serviceId } });
return {
message: CommonMessage.DELETED,
};
}
async getUserQuickAccess(userId: string) {
const quickAccesses = await this.quickAccessRepository.find({
where: { user: { id: userId }, isActive: true },
relations: ["service"],
});
return { quickAccesses };
}
}
@@ -0,0 +1,12 @@
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { UserQuickAccess } from "../entities/user-quick-access.entity";
@Injectable()
export class UserQuickAccessRepository extends Repository<UserQuickAccess> {
constructor(@InjectRepository(UserQuickAccess) userQuickAccessRepository: Repository<UserQuickAccess>) {
super(userQuickAccessRepository.target, userQuickAccessRepository.manager, userQuickAccessRepository.queryRunner);
}
}
@@ -1,4 +1,4 @@
import { Body, Controller, Get, Param, Patch, Post, Query } from "@nestjs/common";
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from "@nestjs/common";
import { ApiOperation } from "@nestjs/swagger";
import { AddSubscriptionsToServiceDto } from "./DTO/create-subscription.dto";
@@ -8,6 +8,7 @@ import { ServiceSubsQueryDto } from "./DTO/service-subs-query.dto";
import { SubscribeServiceDto } from "./DTO/subscribe-service.dto";
import { UpdateSubscriptionPlanDto } from "./DTO/update-subscription.dto";
import { SubscriptionsService } from "./providers/subscriptions.service";
import { UserQuickAccessService } from "./providers/users-quick-access.service";
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
import { PermissionsDec } from "../../common/decorators/permission.decorator";
import { UserDec } from "../../common/decorators/user.decorator";
@@ -16,7 +17,10 @@ import { PermissionEnum } from "../users/enums/permission.enum";
@Controller("subscriptions")
export class SubscriptionsController {
constructor(private readonly subscriptionService: SubscriptionsService) {}
constructor(
private readonly subscriptionService: SubscriptionsService,
private readonly userQuickAccessService: UserQuickAccessService,
) {}
@ApiOperation({ summary: "Create a subscription plan" })
@AuthGuards()
@@ -79,4 +83,25 @@ export class SubscriptionsController {
subscribe(@Param() paramDto: ServiceIdParamDto, @Body() subscribeDto: SubscribeServiceDto, @UserDec("id") userId: string) {
return this.subscriptionService.subscribeToPlan(paramDto.serviceId, subscribeDto, userId);
}
@ApiOperation({ summary: "add quick access a service ==> user route" })
@AuthGuards()
@Post(":serviceId/add-quick-access")
addQuickAccess(@Param() paramDto: ServiceIdParamDto, @UserDec("id") userId: string) {
return this.userQuickAccessService.addQuickAccess(userId, paramDto.serviceId);
}
@ApiOperation({ summary: "get quick access a service ==> user route" })
@AuthGuards()
@Get("quick-access")
getQuickAccess(@UserDec("id") userId: string) {
return this.userQuickAccessService.getUserQuickAccess(userId);
}
@ApiOperation({ summary: "remove quick access a service ==> user route" })
@AuthGuards()
@Delete(":serviceId/remove-quick-access")
removeQuickAccess(@Param() paramDto: ServiceIdParamDto, @UserDec("id") userId: string) {
return this.userQuickAccessService.removeQuickAccess(userId, paramDto.serviceId);
}
}
@@ -11,17 +11,26 @@ import { DanakServicesModule } from "../danak-services/danak-services.module";
import { InvoicesModule } from "../invoices/invoices.module";
import { UsersModule } from "../users/users.module";
import { WalletsModule } from "../wallets/wallets.module";
import { UserQuickAccess } from "./entities/user-quick-access.entity";
import { UserQuickAccessService } from "./providers/users-quick-access.service";
import { UserQuickAccessRepository } from "./repositories/users-quick-access.repository";
@Module({
imports: [
TypeOrmModule.forFeature([SubscriptionPlan, UserSubscription]),
TypeOrmModule.forFeature([SubscriptionPlan, UserSubscription, UserQuickAccess]),
DanakServicesModule,
UsersModule,
WalletsModule,
InvoicesModule,
],
providers: [SubscriptionsService, SubscriptionsPlanRepository, UserSubscriptionsRepository],
providers: [
SubscriptionsService,
SubscriptionsPlanRepository,
UserSubscriptionsRepository,
UserQuickAccessRepository,
UserQuickAccessService,
],
controllers: [SubscriptionsController],
exports: [SubscriptionsService, TypeOrmModule, SubscriptionsPlanRepository],
exports: [SubscriptionsService, TypeOrmModule, SubscriptionsPlanRepository, UserSubscriptionsRepository],
})
export class SubscriptionsModule {}
@@ -19,6 +19,7 @@ import { LearningProgress } from "../../learnings/entities/learning-progress.ent
import { Notification } from "../../notifications/entities/notification.entity";
import { Payment } from "../../payments/entities/payment.entity";
import { UserSetting } from "../../settings/entities/user-setting.entity";
import { UserQuickAccess } from "../../subscriptions/entities/user-quick-access.entity";
import { UserSubscription } from "../../subscriptions/entities/user-subscription.entity";
import { TicketMessage } from "../../tickets/entities/ticket-message.entity";
import { Ticket } from "../../tickets/entities/ticket.entity";
@@ -131,6 +132,9 @@ export class User extends BaseEntity {
@ManyToMany(() => Announcement, (announcement) => announcement.users)
announcements: Announcement[];
@OneToMany(() => UserQuickAccess, (quickAccess) => quickAccess.user)
quickAccesses: UserQuickAccess[];
}
// @ManyToMany(() => DanakService, (danakService) => danakService.users)