parent
46caaba6bd
commit
3e676226b1
|
@ -8,7 +8,6 @@ export class GateLogDto implements GateLogEntity {
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsString()
|
|
||||||
gate_id: string;
|
gate_id: string;
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
GateMasterEntity,
|
GateMasterEntity,
|
||||||
GateResponseEntity,
|
GateResponseEntity,
|
||||||
} from '../domain/entity/gate-response.entity';
|
} from '../domain/entity/gate-response.entity';
|
||||||
import { Gate } from 'src/core/response';
|
|
||||||
import { GateLogDto } from './dto/logs.dto';
|
import { GateLogDto } from './dto/logs.dto';
|
||||||
|
|
||||||
const masterGates = [
|
const masterGates = [
|
||||||
|
@ -49,7 +48,6 @@ const gateResponses = [
|
||||||
@ApiTags(`Gate - read`)
|
@ApiTags(`Gate - read`)
|
||||||
@Controller(`v1/gate`)
|
@Controller(`v1/gate`)
|
||||||
@Public(true)
|
@Public(true)
|
||||||
@Gate()
|
|
||||||
export class GateController {
|
export class GateController {
|
||||||
@Post('scan')
|
@Post('scan')
|
||||||
async scan(
|
async scan(
|
||||||
|
@ -77,7 +75,7 @@ export class GateController {
|
||||||
async logs(@Body() data: GateLogDto): Promise<GateResponseEntity> {
|
async logs(@Body() data: GateLogDto): Promise<GateResponseEntity> {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
return { code: 1, message: 'success' };
|
return { code: 0, message: 'Berhasil menyimpan logs' };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id/master')
|
@Get(':id/master')
|
||||||
|
|
|
@ -64,6 +64,9 @@ export class QueueTicketModel
|
||||||
@Column({ type: 'bigint' })
|
@Column({ type: 'bigint' })
|
||||||
date: number;
|
date: number;
|
||||||
|
|
||||||
|
@Column({ type: 'boolean' })
|
||||||
|
is_printed?: boolean;
|
||||||
|
|
||||||
@OneToMany(() => QueueItemModel, (model) => model.ticket, {
|
@OneToMany(() => QueueItemModel, (model) => model.ticket, {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
|
|
|
@ -81,12 +81,34 @@ export class TicketDataService extends BaseDataService<QueueTicket> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async printTicket(id: string): Promise<QueueTicketModel[]> {
|
||||||
|
const tickets = await this.repo.find({
|
||||||
|
where: {
|
||||||
|
order_id: id,
|
||||||
|
is_printed: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.repo.update(
|
||||||
|
{ order_id: id, is_printed: false },
|
||||||
|
{ is_printed: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
if (tickets.length < 1)
|
||||||
|
throw new UnprocessableEntityException({
|
||||||
|
code: 2,
|
||||||
|
message: 'Semua ticket sudah di print',
|
||||||
|
});
|
||||||
|
|
||||||
|
return tickets;
|
||||||
|
}
|
||||||
|
|
||||||
async ticketByUser(user: string, phone: string): Promise<QueueTicket> {
|
async ticketByUser(user: string, phone: string): Promise<QueueTicket> {
|
||||||
const start = moment().startOf('day').valueOf();
|
const start = moment().startOf('day').valueOf();
|
||||||
const end = moment().endOf('day').valueOf();
|
const end = moment().endOf('day').valueOf();
|
||||||
|
|
||||||
return this.repo.findOne({
|
return this.repo.findOne({
|
||||||
relations: ['items'],
|
relations: ['items', 'order'],
|
||||||
where: {
|
where: {
|
||||||
customer: user,
|
customer: user,
|
||||||
phone: phone,
|
phone: phone,
|
||||||
|
|
|
@ -10,5 +10,6 @@ export interface QueueTicket extends BaseCoreEntity {
|
||||||
date: number;
|
date: number;
|
||||||
order?: QueueOrder;
|
order?: QueueOrder;
|
||||||
order_id?: string;
|
order_id?: string;
|
||||||
|
is_printed?: boolean;
|
||||||
items: QueueItem[];
|
items: QueueItem[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import {
|
||||||
} from '../data/models/queue.model';
|
} from '../data/models/queue.model';
|
||||||
import { CustomerQueueRecommendManager } from './usecases/queue/customer-queue-recommend.manager';
|
import { CustomerQueueRecommendManager } from './usecases/queue/customer-queue-recommend.manager';
|
||||||
import { GenerateQueueManager } from './usecases/generate-queue.manager';
|
import { GenerateQueueManager } from './usecases/generate-queue.manager';
|
||||||
|
import { GenerateTransactionManager } from './usecases/generate-transaction.manager';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueOrchestrator {
|
export class QueueOrchestrator {
|
||||||
|
@ -41,12 +42,21 @@ export class QueueOrchestrator {
|
||||||
private readonly splitQueueManager: SplitQueueManager,
|
private readonly splitQueueManager: SplitQueueManager,
|
||||||
private readonly queueDataService: QueueDataService,
|
private readonly queueDataService: QueueDataService,
|
||||||
private readonly generateQueueManager: GenerateQueueManager,
|
private readonly generateQueueManager: GenerateQueueManager,
|
||||||
|
private readonly generateTransactionManager: GenerateTransactionManager,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async generate(data: any): Promise<QueueModel[]> {
|
async generate(data: any): Promise<QueueModel[]> {
|
||||||
return await this.generateQueueManager.generate(data);
|
return await this.generateQueueManager.generate(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async generateTransaction(data: any): Promise<QueueOrder> {
|
||||||
|
return await this.generateTransactionManager.generate(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async printTicket(id: string): Promise<QueueTicketModel[]> {
|
||||||
|
return await this.dataService.printTicket(id);
|
||||||
|
}
|
||||||
|
|
||||||
async loginCustomer(id: string): Promise<QueueOrder> {
|
async loginCustomer(id: string): Promise<QueueOrder> {
|
||||||
try {
|
try {
|
||||||
const order = await this.dataService.loginQueue(id);
|
const order = await this.dataService.loginQueue(id);
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import * as moment from 'moment';
|
||||||
|
import { TransactionItemModel } from 'src/modules/transaction/transaction/data/models/transaction-item.model';
|
||||||
|
import { TicketDataService } from '../../data/services/ticket.service';
|
||||||
|
import { QueueOrder } from '../entities/order.entity';
|
||||||
|
import { QueueItem } from '../entities/queue-item.entity';
|
||||||
|
import { QueueTicket } from '../entities/ticket.entity';
|
||||||
|
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GenerateTransactionManager {
|
||||||
|
constructor(private readonly ticketService: TicketDataService) {}
|
||||||
|
|
||||||
|
async generate(transaction: TransactionModel) {
|
||||||
|
const date = transaction.booking_date ?? transaction.invoice_date;
|
||||||
|
const queue_date = moment(date, 'YYYY-MM-DD').unix();
|
||||||
|
|
||||||
|
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 = await this.ticketService.ticketByUser(
|
||||||
|
customer_name,
|
||||||
|
customer_phone,
|
||||||
|
);
|
||||||
|
|
||||||
|
const insertTickets: QueueTicket[] = [];
|
||||||
|
if (customer_name && customer_phone && existTicket) {
|
||||||
|
existTicket.items.push(...items);
|
||||||
|
await this.ticketService.updateQueueTicket(existTicket);
|
||||||
|
|
||||||
|
return existTicket.order;
|
||||||
|
} else {
|
||||||
|
const ticket: QueueTicket = { ...customerOrder, items };
|
||||||
|
const order: QueueOrder = { ...customerOrder, tickets: [ticket] };
|
||||||
|
|
||||||
|
const queueOrder = await this.ticketService.createQueueOrder(order);
|
||||||
|
insertTickets.push(...queueOrder.tickets);
|
||||||
|
|
||||||
|
return queueOrder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ export class CustomerQueueSummaryManager extends CustomerQueueManager {
|
||||||
customer: ticket.customer,
|
customer: ticket.customer,
|
||||||
phone: ticket.phone,
|
phone: ticket.phone,
|
||||||
date: ticket.date,
|
date: ticket.date,
|
||||||
|
is_printed: false,
|
||||||
summary: this.summaryTicket(ticket),
|
summary: this.summaryTicket(ticket),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
import { Body, Controller, Get, Param, Post, Query, Res } from '@nestjs/common';
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Query,
|
||||||
|
Res,
|
||||||
|
UnprocessableEntityException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
|
||||||
import { MODULE_NAME } from 'src/core/strings/constants/module.constants';
|
import { MODULE_NAME } from 'src/core/strings/constants/module.constants';
|
||||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
|
@ -13,17 +22,38 @@ import { LoginQueueDto } from './dto/login-queue.dto';
|
||||||
import { LoginReceiptDto } from './dto/login-receipt.dto';
|
import { LoginReceiptDto } from './dto/login-receipt.dto';
|
||||||
import { mappingRevertTransaction } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper';
|
import { mappingRevertTransaction } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper';
|
||||||
import { TransactionType } from 'src/modules/transaction/transaction/constants';
|
import { TransactionType } from 'src/modules/transaction/transaction/constants';
|
||||||
import { QueueModel } from '../../data/models/queue.model';
|
import { QueueModel, QueueTicketModel } from '../../data/models/queue.model';
|
||||||
|
|
||||||
import * as Gtts from 'gtts';
|
import * as Gtts from 'gtts';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
|
import { QueueTimeFormula } from '../../domain/usecases/formula/queue-time.formula';
|
||||||
|
|
||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
@ApiTags(`Queue`)
|
@ApiTags(`Queue`)
|
||||||
@Controller(`v1/${MODULE_NAME.QUEUE}`)
|
@Controller(`v1/${MODULE_NAME.QUEUE}`)
|
||||||
@Public(true)
|
@Public(true)
|
||||||
@ApiBearerAuth('JWT')
|
@ApiBearerAuth('JWT')
|
||||||
export class QueueController {
|
export class QueueController {
|
||||||
constructor(private orchestrator: QueueOrchestrator) {}
|
constructor(
|
||||||
|
private orchestrator: QueueOrchestrator,
|
||||||
|
private readonly queueTimeFormula: QueueTimeFormula,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Post('dummy')
|
||||||
|
async dummyChecker(): Promise<void> {
|
||||||
|
const queueTimes = await this.queueTimeFormula.items(
|
||||||
|
'bbb296cc-2a58-40f3-a11f-923adc3e3b44',
|
||||||
|
);
|
||||||
|
const queues = Object.values<number>(queueTimes);
|
||||||
|
|
||||||
|
console.log(queueTimes);
|
||||||
|
const first = queues[0];
|
||||||
|
const last = queues[queues.length - 1] ?? moment().valueOf();
|
||||||
|
const average = this.queueTimeFormula.average;
|
||||||
|
|
||||||
|
console.log(first, last, average);
|
||||||
|
}
|
||||||
|
|
||||||
@Post('generate')
|
@Post('generate')
|
||||||
async generateQueue(@Body() data: any): Promise<QueueModel[]> {
|
async generateQueue(@Body() data: any): Promise<QueueModel[]> {
|
||||||
|
@ -31,6 +61,18 @@ export class QueueController {
|
||||||
return await this.orchestrator.generate(data);
|
return await this.orchestrator.generate(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('create-transaction')
|
||||||
|
async createTransaction(@Body() data: any): Promise<QueueOrder> {
|
||||||
|
mappingRevertTransaction(data, TransactionType.COUNTER);
|
||||||
|
return await this.orchestrator.generateTransaction(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('print-ticket/:id')
|
||||||
|
async printTicket(@Param('id') id: string): Promise<QueueTicketModel[]> {
|
||||||
|
if (!id) throw new UnprocessableEntityException('Order id is required');
|
||||||
|
return await this.orchestrator.printTicket(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Post('register')
|
@Post('register')
|
||||||
async registerQueue(@Body() data: RegisterQueueDto): Promise<Queue> {
|
async registerQueue(@Body() data: RegisterQueueDto): Promise<Queue> {
|
||||||
return await this.orchestrator.create(data);
|
return await this.orchestrator.create(data);
|
||||||
|
|
|
@ -39,6 +39,7 @@ import { ItemQueueModel } from '../item-related/item-queue/data/models/item-queu
|
||||||
import { QueueTimeFormula } from './domain/usecases/formula/queue-time.formula';
|
import { QueueTimeFormula } from './domain/usecases/formula/queue-time.formula';
|
||||||
import { QueueJobController } from './infrastructure/controllers/queue-job.controller';
|
import { QueueJobController } from './infrastructure/controllers/queue-job.controller';
|
||||||
import { GenerateQueueManager } from './domain/usecases/generate-queue.manager';
|
import { GenerateQueueManager } from './domain/usecases/generate-queue.manager';
|
||||||
|
import { GenerateTransactionManager } from './domain/usecases/generate-transaction.manager';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -81,6 +82,7 @@ import { GenerateQueueManager } from './domain/usecases/generate-queue.manager';
|
||||||
|
|
||||||
QueueTimeFormula,
|
QueueTimeFormula,
|
||||||
GenerateQueueManager,
|
GenerateQueueManager,
|
||||||
|
GenerateTransactionManager,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class QueueModule {}
|
export class QueueModule {}
|
||||||
|
|
Loading…
Reference in New Issue