218 lines
5.7 KiB
TypeScript
218 lines
5.7 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
|
|
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
|
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
|
|
import { Between, DataSource, In, Repository } from 'typeorm';
|
|
import {
|
|
QueueItemModel,
|
|
QueueModel,
|
|
QueueOrderModel,
|
|
} from '../models/queue.model';
|
|
import { BaseReadService } from 'src/core/modules/data/service/base-read.service';
|
|
import { BaseDataService } from 'src/core/modules/data/service/base-data.service';
|
|
import { ItemQueueModel } from 'src/modules/item-related/item-queue/data/models/item-queue.model';
|
|
import * as moment from 'moment';
|
|
import * as math from 'mathjs';
|
|
import { ItemModel } from 'src/modules/item-related/item/data/models/item.model';
|
|
|
|
@Injectable()
|
|
export class QueueDataService extends BaseReadService<QueueModel> {
|
|
constructor(
|
|
@InjectRepository(QueueModel, CONNECTION_NAME.DEFAULT)
|
|
private repo: Repository<QueueModel>,
|
|
|
|
@InjectRepository(ItemQueueModel, CONNECTION_NAME.DEFAULT)
|
|
private itemQueueRepo: Repository<ItemQueueModel>,
|
|
) {
|
|
super(repo);
|
|
}
|
|
|
|
async waitingQueue(item_queue_id: string) {
|
|
const start = moment().startOf('day').valueOf();
|
|
const end = moment().endOf('day').valueOf();
|
|
return this.repo.find({
|
|
where: {
|
|
time: Between(start, end),
|
|
item_queue_id,
|
|
status: 'waiting',
|
|
},
|
|
order: {
|
|
time: 'ASC',
|
|
},
|
|
});
|
|
}
|
|
|
|
async doneQueue(item_queue_id: string) {
|
|
const start = moment().startOf('day').valueOf();
|
|
const end = moment().endOf('day').valueOf();
|
|
return this.repo.find({
|
|
where: {
|
|
time: Between(start, end),
|
|
item_queue_id,
|
|
status: In(['done', 'called']),
|
|
},
|
|
order: {
|
|
time: 'ASC',
|
|
},
|
|
});
|
|
}
|
|
|
|
async lastQueue(item_queue_id: string) {
|
|
const start = moment().startOf('day').valueOf();
|
|
const end = moment().endOf('day').valueOf();
|
|
return this.repo.findOne({
|
|
where: {
|
|
time: Between(start, end),
|
|
item_queue_id,
|
|
status: 'called',
|
|
},
|
|
order: {
|
|
call_time: 'DESC',
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @deprecated
|
|
* Change to QueueTimeFormula (queue-time.formula.ts)
|
|
* @param item_queue_id
|
|
* @returns
|
|
*/
|
|
async queueTimes(item_queue_id: string): Promise<any> {
|
|
const queueTimes = {};
|
|
let now = moment().valueOf();
|
|
const itemQueue = await this.itemQueueRepo.findOne({
|
|
relations: ['items'],
|
|
where: {
|
|
id: item_queue_id,
|
|
},
|
|
});
|
|
|
|
const times = itemQueue.items.map((item) => item.play_estimation ?? 0);
|
|
const average = math.mean(times) * 60 * 1000; // change average minute to milliseconds
|
|
const queues = await this.repo.find({
|
|
where: {
|
|
item_queue_id,
|
|
status: 'waiting',
|
|
},
|
|
});
|
|
|
|
queueTimes[queues[0].id] = now; // first queue will be now
|
|
|
|
for (let i = 1; i < queues.length; i++) {
|
|
const queue = queues[i];
|
|
// duration will be total qty multiple by average
|
|
const duration = queue.qty * average;
|
|
|
|
// time to call will be now + duration
|
|
const time = now + duration;
|
|
queueTimes[queue.id] = time;
|
|
|
|
// update now to last call time
|
|
now = time;
|
|
}
|
|
|
|
return queueTimes;
|
|
}
|
|
|
|
async queueItems(item_queue_id: string[]): Promise<QueueModel[]> {
|
|
return this.repo.find({
|
|
relations: ['item', 'item.item', 'item.item.item_queue'],
|
|
where: {
|
|
item: { item: { item_queue: { id: In(item_queue_id) } } },
|
|
},
|
|
order: {
|
|
time: 'DESC',
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
@Injectable()
|
|
export class QueueService extends BaseDataService<QueueModel> {
|
|
constructor(
|
|
@InjectRepository(QueueModel, CONNECTION_NAME.DEFAULT)
|
|
private repo: Repository<QueueModel>,
|
|
|
|
@InjectRepository(QueueItemModel, CONNECTION_NAME.DEFAULT)
|
|
private item: Repository<QueueItemModel>,
|
|
|
|
@InjectRepository(ItemModel, CONNECTION_NAME.DEFAULT)
|
|
private itemMaster: Repository<ItemModel>,
|
|
|
|
@InjectDataSource(CONNECTION_NAME.DEFAULT)
|
|
private dataSource: DataSource,
|
|
) {
|
|
super(repo);
|
|
}
|
|
|
|
async queues(ids: string[]) {
|
|
const start = moment().startOf('day').valueOf();
|
|
const end = moment().endOf('day').valueOf();
|
|
const playEstimations = {};
|
|
|
|
for (const id of ids) {
|
|
playEstimations[id] = await this.itemAverageTimeEstimation(id);
|
|
}
|
|
|
|
const queues = await this.repo.find({
|
|
where: {
|
|
item_queue_id: In(ids),
|
|
time: Between(start, end),
|
|
},
|
|
order: {
|
|
time: 'ASC',
|
|
},
|
|
});
|
|
|
|
queues.forEach((queue) => {
|
|
queue.average = playEstimations[queue.item_queue_id];
|
|
});
|
|
|
|
return queues;
|
|
}
|
|
|
|
async itemAverageTimeEstimation(item_queue_id: string) {
|
|
const items = await this.itemMaster.find({
|
|
where: {
|
|
item_queue_id,
|
|
},
|
|
});
|
|
|
|
const times = items.map((item) => item.play_estimation ?? 0);
|
|
const average = math.mean(times) * 60 * 1000; // change average minute to milliseconds
|
|
return average;
|
|
}
|
|
|
|
async getTicketItems(ticket_id: string, item_id: string) {
|
|
return this.item.findOneOrFail({
|
|
relations: ['item'],
|
|
where: [
|
|
{
|
|
ticket_id,
|
|
item_id,
|
|
},
|
|
{
|
|
ticket_id,
|
|
item: { item_queue_id: item_id },
|
|
},
|
|
],
|
|
});
|
|
}
|
|
|
|
async updateItemQty(item_id: string, qty: number): Promise<void> {
|
|
const query = `UPDATE queue_items SET qty = qty - ${qty} WHERE id = '${item_id}'`;
|
|
this.dataSource.query(query);
|
|
}
|
|
}
|
|
|
|
@Injectable()
|
|
export class QueueOrderService extends BaseDataService<QueueOrderModel> {
|
|
constructor(
|
|
@InjectRepository(QueueOrderModel, CONNECTION_NAME.DEFAULT)
|
|
private repo: Repository<QueueOrderModel>,
|
|
) {
|
|
super(repo);
|
|
}
|
|
}
|