refactor: use kysely query builder instead

This commit is contained in:
Methapon Metanipat 2024-09-03 09:24:10 +07:00
parent 7fa99fab8f
commit dfb2ab3928

View file

@ -14,96 +14,93 @@ export class ProductServiceController extends Controller {
@Query() pageSize: number = 30, @Query() pageSize: number = 30,
@Query() registeredBranchId?: string, @Query() registeredBranchId?: string,
) { ) {
const union = Prisma.sql` const union = prisma.$kysely
SELECT .selectFrom((eb) =>
"id", eb
"code", .selectFrom("Product")
"name", .select([
"detail", "id",
"price", "code",
"agentPrice", "name",
"serviceCharge", "detail",
"process", "price",
"remark", "agentPrice",
"status", "serviceCharge",
"statusOrder", "process",
"productTypeId", "remark",
"registeredBranchId", "status",
"createdByUserId", "statusOrder",
"createdAt", "productTypeId",
"updatedByUserId", "registeredBranchId",
"updatedAt", "createdByUserId",
'product' as "type" "createdAt",
FROM "Product" "updatedByUserId",
UNION ALL "updatedAt",
SELECT sql<string>`'product'`.as("type"),
"id", ])
"code", .union((eb) =>
"name", eb
"detail", .selectFrom("Service")
null as "price", .select([
null as "agentPrice", "id",
null as "serviceCharge", "code",
null as "process", "name",
null as "remark", "detail",
"status", sql<number>`-1`.as("price"),
"statusOrder", sql<number>`-1`.as("agentPrice"),
"productTypeId", sql<number>`-1`.as("serviceCharge"),
"registeredBranchId", sql<number>`-1`.as("process"),
"createdByUserId", sql<string>`'-'`.as("remark"),
"createdAt", "status",
"updatedByUserId", "statusOrder",
"updatedAt", "productTypeId",
'service' as "type" "registeredBranchId",
FROM "Service" "createdByUserId",
`; "createdAt",
"updatedByUserId",
"updatedAt",
sql<string>`'service'`.as("type"),
]),
)
.as("p"),
)
.where((eb) => {
const condStatus = status ? eb("status", "=", status) : undefined;
const condQuery = query ? eb("name", "like", `%${query}%`) : undefined;
const condProductTypeId = productTypeId
? eb("productTypeId", "=", productTypeId)
: undefined;
const condRegisteredBranchId = registeredBranchId
? eb("registeredBranchId", "=", registeredBranchId).or("registeredBranchId", "is", null)
: undefined;
const or: Prisma.Sql[] = []; return eb.and(
const and: Prisma.Sql[] = []; [condStatus, condQuery, condProductTypeId, condRegisteredBranchId].filter((v) => !!v),
);
});
if (query) or.push(Prisma.sql`"name" LIKE ${`%${query}%`}`); const record = await union
if (status) and.push(Prisma.sql`"status" = ${status}::"Status"`); .selectAll()
if (productTypeId) { .orderBy("statusOrder asc")
and.push(Prisma.sql`"productTypeId" = ${productTypeId}`); .orderBy("createdAt asc")
} .limit(pageSize)
if (registeredBranchId) { .offset((page - 1) * pageSize)
and.push( .execute();
Prisma.sql`("registeredBranchId" = ${registeredBranchId} OR "registeredBranchId" IS NULL)`, const count = await union
); .select((eb) => eb.fn.count<number>("id").as("total"))
} .executeTakeFirst();
const where = Prisma.sql`
${or.length > 0 || and.length > 0 ? Prisma.sql`WHERE ` : Prisma.empty}
${or.length > 0 ? Prisma.join(or, " OR ", "(", ")") : Prisma.empty}
${or.length > 0 && and.length > 0 ? Prisma.sql` AND ` : Prisma.empty}
${and.length > 0 ? Prisma.join(and, " AND ", "(", ")") : Prisma.empty}
`;
console.log(where.sql);
const [result, [{ total }]] = await prisma.$transaction([
prisma.$queryRaw<((Product & { type: "product" }) | (Service & { type: "service" }))[]>`
SELECT * FROM (${union}) AS "ProductService"
${where}
ORDER BY "ProductService"."statusOrder" ASC, "ProductService"."createdAt" ASC
LIMIT ${pageSize} OFFSET ${(page - 1) * pageSize}
`,
prisma.$queryRaw<[{ total: number }]>`
SELECT COUNT(*) AS "total" FROM (${union}) as "ProductService"
${where}
`,
]);
const work = await prisma.work.findMany({ const work = await prisma.work.findMany({
where: { serviceId: { in: result.flatMap((v) => (v.type === "service" ? v.id : [])) } }, where: { serviceId: { in: record.flatMap((v) => (v.type === "service" ? v.id : [])) } },
}); });
return { return {
result: result.map((v) => result: record.map((v) =>
v.type === "service" ? { ...v, work: work.filter((w) => w.serviceId === v.id) || [] } : v, v.type === "service" ? { ...v, work: work.filter((w) => w.serviceId === v.id) || [] } : v,
), ),
page, page,
pageSize, pageSize,
total: +String(total), total: +String(count?.total || 0),
}; };
} }
} }