pos-be/src/modules/queue/domain/queue.orchestrator.ts

233 lines
8.6 KiB
TypeScript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { TicketDataService } from '../data/services/ticket.service';
import { QueueOrder } from './entities/order.entity';
import { Queue } from './entities/queue.entity';
import {
QueueDataService,
QueueOrderService,
QueueService,
} from '../data/services/queue.service';
import { RegisterQueueManager } from './usecases/register-queue.manager';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { RegisterQueueDto } from '../infrastructure/controllers/dto/register-queue.dto';
import { CustomerQueueSummaryManager } from './usecases/queue/customer-queue-summary.manager';
import { CustomerQueueDetailManager } from './usecases/queue/customer-queue-detail.manager';
import { CustomerQueueItemManager } from './usecases/queue/customer-queue-item.manager';
import { CustomerQueueItemListManager } from './usecases/queue/customer-queue-item-list.manager';
import { CustomerQueueListManager } from './usecases/queue/customer-queue-list.manager';
import { SplitQueueDto } from '../infrastructure/controllers/dto/split-queue.dto';
import { SplitQueueManager } from './usecases/split-queue.manager';
import { LoginQueueDto } from '../infrastructure/controllers/dto/login-queue.dto';
import * as moment from 'moment';
import { CustomerQueueTicketSummaryManager } from './usecases/queue/customer-queue-ticket.manager';
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
import { CustomerQueuePosItemManager } from './usecases/queue/customer-queue-pos-item.manager';
import { QueueOrderModel, QueueTicketModel } from '../data/models/queue.model';
import { CustomerQueueRecommendManager } from './usecases/queue/customer-queue-recommend.manager';
@Injectable()
export class QueueOrchestrator {
constructor(
public readonly dataService: TicketDataService,
public readonly transactionService: TransactionDataService,
private readonly queueService: QueueService,
private readonly queueOrderService: QueueOrderService,
private readonly registerQueueManager: RegisterQueueManager,
private readonly splitQueueManager: SplitQueueManager,
private readonly queueDataService: QueueDataService,
) {}
async loginCustomer(id: string): Promise<QueueOrder> {
try {
const order = await this.dataService.loginQueue(id);
const code = order.tickets[0].code ?? order.code;
const tickets = await this.dataService.ticketByCode(code);
order.tickets = tickets;
return order;
} catch (error) {
throw new UnauthorizedException({
message: 'Invoice tidak ditemukan',
error: 'INVOICE_NOT_FOUND',
});
}
}
async loginPhone(login: LoginQueueDto): Promise<QueueOrder> {
const { name, phone } = login;
const now = moment().format('DD/MM/YYYY');
try {
const order = await this.dataService.loginPhone(name, phone);
const code = order.tickets[0].code ?? order.code;
const tickets = await this.dataService.ticketByCode(code);
order.tickets = tickets;
return order;
} catch (error) {
throw new UnauthorizedException({
message: `Antrian atas nama ${name} dan nomor telepon ${phone} pada tanggal ${now} tidak ditemukan`,
error: 'INVOICE_NOT_FOUND',
});
}
}
async create(data: RegisterQueueDto): Promise<Queue> {
const queue = await this.queueService.getTicketItems(
data.ticket_id,
data.item_id,
);
const queueRequest: any = {
qty: data.qty,
item_id: queue.id,
};
this.registerQueueManager.setData(queueRequest);
this.registerQueueManager.setService(this.queueService, TABLE_NAME.QUEUE);
await this.registerQueueManager.execute();
return this.registerQueueManager.getResult();
}
async split(data: SplitQueueDto): Promise<QueueOrder> {
const queueIds = data.items.map((i) => i.queue_item_id);
const queue = await this.dataService.orderItems(data.order_id, queueIds);
const existTicket = await this.dataService.ticketByUser(
data.name,
data.phone,
);
if (existTicket) {
const itemTickets = this.itemsFromOrder(queue);
const items = data.items.map((item) => {
const item_id = itemTickets[item.queue_item_id];
return {
item_queue_id: item_id,
item_id: item_id,
qty: item.qty,
};
});
existTicket.items.push(...items);
await this.dataService.updateQueueTicket(existTicket);
data.items.forEach((item) => {
this.queueService.updateItemQty(item.queue_item_id, item.qty);
});
return queue;
}
this.splitQueueManager.setRequestData(data);
this.splitQueueManager.setData(queue);
this.splitQueueManager.setService(
this.queueOrderService,
TABLE_NAME.QUEUE_ORDER,
);
await this.splitQueueManager.execute();
return this.splitQueueManager.getResult();
}
itemsFromOrder(order: QueueOrderModel) {
const itemTickets = {};
order.tickets.forEach((ticket) => {
ticket.items.forEach((item) => {
itemTickets[item.id] = item.item_id;
});
});
return itemTickets;
}
async queuePOSTickets(order_id: string): Promise<any> {
const tickets = await this.dataService.queuePosTickets(order_id);
const manager = new CustomerQueuePosItemManager(tickets);
return manager.data;
}
async queueTickets(order_id: string): Promise<any> {
const tickets = await this.dataService.queueTickets(order_id);
const manager = new CustomerQueueSummaryManager(tickets);
return manager.data;
}
async queueTicketDetail(order_id: string, ticket_id: string): Promise<any> {
const tickets = await this.dataService.queueTicketItems(
order_id,
ticket_id,
);
const queueItemIds = this.getQueueItemFromTickets(tickets);
const queues = await this.queueService.queues(queueItemIds);
const manager = new CustomerQueueDetailManager(tickets);
manager.currentQueues(queues);
return manager.data;
}
async queueTicketSummary(order_id: string, ticket_id: string): Promise<any> {
const tickets = await this.dataService.queueTicketActive(
order_id,
ticket_id,
);
const manager = new CustomerQueueTicketSummaryManager(tickets);
return manager.data;
}
async queueItemDetail(order_id: string, item_id: string): Promise<any> {
const tickets = await this.dataService.queueItemTickets(order_id, item_id);
const manager = new CustomerQueueItemManager(tickets);
return manager.data;
}
async queueItemRecommendation(order_id: string): Promise<any> {
const tickets = await this.dataService.queueTickets(order_id);
const queueItemIds = this.getQueueItemFromTickets(tickets);
const recommendItems = await this.queueDataService.exclude(queueItemIds);
const recommendIds = recommendItems.map((item) => item.id);
const queues = await this.queueService.queues(recommendIds);
const manager = new CustomerQueueRecommendManager(tickets);
manager.currentQueues(queues);
return manager.recommend(recommendItems);
}
async queueItemSummary(): Promise<any> {
const recommendItems = await this.queueDataService.allQueue();
const recommendIds = recommendItems.map((item) => item.id);
const queues = await this.queueService.queues(recommendIds);
const manager = new CustomerQueueRecommendManager(null);
manager.currentQueues(queues);
return manager.recommend(recommendItems);
}
async queueItems(order_id: string): Promise<any> {
const tickets = await this.dataService.queueTickets(order_id);
const queueItemIds = this.getQueueItemFromTickets(tickets);
const queues = await this.queueService.queues(queueItemIds);
const manager = new CustomerQueueItemListManager(tickets);
manager.currentQueues(queues);
return manager.data;
}
async queueUniqueItems(order_id: string): Promise<any> {
const tickets = await this.dataService.queueUniqueTickets(order_id);
const queueItemIds = this.getQueueItemFromTickets(tickets);
const queues = await this.queueService.queues(queueItemIds);
const manager = new CustomerQueueItemListManager(tickets);
manager.currentQueues(queues);
return manager.data;
}
async queueOrderItems(order_id: string): Promise<any> {
const tickets = await this.dataService.queueTickets(order_id);
const manager = new CustomerQueueListManager(tickets);
return manager.data;
}
getQueueItemFromTickets(tickets: QueueTicketModel[]) {
const queueItemIds = tickets.map((ticket) => {
return ticket.items.map((item) => {
return item.item.item_queue_id;
});
});
return queueItemIds.flat();
}
}