feat: add average item queue time
parent
e9535749d4
commit
2b132c53a8
|
@ -0,0 +1,15 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddItemQueueToQueue1731498661938 implements MigrationInterface {
|
||||||
|
name = 'AddItemQueueToQueue1731498661938';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD "item_queue_id" character varying`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "item_queue_id"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -131,6 +131,9 @@ export class QueueModel extends BaseModel<Queue> implements Queue {
|
||||||
@Column('varchar')
|
@Column('varchar')
|
||||||
item_id: string;
|
item_id: string;
|
||||||
|
|
||||||
|
@Column('varchar', { nullable: true })
|
||||||
|
item_queue_id: string;
|
||||||
|
|
||||||
@Column('int')
|
@Column('int')
|
||||||
qty: number;
|
qty: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { DataSource, In, Repository } from 'typeorm';
|
import { Between, DataSource, In, Repository } from 'typeorm';
|
||||||
import {
|
import {
|
||||||
QueueItemModel,
|
QueueItemModel,
|
||||||
QueueModel,
|
QueueModel,
|
||||||
|
@ -10,6 +10,7 @@ import {
|
||||||
} from '../models/queue.model';
|
} from '../models/queue.model';
|
||||||
import { BaseReadService } from 'src/core/modules/data/service/base-read.service';
|
import { BaseReadService } from 'src/core/modules/data/service/base-read.service';
|
||||||
import { BaseDataService } from 'src/core/modules/data/service/base-data.service';
|
import { BaseDataService } from 'src/core/modules/data/service/base-data.service';
|
||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueDataService extends BaseReadService<QueueModel> {
|
export class QueueDataService extends BaseReadService<QueueModel> {
|
||||||
|
@ -48,6 +49,20 @@ export class QueueService extends BaseDataService<QueueModel> {
|
||||||
super(repo);
|
super(repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async queues(ids: string[]) {
|
||||||
|
const start = moment().startOf('day').valueOf();
|
||||||
|
const end = moment().endOf('day').valueOf();
|
||||||
|
return this.repo.find({
|
||||||
|
where: {
|
||||||
|
item_queue_id: In(ids),
|
||||||
|
time: Between(start, end),
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
time: 'ASC',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getTicketItems(ticket_id: string, item_id: string) {
|
async getTicketItems(ticket_id: string, item_id: string) {
|
||||||
return this.item.findOneOrFail({
|
return this.item.findOneOrFail({
|
||||||
relations: ['item'],
|
relations: ['item'],
|
||||||
|
|
|
@ -133,6 +133,8 @@ export class TicketDataService extends BaseDataService<QueueTicket> {
|
||||||
|
|
||||||
async queueTickets(order_id: string): Promise<QueueTicketModel[]> {
|
async queueTickets(order_id: string): Promise<QueueTicketModel[]> {
|
||||||
const order = await this.orderIds(order_id);
|
const order = await this.orderIds(order_id);
|
||||||
|
const start = moment().startOf('day').valueOf();
|
||||||
|
const end = moment().endOf('day').valueOf();
|
||||||
return this.repo.find({
|
return this.repo.find({
|
||||||
relations: [
|
relations: [
|
||||||
'items',
|
'items',
|
||||||
|
@ -142,6 +144,7 @@ export class TicketDataService extends BaseDataService<QueueTicket> {
|
||||||
],
|
],
|
||||||
where: {
|
where: {
|
||||||
order_id: In(order),
|
order_id: In(order),
|
||||||
|
date: Between(start, end),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import * as moment from 'moment';
|
||||||
import { CustomerQueueTicketSummaryManager } from './usecases/queue/customer-queue-ticket.manager';
|
import { CustomerQueueTicketSummaryManager } from './usecases/queue/customer-queue-ticket.manager';
|
||||||
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 { QueueTicketModel } from '../data/models/queue.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueOrchestrator {
|
export class QueueOrchestrator {
|
||||||
|
@ -103,7 +104,11 @@ export class QueueOrchestrator {
|
||||||
order_id,
|
order_id,
|
||||||
ticket_id,
|
ticket_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const queueItemIds = this.getQueueItemFromTickets(tickets);
|
||||||
|
const queues = await this.queueService.queues(queueItemIds);
|
||||||
const manager = new CustomerQueueDetailManager(tickets);
|
const manager = new CustomerQueueDetailManager(tickets);
|
||||||
|
manager.currentQueues(queues);
|
||||||
return manager.data;
|
return manager.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +130,10 @@ export class QueueOrchestrator {
|
||||||
|
|
||||||
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 queues = await this.queueService.queues(queueItemIds);
|
||||||
const manager = new CustomerQueueItemListManager(tickets);
|
const manager = new CustomerQueueItemListManager(tickets);
|
||||||
|
manager.currentQueues(queues);
|
||||||
return manager.data;
|
return manager.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,4 +142,14 @@ export class QueueOrchestrator {
|
||||||
const manager = new CustomerQueueListManager(tickets);
|
const manager = new CustomerQueueListManager(tickets);
|
||||||
return manager.data;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ export class QueueCondition {
|
||||||
private ticketItems = {};
|
private ticketItems = {};
|
||||||
constructor(readonly items: QueueModel[]) {
|
constructor(readonly items: QueueModel[]) {
|
||||||
items.forEach((item) => {
|
items.forEach((item) => {
|
||||||
const item_id = item.item.item.item_queue?.id ?? item.item.item.id;
|
const item_id = item.item_queue_id;
|
||||||
const currentItem = this.ticketItems[item_id];
|
const currentItem = this.ticketItems[item_id];
|
||||||
this.ticketItems[item_id] = currentItem ? [...currentItem, item] : [item];
|
this.ticketItems[item_id] = currentItem ? [...currentItem, item] : [item];
|
||||||
});
|
});
|
||||||
|
@ -14,14 +14,17 @@ export class QueueCondition {
|
||||||
|
|
||||||
condition(item_id: string) {
|
condition(item_id: string) {
|
||||||
const queues: QueueModel[] = this.ticketItems[item_id] ?? [];
|
const queues: QueueModel[] = this.ticketItems[item_id] ?? [];
|
||||||
const time = queues[0]?.time;
|
const time = queues[0];
|
||||||
const nearest = time ? toTime(time) : 0;
|
const nearest = time ? toTime(time.time) : 0;
|
||||||
|
|
||||||
|
const last = [...queues].pop();
|
||||||
|
const lastTime = last ? toTime(last.time) : 0;
|
||||||
return {
|
return {
|
||||||
available: queues.length == 0,
|
available: queues.length == 0,
|
||||||
average: this.averageTime(queues),
|
average: this.averageTime(queues),
|
||||||
nearest: nearest,
|
nearest: nearest,
|
||||||
crowded_level: queues.length,
|
crowded_level: queues.length,
|
||||||
available_time: nearest,
|
available_time: lastTime,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ import {
|
||||||
} from 'src/core/strings/constants/interface.constants';
|
} from 'src/core/strings/constants/interface.constants';
|
||||||
import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager';
|
import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager';
|
||||||
import { STATUS } from 'src/core/strings/constants/base.constants';
|
import { STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
import { QueueModel } from '../../data/models/queue.model';
|
import { QueueItemModel, QueueModel } from '../../data/models/queue.model';
|
||||||
import { padCode } from 'src/modules/transaction/vip-code/domain/usecases/managers/helpers/generate-random.helper';
|
import { padCode } from 'src/modules/transaction/vip-code/domain/usecases/managers/helpers/generate-random.helper';
|
||||||
import { QueueBucketReadService } from '../../data/services/queue-bucket';
|
import { QueueBucketReadService } from '../../data/services/queue-bucket';
|
||||||
|
import { ItemModel } from 'src/modules/item-related/item/data/models/item.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RegisterQueueManager extends BaseCreateManager<QueueModel> {
|
export class RegisterQueueManager extends BaseCreateManager<QueueModel> {
|
||||||
|
@ -17,12 +18,13 @@ export class RegisterQueueManager extends BaseCreateManager<QueueModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async averageTime(): Promise<number> {
|
async averageTime(): Promise<number> {
|
||||||
const item = await this.getItem();
|
const item = await this.getItemMaster();
|
||||||
return item.item.item.play_estimation;
|
return item.play_estimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
async beforeProcess(): Promise<void> {
|
async beforeProcess(): Promise<void> {
|
||||||
const vip = this.data.vip ?? false;
|
const vip = this.data.vip ?? false;
|
||||||
|
const item = await this.getItemMaster();
|
||||||
const queueNumber = await this.bucketService.getQueue(
|
const queueNumber = await this.bucketService.getQueue(
|
||||||
this.data.item_id,
|
this.data.item_id,
|
||||||
vip,
|
vip,
|
||||||
|
@ -33,19 +35,22 @@ export class RegisterQueueManager extends BaseCreateManager<QueueModel> {
|
||||||
Object.assign(this.data, {
|
Object.assign(this.data, {
|
||||||
status: STATUS.WAITING,
|
status: STATUS.WAITING,
|
||||||
time: new Date().getTime(),
|
time: new Date().getTime(),
|
||||||
|
item_queue_id: item.item_queue_id,
|
||||||
vip,
|
vip,
|
||||||
code,
|
code,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItem(): Promise<QueueModel> {
|
async getItemMaster(): Promise<ItemModel> {
|
||||||
return this.dataService.repo.findOne({
|
const queueItem: QueueItemModel = await this.dataService.item.findOne({
|
||||||
relations: ['item', 'item.item'],
|
relations: ['item'],
|
||||||
where: {
|
where: {
|
||||||
item_id: this.data.item_id,
|
id: this.data.item_id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return queueItem.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
async afterProcess(): Promise<void> {
|
async afterProcess(): Promise<void> {
|
||||||
|
|
Loading…
Reference in New Issue