From 93b1208278bcd0004bad3120a0ef85c071b64564 Mon Sep 17 00:00:00 2001 From: shancheas Date: Tue, 29 Oct 2024 10:30:57 +0700 Subject: [PATCH] refactor: change code to manager --- .../queue/data/services/ticket.service.ts | 21 ++- .../queue/domain/queue.orchestrator.ts | 141 ++---------------- .../queue/customer-queue-detail.manager.ts | 51 +++++++ .../queue/customer-queue-item-list.manager.ts | 41 +++++ .../queue/customer-queue-item.manager.ts | 32 ++++ .../queue/customer-queue-summary.manager.ts | 21 +++ .../usecases/queue/customer-queue.manager.ts | 58 +++++++ 7 files changed, 233 insertions(+), 132 deletions(-) create mode 100644 src/modules/queue/domain/usecases/queue/customer-queue-detail.manager.ts create mode 100644 src/modules/queue/domain/usecases/queue/customer-queue-item-list.manager.ts create mode 100644 src/modules/queue/domain/usecases/queue/customer-queue-item.manager.ts create mode 100644 src/modules/queue/domain/usecases/queue/customer-queue-summary.manager.ts create mode 100644 src/modules/queue/domain/usecases/queue/customer-queue.manager.ts diff --git a/src/modules/queue/data/services/ticket.service.ts b/src/modules/queue/data/services/ticket.service.ts index f2cc833..7d509e3 100644 --- a/src/modules/queue/data/services/ticket.service.ts +++ b/src/modules/queue/data/services/ticket.service.ts @@ -34,7 +34,12 @@ export class TicketDataService extends BaseDataService { async queueTickets(order_id: string): Promise { return this.repo.find({ - relations: ['items', 'items.item', 'items.item.item_queue'], + relations: [ + 'items', + 'items.queue', + 'items.item', + 'items.item.item_queue', + ], where: { order_id, }, @@ -46,7 +51,12 @@ export class TicketDataService extends BaseDataService { ticket_id: string, ): Promise { return this.repo.find({ - relations: ['items', 'items.item', 'items.item.item_queue'], + relations: [ + 'items', + 'items.queue', + 'items.item', + 'items.item.item_queue', + ], where: { order_id, id: ticket_id, @@ -59,7 +69,12 @@ export class TicketDataService extends BaseDataService { item_id: string, ): Promise { return this.repo.find({ - relations: ['items', 'items.item', 'items.item.item_queue'], + relations: [ + 'items', + 'items.queue', + 'items.item', + 'items.item.item_queue', + ], where: { order_id, items: [{ item_id }, { item: { item_queue: { id: item_id } } }], diff --git a/src/modules/queue/domain/queue.orchestrator.ts b/src/modules/queue/domain/queue.orchestrator.ts index c876fd3..aa61f48 100644 --- a/src/modules/queue/domain/queue.orchestrator.ts +++ b/src/modules/queue/domain/queue.orchestrator.ts @@ -1,12 +1,15 @@ import { Injectable, UnauthorizedException } from '@nestjs/common'; import { TicketDataService } from '../data/services/ticket.service'; import { QueueOrder } from './entities/order.entity'; -import { QueueItemModel } from '../data/models/queue.model'; import { Queue } from './entities/queue.entity'; import { 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'; @Injectable() export class QueueOrchestrator { @@ -44,28 +47,8 @@ export class QueueOrchestrator { async queueTickets(order_id: string): Promise { const tickets = await this.dataService.queueTickets(order_id); - return tickets.map((ticket) => { - const totalActivities = ticket.items.length; - const totalTickets = ticket.items.reduce( - (acc, item) => acc + item.qty, - 0, - ); - const totalUsed = 0; - const totalQueue = 0; - return { - id: ticket.id, - code: ticket.code, - customer: ticket.customer, - phone: ticket.phone, - date: ticket.date, - summary: { - total_activities: totalActivities, - total_tickets: totalTickets, - total_used: totalUsed, - total_queue: totalQueue, - }, - }; - }); + const manager = new CustomerQueueSummaryManager(tickets); + return manager.data; } async queueTicketDetail(order_id: string, ticket_id: string): Promise { @@ -73,119 +56,19 @@ export class QueueOrchestrator { order_id, ticket_id, ); - return tickets.map((ticket) => { - const totalActivities = ticket.items.length; - const totalTickets = ticket.items.reduce( - (acc, item) => acc + item.qty, - 0, - ); - const totalUsed = 0; - const totalQueue = 0; - return { - id: ticket.id, - code: ticket.code, - customer: ticket.customer, - phone: ticket.phone, - date: ticket.date, - summary: { - total_activities: totalActivities, - total_tickets: totalTickets, - total_used: totalUsed, - total_queue: totalQueue, - }, - items: ticket.items.map((item) => { - return { - id: item.item_id, - item_queue_id: item.id, - title: item.item.item_queue?.name ?? item.item.name, - image_url: item.item.image_url, - summary: { - total_tickets: item.qty, - total_used: 0, - total_queue: 1, - }, - queue: [ - { - code: 'A001', - qty: 1, - time: '15:00', - status: 'waiting', - }, - ], - queue_condition: { - available: true, - average: 12, - nearest: '13:10', - crowded_level: 20, - available_time: '15:00', - }, - }; - }), - }; - }); + const manager = new CustomerQueueDetailManager(tickets); + return manager.data; } async queueItemDetail(order_id: string, item_id: string): Promise { const tickets = await this.dataService.queueItemTickets(order_id, item_id); - return tickets.map((ticket) => { - const totalActivities = ticket.items.length; - const totalTickets = ticket.items.reduce( - (acc, item) => acc + item.qty, - 0, - ); - const totalUsed = 0; - const totalQueue = 0; - return { - id: ticket.id, - code: ticket.code, - customer: ticket.customer, - phone: ticket.phone, - date: ticket.date, - summary: { - total_activities: totalActivities, - total_tickets: totalTickets, - total_used: totalUsed, - total_queue: totalQueue, - }, - queue: [ - { - code: 'A001', - qty: 1, - time: '15:00', - status: 'waiting', - }, - ], - }; - }); + const manager = new CustomerQueueItemManager(tickets); + return manager.data; } async queueItems(order_id: string): Promise { const tickets = await this.dataService.queueTickets(order_id); - const ticketItems = {}; - - tickets.forEach((ticket) => { - ticket.items.forEach((item) => { - const item_id = item.item.item_queue?.id ?? item.item.id; - const currentItem = ticketItems[item_id]; - ticketItems[item_id] = currentItem ? [...currentItem, item] : [item]; - }); - }); - - return Object.values(ticketItems).map((items) => { - const item = items[0]; - const item_qty = items.reduce((acc, item) => acc + item.qty, 0); - return { - id: item.item_id, - title: item.item.item_queue?.name ?? item.item.name, - image_url: item.item.image_url, - qty: item_qty, - - available: true, - average: 12, - nearest: '13:10', - crowded_level: 20, - available_time: '15:00', - }; - }); + const manager = new CustomerQueueItemListManager(tickets); + return manager.data; } } diff --git a/src/modules/queue/domain/usecases/queue/customer-queue-detail.manager.ts b/src/modules/queue/domain/usecases/queue/customer-queue-detail.manager.ts new file mode 100644 index 0000000..0ce404d --- /dev/null +++ b/src/modules/queue/domain/usecases/queue/customer-queue-detail.manager.ts @@ -0,0 +1,51 @@ +import { CustomerQueueManager } from './customer-queue.manager'; + +export class CustomerQueueDetailManager extends CustomerQueueManager { + get data() { + return this.tickets.map((ticket) => { + return { + id: ticket.id, + code: ticket.code, + customer: ticket.customer, + phone: ticket.phone, + date: ticket.date, + summary: { + total_activities: this.totalActivities(ticket), + total_tickets: this.totalTickets(ticket), + total_used: this.totalUsedTickets(ticket), + total_queue: this.totalQueueTickets(ticket), + }, + items: ticket.items.map((item) => { + return { + id: item.item_id, + item_queue_id: item.id, + title: item.item.item_queue?.name ?? item.item.name, + image_url: item.item.image_url, + summary: { + total_tickets: item.qty, + total_used: this.totalUsedItems(item), + total_queue: this.totalQueueItems(item), + }, + queue: item.queue + .sort((a, b) => b.time - a.time) + .map((q) => { + return { + code: q.code, + qty: q.qty, + time: this.toTime(q.time), + status: q.status, + }; + }), + queue_condition: { + available: true, + average: 12, + nearest: '13:10', + crowded_level: 20, + available_time: '15:00', + }, + }; + }), + }; + }); + } +} diff --git a/src/modules/queue/domain/usecases/queue/customer-queue-item-list.manager.ts b/src/modules/queue/domain/usecases/queue/customer-queue-item-list.manager.ts new file mode 100644 index 0000000..8f0bd69 --- /dev/null +++ b/src/modules/queue/domain/usecases/queue/customer-queue-item-list.manager.ts @@ -0,0 +1,41 @@ +import { QueueItemModel } from 'src/modules/queue/data/models/queue.model'; +import { CustomerQueueManager } from './customer-queue.manager'; + +export class CustomerQueueItemListManager extends CustomerQueueManager { + get data() { + const tickets = this.tickets; + const ticketItems = {}; + + tickets.forEach((ticket) => { + ticket.items.forEach((item) => { + const item_id = item.item.item_queue?.id ?? item.item.id; + const currentItem = ticketItems[item_id]; + ticketItems[item_id] = currentItem ? [...currentItem, item] : [item]; + }); + }); + + return Object.values(ticketItems).map((items) => { + const item = items[0]; + const item_qty = items.reduce((acc, item) => acc + item.qty, 0); + return { + id: item.item_id, + title: item.item.item_queue?.name ?? item.item.name, + image_url: item.item.image_url, + qty: item_qty, + + available: true, + average: 12, + nearest: '13:10', + crowded_level: 20, + available_time: '15:00', + queue_condition: { + available: true, + average: 12, + nearest: '13:10', + crowded_level: 20, + available_time: '15:00', + }, + }; + }); + } +} diff --git a/src/modules/queue/domain/usecases/queue/customer-queue-item.manager.ts b/src/modules/queue/domain/usecases/queue/customer-queue-item.manager.ts new file mode 100644 index 0000000..af4aa9d --- /dev/null +++ b/src/modules/queue/domain/usecases/queue/customer-queue-item.manager.ts @@ -0,0 +1,32 @@ +import { CustomerQueueManager } from './customer-queue.manager'; + +export class CustomerQueueItemManager extends CustomerQueueManager { + get data() { + return this.tickets.map((ticket) => { + const item = ticket.items[0]; + return { + id: ticket.id, + code: ticket.code, + customer: ticket.customer, + phone: ticket.phone, + date: ticket.date, + summary: { + total_activities: this.totalActivities(ticket), + total_tickets: this.totalTickets(ticket), + total_used: this.totalUsedTickets(ticket), + total_queue: this.totalQueueTickets(ticket), + }, + queue: item.queue + .sort((a, b) => b.time - a.time) + .map((q) => { + return { + code: q.code, + qty: q.qty, + time: this.toTime(q.time), + status: q.status, + }; + }), + }; + }); + } +} diff --git a/src/modules/queue/domain/usecases/queue/customer-queue-summary.manager.ts b/src/modules/queue/domain/usecases/queue/customer-queue-summary.manager.ts new file mode 100644 index 0000000..e56ffee --- /dev/null +++ b/src/modules/queue/domain/usecases/queue/customer-queue-summary.manager.ts @@ -0,0 +1,21 @@ +import { CustomerQueueManager } from './customer-queue.manager'; + +export class CustomerQueueSummaryManager extends CustomerQueueManager { + get data() { + return this.tickets.map((ticket) => { + return { + id: ticket.id, + code: ticket.code, + customer: ticket.customer, + phone: ticket.phone, + date: ticket.date, + summary: { + total_activities: this.totalActivities(ticket), + total_tickets: this.totalTickets(ticket), + total_used: this.totalUsedTickets(ticket), + total_queue: this.totalQueueTickets(ticket), + }, + }; + }); + } +} diff --git a/src/modules/queue/domain/usecases/queue/customer-queue.manager.ts b/src/modules/queue/domain/usecases/queue/customer-queue.manager.ts new file mode 100644 index 0000000..5b95ba1 --- /dev/null +++ b/src/modules/queue/domain/usecases/queue/customer-queue.manager.ts @@ -0,0 +1,58 @@ +import { + QueueItemModel, + QueueTicketModel, +} from '../../../data/models/queue.model'; + +export class CustomerQueueManager { + constructor(protected readonly tickets: QueueTicketModel[]) {} + get data(): any { + return this.tickets; + } + + toTime(timestamp: number): string { + // js function to convert timestamp (1729739455000) to time with format HH:mm + const date = new Date(timestamp / 1000); + const hours = date.getHours() + 7; + const minutes = date.getMinutes(); + return `${hours < 10 ? '0' : ''}${hours}:${ + minutes < 10 ? '0' : '' + }${minutes}`; + } + + totalActivities(ticket: QueueTicketModel): number { + return ticket.items.length; + } + + totalTickets(ticket: QueueTicketModel): number { + return ticket.items.reduce((acc, item) => acc + item.qty, 0); + } + + totalUsedItems(item: QueueItemModel): number { + return item.queue + .filter((q) => ['done', 'called'].includes(q.status)) + .reduce((acc, item) => acc + item.qty, 0); + } + + totalUsedTickets(ticket: QueueTicketModel): number { + const tickets = ticket.items.map((item) => { + return this.totalUsedItems(item); + }); + + const reducer = (accumulator, currentValue) => accumulator + currentValue; + return tickets.reduce(reducer, 0); + } + + totalQueueItems(item: QueueItemModel): number { + return item.queue + .filter((q) => ['waiting'].includes(q.status)) + .reduce((acc, item) => acc + item.qty, 0); + } + totalQueueTickets(ticket: QueueTicketModel): number { + const tickets = ticket.items.map((item) => { + return this.totalQueueItems(item); + }); + + const reducer = (accumulator, currentValue) => accumulator + currentValue; + return tickets.reduce(reducer, 0); + } +}