payments event
This commit is contained in:
@@ -47,6 +47,12 @@ export enum PermissionEnum {
|
|||||||
MANAGE_CRITICISMS = 'manage_criticisms',
|
MANAGE_CRITICISMS = 'manage_criticisms',
|
||||||
|
|
||||||
MANAGE_ANNOUNCEMENTS = 'manage_announcements',
|
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_PRINT]: "مدیریت فرم چاپ",
|
||||||
[PermissionEnum.MANAGE_LEARNINGS]: "مدیریت آموزشها",
|
[PermissionEnum.MANAGE_LEARNINGS]: "مدیریت آموزشها",
|
||||||
[PermissionEnum.MANAGE_CRITICISMS]: "مدیریت انتقادها و پیشنهادها",
|
[PermissionEnum.MANAGE_CRITICISMS]: "مدیریت انتقادها و پیشنهادها",
|
||||||
[PermissionEnum.MANAGE_ANNOUNCEMENTS]: "مدیریت اطلاعیهها"
|
[PermissionEnum.MANAGE_ANNOUNCEMENTS]: "مدیریت اطلاعیهها",
|
||||||
|
[PermissionEnum.NEW_REQUEST_NOTIFICATION]: "",
|
||||||
|
[PermissionEnum.NEW_PAYMENT_NOTIFICATION]: ""
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 {
|
export class onlinePaymentSucceedEvent {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly paymentId: string,
|
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 orderNumber: string,
|
||||||
public readonly total: number,
|
public readonly total: number,
|
||||||
) { }
|
) { }
|
||||||
|
|||||||
@@ -1,35 +1,69 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { OnEvent } from '@nestjs/event-emitter';
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
import { AdminRepository } from 'src/modules/admin/repositories/admin.repository';
|
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 { PermissionEnum } from 'src/common/enums/permission.enum';
|
||||||
import { NotifEvent } from 'src/modules/notification/interfaces/notification.interface';
|
import { NotifEvent } from 'src/modules/notification/interfaces/notification.interface';
|
||||||
import { NotificationService } from 'src/modules/notification/services/notification.service';
|
import { Notification } from 'src/modules/notification/entities/notification.entity';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { NotificationQueueService } from 'src/modules/notification/services/notification-queue.service';
|
||||||
// import { OrderService } from 'src/modules/order/providers/order.service';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PaymentListeners {
|
export class PaymentListeners {
|
||||||
private readonly logger = new Logger(PaymentListeners.name);
|
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 getPaymentMethodFarsi(method: string): string {
|
constructor(
|
||||||
const methodMap: Record<string, string> = {
|
private readonly adminRepository: AdminRepository,
|
||||||
Cash: 'نقدی',
|
private readonly em: EntityManager,
|
||||||
Wallet: 'کیف پول',
|
private readonly notificationQueueService: NotificationQueueService,
|
||||||
Online: 'آنلاین',
|
) {}
|
||||||
};
|
|
||||||
return methodMap[method] || method;
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
// @OnEvent(paymentSucceedEvent.name)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { GatewayManager } from '../gateways/gateway.manager';
|
|||||||
import { OrderPaymentContext } from '../interface/payment';
|
import { OrderPaymentContext } from '../interface/payment';
|
||||||
import { PaymentMessage, OrderMessage } from 'src/common/enums/message.enum';
|
import { PaymentMessage, OrderMessage } from 'src/common/enums/message.enum';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
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 { OrderService } from 'src/modules/order/providers/order.service';
|
||||||
import { PayOrderDto } from '../dto/pay-order.dto';
|
import { PayOrderDto } from '../dto/pay-order.dto';
|
||||||
import { PaymentRepository } from '../repositories/payment.repository';
|
import { PaymentRepository } from '../repositories/payment.repository';
|
||||||
@@ -147,11 +147,11 @@ export class PaymentService {
|
|||||||
|
|
||||||
await em.persistAndFlush([payment, newCreditTransaction]);
|
await em.persistAndFlush([payment, newCreditTransaction]);
|
||||||
});
|
});
|
||||||
|
//TODO
|
||||||
this.eventEmitter.emit(
|
// this.eventEmitter.emit(
|
||||||
paymentSucceedEvent.name,
|
// newCashPaymentEvent.name,
|
||||||
new paymentSucceedEvent(ctx.invoice.id, String(ctx.invoice?.invoiceNumber) || '', ctx.method, ctx.amount),
|
// new newCashPaymentEvent(ctx.invoice.id, String(ctx.invoice?.invoiceNumber) || '', ctx.method, ctx.amount),
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleOnlinePayment(ctx: OrderPaymentContext): Promise<{ paymentUrl: string }> {
|
private async handleOnlinePayment(ctx: OrderPaymentContext): Promise<{ paymentUrl: string }> {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const rolesData: RoleConfig[] = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'admin',
|
name: 'interior-admin',
|
||||||
title: 'مدیر داخلی',
|
title: 'مدیر داخلی',
|
||||||
isSystem: true,
|
isSystem: true,
|
||||||
permissionFilter: (name: PermissionEnum) => name !==PermissionEnum.MANAGE_ROLES
|
permissionFilter: (name: PermissionEnum) => name !==PermissionEnum.MANAGE_ROLES
|
||||||
@@ -26,7 +26,9 @@ export const rolesData: RoleConfig[] = [
|
|||||||
name: 'accountant',
|
name: 'accountant',
|
||||||
title: 'حسابدار',
|
title: 'حسابدار',
|
||||||
isSystem: true,
|
isSystem: true,
|
||||||
permissionFilter: (name: PermissionEnum) => name==PermissionEnum.MANAGE_PAYMENTS
|
permissionFilter: (name: PermissionEnum) =>
|
||||||
|
name === PermissionEnum.MANAGE_PAYMENTS ||
|
||||||
|
name === PermissionEnum.NEW_PAYMENT_NOTIFICATION,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user