detail
This commit is contained in:
@@ -4,8 +4,11 @@ export enum OrderStatus {
|
|||||||
// PendingConfirmation = 'pendingConfirmation',
|
// PendingConfirmation = 'pendingConfirmation',
|
||||||
|
|
||||||
Confirmed = 'confirmed',
|
Confirmed = 'confirmed',
|
||||||
|
Preparing = 'preparing',
|
||||||
|
|
||||||
RejectedByRestaurant = 'rejectedByRestaurant',
|
RejectedByRestaurant = 'rejectedByRestaurant',
|
||||||
CancelledByUser = 'cancelledByUser',
|
CancelledByUser = 'cancelledByUser',
|
||||||
|
CancelledBySystem = 'cancelledBySystem',
|
||||||
|
|
||||||
ReadyForCustomerPickup = 'readyForCustomerPickup',
|
ReadyForCustomerPickup = 'readyForCustomerPickup',
|
||||||
ReadyForDineIn = 'readyForDineIn',
|
ReadyForDineIn = 'readyForDineIn',
|
||||||
@@ -13,5 +16,4 @@ export enum OrderStatus {
|
|||||||
ReadyForDeliveryCourier = 'readyForDeliveryCourier',
|
ReadyForDeliveryCourier = 'readyForDeliveryCourier',
|
||||||
|
|
||||||
Delivered = 'delivered',
|
Delivered = 'delivered',
|
||||||
CancelledBySystem = 'cancelledBySystem',
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,8 +252,15 @@ export class OrdersService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
findOne(id: number) {
|
async findOne(id: string): Promise<Order> {
|
||||||
return `This action returns a #${id} order`;
|
const order = await this.orderRepository.findOne(
|
||||||
|
{ id },
|
||||||
|
{ populate: ['user', 'restaurant', 'deliveryMethod', 'address', 'paymentMethod', 'items', 'items.food'] },
|
||||||
|
);
|
||||||
|
if (!order) {
|
||||||
|
throw new NotFoundException('Order not found');
|
||||||
|
}
|
||||||
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
async acceptOrder(orderId: string) {
|
async acceptOrder(orderId: string) {
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
|
||||||
|
import { FilterQuery } from '@mikro-orm/core';
|
||||||
|
import { Order } from '../entities/order.entity';
|
||||||
|
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
|
||||||
|
import { OrderStatus } from '../interface/order-status';
|
||||||
|
import { PaymentStatusEnum } from '../../payments/interface/payment';
|
||||||
|
|
||||||
|
type FindOrdersOpts = {
|
||||||
|
page?: number;
|
||||||
|
limit?: number;
|
||||||
|
status?: OrderStatus;
|
||||||
|
paymentStatus?: PaymentStatusEnum;
|
||||||
|
search?: string;
|
||||||
|
startDate?: string;
|
||||||
|
endDate?: string;
|
||||||
|
orderBy?: string;
|
||||||
|
order?: 'asc' | 'desc';
|
||||||
|
};
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class OrderRepository extends EntityRepository<Order> {
|
||||||
|
constructor(readonly em: EntityManager) {
|
||||||
|
super(em, Order);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find orders with pagination and optional filters.
|
||||||
|
* Supports: status, paymentStatus, search (orderNumber), date range, ordering.
|
||||||
|
*/
|
||||||
|
async findAllPaginated(restId: string, opts: FindOrdersOpts = {}): Promise<PaginatedResult<Order>> {
|
||||||
|
const {
|
||||||
|
page = 1,
|
||||||
|
limit = 10,
|
||||||
|
status,
|
||||||
|
paymentStatus,
|
||||||
|
search,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
orderBy = 'createdAt',
|
||||||
|
order = 'desc',
|
||||||
|
} = opts;
|
||||||
|
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
|
||||||
|
const where: FilterQuery<Order> = { restaurant: { id: restId } };
|
||||||
|
|
||||||
|
// Filter by status
|
||||||
|
if (status) {
|
||||||
|
where.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by payment status
|
||||||
|
if (paymentStatus) {
|
||||||
|
where.paymentStatus = paymentStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by date range
|
||||||
|
if (startDate || endDate) {
|
||||||
|
where.createdAt = {};
|
||||||
|
if (startDate) {
|
||||||
|
where.createdAt.$gte = new Date(startDate);
|
||||||
|
}
|
||||||
|
if (endDate) {
|
||||||
|
where.createdAt.$lte = new Date(endDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [data, total] = await this.findAndCount(where, {
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
orderBy: { [orderBy]: order.toLowerCase() as 'asc' | 'desc' },
|
||||||
|
populate: ['user', 'restaurant', 'deliveryMethod', 'address', 'paymentMethod', 'items', 'items.food'],
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalPages = Math.ceil(total / limit);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
meta: {
|
||||||
|
total,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
totalPages,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user