refactor: the discount servicer
This commit is contained in:
@@ -67,4 +67,10 @@ export class DiscountsController {
|
||||
updateDiscount(@Param() paramDto: ParamDto, @Body() updateDiscountDto: UpdateDiscountDto) {
|
||||
return this.discountsService.updateDiscount(paramDto.id, updateDiscountDto);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Get discount list for user" })
|
||||
@Get("user")
|
||||
getDiscountListForUser(@Query() queryDto: SearchDiscountQueryDto) {
|
||||
return this.discountsService.getDiscountListForUser(queryDto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,16 +86,6 @@ export class DiscountsService {
|
||||
return { discount };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a discount with distinct services for client
|
||||
*/
|
||||
async getDiscountWithDistinctServicesForClient(id: string) {
|
||||
const discount = await this.discountRepository.findDiscountWithDistinctServicesForClient(id);
|
||||
if (!discount) throw new BadRequestException(DiscountMessage.NOT_FOUND);
|
||||
|
||||
return { discount };
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle discount active status
|
||||
*/
|
||||
@@ -177,15 +167,42 @@ export class DiscountsService {
|
||||
}
|
||||
}
|
||||
|
||||
async getDiscountListForUser(queryDto: SearchDiscountQueryDto) {
|
||||
const [discounts, count] = await this.discountRepository.findDiscountForUser(queryDto);
|
||||
|
||||
return {
|
||||
discounts,
|
||||
count,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Soft delete a discount
|
||||
*/
|
||||
async softDeleteDiscount(id: string) {
|
||||
await this.discountRepository.softDeleteDiscount(id);
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
try {
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
return {
|
||||
message: CommonMessage.DELETED,
|
||||
};
|
||||
const discount = await this.discountRepository.findById(id);
|
||||
if (!discount) throw new BadRequestException(DiscountMessage.NOT_FOUND);
|
||||
|
||||
await this.removeDiscountDeactivationJob(id);
|
||||
await this.clearDirectDiscountFromPlans(discount, queryRunner);
|
||||
|
||||
await queryRunner.manager.softDelete(this.discountRepository.target, discount);
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
return {
|
||||
message: CommonMessage.DELETED,
|
||||
};
|
||||
} catch (error) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Repository } from "typeorm";
|
||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||
import { SearchDiscountQueryDto } from "../DTO/search-discount-query.dto";
|
||||
import { Discount } from "../entities/discount.entity";
|
||||
import { DiscountApplicationType } from "../enums/discount-application-type.enum";
|
||||
|
||||
@Injectable()
|
||||
export class DiscountRepository extends Repository<Discount> {
|
||||
@@ -61,50 +62,19 @@ export class DiscountRepository extends Repository<Discount> {
|
||||
return this.softDelete(id);
|
||||
}
|
||||
|
||||
async findDiscountWithDistinctServicesForClient(id: string) {
|
||||
// First, get the basic discount information
|
||||
const discount = await this.findOne({
|
||||
where: { id, isActive: true },
|
||||
withDeleted: false,
|
||||
});
|
||||
|
||||
if (!discount) return null;
|
||||
|
||||
// Get subscription plans with their services
|
||||
async findDiscountForUser(queryDto: SearchDiscountQueryDto) {
|
||||
const { limit, skip } = PaginationUtils(queryDto);
|
||||
const queryBuilder = this.createQueryBuilder("discount")
|
||||
.leftJoinAndSelect("discount.subscriptionPlans", "plans")
|
||||
.leftJoinAndSelect("plans.service", "service")
|
||||
.where("discount.id = :id", { id })
|
||||
.andWhere("discount.isActive = :isActive", { isActive: true });
|
||||
.where("discount.deletedAt IS NULL")
|
||||
.andWhere("discount.isActive = true")
|
||||
.andWhere("discount.startDate <= :now", { now: new Date() })
|
||||
.andWhere("discount.endDate >= :now", { now: new Date() })
|
||||
.andWhere("discount.type = :type", { type: DiscountApplicationType.CODE_BASED });
|
||||
|
||||
const discountWithPlans = await queryBuilder.getOne();
|
||||
if (queryDto.q) {
|
||||
queryBuilder.andWhere("discount.title ILIKE :query", { query: `%${queryDto.q}%` });
|
||||
}
|
||||
|
||||
// Get distinct services using raw SQL
|
||||
const distinctServicesQuery = this.manager.query(
|
||||
`
|
||||
SELECT DISTINCT ON (service.id)
|
||||
service.id,
|
||||
service.name,
|
||||
service.description,
|
||||
service.icon_url as "iconUrl",
|
||||
service.is_active as "isActive"
|
||||
FROM danak_service service
|
||||
INNER JOIN subscription_plan plan ON plan.service_id = service.id
|
||||
INNER JOIN discount_subscription_plans dsp ON dsp.subscription_plan_id = plan.id
|
||||
WHERE dsp.discount_id = $1
|
||||
AND service.deleted_at IS NULL
|
||||
AND service.is_active = true
|
||||
`,
|
||||
[id],
|
||||
);
|
||||
|
||||
// Combine the results
|
||||
const [distinctServices] = await Promise.all([distinctServicesQuery]);
|
||||
|
||||
return {
|
||||
...discount,
|
||||
subscriptionPlans: discountWithPlans?.subscriptionPlans || [],
|
||||
distinctServices,
|
||||
};
|
||||
return queryBuilder.skip(skip).take(limit).orderBy("discount.createdAt", "DESC").getManyAndCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,18 +104,15 @@ export class SubscriptionsService {
|
||||
}
|
||||
//************************************ */
|
||||
async updateSubscriptionPlan(id: string, updateDto: UpdateSubscriptionPlanDto) {
|
||||
// Find the existing subscription plan
|
||||
const subscription = await this.subscriptionsPlanRepository.findOne({ where: { id }, relations: { service: true } });
|
||||
if (!subscription) throw new BadRequestException(SubscriptionMessage.NOT_FOUND);
|
||||
|
||||
// Check if service exists when trying to update it
|
||||
if (updateDto.serviceId) {
|
||||
const danakService = await this.danakServices.findServiceById(updateDto.serviceId);
|
||||
if (!danakService) throw new BadRequestException(ServiceMessage.SERVICE_NOT_FOUND_BY_ID);
|
||||
subscription.service = danakService;
|
||||
}
|
||||
|
||||
// Check for name uniqueness if updating name
|
||||
if (updateDto.name) {
|
||||
const existSubscription = await this.subscriptionsPlanRepository.findOneBy({
|
||||
name: updateDto.name,
|
||||
|
||||
@@ -65,7 +65,6 @@ export class SubscriptionsController {
|
||||
|
||||
@ApiOperation({ summary: "update a subscription plan by id" })
|
||||
@Patch(":id")
|
||||
//TODO:fix this if needed
|
||||
@PermissionsDec(PermissionEnum.SERVICES)
|
||||
updateSubscription(@Param() paramDto: ParamDto, @Body() updateDto: UpdateSubscriptionPlanDto) {
|
||||
return this.subscriptionService.updateSubscriptionPlan(paramDto.id, updateDto);
|
||||
|
||||
Reference in New Issue
Block a user