feat: task order (#7)
* feat: add task order table * refactor: update relation field * feat: basic task endpoints * feat: add filter by work status * refactor: update relation --------- Co-authored-by: Methapon2001 <61303214+Methapon2001@users.noreply.github.com>
This commit is contained in:
parent
ea337bd364
commit
c7f69666f2
3 changed files with 284 additions and 1 deletions
|
|
@ -480,6 +480,8 @@ model User {
|
||||||
paymentCreated Payment[]
|
paymentCreated Payment[]
|
||||||
notificationReceive Notification[] @relation("NotificationReceiver")
|
notificationReceive Notification[] @relation("NotificationReceiver")
|
||||||
notificationRead Notification[]
|
notificationRead Notification[]
|
||||||
|
taskOrderCreated TaskOrder[] @relation("TaskOrderCreatedByUser")
|
||||||
|
taskOrderAccepted TaskOrder[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserResponsibleArea {
|
model UserResponsibleArea {
|
||||||
|
|
@ -981,6 +983,8 @@ model Institution {
|
||||||
subDistrictId String
|
subDistrictId String
|
||||||
|
|
||||||
selectedImage String?
|
selectedImage String?
|
||||||
|
|
||||||
|
taskOrder TaskOrder[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model WorkflowTemplate {
|
model WorkflowTemplate {
|
||||||
|
|
@ -1449,5 +1453,38 @@ model RequestWorkStepStatus {
|
||||||
|
|
||||||
attributes Json?
|
attributes Json?
|
||||||
|
|
||||||
|
taskOrder TaskOrder? @relation(fields: [taskOrderId], references: [id])
|
||||||
|
taskOrderId String?
|
||||||
|
|
||||||
@@id([step, requestWorkId])
|
@@id([step, requestWorkId])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum TaskStatus {
|
||||||
|
Pending
|
||||||
|
InProgress
|
||||||
|
Validate
|
||||||
|
Complete
|
||||||
|
}
|
||||||
|
|
||||||
|
model TaskOrder {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
|
||||||
|
code String
|
||||||
|
|
||||||
|
taskName String
|
||||||
|
taskStatus TaskStatus @default(Pending)
|
||||||
|
taskList RequestWorkStepStatus[]
|
||||||
|
|
||||||
|
contactName String
|
||||||
|
contactTel String
|
||||||
|
|
||||||
|
institution Institution @relation(fields: [institutionId], references: [id])
|
||||||
|
institutionId String
|
||||||
|
|
||||||
|
acceptedBy User? @relation(fields: [acceptedByUserId], references: [id])
|
||||||
|
acceptedByUserId String?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
createdBy User @relation(name: "TaskOrderCreatedByUser", fields: [createdByUserId], references: [id])
|
||||||
|
createdByUserId String
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
import { Body, Controller, Get, Path, Put, Query, Request, Route, Security, Tags } from "tsoa";
|
import { Body, Controller, Get, Path, Put, Query, Request, Route, Security, Tags } from "tsoa";
|
||||||
import { RequestWithUser } from "../interfaces/user";
|
import { RequestWithUser } from "../interfaces/user";
|
||||||
import prisma from "../db";
|
import prisma from "../db";
|
||||||
import { Prisma, RequestDataStatus, RequestWorkStatus } from "@prisma/client";
|
import {
|
||||||
|
Prisma,
|
||||||
|
RequestDataStatus,
|
||||||
|
RequestWorkStatus,
|
||||||
|
RequestWorkStepStatus,
|
||||||
|
} from "@prisma/client";
|
||||||
import { createPermCondition } from "../services/permission";
|
import { createPermCondition } from "../services/permission";
|
||||||
import { queryOrNot } from "../utils/relation";
|
import { queryOrNot } from "../utils/relation";
|
||||||
import { notFoundError } from "../utils/error";
|
import { notFoundError } from "../utils/error";
|
||||||
|
|
@ -161,8 +166,10 @@ export class RequestListController extends Controller {
|
||||||
@Query() page: number = 1,
|
@Query() page: number = 1,
|
||||||
@Query() pageSize: number = 30,
|
@Query() pageSize: number = 30,
|
||||||
@Query() requestDataId?: string,
|
@Query() requestDataId?: string,
|
||||||
|
@Query() workStatus?: RequestWorkStatus,
|
||||||
) {
|
) {
|
||||||
const where = {
|
const where = {
|
||||||
|
stepStatus: { some: { workStatus } },
|
||||||
request: {
|
request: {
|
||||||
id: requestDataId,
|
id: requestDataId,
|
||||||
quotation: {
|
quotation: {
|
||||||
|
|
|
||||||
239
src/controllers/07-task-controller.ts
Normal file
239
src/controllers/07-task-controller.ts
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
Path,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
Query,
|
||||||
|
Request,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
} from "tsoa";
|
||||||
|
import prisma from "../db";
|
||||||
|
import { notFoundError } from "../utils/error";
|
||||||
|
import { TaskStatus } from "@prisma/client";
|
||||||
|
import { RequestWithUser } from "../interfaces/user";
|
||||||
|
|
||||||
|
@Route("/api/v1/task")
|
||||||
|
@Tags("Task Order")
|
||||||
|
export class TaskController extends Controller {
|
||||||
|
@Get()
|
||||||
|
@Security("keycloak")
|
||||||
|
async getTaskOrderList(@Query() query: string, @Query() page = 1, @Query() pageSize = 30) {
|
||||||
|
const [result, total] = await prisma.$transaction([
|
||||||
|
prisma.taskOrder.findMany({
|
||||||
|
include: {
|
||||||
|
institution: true,
|
||||||
|
acceptedBy: true,
|
||||||
|
createdBy: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
prisma.taskOrder.count(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return { result, total, page, pageSize };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("{taskId}")
|
||||||
|
@Security("keycloak")
|
||||||
|
async getTaskOrder(@Path() taskId: string) {
|
||||||
|
const record = await prisma.taskOrder.findFirst({
|
||||||
|
where: { id: taskId },
|
||||||
|
include: {
|
||||||
|
taskList: {
|
||||||
|
include: {
|
||||||
|
requestWork: {
|
||||||
|
include: {
|
||||||
|
productService: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
institution: true,
|
||||||
|
acceptedBy: true,
|
||||||
|
createdBy: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!record) throw notFoundError("Task Order");
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
async createTaskOrderList(
|
||||||
|
@Request() req: RequestWithUser,
|
||||||
|
@Body()
|
||||||
|
body: {
|
||||||
|
taskName: string;
|
||||||
|
taskStatus: TaskStatus;
|
||||||
|
|
||||||
|
contactName: string;
|
||||||
|
contactTel: string;
|
||||||
|
|
||||||
|
institutionId: string;
|
||||||
|
|
||||||
|
requestWork: { requestWorkId: string; step: number }[];
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
return await prisma.$transaction(async (tx) => {
|
||||||
|
const last = await tx.runningNo.upsert({
|
||||||
|
where: {
|
||||||
|
key: "TASK",
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
key: "TASK",
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
value: { increment: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const current = new Date();
|
||||||
|
const year = `${current.getFullYear()}`.slice(-2).padStart(2, "0");
|
||||||
|
const month = `${current.getMonth() + 1}`.padStart(2, "0");
|
||||||
|
|
||||||
|
const code = `PO${year}${month}${last.value.toString().padStart(6, "0")}`;
|
||||||
|
|
||||||
|
await tx.taskOrder.create({
|
||||||
|
include: {
|
||||||
|
taskList: {
|
||||||
|
include: {
|
||||||
|
requestWork: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
institution: true,
|
||||||
|
acceptedBy: true,
|
||||||
|
createdBy: true,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
...body,
|
||||||
|
code,
|
||||||
|
createdByUserId: req.user.sub,
|
||||||
|
taskList: {
|
||||||
|
connect: body.requestWork.map((v) => ({ step_requestWorkId: v })),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("{taskId}")
|
||||||
|
async editTaskById(
|
||||||
|
@Path() taskId: string,
|
||||||
|
@Body()
|
||||||
|
body: {
|
||||||
|
taskName: string;
|
||||||
|
taskStatus: TaskStatus;
|
||||||
|
|
||||||
|
contactName: string;
|
||||||
|
contactTel: string;
|
||||||
|
|
||||||
|
institutionId: string;
|
||||||
|
|
||||||
|
requestWork: { requestWorkId: string; step: number }[];
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const record = await prisma.taskOrder.findFirst({
|
||||||
|
where: { id: taskId },
|
||||||
|
include: {
|
||||||
|
taskList: {
|
||||||
|
include: { requestWork: true },
|
||||||
|
},
|
||||||
|
institution: true,
|
||||||
|
acceptedBy: true,
|
||||||
|
createdBy: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.taskOrder.update({
|
||||||
|
where: { id: taskId },
|
||||||
|
include: {
|
||||||
|
taskList: {
|
||||||
|
include: {
|
||||||
|
requestWork: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
institution: true,
|
||||||
|
acceptedBy: true,
|
||||||
|
createdBy: true,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
...body,
|
||||||
|
taskList: {
|
||||||
|
disconnect: record?.taskList
|
||||||
|
.filter(
|
||||||
|
(lhs) =>
|
||||||
|
!body.requestWork.find(
|
||||||
|
(rhs) => lhs.requestWorkId === rhs.requestWorkId && lhs.step === rhs.step,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map((v) => ({
|
||||||
|
step_requestWorkId: {
|
||||||
|
requestWorkId: v.requestWorkId,
|
||||||
|
step: v.step,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
connect: body.requestWork.map((v) => ({ step_requestWorkId: v })),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete("{taskId}")
|
||||||
|
async deleteTask(@Path() taskId: string) {
|
||||||
|
await prisma.$transaction(async (tx) => {
|
||||||
|
let record = await tx.taskOrder.deleteMany({ where: { id: taskId } });
|
||||||
|
|
||||||
|
if (record.count <= 0) throw notFoundError("Task Order");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route("/api/v1/task/{taskId}")
|
||||||
|
@Tags("Task Order")
|
||||||
|
export class TaskActionController extends Controller {
|
||||||
|
@Post("accept")
|
||||||
|
async acceptTaskOrder(@Request() req: RequestWithUser, @Path() taskId: string) {
|
||||||
|
const record = await prisma.taskOrder.findFirst({
|
||||||
|
include: {
|
||||||
|
taskList: {
|
||||||
|
orderBy: { step: "asc" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
where: { id: taskId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!record) throw notFoundError("Task Order");
|
||||||
|
|
||||||
|
return await prisma.$transaction(async (tx) => {
|
||||||
|
await tx.taskOrder.update({
|
||||||
|
where: { id: taskId },
|
||||||
|
data: {
|
||||||
|
acceptedByUserId: req.user.sub,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await tx.requestWorkStepStatus.updateMany({
|
||||||
|
where: { taskOrderId: taskId },
|
||||||
|
data: {
|
||||||
|
workStatus: "InProgress",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await tx.requestData.updateMany({
|
||||||
|
where: {
|
||||||
|
requestWork: {
|
||||||
|
some: {
|
||||||
|
stepStatus: {
|
||||||
|
some: { taskOrderId: taskId },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: { requestDataStatus: "InProgress" },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue