113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
|
|
import { Ticket, TicketValidationState, Tour } from '@prisma/client';
|
|
import { Interval } from 'date-fns';
|
|
import { PubSub } from 'graphql-subscriptions';
|
|
import {
|
|
decodeOffsetCursor,
|
|
encodeCursor,
|
|
} from 'src/core/base/pagination.util';
|
|
import { DocumentInfoArgs, TicketFilterArgs } from './ticket-arg.types';
|
|
import { TicketLifecycleService } from './ticket-lifecycle.service';
|
|
import {
|
|
TicketSystemEventTypes,
|
|
TicketSystemValidatedEvent,
|
|
} from './ticket-system.events';
|
|
import {
|
|
PaginatedTicketObjectType,
|
|
TicketStateKeyFiguresObjectType,
|
|
TicketStateMetaObjectType,
|
|
} from './ticket.object-type';
|
|
import { TicketRepository } from './ticket.repository';
|
|
|
|
@Injectable()
|
|
export class TicketService {
|
|
public readonly pubSub = new PubSub();
|
|
|
|
@OnEvent(TicketSystemEventTypes.Validated, { async: true })
|
|
notifyOnTicketsValidated(event: TicketSystemValidatedEvent): void {
|
|
this.pubSub.publish('ticketsUpdated', {
|
|
ticketsUpdated: { count: event.count },
|
|
});
|
|
}
|
|
|
|
constructor(
|
|
private readonly repository: TicketRepository,
|
|
private readonly lifecycle: TicketLifecycleService,
|
|
private readonly eventEmitter: EventEmitter2,
|
|
) {}
|
|
|
|
async createTickets(interval: Interval): Promise<void> {
|
|
await this.lifecycle.createTickets(interval);
|
|
|
|
this.eventEmitter.emit(
|
|
TicketSystemEventTypes.Validated,
|
|
new TicketSystemValidatedEvent(0),
|
|
);
|
|
}
|
|
|
|
async updateDocumentInfo(ticketId: string, documentInfo: DocumentInfoArgs) {
|
|
return this.lifecycle.validateDocumentInfoUpdate(ticketId, documentInfo);
|
|
}
|
|
|
|
findById(id: string): Promise<Ticket> {
|
|
return this.repository.findById(id);
|
|
}
|
|
|
|
findAll(): Promise<Ticket[]> {
|
|
return this.repository.findAll() as Promise<Ticket[]>;
|
|
}
|
|
|
|
searchTickets(query: string): Promise<Ticket[]> {
|
|
return this.repository.search(query);
|
|
}
|
|
|
|
async paginateTicketsByState(
|
|
state: TicketValidationState,
|
|
filter: TicketFilterArgs,
|
|
take?: number,
|
|
cursor?: string,
|
|
): Promise<PaginatedTicketObjectType> {
|
|
const skip = cursor ? decodeOffsetCursor(cursor) : 0;
|
|
const { tickets, total } = await this.repository.findByState(
|
|
state,
|
|
filter,
|
|
take,
|
|
skip,
|
|
);
|
|
|
|
const prevPage = skip - take < 0 ? 0 : skip - take;
|
|
const nextPage = skip + take < total ? skip + take : skip;
|
|
|
|
return {
|
|
nodes: tickets,
|
|
prevCursor: encodeCursor(prevPage),
|
|
endCursor: encodeCursor(nextPage),
|
|
hasNextPage: nextPage !== skip,
|
|
totalCount: total,
|
|
};
|
|
}
|
|
|
|
async getTicketStateMeta(
|
|
ticketState: TicketValidationState,
|
|
): Promise<TicketStateMetaObjectType> {
|
|
return this.repository.calculateTicketStateMeta(ticketState);
|
|
}
|
|
|
|
getTicketStateKeyFigures(
|
|
ticketState: TicketValidationState,
|
|
): Promise<TicketStateKeyFiguresObjectType> {
|
|
return this.repository.calculateTicketStateKeyFigures(ticketState);
|
|
}
|
|
|
|
findToursByTicketId(ticketId: string): Promise<Tour[]> {
|
|
return this.repository.findToursByTicketId(ticketId);
|
|
}
|
|
|
|
findStatesByTicketId(ticketId: string): Promise<TicketValidationState[]> {
|
|
return this.repository
|
|
.findStatesByTicketId(ticketId)
|
|
.then((states) => states.map(({ state }) => state));
|
|
}
|
|
}
|