update: change the danak services fetch to another route and accept category id "
query for that
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { ApiProperty, PartialType } from "@nestjs/swagger";
|
||||
import { IsNotEmpty, IsUUID } from "class-validator";
|
||||
|
||||
import { CommonMessage } from "../enums/message.enum";
|
||||
@@ -10,6 +10,8 @@ export class ParamDto {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export class OptionalParamDto extends PartialType(ParamDto) {}
|
||||
|
||||
export class ParamNumberIdDto {
|
||||
@IsNotEmpty({ message: CommonMessage.ID_REQUIRED })
|
||||
@ApiProperty({ description: "Id of the entity", example: "20" })
|
||||
|
||||
@@ -165,6 +165,7 @@ export const enum ServiceMessage {
|
||||
REVIEW_REJECTED = "نظر با موفقیت رد شد",
|
||||
IS_ACTIVE_SHOULD_BE_1_0 = "وضعیت سرویس باید یکی از مقادیر ۰ و ۱ باشد",
|
||||
IS_SUGGEST_SHOULD_BE_1_0 = "وضعیت پیشنهادی بودن سرویس باید یکی از مقادیر ۰ و ۱ باشد",
|
||||
REVIEW_STATUS_REQUIRED = "وضعیت نظر سرویس مورد نیاز است",
|
||||
}
|
||||
|
||||
export const enum AnnouncementMessage {
|
||||
@@ -560,3 +561,7 @@ export const enum UserQuickAccessMessage {
|
||||
QUICK_ACCESS_LIMIT_REACHED = "حداکثر تعداد دسترسی سریع برای این کاربر ایجاد شده است",
|
||||
QUICK_ACCESS_EXIST = "این دسترسی سریع قبلا ایجاد شده است",
|
||||
}
|
||||
|
||||
export const enum SmsMessage {
|
||||
SEND_SMS_ERROR = "خطا در ارسال پیامک",
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ApiPropertyOptional } from "@nestjs/swagger";
|
||||
import { ApiPropertyOptional, PickType } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsIn, IsOptional, IsString } from "class-validator";
|
||||
import { IsIn, IsOptional, IsString, IsUUID } from "class-validator";
|
||||
|
||||
import { PaginationDto } from "../../../common/DTO/pagination.dto";
|
||||
import { CategoryMessage, ServiceMessage } from "../../../common/enums/message.enum";
|
||||
|
||||
export class DanakServicesSearchQueryDto extends PaginationDto {
|
||||
@IsOptional()
|
||||
@IsString({ message: CategoryMessage.CAT_ID_SHOULD_BE_UUID })
|
||||
@IsUUID(4, { message: CategoryMessage.CAT_ID_SHOULD_BE_UUID })
|
||||
@ApiPropertyOptional({ description: "Category id", example: "8b1e8b1e-8b1e-8b1e-8b1e-8b1e8b1e8b1e" })
|
||||
categoryId?: string;
|
||||
|
||||
@@ -28,3 +28,5 @@ export class DanakServicesSearchQueryDto extends PaginationDto {
|
||||
@ApiPropertyOptional({ description: "is danak suggest this service", example: 1 })
|
||||
isDanakSuggest?: number;
|
||||
}
|
||||
|
||||
export class DanakServicesQueryDto extends PickType(DanakServicesSearchQueryDto, ["limit", "page", "categoryId"] as const) {}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsEnum, IsNotEmpty } from "class-validator";
|
||||
|
||||
import { ParamDto } from "../../../common/DTO/param.dto";
|
||||
import { ServiceMessage } from "../../../common/enums/message.enum";
|
||||
import { ReviewStatus } from "../enums/review-status.enum";
|
||||
|
||||
export class UpdateReviewStatusDto extends ParamDto {
|
||||
@IsNotEmpty({ message: ServiceMessage.REVIEW_STATUS_REQUIRED })
|
||||
@IsEnum(ReviewStatus)
|
||||
@ApiProperty({ enum: ReviewStatus, example: ReviewStatus.APPROVED, description: "Review status" })
|
||||
status: ReviewStatus;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Body, Controller, Get, HttpCode, HttpStatus, Param, Post, Query } from "@nestjs/common";
|
||||
import { Body, Controller, Get, HttpCode, HttpStatus, Param, Patch, Post, Query } from "@nestjs/common";
|
||||
import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||
|
||||
import { AddReviewDto } from "./DTO/add-review.dto";
|
||||
@@ -6,7 +6,8 @@ import { CategoryListSearchQueryDto, CategorySearchQueryDto } from "./DTO/catego
|
||||
import { CreateCategoryDto } from "./DTO/create-category.dto";
|
||||
import { CreateServiceDto } from "./DTO/create-service.dto";
|
||||
import { DanakServiceReviewQueryDto } from "./DTO/danak-service-review-query.dto";
|
||||
import { DanakServicesSearchQueryDto } from "./DTO/danak-services-search-query.dto";
|
||||
import { DanakServicesQueryDto, DanakServicesSearchQueryDto } from "./DTO/danak-services-search-query.dto";
|
||||
import { UpdateReviewStatusDto } from "./DTO/update-review-status.dto";
|
||||
import { DanakServicesService } from "./providers/danak-services.service";
|
||||
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||
import { Pagination } from "../../common/decorators/pagination.decorator";
|
||||
@@ -53,12 +54,12 @@ export class DanakServicesController {
|
||||
return this.danakServicesService.getCategoriesUserSide();
|
||||
}
|
||||
|
||||
@AuthGuards()
|
||||
@ApiOperation({ summary: "get category services with category id" })
|
||||
@Get("categories/:id/services")
|
||||
getCategoryServices(@Param() paramDto: ParamDto) {
|
||||
return this.danakServicesService.getCategoryServices(paramDto.id);
|
||||
}
|
||||
// @AuthGuards()
|
||||
// @ApiOperation({ summary: "get category services with category id" })
|
||||
// @Get("categories/:id/services")
|
||||
// getCategoryServices(@Param() paramDto: ParamDto) {
|
||||
// return this.danakServicesService.getCategoryServices(paramDto.id);
|
||||
// }
|
||||
|
||||
@AuthGuards()
|
||||
@PermissionsDec(PermissionEnum.SERVICES)
|
||||
@@ -85,6 +86,13 @@ export class DanakServicesController {
|
||||
return this.danakServicesService.getServicesList(queryDto);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "get all danak services for user side" })
|
||||
@AuthGuards()
|
||||
@Get("public")
|
||||
getServicesForUser(@Query() queryDto: DanakServicesQueryDto) {
|
||||
return this.danakServicesService.getServicesListForUser(queryDto);
|
||||
}
|
||||
|
||||
@AuthGuards()
|
||||
@PermissionsDec(PermissionEnum.SERVICES)
|
||||
@ApiOperation({ summary: "toggle status of danak service => admin route" })
|
||||
@@ -124,6 +132,14 @@ export class DanakServicesController {
|
||||
return this.danakServicesService.getDanakServiceReviews(queryDto);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "update danak service review status ==> admin route" })
|
||||
@AuthGuards()
|
||||
@PermissionsDec(PermissionEnum.SERVICES)
|
||||
@Patch("reviews/:id/:status")
|
||||
updateDanakServiceReviewStatus(@Param() updateParamDto: UpdateReviewStatusDto) {
|
||||
return this.danakServicesService.updateDanakServiceReviewStatus(updateParamDto);
|
||||
}
|
||||
|
||||
// @AuthGuards()
|
||||
//
|
||||
// @ApiOperation({ summary: "get all user purchased danak services" })
|
||||
|
||||
@@ -10,7 +10,8 @@ import { CategoryListSearchQueryDto, CategorySearchQueryDto } from "../DTO/categ
|
||||
import { CreateCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateServiceDto } from "../DTO/create-service.dto";
|
||||
import { DanakServiceReviewQueryDto } from "../DTO/danak-service-review-query.dto";
|
||||
import { DanakServicesSearchQueryDto } from "../DTO/danak-services-search-query.dto";
|
||||
import { DanakServicesQueryDto, DanakServicesSearchQueryDto } from "../DTO/danak-services-search-query.dto";
|
||||
import { UpdateReviewStatusDto } from "../DTO/update-review-status.dto";
|
||||
import { DanakServiceCategory } from "../entities/danak-service-category.entity";
|
||||
import { ReviewStatus } from "../enums/review-status.enum";
|
||||
import { DanakServicesCategoryRepository } from "../repositories/danak-services-category.repository";
|
||||
@@ -96,7 +97,7 @@ export class DanakServicesService {
|
||||
}
|
||||
/******************************************** */
|
||||
|
||||
async getCategoryServices(categoryId: string) {
|
||||
async getCategoryServices(categoryId?: string) {
|
||||
const category = await this.danakServicesCategoryRepository.findOne({
|
||||
where: { id: categoryId, isActive: true, danakServices: { isActive: true } },
|
||||
relations: {
|
||||
@@ -164,6 +165,11 @@ export class DanakServicesService {
|
||||
async getServicesList(queryDto: DanakServicesSearchQueryDto) {
|
||||
return this.danakServicesRepository.getServicesForAdmin(queryDto);
|
||||
}
|
||||
/******************************************** */
|
||||
|
||||
async getServicesListForUser(queryDto: DanakServicesQueryDto) {
|
||||
return this.danakServicesRepository.getServicesForUser(queryDto);
|
||||
}
|
||||
|
||||
/******************************************** */
|
||||
|
||||
@@ -322,6 +328,14 @@ export class DanakServicesService {
|
||||
|
||||
/******************************************** */
|
||||
|
||||
async updateDanakServiceReviewStatus(updateParamDto: UpdateReviewStatusDto) {
|
||||
if (updateParamDto.status === ReviewStatus.APPROVED) {
|
||||
return await this.approveReview(updateParamDto.id);
|
||||
} else {
|
||||
return await this.rejectReview(updateParamDto.id);
|
||||
}
|
||||
}
|
||||
|
||||
async approveReview(reviewId: string) {
|
||||
const review = await this.danakServiceReviewRepository.findOneBy({ id: reviewId });
|
||||
if (!review) throw new BadRequestException(ServiceMessage.REVIEW_NOT_EXIST);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { Brackets, Repository } from "typeorm";
|
||||
|
||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||
import { DanakServicesSearchQueryDto } from "../DTO/danak-services-search-query.dto";
|
||||
import { DanakServicesQueryDto, DanakServicesSearchQueryDto } from "../DTO/danak-services-search-query.dto";
|
||||
import { DanakService } from "../entities/danak-service.entity";
|
||||
|
||||
@Injectable()
|
||||
@@ -19,7 +19,7 @@ export class DanakServicesRepository extends Repository<DanakService> {
|
||||
async findServiceById(id: string): Promise<DanakService | null> {
|
||||
return this.findOneBy({ id });
|
||||
}
|
||||
|
||||
//+********************
|
||||
async getServicesForAdmin(queryDto: DanakServicesSearchQueryDto) {
|
||||
const { limit, skip } = PaginationUtils(queryDto);
|
||||
|
||||
@@ -54,6 +54,31 @@ export class DanakServicesRepository extends Repository<DanakService> {
|
||||
}
|
||||
const [services, count] = await queryBuilder.getManyAndCount();
|
||||
|
||||
return {
|
||||
services,
|
||||
count,
|
||||
};
|
||||
}
|
||||
//+********************
|
||||
async getServicesForUser(queryDto: DanakServicesQueryDto) {
|
||||
const { limit, skip } = PaginationUtils(queryDto);
|
||||
|
||||
const queryBuilder = this.createQueryBuilder("service");
|
||||
queryBuilder
|
||||
.innerJoin("service.subscriptionPlans", "subscriptionPlans", "subscriptionPlans.isActive = :isActive", { isActive: true })
|
||||
.leftJoinAndSelect("service.category", "category")
|
||||
.where("service.isActive = :isActive", { isActive: true })
|
||||
.andWhere("service.isDanakSuggest = :isDanakSuggest", { isDanakSuggest: true })
|
||||
.orderBy("service.createdAt", "DESC")
|
||||
.skip(skip)
|
||||
.take(limit);
|
||||
|
||||
if (queryDto.categoryId) {
|
||||
queryBuilder.andWhere("service.categoryId = :categoryId", { categoryId: queryDto.categoryId });
|
||||
}
|
||||
|
||||
const [services, count] = await queryBuilder.getManyAndCount();
|
||||
|
||||
return {
|
||||
services,
|
||||
count,
|
||||
|
||||
@@ -199,6 +199,7 @@ export class InvoicesService {
|
||||
dueDate,
|
||||
items: invoiceItems,
|
||||
});
|
||||
await queryRunner.manager.save(Invoice, invoice);
|
||||
|
||||
await this.notificationsService.createInvoiceCreationNotification(
|
||||
user.id,
|
||||
@@ -214,7 +215,6 @@ export class InvoicesService {
|
||||
queryRunner,
|
||||
);
|
||||
//
|
||||
await queryRunner.manager.save(Invoice, invoice);
|
||||
return invoice;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Inject, Injectable, InternalServerErrorException, Logger } from "@nestj
|
||||
import { AxiosError } from "axios";
|
||||
import { catchError, firstValueFrom } from "rxjs";
|
||||
|
||||
import { SmsMessage } from "../../../common/enums/message.enum";
|
||||
import { ISmsConfigs } from "../../../configs/sms.config";
|
||||
import { SMS_CONFIG } from "../constants";
|
||||
import { ISmsGetLineResponse, ISmsVerifyBody, ISmsVerifyResponse } from "../interfaces/ISms";
|
||||
@@ -46,6 +47,7 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException(SmsMessage.SEND_SMS_ERROR);
|
||||
}
|
||||
}
|
||||
//************************************************* */
|
||||
@@ -81,7 +83,7 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException("error in sending sms");
|
||||
throw new InternalServerErrorException(SmsMessage.SEND_SMS_ERROR);
|
||||
}
|
||||
}
|
||||
//************************************************* */
|
||||
@@ -109,7 +111,6 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
// throw new InternalServerErrorException("error in sending sms");
|
||||
}
|
||||
}
|
||||
//************************************************* */
|
||||
@@ -135,6 +136,8 @@ export class SmsService {
|
||||
})
|
||||
.pipe(
|
||||
catchError((err: AxiosError) => {
|
||||
console.error(err);
|
||||
|
||||
this.logger.error("error in sending invoice created sms", err);
|
||||
throw new InternalServerErrorException("error in sending invoice created sms");
|
||||
}),
|
||||
@@ -143,7 +146,6 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException("error in sending sms");
|
||||
}
|
||||
}
|
||||
//************************************************* */
|
||||
@@ -174,7 +176,6 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException("error in sending sms");
|
||||
}
|
||||
}
|
||||
//************************************************* */
|
||||
@@ -206,7 +207,6 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException("error in sending sms");
|
||||
}
|
||||
}
|
||||
//************************************************* */
|
||||
@@ -239,7 +239,6 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException("error in sending sms");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +271,6 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException("error in sending sms");
|
||||
}
|
||||
}
|
||||
//************************************************* */
|
||||
@@ -303,7 +301,6 @@ export class SmsService {
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error("error in sending sms", error);
|
||||
throw new InternalServerErrorException("error in sending sms");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user