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

110 lines
3.1 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,
2024-07-04 11:27:26 +07:00
@Query() registeredBranchId?: string,
) {
const union = Prisma.sql`
SELECT
"id",
"code",
"name",
"detail",
"price",
"agentPrice",
"serviceCharge",
"process",
"remark",
"status",
"statusOrder",
"productTypeId",
2024-07-04 11:27:26 +07:00
"registeredBranchId",
2024-07-02 09:41:21 +07:00
"createdByUserId",
"createdAt",
2024-07-02 09:41:21 +07:00
"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",
2024-07-03 11:33:12 +07:00
"productTypeId",
2024-07-04 11:27:26 +07:00
"registeredBranchId",
2024-07-02 09:41:21 +07:00
"createdByUserId",
"createdAt",
2024-07-02 09:41:21 +07:00
"updatedByUserId",
"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) {
2024-07-05 11:02:18 +07:00
and.push(Prisma.sql`"productTypeId" = ${productTypeId}`);
2024-06-25 13:00:15 +07:00
}
2024-07-04 11:27:26 +07:00
if (registeredBranchId) {
and.push(
2024-07-05 11:02:18 +07:00
Prisma.sql`("registeredBranchId" = ${registeredBranchId} OR "registeredBranchId" IS NULL)`,
2024-07-04 11:27:26 +07:00
);
}
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}
`;
2024-07-05 11:02:18 +07:00
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}
`,
]);
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),
};
}
}