import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; import { STATUS } from 'src/core/strings/constants/base.constants'; import { PaymentMethodDataService } from 'src/modules/transaction/payment-method/data/services/payment-method-data.service'; import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service'; import { TransactionChangeStatusEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-change-status.event'; import { sendEmail } from '../helpers/send-email.helper'; import { InvoiceType } from 'src/modules/configuration/export/constants'; import { GeneratePdf } from 'src/modules/configuration/export/domain/templates/helpers/generate-pdf.helper'; import { TransactionUpdatedEvent } from 'src/modules/transaction/transaction/domain/entities/event/transaction-updated.event'; import { RefundChangeStatusEvent } from 'src/modules/transaction/refund/domain/entities/event/refund-change-status.event'; import { RefundCreatedEvent } from 'src/modules/transaction/refund/domain/entities/event/refund-created.event'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; @EventsHandler( TransactionChangeStatusEvent, TransactionUpdatedEvent, RefundChangeStatusEvent, RefundCreatedEvent, ) export class PaymentTransactionHandler implements IEventHandler { constructor( private dataService: TransactionDataService, private paymentService: PaymentMethodDataService, ) {} async handle(event: TransactionChangeStatusEvent) { try { const old_data = event.data.old; const current_data = event.data.data; const data_id = current_data.transaction_id ?? event.data.id; const from_refund = event.data.module == TABLE_NAME.REFUND; const payments = await this.paymentService.getManyByOptions({ where: { status: STATUS.ACTIVE, }, }); const transaction = await this.dataService.getOneByOptions({ where: { id: data_id, }, relations: [ 'items', 'refunds', 'refunds.refund_items', 'refunds.refund_items.transaction_item', ], }); Object.assign(transaction, { booking_date: new Date(transaction.booking_date).toDateString(), booking_date_before: new Date( transaction.booking_date_before, ).toDateString(), email: transaction.customer_email, payment_methods: payments, }); const refund = transaction?.['refunds']?.find( (refund) => ![STATUS.CANCEL].includes(refund.status), ); if (refund) { Object.assign(refund, { refund_date: new Date(refund?.refund_date).toDateString(), request_date: new Date(refund?.request_date).toDateString(), refund_total: Number(refund?.refund_total).toLocaleString('id-ID', { style: 'currency', currency: 'IDR', }), }); Object.assign(transaction, { refund: refund, }); } if (transaction?.['refund']?.refund_items.length > 0) { Object.assign(transaction, { refund_items: `

Refund Items:

`, }); } if (!transaction.customer_email) return; // refund request if ( from_refund && transaction['refund'] && [STATUS.DRAFT].includes(transaction['refund'].status) ) { const pdf = await GeneratePdf( transaction, InvoiceType.REFUND_REQUEST, payments, ); sendEmail( [ { ...transaction, payment_total: Number(transaction.payment_total).toLocaleString( 'id-ID', { style: 'currency', currency: 'IDR', }, ), }, ], InvoiceType.REFUND_REQUEST, pdf, ); } // refund confirmation else if ( from_refund && transaction['refund'] && transaction['refund'].status == STATUS.REFUNDED ) { const pdf = await GeneratePdf( transaction, InvoiceType.REFUND_CONFIRMATION, payments, ); sendEmail( [ { ...transaction, payment_total: Number(transaction.payment_total).toLocaleString( 'id-ID', { style: 'currency', currency: 'IDR', }, ), }, ], InvoiceType.REFUND_CONFIRMATION, pdf, ); } // payment settled else if ( !from_refund && old_data.status != current_data.status && [STATUS.ACTIVE, STATUS.SETTLED].includes(current_data.status) ) { const pdf = await GeneratePdf( transaction, InvoiceType.PAYMENT_CONFIRMATION, payments, ); sendEmail( [ { ...transaction, payment_total: Number(transaction.payment_total).toLocaleString( 'id-ID', { style: 'currency', currency: 'IDR', }, ), }, ], InvoiceType.PAYMENT_CONFIRMATION, pdf, ); } // payment confirm to pending else if ( !from_refund && old_data.status != current_data.status && [STATUS.PENDING].includes(current_data.status) ) { const pdf = await GeneratePdf( transaction, InvoiceType.BOOKING_INVOICE, payments, ); sendEmail( [ { ...transaction, payment_total: Number(transaction.payment_total).toLocaleString( 'id-ID', { style: 'currency', currency: 'IDR', }, ), }, ], InvoiceType.BOOKING_INVOICE, pdf, ); } // payment expired else if ( !from_refund && old_data.status != current_data.status && [STATUS.PENDING].includes(current_data.status) ) { const pdf = await GeneratePdf( transaction, InvoiceType.INVOICE_EXPIRED, payments, ); sendEmail( [ { ...transaction, payment_total: Number(transaction.payment_total).toLocaleString( 'id-ID', { style: 'currency', currency: 'IDR', }, ), }, ], InvoiceType.INVOICE_EXPIRED, pdf, ); } // change booking date else if ( !from_refund && old_data.booking_date != current_data.booking_date && [STATUS.SETTLED, STATUS.ACTIVE, STATUS.PENDING].includes( current_data.status, ) ) { const pdf = await GeneratePdf( transaction, InvoiceType.BOOKING_DATE_CHANGE, payments, ); sendEmail( [ { ...transaction, payment_total: Number(transaction.payment_total).toLocaleString( 'id-ID', { style: 'currency', currency: 'IDR', }, ), }, ], InvoiceType.BOOKING_DATE_CHANGE, pdf, ); } } catch (error) { console.log(error); } } }