feat: add queue recommendations
parent
f7e3d5399c
commit
9db5c4b326
|
@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
||||||
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
|
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
|
||||||
import { Between, DataSource, In, Repository } from 'typeorm';
|
import { Between, DataSource, In, Not, Repository } from 'typeorm';
|
||||||
import {
|
import {
|
||||||
QueueItemModel,
|
QueueItemModel,
|
||||||
QueueModel,
|
QueueModel,
|
||||||
|
@ -57,6 +57,17 @@ export class QueueDataService extends BaseReadService<QueueModel> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async exclude(item_queue_id: string[]) {
|
||||||
|
const queues = await this.itemQueueRepo.find({
|
||||||
|
relations: ['items'],
|
||||||
|
where: {
|
||||||
|
id: Not(In(item_queue_id)),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return queues.filter((q) => q.items.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
async lastQueue(item_queue_id: string) {
|
async lastQueue(item_queue_id: string) {
|
||||||
const start = moment().startOf('day').valueOf();
|
const start = moment().startOf('day').valueOf();
|
||||||
const end = moment().endOf('day').valueOf();
|
const end = moment().endOf('day').valueOf();
|
||||||
|
@ -180,7 +191,7 @@ export class QueueService extends BaseDataService<QueueModel> {
|
||||||
});
|
});
|
||||||
|
|
||||||
const times = items.map((item) => item.play_estimation ?? 0);
|
const times = items.map((item) => item.play_estimation ?? 0);
|
||||||
const average = math.mean(times) * 60 * 1000; // change average minute to milliseconds
|
const average = times.length > 0 ? math.mean(times) * 60 * 1000 : 0; // change average minute to milliseconds
|
||||||
return average;
|
return average;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { TicketDataService } from '../data/services/ticket.service';
|
||||||
import { QueueOrder } from './entities/order.entity';
|
import { QueueOrder } from './entities/order.entity';
|
||||||
import { Queue } from './entities/queue.entity';
|
import { Queue } from './entities/queue.entity';
|
||||||
import {
|
import {
|
||||||
|
QueueDataService,
|
||||||
QueueOrderService,
|
QueueOrderService,
|
||||||
QueueService,
|
QueueService,
|
||||||
} from '../data/services/queue.service';
|
} from '../data/services/queue.service';
|
||||||
|
@ -22,6 +23,7 @@ import { CustomerQueueTicketSummaryManager } from './usecases/queue/customer-que
|
||||||
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
|
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
|
||||||
import { CustomerQueuePosItemManager } from './usecases/queue/customer-queue-pos-item.manager';
|
import { CustomerQueuePosItemManager } from './usecases/queue/customer-queue-pos-item.manager';
|
||||||
import { QueueOrderModel, QueueTicketModel } from '../data/models/queue.model';
|
import { QueueOrderModel, QueueTicketModel } from '../data/models/queue.model';
|
||||||
|
import { CustomerQueueRecommendManager } from './usecases/queue/customer-queue-recommend.manager';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueOrchestrator {
|
export class QueueOrchestrator {
|
||||||
|
@ -32,6 +34,7 @@ export class QueueOrchestrator {
|
||||||
private readonly queueOrderService: QueueOrderService,
|
private readonly queueOrderService: QueueOrderService,
|
||||||
private readonly registerQueueManager: RegisterQueueManager,
|
private readonly registerQueueManager: RegisterQueueManager,
|
||||||
private readonly splitQueueManager: SplitQueueManager,
|
private readonly splitQueueManager: SplitQueueManager,
|
||||||
|
private readonly queueDataService: QueueDataService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async loginCustomer(id: string): Promise<QueueOrder> {
|
async loginCustomer(id: string): Promise<QueueOrder> {
|
||||||
|
@ -169,6 +172,17 @@ export class QueueOrchestrator {
|
||||||
return manager.data;
|
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 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 queueItemIds = this.getQueueItemFromTickets(tickets);
|
const queueItemIds = this.getQueueItemFromTickets(tickets);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { CustomerQueueManager } from './customer-queue.manager';
|
||||||
import { QueueCondition } from '../formula/queue-condition.formula';
|
import { QueueCondition } from '../formula/queue-condition.formula';
|
||||||
|
|
||||||
export class CustomerQueueItemListManager extends CustomerQueueManager {
|
export class CustomerQueueItemListManager extends CustomerQueueManager {
|
||||||
private queues: QueueModel[] = [];
|
protected queues: QueueModel[] = [];
|
||||||
currentQueues(queues: QueueModel[]) {
|
currentQueues(queues: QueueModel[]) {
|
||||||
this.queues = queues;
|
this.queues = queues;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ export class CustomerQueueItemListManager extends CustomerQueueManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private queueItemQty(queues: QueueItemModel[]) {
|
protected queueItemQty(queues: QueueItemModel[]) {
|
||||||
return queues.reduce(
|
return queues.reduce(
|
||||||
(acc, item) => acc + item.queue.reduce((acc, q) => acc + q.qty, 0),
|
(acc, item) => acc + item.queue.reduce((acc, q) => acc + q.qty, 0),
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { QueueCondition } from '../formula/queue-condition.formula';
|
||||||
|
import { CustomerQueueItemListManager } from './customer-queue-item-list.manager';
|
||||||
|
import { ItemQueueModel } from 'src/modules/item-related/item-queue/data/models/item-queue.model';
|
||||||
|
|
||||||
|
export class CustomerQueueRecommendManager extends CustomerQueueItemListManager {
|
||||||
|
recommend(items: ItemQueueModel[]) {
|
||||||
|
const queueCondition = new QueueCondition(this.queues);
|
||||||
|
|
||||||
|
return items.map((queueItem) => {
|
||||||
|
const item = queueItem.items[0];
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
queue_item_id: queueItem.id,
|
||||||
|
title: queueItem.name,
|
||||||
|
image_url: item.image_url,
|
||||||
|
|
||||||
|
queue_condition: queueCondition.condition(queueItem.id),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,6 +66,11 @@ export class QueueController {
|
||||||
return await this.orchestrator.queueTicketSummary(id, ticket_id);
|
return await this.orchestrator.queueTicketSummary(id, ticket_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get(':id/recommendations')
|
||||||
|
async queueItemRecommends(@Param('id') id: string): Promise<void> {
|
||||||
|
return await this.orchestrator.queueItemRecommendation(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Get(':id/items')
|
@Get(':id/items')
|
||||||
async queueItems(@Param('id') id: string): Promise<void> {
|
async queueItems(@Param('id') id: string): Promise<void> {
|
||||||
return await this.orchestrator.queueItems(id);
|
return await this.orchestrator.queueItems(id);
|
||||||
|
|
Loading…
Reference in New Issue