This commit is contained in:
@@ -710,6 +710,8 @@ export const enum OrderMessage {
|
|||||||
REFUND_AMOUNT_EXCEEDS_PAID = 'مبلغ بازگشت وجه بیشتر از مبلغ پرداختشده است',
|
REFUND_AMOUNT_EXCEEDS_PAID = 'مبلغ بازگشت وجه بیشتر از مبلغ پرداختشده است',
|
||||||
REFUND_AMOUNT_EXCEEDS_OVERPAYMENT = 'مبلغ بازگشت وجه بیشتر از مانده منفی سفارش است',
|
REFUND_AMOUNT_EXCEEDS_OVERPAYMENT = 'مبلغ بازگشت وجه بیشتر از مانده منفی سفارش است',
|
||||||
NO_PAID_PAYMENTS_TO_REFUND = 'پرداختی برای بازگشت وجه یافت نشد',
|
NO_PAID_PAYMENTS_TO_REFUND = 'پرداختی برای بازگشت وجه یافت نشد',
|
||||||
|
ADD_PAYMENT_NOT_ALLOWED = 'امکان افزودن پرداخت برای این سفارش وجود ندارد',
|
||||||
|
ADD_PAYMENT_NO_BALANCE = 'ماندهای برای پرداخت وجود ندارد',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum CartMessage {
|
export const enum CartMessage {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { AdminUpdateOrderItemDto } from '../dto/admin-update-order-item.dto';
|
|||||||
import { FoodOrderReportDto } from '../dto/food-order-report.dto';
|
import { FoodOrderReportDto } from '../dto/food-order-report.dto';
|
||||||
import { DailyOrderReportDto } from '../dto/daily-order-report.dto';
|
import { DailyOrderReportDto } from '../dto/daily-order-report.dto';
|
||||||
import { AdminRefundOrderDto } from '../dto/admin-refund-order.dto';
|
import { AdminRefundOrderDto } from '../dto/admin-refund-order.dto';
|
||||||
|
import { AdminAddPaymentDto } from '../dto/admin-add-payment.dto';
|
||||||
|
|
||||||
@ApiTags('orders')
|
@ApiTags('orders')
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@@ -155,6 +156,20 @@ export class OrdersController {
|
|||||||
return this.ordersService.removeOrderItem(orderId, restId, itemId);
|
return this.ordersService.removeOrderItem(orderId, restId, itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(AdminAuthGuard)
|
||||||
|
@Permissions(Permission.MANAGE_ORDERS)
|
||||||
|
@Post('admin/orders/:orderId/payments')
|
||||||
|
@ApiOperation({ summary: 'Add a cash payment to an existing order' })
|
||||||
|
@ApiParam({ name: 'orderId', description: 'Order ID' })
|
||||||
|
@ApiBody({ type: AdminAddPaymentDto })
|
||||||
|
addPayment(
|
||||||
|
@Param('orderId') orderId: string,
|
||||||
|
@Body() dto: AdminAddPaymentDto,
|
||||||
|
@RestId() restId: string,
|
||||||
|
) {
|
||||||
|
return this.ordersService.addPayment(orderId, restId, dto);
|
||||||
|
}
|
||||||
|
|
||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@Permissions(Permission.MANAGE_ORDERS)
|
@Permissions(Permission.MANAGE_ORDERS)
|
||||||
@Post('admin/orders/:orderId/refund')
|
@Post('admin/orders/:orderId/refund')
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { Type } from 'class-transformer';
|
||||||
|
import { IsNumber, IsOptional, IsString, Min } from 'class-validator';
|
||||||
|
|
||||||
|
export class AdminAddPaymentDto {
|
||||||
|
@ApiProperty({ description: 'Payment amount', minimum: 1 })
|
||||||
|
@Type(() => Number)
|
||||||
|
@IsNumber()
|
||||||
|
@Min(1)
|
||||||
|
amount!: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'Payment description' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ import { AdminUpdateOrderFeesDto } from '../dto/admin-update-order-fees.dto';
|
|||||||
import { AdminAddOrderItemDto } from '../dto/admin-add-order-item.dto';
|
import { AdminAddOrderItemDto } from '../dto/admin-add-order-item.dto';
|
||||||
import { AdminUpdateOrderItemDto } from '../dto/admin-update-order-item.dto';
|
import { AdminUpdateOrderItemDto } from '../dto/admin-update-order-item.dto';
|
||||||
import { AdminRefundOrderDto } from '../dto/admin-refund-order.dto';
|
import { AdminRefundOrderDto } from '../dto/admin-refund-order.dto';
|
||||||
|
import { AdminAddPaymentDto } from '../dto/admin-add-payment.dto';
|
||||||
import { FoodOrderReportDto, FoodOrderReportSortBy } from '../dto/food-order-report.dto';
|
import { FoodOrderReportDto, FoodOrderReportSortBy } from '../dto/food-order-report.dto';
|
||||||
import { DailyOrderReportDto, DailyOrderReportSortBy } from '../dto/daily-order-report.dto';
|
import { DailyOrderReportDto, DailyOrderReportSortBy } from '../dto/daily-order-report.dto';
|
||||||
import { CashShiftsService } from './cash-shifts.service';
|
import { CashShiftsService } from './cash-shifts.service';
|
||||||
@@ -545,6 +546,52 @@ export class OrdersService {
|
|||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async addPayment(orderId: string, restId: string, dto: AdminAddPaymentDto): Promise<Order> {
|
||||||
|
return this.em.transactional(async em => {
|
||||||
|
const order = await em.findOne(
|
||||||
|
Order,
|
||||||
|
{ id: orderId, restaurant: { id: restId } },
|
||||||
|
{ populate: ['payments', 'user', 'paymentMethod', 'deliveryMethod', 'items', 'items.food'] },
|
||||||
|
);
|
||||||
|
if (!order) {
|
||||||
|
throw new NotFoundException(OrderMessage.NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order.status === OrderStatus.CANCELED) {
|
||||||
|
throw new BadRequestException(OrderMessage.ADD_PAYMENT_NOT_ALLOWED);
|
||||||
|
}
|
||||||
|
|
||||||
|
const balance = Number(order.balance ?? 0);
|
||||||
|
if (balance <= 0) {
|
||||||
|
throw new BadRequestException(OrderMessage.ADD_PAYMENT_NO_BALANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const amount = Number(dto.amount);
|
||||||
|
if (!amount || amount <= 0) {
|
||||||
|
throw new BadRequestException(PaymentMessage.AMOUNT_MUST_BE_GREATER_THAN_ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
const payment = em.create(Payment, {
|
||||||
|
order,
|
||||||
|
amount,
|
||||||
|
method: PaymentMethodEnum.Cash,
|
||||||
|
gateway: null,
|
||||||
|
status: PaymentStatusEnum.Paid,
|
||||||
|
paidAt: new Date(),
|
||||||
|
description: dto.description?.trim() || null,
|
||||||
|
});
|
||||||
|
em.persist(payment);
|
||||||
|
|
||||||
|
await em.flush();
|
||||||
|
|
||||||
|
return em.findOneOrFail(
|
||||||
|
Order,
|
||||||
|
{ id: orderId },
|
||||||
|
{ populate: ['payments', 'user', 'paymentMethod', 'deliveryMethod', 'items', 'items.food'] },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async refundOrder(orderId: string, restId: string, dto: AdminRefundOrderDto): Promise<Order> {
|
async refundOrder(orderId: string, restId: string, dto: AdminRefundOrderDto): Promise<Order> {
|
||||||
return this.em.transactional(async em => {
|
return this.em.transactional(async em => {
|
||||||
const order = await em.findOne(
|
const order = await em.findOne(
|
||||||
|
|||||||
Reference in New Issue
Block a user