import { Injectable } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; import { PaginationUtils } from "../../utils/providers/pagination.utils"; import { InvoicesSearchQueryDto } from "../DTO/invoices-search-query.dto"; import { Invoice } from "../entities/invoice.entity"; @Injectable() export class InvoicesRepository extends Repository { constructor(@InjectRepository(Invoice) invoicesRepository: Repository) { super(invoicesRepository.target, invoicesRepository.manager, invoicesRepository.queryRunner); } async getInvoicesForAdmin(queryDto: InvoicesSearchQueryDto) { const { limit, skip } = PaginationUtils(queryDto); const queryBuilder = this.createQueryBuilder("invoice"); queryBuilder .leftJoin("invoice.user", "user") .addSelect(["user.id", "user.firstName", "user.lastName", "user.email", "user.phone"]) .leftJoinAndSelect("invoice.items", "items") .leftJoinAndSelect("items.subscriptionPlan", "subscriptionPlan", "subscriptionPlan.id IS NOT NULL") .leftJoinAndSelect("subscriptionPlan.plan", "plan", "subscriptionPlan.id IS NOT NULL") .leftJoin("plan.service", "service", "subscriptionPlan.id IS NOT NULL") .addSelect(["service.name", "service.id"]); if (queryDto.q) { queryBuilder .orWhere("user.firstName ILIKE :search", { search: `%${queryDto.q}%` }) .orWhere("user.lastName ILIKE :search", { search: `%${queryDto.q}%` }) .orWhere("user.email ILIKE :search", { search: `%${queryDto.q}%` }); } if (queryDto.status) { queryBuilder.andWhere("invoice.status = :status", { status: queryDto.status }); } if (queryDto.userId) { queryBuilder.andWhere("invoice.user.id = :userId", { userId: queryDto.userId }); } if (queryDto.serviceId) { queryBuilder.andWhere("plan.serviceId = :serviceId", { serviceId: queryDto.serviceId }); } if (queryDto.since) { queryBuilder.andWhere("(invoice.createdAt >= :since OR invoice.dueDate >= :since OR invoice.paidAt >= :since)", { since: new Date(queryDto.since), }); } if (queryDto.to) { queryBuilder.andWhere("(invoice.createdAt <= :to OR invoice.dueDate <= :to OR invoice.paidAt <= :to)", { to: new Date(queryDto.to), }); } queryBuilder.orderBy("invoice.createdAt", "DESC"); queryBuilder.skip(skip); queryBuilder.take(limit); return await queryBuilder.getManyAndCount(); } async findPaginatedListByUserIds(queryDto: InvoicesSearchQueryDto, userIds: string[]) { if (!userIds.length) { return [[], 0] as [Invoice[], number]; } const { limit, skip } = PaginationUtils(queryDto); const queryBuilder = this.createQueryBuilder("invoice"); queryBuilder .leftJoin("invoice.user", "user") .addSelect(["user.id", "user.firstName", "user.lastName", "user.email", "user.phone"]) .where("user.id IN (:...userIds)", { userIds }); if (queryDto.status) { queryBuilder.andWhere("invoice.status = :status", { status: queryDto.status }); } if (queryDto.since) { queryBuilder.andWhere("(invoice.createdAt >= :since OR invoice.dueDate >= :since OR invoice.paidAt >= :since)", { since: new Date(queryDto.since), }); } if (queryDto.to) { queryBuilder.andWhere("(invoice.createdAt <= :to OR invoice.dueDate <= :to OR invoice.paidAt <= :to)", { to: new Date(queryDto.to), }); } queryBuilder.orderBy("invoice.createdAt", "DESC"); queryBuilder.skip(skip); queryBuilder.take(limit); return await queryBuilder.getManyAndCount(); } }