import { Controller, Get, Post, Param, UseGuards, Patch, Query, Body, Delete } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiHeader, ApiBody } from '@nestjs/swagger'; import { OrdersService } from '../providers/orders.service'; import { AuthGuard } from '../../auth/guards/auth.guard'; import { UserId } from '../../../common/decorators/user-id.decorator'; import { RestId } from 'src/common/decorators/rest-id.decorator'; import { AdminAuthGuard } from '../../auth/guards/adminAuth.guard'; import { FindOrdersDto } from '../dto/find-orders.dto'; import { OrderStatus } from '../interface/order.interface'; import { API_HEADER_SLUG } from 'src/common/constants/index'; import { UpdateOrderStatusDto } from '../dto/update-order-status.dto'; import { Permissions } from 'src/common/decorators/permissions.decorator'; import { Permission } from 'src/common/enums/permission.enum'; import { AdminCreateOrderDto } from '../dto/admin-create-order.dto'; import { AdminUpdateOrderFeesDto } from '../dto/admin-update-order-fees.dto'; import { AdminAddOrderItemDto } from '../dto/admin-add-order-item.dto'; import { AdminUpdateOrderItemDto } from '../dto/admin-update-order-item.dto'; import { FoodOrderReportDto } from '../dto/food-order-report.dto'; import { DailyOrderReportDto } from '../dto/daily-order-report.dto'; import { AdminRefundOrderDto } from '../dto/admin-refund-order.dto'; @ApiTags('orders') @ApiBearerAuth() @Controller() export class OrdersController { constructor(private readonly ordersService: OrdersService) { } @UseGuards(AuthGuard) @Post('public/checkout') @ApiHeader(API_HEADER_SLUG) @ApiOperation({ summary: 'Checkout : create order and payment record' }) checkout(@UserId() userId: string, @RestId() restaurantId: string) { return this.ordersService.checkout(userId, restaurantId); } @UseGuards(AuthGuard) @Get('public/orders') @ApiHeader(API_HEADER_SLUG) @ApiOperation({ summary: 'Get all orders with pagination and filters' }) findAll(@RestId() restId: string, @Query() dto: FindOrdersDto, @UserId() userId: string) { return this.ordersService.findAllForUser(restId, dto, userId); } @UseGuards(AuthGuard) @ApiOperation({ summary: 'Get an order By id for User' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiHeader(API_HEADER_SLUG) @Get('public/orders/:orderId') findOne(@Param('orderId') orderId: string, @RestId() restId: string) { return this.ordersService.findOne(orderId, restId); } @UseGuards(AuthGuard) @Patch('public/orders/:id/:status') @ApiParam({ name: 'status', description: 'Order status', enum: OrderStatus, }) @ApiHeader(API_HEADER_SLUG) @ApiBody({ type: UpdateOrderStatusDto }) @ApiOperation({ summary: 'Update status of an order By User' }) @ApiParam({ name: 'id', description: 'Order ID' }) cancelOrder( @Body() dto: UpdateOrderStatusDto, @Param('id') orderId: string, @Param('status') status: OrderStatus, @RestId() restId: string, ) { return this.ordersService.changeOrderStatus(orderId, restId, status, 'user', dto?.desc); } /******************** Admin Routes **********************/ @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Post('admin/orders') @ApiOperation({ summary: 'Create an order for a user from admin side' }) @ApiBody({ type: AdminCreateOrderDto }) createOrderForUser(@RestId() restId: string, @Body() dto: AdminCreateOrderDto) { return this.ordersService.createOrderForUser(restId, dto); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Get('admin/orders') @ApiOperation({ summary: 'Get all orders with pagination and filters' }) findAllAdmin(@RestId() restId: string, @Query() dto: FindOrdersDto) { return this.ordersService.findAllForAdmin(restId, dto); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @ApiOperation({ summary: 'Get an order By id for User' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @Get('admin/orders/:orderId') findOneAsAdmin(@Param('orderId') orderId: string, @RestId() restId: string) { return this.ordersService.findOne(orderId, restId); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Patch('admin/orders/:orderId/fees') @ApiOperation({ summary: 'Update order delivery fee, packing fee, and preparation time' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiBody({ type: AdminUpdateOrderFeesDto }) updateOrderFees( @Param('orderId') orderId: string, @Body() dto: AdminUpdateOrderFeesDto, @RestId() restId: string, ) { return this.ordersService.updateOrderFees(orderId, restId, dto); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Post('admin/orders/:orderId/items') @ApiOperation({ summary: 'Add an item to an existing order' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiBody({ type: AdminAddOrderItemDto }) addOrderItem( @Param('orderId') orderId: string, @Body() dto: AdminAddOrderItemDto, @RestId() restId: string, ) { return this.ordersService.addOrderItem(orderId, restId, dto); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Patch('admin/orders/:orderId/items/:itemId') @ApiOperation({ summary: 'Update quantity of an order item' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiParam({ name: 'itemId', description: 'Order item ID' }) @ApiBody({ type: AdminUpdateOrderItemDto }) updateOrderItem( @Param('orderId') orderId: string, @Param('itemId') itemId: string, @Body() dto: AdminUpdateOrderItemDto, @RestId() restId: string, ) { return this.ordersService.updateOrderItemQuantity(orderId, restId, itemId, dto); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Delete('admin/orders/:orderId/items/:itemId') @ApiOperation({ summary: 'Remove an item from an order' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiParam({ name: 'itemId', description: 'Order item ID' }) removeOrderItem( @Param('orderId') orderId: string, @Param('itemId') itemId: string, @RestId() restId: string, ) { return this.ordersService.removeOrderItem(orderId, restId, itemId); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Post('admin/orders/:orderId/refund') @ApiOperation({ summary: 'Refund order payment(s) by amount' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiBody({ type: AdminRefundOrderDto }) refundOrder( @Param('orderId') orderId: string, @Body() dto: AdminRefundOrderDto, @RestId() restId: string, ) { return this.ordersService.refundOrder(orderId, restId, dto); } @UseGuards(AdminAuthGuard) @Permissions(Permission.MANAGE_ORDERS) @Patch('admin/orders/:orderId/:status') @ApiOperation({ summary: 'Update an order status' }) @ApiParam({ name: 'orderId', description: 'Order ID' }) @ApiBody({ type: UpdateOrderStatusDto }) @ApiParam({ name: 'status', description: 'Order status', enum: OrderStatus, }) updateStatus( @Param('orderId') orderId: string, @Body() dto: UpdateOrderStatusDto, @Param('status') status: OrderStatus, @RestId() restId: string, ) { return this.ordersService.changeOrderStatus(orderId, restId, status, 'admin', dto?.desc); } @UseGuards(AdminAuthGuard) @Permissions(Permission.VIEW_REPORTS) @ApiOperation({ summary: 'Get Stats for report page' }) @Get('admin/orders/stats') findStats(@RestId() restId: string) { return this.ordersService.getStats(restId); } @UseGuards(AdminAuthGuard) @Permissions(Permission.VIEW_REPORTS) @ApiOperation({ summary: 'Get food sales pie chart data for last month' }) @ApiHeader(API_HEADER_SLUG) @Get('admin/orders/food-sales-pie-chart') getFoodSalesPieChart(@RestId() restId: string) { return this.ordersService.getFoodSalesPieChart(restId); } @UseGuards(AdminAuthGuard) @Permissions(Permission.VIEW_ORDER_REPORTS) @ApiOperation({ summary: 'Get order report grouped by food' }) @Get('admin/orders/report/by-food') getFoodOrderReport(@RestId() restId: string, @Query() dto: FoodOrderReportDto) { return this.ordersService.getFoodOrderReport(restId, dto); } @UseGuards(AdminAuthGuard) @Permissions(Permission.VIEW_ORDER_REPORTS) @ApiOperation({ summary: 'Get order report grouped by day' }) @Get('admin/orders/report/by-day') getDailyOrderReport(@RestId() restId: string, @Query() dto: DailyOrderReportDto) { return this.ordersService.getDailyOrderReport(restId, dto); } }