This commit is contained in:
2026-01-18 18:28:09 +03:30
parent 8db3b8d1ac
commit b1a6af6feb
9 changed files with 222 additions and 192 deletions
@@ -1,10 +1,105 @@
import { Injectable } from '@nestjs/common';
import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
import { EntityManager, EntityRepository, FilterQuery } from '@mikro-orm/postgresql';
import { Payment } from '../entities/payment.entity';
import { FindPaymentsDto } from '../dto/find-payments.dto';
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
import { PaymentStatusEnum } from '../interface/payment';
class FindPaymentsOpts extends FindPaymentsDto {
userId?: string;
};
@Injectable()
export class PaymentRepository extends EntityRepository<Payment> {
constructor(readonly em: EntityManager) {
super(em, Payment);
}
async findAllPaginated(opts: FindPaymentsOpts): Promise<PaginatedResult<Payment>> {
const {
page = 1,
limit = 10,
statuses,
search,
orderBy = 'createdAt',
order = 'desc',
userId,
from,
to
} = opts;
const offset = (page - 1) * limit;
const where: FilterQuery<Payment> = {};
// Filter by statuses
if (statuses) {
// Ensure statuses is always an array and normalize it
const normalizedStatuses = Array.isArray(statuses) ? statuses : [statuses];
// Filter out any empty values
const validStatuses = normalizedStatuses.filter((s): s is PaymentStatusEnum => !!s);
if (validStatuses.length > 0) {
// Use direct equality for single value, $in for multiple values to avoid SQL generation issues
if (validStatuses.length === 1) {
where.status = validStatuses[0];
} else {
where.status = { $in: validStatuses };
}
}
}
if (userId) {
where.order = { user: { id: userId } };
}
// Filter by date range
if (from || to) {
where.createdAt = {};
if (from) {
where.createdAt.$gte = new Date(from);
}
if (to) {
where.createdAt.$lte = new Date(to);
}
}
// Search by order number or user information
if (search) {
const searchPattern = `%${search}%`;
const searchConditions: any[] = [
{ user: { firstName: { $ilike: searchPattern } } },
{ user: { lastName: { $ilike: searchPattern } } },
{ user: { phone: { $ilike: searchPattern } } },
];
// If search is numeric, also search by orderNumber
const numericSearch = Number(search);
if (!isNaN(numericSearch) && isFinite(numericSearch)) {
searchConditions.push({ orderNumber: numericSearch });
}
where.$or = searchConditions;
}
// First, fetch orders without reviews
const [data, total] = await this.findAndCount(where, {
limit,
offset,
orderBy: { [orderBy]: order.toLowerCase() as 'asc' | 'desc' },
populate: [],
});
const totalPages = Math.ceil(total / limit);
return {
data,
meta: {
total,
page,
limit,
totalPages,
},
};
}
}