85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
import { QueueModel } from 'src/modules/queue/data/models/queue.model';
|
|
import { toTime } from '../../helpers/time.helper';
|
|
import * as math from 'mathjs';
|
|
import { QueueTimeFormula } from './queue-time.formula';
|
|
import * as moment from 'moment';
|
|
|
|
export class QueueCondition {
|
|
private ticketItems = {};
|
|
constructor(readonly items: QueueModel[]) {
|
|
items.forEach((item) => {
|
|
const item_id = item.item_queue_id;
|
|
const currentItem = this.ticketItems[item_id];
|
|
this.ticketItems[item_id] = currentItem ? [...currentItem, item] : [item];
|
|
});
|
|
}
|
|
|
|
condition(item_id: string) {
|
|
const queues: QueueModel[] = this.ticketItems[item_id] ?? [];
|
|
const playEstimation = queues[0]?.average ?? 0;
|
|
const peakLevel = queues[0]?.peak_level ?? 100;
|
|
const [time, last] = this.queueTime(queues, playEstimation);
|
|
const nearest = time ? toTime(time) : 0;
|
|
const lastTime = last ? toTime(last + playEstimation) : 0;
|
|
|
|
const queuePeople = this.queuePeople(queues, peakLevel);
|
|
|
|
return {
|
|
available: queuePeople == 0,
|
|
average: this.averageTime(queues),
|
|
nearest: nearest,
|
|
crowded_level: queuePeople,
|
|
available_time: lastTime,
|
|
};
|
|
}
|
|
|
|
queuePeople(queues: QueueModel[], peakLevel): number {
|
|
const queue = this.activeQueue(queues);
|
|
const level = peakLevel / 100;
|
|
const queuePeople = queue.reduce((acc, q) => {
|
|
return acc + q.qty;
|
|
}, 0);
|
|
return queuePeople * level;
|
|
}
|
|
|
|
activeQueue(queues: QueueModel[]) {
|
|
return queues.filter((q) => q.status == 'waiting');
|
|
}
|
|
|
|
queueTime(queues: QueueModel[], average = 0): number[] {
|
|
const calledQueue = queues.filter((q) =>
|
|
['called', 'done'].includes(q.status),
|
|
);
|
|
const lastCalledQueue = calledQueue[calledQueue.length - 1];
|
|
const activeQueues = this.activeQueue(queues);
|
|
|
|
const queueTimes = QueueTimeFormula.queueTime(
|
|
activeQueues,
|
|
lastCalledQueue,
|
|
average,
|
|
);
|
|
|
|
const queueEstimation = Object.values<number>(queueTimes);
|
|
|
|
const first = queueEstimation[0] ?? moment().valueOf();
|
|
const last = queueEstimation[queueEstimation.length - 1] ?? 0;
|
|
return [first, last];
|
|
}
|
|
|
|
averageTime(queues: QueueModel[]) {
|
|
if (queues.length == 0) return 0;
|
|
const calledQueue = queues.filter((q) =>
|
|
['called', 'done'].includes(q.status),
|
|
);
|
|
|
|
if (calledQueue.length < 1) return 0;
|
|
|
|
const times = calledQueue.map((queue) => {
|
|
return (queue.call_time - queue.time) / 1000;
|
|
});
|
|
|
|
const avg = Math.ceil(math.mean(times));
|
|
return Math.max(0, avg);
|
|
}
|
|
}
|