payments event

This commit is contained in:
2026-02-22 16:46:25 +03:30
parent cb5aa7fde4
commit b64e654c08
5 changed files with 85 additions and 45 deletions
+9 -1
View File
@@ -47,6 +47,12 @@ export enum PermissionEnum {
MANAGE_CRITICISMS = 'manage_criticisms',
MANAGE_ANNOUNCEMENTS = 'manage_announcements',
// Notif Permsissions
NEW_REQUEST_NOTIFICATION='new_request_notification',
NEW_PAYMENT_NOTIFICATION='new_payment_notification',
}
/**
@@ -83,5 +89,7 @@ export const PermissionTitles: Record<PermissionEnum, string> = {
[PermissionEnum.MANAGE_PRINT]: "مدیریت فرم چاپ",
[PermissionEnum.MANAGE_LEARNINGS]: "مدیریت آموزش‌ها",
[PermissionEnum.MANAGE_CRITICISMS]: "مدیریت انتقادها و پیشنهادها",
[PermissionEnum.MANAGE_ANNOUNCEMENTS]: "مدیریت اطلاعیه‌ها"
[PermissionEnum.MANAGE_ANNOUNCEMENTS]: "مدیریت اطلاعیه‌ها",
[PermissionEnum.NEW_REQUEST_NOTIFICATION]: "",
[PermissionEnum.NEW_PAYMENT_NOTIFICATION]: ""
};
+10 -14
View File
@@ -1,20 +1,16 @@
import { PaymentMethodEnum } from "../interface/payment";
export class paymentSucceedEvent {
constructor(
public readonly orderId: string,
public readonly orderNumber: string,
public readonly paymentMethod: PaymentMethodEnum,
public readonly total: number
) { }
}
export class onlinePaymentSucceedEvent {
constructor(
public readonly paymentId: string,
public readonly orderId: string,
public readonly invoiceId: string,
public readonly invoiceNumber: string,
public readonly total: number,
) { }
}
export class newCashPaymentEvent {
constructor(
public readonly paymentId: string,
public readonly invoiceId: string,
public readonly orderNumber: string,
public readonly total: number,
) { }
@@ -1,35 +1,69 @@
import { Injectable, Logger } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { EntityManager } from '@mikro-orm/postgresql';
import { AdminRepository } from 'src/modules/admin/repositories/admin.repository';
import { onlinePaymentSucceedEvent, paymentSucceedEvent } from '../events/payment.events';
import { onlinePaymentSucceedEvent } from '../events/payment.events';
import { PermissionEnum } from 'src/common/enums/permission.enum';
import { NotifEvent } from 'src/modules/notification/interfaces/notification.interface';
import { NotificationService } from 'src/modules/notification/services/notification.service';
import { ConfigService } from '@nestjs/config';
// import { OrderService } from 'src/modules/order/providers/order.service';
import { Notification } from 'src/modules/notification/entities/notification.entity';
import { NotificationQueueService } from 'src/modules/notification/services/notification-queue.service';
@Injectable()
export class PaymentListeners {
private readonly logger = new Logger(PaymentListeners.name);
private orderCreatedSmsTemplateId: string;
private paymentSucceedSmsTemplateId: string;
constructor(
private readonly adminService: AdminRepository,
private readonly notificationService: NotificationService,
private readonly configService: ConfigService,
// private readonly orderService: OrderService,
) {
this.orderCreatedSmsTemplateId = this.configService.get<string>('SMS_PATTERN_ORDER_CREATED') ?? '123';
this.paymentSucceedSmsTemplateId = this.configService.get<string>('SMS_PATTERN_ONLINE_PAYMENT_SUCCEED') ?? '123';
private readonly adminRepository: AdminRepository,
private readonly em: EntityManager,
private readonly notificationQueueService: NotificationQueueService,
) {}
@OnEvent(onlinePaymentSucceedEvent.name)
async handleOnlinePaymentVerified(event: InstanceType<typeof onlinePaymentSucceedEvent>) {
try {
this.logger.log(
`Online payment verified: paymentId=${event.paymentId}, invoiceNumber=${event.invoiceNumber}, total=${event.total}`,
);
const admins = await this.adminRepository.findAdminsWithPermission(
PermissionEnum.NEW_PAYMENT_NOTIFICATION,
);
if (admins.length === 0) {
this.logger.log('No admins with NEW_PAYMENT_NOTIFICATION permission');
return;
}
private getPaymentMethodFarsi(method: string): string {
const methodMap: Record<string, string> = {
Cash: 'نقدی',
Wallet: 'کیف پول',
Online: 'آنلاین',
};
return methodMap[method] || method;
const body = `پرداخت آنلاین جدید: پیش‌فاکتور شماره ${event.invoiceNumber} به مبلغ ${event.total.toLocaleString('fa-IR')} تومان`;
const notifications = admins.map((admin) =>
this.em.create(Notification, {
admin,
title: NotifEvent.PAYMENT_SUCCESS,
content: body,
}),
);
await this.em.persistAndFlush(notifications);
await this.notificationQueueService.addBulkInAppNotifications(
notifications.map((n) => ({
recipient: { adminId: n.admin!.id },
subject: NotifEvent.PAYMENT_SUCCESS,
body,
notificationId: n.id,
})),
);
this.logger.log(
`Notification sent to ${admins.length} admin(s) for online payment ${event.paymentId}`,
);
} catch (error) {
this.logger.error(
`Failed to send notification for online payment ${event.paymentId}`,
error instanceof Error ? error.stack : String(error),
);
}
}
// @OnEvent(paymentSucceedEvent.name)
@@ -6,7 +6,7 @@ import { GatewayManager } from '../gateways/gateway.manager';
import { OrderPaymentContext } from '../interface/payment';
import { PaymentMessage, OrderMessage } from 'src/common/enums/message.enum';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { onlinePaymentSucceedEvent, paymentSucceedEvent } from '../events/payment.events';
import { onlinePaymentSucceedEvent, newCashPaymentEvent } from '../events/payment.events';
import { OrderService } from 'src/modules/order/providers/order.service';
import { PayOrderDto } from '../dto/pay-order.dto';
import { PaymentRepository } from '../repositories/payment.repository';
@@ -147,11 +147,11 @@ export class PaymentService {
await em.persistAndFlush([payment, newCreditTransaction]);
});
this.eventEmitter.emit(
paymentSucceedEvent.name,
new paymentSucceedEvent(ctx.invoice.id, String(ctx.invoice?.invoiceNumber) || '', ctx.method, ctx.amount),
);
//TODO
// this.eventEmitter.emit(
// newCashPaymentEvent.name,
// new newCashPaymentEvent(ctx.invoice.id, String(ctx.invoice?.invoiceNumber) || '', ctx.method, ctx.amount),
// );
}
private async handleOnlinePayment(ctx: OrderPaymentContext): Promise<{ paymentUrl: string }> {
+4 -2
View File
@@ -16,7 +16,7 @@ export const rolesData: RoleConfig[] = [
},
{
name: 'admin',
name: 'interior-admin',
title: 'مدیر داخلی',
isSystem: true,
permissionFilter: (name: PermissionEnum) => name !==PermissionEnum.MANAGE_ROLES
@@ -26,7 +26,9 @@ export const rolesData: RoleConfig[] = [
name: 'accountant',
title: 'حسابدار',
isSystem: true,
permissionFilter: (name: PermissionEnum) => name==PermissionEnum.MANAGE_PAYMENTS
permissionFilter: (name: PermissionEnum) =>
name === PermissionEnum.MANAGE_PAYMENTS ||
name === PermissionEnum.NEW_PAYMENT_NOTIFICATION,
},
{