jws-backend/src/controllers/product-service-controller.ts
2024-07-05 11:02:18 +07:00

109 lines
3.1 KiB
TypeScript

import { Controller, Get, Query, Route, Security } from "tsoa";
import prisma from "../db";
import { Prisma, Product, Service } from "@prisma/client";
@Route("/api/v1/product-service")
export class ProductServiceController extends Controller {
@Get()
@Security("keycloak")
async getProductService(
@Query() status?: "ACTIVE" | "INACTIVE",
@Query() query = "",
@Query() productTypeId?: string,
@Query() page: number = 1,
@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 or: Prisma.Sql[] = [];
const and: Prisma.Sql[] = [];
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 work = await prisma.work.findMany({
where: { serviceId: { in: result.flatMap((v) => (v.type === "service" ? v.id : [])) } },
});
return {
result: result.map((v) =>
v.type === "service" ? { ...v, work: work.filter((w) => w.serviceId === v.id) || [] } : v,
),
page,
pageSize,
total: +String(total),
};
}
}