feat(ticket-list): added a route to fetch all tickets, filtered in a precis order
This commit is contained in:
parent
d14924783d
commit
f43d3ade19
|
|
@ -1,13 +1,17 @@
|
|||
import { Module } from "@nestjs/common";
|
||||
import { CreateTicketService } from "src/customer-support/tickets/services/create-ticket.service";
|
||||
import { GetTicketListService } from "src/customer-support/tickets/services/get-ticket-list.service";
|
||||
import { UpdateTicketService } from "src/customer-support/tickets/services/update-ticket.service";
|
||||
import { TicketController } from "src/customer-support/tickets/ticket.controller";
|
||||
import { TicketService } from "src/customer-support/tickets/ticket.service";
|
||||
|
||||
@Module({
|
||||
controllers: [
|
||||
TicketController
|
||||
],
|
||||
providers: [
|
||||
TicketService
|
||||
GetTicketListService,
|
||||
CreateTicketService,
|
||||
UpdateTicketService,
|
||||
],
|
||||
|
||||
}) export class CustomerSupportModule { }
|
||||
|
|
@ -1 +1 @@
|
|||
GET http://localhost:3000/tickets/OPEN?sortOrder=last_update&sortTypes=DESC&offset=0&limit=10&email=gilles@targointernet.com
|
||||
GET http://localhost:3000/tickets/OPEN?sortOrder=last_update&sortTypes=DESC&offset=0&limit=30&email=gilles@targointernet.com
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { PrismaMariaDbService } from "prisma/mariadb/prisma-mariadb.service";
|
||||
|
||||
@Injectable()
|
||||
export class CreateTicketService {
|
||||
constructor(private readonly prisma: PrismaMariaDbService) { }
|
||||
|
||||
createTicket = async () => {
|
||||
|
||||
}
|
||||
}
|
||||
132
src/customer-support/tickets/services/get-ticket-list.service.ts
Normal file
132
src/customer-support/tickets/services/get-ticket-list.service.ts
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { Result } from "src/common/errors/result-error.factory";
|
||||
import { PrismaMariaDbService } from "prisma/mariadb/prisma-mariadb.service";
|
||||
import { TicketList } from "src/customer-support/tickets/dtos/ticket-list.dto";
|
||||
import { sortOrders, sortTypes } from "src/customer-support/tickets/dtos/ticket.dto";
|
||||
import { Prisma } from "prisma/mariadb/generated/prisma/client/mariadb/client";
|
||||
|
||||
export const TIMESTAMP_MINIMUM = 1672531200; // 1er janvier 2023
|
||||
|
||||
@Injectable()
|
||||
export class GetTicketListService {
|
||||
constructor(private readonly prisma: PrismaMariaDbService) { }
|
||||
|
||||
getListOfAllTicketByFilters = async (
|
||||
status: string[],
|
||||
offset: number = 0,
|
||||
limit: number = 25,
|
||||
sortOrder: string = 'last_update',
|
||||
sortType: 'DESC' | 'ASC' = 'DESC',
|
||||
email?: string
|
||||
): Promise<Result<TicketList[], string>> => {
|
||||
|
||||
try {
|
||||
const staff = await this.prisma.staff.findFirst({
|
||||
where: { email },
|
||||
});
|
||||
if (!staff) return { success: false, error: 'EMPLOYEE_NOT_FOUND' }
|
||||
if (!sortOrders.includes(sortOrder) || !sortTypes.includes(sortType)) return { success: false, error: 'INVALID_FILTER' }
|
||||
|
||||
const statusList = Prisma.join(status);
|
||||
|
||||
const rawTicketList = await this.prisma.$queryRaw<TicketList[]>(
|
||||
Prisma.sql`
|
||||
SELECT
|
||||
t.id AS id,
|
||||
t.status AS status,
|
||||
CONCAT(s.first_name,' ',s.last_name) AS assignTo,
|
||||
a.address1 AS deliveryAddress,
|
||||
t.subject AS subject,
|
||||
d.name AS department,
|
||||
t.parent AS parentTicketId,
|
||||
|
||||
CASE
|
||||
WHEN t.due_date > 1672531200
|
||||
THEN FROM_UNIXTIME(t.due_date, '%d/%m/%y')
|
||||
ELSE NULL
|
||||
END AS dueDate,
|
||||
|
||||
FROM_UNIXTIME(t.last_update, '%d/%m/%y') AS lastUpdate,
|
||||
|
||||
CASE
|
||||
WHEN CAST(t.date_closed AS UNSIGNED) > 1672531200
|
||||
THEN FROM_UNIXTIME(CAST(t.date_closed AS UNSIGNED), '%d/%m/%y')
|
||||
ELSE NULL
|
||||
END AS completedAt
|
||||
|
||||
FROM staff s
|
||||
LEFT JOIN ticket t ON t.assign_to = s.id
|
||||
LEFT JOIN account a ON t.account_id = a.id
|
||||
LEFT JOIN ticket_dept d ON t.dept_id = d.id
|
||||
WHERE s.id = ${staff.id}
|
||||
AND t.status IN (${statusList})
|
||||
ORDER BY ${Prisma.raw(sortOrder)} ${Prisma.raw(sortType)}
|
||||
LIMIT ${limit} OFFSET ${offset}
|
||||
`);
|
||||
|
||||
return { success: true, data: rawTicketList }
|
||||
} catch (error) {
|
||||
return { success: false, error: 'TICKET_LIST_NOT_FOUND, ' + error };
|
||||
}
|
||||
}
|
||||
|
||||
getListOfTickets = async (
|
||||
email: string,
|
||||
offset: number = 0,
|
||||
limit: number = 25,
|
||||
): Promise<Result<TicketList[], string>> => {
|
||||
|
||||
try {
|
||||
const staff = await this.prisma.staff.findFirst({
|
||||
where: { email },
|
||||
});
|
||||
if (!staff) return { success: false, error: 'EMPLOYEE_NOT_FOUND' }
|
||||
|
||||
const rawTicketList = await this.prisma.$queryRaw<TicketList[]>(
|
||||
Prisma.sql`
|
||||
SELECT
|
||||
t.id AS id,
|
||||
t.status AS status,
|
||||
CONCAT(s.first_name,' ',s.last_name) AS assignTo,
|
||||
a.address1 AS deliveryAddress,
|
||||
t.subject AS subject,
|
||||
d.name AS department,
|
||||
t.parent AS parentTicketId,
|
||||
|
||||
CASE
|
||||
WHEN t.due_date > 1672531200
|
||||
THEN FROM_UNIXTIME(t.due_date, '%d/%m/%y')
|
||||
ELSE NULL
|
||||
END AS dueDate,
|
||||
|
||||
FROM_UNIXTIME(t.last_update, '%d/%m/%y') AS lastUpdate,
|
||||
|
||||
CASE
|
||||
WHEN CAST(t.date_closed AS UNSIGNED) > 1672531200
|
||||
THEN FROM_UNIXTIME(CAST(t.date_closed AS UNSIGNED), '%d/%m/%y')
|
||||
ELSE NULL
|
||||
END AS completedAt
|
||||
|
||||
FROM staff s
|
||||
LEFT JOIN ticket t ON t.assign_to = s.id
|
||||
LEFT JOIN account a ON t.account_id = a.id
|
||||
LEFT JOIN ticket_dept d ON t.dept_id = d.id
|
||||
WHERE s.id = ${staff.id}
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN t.status = 'open' AND t.assign_to = 0 THEN 0
|
||||
WHEN t.status = 'open' AND t.assign_to = s.id THEN 1
|
||||
WHEN t.status = 'pending' AND t.assign_to = s.id THEN 2
|
||||
WHEN t.status = 'open' AND t.assign_to != s.id THEN 3
|
||||
WHEN t.status = 'pending' AND t.assign_to != s.id THEN 4
|
||||
ELSE 5
|
||||
END
|
||||
LIMIT ${limit} OFFSET ${offset};
|
||||
`);
|
||||
|
||||
return { success: true, data: rawTicketList }
|
||||
} catch (error) {
|
||||
return { success: false, error: 'TICKET_LIST_NOT_FOUND, ' + error };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { PrismaMariaDbService } from "prisma/mariadb/prisma-mariadb.service";
|
||||
import { Result } from "src/common/errors/result-error.factory";
|
||||
|
||||
@Injectable()
|
||||
export class UpdateTicketService {
|
||||
constructor(private readonly prisma: PrismaMariaDbService) { }
|
||||
|
||||
updateTicketById = async (
|
||||
ticketId: number
|
||||
): Promise<Result<boolean, string>> => {
|
||||
try {
|
||||
await this.prisma.ticket.update({
|
||||
where: { id: ticketId },
|
||||
data: {}
|
||||
})
|
||||
|
||||
return { success: true, data: true }
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return { success: false, error: 'INVALID_TICKET_ID' }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,12 @@ import { Controller, Get, Param, ParseIntPipe, Query } from "@nestjs/common";
|
|||
import { Access } from "src/common/decorators/module-access.decorators";
|
||||
import { Result } from "src/common/errors/result-error.factory";
|
||||
import { TicketList } from "src/customer-support/tickets/dtos/ticket-list.dto";
|
||||
import { TicketService } from "src/customer-support/tickets/ticket.service";
|
||||
import { GetTicketListService } from "src/customer-support/tickets/services/get-ticket-list.service";
|
||||
|
||||
@Controller('tickets')
|
||||
export class TicketController {
|
||||
|
||||
constructor(private readonly getService: TicketService) { }
|
||||
constructor(private readonly getService: GetTicketListService) { }
|
||||
|
||||
@Get(':status')
|
||||
async findTicketByFilters(
|
||||
|
|
@ -31,4 +31,17 @@ export class TicketController {
|
|||
queryEmail,
|
||||
);
|
||||
}
|
||||
|
||||
@Get('list')
|
||||
async findTicketList(
|
||||
@Access('email') email:string,
|
||||
@Query('offset', ParseIntPipe) offset: number,
|
||||
@Query('limit', ParseIntPipe) limit: number,
|
||||
) {
|
||||
return await this.getService.getListOfTickets(
|
||||
email,
|
||||
offset,
|
||||
limit
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from "@nestjs/common";
|
||||
import { GetTicketListService } from "src/customer-support/tickets/services/get-ticket-list.service";
|
||||
import { TicketController } from "src/customer-support/tickets/ticket.controller";
|
||||
import { TicketService } from "src/customer-support/tickets/ticket.service";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TicketService
|
||||
GetTicketListService
|
||||
],
|
||||
providers: [
|
||||
TicketController
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { Result } from "src/common/errors/result-error.factory";
|
||||
import { PrismaMariaDbService } from "prisma/mariadb/prisma-mariadb.service";
|
||||
import { TicketList } from "src/customer-support/tickets/dtos/ticket-list.dto";
|
||||
import { sortOrders, sortTypes } from "src/customer-support/tickets/dtos/ticket.dto";
|
||||
import { Prisma } from "prisma/mariadb/generated/prisma/client/mariadb/client";
|
||||
|
||||
@Injectable()
|
||||
export class TicketService {
|
||||
constructor(private readonly prisma: PrismaMariaDbService) { }
|
||||
|
||||
getListOfAllTicketByFilters = async (
|
||||
status: string[],
|
||||
offset: number = 0,
|
||||
limit: number = 25,
|
||||
sortOrder: string = 'last_update',
|
||||
sortType: 'DESC' | 'ASC' = 'DESC',
|
||||
email?: string
|
||||
): Promise<Result<TicketList[], string>> => {
|
||||
|
||||
try {
|
||||
const staff = await this.prisma.staff.findFirst({
|
||||
where: { email },
|
||||
});
|
||||
if (!staff) return { success: false, error: 'EMPLOYEE_NOT_FOUND' }
|
||||
if (!sortOrders.includes(sortOrder) || !sortTypes.includes(sortType)) return { success: false, error: 'INVALID_FILTER' }
|
||||
|
||||
const statusList = Prisma.join(status);
|
||||
|
||||
const rawticketList = await this.prisma.$queryRaw<TicketList[]>(
|
||||
Prisma.sql`
|
||||
SELECT
|
||||
t.id AS id,
|
||||
t.status AS status,
|
||||
CONCAT(s.first_name,' ',s.last_name) AS assignTo,
|
||||
a.address1 AS deliveryAddress,
|
||||
t.subject AS subject,
|
||||
d.name AS department,
|
||||
t.parent AS parentTicketId,
|
||||
DATE_FORMAT(FROM_UNIXTIME(t.due_date / 1000), '%d/%m/%y') AS dueDate,
|
||||
DATE_FORMAT(FROM_UNIXTIME(t.last_update / 1000), '%d/%m/%y') AS updatedAt,
|
||||
CASE
|
||||
WHEN t.date_closed IS NOT NULL
|
||||
THEN DATE_FORMAT(FROM_UNIXTIME(t.date_closed / 1000), '%d/%m/%y')
|
||||
ELSE NULL
|
||||
END AS completedAt
|
||||
FROM staff s
|
||||
LEFT JOIN ticket t ON t.assign_to = s.id
|
||||
LEFT JOIN account a ON t.account_id = a.id
|
||||
LEFT JOIN ticket_dept d ON t.dept_id = d.id
|
||||
WHERE s.email = ${email}
|
||||
AND t.status IN (${statusList})
|
||||
ORDER BY ${Prisma.raw(sortOrder)} ${Prisma.raw(sortType)}
|
||||
LIMIT ${limit} OFFSET ${offset};
|
||||
`);
|
||||
|
||||
return { success: true, data: rawticketList }
|
||||
} catch (error) {
|
||||
return { success: false, error: 'TICKET_LIST_NOT_FOUND, ' + error };
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user