278 lines
8.0 KiB
TypeScript
278 lines
8.0 KiB
TypeScript
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<TransactionChangeStatusEvent>
|
|
{
|
|
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: `
|
|
<p>Refund Items:</p>
|
|
<ul style="padding-left:15px">
|
|
${transaction?.['refund']?.refund_items
|
|
?.filter((item) => Number(item.qty_refund) > 0)
|
|
.map((item) => {
|
|
return `
|
|
<li>${item.qty_refund} ${item.transaction_item.item_name} </li>
|
|
`;
|
|
})}
|
|
</ul>`,
|
|
});
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|