import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service'; import { TransactionChangeStatusEvent, TransactionCreateQueueEvent, } from 'src/modules/transaction/transaction/domain/entities/event/transaction-change-status.event'; import { TicketDataService } from '../../data/services/ticket.service'; import { QueueOrder } from '../../domain/entities/order.entity'; import { QueueTicket } from '../../domain/entities/ticket.entity'; import { QueueItem } from '../../domain/entities/queue-item.entity'; import * as moment from 'moment'; import { TransactionUserType } from 'src/modules/transaction/transaction/constants'; import { RegisterQueueManager } from '../../domain/usecases/register-queue.manager'; import { RegisterQueueDto } from '../controllers/dto/register-queue.dto'; import { QueueService } from '../../data/services/queue.service'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { QueueBucketReadService } from '../../data/services/queue-bucket'; @EventsHandler(TransactionChangeStatusEvent, TransactionCreateQueueEvent) export class QueueTransactionHandler implements IEventHandler { constructor( private readonly dataService: TransactionDataService, private readonly ticketService: TicketDataService, private readonly queueService: QueueService, private readonly bucketService: QueueBucketReadService, ) {} async handle(event: TransactionChangeStatusEvent) { const process_data = event.data.data; /** * If data still in process (not settled) then don't create the queue order */ if (process_data?.status != 'settled') return; const transaction = await this.dataService.getOneByOptions({ where: { id: event.data.id, }, relations: ['customer_category', 'items', 'items.item'], }); const date = transaction.booking_date ?? transaction.invoice_date; const queue_date = moment(date, 'YYYY-MM-DD').unix(); const { id, customer_name, customer_phone, invoice_code } = transaction; const customerOrder = { code: invoice_code, customer: customer_name, phone: customer_phone, date: queue_date * 1000, transaction_id: id, }; const items = transaction.items .filter((item) => item.item.use_queue) .map((item) => { return { item_id: item.item_id, qty: item.qty, }; }); const ticket: QueueTicket = { ...customerOrder, items }; const order: QueueOrder = { ...customerOrder, tickets: [ticket] }; const queueOrder = await this.ticketService.createQueueOrder(order); if ( transaction.customer_category?.has_vip_pass || transaction.customer_type === TransactionUserType.VIP ) { queueOrder.tickets.forEach((ticket) => { const ticket_id = ticket.id; ticket.items.forEach((item) => { const item_id = item.item_id; // for (let i = 0; i < item.qty; i++) { const payload = { item_id, ticket_id, qty: item.qty, }; this.create(payload); // } }); }); } } async create(data: RegisterQueueDto): Promise { const queue = await this.queueService.getTicketItems( data.ticket_id, data.item_id, ); const queueRequest: any = { qty: data.qty, item_id: queue.id, vip: true, }; const registerQueueManager = new RegisterQueueManager(this.bucketService); registerQueueManager.setData(queueRequest); registerQueueManager.setService(this.queueService, TABLE_NAME.QUEUE); await registerQueueManager.execute(); } }