109 lines
3.1 KiB
TypeScript
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),
|
|
};
|
|
}
|
|
}
|