feat: add queue admin list
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
143bf76417
commit
5b507a1c3c
|
@ -88,6 +88,7 @@ import {
|
||||||
QueueOrderModel,
|
QueueOrderModel,
|
||||||
QueueTicketModel,
|
QueueTicketModel,
|
||||||
QueueItemModel,
|
QueueItemModel,
|
||||||
|
QueueModel,
|
||||||
} from './modules/queue/data/models/queue.model';
|
} from './modules/queue/data/models/queue.model';
|
||||||
import { ItemQueueModule } from './modules/item-related/item-queue/item-queue.module';
|
import { ItemQueueModule } from './modules/item-related/item-queue/item-queue.module';
|
||||||
import { ItemQueueModel } from './modules/item-related/item-queue/data/models/item-queue.model';
|
import { ItemQueueModel } from './modules/item-related/item-queue/data/models/item-queue.model';
|
||||||
|
@ -149,6 +150,7 @@ import { ItemQueueModel } from './modules/item-related/item-queue/data/models/it
|
||||||
QueueOrderModel,
|
QueueOrderModel,
|
||||||
QueueTicketModel,
|
QueueTicketModel,
|
||||||
QueueItemModel,
|
QueueItemModel,
|
||||||
|
QueueModel,
|
||||||
],
|
],
|
||||||
synchronize: false,
|
synchronize: false,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -37,6 +37,7 @@ export enum TABLE_NAME {
|
||||||
REPORT_BOOKMARK = 'report_bookmark',
|
REPORT_BOOKMARK = 'report_bookmark',
|
||||||
EXPORT_REPORT_HISTORY = 'export_report_history',
|
EXPORT_REPORT_HISTORY = 'export_report_history',
|
||||||
|
|
||||||
|
QUEUE = 'queues',
|
||||||
QUEUE_ORDER = 'queue_orders',
|
QUEUE_ORDER = 'queue_orders',
|
||||||
QUEUE_TICKET = 'queue_tickets',
|
QUEUE_TICKET = 'queue_tickets',
|
||||||
QUEUE_ITEM = 'queue_items',
|
QUEUE_ITEM = 'queue_items',
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddQueueTable1729756969674 implements MigrationInterface {
|
||||||
|
name = 'AddQueueTable1729756969674';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "queues" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "code" character varying NOT NULL, "status" character varying NOT NULL, "time" bigint NOT NULL, "call_time" bigint NOT NULL, "vip" boolean NOT NULL, "item_id" uuid NOT NULL, "qty" integer NOT NULL, CONSTRAINT "PK_d966f9eb39a9396658387071bb3" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD CONSTRAINT "FK_435954e9a0d9967f17e043d54b4" FOREIGN KEY ("item_id") REFERENCES "queue_items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" DROP CONSTRAINT "FK_435954e9a0d9967f17e043d54b4"`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`DROP TABLE "queues"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddQueueBaseModel1729838994129 implements MigrationInterface {
|
||||||
|
name = 'AddQueueBaseModel1729838994129';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD "creator_id" character varying(36)`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD "creator_name" character varying(125)`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD "editor_id" character varying(36)`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD "editor_name" character varying(125)`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD "created_at" bigint NOT NULL`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ADD "updated_at" bigint NOT NULL`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "queues" ALTER COLUMN "call_time" DROP NOT NULL`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "updated_at"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "created_at"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "editor_name"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "editor_id"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "creator_name"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "creator_id"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,4 +14,8 @@ export class ItemQueueReadService extends BaseReadService<ItemQueueEntity> {
|
||||||
) {
|
) {
|
||||||
super(repo);
|
super(repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async list(): Promise<ItemQueueEntity[]> {
|
||||||
|
return this.repo.find();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,11 @@ export class ItemQueueReadOrchestrator extends BaseReadOrchestrator<ItemQueueEnt
|
||||||
return this.indexManager.getResult();
|
return this.indexManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async list(): Promise<ItemQueueEntity[]> {
|
||||||
|
const items = await this.serviceData.list();
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
async detail(dataId: string): Promise<ItemQueueEntity> {
|
async detail(dataId: string): Promise<ItemQueueEntity> {
|
||||||
this.detailManager.setData(dataId);
|
this.detailManager.setData(dataId);
|
||||||
this.detailManager.setService(this.serviceData, TABLE_NAME.ITEM_QUEUE);
|
this.detailManager.setService(this.serviceData, TABLE_NAME.ITEM_QUEUE);
|
||||||
|
|
|
@ -23,6 +23,19 @@ export class ItemQueueReadController {
|
||||||
return await this.orchestrator.index(params);
|
return await this.orchestrator.index(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('list')
|
||||||
|
@Public(true)
|
||||||
|
async list() {
|
||||||
|
const list = await this.orchestrator.list();
|
||||||
|
return list.map(({ id, name, item_type }) => {
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
item_type,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
async detail(@Param('id') id: string): Promise<ItemQueueEntity> {
|
async detail(@Param('id') id: string): Promise<ItemQueueEntity> {
|
||||||
return await this.orchestrator.detail(id);
|
return await this.orchestrator.detail(id);
|
||||||
|
|
|
@ -4,9 +4,10 @@ import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm';
|
||||||
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
||||||
import { QueueTicket } from '../../domain/entities/ticket.entity';
|
import { QueueTicket } from '../../domain/entities/ticket.entity';
|
||||||
import { QueueItem } from '../../domain/entities/queue-item.entity';
|
import { QueueItem } from '../../domain/entities/queue-item.entity';
|
||||||
import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity';
|
|
||||||
|
|
||||||
import { ItemModel } from 'src/modules/item-related/item/data/models/item.model';
|
import { ItemModel } from 'src/modules/item-related/item/data/models/item.model';
|
||||||
|
import { Queue } from '../../domain/entities/queue.entity';
|
||||||
|
import { BaseModel } from 'src/core/modules/data/model/base.model';
|
||||||
|
|
||||||
@Entity(TABLE_NAME.QUEUE_ORDER)
|
@Entity(TABLE_NAME.QUEUE_ORDER)
|
||||||
export class QueueOrderModel
|
export class QueueOrderModel
|
||||||
|
@ -83,6 +84,12 @@ export class QueueItemModel
|
||||||
@JoinColumn({ name: 'ticket_id' })
|
@JoinColumn({ name: 'ticket_id' })
|
||||||
ticket: QueueTicket;
|
ticket: QueueTicket;
|
||||||
|
|
||||||
|
@OneToMany(() => QueueModel, (model) => model.item, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
onUpdate: 'CASCADE',
|
||||||
|
})
|
||||||
|
queue: QueueModel[];
|
||||||
|
|
||||||
@Column('varchar')
|
@Column('varchar')
|
||||||
item_id: string;
|
item_id: string;
|
||||||
|
|
||||||
|
@ -93,3 +100,34 @@ export class QueueItemModel
|
||||||
@Column('int')
|
@Column('int')
|
||||||
qty: number;
|
qty: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Entity(TABLE_NAME.QUEUE)
|
||||||
|
export class QueueModel extends BaseModel<Queue> implements Queue {
|
||||||
|
@Column('varchar')
|
||||||
|
code: string;
|
||||||
|
|
||||||
|
@Column('varchar')
|
||||||
|
status: string;
|
||||||
|
|
||||||
|
@Column({ type: 'bigint' })
|
||||||
|
time: number;
|
||||||
|
|
||||||
|
@Column({ type: 'bigint' })
|
||||||
|
call_time: number;
|
||||||
|
|
||||||
|
@Column({ type: 'boolean' })
|
||||||
|
vip: boolean;
|
||||||
|
|
||||||
|
@ManyToOne(() => QueueItemModel, (model) => model.queue, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
onUpdate: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn({ name: 'item_id' })
|
||||||
|
item: QueueItemModel;
|
||||||
|
|
||||||
|
@Column('varchar')
|
||||||
|
item_id: string;
|
||||||
|
|
||||||
|
@Column('int')
|
||||||
|
qty: number;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { QueueModel } from '../models/queue.model';
|
||||||
|
import { BaseReadService } from 'src/core/modules/data/service/base-read.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class QueueDataService extends BaseReadService<QueueModel> {
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(QueueModel, CONNECTION_NAME.DEFAULT)
|
||||||
|
private repo: Repository<QueueModel>,
|
||||||
|
) {
|
||||||
|
super(repo);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface FilterQueueEntity {
|
||||||
|
vip: boolean;
|
||||||
|
status: string[];
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entity';
|
||||||
|
import { QueueItem } from './queue-item.entity';
|
||||||
|
|
||||||
|
export interface Queue extends BaseCoreEntity {
|
||||||
|
code: string;
|
||||||
|
qty: number;
|
||||||
|
status: string;
|
||||||
|
time: number;
|
||||||
|
vip: boolean;
|
||||||
|
call_time: number;
|
||||||
|
item: QueueItem;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { QueueDataService } from '../data/services/queue.service';
|
||||||
|
import { IndexQueueManager } from './usecases/index-queue.manager';
|
||||||
|
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
|
||||||
|
import { Queue } from './entities/queue.entity';
|
||||||
|
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class QueueAdminOrchestrator {
|
||||||
|
constructor(
|
||||||
|
private readonly dataService: QueueDataService,
|
||||||
|
private indexManager: IndexQueueManager,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async index(params): Promise<PaginationResponse<Queue>> {
|
||||||
|
this.indexManager.setFilterParam(params);
|
||||||
|
this.indexManager.setService(this.dataService, TABLE_NAME.QUEUE);
|
||||||
|
await this.indexManager.execute();
|
||||||
|
return this.indexManager.getResult();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager';
|
||||||
|
import { SelectQueryBuilder } from 'typeorm';
|
||||||
|
import {
|
||||||
|
Param,
|
||||||
|
RelationParam,
|
||||||
|
} from 'src/core/modules/domain/entities/base-filter.entity';
|
||||||
|
import { Queue } from '../entities/queue.entity';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class IndexQueueManager extends BaseIndexManager<Queue> {
|
||||||
|
async prepareData(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async beforeProcess(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async afterProcess(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
get relations(): RelationParam {
|
||||||
|
return {
|
||||||
|
joinRelations: [],
|
||||||
|
selectRelations: ['item', 'item.ticket'],
|
||||||
|
countRelations: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get selects(): string[] {
|
||||||
|
return [
|
||||||
|
`${this.tableName}.id`,
|
||||||
|
`${this.tableName}.code`,
|
||||||
|
`${this.tableName}.status`,
|
||||||
|
`${this.tableName}.time`,
|
||||||
|
`${this.tableName}.call_time`,
|
||||||
|
`${this.tableName}.vip`,
|
||||||
|
`${this.tableName}.item`,
|
||||||
|
`${this.tableName}.qty`,
|
||||||
|
`${this.tableName}.created_at`,
|
||||||
|
|
||||||
|
`item.id`,
|
||||||
|
`ticket.customer`,
|
||||||
|
`ticket.phone`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
get specificFilter(): Param[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
cols: `${this.tableName}.status`,
|
||||||
|
data: this.filterParam.status,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
setQueryFilter(
|
||||||
|
queryBuilder: SelectQueryBuilder<Queue>,
|
||||||
|
): SelectQueryBuilder<Queue> {
|
||||||
|
if (this.filterParam.vip != null) {
|
||||||
|
queryBuilder.andWhere(`${this.tableName}.vip = :vip`, {
|
||||||
|
vip: this.filterParam.vip,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return queryBuilder;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, ValidateIf } from 'class-validator';
|
||||||
|
import { Transform } from 'class-transformer';
|
||||||
|
import { FilterQueueEntity } from 'src/modules/queue/domain/entities/filter.entity';
|
||||||
|
|
||||||
|
export class QueueDto implements FilterQueueEntity {
|
||||||
|
@ApiProperty({
|
||||||
|
isArray: true,
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
// @IsString()
|
||||||
|
@ValidateIf((body) => body.status)
|
||||||
|
@Transform(({ value }) => {
|
||||||
|
if (!value) return [];
|
||||||
|
return Array.isArray(value) ? value : [value];
|
||||||
|
})
|
||||||
|
status: string[];
|
||||||
|
|
||||||
|
@ApiProperty({ type: Boolean, required: false })
|
||||||
|
@Transform((body) => body.value == 'true')
|
||||||
|
@IsBoolean()
|
||||||
|
@ValidateIf((body) => body.vip)
|
||||||
|
vip: boolean;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { Controller, Get, Query } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { MODULE_NAME } from 'src/core/strings/constants/module.constants';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
import { Public } from 'src/core/guards';
|
||||||
|
import { QueueAdminOrchestrator } from '../../domain/queue-admin.orchestrator';
|
||||||
|
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
|
||||||
|
import { Queue } from '../../domain/entities/queue.entity';
|
||||||
|
import { QueueDto } from './dto/queue.filter';
|
||||||
|
|
||||||
|
@ApiTags(`Queue Admin`)
|
||||||
|
@Controller(`v1/${MODULE_NAME.QUEUE}-admin`)
|
||||||
|
@Public(true)
|
||||||
|
@ApiBearerAuth('JWT')
|
||||||
|
export class QueueAdminController {
|
||||||
|
constructor(private orchestrator: QueueAdminOrchestrator) {}
|
||||||
|
|
||||||
|
@Get('queues')
|
||||||
|
async index(@Query() params: QueueDto): Promise<PaginationResponse<Queue>> {
|
||||||
|
return await this.orchestrator.index(params);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import { CqrsModule } from '@nestjs/cqrs';
|
||||||
import { ItemModel } from 'src/modules/item-related/item/data/models/item.model';
|
import { ItemModel } from 'src/modules/item-related/item/data/models/item.model';
|
||||||
import {
|
import {
|
||||||
QueueItemModel,
|
QueueItemModel,
|
||||||
|
QueueModel,
|
||||||
QueueOrderModel,
|
QueueOrderModel,
|
||||||
QueueTicketModel,
|
QueueTicketModel,
|
||||||
} from './data/models/queue.model';
|
} from './data/models/queue.model';
|
||||||
|
@ -17,6 +18,10 @@ import { QueueTransactionHandler } from './infrastructure/handlers/transaction.h
|
||||||
import { TransactionDataService } from '../transaction/transaction/data/services/transaction-data.service';
|
import { TransactionDataService } from '../transaction/transaction/data/services/transaction-data.service';
|
||||||
import { TransactionModel } from '../transaction/transaction/data/models/transaction.model';
|
import { TransactionModel } from '../transaction/transaction/data/models/transaction.model';
|
||||||
import { TicketDataService } from './data/services/ticket.service';
|
import { TicketDataService } from './data/services/ticket.service';
|
||||||
|
import { QueueDataService } from './data/services/queue.service';
|
||||||
|
import { QueueAdminController } from './infrastructure/controllers/queue-admin.controller';
|
||||||
|
import { QueueAdminOrchestrator } from './domain/queue-admin.orchestrator';
|
||||||
|
import { IndexQueueManager } from './domain/usecases/index-queue.manager';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -26,6 +31,7 @@ import { TicketDataService } from './data/services/ticket.service';
|
||||||
QueueOrderModel,
|
QueueOrderModel,
|
||||||
QueueTicketModel,
|
QueueTicketModel,
|
||||||
QueueItemModel,
|
QueueItemModel,
|
||||||
|
QueueModel,
|
||||||
ItemModel,
|
ItemModel,
|
||||||
TransactionModel,
|
TransactionModel,
|
||||||
],
|
],
|
||||||
|
@ -33,14 +39,18 @@ import { TicketDataService } from './data/services/ticket.service';
|
||||||
),
|
),
|
||||||
CqrsModule,
|
CqrsModule,
|
||||||
],
|
],
|
||||||
controllers: [QueueController],
|
controllers: [QueueController, QueueAdminController],
|
||||||
providers: [
|
providers: [
|
||||||
QueueTransactionHandler,
|
QueueTransactionHandler,
|
||||||
|
|
||||||
QueueOrchestrator,
|
QueueOrchestrator,
|
||||||
|
QueueAdminOrchestrator,
|
||||||
|
|
||||||
TransactionDataService,
|
TransactionDataService,
|
||||||
TicketDataService,
|
TicketDataService,
|
||||||
|
QueueDataService,
|
||||||
|
|
||||||
|
IndexQueueManager,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class QueueModule {}
|
export class QueueModule {}
|
||||||
|
|
Loading…
Reference in New Issue