From dfb2ab39285b1fcb2a1bce8e67893e0055aecd55 Mon Sep 17 00:00:00 2001 From: Methapon Metanipat Date: Tue, 3 Sep 2024 09:24:10 +0700 Subject: [PATCH] refactor: use kysely query builder instead --- src/controllers/product-service-controller.ts | 155 +++++++++--------- 1 file changed, 76 insertions(+), 79 deletions(-) diff --git a/src/controllers/product-service-controller.ts b/src/controllers/product-service-controller.ts index c60ccba..7a361e1 100644 --- a/src/controllers/product-service-controller.ts +++ b/src/controllers/product-service-controller.ts @@ -14,96 +14,93 @@ export class ProductServiceController extends Controller { @Query() pageSize: number = 30, @Query() registeredBranchId?: string, ) { - const union = Prisma.sql` - SELECT - "id", - "code", - "name", - "detail", - "price", - "agentPrice", - "serviceCharge", - "process", - "remark", - "status", - "statusOrder", - "productTypeId", - "registeredBranchId", - "createdByUserId", - "createdAt", - "updatedByUserId", - "updatedAt", - 'product' as "type" - FROM "Product" - UNION ALL - SELECT - "id", - "code", - "name", - "detail", - null as "price", - null as "agentPrice", - null as "serviceCharge", - null as "process", - null as "remark", - "status", - "statusOrder", - "productTypeId", - "registeredBranchId", - "createdByUserId", - "createdAt", - "updatedByUserId", - "updatedAt", - 'service' as "type" - FROM "Service" - `; + const union = prisma.$kysely + .selectFrom((eb) => + eb + .selectFrom("Product") + .select([ + "id", + "code", + "name", + "detail", + "price", + "agentPrice", + "serviceCharge", + "process", + "remark", + "status", + "statusOrder", + "productTypeId", + "registeredBranchId", + "createdByUserId", + "createdAt", + "updatedByUserId", + "updatedAt", + sql`'product'`.as("type"), + ]) + .union((eb) => + eb + .selectFrom("Service") + .select([ + "id", + "code", + "name", + "detail", + sql`-1`.as("price"), + sql`-1`.as("agentPrice"), + sql`-1`.as("serviceCharge"), + sql`-1`.as("process"), + sql`'-'`.as("remark"), + "status", + "statusOrder", + "productTypeId", + "registeredBranchId", + "createdByUserId", + "createdAt", + "updatedByUserId", + "updatedAt", + sql`'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[] = []; - const and: Prisma.Sql[] = []; + return eb.and( + [condStatus, condQuery, condProductTypeId, condRegisteredBranchId].filter((v) => !!v), + ); + }); - if (query) or.push(Prisma.sql`"name" LIKE ${`%${query}%`}`); - if (status) and.push(Prisma.sql`"status" = ${status}::"Status"`); - if (productTypeId) { - and.push(Prisma.sql`"productTypeId" = ${productTypeId}`); - } - if (registeredBranchId) { - and.push( - Prisma.sql`("registeredBranchId" = ${registeredBranchId} OR "registeredBranchId" IS NULL)`, - ); - } - - 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 record = await union + .selectAll() + .orderBy("statusOrder asc") + .orderBy("createdAt asc") + .limit(pageSize) + .offset((page - 1) * pageSize) + .execute(); + const count = await union + .select((eb) => eb.fn.count("id").as("total")) + .executeTakeFirst(); 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 { - result: result.map((v) => + result: record.map((v) => v.type === "service" ? { ...v, work: work.filter((w) => w.serviceId === v.id) || [] } : v, ), page, pageSize, - total: +String(total), + total: +String(count?.total || 0), }; } }