pos-be/src/modules/configuration/mail/domain/handlers/payment-transaction.handler.ts

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);
}
}
}