jws-backend/src/controllers/product-service-controller.ts

101 lines
2.8 KiB
TypeScript
Raw Normal View History

2024-06-25 14:54:48 +07:00
import { Controller, Get, Query, Route, Security } from "tsoa";
import prisma from "../db";
import { Prisma, Product, Service } from "@prisma/client";
2024-06-25 11:53:13 +07:00
@Route("/api/v1/product-service")
export class ProductServiceController extends Controller {
@Get()
2024-06-25 14:54:48 +07:00
@Security("keycloak")
async getProductService(
@Query() status?: "ACTIVE" | "INACTIVE",
2024-06-25 11:53:13 +07:00
@Query() query = "",
@Query() productTypeId?: string,
@Query() page: number = 1,
@Query() pageSize: number = 30,
) {
const union = Prisma.sql`
SELECT
"id",
"code",
"name",
"detail",
"price",
"agentPrice",
"serviceCharge",
"process",
"remark",
"status",
"statusOrder",
"productTypeId",
"createdBy",
"createdAt",
"updatedBy",
"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",
null as "productTypeId",
"createdBy",
"createdAt",
"updatedBy",
"updatedAt",
'service' as "type"
FROM "Service"
`;
const or: Prisma.Sql[] = [];
const and: Prisma.Sql[] = [];
2024-06-25 14:54:58 +07:00
if (query) or.push(Prisma.sql`"name" LIKE ${`%${query}%`}`);
if (status) and.push(Prisma.sql`"status" = ${status}::"Status"`);
2024-06-25 13:00:15 +07:00
if (productTypeId) {
and.push(Prisma.sql`("productTypeId" = ${productTypeId} OR ("type" = 'service'))`);
}
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}
`;
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}
`,
]);
2024-06-25 09:54:59 +07:00
const work = await prisma.work.findMany({
where: { serviceId: { in: result.flatMap((v) => (v.type === "service" ? v.id : [])) } },
});
return {
2024-06-25 09:54:59 +07:00
result: result.map((v) =>
v.type === "service" ? { ...v, work: work.filter((w) => w.serviceId === v.id) || [] } : v,
),
page,
pageSize,
total: +String(total),
};
}
}