162 lines
5.3 KiB
TypeScript
162 lines
5.3 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import * as moment from 'moment';
|
|
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
|
import { TransactionUserType } from 'src/modules/transaction/transaction/constants';
|
|
import { TransactionItemModel } from 'src/modules/transaction/transaction/data/models/transaction-item.model';
|
|
import { QueueBucketReadService } from '../../data/services/queue-bucket';
|
|
import { QueueService } from '../../data/services/queue.service';
|
|
import { TicketDataService } from '../../data/services/ticket.service';
|
|
import { RegisterQueueDto } from '../../infrastructure/controllers/dto/register-queue.dto';
|
|
import { QueueOrder } from '../entities/order.entity';
|
|
import { QueueItem } from '../entities/queue-item.entity';
|
|
import { QueueTicket } from '../entities/ticket.entity';
|
|
import { QueueTimeFormula } from './formula/queue-time.formula';
|
|
import { RegisterQueueManager } from './register-queue.manager';
|
|
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
|
|
import { QueueModel } from '../../data/models/queue.model';
|
|
|
|
@Injectable()
|
|
export class GenerateQueueManager {
|
|
constructor(
|
|
private readonly ticketService: TicketDataService,
|
|
private readonly queueService: QueueService,
|
|
private readonly bucketService: QueueBucketReadService,
|
|
private readonly queueTimeFormula: QueueTimeFormula,
|
|
) {}
|
|
|
|
async generate(transaction: TransactionModel) {
|
|
const date = transaction.booking_date ?? transaction.invoice_date;
|
|
const queue_date = moment(date, 'YYYY-MM-DD').unix();
|
|
const isToday = moment(date, 'YYYY-MM-DD').isSame(moment(), 'day');
|
|
|
|
const { id, customer_name, customer_phone, invoice_code } = transaction;
|
|
|
|
const customerOrder = {
|
|
code: invoice_code,
|
|
customer: customer_name,
|
|
phone: customer_phone,
|
|
date: queue_date * 1000,
|
|
transaction_id: id,
|
|
};
|
|
|
|
const items = this.generateItems(transaction.items);
|
|
|
|
const existTicket = isToday
|
|
? await this.ticketService.ticketByUser(customer_name, customer_phone)
|
|
: null;
|
|
|
|
const insertTickets: QueueTicket[] = [];
|
|
if (customer_name && customer_phone && existTicket) {
|
|
existTicket.items.push(...items);
|
|
await this.ticketService.updateQueueTicket(existTicket);
|
|
|
|
existTicket.items = items;
|
|
insertTickets.push(existTicket);
|
|
} else {
|
|
const ticket: QueueTicket = { ...customerOrder, items };
|
|
const order: QueueOrder = { ...customerOrder, tickets: [ticket] };
|
|
|
|
const queueOrder = await this.ticketService.createQueueOrder(order);
|
|
insertTickets.push(...queueOrder.tickets);
|
|
}
|
|
|
|
const results: QueueModel[] = [];
|
|
const vipCustomer =
|
|
transaction.customer_category?.has_vip_pass ||
|
|
transaction.customer_type === TransactionUserType.VIP;
|
|
if (vipCustomer || transaction.creator_counter_no != null) {
|
|
for (const ticket of insertTickets) {
|
|
const ticket_id = ticket.id;
|
|
const items = {};
|
|
|
|
ticket.items.forEach((item) => {
|
|
const item_id = item['item_queue_id'];
|
|
const currentItem = items[item_id];
|
|
|
|
if (currentItem) {
|
|
currentItem.qty += item.qty;
|
|
}
|
|
items[item_id] = currentItem
|
|
? currentItem
|
|
: {
|
|
item_id,
|
|
ticket_id,
|
|
qty: item.qty,
|
|
};
|
|
});
|
|
|
|
for (const payload of Object.values(items)) {
|
|
const isVip = vipCustomer || transaction.creator_counter_no == null;
|
|
const result = await this.create(payload as any, isVip);
|
|
results.push(result);
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
generateItems(items: TransactionItemModel[]): QueueItem[] {
|
|
const transactionItems = [];
|
|
|
|
items.forEach((item) => {
|
|
if (item.item.use_queue) {
|
|
transactionItems.push({
|
|
item_queue_id: item.item.item_queue_id,
|
|
item_id: item.item_id,
|
|
qty: item.qty,
|
|
});
|
|
}
|
|
|
|
if (item.item.bundling_items.length > 0) {
|
|
item.item.bundling_items.forEach((bundling_item) => {
|
|
if (bundling_item.use_queue) {
|
|
transactionItems.push({
|
|
item_queue_id: bundling_item.item_queue_id,
|
|
item_id: bundling_item.id,
|
|
qty: item.qty,
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
return this.mergeQueueItems(transactionItems);
|
|
}
|
|
|
|
mergeQueueItems(arr) {
|
|
const result = {};
|
|
arr.forEach((item) => {
|
|
if (result[item.item_id]) {
|
|
result[item.item_id].qty += item.qty;
|
|
} else {
|
|
result[item.item_id] = { ...item };
|
|
}
|
|
});
|
|
return Object.values<QueueItem>(result);
|
|
}
|
|
|
|
async create(data: RegisterQueueDto, isVip = false): Promise<QueueModel> {
|
|
const queue = await this.queueService.getTicketItems(
|
|
data.ticket_id,
|
|
data.item_id,
|
|
);
|
|
const queueRequest: any = {
|
|
qty: data.qty,
|
|
item_id: queue.id,
|
|
vip: isVip,
|
|
};
|
|
const registerQueueManager = new RegisterQueueManager(
|
|
this.bucketService,
|
|
this.queueTimeFormula,
|
|
);
|
|
registerQueueManager.setData(queueRequest);
|
|
registerQueueManager.setService(this.queueService, TABLE_NAME.QUEUE);
|
|
await registerQueueManager.execute();
|
|
|
|
const result = await registerQueueManager.getResult();
|
|
result.time = null;
|
|
|
|
return result;
|
|
}
|
|
}
|