chore: add service review add and get in service page and also approve and reject for admin

This commit is contained in:
mahyargdz
2025-02-17 15:08:22 +03:30
parent 763b6b49d9
commit b7cfaf95b2
12 changed files with 186 additions and 47 deletions
@@ -4,12 +4,15 @@ import { FindOptionsWhere, In, IsNull } from "typeorm";
import { ParamDto } from "../../../common/DTO/param.dto";
import { CategoryMessage, CommonMessage, ServiceMessage } from "../../../common/enums/message.enum";
import { PaginationUtils } from "../../utils/providers/pagination.utils";
import { AddReviewDto } from "../DTO/add-review.dto";
import { CategoryListSearchQueryDto, CategorySearchQueryDto } from "../DTO/category-search-query.dto";
import { CreateCategoryDto } from "../DTO/create-category.dto";
import { CreateServiceDto } from "../DTO/create-service.dto";
import { DanakServicesSearchQueryDto } from "../DTO/danak-services-search-query.dto";
import { DanakServiceCategory } from "../entities/danak-service-category.entity";
import { ReviewStatus } from "../enums/review-status.enum";
import { DanakServicesCategoryRepository } from "../repositories/danak-services-category.repository";
import { DanakServiceReviewRepository } from "../repositories/danak-services-review.repository";
import { DanakServicesRepository } from "../repositories/danak-services.repository";
@Injectable()
@@ -18,6 +21,7 @@ export class DanakServicesService {
constructor(
private readonly danakServicesRepository: DanakServicesRepository,
private readonly danakServicesCategoryRepository: DanakServicesCategoryRepository,
private readonly danakServiceReviewRepository: DanakServiceReviewRepository,
) {}
/******************************************** */
@@ -178,8 +182,28 @@ export class DanakServicesService {
relations: { images: true, subscriptionPlans: true },
});
if (!danakService) throw new BadRequestException(ServiceMessage.SERVICE_NOT_FOUND_BY_ID);
const reviews = await this.danakServiceReviewRepository.find({
where: { service: { id: serviceId }, status: ReviewStatus.APPROVED },
relations: { user: true },
select: {
id: true,
comment: true,
rating: true,
title: true,
createdAt: true,
status: true,
user: {
id: true,
firstName: true,
lastName: true,
profilePic: true,
},
},
});
return {
danakService,
reviews,
};
}
@@ -208,46 +232,45 @@ export class DanakServicesService {
/******************************************** */
// async getDiscountedPrice(serviceId: string) {
// const service = await this.danakServicesRepository.findOne({
// where: {
// id: serviceId,
// },
// relations: ["discount"],
// });
// if (!service) throw new BadRequestException(ServiceMessage.SERVICE_NOT_FOUND_BY_ID);
async addReview(userId: string, serviceId: string, addReviewDto: AddReviewDto) {
const service = await this.findServiceById(serviceId);
// const now = new Date();
const review = this.danakServiceReviewRepository.create({ user: { id: userId }, ...addReviewDto, service });
await this.danakServiceReviewRepository.save(review);
return {
message: ServiceMessage.REVIEW_ADDED,
review,
};
}
// const serviceDiscount = service.discounts.filter(
// (d) => d.type === DiscountType.DIRECT && d.isActive && d.startDate <= now && d.endDate >= now,
// );
/******************************************** */
// const globalDiscounts = await this.discountRepository
// .createQueryBuilder("discount")
// .leftJoin("discount.services", "service")
// .where("discount.type = :discountType", { discountType: DiscountType.DIRECT })
// .andWhere("discount.isActive = true")
// .andWhere("discount.startDate <= :now", { now })
// .andWhere("discount.endDate >= :now", { now })
// .andWhere("service.id IS NULL")
// .getMany();
async approveReview(reviewId: string) {
const review = await this.danakServiceReviewRepository.findOneBy({ id: reviewId });
if (!review) throw new BadRequestException(ServiceMessage.REVIEW_NOT_EXIST);
// const applicableDiscounts = [...serviceDiscount, ...globalDiscounts];
// if (applicableDiscounts.length === 0) return service.;
// let maxDiscountValue = 0;
// for (const discount of applicableDiscounts) {
// let discountValue = 0;
// if (discount.calculationType === DiscountCalculationType.FIXED) {
// discountValue = discount.amount;
// } else if (discount.calculationType === DiscountCalculationType.PERCENTAGE) {
// discountValue = service.price * (discount.amount / 100);
// }
// if (discountValue > maxDiscountValue) {
// maxDiscountValue = discountValue;
// }
// }
// const discountedPrice = service.price - maxDiscountValue;
// return discountedPrice > 0 ? discountedPrice : 0;
// }
review.status = ReviewStatus.APPROVED;
await this.danakServiceReviewRepository.save(review);
return {
message: ServiceMessage.REVIEW_APPROVED,
review,
};
}
/******************************************** */
async rejectReview(reviewId: string) {
const review = await this.danakServiceReviewRepository.findOneBy({ id: reviewId });
if (!review) throw new BadRequestException(ServiceMessage.REVIEW_NOT_EXIST);
review.status = ReviewStatus.REJECTED;
await this.danakServiceReviewRepository.save(review);
return {
message: ServiceMessage.REVIEW_REJECTED,
review,
};
}
}