jws-backend/src/controllers/06-request-list-controller.ts

319 lines
8.1 KiB
TypeScript
Raw Normal View History

2024-10-16 17:41:47 +07:00
import { Body, Controller, Get, Path, Put, Query, Request, Route, Security, Tags } from "tsoa";
2024-10-09 15:04:59 +07:00
import { RequestWithUser } from "../interfaces/user";
import prisma from "../db";
2024-11-14 13:15:49 +07:00
import { Prisma, RequestDataStatus, RequestWorkStatus } from "@prisma/client";
2024-10-22 09:22:09 +07:00
import { createPermCondition } from "../services/permission";
import { queryOrNot } from "../utils/relation";
import { notFoundError } from "../utils/error";
2024-10-10 10:28:24 +07:00
// User in company can see.
const permissionCond = createPermCondition((_) => true);
2024-10-09 15:04:59 +07:00
2024-11-14 11:08:03 +07:00
@Route("/api/v1/request-data")
@Tags("Request List")
export class RequestDataController extends Controller {
2024-11-14 13:15:49 +07:00
@Get("stats")
@Security("keycloak")
async getRequestDataStats(@Request() req: RequestWithUser) {
const where = {
quotation: {
customerBranch: {
customer: {
registeredBranch: { OR: permissionCond(req.user) },
},
},
},
} satisfies Prisma.RequestDataWhereInput;
const list = await prisma.requestData.groupBy({
_count: true,
by: "requestDataStatus",
where: where,
});
return list.reduce<Record<RequestDataStatus, number>>(
(a, c) => Object.assign(a, { [c.requestDataStatus]: c._count }),
{
[RequestDataStatus.Pending]: 0,
[RequestDataStatus.InProgress]: 0,
[RequestDataStatus.Completed]: 0,
},
);
}
@Get()
@Security("keycloak")
2024-11-14 11:08:03 +07:00
async getRequestDataList(
@Request() req: RequestWithUser,
@Query() page: number = 1,
@Query() pageSize: number = 30,
2024-11-14 13:15:49 +07:00
@Query() query: string = "",
2024-11-18 13:02:04 +07:00
@Query() requestDataStatus?: RequestDataStatus,
) {
const where = {
OR: queryOrNot<Prisma.RequestDataWhereInput[]>(query, [
{ quotation: { code: { contains: query, mode: "insensitive" } } },
{ quotation: { workName: { contains: query } } },
{
quotation: {
customerBranch: {
OR: [
{ code: { contains: query, mode: "insensitive" } },
{ customerName: { contains: query } },
{ firstName: { contains: query } },
{ firstNameEN: { contains: query } },
{ lastName: { contains: query } },
{ lastNameEN: { contains: query } },
],
},
},
},
]),
2024-11-18 13:02:04 +07:00
requestDataStatus,
quotation: {
customerBranch: {
customer: {
registeredBranch: { OR: permissionCond(req.user) },
},
},
},
} satisfies Prisma.RequestDataWhereInput;
const [result, total] = await prisma.$transaction([
prisma.requestData.findMany({
where,
include: {
quotation: {
include: {
customerBranch: {
include: { customer: true },
},
},
},
employee: true,
},
take: pageSize,
skip: (page - 1) * pageSize,
}),
prisma.requestData.count({ where }),
]);
return { result, page, pageSize, total };
}
2024-11-14 11:08:03 +07:00
@Get("{requestDataId}")
@Security("keycloak")
async getRequestData(@Path() requestDataId: string) {
return await prisma.requestData.findFirst({
where: { id: requestDataId },
include: {
quotation: {
include: {
customerBranch: { include: { customer: true } },
},
},
employee: true,
},
});
}
}
2024-11-14 11:08:03 +07:00
@Route("/api/v1/request-work")
2024-10-09 15:04:59 +07:00
@Tags("Request List")
export class RequestListController extends Controller {
@Get()
@Security("keycloak")
2024-11-14 11:08:03 +07:00
async getRequestWork(
2024-10-09 15:04:59 +07:00
@Request() req: RequestWithUser,
@Query() page: number = 1,
@Query() pageSize: number = 30,
@Query() requestDataId?: string,
2024-10-09 15:04:59 +07:00
) {
2024-10-10 10:28:24 +07:00
const where = {
request: {
id: requestDataId,
2024-10-10 10:28:24 +07:00
quotation: {
customerBranch: {
customer: {
registeredBranch: { OR: permissionCond(req.user) },
},
},
},
},
} satisfies Prisma.RequestWorkWhereInput;
2024-10-10 09:40:09 +07:00
const [result, total] = await prisma.$transaction([
prisma.requestWork.findMany({
2024-10-10 10:28:24 +07:00
where,
2024-10-10 09:40:09 +07:00
include: {
request: {
include: {
quotation: true,
employee: true,
},
},
2024-11-19 13:48:45 +07:00
stepStatus: true,
2024-10-10 09:40:09 +07:00
productService: {
include: {
service: true,
work: true,
product: {
include: { document: true },
},
2024-10-10 09:40:09 +07:00
},
},
},
take: pageSize,
skip: (page - 1) * pageSize,
}),
2024-10-10 10:28:24 +07:00
prisma.requestWork.count({ where }),
2024-10-10 09:40:09 +07:00
]);
return {
result: result.map((v) => {
return Object.assign(v, {
productService: Object.assign(v.productService, {
product: Object.assign(v.productService.product, {
document: v.productService.product.document.map((doc) => doc.name),
}),
}),
});
}),
page,
pageSize,
total,
};
2024-10-09 15:04:59 +07:00
}
2024-11-14 11:08:03 +07:00
@Get("{requestWorkId}")
async getRequestWorkById(@Path() requestWorkId: string) {
const record = await prisma.requestWork.findFirst({
2024-10-10 09:40:09 +07:00
include: {
request: {
include: {
quotation: true,
employee: true,
},
},
2024-11-19 13:48:45 +07:00
stepStatus: true,
2024-10-10 09:40:09 +07:00
productService: {
include: {
service: true,
work: true,
product: {
include: {
document: true,
},
},
2024-10-10 09:40:09 +07:00
},
},
},
2024-11-14 11:08:03 +07:00
where: { id: requestWorkId },
2024-10-09 15:04:59 +07:00
});
if (!record) throw notFoundError("Request Work");
return Object.assign(record, {
productService: Object.assign(record.productService, {
product: Object.assign(record.productService.product, {
document: record.productService.product.document.map((doc) => doc.name),
}),
}),
});
2024-10-09 15:04:59 +07:00
}
2024-11-14 11:08:03 +07:00
@Put("{requestWorkId}")
2024-11-19 13:48:45 +07:00
@Security("keycloak")
2024-11-14 11:08:03 +07:00
async updateRequestWorkById(
2024-10-10 16:43:09 +07:00
@Request() req: RequestWithUser,
2024-11-14 11:08:03 +07:00
@Path() requestWorkId: string,
2024-11-19 13:48:45 +07:00
@Body() payload: { attributes: Record<string, any> },
2024-10-10 16:43:09 +07:00
) {
const record = await prisma.requestWork.update({
include: {
request: {
include: {
quotation: true,
employee: true,
},
},
stepStatus: true,
productService: {
include: {
service: true,
work: true,
product: {
include: {
document: true,
},
},
},
},
},
2024-11-14 11:08:03 +07:00
where: { id: requestWorkId },
data: { attributes: payload.attributes },
2024-10-10 16:43:09 +07:00
});
2024-10-09 15:04:59 +07:00
2024-10-10 16:43:09 +07:00
return record;
2024-10-09 15:04:59 +07:00
}
2024-11-19 13:48:45 +07:00
@Put("{requestWorkId}/step-status/{step}")
@Security("keycloak")
async updateRequestWorkStepStatus(
@Path() requestWorkId: string,
@Path() step: number,
@Body() payload: { requestWorkStatus?: RequestWorkStatus; attributes?: Record<string, any> },
2024-11-28 15:44:08 +07:00
@Query() successAll?: boolean,
2024-11-19 13:48:45 +07:00
) {
const record = await prisma.requestWorkStepStatus.upsert({
include: {
requestWork: true,
},
2024-11-19 13:48:45 +07:00
where: {
step_requestWorkId: {
step: step,
requestWorkId,
},
},
create: {
step: step,
requestWorkId,
workStatus: payload.requestWorkStatus,
attributes: payload.attributes,
2024-11-19 13:48:45 +07:00
},
update: {
workStatus: payload.requestWorkStatus,
attributes: payload.attributes,
2024-11-19 13:48:45 +07:00
},
});
switch (payload.requestWorkStatus) {
case "InProgress":
case "Waiting":
case "Validate":
await prisma.requestData.update({
where: {
id: record.requestWork.requestDataId,
},
data: { requestDataStatus: "InProgress" },
});
break;
case "Completed":
case "Ended":
if (successAll) {
await prisma.requestData.update({
where: {
id: record.requestWork.requestDataId,
},
data: { requestDataStatus: "Completed" },
});
}
break;
}
2024-11-19 13:48:45 +07:00
return record;
}
2024-10-09 15:04:59 +07:00
}
export class RequestListAttachmentController extends Controller {}