218 lines
8.0 KiB
TypeScript
218 lines
8.0 KiB
TypeScript
import { and, eq, ilike, or, sql, asc, inArray } from "drizzle-orm";
|
|
import { Hono } from "hono";
|
|
import checkPermission from "../../middlewares/checkPermission";
|
|
import { z } from "zod";
|
|
import { HTTPException } from "hono/http-exception";
|
|
import db from "../../drizzle";
|
|
import { assessments } from "../../drizzle/schema/assessments";
|
|
import { respondents } from "../../drizzle/schema/respondents";
|
|
import { users } from "../../drizzle/schema/users";
|
|
import HonoEnv from "../../types/HonoEnv";
|
|
import requestValidator from "../../utils/requestValidator";
|
|
import authInfo from "../../middlewares/authInfo";
|
|
|
|
export const assessmentFormSchema = z.object({
|
|
respondentId: z.string().min(1),
|
|
status: z.enum(["menunggu konfirmasi", "diterima", "ditolak", "dalam pengerjaan", "belum diverifikasi", "selesai"]),
|
|
reviewedBy: z.string().min(1),
|
|
verifiedBy: z.string().min(1),
|
|
verifiedAt: z.string().optional(),
|
|
});
|
|
|
|
export const assessmentUpdateSchema = assessmentFormSchema.extend({
|
|
verifiedAt: z.string().optional().or(z.literal("")),
|
|
});
|
|
|
|
const assessmentsRequestManagementRoutes = new Hono<HonoEnv>()
|
|
.use(authInfo)
|
|
/**
|
|
* Get All Assessments (With Metadata)
|
|
*
|
|
* Query params:
|
|
* - withMetadata: boolean
|
|
*/
|
|
.get(
|
|
"/",
|
|
checkPermission("assessmentRequestManagement.readAll"),
|
|
requestValidator(
|
|
"query",
|
|
z.object({
|
|
withMetadata: z
|
|
.string()
|
|
.optional()
|
|
.transform((v) => v?.toLowerCase() === "true"),
|
|
page: z.coerce.number().int().min(0).default(0),
|
|
limit: z.coerce.number().int().min(1).max(1000).default(10),
|
|
q: z.string().default(""),
|
|
})
|
|
),
|
|
async (c) => {
|
|
const { page, limit, q } = c.req.valid("query");
|
|
|
|
const validStatuses = [
|
|
"dalam pengerjaan",
|
|
"menunggu konfirmasi",
|
|
"diterima",
|
|
"ditolak",
|
|
] as ("menunggu konfirmasi" | "diterima" | "ditolak" | "dalam pengerjaan")[];
|
|
|
|
// Query untuk menghitung total jumlah item (totalCountQuery)
|
|
const assessmentCountQuery = await db
|
|
.select({
|
|
count: sql<number>`count(*)`,
|
|
})
|
|
.from(assessments)
|
|
.leftJoin(respondents, eq(assessments.respondentId, respondents.id))
|
|
.leftJoin(users, eq(respondents.userId, users.id))
|
|
.where(
|
|
and(
|
|
inArray(assessments.status, validStatuses),
|
|
q
|
|
? or(
|
|
ilike(users.name, `%${q}%`),
|
|
ilike(respondents.companyName, `%${q}%`),
|
|
sql`CAST(${assessments.status} AS TEXT) ILIKE ${'%' + q + '%'}`,
|
|
eq(assessments.id, q)
|
|
)
|
|
: undefined
|
|
)
|
|
);
|
|
|
|
const totalItems = Number(assessmentCountQuery[0]?.count) || 0;
|
|
|
|
// Query utama untuk mendapatkan data permohonan assessment
|
|
const result = await db
|
|
.select({
|
|
idPermohonan: assessments.id,
|
|
namaResponden: users.name,
|
|
namaPerusahaan: respondents.companyName,
|
|
status: assessments.status,
|
|
tanggal: assessments.createdAt,
|
|
})
|
|
.from(assessments)
|
|
.leftJoin(respondents, eq(assessments.respondentId, respondents.id))
|
|
.leftJoin(users, eq(respondents.userId, users.id))
|
|
.where(
|
|
and(
|
|
inArray(assessments.status, validStatuses),
|
|
q
|
|
? or(
|
|
ilike(users.name, `%${q}%`),
|
|
ilike(respondents.companyName, `%${q}%`),
|
|
sql`CAST(${assessments.status} AS TEXT) ILIKE ${'%' + q + '%'}`,
|
|
eq(assessments.id, q)
|
|
)
|
|
: undefined
|
|
)
|
|
)
|
|
.orderBy(
|
|
sql`
|
|
CASE
|
|
WHEN ${assessments.status} = 'menunggu konfirmasi' THEN 1
|
|
WHEN ${assessments.status} = 'dalam pengerjaan' THEN 2
|
|
WHEN ${assessments.status} = 'diterima' THEN 3
|
|
WHEN ${assessments.status} = 'ditolak' THEN 4
|
|
ELSE 5
|
|
END
|
|
`,
|
|
asc(assessments.createdAt)
|
|
)
|
|
.offset(page * limit)
|
|
.limit(limit);
|
|
|
|
return c.json({
|
|
data: result.map((d) => ({
|
|
idPermohonan: d.idPermohonan,
|
|
namaResponden: d.namaResponden,
|
|
namaPerusahaan: d.namaPerusahaan,
|
|
status: d.status,
|
|
tanggal: d.tanggal,
|
|
})),
|
|
_metadata: {
|
|
currentPage: page,
|
|
totalPages: Math.ceil(totalItems / limit),
|
|
totalItems,
|
|
perPage: limit,
|
|
},
|
|
});
|
|
}
|
|
)
|
|
|
|
// Get assessment by id
|
|
.get(
|
|
"/:id",
|
|
checkPermission("assessmentRequestManagement.read"),
|
|
async (c) => {
|
|
const assessmentId = c.req.param("id");
|
|
|
|
const queryResult = await db
|
|
.select({
|
|
tanggal: assessments.createdAt,
|
|
nama: users.name,
|
|
posisi: respondents.position,
|
|
pengalamanKerja: respondents.workExperience,
|
|
email: users.email,
|
|
namaPerusahaan: respondents.companyName,
|
|
alamat: respondents.address,
|
|
nomorTelepon: respondents.phoneNumber,
|
|
username: users.username,
|
|
status: assessments.status,
|
|
})
|
|
.from(assessments)
|
|
.leftJoin(respondents, eq(assessments.respondentId, respondents.id))
|
|
.leftJoin(users, eq(respondents.userId, users.id))
|
|
.where(eq(assessments.id, assessmentId));
|
|
|
|
if (!queryResult.length)
|
|
throw new HTTPException(404, {
|
|
message: "The assessment does not exist",
|
|
});
|
|
|
|
const assessmentData = queryResult[0];
|
|
|
|
return c.json(assessmentData);
|
|
}
|
|
)
|
|
|
|
.patch(
|
|
"/:id",
|
|
checkPermission("assessmentRequestManagement.update"),
|
|
requestValidator(
|
|
"json",
|
|
z.object({
|
|
status: z.enum(["menunggu konfirmasi", "diterima", "ditolak", "dalam pengerjaan", "belum diverifikasi", "selesai"]),
|
|
})
|
|
),
|
|
async (c) => {
|
|
const assessmentId = c.req.param("id");
|
|
const { status } = c.req.valid("json");
|
|
const userName = c.var.currentUser?.name;
|
|
|
|
const assessment = await db
|
|
.select()
|
|
.from(assessments)
|
|
.where(and(eq(assessments.id, assessmentId),));
|
|
|
|
if (!assessment[0]) throw new HTTPException(404, {
|
|
message: "Assessment tidak ditemukan.",
|
|
});
|
|
|
|
const currentDate = new Date();
|
|
|
|
await db
|
|
.update(assessments)
|
|
.set({
|
|
status,
|
|
reviewedBy: userName,
|
|
reviewedAt: currentDate,
|
|
})
|
|
.where(eq(assessments.id, assessmentId));
|
|
|
|
return c.json({
|
|
message: "Status assessment berhasil diperbarui.",
|
|
});
|
|
}
|
|
)
|
|
|
|
export default assessmentsRequestManagementRoutes;
|