From 53ef4656ebb9c18e32f96c579893b9efa6d7448b Mon Sep 17 00:00:00 2001 From: shancheas Date: Fri, 15 Nov 2024 12:37:43 +0700 Subject: [PATCH] fix: change queue time formula to manager --- .../queue/data/services/queue.service.ts | 47 +++++++++++++++- .../usecases/formula/queue-time.formula.ts | 56 +++++++++++++++++++ .../domain/usecases/index-queue.manager.ts | 7 ++- src/modules/queue/queue.module.ts | 3 + 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/modules/queue/domain/usecases/formula/queue-time.formula.ts diff --git a/src/modules/queue/data/services/queue.service.ts b/src/modules/queue/data/services/queue.service.ts index 048f18c..7d33202 100644 --- a/src/modules/queue/data/services/queue.service.ts +++ b/src/modules/queue/data/services/queue.service.ts @@ -10,8 +10,8 @@ import { } 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 * as moment from 'moment'; import { ItemQueueModel } from 'src/modules/item-related/item-queue/data/models/item-queue.model'; +import * as moment from 'moment'; import * as math from 'mathjs'; @Injectable() @@ -26,6 +26,39 @@ export class QueueDataService extends BaseReadService { 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', + }, + }); + } + + 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 { const queueTimes = {}; let now = moment().valueOf(); @@ -62,6 +95,18 @@ export class QueueDataService extends BaseReadService { return queueTimes; } + + async queueItems(item_queue_id: string[]): Promise { + 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() diff --git a/src/modules/queue/domain/usecases/formula/queue-time.formula.ts b/src/modules/queue/domain/usecases/formula/queue-time.formula.ts new file mode 100644 index 0000000..e25c0a2 --- /dev/null +++ b/src/modules/queue/domain/usecases/formula/queue-time.formula.ts @@ -0,0 +1,56 @@ +import { InjectRepository } from '@nestjs/typeorm'; +import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; +import { ItemQueueModel } from 'src/modules/item-related/item-queue/data/models/item-queue.model'; +import { QueueDataService } from 'src/modules/queue/data/services/queue.service'; +import { Repository } from 'typeorm'; +import * as moment from 'moment'; +import * as math from 'mathjs'; + +export class QueueTimeFormula { + constructor( + private readonly queueDataService: QueueDataService, + @InjectRepository(ItemQueueModel, CONNECTION_NAME.DEFAULT) + private itemQueueRepo: Repository, + ) {} + + async items(item_queue_id: string) { + 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.queueDataService.waitingQueue(item_queue_id); + const calledQueue = await this.queueDataService.lastQueue(item_queue_id); + + const queueTimes = {}; + const timeNow = moment().valueOf(); + const lastCall = calledQueue?.call_time ?? timeNow - average; + + const callTime = lastCall + average; + const currentQueueCallTime = timeNow > callTime ? timeNow : callTime; + + queueTimes[queues[0].id] = currentQueueCallTime; + let now = currentQueueCallTime; + + for (let i = 1; i < queues.length; i++) { + const before = queues[i - 1]; + // duration will be total qty multiple by average from last queue + const duration = before.qty * average; + + const queue = queues[i]; + // 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; + } +} diff --git a/src/modules/queue/domain/usecases/index-queue.manager.ts b/src/modules/queue/domain/usecases/index-queue.manager.ts index 5afd54c..0db811f 100644 --- a/src/modules/queue/domain/usecases/index-queue.manager.ts +++ b/src/modules/queue/domain/usecases/index-queue.manager.ts @@ -8,9 +8,14 @@ import { import { Queue } from '../entities/queue.entity'; import * as moment from 'moment'; import { PaginationResponse } from 'src/core/response/domain/ok-response.interface'; +import { QueueTimeFormula } from './formula/queue-time.formula'; @Injectable() export class IndexQueueManager extends BaseIndexManager { + constructor(private readonly queueTimeFormula: QueueTimeFormula) { + super(); + } + private queueTimes = {}; async prepareData(): Promise { return; @@ -21,7 +26,7 @@ export class IndexQueueManager extends BaseIndexManager { } async afterProcess(): Promise { - this.queueTimes = await this.dataService.queueTimes( + this.queueTimes = await this.queueTimeFormula.items( this.filterParam.queue_id, ); return; diff --git a/src/modules/queue/queue.module.ts b/src/modules/queue/queue.module.ts index ab95226..19b2637 100644 --- a/src/modules/queue/queue.module.ts +++ b/src/modules/queue/queue.module.ts @@ -33,6 +33,7 @@ import { QueueBucketReadService } from './data/services/queue-bucket'; import { SplitQueueManager } from './domain/usecases/split-queue.manager'; import { QueueTransactionCancelHandler } from './infrastructure/handlers/cancel-transaction.handler'; import { ItemQueueModel } from '../item-related/item-queue/data/models/item-queue.model'; +import { QueueTimeFormula } from './domain/usecases/formula/queue-time.formula'; @Module({ imports: [ @@ -71,6 +72,8 @@ import { ItemQueueModel } from '../item-related/item-queue/data/models/item-queu CallQueueManager, RegisterQueueManager, SplitQueueManager, + + QueueTimeFormula, ], }) export class QueueModule {}