From 9fa0e998269b313419bfc8734d94beec773473fd Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Tue, 24 Feb 2026 10:46:26 +0330 Subject: [PATCH] payment --- src/common/enums/permission.enum.ts | 25 +--- .../admin/controllers/admin.controller.ts | 20 +++- .../controller/form-builder.controller.ts | 8 -- src/modules/invoice/invoice.controller.ts | 4 +- .../order/controllers/order.controller.ts | 3 + .../payment/controllers/payment.controller.ts | 110 +++++++++--------- .../payment/services/payments.service.ts | 11 +- 7 files changed, 86 insertions(+), 95 deletions(-) diff --git a/src/common/enums/permission.enum.ts b/src/common/enums/permission.enum.ts index 7b902c5..ef5ac4b 100644 --- a/src/common/enums/permission.enum.ts +++ b/src/common/enums/permission.enum.ts @@ -14,8 +14,6 @@ export enum PermissionEnum { UPDATE_INVOICE = 'update_invoice', DELETE_INVOICE = 'delete_invoice', - VIEW_All_INVOICED_ORDERS = 'view_all_invoiced_orders', - VIEW_MY_ASSIGNED_INVOICED_REQUESTS = 'view_my_assigned_invoiced_requests', VIEW_ORDERS = 'view_orders', VIEW_ASSIGNED_ORDERS = 'view_assigned_orders', @@ -31,9 +29,8 @@ export enum PermissionEnum { VIEW_USERS = 'view_users', - // User & Admin Management MANAGE_ADMINS = 'manage_admins', - // Role Management + MANAGE_ROLES = 'manage_roles', @@ -41,30 +38,21 @@ export enum PermissionEnum { MANAGE_SETTINGS = 'manage_settings', - MANAGE_FORM_BUILDER = 'manage_form_builder', CREATE_PRINT = 'create_print', - - MANAGE_PRINT = 'view_print', + VIEW_PRINT = 'view_print', MANAGE_LEARNINGS = 'manage_learnings', - MANAGE_CRITICISMS = 'manage_criticisms', - MANAGE_ANNOUNCEMENTS = 'manage_announcements', - MANAGE_TICKETS = 'manage_tickets', // Notif Permsissions NEW_REQUEST_NOTIFICATION='new_request_notification', - - NEW_PAYMENT_NOTIFICATION='new_payment_notification', + NEW_PAYMENT_NOTIFICATION='new_payment_notification', } -/** - * Permission titles mapping (Farsi) - * Maps permission names to their Farsi titles - */ + export const PermissionTitles: Record = { [PermissionEnum.MANAGE_PRODUCTS]: 'مدیریت محصولات', [PermissionEnum.MANAGE_CATEGORIES]: 'مدیریت دسته‌بندی‌ها', @@ -79,10 +67,7 @@ export const PermissionTitles: Record = { [PermissionEnum.MANAGE_ROLES]: 'مدیریت نقش‌ها', [PermissionEnum.MANAGE_PAYMENTS]: 'مدیریت پرداخت‌ها', [PermissionEnum.MANAGE_SETTINGS]: 'مدیریت تنظیمات', - [PermissionEnum.MANAGE_FORM_BUILDER]: "مدیریت فرم بیلدر", [PermissionEnum.VIEW_REQUESTS]: "مشاهده همه درخواست سفارش ها", - [PermissionEnum.VIEW_All_INVOICED_ORDERS]: "مشاهده همه سفارشات پیش فاکتور شده", - [PermissionEnum.VIEW_MY_ASSIGNED_INVOICED_REQUESTS]: "مشاهده همه پیش فاکتور های من", [PermissionEnum.DELETE_REQUEST]: "", [PermissionEnum.UPDATE_REQUEST]: "", [PermissionEnum.VIEW_INVOICES]: "", @@ -91,7 +76,7 @@ export const PermissionTitles: Record = { [PermissionEnum.DELETE_INVOICE]: "", [PermissionEnum.DELETE_ORDER]: "", [PermissionEnum.CREATE_PRINT]: "ایجاد فرم چاپ برای سفارش", - [PermissionEnum.MANAGE_PRINT]: "مدیریت فرم چاپ", + [PermissionEnum.VIEW_PRINT]: "مدیریت فرم چاپ", [PermissionEnum.MANAGE_LEARNINGS]: "مدیریت آموزش‌ها", [PermissionEnum.MANAGE_CRITICISMS]: "مدیریت انتقادها و پیشنهادها", [PermissionEnum.MANAGE_ANNOUNCEMENTS]: "مدیریت اطلاعیه‌ها", diff --git a/src/modules/admin/controllers/admin.controller.ts b/src/modules/admin/controllers/admin.controller.ts index 46c99dd..f526e9f 100644 --- a/src/modules/admin/controllers/admin.controller.ts +++ b/src/modules/admin/controllers/admin.controller.ts @@ -2,7 +2,7 @@ import { Controller, Post, Body, Get, UseGuards, Patch, Param, Delete } from '@n import { AdminService } from '../providers/admin.service'; import { CreateAdminDto } from '../dto/create-admin.dto'; import { UpdateAdminDto } from '../dto/update-admin.dto'; -import { ApiTags, ApiOperation, ApiBody, ApiBearerAuth, ApiParam } from '@nestjs/swagger'; +import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { AdminId } from 'src/common/decorators/admin-id.decorator'; import { Admin } from '../entities/admin.entity'; @@ -13,11 +13,11 @@ import { Permissions } from 'src/common/decorators/permissions.decorator'; @ApiTags('admin') @UseGuards(AdminAuthGuard) @ApiBearerAuth() -@Permissions(PermissionEnum.MANAGE_ADMINS) export class AdminController { constructor(private readonly adminService: AdminService) { } @Post('admin/admin') + @Permissions(PermissionEnum.MANAGE_ADMINS) @ApiOperation({ summary: 'Create a new admin' }) async create(@Body() dto: CreateAdminDto,) { const admin = await this.adminService.create(dto); @@ -25,13 +25,20 @@ export class AdminController { } @Get('admin/admins') + @Permissions(PermissionEnum.MANAGE_ADMINS) @ApiOperation({ summary: 'admin' }) - async getAll() { - const admin = await this.adminService.findAll(); - return admin; + getAll() { + return this.adminService.findAll(); + } + + @Get('admin/admins/search') + @ApiOperation({ summary: 'get admin list , has no permission' }) + searchAll() { + return this.adminService.findAll(); } @Get('admin/admins/me') + @Permissions(PermissionEnum.MANAGE_ADMINS) @ApiOperation({ summary: 'admin' }) async getMe(@AdminId() adminId: string,) { const admin = await this.adminService.findById(adminId,); @@ -40,18 +47,21 @@ export class AdminController { @Patch('admin/admins/:adminId') + @Permissions(PermissionEnum.MANAGE_ADMINS) @ApiOperation({ summary: 'Update an admin' }) update(@Param('adminId') adminId: string, @Body() dto: UpdateAdminDto,): Promise { return this.adminService.update(adminId, dto); } @Get('admin/admins/:adminId') + @Permissions(PermissionEnum.MANAGE_ADMINS) @ApiOperation({ summary: 'Get an admin by ID' }) getById(@Param('adminId') adminId: string,): Promise { return this.adminService.findById(adminId,); } @Delete('admin/admins/:adminId') + @Permissions(PermissionEnum.MANAGE_ADMINS) @ApiOperation({ summary: 'Delete an admin by ID' }) deleteById(@Param('adminId') adminId: string,): Promise { return this.adminService.softDelete(adminId,); diff --git a/src/modules/form-builder/controller/form-builder.controller.ts b/src/modules/form-builder/controller/form-builder.controller.ts index 5311580..4c6ff71 100644 --- a/src/modules/form-builder/controller/form-builder.controller.ts +++ b/src/modules/form-builder/controller/form-builder.controller.ts @@ -8,8 +8,6 @@ import { FieldOptionService } from '../provider/field-option.service'; import { UpdateFieldDto } from '../dto/update-field.dto'; import { UpdateFieldOptionDto } from '../dto/update-field-option.dto'; import { FindFieldsGroupDto } from '../dto/find-field-group.dto'; -import { Permissions } from 'src/common/decorators/permissions.decorator'; -import { PermissionEnum } from 'src/common/enums/permission.enum'; @Controller() @ApiBearerAuth() @@ -31,7 +29,6 @@ export class FormBuilderController { // ============= Admin ================= @Post('admin/entity/:id/field') @ApiOperation({ summary: 'Create field for entity' }) - @Permissions(PermissionEnum.MANAGE_FORM_BUILDER) @UseGuards(AdminAuthGuard) createField(@Body() dto: CreateFieldDto, @Param('id') entityId: string) { return this.fieldService.create(entityId, dto); @@ -61,7 +58,6 @@ export class FormBuilderController { @Patch('admin/entity/field/:id') @ApiOperation({ summary: 'Update field' }) @UseGuards(AdminAuthGuard) - @Permissions(PermissionEnum.MANAGE_FORM_BUILDER) updateField(@Param('id') id: string, @Body() dto: UpdateFieldDto) { return this.fieldService.update(id, dto); } @@ -69,7 +65,6 @@ export class FormBuilderController { @Delete('admin/entity/field/:id') @ApiOperation({ summary: 'Remove field' }) @UseGuards(AdminAuthGuard) - @Permissions(PermissionEnum.MANAGE_FORM_BUILDER) removeField(@Param('id') id: string) { return this.fieldService.remove(id); } @@ -79,7 +74,6 @@ export class FormBuilderController { @Post('admin/entity/field/:id/option') @ApiOperation({ summary: 'Create field Options ' }) @UseGuards(AdminAuthGuard) - @Permissions(PermissionEnum.MANAGE_FORM_BUILDER) createFieldOption(@Body() dto: CreateFieldOptionDto, @Param('id') id: string) { return this.fieldOptionService.create(id, dto); } @@ -101,7 +95,6 @@ export class FormBuilderController { @Patch('admin/entity/field/option/:id') @ApiOperation({ summary: 'Update field Option' }) @UseGuards(AdminAuthGuard) - @Permissions(PermissionEnum.MANAGE_FORM_BUILDER) updateFieldOption(@Param('id') id: string, @Body() dto: UpdateFieldOptionDto) { return this.fieldOptionService.update(id, dto); } @@ -109,7 +102,6 @@ export class FormBuilderController { @Delete('admin/entity/field/option/:id') @ApiOperation({ summary: 'Renopve field Option' }) @UseGuards(AdminAuthGuard) - @Permissions(PermissionEnum.MANAGE_FORM_BUILDER) removeFieldOption(@Param('id') id: string) { return this.fieldOptionService.remove(id); } diff --git a/src/modules/invoice/invoice.controller.ts b/src/modules/invoice/invoice.controller.ts index c771b19..953f344 100644 --- a/src/modules/invoice/invoice.controller.ts +++ b/src/modules/invoice/invoice.controller.ts @@ -50,12 +50,14 @@ export class InvoiceController { @Get('admin/invoice') @UseGuards(AdminAuthGuard) @ApiOperation({ summary: 'Get all invoices with pagination and filters' }) + @Permissions(PermissionEnum.VIEW_INVOICES) findAllAsAdmin(@Query() dto: FindInvoicesDto) { return this.invoiceService.findAllAsAdmin(dto); } @Get('admin/invoice/:id') @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.VIEW_INVOICES) @ApiOperation({ summary: 'Get one invoice by id (admin)' }) findOneAsAdmin(@Param('id') id: string) { return this.invoiceService.findOneAsAdmin(id); @@ -65,7 +67,7 @@ export class InvoiceController { @UseGuards(AdminAuthGuard) @Permissions(PermissionEnum.UPDATE_INVOICE) @ApiOperation({ summary: 'Update an invoice (admin)' }) - @ApiBody({ type: UpdateInvoiceDto }) + @Permissions(PermissionEnum.UPDATE_INVOICE) update(@Param('id') id: string, @Body() updateInvoiceDto: UpdateInvoiceDto) { return this.invoiceService.update(id, updateInvoiceDto); } diff --git a/src/modules/order/controllers/order.controller.ts b/src/modules/order/controllers/order.controller.ts index 6a5e4c4..5a4d7f3 100644 --- a/src/modules/order/controllers/order.controller.ts +++ b/src/modules/order/controllers/order.controller.ts @@ -55,6 +55,7 @@ export class OrderController { // Permission handled inside service @Get('admin/orders') @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.VIEW_ORDERS) @ApiOperation({ summary: 'Get all orders with pagination and filters' }) findAllAsAdmin(@Query() dto: FindOrdersDto, @AdminId() adminId: string) { return this.orderService.findOrdersAsAdmin(adminId, dto); @@ -62,6 +63,7 @@ export class OrderController { @Get('admin/orders/:id') @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.VIEW_ORDERS) @ApiOperation({ summary: 'order detail' }) orderDetailAsAdmin(@Param('id') orderId: string) { return this.orderService.findOrderOrFail(orderId); @@ -112,6 +114,7 @@ export class OrderController { @Get('admin/orders/:orderId/print') @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.VIEW_PRINT) @ApiOperation({ summary: 'Get order print' }) getPrint(@Param('orderId') orderId: string) { return this.orderService.getPrint(orderId); diff --git a/src/modules/payment/controllers/payment.controller.ts b/src/modules/payment/controllers/payment.controller.ts index da7e79d..8a098ae 100644 --- a/src/modules/payment/controllers/payment.controller.ts +++ b/src/modules/payment/controllers/payment.controller.ts @@ -5,7 +5,7 @@ import { Query, Delete, } from '@nestjs/common'; -// import { PaymentService } from '../services/payments.service'; +import { PaymentService } from '../services/payments.service'; import { ApiTags, ApiOperation, @@ -25,72 +25,72 @@ import { PermissionEnum } from 'src/common/enums/permission.enum'; @Controller() export class PaymentController { constructor( - // private readonly paymentService: PaymentService, + private readonly paymentService: PaymentService, ) { } - // @Post('public/payments/order/:id/pay') - // @UseGuards(AuthGuard) - // @ApiOperation({ summary: 'Pay for an order' }) - // payAnOrder(@Param('id') orderId: string, @Body() dto: PayOrderDto) { - // return this.paymentService.payOrder(orderId, dto); - // } + @Post('public/payments/invoice/:id/pay') + @UseGuards(AuthGuard) + @ApiOperation({ summary: 'Pay for an order' }) + payAnInvoice(@Param('id') invoiceId: string, @Body() dto: PayOrderDto) { + return this.paymentService.payInvoice(invoiceId, dto); + } - // @Post('public/payments/online/:token/verify') - // @UseGuards(AuthGuard) - // @ApiOperation({ summary: 'Verify online payment' }) - // verifyOnlinePayment(@Param('paymentId') token: string) { - // return this.paymentService.verifyOnlinePayment(token); - // } + @Post('public/payments/online/:token/verify') + @UseGuards(AuthGuard) + @ApiOperation({ summary: 'Verify online payment' }) + verifyOnlinePayment(@Param('paymentId') token: string) { + return this.paymentService.verifyOnlinePayment(token); + } - // @Get('public/payments') - // @ApiOperation({ summary: 'get all payments as user' }) - // findAllByUser(@UserId() userId: string, @Query() dto: FindPaymentsDto) { - // return this.paymentService.findAllByUser(dto, userId); - // } + @Get('public/payments') + @ApiOperation({ summary: 'get all payments as user' }) + findAllByUser(@UserId() userId: string, @Query() dto: FindPaymentsDto) { + return this.paymentService.findAllByUser(dto, userId); + } - // /*=============== Admin =============== */ + /*=============== Admin =============== */ - // @Post('admin/payments/order/:id/pay') - // @UseGuards(AdminAuthGuard) - // @Permissions(PermissionEnum.MANAGE_PAYMENTS) - // @ApiOperation({ summary: 'Pay for an order as Admin' }) - // payOrderAsAdmin(@Param('orderId') orderId: string, @AdminId() adminId: string, @Body() dto: PayOrderDto) { - // return this.paymentService.payOrder(orderId, dto, adminId); - // } + @Post('admin/payments/order/:id/pay') + @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.MANAGE_PAYMENTS) + @ApiOperation({ summary: 'Pay for an order as Admin' }) + payOrderAsAdmin(@Param('orderId') orderId: string, @AdminId() adminId: string, @Body() dto: PayOrderDto) { + return this.paymentService.payInvoice(orderId, dto, adminId); + } - // @Post('admin/payments/online/:token/verify') - // @UseGuards(AdminAuthGuard) - // @Permissions(PermissionEnum.MANAGE_PAYMENTS) - // @ApiOperation({ summary: 'Verify online payment as admin' }) - // verifyOnlinePaymentAsAdmin(@Param('paymentId') token: string) { - // return this.paymentService.verifyOnlinePayment(token); - // } + @Post('admin/payments/online/:token/verify') + @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.MANAGE_PAYMENTS) + @ApiOperation({ summary: 'Verify online payment as admin' }) + verifyOnlinePaymentAsAdmin(@Param('paymentId') token: string) { + return this.paymentService.verifyOnlinePayment(token); + } - // @Post('admin/payments/:paymentId/cash/verify') - // @UseGuards(AdminAuthGuard) - // @Permissions(PermissionEnum.MANAGE_PAYMENTS) - // @ApiOperation({ summary: 'Verify cash payment' }) - // confirmPayment(@Param('paymentId') paymentId: string) { - // return this.paymentService.confirmCashPayment(paymentId); - // } + @Post('admin/payments/:paymentId/cash/verify') + @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.MANAGE_PAYMENTS) + @ApiOperation({ summary: 'Verify cash payment' }) + confirmPayment(@Param('paymentId') paymentId: string) { + return this.paymentService.confirmCashPayment(paymentId); + } - // @Delete('admin/payments/:paymentId/cash/deny') - // @UseGuards(AdminAuthGuard) - // @Permissions(PermissionEnum.MANAGE_PAYMENTS) - // @ApiOperation({ summary: 'Deny cash payment' }) - // denyPayment(@Param('paymentId') paymentId: string) { - // return this.paymentService.denyCashPayment(paymentId); - // } + @Delete('admin/payments/:paymentId/cash/deny') + @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.MANAGE_PAYMENTS) + @ApiOperation({ summary: 'Deny cash payment' }) + denyPayment(@Param('paymentId') paymentId: string) { + return this.paymentService.denyCashPayment(paymentId); + } - // @Get('admin/payments') - // @UseGuards(AdminAuthGuard) - // @Permissions(PermissionEnum.MANAGE_PAYMENTS) - // @ApiOperation({ summary: 'get all payments as admin' }) - // findAllPayments(@Body() dto: FindPaymentsDto) { - // return this.paymentService.findAll(dto); - // } + @Get('admin/payments') + @UseGuards(AdminAuthGuard) + @Permissions(PermissionEnum.MANAGE_PAYMENTS) + @ApiOperation({ summary: 'get all payments as admin' }) + findAllPayments(@Body() dto: FindPaymentsDto) { + return this.paymentService.findAll(dto); + } } diff --git a/src/modules/payment/services/payments.service.ts b/src/modules/payment/services/payments.service.ts index 8018f0a..ca3604b 100644 --- a/src/modules/payment/services/payments.service.ts +++ b/src/modules/payment/services/payments.service.ts @@ -1,7 +1,7 @@ import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'; -import { PaymentGatewayEnum, PaymentMethodEnum, PaymentStatusEnum } from '../interface/payment'; +import { PaymentMethodEnum, PaymentStatusEnum } from '../interface/payment'; import { EntityManager } from '@mikro-orm/postgresql'; - import { Logger } from '@nestjs/common'; +import { Logger } from '@nestjs/common'; import { GatewayManager } from '../gateways/gateway.manager'; import { OrderPaymentContext } from '../interface/payment'; import { PaymentMessage, OrderMessage } from 'src/common/enums/message.enum'; @@ -38,7 +38,7 @@ export class PaymentService { private readonly invoiceService: InvoiceService, ) { } - async payOrder(invoiceId: string, dto: PayOrderDto, adminId?: string): Promise<{ paymentUrl: string | null }> { + async payInvoice(invoiceId: string, dto: PayOrderDto, adminId?: string): Promise<{ paymentUrl: string | null }> { const ctx = await this.loadAndValidateOrder(invoiceId, dto, adminId) @@ -63,8 +63,7 @@ export class PaymentService { private async loadAndValidateOrder(invoiceId: string, dto: PayOrderDto, adminId?: string): Promise { const { amount, method, attachments, description, gateway } = dto - // const order = await this.orderService.findOrderOrFail(invoiceId) - const invoice=await this.invoiceService.findOneOrFail(invoiceId) + const invoice = await this.invoiceService.findOneOrFail(invoiceId) if (!invoice.balance) { throw new NotFoundException('Balance is not set'); @@ -147,7 +146,7 @@ export class PaymentService { await em.persistAndFlush([payment, newCreditTransaction]); }); -//TODO + //TODO // this.eventEmitter.emit( // newCashPaymentEvent.name, // new newCashPaymentEvent(ctx.invoice.id, String(ctx.invoice?.invoiceNumber) || '', ctx.method, ctx.amount),