refactor: the ticket service

This commit is contained in:
mahyargdz
2025-04-21 16:24:54 +03:30
parent 03d8c431fa
commit 368ab0b40a
4 changed files with 100 additions and 84 deletions
+3 -3
View File
@@ -7,13 +7,13 @@ import { ConfigModule } from "@nestjs/config";
import { ThrottlerModule } from "@nestjs/throttler";
import { TypeOrmModule } from "@nestjs/typeorm";
import { MailerModule } from "@nestjs-modules/mailer";
// import { TelegrafModule } from "nestjs-telegraf";
import { TelegrafModule } from "nestjs-telegraf";
import { bullMqConfig } from "./configs/bullmq.config";
import { cacheConfig } from "./configs/cache.config";
import { mailerConfig } from "./configs/mailer.config";
import { rateLimitConfig } from "./configs/rateLimit.config";
// import { telegrafConfig } from "./configs/telegraf.config";
import { telegrafConfig } from "./configs/telegraf.config";
import { databaseConfigs } from "./configs/typeorm.config";
import { HTTPLogger } from "./core/middlewares/logger.middleware";
import { AddressModule } from "./modules/address/address.module";
@@ -42,7 +42,7 @@ import { WalletsModule } from "./modules/wallets/wallets.module";
@Module({
imports: [
// TelegrafModule.forRootAsync(telegrafConfig()),
TelegrafModule.forRootAsync(telegrafConfig()),
MailerModule.forRootAsync(mailerConfig()),
BullModule.forRootAsync(bullMqConfig()),
ThrottlerModule.forRootAsync(rateLimitConfig()),
@@ -8,7 +8,6 @@ import { DanakService } from "../../danak-services/entities/danak-service.entity
import { NotificationsService } from "../../notifications/providers/notifications.service";
import { User } from "../../users/entities/user.entity";
import { UsersService } from "../../users/providers/users.service";
import { PaginationUtils } from "../../utils/providers/pagination.utils";
import { CreateTicketCategoryDto } from "../DTO/create-ticket-category.dto";
import { CreateTicketMessageDto } from "../DTO/create-ticket-message.dto";
import { CreateTicketDto } from "../DTO/create-ticket.dto";
@@ -46,26 +45,7 @@ export class TicketsService {
//******************************** */
async getCategoriesList(queryDto: SearchTicketCategoryDto) {
const { limit, skip } = PaginationUtils(queryDto);
const queryBuilder = this.ticketsCategoryRepository
.createQueryBuilder("category")
// .leftJoinAndSelect("category.group", "group")
// .addSelect(["group.id", "group.name"])
.leftJoin("category.group", "group")
.addSelect(["group.id", "group.name"])
// .leftJoinAndSelect("group.users", "users")
.loadRelationCountAndMap("category.ticketsCount", "category.tickets")
.loadRelationCountAndMap("category.usersCount", "group.users");
if (queryDto.isActive !== undefined) {
queryBuilder.andWhere("category.isActive = :isActive", { isActive: queryDto.isActive === 1 });
}
if (queryDto.q) {
queryBuilder.where("category.title ILIKE :q", { q: `%${queryDto.q}%` });
}
const [categories, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount();
const [categories, count] = await this.ticketsCategoryRepository.findCategoriesList(queryDto);
return { categories, count, paginate: true };
}
@@ -191,73 +171,15 @@ export class TicketsService {
//******************************** */
async getTickets(queryDto: SearchTicketQueryDto, userId: string) {
const { limit, skip } = PaginationUtils(queryDto);
const queryBuilder = this.ticketsRepository
.createQueryBuilder("ticket")
.leftJoinAndSelect("ticket.category", "category")
.leftJoinAndSelect("ticket.danakService", "danakService")
.where("ticket.user.id = :userId", { userId })
.orderBy("ticket.createdAt", "DESC")
.select([
"ticket.id",
"ticket.subject",
"ticket.status",
"ticket.priority",
"ticket.numericId",
"ticket.createdAt",
"ticket.updatedAt",
"category.id",
"category.title",
"danakService.id",
"danakService.name",
])
.skip(skip)
.take(limit);
if (queryDto.status) {
queryBuilder.andWhere("ticket.status = :status", {
status: queryDto.status,
});
} else {
queryBuilder.andWhere("ticket.status != :closedStatus", {
closedStatus: TicketStatus.CLOSED,
});
}
const [tickets, count] = await queryBuilder.getManyAndCount();
const [tickets, count] = await this.ticketsRepository.findTicketsList(queryDto, userId);
return { tickets, count, paginate: true };
}
//******************************** */
async getTicketForAdmin(queryDto: SearchTicketQueryDto, adminId: string) {
const { limit, skip } = PaginationUtils(queryDto);
const isSuperAdmin = await this.usersService.isSuperAdmin(adminId);
const queryBuilder = this.ticketsRepository
.createQueryBuilder("ticket")
.leftJoinAndSelect("ticket.category", "category")
.leftJoinAndSelect("ticket.user", "user")
.leftJoinAndSelect("ticket.assignedTo", "assignedTo")
.leftJoinAndSelect("ticket.danakService", "danakService")
.orderBy("ticket.createdAt", "DESC");
if (!isSuperAdmin) {
queryBuilder.andWhere("ticket.assignedToId = :adminId", { adminId });
}
if (queryDto.status) {
queryBuilder.andWhere("ticket.status = :status", {
status: queryDto.status,
});
}
if (queryDto.userId) {
queryBuilder.andWhere("user.id = :userId", { userId: queryDto.userId });
}
const [tickets, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount();
const [tickets, count] = await this.ticketsRepository.findTicketsListForAdmin(queryDto, adminId, isSuperAdmin);
return { tickets, count, paginate: true };
}
@@ -2,6 +2,8 @@ import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { PaginationUtils } from "../../utils/providers/pagination.utils";
import { SearchTicketCategoryDto } from "../DTO/search-ticket-category.dto";
import { TicketCategory } from "../entities/ticket-category.entity";
@Injectable()
@@ -17,4 +19,27 @@ export class TicketCategoryRepository extends Repository<TicketCategory> {
async findCategoryById(id: string): Promise<TicketCategory | null> {
return this.findOneBy({ id });
}
//******************************** */
async findCategoriesList(queryDto: SearchTicketCategoryDto) {
const { limit, skip } = PaginationUtils(queryDto);
const queryBuilder = this.createQueryBuilder("category")
// .leftJoinAndSelect("category.group", "group")
// .addSelect(["group.id", "group.name"])
.leftJoin("category.group", "group")
.addSelect(["group.id", "group.name"])
// .leftJoinAndSelect("group.users", "users")
.loadRelationCountAndMap("category.ticketsCount", "category.tickets")
.loadRelationCountAndMap("category.usersCount", "group.users");
if (queryDto.isActive !== undefined) {
queryBuilder.andWhere("category.isActive = :isActive", { isActive: queryDto.isActive === 1 });
}
if (queryDto.q) {
queryBuilder.where("category.title ILIKE :q", { q: `%${queryDto.q}%` });
}
return queryBuilder.skip(skip).take(limit).getManyAndCount();
}
}
@@ -2,7 +2,10 @@ import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { PaginationUtils } from "../../utils/providers/pagination.utils";
import { SearchTicketQueryDto } from "../DTO/search-ticket-query.dto";
import { Ticket } from "../entities/ticket.entity";
import { TicketStatus } from "../enums/ticket-status.enum";
@Injectable()
export class TicketsRepository extends Repository<Ticket> {
@@ -47,4 +50,70 @@ export class TicketsRepository extends Repository<Ticket> {
},
});
}
//******************************** */
async findTicketsList(queryDto: SearchTicketQueryDto, userId: string) {
const { limit, skip } = PaginationUtils(queryDto);
const queryBuilder = this.createQueryBuilder("ticket")
.leftJoinAndSelect("ticket.category", "category")
.leftJoinAndSelect("ticket.danakService", "danakService")
.where("ticket.user.id = :userId", { userId })
.orderBy("ticket.createdAt", "DESC")
.select([
"ticket.id",
"ticket.subject",
"ticket.status",
"ticket.priority",
"ticket.numericId",
"ticket.createdAt",
"ticket.updatedAt",
"category.id",
"category.title",
"danakService.id",
"danakService.name",
])
.skip(skip)
.take(limit);
if (queryDto.status) {
queryBuilder.andWhere("ticket.status = :status", {
status: queryDto.status,
});
} else {
queryBuilder.andWhere("ticket.status != :closedStatus", {
closedStatus: TicketStatus.CLOSED,
});
}
return queryBuilder.getManyAndCount();
}
async findTicketsListForAdmin(queryDto: SearchTicketQueryDto, adminId: string, isSuperAdmin: boolean) {
const { limit, skip } = PaginationUtils(queryDto);
const queryBuilder = this.createQueryBuilder("ticket")
.leftJoinAndSelect("ticket.category", "category")
.leftJoinAndSelect("ticket.user", "user")
.leftJoinAndSelect("ticket.assignedTo", "assignedTo")
.leftJoinAndSelect("ticket.danakService", "danakService")
.orderBy("ticket.createdAt", "DESC");
if (!isSuperAdmin) {
queryBuilder.andWhere("ticket.assignedToId = :adminId", { adminId });
}
if (queryDto.status) {
queryBuilder.andWhere("ticket.status = :status", {
status: queryDto.status,
});
}
if (queryDto.userId) {
queryBuilder.andWhere("user.id = :userId", { userId: queryDto.userId });
}
return queryBuilder.skip(skip).take(limit).getManyAndCount();
}
}