add payment
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
2026-07-19 10:18:33 +03:30
parent 17223ced06
commit d1f85d78f4
4 changed files with 80 additions and 0 deletions
+2
View File
@@ -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(