refactor: change code to manager
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
86251f43a2
commit
93b1208278
|
@ -34,7 +34,12 @@ export class TicketDataService extends BaseDataService<QueueTicket> {
|
||||||
|
|
||||||
async queueTickets(order_id: string): Promise<QueueTicketModel[]> {
|
async queueTickets(order_id: string): Promise<QueueTicketModel[]> {
|
||||||
return this.repo.find({
|
return this.repo.find({
|
||||||
relations: ['items', 'items.item', 'items.item.item_queue'],
|
relations: [
|
||||||
|
'items',
|
||||||
|
'items.queue',
|
||||||
|
'items.item',
|
||||||
|
'items.item.item_queue',
|
||||||
|
],
|
||||||
where: {
|
where: {
|
||||||
order_id,
|
order_id,
|
||||||
},
|
},
|
||||||
|
@ -46,7 +51,12 @@ export class TicketDataService extends BaseDataService<QueueTicket> {
|
||||||
ticket_id: string,
|
ticket_id: string,
|
||||||
): Promise<QueueTicketModel[]> {
|
): Promise<QueueTicketModel[]> {
|
||||||
return this.repo.find({
|
return this.repo.find({
|
||||||
relations: ['items', 'items.item', 'items.item.item_queue'],
|
relations: [
|
||||||
|
'items',
|
||||||
|
'items.queue',
|
||||||
|
'items.item',
|
||||||
|
'items.item.item_queue',
|
||||||
|
],
|
||||||
where: {
|
where: {
|
||||||
order_id,
|
order_id,
|
||||||
id: ticket_id,
|
id: ticket_id,
|
||||||
|
@ -59,7 +69,12 @@ export class TicketDataService extends BaseDataService<QueueTicket> {
|
||||||
item_id: string,
|
item_id: string,
|
||||||
): Promise<QueueTicketModel[]> {
|
): Promise<QueueTicketModel[]> {
|
||||||
return this.repo.find({
|
return this.repo.find({
|
||||||
relations: ['items', 'items.item', 'items.item.item_queue'],
|
relations: [
|
||||||
|
'items',
|
||||||
|
'items.queue',
|
||||||
|
'items.item',
|
||||||
|
'items.item.item_queue',
|
||||||
|
],
|
||||||
where: {
|
where: {
|
||||||
order_id,
|
order_id,
|
||||||
items: [{ item_id }, { item: { item_queue: { id: item_id } } }],
|
items: [{ item_id }, { item: { item_queue: { id: item_id } } }],
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
import { TicketDataService } from '../data/services/ticket.service';
|
import { TicketDataService } from '../data/services/ticket.service';
|
||||||
import { QueueOrder } from './entities/order.entity';
|
import { QueueOrder } from './entities/order.entity';
|
||||||
import { QueueItemModel } from '../data/models/queue.model';
|
|
||||||
import { Queue } from './entities/queue.entity';
|
import { Queue } from './entities/queue.entity';
|
||||||
import { QueueService } from '../data/services/queue.service';
|
import { QueueService } from '../data/services/queue.service';
|
||||||
import { RegisterQueueManager } from './usecases/register-queue.manager';
|
import { RegisterQueueManager } from './usecases/register-queue.manager';
|
||||||
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
||||||
import { RegisterQueueDto } from '../infrastructure/controllers/dto/register-queue.dto';
|
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()
|
@Injectable()
|
||||||
export class QueueOrchestrator {
|
export class QueueOrchestrator {
|
||||||
|
@ -44,28 +47,8 @@ export class QueueOrchestrator {
|
||||||
|
|
||||||
async queueTickets(order_id: string): Promise<any> {
|
async queueTickets(order_id: string): Promise<any> {
|
||||||
const tickets = await this.dataService.queueTickets(order_id);
|
const tickets = await this.dataService.queueTickets(order_id);
|
||||||
return tickets.map((ticket) => {
|
const manager = new CustomerQueueSummaryManager(tickets);
|
||||||
const totalActivities = ticket.items.length;
|
return manager.data;
|
||||||
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,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async queueTicketDetail(order_id: string, ticket_id: string): Promise<any> {
|
async queueTicketDetail(order_id: string, ticket_id: string): Promise<any> {
|
||||||
|
@ -73,119 +56,19 @@ export class QueueOrchestrator {
|
||||||
order_id,
|
order_id,
|
||||||
ticket_id,
|
ticket_id,
|
||||||
);
|
);
|
||||||
return tickets.map((ticket) => {
|
const manager = new CustomerQueueDetailManager(tickets);
|
||||||
const totalActivities = ticket.items.length;
|
return manager.data;
|
||||||
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',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async queueItemDetail(order_id: string, item_id: string): Promise<any> {
|
async queueItemDetail(order_id: string, item_id: string): Promise<any> {
|
||||||
const tickets = await this.dataService.queueItemTickets(order_id, item_id);
|
const tickets = await this.dataService.queueItemTickets(order_id, item_id);
|
||||||
return tickets.map((ticket) => {
|
const manager = new CustomerQueueItemManager(tickets);
|
||||||
const totalActivities = ticket.items.length;
|
return manager.data;
|
||||||
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',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async queueItems(order_id: string): Promise<any> {
|
async queueItems(order_id: string): Promise<any> {
|
||||||
const tickets = await this.dataService.queueTickets(order_id);
|
const tickets = await this.dataService.queueTickets(order_id);
|
||||||
const ticketItems = {};
|
const manager = new CustomerQueueItemListManager(tickets);
|
||||||
|
return manager.data;
|
||||||
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<QueueItemModel[]>(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',
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<QueueItemModel[]>(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',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue